]>
Commit | Line | Data |
---|---|---|
c6f9f7f1 GKH |
1 | From d970d7fe65adff5efe75b4a73c4ffc9be57089f7 Mon Sep 17 00:00:00 2001 |
2 | From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | |
3 | Date: Thu, 4 Jul 2013 11:28:51 +0200 | |
4 | Subject: serial/mxs-auart: fix race condition in interrupt handler | |
5 | ||
6 | From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | |
7 | ||
8 | commit d970d7fe65adff5efe75b4a73c4ffc9be57089f7 upstream. | |
9 | ||
10 | The handler needs to ack the pending events before actually handling them. | |
11 | Otherwise a new event might come in after it it considered non-pending or | |
12 | handled and is acked then without being handled. So this event is only | |
13 | noticed when the next interrupt happens. | |
14 | ||
15 | Without this patch an i.MX28 based machine running an rt-patched kernel | |
16 | regularly hangs during boot. | |
17 | ||
18 | Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> | |
19 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
20 | ||
21 | --- | |
22 | drivers/tty/serial/mxs-auart.c | 17 +++++++++-------- | |
23 | 1 file changed, 9 insertions(+), 8 deletions(-) | |
24 | ||
25 | --- a/drivers/tty/serial/mxs-auart.c | |
26 | +++ b/drivers/tty/serial/mxs-auart.c | |
27 | @@ -374,11 +374,18 @@ static void mxs_auart_settermios(struct | |
28 | ||
29 | static irqreturn_t mxs_auart_irq_handle(int irq, void *context) | |
30 | { | |
31 | - u32 istatus, istat; | |
32 | + u32 istat; | |
33 | struct mxs_auart_port *s = context; | |
34 | u32 stat = readl(s->port.membase + AUART_STAT); | |
35 | ||
36 | - istatus = istat = readl(s->port.membase + AUART_INTR); | |
37 | + istat = readl(s->port.membase + AUART_INTR); | |
38 | + | |
39 | + /* ack irq */ | |
40 | + writel(istat & (AUART_INTR_RTIS | |
41 | + | AUART_INTR_TXIS | |
42 | + | AUART_INTR_RXIS | |
43 | + | AUART_INTR_CTSMIS), | |
44 | + s->port.membase + AUART_INTR_CLR); | |
45 | ||
46 | if (istat & AUART_INTR_CTSMIS) { | |
47 | uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS); | |
48 | @@ -397,12 +404,6 @@ static irqreturn_t mxs_auart_irq_handle( | |
49 | istat &= ~AUART_INTR_TXIS; | |
50 | } | |
51 | ||
52 | - writel(istatus & (AUART_INTR_RTIS | |
53 | - | AUART_INTR_TXIS | |
54 | - | AUART_INTR_RXIS | |
55 | - | AUART_INTR_CTSMIS), | |
56 | - s->port.membase + AUART_INTR_CLR); | |
57 | - | |
58 | return IRQ_HANDLED; | |
59 | } | |
60 |