1 /*
2 * Copyright (c) 2012 Corey Tabaka
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8
9 #include <dev/driver.h>
10 #include <assert.h>
11 #include <lk/err.h>
12 #include <lk/trace.h>
13
14 /* static list of devices constructed with DEVICE_INSTANCE macros */
15 extern struct device __start_devices __WEAK;
16 extern struct device __stop_devices __WEAK;
17
device_init_all(void)18 status_t device_init_all(void) {
19 status_t res = NO_ERROR;
20
21 for (struct device *dev = &__start_devices; dev != &__stop_devices; dev++) {
22 if (dev->flags & DEVICE_FLAG_AUTOINIT) {
23 status_t code = device_init(dev);
24
25 if (code < 0) {
26 TRACEF("Driver init failed for driver \"%s\", device \"%s\", reason %d\n",
27 dev->driver->type, dev->name, code);
28
29 res = code;
30 }
31 }
32 }
33
34 return res;
35 }
36
device_fini_all(void)37 status_t device_fini_all(void) {
38 status_t res = NO_ERROR;
39
40 for (struct device *dev = &__start_devices; dev != &__stop_devices; dev++) {
41 status_t code = device_fini(dev);
42
43 if (code < 0) {
44 TRACEF("Driver fini failed for driver \"%s\", device \"%s\", reason %d\n",
45 dev->driver->type, dev->name, code);
46
47 res = code;
48 }
49 }
50
51 return res;
52 }
53
device_init(struct device * dev)54 status_t device_init(struct device *dev) {
55 if (!dev)
56 return ERR_INVALID_ARGS;
57
58 DEBUG_ASSERT(dev->driver);
59
60 const struct driver_ops *ops = dev->driver->ops;
61
62 if (ops && ops->init) {
63 dprintf(INFO, "dev: initializing device %s:%s\n", dev->driver->type, dev->name);
64 status_t err = ops->init(dev);
65 if (err < 0) {
66 dev->device_state = DEVICE_INITIALIZED_FAILED;
67 } else {
68 dev->device_state = DEVICE_INITIALIZED;
69 }
70 return err;
71 } else {
72 return ERR_NOT_SUPPORTED;
73 }
74 }
75
device_fini(struct device * dev)76 status_t device_fini(struct device *dev) {
77 if (!dev)
78 return ERR_INVALID_ARGS;
79
80 DEBUG_ASSERT(dev->driver);
81
82 const struct driver_ops *ops = dev->driver->ops;
83
84 if (ops && ops->fini)
85 return ops->fini(dev);
86 else
87 return ERR_NOT_SUPPORTED;
88 }
89
device_suspend(struct device * dev)90 status_t device_suspend(struct device *dev) {
91 if (!dev)
92 return ERR_NOT_SUPPORTED;
93
94 DEBUG_ASSERT(dev->driver);
95
96 const struct driver_ops *ops = dev->driver->ops;
97
98 if (ops && ops->suspend)
99 return ops->suspend(dev);
100 else
101 return ERR_NOT_SUPPORTED;
102 }
103
device_resume(struct device * dev)104 status_t device_resume(struct device *dev) {
105 if (!dev)
106 return ERR_NOT_SUPPORTED;
107
108 DEBUG_ASSERT(dev->driver);
109
110 const struct driver_ops *ops = dev->driver->ops;
111
112 if (ops && ops->resume)
113 return ops->resume(dev);
114 else
115 return ERR_NOT_SUPPORTED;
116 }
117
118