drm/i915: abstract hpd irq storm detection

Simplify intel_hpd_irq_handler() by extracting HPD irq storm detection
to a separate function.

Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
Jani Nikula 2015-05-29 16:14:37 +03:00 committed by Daniel Vetter
parent bd4b4827ac
commit a2ee48d60e
1 changed files with 40 additions and 13 deletions

View File

@ -1375,6 +1375,45 @@ static irqreturn_t gen8_gt_irq_handler(struct drm_i915_private *dev_priv,
#define HPD_STORM_DETECT_PERIOD 1000
#define HPD_STORM_THRESHOLD 5
/**
* intel_hpd_irq_storm - gather stats and detect HPD irq storm on a pin
* @dev_priv: private driver data pointer
* @pin: the pin to gather stats on
*
* Gather stats about HPD irqs from the specified @pin, and detect irq
* storms. Only the pin specific stats and state are changed, the caller is
* responsible for further action.
*
* @HPD_STORM_THRESHOLD irqs are allowed within @HPD_STORM_DETECT_PERIOD ms,
* otherwise it's considered an irq storm, and the irq state is set to
* @HPD_MARK_DISABLED.
*
* Return true if an irq storm was detected on @pin.
*/
static bool intel_hpd_irq_storm(struct drm_i915_private *dev_priv,
enum hpd_pin pin)
{
unsigned long start = dev_priv->hotplug.stats[pin].last_jiffies;
unsigned long end = start + msecs_to_jiffies(HPD_STORM_DETECT_PERIOD);
bool storm = false;
if (!time_in_range(jiffies, start, end)) {
dev_priv->hotplug.stats[pin].last_jiffies = jiffies;
dev_priv->hotplug.stats[pin].count = 0;
DRM_DEBUG_KMS("Received HPD interrupt on PIN %d - cnt: 0\n", pin);
} else if (dev_priv->hotplug.stats[pin].count > HPD_STORM_THRESHOLD) {
dev_priv->hotplug.stats[pin].state = HPD_MARK_DISABLED;
DRM_DEBUG_KMS("HPD interrupt storm detected on PIN %d\n", pin);
storm = true;
} else {
dev_priv->hotplug.stats[pin].count++;
DRM_DEBUG_KMS("Received HPD interrupt on PIN %d - cnt: %d\n", pin,
dev_priv->hotplug.stats[pin].count);
}
return storm;
}
static bool pch_port_hotplug_long_detect(enum port port, u32 val)
{
switch (port) {
@ -1544,21 +1583,9 @@ static void intel_hpd_irq_handler(struct drm_device *dev,
queue_hp = true;
}
if (!time_in_range(jiffies, dev_priv->hotplug.stats[i].last_jiffies,
dev_priv->hotplug.stats[i].last_jiffies
+ msecs_to_jiffies(HPD_STORM_DETECT_PERIOD))) {
dev_priv->hotplug.stats[i].last_jiffies = jiffies;
dev_priv->hotplug.stats[i].count = 0;
DRM_DEBUG_KMS("Received HPD interrupt on PIN %d - cnt: 0\n", i);
} else if (dev_priv->hotplug.stats[i].count > HPD_STORM_THRESHOLD) {
dev_priv->hotplug.stats[i].state = HPD_MARK_DISABLED;
if (intel_hpd_irq_storm(dev_priv, i)) {
dev_priv->hotplug.event_bits &= ~BIT(i);
DRM_DEBUG_KMS("HPD interrupt storm detected on PIN %d\n", i);
storm_detected = true;
} else {
dev_priv->hotplug.stats[i].count++;
DRM_DEBUG_KMS("Received HPD interrupt on PIN %d - cnt: %d\n", i,
dev_priv->hotplug.stats[i].count);
}
}