slimbus: core: match device tree based devices correctly
[linux-2.6-block.git] / drivers / slimbus / core.c
CommitLineData
3648e78e
SD
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2011-2017, The Linux Foundation
4 */
5
6#include <linux/kernel.h>
7#include <linux/errno.h>
8#include <linux/slab.h>
9#include <linux/init.h>
46a2bb5a 10#include <linux/idr.h>
7588a511 11#include <linux/of.h>
4b14e62a 12#include <linux/pm_runtime.h>
3648e78e 13#include <linux/slimbus.h>
46a2bb5a
SD
14#include "slimbus.h"
15
16static DEFINE_IDA(ctrl_ida);
3648e78e
SD
17
18static const struct slim_device_id *slim_match(const struct slim_device_id *id,
19 const struct slim_device *sbdev)
20{
21 while (id->manf_id != 0 || id->prod_code != 0) {
22 if (id->manf_id == sbdev->e_addr.manf_id &&
23 id->prod_code == sbdev->e_addr.prod_code)
24 return id;
25 id++;
26 }
27 return NULL;
28}
29
30static int slim_device_match(struct device *dev, struct device_driver *drv)
31{
32 struct slim_device *sbdev = to_slim_device(dev);
33 struct slim_driver *sbdrv = to_slim_driver(drv);
34
14a649d3
SK
35 /* Attempt an OF style match first */
36 if (of_driver_match_device(dev, drv))
37 return 1;
38
3648e78e
SD
39 return !!slim_match(sbdrv->id_table, sbdev);
40}
41
42static int slim_device_probe(struct device *dev)
43{
44 struct slim_device *sbdev = to_slim_device(dev);
45 struct slim_driver *sbdrv = to_slim_driver(dev->driver);
46
47 return sbdrv->probe(sbdev);
48}
49
50static int slim_device_remove(struct device *dev)
51{
52 struct slim_device *sbdev = to_slim_device(dev);
53 struct slim_driver *sbdrv;
54
55 if (dev->driver) {
56 sbdrv = to_slim_driver(dev->driver);
57 if (sbdrv->remove)
58 sbdrv->remove(sbdev);
59 }
60
61 return 0;
62}
63
64struct bus_type slimbus_bus = {
65 .name = "slimbus",
66 .match = slim_device_match,
67 .probe = slim_device_probe,
68 .remove = slim_device_remove,
69};
70EXPORT_SYMBOL_GPL(slimbus_bus);
71
72/*
73 * __slim_driver_register() - Client driver registration with SLIMbus
74 *
75 * @drv:Client driver to be associated with client-device.
76 * @owner: owning module/driver
77 *
78 * This API will register the client driver with the SLIMbus
79 * It is called from the driver's module-init function.
80 */
81int __slim_driver_register(struct slim_driver *drv, struct module *owner)
82{
83 /* ID table and probe are mandatory */
14a649d3 84 if (!(drv->driver.of_match_table || drv->id_table) || !drv->probe)
3648e78e
SD
85 return -EINVAL;
86
87 drv->driver.bus = &slimbus_bus;
88 drv->driver.owner = owner;
89
90 return driver_register(&drv->driver);
91}
92EXPORT_SYMBOL_GPL(__slim_driver_register);
93
94/*
95 * slim_driver_unregister() - Undo effect of slim_driver_register
96 *
97 * @drv: Client driver to be unregistered
98 */
99void slim_driver_unregister(struct slim_driver *drv)
100{
101 driver_unregister(&drv->driver);
102}
103EXPORT_SYMBOL_GPL(slim_driver_unregister);
104
46a2bb5a
SD
105static void slim_dev_release(struct device *dev)
106{
107 struct slim_device *sbdev = to_slim_device(dev);
108
109 kfree(sbdev);
110}
111
112static int slim_add_device(struct slim_controller *ctrl,
113 struct slim_device *sbdev,
114 struct device_node *node)
115{
116 sbdev->dev.bus = &slimbus_bus;
117 sbdev->dev.parent = ctrl->dev;
118 sbdev->dev.release = slim_dev_release;
119 sbdev->dev.driver = NULL;
120 sbdev->ctrl = ctrl;
abb9c9b8
SK
121 INIT_LIST_HEAD(&sbdev->stream_list);
122 spin_lock_init(&sbdev->stream_list_lock);
46a2bb5a 123
7588a511
SK
124 if (node)
125 sbdev->dev.of_node = of_node_get(node);
126
46a2bb5a
SD
127 dev_set_name(&sbdev->dev, "%x:%x:%x:%x",
128 sbdev->e_addr.manf_id,
129 sbdev->e_addr.prod_code,
130 sbdev->e_addr.dev_index,
131 sbdev->e_addr.instance);
132
133 return device_register(&sbdev->dev);
134}
135
136static struct slim_device *slim_alloc_device(struct slim_controller *ctrl,
137 struct slim_eaddr *eaddr,
138 struct device_node *node)
139{
140 struct slim_device *sbdev;
141 int ret;
142
143 sbdev = kzalloc(sizeof(*sbdev), GFP_KERNEL);
144 if (!sbdev)
145 return NULL;
146
147 sbdev->e_addr = *eaddr;
148 ret = slim_add_device(ctrl, sbdev, node);
149 if (ret) {
bd329f02 150 put_device(&sbdev->dev);
46a2bb5a
SD
151 return NULL;
152 }
153
154 return sbdev;
155}
156
7588a511
SK
157static void of_register_slim_devices(struct slim_controller *ctrl)
158{
159 struct device *dev = ctrl->dev;
160 struct device_node *node;
161
162 if (!ctrl->dev->of_node)
163 return;
164
165 for_each_child_of_node(ctrl->dev->of_node, node) {
166 struct slim_device *sbdev;
167 struct slim_eaddr e_addr;
168 const char *compat = NULL;
169 int reg[2], ret;
170 int manf_id, prod_code;
171
172 compat = of_get_property(node, "compatible", NULL);
173 if (!compat)
174 continue;
175
176 ret = sscanf(compat, "slim%x,%x", &manf_id, &prod_code);
177 if (ret != 2) {
178 dev_err(dev, "Manf ID & Product code not found %s\n",
179 compat);
180 continue;
181 }
182
183 ret = of_property_read_u32_array(node, "reg", reg, 2);
184 if (ret) {
185 dev_err(dev, "Device and Instance id not found:%d\n",
186 ret);
187 continue;
188 }
189
190 e_addr.dev_index = reg[0];
191 e_addr.instance = reg[1];
192 e_addr.manf_id = manf_id;
193 e_addr.prod_code = prod_code;
194
195 sbdev = slim_alloc_device(ctrl, &e_addr, node);
196 if (!sbdev)
197 continue;
198 }
199}
200
46a2bb5a
SD
201/*
202 * slim_register_controller() - Controller bring-up and registration.
203 *
204 * @ctrl: Controller to be registered.
205 *
206 * A controller is registered with the framework using this API.
207 * If devices on a controller were registered before controller,
208 * this will make sure that they get probed when controller is up
209 */
210int slim_register_controller(struct slim_controller *ctrl)
211{
212 int id;
213
214 id = ida_simple_get(&ctrl_ida, 0, 0, GFP_KERNEL);
215 if (id < 0)
216 return id;
217
218 ctrl->id = id;
219
220 if (!ctrl->min_cg)
221 ctrl->min_cg = SLIM_MIN_CLK_GEAR;
222 if (!ctrl->max_cg)
223 ctrl->max_cg = SLIM_MAX_CLK_GEAR;
224
225 ida_init(&ctrl->laddr_ida);
226 idr_init(&ctrl->tid_idr);
227 mutex_init(&ctrl->lock);
4b14e62a
SD
228 mutex_init(&ctrl->sched.m_reconf);
229 init_completion(&ctrl->sched.pause_comp);
46a2bb5a
SD
230
231 dev_dbg(ctrl->dev, "Bus [%s] registered:dev:%p\n",
232 ctrl->name, ctrl->dev);
233
7588a511
SK
234 of_register_slim_devices(ctrl);
235
46a2bb5a
SD
236 return 0;
237}
238EXPORT_SYMBOL_GPL(slim_register_controller);
239
240/* slim_remove_device: Remove the effect of slim_add_device() */
241static void slim_remove_device(struct slim_device *sbdev)
242{
243 device_unregister(&sbdev->dev);
244}
245
246static int slim_ctrl_remove_device(struct device *dev, void *null)
247{
248 slim_remove_device(to_slim_device(dev));
249 return 0;
250}
251
252/**
253 * slim_unregister_controller() - Controller tear-down.
254 *
255 * @ctrl: Controller to tear-down.
256 */
257int slim_unregister_controller(struct slim_controller *ctrl)
258{
259 /* Remove all clients */
260 device_for_each_child(ctrl->dev, NULL, slim_ctrl_remove_device);
4b14e62a
SD
261 /* Enter Clock Pause */
262 slim_ctrl_clk_pause(ctrl, false, 0);
46a2bb5a
SD
263 ida_simple_remove(&ctrl_ida, ctrl->id);
264
265 return 0;
266}
267EXPORT_SYMBOL_GPL(slim_unregister_controller);
268
269static void slim_device_update_status(struct slim_device *sbdev,
270 enum slim_device_status status)
271{
272 struct slim_driver *sbdrv;
273
274 if (sbdev->status == status)
275 return;
276
277 sbdev->status = status;
278 if (!sbdev->dev.driver)
279 return;
280
281 sbdrv = to_slim_driver(sbdev->dev.driver);
282 if (sbdrv->device_status)
283 sbdrv->device_status(sbdev, sbdev->status);
284}
285
286/**
287 * slim_report_absent() - Controller calls this function when a device
288 * reports absent, OR when the device cannot be communicated with
289 *
290 * @sbdev: Device that cannot be reached, or sent report absent
291 */
292void slim_report_absent(struct slim_device *sbdev)
293{
294 struct slim_controller *ctrl = sbdev->ctrl;
295
296 if (!ctrl)
297 return;
298
299 /* invalidate logical addresses */
300 mutex_lock(&ctrl->lock);
301 sbdev->is_laddr_valid = false;
302 mutex_unlock(&ctrl->lock);
303
304 ida_simple_remove(&ctrl->laddr_ida, sbdev->laddr);
305 slim_device_update_status(sbdev, SLIM_DEVICE_STATUS_DOWN);
306}
307EXPORT_SYMBOL_GPL(slim_report_absent);
308
309static bool slim_eaddr_equal(struct slim_eaddr *a, struct slim_eaddr *b)
310{
311 return (a->manf_id == b->manf_id &&
312 a->prod_code == b->prod_code &&
313 a->dev_index == b->dev_index &&
314 a->instance == b->instance);
315}
316
317static int slim_match_dev(struct device *dev, void *data)
318{
319 struct slim_eaddr *e_addr = data;
320 struct slim_device *sbdev = to_slim_device(dev);
321
322 return slim_eaddr_equal(&sbdev->e_addr, e_addr);
323}
324
325static struct slim_device *find_slim_device(struct slim_controller *ctrl,
326 struct slim_eaddr *eaddr)
327{
328 struct slim_device *sbdev;
329 struct device *dev;
330
331 dev = device_find_child(ctrl->dev, eaddr, slim_match_dev);
332 if (dev) {
333 sbdev = to_slim_device(dev);
334 return sbdev;
335 }
336
337 return NULL;
338}
339
340/**
341 * slim_get_device() - get handle to a device.
342 *
343 * @ctrl: Controller on which this device will be added/queried
344 * @e_addr: Enumeration address of the device to be queried
345 *
346 * Return: pointer to a device if it has already reported. Creates a new
347 * device and returns pointer to it if the device has not yet enumerated.
348 */
349struct slim_device *slim_get_device(struct slim_controller *ctrl,
350 struct slim_eaddr *e_addr)
351{
352 struct slim_device *sbdev;
353
354 sbdev = find_slim_device(ctrl, e_addr);
355 if (!sbdev) {
356 sbdev = slim_alloc_device(ctrl, e_addr, NULL);
357 if (!sbdev)
358 return ERR_PTR(-ENOMEM);
359 }
360
361 return sbdev;
362}
363EXPORT_SYMBOL_GPL(slim_get_device);
364
e0772de8
SK
365static int of_slim_match_dev(struct device *dev, void *data)
366{
367 struct device_node *np = data;
368 struct slim_device *sbdev = to_slim_device(dev);
369
370 return (sbdev->dev.of_node == np);
371}
372
373static struct slim_device *of_find_slim_device(struct slim_controller *ctrl,
374 struct device_node *np)
375{
376 struct slim_device *sbdev;
377 struct device *dev;
378
379 dev = device_find_child(ctrl->dev, np, of_slim_match_dev);
380 if (dev) {
381 sbdev = to_slim_device(dev);
382 return sbdev;
383 }
384
385 return NULL;
386}
387
388/**
389 * of_slim_get_device() - get handle to a device using dt node.
390 *
391 * @ctrl: Controller on which this device will be added/queried
392 * @np: node pointer to device
393 *
394 * Return: pointer to a device if it has already reported. Creates a new
395 * device and returns pointer to it if the device has not yet enumerated.
396 */
397struct slim_device *of_slim_get_device(struct slim_controller *ctrl,
398 struct device_node *np)
399{
400 return of_find_slim_device(ctrl, np);
401}
402EXPORT_SYMBOL_GPL(of_slim_get_device);
403
46a2bb5a
SD
404static int slim_device_alloc_laddr(struct slim_device *sbdev,
405 bool report_present)
406{
407 struct slim_controller *ctrl = sbdev->ctrl;
408 u8 laddr;
409 int ret;
410
411 mutex_lock(&ctrl->lock);
412 if (ctrl->get_laddr) {
413 ret = ctrl->get_laddr(ctrl, &sbdev->e_addr, &laddr);
414 if (ret < 0)
415 goto err;
416 } else if (report_present) {
417 ret = ida_simple_get(&ctrl->laddr_ida,
418 0, SLIM_LA_MANAGER - 1, GFP_KERNEL);
419 if (ret < 0)
420 goto err;
421
422 laddr = ret;
423 } else {
424 ret = -EINVAL;
425 goto err;
426 }
427
428 if (ctrl->set_laddr) {
429 ret = ctrl->set_laddr(ctrl, &sbdev->e_addr, laddr);
430 if (ret) {
431 ret = -EINVAL;
432 goto err;
433 }
434 }
435
436 sbdev->laddr = laddr;
437 sbdev->is_laddr_valid = true;
438
439 slim_device_update_status(sbdev, SLIM_DEVICE_STATUS_UP);
440
441 dev_dbg(ctrl->dev, "setting slimbus l-addr:%x, ea:%x,%x,%x,%x\n",
442 laddr, sbdev->e_addr.manf_id, sbdev->e_addr.prod_code,
443 sbdev->e_addr.dev_index, sbdev->e_addr.instance);
444
445err:
446 mutex_unlock(&ctrl->lock);
447 return ret;
448
449}
450
451/**
452 * slim_device_report_present() - Report enumerated device.
453 *
454 * @ctrl: Controller with which device is enumerated.
455 * @e_addr: Enumeration address of the device.
456 * @laddr: Return logical address (if valid flag is false)
457 *
458 * Called by controller in response to REPORT_PRESENT. Framework will assign
459 * a logical address to this enumeration address.
460 * Function returns -EXFULL to indicate that all logical addresses are already
461 * taken.
462 */
463int slim_device_report_present(struct slim_controller *ctrl,
464 struct slim_eaddr *e_addr, u8 *laddr)
465{
466 struct slim_device *sbdev;
467 int ret;
468
4b14e62a
SD
469 ret = pm_runtime_get_sync(ctrl->dev);
470
471 if (ctrl->sched.clk_state != SLIM_CLK_ACTIVE) {
472 dev_err(ctrl->dev, "slim ctrl not active,state:%d, ret:%d\n",
473 ctrl->sched.clk_state, ret);
474 goto slimbus_not_active;
475 }
476
46a2bb5a
SD
477 sbdev = slim_get_device(ctrl, e_addr);
478 if (IS_ERR(sbdev))
479 return -ENODEV;
480
481 if (sbdev->is_laddr_valid) {
482 *laddr = sbdev->laddr;
483 return 0;
484 }
485
486 ret = slim_device_alloc_laddr(sbdev, true);
487
4b14e62a
SD
488slimbus_not_active:
489 pm_runtime_mark_last_busy(ctrl->dev);
490 pm_runtime_put_autosuspend(ctrl->dev);
46a2bb5a
SD
491 return ret;
492}
493EXPORT_SYMBOL_GPL(slim_device_report_present);
494
495/**
496 * slim_get_logical_addr() - get/allocate logical address of a SLIMbus device.
497 *
498 * @sbdev: client handle requesting the address.
499 *
500 * Return: zero if a logical address is valid or a new logical address
501 * has been assigned. error code in case of error.
502 */
503int slim_get_logical_addr(struct slim_device *sbdev)
504{
505 if (!sbdev->is_laddr_valid)
506 return slim_device_alloc_laddr(sbdev, false);
507
508 return 0;
509}
510EXPORT_SYMBOL_GPL(slim_get_logical_addr);
511
3648e78e
SD
512static void __exit slimbus_exit(void)
513{
514 bus_unregister(&slimbus_bus);
515}
516module_exit(slimbus_exit);
517
518static int __init slimbus_init(void)
519{
520 return bus_register(&slimbus_bus);
521}
522postcore_initcall(slimbus_init);
523
524MODULE_LICENSE("GPL v2");
525MODULE_DESCRIPTION("SLIMbus core");