xref: /linux/drivers/gpu/host1x/bus.c (revision e5c86679d5e864947a52fb31e45a425dea3e7fa9)
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.of_node = host1x->dev->of_node;
403 	device->dev.bus = &host1x_bus_type;
404 	device->dev.parent = host1x->dev;
405 
406 	err = host1x_device_parse_dt(device, driver);
407 	if (err < 0) {
408 		kfree(device);
409 		return err;
410 	}
411 
412 	list_add_tail(&device->list, &host1x->devices);
413 
414 	mutex_lock(&clients_lock);
415 
416 	list_for_each_entry_safe(client, tmp, &clients, list) {
417 		list_for_each_entry(subdev, &device->subdevs, list) {
418 			if (subdev->np == client->dev->of_node) {
419 				host1x_subdev_register(device, subdev, client);
420 				break;
421 			}
422 		}
423 	}
424 
425 	mutex_unlock(&clients_lock);
426 
427 	return 0;
428 }
429 
430 /*
431  * Removes a device by first unregistering any subdevices and then removing
432  * itself from the list of devices.
433  *
434  * This function must be called with the host1x->devices_lock held.
435  */
436 static void host1x_device_del(struct host1x *host1x,
437 			      struct host1x_device *device)
438 {
439 	if (device->registered) {
440 		device->registered = false;
441 		device_del(&device->dev);
442 	}
443 
444 	put_device(&device->dev);
445 }
446 
447 static void host1x_attach_driver(struct host1x *host1x,
448 				 struct host1x_driver *driver)
449 {
450 	struct host1x_device *device;
451 	int err;
452 
453 	mutex_lock(&host1x->devices_lock);
454 
455 	list_for_each_entry(device, &host1x->devices, list) {
456 		if (device->driver == driver) {
457 			mutex_unlock(&host1x->devices_lock);
458 			return;
459 		}
460 	}
461 
462 	err = host1x_device_add(host1x, driver);
463 	if (err < 0)
464 		dev_err(host1x->dev, "failed to allocate device: %d\n", err);
465 
466 	mutex_unlock(&host1x->devices_lock);
467 }
468 
469 static void host1x_detach_driver(struct host1x *host1x,
470 				 struct host1x_driver *driver)
471 {
472 	struct host1x_device *device, *tmp;
473 
474 	mutex_lock(&host1x->devices_lock);
475 
476 	list_for_each_entry_safe(device, tmp, &host1x->devices, list)
477 		if (device->driver == driver)
478 			host1x_device_del(host1x, device);
479 
480 	mutex_unlock(&host1x->devices_lock);
481 }
482 
483 int host1x_register(struct host1x *host1x)
484 {
485 	struct host1x_driver *driver;
486 
487 	mutex_lock(&devices_lock);
488 	list_add_tail(&host1x->list, &devices);
489 	mutex_unlock(&devices_lock);
490 
491 	mutex_lock(&drivers_lock);
492 
493 	list_for_each_entry(driver, &drivers, list)
494 		host1x_attach_driver(host1x, driver);
495 
496 	mutex_unlock(&drivers_lock);
497 
498 	return 0;
499 }
500 
501 int host1x_unregister(struct host1x *host1x)
502 {
503 	struct host1x_driver *driver;
504 
505 	mutex_lock(&drivers_lock);
506 
507 	list_for_each_entry(driver, &drivers, list)
508 		host1x_detach_driver(host1x, driver);
509 
510 	mutex_unlock(&drivers_lock);
511 
512 	mutex_lock(&devices_lock);
513 	list_del_init(&host1x->list);
514 	mutex_unlock(&devices_lock);
515 
516 	return 0;
517 }
518 
519 int host1x_driver_register_full(struct host1x_driver *driver,
520 				struct module *owner)
521 {
522 	struct host1x *host1x;
523 
524 	INIT_LIST_HEAD(&driver->list);
525 
526 	mutex_lock(&drivers_lock);
527 	list_add_tail(&driver->list, &drivers);
528 	mutex_unlock(&drivers_lock);
529 
530 	mutex_lock(&devices_lock);
531 
532 	list_for_each_entry(host1x, &devices, list)
533 		host1x_attach_driver(host1x, driver);
534 
535 	mutex_unlock(&devices_lock);
536 
537 	driver->driver.bus = &host1x_bus_type;
538 	driver->driver.owner = owner;
539 
540 	return driver_register(&driver->driver);
541 }
542 EXPORT_SYMBOL(host1x_driver_register_full);
543 
544 void host1x_driver_unregister(struct host1x_driver *driver)
545 {
546 	driver_unregister(&driver->driver);
547 
548 	mutex_lock(&drivers_lock);
549 	list_del_init(&driver->list);
550 	mutex_unlock(&drivers_lock);
551 }
552 EXPORT_SYMBOL(host1x_driver_unregister);
553 
554 int host1x_client_register(struct host1x_client *client)
555 {
556 	struct host1x *host1x;
557 	int err;
558 
559 	mutex_lock(&devices_lock);
560 
561 	list_for_each_entry(host1x, &devices, list) {
562 		err = host1x_add_client(host1x, client);
563 		if (!err) {
564 			mutex_unlock(&devices_lock);
565 			return 0;
566 		}
567 	}
568 
569 	mutex_unlock(&devices_lock);
570 
571 	mutex_lock(&clients_lock);
572 	list_add_tail(&client->list, &clients);
573 	mutex_unlock(&clients_lock);
574 
575 	return 0;
576 }
577 EXPORT_SYMBOL(host1x_client_register);
578 
579 int host1x_client_unregister(struct host1x_client *client)
580 {
581 	struct host1x_client *c;
582 	struct host1x *host1x;
583 	int err;
584 
585 	mutex_lock(&devices_lock);
586 
587 	list_for_each_entry(host1x, &devices, list) {
588 		err = host1x_del_client(host1x, client);
589 		if (!err) {
590 			mutex_unlock(&devices_lock);
591 			return 0;
592 		}
593 	}
594 
595 	mutex_unlock(&devices_lock);
596 	mutex_lock(&clients_lock);
597 
598 	list_for_each_entry(c, &clients, list) {
599 		if (c == client) {
600 			list_del_init(&c->list);
601 			break;
602 		}
603 	}
604 
605 	mutex_unlock(&clients_lock);
606 
607 	return 0;
608 }
609 EXPORT_SYMBOL(host1x_client_unregister);
610