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