xref: /openbmc/linux/drivers/slimbus/core.c (revision 3648e78e)
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>
10 #include <linux/slimbus.h>
11 
12 static 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 
24 static 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 
32 static 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 
40 static 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 
54 struct bus_type slimbus_bus = {
55 	.name		= "slimbus",
56 	.match		= slim_device_match,
57 	.probe		= slim_device_probe,
58 	.remove		= slim_device_remove,
59 };
60 EXPORT_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  */
71 int __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 }
82 EXPORT_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  */
89 void slim_driver_unregister(struct slim_driver *drv)
90 {
91 	driver_unregister(&drv->driver);
92 }
93 EXPORT_SYMBOL_GPL(slim_driver_unregister);
94 
95 static void __exit slimbus_exit(void)
96 {
97 	bus_unregister(&slimbus_bus);
98 }
99 module_exit(slimbus_exit);
100 
101 static int __init slimbus_init(void)
102 {
103 	return bus_register(&slimbus_bus);
104 }
105 postcore_initcall(slimbus_init);
106 
107 MODULE_LICENSE("GPL v2");
108 MODULE_DESCRIPTION("SLIMbus core");
109