From c1bf8ceb2e137dff210a003269c8b42c894e7502 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 14 Sep 2010 19:59:53 +1000 Subject: [PATCH] drm: workaround race condtion v1 --- drivers/gpu/drm/drm_pci.c | 14 ++++++++++++++ drivers/gpu/drm/drm_platform.c | 15 +++++++++++++++ drivers/gpu/drm/drm_stub.c | 17 +++++++++++------ drivers/gpu/drm/drm_sysfs.c | 19 +++++++++++++++++-- drivers/gpu/drm/i915/intel_crt.c | 2 -- drivers/gpu/drm/i915/intel_dp.c | 1 - drivers/gpu/drm/i915/intel_dvo.c | 1 - drivers/gpu/drm/i915/intel_hdmi.c | 2 -- drivers/gpu/drm/i915/intel_lvds.c | 1 - drivers/gpu/drm/i915/intel_sdvo.c | 1 - drivers/gpu/drm/i915/intel_tv.c | 2 +- drivers/gpu/drm/nouveau/nouveau_connector.c | 1 - drivers/gpu/drm/radeon/radeon_connectors.c | 2 -- include/drm/drmP.h | 3 ++- 14 files changed, 60 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index e20f78b..0d11371 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c @@ -193,6 +193,20 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, goto err_g4; } + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + ret = drm_register_minor(dev->control); + if (ret) + goto err_g4; + } + ret = drm_register_minor(dev->primary); + if (ret) + goto err_g4; + + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + ret = drm_sysfs_connectors_add(dev); + if (ret) + 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", diff --git a/drivers/gpu/drm/drm_platform.c b/drivers/gpu/drm/drm_platform.c index 460e9a3..8e4b07d 100644 --- a/drivers/gpu/drm/drm_platform.c +++ b/drivers/gpu/drm/drm_platform.c @@ -85,6 +85,21 @@ int drm_get_platform_dev(struct platform_device *platdev, goto err_g3; } + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + ret = drm_register_minor(dev->control); + if (ret) + goto err_g3; + } + ret = drm_register_minor(dev->primary); + if (ret) + goto err_g3; + + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + ret = drm_sysfs_connectors_add(dev); + if (ret) + goto err_g3; + } + list_add_tail(&dev->driver_item, &driver->device_list); DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index d1ad574..97423bc 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -359,12 +359,6 @@ int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type) } #endif - ret = drm_sysfs_device_add(new_minor); - if (ret) { - printk(KERN_ERR - "DRM: Error sysfs_device_add.\n"); - goto err_g2; - } *minor = new_minor; DRM_DEBUG("new minor assigned %d\n", minor_id); @@ -382,6 +376,17 @@ err_idr: return ret; } +int drm_register_minor(struct drm_minor *minor) +{ + int ret; + ret = drm_sysfs_device_add(minor); + if (ret) { + printk(KERN_ERR + "DRM: Error sysfs_device_add.\n"); + } + return ret; +} + /** * Put a secondary minor number. * diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index 85da4c4..62b09c3 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -352,7 +352,7 @@ static struct bin_attribute edid_attr = { * A second call for an already registered device will trigger the BUG_ON * below. */ -int drm_sysfs_connector_add(struct drm_connector *connector) +static int drm_sysfs_connector_add(struct drm_connector *connector) { struct drm_device *dev = connector->dev; int attr_cnt = 0; @@ -427,9 +427,24 @@ err_out_files: out: return ret; } -EXPORT_SYMBOL(drm_sysfs_connector_add); /** + * drm_sysfs_connectors_add - add all connectors to sysfs + * @connector: connector to add + */ +int drm_sysfs_connectors_add(struct drm_device *dev) +{ + struct drm_connector *connector; + int ret; + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + ret = drm_sysfs_connector_add(connector); + if (ret) + return ret; + } + return 0; +} +/** * drm_sysfs_connector_remove - remove an connector device from sysfs * @connector: connector to remove * diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 0350e5d..8f69c46 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -570,8 +570,6 @@ void intel_crt_init(struct drm_device *dev) drm_encoder_helper_add(&intel_encoder->enc, &intel_crt_helper_funcs); drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); - drm_sysfs_connector_add(connector); - if (I915_HAS_HOTPLUG(dev)) connector->polled = DRM_CONNECTOR_POLL_HPD; else diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index e1a2a05..8d6e496 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1620,7 +1620,6 @@ intel_dp_init(struct drm_device *dev, int output_reg) drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); - drm_sysfs_connector_add(connector); /* Set up the DDC bus. */ switch (output_reg) { diff --git a/drivers/gpu/drm/i915/intel_dvo.c b/drivers/gpu/drm/i915/intel_dvo.c index f0de1ad..d7d82c7 100644 --- a/drivers/gpu/drm/i915/intel_dvo.c +++ b/drivers/gpu/drm/i915/intel_dvo.c @@ -448,7 +448,6 @@ void intel_dvo_init(struct drm_device *dev) intel_dvo->panel_wants_dither = true; } - drm_sysfs_connector_add(connector); return; } diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 2ea123d..1fd71f1 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c @@ -176,7 +176,6 @@ static int intel_hdmi_get_modes(struct drm_connector *connector) static void intel_hdmi_destroy(struct drm_connector *connector) { - drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); kfree(connector); } @@ -273,7 +272,6 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) drm_mode_connector_attach_encoder(&intel_connector->base, &intel_encoder->enc); - drm_sysfs_connector_add(connector); /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written * 0xd. Failure to do so will result in spurious interrupts being diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index fb1bed8..b32ef76 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -993,7 +993,6 @@ out: } /* keep the LVDS connector */ dev_priv->int_lvds_connector = connector; - drm_sysfs_connector_add(connector); return; failed: diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index db6b6d4..14e6c15 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -2090,7 +2090,6 @@ intel_sdvo_connector_init(struct drm_encoder *encoder, connector->display_info.subpixel_order = SubPixelHorizontalRGB; drm_mode_connector_attach_encoder(connector, encoder); - drm_sysfs_connector_add(connector); } static bool diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index d20b550..4b2a05b 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1710,5 +1710,5 @@ intel_tv_init(struct drm_device *dev) dev->mode_config.tv_bottom_margin_property, intel_tv->margin[TV_MARGIN_BOTTOM]); out: - drm_sysfs_connector_add(connector); + return; } diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 67d515c..5dcec0e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -841,7 +841,6 @@ nouveau_connector_create(struct drm_device *dev, int index) nouveau_connector_set_polling(connector); - drm_sysfs_connector_add(connector); dcb->drm = connector; return dcb->drm; diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 31d309a..41f76c1 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1264,7 +1264,6 @@ radeon_add_atom_connector(struct drm_device *dev, connector->polled = DRM_CONNECTOR_POLL_HPD; connector->display_info.subpixel_order = subpixel_order; - drm_sysfs_connector_add(connector); return; failed: @@ -1407,7 +1406,6 @@ radeon_add_legacy_connector(struct drm_device *dev, } else connector->polled = DRM_CONNECTOR_POLL_HPD; connector->display_info.subpixel_order = subpixel_order; - drm_sysfs_connector_add(connector); return; failed: diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 7809d23..2281250 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1447,7 +1447,7 @@ extern int drm_sysfs_device_add(struct drm_minor *minor); extern void drm_sysfs_hotplug_event(struct drm_device *dev); extern void drm_sysfs_device_remove(struct drm_minor *minor); extern char *drm_get_connector_status_name(enum drm_connector_status status); -extern int drm_sysfs_connector_add(struct drm_connector *connector); +extern int drm_sysfs_connectors_add(struct drm_device *dev); extern void drm_sysfs_connector_remove(struct drm_connector *connector); /* Graphics Execution Manager library functions (drm_gem.c) */ @@ -1598,6 +1598,7 @@ 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_minor(struct drm_minor *minor); /*@}*/ #endif /* __KERNEL__ */ -- 1.7.2.2