Merge tag 'tag-chrome-platform-for-v5.2' of ssh://gitolite.kernel.org/pub/scm/linux...
[linux-2.6-microblaze.git] / drivers / staging / greybus / gbphy.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Greybus Bridged-Phy Bus driver
4  *
5  * Copyright 2014 Google Inc.
6  * Copyright 2014 Linaro Ltd.
7  */
8
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10
11 #include <linux/types.h>
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/slab.h>
15 #include <linux/device.h>
16
17 #include "greybus.h"
18 #include "gbphy.h"
19
20 #define GB_GBPHY_AUTOSUSPEND_MS 3000
21
22 struct gbphy_host {
23         struct gb_bundle *bundle;
24         struct list_head devices;
25 };
26
27 static DEFINE_IDA(gbphy_id);
28
29 static ssize_t protocol_id_show(struct device *dev,
30                                  struct device_attribute *attr, char *buf)
31 {
32         struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
33
34         return sprintf(buf, "0x%02x\n", gbphy_dev->cport_desc->protocol_id);
35 }
36 static DEVICE_ATTR_RO(protocol_id);
37
38 static struct attribute *gbphy_dev_attrs[] = {
39         &dev_attr_protocol_id.attr,
40         NULL,
41 };
42
43 ATTRIBUTE_GROUPS(gbphy_dev);
44
45 static void gbphy_dev_release(struct device *dev)
46 {
47         struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
48
49         ida_simple_remove(&gbphy_id, gbphy_dev->id);
50         kfree(gbphy_dev);
51 }
52
53 #ifdef CONFIG_PM
54 static int gb_gbphy_idle(struct device *dev)
55 {
56         pm_runtime_mark_last_busy(dev);
57         pm_request_autosuspend(dev);
58         return 0;
59 }
60 #endif
61
62 static const struct dev_pm_ops gb_gbphy_pm_ops = {
63         SET_RUNTIME_PM_OPS(pm_generic_runtime_suspend,
64                            pm_generic_runtime_resume,
65                            gb_gbphy_idle)
66 };
67
68 static const struct device_type greybus_gbphy_dev_type = {
69         .name    =      "gbphy_device",
70         .release =      gbphy_dev_release,
71         .pm     =       &gb_gbphy_pm_ops,
72 };
73
74 static int gbphy_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
75 {
76         struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
77         struct greybus_descriptor_cport *cport_desc = gbphy_dev->cport_desc;
78         struct gb_bundle *bundle = gbphy_dev->bundle;
79         struct gb_interface *intf = bundle->intf;
80         struct gb_module *module = intf->module;
81         struct gb_host_device *hd = intf->hd;
82
83         if (add_uevent_var(env, "BUS=%u", hd->bus_id))
84                 return -ENOMEM;
85         if (add_uevent_var(env, "MODULE=%u", module->module_id))
86                 return -ENOMEM;
87         if (add_uevent_var(env, "INTERFACE=%u", intf->interface_id))
88                 return -ENOMEM;
89         if (add_uevent_var(env, "GREYBUS_ID=%08x/%08x",
90                            intf->vendor_id, intf->product_id))
91                 return -ENOMEM;
92         if (add_uevent_var(env, "BUNDLE=%u", gbphy_dev->bundle->id))
93                 return -ENOMEM;
94         if (add_uevent_var(env, "BUNDLE_CLASS=%02x", bundle->class))
95                 return -ENOMEM;
96         if (add_uevent_var(env, "GBPHY=%u", gbphy_dev->id))
97                 return -ENOMEM;
98         if (add_uevent_var(env, "PROTOCOL_ID=%02x", cport_desc->protocol_id))
99                 return -ENOMEM;
100
101         return 0;
102 }
103
104 static const struct gbphy_device_id *
105 gbphy_dev_match_id(struct gbphy_device *gbphy_dev,
106                    struct gbphy_driver *gbphy_drv)
107 {
108         const struct gbphy_device_id *id = gbphy_drv->id_table;
109
110         if (!id)
111                 return NULL;
112
113         for (; id->protocol_id; id++)
114                 if (id->protocol_id == gbphy_dev->cport_desc->protocol_id)
115                         return id;
116
117         return NULL;
118 }
119
120 static int gbphy_dev_match(struct device *dev, struct device_driver *drv)
121 {
122         struct gbphy_driver *gbphy_drv = to_gbphy_driver(drv);
123         struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
124         const struct gbphy_device_id *id;
125
126         id = gbphy_dev_match_id(gbphy_dev, gbphy_drv);
127         if (id)
128                 return 1;
129
130         return 0;
131 }
132
133 static int gbphy_dev_probe(struct device *dev)
134 {
135         struct gbphy_driver *gbphy_drv = to_gbphy_driver(dev->driver);
136         struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
137         const struct gbphy_device_id *id;
138         int ret;
139
140         id = gbphy_dev_match_id(gbphy_dev, gbphy_drv);
141         if (!id)
142                 return -ENODEV;
143
144         /* for old kernels we need get_sync to resume parent devices */
145         ret = gb_pm_runtime_get_sync(gbphy_dev->bundle);
146         if (ret < 0)
147                 return ret;
148
149         pm_runtime_set_autosuspend_delay(dev, GB_GBPHY_AUTOSUSPEND_MS);
150         pm_runtime_use_autosuspend(dev);
151         pm_runtime_get_noresume(dev);
152         pm_runtime_set_active(dev);
153         pm_runtime_enable(dev);
154
155         /*
156          * Drivers should call put on the gbphy dev before returning
157          * from probe if they support runtime pm.
158          */
159         ret = gbphy_drv->probe(gbphy_dev, id);
160         if (ret) {
161                 pm_runtime_disable(dev);
162                 pm_runtime_set_suspended(dev);
163                 pm_runtime_put_noidle(dev);
164                 pm_runtime_dont_use_autosuspend(dev);
165         }
166
167         gb_pm_runtime_put_autosuspend(gbphy_dev->bundle);
168
169         return ret;
170 }
171
172 static int gbphy_dev_remove(struct device *dev)
173 {
174         struct gbphy_driver *gbphy_drv = to_gbphy_driver(dev->driver);
175         struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
176
177         gbphy_drv->remove(gbphy_dev);
178
179         pm_runtime_disable(dev);
180         pm_runtime_set_suspended(dev);
181         pm_runtime_put_noidle(dev);
182         pm_runtime_dont_use_autosuspend(dev);
183
184         return 0;
185 }
186
187 static struct bus_type gbphy_bus_type = {
188         .name =         "gbphy",
189         .match =        gbphy_dev_match,
190         .probe =        gbphy_dev_probe,
191         .remove =       gbphy_dev_remove,
192         .uevent =       gbphy_dev_uevent,
193 };
194
195 int gb_gbphy_register_driver(struct gbphy_driver *driver,
196                              struct module *owner, const char *mod_name)
197 {
198         int retval;
199
200         if (greybus_disabled())
201                 return -ENODEV;
202
203         driver->driver.bus = &gbphy_bus_type;
204         driver->driver.name = driver->name;
205         driver->driver.owner = owner;
206         driver->driver.mod_name = mod_name;
207
208         retval = driver_register(&driver->driver);
209         if (retval)
210                 return retval;
211
212         pr_info("registered new driver %s\n", driver->name);
213         return 0;
214 }
215 EXPORT_SYMBOL_GPL(gb_gbphy_register_driver);
216
217 void gb_gbphy_deregister_driver(struct gbphy_driver *driver)
218 {
219         driver_unregister(&driver->driver);
220 }
221 EXPORT_SYMBOL_GPL(gb_gbphy_deregister_driver);
222
223 static struct gbphy_device *gb_gbphy_create_dev(struct gb_bundle *bundle,
224                                 struct greybus_descriptor_cport *cport_desc)
225 {
226         struct gbphy_device *gbphy_dev;
227         int retval;
228         int id;
229
230         id = ida_simple_get(&gbphy_id, 1, 0, GFP_KERNEL);
231         if (id < 0)
232                 return ERR_PTR(id);
233
234         gbphy_dev = kzalloc(sizeof(*gbphy_dev), GFP_KERNEL);
235         if (!gbphy_dev) {
236                 ida_simple_remove(&gbphy_id, id);
237                 return ERR_PTR(-ENOMEM);
238         }
239
240         gbphy_dev->id = id;
241         gbphy_dev->bundle = bundle;
242         gbphy_dev->cport_desc = cport_desc;
243         gbphy_dev->dev.parent = &bundle->dev;
244         gbphy_dev->dev.bus = &gbphy_bus_type;
245         gbphy_dev->dev.type = &greybus_gbphy_dev_type;
246         gbphy_dev->dev.groups = gbphy_dev_groups;
247         gbphy_dev->dev.dma_mask = bundle->dev.dma_mask;
248         dev_set_name(&gbphy_dev->dev, "gbphy%d", id);
249
250         retval = device_register(&gbphy_dev->dev);
251         if (retval) {
252                 put_device(&gbphy_dev->dev);
253                 return ERR_PTR(retval);
254         }
255
256         return gbphy_dev;
257 }
258
259 static void gb_gbphy_disconnect(struct gb_bundle *bundle)
260 {
261         struct gbphy_host *gbphy_host = greybus_get_drvdata(bundle);
262         struct gbphy_device *gbphy_dev, *temp;
263         int ret;
264
265         ret = gb_pm_runtime_get_sync(bundle);
266         if (ret < 0)
267                 gb_pm_runtime_get_noresume(bundle);
268
269         list_for_each_entry_safe(gbphy_dev, temp, &gbphy_host->devices, list) {
270                 list_del(&gbphy_dev->list);
271                 device_unregister(&gbphy_dev->dev);
272         }
273
274         kfree(gbphy_host);
275 }
276
277 static int gb_gbphy_probe(struct gb_bundle *bundle,
278                           const struct greybus_bundle_id *id)
279 {
280         struct gbphy_host *gbphy_host;
281         struct gbphy_device *gbphy_dev;
282         int i;
283
284         if (bundle->num_cports == 0)
285                 return -ENODEV;
286
287         gbphy_host = kzalloc(sizeof(*gbphy_host), GFP_KERNEL);
288         if (!gbphy_host)
289                 return -ENOMEM;
290
291         gbphy_host->bundle = bundle;
292         INIT_LIST_HEAD(&gbphy_host->devices);
293         greybus_set_drvdata(bundle, gbphy_host);
294
295         /*
296          * Create a bunch of children devices, one per cport, and bind the
297          * bridged phy drivers to them.
298          */
299         for (i = 0; i < bundle->num_cports; ++i) {
300                 gbphy_dev = gb_gbphy_create_dev(bundle, &bundle->cport_desc[i]);
301                 if (IS_ERR(gbphy_dev)) {
302                         gb_gbphy_disconnect(bundle);
303                         return PTR_ERR(gbphy_dev);
304                 }
305                 list_add(&gbphy_dev->list, &gbphy_host->devices);
306         }
307
308         gb_pm_runtime_put_autosuspend(bundle);
309
310         return 0;
311 }
312
313 static const struct greybus_bundle_id gb_gbphy_id_table[] = {
314         { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_BRIDGED_PHY) },
315         { },
316 };
317 MODULE_DEVICE_TABLE(greybus, gb_gbphy_id_table);
318
319 static struct greybus_driver gb_gbphy_driver = {
320         .name           = "gbphy",
321         .probe          = gb_gbphy_probe,
322         .disconnect     = gb_gbphy_disconnect,
323         .id_table       = gb_gbphy_id_table,
324 };
325
326 static int __init gbphy_init(void)
327 {
328         int retval;
329
330         retval = bus_register(&gbphy_bus_type);
331         if (retval) {
332                 pr_err("gbphy bus register failed (%d)\n", retval);
333                 return retval;
334         }
335
336         retval = greybus_register(&gb_gbphy_driver);
337         if (retval) {
338                 pr_err("error registering greybus driver\n");
339                 goto error_gbphy;
340         }
341
342         return 0;
343
344 error_gbphy:
345         bus_unregister(&gbphy_bus_type);
346         ida_destroy(&gbphy_id);
347         return retval;
348 }
349 module_init(gbphy_init);
350
351 static void __exit gbphy_exit(void)
352 {
353         greybus_deregister(&gb_gbphy_driver);
354         bus_unregister(&gbphy_bus_type);
355         ida_destroy(&gbphy_id);
356 }
357 module_exit(gbphy_exit);
358
359 MODULE_LICENSE("GPL v2");