diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index 02679793c9e2..efadad850288 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -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"); } diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index 56a48033eced..21fc82006b78 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c @@ -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); diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 74e0357c1c38..9de0d3d91cc6 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -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); diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c index b179b70e7853..21ae8d96880b 100644 --- a/drivers/gpu/drm/drm_usb.c +++ b/drivers/gpu/drm/drm_usb.c @@ -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; diff --git a/drivers/gpu/drm/tegra/bus.c b/drivers/gpu/drm/tegra/bus.c index 565f8f7b9a47..e38e5967d77b 100644 --- a/drivers/gpu/drm/tegra/bus.c +++ b/drivers/gpu/drm/tegra/bus.c @@ -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); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 2f725b767a19..de86cce1e074 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -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 */