* [PATCH 1/3] Blackfin SPORTS UART Driver: converting BFIN->BLACKFIN
2008-05-12 4:10 [PATCH 0/3] Blackfin Sports UART Driver fixing Bryan Wu
@ 2008-05-12 4:10 ` Bryan Wu
2008-05-12 4:10 ` [PATCH 2/3] Blackfin Sports UART Driver: fix bug - the bug caused by sport overrun, use timer to flip the tty buffer in order to return from rx ISR quickly Bryan Wu
2008-05-12 4:10 ` [PATCH 3/3] Blackfin SPORT UART Driver: rewrite assembly with better constraints (and proper clobber lists) so gcc can do a better job Bryan Wu
2 siblings, 0 replies; 6+ messages in thread
From: Bryan Wu @ 2008-05-12 4:10 UTC (permalink / raw)
To: akpm, alan, linux-kernel; +Cc: Mike Frysinger, Bryan Wu
From: Mike Frysinger <michael.frysinger@analog.com>
Signed-off-by: Mike Frysinger <michael.frysinger@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
---
drivers/serial/Kconfig | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 36acbcc..c88cd1d 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1357,7 +1357,7 @@ config SERIAL_SC26XX_CONSOLE
config SERIAL_BFIN_SPORT
tristate "Blackfin SPORT emulate UART (EXPERIMENTAL)"
- depends on BFIN && EXPERIMENTAL
+ depends on BLACKFIN && EXPERIMENTAL
select SERIAL_CORE
help
Enble support SPORT emulate UART on Blackfin series.
--
1.5.5
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/3] Blackfin Sports UART Driver: fix bug - the bug caused by sport overrun, use timer to flip the tty buffer in order to return from rx ISR quickly
2008-05-12 4:10 [PATCH 0/3] Blackfin Sports UART Driver fixing Bryan Wu
2008-05-12 4:10 ` [PATCH 1/3] Blackfin SPORTS UART Driver: converting BFIN->BLACKFIN Bryan Wu
@ 2008-05-12 4:10 ` Bryan Wu
2008-05-12 9:48 ` Alan Cox
2008-05-12 4:10 ` [PATCH 3/3] Blackfin SPORT UART Driver: rewrite assembly with better constraints (and proper clobber lists) so gcc can do a better job Bryan Wu
2 siblings, 1 reply; 6+ messages in thread
From: Bryan Wu @ 2008-05-12 4:10 UTC (permalink / raw)
To: akpm, alan, linux-kernel; +Cc: Cliff Cai, Bryan Wu
From: Cliff Cai <cliff.cai@analog.com>
http://blackfin.uclinux.org/gf/project/uclinux-dist/tracker/?action=TrackerItemEdit&tracker_item_id=3911
Signed-off-by: Cliff Cai <cliff.cai@analog.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
---
drivers/serial/bfin_sport_uart.c | 32 +++++++++++++++++++++++++-------
1 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c
index aca1240..c31ca6f 100644
--- a/drivers/serial/bfin_sport_uart.c
+++ b/drivers/serial/bfin_sport_uart.c
@@ -88,7 +88,8 @@ unsigned short bfin_uart_pin_req_sport1[] =
struct sport_uart_port {
struct uart_port port;
char *name;
-
+ struct timer_list rx_timer;
+ int once;
int tx_irq;
int rx_irq;
int err_irq;
@@ -115,9 +116,10 @@ static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value)
SPORT_PUT_TX(up, value);
}
-static inline unsigned int rx_one_byte(struct sport_uart_port *up)
+static inline unsigned char rx_one_byte(struct sport_uart_port *up)
{
- unsigned int value, extract;
+ unsigned int value;
+ unsigned char extract;
value = SPORT_GET_RX32(up);
pr_debug("%s value:%x\n", __FUNCTION__, value);
@@ -171,11 +173,20 @@ static int sport_uart_setup(struct sport_uart_port *up, int sclk, int baud_rate)
return 0;
}
+static void rx_push(unsigned long data)
+{
+ struct sport_uart_port *up = (struct sport_uart_port *)data;
+ struct tty_struct *tty = up->port.info->tty;
+ tty_flip_buffer_push(tty);
+ add_timer(&up->rx_timer);
+}
+
+
static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id)
{
struct sport_uart_port *up = dev_id;
struct tty_struct *tty = up->port.info->tty;
- unsigned int ch;
+ unsigned char ch;
do {
ch = rx_one_byte(up);
@@ -186,8 +197,10 @@ static irqreturn_t sport_uart_rx_irq(int irq, void *dev_id)
else
tty_insert_flip_char(tty, ch, TTY_NORMAL);
} while (SPORT_GET_STAT(up) & RXNE);
- tty_flip_buffer_push(tty);
-
+ if (up->once == 0) {
+ add_timer(&up->rx_timer);
+ up->once = 1;
+ }
return IRQ_HANDLED;
}
@@ -253,7 +266,10 @@ static int sport_startup(struct uart_port *port)
printk(KERN_ERR "Unable to request interrupt %s\n", buffer);
goto fail2;
}
-
+ init_timer(&up->rx_timer);
+ up->rx_timer.data = (unsigned long)up;
+ up->rx_timer.expires = jiffies + 5;
+ up->rx_timer.function = (void *)rx_push;
if (port->line) {
if (peripheral_request_list(bfin_uart_pin_req_sport1, DRV_NAME))
goto fail3;
@@ -380,6 +396,8 @@ static void sport_stop_rx(struct uart_port *port)
{
struct sport_uart_port *up = (struct sport_uart_port *)port;
+ del_timer(&up->rx_timer);
+ up->once = 0;
pr_debug("%s enter\n", __FUNCTION__);
/* Disable sport to stop rx */
SPORT_PUT_RCR1(up, (SPORT_GET_RCR1(up) & ~RSPEN));
--
1.5.5
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH 2/3] Blackfin Sports UART Driver: fix bug - the bug caused by sport overrun, use timer to flip the tty buffer in order to return from rx ISR quickly
2008-05-12 4:10 ` [PATCH 2/3] Blackfin Sports UART Driver: fix bug - the bug caused by sport overrun, use timer to flip the tty buffer in order to return from rx ISR quickly Bryan Wu
@ 2008-05-12 9:48 ` Alan Cox
2008-05-13 6:02 ` Cai, Cliff
0 siblings, 1 reply; 6+ messages in thread
From: Alan Cox @ 2008-05-12 9:48 UTC (permalink / raw)
To: Bryan Wu; +Cc: akpm, linux-kernel, Cliff Cai, Bryan Wu
Can you explain what the timer is for ? If you are trying to push the tty
processing out of the interrupt handler then surely schedule_work would
be sufficient. Also if you don't have tty->low_latency set the tty layer
will already do the actual processing work each timer event not in the
IRQ.
^ permalink raw reply [flat|nested] 6+ messages in thread
* RE: [PATCH 2/3] Blackfin Sports UART Driver: fix bug - the bug caused by sport overrun, use timer to flip the tty buffer in order to return from rx ISR quickly
2008-05-12 9:48 ` Alan Cox
@ 2008-05-13 6:02 ` Cai, Cliff
0 siblings, 0 replies; 6+ messages in thread
From: Cai, Cliff @ 2008-05-13 6:02 UTC (permalink / raw)
To: Alan Cox, Bryan Wu; +Cc: akpm, linux-kernel
I will check it later.
Thanks a lot!
Cliff Cai
-----Original Message-----
From: Alan Cox [mailto:alan@lxorguk.ukuu.org.uk]
Sent: Monday, May 12, 2008 5:49 PM
To: Bryan Wu
Cc: akpm@linux-foundation.org; linux-kernel@vger.kernel.org; Cliff Cai;
Bryan Wu
Subject: Re: [PATCH 2/3] Blackfin Sports UART Driver: fix bug - the bug
caused by sport overrun, use timer to flip the tty buffer in order to
return from rx ISR quickly
Can you explain what the timer is for ? If you are trying to push the
tty processing out of the interrupt handler then surely schedule_work
would be sufficient. Also if you don't have tty->low_latency set the tty
layer will already do the actual processing work each timer event not in
the IRQ.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 3/3] Blackfin SPORT UART Driver: rewrite assembly with better constraints (and proper clobber lists) so gcc can do a better job
2008-05-12 4:10 [PATCH 0/3] Blackfin Sports UART Driver fixing Bryan Wu
2008-05-12 4:10 ` [PATCH 1/3] Blackfin SPORTS UART Driver: converting BFIN->BLACKFIN Bryan Wu
2008-05-12 4:10 ` [PATCH 2/3] Blackfin Sports UART Driver: fix bug - the bug caused by sport overrun, use timer to flip the tty buffer in order to return from rx ISR quickly Bryan Wu
@ 2008-05-12 4:10 ` Bryan Wu
2 siblings, 0 replies; 6+ messages in thread
From: Bryan Wu @ 2008-05-12 4:10 UTC (permalink / raw)
To: akpm, alan, linux-kernel; +Cc: Mike Frysinger, Bryan Wu
From: Mike Frysinger <vapier.adi@gmail.com>
Signed-off-by: Mike Frysinger <vapier.adi@gmail.com>
Signed-off-by: Bryan Wu <cooloney@kernel.org>
---
drivers/serial/bfin_sport_uart.c | 54 ++++++++++++++++++++-----------------
1 files changed, 29 insertions(+), 25 deletions(-)
diff --git a/drivers/serial/bfin_sport_uart.c b/drivers/serial/bfin_sport_uart.c
index c31ca6f..786451d 100644
--- a/drivers/serial/bfin_sport_uart.c
+++ b/drivers/serial/bfin_sport_uart.c
@@ -102,15 +102,16 @@ static inline void tx_one_byte(struct sport_uart_port *up, unsigned int value)
{
pr_debug("%s value:%x\n", __FUNCTION__, value);
/* Place a Start and Stop bit */
- __asm__ volatile (
- "R2 = b#01111111100;\n\t"
- "R3 = b#10000000001;\n\t"
- "%0 <<= 2;\n\t"
- "%0 = %0 & R2;\n\t"
- "%0 = %0 | R3;\n\t"
- :"=r"(value)
- :"0"(value)
- :"R2", "R3");
+ __asm__ __volatile__ (
+ "R2 = b#01111111100;"
+ "R3 = b#10000000001;"
+ "%0 <<= 2;"
+ "%0 = %0 & R2;"
+ "%0 = %0 | R3;"
+ : "=d"(value)
+ :
+ : "ASTAT", "R2", "R3"
+ );
pr_debug("%s value:%x\n", __FUNCTION__, value);
SPORT_PUT_TX(up, value);
@@ -120,27 +121,30 @@ static inline unsigned char rx_one_byte(struct sport_uart_port *up)
{
unsigned int value;
unsigned char extract;
+ u32 tmp_mask1, tmp_mask2, tmp_shift, tmp;
value = SPORT_GET_RX32(up);
pr_debug("%s value:%x\n", __FUNCTION__, value);
/* Extract 8 bits data */
- __asm__ volatile (
- "R5 = 0;\n\t"
- "P0 = 8;\n\t"
- "R1 = 0x1801(Z);\n\t"
- "R3 = 0x0300(Z);\n\t"
- "R4 = 0;\n\t"
- "LSETUP(loop_s, loop_e) LC0 = P0;\nloop_s:\t"
- "R2 = extract(%1, R1.L)(Z);\n\t"
- "R2 <<= R4;\n\t"
- "R5 = R5 | R2;\n\t"
- "R1 = R1 - R3;\nloop_e:\t"
- "R4 += 1;\n\t"
- "%0 = R5;\n\t"
- :"=r"(extract)
- :"r"(value)
- :"P0", "R1", "R2","R3","R4", "R5");
+ __asm__ __volatile__ (
+ "%0 = 0;"
+ "%[mask1] = 0x1801(Z);"
+ "%[mask2] = 0x0300(Z);"
+ "%[shift] = 0;"
+ "LSETUP(.Lloop_s, .Lloop_e) LC0 = %[lc];"
+ ".Lloop_s:"
+ "%[tmp] = extract(%[val], %[mask1].L)(Z);"
+ "%[tmp] <<= %[shift];"
+ "%0 = %0 | %[tmp];"
+ "%[mask1] = %[mask1] - %[mask2];"
+ ".Lloop_e:"
+ "%[shift] += 1;"
+ : "=d"(extract), [shift]"=d"(tmp_shift), [tmp]"=d"(tmp),
+ [mask1]"=d"(tmp_mask1), [mask2]"=d"(tmp_mask2)
+ : [val]"d"(value), [lc]"a"(8)
+ : "ASTAT", "LB0", "LC0", "LT0"
+ );
pr_debug(" extract:%x\n", extract);
return extract;
--
1.5.5
^ permalink raw reply related [flat|nested] 6+ messages in thread