Browse Source

[DM/FEATURE] DM Device IDA management

Drivers can manage their own IDs without having to concern
themselves with the register/unregister in system

Link: https://github.com/RT-Thread/rt-thread/issues/9534

Signed-off-by: GuEe-GUI <2991707448@qq.com>
GuEe-GUI 9 months ago
parent
commit
3b22dbd049

+ 131 - 0
components/drivers/core/dm.c

@@ -53,6 +53,137 @@ void rt_dm_secondary_cpu_init(void)
 }
 #endif /* RT_USING_SMP */
 
+/**
+ * @brief This function will alloc an id in an IDA object
+ *
+ * @param ida is the IDA object
+ *
+ * @return the id or -RT_EEMPTY
+ */
+int rt_dm_ida_alloc(struct rt_dm_ida *ida)
+{
+    int id;
+    RT_ASSERT(ida != RT_NULL);
+
+    rt_spin_lock(&ida->lock);
+
+    id = rt_bitmap_next_clear_bit(ida->map, 0, RT_DM_IDA_NUM);
+
+    if (id != RT_DM_IDA_NUM)
+    {
+        rt_bitmap_set_bit(ida->map, id);
+    }
+
+    rt_spin_unlock(&ida->lock);
+
+    if (id != RT_DM_IDA_NUM)
+    {
+        return id;
+    }
+
+    return -RT_EEMPTY;
+}
+
+/**
+ * @brief This function will take (force) an id in an IDA object
+ *
+ * @param ida is the IDA object
+ *
+ * @param id is the id that want to take
+ *
+ * @return the result of taking
+ */
+rt_bool_t rt_dm_ida_take(struct rt_dm_ida *ida, int id)
+{
+    RT_ASSERT(ida != RT_NULL);
+    RT_ASSERT(id >= 0);
+
+    rt_spin_lock(&ida->lock);
+
+    if (!rt_bitmap_test_bit(ida->map, id))
+    {
+        rt_bitmap_set_bit(ida->map, id);
+    }
+    else
+    {
+        id = RT_DM_IDA_NUM;
+    }
+
+    rt_spin_unlock(&ida->lock);
+
+    return id != RT_DM_IDA_NUM;
+}
+
+/**
+ * @brief This function will release an id in an IDA object
+ *
+ * @param ida is the IDA object
+ *
+ * @param id is the id of IDA object
+ */
+void rt_dm_ida_free(struct rt_dm_ida *ida, int id)
+{
+    RT_ASSERT(ida != RT_NULL);
+    RT_ASSERT(id >= 0);
+
+    rt_spin_lock(&ida->lock);
+
+    rt_bitmap_clear_bit(ida->map, id);
+
+    rt_spin_unlock(&ida->lock);
+}
+
+/**
+ * @brief This function will return the specified master id and device id of device.
+ *
+ * @param master_id is the master id (0, 255] of device
+ *
+ * @param device_id is the device id [-1, 255] of device, when device_id is -1,
+ *        the function will end when find the first device.
+ *
+ * @return the device object or RT_NULL
+ */
+rt_device_t rt_dm_device_find(int master_id, int device_id)
+{
+    struct rt_device *dev, *ret_dev = RT_NULL;
+    struct rt_object_information *information = RT_NULL;
+
+    if (master_id <= 0 || device_id > 255)
+    {
+        return RT_NULL;
+    }
+
+    information = rt_object_get_information(RT_Object_Class_Device);
+
+    /* parameter check */
+    if (!information)
+    {
+        return RT_NULL;
+    }
+
+    /* which is invoke in interrupt status */
+    RT_DEBUG_NOT_IN_INTERRUPT;
+
+    /* enter critical */
+    rt_enter_critical();
+
+    /* try to find object */
+    rt_list_for_each_entry(dev, &information->object_list, parent.list)
+    {
+        if (master_id == dev->master_id &&
+            (device_id == -1 || device_id == dev->device_id))
+        {
+            ret_dev = dev;
+            break;
+        }
+    }
+
+    /* leave critical */
+    rt_exit_critical();
+
+    return ret_dev;
+}
+
 struct prefix_track
 {
     rt_list_t list;

+ 19 - 0
components/drivers/include/drivers/core/dm.h

@@ -13,6 +13,7 @@
 
 #include <rthw.h>
 #include <rtdef.h>
+#include <bitmap.h>
 #include <ioremap.h>
 #include <drivers/misc.h>
 #include <drivers/byteorder.h>
@@ -27,6 +28,24 @@ extern int rt_hw_cpu_id(void);
 
 void rt_dm_secondary_cpu_init(void);
 
+/* ID Allocation */
+struct rt_dm_ida
+{
+    rt_uint8_t master_id;
+
+#define RT_DM_IDA_NUM 256
+    RT_BITMAP_DECLARE(map, RT_DM_IDA_NUM);
+    struct rt_spinlock lock;
+};
+
+#define RT_DM_IDA_INIT(id)  { .master_id = MASTER_ID_##id }
+
+int rt_dm_ida_alloc(struct rt_dm_ida *ida);
+rt_bool_t rt_dm_ida_take(struct rt_dm_ida *ida, int id);
+void rt_dm_ida_free(struct rt_dm_ida *ida, int id);
+
+rt_device_t rt_dm_device_find(int master_id, int device_id);
+
 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);
 

+ 94 - 0
components/drivers/include/drivers/core/master_id.h

@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-04-20     GuEe-GUI     the first version
+ */
+
+#ifndef __RT_DM_MASTER_ID_H__
+#define __RT_DM_MASTER_ID_H__
+
+#define MASTER_ID_CUSTOM                                0
+
+/* Block */
+#define MASTER_ID_NVME                                  1
+#define MASTER_ID_SCSI_SD                               2
+#define MASTER_ID_SCSI_CDROM                            3
+#define MASTER_ID_SDIO                                  4
+#define MASTER_ID_VIRTUAL_BLOCK                         5
+
+/* Char */
+#define MASTER_ID_RPMSG_EPT                             11
+#define MASTER_ID_RPMSG_CHAR                            12
+#define MASTER_ID_SERIAL                                13
+
+/* Clock Timer */
+#define MASTER_ID_HWTIMER                               21
+#define MASTER_ID_PTP                                   22
+#define MASTER_ID_RTC                                   23
+
+/* Graphic Display */
+#define MASTER_ID_GRAPHIC_BACKLIGHT                     31
+#define MASTER_ID_GRAPHIC_FRAMEBUFFER                   32
+#define MASTER_ID_LED                                   33
+
+/* Hardware Monitor */
+#define MASTER_ID_DVFS                                  41
+#define MASTER_ID_SENSOR                                42
+#define MASTER_ID_THERMAL                               43
+#define MASTER_ID_WATCHDOG                              44
+
+/* I2C */
+#define MASTER_ID_I2C_BUS                               51
+#define MASTER_ID_I2C_DEV                               52
+
+/* IO Contorl */
+#define MASTER_ID_ADC                                   61
+#define MASTER_ID_DAC                                   62
+#define MASTER_ID_PIN                                   63
+#define MASTER_ID_PWM                                   64
+
+/* Memory */
+#define MASTER_ID_MEM                                   71
+#define MASTER_ID_MTD                                   72
+
+/* MISC */
+#define MASTER_ID_MISC                                  81
+
+/* Multimedia */
+#define MASTER_ID_AUDIO                                 91
+
+/* Net */
+#define MASTER_ID_CAN                                   101
+#define MASTER_ID_ETH                                   102
+#define MASTER_ID_PHY                                   103
+#define MASTER_ID_WLAN                                  104
+
+/* Input */
+#define MASTER_ID_INPUT                                 111
+#define MASTER_ID_TOUCH                                 112
+
+/* Security */
+#define MASTER_ID_HWCRYPTO                              121
+#define MASTER_ID_RNG                                   122
+#define MASTER_ID_TEE                                   123
+
+/* SPI */
+#define MASTER_ID_SPI_BUS                               131
+#define MASTER_ID_SPI_DEV                               132
+
+/* TTY */
+#define MASTER_ID_TTY                                   141
+#define MASTER_ID_TTY_SLAVES                            142
+#define MASTER_ID_TTY_ALTERNATE                        	143
+#define MASTER_ID_PTMX                                  144
+
+/* USB */
+#define MASTER_ID_USB_DEV                               151
+#define MASTER_ID_USB_BUS                               152
+#define MASTER_ID_USB_OTG                               153
+
+#endif /* __RT_DM_MASTER_ID_H__ */

+ 3 - 0
include/rtdef.h

@@ -1390,6 +1390,9 @@ struct rt_device
     rt_uint16_t               open_flag;                /**< device open flag */
 
     rt_uint8_t                ref_count;                /**< reference count */
+#ifdef RT_USING_DM
+    rt_uint8_t                master_id;                /**< 0 - 255 */
+#endif
     rt_uint8_t                device_id;                /**< 0 - 255 */
 
     /* device call back */