[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>
This commit is contained in:
GuEe-GUI 2024-10-23 19:07:06 +08:00 committed by Rbb666
parent 45aba1bcd7
commit 3b22dbd049
4 changed files with 247 additions and 0 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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__ */

View File

@ -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 */