2012-05-16 06:33:56

by Sonic Zhang

[permalink] [raw]
Subject: [PATCH 1/4] serial:bfin_uart: Adapt bf5xx serial driver to bf60x serial4 controller.

From: Sonic Zhang <[email protected]>

The serial4 controller on bf60x is an enhanced version of serial controller
on bf5xx. MMR size is 32 bits other than 16 bits. MMR GCTL, MCR and LCR are
combined into one control MMR. MSR and LSR are combined into one status MMR.

This patch adapts current bf5xx serial driver to serial4 controller on bf60x.

Signed-off-by: Sonic Zhang <[email protected]>
Signed-off-by: Bob Liu <[email protected]>
---
drivers/tty/serial/bfin_uart.c | 32 +++++++++++++-------------------
1 files changed, 13 insertions(+), 19 deletions(-)

diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c
index 5832fde..9acab11 100644
--- a/drivers/tty/serial/bfin_uart.c
+++ b/drivers/tty/serial/bfin_uart.c
@@ -1,7 +1,7 @@
/*
* Blackfin On-Chip Serial Driver
*
- * Copyright 2006-2010 Analog Devices Inc.
+ * Copyright 2006-2011 Analog Devices Inc.
*
* Enter bugs at http://blackfin.uclinux.org/
*
@@ -35,10 +35,6 @@
#include <asm/portmux.h>
#include <asm/cacheflush.h>
#include <asm/dma.h>
-
-#define port_membase(uart) (((struct bfin_serial_port *)(uart))->port.membase)
-#define get_lsr_cache(uart) (((struct bfin_serial_port *)(uart))->lsr)
-#define put_lsr_cache(uart, v) (((struct bfin_serial_port *)(uart))->lsr = (v))
#include <asm/bfin_serial.h>

#ifdef CONFIG_SERIAL_BFIN_MODULE
@@ -166,7 +162,7 @@ static void bfin_serial_stop_tx(struct uart_port *port)
uart->tx_count = 0;
uart->tx_done = 1;
#else
-#ifdef CONFIG_BF54x
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x)
/* Clear TFI bit */
UART_PUT_LSR(uart, TFI);
#endif
@@ -337,7 +333,7 @@ static void bfin_serial_tx_chars(struct bfin_serial_port *uart)
struct circ_buf *xmit = &uart->port.state->xmit;

if (uart_circ_empty(xmit) || uart_tx_stopped(&uart->port)) {
-#ifdef CONFIG_BF54x
+#if defined(CONFIG_BF54x) || defined(CONFIG_BF60x)
/* Clear TFI bit */
UART_PUT_LSR(uart, TFI);
#endif
@@ -877,11 +873,10 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
ier = UART_GET_IER(uart);
UART_DISABLE_INTS(uart);

- /* Set DLAB in LCR to Access DLL and DLH */
+ /* Set DLAB in LCR to Access CLK */
UART_SET_DLAB(uart);

- UART_PUT_DLL(uart, quot & 0xFF);
- UART_PUT_DLH(uart, (quot >> 8) & 0xFF);
+ UART_PUT_CLK(uart, quot);
SSYNC();

/* Clear DLAB in LCR to Access THR RBR IER */
@@ -959,12 +954,12 @@ static void bfin_serial_set_ldisc(struct uart_port *port, int ld)
switch (ld) {
case N_IRDA:
val = UART_GET_GCTL(uart);
- val |= (IREN | RPOLC);
+ val |= (UMOD_IRDA | RPOLC);
UART_PUT_GCTL(uart, val);
break;
default:
val = UART_GET_GCTL(uart);
- val &= ~(IREN | RPOLC);
+ val &= ~(UMOD_MASK | RPOLC);
UART_PUT_GCTL(uart, val);
}
}
@@ -975,10 +970,10 @@ static void bfin_serial_reset_irda(struct uart_port *port)
unsigned short val;

val = UART_GET_GCTL(uart);
- val &= ~(IREN | RPOLC);
+ val &= ~(UMOD_MASK | RPOLC);
UART_PUT_GCTL(uart, val);
SSYNC();
- val |= (IREN | RPOLC);
+ val |= (UMOD_IRDA | RPOLC);
UART_PUT_GCTL(uart, val);
SSYNC();
}
@@ -1075,7 +1070,7 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,
status = UART_GET_IER(uart) & (ERBFI | ETBEI);
if (status == (ERBFI | ETBEI)) {
/* ok, the port was enabled */
- u16 lcr, dlh, dll;
+ u16 lcr, clk;

lcr = UART_GET_LCR(uart);

@@ -1100,16 +1095,15 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,
*bits = 8;
break;
}
- /* Set DLAB in LCR to Access DLL and DLH */
+ /* Set DLAB in LCR to Access CLK */
UART_SET_DLAB(uart);

- dll = UART_GET_DLL(uart);
- dlh = UART_GET_DLH(uart);
+ clk = UART_GET_CLK(uart);

/* Clear DLAB in LCR to Access THR RBR IER */
UART_CLEAR_DLAB(uart);

- *baud = get_sclk() / (16*(dll | dlh << 8));
+ *baud = get_sclk() / (16*clk);
}
pr_debug("%s:baud = %d, parity = %c, bits= %d\n", __func__, *baud, *parity, *bits);
}
--
1.7.0.4


2012-05-16 06:33:27

by Sonic Zhang

[permalink] [raw]
Subject: [PATCH 2/4] serial: bfin_uart: narrow the reboot condition in DMA tx interrupt

From: Sonic Zhang <[email protected]>

Check if xmit buffer pointers are set to zero.

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

diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c
index 9acab11..56b95b0 100644
--- a/drivers/tty/serial/bfin_uart.c
+++ b/drivers/tty/serial/bfin_uart.c
@@ -532,7 +532,7 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id)
*/
UART_CLEAR_IER(uart, ETBEI);
uart->port.icount.tx += uart->tx_count;
- if (!uart_circ_empty(xmit)) {
+ if (!(xmit->tail == 0 && xmit->head == 0)) {
xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1);

if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
--
1.7.0.4

2012-05-16 06:33:31

by Sonic Zhang

[permalink] [raw]
Subject: [PATCH 3/4] serial: bfin_uart: RTS and CTS MMRs can be either 16-bit width or 32-bit width.

From: Sonic Zhang <[email protected]>

Change hardware flow control code to adapt to both bf5xx and bf60x.
Disabled serial device before set termios for bf60x.

Signed-off-by: Sonic Zhang <[email protected]>
Signed-off-by: Bob Liu <[email protected]>
---
drivers/tty/serial/bfin_uart.c | 22 ++++++++++------------
1 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c
index 56b95b0..7924ba6 100644
--- a/drivers/tty/serial/bfin_uart.c
+++ b/drivers/tty/serial/bfin_uart.c
@@ -549,7 +549,7 @@ static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id)
static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id)
{
struct bfin_serial_port *uart = dev_id;
- unsigned short irqstat;
+ unsigned int irqstat;
int x_pos, pos;

spin_lock(&uart->rx_lock);
@@ -582,7 +582,7 @@ static irqreturn_t bfin_serial_dma_rx_int(int irq, void *dev_id)
static unsigned int bfin_serial_tx_empty(struct uart_port *port)
{
struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
- unsigned short lsr;
+ unsigned int lsr;

lsr = UART_GET_LSR(uart);
if (lsr & TEMT)
@@ -741,7 +741,7 @@ static int bfin_serial_startup(struct uart_port *port)
}

/* CTS RTS PINs are negative assertive. */
- UART_PUT_MCR(uart, ACTS);
+ UART_PUT_MCR(uart, UART_GET_MCR(uart) | ACTS);
UART_SET_IER(uart, EDSSI);
}
#endif
@@ -799,7 +799,7 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
unsigned long flags;
unsigned int baud, quot;
- unsigned short val, ier, lcr = 0;
+ unsigned int ier, lcr = 0;

switch (termios->c_cflag & CSIZE) {
case CS8:
@@ -871,6 +871,7 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,

/* Disable UART */
ier = UART_GET_IER(uart);
+ UART_PUT_GCTL(uart, UART_GET_GCTL(uart) & ~UCEN);
UART_DISABLE_INTS(uart);

/* Set DLAB in LCR to Access CLK */
@@ -882,14 +883,11 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
/* Clear DLAB in LCR to Access THR RBR IER */
UART_CLEAR_DLAB(uart);

- UART_PUT_LCR(uart, lcr);
+ UART_PUT_LCR(uart, (UART_GET_LCR(uart) & ~LCR_MASK) | lcr);

/* Enable UART */
UART_ENABLE_INTS(uart, ier);
-
- val = UART_GET_GCTL(uart);
- val |= UCEN;
- UART_PUT_GCTL(uart, val);
+ UART_PUT_GCTL(uart, UART_GET_GCTL(uart) | UCEN);

/* Port speed changed, update the per-port timeout. */
uart_update_timeout(port, termios->c_cflag, baud);
@@ -949,7 +947,7 @@ bfin_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
static void bfin_serial_set_ldisc(struct uart_port *port, int ld)
{
struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
- unsigned short val;
+ unsigned int val;

switch (ld) {
case N_IRDA:
@@ -967,7 +965,7 @@ static void bfin_serial_set_ldisc(struct uart_port *port, int ld)
static void bfin_serial_reset_irda(struct uart_port *port)
{
struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
- unsigned short val;
+ unsigned int val;

val = UART_GET_GCTL(uart);
val &= ~(UMOD_MASK | RPOLC);
@@ -1065,7 +1063,7 @@ static void __init
bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,
int *parity, int *bits)
{
- unsigned short status;
+ unsigned int status;

status = UART_GET_IER(uart) & (ERBFI | ETBEI);
if (status == (ERBFI | ETBEI)) {
--
1.7.0.4

2012-05-16 06:34:16

by Sonic Zhang

[permalink] [raw]
Subject: [PATCH 4/4] serial: bfin_uart: Make MMR access compatible with 32 bits bf609 style controller.

From: Sonic Zhang <[email protected]>

Simplify serial data width calculation and adapt to bf609 LCR bit mask.

Signed-off-by: Sonic Zhang <[email protected]>
---
drivers/tty/serial/bfin_uart.c | 20 ++++----------------
1 files changed, 4 insertions(+), 16 deletions(-)

diff --git a/drivers/tty/serial/bfin_uart.c b/drivers/tty/serial/bfin_uart.c
index 7924ba6..bd97db2 100644
--- a/drivers/tty/serial/bfin_uart.c
+++ b/drivers/tty/serial/bfin_uart.c
@@ -594,7 +594,7 @@ static unsigned int bfin_serial_tx_empty(struct uart_port *port)
static void bfin_serial_break_ctl(struct uart_port *port, int break_state)
{
struct bfin_serial_port *uart = (struct bfin_serial_port *)port;
- u16 lcr = UART_GET_LCR(uart);
+ u32 lcr = UART_GET_LCR(uart);
if (break_state)
lcr |= SB;
else
@@ -1068,7 +1068,7 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,
status = UART_GET_IER(uart) & (ERBFI | ETBEI);
if (status == (ERBFI | ETBEI)) {
/* ok, the port was enabled */
- u16 lcr, clk;
+ u32 lcr, clk;

lcr = UART_GET_LCR(uart);

@@ -1079,20 +1079,8 @@ bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud,
else
*parity = 'o';
}
- switch (lcr & 0x03) {
- case 0:
- *bits = 5;
- break;
- case 1:
- *bits = 6;
- break;
- case 2:
- *bits = 7;
- break;
- case 3:
- *bits = 8;
- break;
- }
+ *bits = ((lcr & WLS_MASK) >> WLS_OFFSET) + 5;
+
/* Set DLAB in LCR to Access CLK */
UART_SET_DLAB(uart);

--
1.7.0.4