[Intel-gfx] [PATCH] drm/i915: Delay 250ms before running the hotplug code
Keith Packard
keithp at keithp.com
Fri Jul 29 01:49:46 CEST 2011
If the connector is inserted or removed slowly, the hotplug line may
well change state before the data lines do. So, assume the user isn't
trying to fool us and give them 250ms to get the connector plugged or
unplugged.
v2: use queue_delayed_work instead of msleep
Signed-off-by: Keith Packard <keithp at keithp.com>
---
drivers/gpu/drm/i915/i915_drv.h | 2 +-
drivers/gpu/drm/i915/i915_irq.c | 17 +++++++++--------
drivers/gpu/drm/i915/intel_display.c | 2 +-
3 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 6867e19..0e57ebc 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -315,7 +315,7 @@ typedef struct drm_i915_private {
u32 pch_irq_mask;
u32 hotplug_supported_mask;
- struct work_struct hotplug_work;
+ struct delayed_work hotplug_delayed_work;
int tex_lru_log_granularity;
int allow_batchbuffer;
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 02f96fd..11fe413 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -300,8 +300,9 @@ static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
*/
static void i915_hotplug_work_func(struct work_struct *work)
{
- drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
- hotplug_work);
+ struct delayed_work *delayed_work = to_delayed_work(work);
+ drm_i915_private_t *dev_priv = container_of(delayed_work, drm_i915_private_t,
+ hotplug_delayed_work);
struct drm_device *dev = dev_priv->dev;
struct drm_mode_config *mode_config = &dev->mode_config;
struct intel_encoder *encoder;
@@ -528,7 +529,7 @@ static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
/* check event from PCH */
if (de_iir & DE_PCH_EVENT_IVB) {
if (pch_iir & SDE_HOTPLUG_MASK_CPT)
- queue_work(dev_priv->wq, &dev_priv->hotplug_work);
+ queue_delayed_work(dev_priv->wq, &dev_priv->hotplug_delayed_work, HZ/4);
pch_irq_handler(dev);
}
@@ -627,7 +628,7 @@ static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
/* check event from PCH */
if (de_iir & DE_PCH_EVENT) {
if (pch_iir & hotplug_mask)
- queue_work(dev_priv->wq, &dev_priv->hotplug_work);
+ queue_delayed_work(dev_priv->wq, &dev_priv->hotplug_delayed_work, HZ/4);
pch_irq_handler(dev);
}
@@ -1279,8 +1280,8 @@ static irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
DRM_DEBUG_DRIVER("hotplug event received, stat 0x%08x\n",
hotplug_status);
if (hotplug_status & dev_priv->hotplug_supported_mask)
- queue_work(dev_priv->wq,
- &dev_priv->hotplug_work);
+ queue_delayed_work(dev_priv->wq,
+ &dev_priv->hotplug_delayed_work, HZ/4);
I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
I915_READ(PORT_HOTPLUG_STAT);
@@ -1742,7 +1743,7 @@ static void ironlake_irq_preinstall(struct drm_device *dev)
atomic_set(&dev_priv->irq_received, 0);
- INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
+ INIT_DELAYED_WORK(&dev_priv->hotplug_delayed_work, i915_hotplug_work_func);
INIT_WORK(&dev_priv->error_work, i915_error_work_func);
if (IS_GEN6(dev) || IS_IVYBRIDGE(dev))
INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work);
@@ -1906,7 +1907,7 @@ static void i915_driver_irq_preinstall(struct drm_device * dev)
atomic_set(&dev_priv->irq_received, 0);
- INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
+ INIT_DELAYED_WORK(&dev_priv->hotplug_delayed_work, i915_hotplug_work_func);
INIT_WORK(&dev_priv->error_work, i915_error_work_func);
if (I915_HAS_HOTPLUG(dev)) {
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ce908ec..d36e7fc 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -8361,7 +8361,7 @@ void intel_modeset_cleanup(struct drm_device *dev)
/* Disable the irq before mode object teardown, for the irq might
* enqueue unpin/hotplug work. */
drm_irq_uninstall(dev);
- cancel_work_sync(&dev_priv->hotplug_work);
+ cancel_delayed_work_sync(&dev_priv->hotplug_delayed_work);
/* flush any delayed tasks or pending work */
flush_scheduled_work();
--
1.7.5.4
More information about the Intel-gfx
mailing list