summaryrefslogtreecommitdiff
path: root/components/drivers/core/dm.c
blob: 20c2fca1d317a845746411471cdc87e36e0f7ae5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
 * Copyright (c) 2006-2023, 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>

#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)
{
#if RT_DEBUGING_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_INIT */
}
#endif /* RT_USING_SMP */

struct prefix_track
{
    rt_list_t list;

    int uid;
    const char *prefix;
};
static struct rt_spinlock _prefix_nodes_lock;
static rt_list_t _prefix_nodes = RT_LIST_OBJECT_INIT(_prefix_nodes);

int rt_dm_set_dev_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_set_dev_name(dev, "%s%u", prefix, uid);
}

int rt_dm_get_dev_name_id(rt_device_t dev)
{
    int id = 0, len;
    const char *name;

    RT_ASSERT(dev != RT_NULL);

    name = rt_dm_get_dev_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_set_dev_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_get_dev_name(rt_device_t dev)
{
    RT_ASSERT(dev != RT_NULL);

    return dev->parent.name;
}