Title: [4040] branches/2007R1: backport anomaly rework from trunk
Revision
4040
Author
vapier
Date
2007-12-13 13:20:47 -0600 (Thu, 13 Dec 2007)

Log Message

backport anomaly rework from trunk

Diffstat

 drivers/serial/bfin_5xx.c                         |   76 ++++++++++++++++------
 include/asm-blackfin/mach-bf533/bfin_serial_5xx.h |    3 
 include/asm-blackfin/mach-bf561/bfin_serial_5xx.h |    3 
 3 files changed, 64 insertions(+), 18 deletions(-)

Modified Paths


Diff

Modified: branches/2007R1/drivers/serial/bfin_5xx.c (4039 => 4040)


--- branches/2007R1/drivers/serial/bfin_5xx.c	2007-12-13 03:00:41 UTC (rev 4039)
+++ branches/2007R1/drivers/serial/bfin_5xx.c	2007-12-13 19:20:47 UTC (rev 4040)
@@ -182,6 +182,14 @@
 }
 #endif
 
+#if defined(ANOMALY_05000230) && defined(CONFIG_SERIAL_BFIN_PIO)
+# define UART_GET_ANOMALY_THRESHOLD(uart)    ((uart)->anomaly_threshold)
+# define UART_SET_ANOMALY_THRESHOLD(uart, v) ((uart)->anomaly_threshold = (v))
+#else
+# define UART_GET_ANOMALY_THRESHOLD(uart)    0
+# define UART_SET_ANOMALY_THRESHOLD(uart, v)
+#endif
+
 #ifdef CONFIG_SERIAL_BFIN_PIO
 static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
 {
@@ -190,8 +198,8 @@
 #ifdef CONFIG_KGDB_UART
 	struct pt_regs *regs = get_irq_regs();
 #endif
-#ifdef BF533_FAMILY
-	static int in_break = 0;
+#ifdef ANOMALY_05000230
+	static struct timeval anomaly_start = { .tv_sec = 0 };
 #endif
 
 	status = UART_GET_LSR(uart);
@@ -218,28 +226,58 @@
 		}
 	}
 #endif
- 
-#ifdef BF533_FAMILY
-	/* The BF533 family of processors have a nice misbehavior where
-	 * they continuously generate characters for a "single" break.
+
+#ifdef ANOMALY_05000230
+	/* The BF533 (and BF561) family of processors have a nice anomaly
+	 * where they continuously generate characters for a "single" break.
 	 * We have to basically ignore this flood until the "next" valid
-	 * character comes across.  All other Blackfin families operate
-	 * properly though.
+	 * character comes across.  Due to the nature of the flood, it is
+	 * not possible to reliably catch bytes that are sent too quickly
+	 * after this break.  So application code talking to the Blackfin
+	 * which sends a break signal must allow at least 1.5 character
+	 * times after the end of the break for things to stabilize.  This
+	 * timeout was picked as it must absolutely be larger than 1
+	 * character time +/- some percent.  So 1.5 sounds good.  All other
+	 * Blackfin families operate properly.  Woo.
+	 * Note: While Anomaly 05000230 does not directly address this,
+	 *       the changes that went in for it also fixed this issue.
+	 *       That anomaly was fixed in 0.5+ silicon.  I like bunnies.
 	 */
-	if (in_break) {
-		if (ch != 0) {
-			in_break = 0;
-			ch = UART_GET_CHAR(uart);
-			if (bfin_revid() < 5)
-				return;
-		} else
-			return;
+	if (anomaly_start.tv_sec) {
+		struct timeval curr;
+		suseconds_t usecs;
+
+		if ((~ch & (~ch + 1)) & 0xff)
+			goto known_good_char;
+
+		do_gettimeofday(&curr);
+		if (curr.tv_sec - anomaly_start.tv_sec > 1)
+			goto known_good_char;
+
+		usecs = 0;
+		if (curr.tv_sec != anomaly_start.tv_sec)
+			usecs += USEC_PER_SEC;
+		usecs += curr.tv_usec - anomaly_start.tv_usec;
+
+		if (usecs > UART_GET_ANOMALY_THRESHOLD(uart))
+			goto known_good_char;
+
+		if (ch)
+			anomaly_start.tv_sec = 0;
+		else
+			anomaly_start = curr;
+
+		return;
+
+ known_good_char:
+		anomaly_start.tv_sec = 0;
 	}
 #endif
 
 	if (status & BI) {
-#ifdef BF533_FAMILY
-		in_break = 1;
+#ifdef ANOMALY_05000230
+		if (bfin_revid() < 5)
+			do_gettimeofday(&anomaly_start);
 #endif
 		uart->port.icount.brk++;
 		if (uart_handle_break(&uart->port))
@@ -730,6 +768,8 @@
 	quot = uart_get_divisor(port, baud);
 	spin_lock_irqsave(&uart->port.lock, flags);
 
+	UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15);
+
 	do {
 		lsr = UART_GET_LSR(uart);
 	} while (!(lsr & TEMT));

Modified: branches/2007R1/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h (4039 => 4040)


--- branches/2007R1/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h	2007-12-13 03:00:41 UTC (rev 4039)
+++ branches/2007R1/include/asm-blackfin/mach-bf533/bfin_serial_5xx.h	2007-12-13 19:20:47 UTC (rev 4040)
@@ -56,6 +56,9 @@
 	struct work_struct	tx_dma_workqueue;
 #else
 	struct work_struct 	cts_workqueue;
+# ifdef ANOMALY_05000230
+    unsigned int anomaly_threshold;
+# endif
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
 	int			cts_pin;

Modified: branches/2007R1/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h (4039 => 4040)


--- branches/2007R1/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h	2007-12-13 03:00:41 UTC (rev 4039)
+++ branches/2007R1/include/asm-blackfin/mach-bf561/bfin_serial_5xx.h	2007-12-13 19:20:47 UTC (rev 4040)
@@ -56,6 +56,9 @@
 	struct work_struct	tx_dma_workqueue;
 #else
 	struct work_struct 	cts_workqueue;
+# ifdef ANOMALY_05000230
+    unsigned int anomaly_threshold;
+# endif
 #endif
 #ifdef CONFIG_SERIAL_BFIN_CTSRTS
 	int			cts_pin;
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
http://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to