aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJani Nikula2013-04-12 07:18:38 -0500
committerGreg Kroah-Hartman2013-05-11 15:54:02 -0500
commit99367f6b937fd2cd0148c933b76ce7b4883d6501 (patch)
tree14b90a19ffd2c5f3e3b9b65b562928d6d01cbac9
parent12622510457a776e4871e314c99ca1e279f8c399 (diff)
downloadkernel-omap-99367f6b937fd2cd0148c933b76ce7b4883d6501.tar.gz
kernel-omap-99367f6b937fd2cd0148c933b76ce7b4883d6501.tar.xz
kernel-omap-99367f6b937fd2cd0148c933b76ce7b4883d6501.zip
drm/i915: ensure single initialization and cleanup of backlight device
commit dc652f90e088798bfa31f496ba994ddadd5d5680 upstream. Backlight cleanup in the eDP connector destroy callback caused the backlight device to be removed on some systems that first initialized LVDS and then attempted to initialize eDP. Prevent multiple backlight initializations, and ensure backlight cleanup is only done once by moving it to modeset cleanup. A small wrinkle is the introduced asymmetry in backlight setup/cleanup. This could be solved by adding refcounting, but it seems overkill considering that there should only ever be one backlight device. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=55701 Signed-off-by: Jani Nikula <jani.nikula@intel.com> Tested-by: Peter Verthez <peter.verthez@skynet.be> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/gpu/drm/i915/intel_display.c3
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c5
-rw-r--r--drivers/gpu/drm/i915/intel_lvds.c1
-rw-r--r--drivers/gpu/drm/i915/intel_panel.c7
4 files changed, 10 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index d3f834a56ab3..6c9535967166 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9388,6 +9388,9 @@ void intel_modeset_cleanup(struct drm_device *dev)
9388 /* flush any delayed tasks or pending work */ 9388 /* flush any delayed tasks or pending work */
9389 flush_scheduled_work(); 9389 flush_scheduled_work();
9390 9390
9391 /* destroy backlight, if any, before the connectors */
9392 intel_panel_destroy_backlight(dev);
9393
9391 drm_mode_config_cleanup(dev); 9394 drm_mode_config_cleanup(dev);
9392} 9395}
9393 9396
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index 73ce6e903be6..cbe1ec3d07bd 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -2467,17 +2467,14 @@ done:
2467static void 2467static void
2468intel_dp_destroy(struct drm_connector *connector) 2468intel_dp_destroy(struct drm_connector *connector)
2469{ 2469{
2470 struct drm_device *dev = connector->dev;
2471 struct intel_dp *intel_dp = intel_attached_dp(connector); 2470 struct intel_dp *intel_dp = intel_attached_dp(connector);
2472 struct intel_connector *intel_connector = to_intel_connector(connector); 2471 struct intel_connector *intel_connector = to_intel_connector(connector);
2473 2472
2474 if (!IS_ERR_OR_NULL(intel_connector->edid)) 2473 if (!IS_ERR_OR_NULL(intel_connector->edid))
2475 kfree(intel_connector->edid); 2474 kfree(intel_connector->edid);
2476 2475
2477 if (is_edp(intel_dp)) { 2476 if (is_edp(intel_dp))
2478 intel_panel_destroy_backlight(dev);
2479 intel_panel_fini(&intel_connector->panel); 2477 intel_panel_fini(&intel_connector->panel);
2480 }
2481 2478
2482 drm_sysfs_connector_remove(connector); 2479 drm_sysfs_connector_remove(connector);
2483 drm_connector_cleanup(connector); 2480 drm_connector_cleanup(connector);
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index f93078221924..8b383a61a957 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -556,7 +556,6 @@ static void intel_lvds_destroy(struct drm_connector *connector)
556 if (!IS_ERR_OR_NULL(lvds_connector->base.edid)) 556 if (!IS_ERR_OR_NULL(lvds_connector->base.edid))
557 kfree(lvds_connector->base.edid); 557 kfree(lvds_connector->base.edid);
558 558
559 intel_panel_destroy_backlight(connector->dev);
560 intel_panel_fini(&lvds_connector->base.panel); 559 intel_panel_fini(&lvds_connector->base.panel);
561 560
562 drm_sysfs_connector_remove(connector); 561 drm_sysfs_connector_remove(connector);
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index bee8cb6108a7..94d895b665d5 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -422,6 +422,9 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
422 422
423 intel_panel_init_backlight(dev); 423 intel_panel_init_backlight(dev);
424 424
425 if (WARN_ON(dev_priv->backlight))
426 return -ENODEV;
427
425 memset(&props, 0, sizeof(props)); 428 memset(&props, 0, sizeof(props));
426 props.type = BACKLIGHT_RAW; 429 props.type = BACKLIGHT_RAW;
427 props.max_brightness = _intel_panel_get_max_backlight(dev); 430 props.max_brightness = _intel_panel_get_max_backlight(dev);
@@ -447,8 +450,10 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
447void intel_panel_destroy_backlight(struct drm_device *dev) 450void intel_panel_destroy_backlight(struct drm_device *dev)
448{ 451{
449 struct drm_i915_private *dev_priv = dev->dev_private; 452 struct drm_i915_private *dev_priv = dev->dev_private;
450 if (dev_priv->backlight) 453 if (dev_priv->backlight) {
451 backlight_device_unregister(dev_priv->backlight); 454 backlight_device_unregister(dev_priv->backlight);
455 dev_priv->backlight = NULL;
456 }
452} 457}
453#else 458#else
454int intel_panel_setup_backlight(struct drm_connector *connector) 459int intel_panel_setup_backlight(struct drm_connector *connector)