]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
drm/bridge/adv7511: Delay clearing of HPD interrupt status
authorArchit Taneja <architt@codeaurora.org>
Mon, 29 Jan 2018 09:48:09 +0000 (15:18 +0530)
committerThadeu Lima de Souza Cascardo <cascardo@canonical.com>
Wed, 11 Apr 2018 16:43:54 +0000 (13:43 -0300)
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>
drivers/gpu/drm/bridge/adv7511/adv7511_drv.c

index efa29db5fc2b7eeff375d2f6cdafce9340fd6301..9d6e93a7a56d4d6c6ef4976dc2f1b6df96030b07 100644 (file)
@@ -450,7 +450,16 @@ static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd)
        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)