[Intel-gfx] [PATCH 05/10] drm/i915: Move the ACPI lid notifier away from LVDS to the generic panel

Chris Wilson chris at chris-wilson.co.uk
Fri Apr 22 11:19:13 CEST 2011


... in preparation for enabling it from eDP as well.

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/intel_drv.h   |    8 +++
 drivers/gpu/drm/i915/intel_lvds.c  |   79 ++-----------------------------
 drivers/gpu/drm/i915/intel_panel.c |   92 ++++++++++++++++++++++++++++++++++++
 3 files changed, 104 insertions(+), 75 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f5b0d83..7ca9003 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -257,6 +257,14 @@ extern void intel_edp_link_config (struct intel_encoder *, int *, int *);
 extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder);
 
 /* intel_panel.c */
+struct intel_panel {
+	struct intel_connector *connector;
+	struct notifier_block lid_notifier;
+};
+extern int intel_panel_init(struct intel_panel *panel,
+			    struct intel_connector *connector);
+extern void intel_panel_fini(struct intel_panel *panel);
+
 extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode,
 				   struct drm_display_mode *adjusted_mode);
 extern void intel_pch_panel_fitting(struct drm_device *dev,
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index f87adaa..20d6235 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -27,7 +27,6 @@
  *      Jesse Barnes <jesse.barnes at intel.com>
  */
 
-#include <acpi/button.h>
 #include <linux/dmi.h>
 #include <linux/i2c.h>
 #include <linux/slab.h>
@@ -38,13 +37,12 @@
 #include "intel_drv.h"
 #include "i915_drm.h"
 #include "i915_drv.h"
-#include <linux/acpi.h>
 
 /* Private structure for the integrated LVDS support */
 struct intel_lvds_connector {
 	struct intel_connector base;
+	struct intel_panel panel;
 
-	struct notifier_block lid_notifier;
 	struct drm_display_mode *fixed_mode;
 	struct edid *edid;
 
@@ -509,71 +507,6 @@ static int intel_lvds_connector_get_modes(struct drm_connector *connector)
 	return 1;
 }
 
-static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id)
-{
-	DRM_DEBUG_KMS("Skipping forced modeset for %s\n", id->ident);
-	return 1;
-}
-
-/* The GPU hangs up on these systems if modeset is performed on LID open */
-static const struct dmi_system_id intel_no_modeset_on_lid[] = {
-	{
-		.callback = intel_no_modeset_on_lid_dmi_callback,
-		.ident = "Toshiba Tecra A11",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A11"),
-		},
-	},
-
-	{ }	/* terminating entry */
-};
-
-/*
- * Lid events. Note the use of 'modeset_on_lid':
- *  - we set it on lid close, and reset it on open
- *  - we use it as a "only once" bit (ie we ignore
- *    duplicate events where it was already properly
- *    set/reset)
- *  - the suspend/resume paths will also set it to
- *    zero, since they restore the mode ("lid open").
- */
-static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
-			    void *unused)
-{
-	struct intel_lvds_connector *lvds_connector =
-		container_of(nb, struct intel_lvds_connector, lid_notifier);
-	struct drm_device *dev = lvds_connector->base.base.dev;
-	struct drm_i915_private *dev_priv = dev->dev_private;
-
-	/*
-	 * check and update the status of LVDS connector after receiving
-	 * the LID nofication event.
-	 */
-	lvds_connector->base.base.status =
-		lvds_connector->base.base.funcs->detect(&lvds_connector->base.base,
-							false);
-
-	/* Don't force modeset on machines where it causes a GPU lockup */
-	if (dmi_check_system(intel_no_modeset_on_lid))
-		return NOTIFY_OK;
-	if (!acpi_lid_open()) {
-		dev_priv->modeset_on_lid = 1;
-		return NOTIFY_OK;
-	}
-
-	if (!dev_priv->modeset_on_lid)
-		return NOTIFY_OK;
-
-	dev_priv->modeset_on_lid = 0;
-
-	mutex_lock(&dev->mode_config.mutex);
-	drm_helper_resume_force_mode(dev);
-	mutex_unlock(&dev->mode_config.mutex);
-
-	return NOTIFY_OK;
-}
-
 /**
  * intel_lvds_encoder_destroy - unregister and free LVDS structures
  * @connector: connector to free
@@ -586,8 +519,7 @@ static void intel_lvds_connector_destroy(struct drm_connector *connector)
 	struct intel_lvds_connector *lvds_connector =
 		to_lvds_connector(connector);
 
-	if (lvds_connector->lid_notifier.notifier_call)
-		acpi_lid_notifier_unregister(&lvds_connector->lid_notifier);
+	intel_panel_fini(&lvds_connector->panel);
 
 	drm_sysfs_connector_remove(connector);
 	drm_connector_cleanup(connector);
@@ -1063,11 +995,8 @@ out:
 		pwm |= PWM_PCH_ENABLE;
 		I915_WRITE(BLC_PWM_PCH_CTL1, pwm);
 	}
-	lvds_connector->lid_notifier.notifier_call = intel_lid_notify;
-	if (acpi_lid_notifier_register(&lvds_connector->lid_notifier)) {
-		DRM_DEBUG_KMS("lid notifier registration failed\n");
-		lvds_connector->lid_notifier.notifier_call = NULL;
-	}
+
+	intel_panel_init(&lvds_connector->panel, &lvds_connector->base);
 	drm_sysfs_connector_add(connector);
 	return true;
 
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index a06ff07..d2dc066 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -28,6 +28,10 @@
  *      Chris Wilson <chris at chris-wilson.co.uk>
  */
 
+#include <linux/acpi.h>
+#include <linux/dmi.h>
+#include <acpi/button.h>
+
 #include "intel_drv.h"
 
 #define PCI_LBPC 0xf4 /* legacy/combination backlight modes */
@@ -112,6 +116,94 @@ done:
 	dev_priv->pch_pf_size = (width << 16) | height;
 }
 
+/* Lid interactions */
+
+static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id)
+{
+	DRM_DEBUG_KMS("Skipping forced modeset for %s\n", id->ident);
+	return 1;
+}
+
+/* The GPU hangs up on these systems if modeset is performed on LID open */
+static const struct dmi_system_id intel_no_modeset_on_lid[] = {
+	{
+		.callback = intel_no_modeset_on_lid_dmi_callback,
+		.ident = "Toshiba Tecra A11",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A11"),
+		},
+	},
+
+	{ }	/* terminating entry */
+};
+
+/*
+ * Lid events. Note the use of 'modeset_on_lid':
+ *  - we set it on lid close, and reset it on open
+ *  - we use it as a "only once" bit (ie we ignore
+ *    duplicate events where it was already properly
+ *    set/reset)
+ *  - the suspend/resume paths will also set it to
+ *    zero, since they restore the mode ("lid open").
+ */
+static int intel_panel_lid_notify(struct notifier_block *nb, unsigned long val,
+				  void *unused)
+{
+	struct intel_panel *panel =
+		container_of(nb, struct intel_panel, lid_notifier);
+	struct intel_connector *connector = panel->connector;
+	struct drm_device *dev = connector->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/*
+	 * check and update the status of LVDS connector after receiving
+	 * the LID nofication event.
+	 */
+	connector->base.status =
+		connector->base.funcs->detect(&connector->base, false);
+
+	/* Don't force modeset on machines where it causes a GPU lockup */
+	if (dmi_check_system(intel_no_modeset_on_lid))
+		return NOTIFY_OK;
+	if (!acpi_lid_open()) {
+		dev_priv->modeset_on_lid = 1;
+		return NOTIFY_OK;
+	}
+
+	if (!dev_priv->modeset_on_lid)
+		return NOTIFY_OK;
+
+	dev_priv->modeset_on_lid = 0;
+
+	mutex_lock(&dev->mode_config.mutex);
+	drm_helper_resume_force_mode(dev);
+	mutex_unlock(&dev->mode_config.mutex);
+
+	return NOTIFY_OK;
+}
+
+int intel_panel_init(struct intel_panel *panel, struct intel_connector *connector)
+{
+	panel->connector = connector;
+
+	panel->lid_notifier.notifier_call = intel_panel_lid_notify;
+	if (acpi_lid_notifier_register(&panel->lid_notifier)) {
+		DRM_DEBUG_KMS("lid notifier registration failed\n");
+		panel->lid_notifier.notifier_call = NULL;
+	}
+
+	return 0;
+}
+
+void intel_panel_fini(struct intel_panel *panel)
+{
+	if (panel->lid_notifier.notifier_call)
+		acpi_lid_notifier_unregister(&panel->lid_notifier);
+}
+
+/* Panel backlight controls */
+
 static int is_backlight_combination_mode(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
-- 
1.7.4.1




More information about the Intel-gfx mailing list