blob: 02f5075a9309dd8ee55908486f023e4fad2789db [file] [log] [blame]
Sagar Dharia3648e782017-12-11 23:42:57 +00001// 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>
10#include <linux/slimbus.h>
11
12static const struct slim_device_id *slim_match(const struct slim_device_id *id,
13 const struct slim_device *sbdev)
14{
15 while (id->manf_id != 0 || id->prod_code != 0) {
16 if (id->manf_id == sbdev->e_addr.manf_id &&
17 id->prod_code == sbdev->e_addr.prod_code)
18 return id;
19 id++;
20 }
21 return NULL;
22}
23
24static int slim_device_match(struct device *dev, struct device_driver *drv)
25{
26 struct slim_device *sbdev = to_slim_device(dev);
27 struct slim_driver *sbdrv = to_slim_driver(drv);
28
29 return !!slim_match(sbdrv->id_table, sbdev);
30}
31
32static int slim_device_probe(struct device *dev)
33{
34 struct slim_device *sbdev = to_slim_device(dev);
35 struct slim_driver *sbdrv = to_slim_driver(dev->driver);
36
37 return sbdrv->probe(sbdev);
38}
39
40static int slim_device_remove(struct device *dev)
41{
42 struct slim_device *sbdev = to_slim_device(dev);
43 struct slim_driver *sbdrv;
44
45 if (dev->driver) {
46 sbdrv = to_slim_driver(dev->driver);
47 if (sbdrv->remove)
48 sbdrv->remove(sbdev);
49 }
50
51 return 0;
52}
53
54struct bus_type slimbus_bus = {
55 .name = "slimbus",
56 .match = slim_device_match,
57 .probe = slim_device_probe,
58 .remove = slim_device_remove,
59};
60EXPORT_SYMBOL_GPL(slimbus_bus);
61
62/*
63 * __slim_driver_register() - Client driver registration with SLIMbus
64 *
65 * @drv:Client driver to be associated with client-device.
66 * @owner: owning module/driver
67 *
68 * This API will register the client driver with the SLIMbus
69 * It is called from the driver's module-init function.
70 */
71int __slim_driver_register(struct slim_driver *drv, struct module *owner)
72{
73 /* ID table and probe are mandatory */
74 if (!drv->id_table || !drv->probe)
75 return -EINVAL;
76
77 drv->driver.bus = &slimbus_bus;
78 drv->driver.owner = owner;
79
80 return driver_register(&drv->driver);
81}
82EXPORT_SYMBOL_GPL(__slim_driver_register);
83
84/*
85 * slim_driver_unregister() - Undo effect of slim_driver_register
86 *
87 * @drv: Client driver to be unregistered
88 */
89void slim_driver_unregister(struct slim_driver *drv)
90{
91 driver_unregister(&drv->driver);
92}
93EXPORT_SYMBOL_GPL(slim_driver_unregister);
94
95static void __exit slimbus_exit(void)
96{
97 bus_unregister(&slimbus_bus);
98}
99module_exit(slimbus_exit);
100
101static int __init slimbus_init(void)
102{
103 return bus_register(&slimbus_bus);
104}
105postcore_initcall(slimbus_init);
106
107MODULE_LICENSE("GPL v2");
108MODULE_DESCRIPTION("SLIMbus core");