--- /dev/null
+From d0be8584b01160eb6f49e77f8e9c1da286bb4ffb Mon Sep 17 00:00:00 2001
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Date: Mon, 4 Jan 2016 03:33:45 +0100
+Subject: drm: adv7511: really enable interrupts for EDID detection
+
+From: Wolfram Sang <wsa+renesas@sang-engineering.com>
+
+commit d0be8584b01160eb6f49e77f8e9c1da286bb4ffb upstream.
+
+The interrupts for EDID_READY or DDC_ERROR were never enabled in this
+driver, so reading EDID always timed out when chip was powered down and
+interrupts were used. Fix this and also remove clearing the interrupt
+flags, they are cleared in POWER_DOWN mode anyhow (unlike the interrupt
+enable flags) according to docs and my tests.
+
+Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Tested-by: Archit Taneja <architt@codeaurora.org>
+Signed-off-by: Thong Ho <thong.ho.px@rvc.renesas.com>
+Signed-off-by: Nhan Nguyen <nhan.nguyen.yb@renesas.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i2c/adv7511.c | 25 +++++++++++++++++--------
+ 1 file changed, 17 insertions(+), 8 deletions(-)
+
+--- a/drivers/gpu/drm/i2c/adv7511.c
++++ b/drivers/gpu/drm/i2c/adv7511.c
+@@ -362,12 +362,19 @@ static void adv7511_power_on(struct adv7
+ {
+ adv7511->current_edid_segment = -1;
+
+- regmap_write(adv7511->regmap, ADV7511_REG_INT(0),
+- ADV7511_INT0_EDID_READY);
+- regmap_write(adv7511->regmap, ADV7511_REG_INT(1),
+- ADV7511_INT1_DDC_ERROR);
+ regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
+ ADV7511_POWER_POWER_DOWN, 0);
++ if (adv7511->i2c_main->irq) {
++ /*
++ * Documentation says the INT_ENABLE registers are reset in
++ * POWER_DOWN mode. My 7511w preserved the bits, however.
++ * Still, let's be safe and stick to the documentation.
++ */
++ regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(0),
++ ADV7511_INT0_EDID_READY);
++ regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(1),
++ ADV7511_INT1_DDC_ERROR);
++ }
+
+ /*
+ * Per spec it is allowed to pulse the HDP signal to indicate that the
+@@ -567,12 +574,14 @@ static int adv7511_get_modes(struct drm_
+
+ /* Reading the EDID only works if the device is powered */
+ if (!adv7511->powered) {
+- regmap_write(adv7511->regmap, ADV7511_REG_INT(0),
+- ADV7511_INT0_EDID_READY);
+- regmap_write(adv7511->regmap, ADV7511_REG_INT(1),
+- ADV7511_INT1_DDC_ERROR);
+ regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER,
+ ADV7511_POWER_POWER_DOWN, 0);
++ if (adv7511->i2c_main->irq) {
++ regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(0),
++ ADV7511_INT0_EDID_READY);
++ regmap_write(adv7511->regmap, ADV7511_REG_INT_ENABLE(1),
++ ADV7511_INT1_DDC_ERROR);
++ }
+ adv7511->current_edid_segment = -1;
+ }
+
--- /dev/null
+From f0bfcc22d9822947b0ad3095e8363eab5261864c Mon Sep 17 00:00:00 2001
+From: Archit Taneja <architt@codeaurora.org>
+Date: Wed, 15 Jun 2016 16:20:45 +0530
+Subject: drm/bridge: adv7511: Fix mutex deadlock when interrupts are disabled
+
+From: Archit Taneja <architt@codeaurora.org>
+
+commit f0bfcc22d9822947b0ad3095e8363eab5261864c upstream.
+
+When the adv7511 i2c client doesn't have an interrupt line, we observe a
+deadlock on caused by trying to lock drm device's mode_config.mutex twice
+in the same context.
+
+Here is the sequence that causes it:
+
+ioctl DRM_IOCTL_MODE_GETCONNECTOR from userspace
+ drm_mode_getconnector (acquires mode_config mutex)
+ connector->fill_modes()
+ drm_helper_probe_single_connector_modes
+ connector_funcs->get_modes
+ adv7511_encoder_get_modes
+ adv7511_get_edid_block
+ adv7511_irq_process
+ drm_helper_hpd_irq_event (acquires mode_config mutex again)
+
+In adv7511_irq_process, don't call drm_helper_hpd_irq_event when not
+called from the interrupt handler. It doesn't serve any purpose there
+anyway.
+
+Signed-off-by: Archit Taneja <architt@codeaurora.org>
+Signed-off-by: Thong Ho <thong.ho.px@rvc.renesas.com>
+Signed-off-by: Nhan Nguyen <nhan.nguyen.yb@renesas.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i2c/adv7511.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/i2c/adv7511.c
++++ b/drivers/gpu/drm/i2c/adv7511.c
+@@ -429,7 +429,7 @@ static bool adv7511_hpd(struct adv7511 *
+ return false;
+ }
+
+-static int adv7511_irq_process(struct adv7511 *adv7511)
++static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd)
+ {
+ unsigned int irq0, irq1;
+ int ret;
+@@ -445,7 +445,7 @@ static int adv7511_irq_process(struct ad
+ regmap_write(adv7511->regmap, ADV7511_REG_INT(0), irq0);
+ regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1);
+
+- if (irq0 & ADV7511_INT0_HDP && adv7511->encoder)
++ if (process_hpd && irq0 & ADV7511_INT0_HDP && adv7511->encoder)
+ drm_helper_hpd_irq_event(adv7511->encoder->dev);
+
+ if (irq0 & ADV7511_INT0_EDID_READY || irq1 & ADV7511_INT1_DDC_ERROR) {
+@@ -463,7 +463,7 @@ static irqreturn_t adv7511_irq_handler(i
+ struct adv7511 *adv7511 = devid;
+ int ret;
+
+- ret = adv7511_irq_process(adv7511);
++ ret = adv7511_irq_process(adv7511, true);
+ return ret < 0 ? IRQ_NONE : IRQ_HANDLED;
+ }
+
+@@ -480,7 +480,7 @@ static int adv7511_wait_for_edid(struct
+ adv7511->edid_read, msecs_to_jiffies(timeout));
+ } else {
+ for (; timeout > 0; timeout -= 25) {
+- ret = adv7511_irq_process(adv7511);
++ ret = adv7511_irq_process(adv7511, false);
+ if (ret < 0)
+ break;
+
--- /dev/null
+From 3587c856675c45809010c2cee5b21096f6e8e938 Mon Sep 17 00:00:00 2001
+From: John Stultz <john.stultz@linaro.org>
+Date: Mon, 16 Jan 2017 16:52:52 -0800
+Subject: drm/bridge: adv7511: Re-write the i2c address before EDID probing
+
+From: John Stultz <john.stultz@linaro.org>
+
+commit 3587c856675c45809010c2cee5b21096f6e8e938 upstream.
+
+I've found that by just turning the chip on and off via the
+POWER_DOWN register, I end up getting i2c_transfer errors on
+HiKey.
+
+Investigating further, it turns out that some of the register
+state in hardware is getting lost, as the device registers are
+reset when the chip is powered down.
+
+Thus this patch simply re-writes the i2c address to the
+ADV7511_REG_EDID_I2C_ADDR register to ensure its properly set
+before we try to read the EDID data.
+
+Cc: David Airlie <airlied@linux.ie>
+Cc: Archit Taneja <architt@codeaurora.org>
+Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Cc: Lars-Peter Clausen <lars@metafoo.de>
+Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Cc: dri-devel@lists.freedesktop.org
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Tested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: Archit Taneja <architt@codeaurora.org>
+Link: http://patchwork.freedesktop.org/patch/msgid/1484614372-15342-7-git-send-email-john.stultz@linaro.org
+Signed-off-by: Thong Ho <thong.ho.px@rvc.renesas.com>
+Signed-off-by: Nhan Nguyen <nhan.nguyen.yb@renesas.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/gpu/drm/i2c/adv7511.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/drivers/gpu/drm/i2c/adv7511.c
++++ b/drivers/gpu/drm/i2c/adv7511.c
+@@ -51,6 +51,10 @@ struct adv7511 {
+ struct gpio_desc *gpio_pd;
+ };
+
++static const int edid_i2c_addr = 0x7e;
++static const int packet_i2c_addr = 0x70;
++static const int cec_i2c_addr = 0x78;
++
+ static struct adv7511 *encoder_to_adv7511(struct drm_encoder *encoder)
+ {
+ return to_encoder_slave(encoder)->slave_priv;
+@@ -606,6 +610,9 @@ static int adv7511_get_modes(struct drm_
+ ADV7511_INT1_DDC_ERROR);
+ }
+ adv7511->current_edid_segment = -1;
++ /* Reset the EDID_I2C_ADDR register as it might be cleared */
++ regmap_write(adv7511->regmap, ADV7511_REG_EDID_I2C_ADDR,
++ edid_i2c_addr);
+ }
+
+ edid = drm_do_get_edid(connector, adv7511_get_edid_block, adv7511);
+@@ -881,10 +888,6 @@ static int adv7511_parse_dt(struct devic
+ return 0;
+ }
+
+-static const int edid_i2c_addr = 0x7e;
+-static const int packet_i2c_addr = 0x70;
+-static const int cec_i2c_addr = 0x78;
+-
+ static int adv7511_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+ {
+ struct adv7511_link_config link_config;
--- /dev/null
+From 6d5104c5a6b56385426e15047050584794bb6254 Mon Sep 17 00:00:00 2001
+From: John Stultz <john.stultz@linaro.org>
+Date: Mon, 16 Jan 2017 16:52:48 -0800
+Subject: drm/bridge: adv7511: Switch to using drm_kms_helper_hotplug_event()
+
+From: John Stultz <john.stultz@linaro.org>
+
+commit 6d5104c5a6b56385426e15047050584794bb6254 upstream.
+
+In chasing down a previous issue with EDID probing from calling
+drm_helper_hpd_irq_event() from irq context, Laurent noticed
+that the DRM documentation suggests that
+drm_kms_helper_hotplug_event() should be used instead.
+
+Thus this patch replaces drm_helper_hpd_irq_event() with
+drm_kms_helper_hotplug_event(), which requires we update the
+connector.status entry and only call _hotplug_event() when the
+status changes.
+
+Cc: David Airlie <airlied@linux.ie>
+Cc: Archit Taneja <architt@codeaurora.org>
+Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Cc: Lars-Peter Clausen <lars@metafoo.de>
+Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Cc: dri-devel@lists.freedesktop.org
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Tested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: Archit Taneja <architt@codeaurora.org>
+Link: http://patchwork.freedesktop.org/patch/msgid/1484614372-15342-3-git-send-email-john.stultz@linaro.org
+Signed-off-by: Thong Ho <thong.ho.px@rvc.renesas.com>
+Signed-off-by: Nhan Nguyen <nhan.nguyen.yb@renesas.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i2c/adv7511.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i2c/adv7511.c
++++ b/drivers/gpu/drm/i2c/adv7511.c
+@@ -435,8 +435,21 @@ static bool adv7511_hpd(struct adv7511 *
+ static void adv7511_hpd_work(struct work_struct *work)
+ {
+ struct adv7511 *adv7511 = container_of(work, struct adv7511, hpd_work);
++ enum drm_connector_status status;
++ unsigned int val;
++ int ret;
++ ret = regmap_read(adv7511->regmap, ADV7511_REG_STATUS, &val);
++ if (ret < 0)
++ status = connector_status_disconnected;
++ else if (val & ADV7511_STATUS_HPD)
++ status = connector_status_connected;
++ else
++ status = connector_status_disconnected;
+
+- drm_helper_hpd_irq_event(adv7511->connector.dev);
++ if (adv7511->connector.status != status) {
++ adv7511->connector.status = status;
++ drm_kms_helper_hotplug_event(adv7511->connector.dev);
++ }
+ }
+
+ static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd)
--- /dev/null
+From 518cb7057a59b9441336d2e88a396d52b6ab0cce Mon Sep 17 00:00:00 2001
+From: John Stultz <john.stultz@linaro.org>
+Date: Mon, 16 Jan 2017 16:52:47 -0800
+Subject: drm/bridge: adv7511: Use work_struct to defer hotplug handing to out of irq context
+
+From: John Stultz <john.stultz@linaro.org>
+
+commit 518cb7057a59b9441336d2e88a396d52b6ab0cce upstream.
+
+I was recently seeing issues with EDID probing, where
+the logic to wait for the EDID read bit to be set by the
+IRQ wasn't happening and the code would time out and fail.
+
+Digging deeper, I found this was due to the fact that
+IRQs were disabled as we were running in IRQ context from
+the HPD signal.
+
+Thus this patch changes the logic to handle the HPD signal
+via a work_struct so we can be out of irq context.
+
+With this patch, the EDID probing on hotplug does not time
+out.
+
+Cc: David Airlie <airlied@linux.ie>
+Cc: Archit Taneja <architt@codeaurora.org>
+Cc: Wolfram Sang <wsa+renesas@sang-engineering.com>
+Cc: Lars-Peter Clausen <lars@metafoo.de>
+Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Cc: dri-devel@lists.freedesktop.org
+Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Tested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Signed-off-by: John Stultz <john.stultz@linaro.org>
+Signed-off-by: Archit Taneja <architt@codeaurora.org>
+Link: http://patchwork.freedesktop.org/patch/msgid/1484614372-15342-2-git-send-email-john.stultz@linaro.org
+Signed-off-by: Thong Ho <thong.ho.px@rvc.renesas.com>
+Signed-off-by: Nhan Nguyen <nhan.nguyen.yb@renesas.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i2c/adv7511.c | 14 +++++++++++++-
+ 1 file changed, 13 insertions(+), 1 deletion(-)
+
+--- a/drivers/gpu/drm/i2c/adv7511.c
++++ b/drivers/gpu/drm/i2c/adv7511.c
+@@ -36,7 +36,10 @@ struct adv7511 {
+ bool edid_read;
+
+ wait_queue_head_t wq;
++ struct work_struct hpd_work;
++
+ struct drm_encoder *encoder;
++ struct drm_connector connector;
+
+ bool embedded_sync;
+ enum adv7511_sync_polarity vsync_polarity;
+@@ -429,6 +432,13 @@ static bool adv7511_hpd(struct adv7511 *
+ return false;
+ }
+
++static void adv7511_hpd_work(struct work_struct *work)
++{
++ struct adv7511 *adv7511 = container_of(work, struct adv7511, hpd_work);
++
++ drm_helper_hpd_irq_event(adv7511->connector.dev);
++}
++
+ static int adv7511_irq_process(struct adv7511 *adv7511, bool process_hpd)
+ {
+ unsigned int irq0, irq1;
+@@ -446,7 +456,7 @@ static int adv7511_irq_process(struct ad
+ regmap_write(adv7511->regmap, ADV7511_REG_INT(1), irq1);
+
+ if (process_hpd && irq0 & ADV7511_INT0_HDP && adv7511->encoder)
+- drm_helper_hpd_irq_event(adv7511->encoder->dev);
++ schedule_work(&adv7511->hpd_work);
+
+ if (irq0 & ADV7511_INT0_EDID_READY || irq1 & ADV7511_INT1_DDC_ERROR) {
+ adv7511->edid_read = true;
+@@ -922,6 +932,8 @@ static int adv7511_probe(struct i2c_clie
+ if (!adv7511->i2c_edid)
+ return -ENOMEM;
+
++ INIT_WORK(&adv7511->hpd_work, adv7511_hpd_work);
++
+ if (i2c->irq) {
+ init_waitqueue_head(&adv7511->wq);
+
cs5536-add-support-for-ide-controller-variant.patch
scsi-sg-protect-against-races-between-mmap-and-sg_set_reserved_size.patch
scsi-sg-recheck-mmap_io-request-length-with-lock-held.patch
+drm-adv7511-really-enable-interrupts-for-edid-detection.patch
+drm-bridge-adv7511-fix-mutex-deadlock-when-interrupts-are-disabled.patch
+drm-bridge-adv7511-use-work_struct-to-defer-hotplug-handing-to-out-of-irq-context.patch
+drm-bridge-adv7511-switch-to-using-drm_kms_helper_hotplug_event.patch
+drm-bridge-adv7511-re-write-the-i2c-address-before-edid-probing.patch