xref: /openbmc/linux/drivers/gpu/host1x/bus.c (revision 0edbfea5)
1 /*
2  * Copyright (C) 2012 Avionic Design GmbH
3  * Copyright (C) 2012-2013, NVIDIA Corporation
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms and conditions of the GNU General Public License,
7  * version 2, as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <linux/host1x.h>
19 #include <linux/of.h>
20 #include <linux/slab.h>
21 #include <linux/of_device.h>
22 
23 #include "bus.h"
24 #include "dev.h"
25 
26 static DEFINE_MUTEX(clients_lock);
27 static LIST_HEAD(clients);
28 
29 static DEFINE_MUTEX(drivers_lock);
30 static LIST_HEAD(drivers);
31 
32 static DEFINE_MUTEX(devices_lock);
33 static LIST_HEAD(devices);
34 
35 struct host1x_subdev {
36 	struct host1x_client *client;
37 	struct device_node *np;
38 	struct list_head list;
39 };
40 
41 /**
42  * host1x_subdev_add() - add a new subdevice with an associated device node
43  */
44 static int host1x_subdev_add(struct host1x_device *device,
45 			     struct device_node *np)
46 {
47 	struct host1x_subdev *subdev;
48 
49 	subdev = kzalloc(sizeof(*subdev), GFP_KERNEL);
50 	if (!subdev)
51 		return -ENOMEM;
52 
53 	INIT_LIST_HEAD(&subdev->list);
54 	subdev->np = of_node_get(np);
55 
56 	mutex_lock(&device->subdevs_lock);
57 	list_add_tail(&subdev->list, &device->subdevs);
58 	mutex_unlock(&device->subdevs_lock);
59 
60 	return 0;
61 }
62 
63 /**
64  * host1x_subdev_del() - remove subdevice
65  */
66 static void host1x_subdev_del(struct host1x_subdev *subdev)
67 {
68 	list_del(&subdev->list);
69 	of_node_put(subdev->np);
70 	kfree(subdev);
71 }
72 
73 /**
74  * host1x_device_parse_dt() - scan device tree and add matching subdevices
75  */
76 static int host1x_device_parse_dt(struct host1x_device *device,
77 				  struct host1x_driver *driver)
78 {
79 	struct device_node *np;
80 	int err;
81 
82 	for_each_child_of_node(device->dev.parent->of_node, np) {
83 		if (of_match_node(driver->subdevs, np) &&
84 		    of_device_is_available(np)) {
85 			err = host1x_subdev_add(device, np);
86 			if (err < 0) {
87 				of_node_put(np);
88 				return err;
89 			}
90 		}
91 	}
92 
93 	return 0;
94 }
95 
96 static void host1x_subdev_register(struct host1x_device *device,
97 				   struct host1x_subdev *subdev,
98 				   struct host1x_client *client)
99 {
100 	int err;
101 
102 	/*
103 	 * Move the subdevice to the list of active (registered) subdevices
104 	 * and associate it with a client. At the same time, associate the
105 	 * client with its parent device.
106 	 */
107 	mutex_lock(&device->subdevs_lock);
108 	mutex_lock(&device->clients_lock);
109 	list_move_tail(&client->list, &device->clients);
110 	list_move_tail(&subdev->list, &device->active);
111 	client->parent = &device->dev;
112 	subdev->client = client;
113 	mutex_unlock(&device->clients_lock);
114 	mutex_unlock(&device->subdevs_lock);
115 
116 	if (list_empty(&device->subdevs)) {
117 		err = device_add(&device->dev);
118 		if (err < 0)
119 			dev_err(&device->dev, "failed to add: %d\n", err);
120 		else
121 			device->registered = true;
122 	}
123 }
124 
125 static void __host1x_subdev_unregister(struct host1x_device *device,
126 				       struct host1x_subdev *subdev)
127 {
128 	struct host1x_client *client = subdev->client;
129 
130 	/*
131 	 * If all subdevices have been activated, we're about to remove the
132 	 * first active subdevice, so unload the driver first.
133 	 */
134 	if (list_empty(&device->subdevs)) {
135 		if (device->registered) {
136 			device->registered = false;
137 			device_del(&device->dev);
138 		}
139 	}
140 
141 	/*
142 	 * Move the subdevice back to the list of idle subdevices and remove
143 	 * it from list of clients.
144 	 */
145 	mutex_lock(&device->clients_lock);
146 	subdev->client = NULL;
147 	client->parent = NULL;
148 	list_move_tail(&subdev->list, &device->subdevs);
149 	/*
150 	 * XXX: Perhaps don't do this here, but rather explicitly remove it
151 	 * when the device is about to be deleted.
152 	 *
153 	 * This is somewhat complicated by the fact that this function is
154 	 * used to remove the subdevice when a client is unregistered but
155 	 * also when the composite device is about to be removed.
156 	 */
157 	list_del_init(&client->list);
158 	mutex_unlock(&device->clients_lock);
159 }
160 
161 static void host1x_subdev_unregister(struct host1x_device *device,
162 				     struct host1x_subdev *subdev)
163 {
164 	mutex_lock(&device->subdevs_lock);
165 	__host1x_subdev_unregister(device, subdev);
166 	mutex_unlock(&device->subdevs_lock);
167 }
168 
169 int host1x_device_init(struct host1x_device *device)
170 {
171 	struct host1x_client *client;
172 	int err;
173 
174 	mutex_lock(&device->clients_lock);
175 
176 	list_for_each_entry(client, &device->clients, list) {
177 		if (client->ops && client->ops->init) {
178 			err = client->ops->init(client);
179 			if (err < 0) {
180 				dev_err(&device->dev,
181 					"failed to initialize %s: %d\n",
182 					dev_name(client->dev), err);
183 				mutex_unlock(&device->clients_lock);
184 				return err;
185 			}
186 		}
187 	}
188 
189 	mutex_unlock(&device->clients_lock);
190 
191 	return 0;
192 }
193 EXPORT_SYMBOL(host1x_device_init);
194 
195 int host1x_device_exit(struct host1x_device *device)
196 {
197 	struct host1x_client *client;
198 	int err;
199 
200 	mutex_lock(&device->clients_lock);
201 
202 	list_for_each_entry_reverse(client, &device->clients, list) {
203 		if (client->ops && client->ops->exit) {
204 			err = client->ops->exit(client);
205 			if (err < 0) {
206 				dev_err(&device->dev,
207 					"failed to cleanup %s: %d\n",
208 					dev_name(client->dev), err);
209 				mutex_unlock(&device->clients_lock);
210 				return err;
211 			}
212 		}
213 	}
214 
215 	mutex_unlock(&device->clients_lock);
216 
217 	return 0;
218 }
219 EXPORT_SYMBOL(host1x_device_exit);
220 
221 static int host1x_add_client(struct host1x *host1x,
222 			     struct host1x_client *client)
223 {
224 	struct host1x_device *device;
225 	struct host1x_subdev *subdev;
226 
227 	mutex_lock(&host1x->devices_lock);
228 
229 	list_for_each_entry(device, &host1x->devices, list) {
230 		list_for_each_entry(subdev, &device->subdevs, list) {
231 			if (subdev->np == client->dev->of_node) {
232 				host1x_subdev_register(device, subdev, client);
233 				mutex_unlock(&host1x->devices_lock);
234 				return 0;
235 			}
236 		}
237 	}
238 
239 	mutex_unlock(&host1x->devices_lock);
240 	return -ENODEV;
241 }
242 
243 static int host1x_del_client(struct host1x *host1x,
244 			     struct host1x_client *client)
245 {
246 	struct host1x_device *device, *dt;
247 	struct host1x_subdev *subdev;
248 
249 	mutex_lock(&host1x->devices_lock);
250 
251 	list_for_each_entry_safe(device, dt, &host1x->devices, list) {
252 		list_for_each_entry(subdev, &device->active, list) {
253 			if (subdev->client == client) {
254 				host1x_subdev_unregister(device, subdev);
255 				mutex_unlock(&host1x->devices_lock);
256 				return 0;
257 			}
258 		}
259 	}
260 
261 	mutex_unlock(&host1x->devices_lock);
262 	return -ENODEV;
263 }
264 
265 static int host1x_device_match(struct device *dev, struct device_driver *drv)
266 {
267 	return strcmp(dev_name(dev), drv->name) == 0;
268 }
269 
270 static int host1x_device_probe(struct device *dev)
271 {
272 	struct host1x_driver *driver = to_host1x_driver(dev->driver);
273 	struct host1x_device *device = to_host1x_device(dev);
274 
275 	if (driver->probe)
276 		return driver->probe(device);
277 
278 	return 0;
279 }
280 
281 static int host1x_device_remove(struct device *dev)
282 {
283 	struct host1x_driver *driver = to_host1x_driver(dev->driver);
284 	struct host1x_device *device = to_host1x_device(dev);
285 
286 	if (driver->remove)
287 		return driver->remove(device);
288 
289 	return 0;
290 }
291 
292 static void host1x_device_shutdown(struct device *dev)
293 {
294 	struct host1x_driver *driver = to_host1x_driver(dev->driver);
295 	struct host1x_device *device = to_host1x_device(dev);
296 
297 	if (driver->shutdown)
298 		driver->shutdown(device);
299 }
300 
301 static const struct dev_pm_ops host1x_device_pm_ops = {
302 	.suspend = pm_generic_suspend,
303 	.resume = pm_generic_resume,
304 	.freeze = pm_generic_freeze,
305 	.thaw = pm_generic_thaw,
306 	.poweroff = pm_generic_poweroff,
307 	.restore = pm_generic_restore,
308 };
309 
310 struct bus_type host1x_bus_type = {
311 	.name = "host1x",
312 	.match = host1x_device_match,
313 	.probe = host1x_device_probe,
314 	.remove = host1x_device_remove,
315 	.shutdown = host1x_device_shutdown,
316 	.pm = &host1x_device_pm_ops,
317 };
318 
319 static void __host1x_device_del(struct host1x_device *device)
320 {
321 	struct host1x_subdev *subdev, *sd;
322 	struct host1x_client *client, *cl;
323 
324 	mutex_lock(&device->subdevs_lock);
325 
326 	/* unregister subdevices */
327 	list_for_each_entry_safe(subdev, sd, &device->active, list) {
328 		/*
329 		 * host1x_subdev_unregister() will remove the client from
330 		 * any lists, so we'll need to manually add it back to the
331 		 * list of idle clients.
332 		 *
333 		 * XXX: Alternatively, perhaps don't remove the client from
334 		 * any lists in host1x_subdev_unregister() and instead do
335 		 * that explicitly from host1x_unregister_client()?
336 		 */
337 		client = subdev->client;
338 
339 		__host1x_subdev_unregister(device, subdev);
340 
341 		/* add the client to the list of idle clients */
342 		mutex_lock(&clients_lock);
343 		list_add_tail(&client->list, &clients);
344 		mutex_unlock(&clients_lock);
345 	}
346 
347 	/* remove subdevices */
348 	list_for_each_entry_safe(subdev, sd, &device->subdevs, list)
349 		host1x_subdev_del(subdev);
350 
351 	mutex_unlock(&device->subdevs_lock);
352 
353 	/* move clients to idle list */
354 	mutex_lock(&clients_lock);
355 	mutex_lock(&device->clients_lock);
356 
357 	list_for_each_entry_safe(client, cl, &device->clients, list)
358 		list_move_tail(&client->list, &clients);
359 
360 	mutex_unlock(&device->clients_lock);
361 	mutex_unlock(&clients_lock);
362 
363 	/* finally remove the device */
364 	list_del_init(&device->list);
365 }
366 
367 static void host1x_device_release(struct device *dev)
368 {
369 	struct host1x_device *device = to_host1x_device(dev);
370 
371 	__host1x_device_del(device);
372 	kfree(device);
373 }
374 
375 static int host1x_device_add(struct host1x *host1x,
376 			     struct host1x_driver *driver)
377 {
378 	struct host1x_client *client, *tmp;
379 	struct host1x_subdev *subdev;
380 	struct host1x_device *device;
381 	int err;
382 
383 	device = kzalloc(sizeof(*device), GFP_KERNEL);
384 	if (!device)
385 		return -ENOMEM;
386 
387 	device_initialize(&device->dev);
388 
389 	mutex_init(&device->subdevs_lock);
390 	INIT_LIST_HEAD(&device->subdevs);
391 	INIT_LIST_HEAD(&device->active);
392 	mutex_init(&device->clients_lock);
393 	INIT_LIST_HEAD(&device->clients);
394 	INIT_LIST_HEAD(&device->list);
395 	device->driver = driver;
396 
397 	device->dev.coherent_dma_mask = host1x->dev->coherent_dma_mask;
398 	device->dev.dma_mask = &device->dev.coherent_dma_mask;
399 	dev_set_name(&device->dev, "%s", driver->driver.name);
400 	of_dma_configure(&device->dev, host1x->dev->of_node);
401 	device->dev.release = host1x_device_release;
402 	device->dev.bus = &host1x_bus_type;
403 	device->dev.parent = host1x->dev;
404 
405 	err = host1x_device_parse_dt(device, driver);
406 	if (err < 0) {
407 		kfree(device);
408 		return err;
409 	}
410 
411 	list_add_tail(&device->list, &host1x->devices);
412 
413 	mutex_lock(&clients_lock);
414 
415 	list_for_each_entry_safe(client, tmp, &clients, list) {
416 		list_for_each_entry(subdev, &device->subdevs, list) {
417 			if (subdev->np == client->dev->of_node) {
418 				host1x_subdev_register(device, subdev, client);
419 				break;
420 			}
421 		}
422 	}
423 
424 	mutex_unlock(&clients_lock);
425 
426 	return 0;
427 }
428 
429 /*
430  * Removes a device by first unregistering any subdevices and then removing
431  * itself from the list of devices.
432  *
433  * This function must be called with the host1x->devices_lock held.
434  */
435 static void host1x_device_del(struct host1x *host1x,
436 			      struct host1x_device *device)
437 {
438 	if (device->registered) {
439 		device->registered = false;
440 		device_del(&device->dev);
441 	}
442 
443 	put_device(&device->dev);
444 }
445 
446 static void host1x_attach_driver(struct host1x *host1x,
447 				 struct host1x_driver *driver)
448 {
449 	struct host1x_device *device;
450 	int err;
451 
452 	mutex_lock(&host1x->devices_lock);
453 
454 	list_for_each_entry(device, &host1x->devices, list) {
455 		if (device->driver == driver) {
456 			mutex_unlock(&host1x->devices_lock);
457 			return;
458 		}
459 	}
460 
461 	err = host1x_device_add(host1x, driver);
462 	if (err < 0)
463 		dev_err(host1x->dev, "failed to allocate device: %d\n", err);
464 
465 	mutex_unlock(&host1x->devices_lock);
466 }
467 
468 static void host1x_detach_driver(struct host1x *host1x,
469 				 struct host1x_driver *driver)
470 {
471 	struct host1x_device *device, *tmp;
472 
473 	mutex_lock(&host1x->devices_lock);
474 
475 	list_for_each_entry_safe(device, tmp, &host1x->devices, list)
476 		if (device->driver == driver)
477 			host1x_device_del(host1x, device);
478 
479 	mutex_unlock(&host1x->devices_lock);
480 }
481 
482 int host1x_register(struct host1x *host1x)
483 {
484 	struct host1x_driver *driver;
485 
486 	mutex_lock(&devices_lock);
487 	list_add_tail(&host1x->list, &devices);
488 	mutex_unlock(&devices_lock);
489 
490 	mutex_lock(&drivers_lock);
491 
492 	list_for_each_entry(driver, &drivers, list)
493 		host1x_attach_driver(host1x, driver);
494 
495 	mutex_unlock(&drivers_lock);
496 
497 	return 0;
498 }
499 
500 int host1x_unregister(struct host1x *host1x)
501 {
502 	struct host1x_driver *driver;
503 
504 	mutex_lock(&drivers_lock);
505 
506 	list_for_each_entry(driver, &drivers, list)
507 		host1x_detach_driver(host1x, driver);
508 
509 	mutex_unlock(&drivers_lock);
510 
511 	mutex_lock(&devices_lock);
512 	list_del_init(&host1x->list);
513 	mutex_unlock(&devices_lock);
514 
515 	return 0;
516 }
517 
518 int host1x_driver_register_full(struct host1x_driver *driver,
519 				struct module *owner)
520 {
521 	struct host1x *host1x;
522 
523 	INIT_LIST_HEAD(&driver->list);
524 
525 	mutex_lock(&drivers_lock);
526 	list_add_tail(&driver->list, &drivers);
527 	mutex_unlock(&drivers_lock);
528 
529 	mutex_lock(&devices_lock);
530 
531 	list_for_each_entry(host1x, &devices, list)
532 		host1x_attach_driver(host1x, driver);
533 
534 	mutex_unlock(&devices_lock);
535 
536 	driver->driver.bus = &host1x_bus_type;
537 	driver->driver.owner = owner;
538 
539 	return driver_register(&driver->driver);
540 }
541 EXPORT_SYMBOL(host1x_driver_register_full);
542 
543 void host1x_driver_unregister(struct host1x_driver *driver)
544 {
545 	driver_unregister(&driver->driver);
546 
547 	mutex_lock(&drivers_lock);
548 	list_del_init(&driver->list);
549 	mutex_unlock(&drivers_lock);
550 }
551 EXPORT_SYMBOL(host1x_driver_unregister);
552 
553 int host1x_client_register(struct host1x_client *client)
554 {
555 	struct host1x *host1x;
556 	int err;
557 
558 	mutex_lock(&devices_lock);
559 
560 	list_for_each_entry(host1x, &devices, list) {
561 		err = host1x_add_client(host1x, client);
562 		if (!err) {
563 			mutex_unlock(&devices_lock);
564 			return 0;
565 		}
566 	}
567 
568 	mutex_unlock(&devices_lock);
569 
570 	mutex_lock(&clients_lock);
571 	list_add_tail(&client->list, &clients);
572 	mutex_unlock(&clients_lock);
573 
574 	return 0;
575 }
576 EXPORT_SYMBOL(host1x_client_register);
577 
578 int host1x_client_unregister(struct host1x_client *client)
579 {
580 	struct host1x_client *c;
581 	struct host1x *host1x;
582 	int err;
583 
584 	mutex_lock(&devices_lock);
585 
586 	list_for_each_entry(host1x, &devices, list) {
587 		err = host1x_del_client(host1x, client);
588 		if (!err) {
589 			mutex_unlock(&devices_lock);
590 			return 0;
591 		}
592 	}
593 
594 	mutex_unlock(&devices_lock);
595 	mutex_lock(&clients_lock);
596 
597 	list_for_each_entry(c, &clients, list) {
598 		if (c == client) {
599 			list_del_init(&c->list);
600 			break;
601 		}
602 	}
603 
604 	mutex_unlock(&clients_lock);
605 
606 	return 0;
607 }
608 EXPORT_SYMBOL(host1x_client_unregister);
609