2009-03-06 06:41:11

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 00/18] Blackfin Serial Driver bug fixing and update


Hi Alan,

We still got 18 Blackfin serial driver patches pending here.
Is that possible to merge them into 2.6.29 release?

Thanks
-Bryan


2009-03-06 06:41:28

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 01/18] Blackfin Serial Driver: Add a debug function to serial driver.

From: Graf Yang <[email protected]>

Signed-off-by: Graf Yang <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
drivers/serial/bfin_5xx.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 44 insertions(+), 0 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 318d69d..52ccc27 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -21,6 +21,7 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial_core.h>
+#include <stdarg.h>

#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
@@ -1177,6 +1178,49 @@ struct console __init *bfin_earlyserial_init(unsigned int port,

#endif /* CONFIG_EARLY_PRINTK */

+#ifdef CONFIG_DEBUG_KERNEL
+void bfin_serial_debug(const char *fmt, ...)
+{
+ struct bfin_serial_port *uart = &bfin_serial_ports[0];
+ unsigned short status, tmp;
+ int flags, i, count;
+ char buf[128];
+ va_list ap;
+
+ if (bfin_serial_console.index < 0)
+ return; /* Too early. */
+
+ va_start(ap, fmt);
+ vsprintf(buf, fmt, ap);
+ va_end(ap);
+ count = strlen(buf);
+
+ spin_lock_irqsave(&uart->port.lock, flags);
+
+ for (i = 0; i < count; i++) {
+ do {
+ status = UART_GET_LSR(uart);
+ } while (!(status & THRE));
+
+#ifndef CONFIG_BF54x
+ tmp = UART_GET_LCR(uart);
+ tmp &= ~DLAB;
+ UART_PUT_LCR(uart, tmp);
+#endif
+ UART_PUT_CHAR(uart, buf[i]);
+ if (buf[i] == '\n') {
+ do {
+ status = UART_GET_LSR(uart);
+ } while (!(status & THRE));
+ UART_PUT_CHAR(uart, '\r');
+ }
+ }
+
+ spin_unlock_irqrestore(&uart->port.lock, flags);
+}
+EXPORT_SYMBOL(bfin_serial_debug);
+#endif
+
static struct uart_driver bfin_serial_reg = {
.owner = THIS_MODULE,
.driver_name = "bfin-uart",
--
1.5.6.3

2009-03-06 06:41:44

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 02/18] Blackfin Serial Driver: use barrier instead of cpu_relax for Blackfin SMP like patch

From: Graf Yang <[email protected]>

We are making a SMP like patch to blackfin, cpu_relax() is replaced by a
data cache flush function which will count it to a per-cpu counter.
If this serial function is called too early, the per-cpu data area have
not been initialized, this call will cause crash.
So we'd like to use barrier() instead of cpu_relax().

Signed-off-by: Graf Yang <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
drivers/serial/bfin_5xx.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 52ccc27..350bfc4 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -1129,7 +1129,8 @@ static __init void early_serial_putc(struct uart_port *port, int ch)
struct bfin_serial_port *uart = (struct bfin_serial_port *)port;

while ((!(UART_GET_LSR(uart) & THRE)) && --timeout)
- cpu_relax();
+ barrier();
+
UART_PUT_CHAR(uart, ch);
}

--
1.5.6.3

2009-03-06 06:42:00

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 03/18] Blackfin Serial Driver: fix a in dma circle rx buffer handling

From: Sonic Zhang <[email protected]>

Reported-by: Qian Zhang <[email protected]>
Signed-off-by: Sonic Zhang <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
drivers/serial/bfin_5xx.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 350bfc4..1e027e3 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -402,9 +402,11 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
else
flg = TTY_NORMAL;

- for (i = uart->rx_dma_buf.tail; i != uart->rx_dma_buf.head; i++) {
+ for (i = uart->rx_dma_buf.tail; ; i++) {
if (i >= UART_XMIT_SIZE)
i = 0;
+ if (i == uart->rx_dma_buf.head)
+ break;
if (!uart_handle_sysrq_char(&uart->port, uart->rx_dma_buf.buf[i]))
uart_insert_char(&uart->port, status, OE,
uart->rx_dma_buf.buf[i], flg);
--
1.5.6.3

2009-03-06 06:42:23

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 04/18] Blackfin Serial Driver: Change hardware flowcontrol from poll to interrupt driven.

From: Sonic Zhang <[email protected]>

Only CTS bit is affected.

Signed-off-by: Sonic Zhang <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
.../mach-bf527/include/mach/bfin_serial_5xx.h | 26 ----
.../mach-bf533/include/mach/bfin_serial_5xx.h | 20 ---
.../mach-bf537/include/mach/bfin_serial_5xx.h | 27 ----
.../mach-bf548/include/mach/bfin_serial_5xx.h | 45 -------
.../mach-bf561/include/mach/bfin_serial_5xx.h | 20 ---
drivers/serial/bfin_5xx.c | 131 ++++++++++++--------
6 files changed, 82 insertions(+), 187 deletions(-)

diff --git a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
index e8c41fd..d2b160c 100644
--- a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
@@ -167,29 +167,3 @@ struct bfin_serial_res bfin_serial_resource[] = {
};

#define DRIVER_NAME "bfin-uart"
-
-static void bfin_serial_hw_init(struct bfin_serial_port *uart)
-{
-
-#ifdef CONFIG_SERIAL_BFIN_UART0
- peripheral_request(P_UART0_TX, DRIVER_NAME);
- peripheral_request(P_UART0_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_UART1
- peripheral_request(P_UART1_TX, DRIVER_NAME);
- peripheral_request(P_UART1_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- if (uart->cts_pin >= 0) {
- gpio_request(uart->cts_pin, DRIVER_NAME);
- gpio_direction_input(uart->cts_pin);
- }
-
- if (uart->rts_pin >= 0) {
- gpio_request(uart->rts_pin, DRIVER_NAME);
- gpio_direction_output(uart->rts_pin, 0);
- }
-#endif
-}
diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
index 5f517f5..70356dd 100644
--- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
@@ -142,23 +142,3 @@ struct bfin_serial_res bfin_serial_resource[] = {
};

#define DRIVER_NAME "bfin-uart"
-
-static void bfin_serial_hw_init(struct bfin_serial_port *uart)
-{
-
-#ifdef CONFIG_SERIAL_BFIN_UART0
- peripheral_request(P_UART0_TX, DRIVER_NAME);
- peripheral_request(P_UART0_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- if (uart->cts_pin >= 0) {
- gpio_request(uart->cts_pin, DRIVER_NAME);
- gpio_direction_input(uart->cts_pin);
- }
- if (uart->rts_pin >= 0) {
- gpio_request(uart->rts_pin, DRIVER_NAME);
- gpio_direction_output(uart->rts_pin, 0);
- }
-#endif
-}
diff --git a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
index 9e34700..d46fc4f 100644
--- a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
@@ -99,7 +99,6 @@ struct bfin_serial_port {
struct work_struct tx_dma_workqueue;
#endif
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- struct timer_list cts_timer;
int cts_pin;
int rts_pin;
#endif
@@ -167,29 +166,3 @@ struct bfin_serial_res bfin_serial_resource[] = {
};

#define DRIVER_NAME "bfin-uart"
-
-static void bfin_serial_hw_init(struct bfin_serial_port *uart)
-{
-
-#ifdef CONFIG_SERIAL_BFIN_UART0
- peripheral_request(P_UART0_TX, DRIVER_NAME);
- peripheral_request(P_UART0_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_UART1
- peripheral_request(P_UART1_TX, DRIVER_NAME);
- peripheral_request(P_UART1_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- if (uart->cts_pin >= 0) {
- gpio_request(uart->cts_pin, DRIVER_NAME);
- gpio_direction_input(uart->cts_pin);
- }
-
- if (uart->rts_pin >= 0) {
- gpio_request(uart->rts_pin, DRIVER_NAME);
- gpio_direction_output(uart->rts_pin, 0);
- }
-#endif
-}
diff --git a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
index c05e79c..388e232 100644
--- a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
@@ -181,48 +181,3 @@ struct bfin_serial_res bfin_serial_resource[] = {
};

#define DRIVER_NAME "bfin-uart"
-
-static void bfin_serial_hw_init(struct bfin_serial_port *uart)
-{
-#ifdef CONFIG_SERIAL_BFIN_UART0
- peripheral_request(P_UART0_TX, DRIVER_NAME);
- peripheral_request(P_UART0_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_UART1
- peripheral_request(P_UART1_TX, DRIVER_NAME);
- peripheral_request(P_UART1_RX, DRIVER_NAME);
-
-#ifdef CONFIG_BFIN_UART1_CTSRTS
- peripheral_request(P_UART1_RTS, DRIVER_NAME);
- peripheral_request(P_UART1_CTS, DRIVER_NAME);
-#endif
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_UART2
- peripheral_request(P_UART2_TX, DRIVER_NAME);
- peripheral_request(P_UART2_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_UART3
- peripheral_request(P_UART3_TX, DRIVER_NAME);
- peripheral_request(P_UART3_RX, DRIVER_NAME);
-
-#ifdef CONFIG_BFIN_UART3_CTSRTS
- peripheral_request(P_UART3_RTS, DRIVER_NAME);
- peripheral_request(P_UART3_CTS, DRIVER_NAME);
-#endif
-#endif
- SSYNC();
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- if (uart->cts_pin >= 0) {
- gpio_request(uart->cts_pin, DRIVER_NAME);
- gpio_direction_input(uart->cts_pin);
- }
-
- if (uart->rts_pin >= 0) {
- gpio_request(uart->rts_pin, DRIVER_NAME);
- gpio_direction_output(uart->rts_pin, 0);
- }
-#endif
-}
diff --git a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
index ca8c5f6..d0469e3 100644
--- a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
@@ -142,23 +142,3 @@ struct bfin_serial_res bfin_serial_resource[] = {
};

#define DRIVER_NAME "bfin-uart"
-
-static void bfin_serial_hw_init(struct bfin_serial_port *uart)
-{
-
-#ifdef CONFIG_SERIAL_BFIN_UART0
- peripheral_request(P_UART0_TX, DRIVER_NAME);
- peripheral_request(P_UART0_RX, DRIVER_NAME);
-#endif
-
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- if (uart->cts_pin >= 0) {
- gpio_request(uart->cts_pin, DRIVER_NAME);
- gpio_direction_input(uart->cts_pin);
- }
- if (uart->rts_pin >= 0) {
- gpio_request(uart->rts_pin, DRIVER_NAME);
- gpio_direction_output(uart->rts_pin, 0);
- }
-#endif
-}
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 1e027e3..8d34ccd 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -64,7 +64,6 @@ static int kgdboc_break_enabled;
#define DMA_RX_YCOUNT (PAGE_SIZE / DMA_RX_XCOUNT)

#define DMA_RX_FLUSH_JIFFIES (HZ / 50)
-#define CTS_CHECK_JIFFIES (HZ / 50)

#ifdef CONFIG_SERIAL_BFIN_DMA
static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart);
@@ -72,8 +71,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart);
static void bfin_serial_tx_chars(struct bfin_serial_port *uart);
#endif

-static void bfin_serial_mctrl_check(struct bfin_serial_port *uart);
-
static void bfin_serial_reset_irda(struct uart_port *port);

/*
@@ -265,12 +262,6 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart)
{
struct circ_buf *xmit = &uart->port.info->xmit;

- /*
- * Check the modem control lines before
- * transmitting anything.
- */
- bfin_serial_mctrl_check(uart);
-
if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
#ifdef CONFIG_BF54x
/* Clear TFI bit */
@@ -329,12 +320,6 @@ static void bfin_serial_dma_tx_chars(struct bfin_serial_port *uart)

uart->tx_done = 0;

- /*
- * Check the modem control lines before
- * transmitting anything.
- */
- bfin_serial_mctrl_check(uart);
-
if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
uart->tx_count = 0;
uart->tx_done = 1;
@@ -524,29 +509,21 @@ static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
#endif
}

+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
/*
- * Handle any change of modem status signal since we were last called.
+ * Handle any change of modem status signal.
*/
-static void bfin_serial_mctrl_check(struct bfin_serial_port *uart)
+static irqreturn_t bfin_serial_mctrl_cts_int(int irq, void *dev_id)
{
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ struct bfin_serial_port *uart = dev_id;
unsigned int status;
- struct uart_info *info = uart->port.info;
- struct tty_struct *tty = info->port.tty;

status = bfin_serial_get_mctrl(&uart->port);
uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
- if (!(status & TIOCM_CTS)) {
- tty->hw_stopped = 1;
- uart->cts_timer.data = (unsigned long)(uart);
- uart->cts_timer.function = (void *)bfin_serial_mctrl_check;
- uart->cts_timer.expires = jiffies + CTS_CHECK_JIFFIES;
- add_timer(&(uart->cts_timer));
- } else {
- tty->hw_stopped = 0;
- }
-#endif
+
+ return IRQ_HANDLED;
}
+#endif

/*
* Interrupts are always disabled.
@@ -606,7 +583,7 @@ static int bfin_serial_startup(struct uart_port *port)
uart->rx_dma_timer.expires = jiffies + DMA_RX_FLUSH_JIFFIES;
add_timer(&(uart->rx_dma_timer));
#else
-#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
+# if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
if (kgdboc_port_line == uart->port.line && kgdboc_break_enabled)
kgdboc_break_enabled = 0;
@@ -661,11 +638,28 @@ static int bfin_serial_startup(struct uart_port *port)
}
}
# endif
-#if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
+# if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
}
# endif
#endif
+
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ if (uart->cts_pin >= 0) {
+ if (request_irq(gpio_to_irq(uart->cts_pin),
+ bfin_serial_mctrl_cts_int,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
+ IRQF_DISABLED, "BFIN_UART_CTS", uart)) {
+ uart->cts_pin = -1;
+ pr_info("Unable to attach BlackFin UART CTS interrupt.\
+ So, disable it.\n");
+ }
+ }
+ if (uart->rts_pin >= 0) {
+ gpio_request(uart->rts_pin, DRIVER_NAME);
+ gpio_direction_output(uart->rts_pin, 0);
+ }
+#endif
UART_SET_IER(uart, ERBFI);
return 0;
}
@@ -699,6 +693,13 @@ static void bfin_serial_shutdown(struct uart_port *port)
free_irq(uart->port.irq, uart);
free_irq(uart->port.irq+1, uart);
#endif
+
+# ifdef CONFIG_SERIAL_BFIN_CTSRTS
+ if (uart->cts_pin >= 0)
+ free_irq(gpio_to_irq(uart->cts_pin), uart);
+ if (uart->rts_pin >= 0)
+ gpio_free(uart->rts_pin);
+# endif
}

static void
@@ -864,6 +865,20 @@ static void bfin_serial_set_ldisc(struct uart_port *port)
}
}

+static void bfin_serial_reset_irda(struct uart_port *port)
+{
+ int line = port->line;
+ unsigned short val;
+
+ val = UART_GET_GCTL(&bfin_serial_ports[line]);
+ val &= ~(IREN | RPOLC);
+ UART_PUT_GCTL(&bfin_serial_ports[line], val);
+ SSYNC();
+ val |= (IREN | RPOLC);
+ UART_PUT_GCTL(&bfin_serial_ports[line], val);
+ SSYNC();
+}
+
#ifdef CONFIG_CONSOLE_POLL
static void bfin_serial_poll_put_char(struct uart_port *port, unsigned char chr)
{
@@ -909,20 +924,6 @@ static int bfin_kgdboc_port_startup(struct uart_port *port)
}
#endif

-static void bfin_serial_reset_irda(struct uart_port *port)
-{
- int line = port->line;
- unsigned short val;
-
- val = UART_GET_GCTL(&bfin_serial_ports[line]);
- val &= ~(IREN | RPOLC);
- UART_PUT_GCTL(&bfin_serial_ports[line], val);
- SSYNC();
- val |= (IREN | RPOLC);
- UART_PUT_GCTL(&bfin_serial_ports[line], val);
- SSYNC();
-}
-
static struct uart_ops bfin_serial_pops = {
.tx_empty = bfin_serial_tx_empty,
.set_mctrl = bfin_serial_set_mctrl,
@@ -952,6 +953,39 @@ static struct uart_ops bfin_serial_pops = {
#endif
};

+static void __init bfin_serial_hw_init(void)
+{
+#ifdef CONFIG_SERIAL_BFIN_UART0
+ peripheral_request(P_UART0_TX, DRIVER_NAME);
+ peripheral_request(P_UART0_RX, DRIVER_NAME);
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_UART1
+ peripheral_request(P_UART1_TX, DRIVER_NAME);
+ peripheral_request(P_UART1_RX, DRIVER_NAME);
+
+# if defined(CONFIG_BFIN_UART1_CTSRTS) && defined(CONFIG_BF54x)
+ peripheral_request(P_UART1_RTS, DRIVER_NAME);
+ peripheral_request(P_UART1_CTS, DRIVER_NAME);
+# endif
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_UART2
+ peripheral_request(P_UART2_TX, DRIVER_NAME);
+ peripheral_request(P_UART2_RX, DRIVER_NAME);
+#endif
+
+#ifdef CONFIG_SERIAL_BFIN_UART3
+ peripheral_request(P_UART3_TX, DRIVER_NAME);
+ peripheral_request(P_UART3_RX, DRIVER_NAME);
+
+# if defined(CONFIG_BFIN_UART3_CTSRTS) && defined(CONFIG_BF54x)
+ peripheral_request(P_UART3_RTS, DRIVER_NAME);
+ peripheral_request(P_UART3_CTS, DRIVER_NAME);
+# endif
+#endif
+}
+
static void __init bfin_serial_init_ports(void)
{
static int first = 1;
@@ -961,6 +995,8 @@ static void __init bfin_serial_init_ports(void)
return;
first = 0;

+ bfin_serial_hw_init();
+
for (i = 0; i < nr_active_ports; i++) {
bfin_serial_ports[i].port.uartclk = get_sclk();
bfin_serial_ports[i].port.fifosize = BFIN_UART_TX_FIFO_SIZE;
@@ -984,15 +1020,12 @@ static void __init bfin_serial_init_ports(void)
init_timer(&(bfin_serial_ports[i].rx_dma_timer));
#endif
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- init_timer(&(bfin_serial_ports[i].cts_timer));
bfin_serial_ports[i].cts_pin =
bfin_serial_resource[i].uart_cts_pin;
bfin_serial_ports[i].rts_pin =
bfin_serial_resource[i].uart_rts_pin;
#endif
- bfin_serial_hw_init(&bfin_serial_ports[i]);
}
-
}

#if defined(CONFIG_SERIAL_BFIN_CONSOLE) || defined(CONFIG_EARLY_PRINTK)
--
1.5.6.3

2009-03-06 06:42:41

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 06/18] Blackfin Serial Driver: explain why we cannot cpu_relax() in early serial code

From: Mike Frysinger <[email protected]>

Signed-off-by: Mike Frysinger <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
drivers/serial/bfin_5xx.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 5a163f6..de8709d 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -1190,6 +1190,10 @@ static __init void early_serial_putc(struct uart_port *port, int ch)
unsigned timeout = 0xffff;
struct bfin_serial_port *uart = (struct bfin_serial_port *)port;

+ /* We cannot cpu_relax() here as doing so on the BF561 relies
+ * on the per-cpu region being setup, and since this is early
+ * serial code, it may not yet be usable ...
+ */
while ((!(UART_GET_LSR(uart) & THRE)) && --timeout)
barrier();

--
1.5.6.3

2009-03-06 06:42:56

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 09/18] Blackfin Serial Driver: irq funcs take an unsigned long for flags

From: Mike Frysinger <[email protected]>

Signed-off-by: Mike Frysinger <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
drivers/serial/bfin_5xx.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 2eab47e..130e321 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -1251,7 +1251,8 @@ void bfin_serial_debug(const char *fmt, ...)
{
struct bfin_serial_port *uart = &bfin_serial_ports[0];
unsigned short status, tmp;
- int flags, i, count;
+ unsigned long flags;
+ int i, count;
char buf[128];
va_list ap;

--
1.5.6.3

2009-03-06 06:43:18

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 10/18] Blackfin Serial Driver: fix compile error in PIO mode

From: Sonic Zhang <[email protected]>

drivers/serial/bfin_5xx.c: In function bfin_serial_rx_chars:
drivers/serial/bfin_5xx.c:178: error: struct uart_info has no
member
named tty
make[3]: *** [drivers/serial/bfin_5xx.o] Error 1
make[2]: *** [drivers/serial] Error 2
make[1]: *** [drivers] Error 2
make[1]: *** Waiting for unfinished jobs....
make[1]: Leaving directory `/root/projects/uClinux-dist/linux-2.6.x'
make: *** [linux] Error 1

Signed-off-by: Sonic Zhang <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
drivers/serial/bfin_5xx.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 130e321..5193d62 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -172,10 +172,10 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
return;
}

- if (!uart->port.info || !uart->port.info->tty)
+ if (!uart->port.info || !uart->port.info->port.tty)
return;
#endif
- tty = uart->port.info->tty;
+ tty = uart->port.info->port.tty;

if (ANOMALY_05000363) {
/* The BF533 (and BF561) family of processors have a nice anomaly
--
1.5.6.3

2009-03-06 06:43:35

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 08/18] Blackfin Serial Driver: use "unsigned long" for flags with irq functions rather than "int"

From: Mike Frysinger <[email protected]>

Signed-off-by: Mike Frysinger <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
drivers/serial/bfin_5xx.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index de8709d..2eab47e 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -403,7 +403,8 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)

void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
{
- int x_pos, pos, flags;
+ int x_pos, pos;
+ unsigned long flags;

spin_lock_irqsave(&uart->port.lock, flags);

@@ -1151,7 +1152,7 @@ static void
bfin_serial_console_write(struct console *co, const char *s, unsigned int count)
{
struct bfin_serial_port *uart = &bfin_serial_ports[co->index];
- int flags = 0;
+ unsigned long flags;

spin_lock_irqsave(&uart->port.lock, flags);
uart_console_write(&uart->port, s, count, bfin_serial_console_putchar);
--
1.5.6.3

2009-03-06 06:43:52

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 07/18] Blackfin Serial Driver: BF538/9 Linux kernel Support

From: Michael Hennerich <[email protected]>

Enable third UART on BF538/9

Signed-off-by: Michael Hennerich <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
drivers/serial/Kconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 7d7f576..d2082fd 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -770,7 +770,7 @@ config UART1_RTS_PIN

config SERIAL_BFIN_UART2
bool "Enable UART2"
- depends on SERIAL_BFIN && (BF54x)
+ depends on SERIAL_BFIN && (BF54x || BF538 || BF539)
help
Enable UART2

--
1.5.6.3

2009-03-06 06:44:13

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 11/18] Blackfin Serial Driver: update KGDB UART config name

From: Mike Frysinger <[email protected]>

Signed-off-by: Mike Frysinger <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
drivers/serial/Kconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index d2082fd..21936c1 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -700,7 +700,7 @@ choice

config SERIAL_BFIN_DMA
bool "DMA mode"
- depends on !DMA_UNCACHED_NONE && !KGDB_UART
+ depends on !DMA_UNCACHED_NONE && !KGDB_SERIAL_CONSOLE
help
This driver works under DMA mode. If this option is selected, the
blackfin simple dma driver is also enabled.
--
1.5.6.3

2009-03-06 06:44:32

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 13/18] Blackfin Serial Driver: depend on KGDB_SERIAL_CONSOLE being set to N

From: Mike Frysinger <[email protected]>

Depend on KGDB_SERIAL_CONSOLE being set to N rather than !Y,
since it can be built as a module.

Signed-off-by: Mike Frysinger <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
drivers/serial/Kconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 21936c1..87f41ed 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -700,7 +700,7 @@ choice

config SERIAL_BFIN_DMA
bool "DMA mode"
- depends on !DMA_UNCACHED_NONE && !KGDB_SERIAL_CONSOLE
+ depends on !DMA_UNCACHED_NONE && KGDB_SERIAL_CONSOLE=n
help
This driver works under DMA mode. If this option is selected, the
blackfin simple dma driver is also enabled.
--
1.5.6.3

2009-03-06 06:44:48

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 12/18] Blackfin Serial Driver: fix building when debug is enabled but serial console is disabled

From: Mike Frysinger <[email protected]>

Signed-off-by: Mike Frysinger <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
drivers/serial/bfin_5xx.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 5193d62..b89861d 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -1256,8 +1256,10 @@ void bfin_serial_debug(const char *fmt, ...)
char buf[128];
va_list ap;

+#ifdef CONFIG_SERIAL_BFIN_CONSOLE
if (bfin_serial_console.index < 0)
return; /* Too early. */
+#endif

va_start(ap, fmt);
vsprintf(buf, fmt, ap);
--
1.5.6.3

2009-03-06 06:45:11

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 14/18] Blackfin Serial Driver: use the DLAB macro to hide variant differences

From: Mike Frysinger <[email protected]>

Signed-off-by: Mike Frysinger <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
drivers/serial/bfin_5xx.c | 8 ++------
1 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index b89861d..71a9e6b 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -1250,7 +1250,7 @@ struct console __init *bfin_earlyserial_init(unsigned int port,
void bfin_serial_debug(const char *fmt, ...)
{
struct bfin_serial_port *uart = &bfin_serial_ports[0];
- unsigned short status, tmp;
+ unsigned short status;
unsigned long flags;
int i, count;
char buf[128];
@@ -1273,11 +1273,7 @@ void bfin_serial_debug(const char *fmt, ...)
status = UART_GET_LSR(uart);
} while (!(status & THRE));

-#ifndef CONFIG_BF54x
- tmp = UART_GET_LCR(uart);
- tmp &= ~DLAB;
- UART_PUT_LCR(uart, tmp);
-#endif
+ UART_CLEAR_DLAB(uart);
UART_PUT_CHAR(uart, buf[i]);
if (buf[i] == '\n') {
do {
--
1.5.6.3

2009-03-06 06:45:36

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 15/18] Blackfin Serial Driver: merge the upstream adeos/xenomai

From: Philippe Gerum <[email protected]>

add ipipe serial debug function for adeos

Signed-off-by: Philippe Gerum <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
drivers/serial/bfin_5xx.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 71a9e6b..8aa0e37 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -1145,6 +1145,51 @@ static void bfin_serial_console_putchar(struct uart_port *port, int ch)
SSYNC();
}

+#ifdef CONFIG_IPIPE
+
+#include <stdarg.h>
+
+void __ipipe_serial_debug(const char *fmt, ...)
+{
+ struct bfin_serial_port *uart = &bfin_serial_ports[0];
+ unsigned short status, tmp;
+ int flags, i, count;
+ char buf[128];
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsprintf(buf, fmt, ap);
+ va_end(ap);
+ count = strlen(buf);
+
+ local_irq_save_hw(flags);
+
+ for (i = 0; i < count; i++) {
+ do {
+ status = UART_GET_LSR(uart);
+ } while (!(status & THRE));
+
+#ifndef CONFIG_BF54x
+ tmp = UART_GET_LCR(uart);
+ tmp &= ~DLAB;
+ UART_PUT_LCR(uart, tmp);
+#endif
+
+ UART_PUT_CHAR(uart, buf[i]);
+ if (buf[i] == '\n') {
+ do {
+ status = UART_GET_LSR(uart);
+ } while (!(status & THRE));
+ UART_PUT_CHAR(uart, '\r');
+ }
+ }
+
+ local_irq_restore_hw(flags);
+}
+EXPORT_SYMBOL(__ipipe_serial_debug);
+
+#endif /* CONFIG_IPIPE */
+
/*
* Interrupts are disabled on entering
*/
--
1.5.6.3

2009-03-06 06:45:52

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 16/18] Blackfin Serial Driver: fix bug - up arrow key works abnormal for bf561 ezkit board

From: Graf Yang <[email protected]>

Subtrack ANOMALY_05000230 on quot.

Signed-off-by: Graf Yang <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
drivers/serial/bfin_5xx.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 8aa0e37..c037e8e 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -789,7 +789,7 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
}

baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
- quot = uart_get_divisor(port, baud);
+ quot = uart_get_divisor(port, baud) - ANOMALY_05000230;
spin_lock_irqsave(&uart->port.lock, flags);

UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15);
--
1.5.6.3

2009-03-06 06:46:17

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 18/18] Blackfin Serial Driver: update path to gpio header

From: Mike Frysinger <[email protected]>

Signed-off-by: Mike Frysinger <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
drivers/serial/Kconfig | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index beb4617..33c678a 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -731,7 +731,7 @@ config UART0_CTS_PIN
default 23
help
The default pin is GPIO_GP7.
- Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.

config UART0_RTS_PIN
int "UART0 RTS pin"
@@ -739,7 +739,7 @@ config UART0_RTS_PIN
default 22
help
The default pin is GPIO_GP6.
- Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.

config SERIAL_BFIN_UART1
bool "Enable UART1"
@@ -759,14 +759,14 @@ config UART1_CTS_PIN
depends on BFIN_UART1_CTSRTS && !BF548
default -1
help
- Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.

config UART1_RTS_PIN
int "UART1 RTS pin"
depends on BFIN_UART1_CTSRTS && !BF548
default -1
help
- Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.

config SERIAL_BFIN_UART2
bool "Enable UART2"
@@ -786,14 +786,14 @@ config UART2_CTS_PIN
depends on BFIN_UART2_CTSRTS && !BF548
default -1
help
- Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.

config UART2_RTS_PIN
int "UART2 RTS pin"
depends on BFIN_UART2_CTSRTS && !BF548
default -1
help
- Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.

config SERIAL_BFIN_UART3
bool "Enable UART3"
@@ -813,14 +813,14 @@ config UART3_CTS_PIN
depends on BFIN_UART3_CTSRTS && !BF548
default -1
help
- Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.

config UART3_RTS_PIN
int "UART3 RTS pin"
depends on BFIN_UART3_CTSRTS && !BF548
default -1
help
- Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+ Refer to arch/blackfin/mach-*/include/mach/gpio.h to see the GPIO map.

config SERIAL_IMX
bool "IMX serial port support"
--
1.5.6.3

2009-03-06 06:46:34

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 17/18] Blackfin Serial Driver: Fix bug - Enable hardware based CTS and RTS for bf548.

From: Sonic Zhang <[email protected]>

Both software emulated and hardware based CTS and RTS are enabled in
serial driver.

The CTS RTS PIN connection on BF548 UART port is defined as a modem
device not as a host device. In order to test it under Linux, please
nake a cross UART cable to exchange CTS and RTS signal.

Signed-off-by: Sonic Zhang <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
.../mach-bf518/include/mach/bfin_serial_5xx.h | 10 +-
.../mach-bf527/include/mach/bfin_serial_5xx.h | 10 +-
.../mach-bf533/include/mach/bfin_serial_5xx.h | 9 +-
.../mach-bf537/include/mach/bfin_serial_5xx.h | 10 +-
.../mach-bf538/include/mach/bfin_serial_5xx.h | 10 +-
.../mach-bf548/include/mach/bfin_serial_5xx.h | 72 ++++-----
.../mach-bf561/include/mach/bfin_serial_5xx.h | 9 +-
drivers/serial/Kconfig | 26 +++-
drivers/serial/bfin_5xx.c | 169 ++++++++++++++------
9 files changed, 209 insertions(+), 116 deletions(-)

diff --git a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
index e21c1c3..0fb2ce5 100644
--- a/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
@@ -53,9 +53,9 @@
#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)

-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)

@@ -87,6 +87,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ int status_irq;
unsigned int lsr;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
@@ -125,6 +126,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
+ int uart_status_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
unsigned int uart_tx_dma_channel;
unsigned int uart_rx_dma_channel;
@@ -140,6 +142,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC00400,
IRQ_UART0_RX,
+ IRQ_UART0_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART0_TX,
CH_UART0_RX,
@@ -154,6 +157,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC02000,
IRQ_UART1_RX,
+ IRQ_UART1_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART1_TX,
CH_UART1_RX,
diff --git a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
index d2b160c..a625659 100644
--- a/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
@@ -53,9 +53,9 @@
#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)

-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)

@@ -87,6 +87,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ int status_irq;
unsigned int lsr;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
@@ -125,6 +126,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
+ int uart_status_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
unsigned int uart_tx_dma_channel;
unsigned int uart_rx_dma_channel;
@@ -140,6 +142,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC00400,
IRQ_UART0_RX,
+ IRQ_UART0_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART0_TX,
CH_UART0_RX,
@@ -154,6 +157,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC02000,
IRQ_UART1_RX,
+ IRQ_UART1_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART1_TX,
CH_UART1_RX,
diff --git a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
index 70356dd..a3789d7 100644
--- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
@@ -53,9 +53,9 @@
#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)

-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)

@@ -74,6 +74,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ int status_irq;
unsigned int lsr;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
@@ -116,6 +117,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
+ int uart_status_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
unsigned int uart_tx_dma_channel;
unsigned int uart_rx_dma_channel;
@@ -130,6 +132,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC00400,
IRQ_UART_RX,
+ IRQ_UART_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART_TX,
CH_UART_RX,
diff --git a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
index d46fc4f..b86662f 100644
--- a/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
@@ -53,9 +53,9 @@
#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)

-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)

@@ -87,6 +87,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ int status_irq;
unsigned int lsr;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
@@ -124,6 +125,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
+ int uart_status_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
unsigned int uart_tx_dma_channel;
unsigned int uart_rx_dma_channel;
@@ -139,6 +141,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC00400,
IRQ_UART0_RX,
+ IRQ_UART0_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART0_TX,
CH_UART0_RX,
@@ -153,6 +156,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC02000,
IRQ_UART1_RX,
+ IRQ_UART1_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART1_TX,
CH_UART1_RX,
diff --git a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
index 3c2811e..c536551 100644
--- a/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
@@ -53,9 +53,9 @@
#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)

-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)

@@ -87,6 +87,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ int status_irq;
unsigned int lsr;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
@@ -125,6 +126,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
+ int uart_status_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
unsigned int uart_tx_dma_channel;
unsigned int uart_rx_dma_channel;
@@ -140,6 +142,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC00400,
IRQ_UART0_RX,
+ IRQ_UART0_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART0_TX,
CH_UART0_RX,
@@ -154,6 +157,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC02000,
IRQ_UART1_RX,
+ IRQ_UART1_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART1_TX,
CH_UART1_RX,
diff --git a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
index 388e232..2d1b5fa 100644
--- a/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
@@ -46,41 +46,27 @@
#define UART_PUT_CHAR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_THR),v)
#define UART_PUT_DLL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
#define UART_SET_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER_SET),v)
-#define UART_CLEAR_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER_CLEAR),v)
+#define UART_CLEAR_IER(uart,v) bfin_write16(((uart)->port.membase + OFFSET_IER_CLEAR),v)
#define UART_PUT_DLH(uart,v) bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
#define UART_PUT_LSR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LSR),v)
#define UART_PUT_LCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
#define UART_CLEAR_LSR(uart) bfin_write16(((uart)->port.membase + OFFSET_LSR), -1)
#define UART_PUT_GCTL(uart,v) bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)
#define UART_PUT_MCR(uart,v) bfin_write16(((uart)->port.membase + OFFSET_MCR),v)
+#define UART_CLEAR_SCTS(uart) bfin_write16(((uart)->port.membase + OFFSET_MSR),SCTS)

#define UART_SET_DLAB(uart) /* MMRs not muxed on BF54x */
#define UART_CLEAR_DLAB(uart) /* MMRs not muxed on BF54x */

#define UART_GET_CTS(x) (UART_GET_MSR(x) & CTS)
-#define UART_SET_RTS(x) (UART_PUT_MCR(x, UART_GET_MCR(x) | MRTS))
-#define UART_CLEAR_RTS(x) (UART_PUT_MCR(x, UART_GET_MCR(x) & ~MRTS))
+#define UART_DISABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) & ~(ARTS|MRTS))
+#define UART_ENABLE_RTS(x) UART_PUT_MCR(x, UART_GET_MCR(x) | MRTS | ARTS)
#define UART_ENABLE_INTS(x, v) UART_SET_IER(x, v)
#define UART_DISABLE_INTS(x) UART_CLEAR_IER(x, 0xF)

-#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART2_CTSRTS)
-# define CONFIG_SERIAL_BFIN_CTSRTS
-
-# ifndef CONFIG_UART0_CTS_PIN
-# define CONFIG_UART0_CTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART0_RTS_PIN
-# define CONFIG_UART0_RTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART2_CTS_PIN
-# define CONFIG_UART2_CTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART2_RTS_PIN
-# define CONFIG_UART2_RTS_PIN -1
-# endif
+#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) || \
+ defined(CONFIG_BFIN_UART2_CTSRTS) || defined(CONFIG_BFIN_UART3_CTSRTS)
+# define CONFIG_SERIAL_BFIN_HARD_CTSRTS
#endif

#define BFIN_UART_TX_FIFO_SIZE 2
@@ -91,6 +77,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ int status_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
int tx_count;
@@ -101,23 +88,24 @@ struct bfin_serial_port {
unsigned int rx_dma_channel;
struct work_struct tx_dma_workqueue;
#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- struct timer_list cts_timer;
- int cts_pin;
- int rts_pin;
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ int scts;
+ int cts_pin;
+ int rts_pin;
#endif
};

struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
+ int uart_status_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
unsigned int uart_tx_dma_channel;
unsigned int uart_rx_dma_channel;
#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- int uart_cts_pin;
- int uart_rts_pin;
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ int uart_cts_pin;
+ int uart_rts_pin;
#endif
};

@@ -126,13 +114,14 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC00400,
IRQ_UART0_RX,
+ IRQ_UART0_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART0_TX,
CH_UART0_RX,
#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- CONFIG_UART0_CTS_PIN,
- CONFIG_UART0_RTS_PIN,
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ 0,
+ 0,
#endif
},
#endif
@@ -140,13 +129,14 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC02000,
IRQ_UART1_RX,
+ IRQ_UART1_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART1_TX,
CH_UART1_RX,
#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- 0,
- 0,
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ GPIO_PE10,
+ GPIO_PE9,
#endif
},
#endif
@@ -154,13 +144,14 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC02100,
IRQ_UART2_RX,
+ IRQ_UART2_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART2_TX,
CH_UART2_RX,
#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- CONFIG_UART2_CTS_PIN,
- CONFIG_UART2_RTS_PIN,
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ 0,
+ 0,
#endif
},
#endif
@@ -168,13 +159,14 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC03100,
IRQ_UART3_RX,
+ IRQ_UART3_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART3_TX,
CH_UART3_RX,
#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- 0,
- 0,
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ GPIO_PB3,
+ GPIO_PB2,
#endif
},
#endif
diff --git a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
index d0469e3..a1b5087 100644
--- a/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
+++ b/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
@@ -53,9 +53,9 @@
#define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
#define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)

-#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
-#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
-#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
+#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
+#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
+#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
#define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
#define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)

@@ -74,6 +74,7 @@
struct bfin_serial_port {
struct uart_port port;
unsigned int old_status;
+ int status_irq;
unsigned int lsr;
#ifdef CONFIG_SERIAL_BFIN_DMA
int tx_done;
@@ -116,6 +117,7 @@ static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
struct bfin_serial_res {
unsigned long uart_base_addr;
int uart_irq;
+ int uart_status_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
unsigned int uart_tx_dma_channel;
unsigned int uart_rx_dma_channel;
@@ -130,6 +132,7 @@ struct bfin_serial_res bfin_serial_resource[] = {
{
0xFFC00400,
IRQ_UART_RX,
+ IRQ_UART_ERROR,
#ifdef CONFIG_SERIAL_BFIN_DMA
CH_UART_TX,
CH_UART_RX,
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 87f41ed..beb4617 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -727,7 +727,7 @@ config BFIN_UART0_CTSRTS

config UART0_CTS_PIN
int "UART0 CTS pin"
- depends on BFIN_UART0_CTSRTS
+ depends on BFIN_UART0_CTSRTS && !BF548
default 23
help
The default pin is GPIO_GP7.
@@ -735,7 +735,7 @@ config UART0_CTS_PIN

config UART0_RTS_PIN
int "UART0 RTS pin"
- depends on BFIN_UART0_CTSRTS
+ depends on BFIN_UART0_CTSRTS && !BF548
default 22
help
The default pin is GPIO_GP6.
@@ -756,14 +756,14 @@ config BFIN_UART1_CTSRTS

config UART1_CTS_PIN
int "UART1 CTS pin"
- depends on BFIN_UART1_CTSRTS && !BF54x
+ depends on BFIN_UART1_CTSRTS && !BF548
default -1
help
Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.

config UART1_RTS_PIN
int "UART1 RTS pin"
- depends on BFIN_UART1_CTSRTS && !BF54x
+ depends on BFIN_UART1_CTSRTS && !BF548
default -1
help
Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
@@ -783,14 +783,14 @@ config BFIN_UART2_CTSRTS

config UART2_CTS_PIN
int "UART2 CTS pin"
- depends on BFIN_UART2_CTSRTS
+ depends on BFIN_UART2_CTSRTS && !BF548
default -1
help
Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.

config UART2_RTS_PIN
int "UART2 RTS pin"
- depends on BFIN_UART2_CTSRTS
+ depends on BFIN_UART2_CTSRTS && !BF548
default -1
help
Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
@@ -808,6 +808,20 @@ config BFIN_UART3_CTSRTS
Enable hardware flow control in the driver. Using GPIO emulate the CTS/RTS
signal.

+config UART3_CTS_PIN
+ int "UART3 CTS pin"
+ depends on BFIN_UART3_CTSRTS && !BF548
+ default -1
+ help
+ Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+
+config UART3_RTS_PIN
+ int "UART3 RTS pin"
+ depends on BFIN_UART3_CTSRTS && !BF548
+ default -1
+ help
+ Refer to ./include/asm-blackfin/gpio.h to see the GPIO map.
+
config SERIAL_IMX
bool "IMX serial port support"
depends on ARM && (ARCH_IMX || ARCH_MXC)
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index c037e8e..71b010c 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -73,6 +73,63 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart);

static void bfin_serial_reset_irda(struct uart_port *port);

+#if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \
+ defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS)
+static unsigned int bfin_serial_get_mctrl(struct uart_port *port)
+{
+ struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+ if (uart->cts_pin < 0)
+ return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+
+ /* CTS PIN is negative assertive. */
+ if (UART_GET_CTS(uart))
+ return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+ else
+ return TIOCM_DSR | TIOCM_CAR;
+}
+
+static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+ struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
+ if (uart->rts_pin < 0)
+ return;
+
+ /* RTS PIN is negative assertive. */
+ if (mctrl & TIOCM_RTS)
+ UART_ENABLE_RTS(uart);
+ else
+ UART_DISABLE_RTS(uart);
+}
+
+/*
+ * Handle any change of modem status signal.
+ */
+static irqreturn_t bfin_serial_mctrl_cts_int(int irq, void *dev_id)
+{
+ struct bfin_serial_port *uart = dev_id;
+ unsigned int status;
+
+ status = bfin_serial_get_mctrl(&uart->port);
+ uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ uart->scts = 1;
+ UART_CLEAR_SCTS(uart);
+ UART_CLEAR_IER(uart, EDSSI);
+#endif
+
+ return IRQ_HANDLED;
+}
+#else
+static unsigned int bfin_serial_get_mctrl(struct uart_port *port)
+{
+ return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
+}
+
+static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+}
+#endif
+
/*
* interrupts are disabled on entry
*/
@@ -109,6 +166,13 @@ static void bfin_serial_start_tx(struct uart_port *port)
struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
struct tty_struct *tty = uart->port.info->port.tty;

+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ if (uart->scts && (!bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) {
+ uart->scts = 0;
+ uart_handle_cts_change(&uart->port, uart->scts);
+ }
+#endif
+
/*
* To avoid losting RX interrupt, we reset IR function
* before sending data.
@@ -304,6 +368,12 @@ static irqreturn_t bfin_serial_tx_int(int irq, void *dev_id)
{
struct bfin_serial_port *uart = dev_id;

+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ if (uart->scts && (!bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) {
+ uart->scts = 0;
+ uart_handle_cts_change(&uart->port, uart->scts);
+ }
+#endif
spin_lock(&uart->port.lock);
if (UART_GET_LSR(uart) & THRE)
bfin_serial_tx_chars(uart);
@@ -447,6 +517,13 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id)
struct bfin_serial_port *uart = dev_id;
struct circ_buf *xmit = &uart->port.info->xmit;

+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ if (uart->scts && (!bfin_serial_get_mctrl(&uart->port)&TIOCM_CTS)) {
+ uart->scts = 0;
+ uart_handle_cts_change(&uart->port, uart->scts);
+ }
+#endif
+
spin_lock(&uart->port.lock);
if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) {
disable_dma(uart->tx_dma_channel);
@@ -509,53 +586,6 @@ static unsigned int bfin_serial_tx_empty(struct uart_port *port)
return 0;
}

-static unsigned int bfin_serial_get_mctrl(struct uart_port *port)
-{
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
- if (uart->cts_pin < 0)
- return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
-
- if (UART_GET_CTS(uart))
- return TIOCM_DSR | TIOCM_CAR;
- else
-#endif
- return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
-}
-
-static void bfin_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
-{
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
- struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
- if (uart->rts_pin < 0)
- return;
-
- if (mctrl & TIOCM_RTS)
- UART_CLEAR_RTS(uart);
- else
- UART_SET_RTS(uart);
-#endif
-}
-
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-/*
- * Handle any change of modem status signal.
- */
-static irqreturn_t bfin_serial_mctrl_cts_int(int irq, void *dev_id)
-{
- struct bfin_serial_port *uart = dev_id;
- unsigned int status;
-
- status = bfin_serial_get_mctrl(&uart->port);
- uart_handle_cts_change(&uart->port, status & TIOCM_CTS);
-
- return IRQ_HANDLED;
-}
-#endif
-
-/*
- * Interrupts are always disabled.
- */
static void bfin_serial_break_ctl(struct uart_port *port, int break_state)
{
struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
@@ -688,6 +718,28 @@ static int bfin_serial_startup(struct uart_port *port)
gpio_direction_output(uart->rts_pin, 0);
}
#endif
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ if (request_irq(uart->status_irq,
+ bfin_serial_mctrl_cts_int,
+ IRQF_DISABLED, "BFIN_UART_MODEM_STATUS", uart)) {
+ pr_info("Unable to attach BlackFin UART Modem \
+ Status interrupt.\n");
+ }
+
+ if (uart->cts_pin >= 0) {
+ gpio_request(uart->cts_pin, DRIVER_NAME);
+ gpio_direction_output(uart->cts_pin, 1);
+ }
+ if (uart->rts_pin >= 0) {
+ gpio_request(uart->rts_pin, DRIVER_NAME);
+ gpio_direction_output(uart->rts_pin, 0);
+ }
+
+ /* CTS RTS PINs are negative assertive. */
+ UART_PUT_MCR(uart, ACTS);
+ UART_SET_IER(uart, EDSSI);
+#endif
+
UART_SET_IER(uart, ERBFI);
return 0;
}
@@ -722,12 +774,20 @@ static void bfin_serial_shutdown(struct uart_port *port)
free_irq(uart->port.irq+1, uart);
#endif

-# ifdef CONFIG_SERIAL_BFIN_CTSRTS
+#ifdef CONFIG_SERIAL_BFIN_CTSRTS
if (uart->cts_pin >= 0)
free_irq(gpio_to_irq(uart->cts_pin), uart);
if (uart->rts_pin >= 0)
gpio_free(uart->rts_pin);
-# endif
+#endif
+#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
+ if (uart->cts_pin >= 0)
+ gpio_free(uart->cts_pin);
+ if (uart->rts_pin >= 0)
+ gpio_free(uart->rts_pin);
+ if (UART_GET_IER(uart) && EDSSI)
+ free_irq(uart->status_irq, uart);
+#endif
}

static void
@@ -1037,6 +1097,8 @@ static void __init bfin_serial_init_ports(void)
bfin_serial_resource[i].uart_base_addr;
bfin_serial_ports[i].port.irq =
bfin_serial_resource[i].uart_irq;
+ bfin_serial_ports[i].status_irq =
+ bfin_serial_resource[i].uart_status_irq;
bfin_serial_ports[i].port.flags = UPF_BOOT_AUTOCONF;
#ifdef CONFIG_SERIAL_BFIN_DMA
bfin_serial_ports[i].tx_done = 1;
@@ -1047,7 +1109,8 @@ static void __init bfin_serial_init_ports(void)
bfin_serial_resource[i].uart_rx_dma_channel;
init_timer(&(bfin_serial_ports[i].rx_dma_timer));
#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+#if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \
+ defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS)
bfin_serial_ports[i].cts_pin =
bfin_serial_resource[i].uart_cts_pin;
bfin_serial_ports[i].rts_pin =
@@ -1110,7 +1173,8 @@ bfin_serial_console_setup(struct console *co, char *options)
int baud = 57600;
int bits = 8;
int parity = 'n';
-# ifdef CONFIG_SERIAL_BFIN_CTSRTS
+# if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \
+ defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS)
int flow = 'r';
# else
int flow = 'n';
@@ -1399,7 +1463,8 @@ static int bfin_serial_remove(struct platform_device *dev)
continue;
uart_remove_one_port(&bfin_serial_reg, &bfin_serial_ports[i].port);
bfin_serial_ports[i].port.dev = NULL;
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
+#if defined(CONFIG_SERIAL_BFIN_CTSRTS) || \
+ defined(CONFIG_SERIAL_BFIN_HARD_CTSRTS)
gpio_free(bfin_serial_ports[i].cts_pin);
gpio_free(bfin_serial_ports[i].rts_pin);
#endif
--
1.5.6.3

2009-03-06 06:46:50

by Bryan Wu

[permalink] [raw]
Subject: [PATCH 05/18] Blackfin Serial Driver: fix bug - serial port transfer big file from host to target would have more lines

From: Sonic Zhang <[email protected]>

Ignore receiving data if new position is in the same line of
current buffer tail and small.

Signed-off-by: Sonic Zhang <[email protected]>
Signed-off-by: Bryan Wu <[email protected]>
---
drivers/serial/bfin_5xx.c | 31 +++++++++++++++++++++++++++++--
1 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 8d34ccd..5a163f6 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -407,6 +407,15 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)

spin_lock_irqsave(&uart->port.lock, flags);

+ /* 2D DMA RX buffer ring is used. Because curr_y_count and
+ * curr_x_count can't be read as an atomic operation,
+ * curr_y_count should be read before curr_x_count. When
+ * curr_x_count is read, curr_y_count may already indicate
+ * next buffer line. But, the position calculated here is
+ * still indicate the old line. The wrong position data may
+ * be smaller than current buffer tail, which cause garbages
+ * are received if it is not prohibit.
+ */
uart->rx_dma_nrows = get_dma_curr_ycount(uart->rx_dma_channel);
x_pos = get_dma_curr_xcount(uart->rx_dma_channel);
uart->rx_dma_nrows = DMA_RX_YCOUNT - uart->rx_dma_nrows;
@@ -417,7 +426,11 @@ void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
x_pos = 0;

pos = uart->rx_dma_nrows * DMA_RX_XCOUNT + x_pos;
- if (pos != uart->rx_dma_buf.tail) {
+ /* Ignore receiving data if new position is in the same line of
+ * current buffer tail and small.
+ */
+ if (pos > uart->rx_dma_buf.tail ||
+ uart->rx_dma_nrows < (uart->rx_dma_buf.tail/DMA_RX_XCOUNT)) {
uart->rx_dma_buf.head = pos;
bfin_serial_dma_rx_chars(uart);
uart->rx_dma_buf.tail = uart->rx_dma_buf.head;
@@ -455,11 +468,25 @@ static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id)
{
struct bfin_serial_port *uart = dev_id;
unsigned short irqstat;
+ int pos;

spin_lock(&uart->port.lock);
irqstat = get_dma_curr_irqstat(uart->rx_dma_channel);
clear_dma_irqstat(uart->rx_dma_channel);
- bfin_serial_dma_rx_chars(uart);
+
+ uart->rx_dma_nrows = get_dma_curr_ycount(uart->rx_dma_channel);
+ uart->rx_dma_nrows = DMA_RX_YCOUNT - uart->rx_dma_nrows;
+ if (uart->rx_dma_nrows == DMA_RX_YCOUNT)
+ uart->rx_dma_nrows = 0;
+
+ pos = uart->rx_dma_nrows * DMA_RX_XCOUNT;
+ if (pos > uart->rx_dma_buf.tail ||
+ uart->rx_dma_nrows < (uart->rx_dma_buf.tail/DMA_RX_XCOUNT)) {
+ uart->rx_dma_buf.head = pos;
+ bfin_serial_dma_rx_chars(uart);
+ uart->rx_dma_buf.tail = uart->rx_dma_buf.head;
+ }
+
spin_unlock(&uart->port.lock);

return IRQ_HANDLED;
--
1.5.6.3

2009-03-06 22:38:46

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 01/18] Blackfin Serial Driver: Add a debug function to serial driver.

On Fri, 6 Mar 2009 14:42:43 +0800
Bryan Wu <[email protected]> wrote:

> From: Graf Yang <[email protected]>
>
> Signed-off-by: Graf Yang <[email protected]>
> Signed-off-by: Bryan Wu <[email protected]>
> ---
> drivers/serial/bfin_5xx.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 44 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
> index 318d69d..52ccc27 100644
> --- a/drivers/serial/bfin_5xx.c
> +++ b/drivers/serial/bfin_5xx.c
> @@ -21,6 +21,7 @@
> #include <linux/tty.h>
> #include <linux/tty_flip.h>
> #include <linux/serial_core.h>
> +#include <stdarg.h>
>
> #if defined(CONFIG_KGDB_SERIAL_CONSOLE) || \
> defined(CONFIG_KGDB_SERIAL_CONSOLE_MODULE)
> @@ -1177,6 +1178,49 @@ struct console __init *bfin_earlyserial_init(unsigned int port,
>
> #endif /* CONFIG_EARLY_PRINTK */
>
> +#ifdef CONFIG_DEBUG_KERNEL
> +void bfin_serial_debug(const char *fmt, ...)
> +{
> + struct bfin_serial_port *uart = &bfin_serial_ports[0];
> + unsigned short status, tmp;
> + int flags, i, count;
> + char buf[128];
> + va_list ap;
> +
> + if (bfin_serial_console.index < 0)
> + return; /* Too early. */
> +
> + va_start(ap, fmt);
> + vsprintf(buf, fmt, ap);
> + va_end(ap);
> + count = strlen(buf);
> +
> + spin_lock_irqsave(&uart->port.lock, flags);
> +
> + for (i = 0; i < count; i++) {
> + do {
> + status = UART_GET_LSR(uart);
> + } while (!(status & THRE));
> +
> +#ifndef CONFIG_BF54x
> + tmp = UART_GET_LCR(uart);
> + tmp &= ~DLAB;
> + UART_PUT_LCR(uart, tmp);
> +#endif
> + UART_PUT_CHAR(uart, buf[i]);
> + if (buf[i] == '\n') {
> + do {
> + status = UART_GET_LSR(uart);
> + } while (!(status & THRE));
> + UART_PUT_CHAR(uart, '\r');
> + }
> + }
> +
> + spin_unlock_irqrestore(&uart->port.lock, flags);
> +}
> +EXPORT_SYMBOL(bfin_serial_debug);
> +#endif

This function is used in later bugfix patches - otherwise it wouldn't
be a 2.6.29 patch.

I shall update the changelog to reflect this.

2009-03-06 22:39:00

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 02/18] Blackfin Serial Driver: use barrier instead of cpu_relax for Blackfin SMP like patch

On Fri, 6 Mar 2009 14:42:44 +0800
Bryan Wu <[email protected]> wrote:

> From: Graf Yang <[email protected]>
>
> We are making a SMP like patch to blackfin, cpu_relax() is replaced by a
> data cache flush function which will count it to a per-cpu counter.
> If this serial function is called too early, the per-cpu data area have
> not been initialized, this call will cause crash.

That's a bug in blackfin architecture support. The kernel should be
able to call cpu_relax() at any time, surely. It's a very low-level
and simple thing.

> So we'd like to use barrier() instead of cpu_relax().
>

barrier() is purely a compiler concept. We might as well just remove
the cpu_relax() altogether.


> drivers/serial/bfin_5xx.c | 3 ++-
> 1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
> index 52ccc27..350bfc4 100644
> --- a/drivers/serial/bfin_5xx.c
> +++ b/drivers/serial/bfin_5xx.c
> @@ -1129,7 +1129,8 @@ static __init void early_serial_putc(struct uart_port *port, int ch)
> struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
>
> while ((!(UART_GET_LSR(uart) & THRE)) && --timeout)
> - cpu_relax();
> + barrier();
> +
> UART_PUT_CHAR(uart, ch);
> }

I grumpily queued this, but it seems all wrong.

2009-03-06 22:39:25

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 05/18] Blackfin Serial Driver: fix bug - serial port transfer big file from host to target would have more lines

On Fri, 6 Mar 2009 14:42:47 +0800
Bryan Wu <[email protected]> wrote:

> From: Sonic Zhang <[email protected]>
>
> Ignore receiving data if new position is in the same line of
> current buffer tail and small.
>
> Signed-off-by: Sonic Zhang <[email protected]>
> Signed-off-by: Bryan Wu <[email protected]>

Changelog fails to describe the bug which is being fixed, and fails to
describe the impact of that bug and fails to explain _why_ this change
is being made. I presently have no reason to merge this into 2.6.29.

2009-03-06 22:39:41

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 06/18] Blackfin Serial Driver: explain why we cannot cpu_relax() in early serial code

On Fri, 6 Mar 2009 14:42:48 +0800
Bryan Wu <[email protected]> wrote:

> From: Mike Frysinger <[email protected]>
>
> Signed-off-by: Mike Frysinger <[email protected]>
> Signed-off-by: Bryan Wu <[email protected]>
> ---
> drivers/serial/bfin_5xx.c | 4 ++++
> 1 files changed, 4 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
> index 5a163f6..de8709d 100644
> --- a/drivers/serial/bfin_5xx.c
> +++ b/drivers/serial/bfin_5xx.c
> @@ -1190,6 +1190,10 @@ static __init void early_serial_putc(struct uart_port *port, int ch)
> unsigned timeout = 0xffff;
> struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
>
> + /* We cannot cpu_relax() here as doing so on the BF561 relies
> + * on the per-cpu region being setup, and since this is early
> + * serial code, it may not yet be usable ...
> + */
> while ((!(UART_GET_LSR(uart) & THRE)) && --timeout)
> barrier();

Again: this is blackfin core breakage.

2009-03-06 22:39:57

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 14/18] Blackfin Serial Driver: use the DLAB macro to hide variant differences

On Fri, 6 Mar 2009 14:42:56 +0800
Bryan Wu <[email protected]> wrote:

> From: Mike Frysinger <[email protected]>
>
> Signed-off-by: Mike Frysinger <[email protected]>
> Signed-off-by: Bryan Wu <[email protected]>
> ---
> drivers/serial/bfin_5xx.c | 8 ++------
> 1 files changed, 2 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
> index b89861d..71a9e6b 100644
> --- a/drivers/serial/bfin_5xx.c
> +++ b/drivers/serial/bfin_5xx.c
> @@ -1250,7 +1250,7 @@ struct console __init *bfin_earlyserial_init(unsigned int port,
> void bfin_serial_debug(const char *fmt, ...)
> {
> struct bfin_serial_port *uart = &bfin_serial_ports[0];
> - unsigned short status, tmp;
> + unsigned short status;
> unsigned long flags;
> int i, count;
> char buf[128];
> @@ -1273,11 +1273,7 @@ void bfin_serial_debug(const char *fmt, ...)
> status = UART_GET_LSR(uart);
> } while (!(status & THRE));
>
> -#ifndef CONFIG_BF54x
> - tmp = UART_GET_LCR(uart);
> - tmp &= ~DLAB;
> - UART_PUT_LCR(uart, tmp);
> -#endif
> + UART_CLEAR_DLAB(uart);
> UART_PUT_CHAR(uart, buf[i]);
> if (buf[i] == '\n') {
> do {

This appears to be a small cleanup, not a bugfix.

I'm OK with sneaking the odd non-bugfix into late -rc by accident -
it's not teribly important, and getting the main bugs fixed overwhelms
such considerations.

However I have a sneaky suspicion that this patch might actually fix a
bug, only we weren't told about it?

2009-03-06 22:40:25

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 15/18] Blackfin Serial Driver: merge the upstream adeos/xenomai

On Fri, 6 Mar 2009 14:42:57 +0800
Bryan Wu <[email protected]> wrote:

> From: Philippe Gerum <[email protected]>
>
> add ipipe serial debug function for adeos
>
> Signed-off-by: Philippe Gerum <[email protected]>
> Signed-off-by: Bryan Wu <[email protected]>

Changelog is useless.

> 1 files changed, 45 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
> index 71a9e6b..8aa0e37 100644
> --- a/drivers/serial/bfin_5xx.c
> +++ b/drivers/serial/bfin_5xx.c
> @@ -1145,6 +1145,51 @@ static void bfin_serial_console_putchar(struct uart_port *port, int ch)
> SSYNC();
> }
>
> +#ifdef CONFIG_IPIPE
> +
> +#include <stdarg.h>
> +
> +void __ipipe_serial_debug(const char *fmt, ...)
> +{
> + struct bfin_serial_port *uart = &bfin_serial_ports[0];
> + unsigned short status, tmp;
> + int flags, i, count;
> + char buf[128];
> + va_list ap;
> +
> + va_start(ap, fmt);
> + vsprintf(buf, fmt, ap);
> + va_end(ap);
> + count = strlen(buf);
> +
> + local_irq_save_hw(flags);
> +
> + for (i = 0; i < count; i++) {
> + do {
> + status = UART_GET_LSR(uart);
> + } while (!(status & THRE));
> +
> +#ifndef CONFIG_BF54x
> + tmp = UART_GET_LCR(uart);
> + tmp &= ~DLAB;
> + UART_PUT_LCR(uart, tmp);
> +#endif
> +
> + UART_PUT_CHAR(uart, buf[i]);
> + if (buf[i] == '\n') {
> + do {
> + status = UART_GET_LSR(uart);
> + } while (!(status & THRE));
> + UART_PUT_CHAR(uart, '\r');
> + }
> + }
> +
> + local_irq_restore_hw(flags);
> +}
> +EXPORT_SYMBOL(__ipipe_serial_debug);
> +
> +#endif /* CONFIG_IPIPE */

What does this do? What bug does it fix? Why is it needed in 2.6.29?

None of the other patches add references to this symbol.

Why is it exported to modules?

2009-03-06 22:40:44

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 17/18] Blackfin Serial Driver: Fix bug - Enable hardware based CTS and RTS for bf548.

On Fri, 6 Mar 2009 14:42:59 +0800
Bryan Wu <[email protected]> wrote:

> From: Sonic Zhang <[email protected]>
>
> Both software emulated and hardware based CTS and RTS are enabled in
> serial driver.
>
> The CTS RTS PIN connection on BF548 UART port is defined as a modem
> device not as a host device. In order to test it under Linux, please
> nake a cross UART cable to exchange CTS and RTS signal.
>
> Signed-off-by: Sonic Zhang <[email protected]>
> Signed-off-by: Bryan Wu <[email protected]>
> ---
> .../mach-bf518/include/mach/bfin_serial_5xx.h | 10 +-
> .../mach-bf527/include/mach/bfin_serial_5xx.h | 10 +-
> .../mach-bf533/include/mach/bfin_serial_5xx.h | 9 +-
> .../mach-bf537/include/mach/bfin_serial_5xx.h | 10 +-
> .../mach-bf538/include/mach/bfin_serial_5xx.h | 10 +-
> .../mach-bf548/include/mach/bfin_serial_5xx.h | 72 ++++-----
> .../mach-bf561/include/mach/bfin_serial_5xx.h | 9 +-
> drivers/serial/Kconfig | 26 +++-
> drivers/serial/bfin_5xx.c | 169 ++++++++++++++------
> 9 files changed, 209 insertions(+), 116 deletions(-)

This is a huge patch for us to be merging into -rc7.

> --- a/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
> +++ b/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
> @@ -53,9 +53,9 @@
> #define UART_SET_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) | DLAB); SSYNC(); } while (0)
> #define UART_CLEAR_DLAB(uart) do { UART_PUT_LCR(uart, UART_GET_LCR(uart) & ~DLAB); SSYNC(); } while (0)
>
> -#define UART_GET_CTS(x) gpio_get_value(x->cts_pin)
> -#define UART_SET_RTS(x) gpio_set_value(x->rts_pin, 1)
> -#define UART_CLEAR_RTS(x) gpio_set_value(x->rts_pin, 0)
> +#define UART_GET_CTS(x) (!gpio_get_value(x->cts_pin))
> +#define UART_DISABLE_RTS(x) gpio_set_value(x->rts_pin, 1)
> +#define UART_ENABLE_RTS(x) gpio_set_value(x->rts_pin, 0)
> #define UART_ENABLE_INTS(x, v) UART_PUT_IER(x, v)
> #define UART_DISABLE_INTS(x) UART_PUT_IER(x, 0)
>
> @@ -74,6 +74,7 @@
> struct bfin_serial_port {
> struct uart_port port;
> unsigned int old_status;
> + int status_irq;
> unsigned int lsr;

whitepace bustage in here.

2009-03-06 22:41:44

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 04/18] Blackfin Serial Driver: Change hardware flowcontrol from poll to interrupt driven.

On Fri, 6 Mar 2009 14:42:46 +0800
Bryan Wu <[email protected]> wrote:

> From: Sonic Zhang <[email protected]>
>
> Only CTS bit is affected.
>
> Signed-off-by: Sonic Zhang <[email protected]>
> Signed-off-by: Bryan Wu <[email protected]>

Another completely useless changelog.

Your [PATCH 00/18] email described all these patches as
needed-in-2.6.29 bugfixes. As far as I can tell (based on almost zero
information), this patch is not a bugfix.

2009-03-06 22:42:00

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 03/18] Blackfin Serial Driver: fix a in dma circle rx buffer handling

On Fri, 6 Mar 2009 14:42:45 +0800
Bryan Wu <[email protected]> wrote:

> Subject: [PATCH 03/18] Blackfin Serial Driver: fix a in dma circle rx buffer handling

I changed this to "fix a bug"

> Date: Fri, 6 Mar 2009 14:42:45 +0800
> Sender: [email protected]
> X-Mailer: git-send-email 1.5.6.3
>
> From: Sonic Zhang <[email protected]>
>
> Reported-by: Qian Zhang <[email protected]>
> Signed-off-by: Sonic Zhang <[email protected]>
> Signed-off-by: Bryan Wu <[email protected]>

No changelog.

> drivers/serial/bfin_5xx.c | 4 +++-
> 1 files changed, 3 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
> index 350bfc4..1e027e3 100644
> --- a/drivers/serial/bfin_5xx.c
> +++ b/drivers/serial/bfin_5xx.c
> @@ -402,9 +402,11 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
> else
> flg = TTY_NORMAL;
>
> - for (i = uart->rx_dma_buf.tail; i != uart->rx_dma_buf.head; i++) {
> + for (i = uart->rx_dma_buf.tail; ; i++) {
> if (i >= UART_XMIT_SIZE)
> i = 0;
> + if (i == uart->rx_dma_buf.head)
> + break;
> if (!uart_handle_sysrq_char(&uart->port, uart->rx_dma_buf.buf[i]))
> uart_insert_char(&uart->port, status, OE,
> uart->rx_dma_buf.buf[i], flg);

The fix is not sufficiently obvious to justify the omission of a
changelog.

Please always include a changelog unless the patch is quite obvious.

Please send a changelog entry for this patch. This one should contain
a description of the bug and a description of how it was fixed. A
bugfix's changelog should also provide the reviewer with an
understanding of the seriousness of the bug - what impact does it have
upon users? Because without this information we cannot decide into
which kernel version(s) the code should be merged.

It is alse very useful if the maintainer and/or patch submitter provide
information about which kernel versions are affected and whether the
fix should be backported into -stable kerenls and if so, why.


Bryan, I should not need to explain all this stuff to you. Please
don't let this happen again.

2009-03-06 22:42:25

by Mike Frysinger

[permalink] [raw]
Subject: Re: [PATCH 14/18] Blackfin Serial Driver: use the DLAB macro to hide variant differences

On Fri, Mar 6, 2009 at 17:38, Andrew Morton wrote:
> On Fri, ?6 Mar 2009 14:42:56 +0800 Bryan Wu wrote:
>> From: Mike Frysinger <[email protected]>
>>
>> Signed-off-by: Mike Frysinger <[email protected]>
>> Signed-off-by: Bryan Wu <[email protected]>
>> ---
>> ?drivers/serial/bfin_5xx.c | ? ?8 ++------
>> ?1 files changed, 2 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
>> index b89861d..71a9e6b 100644
>> --- a/drivers/serial/bfin_5xx.c
>> +++ b/drivers/serial/bfin_5xx.c
>> @@ -1250,7 +1250,7 @@ struct console __init *bfin_earlyserial_init(unsigned int port,
>> ?void bfin_serial_debug(const char *fmt, ...)
>> ?{
>> ? ? ? struct bfin_serial_port *uart = &bfin_serial_ports[0];
>> - ? ? unsigned short status, tmp;
>> + ? ? unsigned short status;
>> ? ? ? unsigned long flags;
>> ? ? ? int i, count;
>> ? ? ? char buf[128];
>> @@ -1273,11 +1273,7 @@ void bfin_serial_debug(const char *fmt, ...)
>> ? ? ? ? ? ? ? ? ? ? ? status = UART_GET_LSR(uart);
>> ? ? ? ? ? ? ? } while (!(status & THRE));
>>
>> -#ifndef CONFIG_BF54x
>> - ? ? ? ? ? ? tmp = UART_GET_LCR(uart);
>> - ? ? ? ? ? ? tmp &= ~DLAB;
>> - ? ? ? ? ? ? UART_PUT_LCR(uart, tmp);
>> -#endif
>> + ? ? ? ? ? ? UART_CLEAR_DLAB(uart);
>> ? ? ? ? ? ? ? UART_PUT_CHAR(uart, buf[i]);
>> ? ? ? ? ? ? ? if (buf[i] == '\n') {
>> ? ? ? ? ? ? ? ? ? ? ? do {
>
> This appears to be a small cleanup, not a bugfix.
>
> I'm OK with sneaking the odd non-bugfix into late -rc by accident -
> it's not teribly important, and getting the main bugs fixed overwhelms
> such considerations.
>
> However I have a sneaky suspicion that this patch might actually fix a
> bug, only we weren't told about it?

fixes an unused var warning. not really a "bug", but ...
-mike

2009-03-06 22:43:20

by Mike Frysinger

[permalink] [raw]
Subject: Re: [PATCH 15/18] Blackfin Serial Driver: merge the upstream adeos/xenomai

just drop this patch. this was supposed to be merged with some other
code but Yi hasnt had a chance to do it yet.
-mike

2009-03-06 22:49:26

by Mike Frysinger

[permalink] [raw]
Subject: Re: [PATCH 04/18] Blackfin Serial Driver: Change hardware flowcontrol from poll to interrupt driven.

On Fri, Mar 6, 2009 at 17:38, Andrew Morton wrote:
> On Fri, ?6 Mar 2009 14:42:46 +0800 Bryan Wu wrote:
>> From: Sonic Zhang <[email protected]>
>>
>> Only CTS bit is affected.
>>
>> Signed-off-by: Sonic Zhang <[email protected]>
>> Signed-off-by: Bryan Wu <[email protected]>
>
> Another completely useless changelog.

the summary, while brief, describes the change: the flowcontrol is
currently implemented by polling, but this changes it to an interrupt
based system

> Your [PATCH 00/18] email described all these patches as
> needed-in-2.6.29 bugfixes. ?As far as I can tell (based on almost zero
> information), this patch is not a bugfix.

because the current implementation is polling (busy waiting), the
kernel will basically hang when the remote asserts hardware
flowcontrol pins. if this is only asserted for short periods (less
than 1 char time), then it's not really noticed ... but it still
destroys latencies.
-mike

2009-03-06 23:01:24

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 04/18] Blackfin Serial Driver: Change hardware flowcontrol from poll to interrupt driven.

On Fri, 6 Mar 2009 17:49:13 -0500
Mike Frysinger <[email protected]> wrote:

> On Fri, Mar 6, 2009 at 17:38, Andrew Morton wrote:
> > On Fri, __6 Mar 2009 14:42:46 +0800 Bryan Wu wrote:
> >> From: Sonic Zhang <[email protected]>
> >>
> >> Only CTS bit is affected.
> >>
> >> Signed-off-by: Sonic Zhang <[email protected]>
> >> Signed-off-by: Bryan Wu <[email protected]>
> >
> > Another completely useless changelog.
>
> the summary, while brief, describes the change: the flowcontrol is
> currently implemented by polling, but this changes it to an interrupt
> based system

yes, but it doesn't explain why the change was made.

> > Your [PATCH 00/18] email described all these patches as
> > needed-in-2.6.29 bugfixes. __As far as I can tell (based on almost zero
> > information), this patch is not a bugfix.
>
> because the current implementation is polling (busy waiting), the
> kernel will basically hang when the remote asserts hardware
> flowcontrol pins. if this is only asserted for short periods (less
> than 1 char time), then it's not really noticed ... but it still
> destroys latencies.

That.

Please send through replacement changelogs for all the patches which I
complained about. Then I'll pick through it all and see what we can do
about a 2.6.29 merge.

2009-03-10 10:17:34

by gyang

[permalink] [raw]
Subject: Re: [PATCH 02/18] Blackfin Serial Driver: use barrier instead of cpu_relax for Blackfin SMP like patch

On Fri, 2009-03-06 at 14:37 -0800, Andrew Morton wrote:
> On Fri, 6 Mar 2009 14:42:44 +0800
> Bryan Wu <[email protected]> wrote:
>
> > From: Graf Yang <[email protected]>
> >
> > We are making a SMP like patch to blackfin, cpu_relax() is replaced by a
> > data cache flush function which will count it to a per-cpu counter.
> > If this serial function is called too early, the per-cpu data area have
> > not been initialized, this call will cause crash.
>
> That's a bug in blackfin architecture support. The kernel should be
> able to call cpu_relax() at any time, surely. It's a very low-level
> and simple thing.
>
> > So we'd like to use barrier() instead of cpu_relax().
> >
>
> barrier() is purely a compiler concept. We might as well just remove
> the cpu_relax() altogether.

Do you mean remove cpu_relax(), and either not add barrier() here?

>
>
> > drivers/serial/bfin_5xx.c | 3 ++-
> > 1 files changed, 2 insertions(+), 1 deletions(-)
> >
> > diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
> > index 52ccc27..350bfc4 100644
> > --- a/drivers/serial/bfin_5xx.c
> > +++ b/drivers/serial/bfin_5xx.c
> > @@ -1129,7 +1129,8 @@ static __init void early_serial_putc(struct uart_port *port, int ch)
> > struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
> >
> > while ((!(UART_GET_LSR(uart) & THRE)) && --timeout)
> > - cpu_relax();
> > + barrier();
> > +
> > UART_PUT_CHAR(uart, ch);
> > }
>
> I grumpily queued this, but it seems all wrong.

2009-03-10 10:25:27

by Mike Frysinger

[permalink] [raw]
Subject: Re: [PATCH 02/18] Blackfin Serial Driver: use barrier instead of cpu_relax for Blackfin SMP like patch

On Tue, Mar 10, 2009 at 06:07, gyang wrote:
> On Fri, 2009-03-06 at 14:37 -0800, Andrew Morton wrote:
>> On Fri,  6 Mar 2009 14:42:44 +0800
>> Bryan Wu <[email protected]> wrote:
>>
>> > From: Graf Yang <[email protected]>
>> >
>> > We are making a SMP like patch to blackfin, cpu_relax() is replaced by a
>> > data cache flush function which will count it to a per-cpu counter.
>> > If this serial function is called too early, the per-cpu data area have
>> > not been initialized, this call will cause crash.
>>
>> That's a bug in blackfin architecture support.  The kernel should be
>> able to call cpu_relax() at any time, surely.  It's a very low-level
>> and simple thing.
>>
>> > So we'd like to use barrier() instead of cpu_relax().
>> >
>>
>> barrier() is purely a compiler concept.  We might as well just remove
>> the cpu_relax() altogether.
>
> Do you mean remove cpu_relax(), and either not add barrier() here?

afaik, early printk all runs before SMP is setup, so having it be a
100% busy wait is fine
-mike

2009-03-10 16:54:52

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 02/18] Blackfin Serial Driver: use barrier instead of cpu_relax for Blackfin SMP like patch

On Tue, 10 Mar 2009 06:25:08 -0400 Mike Frysinger <[email protected]> wrote:

> On Tue, Mar 10, 2009 at 06:07, gyang wrote:
> > On Fri, 2009-03-06 at 14:37 -0800, Andrew Morton wrote:
> >> On Fri, ?6 Mar 2009 14:42:44 +0800
> >> Bryan Wu <[email protected]> wrote:
> >>
> >> > From: Graf Yang <[email protected]>
> >> >
> >> > We are making a SMP like patch to blackfin, cpu_relax() is replaced by a
> >> > data cache flush function which will count it to a per-cpu counter.
> >> > If this serial function is called too early, the per-cpu data area have
> >> > not been initialized, this call will cause crash.
> >>
> >> That's a bug in blackfin architecture support. ?The kernel should be
> >> able to call cpu_relax() at any time, surely. ?It's a very low-level
> >> and simple thing.
> >>
> >> > So we'd like to use barrier() instead of cpu_relax().
> >> >
> >>
> >> barrier() is purely a compiler concept. ?We might as well just remove
> >> the cpu_relax() altogether.
> >
> > Do you mean remove cpu_relax(), and either not add barrier() here?
>
> afaik, early printk all runs before SMP is setup, so having it be a
> 100% busy wait is fine

No, blackfin is busted, please fix this bug in blackfin core.

What happens if core kernel code decides to run cpu_relax() prior to
initialising per-cpu data?

2009-03-11 09:50:34

by graff yang

[permalink] [raw]
Subject: Re: [PATCH 02/18] Blackfin Serial Driver: use barrier instead of cpu_relax for Blackfin SMP like patch

On Wed, Mar 11, 2009 at 12:48 AM, Andrew Morton
<[email protected]> wrote:
>
> On Tue, 10 Mar 2009 06:25:08 -0400 Mike Frysinger <[email protected]> wrote:
>
> > On Tue, Mar 10, 2009 at 06:07, gyang wrote:
> > > On Fri, 2009-03-06 at 14:37 -0800, Andrew Morton wrote:
> > >> On Fri,  6 Mar 2009 14:42:44 +0800
> > >> Bryan Wu <[email protected]> wrote:
> > >>
> > >> > From: Graf Yang <[email protected]>
> > >> >
> > >> > We are making a SMP like patch to blackfin, cpu_relax() is replaced by a
> > >> > data cache flush function which will count it to a per-cpu counter.
> > >> > If this serial function is called too early, the per-cpu data area have
> > >> > not been initialized, this call will cause crash.
> > >>
> > >> That's a bug in blackfin architecture support.  The kernel should be
> > >> able to call cpu_relax() at any time, surely.  It's a very low-level
> > >> and simple thing.
> > >>
> > >> > So we'd like to use barrier() instead of cpu_relax().
> > >> >
> > >>
> > >> barrier() is purely a compiler concept.  We might as well just remove
> > >> the cpu_relax() altogether.
> > >
> > > Do you mean remove cpu_relax(), and either not add barrier() here?
> >
> > afaik, early printk all runs before SMP is setup, so having it be a
> > 100% busy wait is fine
>
> No, blackfin is busted, please fix this bug in blackfin core.
>
> What happens if core kernel code decides to run cpu_relax() prior to
> initialising per-cpu data?

cpu_relax() will call smp_mb(), and it need to invalidate data-cache
in blackfin smp-like kernel,
the cache flush number is increased and recorded into a per-cpu data.

When cpu_relax() is called from early-printk functions, the per-cpu
data areas have not
been initialized.

> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



--
-Graff

2009-03-11 16:52:00

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 02/18] Blackfin Serial Driver: use barrier instead of cpu_relax for Blackfin SMP like patch

On Wed, 11 Mar 2009 17:50:21 +0800 graff yang <[email protected]> wrote:

> On Wed, Mar 11, 2009 at 12:48 AM, Andrew Morton
> <[email protected]> wrote:
> >
> > On Tue, 10 Mar 2009 06:25:08 -0400 Mike Frysinger <[email protected]> wrote:
> >
> > > On Tue, Mar 10, 2009 at 06:07, gyang wrote:
> > > > On Fri, 2009-03-06 at 14:37 -0800, Andrew Morton wrote:
> > > >> On Fri, __6 Mar 2009 14:42:44 +0800
> > > >> Bryan Wu <[email protected]> wrote:
> > > >>
> > > >> > From: Graf Yang <[email protected]>
> > > >> >
> > > >> > We are making a SMP like patch to blackfin, cpu_relax() is replaced by a
> > > >> > data cache flush function which will count it to a per-cpu counter.
> > > >> > If this serial function is called too early, the per-cpu data area have
> > > >> > not been initialized, this call will cause crash.
> > > >>
> > > >> That's a bug in blackfin architecture support. __The kernel should be
> > > >> able to call cpu_relax() at any time, surely. __It's a very low-level
> > > >> and simple thing.
> > > >>
> > > >> > So we'd like to use barrier() instead of cpu_relax().
> > > >> >
> > > >>
> > > >> barrier() is purely a compiler concept. __We might as well just remove
> > > >> the cpu_relax() altogether.
> > > >
> > > > Do you mean remove cpu_relax(), and either not add barrier() here?
> > >
> > > afaik, early printk all runs before SMP is setup, so having it be a
> > > 100% busy wait is fine
> >
> > No, blackfin is busted, please fix this bug in blackfin core.
> >
> > What happens if core kernel code decides to run cpu_relax() prior to
> > initialising per-cpu data?
>
> cpu_relax() will call smp_mb(), and it need to invalidate data-cache
> in blackfin smp-like kernel,
> the cache flush number is increased and recorded into a per-cpu data.
>
> When cpu_relax() is called from early-printk functions, the per-cpu
> data areas have not
> been initialized.

Right. And we've demonstrated here that this was a bad idea.

So I suggest that the blackfin maintainers delete that code.

If it's really valuable (which I doubt) then it could be reimplemented
via a statically-allocated array of longs and local_irq_save()
protection. Or a statically allocated array of atomic_long_t's.