root/drivers/gpu/host1x/bus.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. host1x_subdev_add
  2. host1x_subdev_del
  3. host1x_device_parse_dt
  4. host1x_subdev_register
  5. __host1x_subdev_unregister
  6. host1x_subdev_unregister
  7. host1x_device_init
  8. host1x_device_exit
  9. host1x_add_client
  10. host1x_del_client
  11. host1x_device_match
  12. host1x_device_uevent
  13. host1x_dma_configure
  14. __host1x_device_del
  15. host1x_device_release
  16. host1x_device_add
  17. host1x_device_del
  18. host1x_attach_driver
  19. host1x_detach_driver
  20. host1x_devices_show
  21. host1x_register
  22. host1x_unregister
  23. host1x_device_probe
  24. host1x_device_remove
  25. host1x_device_shutdown
  26. host1x_driver_register_full
  27. host1x_driver_unregister
  28. host1x_client_register
  29. host1x_client_unregister

   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/host1x.h>
   9 #include <linux/of.h>
  10 #include <linux/seq_file.h>
  11 #include <linux/slab.h>
  12 #include <linux/of_device.h>
  13 
  14 #include "bus.h"
  15 #include "dev.h"
  16 
  17 static DEFINE_MUTEX(clients_lock);
  18 static LIST_HEAD(clients);
  19 
  20 static DEFINE_MUTEX(drivers_lock);
  21 static LIST_HEAD(drivers);
  22 
  23 static DEFINE_MUTEX(devices_lock);
  24 static LIST_HEAD(devices);
  25 
  26 struct host1x_subdev {
  27         struct host1x_client *client;
  28         struct device_node *np;
  29         struct list_head list;
  30 };
  31 
  32 /**
  33  * host1x_subdev_add() - add a new subdevice with an associated device node
  34  * @device: host1x device to add the subdevice to
  35  * @np: device node
  36  */
  37 static int host1x_subdev_add(struct host1x_device *device,
  38                              struct host1x_driver *driver,
  39                              struct device_node *np)
  40 {
  41         struct host1x_subdev *subdev;
  42         struct device_node *child;
  43         int err;
  44 
  45         subdev = kzalloc(sizeof(*subdev), GFP_KERNEL);
  46         if (!subdev)
  47                 return -ENOMEM;
  48 
  49         INIT_LIST_HEAD(&subdev->list);
  50         subdev->np = of_node_get(np);
  51 
  52         mutex_lock(&device->subdevs_lock);
  53         list_add_tail(&subdev->list, &device->subdevs);
  54         mutex_unlock(&device->subdevs_lock);
  55 
  56         /* recursively add children */
  57         for_each_child_of_node(np, child) {
  58                 if (of_match_node(driver->subdevs, child) &&
  59                     of_device_is_available(child)) {
  60                         err = host1x_subdev_add(device, driver, child);
  61                         if (err < 0) {
  62                                 /* XXX cleanup? */
  63                                 of_node_put(child);
  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         struct device_node *np;
  92         int err;
  93 
  94         for_each_child_of_node(device->dev.parent->of_node, np) {
  95                 if (of_match_node(driver->subdevs, np) &&
  96                     of_device_is_available(np)) {
  97                         err = host1x_subdev_add(device, driver, np);
  98                         if (err < 0) {
  99                                 of_node_put(np);
 100                                 return err;
 101                         }
 102                 }
 103         }
 104 
 105         return 0;
 106 }
 107 
 108 static void host1x_subdev_register(struct host1x_device *device,
 109                                    struct host1x_subdev *subdev,
 110                                    struct host1x_client *client)
 111 {
 112         int err;
 113 
 114         /*
 115          * Move the subdevice to the list of active (registered) subdevices
 116          * and associate it with a client. At the same time, associate the
 117          * client with its parent device.
 118          */
 119         mutex_lock(&device->subdevs_lock);
 120         mutex_lock(&device->clients_lock);
 121         list_move_tail(&client->list, &device->clients);
 122         list_move_tail(&subdev->list, &device->active);
 123         client->parent = &device->dev;
 124         subdev->client = client;
 125         mutex_unlock(&device->clients_lock);
 126         mutex_unlock(&device->subdevs_lock);
 127 
 128         if (list_empty(&device->subdevs)) {
 129                 err = device_add(&device->dev);
 130                 if (err < 0)
 131                         dev_err(&device->dev, "failed to add: %d\n", err);
 132                 else
 133                         device->registered = true;
 134         }
 135 }
 136 
 137 static void __host1x_subdev_unregister(struct host1x_device *device,
 138                                        struct host1x_subdev *subdev)
 139 {
 140         struct host1x_client *client = subdev->client;
 141 
 142         /*
 143          * If all subdevices have been activated, we're about to remove the
 144          * first active subdevice, so unload the driver first.
 145          */
 146         if (list_empty(&device->subdevs)) {
 147                 if (device->registered) {
 148                         device->registered = false;
 149                         device_del(&device->dev);
 150                 }
 151         }
 152 
 153         /*
 154          * Move the subdevice back to the list of idle subdevices and remove
 155          * it from list of clients.
 156          */
 157         mutex_lock(&device->clients_lock);
 158         subdev->client = NULL;
 159         client->parent = NULL;
 160         list_move_tail(&subdev->list, &device->subdevs);
 161         /*
 162          * XXX: Perhaps don't do this here, but rather explicitly remove it
 163          * when the device is about to be deleted.
 164          *
 165          * This is somewhat complicated by the fact that this function is
 166          * used to remove the subdevice when a client is unregistered but
 167          * also when the composite device is about to be removed.
 168          */
 169         list_del_init(&client->list);
 170         mutex_unlock(&device->clients_lock);
 171 }
 172 
 173 static void host1x_subdev_unregister(struct host1x_device *device,
 174                                      struct host1x_subdev *subdev)
 175 {
 176         mutex_lock(&device->subdevs_lock);
 177         __host1x_subdev_unregister(device, subdev);
 178         mutex_unlock(&device->subdevs_lock);
 179 }
 180 
 181 /**
 182  * host1x_device_init() - initialize a host1x logical device
 183  * @device: host1x logical device
 184  *
 185  * The driver for the host1x logical device can call this during execution of
 186  * its &host1x_driver.probe implementation to initialize each of its clients.
 187  * The client drivers access the subsystem specific driver data using the
 188  * &host1x_client.parent field and driver data associated with it (usually by
 189  * calling dev_get_drvdata()).
 190  */
 191 int host1x_device_init(struct host1x_device *device)
 192 {
 193         struct host1x_client *client;
 194         int err;
 195 
 196         mutex_lock(&device->clients_lock);
 197 
 198         list_for_each_entry(client, &device->clients, list) {
 199                 if (client->ops && client->ops->init) {
 200                         err = client->ops->init(client);
 201                         if (err < 0) {
 202                                 dev_err(&device->dev,
 203                                         "failed to initialize %s: %d\n",
 204                                         dev_name(client->dev), err);
 205                                 goto teardown;
 206                         }
 207                 }
 208         }
 209 
 210         mutex_unlock(&device->clients_lock);
 211 
 212         return 0;
 213 
 214 teardown:
 215         list_for_each_entry_continue_reverse(client, &device->clients, list)
 216                 if (client->ops->exit)
 217                         client->ops->exit(client);
 218 
 219         mutex_unlock(&device->clients_lock);
 220         return err;
 221 }
 222 EXPORT_SYMBOL(host1x_device_init);
 223 
 224 /**
 225  * host1x_device_exit() - uninitialize host1x logical device
 226  * @device: host1x logical device
 227  *
 228  * When the driver for a host1x logical device is unloaded, it can call this
 229  * function to tear down each of its clients. Typically this is done after a
 230  * subsystem-specific data structure is removed and the functionality can no
 231  * longer be used.
 232  */
 233 int host1x_device_exit(struct host1x_device *device)
 234 {
 235         struct host1x_client *client;
 236         int err;
 237 
 238         mutex_lock(&device->clients_lock);
 239 
 240         list_for_each_entry_reverse(client, &device->clients, list) {
 241                 if (client->ops && client->ops->exit) {
 242                         err = client->ops->exit(client);
 243                         if (err < 0) {
 244                                 dev_err(&device->dev,
 245                                         "failed to cleanup %s: %d\n",
 246                                         dev_name(client->dev), err);
 247                                 mutex_unlock(&device->clients_lock);
 248                                 return err;
 249                         }
 250                 }
 251         }
 252 
 253         mutex_unlock(&device->clients_lock);
 254 
 255         return 0;
 256 }
 257 EXPORT_SYMBOL(host1x_device_exit);
 258 
 259 static int host1x_add_client(struct host1x *host1x,
 260                              struct host1x_client *client)
 261 {
 262         struct host1x_device *device;
 263         struct host1x_subdev *subdev;
 264 
 265         mutex_lock(&host1x->devices_lock);
 266 
 267         list_for_each_entry(device, &host1x->devices, list) {
 268                 list_for_each_entry(subdev, &device->subdevs, list) {
 269                         if (subdev->np == client->dev->of_node) {
 270                                 host1x_subdev_register(device, subdev, client);
 271                                 mutex_unlock(&host1x->devices_lock);
 272                                 return 0;
 273                         }
 274                 }
 275         }
 276 
 277         mutex_unlock(&host1x->devices_lock);
 278         return -ENODEV;
 279 }
 280 
 281 static int host1x_del_client(struct host1x *host1x,
 282                              struct host1x_client *client)
 283 {
 284         struct host1x_device *device, *dt;
 285         struct host1x_subdev *subdev;
 286 
 287         mutex_lock(&host1x->devices_lock);
 288 
 289         list_for_each_entry_safe(device, dt, &host1x->devices, list) {
 290                 list_for_each_entry(subdev, &device->active, list) {
 291                         if (subdev->client == client) {
 292                                 host1x_subdev_unregister(device, subdev);
 293                                 mutex_unlock(&host1x->devices_lock);
 294                                 return 0;
 295                         }
 296                 }
 297         }
 298 
 299         mutex_unlock(&host1x->devices_lock);
 300         return -ENODEV;
 301 }
 302 
 303 static int host1x_device_match(struct device *dev, struct device_driver *drv)
 304 {
 305         return strcmp(dev_name(dev), drv->name) == 0;
 306 }
 307 
 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 
 338 static int host1x_dma_configure(struct device *dev)
 339 {
 340         return of_dma_configure(dev, dev->of_node, true);
 341 }
 342 
 343 static const struct dev_pm_ops host1x_device_pm_ops = {
 344         .suspend = pm_generic_suspend,
 345         .resume = pm_generic_resume,
 346         .freeze = pm_generic_freeze,
 347         .thaw = pm_generic_thaw,
 348         .poweroff = pm_generic_poweroff,
 349         .restore = pm_generic_restore,
 350 };
 351 
 352 struct bus_type host1x_bus_type = {
 353         .name = "host1x",
 354         .match = host1x_device_match,
 355         .uevent = host1x_device_uevent,
 356         .dma_configure = host1x_dma_configure,
 357         .pm = &host1x_device_pm_ops,
 358 };
 359 
 360 static void __host1x_device_del(struct host1x_device *device)
 361 {
 362         struct host1x_subdev *subdev, *sd;
 363         struct host1x_client *client, *cl;
 364 
 365         mutex_lock(&device->subdevs_lock);
 366 
 367         /* unregister subdevices */
 368         list_for_each_entry_safe(subdev, sd, &device->active, list) {
 369                 /*
 370                  * host1x_subdev_unregister() will remove the client from
 371                  * any lists, so we'll need to manually add it back to the
 372                  * list of idle clients.
 373                  *
 374                  * XXX: Alternatively, perhaps don't remove the client from
 375                  * any lists in host1x_subdev_unregister() and instead do
 376                  * that explicitly from host1x_unregister_client()?
 377                  */
 378                 client = subdev->client;
 379 
 380                 __host1x_subdev_unregister(device, subdev);
 381 
 382                 /* add the client to the list of idle clients */
 383                 mutex_lock(&clients_lock);
 384                 list_add_tail(&client->list, &clients);
 385                 mutex_unlock(&clients_lock);
 386         }
 387 
 388         /* remove subdevices */
 389         list_for_each_entry_safe(subdev, sd, &device->subdevs, list)
 390                 host1x_subdev_del(subdev);
 391 
 392         mutex_unlock(&device->subdevs_lock);
 393 
 394         /* move clients to idle list */
 395         mutex_lock(&clients_lock);
 396         mutex_lock(&device->clients_lock);
 397 
 398         list_for_each_entry_safe(client, cl, &device->clients, list)
 399                 list_move_tail(&client->list, &clients);
 400 
 401         mutex_unlock(&device->clients_lock);
 402         mutex_unlock(&clients_lock);
 403 
 404         /* finally remove the device */
 405         list_del_init(&device->list);
 406 }
 407 
 408 static void host1x_device_release(struct device *dev)
 409 {
 410         struct host1x_device *device = to_host1x_device(dev);
 411 
 412         __host1x_device_del(device);
 413         kfree(device);
 414 }
 415 
 416 static int host1x_device_add(struct host1x *host1x,
 417                              struct host1x_driver *driver)
 418 {
 419         struct host1x_client *client, *tmp;
 420         struct host1x_subdev *subdev;
 421         struct host1x_device *device;
 422         int err;
 423 
 424         device = kzalloc(sizeof(*device), GFP_KERNEL);
 425         if (!device)
 426                 return -ENOMEM;
 427 
 428         device_initialize(&device->dev);
 429 
 430         mutex_init(&device->subdevs_lock);
 431         INIT_LIST_HEAD(&device->subdevs);
 432         INIT_LIST_HEAD(&device->active);
 433         mutex_init(&device->clients_lock);
 434         INIT_LIST_HEAD(&device->clients);
 435         INIT_LIST_HEAD(&device->list);
 436         device->driver = driver;
 437 
 438         device->dev.coherent_dma_mask = host1x->dev->coherent_dma_mask;
 439         device->dev.dma_mask = &device->dev.coherent_dma_mask;
 440         dev_set_name(&device->dev, "%s", driver->driver.name);
 441         device->dev.release = host1x_device_release;
 442         device->dev.bus = &host1x_bus_type;
 443         device->dev.parent = host1x->dev;
 444 
 445         of_dma_configure(&device->dev, host1x->dev->of_node, true);
 446 
 447         device->dev.dma_parms = &device->dma_parms;
 448         dma_set_max_seg_size(&device->dev, SZ_4M);
 449 
 450         err = host1x_device_parse_dt(device, driver);
 451         if (err < 0) {
 452                 kfree(device);
 453                 return err;
 454         }
 455 
 456         list_add_tail(&device->list, &host1x->devices);
 457 
 458         mutex_lock(&clients_lock);
 459 
 460         list_for_each_entry_safe(client, tmp, &clients, list) {
 461                 list_for_each_entry(subdev, &device->subdevs, list) {
 462                         if (subdev->np == client->dev->of_node) {
 463                                 host1x_subdev_register(device, subdev, client);
 464                                 break;
 465                         }
 466                 }
 467         }
 468 
 469         mutex_unlock(&clients_lock);
 470 
 471         return 0;
 472 }
 473 
 474 /*
 475  * Removes a device by first unregistering any subdevices and then removing
 476  * itself from the list of devices.
 477  *
 478  * This function must be called with the host1x->devices_lock held.
 479  */
 480 static void host1x_device_del(struct host1x *host1x,
 481                               struct host1x_device *device)
 482 {
 483         if (device->registered) {
 484                 device->registered = false;
 485                 device_del(&device->dev);
 486         }
 487 
 488         put_device(&device->dev);
 489 }
 490 
 491 static void host1x_attach_driver(struct host1x *host1x,
 492                                  struct host1x_driver *driver)
 493 {
 494         struct host1x_device *device;
 495         int err;
 496 
 497         mutex_lock(&host1x->devices_lock);
 498 
 499         list_for_each_entry(device, &host1x->devices, list) {
 500                 if (device->driver == driver) {
 501                         mutex_unlock(&host1x->devices_lock);
 502                         return;
 503                 }
 504         }
 505 
 506         err = host1x_device_add(host1x, driver);
 507         if (err < 0)
 508                 dev_err(host1x->dev, "failed to allocate device: %d\n", err);
 509 
 510         mutex_unlock(&host1x->devices_lock);
 511 }
 512 
 513 static void host1x_detach_driver(struct host1x *host1x,
 514                                  struct host1x_driver *driver)
 515 {
 516         struct host1x_device *device, *tmp;
 517 
 518         mutex_lock(&host1x->devices_lock);
 519 
 520         list_for_each_entry_safe(device, tmp, &host1x->devices, list)
 521                 if (device->driver == driver)
 522                         host1x_device_del(host1x, device);
 523 
 524         mutex_unlock(&host1x->devices_lock);
 525 }
 526 
 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 
 557 /**
 558  * host1x_register() - register a host1x controller
 559  * @host1x: host1x controller
 560  *
 561  * The host1x controller driver uses this to register a host1x controller with
 562  * the infrastructure. Note that all Tegra SoC generations have only ever come
 563  * with a single host1x instance, so this function is somewhat academic.
 564  */
 565 int host1x_register(struct host1x *host1x)
 566 {
 567         struct host1x_driver *driver;
 568 
 569         mutex_lock(&devices_lock);
 570         list_add_tail(&host1x->list, &devices);
 571         mutex_unlock(&devices_lock);
 572 
 573         mutex_lock(&drivers_lock);
 574 
 575         list_for_each_entry(driver, &drivers, list)
 576                 host1x_attach_driver(host1x, driver);
 577 
 578         mutex_unlock(&drivers_lock);
 579 
 580         debugfs_create_file("devices", S_IRUGO, host1x->debugfs, host1x,
 581                             &host1x_devices_fops);
 582 
 583         return 0;
 584 }
 585 
 586 /**
 587  * host1x_unregister() - unregister a host1x controller
 588  * @host1x: host1x controller
 589  *
 590  * The host1x controller driver uses this to remove a host1x controller from
 591  * the infrastructure.
 592  */
 593 int host1x_unregister(struct host1x *host1x)
 594 {
 595         struct host1x_driver *driver;
 596 
 597         mutex_lock(&drivers_lock);
 598 
 599         list_for_each_entry(driver, &drivers, list)
 600                 host1x_detach_driver(host1x, driver);
 601 
 602         mutex_unlock(&drivers_lock);
 603 
 604         mutex_lock(&devices_lock);
 605         list_del_init(&host1x->list);
 606         mutex_unlock(&devices_lock);
 607 
 608         return 0;
 609 }
 610 
 611 static int host1x_device_probe(struct device *dev)
 612 {
 613         struct host1x_driver *driver = to_host1x_driver(dev->driver);
 614         struct host1x_device *device = to_host1x_device(dev);
 615 
 616         if (driver->probe)
 617                 return driver->probe(device);
 618 
 619         return 0;
 620 }
 621 
 622 static int host1x_device_remove(struct device *dev)
 623 {
 624         struct host1x_driver *driver = to_host1x_driver(dev->driver);
 625         struct host1x_device *device = to_host1x_device(dev);
 626 
 627         if (driver->remove)
 628                 return driver->remove(device);
 629 
 630         return 0;
 631 }
 632 
 633 static void host1x_device_shutdown(struct device *dev)
 634 {
 635         struct host1x_driver *driver = to_host1x_driver(dev->driver);
 636         struct host1x_device *device = to_host1x_device(dev);
 637 
 638         if (driver->shutdown)
 639                 driver->shutdown(device);
 640 }
 641 
 642 /**
 643  * host1x_driver_register_full() - register a host1x driver
 644  * @driver: host1x driver
 645  * @owner: owner module
 646  *
 647  * Drivers for host1x logical devices call this function to register a driver
 648  * with the infrastructure. Note that since these drive logical devices, the
 649  * registration of the driver actually triggers tho logical device creation.
 650  * A logical device will be created for each host1x instance.
 651  */
 652 int host1x_driver_register_full(struct host1x_driver *driver,
 653                                 struct module *owner)
 654 {
 655         struct host1x *host1x;
 656 
 657         INIT_LIST_HEAD(&driver->list);
 658 
 659         mutex_lock(&drivers_lock);
 660         list_add_tail(&driver->list, &drivers);
 661         mutex_unlock(&drivers_lock);
 662 
 663         mutex_lock(&devices_lock);
 664 
 665         list_for_each_entry(host1x, &devices, list)
 666                 host1x_attach_driver(host1x, driver);
 667 
 668         mutex_unlock(&devices_lock);
 669 
 670         driver->driver.bus = &host1x_bus_type;
 671         driver->driver.owner = owner;
 672         driver->driver.probe = host1x_device_probe;
 673         driver->driver.remove = host1x_device_remove;
 674         driver->driver.shutdown = host1x_device_shutdown;
 675 
 676         return driver_register(&driver->driver);
 677 }
 678 EXPORT_SYMBOL(host1x_driver_register_full);
 679 
 680 /**
 681  * host1x_driver_unregister() - unregister a host1x driver
 682  * @driver: host1x driver
 683  *
 684  * Unbinds the driver from each of the host1x logical devices that it is
 685  * bound to, effectively removing the subsystem devices that they represent.
 686  */
 687 void host1x_driver_unregister(struct host1x_driver *driver)
 688 {
 689         driver_unregister(&driver->driver);
 690 
 691         mutex_lock(&drivers_lock);
 692         list_del_init(&driver->list);
 693         mutex_unlock(&drivers_lock);
 694 }
 695 EXPORT_SYMBOL(host1x_driver_unregister);
 696 
 697 /**
 698  * host1x_client_register() - register a host1x client
 699  * @client: host1x client
 700  *
 701  * Registers a host1x client with each host1x controller instance. Note that
 702  * each client will only match their parent host1x controller and will only be
 703  * associated with that instance. Once all clients have been registered with
 704  * their parent host1x controller, the infrastructure will set up the logical
 705  * device and call host1x_device_init(), which will in turn call each client's
 706  * &host1x_client_ops.init implementation.
 707  */
 708 int host1x_client_register(struct host1x_client *client)
 709 {
 710         struct host1x *host1x;
 711         int err;
 712 
 713         mutex_lock(&devices_lock);
 714 
 715         list_for_each_entry(host1x, &devices, list) {
 716                 err = host1x_add_client(host1x, client);
 717                 if (!err) {
 718                         mutex_unlock(&devices_lock);
 719                         return 0;
 720                 }
 721         }
 722 
 723         mutex_unlock(&devices_lock);
 724 
 725         mutex_lock(&clients_lock);
 726         list_add_tail(&client->list, &clients);
 727         mutex_unlock(&clients_lock);
 728 
 729         return 0;
 730 }
 731 EXPORT_SYMBOL(host1x_client_register);
 732 
 733 /**
 734  * host1x_client_unregister() - unregister a host1x client
 735  * @client: host1x client
 736  *
 737  * Removes a host1x client from its host1x controller instance. If a logical
 738  * device has already been initialized, it will be torn down.
 739  */
 740 int host1x_client_unregister(struct host1x_client *client)
 741 {
 742         struct host1x_client *c;
 743         struct host1x *host1x;
 744         int err;
 745 
 746         mutex_lock(&devices_lock);
 747 
 748         list_for_each_entry(host1x, &devices, list) {
 749                 err = host1x_del_client(host1x, client);
 750                 if (!err) {
 751                         mutex_unlock(&devices_lock);
 752                         return 0;
 753                 }
 754         }
 755 
 756         mutex_unlock(&devices_lock);
 757         mutex_lock(&clients_lock);
 758 
 759         list_for_each_entry(c, &clients, list) {
 760                 if (c == client) {
 761                         list_del_init(&c->list);
 762                         break;
 763                 }
 764         }
 765 
 766         mutex_unlock(&clients_lock);
 767 
 768         return 0;
 769 }
 770 EXPORT_SYMBOL(host1x_client_unregister);

/* [<][>][^][v][top][bottom][index][help] */