Merge tag 'powerpc-4.5-5' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[cascardo/linux.git] / drivers / gpu / host1x / bus.c
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                                 return err;
88                 }
89         }
90
91         return 0;
92 }
93
94 static void host1x_subdev_register(struct host1x_device *device,
95                                    struct host1x_subdev *subdev,
96                                    struct host1x_client *client)
97 {
98         int err;
99
100         /*
101          * Move the subdevice to the list of active (registered) subdevices
102          * and associate it with a client. At the same time, associate the
103          * client with its parent device.
104          */
105         mutex_lock(&device->subdevs_lock);
106         mutex_lock(&device->clients_lock);
107         list_move_tail(&client->list, &device->clients);
108         list_move_tail(&subdev->list, &device->active);
109         client->parent = &device->dev;
110         subdev->client = client;
111         mutex_unlock(&device->clients_lock);
112         mutex_unlock(&device->subdevs_lock);
113
114         if (list_empty(&device->subdevs)) {
115                 err = device_add(&device->dev);
116                 if (err < 0)
117                         dev_err(&device->dev, "failed to add: %d\n", err);
118                 else
119                         device->registered = true;
120         }
121 }
122
123 static void __host1x_subdev_unregister(struct host1x_device *device,
124                                        struct host1x_subdev *subdev)
125 {
126         struct host1x_client *client = subdev->client;
127
128         /*
129          * If all subdevices have been activated, we're about to remove the
130          * first active subdevice, so unload the driver first.
131          */
132         if (list_empty(&device->subdevs)) {
133                 if (device->registered) {
134                         device->registered = false;
135                         device_del(&device->dev);
136                 }
137         }
138
139         /*
140          * Move the subdevice back to the list of idle subdevices and remove
141          * it from list of clients.
142          */
143         mutex_lock(&device->clients_lock);
144         subdev->client = NULL;
145         client->parent = NULL;
146         list_move_tail(&subdev->list, &device->subdevs);
147         /*
148          * XXX: Perhaps don't do this here, but rather explicitly remove it
149          * when the device is about to be deleted.
150          *
151          * This is somewhat complicated by the fact that this function is
152          * used to remove the subdevice when a client is unregistered but
153          * also when the composite device is about to be removed.
154          */
155         list_del_init(&client->list);
156         mutex_unlock(&device->clients_lock);
157 }
158
159 static void host1x_subdev_unregister(struct host1x_device *device,
160                                      struct host1x_subdev *subdev)
161 {
162         mutex_lock(&device->subdevs_lock);
163         __host1x_subdev_unregister(device, subdev);
164         mutex_unlock(&device->subdevs_lock);
165 }
166
167 int host1x_device_init(struct host1x_device *device)
168 {
169         struct host1x_client *client;
170         int err;
171
172         mutex_lock(&device->clients_lock);
173
174         list_for_each_entry(client, &device->clients, list) {
175                 if (client->ops && client->ops->init) {
176                         err = client->ops->init(client);
177                         if (err < 0) {
178                                 dev_err(&device->dev,
179                                         "failed to initialize %s: %d\n",
180                                         dev_name(client->dev), err);
181                                 mutex_unlock(&device->clients_lock);
182                                 return err;
183                         }
184                 }
185         }
186
187         mutex_unlock(&device->clients_lock);
188
189         return 0;
190 }
191 EXPORT_SYMBOL(host1x_device_init);
192
193 int host1x_device_exit(struct host1x_device *device)
194 {
195         struct host1x_client *client;
196         int err;
197
198         mutex_lock(&device->clients_lock);
199
200         list_for_each_entry_reverse(client, &device->clients, list) {
201                 if (client->ops && client->ops->exit) {
202                         err = client->ops->exit(client);
203                         if (err < 0) {
204                                 dev_err(&device->dev,
205                                         "failed to cleanup %s: %d\n",
206                                         dev_name(client->dev), err);
207                                 mutex_unlock(&device->clients_lock);
208                                 return err;
209                         }
210                 }
211         }
212
213         mutex_unlock(&device->clients_lock);
214
215         return 0;
216 }
217 EXPORT_SYMBOL(host1x_device_exit);
218
219 static int host1x_add_client(struct host1x *host1x,
220                              struct host1x_client *client)
221 {
222         struct host1x_device *device;
223         struct host1x_subdev *subdev;
224
225         mutex_lock(&host1x->devices_lock);
226
227         list_for_each_entry(device, &host1x->devices, list) {
228                 list_for_each_entry(subdev, &device->subdevs, list) {
229                         if (subdev->np == client->dev->of_node) {
230                                 host1x_subdev_register(device, subdev, client);
231                                 mutex_unlock(&host1x->devices_lock);
232                                 return 0;
233                         }
234                 }
235         }
236
237         mutex_unlock(&host1x->devices_lock);
238         return -ENODEV;
239 }
240
241 static int host1x_del_client(struct host1x *host1x,
242                              struct host1x_client *client)
243 {
244         struct host1x_device *device, *dt;
245         struct host1x_subdev *subdev;
246
247         mutex_lock(&host1x->devices_lock);
248
249         list_for_each_entry_safe(device, dt, &host1x->devices, list) {
250                 list_for_each_entry(subdev, &device->active, list) {
251                         if (subdev->client == client) {
252                                 host1x_subdev_unregister(device, subdev);
253                                 mutex_unlock(&host1x->devices_lock);
254                                 return 0;
255                         }
256                 }
257         }
258
259         mutex_unlock(&host1x->devices_lock);
260         return -ENODEV;
261 }
262
263 static int host1x_device_match(struct device *dev, struct device_driver *drv)
264 {
265         return strcmp(dev_name(dev), drv->name) == 0;
266 }
267
268 static int host1x_device_probe(struct device *dev)
269 {
270         struct host1x_driver *driver = to_host1x_driver(dev->driver);
271         struct host1x_device *device = to_host1x_device(dev);
272
273         if (driver->probe)
274                 return driver->probe(device);
275
276         return 0;
277 }
278
279 static int host1x_device_remove(struct device *dev)
280 {
281         struct host1x_driver *driver = to_host1x_driver(dev->driver);
282         struct host1x_device *device = to_host1x_device(dev);
283
284         if (driver->remove)
285                 return driver->remove(device);
286
287         return 0;
288 }
289
290 static void host1x_device_shutdown(struct device *dev)
291 {
292         struct host1x_driver *driver = to_host1x_driver(dev->driver);
293         struct host1x_device *device = to_host1x_device(dev);
294
295         if (driver->shutdown)
296                 driver->shutdown(device);
297 }
298
299 static const struct dev_pm_ops host1x_device_pm_ops = {
300         .suspend = pm_generic_suspend,
301         .resume = pm_generic_resume,
302         .freeze = pm_generic_freeze,
303         .thaw = pm_generic_thaw,
304         .poweroff = pm_generic_poweroff,
305         .restore = pm_generic_restore,
306 };
307
308 struct bus_type host1x_bus_type = {
309         .name = "host1x",
310         .match = host1x_device_match,
311         .probe = host1x_device_probe,
312         .remove = host1x_device_remove,
313         .shutdown = host1x_device_shutdown,
314         .pm = &host1x_device_pm_ops,
315 };
316
317 static void __host1x_device_del(struct host1x_device *device)
318 {
319         struct host1x_subdev *subdev, *sd;
320         struct host1x_client *client, *cl;
321
322         mutex_lock(&device->subdevs_lock);
323
324         /* unregister subdevices */
325         list_for_each_entry_safe(subdev, sd, &device->active, list) {
326                 /*
327                  * host1x_subdev_unregister() will remove the client from
328                  * any lists, so we'll need to manually add it back to the
329                  * list of idle clients.
330                  *
331                  * XXX: Alternatively, perhaps don't remove the client from
332                  * any lists in host1x_subdev_unregister() and instead do
333                  * that explicitly from host1x_unregister_client()?
334                  */
335                 client = subdev->client;
336
337                 __host1x_subdev_unregister(device, subdev);
338
339                 /* add the client to the list of idle clients */
340                 mutex_lock(&clients_lock);
341                 list_add_tail(&client->list, &clients);
342                 mutex_unlock(&clients_lock);
343         }
344
345         /* remove subdevices */
346         list_for_each_entry_safe(subdev, sd, &device->subdevs, list)
347                 host1x_subdev_del(subdev);
348
349         mutex_unlock(&device->subdevs_lock);
350
351         /* move clients to idle list */
352         mutex_lock(&clients_lock);
353         mutex_lock(&device->clients_lock);
354
355         list_for_each_entry_safe(client, cl, &device->clients, list)
356                 list_move_tail(&client->list, &clients);
357
358         mutex_unlock(&device->clients_lock);
359         mutex_unlock(&clients_lock);
360
361         /* finally remove the device */
362         list_del_init(&device->list);
363 }
364
365 static void host1x_device_release(struct device *dev)
366 {
367         struct host1x_device *device = to_host1x_device(dev);
368
369         __host1x_device_del(device);
370         kfree(device);
371 }
372
373 static int host1x_device_add(struct host1x *host1x,
374                              struct host1x_driver *driver)
375 {
376         struct host1x_client *client, *tmp;
377         struct host1x_subdev *subdev;
378         struct host1x_device *device;
379         int err;
380
381         device = kzalloc(sizeof(*device), GFP_KERNEL);
382         if (!device)
383                 return -ENOMEM;
384
385         device_initialize(&device->dev);
386
387         mutex_init(&device->subdevs_lock);
388         INIT_LIST_HEAD(&device->subdevs);
389         INIT_LIST_HEAD(&device->active);
390         mutex_init(&device->clients_lock);
391         INIT_LIST_HEAD(&device->clients);
392         INIT_LIST_HEAD(&device->list);
393         device->driver = driver;
394
395         device->dev.coherent_dma_mask = host1x->dev->coherent_dma_mask;
396         device->dev.dma_mask = &device->dev.coherent_dma_mask;
397         dev_set_name(&device->dev, "%s", driver->driver.name);
398         of_dma_configure(&device->dev, host1x->dev->of_node);
399         device->dev.release = host1x_device_release;
400         device->dev.bus = &host1x_bus_type;
401         device->dev.parent = host1x->dev;
402
403         err = host1x_device_parse_dt(device, driver);
404         if (err < 0) {
405                 kfree(device);
406                 return err;
407         }
408
409         list_add_tail(&device->list, &host1x->devices);
410
411         mutex_lock(&clients_lock);
412
413         list_for_each_entry_safe(client, tmp, &clients, list) {
414                 list_for_each_entry(subdev, &device->subdevs, list) {
415                         if (subdev->np == client->dev->of_node) {
416                                 host1x_subdev_register(device, subdev, client);
417                                 break;
418                         }
419                 }
420         }
421
422         mutex_unlock(&clients_lock);
423
424         return 0;
425 }
426
427 /*
428  * Removes a device by first unregistering any subdevices and then removing
429  * itself from the list of devices.
430  *
431  * This function must be called with the host1x->devices_lock held.
432  */
433 static void host1x_device_del(struct host1x *host1x,
434                               struct host1x_device *device)
435 {
436         if (device->registered) {
437                 device->registered = false;
438                 device_del(&device->dev);
439         }
440
441         put_device(&device->dev);
442 }
443
444 static void host1x_attach_driver(struct host1x *host1x,
445                                  struct host1x_driver *driver)
446 {
447         struct host1x_device *device;
448         int err;
449
450         mutex_lock(&host1x->devices_lock);
451
452         list_for_each_entry(device, &host1x->devices, list) {
453                 if (device->driver == driver) {
454                         mutex_unlock(&host1x->devices_lock);
455                         return;
456                 }
457         }
458
459         err = host1x_device_add(host1x, driver);
460         if (err < 0)
461                 dev_err(host1x->dev, "failed to allocate device: %d\n", err);
462
463         mutex_unlock(&host1x->devices_lock);
464 }
465
466 static void host1x_detach_driver(struct host1x *host1x,
467                                  struct host1x_driver *driver)
468 {
469         struct host1x_device *device, *tmp;
470
471         mutex_lock(&host1x->devices_lock);
472
473         list_for_each_entry_safe(device, tmp, &host1x->devices, list)
474                 if (device->driver == driver)
475                         host1x_device_del(host1x, device);
476
477         mutex_unlock(&host1x->devices_lock);
478 }
479
480 int host1x_register(struct host1x *host1x)
481 {
482         struct host1x_driver *driver;
483
484         mutex_lock(&devices_lock);
485         list_add_tail(&host1x->list, &devices);
486         mutex_unlock(&devices_lock);
487
488         mutex_lock(&drivers_lock);
489
490         list_for_each_entry(driver, &drivers, list)
491                 host1x_attach_driver(host1x, driver);
492
493         mutex_unlock(&drivers_lock);
494
495         return 0;
496 }
497
498 int host1x_unregister(struct host1x *host1x)
499 {
500         struct host1x_driver *driver;
501
502         mutex_lock(&drivers_lock);
503
504         list_for_each_entry(driver, &drivers, list)
505                 host1x_detach_driver(host1x, driver);
506
507         mutex_unlock(&drivers_lock);
508
509         mutex_lock(&devices_lock);
510         list_del_init(&host1x->list);
511         mutex_unlock(&devices_lock);
512
513         return 0;
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
537         return driver_register(&driver->driver);
538 }
539 EXPORT_SYMBOL(host1x_driver_register_full);
540
541 void host1x_driver_unregister(struct host1x_driver *driver)
542 {
543         driver_unregister(&driver->driver);
544
545         mutex_lock(&drivers_lock);
546         list_del_init(&driver->list);
547         mutex_unlock(&drivers_lock);
548 }
549 EXPORT_SYMBOL(host1x_driver_unregister);
550
551 int host1x_client_register(struct host1x_client *client)
552 {
553         struct host1x *host1x;
554         int err;
555
556         mutex_lock(&devices_lock);
557
558         list_for_each_entry(host1x, &devices, list) {
559                 err = host1x_add_client(host1x, client);
560                 if (!err) {
561                         mutex_unlock(&devices_lock);
562                         return 0;
563                 }
564         }
565
566         mutex_unlock(&devices_lock);
567
568         mutex_lock(&clients_lock);
569         list_add_tail(&client->list, &clients);
570         mutex_unlock(&clients_lock);
571
572         return 0;
573 }
574 EXPORT_SYMBOL(host1x_client_register);
575
576 int host1x_client_unregister(struct host1x_client *client)
577 {
578         struct host1x_client *c;
579         struct host1x *host1x;
580         int err;
581
582         mutex_lock(&devices_lock);
583
584         list_for_each_entry(host1x, &devices, list) {
585                 err = host1x_del_client(host1x, client);
586                 if (!err) {
587                         mutex_unlock(&devices_lock);
588                         return 0;
589                 }
590         }
591
592         mutex_unlock(&devices_lock);
593         mutex_lock(&clients_lock);
594
595         list_for_each_entry(c, &clients, list) {
596                 if (c == client) {
597                         list_del_init(&c->list);
598                         break;
599                 }
600         }
601
602         mutex_unlock(&clients_lock);
603
604         return 0;
605 }
606 EXPORT_SYMBOL(host1x_client_unregister);