xref: /openbmc/linux/drivers/staging/greybus/gbphy.c (revision 2a81ada3)
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 #include <linux/greybus.h>
17 
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 
protocol_id_show(struct device * dev,struct device_attribute * attr,char * buf)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 
gbphy_dev_release(struct device * dev)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
gb_gbphy_idle(struct device * dev)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 
gbphy_dev_uevent(const struct device * dev,struct kobj_uevent_env * env)74 static int gbphy_dev_uevent(const struct device *dev, struct kobj_uevent_env *env)
75 {
76 	const struct gbphy_device *gbphy_dev = to_gbphy_dev(dev);
77 	const struct greybus_descriptor_cport *cport_desc = gbphy_dev->cport_desc;
78 	const struct gb_bundle *bundle = gbphy_dev->bundle;
79 	const struct gb_interface *intf = bundle->intf;
80 	const struct gb_module *module = intf->module;
81 	const 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 *
gbphy_dev_match_id(struct gbphy_device * gbphy_dev,struct gbphy_driver * gbphy_drv)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 
gbphy_dev_match(struct device * dev,struct device_driver * drv)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 
gbphy_dev_probe(struct device * dev)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 
gbphy_dev_remove(struct device * dev)172 static void 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 
185 static struct bus_type gbphy_bus_type = {
186 	.name =		"gbphy",
187 	.match =	gbphy_dev_match,
188 	.probe =	gbphy_dev_probe,
189 	.remove =	gbphy_dev_remove,
190 	.uevent =	gbphy_dev_uevent,
191 };
192 
gb_gbphy_register_driver(struct gbphy_driver * driver,struct module * owner,const char * mod_name)193 int gb_gbphy_register_driver(struct gbphy_driver *driver,
194 			     struct module *owner, const char *mod_name)
195 {
196 	int retval;
197 
198 	if (greybus_disabled())
199 		return -ENODEV;
200 
201 	driver->driver.bus = &gbphy_bus_type;
202 	driver->driver.name = driver->name;
203 	driver->driver.owner = owner;
204 	driver->driver.mod_name = mod_name;
205 
206 	retval = driver_register(&driver->driver);
207 	if (retval)
208 		return retval;
209 
210 	pr_info("registered new driver %s\n", driver->name);
211 	return 0;
212 }
213 EXPORT_SYMBOL_GPL(gb_gbphy_register_driver);
214 
gb_gbphy_deregister_driver(struct gbphy_driver * driver)215 void gb_gbphy_deregister_driver(struct gbphy_driver *driver)
216 {
217 	driver_unregister(&driver->driver);
218 }
219 EXPORT_SYMBOL_GPL(gb_gbphy_deregister_driver);
220 
gb_gbphy_create_dev(struct gb_bundle * bundle,struct greybus_descriptor_cport * cport_desc)221 static struct gbphy_device *gb_gbphy_create_dev(struct gb_bundle *bundle,
222 						struct greybus_descriptor_cport *cport_desc)
223 {
224 	struct gbphy_device *gbphy_dev;
225 	int retval;
226 	int id;
227 
228 	id = ida_simple_get(&gbphy_id, 1, 0, GFP_KERNEL);
229 	if (id < 0)
230 		return ERR_PTR(id);
231 
232 	gbphy_dev = kzalloc(sizeof(*gbphy_dev), GFP_KERNEL);
233 	if (!gbphy_dev) {
234 		ida_simple_remove(&gbphy_id, id);
235 		return ERR_PTR(-ENOMEM);
236 	}
237 
238 	gbphy_dev->id = id;
239 	gbphy_dev->bundle = bundle;
240 	gbphy_dev->cport_desc = cport_desc;
241 	gbphy_dev->dev.parent = &bundle->dev;
242 	gbphy_dev->dev.bus = &gbphy_bus_type;
243 	gbphy_dev->dev.type = &greybus_gbphy_dev_type;
244 	gbphy_dev->dev.groups = gbphy_dev_groups;
245 	gbphy_dev->dev.dma_mask = bundle->dev.dma_mask;
246 	dev_set_name(&gbphy_dev->dev, "gbphy%d", id);
247 
248 	retval = device_register(&gbphy_dev->dev);
249 	if (retval) {
250 		put_device(&gbphy_dev->dev);
251 		return ERR_PTR(retval);
252 	}
253 
254 	return gbphy_dev;
255 }
256 
gb_gbphy_disconnect(struct gb_bundle * bundle)257 static void gb_gbphy_disconnect(struct gb_bundle *bundle)
258 {
259 	struct gbphy_host *gbphy_host = greybus_get_drvdata(bundle);
260 	struct gbphy_device *gbphy_dev, *temp;
261 	int ret;
262 
263 	ret = gb_pm_runtime_get_sync(bundle);
264 	if (ret < 0)
265 		gb_pm_runtime_get_noresume(bundle);
266 
267 	list_for_each_entry_safe(gbphy_dev, temp, &gbphy_host->devices, list) {
268 		list_del(&gbphy_dev->list);
269 		device_unregister(&gbphy_dev->dev);
270 	}
271 
272 	kfree(gbphy_host);
273 }
274 
gb_gbphy_probe(struct gb_bundle * bundle,const struct greybus_bundle_id * id)275 static int gb_gbphy_probe(struct gb_bundle *bundle,
276 			  const struct greybus_bundle_id *id)
277 {
278 	struct gbphy_host *gbphy_host;
279 	struct gbphy_device *gbphy_dev;
280 	int i;
281 
282 	if (bundle->num_cports == 0)
283 		return -ENODEV;
284 
285 	gbphy_host = kzalloc(sizeof(*gbphy_host), GFP_KERNEL);
286 	if (!gbphy_host)
287 		return -ENOMEM;
288 
289 	gbphy_host->bundle = bundle;
290 	INIT_LIST_HEAD(&gbphy_host->devices);
291 	greybus_set_drvdata(bundle, gbphy_host);
292 
293 	/*
294 	 * Create a bunch of children devices, one per cport, and bind the
295 	 * bridged phy drivers to them.
296 	 */
297 	for (i = 0; i < bundle->num_cports; ++i) {
298 		gbphy_dev = gb_gbphy_create_dev(bundle, &bundle->cport_desc[i]);
299 		if (IS_ERR(gbphy_dev)) {
300 			gb_gbphy_disconnect(bundle);
301 			return PTR_ERR(gbphy_dev);
302 		}
303 		list_add(&gbphy_dev->list, &gbphy_host->devices);
304 	}
305 
306 	gb_pm_runtime_put_autosuspend(bundle);
307 
308 	return 0;
309 }
310 
311 static const struct greybus_bundle_id gb_gbphy_id_table[] = {
312 	{ GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_BRIDGED_PHY) },
313 	{ },
314 };
315 MODULE_DEVICE_TABLE(greybus, gb_gbphy_id_table);
316 
317 static struct greybus_driver gb_gbphy_driver = {
318 	.name		= "gbphy",
319 	.probe		= gb_gbphy_probe,
320 	.disconnect	= gb_gbphy_disconnect,
321 	.id_table	= gb_gbphy_id_table,
322 };
323 
gbphy_init(void)324 static int __init gbphy_init(void)
325 {
326 	int retval;
327 
328 	retval = bus_register(&gbphy_bus_type);
329 	if (retval) {
330 		pr_err("gbphy bus register failed (%d)\n", retval);
331 		return retval;
332 	}
333 
334 	retval = greybus_register(&gb_gbphy_driver);
335 	if (retval) {
336 		pr_err("error registering greybus driver\n");
337 		goto error_gbphy;
338 	}
339 
340 	return 0;
341 
342 error_gbphy:
343 	bus_unregister(&gbphy_bus_type);
344 	ida_destroy(&gbphy_id);
345 	return retval;
346 }
347 module_init(gbphy_init);
348 
gbphy_exit(void)349 static void __exit gbphy_exit(void)
350 {
351 	greybus_deregister(&gb_gbphy_driver);
352 	bus_unregister(&gbphy_bus_type);
353 	ida_destroy(&gbphy_id);
354 }
355 module_exit(gbphy_exit);
356 
357 MODULE_LICENSE("GPL v2");
358