drm: restrict the device list for shadow attached drivers
authorDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 11 Dec 2013 10:34:31 +0000 (11:34 +0100)
committerDave Airlie <airlied@redhat.com>
Wed, 18 Dec 2013 01:08:36 +0000 (11:08 +1000)
There's really no need for the drm core to keep a list of all
devices of a given driver - the linux device model keeps perfect
track of this already for us.

The exception is old legacy ums drivers using pci shadow attaching.
So rename the lists to make the use case clearer and rip out everything
else.

v2: Rebase on top of David Herrmann's drm device register changes.
Also drop the bogus dev_set_drvdata for platform drivers that somehow
crept into the original version - drivers really should be in full
control of that field.

v3: Initialize driver->legacy_dev_list outside of the loop, spotted by
David Herrmann.

v4: Rebase on top of the newly created host1x drm_bus for tegra.

Cc: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/drm_pci.c
drivers/gpu/drm/drm_platform.c
drivers/gpu/drm/drm_stub.c
drivers/gpu/drm/drm_usb.c
drivers/gpu/drm/tegra/bus.c
include/drm/drmP.h

index 02679793c9e2e73d3d175136bbfb638a7cd0784f..efadad85028898f4877c473325250b34067165c8 100644 (file)
@@ -346,6 +346,11 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
                 driver->name, driver->major, driver->minor, driver->patchlevel,
                 driver->date, pci_name(pdev), dev->primary->index);
 
+       /* No locking needed since shadow-attach is single-threaded since it may
+        * only be called from the per-driver module init hook. */
+       if (!drm_core_check_feature(dev, DRIVER_MODESET))
+               list_add_tail(&dev->legacy_dev_list, &driver->legacy_dev_list);
+
        return 0;
 
 err_pci:
@@ -375,7 +380,6 @@ int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
 
        DRM_DEBUG("\n");
 
-       INIT_LIST_HEAD(&driver->device_list);
        driver->kdriver.pci = pdriver;
        driver->bus = &drm_pci_bus;
 
@@ -383,6 +387,7 @@ int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver)
                return pci_register_driver(pdriver);
 
        /* If not using KMS, fall back to stealth mode manual scanning. */
+       INIT_LIST_HEAD(&driver->legacy_dev_list);
        for (i = 0; pdriver->id_table[i].vendor != 0; i++) {
                pid = &pdriver->id_table[i];
 
@@ -465,8 +470,11 @@ void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver)
        if (driver->driver_features & DRIVER_MODESET) {
                pci_unregister_driver(pdriver);
        } else {
-               list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item)
+               list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list,
+                                        legacy_dev_list) {
                        drm_put_dev(dev);
+                       list_del(&dev->legacy_dev_list);
+               }
        }
        DRM_INFO("Module unloaded\n");
 }
index 56a48033ecede804923bc47012eb7761ee151c60..21fc82006b78c3423c801b54ef5acd40d4f79805 100644 (file)
@@ -147,7 +147,6 @@ int drm_platform_init(struct drm_driver *driver, struct platform_device *platfor
 
        driver->kdriver.platform_device = platform_device;
        driver->bus = &drm_platform_bus;
-       INIT_LIST_HEAD(&driver->device_list);
        return drm_get_platform_dev(platform_device, driver);
 }
 EXPORT_SYMBOL(drm_platform_init);
index 74e0357c1c38efdc7cf0658774698be4f3e0a630..9de0d3d91cc6931dc11ed714d9ea94e915540e27 100644 (file)
@@ -563,8 +563,6 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags)
                        goto err_unload;
        }
 
-       list_add_tail(&dev->driver_item, &dev->driver->device_list);
-
        ret = 0;
        goto out_unlock;
 
@@ -614,7 +612,5 @@ void drm_dev_unregister(struct drm_device *dev)
        drm_unplug_minor(dev->control);
        drm_unplug_minor(dev->render);
        drm_unplug_minor(dev->primary);
-
-       list_del(&dev->driver_item);
 }
 EXPORT_SYMBOL(drm_dev_unregister);
index b179b70e7853b4bb4eb69c9a97a57295ae26a084..21ae8d96880b42d1192d0d7fb35a20a8abd7f2be 100644 (file)
@@ -63,7 +63,6 @@ int drm_usb_init(struct drm_driver *driver, struct usb_driver *udriver)
        int res;
        DRM_DEBUG("\n");
 
-       INIT_LIST_HEAD(&driver->device_list);
        driver->kdriver.usb = udriver;
        driver->bus = &drm_usb_bus;
 
index 565f8f7b9a4781d0f9d0b33e1b53b2ecbe2b7eda..e38e5967d77bdc4a4c709cd44744887318cb87bf 100644 (file)
@@ -46,7 +46,6 @@ int drm_host1x_init(struct drm_driver *driver, struct host1x_device *device)
        struct drm_device *drm;
        int ret;
 
-       INIT_LIST_HEAD(&driver->device_list);
        driver->bus = &drm_host1x_bus;
 
        drm = drm_dev_alloc(driver, &device->dev);
index 2f725b767a19244aa91eec5faac259f16bf76bcf..de86cce1e07439666dca9915ed2e2637e8af9730 100644 (file)
@@ -1012,8 +1012,8 @@ struct drm_driver {
        } kdriver;
        struct drm_bus *bus;
 
-       /* List of devices hanging off this driver */
-       struct list_head device_list;
+       /* List of devices hanging off this driver with stealth attach. */
+       struct list_head legacy_dev_list;
 };
 
 #define DRM_MINOR_UNASSIGNED 0
@@ -1102,7 +1102,7 @@ struct drm_vblank_crtc {
  * may contain multiple heads.
  */
 struct drm_device {
-       struct list_head driver_item;   /**< list of devices per driver */
+       struct list_head legacy_dev_list;/**< list of devices per driver for stealth attach cleanup */
        char *devname;                  /**< For /proc/interrupts */
        int if_version;                 /**< Highest interface version set */