1 /*
2 * Copyright (c) 2012 Corey Tabaka
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 #include <dev/driver.h>
25 #include <assert.h>
26 #include <err.h>
27 #include <trace.h>
28
29 extern struct device __devices[];
30 extern struct device __devices_end[];
31
device_init_all(void)32 status_t device_init_all(void)
33 {
34 status_t res = NO_ERROR;
35
36 struct device *dev = __devices;
37 while (dev != __devices_end) {
38 status_t code = device_init(dev);
39
40 if (code < 0) {
41 TRACEF("Driver init failed for driver \"%s\", device \"%s\", reason %d\n",
42 dev->driver->type, dev->name, code);
43
44 res = code;
45 }
46
47 dev++;
48 }
49
50 return res;
51 }
52
device_fini_all(void)53 status_t device_fini_all(void)
54 {
55 status_t res = NO_ERROR;
56
57 struct device *dev = __devices;
58 while (dev != __devices_end) {
59 status_t code = device_fini(dev);
60
61 if (code < 0) {
62 TRACEF("Driver fini failed for driver \"%s\", device \"%s\", reason %d\n",
63 dev->driver->type, dev->name, code);
64
65 res = code;
66 }
67
68 dev++;
69 }
70
71 return res;
72 }
73
device_init(struct device * dev)74 status_t device_init(struct device *dev)
75 {
76 if (!dev)
77 return ERR_INVALID_ARGS;
78
79 DEBUG_ASSERT(dev->driver);
80
81 const struct driver_ops *ops = dev->driver->ops;
82
83 if (ops && ops->init)
84 return ops->init(dev);
85 else
86 return ERR_NOT_SUPPORTED;
87 }
88
device_fini(struct device * dev)89 status_t device_fini(struct device *dev)
90 {
91 if (!dev)
92 return ERR_INVALID_ARGS;
93
94 DEBUG_ASSERT(dev->driver);
95
96 const struct driver_ops *ops = dev->driver->ops;
97
98 if (ops && ops->fini)
99 return ops->fini(dev);
100 else
101 return ERR_NOT_SUPPORTED;
102 }
103
device_suspend(struct device * dev)104 status_t device_suspend(struct device *dev)
105 {
106 if (!dev)
107 return ERR_NOT_SUPPORTED;
108
109 DEBUG_ASSERT(dev->driver);
110
111 const struct driver_ops *ops = dev->driver->ops;
112
113 if (ops && ops->suspend)
114 return ops->suspend(dev);
115 else
116 return ERR_NOT_SUPPORTED;
117 }
118
device_resume(struct device * dev)119 status_t device_resume(struct device *dev)
120 {
121 if (!dev)
122 return ERR_NOT_SUPPORTED;
123
124 DEBUG_ASSERT(dev->driver);
125
126 const struct driver_ops *ops = dev->driver->ops;
127
128 if (ops && ops->resume)
129 return ops->resume(dev);
130 else
131 return ERR_NOT_SUPPORTED;
132 }
133
134