BugLink: http://bugs.launchpad.net/bugs/1763040
When a hotplug event occurs, the adv7511 interrupt handler schedules
an hpd work after clearing the interrupt status registers
(ADV7511_REG_INT(x). The hpd work calls a drm helper that sends a
uevent to notify the userspace about the hotplug event.
On a hotplug connect, the userspace generally acts upon this uevent by
calling an ioctl (DRM_IOCTL_MODE_GETCONNECTOR) that probes on the
connector.This results in the connector's detect() drm_connector_func
being called. In the ADV7511 driver, this is a wrapper around the
adv7511_detect() call.
adv7511_detect() checks on the same interrupt ADV7511_REG_INT(0)
register which was previously cleared by the interrupt handler,
resulting in the func not realizing that a hotplug connect event
took place. ADV7511 loses its state when a disconnect happens, and
the driver needs to do a power-on to re-enable the hardware. This
fails to happen since calls to adv7511_detect() can fail to identify
that a hotplug connect took place.
Fix this by delaying the clearing of the ADV7511_INT0_HPD status flag.
Let the call to adv7511_hpd() be the only one responsible for clearing
this bitfield.
Note: Not sure if this is the best approach. Clearing a status flag
outside of the interrupt handler is generally looked down upon.
Signed-off-by: Archit Taneja <architt@codeaurora.org>
(cherry picked from commit
a80597ef620a0633f96ede44d530d5ef805dbdfc
http://git.linaro.org/landing-teams/working/qualcomm/kernel.git release/qcomlt-4.14)
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
Acked-by: Seth Forshee <seth.forshee@canonical.com>
Acked-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
if (ret < 0)
return ret;
- regmap_write(adv7511->regmap, ADV7511_REG_INT(0), irq0);
+ /*
+ * Don't clear HPD flag right now, let it be cleared later in
+ * adv7511_detect(). If we don't do this, adv7511_detect
+ * (i.e. the connector's detect op) doesn't realize that we need to
+ * re-enable the display.
+ *
+ * Problem with this fix: Can not clearing this flag before returning
+ * IRQ_HANDLED cause spurious interrupts?
+ */
+ regmap_write(adv7511->regmap, ADV7511_REG_INT(0), irq0 & ~ADV7511_INT0_HPD);
regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1);
if (process_hpd && irq0 & ADV7511_INT0_HPD && adv7511->bridge.encoder)