123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469 |
- /*
- * Copyright (c) 2006-2024, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2023-04-20 ErikChan the first version
- */
- #include <rtthread.h>
- #ifdef RT_USING_OFW
- #include <drivers/ofw_io.h>
- #include <drivers/ofw_irq.h>
- #endif
- #include <drivers/core/dm.h>
- #ifdef RT_USING_SMP
- static int rti_secondary_cpu_start(void)
- {
- return 0;
- }
- INIT_EXPORT(rti_secondary_cpu_start, "6.end");
- static int rti_secondary_cpu_end(void)
- {
- return 0;
- }
- INIT_EXPORT(rti_secondary_cpu_end, "7.end");
- void rt_dm_secondary_cpu_init(void)
- {
- #ifdef RT_DEBUGING_AUTO_INIT
- int result;
- const struct rt_init_desc *desc;
- rt_kprintf("do secondary cpu initialization.\n");
- for (desc = &__rt_init_desc_rti_secondary_cpu_start; desc < &__rt_init_desc_rti_secondary_cpu_end; ++desc)
- {
- rt_kprintf("initialize %s", desc->fn_name);
- result = desc->fn();
- rt_kprintf(":%d done\n", result);
- }
- #else
- volatile const init_fn_t *fn_ptr;
- for (fn_ptr = &__rt_init_rti_secondary_cpu_start; fn_ptr < &__rt_init_rti_secondary_cpu_end; ++fn_ptr)
- {
- (*fn_ptr)();
- }
- #endif /* RT_DEBUGING_AUTO_INIT */
- }
- #endif /* RT_USING_SMP */
- struct prefix_track
- {
- rt_list_t list;
- int uid;
- const char *prefix;
- };
- static struct rt_spinlock _prefix_nodes_lock = { 0 };
- static rt_list_t _prefix_nodes = RT_LIST_OBJECT_INIT(_prefix_nodes);
- int rt_dm_dev_set_name_auto(rt_device_t dev, const char *prefix)
- {
- int uid = -1;
- struct prefix_track *pt = RT_NULL;
- RT_ASSERT(dev != RT_NULL);
- RT_ASSERT(prefix != RT_NULL);
- RT_DEBUG_NOT_IN_INTERRUPT;
- rt_spin_lock(&_prefix_nodes_lock);
- rt_list_for_each_entry(pt, &_prefix_nodes, list)
- {
- /* caller always input constants string, check ptr is faster */
- if (pt->prefix == prefix || !rt_strcmp(pt->prefix, prefix))
- {
- uid = ++pt->uid;
- break;
- }
- }
- rt_spin_unlock(&_prefix_nodes_lock);
- if (uid < 0)
- {
- pt = rt_malloc(sizeof(*pt));
- if (!pt)
- {
- return -RT_ENOMEM;
- }
- rt_list_init(&pt->list);
- pt->uid = uid = 0;
- pt->prefix = prefix;
- rt_spin_lock(&_prefix_nodes_lock);
- rt_list_insert_before(&_prefix_nodes, &pt->list);
- rt_spin_unlock(&_prefix_nodes_lock);
- }
- return rt_dm_dev_set_name(dev, "%s%u", prefix, uid);
- }
- int rt_dm_dev_get_name_id(rt_device_t dev)
- {
- int id = 0, len;
- const char *name;
- RT_ASSERT(dev != RT_NULL);
- name = rt_dm_dev_get_name(dev);
- len = rt_strlen(name) - 1;
- name += len;
- while (len --> 0)
- {
- if (*name < '0' || *name > '9')
- {
- while (*(++name))
- {
- id *= 10;
- id += *name - '0';
- }
- break;
- }
- --name;
- }
- return id;
- }
- int rt_dm_dev_set_name(rt_device_t dev, const char *format, ...)
- {
- int n;
- va_list arg_ptr;
- RT_ASSERT(dev != RT_NULL);
- RT_ASSERT(format != RT_NULL);
- va_start(arg_ptr, format);
- n = rt_vsnprintf(dev->parent.name, RT_NAME_MAX, format, arg_ptr);
- va_end(arg_ptr);
- return n;
- }
- const char *rt_dm_dev_get_name(rt_device_t dev)
- {
- RT_ASSERT(dev != RT_NULL);
- return dev->parent.name;
- }
- #ifdef RT_USING_OFW
- #define ofw_api_call(name, ...) rt_ofw_##name(__VA_ARGS__)
- #define ofw_api_call_ptr(name, ...) ofw_api_call(name, __VA_ARGS__)
- #else
- #define ofw_api_call(name, ...) (-RT_ENOSYS)
- #define ofw_api_call_ptr(name, ...) RT_NULL
- #endif
- int rt_dm_dev_get_address_count(rt_device_t dev)
- {
- RT_ASSERT(dev != RT_NULL);
- #ifdef RT_USING_OFW
- if (dev->ofw_node)
- {
- return ofw_api_call(get_address_count, dev->ofw_node);
- }
- #endif
- return -RT_ENOSYS;
- }
- 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_ASSERT(dev != RT_NULL);
- #ifdef RT_USING_OFW
- if (dev->ofw_node)
- {
- return ofw_api_call(get_address, dev->ofw_node, index,
- out_address, out_size);
- }
- #endif
- return -RT_ENOSYS;
- }
- 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)
- {
- RT_ASSERT(dev != RT_NULL);
- #ifdef RT_USING_OFW
- if (dev->ofw_node)
- {
- return ofw_api_call(get_address_by_name, dev->ofw_node, name,
- out_address, out_size);
- }
- #endif
- return -RT_ENOSYS;
- }
- int rt_dm_dev_get_address_array(rt_device_t dev, int nr, rt_uint64_t *out_regs)
- {
- RT_ASSERT(dev != RT_NULL);
- #ifdef RT_USING_OFW
- if (dev->ofw_node)
- {
- return ofw_api_call(get_address_array, dev->ofw_node, nr, out_regs);
- }
- #endif
- return -RT_ENOSYS;
- }
- void *rt_dm_dev_iomap(rt_device_t dev, int index)
- {
- RT_ASSERT(dev != RT_NULL);
- #ifdef RT_USING_OFW
- if (dev->ofw_node)
- {
- return ofw_api_call_ptr(iomap, dev->ofw_node, index);
- }
- #endif
- return RT_NULL;
- }
- void *rt_dm_dev_iomap_by_name(rt_device_t dev, const char *name)
- {
- RT_ASSERT(dev != RT_NULL);
- #ifdef RT_USING_OFW
- if (dev->ofw_node)
- {
- return ofw_api_call_ptr(iomap_by_name, dev->ofw_node, name);
- }
- #endif
- return RT_NULL;
- }
- int rt_dm_dev_get_irq_count(rt_device_t dev)
- {
- RT_ASSERT(dev != RT_NULL);
- #if defined(RT_USING_OFW) && defined(RT_USING_PIC)
- if (dev->ofw_node)
- {
- return ofw_api_call(get_irq_count, dev->ofw_node);
- }
- #endif
- return -RT_ENOSYS;
- }
- int rt_dm_dev_get_irq(rt_device_t dev, int index)
- {
- RT_ASSERT(dev != RT_NULL);
- #if defined(RT_USING_OFW) && defined(RT_USING_PIC)
- if (dev->ofw_node)
- {
- return ofw_api_call(get_irq, dev->ofw_node, index);
- }
- #endif
- return -RT_ENOSYS;
- }
- int rt_dm_dev_get_irq_by_name(rt_device_t dev, const char *name)
- {
- RT_ASSERT(dev != RT_NULL);
- #if defined(RT_USING_OFW) && defined(RT_USING_PIC)
- if (dev->ofw_node)
- {
- return ofw_api_call(get_irq_by_name, dev->ofw_node, name);
- }
- #endif
- return -RT_ENOSYS;
- }
- void rt_dm_dev_bind_fwdata(rt_device_t dev, void *fw_np, void *data)
- {
- RT_ASSERT(dev != RT_NULL);
- #ifdef RT_USING_OFW
- if (!dev->ofw_node && fw_np)
- {
- dev->ofw_node = fw_np;
- rt_ofw_data(fw_np) = data;
- }
- if (dev->ofw_node == RT_NULL)
- {
- rt_kprintf("[%s:%s] line=%d ofw_node is NULL\r\n", __FILE__, __func__, __LINE__);
- return;
- }
- rt_ofw_data(dev->ofw_node) = data;
- #endif
- }
- void rt_dm_dev_unbind_fwdata(rt_device_t dev, void *fw_np)
- {
- RT_ASSERT(dev!= RT_NULL);
- #ifdef RT_USING_OFW
- void *dev_fw_np = RT_NULL;
- if (!dev->ofw_node && fw_np)
- {
- dev_fw_np = fw_np;
- rt_ofw_data(fw_np) = RT_NULL;
- }
- if (dev_fw_np == RT_NULL)
- {
- rt_kprintf("[%s:%s] line=%d dev_fw_np is NULL\r\n", __FILE__, __func__, __LINE__);
- return;
- }
- rt_ofw_data(dev_fw_np) = RT_NULL;
- #endif
- }
- 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)
- {
- RT_ASSERT(dev != RT_NULL);
- #ifdef RT_UISNG_OFW
- if (dev->ofw_node)
- {
- return ofw_api_call(prop_read_u8_array_index, dev->ofw_node, propname,
- index, nr, out_value);
- }
- #endif
- return -RT_ENOSYS;
- }
- 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)
- {
- RT_ASSERT(dev != RT_NULL);
- #ifdef RT_USING_OFW
- if (dev->ofw_node)
- {
- return ofw_api_call(prop_read_u16_array_index, dev->ofw_node, propname,
- index, nr, out_values);
- }
- #endif
- return -RT_ENOSYS;
- }
- 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)
- {
- RT_ASSERT(dev != RT_NULL);
- #ifdef RT_USING_OFW
- if (dev->ofw_node)
- {
- return ofw_api_call(prop_read_u32_array_index, dev->ofw_node, propname,
- index, nr, out_values);
- }
- #endif
- return -RT_ENOSYS;
- }
- 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)
- {
- RT_ASSERT(dev != RT_NULL);
- #ifdef RT_USING_OFW
- if (dev->ofw_node)
- {
- return ofw_api_call(prop_read_u64_array_index, dev->ofw_node, propname,
- index, nr, out_values);
- }
- #endif
- return -RT_ENOSYS;
- }
- int rt_dm_dev_prop_read_string_array_index(rt_device_t dev, const char *propname,
- int index, int nr, const char **out_strings)
- {
- RT_ASSERT(dev != RT_NULL);
- #ifdef RT_USING_OFW
- if (dev->ofw_node)
- {
- return ofw_api_call(prop_read_string_array_index, dev->ofw_node, propname,
- index, nr, out_strings);
- }
- #endif
- return -RT_ENOSYS;
- }
- int rt_dm_dev_prop_count_of_size(rt_device_t dev, const char *propname, int size)
- {
- RT_ASSERT(dev != RT_NULL);
- #ifdef RT_USING_OFW
- if (dev->ofw_node)
- {
- return ofw_api_call(prop_count_of_size, dev->ofw_node, propname, size);
- }
- #endif
- return -RT_ENOSYS;
- }
- int rt_dm_dev_prop_index_of_string(rt_device_t dev, const char *propname, const char *string)
- {
- RT_ASSERT(dev != RT_NULL);
- #ifdef RT_USING_OFW
- if (dev->ofw_node)
- {
- return ofw_api_call(prop_index_of_string, dev->ofw_node, propname, string);
- }
- #endif
- return -RT_ENOSYS;
- }
- rt_bool_t rt_dm_dev_prop_read_bool(rt_device_t dev, const char *propname)
- {
- RT_ASSERT(dev != RT_NULL);
- #ifdef RT_USING_OFW
- if (dev->ofw_node)
- {
- return ofw_api_call(prop_read_bool, dev->ofw_node, propname);
- }
- #endif
- return RT_FALSE;
- }
|