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