]>
git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/gpu/host1x/bus.c
2 * Copyright (C) 2012 Avionic Design GmbH
3 * Copyright (C) 2012-2013, NVIDIA Corporation
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.
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
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/>.
18 #include <linux/host1x.h>
20 #include <linux/slab.h>
24 static DEFINE_MUTEX(clients_lock
);
25 static LIST_HEAD(clients
);
27 static DEFINE_MUTEX(drivers_lock
);
28 static LIST_HEAD(drivers
);
30 static DEFINE_MUTEX(devices_lock
);
31 static LIST_HEAD(devices
);
33 struct host1x_subdev
{
34 struct host1x_client
*client
;
35 struct device_node
*np
;
36 struct list_head list
;
40 * host1x_subdev_add() - add a new subdevice with an associated device node
42 static int host1x_subdev_add(struct host1x_device
*device
,
43 struct device_node
*np
)
45 struct host1x_subdev
*subdev
;
47 subdev
= kzalloc(sizeof(*subdev
), GFP_KERNEL
);
51 INIT_LIST_HEAD(&subdev
->list
);
52 subdev
->np
= of_node_get(np
);
54 mutex_lock(&device
->subdevs_lock
);
55 list_add_tail(&subdev
->list
, &device
->subdevs
);
56 mutex_unlock(&device
->subdevs_lock
);
62 * host1x_subdev_del() - remove subdevice
64 static void host1x_subdev_del(struct host1x_subdev
*subdev
)
66 list_del(&subdev
->list
);
67 of_node_put(subdev
->np
);
72 * host1x_device_parse_dt() - scan device tree and add matching subdevices
74 static int host1x_device_parse_dt(struct host1x_device
*device
)
76 struct device_node
*np
;
79 for_each_child_of_node(device
->dev
.parent
->of_node
, np
) {
80 if (of_match_node(device
->driver
->subdevs
, np
) &&
81 of_device_is_available(np
)) {
82 err
= host1x_subdev_add(device
, np
);
91 static void host1x_subdev_register(struct host1x_device
*device
,
92 struct host1x_subdev
*subdev
,
93 struct host1x_client
*client
)
98 * Move the subdevice to the list of active (registered) subdevices
99 * and associate it with a client. At the same time, associate the
100 * client with its parent device.
102 mutex_lock(&device
->subdevs_lock
);
103 mutex_lock(&device
->clients_lock
);
104 list_move_tail(&client
->list
, &device
->clients
);
105 list_move_tail(&subdev
->list
, &device
->active
);
106 client
->parent
= &device
->dev
;
107 subdev
->client
= client
;
108 mutex_unlock(&device
->clients_lock
);
109 mutex_unlock(&device
->subdevs_lock
);
112 * When all subdevices have been registered, the composite device is
113 * ready to be probed.
115 if (list_empty(&device
->subdevs
)) {
116 err
= device
->driver
->probe(device
);
118 dev_err(&device
->dev
, "probe failed: %d\n", err
);
122 static void __host1x_subdev_unregister(struct host1x_device
*device
,
123 struct host1x_subdev
*subdev
)
125 struct host1x_client
*client
= subdev
->client
;
129 * If all subdevices have been activated, we're about to remove the
130 * first active subdevice, so unload the driver first.
132 if (list_empty(&device
->subdevs
)) {
133 err
= device
->driver
->remove(device
);
135 dev_err(&device
->dev
, "remove failed: %d\n", err
);
139 * Move the subdevice back to the list of idle subdevices and remove
140 * it from list of clients.
142 mutex_lock(&device
->clients_lock
);
143 subdev
->client
= NULL
;
144 client
->parent
= NULL
;
145 list_move_tail(&subdev
->list
, &device
->subdevs
);
147 * XXX: Perhaps don't do this here, but rather explicitly remove it
148 * when the device is about to be deleted.
150 * This is somewhat complicated by the fact that this function is
151 * used to remove the subdevice when a client is unregistered but
152 * also when the composite device is about to be removed.
154 list_del_init(&client
->list
);
155 mutex_unlock(&device
->clients_lock
);
158 static void host1x_subdev_unregister(struct host1x_device
*device
,
159 struct host1x_subdev
*subdev
)
161 mutex_lock(&device
->subdevs_lock
);
162 __host1x_subdev_unregister(device
, subdev
);
163 mutex_unlock(&device
->subdevs_lock
);
166 int host1x_device_init(struct host1x_device
*device
)
168 struct host1x_client
*client
;
171 mutex_lock(&device
->clients_lock
);
173 list_for_each_entry(client
, &device
->clients
, list
) {
174 if (client
->ops
&& client
->ops
->init
) {
175 err
= client
->ops
->init(client
);
177 dev_err(&device
->dev
,
178 "failed to initialize %s: %d\n",
179 dev_name(client
->dev
), err
);
180 mutex_unlock(&device
->clients_lock
);
186 mutex_unlock(&device
->clients_lock
);
191 int host1x_device_exit(struct host1x_device
*device
)
193 struct host1x_client
*client
;
196 mutex_lock(&device
->clients_lock
);
198 list_for_each_entry_reverse(client
, &device
->clients
, list
) {
199 if (client
->ops
&& client
->ops
->exit
) {
200 err
= client
->ops
->exit(client
);
202 dev_err(&device
->dev
,
203 "failed to cleanup %s: %d\n",
204 dev_name(client
->dev
), err
);
205 mutex_unlock(&device
->clients_lock
);
211 mutex_unlock(&device
->clients_lock
);
216 static int host1x_register_client(struct host1x
*host1x
,
217 struct host1x_client
*client
)
219 struct host1x_device
*device
;
220 struct host1x_subdev
*subdev
;
222 mutex_lock(&host1x
->devices_lock
);
224 list_for_each_entry(device
, &host1x
->devices
, list
) {
225 list_for_each_entry(subdev
, &device
->subdevs
, list
) {
226 if (subdev
->np
== client
->dev
->of_node
) {
227 host1x_subdev_register(device
, subdev
, client
);
228 mutex_unlock(&host1x
->devices_lock
);
234 mutex_unlock(&host1x
->devices_lock
);
238 static int host1x_unregister_client(struct host1x
*host1x
,
239 struct host1x_client
*client
)
241 struct host1x_device
*device
, *dt
;
242 struct host1x_subdev
*subdev
;
244 mutex_lock(&host1x
->devices_lock
);
246 list_for_each_entry_safe(device
, dt
, &host1x
->devices
, list
) {
247 list_for_each_entry(subdev
, &device
->active
, list
) {
248 if (subdev
->client
== client
) {
249 host1x_subdev_unregister(device
, subdev
);
250 mutex_unlock(&host1x
->devices_lock
);
256 mutex_unlock(&host1x
->devices_lock
);
260 struct bus_type host1x_bus_type
= {
264 int host1x_bus_init(void)
266 return bus_register(&host1x_bus_type
);
269 void host1x_bus_exit(void)
271 bus_unregister(&host1x_bus_type
);
274 static void host1x_device_release(struct device
*dev
)
276 struct host1x_device
*device
= to_host1x_device(dev
);
281 static int host1x_device_add(struct host1x
*host1x
,
282 struct host1x_driver
*driver
)
284 struct host1x_client
*client
, *tmp
;
285 struct host1x_subdev
*subdev
;
286 struct host1x_device
*device
;
289 device
= kzalloc(sizeof(*device
), GFP_KERNEL
);
293 mutex_init(&device
->subdevs_lock
);
294 INIT_LIST_HEAD(&device
->subdevs
);
295 INIT_LIST_HEAD(&device
->active
);
296 mutex_init(&device
->clients_lock
);
297 INIT_LIST_HEAD(&device
->clients
);
298 INIT_LIST_HEAD(&device
->list
);
299 device
->driver
= driver
;
301 device
->dev
.coherent_dma_mask
= host1x
->dev
->coherent_dma_mask
;
302 device
->dev
.dma_mask
= &device
->dev
.coherent_dma_mask
;
303 device
->dev
.release
= host1x_device_release
;
304 dev_set_name(&device
->dev
, driver
->name
);
305 device
->dev
.bus
= &host1x_bus_type
;
306 device
->dev
.parent
= host1x
->dev
;
308 err
= device_register(&device
->dev
);
312 err
= host1x_device_parse_dt(device
);
314 device_unregister(&device
->dev
);
318 mutex_lock(&host1x
->devices_lock
);
319 list_add_tail(&device
->list
, &host1x
->devices
);
320 mutex_unlock(&host1x
->devices_lock
);
322 mutex_lock(&clients_lock
);
324 list_for_each_entry_safe(client
, tmp
, &clients
, list
) {
325 list_for_each_entry(subdev
, &device
->subdevs
, list
) {
326 if (subdev
->np
== client
->dev
->of_node
) {
327 host1x_subdev_register(device
, subdev
, client
);
333 mutex_unlock(&clients_lock
);
339 * Removes a device by first unregistering any subdevices and then removing
340 * itself from the list of devices.
342 * This function must be called with the host1x->devices_lock held.
344 static void host1x_device_del(struct host1x
*host1x
,
345 struct host1x_device
*device
)
347 struct host1x_subdev
*subdev
, *sd
;
348 struct host1x_client
*client
, *cl
;
350 mutex_lock(&device
->subdevs_lock
);
352 /* unregister subdevices */
353 list_for_each_entry_safe(subdev
, sd
, &device
->active
, list
) {
355 * host1x_subdev_unregister() will remove the client from
356 * any lists, so we'll need to manually add it back to the
357 * list of idle clients.
359 * XXX: Alternatively, perhaps don't remove the client from
360 * any lists in host1x_subdev_unregister() and instead do
361 * that explicitly from host1x_unregister_client()?
363 client
= subdev
->client
;
365 __host1x_subdev_unregister(device
, subdev
);
367 /* add the client to the list of idle clients */
368 mutex_lock(&clients_lock
);
369 list_add_tail(&client
->list
, &clients
);
370 mutex_unlock(&clients_lock
);
373 /* remove subdevices */
374 list_for_each_entry_safe(subdev
, sd
, &device
->subdevs
, list
)
375 host1x_subdev_del(subdev
);
377 mutex_unlock(&device
->subdevs_lock
);
379 /* move clients to idle list */
380 mutex_lock(&clients_lock
);
381 mutex_lock(&device
->clients_lock
);
383 list_for_each_entry_safe(client
, cl
, &device
->clients
, list
)
384 list_move_tail(&client
->list
, &clients
);
386 mutex_unlock(&device
->clients_lock
);
387 mutex_unlock(&clients_lock
);
389 /* finally remove the device */
390 list_del_init(&device
->list
);
391 device_unregister(&device
->dev
);
394 static void host1x_attach_driver(struct host1x
*host1x
,
395 struct host1x_driver
*driver
)
397 struct host1x_device
*device
;
400 mutex_lock(&host1x
->devices_lock
);
402 list_for_each_entry(device
, &host1x
->devices
, list
) {
403 if (device
->driver
== driver
) {
404 mutex_unlock(&host1x
->devices_lock
);
409 mutex_unlock(&host1x
->devices_lock
);
411 err
= host1x_device_add(host1x
, driver
);
413 dev_err(host1x
->dev
, "failed to allocate device: %d\n", err
);
416 static void host1x_detach_driver(struct host1x
*host1x
,
417 struct host1x_driver
*driver
)
419 struct host1x_device
*device
, *tmp
;
421 mutex_lock(&host1x
->devices_lock
);
423 list_for_each_entry_safe(device
, tmp
, &host1x
->devices
, list
)
424 if (device
->driver
== driver
)
425 host1x_device_del(host1x
, device
);
427 mutex_unlock(&host1x
->devices_lock
);
430 int host1x_register(struct host1x
*host1x
)
432 struct host1x_driver
*driver
;
434 mutex_lock(&devices_lock
);
435 list_add_tail(&host1x
->list
, &devices
);
436 mutex_unlock(&devices_lock
);
438 mutex_lock(&drivers_lock
);
440 list_for_each_entry(driver
, &drivers
, list
)
441 host1x_attach_driver(host1x
, driver
);
443 mutex_unlock(&drivers_lock
);
448 int host1x_unregister(struct host1x
*host1x
)
450 struct host1x_driver
*driver
;
452 mutex_lock(&drivers_lock
);
454 list_for_each_entry(driver
, &drivers
, list
)
455 host1x_detach_driver(host1x
, driver
);
457 mutex_unlock(&drivers_lock
);
459 mutex_lock(&devices_lock
);
460 list_del_init(&host1x
->list
);
461 mutex_unlock(&devices_lock
);
466 int host1x_driver_register(struct host1x_driver
*driver
)
468 struct host1x
*host1x
;
470 INIT_LIST_HEAD(&driver
->list
);
472 mutex_lock(&drivers_lock
);
473 list_add_tail(&driver
->list
, &drivers
);
474 mutex_unlock(&drivers_lock
);
476 mutex_lock(&devices_lock
);
478 list_for_each_entry(host1x
, &devices
, list
)
479 host1x_attach_driver(host1x
, driver
);
481 mutex_unlock(&devices_lock
);
485 EXPORT_SYMBOL(host1x_driver_register
);
487 void host1x_driver_unregister(struct host1x_driver
*driver
)
489 mutex_lock(&drivers_lock
);
490 list_del_init(&driver
->list
);
491 mutex_unlock(&drivers_lock
);
493 EXPORT_SYMBOL(host1x_driver_unregister
);
495 int host1x_client_register(struct host1x_client
*client
)
497 struct host1x
*host1x
;
500 mutex_lock(&devices_lock
);
502 list_for_each_entry(host1x
, &devices
, list
) {
503 err
= host1x_register_client(host1x
, client
);
505 mutex_unlock(&devices_lock
);
510 mutex_unlock(&devices_lock
);
512 mutex_lock(&clients_lock
);
513 list_add_tail(&client
->list
, &clients
);
514 mutex_unlock(&clients_lock
);
518 EXPORT_SYMBOL(host1x_client_register
);
520 int host1x_client_unregister(struct host1x_client
*client
)
522 struct host1x_client
*c
;
523 struct host1x
*host1x
;
526 mutex_lock(&devices_lock
);
528 list_for_each_entry(host1x
, &devices
, list
) {
529 err
= host1x_unregister_client(host1x
, client
);
531 mutex_unlock(&devices_lock
);
536 mutex_unlock(&devices_lock
);
537 mutex_lock(&clients_lock
);
539 list_for_each_entry(c
, &clients
, list
) {
541 list_del_init(&c
->list
);
546 mutex_unlock(&clients_lock
);
550 EXPORT_SYMBOL(host1x_client_unregister
);