diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-12-14 00:23:18 +0300 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2016-12-14 00:23:18 +0300 |
commit | 010f5b9f0d44f73943e0b63d7f4362af227ae2ea (patch) | |
tree | 4dc737ec6bda0af04098ecaa5d1863780fcdd6e6 /drivers/gpu/drm/drm_drv.c | |
parent | de7b6be7f3009fef47a2ca0df237a055147b6d25 (diff) | |
parent | 2cf026ae85c42f253feb9f420d1b4bc99bd5503d (diff) | |
download | linux-010f5b9f0d44f73943e0b63d7f4362af227ae2ea.tar.xz |
Merge tag 'drm-for-v4.10' of git://people.freedesktop.org/~airlied/linux into drm-misc-next
Main pull request for drm for 4.10 kernel - resync drm-misc with full
4.10 state (2 new drivers) so that we can start pulling in all the
refactorings for 4.11!
Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'drivers/gpu/drm/drm_drv.c')
-rw-r--r-- | drivers/gpu/drm/drm_drv.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 4ec61ac27477..4a7b3e98d586 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -650,6 +650,62 @@ void drm_dev_unref(struct drm_device *dev) } EXPORT_SYMBOL(drm_dev_unref); +static int create_compat_control_link(struct drm_device *dev) +{ + struct drm_minor *minor; + char *name; + int ret; + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return 0; + + minor = *drm_minor_get_slot(dev, DRM_MINOR_PRIMARY); + if (!minor) + return 0; + + /* + * Some existing userspace out there uses the existing of the controlD* + * sysfs files to figure out whether it's a modeset driver. It only does + * readdir, hence a symlink is sufficient (and the least confusing + * option). Otherwise controlD* is entirely unused. + * + * Old controlD chardev have been allocated in the range + * 64-127. + */ + name = kasprintf(GFP_KERNEL, "controlD%d", minor->index + 64); + if (!name) + return -ENOMEM; + + ret = sysfs_create_link(minor->kdev->kobj.parent, + &minor->kdev->kobj, + name); + + kfree(name); + + return ret; +} + +static void remove_compat_control_link(struct drm_device *dev) +{ + struct drm_minor *minor; + char *name; + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return; + + minor = *drm_minor_get_slot(dev, DRM_MINOR_PRIMARY); + if (!minor) + return; + + name = kasprintf(GFP_KERNEL, "controlD%d", minor->index); + if (!name) + return; + + sysfs_remove_link(minor->kdev->kobj.parent, name); + + kfree(name); +} + /** * drm_dev_register - Register DRM device * @dev: Device to register @@ -688,6 +744,10 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) if (ret) goto err_minors; + ret = create_compat_control_link(dev); + if (ret) + goto err_minors; + if (dev->driver->load) { ret = dev->driver->load(dev, flags); if (ret) @@ -701,6 +761,7 @@ int drm_dev_register(struct drm_device *dev, unsigned long flags) goto out_unlock; err_minors: + remove_compat_control_link(dev); drm_minor_unregister(dev, DRM_MINOR_PRIMARY); drm_minor_unregister(dev, DRM_MINOR_RENDER); drm_minor_unregister(dev, DRM_MINOR_CONTROL); @@ -741,6 +802,7 @@ void drm_dev_unregister(struct drm_device *dev) list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head) drm_legacy_rmmap(dev, r_list->map); + remove_compat_control_link(dev); drm_minor_unregister(dev, DRM_MINOR_PRIMARY); drm_minor_unregister(dev, DRM_MINOR_RENDER); drm_minor_unregister(dev, DRM_MINOR_CONTROL); |