aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2015-06-06 16:41:10 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2015-09-15 11:19:49 -0400
commitec5d3e83d332ac5dfde8e0a1f57393fc91d55030 (patch)
tree16c4f6055e238df4450e6e514b2a05a3a0070492
parente66e03abf80f701da60ae085cbb913e67ce6741d (diff)
drm/i2c: tda998x: handle all outstanding interrupts
As reading the interrupt registers clears the outstanding interrupts, we must process all received interrupts to avoid dropping any. Rearrange the code to achieve this, and properly check for a HPD interrupt from the CEC_RXSHPDINT register. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--drivers/gpu/drm/i2c/tda998x_drv.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/gpu/drm/i2c/tda998x_drv.c b/drivers/gpu/drm/i2c/tda998x_drv.c
index 6d6aaadc0d2f..1285fb354813 100644
--- a/drivers/gpu/drm/i2c/tda998x_drv.c
+++ b/drivers/gpu/drm/i2c/tda998x_drv.c
@@ -330,6 +330,8 @@ struct tda998x_priv {
330# define CEC_FRO_IM_CLK_CTRL_FRO_DIV (1 << 0) 330# define CEC_FRO_IM_CLK_CTRL_FRO_DIV (1 << 0)
331#define REG_CEC_RXSHPDINTENA 0xfc /* read/write */ 331#define REG_CEC_RXSHPDINTENA 0xfc /* read/write */
332#define REG_CEC_RXSHPDINT 0xfd /* read */ 332#define REG_CEC_RXSHPDINT 0xfd /* read */
333# define CEC_RXSHPDINT_RXSENS BIT(0)
334# define CEC_RXSHPDINT_HPD BIT(1)
333#define REG_CEC_RXSHPDLEV 0xfe /* read */ 335#define REG_CEC_RXSHPDLEV 0xfe /* read */
334# define CEC_RXSHPDLEV_RXSENS (1 << 0) 336# define CEC_RXSHPDLEV_RXSENS (1 << 0)
335# define CEC_RXSHPDLEV_HPD (1 << 1) 337# define CEC_RXSHPDLEV_HPD (1 << 1)
@@ -619,11 +621,8 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
619 DRM_DEBUG_DRIVER( 621 DRM_DEBUG_DRIVER(
620 "tda irq sta %02x cec %02x lvl %02x f0 %02x f1 %02x f2 %02x\n", 622 "tda irq sta %02x cec %02x lvl %02x f0 %02x f1 %02x f2 %02x\n",
621 sta, cec, lvl, flag0, flag1, flag2); 623 sta, cec, lvl, flag0, flag1, flag2);
622 if ((flag2 & INT_FLAGS_2_EDID_BLK_RD) && priv->wq_edid_wait) { 624
623 priv->wq_edid_wait = 0; 625 if (cec & CEC_RXSHPDINT_HPD) {
624 wake_up(&priv->wq_edid);
625 handled = true;
626 } else if (cec != 0) { /* HPD change */
627 if (lvl & CEC_RXSHPDLEV_HPD) 626 if (lvl & CEC_RXSHPDLEV_HPD)
628 tda998x_edid_delay_start(priv); 627 tda998x_edid_delay_start(priv);
629 else 628 else
@@ -631,6 +630,13 @@ static irqreturn_t tda998x_irq_thread(int irq, void *data)
631 630
632 handled = true; 631 handled = true;
633 } 632 }
633
634 if ((flag2 & INT_FLAGS_2_EDID_BLK_RD) && priv->wq_edid_wait) {
635 priv->wq_edid_wait = 0;
636 wake_up(&priv->wq_edid);
637 handled = true;
638 }
639
634 return IRQ_RETVAL(handled); 640 return IRQ_RETVAL(handled);
635} 641}
636 642