Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/gpu/host1x/bus.c
26444 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* Copyright (C) 2012 Avionic Design GmbH
4
* Copyright (C) 2012-2013, NVIDIA Corporation
5
*/
6
7
#include <linux/debugfs.h>
8
#include <linux/dma-mapping.h>
9
#include <linux/host1x.h>
10
#include <linux/of.h>
11
#include <linux/seq_file.h>
12
#include <linux/slab.h>
13
#include <linux/of_device.h>
14
15
#include "bus.h"
16
#include "dev.h"
17
18
static DEFINE_MUTEX(clients_lock);
19
static LIST_HEAD(clients);
20
21
static DEFINE_MUTEX(drivers_lock);
22
static LIST_HEAD(drivers);
23
24
static DEFINE_MUTEX(devices_lock);
25
static LIST_HEAD(devices);
26
27
struct host1x_subdev {
28
struct host1x_client *client;
29
struct device_node *np;
30
struct list_head list;
31
};
32
33
/**
34
* host1x_subdev_add() - add a new subdevice with an associated device node
35
* @device: host1x device to add the subdevice to
36
* @driver: host1x driver containing the subdevices
37
* @np: device node
38
*/
39
static int host1x_subdev_add(struct host1x_device *device,
40
struct host1x_driver *driver,
41
struct device_node *np)
42
{
43
struct host1x_subdev *subdev;
44
int err;
45
46
subdev = kzalloc(sizeof(*subdev), GFP_KERNEL);
47
if (!subdev)
48
return -ENOMEM;
49
50
INIT_LIST_HEAD(&subdev->list);
51
subdev->np = of_node_get(np);
52
53
mutex_lock(&device->subdevs_lock);
54
list_add_tail(&subdev->list, &device->subdevs);
55
mutex_unlock(&device->subdevs_lock);
56
57
/* recursively add children */
58
for_each_child_of_node_scoped(np, child) {
59
if (of_match_node(driver->subdevs, child) &&
60
of_device_is_available(child)) {
61
err = host1x_subdev_add(device, driver, child);
62
if (err < 0) {
63
/* XXX cleanup? */
64
return err;
65
}
66
}
67
}
68
69
return 0;
70
}
71
72
/**
73
* host1x_subdev_del() - remove subdevice
74
* @subdev: subdevice to remove
75
*/
76
static void host1x_subdev_del(struct host1x_subdev *subdev)
77
{
78
list_del(&subdev->list);
79
of_node_put(subdev->np);
80
kfree(subdev);
81
}
82
83
/**
84
* host1x_device_parse_dt() - scan device tree and add matching subdevices
85
* @device: host1x logical device
86
* @driver: host1x driver
87
*/
88
static int host1x_device_parse_dt(struct host1x_device *device,
89
struct host1x_driver *driver)
90
{
91
int err;
92
93
for_each_child_of_node_scoped(device->dev.parent->of_node, np) {
94
if (of_match_node(driver->subdevs, np) &&
95
of_device_is_available(np)) {
96
err = host1x_subdev_add(device, driver, np);
97
if (err < 0)
98
return err;
99
}
100
}
101
102
return 0;
103
}
104
105
static void host1x_subdev_register(struct host1x_device *device,
106
struct host1x_subdev *subdev,
107
struct host1x_client *client)
108
{
109
int err;
110
111
/*
112
* Move the subdevice to the list of active (registered) subdevices
113
* and associate it with a client. At the same time, associate the
114
* client with its parent device.
115
*/
116
mutex_lock(&device->subdevs_lock);
117
mutex_lock(&device->clients_lock);
118
list_move_tail(&client->list, &device->clients);
119
list_move_tail(&subdev->list, &device->active);
120
client->host = &device->dev;
121
subdev->client = client;
122
mutex_unlock(&device->clients_lock);
123
mutex_unlock(&device->subdevs_lock);
124
125
if (list_empty(&device->subdevs)) {
126
err = device_add(&device->dev);
127
if (err < 0)
128
dev_err(&device->dev, "failed to add: %d\n", err);
129
else
130
device->registered = true;
131
}
132
}
133
134
static void __host1x_subdev_unregister(struct host1x_device *device,
135
struct host1x_subdev *subdev)
136
{
137
struct host1x_client *client = subdev->client;
138
139
/*
140
* If all subdevices have been activated, we're about to remove the
141
* first active subdevice, so unload the driver first.
142
*/
143
if (list_empty(&device->subdevs)) {
144
if (device->registered) {
145
device->registered = false;
146
device_del(&device->dev);
147
}
148
}
149
150
/*
151
* Move the subdevice back to the list of idle subdevices and remove
152
* it from list of clients.
153
*/
154
mutex_lock(&device->clients_lock);
155
subdev->client = NULL;
156
client->host = NULL;
157
list_move_tail(&subdev->list, &device->subdevs);
158
/*
159
* XXX: Perhaps don't do this here, but rather explicitly remove it
160
* when the device is about to be deleted.
161
*
162
* This is somewhat complicated by the fact that this function is
163
* used to remove the subdevice when a client is unregistered but
164
* also when the composite device is about to be removed.
165
*/
166
list_del_init(&client->list);
167
mutex_unlock(&device->clients_lock);
168
}
169
170
static void host1x_subdev_unregister(struct host1x_device *device,
171
struct host1x_subdev *subdev)
172
{
173
mutex_lock(&device->subdevs_lock);
174
__host1x_subdev_unregister(device, subdev);
175
mutex_unlock(&device->subdevs_lock);
176
}
177
178
/**
179
* host1x_device_init() - initialize a host1x logical device
180
* @device: host1x logical device
181
*
182
* The driver for the host1x logical device can call this during execution of
183
* its &host1x_driver.probe implementation to initialize each of its clients.
184
* The client drivers access the subsystem specific driver data using the
185
* &host1x_client.parent field and driver data associated with it (usually by
186
* calling dev_get_drvdata()).
187
*/
188
int host1x_device_init(struct host1x_device *device)
189
{
190
struct host1x_client *client;
191
int err;
192
193
mutex_lock(&device->clients_lock);
194
195
list_for_each_entry(client, &device->clients, list) {
196
if (client->ops && client->ops->early_init) {
197
err = client->ops->early_init(client);
198
if (err < 0) {
199
dev_err(&device->dev, "failed to early initialize %s: %d\n",
200
dev_name(client->dev), err);
201
goto teardown_late;
202
}
203
}
204
}
205
206
list_for_each_entry(client, &device->clients, list) {
207
if (client->ops && client->ops->init) {
208
err = client->ops->init(client);
209
if (err < 0) {
210
dev_err(&device->dev,
211
"failed to initialize %s: %d\n",
212
dev_name(client->dev), err);
213
goto teardown;
214
}
215
}
216
}
217
218
mutex_unlock(&device->clients_lock);
219
220
return 0;
221
222
teardown:
223
list_for_each_entry_continue_reverse(client, &device->clients, list)
224
if (client->ops->exit)
225
client->ops->exit(client);
226
227
/* reset client to end of list for late teardown */
228
client = list_entry(&device->clients, struct host1x_client, list);
229
230
teardown_late:
231
list_for_each_entry_continue_reverse(client, &device->clients, list)
232
if (client->ops->late_exit)
233
client->ops->late_exit(client);
234
235
mutex_unlock(&device->clients_lock);
236
return err;
237
}
238
EXPORT_SYMBOL(host1x_device_init);
239
240
/**
241
* host1x_device_exit() - uninitialize host1x logical device
242
* @device: host1x logical device
243
*
244
* When the driver for a host1x logical device is unloaded, it can call this
245
* function to tear down each of its clients. Typically this is done after a
246
* subsystem-specific data structure is removed and the functionality can no
247
* longer be used.
248
*/
249
int host1x_device_exit(struct host1x_device *device)
250
{
251
struct host1x_client *client;
252
int err;
253
254
mutex_lock(&device->clients_lock);
255
256
list_for_each_entry_reverse(client, &device->clients, list) {
257
if (client->ops && client->ops->exit) {
258
err = client->ops->exit(client);
259
if (err < 0) {
260
dev_err(&device->dev,
261
"failed to cleanup %s: %d\n",
262
dev_name(client->dev), err);
263
mutex_unlock(&device->clients_lock);
264
return err;
265
}
266
}
267
}
268
269
list_for_each_entry_reverse(client, &device->clients, list) {
270
if (client->ops && client->ops->late_exit) {
271
err = client->ops->late_exit(client);
272
if (err < 0) {
273
dev_err(&device->dev, "failed to late cleanup %s: %d\n",
274
dev_name(client->dev), err);
275
mutex_unlock(&device->clients_lock);
276
return err;
277
}
278
}
279
}
280
281
mutex_unlock(&device->clients_lock);
282
283
return 0;
284
}
285
EXPORT_SYMBOL(host1x_device_exit);
286
287
static int host1x_add_client(struct host1x *host1x,
288
struct host1x_client *client)
289
{
290
struct host1x_device *device;
291
struct host1x_subdev *subdev;
292
293
mutex_lock(&host1x->devices_lock);
294
295
list_for_each_entry(device, &host1x->devices, list) {
296
list_for_each_entry(subdev, &device->subdevs, list) {
297
if (subdev->np == client->dev->of_node) {
298
host1x_subdev_register(device, subdev, client);
299
mutex_unlock(&host1x->devices_lock);
300
return 0;
301
}
302
}
303
}
304
305
mutex_unlock(&host1x->devices_lock);
306
return -ENODEV;
307
}
308
309
static int host1x_del_client(struct host1x *host1x,
310
struct host1x_client *client)
311
{
312
struct host1x_device *device, *dt;
313
struct host1x_subdev *subdev;
314
315
mutex_lock(&host1x->devices_lock);
316
317
list_for_each_entry_safe(device, dt, &host1x->devices, list) {
318
list_for_each_entry(subdev, &device->active, list) {
319
if (subdev->client == client) {
320
host1x_subdev_unregister(device, subdev);
321
mutex_unlock(&host1x->devices_lock);
322
return 0;
323
}
324
}
325
}
326
327
mutex_unlock(&host1x->devices_lock);
328
return -ENODEV;
329
}
330
331
static int host1x_device_match(struct device *dev, const struct device_driver *drv)
332
{
333
return strcmp(dev_name(dev), drv->name) == 0;
334
}
335
336
/*
337
* Note that this is really only needed for backwards compatibility
338
* with libdrm, which parses this information from sysfs and will
339
* fail if it can't find the OF_FULLNAME, specifically.
340
*/
341
static int host1x_device_uevent(const struct device *dev,
342
struct kobj_uevent_env *env)
343
{
344
of_device_uevent(dev->parent, env);
345
346
return 0;
347
}
348
349
static const struct dev_pm_ops host1x_device_pm_ops = {
350
.suspend = pm_generic_suspend,
351
.resume = pm_generic_resume,
352
.freeze = pm_generic_freeze,
353
.thaw = pm_generic_thaw,
354
.poweroff = pm_generic_poweroff,
355
.restore = pm_generic_restore,
356
};
357
358
const struct bus_type host1x_bus_type = {
359
.name = "host1x",
360
.match = host1x_device_match,
361
.uevent = host1x_device_uevent,
362
.pm = &host1x_device_pm_ops,
363
};
364
365
static void __host1x_device_del(struct host1x_device *device)
366
{
367
struct host1x_subdev *subdev, *sd;
368
struct host1x_client *client, *cl;
369
370
mutex_lock(&device->subdevs_lock);
371
372
/* unregister subdevices */
373
list_for_each_entry_safe(subdev, sd, &device->active, list) {
374
/*
375
* host1x_subdev_unregister() will remove the client from
376
* any lists, so we'll need to manually add it back to the
377
* list of idle clients.
378
*
379
* XXX: Alternatively, perhaps don't remove the client from
380
* any lists in host1x_subdev_unregister() and instead do
381
* that explicitly from host1x_unregister_client()?
382
*/
383
client = subdev->client;
384
385
__host1x_subdev_unregister(device, subdev);
386
387
/* add the client to the list of idle clients */
388
mutex_lock(&clients_lock);
389
list_add_tail(&client->list, &clients);
390
mutex_unlock(&clients_lock);
391
}
392
393
/* remove subdevices */
394
list_for_each_entry_safe(subdev, sd, &device->subdevs, list)
395
host1x_subdev_del(subdev);
396
397
mutex_unlock(&device->subdevs_lock);
398
399
/* move clients to idle list */
400
mutex_lock(&clients_lock);
401
mutex_lock(&device->clients_lock);
402
403
list_for_each_entry_safe(client, cl, &device->clients, list)
404
list_move_tail(&client->list, &clients);
405
406
mutex_unlock(&device->clients_lock);
407
mutex_unlock(&clients_lock);
408
409
/* finally remove the device */
410
list_del_init(&device->list);
411
}
412
413
static void host1x_device_release(struct device *dev)
414
{
415
struct host1x_device *device = to_host1x_device(dev);
416
417
__host1x_device_del(device);
418
kfree(device);
419
}
420
421
static int host1x_device_add(struct host1x *host1x,
422
struct host1x_driver *driver)
423
{
424
struct host1x_client *client, *tmp;
425
struct host1x_subdev *subdev;
426
struct host1x_device *device;
427
int err;
428
429
device = kzalloc(sizeof(*device), GFP_KERNEL);
430
if (!device)
431
return -ENOMEM;
432
433
device_initialize(&device->dev);
434
435
mutex_init(&device->subdevs_lock);
436
INIT_LIST_HEAD(&device->subdevs);
437
INIT_LIST_HEAD(&device->active);
438
mutex_init(&device->clients_lock);
439
INIT_LIST_HEAD(&device->clients);
440
INIT_LIST_HEAD(&device->list);
441
device->driver = driver;
442
443
device->dev.coherent_dma_mask = host1x->dev->coherent_dma_mask;
444
device->dev.dma_mask = &device->dev.coherent_dma_mask;
445
dev_set_name(&device->dev, "%s", driver->driver.name);
446
device->dev.release = host1x_device_release;
447
device->dev.bus = &host1x_bus_type;
448
device->dev.parent = host1x->dev;
449
450
device->dev.dma_parms = &device->dma_parms;
451
dma_set_max_seg_size(&device->dev, UINT_MAX);
452
453
err = host1x_device_parse_dt(device, driver);
454
if (err < 0) {
455
kfree(device);
456
return err;
457
}
458
459
list_add_tail(&device->list, &host1x->devices);
460
461
mutex_lock(&clients_lock);
462
463
list_for_each_entry_safe(client, tmp, &clients, list) {
464
list_for_each_entry(subdev, &device->subdevs, list) {
465
if (subdev->np == client->dev->of_node) {
466
host1x_subdev_register(device, subdev, client);
467
break;
468
}
469
}
470
}
471
472
mutex_unlock(&clients_lock);
473
474
return 0;
475
}
476
477
/*
478
* Removes a device by first unregistering any subdevices and then removing
479
* itself from the list of devices.
480
*
481
* This function must be called with the host1x->devices_lock held.
482
*/
483
static void host1x_device_del(struct host1x *host1x,
484
struct host1x_device *device)
485
{
486
if (device->registered) {
487
device->registered = false;
488
device_del(&device->dev);
489
}
490
491
put_device(&device->dev);
492
}
493
494
static void host1x_attach_driver(struct host1x *host1x,
495
struct host1x_driver *driver)
496
{
497
struct host1x_device *device;
498
int err;
499
500
mutex_lock(&host1x->devices_lock);
501
502
list_for_each_entry(device, &host1x->devices, list) {
503
if (device->driver == driver) {
504
mutex_unlock(&host1x->devices_lock);
505
return;
506
}
507
}
508
509
err = host1x_device_add(host1x, driver);
510
if (err < 0)
511
dev_err(host1x->dev, "failed to allocate device: %d\n", err);
512
513
mutex_unlock(&host1x->devices_lock);
514
}
515
516
static void host1x_detach_driver(struct host1x *host1x,
517
struct host1x_driver *driver)
518
{
519
struct host1x_device *device, *tmp;
520
521
mutex_lock(&host1x->devices_lock);
522
523
list_for_each_entry_safe(device, tmp, &host1x->devices, list)
524
if (device->driver == driver)
525
host1x_device_del(host1x, device);
526
527
mutex_unlock(&host1x->devices_lock);
528
}
529
530
static int host1x_devices_show(struct seq_file *s, void *data)
531
{
532
struct host1x *host1x = s->private;
533
struct host1x_device *device;
534
535
mutex_lock(&host1x->devices_lock);
536
537
list_for_each_entry(device, &host1x->devices, list) {
538
struct host1x_subdev *subdev;
539
540
seq_printf(s, "%s\n", dev_name(&device->dev));
541
542
mutex_lock(&device->subdevs_lock);
543
544
list_for_each_entry(subdev, &device->active, list)
545
seq_printf(s, " %pOFf: %s\n", subdev->np,
546
dev_name(subdev->client->dev));
547
548
list_for_each_entry(subdev, &device->subdevs, list)
549
seq_printf(s, " %pOFf:\n", subdev->np);
550
551
mutex_unlock(&device->subdevs_lock);
552
}
553
554
mutex_unlock(&host1x->devices_lock);
555
556
return 0;
557
}
558
DEFINE_SHOW_ATTRIBUTE(host1x_devices);
559
560
/**
561
* host1x_register() - register a host1x controller
562
* @host1x: host1x controller
563
*
564
* The host1x controller driver uses this to register a host1x controller with
565
* the infrastructure. Note that all Tegra SoC generations have only ever come
566
* with a single host1x instance, so this function is somewhat academic.
567
*/
568
int host1x_register(struct host1x *host1x)
569
{
570
struct host1x_driver *driver;
571
572
mutex_lock(&devices_lock);
573
list_add_tail(&host1x->list, &devices);
574
mutex_unlock(&devices_lock);
575
576
mutex_lock(&drivers_lock);
577
578
list_for_each_entry(driver, &drivers, list)
579
host1x_attach_driver(host1x, driver);
580
581
mutex_unlock(&drivers_lock);
582
583
debugfs_create_file("devices", S_IRUGO, host1x->debugfs, host1x,
584
&host1x_devices_fops);
585
586
return 0;
587
}
588
589
/**
590
* host1x_unregister() - unregister a host1x controller
591
* @host1x: host1x controller
592
*
593
* The host1x controller driver uses this to remove a host1x controller from
594
* the infrastructure.
595
*/
596
int host1x_unregister(struct host1x *host1x)
597
{
598
struct host1x_driver *driver;
599
600
mutex_lock(&drivers_lock);
601
602
list_for_each_entry(driver, &drivers, list)
603
host1x_detach_driver(host1x, driver);
604
605
mutex_unlock(&drivers_lock);
606
607
mutex_lock(&devices_lock);
608
list_del_init(&host1x->list);
609
mutex_unlock(&devices_lock);
610
611
return 0;
612
}
613
614
static int host1x_device_probe(struct device *dev)
615
{
616
struct host1x_driver *driver = to_host1x_driver(dev->driver);
617
struct host1x_device *device = to_host1x_device(dev);
618
619
if (driver->probe)
620
return driver->probe(device);
621
622
return 0;
623
}
624
625
static int host1x_device_remove(struct device *dev)
626
{
627
struct host1x_driver *driver = to_host1x_driver(dev->driver);
628
struct host1x_device *device = to_host1x_device(dev);
629
630
if (driver->remove)
631
return driver->remove(device);
632
633
return 0;
634
}
635
636
static void host1x_device_shutdown(struct device *dev)
637
{
638
struct host1x_driver *driver = to_host1x_driver(dev->driver);
639
struct host1x_device *device = to_host1x_device(dev);
640
641
if (driver->shutdown)
642
driver->shutdown(device);
643
}
644
645
/**
646
* host1x_driver_register_full() - register a host1x driver
647
* @driver: host1x driver
648
* @owner: owner module
649
*
650
* Drivers for host1x logical devices call this function to register a driver
651
* with the infrastructure. Note that since these drive logical devices, the
652
* registration of the driver actually triggers tho logical device creation.
653
* A logical device will be created for each host1x instance.
654
*/
655
int host1x_driver_register_full(struct host1x_driver *driver,
656
struct module *owner)
657
{
658
struct host1x *host1x;
659
660
INIT_LIST_HEAD(&driver->list);
661
662
mutex_lock(&drivers_lock);
663
list_add_tail(&driver->list, &drivers);
664
mutex_unlock(&drivers_lock);
665
666
mutex_lock(&devices_lock);
667
668
list_for_each_entry(host1x, &devices, list)
669
host1x_attach_driver(host1x, driver);
670
671
mutex_unlock(&devices_lock);
672
673
driver->driver.bus = &host1x_bus_type;
674
driver->driver.owner = owner;
675
driver->driver.probe = host1x_device_probe;
676
driver->driver.remove = host1x_device_remove;
677
driver->driver.shutdown = host1x_device_shutdown;
678
679
return driver_register(&driver->driver);
680
}
681
EXPORT_SYMBOL(host1x_driver_register_full);
682
683
/**
684
* host1x_driver_unregister() - unregister a host1x driver
685
* @driver: host1x driver
686
*
687
* Unbinds the driver from each of the host1x logical devices that it is
688
* bound to, effectively removing the subsystem devices that they represent.
689
*/
690
void host1x_driver_unregister(struct host1x_driver *driver)
691
{
692
struct host1x *host1x;
693
694
driver_unregister(&driver->driver);
695
696
mutex_lock(&devices_lock);
697
698
list_for_each_entry(host1x, &devices, list)
699
host1x_detach_driver(host1x, driver);
700
701
mutex_unlock(&devices_lock);
702
703
mutex_lock(&drivers_lock);
704
list_del_init(&driver->list);
705
mutex_unlock(&drivers_lock);
706
}
707
EXPORT_SYMBOL(host1x_driver_unregister);
708
709
/**
710
* __host1x_client_init() - initialize a host1x client
711
* @client: host1x client
712
* @key: lock class key for the client-specific mutex
713
*/
714
void __host1x_client_init(struct host1x_client *client, struct lock_class_key *key)
715
{
716
host1x_bo_cache_init(&client->cache);
717
INIT_LIST_HEAD(&client->list);
718
__mutex_init(&client->lock, "host1x client lock", key);
719
client->usecount = 0;
720
}
721
EXPORT_SYMBOL(__host1x_client_init);
722
723
/**
724
* host1x_client_exit() - uninitialize a host1x client
725
* @client: host1x client
726
*/
727
void host1x_client_exit(struct host1x_client *client)
728
{
729
mutex_destroy(&client->lock);
730
}
731
EXPORT_SYMBOL(host1x_client_exit);
732
733
/**
734
* __host1x_client_register() - register a host1x client
735
* @client: host1x client
736
*
737
* Registers a host1x client with each host1x controller instance. Note that
738
* each client will only match their parent host1x controller and will only be
739
* associated with that instance. Once all clients have been registered with
740
* their parent host1x controller, the infrastructure will set up the logical
741
* device and call host1x_device_init(), which will in turn call each client's
742
* &host1x_client_ops.init implementation.
743
*/
744
int __host1x_client_register(struct host1x_client *client)
745
{
746
struct host1x *host1x;
747
int err;
748
749
mutex_lock(&devices_lock);
750
751
list_for_each_entry(host1x, &devices, list) {
752
err = host1x_add_client(host1x, client);
753
if (!err) {
754
mutex_unlock(&devices_lock);
755
return 0;
756
}
757
}
758
759
mutex_unlock(&devices_lock);
760
761
mutex_lock(&clients_lock);
762
list_add_tail(&client->list, &clients);
763
mutex_unlock(&clients_lock);
764
765
return 0;
766
}
767
EXPORT_SYMBOL(__host1x_client_register);
768
769
/**
770
* host1x_client_unregister() - unregister a host1x client
771
* @client: host1x client
772
*
773
* Removes a host1x client from its host1x controller instance. If a logical
774
* device has already been initialized, it will be torn down.
775
*/
776
void host1x_client_unregister(struct host1x_client *client)
777
{
778
struct host1x_client *c;
779
struct host1x *host1x;
780
int err;
781
782
mutex_lock(&devices_lock);
783
784
list_for_each_entry(host1x, &devices, list) {
785
err = host1x_del_client(host1x, client);
786
if (!err) {
787
mutex_unlock(&devices_lock);
788
return;
789
}
790
}
791
792
mutex_unlock(&devices_lock);
793
mutex_lock(&clients_lock);
794
795
list_for_each_entry(c, &clients, list) {
796
if (c == client) {
797
list_del_init(&c->list);
798
break;
799
}
800
}
801
802
mutex_unlock(&clients_lock);
803
804
host1x_bo_cache_destroy(&client->cache);
805
}
806
EXPORT_SYMBOL(host1x_client_unregister);
807
808
int host1x_client_suspend(struct host1x_client *client)
809
{
810
int err = 0;
811
812
mutex_lock(&client->lock);
813
814
if (client->usecount == 1) {
815
if (client->ops && client->ops->suspend) {
816
err = client->ops->suspend(client);
817
if (err < 0)
818
goto unlock;
819
}
820
}
821
822
client->usecount--;
823
dev_dbg(client->dev, "use count: %u\n", client->usecount);
824
825
if (client->parent) {
826
err = host1x_client_suspend(client->parent);
827
if (err < 0)
828
goto resume;
829
}
830
831
goto unlock;
832
833
resume:
834
if (client->usecount == 0)
835
if (client->ops && client->ops->resume)
836
client->ops->resume(client);
837
838
client->usecount++;
839
unlock:
840
mutex_unlock(&client->lock);
841
return err;
842
}
843
EXPORT_SYMBOL(host1x_client_suspend);
844
845
int host1x_client_resume(struct host1x_client *client)
846
{
847
int err = 0;
848
849
mutex_lock(&client->lock);
850
851
if (client->parent) {
852
err = host1x_client_resume(client->parent);
853
if (err < 0)
854
goto unlock;
855
}
856
857
if (client->usecount == 0) {
858
if (client->ops && client->ops->resume) {
859
err = client->ops->resume(client);
860
if (err < 0)
861
goto suspend;
862
}
863
}
864
865
client->usecount++;
866
dev_dbg(client->dev, "use count: %u\n", client->usecount);
867
868
goto unlock;
869
870
suspend:
871
if (client->parent)
872
host1x_client_suspend(client->parent);
873
unlock:
874
mutex_unlock(&client->lock);
875
return err;
876
}
877
EXPORT_SYMBOL(host1x_client_resume);
878
879
struct host1x_bo_mapping *host1x_bo_pin(struct device *dev, struct host1x_bo *bo,
880
enum dma_data_direction dir,
881
struct host1x_bo_cache *cache)
882
{
883
struct host1x_bo_mapping *mapping;
884
885
if (cache) {
886
mutex_lock(&cache->lock);
887
888
list_for_each_entry(mapping, &cache->mappings, entry) {
889
if (mapping->bo == bo && mapping->direction == dir) {
890
kref_get(&mapping->ref);
891
goto unlock;
892
}
893
}
894
}
895
896
mapping = bo->ops->pin(dev, bo, dir);
897
if (IS_ERR(mapping))
898
goto unlock;
899
900
spin_lock(&mapping->bo->lock);
901
list_add_tail(&mapping->list, &bo->mappings);
902
spin_unlock(&mapping->bo->lock);
903
904
if (cache) {
905
INIT_LIST_HEAD(&mapping->entry);
906
mapping->cache = cache;
907
908
list_add_tail(&mapping->entry, &cache->mappings);
909
910
/* bump reference count to track the copy in the cache */
911
kref_get(&mapping->ref);
912
}
913
914
unlock:
915
if (cache)
916
mutex_unlock(&cache->lock);
917
918
return mapping;
919
}
920
EXPORT_SYMBOL(host1x_bo_pin);
921
922
static void __host1x_bo_unpin(struct kref *ref)
923
{
924
struct host1x_bo_mapping *mapping = to_host1x_bo_mapping(ref);
925
926
/*
927
* When the last reference of the mapping goes away, make sure to remove the mapping from
928
* the cache.
929
*/
930
if (mapping->cache)
931
list_del(&mapping->entry);
932
933
spin_lock(&mapping->bo->lock);
934
list_del(&mapping->list);
935
spin_unlock(&mapping->bo->lock);
936
937
mapping->bo->ops->unpin(mapping);
938
}
939
940
void host1x_bo_unpin(struct host1x_bo_mapping *mapping)
941
{
942
struct host1x_bo_cache *cache = mapping->cache;
943
944
if (cache)
945
mutex_lock(&cache->lock);
946
947
kref_put(&mapping->ref, __host1x_bo_unpin);
948
949
if (cache)
950
mutex_unlock(&cache->lock);
951
}
952
EXPORT_SYMBOL(host1x_bo_unpin);
953
954