xref: /openbmc/linux/drivers/gpu/host1x/bus.c (revision 020c5260)
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 const struct dev_pm_ops host1x_device_pm_ops = {
271 	.suspend = pm_generic_suspend,
272 	.resume = pm_generic_resume,
273 	.freeze = pm_generic_freeze,
274 	.thaw = pm_generic_thaw,
275 	.poweroff = pm_generic_poweroff,
276 	.restore = pm_generic_restore,
277 };
278 
279 struct bus_type host1x_bus_type = {
280 	.name = "host1x",
281 	.match = host1x_device_match,
282 	.pm = &host1x_device_pm_ops,
283 };
284 
285 static void __host1x_device_del(struct host1x_device *device)
286 {
287 	struct host1x_subdev *subdev, *sd;
288 	struct host1x_client *client, *cl;
289 
290 	mutex_lock(&device->subdevs_lock);
291 
292 	/* unregister subdevices */
293 	list_for_each_entry_safe(subdev, sd, &device->active, list) {
294 		/*
295 		 * host1x_subdev_unregister() will remove the client from
296 		 * any lists, so we'll need to manually add it back to the
297 		 * list of idle clients.
298 		 *
299 		 * XXX: Alternatively, perhaps don't remove the client from
300 		 * any lists in host1x_subdev_unregister() and instead do
301 		 * that explicitly from host1x_unregister_client()?
302 		 */
303 		client = subdev->client;
304 
305 		__host1x_subdev_unregister(device, subdev);
306 
307 		/* add the client to the list of idle clients */
308 		mutex_lock(&clients_lock);
309 		list_add_tail(&client->list, &clients);
310 		mutex_unlock(&clients_lock);
311 	}
312 
313 	/* remove subdevices */
314 	list_for_each_entry_safe(subdev, sd, &device->subdevs, list)
315 		host1x_subdev_del(subdev);
316 
317 	mutex_unlock(&device->subdevs_lock);
318 
319 	/* move clients to idle list */
320 	mutex_lock(&clients_lock);
321 	mutex_lock(&device->clients_lock);
322 
323 	list_for_each_entry_safe(client, cl, &device->clients, list)
324 		list_move_tail(&client->list, &clients);
325 
326 	mutex_unlock(&device->clients_lock);
327 	mutex_unlock(&clients_lock);
328 
329 	/* finally remove the device */
330 	list_del_init(&device->list);
331 }
332 
333 static void host1x_device_release(struct device *dev)
334 {
335 	struct host1x_device *device = to_host1x_device(dev);
336 
337 	__host1x_device_del(device);
338 	kfree(device);
339 }
340 
341 static int host1x_device_add(struct host1x *host1x,
342 			     struct host1x_driver *driver)
343 {
344 	struct host1x_client *client, *tmp;
345 	struct host1x_subdev *subdev;
346 	struct host1x_device *device;
347 	int err;
348 
349 	device = kzalloc(sizeof(*device), GFP_KERNEL);
350 	if (!device)
351 		return -ENOMEM;
352 
353 	device_initialize(&device->dev);
354 
355 	mutex_init(&device->subdevs_lock);
356 	INIT_LIST_HEAD(&device->subdevs);
357 	INIT_LIST_HEAD(&device->active);
358 	mutex_init(&device->clients_lock);
359 	INIT_LIST_HEAD(&device->clients);
360 	INIT_LIST_HEAD(&device->list);
361 	device->driver = driver;
362 
363 	device->dev.coherent_dma_mask = host1x->dev->coherent_dma_mask;
364 	device->dev.dma_mask = &device->dev.coherent_dma_mask;
365 	dev_set_name(&device->dev, "%s", driver->driver.name);
366 	of_dma_configure(&device->dev, host1x->dev->of_node);
367 	device->dev.release = host1x_device_release;
368 	device->dev.of_node = host1x->dev->of_node;
369 	device->dev.bus = &host1x_bus_type;
370 	device->dev.parent = host1x->dev;
371 
372 	err = host1x_device_parse_dt(device, driver);
373 	if (err < 0) {
374 		kfree(device);
375 		return err;
376 	}
377 
378 	list_add_tail(&device->list, &host1x->devices);
379 
380 	mutex_lock(&clients_lock);
381 
382 	list_for_each_entry_safe(client, tmp, &clients, list) {
383 		list_for_each_entry(subdev, &device->subdevs, list) {
384 			if (subdev->np == client->dev->of_node) {
385 				host1x_subdev_register(device, subdev, client);
386 				break;
387 			}
388 		}
389 	}
390 
391 	mutex_unlock(&clients_lock);
392 
393 	return 0;
394 }
395 
396 /*
397  * Removes a device by first unregistering any subdevices and then removing
398  * itself from the list of devices.
399  *
400  * This function must be called with the host1x->devices_lock held.
401  */
402 static void host1x_device_del(struct host1x *host1x,
403 			      struct host1x_device *device)
404 {
405 	if (device->registered) {
406 		device->registered = false;
407 		device_del(&device->dev);
408 	}
409 
410 	put_device(&device->dev);
411 }
412 
413 static void host1x_attach_driver(struct host1x *host1x,
414 				 struct host1x_driver *driver)
415 {
416 	struct host1x_device *device;
417 	int err;
418 
419 	mutex_lock(&host1x->devices_lock);
420 
421 	list_for_each_entry(device, &host1x->devices, list) {
422 		if (device->driver == driver) {
423 			mutex_unlock(&host1x->devices_lock);
424 			return;
425 		}
426 	}
427 
428 	err = host1x_device_add(host1x, driver);
429 	if (err < 0)
430 		dev_err(host1x->dev, "failed to allocate device: %d\n", err);
431 
432 	mutex_unlock(&host1x->devices_lock);
433 }
434 
435 static void host1x_detach_driver(struct host1x *host1x,
436 				 struct host1x_driver *driver)
437 {
438 	struct host1x_device *device, *tmp;
439 
440 	mutex_lock(&host1x->devices_lock);
441 
442 	list_for_each_entry_safe(device, tmp, &host1x->devices, list)
443 		if (device->driver == driver)
444 			host1x_device_del(host1x, device);
445 
446 	mutex_unlock(&host1x->devices_lock);
447 }
448 
449 int host1x_register(struct host1x *host1x)
450 {
451 	struct host1x_driver *driver;
452 
453 	mutex_lock(&devices_lock);
454 	list_add_tail(&host1x->list, &devices);
455 	mutex_unlock(&devices_lock);
456 
457 	mutex_lock(&drivers_lock);
458 
459 	list_for_each_entry(driver, &drivers, list)
460 		host1x_attach_driver(host1x, driver);
461 
462 	mutex_unlock(&drivers_lock);
463 
464 	return 0;
465 }
466 
467 int host1x_unregister(struct host1x *host1x)
468 {
469 	struct host1x_driver *driver;
470 
471 	mutex_lock(&drivers_lock);
472 
473 	list_for_each_entry(driver, &drivers, list)
474 		host1x_detach_driver(host1x, driver);
475 
476 	mutex_unlock(&drivers_lock);
477 
478 	mutex_lock(&devices_lock);
479 	list_del_init(&host1x->list);
480 	mutex_unlock(&devices_lock);
481 
482 	return 0;
483 }
484 
485 static int host1x_device_probe(struct device *dev)
486 {
487 	struct host1x_driver *driver = to_host1x_driver(dev->driver);
488 	struct host1x_device *device = to_host1x_device(dev);
489 
490 	if (driver->probe)
491 		return driver->probe(device);
492 
493 	return 0;
494 }
495 
496 static int host1x_device_remove(struct device *dev)
497 {
498 	struct host1x_driver *driver = to_host1x_driver(dev->driver);
499 	struct host1x_device *device = to_host1x_device(dev);
500 
501 	if (driver->remove)
502 		return driver->remove(device);
503 
504 	return 0;
505 }
506 
507 static void host1x_device_shutdown(struct device *dev)
508 {
509 	struct host1x_driver *driver = to_host1x_driver(dev->driver);
510 	struct host1x_device *device = to_host1x_device(dev);
511 
512 	if (driver->shutdown)
513 		driver->shutdown(device);
514 }
515 
516 int host1x_driver_register_full(struct host1x_driver *driver,
517 				struct module *owner)
518 {
519 	struct host1x *host1x;
520 
521 	INIT_LIST_HEAD(&driver->list);
522 
523 	mutex_lock(&drivers_lock);
524 	list_add_tail(&driver->list, &drivers);
525 	mutex_unlock(&drivers_lock);
526 
527 	mutex_lock(&devices_lock);
528 
529 	list_for_each_entry(host1x, &devices, list)
530 		host1x_attach_driver(host1x, driver);
531 
532 	mutex_unlock(&devices_lock);
533 
534 	driver->driver.bus = &host1x_bus_type;
535 	driver->driver.owner = owner;
536 	driver->driver.probe = host1x_device_probe;
537 	driver->driver.remove = host1x_device_remove;
538 	driver->driver.shutdown = host1x_device_shutdown;
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