aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorFeng Tang <feng.tang@intel.com>2010-07-27 03:20:42 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 16:47:46 -0400
commit06c77e21ae7c199435097116b8212b0761fc8ba8 (patch)
tree2ae53076c07cbf8c112345aeeedb26a22ad7fd59 /drivers/serial
parent669b7a0938e759097c150400cd36bd49befaf5bb (diff)
hsu: some code cleanup
Major changes are: * refine the comments in the driver * remove unused member from structure "hsu_port" * extended spin_lock protoction for dma mode in port_irq() Signed-off-by: Feng Tang <feng.tang@intel.com> Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/mfd.c85
1 files changed, 19 insertions, 66 deletions
diff --git a/drivers/serial/mfd.c b/drivers/serial/mfd.c
index ed2bf6b14a4a..f5e7569c1773 100644
--- a/drivers/serial/mfd.c
+++ b/drivers/serial/mfd.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Refer pxa.c, 8250.c and some other drivers in drivers/serial/ 4 * Refer pxa.c, 8250.c and some other drivers in drivers/serial/
5 * 5 *
6 * (C) Copyright 2009 Intel Corporation 6 * (C) Copyright 2010 Intel Corporation
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
@@ -11,30 +11,16 @@
11 * of the License. 11 * of the License.
12 */ 12 */
13 13
14
15/* Notes: 14/* Notes:
16 * 1. there should be 2 types of register access method, one for 15 * 1. DMA channel allocation: 0/1 channel are assigned to port 0,
17 * UART ports, the other for the general purpose registers 16 * 2/3 chan to port 1, 4/5 chan to port 3. Even number chans
18 * 17 * are used for RX, odd chans for TX
19 * 2. It used to have a Irda port, but was defeatured recently
20 *
21 * 3. Based on the info from HSU MAS, 0/1 channel are assigned to
22 * port0, 2/3 chan to port 1, 4/5 chan to port 3. Even number
23 * chan will be read, odd chan for write
24 *
25 * 4. HUS supports both the 64B and 16B FIFO version, but this driver
26 * will only use 64B version
27 * 18 *
28 * 5. In A0 stepping, UART will not support TX half empty flag, thus 19 * 2. In A0 stepping, UART will not support TX half empty flag
29 * need add a #ifdef judgement
30 * 20 *
31 * 6. One more bug for A0, the loopback mode won't support AFC 21 * 3. The RI/DSR/DCD/DTR are not pinned out, DCD & DSR are always
32 * auto-flow control 22 * asserted, only when the HW is reset the DDCD and DDSR will
33 * 23 * be triggered
34 * 7. HSU has some special FCR control bits, we add it to serial_reg.h
35 *
36 * 8. The RI/DSR/DCD/DTR are not pinned out, DCD & DSR are always asserted,
37 * only when the HW is reset the DDCD and DDSR will be triggered
38 */ 24 */
39 25
40#include <linux/module.h> 26#include <linux/module.h>
@@ -75,7 +61,7 @@ struct hsu_dma_buffer {
75 61
76struct hsu_dma_chan { 62struct hsu_dma_chan {
77 u32 id; 63 u32 id;
78 u32 dirt; /* to or from device */ 64 enum dma_data_direction dirt;
79 struct uart_hsu_port *uport; 65 struct uart_hsu_port *uport;
80 void __iomem *reg; 66 void __iomem *reg;
81 struct timer_list rx_timer; /* only needed by RX channel */ 67 struct timer_list rx_timer; /* only needed by RX channel */
@@ -102,8 +88,6 @@ struct uart_hsu_port {
102 88
103/* Top level data structure of HSU */ 89/* Top level data structure of HSU */
104struct hsu_port { 90struct hsu_port {
105 struct pci_device *pdev;
106
107 void __iomem *reg; 91 void __iomem *reg;
108 unsigned long paddr; 92 unsigned long paddr;
109 unsigned long iolen; 93 unsigned long iolen;
@@ -112,23 +96,9 @@ struct hsu_port {
112 struct uart_hsu_port port[3]; 96 struct uart_hsu_port port[3];
113 struct hsu_dma_chan chans[10]; 97 struct hsu_dma_chan chans[10];
114 98
115#ifdef CONFIG_DEBUG_FS
116 struct dentry *debugfs; 99 struct dentry *debugfs;
117#endif
118}; 100};
119 101
120static inline void hexdump(char *str, u8 *addr, int cnt)
121{
122 int i;
123
124 for (i = 0; i < cnt; i += 8) {
125 printk("0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
126 addr[i], addr[i+1], addr[i+2], addr[i+3],
127 addr[i+4], addr[i+5], addr[i+6], addr[i+7]);
128 printk("\n");
129 }
130}
131
132static inline unsigned int serial_in(struct uart_hsu_port *up, int offset) 102static inline unsigned int serial_in(struct uart_hsu_port *up, int offset)
133{ 103{
134 unsigned int val; 104 unsigned int val;
@@ -353,9 +323,6 @@ void hsu_dma_tx(struct uart_hsu_port *up)
353 | (0x1 << 8) 323 | (0x1 << 8)
354 | (0x1 << 16) 324 | (0x1 << 16)
355 | (0x1 << 24)); 325 | (0x1 << 24));
356
357 WARN(chan_readl(up->txc, HSU_CH_CR) & 0x1,
358 "TX channel has already be started!!\n");
359 up->dma_tx_on = 1; 326 up->dma_tx_on = 1;
360 chan_writel(up->txc, HSU_CH_CR, 0x1); 327 chan_writel(up->txc, HSU_CH_CR, 0x1);
361 } 328 }
@@ -367,7 +334,6 @@ void hsu_dma_tx(struct uart_hsu_port *up)
367/* The buffer is already cache coherent */ 334/* The buffer is already cache coherent */
368void hsu_dma_start_rx_chan(struct hsu_dma_chan *rxc, struct hsu_dma_buffer *dbuf) 335void hsu_dma_start_rx_chan(struct hsu_dma_chan *rxc, struct hsu_dma_buffer *dbuf)
369{ 336{
370 /* Need start RX dma channel here */
371 dbuf->ofs = 0; 337 dbuf->ofs = 0;
372 338
373 chan_writel(rxc, HSU_CH_BSR, 32); 339 chan_writel(rxc, HSU_CH_BSR, 32);
@@ -426,35 +392,32 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts)
426 return; 392 return;
427 393
428 /* 394 /*
429 * first need to know how many is already transferred, 395 * First need to know how many is already transferred,
430 * then check if its a timeout DMA irq, and return 396 * then check if its a timeout DMA irq, and return
431 * the trail bytes out, push them up and reenable the 397 * the trail bytes out, push them up and reenable the
432 * channel, better to use 2 descriptors at the same time 398 * channel
433 */ 399 */
434 400
435 /* timeout IRQ, need wait some time, see Errata 2 */ 401 /* Timeout IRQ, need wait some time, see Errata 2 */
436 if (int_sts & 0xf00) 402 if (int_sts & 0xf00)
437 udelay(2); 403 udelay(2);
438 404
439 /* Stop the channel */ 405 /* Stop the channel */
440 chan_writel(chan, HSU_CH_CR, 0x0); 406 chan_writel(chan, HSU_CH_CR, 0x0);
441 407
442 /* We can use 2 ways to calc the actual transfer len */
443 count = chan_readl(chan, HSU_CH_D0SAR) - dbuf->dma_addr; 408 count = chan_readl(chan, HSU_CH_D0SAR) - dbuf->dma_addr;
444
445 if (!count) { 409 if (!count) {
446 /* restart the channel before we leave */ 410 /* Restart the channel before we leave */
447 chan_writel(chan, HSU_CH_CR, 0x3); 411 chan_writel(chan, HSU_CH_CR, 0x3);
448 return; 412 return;
449 } 413 }
450
451 del_timer(&chan->rx_timer); 414 del_timer(&chan->rx_timer);
452 415
453 dma_sync_single_for_cpu(port->dev, dbuf->dma_addr, 416 dma_sync_single_for_cpu(port->dev, dbuf->dma_addr,
454 dbuf->dma_size, DMA_FROM_DEVICE); 417 dbuf->dma_size, DMA_FROM_DEVICE);
455 418
456 /* 419 /*
457 * head will only wrap around when we recycle 420 * Head will only wrap around when we recycle
458 * the DMA buffer, and when that happens, we 421 * the DMA buffer, and when that happens, we
459 * explicitly set tail to 0. So head will 422 * explicitly set tail to 0. So head will
460 * always be greater than tail. 423 * always be greater than tail.
@@ -496,10 +459,6 @@ static void serial_hsu_stop_rx(struct uart_port *port)
496 } 459 }
497} 460}
498 461
499/*
500 * if there is error flag, should we just reset the FIFO or keeps
501 * working on it
502 */
503static inline void receive_chars(struct uart_hsu_port *up, int *status) 462static inline void receive_chars(struct uart_hsu_port *up, int *status)
504{ 463{
505 struct tty_struct *tty = up->port.state->port.tty; 464 struct tty_struct *tty = up->port.state->port.tty;
@@ -571,7 +530,6 @@ static void transmit_chars(struct uart_hsu_port *up)
571{ 530{
572 struct circ_buf *xmit = &up->port.state->xmit; 531 struct circ_buf *xmit = &up->port.state->xmit;
573 int count; 532 int count;
574 int i = 0; /* for debug use */
575 533
576 if (up->port.x_char) { 534 if (up->port.x_char) {
577 serial_out(up, UART_TX, up->port.x_char); 535 serial_out(up, UART_TX, up->port.x_char);
@@ -592,13 +550,11 @@ static void transmit_chars(struct uart_hsu_port *up)
592 * into it won't clear the EMPT bit, so we may need be cautious 550 * into it won't clear the EMPT bit, so we may need be cautious
593 * by useing a shorter buffer 551 * by useing a shorter buffer
594 */ 552 */
595 /* count = up->port.fifosize; */
596 count = up->port.fifosize - 4; 553 count = up->port.fifosize - 4;
597#endif 554#endif
598 do { 555 do {
599 serial_out(up, UART_TX, xmit->buf[xmit->tail]); 556 serial_out(up, UART_TX, xmit->buf[xmit->tail]);
600 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 557 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
601 i++;
602 558
603 up->port.icount.tx++; 559 up->port.icount.tx++;
604 if (uart_circ_empty(xmit)) 560 if (uart_circ_empty(xmit))
@@ -628,7 +584,7 @@ static inline void check_modem_status(struct uart_hsu_port *up)
628 /* We may only get DDCD when HW init and reset */ 584 /* We may only get DDCD when HW init and reset */
629 if (status & UART_MSR_DDCD) 585 if (status & UART_MSR_DDCD)
630 uart_handle_dcd_change(&up->port, status & UART_MSR_DCD); 586 uart_handle_dcd_change(&up->port, status & UART_MSR_DCD);
631 /* will start/stop_tx accordingly */ 587 /* Will start/stop_tx accordingly */
632 if (status & UART_MSR_DCTS) 588 if (status & UART_MSR_DCTS)
633 uart_handle_cts_change(&up->port, status & UART_MSR_CTS); 589 uart_handle_cts_change(&up->port, status & UART_MSR_CTS);
634 590
@@ -647,6 +603,7 @@ static irqreturn_t port_irq(int irq, void *dev_id)
647 if (unlikely(!up->running)) 603 if (unlikely(!up->running))
648 return IRQ_NONE; 604 return IRQ_NONE;
649 605
606 spin_lock_irqsave(&up->port.lock, flags);
650 if (up->use_dma) { 607 if (up->use_dma) {
651 lsr = serial_in(up, UART_LSR); 608 lsr = serial_in(up, UART_LSR);
652 if (unlikely(lsr & (UART_LSR_BI | UART_LSR_PE | 609 if (unlikely(lsr & (UART_LSR_BI | UART_LSR_PE |
@@ -655,10 +612,10 @@ static irqreturn_t port_irq(int irq, void *dev_id)
655 "Got lsr irq while using DMA, lsr = 0x%2x\n", 612 "Got lsr irq while using DMA, lsr = 0x%2x\n",
656 lsr); 613 lsr);
657 check_modem_status(up); 614 check_modem_status(up);
615 spin_unlock_irqrestore(&up->port.lock, flags);
658 return IRQ_HANDLED; 616 return IRQ_HANDLED;
659 } 617 }
660 618
661 spin_lock_irqsave(&up->port.lock, flags);
662 iir = serial_in(up, UART_IIR); 619 iir = serial_in(up, UART_IIR);
663 if (iir & UART_IIR_NO_INT) { 620 if (iir & UART_IIR_NO_INT) {
664 spin_unlock_irqrestore(&up->port.lock, flags); 621 spin_unlock_irqrestore(&up->port.lock, flags);
@@ -666,9 +623,9 @@ static irqreturn_t port_irq(int irq, void *dev_id)
666 } 623 }
667 624
668 lsr = serial_in(up, UART_LSR); 625 lsr = serial_in(up, UART_LSR);
669
670 if (lsr & UART_LSR_DR) 626 if (lsr & UART_LSR_DR)
671 receive_chars(up, &lsr); 627 receive_chars(up, &lsr);
628 check_modem_status(up);
672 629
673 /* lsr will be renewed during the receive_chars */ 630 /* lsr will be renewed during the receive_chars */
674 if (lsr & UART_LSR_THRE) 631 if (lsr & UART_LSR_THRE)
@@ -701,7 +658,6 @@ static inline void dma_chan_irq(struct hsu_dma_chan *chan)
701 658
702 /* Tx channel */ 659 /* Tx channel */
703 if (chan->dirt == DMA_TO_DEVICE) { 660 if (chan->dirt == DMA_TO_DEVICE) {
704 /* dma for irq should be done */
705 chan_writel(chan, HSU_CH_CR, 0x0); 661 chan_writel(chan, HSU_CH_CR, 0x0);
706 up->dma_tx_on = 0; 662 up->dma_tx_on = 0;
707 hsu_dma_tx(up); 663 hsu_dma_tx(up);
@@ -851,7 +807,6 @@ static int serial_hsu_startup(struct uart_port *port)
851 spin_unlock_irqrestore(&up->port.lock, flags); 807 spin_unlock_irqrestore(&up->port.lock, flags);
852 808
853 /* DMA init */ 809 /* DMA init */
854 /* When use DMA, TX/RX's FIFO and IRQ should be disabled */
855 if (up->use_dma) { 810 if (up->use_dma) {
856 struct hsu_dma_buffer *dbuf; 811 struct hsu_dma_buffer *dbuf;
857 struct circ_buf *xmit = &port->state->xmit; 812 struct circ_buf *xmit = &port->state->xmit;
@@ -1090,11 +1045,9 @@ static int serial_hsu_request_port(struct uart_port *port)
1090 1045
1091static void serial_hsu_config_port(struct uart_port *port, int flags) 1046static void serial_hsu_config_port(struct uart_port *port, int flags)
1092{ 1047{
1093#if 0
1094 struct uart_hsu_port *up = 1048 struct uart_hsu_port *up =
1095 container_of(port, struct uart_hsu_port, port); 1049 container_of(port, struct uart_hsu_port, port);
1096 up->port.type = PORT_MFD; 1050 up->port.type = PORT_MFD;
1097#endif
1098} 1051}
1099 1052
1100static int 1053static int
@@ -1426,7 +1379,7 @@ static void hsu_global_init(void)
1426 uport->port.ops = &serial_hsu_pops; 1379 uport->port.ops = &serial_hsu_pops;
1427 uport->port.line = i; 1380 uport->port.line = i;
1428 uport->port.flags = UPF_IOREMAP; 1381 uport->port.flags = UPF_IOREMAP;
1429 /* make the maxim support rate to 2746800 bps */ 1382 /* set the scalable maxim support rate to 2746800 bps */
1430 uport->port.uartclk = 115200 * 24 * 16; 1383 uport->port.uartclk = 115200 * 24 * 16;
1431 1384
1432 uport->running = 0; 1385 uport->running = 0;