mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-10-02 14:23:19 +08:00
[drivers][core] 完善设备模型 (#8384)
This commit is contained in:
+238
-128
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,10 @@
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#define DBG_TAG "rtdm.pltaform"
|
||||
#define DBG_LVL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
|
||||
#include <drivers/platform.h>
|
||||
#include <drivers/core/bus.h>
|
||||
#include <drivers/core/dm.h>
|
||||
@@ -28,6 +32,11 @@ struct rt_platform_device *rt_platform_device_alloc(const char *name)
|
||||
{
|
||||
struct rt_platform_device *pdev = rt_calloc(1, sizeof(*pdev));
|
||||
|
||||
if (!pdev)
|
||||
{
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
pdev->parent.bus = &platform_bus;
|
||||
pdev->name = name;
|
||||
|
||||
@@ -44,7 +53,11 @@ rt_err_t rt_platform_driver_register(struct rt_platform_driver *pdrv)
|
||||
RT_ASSERT(pdrv != RT_NULL);
|
||||
|
||||
pdrv->parent.bus = &platform_bus;
|
||||
|
||||
#if RT_NAME_MAX > 0
|
||||
rt_strcpy(pdrv->parent.parent.name, pdrv->name);
|
||||
#else
|
||||
pdrv->parent.parent.name = pdrv->name;
|
||||
#endif
|
||||
return rt_driver_register(&pdrv->parent);
|
||||
}
|
||||
|
||||
@@ -67,20 +80,22 @@ static rt_bool_t platform_match(rt_driver_t drv, rt_device_t dev)
|
||||
|
||||
#ifdef RT_USING_OFW
|
||||
struct rt_ofw_node *np = dev->ofw_node;
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_OFW
|
||||
/* 1、match with ofw node */
|
||||
if (np)
|
||||
{
|
||||
/* 1、match with ofw node */
|
||||
pdev->id = rt_ofw_node_match(np, pdrv->ids);
|
||||
|
||||
return !!pdev->id;
|
||||
if (pdev->id)
|
||||
{
|
||||
return RT_TRUE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 2、match with name */
|
||||
if (pdev->name && pdrv->name)
|
||||
{
|
||||
/* 2、match with name */
|
||||
if (pdev->name == pdrv->name)
|
||||
{
|
||||
return RT_TRUE;
|
||||
@@ -97,7 +112,6 @@ static rt_bool_t platform_match(rt_driver_t drv, rt_device_t dev)
|
||||
static rt_err_t platform_probe(rt_device_t dev)
|
||||
{
|
||||
rt_err_t err;
|
||||
|
||||
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);
|
||||
#ifdef RT_USING_OFW
|
||||
@@ -106,22 +120,22 @@ static rt_err_t platform_probe(rt_device_t dev)
|
||||
|
||||
err = pdrv->probe(pdev);
|
||||
|
||||
#ifdef RT_USING_OFW
|
||||
if (!err)
|
||||
{
|
||||
#ifdef RT_USING_OFW
|
||||
if (np)
|
||||
{
|
||||
rt_ofw_node_set_flag(np, RT_OFW_F_READLY);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (np)
|
||||
if (err == -RT_ENOMEM)
|
||||
{
|
||||
rt_ofw_data(np) = &pdev->parent;
|
||||
LOG_W("System not memory in driver %s", pdrv->name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,32 +21,32 @@ struct rt_bus
|
||||
{
|
||||
struct rt_object parent; /**< inherit from rt_object */
|
||||
|
||||
char *name;
|
||||
struct rt_bus *bus;
|
||||
const char *name;
|
||||
|
||||
rt_list_t list;
|
||||
rt_list_t children;
|
||||
rt_list_t dev_list;
|
||||
rt_list_t drv_list;
|
||||
|
||||
struct rt_spinlock spinlock;
|
||||
struct rt_spinlock dev_lock;
|
||||
struct rt_spinlock drv_lock;
|
||||
|
||||
rt_bool_t (*match)(rt_driver_t drv, rt_device_t dev);
|
||||
rt_err_t (*probe)(rt_device_t dev);
|
||||
rt_err_t (*remove)(rt_device_t dev);
|
||||
rt_err_t (*shutdown)(rt_device_t dev);
|
||||
};
|
||||
|
||||
rt_bus_t rt_bus_root(void);
|
||||
rt_err_t rt_bus_for_each_dev(rt_bus_t bus, void *data, int (*fn)(rt_device_t dev, void *));
|
||||
rt_err_t rt_bus_for_each_drv(rt_bus_t bus, void *data, int (*fn)(rt_driver_t drv, 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_shutdown(void);
|
||||
|
||||
rt_bus_t rt_bus_find_by_name(const 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);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtdef.h>
|
||||
#include <ioremap.h>
|
||||
#include <drivers/misc.h>
|
||||
#include <drivers/byteorder.h>
|
||||
|
||||
@@ -26,10 +27,139 @@ extern int rt_hw_cpu_id(void);
|
||||
|
||||
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_dev_set_name_auto(rt_device_t dev, const char *prefix);
|
||||
int rt_dm_dev_get_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);
|
||||
int rt_dm_dev_set_name(rt_device_t dev, const char *format, ...);
|
||||
const char *rt_dm_dev_get_name(rt_device_t dev);
|
||||
|
||||
int rt_dm_dev_get_address_count(rt_device_t dev);
|
||||
rt_err_t rt_dm_dev_get_address(rt_device_t dev, int index,
|
||||
rt_uint64_t *out_address, rt_uint64_t *out_size);
|
||||
rt_err_t rt_dm_dev_get_address_by_name(rt_device_t dev, const char *name,
|
||||
rt_uint64_t *out_address, rt_uint64_t *out_size);
|
||||
int rt_dm_dev_get_address_array(rt_device_t dev, int nr, rt_uint64_t *out_regs);
|
||||
|
||||
void *rt_dm_dev_iomap(rt_device_t dev, int index);
|
||||
void *rt_dm_dev_iomap_by_name(rt_device_t dev, const char *name);
|
||||
|
||||
int rt_dm_dev_get_irq_count(rt_device_t dev);
|
||||
int rt_dm_dev_get_irq(rt_device_t dev, int index);
|
||||
int rt_dm_dev_get_irq_by_name(rt_device_t dev, const char *name);
|
||||
|
||||
void rt_dm_dev_bind_fwdata(rt_device_t dev, void *fw_np, void *data);
|
||||
void rt_dm_dev_unbind_fwdata(rt_device_t dev, void *fw_np);
|
||||
|
||||
int rt_dm_dev_prop_read_u8_array_index(rt_device_t dev, const char *propname,
|
||||
int index, int nr, rt_uint8_t *out_values);
|
||||
int rt_dm_dev_prop_read_u16_array_index(rt_device_t dev, const char *propname,
|
||||
int index, int nr, rt_uint16_t *out_values);
|
||||
int rt_dm_dev_prop_read_u32_array_index(rt_device_t dev, const char *propname,
|
||||
int index, int nr, rt_uint32_t *out_values);
|
||||
int rt_dm_dev_prop_read_u64_array_index(rt_device_t dev, const char *propname,
|
||||
int index, int nr, rt_uint64_t *out_values);
|
||||
int rt_dm_dev_prop_read_string_array_index(rt_device_t dev, const char *propname,
|
||||
int index, int nr, const char **out_strings);
|
||||
|
||||
int rt_dm_dev_prop_count_of_size(rt_device_t dev, const char *propname, int size);
|
||||
int rt_dm_dev_prop_index_of_string(rt_device_t dev, const char *propname, const char *string);
|
||||
|
||||
rt_bool_t rt_dm_dev_prop_read_bool(rt_device_t dev, const char *propname);
|
||||
|
||||
rt_inline rt_err_t rt_dm_dev_prop_read_u8_index(rt_device_t dev, const char *propname,
|
||||
int index, rt_uint8_t *out_value)
|
||||
{
|
||||
int nr = rt_dm_dev_prop_read_u8_array_index(dev, propname, index, 1, out_value);
|
||||
|
||||
return nr > 0 ? RT_EOK : (rt_err_t)nr;
|
||||
}
|
||||
|
||||
rt_inline rt_err_t rt_dm_dev_prop_read_u16_index(rt_device_t dev, const char *propname,
|
||||
int index, rt_uint16_t *out_value)
|
||||
{
|
||||
int nr = rt_dm_dev_prop_read_u16_array_index(dev, propname, index, 1, out_value);
|
||||
|
||||
return nr > 0 ? RT_EOK : (rt_err_t)nr;
|
||||
}
|
||||
|
||||
rt_inline rt_err_t rt_dm_dev_prop_read_u32_index(rt_device_t dev, const char *propname,
|
||||
int index, rt_uint32_t *out_value)
|
||||
{
|
||||
int nr = rt_dm_dev_prop_read_u32_array_index(dev, propname, index, 1, out_value);
|
||||
|
||||
return nr > 0 ? RT_EOK : (rt_err_t)nr;
|
||||
}
|
||||
|
||||
rt_inline rt_err_t rt_dm_dev_prop_read_u64_index(rt_device_t dev, const char *propname,
|
||||
int index, rt_uint64_t *out_value)
|
||||
{
|
||||
int nr = rt_dm_dev_prop_read_u64_array_index(dev, propname, index, 1, out_value);
|
||||
|
||||
return nr > 0 ? RT_EOK : (rt_err_t)nr;
|
||||
}
|
||||
|
||||
rt_inline rt_err_t rt_dm_dev_prop_read_string_index(rt_device_t dev, const char *propname,
|
||||
int index, const char **out_string)
|
||||
{
|
||||
int nr = rt_dm_dev_prop_read_string_array_index(dev, propname, index, 1, out_string);
|
||||
|
||||
return nr > 0 ? RT_EOK : (rt_err_t)nr;
|
||||
}
|
||||
|
||||
rt_inline rt_err_t rt_dm_dev_prop_read_u8(rt_device_t dev, const char *propname,
|
||||
rt_uint8_t *out_value)
|
||||
{
|
||||
return rt_dm_dev_prop_read_u8_index(dev, propname, 0, out_value);
|
||||
}
|
||||
|
||||
rt_inline rt_err_t rt_dm_dev_prop_read_u16(rt_device_t dev, const char *propname,
|
||||
rt_uint16_t *out_value)
|
||||
{
|
||||
return rt_dm_dev_prop_read_u16_index(dev, propname, 0, out_value);
|
||||
}
|
||||
|
||||
rt_inline rt_err_t rt_dm_dev_prop_read_u32(rt_device_t dev, const char *propname,
|
||||
rt_uint32_t *out_value)
|
||||
{
|
||||
return rt_dm_dev_prop_read_u32_index(dev, propname, 0, out_value);
|
||||
}
|
||||
|
||||
rt_inline rt_err_t rt_dm_dev_prop_read_s32(rt_device_t dev, const char *propname,
|
||||
rt_int32_t *out_value)
|
||||
{
|
||||
return rt_dm_dev_prop_read_u32_index(dev, propname, 0, (rt_uint32_t *)out_value);
|
||||
}
|
||||
|
||||
rt_inline rt_err_t rt_dm_dev_prop_read_u64(rt_device_t dev, const char *propname,
|
||||
rt_uint64_t *out_value)
|
||||
{
|
||||
return rt_dm_dev_prop_read_u64_index(dev, propname, 0, out_value);
|
||||
}
|
||||
|
||||
rt_inline rt_err_t rt_dm_dev_prop_read_string(rt_device_t dev, const char *propname,
|
||||
const char **out_string)
|
||||
{
|
||||
return rt_dm_dev_prop_read_string_index(dev, propname, 0, out_string);
|
||||
}
|
||||
|
||||
rt_inline int rt_dm_dev_prop_count_of_u8(rt_device_t dev, const char *propname)
|
||||
{
|
||||
return rt_dm_dev_prop_count_of_size(dev, propname, sizeof(rt_uint8_t));
|
||||
}
|
||||
|
||||
rt_inline int rt_dm_dev_prop_count_of_u16(rt_device_t dev, const char *propname)
|
||||
{
|
||||
return rt_dm_dev_prop_count_of_size(dev, propname, sizeof(rt_uint16_t));
|
||||
}
|
||||
|
||||
rt_inline int rt_dm_dev_prop_count_of_u32(rt_device_t dev, const char *propname)
|
||||
{
|
||||
return rt_dm_dev_prop_count_of_size(dev, propname, sizeof(rt_uint32_t));
|
||||
}
|
||||
|
||||
rt_inline int rt_dm_dev_prop_count_of_u64(rt_device_t dev, const char *propname)
|
||||
{
|
||||
return rt_dm_dev_prop_count_of_size(dev, propname, sizeof(rt_uint64_t));
|
||||
}
|
||||
|
||||
#endif /* __RT_DM_H__ */
|
||||
|
||||
@@ -13,13 +13,14 @@
|
||||
|
||||
#include <rtdef.h>
|
||||
|
||||
struct rt_bus;
|
||||
|
||||
struct rt_driver
|
||||
{
|
||||
struct rt_object parent;
|
||||
struct rt_bus *bus;
|
||||
rt_list_t node;
|
||||
|
||||
rt_uint32_t ref_count;
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
const struct rt_device_ops *dev_ops;
|
||||
#else
|
||||
@@ -34,16 +35,10 @@ struct rt_driver
|
||||
|
||||
const struct filesystem_ops *fops;
|
||||
|
||||
const char *name;
|
||||
|
||||
int (*probe)(struct rt_device *dev);
|
||||
int (*remove)(struct rt_device *dev);
|
||||
|
||||
void *priv;
|
||||
int (*shutdown)(struct rt_device *dev);
|
||||
};
|
||||
typedef struct rt_driver* rt_driver_t;
|
||||
|
||||
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);
|
||||
|
||||
@@ -205,11 +205,15 @@ struct rt_ofw_node *rt_ofw_get_alias_node(const char *tag, int id);
|
||||
int rt_ofw_get_alias_id(struct rt_ofw_node *np, const char *tag);
|
||||
int rt_ofw_get_alias_last_id(const char *tag);
|
||||
|
||||
struct rt_ofw_node *rt_ofw_append_child(struct rt_ofw_node *parent, const char *full_name);
|
||||
rt_err_t rt_ofw_append_prop(struct rt_ofw_node *np, const char *name, int length, void *value);
|
||||
|
||||
struct rt_ofw_node *rt_ofw_parse_phandle(const struct rt_ofw_node *np, const char *phandle_name, int index);
|
||||
rt_err_t rt_ofw_parse_phandle_cells(const struct rt_ofw_node *np, const char *list_name, const char *cells_name,
|
||||
int index, struct rt_ofw_cell_args *out_args);
|
||||
int rt_ofw_count_phandle_cells(const struct rt_ofw_node *np, const char *list_name, const char *cells_name);
|
||||
|
||||
const char *rt_ofw_get_prop_fuzzy_name(const struct rt_ofw_node *np, const char *name);
|
||||
struct rt_ofw_prop *rt_ofw_get_prop(const struct rt_ofw_node *np, const char *name, rt_ssize_t *out_length);
|
||||
|
||||
rt_inline const void *rt_ofw_prop_read_raw(const struct rt_ofw_node *np, const char *name, rt_ssize_t *out_length)
|
||||
|
||||
@@ -20,6 +20,7 @@ struct rt_fdt_earlycon
|
||||
union { rt_ubase_t size, width; };
|
||||
|
||||
void *fdt;
|
||||
char options[32];
|
||||
long nodeoffset;
|
||||
|
||||
void *data;
|
||||
@@ -41,8 +42,6 @@ struct rt_fdt_earlycon_id
|
||||
rt_err_t (*setup)(struct rt_fdt_earlycon *earlycon, const char *options);
|
||||
};
|
||||
|
||||
#define RT_FDT_EARLYCON_OPTION_SIGNATURE '\n'
|
||||
|
||||
#define RT_FDT_EARLYCON_EXPORT(_name, _type, _compatible, _setup) \
|
||||
static const struct rt_fdt_earlycon_id __rt_fdt_##_name##_earlycon \
|
||||
rt_used RT_OFW_SYMBOL(earlycon, _) = \
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#ifndef __OFW_IO_H__
|
||||
#define __OFW_IO_H__
|
||||
|
||||
#include <ioremap.h>
|
||||
#include <drivers/ofw.h>
|
||||
|
||||
int rt_ofw_bus_addr_cells(struct rt_ofw_node *np);
|
||||
|
||||
@@ -22,6 +22,8 @@ struct rt_platform_device
|
||||
{
|
||||
struct rt_device parent;
|
||||
|
||||
int dev_id;
|
||||
|
||||
const char *name;
|
||||
|
||||
#ifdef RT_USING_OFW
|
||||
@@ -42,6 +44,8 @@ struct rt_platform_driver
|
||||
#endif
|
||||
|
||||
rt_err_t (*probe)(struct rt_platform_device *pdev);
|
||||
rt_err_t (*remove)(struct rt_platform_device *pdev);
|
||||
rt_err_t (*shutdown)(struct rt_platform_device *pdev);
|
||||
};
|
||||
|
||||
struct rt_platform_device *rt_platform_device_alloc(const char *name);
|
||||
@@ -49,6 +53,8 @@ struct rt_platform_device *rt_platform_device_alloc(const char *name);
|
||||
rt_err_t rt_platform_driver_register(struct rt_platform_driver *pdrv);
|
||||
rt_err_t rt_platform_device_register(struct rt_platform_device *pdev);
|
||||
|
||||
rt_err_t rt_platform_ofw_device_probe_child(struct rt_ofw_node *np);
|
||||
|
||||
#define RT_PLATFORM_DRIVER_EXPORT(driver) RT_DRIVER_EXPORT(driver, platform, BUILIN)
|
||||
|
||||
#endif /* __PLATFORM_H__ */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Executable → Regular
+29
-21
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
@@ -321,7 +321,7 @@ static rt_err_t fdt_reserved_memory_reg(int nodeoffset, const char *uname)
|
||||
}
|
||||
else
|
||||
{
|
||||
while (len >= t_len)
|
||||
for (; len >= t_len; len -= t_len)
|
||||
{
|
||||
base = rt_fdt_next_cell(&prop, _root_addr_cells);
|
||||
size = rt_fdt_next_cell(&prop, _root_size_cells);
|
||||
@@ -664,12 +664,17 @@ void rt_fdt_earlycon_kick(int why)
|
||||
fdt_earlycon.console_kick(&fdt_earlycon, why);
|
||||
}
|
||||
|
||||
if (why == FDT_EARLYCON_KICK_COMPLETED && fdt_earlycon.msg_idx)
|
||||
if (why == FDT_EARLYCON_KICK_COMPLETED)
|
||||
{
|
||||
fdt_earlycon.msg_idx = 0;
|
||||
fdt_earlycon.console_putc = RT_NULL;
|
||||
|
||||
/* Dump old messages */
|
||||
rt_kputs(fdt_earlycon.msg);
|
||||
if (fdt_earlycon.msg_idx)
|
||||
{
|
||||
fdt_earlycon.msg_idx = 0;
|
||||
|
||||
/* Dump old messages */
|
||||
rt_kputs(fdt_earlycon.msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -787,6 +792,8 @@ rt_err_t rt_fdt_scan_chosen_stdout(void)
|
||||
if (options && *options && *options != ' ')
|
||||
{
|
||||
options_len = strchrnul(options, ' ') - options;
|
||||
|
||||
rt_strncpy(fdt_earlycon.options, options, options_len);
|
||||
}
|
||||
|
||||
/* console > stdout-path */
|
||||
@@ -824,7 +831,7 @@ rt_err_t rt_fdt_scan_chosen_stdout(void)
|
||||
|
||||
if (best_earlycon_id && best_earlycon_id->setup)
|
||||
{
|
||||
rt_bool_t used_options = RT_FALSE;
|
||||
const char earlycon_magic[] = { 'O', 'F', 'W', '\0' };
|
||||
|
||||
if (!con_type)
|
||||
{
|
||||
@@ -833,24 +840,25 @@ rt_err_t rt_fdt_scan_chosen_stdout(void)
|
||||
fdt_earlycon.fdt = _fdt;
|
||||
fdt_earlycon.nodeoffset = offset;
|
||||
|
||||
err = best_earlycon_id->setup(&fdt_earlycon, options);
|
||||
options = &fdt_earlycon.options[options_len + 1];
|
||||
rt_strncpy((void *)options, earlycon_magic, RT_ARRAY_SIZE(earlycon_magic));
|
||||
|
||||
for (int i = 0; i < options_len; ++i)
|
||||
err = best_earlycon_id->setup(&fdt_earlycon, fdt_earlycon.options);
|
||||
|
||||
if (rt_strncmp(options, earlycon_magic, RT_ARRAY_SIZE(earlycon_magic)))
|
||||
{
|
||||
if (options[i] == RT_FDT_EARLYCON_OPTION_SIGNATURE)
|
||||
const char *option_start = options - 1;
|
||||
|
||||
while (option_start[-1] != '\0')
|
||||
{
|
||||
/* Restore ',' */
|
||||
((char *)options)[i++] = ',';
|
||||
options = &options[i];
|
||||
options_len -= i;
|
||||
used_options = RT_TRUE;
|
||||
break;
|
||||
--option_start;
|
||||
}
|
||||
|
||||
rt_memmove(fdt_earlycon.options, option_start, options - option_start);
|
||||
}
|
||||
if (!used_options)
|
||||
else
|
||||
{
|
||||
options = RT_NULL;
|
||||
options_len = 0;
|
||||
fdt_earlycon.options[0] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -877,8 +885,8 @@ rt_err_t rt_fdt_scan_chosen_stdout(void)
|
||||
|
||||
if (fdt_earlycon.mmio)
|
||||
{
|
||||
LOG_I("Earlycon: %s at MMIO/PIO %p (options '%.*s')",
|
||||
con_type, fdt_earlycon.mmio, options_len, options ? options : "");
|
||||
LOG_I("Earlycon: %s at MMIO/PIO %p (options '%s')",
|
||||
con_type, fdt_earlycon.mmio, fdt_earlycon.options);
|
||||
}
|
||||
|
||||
return err;
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#include <ioremap.h>
|
||||
#include <drivers/ofw.h>
|
||||
#include <drivers/ofw_io.h>
|
||||
#include <drivers/ofw_fdt.h>
|
||||
@@ -155,7 +154,7 @@ static rt_err_t ofw_get_address_by_name(struct rt_ofw_node *np, const char *name
|
||||
|
||||
{
|
||||
int index = 0;
|
||||
rt_err_t err = RT_EOK;
|
||||
rt_err_t err = -RT_EEMPTY;
|
||||
const char *reg_name;
|
||||
struct rt_ofw_prop *prop;
|
||||
|
||||
@@ -386,6 +385,22 @@ rt_uint64_t rt_ofw_translate_address(struct rt_ofw_node *np, const char *range_t
|
||||
return cpu_addr;
|
||||
}
|
||||
|
||||
#ifdef ARCH_CPU_64BIT
|
||||
#define ofw_address_cpu_cast(np, address) (void *)(address)
|
||||
#else
|
||||
#define ofw_address_cpu_cast(np, address) \
|
||||
({ \
|
||||
if (((address) >> 32)) \
|
||||
{ \
|
||||
LOG_W("%s find 64 bits address = %x%x", \
|
||||
rt_ofw_node_full_name(np), \
|
||||
ofw_static_cast(rt_ubase_t, (address) >> 32), \
|
||||
ofw_static_cast(rt_ubase_t, (address))); \
|
||||
} \
|
||||
(void *)ofw_static_cast(rt_ubase_t, (address)); \
|
||||
})
|
||||
#endif
|
||||
|
||||
void *rt_ofw_iomap(struct rt_ofw_node *np, int index)
|
||||
{
|
||||
void *iomem = RT_NULL;
|
||||
@@ -396,7 +411,7 @@ void *rt_ofw_iomap(struct rt_ofw_node *np, int index)
|
||||
|
||||
if (!ofw_get_address(np, index, ®s[0], ®s[1]))
|
||||
{
|
||||
iomem = rt_ioremap((void *)regs[0], (size_t)regs[1]);
|
||||
iomem = rt_ioremap(ofw_address_cpu_cast(np, regs[0]), (size_t)regs[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,7 +428,7 @@ void *rt_ofw_iomap_by_name(struct rt_ofw_node *np, const char *name)
|
||||
|
||||
if (!ofw_get_address_by_name(np, name, ®s[0], ®s[1]))
|
||||
{
|
||||
iomem = rt_ioremap((void *)regs[0], (size_t)regs[1]);
|
||||
iomem = rt_ioremap(ofw_address_cpu_cast(np, regs[0]), (size_t)regs[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Executable → Regular
+49
-24
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
@@ -85,6 +85,41 @@ static const char *ofw_console_serial_find(char *dst_con, struct rt_ofw_node *np
|
||||
return ofw_name;
|
||||
}
|
||||
|
||||
static int tty_device_compare(rt_device_t dev, void *data)
|
||||
{
|
||||
rt_ubase_t *args_list;
|
||||
char *dst_con;
|
||||
const char *console, **ofw_name;
|
||||
const struct rt_ofw_node_id *id;
|
||||
struct rt_platform_device *pdev;
|
||||
int *tty_idx, tty_id, tty_name_len;
|
||||
|
||||
pdev = rt_container_of(dev, struct rt_platform_device, parent);
|
||||
id = pdev->id;
|
||||
|
||||
args_list = data;
|
||||
tty_idx = (int *)args_list[0];
|
||||
tty_id = args_list[1];
|
||||
console = (const char *)args_list[2];
|
||||
tty_name_len = args_list[3];
|
||||
dst_con = (char *)args_list[4];
|
||||
ofw_name = (const char **)args_list[5];
|
||||
|
||||
if (id && id->type[0] && !strncmp(id->type, console, tty_name_len))
|
||||
{
|
||||
if (*tty_idx == tty_id)
|
||||
{
|
||||
*ofw_name = ofw_console_serial_find(dst_con, pdev->parent.ofw_node);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
++*tty_idx;
|
||||
}
|
||||
|
||||
return -RT_EEMPTY;
|
||||
}
|
||||
|
||||
static const char *ofw_console_tty_find(char *dst_con, const char *con)
|
||||
{
|
||||
const char *ofw_name = RT_NULL;
|
||||
@@ -97,8 +132,7 @@ static const char *ofw_console_tty_find(char *dst_con, const char *con)
|
||||
|
||||
if (platform_bus)
|
||||
{
|
||||
rt_device_t dev;
|
||||
rt_ubase_t level;
|
||||
rt_ubase_t args_list[6];
|
||||
const char *console = con;
|
||||
int tty_idx = 0, tty_id = 0, tty_name_len;
|
||||
|
||||
@@ -119,27 +153,13 @@ static const char *ofw_console_tty_find(char *dst_con, const char *con)
|
||||
++con;
|
||||
}
|
||||
|
||||
level = rt_spin_lock_irqsave(&platform_bus->spinlock);
|
||||
|
||||
rt_list_for_each_entry(dev, &platform_bus->dev_list, node)
|
||||
{
|
||||
struct rt_platform_device *pdev = rt_container_of(dev, struct rt_platform_device, parent);
|
||||
const struct rt_ofw_node_id *id = pdev->id;
|
||||
|
||||
if (id && id->type[0] && !rt_strncmp(id->type, console, tty_name_len))
|
||||
{
|
||||
if (tty_idx == tty_id)
|
||||
{
|
||||
ofw_name = ofw_console_serial_find(dst_con, pdev->parent.ofw_node);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
++tty_idx;
|
||||
}
|
||||
}
|
||||
|
||||
rt_spin_unlock_irqrestore(&platform_bus->spinlock, level);
|
||||
args_list[0] = (rt_ubase_t)&tty_idx;
|
||||
args_list[1] = tty_id;
|
||||
args_list[2] = (rt_ubase_t)console;
|
||||
args_list[3] = tty_name_len;
|
||||
args_list[4] = (rt_ubase_t)dst_con;
|
||||
args_list[5] = (rt_ubase_t)&ofw_name;
|
||||
rt_bus_for_each_dev(platform_bus, &args_list, tty_device_compare);
|
||||
}
|
||||
|
||||
return ofw_name;
|
||||
@@ -463,6 +483,11 @@ static void ofw_node_dump_dts(struct rt_ofw_node *np, rt_bool_t sibling_too)
|
||||
dts_put_depth(depth);
|
||||
rt_kputs("};\n");
|
||||
|
||||
if (!sibling_too && org_np == np)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
while (np->parent && !np->sibling)
|
||||
{
|
||||
np = np->parent;
|
||||
|
||||
@@ -68,6 +68,7 @@ extern struct rt_fdt_earlycon fdt_earlycon;
|
||||
(to_type)(((value) >> ((sizeof(value) - sizeof(to_type)) * 8)))
|
||||
|
||||
rt_err_t ofw_alias_scan(void);
|
||||
int ofw_alias_node_id(struct rt_ofw_node *np);
|
||||
rt_err_t ofw_phandle_hash_reset(rt_phandle min, rt_phandle max);
|
||||
|
||||
#endif /* __OFW_INTERNAL_H__ */
|
||||
|
||||
@@ -1470,6 +1470,7 @@ enum rt_device_class_type
|
||||
*/
|
||||
#define RT_DEVICE_CTRL_BASE(Type) ((RT_Device_Class_##Type + 1) * 0x100)
|
||||
|
||||
typedef struct rt_driver *rt_driver_t;
|
||||
typedef struct rt_device *rt_device_t;
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
|
||||
Reference in New Issue
Block a user