3714e6307b05908416e4ad636d96a7ef9b26945a
[linux-2.6-microblaze.git] / drivers / firmware / arm_scmi / bus.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * System Control and Management Interface (SCMI) Message Protocol bus layer
4  *
5  * Copyright (C) 2018 ARM Ltd.
6  */
7
8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9
10 #include <linux/types.h>
11 #include <linux/module.h>
12 #include <linux/kernel.h>
13 #include <linux/slab.h>
14 #include <linux/device.h>
15
16 #include "common.h"
17
18 static DEFINE_IDA(scmi_bus_id);
19 static DEFINE_IDR(scmi_protocols);
20 static DEFINE_SPINLOCK(protocol_lock);
21
22 static const struct scmi_device_id *
23 scmi_dev_match_id(struct scmi_device *scmi_dev, struct scmi_driver *scmi_drv)
24 {
25         const struct scmi_device_id *id = scmi_drv->id_table;
26
27         if (!id)
28                 return NULL;
29
30         for (; id->protocol_id; id++)
31                 if (id->protocol_id == scmi_dev->protocol_id) {
32                         if (!id->name)
33                                 return id;
34                         else if (!strcmp(id->name, scmi_dev->name))
35                                 return id;
36                 }
37
38         return NULL;
39 }
40
41 static int scmi_dev_match(struct device *dev, struct device_driver *drv)
42 {
43         struct scmi_driver *scmi_drv = to_scmi_driver(drv);
44         struct scmi_device *scmi_dev = to_scmi_dev(dev);
45         const struct scmi_device_id *id;
46
47         id = scmi_dev_match_id(scmi_dev, scmi_drv);
48         if (id)
49                 return 1;
50
51         return 0;
52 }
53
54 static int scmi_protocol_init(int protocol_id, struct scmi_handle *handle)
55 {
56         scmi_prot_init_fn_t fn = idr_find(&scmi_protocols, protocol_id);
57
58         if (unlikely(!fn))
59                 return -EINVAL;
60         return fn(handle);
61 }
62
63 static int scmi_dev_probe(struct device *dev)
64 {
65         struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
66         struct scmi_device *scmi_dev = to_scmi_dev(dev);
67         const struct scmi_device_id *id;
68         int ret;
69
70         id = scmi_dev_match_id(scmi_dev, scmi_drv);
71         if (!id)
72                 return -ENODEV;
73
74         if (!scmi_dev->handle)
75                 return -EPROBE_DEFER;
76
77         ret = scmi_protocol_init(scmi_dev->protocol_id, scmi_dev->handle);
78         if (ret)
79                 return ret;
80
81         return scmi_drv->probe(scmi_dev);
82 }
83
84 static int scmi_dev_remove(struct device *dev)
85 {
86         struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
87         struct scmi_device *scmi_dev = to_scmi_dev(dev);
88
89         if (scmi_drv->remove)
90                 scmi_drv->remove(scmi_dev);
91
92         return 0;
93 }
94
95 static struct bus_type scmi_bus_type = {
96         .name = "scmi_protocol",
97         .match = scmi_dev_match,
98         .probe = scmi_dev_probe,
99         .remove = scmi_dev_remove,
100 };
101
102 int scmi_driver_register(struct scmi_driver *driver, struct module *owner,
103                          const char *mod_name)
104 {
105         int retval;
106
107         driver->driver.bus = &scmi_bus_type;
108         driver->driver.name = driver->name;
109         driver->driver.owner = owner;
110         driver->driver.mod_name = mod_name;
111
112         retval = driver_register(&driver->driver);
113         if (!retval)
114                 pr_debug("registered new scmi driver %s\n", driver->name);
115
116         return retval;
117 }
118 EXPORT_SYMBOL_GPL(scmi_driver_register);
119
120 void scmi_driver_unregister(struct scmi_driver *driver)
121 {
122         driver_unregister(&driver->driver);
123 }
124 EXPORT_SYMBOL_GPL(scmi_driver_unregister);
125
126 static void scmi_device_release(struct device *dev)
127 {
128         kfree(to_scmi_dev(dev));
129 }
130
131 struct scmi_device *
132 scmi_device_create(struct device_node *np, struct device *parent, int protocol,
133                    const char *name)
134 {
135         int id, retval;
136         struct scmi_device *scmi_dev;
137
138         scmi_dev = kzalloc(sizeof(*scmi_dev), GFP_KERNEL);
139         if (!scmi_dev)
140                 return NULL;
141
142         scmi_dev->name = kstrdup_const(name ?: "unknown", GFP_KERNEL);
143         if (!scmi_dev->name) {
144                 kfree(scmi_dev);
145                 return NULL;
146         }
147
148         id = ida_simple_get(&scmi_bus_id, 1, 0, GFP_KERNEL);
149         if (id < 0) {
150                 kfree_const(scmi_dev->name);
151                 kfree(scmi_dev);
152                 return NULL;
153         }
154
155         scmi_dev->id = id;
156         scmi_dev->protocol_id = protocol;
157         scmi_dev->dev.parent = parent;
158         scmi_dev->dev.of_node = np;
159         scmi_dev->dev.bus = &scmi_bus_type;
160         scmi_dev->dev.release = scmi_device_release;
161         dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id);
162
163         retval = device_register(&scmi_dev->dev);
164         if (retval)
165                 goto put_dev;
166
167         return scmi_dev;
168 put_dev:
169         kfree_const(scmi_dev->name);
170         put_device(&scmi_dev->dev);
171         ida_simple_remove(&scmi_bus_id, id);
172         return NULL;
173 }
174
175 void scmi_device_destroy(struct scmi_device *scmi_dev)
176 {
177         kfree_const(scmi_dev->name);
178         scmi_handle_put(scmi_dev->handle);
179         ida_simple_remove(&scmi_bus_id, scmi_dev->id);
180         device_unregister(&scmi_dev->dev);
181 }
182
183 void scmi_set_handle(struct scmi_device *scmi_dev)
184 {
185         scmi_dev->handle = scmi_handle_get(&scmi_dev->dev);
186 }
187
188 int scmi_protocol_register(int protocol_id, scmi_prot_init_fn_t fn)
189 {
190         int ret;
191
192         spin_lock(&protocol_lock);
193         ret = idr_alloc(&scmi_protocols, fn, protocol_id, protocol_id + 1,
194                         GFP_ATOMIC);
195         spin_unlock(&protocol_lock);
196         if (ret != protocol_id)
197                 pr_err("unable to allocate SCMI idr slot, err %d\n", ret);
198
199         return ret;
200 }
201 EXPORT_SYMBOL_GPL(scmi_protocol_register);
202
203 void scmi_protocol_unregister(int protocol_id)
204 {
205         spin_lock(&protocol_lock);
206         idr_remove(&scmi_protocols, protocol_id);
207         spin_unlock(&protocol_lock);
208 }
209 EXPORT_SYMBOL_GPL(scmi_protocol_unregister);
210
211 static int __scmi_devices_unregister(struct device *dev, void *data)
212 {
213         struct scmi_device *scmi_dev = to_scmi_dev(dev);
214
215         scmi_device_destroy(scmi_dev);
216         return 0;
217 }
218
219 static void scmi_devices_unregister(void)
220 {
221         bus_for_each_dev(&scmi_bus_type, NULL, NULL, __scmi_devices_unregister);
222 }
223
224 static int __init scmi_bus_init(void)
225 {
226         int retval;
227
228         retval = bus_register(&scmi_bus_type);
229         if (retval)
230                 pr_err("scmi protocol bus register failed (%d)\n", retval);
231
232         return retval;
233 }
234 subsys_initcall(scmi_bus_init);
235
236 static void __exit scmi_bus_exit(void)
237 {
238         scmi_devices_unregister();
239         bus_unregister(&scmi_bus_type);
240         ida_destroy(&scmi_bus_id);
241 }
242 module_exit(scmi_bus_exit);