【dd2.0】Support the Core API for dd2.0 (#7791)
This commit is contained in:
parent
259431ace3
commit
2f5e4ac27e
|
@ -4,11 +4,14 @@ cwd = GetCurrentDir()
|
|||
src = ['device.c']
|
||||
CPPPATH = [cwd + '/../include']
|
||||
|
||||
if GetDepend(['RT_USING_DEV_BUS']):
|
||||
if GetDepend(['RT_USING_DEV_BUS']) or GetDepend(['RT_USING_DM']):
|
||||
src = src + ['bus.c']
|
||||
|
||||
if GetDepend(['RT_USING_DM']):
|
||||
src = src + ['dm.c', 'driver.c']
|
||||
src = src + ['dm.c', 'driver.c', 'platform.c']
|
||||
|
||||
if GetDepend(['RT_USING_OFW']):
|
||||
src += ['platform_ofw.c']
|
||||
|
||||
group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_DEVICE'], CPPPATH = CPPPATH)
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-10-13 flybreak the first version
|
||||
* 2023-04-12 ErikChan support rt_bus
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
@ -18,6 +19,18 @@
|
|||
#define DBG_LVL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
|
||||
#ifdef RT_USING_DM
|
||||
#include <drivers/core/bus.h>
|
||||
|
||||
static struct rt_bus bus_root =
|
||||
{
|
||||
.name = "root",
|
||||
.children = RT_LIST_OBJECT_INIT(bus_root.children),
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_DEV_BUS
|
||||
|
||||
#if defined(RT_USING_POSIX_DEVIO)
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
@ -78,3 +91,320 @@ rt_err_t rt_device_bus_destroy(rt_device_t dev)
|
|||
LOG_D("bus destroy");
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_DM
|
||||
/**
|
||||
* @brief This function get the root bus
|
||||
*/
|
||||
rt_bus_t rt_bus_root(void)
|
||||
{
|
||||
return &bus_root;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function loop the dev_list of the bus, and call fn in each loop
|
||||
*
|
||||
* @param bus the target bus
|
||||
*
|
||||
* @param drv the target drv to be matched
|
||||
*
|
||||
* @param fn the function callback in each loop
|
||||
*
|
||||
* @return the error code, RT_EOK on added successfully.
|
||||
*/
|
||||
rt_err_t rt_bus_for_each_dev(rt_bus_t bus, rt_driver_t drv, int (*fn)(rt_driver_t drv, rt_device_t dev))
|
||||
{
|
||||
rt_base_t level;
|
||||
rt_device_t dev;
|
||||
|
||||
RT_ASSERT(bus != RT_NULL);
|
||||
RT_ASSERT(drv != RT_NULL);
|
||||
|
||||
level = rt_spin_lock_irqsave(&bus->spinlock);
|
||||
|
||||
rt_list_for_each_entry(dev, &bus->dev_list, node)
|
||||
{
|
||||
fn(drv, dev);
|
||||
}
|
||||
|
||||
rt_spin_unlock_irqrestore(&bus->spinlock, level);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function loop the drv_list of the bus, and call fn in each loop
|
||||
*
|
||||
* @param bus the target bus
|
||||
*
|
||||
* @param dev the target dev to be matched
|
||||
*
|
||||
* @param fn the function callback in each loop
|
||||
*
|
||||
* @return the error code, RT_EOK on added successfully.
|
||||
*/
|
||||
rt_err_t rt_bus_for_each_drv(rt_bus_t bus, rt_device_t dev, int (*fn)(rt_driver_t drv, rt_device_t dev))
|
||||
{
|
||||
rt_err_t err;
|
||||
rt_base_t level;
|
||||
rt_driver_t drv;
|
||||
|
||||
RT_ASSERT(bus != RT_NULL);
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
if (rt_list_isempty(&bus->drv_list))
|
||||
{
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
err = -RT_ERROR;
|
||||
|
||||
level = rt_spin_lock_irqsave(&bus->spinlock);
|
||||
|
||||
rt_list_for_each_entry(drv, &bus->drv_list, node)
|
||||
{
|
||||
if (fn(drv, dev))
|
||||
{
|
||||
err = -RT_EOK;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rt_spin_unlock_irqrestore(&bus->spinlock, level);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function add a bus to the root
|
||||
*
|
||||
* @param bus_node the bus to be added
|
||||
*
|
||||
* @return the error code, RT_EOK on added successfully.
|
||||
*/
|
||||
rt_err_t rt_bus_add(rt_bus_t bus_node)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
RT_ASSERT(bus_node != RT_NULL);
|
||||
|
||||
bus_node->bus = &bus_root;
|
||||
rt_list_init(&bus_node->list);
|
||||
|
||||
level = rt_spin_lock_irqsave(&bus_node->spinlock);
|
||||
|
||||
rt_list_insert_before(&bus_root.children, &bus_node->list);
|
||||
|
||||
rt_spin_unlock_irqrestore(&bus_node->spinlock, level);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function match the device and driver, probe them if match successed
|
||||
*
|
||||
* @param drv the drv to match/probe
|
||||
*
|
||||
* @param dev the dev to match/probe
|
||||
*
|
||||
* @return the result of probe, 1 on added successfully.
|
||||
*/
|
||||
static int rt_bus_probe(rt_driver_t drv, rt_device_t dev)
|
||||
{
|
||||
int ret = 0;
|
||||
rt_bus_t bus = drv->bus;
|
||||
|
||||
if (!bus)
|
||||
{
|
||||
bus = dev->bus;
|
||||
}
|
||||
|
||||
RT_ASSERT(bus != RT_NULL);
|
||||
|
||||
if (!dev->drv && bus->match(drv, dev))
|
||||
{
|
||||
dev->drv = drv;
|
||||
|
||||
ret = bus->probe(dev);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
dev->drv = RT_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function add a driver to the drv_list of a specific bus
|
||||
*
|
||||
* @param bus the bus to add
|
||||
*
|
||||
* @param drv the driver to be added
|
||||
*
|
||||
* @return the error code, RT_EOK on added successfully.
|
||||
*/
|
||||
rt_err_t rt_bus_add_driver(rt_bus_t bus, rt_driver_t drv)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
RT_ASSERT(bus != RT_NULL);
|
||||
RT_ASSERT(drv != RT_NULL);
|
||||
|
||||
drv->bus = bus;
|
||||
|
||||
level = rt_spin_lock_irqsave(&bus->spinlock);
|
||||
|
||||
rt_list_insert_before(&bus->drv_list, &drv->node);
|
||||
|
||||
rt_spin_unlock_irqrestore(&bus->spinlock, level);
|
||||
|
||||
rt_bus_for_each_dev(drv->bus, drv, rt_bus_probe);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function add a device to the dev_list of a specific bus
|
||||
*
|
||||
* @param bus the bus to add
|
||||
*
|
||||
* @param dev the device to be added
|
||||
*
|
||||
* @return the error code, RT_EOK on added successfully.
|
||||
*/
|
||||
rt_err_t rt_bus_add_device(rt_bus_t bus, rt_device_t dev)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
RT_ASSERT(bus != RT_NULL);
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
dev->bus = bus;
|
||||
|
||||
level = rt_spin_lock_irqsave(&bus->spinlock);
|
||||
|
||||
rt_list_insert_before(&bus->dev_list, &dev->node);
|
||||
|
||||
rt_spin_unlock_irqrestore(&bus->spinlock, level);
|
||||
|
||||
rt_bus_for_each_drv(dev->bus, dev, rt_bus_probe);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function remove a driver from bus
|
||||
*
|
||||
* @param drv the driver to be removed
|
||||
*
|
||||
* @return the error code, RT_EOK on added successfully.
|
||||
*/
|
||||
rt_err_t rt_bus_remove_driver(rt_driver_t drv)
|
||||
{
|
||||
RT_ASSERT(drv->bus != RT_NULL);
|
||||
|
||||
LOG_D("Bus(%s) remove driver %s", drv->bus->name, drv->name);
|
||||
|
||||
rt_list_remove(&drv->node);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function remove a device from bus
|
||||
*
|
||||
* @param dev the device to be removed
|
||||
*
|
||||
* @return the error code, RT_EOK on added successfully.
|
||||
*/
|
||||
rt_err_t rt_bus_remove_device(rt_device_t dev)
|
||||
{
|
||||
RT_ASSERT(dev->bus != RT_NULL);
|
||||
|
||||
LOG_D("Bus(%s) remove device %s", dev->bus->name, dev->name);
|
||||
|
||||
rt_list_remove(&dev->node);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function find a bus by name
|
||||
* @param bus the name to be finded
|
||||
*
|
||||
* @return the bus finded by name.
|
||||
*/
|
||||
rt_bus_t rt_bus_find_by_name(char *name)
|
||||
{
|
||||
rt_bus_t bus = RT_NULL;
|
||||
struct rt_list_node *node = RT_NULL;
|
||||
|
||||
if (!rt_list_isempty(&bus_root.children))
|
||||
{
|
||||
rt_list_for_each(node, &bus_root.children)
|
||||
{
|
||||
bus = rt_list_entry(node, struct rt_bus, list);
|
||||
|
||||
if (!rt_strncmp(bus->name, name, RT_NAME_MAX))
|
||||
{
|
||||
return bus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function transfer dev_list and drv_list to the other bus
|
||||
*
|
||||
* @param new_bus the bus to transfer
|
||||
*
|
||||
* @param dev the target device
|
||||
*
|
||||
* @return the error code, RT_EOK on added successfully.
|
||||
*/
|
||||
rt_err_t rt_bus_reload_driver_device(rt_bus_t new_bus, rt_device_t dev)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
RT_ASSERT(new_bus != RT_NULL);
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
level = rt_spin_lock_irqsave(&new_bus->spinlock);
|
||||
|
||||
rt_list_remove(&dev->node);
|
||||
rt_list_insert_before(&new_bus->dev_list, &dev->node);
|
||||
|
||||
rt_list_remove(&dev->drv->node);
|
||||
rt_list_insert_before(&new_bus->drv_list, &dev->drv->node);
|
||||
|
||||
rt_spin_unlock_irqrestore(&new_bus->spinlock, level);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function register a bus
|
||||
* @param bus the bus to be registered
|
||||
*
|
||||
* @return the error code, RT_EOK on registeration successfully.
|
||||
*/
|
||||
rt_err_t rt_bus_register(rt_bus_t bus)
|
||||
{
|
||||
rt_list_init(&bus->children);
|
||||
rt_list_init(&bus->dev_list);
|
||||
rt_list_init(&bus->drv_list);
|
||||
|
||||
rt_spin_lock_init(&bus->spinlock);
|
||||
|
||||
rt_bus_add(bus);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -470,87 +470,4 @@ rt_err_t rt_device_set_tx_complete(rt_device_t dev,
|
|||
}
|
||||
RTM_EXPORT(rt_device_set_tx_complete);
|
||||
|
||||
#ifdef RT_USING_DM
|
||||
/**
|
||||
* This function bind drvier and device
|
||||
*
|
||||
* @param device the pointer of device structure
|
||||
* @param driver the pointer of driver structure
|
||||
* @param node the pointer of fdt node structure
|
||||
*
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
*/
|
||||
rt_err_t rt_device_bind_driver(rt_device_t device, rt_driver_t driver, void *node)
|
||||
{
|
||||
if((!driver) || (!device))
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
|
||||
device->drv = driver;
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
device->ops = driver->dev_ops;
|
||||
#endif
|
||||
device->dtb_node = node;
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
RTM_EXPORT(rt_device_bind_driver);
|
||||
|
||||
/**
|
||||
* This function create rt_device according to driver infomation
|
||||
*
|
||||
* @param drv the pointer of driver structure
|
||||
* @param device_id specify the ID of the rt_device
|
||||
*
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
*/
|
||||
rt_device_t rt_device_create_since_driver(rt_driver_t drv,int device_id)
|
||||
{
|
||||
rt_device_t device;
|
||||
if (!drv)
|
||||
{
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
device = (rt_device_t)rt_calloc(1,drv->device_size);
|
||||
if(device == RT_NULL)
|
||||
{
|
||||
return RT_NULL;
|
||||
}
|
||||
device->device_id = device_id;
|
||||
rt_snprintf(device->parent.name, sizeof(device->parent.name), "%s%d", drv->name, device_id);
|
||||
return device;
|
||||
}
|
||||
RTM_EXPORT(rt_device_create_since_driver);
|
||||
|
||||
/**
|
||||
* This function rt_device probe and init
|
||||
*
|
||||
* @param device the pointer of rt_device structure
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
*/
|
||||
rt_err_t rt_device_probe_and_init(rt_device_t device)
|
||||
{
|
||||
int ret = -RT_ERROR;
|
||||
if (!device)
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
if(!device->drv)
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
if(device->drv->probe)
|
||||
{
|
||||
ret = device->drv->probe((rt_device_t)device);
|
||||
}
|
||||
if(device->drv->probe_init)
|
||||
{
|
||||
ret = device->drv->probe_init((rt_device_t)device);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
RTM_EXPORT(rt_device_probe_and_init);
|
||||
#endif /* RT_USING_DM */
|
||||
#endif /* RT_USING_DEVICE */
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <rtthread.h>
|
||||
|
||||
#include <drivers/core/rtdm.h>
|
||||
#include <drivers/core/dm.h>
|
||||
|
||||
#ifdef RT_USING_SMP
|
||||
static int rti_secondary_cpu_start(void)
|
||||
|
|
|
@ -5,109 +5,49 @@
|
|||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <drivers/core/bus.h>
|
||||
|
||||
#ifdef RT_USING_DM
|
||||
|
||||
#ifdef RT_USING_FDT
|
||||
#include <dtb_node.h>
|
||||
#if defined(RT_USING_POSIX_DEVIO)
|
||||
#include <rtdevice.h> /* for wqueue_init */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This function driver device match with id
|
||||
* This function attach a driver to bus
|
||||
*
|
||||
* @param drv the pointer of driver structure
|
||||
* @param device_id the id of the device
|
||||
*
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
* @param drv the driver to be attached
|
||||
*/
|
||||
rt_err_t rt_driver_match_with_id(const rt_driver_t drv,int device_id)
|
||||
rt_err_t rt_driver_register(rt_driver_t drv)
|
||||
{
|
||||
rt_device_t device;
|
||||
int ret;
|
||||
if (!drv)
|
||||
rt_err_t ret;
|
||||
struct rt_bus *bus = RT_NULL;
|
||||
|
||||
RT_ASSERT(drv != RT_NULL);
|
||||
|
||||
if (drv->bus)
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
bus = drv->bus;
|
||||
ret = rt_bus_add_driver(bus, drv);
|
||||
}
|
||||
device = rt_device_create_since_driver(drv,device_id);
|
||||
if(!device)
|
||||
else
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
ret = rt_device_bind_driver(device,drv,RT_NULL);
|
||||
if(ret != 0)
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
ret = rt_device_probe_and_init(device);
|
||||
if(ret != 0)
|
||||
{
|
||||
return -RT_ERROR;
|
||||
ret = -RT_EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
RTM_EXPORT(rt_driver_match_with_id);
|
||||
RTM_EXPORT(rt_driver_register);
|
||||
|
||||
#ifdef RT_USING_FDT
|
||||
/**
|
||||
* This function driver device match with dtb_node
|
||||
* This function remove driver from system.
|
||||
*
|
||||
* @param drv the pointer of driver structure
|
||||
* @param from_node dtb node entry
|
||||
* @param max_dev_num the max device support
|
||||
*
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
* @param drv the driver to be removed
|
||||
*/
|
||||
rt_err_t rt_driver_match_with_dtb(const rt_driver_t drv,void *from_node,int max_dev_num)
|
||||
rt_err_t rt_driver_unregister(rt_driver_t drv)
|
||||
{
|
||||
struct dtb_node** node_list;
|
||||
rt_device_t device;
|
||||
int ret,i;
|
||||
int total_dev_num = 0;
|
||||
if ((!drv)||(!drv->dev_match)||(!drv->dev_match->compatible)||(!from_node)||(!drv->device_size))
|
||||
{
|
||||
return -RT_EINVAL;
|
||||
}
|
||||
rt_err_t ret;
|
||||
|
||||
node_list = rt_calloc(max_dev_num,sizeof(void *));
|
||||
if(!node_list)
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
ret = rt_bus_remove_driver(drv);
|
||||
|
||||
ret = dtb_node_find_all_compatible_node(from_node,drv->dev_match->compatible,node_list,max_dev_num,&total_dev_num);
|
||||
if((ret != 0) || (!total_dev_num))
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
for(i = 0; i < total_dev_num; i ++)
|
||||
{
|
||||
if (!dtb_node_device_is_available(node_list[i]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
device = rt_device_create_since_driver(drv,i);
|
||||
if(!device)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = rt_device_bind_driver(device,drv,node_list[i]);
|
||||
if(ret != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
ret = rt_device_probe_and_init(device);
|
||||
if(ret != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
rt_free(node_list);
|
||||
return ret;
|
||||
}
|
||||
RTM_EXPORT(rt_driver_match_with_dtb);
|
||||
#endif /* RT_USING_FDT */
|
||||
|
||||
#endif /* RT_USING_DM */
|
||||
|
||||
RTM_EXPORT(rt_driver_register);
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-04-12 ErikChan the first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#include <drivers/platform.h>
|
||||
#include <drivers/core/bus.h>
|
||||
#include <drivers/core/dm.h>
|
||||
|
||||
static struct rt_bus platform_bus;
|
||||
|
||||
/**
|
||||
* @brief This function create a platform device.
|
||||
*
|
||||
* @param name is name of the platform device.
|
||||
*
|
||||
* @return a new platform device.
|
||||
*/
|
||||
struct rt_platform_device *rt_platform_device_alloc(const char *name)
|
||||
{
|
||||
struct rt_platform_device *pdev = rt_calloc(1, sizeof(*pdev));
|
||||
|
||||
pdev->parent.bus = &platform_bus;
|
||||
pdev->name = name;
|
||||
|
||||
return pdev;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function register a rt_driver to platform bus.
|
||||
*
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
*/
|
||||
rt_err_t rt_platform_driver_register(struct rt_platform_driver *pdrv)
|
||||
{
|
||||
RT_ASSERT(pdrv != RT_NULL);
|
||||
|
||||
pdrv->parent.bus = &platform_bus;
|
||||
|
||||
return rt_driver_register(&pdrv->parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function register a rt_device to platform bus.
|
||||
*
|
||||
* @return the error code, RT_EOK on successfully.
|
||||
*/
|
||||
rt_err_t rt_platform_device_register(struct rt_platform_device *pdev)
|
||||
{
|
||||
RT_ASSERT(pdev != RT_NULL);
|
||||
|
||||
return rt_bus_add_device(&platform_bus, &pdev->parent);
|
||||
}
|
||||
|
||||
static rt_bool_t platform_match(rt_driver_t drv, rt_device_t dev)
|
||||
{
|
||||
struct rt_ofw_node *np = dev->ofw_node;
|
||||
struct rt_platform_driver *pdrv = rt_container_of(drv, struct rt_platform_driver, parent);
|
||||
struct rt_platform_device *pdev = rt_container_of(dev, struct rt_platform_device, parent);
|
||||
|
||||
if (np)
|
||||
{
|
||||
/* 1、match with ofw node */
|
||||
pdev->id = rt_ofw_node_match(np, pdrv->ids);
|
||||
|
||||
return !!pdev->id;
|
||||
}
|
||||
else if (pdev->name && pdrv->name)
|
||||
{
|
||||
/* 2、match with name */
|
||||
if (pdev->name == pdrv->name)
|
||||
{
|
||||
return RT_TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return !rt_strcmp(pdrv->name, pdev->name);
|
||||
}
|
||||
}
|
||||
|
||||
return RT_FALSE;
|
||||
}
|
||||
|
||||
static rt_err_t platform_probe(rt_device_t dev)
|
||||
{
|
||||
rt_err_t err;
|
||||
struct rt_ofw_node *np = dev->ofw_node;
|
||||
struct rt_platform_driver *pdrv = rt_container_of(dev->drv, struct rt_platform_driver, parent);
|
||||
struct rt_platform_device *pdev = rt_container_of(dev, struct rt_platform_device, parent);
|
||||
|
||||
err = pdrv->probe(pdev);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
if (np)
|
||||
{
|
||||
rt_ofw_node_set_flag(np, RT_OFW_F_READLY);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (np)
|
||||
{
|
||||
rt_ofw_data(np) = &pdev->parent;
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static struct rt_bus platform_bus =
|
||||
{
|
||||
.name = "platform",
|
||||
.match = platform_match,
|
||||
.probe = platform_probe,
|
||||
};
|
||||
|
||||
static int platform_bus_init(void)
|
||||
{
|
||||
rt_bus_register(&platform_bus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_CORE_EXPORT(platform_bus_init);
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-06-04 GuEe-GUI the first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#define DBG_TAG "drv.platform"
|
||||
#define DBG_LVL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
|
||||
#include <drivers/platform.h>
|
||||
#include <drivers/core/dm.h>
|
||||
|
||||
static const struct rt_ofw_node_id platform_ofw_ids[] =
|
||||
{
|
||||
{ .compatible = "simple-bus", },
|
||||
#ifdef RT_USING_MFD
|
||||
{ .compatible = "simple-mfd", },
|
||||
#endif
|
||||
#ifdef RT_USING_ISA
|
||||
{ .compatible = "isa", },
|
||||
#endif
|
||||
#ifdef RT_USING_AMBA_BUS
|
||||
/*
|
||||
* Maybe ARM has replaced it with compatible: "arm,primecell" and will not
|
||||
* used anymore in the future.
|
||||
*/
|
||||
{ .compatible = "arm,amba-bus", },
|
||||
#endif
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static rt_err_t platform_ofw_device_probe_once(struct rt_ofw_node *parent_np)
|
||||
{
|
||||
rt_err_t err = RT_EOK;
|
||||
struct rt_ofw_node *np, *child;
|
||||
struct rt_platform_device *pdev;
|
||||
|
||||
rt_ofw_foreach_available_child_node(parent_np, np)
|
||||
{
|
||||
const char *name;
|
||||
struct rt_ofw_node_id *id;
|
||||
struct rt_ofw_prop *compat_prop = RT_NULL;
|
||||
|
||||
/* Is system node or have driver */
|
||||
if (rt_ofw_node_test_flag(np, RT_OFW_F_SYSTEM) ||
|
||||
rt_ofw_node_test_flag(np, RT_OFW_F_READLY))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
compat_prop = rt_ofw_get_prop(np, "compatible", RT_NULL);
|
||||
name = rt_ofw_node_name(np);
|
||||
|
||||
/* Not have name and compatible */
|
||||
if (!compat_prop && (name == (const char *)"<NULL>" || !rt_strcmp(name, "<NULL>")))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
id = rt_ofw_prop_match(compat_prop, platform_ofw_ids);
|
||||
|
||||
if (id && (child = rt_ofw_get_next_child(np, RT_NULL)))
|
||||
{
|
||||
/* scan next level */
|
||||
err = platform_ofw_device_probe_once(child);
|
||||
|
||||
rt_ofw_node_put(child);
|
||||
|
||||
if (err)
|
||||
{
|
||||
LOG_E("%s bus probe fail", np->full_name);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pdev = rt_platform_device_alloc(np->name);
|
||||
|
||||
if (!pdev)
|
||||
{
|
||||
err = -RT_ENOMEM;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* inc reference of dt-node */
|
||||
rt_ofw_node_get(np);
|
||||
rt_ofw_node_set_flag(np, RT_OFW_F_PLATFORM);
|
||||
|
||||
pdev->parent.ofw_node = np;
|
||||
|
||||
rt_platform_device_register(pdev);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int platform_ofw_device_probe(void)
|
||||
{
|
||||
rt_err_t err = RT_EOK;
|
||||
struct rt_ofw_node *root_np;
|
||||
|
||||
root_np = rt_ofw_find_node_by_path("/");
|
||||
|
||||
if (root_np)
|
||||
{
|
||||
err = platform_ofw_device_probe_once(root_np);
|
||||
|
||||
rt_ofw_node_put(root_np);
|
||||
}
|
||||
else
|
||||
{
|
||||
err = -RT_ENOSYS;
|
||||
}
|
||||
|
||||
return (int)err;
|
||||
}
|
||||
INIT_PLATFORM_EXPORT(platform_ofw_device_probe);
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-04-12 ErikChan the first version
|
||||
*/
|
||||
|
||||
#ifndef __BUS_H__
|
||||
#define __BUS_H__
|
||||
|
||||
#include <rthw.h>
|
||||
#include <drivers/core/device.h>
|
||||
#include <drivers/core/driver.h>
|
||||
|
||||
typedef struct rt_bus *rt_bus_t;
|
||||
|
||||
struct rt_bus
|
||||
{
|
||||
struct rt_object parent; /**< inherit from rt_object */
|
||||
|
||||
char *name;
|
||||
struct rt_bus *bus;
|
||||
|
||||
rt_list_t list;
|
||||
rt_list_t children;
|
||||
rt_list_t dev_list;
|
||||
rt_list_t drv_list;
|
||||
|
||||
struct rt_spinlock spinlock;
|
||||
|
||||
rt_bool_t (*match)(rt_driver_t drv, rt_device_t dev);
|
||||
rt_err_t (*probe)(rt_device_t dev);
|
||||
};
|
||||
|
||||
rt_bus_t rt_bus_root(void);
|
||||
|
||||
rt_err_t rt_bus_for_each_dev(rt_bus_t bus, rt_driver_t drv, int (*fn)(rt_driver_t drv, rt_device_t dev));
|
||||
rt_err_t rt_bus_for_each_drv(rt_bus_t bus, rt_device_t dev, int (*fn)(rt_driver_t drv, rt_device_t dev));
|
||||
|
||||
rt_err_t rt_bus_add(rt_bus_t bus);
|
||||
rt_err_t rt_bus_add_driver(rt_bus_t bus, rt_driver_t drv);
|
||||
rt_err_t rt_bus_add_device(rt_bus_t bus, rt_device_t dev);
|
||||
rt_err_t rt_bus_remove_driver(rt_driver_t drv);
|
||||
rt_err_t rt_bus_remove_device(rt_device_t dev);
|
||||
|
||||
rt_bus_t rt_bus_find_by_name(char *name);
|
||||
rt_err_t rt_bus_reload_driver_device(rt_bus_t new_bus, rt_device_t dev);
|
||||
|
||||
rt_err_t rt_bus_register(rt_bus_t bus);
|
||||
|
||||
#endif /* __BUS_H__ */
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-04-12 ErikChan the first version
|
||||
*/
|
||||
|
||||
#ifndef __DEVICE_H__
|
||||
#define __DEVICE_H__
|
||||
|
||||
#include <rtdef.h>
|
||||
|
||||
typedef struct rt_driver *rt_driver_t;
|
||||
typedef struct rt_device *rt_device_t;
|
||||
|
||||
/**
|
||||
* Notify structure
|
||||
*/
|
||||
struct rt_device_notify
|
||||
{
|
||||
void (*notify)(rt_device_t dev);
|
||||
struct rt_device *dev;
|
||||
};
|
||||
|
||||
/**
|
||||
* Device structure
|
||||
*/
|
||||
struct rt_device
|
||||
{
|
||||
struct rt_object parent; /**< inherit from rt_object */
|
||||
rt_list_t node;
|
||||
struct rt_bus *bus;
|
||||
void *priv;
|
||||
|
||||
#ifdef RT_USING_DM
|
||||
rt_driver_t drv;
|
||||
void *ofw_node;
|
||||
#endif
|
||||
enum rt_device_class_type type; /**< device type */
|
||||
rt_uint16_t flag; /**< device flag */
|
||||
rt_uint16_t open_flag; /**< device open flag */
|
||||
|
||||
rt_uint8_t ref_count; /**< reference count */
|
||||
rt_uint8_t device_id; /**< 0 - 255 */
|
||||
|
||||
/* device call back */
|
||||
rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
|
||||
rt_err_t (*tx_complete)(rt_device_t dev, void *buffer);
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
const struct rt_device_ops *ops;
|
||||
#else
|
||||
/* common device interface */
|
||||
rt_err_t (*init) (rt_device_t dev);
|
||||
rt_err_t (*open) (rt_device_t dev, rt_uint16_t oflag);
|
||||
rt_err_t (*close) (rt_device_t dev);
|
||||
rt_ssize_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
|
||||
rt_ssize_t (*write) (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
|
||||
rt_err_t (*control)(rt_device_t dev, int cmd, void *args);
|
||||
#endif /* RT_USING_DEVICE_OPS */
|
||||
|
||||
#ifdef RT_USING_POSIX_DEVIO
|
||||
const struct dfs_file_ops *fops;
|
||||
struct rt_wqueue wait_queue;
|
||||
#endif /* RT_USING_POSIX_DEVIO */
|
||||
|
||||
void *user_data; /**< device private data */
|
||||
};
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
/**
|
||||
* operations set for device object
|
||||
*/
|
||||
struct rt_device_ops
|
||||
{
|
||||
/* common device interface */
|
||||
rt_err_t (*init) (rt_device_t dev);
|
||||
rt_err_t (*open) (rt_device_t dev, rt_uint16_t oflag);
|
||||
rt_err_t (*close) (rt_device_t dev);
|
||||
rt_ssize_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
|
||||
rt_ssize_t (*write) (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
|
||||
rt_err_t (*control)(rt_device_t dev, int cmd, void *args);
|
||||
};
|
||||
#endif /* RT_USING_DEVICE_OPS */
|
||||
|
||||
#endif /* __DEVICE_H__ */
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-04-20 ErikChan the first version
|
||||
*/
|
||||
|
||||
#ifndef __RT_DM_H__
|
||||
#define __RT_DM_H__
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtdef.h>
|
||||
#include <drivers/misc.h>
|
||||
#include <drivers/byteorder.h>
|
||||
|
||||
#ifndef RT_CPUS_NR
|
||||
#define RT_CPUS_NR 1
|
||||
#endif
|
||||
|
||||
#ifndef RT_USING_SMP
|
||||
extern int rt_hw_cpu_id(void);
|
||||
#endif
|
||||
|
||||
void rt_dm_secondary_cpu_init(void);
|
||||
|
||||
int rt_dm_set_dev_name_auto(rt_device_t dev, const char *prefix);
|
||||
int rt_dm_get_dev_name_id(rt_device_t dev);
|
||||
|
||||
int rt_dm_set_dev_name(rt_device_t dev, const char *format, ...);
|
||||
const char *rt_dm_get_dev_name(rt_device_t dev);
|
||||
|
||||
#endif /* __RT_DM_H__ */
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2006-2023, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-04-12 ErikChan the first version
|
||||
*/
|
||||
|
||||
#ifndef __DRIVER_H__
|
||||
#define __DRIVER_H__
|
||||
|
||||
#include <drivers/core/device.h>
|
||||
|
||||
struct rt_driver
|
||||
{
|
||||
struct rt_bus *bus;
|
||||
rt_list_t node;
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
const struct rt_device_ops *dev_ops;
|
||||
#else
|
||||
/* common device interface */
|
||||
rt_err_t (*init) (rt_device_t dev);
|
||||
rt_err_t (*open) (rt_device_t dev, rt_uint16_t oflag);
|
||||
rt_err_t (*close) (rt_device_t dev);
|
||||
rt_ssize_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size);
|
||||
rt_ssize_t (*write) (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);
|
||||
rt_err_t (*control)(rt_device_t dev, int cmd, void *args);
|
||||
#endif
|
||||
|
||||
const struct filesystem_ops *fops;
|
||||
|
||||
const char *name;
|
||||
|
||||
int (*probe)(struct rt_device *dev);
|
||||
int (*remove)(struct rt_device *dev);
|
||||
|
||||
void *priv;
|
||||
};
|
||||
|
||||
int rt_driver_probe_device(struct rt_driver *drv, struct rt_device *dev);
|
||||
|
||||
rt_err_t rt_driver_register(rt_driver_t drv);
|
||||
rt_err_t rt_driver_unregister(rt_driver_t drv);
|
||||
|
||||
#define RT_DRIVER_EXPORT(driver, bus_name, mode) \
|
||||
static int ___##driver##_register(void) \
|
||||
{ \
|
||||
rt_##bus_name##_driver_register(&driver); \
|
||||
return 0; \
|
||||
} \
|
||||
INIT_DEVICE_EXPORT(___##driver##_register); \
|
||||
|
||||
#endif /* __DRIVER_H__ */
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include <bitmap.h>
|
||||
#include <drivers/ofw.h>
|
||||
#include <drivers/core/rtdm.h>
|
||||
#include <drivers/core/dm.h>
|
||||
|
||||
struct rt_pci_msi_desc;
|
||||
struct rt_pci_msi_msg;
|
||||
|
|
|
@ -170,7 +170,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#ifdef RT_USING_DM
|
||||
#include "drivers/core/rtdm.h"
|
||||
#include "drivers/core/dm.h"
|
||||
|
||||
#ifdef RT_USING_OFW
|
||||
#include "drivers/ofw.h"
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
#include <drivers/ofw_fdt.h>
|
||||
#include <drivers/ofw_raw.h>
|
||||
#include <drivers/core/rtdm.h>
|
||||
#include <drivers/core/dm.h>
|
||||
|
||||
#define DBG_TAG "rtdm.ofw"
|
||||
#define DBG_LVL DBG_INFO
|
||||
|
@ -79,14 +79,13 @@ rt_uint64_t rt_fdt_translate_address(void *fdt, int nodeoffset, rt_uint64_t addr
|
|||
int addr_cells;
|
||||
int size_cells;
|
||||
} local, cpu;
|
||||
int parent, length, group_len;
|
||||
int parent, length = 0, group_len;
|
||||
const fdt32_t *ranges = RT_NULL;
|
||||
|
||||
parent = fdt_parent_offset(fdt, nodeoffset);
|
||||
|
||||
if (parent >= 0)
|
||||
{
|
||||
length = 0;
|
||||
ranges = fdt_getprop(fdt, nodeoffset, "ranges", &length);
|
||||
}
|
||||
|
||||
|
|
|
@ -54,9 +54,9 @@ static rt_list_t _traps_nodes = RT_LIST_OBJECT_INIT(_traps_nodes);
|
|||
|
||||
static struct rt_pic_irq *irq2pirq(int irq)
|
||||
{
|
||||
struct rt_pic_irq *pirq;
|
||||
struct rt_pic_irq *pirq = RT_NULL;
|
||||
|
||||
if (irq >= 0 && irq < MAX_HANDLERS)
|
||||
if ((irq >= 0) && (irq < MAX_HANDLERS))
|
||||
{
|
||||
pirq = &_pirq_hash[irq];
|
||||
|
||||
|
@ -453,7 +453,7 @@ rt_err_t rt_pic_do_traps(void)
|
|||
|
||||
rt_err_t rt_pic_handle_isr(struct rt_pic_irq *pirq)
|
||||
{
|
||||
rt_err_t err;
|
||||
rt_err_t err = RT_EOK;
|
||||
rt_list_t *handler_nodes;
|
||||
struct rt_irq_desc *action;
|
||||
|
||||
|
@ -547,49 +547,101 @@ rt_err_t rt_pic_irq_finit(void)
|
|||
return err;
|
||||
}
|
||||
|
||||
#define _irq_call_helper(irq, fn) \
|
||||
({ \
|
||||
struct rt_pic_irq *pirq; \
|
||||
if ((pirq = irq2pirq(irq))) \
|
||||
{ \
|
||||
rt_spin_lock(&pirq->rw_lock); \
|
||||
if (pirq->pic->ops->fn) \
|
||||
pirq->pic->ops->fn(pirq); \
|
||||
rt_spin_unlock(&pirq->rw_lock); \
|
||||
} \
|
||||
})
|
||||
|
||||
void rt_pic_irq_enable(int irq)
|
||||
{
|
||||
_irq_call_helper(irq, irq_enable);
|
||||
struct rt_pic_irq *pirq = irq2pirq(irq);
|
||||
|
||||
RT_ASSERT(pirq != RT_NULL);
|
||||
|
||||
rt_spin_lock(&pirq->rw_lock);
|
||||
|
||||
if (pirq->pic->ops->irq_enable)
|
||||
{
|
||||
pirq->pic->ops->irq_enable(pirq);
|
||||
}
|
||||
|
||||
rt_spin_unlock(&pirq->rw_lock);
|
||||
}
|
||||
|
||||
void rt_pic_irq_disable(int irq)
|
||||
{
|
||||
_irq_call_helper(irq, irq_disable);
|
||||
struct rt_pic_irq *pirq = irq2pirq(irq);
|
||||
|
||||
RT_ASSERT(pirq != RT_NULL);
|
||||
|
||||
rt_spin_lock(&pirq->rw_lock);
|
||||
|
||||
if (pirq->pic->ops->irq_disable)
|
||||
{
|
||||
pirq->pic->ops->irq_disable(pirq);
|
||||
}
|
||||
|
||||
rt_spin_unlock(&pirq->rw_lock);
|
||||
}
|
||||
|
||||
void rt_pic_irq_ack(int irq)
|
||||
{
|
||||
_irq_call_helper(irq, irq_ack);
|
||||
struct rt_pic_irq *pirq = irq2pirq(irq);
|
||||
|
||||
RT_ASSERT(pirq != RT_NULL);
|
||||
|
||||
rt_spin_lock(&pirq->rw_lock);
|
||||
|
||||
if (pirq->pic->ops->irq_ack)
|
||||
{
|
||||
pirq->pic->ops->irq_ack(pirq);
|
||||
}
|
||||
|
||||
rt_spin_unlock(&pirq->rw_lock);
|
||||
}
|
||||
|
||||
void rt_pic_irq_mask(int irq)
|
||||
{
|
||||
_irq_call_helper(irq, irq_mask);
|
||||
struct rt_pic_irq *pirq = irq2pirq(irq);
|
||||
|
||||
RT_ASSERT(pirq != RT_NULL);
|
||||
|
||||
rt_spin_lock(&pirq->rw_lock);
|
||||
|
||||
if (pirq->pic->ops->irq_mask)
|
||||
{
|
||||
pirq->pic->ops->irq_mask(pirq);
|
||||
}
|
||||
|
||||
rt_spin_unlock(&pirq->rw_lock);
|
||||
}
|
||||
|
||||
void rt_pic_irq_unmask(int irq)
|
||||
{
|
||||
_irq_call_helper(irq, irq_unmask);
|
||||
struct rt_pic_irq *pirq = irq2pirq(irq);
|
||||
|
||||
RT_ASSERT(pirq != RT_NULL);
|
||||
|
||||
rt_spin_lock(&pirq->rw_lock);
|
||||
|
||||
if (pirq->pic->ops->irq_unmask)
|
||||
{
|
||||
pirq->pic->ops->irq_unmask(pirq);
|
||||
}
|
||||
|
||||
rt_spin_unlock(&pirq->rw_lock);
|
||||
}
|
||||
|
||||
void rt_pic_irq_eoi(int irq)
|
||||
{
|
||||
_irq_call_helper(irq, irq_eoi);
|
||||
}
|
||||
struct rt_pic_irq *pirq = irq2pirq(irq);
|
||||
|
||||
#undef _irq_call_helper
|
||||
RT_ASSERT(pirq != RT_NULL);
|
||||
|
||||
rt_spin_lock(&pirq->rw_lock);
|
||||
|
||||
if (pirq->pic->ops->irq_eoi)
|
||||
{
|
||||
pirq->pic->ops->irq_eoi(pirq);
|
||||
}
|
||||
|
||||
rt_spin_unlock(&pirq->rw_lock);
|
||||
}
|
||||
|
||||
rt_err_t rt_pic_irq_set_priority(int irq, rt_uint32_t priority)
|
||||
{
|
||||
|
@ -747,58 +799,145 @@ void rt_pic_irq_send_ipi(int irq, rt_bitmap_t *cpumask)
|
|||
}
|
||||
}
|
||||
|
||||
#define _pirq_parent_call_helper(ppic, pirq, fn, ret,...) \
|
||||
({ \
|
||||
if (ppic && pirq) \
|
||||
{ \
|
||||
rt_spin_lock(&pirq->rw_lock); \
|
||||
if (ppic->ops->fn) \
|
||||
{ \
|
||||
struct rt_pic *cpic; \
|
||||
cpic = pirq->pic; /* push old pic */ \
|
||||
pirq->pic = ppic; \
|
||||
ret ppic->ops->fn(pirq __VA_ARGS__); \
|
||||
pirq->pic = cpic; /* pop old pic */ \
|
||||
} \
|
||||
rt_spin_unlock(&pirq->rw_lock); \
|
||||
} \
|
||||
})
|
||||
#define _pic_push(stack, pirq, ppic) struct rt_pic *(stack) = (pirq)->pic; (pirq)->pic = ppic;
|
||||
#define _pic_pop(stack, pirq) (pirq)->pic = (stack)
|
||||
|
||||
void rt_pic_irq_parent_enable(struct rt_pic *ppic, struct rt_pic_irq *pirq)
|
||||
{
|
||||
_pirq_parent_call_helper(ppic, pirq, irq_enable,,);
|
||||
RT_ASSERT(ppic != RT_NULL);
|
||||
RT_ASSERT(pirq != RT_NULL);
|
||||
|
||||
rt_spin_lock(&pirq->rw_lock);
|
||||
|
||||
if (ppic->ops->irq_enable)
|
||||
{
|
||||
_pic_push(pic_stack, pirq, ppic);
|
||||
|
||||
ppic->ops->irq_enable(pirq);
|
||||
|
||||
_pic_pop(pic_stack, pirq);
|
||||
}
|
||||
|
||||
rt_spin_unlock(&pirq->rw_lock);
|
||||
}
|
||||
|
||||
void rt_pic_irq_parent_disable(struct rt_pic *ppic, struct rt_pic_irq *pirq)
|
||||
{
|
||||
_pirq_parent_call_helper(ppic, pirq, irq_disable,,);
|
||||
RT_ASSERT(ppic != RT_NULL);
|
||||
RT_ASSERT(pirq != RT_NULL);
|
||||
|
||||
rt_spin_lock(&pirq->rw_lock);
|
||||
|
||||
if (ppic->ops->irq_disable)
|
||||
{
|
||||
_pic_push(pic_stack, pirq, ppic);
|
||||
|
||||
ppic->ops->irq_disable(pirq);
|
||||
|
||||
_pic_pop(pic_stack, pirq);
|
||||
}
|
||||
|
||||
rt_spin_unlock(&pirq->rw_lock);
|
||||
}
|
||||
|
||||
void rt_pic_irq_parent_ack(struct rt_pic *ppic, struct rt_pic_irq *pirq)
|
||||
{
|
||||
_pirq_parent_call_helper(ppic, pirq, irq_ack,,);
|
||||
RT_ASSERT(ppic != RT_NULL);
|
||||
RT_ASSERT(pirq != RT_NULL);
|
||||
|
||||
rt_spin_lock(&pirq->rw_lock);
|
||||
|
||||
if (ppic->ops->irq_ack)
|
||||
{
|
||||
_pic_push(pic_stack, pirq, ppic);
|
||||
|
||||
ppic->ops->irq_ack(pirq);
|
||||
|
||||
_pic_pop(pic_stack, pirq);
|
||||
}
|
||||
|
||||
rt_spin_unlock(&pirq->rw_lock);
|
||||
}
|
||||
|
||||
void rt_pic_irq_parent_mask(struct rt_pic *ppic, struct rt_pic_irq *pirq)
|
||||
{
|
||||
_pirq_parent_call_helper(ppic, pirq, irq_mask,,);
|
||||
RT_ASSERT(ppic != RT_NULL);
|
||||
RT_ASSERT(pirq != RT_NULL);
|
||||
|
||||
rt_spin_lock(&pirq->rw_lock);
|
||||
|
||||
if (ppic->ops->irq_mask)
|
||||
{
|
||||
_pic_push(pic_stack, pirq, ppic);
|
||||
|
||||
ppic->ops->irq_mask(pirq);
|
||||
|
||||
_pic_pop(pic_stack, pirq);
|
||||
}
|
||||
|
||||
rt_spin_unlock(&pirq->rw_lock);
|
||||
}
|
||||
|
||||
void rt_pic_irq_parent_unmask(struct rt_pic *ppic, struct rt_pic_irq *pirq)
|
||||
{
|
||||
_pirq_parent_call_helper(ppic, pirq, irq_unmask,,);
|
||||
RT_ASSERT(ppic != RT_NULL);
|
||||
RT_ASSERT(pirq != RT_NULL);
|
||||
|
||||
rt_spin_lock(&pirq->rw_lock);
|
||||
|
||||
if (ppic->ops->irq_unmask)
|
||||
{
|
||||
_pic_push(pic_stack, pirq, ppic);
|
||||
|
||||
ppic->ops->irq_unmask(pirq);
|
||||
|
||||
_pic_pop(pic_stack, pirq);
|
||||
}
|
||||
|
||||
rt_spin_unlock(&pirq->rw_lock);
|
||||
}
|
||||
|
||||
void rt_pic_irq_parent_eoi(struct rt_pic *ppic, struct rt_pic_irq *pirq)
|
||||
{
|
||||
_pirq_parent_call_helper(ppic, pirq, irq_eoi,,);
|
||||
RT_ASSERT(ppic != RT_NULL);
|
||||
RT_ASSERT(pirq != RT_NULL);
|
||||
|
||||
rt_spin_lock(&pirq->rw_lock);
|
||||
|
||||
if (ppic->ops->irq_eoi)
|
||||
{
|
||||
_pic_push(pic_stack, pirq, ppic);
|
||||
|
||||
ppic->ops->irq_eoi(pirq);
|
||||
|
||||
_pic_pop(pic_stack, pirq);
|
||||
}
|
||||
|
||||
rt_spin_unlock(&pirq->rw_lock);
|
||||
}
|
||||
|
||||
rt_err_t rt_pic_irq_parent_set_priority(struct rt_pic *ppic, struct rt_pic_irq *pirq, rt_uint32_t priority)
|
||||
{
|
||||
rt_err_t err = -RT_ENOSYS;
|
||||
|
||||
_pirq_parent_call_helper(ppic, pirq, irq_set_priority, err = , ,priority);
|
||||
RT_ASSERT(ppic != RT_NULL);
|
||||
RT_ASSERT(pirq != RT_NULL);
|
||||
|
||||
rt_spin_lock(&pirq->rw_lock);
|
||||
|
||||
if (ppic->ops->irq_set_priority)
|
||||
{
|
||||
_pic_push(pic_stack, pirq, ppic);
|
||||
|
||||
if (!(err = ppic->ops->irq_set_priority(pirq, priority)))
|
||||
{
|
||||
pirq->priority = priority;
|
||||
}
|
||||
|
||||
_pic_pop(pic_stack, pirq);
|
||||
}
|
||||
|
||||
rt_spin_unlock(&pirq->rw_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -807,7 +946,24 @@ rt_err_t rt_pic_irq_parent_set_affinity(struct rt_pic *ppic, struct rt_pic_irq *
|
|||
{
|
||||
rt_err_t err = -RT_ENOSYS;
|
||||
|
||||
_pirq_parent_call_helper(ppic, pirq, irq_set_affinity, err = , ,affinity);
|
||||
RT_ASSERT(ppic != RT_NULL);
|
||||
RT_ASSERT(pirq != RT_NULL);
|
||||
|
||||
rt_spin_lock(&pirq->rw_lock);
|
||||
|
||||
if (ppic->ops->irq_set_affinity)
|
||||
{
|
||||
_pic_push(pic_stack, pirq, ppic);
|
||||
|
||||
if (!(err = ppic->ops->irq_set_affinity(pirq, affinity)))
|
||||
{
|
||||
rt_memcpy(pirq->affinity, affinity, sizeof(pirq->affinity));
|
||||
}
|
||||
|
||||
_pic_pop(pic_stack, pirq);
|
||||
}
|
||||
|
||||
rt_spin_unlock(&pirq->rw_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -816,12 +972,30 @@ rt_err_t rt_pic_irq_parent_set_triger_mode(struct rt_pic *ppic, struct rt_pic_ir
|
|||
{
|
||||
rt_err_t err = -RT_ENOSYS;
|
||||
|
||||
_pirq_parent_call_helper(ppic, pirq, irq_set_triger_mode, err = , ,mode);
|
||||
RT_ASSERT(ppic != RT_NULL);
|
||||
RT_ASSERT(pirq != RT_NULL);
|
||||
|
||||
rt_spin_lock(&pirq->rw_lock);
|
||||
|
||||
if (ppic->ops->irq_set_triger_mode)
|
||||
{
|
||||
_pic_push(pic_stack, pirq, ppic);
|
||||
|
||||
if (!(err = ppic->ops->irq_set_triger_mode(pirq, mode)))
|
||||
{
|
||||
pirq->mode = mode;
|
||||
}
|
||||
|
||||
_pic_pop(pic_stack, pirq);
|
||||
}
|
||||
|
||||
rt_spin_unlock(&pirq->rw_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#undef _pirq_parent_call_helper
|
||||
#undef _pic_push
|
||||
#undef _pic_pop
|
||||
|
||||
#ifdef RT_USING_OFW
|
||||
RT_OFW_STUB_RANGE_EXPORT(pic, _pic_ofw_start, _pic_ofw_end);
|
||||
|
|
|
@ -318,6 +318,17 @@ typedef int (*init_fn_t)(void);
|
|||
/* board init routines will be called in board_init() function */
|
||||
#define INIT_BOARD_EXPORT(fn) INIT_EXPORT(fn, "1")
|
||||
|
||||
/* init cpu, memory, interrupt-controller, bus... */
|
||||
#define INIT_CORE_EXPORT(fn) INIT_EXPORT(fn, "1.0")
|
||||
/* init pci/pcie, usb platform driver... */
|
||||
#define INIT_FRAMEWORK_EXPORT(fn) INIT_EXPORT(fn, "1.1")
|
||||
/* init platform, user code... */
|
||||
#define INIT_PLATFORM_EXPORT(fn) INIT_EXPORT(fn, "1.2")
|
||||
/* init sys-timer, clk, pinctrl... */
|
||||
#define INIT_SUBSYS_EXPORT(fn) INIT_EXPORT(fn, "1.3")
|
||||
/* init early drivers */
|
||||
#define INIT_DRIVER_EARLY_EXPORT(fn) INIT_EXPORT(fn, "1.4")
|
||||
|
||||
/* pre/device/component/env/app init routines will be called in init_thread */
|
||||
/* components pre-initialization (pure software initialization) */
|
||||
#define INIT_PREV_EXPORT(fn) INIT_EXPORT(fn, "2")
|
||||
|
@ -330,6 +341,11 @@ typedef int (*init_fn_t)(void);
|
|||
/* application initialization (rtgui application etc ...) */
|
||||
#define INIT_APP_EXPORT(fn) INIT_EXPORT(fn, "6")
|
||||
|
||||
/* init after mount fs */
|
||||
#define INIT_FS_EXPORT(fn) INIT_EXPORT(fn, "6.0")
|
||||
/* init in secondary_cpu_c_start */
|
||||
#define INIT_SECONDARY_CPU_EXPORT(fn) INIT_EXPORT(fn, "7")
|
||||
|
||||
#if !defined(RT_USING_FINSH)
|
||||
/* define these to empty, even if not include finsh.h file */
|
||||
#define FINSH_FUNCTION_EXPORT(name, desc)
|
||||
|
|
|
@ -602,14 +602,7 @@ rt_ssize_t rt_device_write(rt_device_t dev,
|
|||
const void *buffer,
|
||||
rt_size_t size);
|
||||
rt_err_t rt_device_control(rt_device_t dev, int cmd, void *arg);
|
||||
#ifdef RT_USING_DM
|
||||
rt_err_t rt_device_bind_driver(rt_device_t device, rt_driver_t driver, void *node);
|
||||
rt_device_t rt_device_create_since_driver(rt_driver_t drv,int device_id);
|
||||
rt_err_t rt_device_probe_and_init(rt_device_t device);
|
||||
|
||||
rt_err_t rt_driver_match_with_id(const rt_driver_t drv,int device_id);
|
||||
rt_err_t rt_driver_match_with_dtb(const rt_driver_t drv,void *from_node,int max_dev_num);
|
||||
#endif
|
||||
/**@}*/
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue