blob: 86fcb6be32bd939f3d67b210cbdadb97741f237a [file] [log] [blame]
Kumar Galad12d8af2016-10-05 12:01:54 -05001/*
2 * Copyright (c) 2015-2016 Intel Corporation.
3 *
David B. Kinderac74d8b2017-01-18 17:01:01 -08004 * SPDX-License-Identifier: Apache-2.0
Kumar Galad12d8af2016-10-05 12:01:54 -05005 */
6
7#include <errno.h>
8#include <string.h>
9#include <device.h>
10#include <misc/util.h>
11#include <atomic.h>
12
13extern struct device __device_init_start[];
Andrew Boie0b474ee2016-11-08 11:06:55 -080014extern struct device __device_PRE_KERNEL_1_start[];
15extern struct device __device_PRE_KERNEL_2_start[];
16extern struct device __device_POST_KERNEL_start[];
17extern struct device __device_APPLICATION_start[];
Kumar Galad12d8af2016-10-05 12:01:54 -050018extern struct device __device_init_end[];
19
20static struct device *config_levels[] = {
Andrew Boie0b474ee2016-11-08 11:06:55 -080021 __device_PRE_KERNEL_1_start,
22 __device_PRE_KERNEL_2_start,
23 __device_POST_KERNEL_start,
24 __device_APPLICATION_start,
Andrew Boie0b474ee2016-11-08 11:06:55 -080025 /* End marker */
Kumar Galad12d8af2016-10-05 12:01:54 -050026 __device_init_end,
27};
28
29#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
Kumar Galacc334c72017-04-21 10:55:34 -050030extern u32_t __device_busy_start[];
31extern u32_t __device_busy_end[];
Kumar Galad12d8af2016-10-05 12:01:54 -050032#define DEVICE_BUSY_SIZE (__device_busy_end - __device_busy_start)
33#endif
34
35/**
36 * @brief Execute all the device initialization functions at a given level
37 *
38 * @details Invokes the initialization routine for each device object
39 * created by the DEVICE_INIT() macro using the specified level.
40 * The linker script places the device objects in memory in the order
41 * they need to be invoked, with symbols indicating where one level leaves
42 * off and the next one begins.
43 *
44 * @param level init level to run.
45 */
46void _sys_device_do_config_level(int level)
47{
48 struct device *info;
49
Amir Kaplan61b6f5a2017-03-22 14:49:34 +020050 for (info = config_levels[level]; info < config_levels[level+1];
51 info++) {
Kumar Galad12d8af2016-10-05 12:01:54 -050052 struct device_config *device = info->config;
53
54 device->init(info);
Andrew Boie5bd891d2017-09-27 12:59:28 -070055 _k_object_init(info);
Kumar Galad12d8af2016-10-05 12:01:54 -050056 }
57}
58
59struct device *device_get_binding(const char *name)
60{
61 struct device *info;
62
63 for (info = __device_init_start; info != __device_init_end; info++) {
64 if (info->driver_api && !strcmp(name, info->config->name)) {
65 return info;
66 }
67 }
68
69 return NULL;
70}
71
72#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
Ramesh Thomas6249c562016-10-07 17:07:04 -070073int device_pm_control_nop(struct device *unused_device,
Kumar Galacc334c72017-04-21 10:55:34 -050074 u32_t unused_ctrl_command, void *unused_context)
Kumar Galad12d8af2016-10-05 12:01:54 -050075{
76 return 0;
77}
Ramesh Thomas6249c562016-10-07 17:07:04 -070078
Kumar Galad12d8af2016-10-05 12:01:54 -050079void device_list_get(struct device **device_list, int *device_count)
80{
81
82 *device_list = __device_init_start;
83 *device_count = __device_init_end - __device_init_start;
84}
85
86
87int device_any_busy_check(void)
88{
89 int i = 0;
90
91 for (i = 0; i < DEVICE_BUSY_SIZE; i++) {
92 if (__device_busy_start[i] != 0) {
93 return -EBUSY;
94 }
95 }
96 return 0;
97}
98
99int device_busy_check(struct device *chk_dev)
100{
101 if (atomic_test_bit((const atomic_t *)__device_busy_start,
102 (chk_dev - __device_init_start))) {
103 return -EBUSY;
104 }
105 return 0;
106}
107
108#endif
109
110void device_busy_set(struct device *busy_dev)
111{
112#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
113 atomic_set_bit((atomic_t *) __device_busy_start,
114 (busy_dev - __device_init_start));
Flavio Santesb80db0a2016-12-11 00:19:26 -0600115#else
116 ARG_UNUSED(busy_dev);
Kumar Galad12d8af2016-10-05 12:01:54 -0500117#endif
118}
119
120void device_busy_clear(struct device *busy_dev)
121{
122#ifdef CONFIG_DEVICE_POWER_MANAGEMENT
123 atomic_clear_bit((atomic_t *) __device_busy_start,
124 (busy_dev - __device_init_start));
Flavio Santesb80db0a2016-12-11 00:19:26 -0600125#else
126 ARG_UNUSED(busy_dev);
Kumar Galad12d8af2016-10-05 12:01:54 -0500127#endif
128}