linux: add CEC upstream fix

Signed-off-by: Stephan Raue <stephan@openelec.tv>
This commit is contained in:
Stephan Raue 2014-04-30 13:47:33 +02:00
parent 2ec8b1bc94
commit cd9c15bc2c

View File

@ -0,0 +1,76 @@
From 76796e32b20dd8f34aadad8fd91672017d143812 Mon Sep 17 00:00:00 2001
From: wolfgar <stephan.rafin@laposte.net>
Date: Tue, 29 Apr 2014 01:35:01 +0200
Subject: [PATCH] Fix a bug that could result in CEC interrupts to be
improperly muted in case the CEC_STAT register was 0, the worker was not
invoked and as a consequence the interrupts were not unmuted Also try to play
better with the interrupt sharing with hmdi_video
---
drivers/mxc/hdmi-cec/mxc_hdmi-cec.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c b/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
index 3a8aff4..85e259c 100644
--- a/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
+++ b/drivers/mxc/hdmi-cec/mxc_hdmi-cec.c
@@ -97,6 +97,7 @@ static irqreturn_t mxc_hdmi_cec_isr(int irq, void *data)
u16 cec_stat = 0;
unsigned long flags;
u8 phy_stat0;
+ irqreturn_t ret = IRQ_HANDLED;
spin_lock_irqsave(&hdmi_cec->irq_lock, flags);
@@ -105,6 +106,13 @@ static irqreturn_t mxc_hdmi_cec_isr(int irq, void *data)
cec_stat = hdmi_readb(HDMI_IH_CEC_STAT0);
hdmi_writeb(cec_stat, HDMI_IH_CEC_STAT0);
phy_stat0 = hdmi_readb(HDMI_PHY_STAT0) & 0x02;
+
+ if ((cec_stat & (HDMI_IH_CEC_STAT0_ERROR_INIT | \
+ HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | \
+ HDMI_IH_CEC_STAT0_DONE)) == 0) {
+ ret = IRQ_NONE;
+ cec_stat = 0;
+ }
if (hdmi_cec->link_status ^ phy_stat0) {
/* HPD value changed */
hdmi_cec->link_status = phy_stat0;
@@ -113,21 +121,14 @@ static irqreturn_t mxc_hdmi_cec_isr(int irq, void *data)
else
cec_stat |= 0x100; /* Disconnected */
}
- if ((cec_stat & (HDMI_IH_CEC_STAT0_ERROR_INIT | \
- HDMI_IH_CEC_STAT0_NACK | HDMI_IH_CEC_STAT0_EOM | \
- HDMI_IH_CEC_STAT0_DONE | 0x180)) == 0) {
- spin_unlock_irqrestore(&hdmi_cec->irq_lock, flags);
- return IRQ_HANDLED;
- }
pr_debug("HDMI CEC interrupt received\n");
- /* FIXME : there is a race with latest_cec_stat */
hdmi_cec->latest_cec_stat = cec_stat ;
schedule_delayed_work(&(hdmi_cec->hdmi_cec_work), msecs_to_jiffies(20));
spin_unlock_irqrestore(&hdmi_cec->irq_lock, flags);
- return IRQ_HANDLED;
+ return ret;
}
void mxc_hdmi_cec_handle(u16 cec_stat)
@@ -479,9 +480,9 @@ static unsigned int hdmi_cec_poll(struct file *file, poll_table *wait)
poll_wait(file, &hdmi_cec_queue, wait);
- /* Always writable */
- mask = (POLLOUT | POLLWRNORM);
mutex_lock(&hdmi_cec_data.lock);
+ if (hdmi_cec_data.tx_answer == CEC_TX_AVAIL)
+ mask = (POLLOUT | POLLWRNORM);
if (!list_empty(&head))
mask |= (POLLIN | POLLRDNORM);
mutex_unlock(&hdmi_cec_data.lock);
--
1.9.1