aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/mfd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/mfd.c')
-rw-r--r--drivers/tty/serial/mfd.c73
1 files changed, 15 insertions, 58 deletions
diff --git a/drivers/tty/serial/mfd.c b/drivers/tty/serial/mfd.c
index d40010a22ecd..c111f36f5d21 100644
--- a/drivers/tty/serial/mfd.c
+++ b/drivers/tty/serial/mfd.c
@@ -16,9 +16,7 @@
16 * 2/3 chan to port 1, 4/5 chan to port 3. Even number chans 16 * 2/3 chan to port 1, 4/5 chan to port 3. Even number chans
17 * are used for RX, odd chans for TX 17 * are used for RX, odd chans for TX
18 * 18 *
19 * 2. In A0 stepping, UART will not support TX half empty flag 19 * 2. The RI/DSR/DCD/DTR are not pinned out, DCD & DSR are always
20 *
21 * 3. The RI/DSR/DCD/DTR are not pinned out, DCD & DSR are always
22 * asserted, only when the HW is reset the DDCD and DDSR will 20 * asserted, only when the HW is reset the DDCD and DDSR will
23 * be triggered 21 * be triggered
24 */ 22 */
@@ -41,8 +39,6 @@
41#include <linux/io.h> 39#include <linux/io.h>
42#include <linux/debugfs.h> 40#include <linux/debugfs.h>
43 41
44#define MFD_HSU_A0_STEPPING 1
45
46#define HSU_DMA_BUF_SIZE 2048 42#define HSU_DMA_BUF_SIZE 2048
47 43
48#define chan_readl(chan, offset) readl(chan->reg + offset) 44#define chan_readl(chan, offset) readl(chan->reg + offset)
@@ -51,7 +47,10 @@
51#define mfd_readl(obj, offset) readl(obj->reg + offset) 47#define mfd_readl(obj, offset) readl(obj->reg + offset)
52#define mfd_writel(obj, offset, val) writel(val, obj->reg + offset) 48#define mfd_writel(obj, offset, val) writel(val, obj->reg + offset)
53 49
54#define HSU_DMA_TIMEOUT_CHECK_FREQ (HZ/10) 50static int hsu_dma_enable;
51module_param(hsu_dma_enable, int, 0);
52MODULE_PARM_DESC(hsu_dma_enable, "It is a bitmap to set working mode, if \
53bit[x] is 1, then port[x] will work in DMA mode, otherwise in PIO mode.");
55 54
56struct hsu_dma_buffer { 55struct hsu_dma_buffer {
57 u8 *buf; 56 u8 *buf;
@@ -65,7 +64,6 @@ struct hsu_dma_chan {
65 enum dma_data_direction dirt; 64 enum dma_data_direction dirt;
66 struct uart_hsu_port *uport; 65 struct uart_hsu_port *uport;
67 void __iomem *reg; 66 void __iomem *reg;
68 struct timer_list rx_timer; /* only needed by RX channel */
69}; 67};
70 68
71struct uart_hsu_port { 69struct uart_hsu_port {
@@ -355,8 +353,6 @@ void hsu_dma_start_rx_chan(struct hsu_dma_chan *rxc, struct hsu_dma_buffer *dbuf
355 | (0x1 << 24) /* timeout bit, see HSU Errata 1 */ 353 | (0x1 << 24) /* timeout bit, see HSU Errata 1 */
356 ); 354 );
357 chan_writel(rxc, HSU_CH_CR, 0x3); 355 chan_writel(rxc, HSU_CH_CR, 0x3);
358
359 mod_timer(&rxc->rx_timer, jiffies + HSU_DMA_TIMEOUT_CHECK_FREQ);
360} 356}
361 357
362/* Protected by spin_lock_irqsave(port->lock) */ 358/* Protected by spin_lock_irqsave(port->lock) */
@@ -420,7 +416,6 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts)
420 chan_writel(chan, HSU_CH_CR, 0x3); 416 chan_writel(chan, HSU_CH_CR, 0x3);
421 return; 417 return;
422 } 418 }
423 del_timer(&chan->rx_timer);
424 419
425 dma_sync_single_for_cpu(port->dev, dbuf->dma_addr, 420 dma_sync_single_for_cpu(port->dev, dbuf->dma_addr,
426 dbuf->dma_size, DMA_FROM_DEVICE); 421 dbuf->dma_size, DMA_FROM_DEVICE);
@@ -448,8 +443,6 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts)
448 tty_flip_buffer_push(tty); 443 tty_flip_buffer_push(tty);
449 444
450 chan_writel(chan, HSU_CH_CR, 0x3); 445 chan_writel(chan, HSU_CH_CR, 0x3);
451 chan->rx_timer.expires = jiffies + HSU_DMA_TIMEOUT_CHECK_FREQ;
452 add_timer(&chan->rx_timer);
453 446
454} 447}
455 448
@@ -551,16 +544,9 @@ static void transmit_chars(struct uart_hsu_port *up)
551 return; 544 return;
552 } 545 }
553 546
554#ifndef MFD_HSU_A0_STEPPING 547 /* The IRQ is for TX FIFO half-empty */
555 count = up->port.fifosize / 2; 548 count = up->port.fifosize / 2;
556#else 549
557 /*
558 * A0 only supports fully empty IRQ, and the first char written
559 * into it won't clear the EMPT bit, so we may need be cautious
560 * by useing a shorter buffer
561 */
562 count = up->port.fifosize - 4;
563#endif
564 do { 550 do {
565 serial_out(up, UART_TX, xmit->buf[xmit->tail]); 551 serial_out(up, UART_TX, xmit->buf[xmit->tail]);
566 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 552 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
@@ -769,9 +755,8 @@ static void serial_hsu_break_ctl(struct uart_port *port, int break_state)
769/* 755/*
770 * What special to do: 756 * What special to do:
771 * 1. chose the 64B fifo mode 757 * 1. chose the 64B fifo mode
772 * 2. make sure not to select half empty mode for A0 stepping 758 * 2. start dma or pio depends on configuration
773 * 3. start dma or pio depends on configuration 759 * 3. we only allocate dma memory when needed
774 * 4. we only allocate dma memory when needed
775 */ 760 */
776static int serial_hsu_startup(struct uart_port *port) 761static int serial_hsu_startup(struct uart_port *port)
777{ 762{
@@ -870,8 +855,6 @@ static void serial_hsu_shutdown(struct uart_port *port)
870 container_of(port, struct uart_hsu_port, port); 855 container_of(port, struct uart_hsu_port, port);
871 unsigned long flags; 856 unsigned long flags;
872 857
873 del_timer_sync(&up->rxc->rx_timer);
874
875 /* Disable interrupts from this port */ 858 /* Disable interrupts from this port */
876 up->ier = 0; 859 up->ier = 0;
877 serial_out(up, UART_IER, 0); 860 serial_out(up, UART_IER, 0);
@@ -977,10 +960,6 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
977 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_32B; 960 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_32B;
978 961
979 fcr |= UART_FCR_HSU_64B_FIFO; 962 fcr |= UART_FCR_HSU_64B_FIFO;
980#ifdef MFD_HSU_A0_STEPPING
981 /* A0 doesn't support half empty IRQ */
982 fcr |= UART_FCR_FULL_EMPT_TXI;
983#endif
984 963
985 /* 964 /*
986 * Ok, we're now changing the port state. Do it with 965 * Ok, we're now changing the port state. Do it with
@@ -1343,28 +1322,6 @@ err_disable:
1343 return ret; 1322 return ret;
1344} 1323}
1345 1324
1346static void hsu_dma_rx_timeout(unsigned long data)
1347{
1348 struct hsu_dma_chan *chan = (void *)data;
1349 struct uart_hsu_port *up = chan->uport;
1350 struct hsu_dma_buffer *dbuf = &up->rxbuf;
1351 int count = 0;
1352 unsigned long flags;
1353
1354 spin_lock_irqsave(&up->port.lock, flags);
1355
1356 count = chan_readl(chan, HSU_CH_D0SAR) - dbuf->dma_addr;
1357
1358 if (!count) {
1359 mod_timer(&chan->rx_timer, jiffies + HSU_DMA_TIMEOUT_CHECK_FREQ);
1360 goto exit;
1361 }
1362
1363 hsu_dma_rx(up, 0);
1364exit:
1365 spin_unlock_irqrestore(&up->port.lock, flags);
1366}
1367
1368static void hsu_global_init(void) 1325static void hsu_global_init(void)
1369{ 1326{
1370 struct hsu_port *hsu; 1327 struct hsu_port *hsu;
@@ -1415,6 +1372,12 @@ static void hsu_global_init(void)
1415 1372
1416 serial_hsu_ports[i] = uport; 1373 serial_hsu_ports[i] = uport;
1417 uport->index = i; 1374 uport->index = i;
1375
1376 if (hsu_dma_enable & (1<<i))
1377 uport->use_dma = 1;
1378 else
1379 uport->use_dma = 0;
1380
1418 uport++; 1381 uport++;
1419 } 1382 }
1420 1383
@@ -1427,12 +1390,6 @@ static void hsu_global_init(void)
1427 dchan->reg = hsu->reg + HSU_DMA_CHANS_REG_OFFSET + 1390 dchan->reg = hsu->reg + HSU_DMA_CHANS_REG_OFFSET +
1428 i * HSU_DMA_CHANS_REG_LENGTH; 1391 i * HSU_DMA_CHANS_REG_LENGTH;
1429 1392
1430 /* Work around for RX */
1431 if (dchan->dirt == DMA_FROM_DEVICE) {
1432 init_timer(&dchan->rx_timer);
1433 dchan->rx_timer.function = hsu_dma_rx_timeout;
1434 dchan->rx_timer.data = (unsigned long)dchan;
1435 }
1436 dchan++; 1393 dchan++;
1437 } 1394 }
1438 1395