Skip to content

Commit

Permalink
Merge tag 'drm-misc-next-fixes-2016-12-10' of git://anongit.freedeskt…
Browse files Browse the repository at this point in the history
…op.org/git/drm-misc into drm-next

single fix for backwards compat.

* tag 'drm-misc-next-fixes-2016-12-10' of git://anongit.freedesktop.org/git/drm-misc:
  drm: Add fake controlD* symlinks for backwards compat
  • Loading branch information
Dave Airlie committed Dec 13, 2016
2 parents 2601a15 + 6449b08 commit 8a5c61f
Showing 1 changed file with 62 additions and 0 deletions.
62 changes: 62 additions & 0 deletions drivers/gpu/drm/drm_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,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
Expand Down Expand Up @@ -685,6 +741,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)
Expand All @@ -698,6 +758,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);
Expand Down Expand Up @@ -738,6 +799,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);
Expand Down

0 comments on commit 8a5c61f

Please sign in to comment.