The non modesetting drm drivers currently use a handcrafted pci probe function. This requires the drm core to keep a list of registered devices for each driver. This series adds a probe function for the non modesetting drivers and removes the legacy probe code. The USB and platform drivers use the devices_list aswell which is unnecessary. This is also cleaned up in this series.
I am confident that the standard pci probe mechanism will work for the non modesetting drivers, but unfortunately I have non of them handy for testing, so it would be great if someone with access to one of those devices could give this series a test.
Sascha
Sascha Hauer (12): drm: remove kdriver union from struct drm_driver drm: remove platformdev and usbdev from struct drm_device drm: remove unused field bus_type from struct drm_bus drm: provide a pci probe function for non modesetting devices drm: use drm_get_platform_dev and drop drm_platform_init/exit drm usb: drop drm_usb_init/exit drm: remove now unused device_list drm vmwgfx: remove unused field vmw_chipset from struct vmw_private drm: Add drm_register_device function drm pci: use drm_register_device drm platform: use drm_register_device drm usb: use drm_register_device
drivers/gpu/drm/drm_pci.c | 98 ++------------------------ drivers/gpu/drm/drm_platform.c | 108 +++++------------------------ drivers/gpu/drm/drm_stub.c | 56 +++++++++++++++ drivers/gpu/drm/drm_usb.c | 72 ++------------------ drivers/gpu/drm/exynos/exynos_drm_drv.c | 6 +- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 3 +- drivers/gpu/drm/i810/i810_drv.c | 16 ++++ drivers/gpu/drm/mga/mga_drv.c | 16 ++++ drivers/gpu/drm/r128/r128_drv.c | 16 ++++ drivers/gpu/drm/savage/savage_drv.c | 16 ++++ drivers/gpu/drm/sis/sis_drv.c | 16 ++++ drivers/gpu/drm/tdfx/tdfx_drv.c | 16 ++++ drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 1 - include/drm/drmP.h | 21 +----- include/drm/drm_usb.h | 3 - 16 files changed, 190 insertions(+), 275 deletions(-)
struct drm_driver has a union containing the different drivers. This field is unused in case of a usb or platform device. For pci devices it is only used in drm_pci_get_name() which uses the pci_driver to return the pci driver name. For all existing drm drivers this driver name matches the struct drm_device->name, so return this name instead and remove the now unnecessary code.
Signed-off-by: Sascha Hauer s.hauer@pengutronix.de --- drivers/gpu/drm/drm_pci.c | 10 +++------- drivers/gpu/drm/drm_platform.c | 1 - drivers/gpu/drm/drm_usb.c | 1 - include/drm/drmP.h | 5 ----- 4 files changed, 3 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index d4d10b7..1c06d3a 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -148,14 +148,12 @@ static int drm_pci_get_irq(struct drm_device *dev)
static const char *drm_pci_get_name(struct drm_device *dev) { - struct pci_driver *pdriver = dev->driver->kdriver.pci; - return pdriver->name; + return dev->driver->name; }
int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master) { int len, ret; - struct pci_driver *pdriver = dev->driver->kdriver.pci; master->unique_len = 40; master->unique_size = master->unique_len; master->unique = kmalloc(master->unique_size, GFP_KERNEL); @@ -178,7 +176,7 @@ int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master) master->unique_len = len;
dev->devname = - kmalloc(strlen(pdriver->name) + + kmalloc(strlen(dev->driver->name) + master->unique_len + 2, GFP_KERNEL);
if (dev->devname == NULL) { @@ -186,8 +184,7 @@ int drm_pci_set_busid(struct drm_device *dev, struct drm_master *master) goto err; }
- sprintf(dev->devname, "%s@%s", pdriver->name, - master->unique); + sprintf(dev->devname, "%s@%s", dev->driver->name, master->unique);
return 0; err: @@ -410,7 +407,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;
if (driver->driver_features & DRIVER_MODESET) diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index ae9db5e..f21243c 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c @@ -179,7 +179,6 @@ int drm_platform_init(struct drm_driver *driver, struct platform_device *platfor { DRM_DEBUG("\n");
- 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); diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c index 445003f..bd7fe72 100644 --- a/drivers/gpu/drm/drm_usb.c +++ b/drivers/gpu/drm/drm_usb.c @@ -101,7 +101,6 @@ int drm_usb_init(struct drm_driver *driver, struct usb_driver *udriver) DRM_DEBUG("\n");
INIT_LIST_HEAD(&driver->device_list); - driver->kdriver.usb = udriver; driver->bus = &drm_usb_bus;
res = usb_register(udriver); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 92f0981..38b95cb 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -919,11 +919,6 @@ struct drm_driver { struct drm_ioctl_desc *ioctls; int num_ioctls; const struct file_operations *fops; - union { - struct pci_driver *pci; - struct platform_device *platform_device; - struct usb_driver *usb; - } kdriver; struct drm_bus *bus;
/* List of devices hanging off this driver */
struct drm_device has a struct usbdevice * and a struct platform_device *. This is unused, so remove it. If the platform_device or usbdevice is needed, we can always get it using to_usb_device or to to_platform_device.
Signed-off-by: Sascha Hauer s.hauer@pengutronix.de --- drivers/gpu/drm/drm_platform.c | 18 +++++++++++------- drivers/gpu/drm/drm_usb.c | 1 - drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 3 +-- include/drm/drmP.h | 3 --- 4 files changed, 12 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index f21243c..1c1d581 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c @@ -51,7 +51,6 @@ int drm_get_platform_dev(struct platform_device *platdev, if (!dev) return -ENOMEM;
- dev->platformdev = platdev; dev->dev = &platdev->dev;
mutex_lock(&drm_global_mutex); @@ -112,19 +111,24 @@ EXPORT_SYMBOL(drm_get_platform_dev);
static int drm_platform_get_irq(struct drm_device *dev) { - return platform_get_irq(dev->platformdev, 0); + struct platform_device *pdev = to_platform_device(dev->dev); + + return platform_get_irq(pdev, 0); }
static const char *drm_platform_get_name(struct drm_device *dev) { - return dev->platformdev->name; + struct platform_device *pdev = to_platform_device(dev->dev); + + return pdev->name; }
static int drm_platform_set_busid(struct drm_device *dev, struct drm_master *master) { + struct platform_device *pdev = to_platform_device(dev->dev); int len, ret;
- master->unique_len = 13 + strlen(dev->platformdev->name); + master->unique_len = 13 + strlen(pdev->name); master->unique_size = master->unique_len; master->unique = kmalloc(master->unique_len + 1, GFP_KERNEL);
@@ -132,7 +136,7 @@ static int drm_platform_set_busid(struct drm_device *dev, struct drm_master *mas return -ENOMEM;
len = snprintf(master->unique, master->unique_len, - "platform:%s:%02d", dev->platformdev->name, dev->platformdev->id); + "platform:%s:%02d", pdev->name, pdev->id);
if (len > master->unique_len) { DRM_ERROR("Unique buffer overflowed\n"); @@ -141,7 +145,7 @@ static int drm_platform_set_busid(struct drm_device *dev, struct drm_master *mas }
dev->devname = - kmalloc(strlen(dev->platformdev->name) + + kmalloc(strlen(pdev->name) + master->unique_len + 2, GFP_KERNEL);
if (dev->devname == NULL) { @@ -149,7 +153,7 @@ static int drm_platform_set_busid(struct drm_device *dev, struct drm_master *mas goto err; }
- sprintf(dev->devname, "%s@%s", dev->platformdev->name, + sprintf(dev->devname, "%s@%s", pdev->name, master->unique); return 0; err: diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c index bd7fe72..224dbdd 100644 --- a/drivers/gpu/drm/drm_usb.c +++ b/drivers/gpu/drm/drm_usb.c @@ -18,7 +18,6 @@ int drm_get_usb_dev(struct usb_interface *interface, return -ENOMEM;
usbdev = interface_to_usbdev(interface); - dev->usbdev = usbdev; dev->dev = &usbdev->dev;
mutex_lock(&drm_global_mutex); diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index d7ae29d..3a9589b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -125,7 +125,6 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper, struct drm_device *dev = helper->dev; struct fb_info *fbi; struct drm_mode_fb_cmd2 mode_cmd = { 0 }; - struct platform_device *pdev = dev->platformdev; unsigned long size; int ret;
@@ -143,7 +142,7 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
mutex_lock(&dev->struct_mutex);
- fbi = framebuffer_alloc(0, &pdev->dev); + fbi = framebuffer_alloc(0, dev->dev); if (!fbi) { DRM_ERROR("failed to allocate fb info.\n"); ret = -ENOMEM; diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 38b95cb..d770eef 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1140,9 +1140,6 @@ struct drm_device { struct pci_controller *hose; #endif
- struct platform_device *platformdev; /**< Platform device struture */ - struct usb_device *usbdev; - struct drm_sg_mem *sg; /**< Scatter gather memory */ unsigned int num_crtcs; /**< Number of CRTCs on this device */ void *dev_private; /**< device private data */
Signed-off-by: Sascha Hauer s.hauer@pengutronix.de --- drivers/gpu/drm/drm_pci.c | 1 - drivers/gpu/drm/drm_platform.c | 1 - drivers/gpu/drm/drm_usb.c | 1 - include/drm/drmP.h | 5 ----- 4 files changed, 0 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index 1c06d3a..f2e8019 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -285,7 +285,6 @@ int drm_pci_agp_init(struct drm_device *dev) }
static struct drm_bus drm_pci_bus = { - .bus_type = DRIVER_BUS_PCI, .get_irq = drm_pci_get_irq, .get_name = drm_pci_get_name, .set_busid = drm_pci_set_busid, diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index 1c1d581..453da2d 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c @@ -161,7 +161,6 @@ err: }
static struct drm_bus drm_platform_bus = { - .bus_type = DRIVER_BUS_PLATFORM, .get_irq = drm_platform_get_irq, .get_name = drm_platform_get_name, .set_busid = drm_platform_set_busid, diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c index 224dbdd..b7eb64a 100644 --- a/drivers/gpu/drm/drm_usb.c +++ b/drivers/gpu/drm/drm_usb.c @@ -88,7 +88,6 @@ static int drm_usb_set_busid(struct drm_device *dev, }
static struct drm_bus drm_usb_bus = { - .bus_type = DRIVER_BUS_USB, .get_irq = drm_usb_get_irq, .get_name = drm_usb_get_name, .set_busid = drm_usb_set_busid, diff --git a/include/drm/drmP.h b/include/drm/drmP.h index d770eef..3d1ce03 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -151,10 +151,6 @@ int drm_err(const char *func, const char *format, ...); #define DRIVER_GEM 0x1000 #define DRIVER_MODESET 0x2000
-#define DRIVER_BUS_PCI 0x1 -#define DRIVER_BUS_PLATFORM 0x2 -#define DRIVER_BUS_USB 0x3 - /***********************************************************************/ /** \name Begin the DRM... */ /*@{*/ @@ -697,7 +693,6 @@ struct drm_master { #define DRM_SCANOUTPOS_ACCURATE (1 << 2)
struct drm_bus { - int bus_type; int (*get_irq)(struct drm_device *dev); const char *(*get_name)(struct drm_device *dev); int (*set_busid)(struct drm_device *dev, struct drm_master *master);
This way we do not need the legacy handcrafted probe mechanism anymore and can remove it.
Signed-off-by: Sascha Hauer s.hauer@pengutronix.de --- drivers/gpu/drm/drm_pci.c | 41 +--------------------------------- drivers/gpu/drm/i810/i810_drv.c | 16 +++++++++++++ drivers/gpu/drm/mga/mga_drv.c | 16 +++++++++++++ drivers/gpu/drm/r128/r128_drv.c | 16 +++++++++++++ drivers/gpu/drm/savage/savage_drv.c | 16 +++++++++++++ drivers/gpu/drm/sis/sis_drv.c | 16 +++++++++++++ drivers/gpu/drm/tdfx/tdfx_drv.c | 16 +++++++++++++ 7 files changed, 98 insertions(+), 39 deletions(-)
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index f2e8019..b53427e 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -363,8 +363,6 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, goto err_g4; }
- list_add_tail(&dev->driver_item, &driver->device_list); - DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", driver->name, driver->major, driver->minor, driver->patchlevel, driver->date, pci_name(pdev), dev->primary->index); @@ -399,41 +397,12 @@ EXPORT_SYMBOL(drm_get_pci_dev); */ int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver) { - struct pci_dev *pdev = NULL; - const struct pci_device_id *pid; - int i; - DRM_DEBUG("\n");
INIT_LIST_HEAD(&driver->device_list); driver->bus = &drm_pci_bus;
- if (driver->driver_features & DRIVER_MODESET) - return pci_register_driver(pdriver); - - /* If not using KMS, fall back to stealth mode manual scanning. */ - for (i = 0; pdriver->id_table[i].vendor != 0; i++) { - pid = &pdriver->id_table[i]; - - /* Loop around setting up a DRM device for each PCI device - * matching our ID and device class. If we had the internal - * function that pci_get_subsys and pci_get_class used, we'd - * be able to just pass pid in instead of doing a two-stage - * thing. - */ - pdev = NULL; - while ((pdev = - pci_get_subsys(pid->vendor, pid->device, pid->subvendor, - pid->subdevice, pdev)) != NULL) { - if ((pdev->class & pid->class_mask) != pid->class) - continue; - - /* stealth mode requires a manual probe */ - pci_dev_get(pdev); - drm_get_pci_dev(pdev, pid, driver); - } - } - return 0; + return pci_register_driver(pdriver); }
#else @@ -450,15 +419,9 @@ EXPORT_SYMBOL(drm_pci_init); /*@}*/ void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver) { - struct drm_device *dev, *tmp; DRM_DEBUG("\n");
- if (driver->driver_features & DRIVER_MODESET) { - pci_unregister_driver(pdriver); - } else { - list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item) - drm_put_dev(dev); - } + pci_unregister_driver(pdriver); DRM_INFO("Module unloaded\n"); } EXPORT_SYMBOL(drm_pci_exit); diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c index ec12f7d..94f0660 100644 --- a/drivers/gpu/drm/i810/i810_drv.c +++ b/drivers/gpu/drm/i810/i810_drv.c @@ -75,7 +75,23 @@ static struct drm_driver driver = { .patchlevel = DRIVER_PATCHLEVEL, };
+static int __devinit +i810_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + return drm_get_pci_dev(pdev, ent, &driver); +} + +static void +i810_pci_remove(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + + drm_put_dev(dev); +} + static struct pci_driver i810_pci_driver = { + .probe = i810_pci_probe, + .remove = i810_pci_remove, .name = DRIVER_NAME, .id_table = pciidlist, }; diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c index f9a925d..45d848a 100644 --- a/drivers/gpu/drm/mga/mga_drv.c +++ b/drivers/gpu/drm/mga/mga_drv.c @@ -87,7 +87,23 @@ static struct drm_driver driver = { .patchlevel = DRIVER_PATCHLEVEL, };
+static int __devinit +mga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + return drm_get_pci_dev(pdev, ent, &driver); +} + +static void +mga_pci_remove(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + + drm_put_dev(dev); +} + static struct pci_driver mga_pci_driver = { + .probe = mga_pci_probe, + .remove = mga_pci_remove, .name = DRIVER_NAME, .id_table = pciidlist, }; diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c index 6a5f439..257f8eb 100644 --- a/drivers/gpu/drm/r128/r128_drv.c +++ b/drivers/gpu/drm/r128/r128_drv.c @@ -88,7 +88,23 @@ int r128_driver_load(struct drm_device *dev, unsigned long flags) return drm_vblank_init(dev, 1); }
+static int __devinit +r128_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + return drm_get_pci_dev(pdev, ent, &driver); +} + +static void +r128_pci_remove(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + + drm_put_dev(dev); +} + static struct pci_driver r128_pci_driver = { + .probe = r128_pci_probe, + .remove = r128_pci_remove, .name = DRIVER_NAME, .id_table = pciidlist, }; diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c index 89afe0b..780270c 100644 --- a/drivers/gpu/drm/savage/savage_drv.c +++ b/drivers/gpu/drm/savage/savage_drv.c @@ -66,7 +66,23 @@ static struct drm_driver driver = { .patchlevel = DRIVER_PATCHLEVEL, };
+static int __devinit +savage_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + return drm_get_pci_dev(pdev, ent, &driver); +} + +static void +savage_pci_remove(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + + drm_put_dev(dev); +} + static struct pci_driver savage_pci_driver = { + .probe = savage_pci_probe, + .remove = savage_pci_remove, .name = DRIVER_NAME, .id_table = pciidlist, }; diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 573220c..8e3d39a 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c @@ -118,7 +118,23 @@ static struct drm_driver driver = { .patchlevel = DRIVER_PATCHLEVEL, };
+static int __devinit +sis_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + return drm_get_pci_dev(pdev, ent, &driver); +} + +static void +sis_pci_remove(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + + drm_put_dev(dev); +} + static struct pci_driver sis_pci_driver = { + .probe = sis_pci_probe, + .remove = sis_pci_remove, .name = DRIVER_NAME, .id_table = pciidlist, }; diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c index 1613c78..a863fdc 100644 --- a/drivers/gpu/drm/tdfx/tdfx_drv.c +++ b/drivers/gpu/drm/tdfx/tdfx_drv.c @@ -64,7 +64,23 @@ static struct drm_driver driver = { .patchlevel = DRIVER_PATCHLEVEL, };
+static int __devinit +tdfx_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + return drm_get_pci_dev(pdev, ent, &driver); +} + +static void +tdfx_pci_remove(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + + drm_put_dev(dev); +} + static struct pci_driver tdfx_pci_driver = { + .probe = tdfx_pci_probe, + .remove = tdfx_pci_remove, .name = DRIVER_NAME, .id_table = pciidlist, };
drm_platform_init is modelled after the legacy pci probe support. It initializes a device_list, but this list will only ever have a single entry as it is specific to a single platform device instance. Simplify this by calling drm_get_platform_dev directly from the driver.
Signed-off-by: Sascha Hauer s.hauer@pengutronix.de --- drivers/gpu/drm/drm_platform.c | 39 +++--------------------------- drivers/gpu/drm/exynos/exynos_drm_drv.c | 6 +++- include/drm/drmP.h | 3 -- 3 files changed, 8 insertions(+), 40 deletions(-)
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index 453da2d..7153508 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c @@ -28,6 +28,8 @@ #include <linux/export.h> #include "drmP.h"
+static struct drm_bus drm_platform_bus; + /** * Register. * @@ -53,6 +55,8 @@ int drm_get_platform_dev(struct platform_device *platdev,
dev->dev = &platdev->dev;
+ driver->bus = &drm_platform_bus; + mutex_lock(&drm_global_mutex);
ret = drm_fill_in_dev(dev, NULL, driver); @@ -87,8 +91,6 @@ int drm_get_platform_dev(struct platform_device *platdev, goto err_g3; }
- list_add_tail(&dev->driver_item, &driver->device_list); - mutex_unlock(&drm_global_mutex);
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", @@ -165,36 +167,3 @@ static struct drm_bus drm_platform_bus = { .get_name = drm_platform_get_name, .set_busid = drm_platform_set_busid, }; - -/** - * Platform device initialization. Called direct from modules. - * - * \return zero on success or a negative number on failure. - * - * Initializes a drm_device structures,registering the - * stubs - * - * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and - * after the initialization for driver customization. - */ - -int drm_platform_init(struct drm_driver *driver, struct platform_device *platform_device) -{ - DRM_DEBUG("\n"); - - driver->bus = &drm_platform_bus; - INIT_LIST_HEAD(&driver->device_list); - return drm_get_platform_dev(platform_device, driver); -} -EXPORT_SYMBOL(drm_platform_init); - -void drm_platform_exit(struct drm_driver *driver, struct platform_device *platform_device) -{ - struct drm_device *dev, *tmp; - DRM_DEBUG("\n"); - - list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item) - drm_put_dev(dev); - DRM_INFO("Module unloaded\n"); -} -EXPORT_SYMBOL(drm_platform_exit); diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 35889ca..17a100c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -219,14 +219,16 @@ static int exynos_drm_platform_probe(struct platform_device *pdev)
exynos_drm_driver.num_ioctls = DRM_ARRAY_SIZE(exynos_ioctls);
- return drm_platform_init(&exynos_drm_driver, pdev); + return drm_get_platform_dev(pdev, &exynos_drm_driver); }
static int exynos_drm_platform_remove(struct platform_device *pdev) { + struct drm_device *dev = platform_get_drvdata(pdev); + DRM_DEBUG_DRIVER("%s\n", __FILE__);
- drm_platform_exit(&exynos_drm_driver, pdev); + drm_put_dev(dev);
return 0; } diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 3d1ce03..d14c23a 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1678,9 +1678,6 @@ extern int drm_get_pci_dev(struct pci_dev *pdev,
/* platform section */ -extern int drm_platform_init(struct drm_driver *driver, struct platform_device *platform_device); -extern void drm_platform_exit(struct drm_driver *driver, struct platform_device *platform_device); - extern int drm_get_platform_dev(struct platform_device *pdev, struct drm_driver *driver);
Usb drivers can register themselves and call drm_get_usb_dev in their probe function. We don't need a drm specific wrapper function for this. As there are currently no users, none a touched here.
Signed-off-by: Sascha Hauer s.hauer@pengutronix.de --- drivers/gpu/drm/drm_usb.c | 26 ++++---------------------- include/drm/drm_usb.h | 3 --- 2 files changed, 4 insertions(+), 25 deletions(-)
diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c index b7eb64a..dd154d4 100644 --- a/drivers/gpu/drm/drm_usb.c +++ b/drivers/gpu/drm/drm_usb.c @@ -2,6 +2,8 @@ #include <linux/usb.h> #include <linux/export.h>
+static struct drm_bus drm_usb_bus; + #ifdef CONFIG_USB int drm_get_usb_dev(struct usb_interface *interface, const struct usb_device_id *id, @@ -17,6 +19,8 @@ int drm_get_usb_dev(struct usb_interface *interface, if (!dev) return -ENOMEM;
+ driver->bus = &drm_usb_bus; + usbdev = interface_to_usbdev(interface); dev->dev = &usbdev->dev;
@@ -49,8 +53,6 @@ int drm_get_usb_dev(struct usb_interface *interface, if (ret) goto err_g3;
- list_add_tail(&dev->driver_item, &driver->device_list); - mutex_unlock(&drm_global_mutex);
DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", @@ -92,24 +94,4 @@ static struct drm_bus drm_usb_bus = { .get_name = drm_usb_get_name, .set_busid = drm_usb_set_busid, }; - -int drm_usb_init(struct drm_driver *driver, struct usb_driver *udriver) -{ - int res; - DRM_DEBUG("\n"); - - INIT_LIST_HEAD(&driver->device_list); - driver->bus = &drm_usb_bus; - - res = usb_register(udriver); - return res; -} -EXPORT_SYMBOL(drm_usb_init); - -void drm_usb_exit(struct drm_driver *driver, - struct usb_driver *udriver) -{ - usb_deregister(udriver); -} -EXPORT_SYMBOL(drm_usb_exit); #endif diff --git a/include/drm/drm_usb.h b/include/drm/drm_usb.h index 33506c11..198f90b 100644 --- a/include/drm/drm_usb.h +++ b/include/drm/drm_usb.h @@ -5,9 +5,6 @@
#include <linux/usb.h>
-extern int drm_usb_init(struct drm_driver *driver, struct usb_driver *udriver); -extern void drm_usb_exit(struct drm_driver *driver, struct usb_driver *udriver); - int drm_get_usb_dev(struct usb_interface *interface, const struct usb_device_id *id, struct drm_driver *driver);
The driver core is better at tracking the devices associated to a device, no need to do this ourselves.
Signed-off-by: Sascha Hauer s.hauer@pengutronix.de --- drivers/gpu/drm/drm_pci.c | 1 - include/drm/drmP.h | 3 --- 2 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index b53427e..c0d47ab 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -399,7 +399,6 @@ int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver) { DRM_DEBUG("\n");
- INIT_LIST_HEAD(&driver->device_list); driver->bus = &drm_pci_bus;
return pci_register_driver(pdriver); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index d14c23a..3c14c05 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -915,9 +915,6 @@ struct drm_driver { int num_ioctls; const struct file_operations *fops; struct drm_bus *bus; - - /* List of devices hanging off this driver */ - struct list_head device_list; };
#define DRM_MINOR_UNASSIGNED 0
Signed-off-by: Sascha Hauer s.hauer@pengutronix.de --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 1 - 2 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index f390f5f..8c7ac41 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -401,7 +401,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) memset(dev_priv, 0, sizeof(*dev_priv));
dev_priv->dev = dev; - dev_priv->vmw_chipset = chipset; dev_priv->last_read_seqno = (uint32_t) -100; mutex_init(&dev_priv->hw_mutex); mutex_init(&dev_priv->cmdbuf_mutex); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index dc27970..252dba2 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -194,7 +194,6 @@ struct vmw_private { struct vmw_fifo_state fifo;
struct drm_device *dev; - unsigned long vmw_chipset; unsigned int io_start; uint32_t vram_start; uint32_t vram_size;
pci, usb and platform support all duplicate the same code. Provide a common function for this.
Signed-off-by: Sascha Hauer s.hauer@pengutronix.de --- drivers/gpu/drm/drm_stub.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ include/drm/drmP.h | 2 + 2 files changed, 58 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index 6d7b083..c36b19c 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -320,6 +320,62 @@ int drm_fill_in_dev(struct drm_device *dev, return retcode; }
+int drm_register_device(struct drm_device *dev, struct drm_driver *driver, + unsigned long flags) +{ + int ret; + + mutex_lock(&drm_global_mutex); + + ret = drm_fill_in_dev(dev, NULL, driver); + if (ret) { + printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); + goto err_g1; + } + + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); + if (ret) + goto err_g1; + } + + ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); + if (ret) + goto err_g2; + + if (dev->driver->load) { + ret = dev->driver->load(dev, flags); + if (ret) + goto err_g3; + } + + /* setup the grouping for the legacy output */ + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + ret = drm_mode_group_init_legacy_group(dev, + &dev->primary->mode_group); + if (ret) + goto err_g3; + } + + mutex_unlock(&drm_global_mutex); + + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", + driver->name, driver->major, driver->minor, driver->patchlevel, + driver->date, dev->primary->index); + + return 0; + +err_g3: + drm_put_minor(&dev->primary); +err_g2: + if (drm_core_check_feature(dev, DRIVER_MODESET)) + drm_put_minor(&dev->control); +err_g1: + mutex_unlock(&drm_global_mutex); + + return ret; +} +EXPORT_SYMBOL(drm_register_device);
/** * Get a secondary minor number. diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 3c14c05..467a9a5 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1651,6 +1651,8 @@ extern int drm_fill_in_dev(struct drm_device *dev, const struct pci_device_id *ent, struct drm_driver *driver); int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type); +int drm_register_device(struct drm_device *dev, struct drm_driver *driver, + unsigned long flags); /*@}*/
/* PCI section */
Signed-off-by: Sascha Hauer s.hauer@pengutronix.de --- drivers/gpu/drm/drm_pci.c | 45 +++------------------------------------------ 1 files changed, 3 insertions(+), 42 deletions(-)
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index c0d47ab..2407a1d 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -332,54 +332,15 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, dev->hose = pdev->sysdata; #endif
- mutex_lock(&drm_global_mutex); - - if ((ret = drm_fill_in_dev(dev, ent, driver))) { - printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); + ret = drm_register_device(dev, driver, ent->driver_data); + if (ret) goto err_g2; - } - - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - pci_set_drvdata(pdev, dev); - ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); - if (ret) - goto err_g2; - } - - if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY))) - goto err_g3; - - if (dev->driver->load) { - ret = dev->driver->load(dev, ent->driver_data); - if (ret) - goto err_g4; - } - - /* setup the grouping for the legacy output */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - ret = drm_mode_group_init_legacy_group(dev, - &dev->primary->mode_group); - if (ret) - goto err_g4; - } - - DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n", - driver->name, driver->major, driver->minor, driver->patchlevel, - driver->date, pci_name(pdev), dev->primary->index);
- mutex_unlock(&drm_global_mutex); - return 0; - -err_g4: - drm_put_minor(&dev->primary); -err_g3: - if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_put_minor(&dev->control); + return ret; err_g2: pci_disable_device(pdev); err_g1: kfree(dev); - mutex_unlock(&drm_global_mutex); return ret; } EXPORT_SYMBOL(drm_get_pci_dev);
Signed-off-by: Sascha Hauer s.hauer@pengutronix.de --- drivers/gpu/drm/drm_platform.c | 51 ++------------------------------------- 1 files changed, 3 insertions(+), 48 deletions(-)
diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index 7153508..5d5e388 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c @@ -56,57 +56,12 @@ int drm_get_platform_dev(struct platform_device *platdev, dev->dev = &platdev->dev;
driver->bus = &drm_platform_bus; + dev_set_drvdata(&platdev->dev, dev);
- mutex_lock(&drm_global_mutex); - - ret = drm_fill_in_dev(dev, NULL, driver); - - if (ret) { - printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); - goto err_g1; - } - - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - dev_set_drvdata(&platdev->dev, dev); - ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); - if (ret) - goto err_g1; - } - - ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); + ret = drm_register_device(dev, driver, 0); if (ret) - goto err_g2; - - if (dev->driver->load) { - ret = dev->driver->load(dev, 0); - if (ret) - goto err_g3; - } - - /* setup the grouping for the legacy output */ - if (drm_core_check_feature(dev, DRIVER_MODESET)) { - ret = drm_mode_group_init_legacy_group(dev, - &dev->primary->mode_group); - if (ret) - goto err_g3; - } - - mutex_unlock(&drm_global_mutex); - - DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", - driver->name, driver->major, driver->minor, driver->patchlevel, - driver->date, dev->primary->index); - - return 0; + kfree(dev);
-err_g3: - drm_put_minor(&dev->primary); -err_g2: - if (drm_core_check_feature(dev, DRIVER_MODESET)) - drm_put_minor(&dev->control); -err_g1: - kfree(dev); - mutex_unlock(&drm_global_mutex); return ret; } EXPORT_SYMBOL(drm_get_platform_dev);
Signed-off-by: Sascha Hauer s.hauer@pengutronix.de --- drivers/gpu/drm/drm_usb.c | 43 ++----------------------------------------- 1 files changed, 2 insertions(+), 41 deletions(-)
diff --git a/drivers/gpu/drm/drm_usb.c b/drivers/gpu/drm/drm_usb.c index dd154d4..b741b54 100644 --- a/drivers/gpu/drm/drm_usb.c +++ b/drivers/gpu/drm/drm_usb.c @@ -24,52 +24,13 @@ int drm_get_usb_dev(struct usb_interface *interface, usbdev = interface_to_usbdev(interface); dev->dev = &usbdev->dev;
- mutex_lock(&drm_global_mutex); - - ret = drm_fill_in_dev(dev, NULL, driver); - if (ret) { - printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); - goto err_g1; - } - usb_set_intfdata(interface, dev); - ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); - if (ret) - goto err_g1; - - ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY); - if (ret) - goto err_g2; - - if (dev->driver->load) { - ret = dev->driver->load(dev, 0); - if (ret) - goto err_g3; - }
- /* setup the grouping for the legacy output */ - ret = drm_mode_group_init_legacy_group(dev, - &dev->primary->mode_group); + ret = drm_register_device(dev, driver, 0); if (ret) - goto err_g3; + kfree(dev);
- mutex_unlock(&drm_global_mutex); - - DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", - driver->name, driver->major, driver->minor, driver->patchlevel, - driver->date, dev->primary->index); - - return 0; - -err_g3: - drm_put_minor(&dev->primary); -err_g2: - drm_put_minor(&dev->control); -err_g1: - kfree(dev); - mutex_unlock(&drm_global_mutex); return ret; - } EXPORT_SYMBOL(drm_get_usb_dev);
----- Original Message -----
From: "Sascha Hauer" s.hauer@pengutronix.de To: dri-devel@lists.freedesktop.org Cc: "Inki Dae" inki.dae@samsung.com, kernel@pengutronix.de Sent: Thursday, 2 February, 2012 11:57:52 AM Subject: [PATCH] drm: cleanup device registration
The non modesetting drm drivers currently use a handcrafted pci probe function. This requires the drm core to keep a list of registered devices for each driver. This series adds a probe function for the non modesetting drivers and removes the legacy probe code. The USB and platform drivers use the devices_list aswell which is unnecessary. This is also cleaned up in this series.
No it can't work like this because we have conflicts between fb and drm drivers, so the DRM is required to do its own probe if an fb driver for a device is already loaded.
it can't use the PCI probe out of the box.
Dave.
On Thu, Feb 02, 2012 at 07:05:00AM -0500, David Airlie wrote:
----- Original Message -----
From: "Sascha Hauer" s.hauer@pengutronix.de To: dri-devel@lists.freedesktop.org Cc: "Inki Dae" inki.dae@samsung.com, kernel@pengutronix.de Sent: Thursday, 2 February, 2012 11:57:52 AM Subject: [PATCH] drm: cleanup device registration
The non modesetting drm drivers currently use a handcrafted pci probe function. This requires the drm core to keep a list of registered devices for each driver. This series adds a probe function for the non modesetting drivers and removes the legacy probe code. The USB and platform drivers use the devices_list aswell which is unnecessary. This is also cleaned up in this series.
No it can't work like this because we have conflicts between fb and drm drivers, so the DRM is required to do its own probe if an fb driver for a device is already loaded.
it can't use the PCI probe out of the box.
I see. For example the i810 also has a framebuffer driver. Do you see a way to fix this except writing a kms driver for all legacy devices? Otherwise I would leave the pci part untouched and only keep the platform/USB pieces which I'm admittedly more interested in.
Sascha
----- Original Message -----
From: "Sascha Hauer" s.hauer@pengutronix.de To: "David Airlie" airlied@redhat.com Cc: "Inki Dae" inki.dae@samsung.com, kernel@pengutronix.de, dri-devel@lists.freedesktop.org Sent: Thursday, 2 February, 2012 12:34:02 PM Subject: Re: [PATCH] drm: cleanup device registration
On Thu, Feb 02, 2012 at 07:05:00AM -0500, David Airlie wrote:
----- Original Message -----
From: "Sascha Hauer" s.hauer@pengutronix.de To: dri-devel@lists.freedesktop.org Cc: "Inki Dae" inki.dae@samsung.com, kernel@pengutronix.de Sent: Thursday, 2 February, 2012 11:57:52 AM Subject: [PATCH] drm: cleanup device registration
The non modesetting drm drivers currently use a handcrafted pci probe function. This requires the drm core to keep a list of registered devices for each driver. This series adds a probe function for the non modesetting drivers and removes the legacy probe code. The USB and platform drivers use the devices_list aswell which is unnecessary. This is also cleaned up in this series.
No it can't work like this because we have conflicts between fb and drm drivers, so the DRM is required to do its own probe if an fb driver for a device is already loaded.
it can't use the PCI probe out of the box.
I see. For example the i810 also has a framebuffer driver. Do you see a way to fix this except writing a kms driver for all legacy devices? Otherwise I would leave the pci part untouched and only keep the platform/USB pieces which I'm admittedly more interested in.
Its one of those things that would be a real pain to fix, since we can't remove drm drivers since their interfaces are ABI. So its why its been left like it is.
It might be possible to split the PCI path up a bit so the non-kms drivers use it, and we port kms ones to a newer interfaces, but I think nouveau is the only PCI KMS only driver we have (maybe vmwgfx as well).
Dave.
I see. For example the i810 also has a framebuffer driver. Do you see a way to fix this except writing a kms driver for all legacy devices? Otherwise I would leave the pci part untouched and only keep the platform/USB pieces which I'm admittedly more interested in.
Which is obsolete and unmaintained. More of a problem would be the various ati framebuffer drivers.
I would like to see Linux move to the situation where if there is a driver for a given device its either one or the other not one and some legacy code which is just extra work.
Doesn't need to be "all KMS" - but for any given card either/or seems perfectly reasonable.
The big thing that is needed is someone crazy enough to write a KMS driver to replace vesa/uvesafb and the like.
Alan
On Thu, Feb 02, 2012 at 02:27:18PM +0000, Alan Cox wrote:
I see. For example the i810 also has a framebuffer driver. Do you see a way to fix this except writing a kms driver for all legacy devices? Otherwise I would leave the pci part untouched and only keep the platform/USB pieces which I'm admittedly more interested in.
Which is obsolete and unmaintained. More of a problem would be the various ati framebuffer drivers.
I would like to see Linux move to the situation where if there is a driver for a given device its either one or the other not one and some legacy code which is just extra work.
Doesn't need to be "all KMS" - but for any given card either/or seems perfectly reasonable.
The big thing that is needed is someone crazy enough to write a KMS driver to replace vesa/uvesafb and the like.
I am currently working on a layer which provides all the necessary drm glue code for simple framebuffer devices. My test driver is a Freescale i.MX framebuffer driver. This currently has < 500 loc which is less than the corresponding driver under drivers/video. I am not crazy enough to implement a vesa KMS driver, but my hope is that these tasks can become quite easy with such a layer.
Sascha
dri-devel@lists.freedesktop.org