1 /*
2 * Copyright (C) 2021 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19 #ifndef __LIUNX_DEVICE_H__
20 #define __LIUNX_DEVICE_H__
21
22 #include "los_base.h"
23 #include "los_mux.h"
24 #include "linux/list.h"
25 #include "linux/pm.h"
26
27 #ifdef __cplusplus
28 #if __cplusplus
29 extern "C" {
30 #endif /* __cplusplus */
31 #endif /* __cplusplus */
32
33 struct bus_type;
34 struct device_driver;
35 struct dev_pm_op;
36
37 /* device define */
38 /* *
39 * @ingroup los_drivers
40 * Define the structure of the parameters used for device creation.
41 */
42 struct device {
43 const CHAR *name;
44 LOS_DL_LIST children_list;
45 LOS_DL_LIST parent_node;
46 LOS_DL_LIST driver_node;
47 LOS_DL_LIST bus_node;
48 struct device *parent;
49 VOID *p; /**< private data */
50 LosMux mutex;
51 struct bus_type *bus; /**< type of bus device is on */
52 struct device_driver *driver; /**< which driver has allocated this device */
53 VOID *driver_data;
54 VOID *platform_data; /**< Platform specific data, device core doesn't touch it */
55 struct dev_pm_op *ops;
56 VOID (*release)(struct device *dev);
57 struct dev_pm_info power;
58 };
59
60 /* driver define */
61 /* *
62 * @ingroup los_drivers
63 * Define the structure of the parameters used for driver creation.
64 */
65 struct device_driver {
66 const CHAR *name;
67 struct bus_type *bus;
68 INT32 (*probe)(struct device *dev);
69 INT32 (*remove)(struct device *dev);
70 VOID (*shutdown)(struct device *dev);
71 INT32 (*suspend)(struct device *dev, INT32 state);
72 INT32 (*resume)(struct device *dev);
73 const struct dev_pm_op *pm;
74 VOID *p;
75 LOS_DL_LIST device_list;
76 LOS_DL_LIST bus_node;
77 LosMux mutex;
78 };
79
80 struct dev_pm_op {
81 INT32 (*suspend)(struct device *ptr);
82 INT32 (*resume)(struct device *ptr);
83 INT32 (*prepare)(struct device *dev);
84 INT32 (*complete)(struct device *dev);
85 };
86
87 /* *
88 * @ingroup los_drivers
89 * Define the structure of the parameters used for bus creation.
90 */
91 struct bus_type {
92 const CHAR *name;
93 LOS_DL_LIST bus_node;
94 INT32 (*match)(struct device *dev, struct device_driver *drv);
95 INT32 (*probe)(struct device *dev);
96 INT32 (*remove)(struct device *dev);
97 VOID (*shutdown)(struct device *dev);
98 const struct dev_pm_op *pm;
99 LOS_DL_LIST device_list;
100 LOS_DL_LIST driver_list;
101 VOID *p;
102 LosMux mutex;
103 };
104
105 /* errno */
106 /* *
107 * @ingroup los_task
108 * Task error code: Invalid input.
109 *
110 * Value: 0x02004110
111 *
112 * Solution: Check the Input.
113 */
114 #define LOS_ERRNO_DRIVER_INPUT_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_DRIVER, 0x10)
115
116 /* *
117 * @ingroup los_task
118 * Task error code: Bus register twice.
119 *
120 * Value: 0x02004111
121 *
122 * Solution: Check the Input.
123 */
124 #define LOS_ERRNO_DRIVER_BUS_REGISTERED LOS_ERRNO_OS_ERROR(LOS_MOD_DRIVER, 0x11)
125
126 /* *
127 * @ingroup los_task
128 * Task error code: Invalid input.
129 *
130 * Value: 0x02004112
131 *
132 * Solution: Check the Input.
133 */
134 #define LOS_ERRNO_DRIVER_BUS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_DRIVER, 0x12)
135
136 /* *
137 * @ingroup los_task
138 * Task error code: Invalid input.
139 *
140 * Value: 0x02004113
141 *
142 * Solution: This error code is not in use temporarily.
143 */
144 #define LOS_ERRNO_DRIVER_BUS_INPUT_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_DRIVER, 0x13)
145
146 /* *
147 * @ingroup los_task
148 * Task error code: Do match function failed.
149 *
150 * Value: 0x02004114
151 *
152 * Solution: Check match function.
153 */
154 #define LOS_ERRNO_DRIVER_BUS_MATCH_FAIL LOS_ERRNO_OS_ERROR(LOS_MOD_DRIVER, 0x14)
155
156 /* *
157 * @ingroup los_task
158 * Task error code: Do probe function failed.
159 *
160 * Value: 0x02004115
161 *
162 * Solution: Check probe function.
163 */
164 #define LOS_ERRNO_DRIVER_BUS_PROBE_FAIL LOS_ERRNO_OS_ERROR(LOS_MOD_DRIVER, 0x15)
165
166 /* *
167 * @ingroup los_task
168 * Task error code: Create mux failed.
169 *
170 * Value: 0x02004116
171 *
172 * Solution: Check the system state.
173 */
174 #define LOS_ERRNO_DRIVER_BUS_MUX_FAIL LOS_ERRNO_OS_ERROR(LOS_MOD_DRIVER, 0x16)
175
176 /* *
177 * @ingroup los_task
178 * Task error code: Do match function failed.
179 *
180 * Value: 0x02004120
181 *
182 * Solution: This error code is not in use temporarily.
183 */
184 #define LOS_ERRNO_DRIVER_DRIVER_MATCH_FAIL LOS_ERRNO_OS_ERROR(LOS_MOD_DRIVER, 0x20)
185
186 /* *
187 * @ingroup los_task
188 * Task error code: Do probe function failed.
189 *
190 * Value: 0x02004121
191 *
192 * Solution: This error code is not in use temporarily.
193 */
194 #define LOS_ERRNO_DRIVER_DRIVER_PROBE_FAIL LOS_ERRNO_OS_ERROR(LOS_MOD_DRIVER, 0x21)
195
196 /* *
197 * @ingroup los_task
198 * Task error code: driver register twice.
199 *
200 * Value: 0x02004122
201 *
202 * Solution: Check the Input.
203 */
204 #define LOS_ERRNO_DRIVER_DRIVER_REGISTERED LOS_ERRNO_OS_ERROR(LOS_MOD_DRIVER, 0x22)
205
206 /* *
207 * @ingroup los_task
208 * Task error code: Invalid input.
209 *
210 * Value: 0x02004123
211 *
212 * Solution: Check the Input.
213 */
214 #define LOS_ERRNO_DRIVER_DRIVER_NOTFOUND LOS_ERRNO_OS_ERROR(LOS_MOD_DRIVER, 0x23)
215
216 /* *
217 * @ingroup los_task
218 * Task error code: Device already attach to driver.
219 *
220 * Value: 0x02004130
221 *
222 * Solution: Check the Input.
223 */
224 #define LOS_ERRNO_DRIVER_DEVICE_BOUNDED LOS_ERRNO_OS_ERROR(LOS_MOD_DRIVER, 0x30)
225
226 /* *
227 * @ingroup los_task
228 * Task error code: Invalid input.
229 *
230 * Value: 0x02004131
231 *
232 * Solution: Check the Input.
233 */
234 #define LOS_ERRNO_DRIVER_DEVICE_INITIALFAIL LOS_ERRNO_OS_ERROR(LOS_MOD_DRIVER, 0x31)
235
236 /* *
237 * @ingroup los_task
238 * Task error code: Device register twice.
239 *
240 * Value: 0x02004132
241 *
242 * Solution: Check the Input.
243 */
244 #define LOS_ERRNO_DRIVER_DEVICE_REGISTERED LOS_ERRNO_OS_ERROR(LOS_MOD_DRIVER, 0x32)
245
246 /* *
247 * @ingroup los_task
248 * Task error code: Device busy.
249 *
250 * Value: 0x02004133
251 *
252 * Solution: Check the Input.
253 */
254 #define LOS_ERRNO_DRIVER_DEVICE_BUSY LOS_ERRNO_OS_ERROR(LOS_MOD_DRIVER, 0x33)
255
256 /* bus api */
257 /* *
258 * @ingroup los_drivers
259 * @brief register a new bus system.
260 *
261 * @par Description:
262 * <ul>
263 * <li>This API is used to register a bus system that can manage its drivers and devices.</li>
264 * </ul>
265 * @attention
266 * <ul>
267 * <li>The param match and probe used for attaching the device and the driver.</li>
268 * <li>The same bus node can not be registered twice.</li>
269 * <li>Do not use device_list and driver_list by yourself.</li>
270 * </ul>
271 *
272 * @param bus [IN]A pointer to bus_type.
273 *
274 * @retval #LOS_ERRNO_DRIVER_INPUT_INVALID Invalid input.bus or bus->name may be NULL.
275 * @retval #LOS_ERRNO_DRIVER_BUS_REGISTERED Invalid input.Node can not be registered twice.
276 * @retval #LOS_ERRNO_DRIVER_BUS_MUX_FAIL Mux creat failed.
277 * @retval #LOS_OK The bus register success.
278 * @par Dependency:
279 * <ul><li>device.h: the header file that contains the API declaration.</li></ul>
280 */
281 extern UINT32 bus_register(struct bus_type *bus);
282
283 /* *
284 * @ingroup los_drivers
285 * @brief unregister a bus system.
286 *
287 * @par Description:
288 * <ul>
289 * <li>This API is used to unregister a bus system.</li>
290 * </ul>
291 *
292 * @param bus [IN]A pointer to bus_type.bus_type bus can not be NULL.
293 *
294 * @par Dependency:
295 * <ul><li>device.h: the header file that contains the API declaration.</li></ul>
296 */
297 extern void bus_unregister(struct bus_type *bus);
298 extern UINT32 bus_rescan_devices(struct bus_type *bus);
299 extern UINT32 bus_add_driver(struct device_driver *drv);
300 extern struct bus_type *bus_get(struct bus_type *bus);
301 extern UINT32 bus_add_device(struct device *dev);
302 extern UINT32 bus_del_device(struct device *dev);
303 extern UINT32 bus_probe_device(struct device *dev);
304 extern UINT32 bus_remove_device(struct device *dev);
305 extern UINT32 bus_for_each_drv(struct bus_type *bus, struct device_driver *start, VOID *data,
306 INT32 (*fn)(struct device_driver *, VOID *));
307 extern UINT32 bus_for_each_dev(struct bus_type *bus, struct device *start, VOID *data,
308 INT32 (*fn)(struct device *, VOID *));
309 extern UINT32 bus_remove_driver(struct device_driver *drv);
310
311 #define bus_lock(bus) (VOID)LOS_MuxLock(&(bus)->mutex, LOS_WAIT_FOREVER);
312 #define bus_unlock(bus) (VOID)LOS_MuxUnlock(&(bus)->mutex);
313
314 /* driver api */
315 /* *
316 * @ingroup los_drivers
317 * @brief register a new driver to the bus system.
318 *
319 * @par Description:
320 * <ul>
321 * <li>This API is used to register a driver to the bus system.</li>
322 * </ul>
323 * @attention
324 * <ul>
325 * <li>The param probe function is applied after attach the device to the driver.</li>
326 * <li>The param remove function is used when device or driver is deleted.</li>
327 * </ul>
328 *
329 * @param drv [IN]A pointer to device_driver.
330 *
331 * @retval #LOS_ERRNO_DRIVER_INPUT_INVALID Invalid input.drv/drv->name/drv->bus can not be NULL.
332 * @retval #LOS_ERRNO_DRIVER_DRIVER_REGISTERED Invalid input.drv node register twice.
333 * @retval #LOS_ERRNO_DRIVER_BUS_MUX_FAIL Mux creat failed.
334 * @retval #LOS_ERRNO_DRIVER_BUS_INVALID drv->bus is not in system.
335 * @retval #LOS_ERRNO_DRIVER_BUS_MATCH_FAIL Do match failed.
336 * @retval #LOS_ERRNO_DRIVER_BUS_PROBE_FAIL Do probe failed.
337 * @retval #LOS_OK The driver register success.
338 * @par Dependency:
339 * <ul><li>device.h: the header file that contains the API declaration.</li></ul>
340 */
341 extern UINT32 driver_register(struct device_driver *drv);
342
343 /* *
344 * @ingroup los_drivers
345 * @brief unregister a driver from the bus system.
346 *
347 * @par Description:
348 * <ul>
349 * <li>This API is used to unregister a driver from the bus system.</li>
350 * </ul>
351 *
352 * @retval #LOS_ERRNO_DRIVER_INPUT_INVALID Invalid input.drv and drv.driver->name can not be NULL.
353 * @retval #LOS_ERRNO_DRIVER_DRIVER_NOTFOUND Driver not found.
354 * @retval #LOS_ERRNO_DRIVER_BUS_INVALID Bus is not in system.
355 * @retval #LOS_ERRNO_DRIVER_DEVICE_BUSY Device busy.
356 * @retval #LOS_OK The driver unregister success.
357 * @param drv [IN]A pointer to device_driver.drv/drv->name/drv->bus can not be NULL.
358 *
359 * @par Dependency:
360 * <ul><li>device.h: the header file that contains the API declaration.</li></ul>
361 */
362 extern UINT32 driver_unregister(struct device_driver *drv);
363 extern UINT32 driver_for_each_device(struct device_driver *drv, struct device *start, VOID *data,
364 INT32 (*fn)(struct device *, VOID *));
365 extern struct device_driver *driver_find(const CHAR *name, struct bus_type *bus);
366 extern UINT32 driver_attach(struct device_driver *drv);
367 extern UINT32 driver_detach(struct device_driver *drv);
368 extern UINT32 driver_probe_device(struct device_driver *drv, struct device *dev);
369 extern UINT32 driver_remove_device(struct device_driver *drv, struct device *dev);
370
371 #define driver_lock(_drv) (VOID)LOS_MuxLock(&(_drv)->mutex, LOS_WAIT_FOREVER)
372 #define driver_unlock(_drv) (VOID)LOS_MuxUnlock(&(_drv)->mutex)
373
374
375 /* device api */
376 /* *
377 * @ingroup los_drivers
378 * @brief unregister a device from the bus system.
379 *
380 * @par Description:
381 * <ul>
382 * <li>This API is used to unregister a device from the bus system.</li>
383 * </ul>
384 * @param dev [IN]A pointer to device.dev/dev->name can not be NULL.
385 *
386 * @par Dependency:
387 * <ul><li>device.h: the header file that contains the API declaration.</li></ul>
388 */
389 extern void device_unregister(struct device *dev);
390
391 /* *
392 * @ingroup los_drivers
393 * @brief register a new device to the bus system.
394 *
395 * @par Description:
396 * <ul>
397 * <li>This API is used to register a device to the bus system.</li>
398 * </ul>
399 * @attention
400 * <ul>
401 * <li>The same dev node can not be registered twice.</li>
402 * </ul>
403 *
404 * @param dev [IN]A pointer to device.
405 *
406 * @retval #LOS_ERRNO_DRIVER_INPUT_INVALID Invalid input.dev/dev->name/dev->bus can not be NULL.
407 * @retval #LOS_ERRNO_DRIVER_DEVICE_REGISTERED Device register twice.
408 * @retval #LOS_ERRNO_DRIVER_DEVICE_INITIALFAIL Mux create failed.
409 * @retval #LOS_ERRNO_DRIVER_DEVICE_BOUNDED Do attach failed.device has bounded.
410 * @retval #LOS_ERRNO_DRIVER_BUS_MATCH_FAIL Do match failed.
411 * @retval #LOS_ERRNO_DRIVER_BUS_PROBE_FAIL Do probe failed.
412 * @retval #LOS_OK The device register success.
413 * @par Dependency:
414 * <ul><li>device.h: the header file that contains the API declaration.</li></ul>
415 */
416 extern UINT32 device_register(struct device *dev);
417 extern UINT32 device_initialize(struct device *dev);
418 extern BOOL device_is_registered(struct device *dev);
419 extern UINT32 device_remove(struct device *dev);
420 extern UINT32 linux_device_attach(struct device *dev);
421 extern UINT32 device_add(struct device *dev);
422 extern VOID device_del(struct device *dev);
423
dev_get_platdata(const struct device * dev)424 STATIC INLINE VOID *dev_get_platdata(const struct device *dev)
425 {
426 if (dev == NULL) {
427 PRINT_WARN("dev_get_platdata :the input dev is NULL!\n");
428 return NULL;
429 }
430 return dev->platform_data;
431 }
432
dev_set_platdata(struct device * dev,VOID * data)433 STATIC INLINE VOID dev_set_platdata(struct device *dev, VOID *data)
434 {
435 if (dev == NULL) {
436 PRINT_WARN("dev_set_platdata :the input dev is NULL!\n");
437 return;
438 }
439 dev->platform_data = data;
440 }
441
dev_get_drvdata(const struct device * dev)442 STATIC INLINE VOID *dev_get_drvdata(const struct device *dev)
443 {
444 if (dev == NULL) {
445 PRINT_WARN("dev_get_drvdata :the input dev is NULL!\n");
446 return NULL;
447 }
448 return dev->driver_data;
449 }
450
dev_set_drvdata(struct device * dev,VOID * data)451 STATIC INLINE VOID dev_set_drvdata(struct device *dev, VOID *data)
452 {
453 if (dev == NULL) {
454 PRINT_WARN("dev_set_drvdata :the input dev is NULL!\n");
455 return;
456 }
457 dev->driver_data = data;
458 }
459
460 #define device_lock(dev) (VOID)LOS_MuxLock(&(dev)->mutex, LOS_WAIT_FOREVER)
461 #define device_unlock(dev) (VOID)LOS_MuxUnlock(&(dev)->mutex)
462
463 #ifdef __cplusplus
464 #if __cplusplus
465 }
466 #endif /* __cplusplus */
467 #endif /* __cplusplus */
468
469 #endif
470