media: st_rc: Don't stay on an IRQ handler forever
As warned by smatch: drivers/media/rc/st_rc.c:110 st_rc_rx_interrupt() warn: this loop depends on readl() succeeding If something goes wrong at readl(), the logic will stay there inside an IRQ code forever. This is not the nicest thing to do :-) So, add a timeout there, preventing staying inside the IRQ for more than 10ms. Acked-by: Patrice Chotard <patrice.chotard@st.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
parent
ca33f8f61a
commit
ee2d243d6b
|
@ -96,19 +96,24 @@ static void st_rc_send_lirc_timeout(struct rc_dev *rdev)
|
|||
|
||||
static irqreturn_t st_rc_rx_interrupt(int irq, void *data)
|
||||
{
|
||||
unsigned long timeout;
|
||||
unsigned int symbol, mark = 0;
|
||||
struct st_rc_device *dev = data;
|
||||
int last_symbol = 0;
|
||||
u32 status;
|
||||
u32 status, int_status;
|
||||
DEFINE_IR_RAW_EVENT(ev);
|
||||
|
||||
if (dev->irq_wake)
|
||||
pm_wakeup_event(dev->dev, 0);
|
||||
|
||||
status = readl(dev->rx_base + IRB_RX_STATUS);
|
||||
/* FIXME: is 10ms good enough ? */
|
||||
timeout = jiffies + msecs_to_jiffies(10);
|
||||
do {
|
||||
status = readl(dev->rx_base + IRB_RX_STATUS);
|
||||
if (!(status & (IRB_FIFO_NOT_EMPTY | IRB_OVERFLOW)))
|
||||
break;
|
||||
|
||||
while (status & (IRB_FIFO_NOT_EMPTY | IRB_OVERFLOW)) {
|
||||
u32 int_status = readl(dev->rx_base + IRB_RX_INT_STATUS);
|
||||
int_status = readl(dev->rx_base + IRB_RX_INT_STATUS);
|
||||
if (unlikely(int_status & IRB_RX_OVERRUN_INT)) {
|
||||
/* discard the entire collection in case of errors! */
|
||||
ir_raw_event_reset(dev->rdev);
|
||||
|
@ -148,8 +153,7 @@ static irqreturn_t st_rc_rx_interrupt(int irq, void *data)
|
|||
|
||||
}
|
||||
last_symbol = 0;
|
||||
status = readl(dev->rx_base + IRB_RX_STATUS);
|
||||
}
|
||||
} while (time_is_after_jiffies(timeout));
|
||||
|
||||
writel(IRB_RX_INTS, dev->rx_base + IRB_RX_INT_CLEAR);
|
||||
|
||||
|
|
Loading…
Reference in New Issue