diff options
author | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2014-04-07 23:49:35 (GMT) |
commit | 62b8c978ee6b8d135d9e7953221de58000dba986 (patch) | |
tree | 683b04b2e627f6710c22c151b23c8cc9a165315e /drivers/gpu/drm/drm_sysfs.c | |
parent | 78fd82238d0e5716578c326404184a27ba67fd6e (diff) | |
download | linux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz |
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'drivers/gpu/drm/drm_sysfs.c')
-rw-r--r-- | drivers/gpu/drm/drm_sysfs.c | 118 |
1 files changed, 63 insertions, 55 deletions
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index c22c309..2290b3b 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -22,8 +22,8 @@ #include <drm/drm_core.h> #include <drm/drmP.h> -#define to_drm_minor(d) dev_get_drvdata(d) -#define to_drm_connector(d) dev_get_drvdata(d) +#define to_drm_minor(d) container_of(d, struct drm_minor, kdev) +#define to_drm_connector(d) container_of(d, struct drm_connector, kdev) static struct device_type drm_sysfs_device_minor = { .name = "drm_minor" @@ -162,6 +162,20 @@ void drm_sysfs_destroy(void) drm_class = NULL; } +/** + * drm_sysfs_device_release - do nothing + * @dev: Linux device + * + * Normally, this would free the DRM device associated with @dev, along + * with cleaning up any other stuff. But we do that in the DRM core, so + * this function can just return and hope that the core does its job. + */ +static void drm_sysfs_device_release(struct device *dev) +{ + memset(dev, 0, sizeof(struct device)); + return; +} + /* * Connector properties */ @@ -366,6 +380,11 @@ static struct bin_attribute edid_attr = { * properties (so far, connection status, dpms, mode list & edid) and * generate a hotplug event so userspace knows there's a new connector * available. + * + * Note: + * This routine should only be called *once* for each registered connector. + * A second call for an already registered connector will trigger the BUG_ON + * below. */ int drm_sysfs_connector_add(struct drm_connector *connector) { @@ -375,25 +394,29 @@ int drm_sysfs_connector_add(struct drm_connector *connector) int i; int ret; - if (connector->kdev) - return 0; + /* We shouldn't get called more than once for the same connector */ + BUG_ON(device_is_registered(&connector->kdev)); + + connector->kdev.parent = &dev->primary->kdev; + connector->kdev.class = drm_class; + connector->kdev.release = drm_sysfs_device_release; - connector->kdev = device_create(drm_class, dev->primary->kdev, - 0, connector, "card%d-%s", - dev->primary->index, drm_get_connector_name(connector)); DRM_DEBUG("adding \"%s\" to sysfs\n", drm_get_connector_name(connector)); - if (IS_ERR(connector->kdev)) { - DRM_ERROR("failed to register connector device: %ld\n", PTR_ERR(connector->kdev)); - ret = PTR_ERR(connector->kdev); + dev_set_name(&connector->kdev, "card%d-%s", + dev->primary->index, drm_get_connector_name(connector)); + ret = device_register(&connector->kdev); + + if (ret) { + DRM_ERROR("failed to register connector device: %d\n", ret); goto out; } /* Standard attributes */ for (attr_cnt = 0; attr_cnt < ARRAY_SIZE(connector_attrs); attr_cnt++) { - ret = device_create_file(connector->kdev, &connector_attrs[attr_cnt]); + ret = device_create_file(&connector->kdev, &connector_attrs[attr_cnt]); if (ret) goto err_out_files; } @@ -410,7 +433,7 @@ int drm_sysfs_connector_add(struct drm_connector *connector) case DRM_MODE_CONNECTOR_Component: case DRM_MODE_CONNECTOR_TV: for (opt_cnt = 0; opt_cnt < ARRAY_SIZE(connector_attrs_opt1); opt_cnt++) { - ret = device_create_file(connector->kdev, &connector_attrs_opt1[opt_cnt]); + ret = device_create_file(&connector->kdev, &connector_attrs_opt1[opt_cnt]); if (ret) goto err_out_files; } @@ -419,7 +442,7 @@ int drm_sysfs_connector_add(struct drm_connector *connector) break; } - ret = sysfs_create_bin_file(&connector->kdev->kobj, &edid_attr); + ret = sysfs_create_bin_file(&connector->kdev.kobj, &edid_attr); if (ret) goto err_out_files; @@ -430,10 +453,10 @@ int drm_sysfs_connector_add(struct drm_connector *connector) err_out_files: for (i = 0; i < opt_cnt; i++) - device_remove_file(connector->kdev, &connector_attrs_opt1[i]); + device_remove_file(&connector->kdev, &connector_attrs_opt1[i]); for (i = 0; i < attr_cnt; i++) - device_remove_file(connector->kdev, &connector_attrs[i]); - device_unregister(connector->kdev); + device_remove_file(&connector->kdev, &connector_attrs[i]); + device_unregister(&connector->kdev); out: return ret; @@ -457,16 +480,16 @@ void drm_sysfs_connector_remove(struct drm_connector *connector) { int i; - if (!connector->kdev) + if (!connector->kdev.parent) return; DRM_DEBUG("removing \"%s\" from sysfs\n", drm_get_connector_name(connector)); for (i = 0; i < ARRAY_SIZE(connector_attrs); i++) - device_remove_file(connector->kdev, &connector_attrs[i]); - sysfs_remove_bin_file(&connector->kdev->kobj, &edid_attr); - device_unregister(connector->kdev); - connector->kdev = NULL; + device_remove_file(&connector->kdev, &connector_attrs[i]); + sysfs_remove_bin_file(&connector->kdev.kobj, &edid_attr); + device_unregister(&connector->kdev); + connector->kdev.parent = NULL; } EXPORT_SYMBOL(drm_sysfs_connector_remove); @@ -485,15 +508,10 @@ void drm_sysfs_hotplug_event(struct drm_device *dev) DRM_DEBUG("generating hotplug event\n"); - kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp); + kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp); } EXPORT_SYMBOL(drm_sysfs_hotplug_event); -static void drm_sysfs_release(struct device *dev) -{ - kfree(dev); -} - /** * drm_sysfs_device_add - adds a class device to sysfs for a character driver * @dev: DRM device to be added @@ -505,9 +523,15 @@ static void drm_sysfs_release(struct device *dev) */ int drm_sysfs_device_add(struct drm_minor *minor) { + int err; char *minor_str; - int r; + minor->kdev.parent = minor->dev->dev; + + minor->kdev.class = drm_class; + minor->kdev.release = drm_sysfs_device_release; + minor->kdev.devt = minor->device; + minor->kdev.type = &drm_sysfs_device_minor; if (minor->type == DRM_MINOR_CONTROL) minor_str = "controlD%d"; else if (minor->type == DRM_MINOR_RENDER) @@ -515,34 +539,18 @@ int drm_sysfs_device_add(struct drm_minor *minor) else minor_str = "card%d"; - minor->kdev = kzalloc(sizeof(*minor->kdev), GFP_KERNEL); - if (!minor->kdev) { - r = -ENOMEM; - goto error; - } + dev_set_name(&minor->kdev, minor_str, minor->index); - device_initialize(minor->kdev); - minor->kdev->devt = MKDEV(DRM_MAJOR, minor->index); - minor->kdev->class = drm_class; - minor->kdev->type = &drm_sysfs_device_minor; - minor->kdev->parent = minor->dev->dev; - minor->kdev->release = drm_sysfs_release; - dev_set_drvdata(minor->kdev, minor); - - r = dev_set_name(minor->kdev, minor_str, minor->index); - if (r < 0) - goto error; - - r = device_add(minor->kdev); - if (r < 0) - goto error; + err = device_register(&minor->kdev); + if (err) { + DRM_ERROR("device add failed: %d\n", err); + goto err_out; + } return 0; -error: - DRM_ERROR("device create failed %d\n", r); - put_device(minor->kdev); - return r; +err_out: + return err; } /** @@ -554,9 +562,9 @@ error: */ void drm_sysfs_device_remove(struct drm_minor *minor) { - if (minor->kdev) - device_unregister(minor->kdev); - minor->kdev = NULL; + if (minor->kdev.parent) + device_unregister(&minor->kdev); + minor->kdev.parent = NULL; } |