linux/drivers/gpu/host1x/bus.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2012 Avionic Design GmbH
   3 * Copyright (C) 2012-2013, NVIDIA Corporation
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms and conditions of the GNU General Public License,
   7 * version 2, as published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12 * more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  16 */
  17
  18#include <linux/host1x.h>
  19#include <linux/of.h>
  20#include <linux/slab.h>
  21#include <linux/of_device.h>
  22
  23#include "bus.h"
  24#include "dev.h"
  25
  26static DEFINE_MUTEX(clients_lock);
  27static LIST_HEAD(clients);
  28
  29static DEFINE_MUTEX(drivers_lock);
  30static LIST_HEAD(drivers);
  31
  32static DEFINE_MUTEX(devices_lock);
  33static LIST_HEAD(devices);
  34
  35struct host1x_subdev {
  36        struct host1x_client *client;
  37        struct device_node *np;
  38        struct list_head list;
  39};
  40
  41/**
  42 * host1x_subdev_add() - add a new subdevice with an associated device node
  43 * @device: host1x device to add the subdevice to
  44 * @driver: host1x driver
  45 * @np: device node
  46 */
  47static int host1x_subdev_add(struct host1x_device *device,
  48                             struct device_node *np)
  49{
  50        struct host1x_subdev *subdev;
  51
  52        subdev = kzalloc(sizeof(*subdev), GFP_KERNEL);
  53        if (!subdev)
  54                return -ENOMEM;
  55
  56        INIT_LIST_HEAD(&subdev->list);
  57        subdev->np = of_node_get(np);
  58
  59        mutex_lock(&device->subdevs_lock);
  60        list_add_tail(&subdev->list, &device->subdevs);
  61        mutex_unlock(&device->subdevs_lock);
  62
  63        return 0;
  64}
  65
  66/**
  67 * host1x_subdev_del() - remove subdevice
  68 * @subdev: subdevice to remove
  69 */
  70static void host1x_subdev_del(struct host1x_subdev *subdev)
  71{
  72        list_del(&subdev->list);
  73        of_node_put(subdev->np);
  74        kfree(subdev);
  75}
  76
  77/**
  78 * host1x_device_parse_dt() - scan device tree and add matching subdevices
  79 * @device: host1x logical device
  80 * @driver: host1x driver
  81 */
  82static int host1x_device_parse_dt(struct host1x_device *device,
  83                                  struct host1x_driver *driver)
  84{
  85        struct device_node *np;
  86        int err;
  87
  88        for_each_child_of_node(device->dev.parent->of_node, np) {
  89                if (of_match_node(driver->subdevs, np) &&
  90                    of_device_is_available(np)) {
  91                        err = host1x_subdev_add(device, np);
  92                        if (err < 0) {
  93                                of_node_put(np);
  94                                return err;
  95                        }
  96                }
  97        }
  98
  99        return 0;
 100}
 101
 102static void host1x_subdev_register(struct host1x_device *device,
 103                                   struct host1x_subdev *subdev,
 104                                   struct host1x_client *client)
 105{
 106        int err;
 107
 108        /*
 109         * Move the subdevice to the list of active (registered) subdevices
 110         * and associate it with a client. At the same time, associate the
 111         * client with its parent device.
 112         */
 113        mutex_lock(&device->subdevs_lock);
 114        mutex_lock(&device->clients_lock);
 115        list_move_tail(&client->list, &device->clients);
 116        list_move_tail(&subdev->list, &device->active);
 117        client->parent = &device->dev;
 118        subdev->client = client;
 119        mutex_unlock(&device->clients_lock);
 120        mutex_unlock(&device->subdevs_lock);
 121
 122        if (list_empty(&device->subdevs)) {
 123                err = device_add(&device->dev);
 124                if (err < 0)
 125                        dev_err(&device->dev, "failed to add: %d\n", err);
 126                else
 127                        device->registered = true;
 128        }
 129}
 130
 131static void __host1x_subdev_unregister(struct host1x_device *device,
 132                                       struct host1x_subdev *subdev)
 133{
 134        struct host1x_client *client = subdev->client;
 135
 136        /*
 137         * If all subdevices have been activated, we're about to remove the
 138         * first active subdevice, so unload the driver first.
 139         */
 140        if (list_empty(&device->subdevs)) {
 141                if (device->registered) {
 142                        device->registered = false;
 143                        device_del(&device->dev);
 144                }
 145        }
 146
 147        /*
 148         * Move the subdevice back to the list of idle subdevices and remove
 149         * it from list of clients.
 150         */
 151        mutex_lock(&device->clients_lock);
 152        subdev->client = NULL;
 153        client->parent = NULL;
 154        list_move_tail(&subdev->list, &device->subdevs);
 155        /*
 156         * XXX: Perhaps don't do this here, but rather explicitly remove it
 157         * when the device is about to be deleted.
 158         *
 159         * This is somewhat complicated by the fact that this function is
 160         * used to remove the subdevice when a client is unregistered but
 161         * also when the composite device is about to be removed.
 162         */
 163        list_del_init(&client->list);
 164        mutex_unlock(&device->clients_lock);
 165}
 166
 167static void host1x_subdev_unregister(struct host1x_device *device,
 168                                     struct host1x_subdev *subdev)
 169{
 170        mutex_lock(&device->subdevs_lock);
 171        __host1x_subdev_unregister(device, subdev);
 172        mutex_unlock(&device->subdevs_lock);
 173}
 174
 175/**
 176 * host1x_device_init() - initialize a host1x logical device
 177 * @device: host1x logical device
 178 *
 179 * The driver for the host1x logical device can call this during execution of
 180 * its &host1x_driver.probe implementation to initialize each of its clients.
 181 * The client drivers access the subsystem specific driver data using the
 182 * &host1x_client.parent field and driver data associated with it (usually by
 183 * calling dev_get_drvdata()).
 184 */
 185int host1x_device_init(struct host1x_device *device)
 186{
 187        struct host1x_client *client;
 188        int err;
 189
 190        mutex_lock(&device->clients_lock);
 191
 192        list_for_each_entry(client, &device->clients, list) {
 193                if (client->ops && client->ops->init) {
 194                        err = client->ops->init(client);
 195                        if (err < 0) {
 196                                dev_err(&device->dev,
 197                                        "failed to initialize %s: %d\n",
 198                                        dev_name(client->dev), err);
 199                                mutex_unlock(&device->clients_lock);
 200                                return err;
 201                        }
 202                }
 203        }
 204
 205        mutex_unlock(&device->clients_lock);
 206
 207        return 0;
 208}
 209EXPORT_SYMBOL(host1x_device_init);
 210
 211/**
 212 * host1x_device_exit() - uninitialize host1x logical device
 213 * @device: host1x logical device
 214 *
 215 * When the driver for a host1x logical device is unloaded, it can call this
 216 * function to tear down each of its clients. Typically this is done after a
 217 * subsystem-specific data structure is removed and the functionality can no
 218 * longer be used.
 219 */
 220int host1x_device_exit(struct host1x_device *device)
 221{
 222        struct host1x_client *client;
 223        int err;
 224
 225        mutex_lock(&device->clients_lock);
 226
 227        list_for_each_entry_reverse(client, &device->clients, list) {
 228                if (client->ops && client->ops->exit) {
 229                        err = client->ops->exit(client);
 230                        if (err < 0) {
 231                                dev_err(&device->dev,
 232                                        "failed to cleanup %s: %d\n",
 233                                        dev_name(client->dev), err);
 234                                mutex_unlock(&device->clients_lock);
 235                                return err;
 236                        }
 237                }
 238        }
 239
 240        mutex_unlock(&device->clients_lock);
 241
 242        return 0;
 243}
 244EXPORT_SYMBOL(host1x_device_exit);
 245
 246static int host1x_add_client(struct host1x *host1x,
 247                             struct host1x_client *client)
 248{
 249        struct host1x_device *device;
 250        struct host1x_subdev *subdev;
 251
 252        mutex_lock(&host1x->devices_lock);
 253
 254        list_for_each_entry(device, &host1x->devices, list) {
 255                list_for_each_entry(subdev, &device->subdevs, list) {
 256                        if (subdev->np == client->dev->of_node) {
 257                                host1x_subdev_register(device, subdev, client);
 258                                mutex_unlock(&host1x->devices_lock);
 259                                return 0;
 260                        }
 261                }
 262        }
 263
 264        mutex_unlock(&host1x->devices_lock);
 265        return -ENODEV;
 266}
 267
 268static int host1x_del_client(struct host1x *host1x,
 269                             struct host1x_client *client)
 270{
 271        struct host1x_device *device, *dt;
 272        struct host1x_subdev *subdev;
 273
 274        mutex_lock(&host1x->devices_lock);
 275
 276        list_for_each_entry_safe(device, dt, &host1x->devices, list) {
 277                list_for_each_entry(subdev, &device->active, list) {
 278                        if (subdev->client == client) {
 279                                host1x_subdev_unregister(device, subdev);
 280                                mutex_unlock(&host1x->devices_lock);
 281                                return 0;
 282                        }
 283                }
 284        }
 285
 286        mutex_unlock(&host1x->devices_lock);
 287        return -ENODEV;
 288}
 289
 290static int host1x_device_match(struct device *dev, struct device_driver *drv)
 291{
 292        return strcmp(dev_name(dev), drv->name) == 0;
 293}
 294
 295static const struct dev_pm_ops host1x_device_pm_ops = {
 296        .suspend = pm_generic_suspend,
 297        .resume = pm_generic_resume,
 298        .freeze = pm_generic_freeze,
 299        .thaw = pm_generic_thaw,
 300        .poweroff = pm_generic_poweroff,
 301        .restore = pm_generic_restore,
 302};
 303
 304struct bus_type host1x_bus_type = {
 305        .name = "host1x",
 306        .match = host1x_device_match,
 307        .pm = &host1x_device_pm_ops,
 308};
 309
 310static void __host1x_device_del(struct host1x_device *device)
 311{
 312        struct host1x_subdev *subdev, *sd;
 313        struct host1x_client *client, *cl;
 314
 315        mutex_lock(&device->subdevs_lock);
 316
 317        /* unregister subdevices */
 318        list_for_each_entry_safe(subdev, sd, &device->active, list) {
 319                /*
 320                 * host1x_subdev_unregister() will remove the client from
 321                 * any lists, so we'll need to manually add it back to the
 322                 * list of idle clients.
 323                 *
 324                 * XXX: Alternatively, perhaps don't remove the client from
 325                 * any lists in host1x_subdev_unregister() and instead do
 326                 * that explicitly from host1x_unregister_client()?
 327                 */
 328                client = subdev->client;
 329
 330                __host1x_subdev_unregister(device, subdev);
 331
 332                /* add the client to the list of idle clients */
 333                mutex_lock(&clients_lock);
 334                list_add_tail(&client->list, &clients);
 335                mutex_unlock(&clients_lock);
 336        }
 337
 338        /* remove subdevices */
 339        list_for_each_entry_safe(subdev, sd, &device->subdevs, list)
 340                host1x_subdev_del(subdev);
 341
 342        mutex_unlock(&device->subdevs_lock);
 343
 344        /* move clients to idle list */
 345        mutex_lock(&clients_lock);
 346        mutex_lock(&device->clients_lock);
 347
 348        list_for_each_entry_safe(client, cl, &device->clients, list)
 349                list_move_tail(&client->list, &clients);
 350
 351        mutex_unlock(&device->clients_lock);
 352        mutex_unlock(&clients_lock);
 353
 354        /* finally remove the device */
 355        list_del_init(&device->list);
 356}
 357
 358static void host1x_device_release(struct device *dev)
 359{
 360        struct host1x_device *device = to_host1x_device(dev);
 361
 362        __host1x_device_del(device);
 363        kfree(device);
 364}
 365
 366static int host1x_device_add(struct host1x *host1x,
 367                             struct host1x_driver *driver)
 368{
 369        struct host1x_client *client, *tmp;
 370        struct host1x_subdev *subdev;
 371        struct host1x_device *device;
 372        int err;
 373
 374        device = kzalloc(sizeof(*device), GFP_KERNEL);
 375        if (!device)
 376                return -ENOMEM;
 377
 378        device_initialize(&device->dev);
 379
 380        mutex_init(&device->subdevs_lock);
 381        INIT_LIST_HEAD(&device->subdevs);
 382        INIT_LIST_HEAD(&device->active);
 383        mutex_init(&device->clients_lock);
 384        INIT_LIST_HEAD(&device->clients);
 385        INIT_LIST_HEAD(&device->list);
 386        device->driver = driver;
 387
 388        device->dev.coherent_dma_mask = host1x->dev->coherent_dma_mask;
 389        device->dev.dma_mask = &device->dev.coherent_dma_mask;
 390        dev_set_name(&device->dev, "%s", driver->driver.name);
 391        of_dma_configure(&device->dev, host1x->dev->of_node);
 392        device->dev.release = host1x_device_release;
 393        device->dev.of_node = host1x->dev->of_node;
 394        device->dev.bus = &host1x_bus_type;
 395        device->dev.parent = host1x->dev;
 396
 397        err = host1x_device_parse_dt(device, driver);
 398        if (err < 0) {
 399                kfree(device);
 400                return err;
 401        }
 402
 403        list_add_tail(&device->list, &host1x->devices);
 404
 405        mutex_lock(&clients_lock);
 406
 407        list_for_each_entry_safe(client, tmp, &clients, list) {
 408                list_for_each_entry(subdev, &device->subdevs, list) {
 409                        if (subdev->np == client->dev->of_node) {
 410                                host1x_subdev_register(device, subdev, client);
 411                                break;
 412                        }
 413                }
 414        }
 415
 416        mutex_unlock(&clients_lock);
 417
 418        return 0;
 419}
 420
 421/*
 422 * Removes a device by first unregistering any subdevices and then removing
 423 * itself from the list of devices.
 424 *
 425 * This function must be called with the host1x->devices_lock held.
 426 */
 427static void host1x_device_del(struct host1x *host1x,
 428                              struct host1x_device *device)
 429{
 430        if (device->registered) {
 431                device->registered = false;
 432                device_del(&device->dev);
 433        }
 434
 435        put_device(&device->dev);
 436}
 437
 438static void host1x_attach_driver(struct host1x *host1x,
 439                                 struct host1x_driver *driver)
 440{
 441        struct host1x_device *device;
 442        int err;
 443
 444        mutex_lock(&host1x->devices_lock);
 445
 446        list_for_each_entry(device, &host1x->devices, list) {
 447                if (device->driver == driver) {
 448                        mutex_unlock(&host1x->devices_lock);
 449                        return;
 450                }
 451        }
 452
 453        err = host1x_device_add(host1x, driver);
 454        if (err < 0)
 455                dev_err(host1x->dev, "failed to allocate device: %d\n", err);
 456
 457        mutex_unlock(&host1x->devices_lock);
 458}
 459
 460static void host1x_detach_driver(struct host1x *host1x,
 461                                 struct host1x_driver *driver)
 462{
 463        struct host1x_device *device, *tmp;
 464
 465        mutex_lock(&host1x->devices_lock);
 466
 467        list_for_each_entry_safe(device, tmp, &host1x->devices, list)
 468                if (device->driver == driver)
 469                        host1x_device_del(host1x, device);
 470
 471        mutex_unlock(&host1x->devices_lock);
 472}
 473
 474/**
 475 * host1x_register() - register a host1x controller
 476 * @host1x: host1x controller
 477 *
 478 * The host1x controller driver uses this to register a host1x controller with
 479 * the infrastructure. Note that all Tegra SoC generations have only ever come
 480 * with a single host1x instance, so this function is somewhat academic.
 481 */
 482int host1x_register(struct host1x *host1x)
 483{
 484        struct host1x_driver *driver;
 485
 486        mutex_lock(&devices_lock);
 487        list_add_tail(&host1x->list, &devices);
 488        mutex_unlock(&devices_lock);
 489
 490        mutex_lock(&drivers_lock);
 491
 492        list_for_each_entry(driver, &drivers, list)
 493                host1x_attach_driver(host1x, driver);
 494
 495        mutex_unlock(&drivers_lock);
 496
 497        return 0;
 498}
 499
 500/**
 501 * host1x_unregister() - unregister a host1x controller
 502 * @host1x: host1x controller
 503 *
 504 * The host1x controller driver uses this to remove a host1x controller from
 505 * the infrastructure.
 506 */
 507int host1x_unregister(struct host1x *host1x)
 508{
 509        struct host1x_driver *driver;
 510
 511        mutex_lock(&drivers_lock);
 512
 513        list_for_each_entry(driver, &drivers, list)
 514                host1x_detach_driver(host1x, driver);
 515
 516        mutex_unlock(&drivers_lock);
 517
 518        mutex_lock(&devices_lock);
 519        list_del_init(&host1x->list);
 520        mutex_unlock(&devices_lock);
 521
 522        return 0;
 523}
 524
 525static int host1x_device_probe(struct device *dev)
 526{
 527        struct host1x_driver *driver = to_host1x_driver(dev->driver);
 528        struct host1x_device *device = to_host1x_device(dev);
 529
 530        if (driver->probe)
 531                return driver->probe(device);
 532
 533        return 0;
 534}
 535
 536static int host1x_device_remove(struct device *dev)
 537{
 538        struct host1x_driver *driver = to_host1x_driver(dev->driver);
 539        struct host1x_device *device = to_host1x_device(dev);
 540
 541        if (driver->remove)
 542                return driver->remove(device);
 543
 544        return 0;
 545}
 546
 547static void host1x_device_shutdown(struct device *dev)
 548{
 549        struct host1x_driver *driver = to_host1x_driver(dev->driver);
 550        struct host1x_device *device = to_host1x_device(dev);
 551
 552        if (driver->shutdown)
 553                driver->shutdown(device);
 554}
 555
 556/**
 557 * host1x_driver_register_full() - register a host1x driver
 558 * @driver: host1x driver
 559 * @owner: owner module
 560 *
 561 * Drivers for host1x logical devices call this function to register a driver
 562 * with the infrastructure. Note that since these drive logical devices, the
 563 * registration of the driver actually triggers tho logical device creation.
 564 * A logical device will be created for each host1x instance.
 565 */
 566int host1x_driver_register_full(struct host1x_driver *driver,
 567                                struct module *owner)
 568{
 569        struct host1x *host1x;
 570
 571        INIT_LIST_HEAD(&driver->list);
 572
 573        mutex_lock(&drivers_lock);
 574        list_add_tail(&driver->list, &drivers);
 575        mutex_unlock(&drivers_lock);
 576
 577        mutex_lock(&devices_lock);
 578
 579        list_for_each_entry(host1x, &devices, list)
 580                host1x_attach_driver(host1x, driver);
 581
 582        mutex_unlock(&devices_lock);
 583
 584        driver->driver.bus = &host1x_bus_type;
 585        driver->driver.owner = owner;
 586        driver->driver.probe = host1x_device_probe;
 587        driver->driver.remove = host1x_device_remove;
 588        driver->driver.shutdown = host1x_device_shutdown;
 589
 590        return driver_register(&driver->driver);
 591}
 592EXPORT_SYMBOL(host1x_driver_register_full);
 593
 594/**
 595 * host1x_driver_unregister() - unregister a host1x driver
 596 * @driver: host1x driver
 597 *
 598 * Unbinds the driver from each of the host1x logical devices that it is
 599 * bound to, effectively removing the subsystem devices that they represent.
 600 */
 601void host1x_driver_unregister(struct host1x_driver *driver)
 602{
 603        driver_unregister(&driver->driver);
 604
 605        mutex_lock(&drivers_lock);
 606        list_del_init(&driver->list);
 607        mutex_unlock(&drivers_lock);
 608}
 609EXPORT_SYMBOL(host1x_driver_unregister);
 610
 611/**
 612 * host1x_client_register() - register a host1x client
 613 * @client: host1x client
 614 *
 615 * Registers a host1x client with each host1x controller instance. Note that
 616 * each client will only match their parent host1x controller and will only be
 617 * associated with that instance. Once all clients have been registered with
 618 * their parent host1x controller, the infrastructure will set up the logical
 619 * device and call host1x_device_init(), which will in turn call each client's
 620 * &host1x_client_ops.init implementation.
 621 */
 622int host1x_client_register(struct host1x_client *client)
 623{
 624        struct host1x *host1x;
 625        int err;
 626
 627        mutex_lock(&devices_lock);
 628
 629        list_for_each_entry(host1x, &devices, list) {
 630                err = host1x_add_client(host1x, client);
 631                if (!err) {
 632                        mutex_unlock(&devices_lock);
 633                        return 0;
 634                }
 635        }
 636
 637        mutex_unlock(&devices_lock);
 638
 639        mutex_lock(&clients_lock);
 640        list_add_tail(&client->list, &clients);
 641        mutex_unlock(&clients_lock);
 642
 643        return 0;
 644}
 645EXPORT_SYMBOL(host1x_client_register);
 646
 647/**
 648 * host1x_client_unregister() - unregister a host1x client
 649 * @client: host1x client
 650 *
 651 * Removes a host1x client from its host1x controller instance. If a logical
 652 * device has already been initialized, it will be torn down.
 653 */
 654int host1x_client_unregister(struct host1x_client *client)
 655{
 656        struct host1x_client *c;
 657        struct host1x *host1x;
 658        int err;
 659
 660        mutex_lock(&devices_lock);
 661
 662        list_for_each_entry(host1x, &devices, list) {
 663                err = host1x_del_client(host1x, client);
 664                if (!err) {
 665                        mutex_unlock(&devices_lock);
 666                        return 0;
 667                }
 668        }
 669
 670        mutex_unlock(&devices_lock);
 671        mutex_lock(&clients_lock);
 672
 673        list_for_each_entry(c, &clients, list) {
 674                if (c == client) {
 675                        list_del_init(&c->list);
 676                        break;
 677                }
 678        }
 679
 680        mutex_unlock(&clients_lock);
 681
 682        return 0;
 683}
 684EXPORT_SYMBOL(host1x_client_unregister);
 685