blob: 4b31ac1fd00be39c6db7b61d0d4f6a4ecd949f5e [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
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
29extern struct device __devices[];
30extern struct device __devices_end[];
31
32status_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
53status_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
74status_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
89status_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
104status_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
119status_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