forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
kernel/drivers/firmware/arm_scmi/bus.c
....@@ -16,7 +16,7 @@
1616 #include "common.h"
1717
1818 static DEFINE_IDA(scmi_bus_id);
19
-static DEFINE_IDR(scmi_protocols);
19
+static DEFINE_IDR(scmi_available_protocols);
2020 static DEFINE_SPINLOCK(protocol_lock);
2121
2222 static const struct scmi_device_id *
....@@ -51,13 +51,53 @@
5151 return 0;
5252 }
5353
54
-static int scmi_protocol_init(int protocol_id, struct scmi_handle *handle)
54
+static int scmi_match_by_id_table(struct device *dev, void *data)
5555 {
56
- scmi_prot_init_fn_t fn = idr_find(&scmi_protocols, protocol_id);
56
+ struct scmi_device *sdev = to_scmi_dev(dev);
57
+ struct scmi_device_id *id_table = data;
5758
58
- if (unlikely(!fn))
59
- return -EINVAL;
60
- return fn(handle);
59
+ return sdev->protocol_id == id_table->protocol_id &&
60
+ !strcmp(sdev->name, id_table->name);
61
+}
62
+
63
+struct scmi_device *scmi_find_child_dev(struct device *parent,
64
+ int prot_id, const char *name)
65
+{
66
+ struct scmi_device_id id_table;
67
+ struct device *dev;
68
+
69
+ id_table.protocol_id = prot_id;
70
+ id_table.name = name;
71
+
72
+ dev = device_find_child(parent, &id_table, scmi_match_by_id_table);
73
+ if (!dev)
74
+ return NULL;
75
+
76
+ return to_scmi_dev(dev);
77
+}
78
+
79
+const struct scmi_protocol *scmi_get_protocol(int protocol_id)
80
+{
81
+ const struct scmi_protocol *proto;
82
+
83
+ proto = idr_find(&scmi_available_protocols, protocol_id);
84
+ if (!proto || !try_module_get(proto->owner)) {
85
+ pr_warn("SCMI Protocol 0x%x not found!\n", protocol_id);
86
+ return NULL;
87
+ }
88
+
89
+ pr_debug("GOT SCMI Protocol 0x%x\n", protocol_id);
90
+
91
+ return proto;
92
+}
93
+
94
+void scmi_put_protocol(int protocol_id)
95
+{
96
+ const struct scmi_protocol *proto;
97
+
98
+ proto = idr_find(&scmi_available_protocols, protocol_id);
99
+ if (proto)
100
+ module_put(proto->owner);
61101 }
62102
63103 static int scmi_dev_probe(struct device *dev)
....@@ -65,7 +105,6 @@
65105 struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
66106 struct scmi_device *scmi_dev = to_scmi_dev(dev);
67107 const struct scmi_device_id *id;
68
- int ret;
69108
70109 id = scmi_dev_match_id(scmi_dev, scmi_drv);
71110 if (!id)
....@@ -73,10 +112,6 @@
73112
74113 if (!scmi_dev->handle)
75114 return -EPROBE_DEFER;
76
-
77
- ret = scmi_protocol_init(scmi_dev->protocol_id, scmi_dev->handle);
78
- if (ret)
79
- return ret;
80115
81116 return scmi_drv->probe(scmi_dev);
82117 }
....@@ -107,6 +142,10 @@
107142 if (!driver->probe)
108143 return -EINVAL;
109144
145
+ retval = scmi_request_protocol_device(driver->id_table);
146
+ if (retval)
147
+ return retval;
148
+
110149 driver->driver.bus = &scmi_bus_type;
111150 driver->driver.name = driver->name;
112151 driver->driver.owner = owner;
....@@ -123,6 +162,7 @@
123162 void scmi_driver_unregister(struct scmi_driver *driver)
124163 {
125164 driver_unregister(&driver->driver);
165
+ scmi_unrequest_protocol_device(driver->id_table);
126166 }
127167 EXPORT_SYMBOL_GPL(scmi_driver_unregister);
128168
....@@ -188,26 +228,45 @@
188228 scmi_dev->handle = scmi_handle_get(&scmi_dev->dev);
189229 }
190230
191
-int scmi_protocol_register(int protocol_id, scmi_prot_init_fn_t fn)
231
+int scmi_protocol_register(const struct scmi_protocol *proto)
192232 {
193233 int ret;
194234
195
- spin_lock(&protocol_lock);
196
- ret = idr_alloc(&scmi_protocols, fn, protocol_id, protocol_id + 1,
197
- GFP_ATOMIC);
198
- spin_unlock(&protocol_lock);
199
- if (ret != protocol_id)
200
- pr_err("unable to allocate SCMI idr slot, err %d\n", ret);
235
+ if (!proto) {
236
+ pr_err("invalid protocol\n");
237
+ return -EINVAL;
238
+ }
201239
202
- return ret;
240
+ if (!proto->init_instance) {
241
+ pr_err("missing .init() for protocol 0x%x\n", proto->id);
242
+ return -EINVAL;
243
+ }
244
+
245
+ spin_lock(&protocol_lock);
246
+ ret = idr_alloc(&scmi_available_protocols, (void *)proto,
247
+ proto->id, proto->id + 1, GFP_ATOMIC);
248
+ spin_unlock(&protocol_lock);
249
+ if (ret != proto->id) {
250
+ pr_err("unable to allocate SCMI idr slot for 0x%x - err %d\n",
251
+ proto->id, ret);
252
+ return ret;
253
+ }
254
+
255
+ pr_debug("Registered SCMI Protocol 0x%x\n", proto->id);
256
+
257
+ return 0;
203258 }
204259 EXPORT_SYMBOL_GPL(scmi_protocol_register);
205260
206
-void scmi_protocol_unregister(int protocol_id)
261
+void scmi_protocol_unregister(const struct scmi_protocol *proto)
207262 {
208263 spin_lock(&protocol_lock);
209
- idr_remove(&scmi_protocols, protocol_id);
264
+ idr_remove(&scmi_available_protocols, proto->id);
210265 spin_unlock(&protocol_lock);
266
+
267
+ pr_debug("Unregistered SCMI Protocol 0x%x\n", proto->id);
268
+
269
+ return;
211270 }
212271 EXPORT_SYMBOL_GPL(scmi_protocol_unregister);
213272