hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/drivers/gpu/host1x/bus.c
....@@ -1,22 +1,13 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2012 Avionic Design GmbH
34 * 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/>.
165 */
176
7
+#include <linux/debugfs.h>
188 #include <linux/host1x.h>
199 #include <linux/of.h>
10
+#include <linux/seq_file.h>
2011 #include <linux/slab.h>
2112 #include <linux/of_device.h>
2213
....@@ -129,7 +120,7 @@
129120 mutex_lock(&device->clients_lock);
130121 list_move_tail(&client->list, &device->clients);
131122 list_move_tail(&subdev->list, &device->active);
132
- client->parent = &device->dev;
123
+ client->host = &device->dev;
133124 subdev->client = client;
134125 mutex_unlock(&device->clients_lock);
135126 mutex_unlock(&device->subdevs_lock);
....@@ -165,7 +156,7 @@
165156 */
166157 mutex_lock(&device->clients_lock);
167158 subdev->client = NULL;
168
- client->parent = NULL;
159
+ client->host = NULL;
169160 list_move_tail(&subdev->list, &device->subdevs);
170161 /*
171162 * XXX: Perhaps don't do this here, but rather explicitly remove it
....@@ -314,6 +305,36 @@
314305 return strcmp(dev_name(dev), drv->name) == 0;
315306 }
316307
308
+static int host1x_device_uevent(struct device *dev,
309
+ struct kobj_uevent_env *env)
310
+{
311
+ struct device_node *np = dev->parent->of_node;
312
+ unsigned int count = 0;
313
+ struct property *p;
314
+ const char *compat;
315
+
316
+ /*
317
+ * This duplicates most of of_device_uevent(), but the latter cannot
318
+ * be called from modules and operates on dev->of_node, which is not
319
+ * available in this case.
320
+ *
321
+ * Note that this is really only needed for backwards compatibility
322
+ * with libdrm, which parses this information from sysfs and will
323
+ * fail if it can't find the OF_FULLNAME, specifically.
324
+ */
325
+ add_uevent_var(env, "OF_NAME=%pOFn", np);
326
+ add_uevent_var(env, "OF_FULLNAME=%pOF", np);
327
+
328
+ of_property_for_each_string(np, "compatible", p, compat) {
329
+ add_uevent_var(env, "OF_COMPATIBLE_%u=%s", count, compat);
330
+ count++;
331
+ }
332
+
333
+ add_uevent_var(env, "OF_COMPATIBLE_N=%u", count);
334
+
335
+ return 0;
336
+}
337
+
317338 static int host1x_dma_configure(struct device *dev)
318339 {
319340 return of_dma_configure(dev, dev->of_node, true);
....@@ -331,7 +352,8 @@
331352 struct bus_type host1x_bus_type = {
332353 .name = "host1x",
333354 .match = host1x_device_match,
334
- .dma_configure = host1x_dma_configure,
355
+ .uevent = host1x_device_uevent,
356
+ .dma_configure = host1x_dma_configure,
335357 .pm = &host1x_device_pm_ops,
336358 };
337359
....@@ -417,14 +439,13 @@
417439 device->dev.dma_mask = &device->dev.coherent_dma_mask;
418440 dev_set_name(&device->dev, "%s", driver->driver.name);
419441 device->dev.release = host1x_device_release;
420
- device->dev.of_node = host1x->dev->of_node;
421442 device->dev.bus = &host1x_bus_type;
422443 device->dev.parent = host1x->dev;
423444
424445 of_dma_configure(&device->dev, host1x->dev->of_node, true);
425446
426447 device->dev.dma_parms = &device->dma_parms;
427
- dma_set_max_seg_size(&device->dev, SZ_4M);
448
+ dma_set_max_seg_size(&device->dev, UINT_MAX);
428449
429450 err = host1x_device_parse_dt(device, driver);
430451 if (err < 0) {
....@@ -503,6 +524,36 @@
503524 mutex_unlock(&host1x->devices_lock);
504525 }
505526
527
+static int host1x_devices_show(struct seq_file *s, void *data)
528
+{
529
+ struct host1x *host1x = s->private;
530
+ struct host1x_device *device;
531
+
532
+ mutex_lock(&host1x->devices_lock);
533
+
534
+ list_for_each_entry(device, &host1x->devices, list) {
535
+ struct host1x_subdev *subdev;
536
+
537
+ seq_printf(s, "%s\n", dev_name(&device->dev));
538
+
539
+ mutex_lock(&device->subdevs_lock);
540
+
541
+ list_for_each_entry(subdev, &device->active, list)
542
+ seq_printf(s, " %pOFf: %s\n", subdev->np,
543
+ dev_name(subdev->client->dev));
544
+
545
+ list_for_each_entry(subdev, &device->subdevs, list)
546
+ seq_printf(s, " %pOFf:\n", subdev->np);
547
+
548
+ mutex_unlock(&device->subdevs_lock);
549
+ }
550
+
551
+ mutex_unlock(&host1x->devices_lock);
552
+
553
+ return 0;
554
+}
555
+DEFINE_SHOW_ATTRIBUTE(host1x_devices);
556
+
506557 /**
507558 * host1x_register() - register a host1x controller
508559 * @host1x: host1x controller
....@@ -525,6 +576,9 @@
525576 host1x_attach_driver(host1x, driver);
526577
527578 mutex_unlock(&drivers_lock);
579
+
580
+ debugfs_create_file("devices", S_IRUGO, host1x->debugfs, host1x,
581
+ &host1x_devices_fops);
528582
529583 return 0;
530584 }
....@@ -650,8 +704,32 @@
650704 EXPORT_SYMBOL(host1x_driver_unregister);
651705
652706 /**
653
- * host1x_client_register() - register a host1x client
707
+ * __host1x_client_init() - initialize a host1x client
654708 * @client: host1x client
709
+ * @key: lock class key for the client-specific mutex
710
+ */
711
+void __host1x_client_init(struct host1x_client *client, struct lock_class_key *key)
712
+{
713
+ INIT_LIST_HEAD(&client->list);
714
+ __mutex_init(&client->lock, "host1x client lock", key);
715
+ client->usecount = 0;
716
+}
717
+EXPORT_SYMBOL(__host1x_client_init);
718
+
719
+/**
720
+ * host1x_client_exit() - uninitialize a host1x client
721
+ * @client: host1x client
722
+ */
723
+void host1x_client_exit(struct host1x_client *client)
724
+{
725
+ mutex_destroy(&client->lock);
726
+}
727
+EXPORT_SYMBOL(host1x_client_exit);
728
+
729
+/**
730
+ * __host1x_client_register() - register a host1x client
731
+ * @client: host1x client
732
+ * @key: lock class key for the client-specific mutex
655733 *
656734 * Registers a host1x client with each host1x controller instance. Note that
657735 * each client will only match their parent host1x controller and will only be
....@@ -660,7 +738,7 @@
660738 * device and call host1x_device_init(), which will in turn call each client's
661739 * &host1x_client_ops.init implementation.
662740 */
663
-int host1x_client_register(struct host1x_client *client)
741
+int __host1x_client_register(struct host1x_client *client)
664742 {
665743 struct host1x *host1x;
666744 int err;
....@@ -683,7 +761,7 @@
683761
684762 return 0;
685763 }
686
-EXPORT_SYMBOL(host1x_client_register);
764
+EXPORT_SYMBOL(__host1x_client_register);
687765
688766 /**
689767 * host1x_client_unregister() - unregister a host1x client
....@@ -723,3 +801,74 @@
723801 return 0;
724802 }
725803 EXPORT_SYMBOL(host1x_client_unregister);
804
+
805
+int host1x_client_suspend(struct host1x_client *client)
806
+{
807
+ int err = 0;
808
+
809
+ mutex_lock(&client->lock);
810
+
811
+ if (client->usecount == 1) {
812
+ if (client->ops && client->ops->suspend) {
813
+ err = client->ops->suspend(client);
814
+ if (err < 0)
815
+ goto unlock;
816
+ }
817
+ }
818
+
819
+ client->usecount--;
820
+ dev_dbg(client->dev, "use count: %u\n", client->usecount);
821
+
822
+ if (client->parent) {
823
+ err = host1x_client_suspend(client->parent);
824
+ if (err < 0)
825
+ goto resume;
826
+ }
827
+
828
+ goto unlock;
829
+
830
+resume:
831
+ if (client->usecount == 0)
832
+ if (client->ops && client->ops->resume)
833
+ client->ops->resume(client);
834
+
835
+ client->usecount++;
836
+unlock:
837
+ mutex_unlock(&client->lock);
838
+ return err;
839
+}
840
+EXPORT_SYMBOL(host1x_client_suspend);
841
+
842
+int host1x_client_resume(struct host1x_client *client)
843
+{
844
+ int err = 0;
845
+
846
+ mutex_lock(&client->lock);
847
+
848
+ if (client->parent) {
849
+ err = host1x_client_resume(client->parent);
850
+ if (err < 0)
851
+ goto unlock;
852
+ }
853
+
854
+ if (client->usecount == 0) {
855
+ if (client->ops && client->ops->resume) {
856
+ err = client->ops->resume(client);
857
+ if (err < 0)
858
+ goto suspend;
859
+ }
860
+ }
861
+
862
+ client->usecount++;
863
+ dev_dbg(client->dev, "use count: %u\n", client->usecount);
864
+
865
+ goto unlock;
866
+
867
+suspend:
868
+ if (client->parent)
869
+ host1x_client_suspend(client->parent);
870
+unlock:
871
+ mutex_unlock(&client->lock);
872
+ return err;
873
+}
874
+EXPORT_SYMBOL(host1x_client_resume);