summaryrefslogtreecommitdiff
path: root/packages/linux/linux-ezx-2.6.24/patches/ezx-serial-bug-workaround.patch
blob: efff7e06a59cb15f39e34427cf7053e611c174a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
Work around some errata in the pxa serial code (copied from motorolas 2.4.x tree)

Index: linux-2.6.24/drivers/serial/pxa.c
===================================================================
--- linux-2.6.24.orig/drivers/serial/pxa.c
+++ linux-2.6.24/drivers/serial/pxa.c
@@ -29,6 +29,10 @@
 #define SUPPORT_SYSRQ
 #endif
 
+#define pxa_buggy_port(x) ({ \
+	int cpu_ver; asm("mrc%? p15, 0, %0, c0, c0" : "=r" (cpu_ver)); \
+	((x) == PORT_PXA && (cpu_ver & ~1) == 0x69052100); })
+
 #include <linux/module.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
@@ -196,7 +200,7 @@
 	if (uart_circ_empty(xmit))
 		serial_pxa_stop_tx(&up->port);
 }
-
+static inline irqreturn_t serial_pxa_irq(int, void *);
 static void serial_pxa_start_tx(struct uart_port *port)
 {
 	struct uart_pxa_port *up = (struct uart_pxa_port *)port;
@@ -204,6 +208,8 @@
 	if (!(up->ier & UART_IER_THRI)) {
 		up->ier |= UART_IER_THRI;
 		serial_out(up, UART_IER, up->ier);
+		if (pxa_buggy_port(up->port.type))
+			serial_pxa_irq(up->port.irq, NULL);
 	}
 }
 
@@ -299,6 +305,9 @@
 
 	mcr |= up->mcr;
 
+	if (pxa_buggy_port(up->port.type) && up->port.irq != 0)
+		mcr ^= UART_MCR_OUT2;
+
 	serial_out(up, UART_MCR, mcr);
 }