diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 01:11:04 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-17 01:11:04 +0300 |
commit | e6bee325e49f17c65c1fd66e9e8b348c85788341 (patch) | |
tree | bcc9e5d8e82efa9009edd481a837cc3626360091 /drivers/tty/serial/mfd.c | |
parent | a5e6b135bdff649e4330f98e2e80dbb1984f7e77 (diff) | |
parent | 6ae705b23be8da52d3163be9d81e9b767876aaf9 (diff) | |
download | linux-e6bee325e49f17c65c1fd66e9e8b348c85788341.tar.xz |
Merge branch 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6
* 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6: (76 commits)
pch_uart: reference clock on CM-iTC
pch_phub: add new device ML7213
n_gsm: fix UIH control byte : P bit should be 0
n_gsm: add a documentation
serial: msm_serial_hs: Add MSM high speed UART driver
tty_audit: fix tty_audit_add_data live lock on audit disabled
tty: move cd1865.h to drivers/staging/tty/
Staging: tty: fix build with epca.c driver
pcmcia: synclink_cs: fix prototype for mgslpc_ioctl()
Staging: generic_serial: fix double locking bug
nozomi: don't use flush_scheduled_work()
tty/serial: Relax the device_type restriction from of_serial
MAINTAINERS: Update HVC file patterns
tty: phase out of ioctl file pointer for tty3270 as well
tty: forgot to remove ipwireless from drivers/char/pcmcia/Makefile
pch_uart: Fix DMA channel miss-setting issue.
pch_uart: fix exclusive access issue
pch_uart: fix auto flow control miss-setting issue
pch_uart: fix uart clock setting issue
pch_uart : Use dev_xxx not pr_xxx
...
Fix up trivial conflicts in drivers/misc/pch_phub.c (same patch applied
twice, then changes to the same area in one branch)
Diffstat (limited to 'drivers/tty/serial/mfd.c')
-rw-r--r-- | drivers/tty/serial/mfd.c | 73 |
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 @@ * 2/3 chan to port 1, 4/5 chan to port 3. Even number chans * are used for RX, odd chans for TX * - * 2. In A0 stepping, UART will not support TX half empty flag - * - * 3. The RI/DSR/DCD/DTR are not pinned out, DCD & DSR are always + * 2. The RI/DSR/DCD/DTR are not pinned out, DCD & DSR are always * asserted, only when the HW is reset the DDCD and DDSR will * be triggered */ @@ -41,8 +39,6 @@ #include <linux/io.h> #include <linux/debugfs.h> -#define MFD_HSU_A0_STEPPING 1 - #define HSU_DMA_BUF_SIZE 2048 #define chan_readl(chan, offset) readl(chan->reg + offset) @@ -51,7 +47,10 @@ #define mfd_readl(obj, offset) readl(obj->reg + offset) #define mfd_writel(obj, offset, val) writel(val, obj->reg + offset) -#define HSU_DMA_TIMEOUT_CHECK_FREQ (HZ/10) +static int hsu_dma_enable; +module_param(hsu_dma_enable, int, 0); +MODULE_PARM_DESC(hsu_dma_enable, "It is a bitmap to set working mode, if \ +bit[x] is 1, then port[x] will work in DMA mode, otherwise in PIO mode."); struct hsu_dma_buffer { u8 *buf; @@ -65,7 +64,6 @@ struct hsu_dma_chan { enum dma_data_direction dirt; struct uart_hsu_port *uport; void __iomem *reg; - struct timer_list rx_timer; /* only needed by RX channel */ }; struct uart_hsu_port { @@ -355,8 +353,6 @@ void hsu_dma_start_rx_chan(struct hsu_dma_chan *rxc, struct hsu_dma_buffer *dbuf | (0x1 << 24) /* timeout bit, see HSU Errata 1 */ ); chan_writel(rxc, HSU_CH_CR, 0x3); - - mod_timer(&rxc->rx_timer, jiffies + HSU_DMA_TIMEOUT_CHECK_FREQ); } /* Protected by spin_lock_irqsave(port->lock) */ @@ -420,7 +416,6 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) chan_writel(chan, HSU_CH_CR, 0x3); return; } - del_timer(&chan->rx_timer); dma_sync_single_for_cpu(port->dev, dbuf->dma_addr, dbuf->dma_size, DMA_FROM_DEVICE); @@ -448,8 +443,6 @@ void hsu_dma_rx(struct uart_hsu_port *up, u32 int_sts) tty_flip_buffer_push(tty); chan_writel(chan, HSU_CH_CR, 0x3); - chan->rx_timer.expires = jiffies + HSU_DMA_TIMEOUT_CHECK_FREQ; - add_timer(&chan->rx_timer); } @@ -551,16 +544,9 @@ static void transmit_chars(struct uart_hsu_port *up) return; } -#ifndef MFD_HSU_A0_STEPPING + /* The IRQ is for TX FIFO half-empty */ count = up->port.fifosize / 2; -#else - /* - * A0 only supports fully empty IRQ, and the first char written - * into it won't clear the EMPT bit, so we may need be cautious - * by useing a shorter buffer - */ - count = up->port.fifosize - 4; -#endif + do { serial_out(up, UART_TX, xmit->buf[xmit->tail]); 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) /* * What special to do: * 1. chose the 64B fifo mode - * 2. make sure not to select half empty mode for A0 stepping - * 3. start dma or pio depends on configuration - * 4. we only allocate dma memory when needed + * 2. start dma or pio depends on configuration + * 3. we only allocate dma memory when needed */ static int serial_hsu_startup(struct uart_port *port) { @@ -870,8 +855,6 @@ static void serial_hsu_shutdown(struct uart_port *port) container_of(port, struct uart_hsu_port, port); unsigned long flags; - del_timer_sync(&up->rxc->rx_timer); - /* Disable interrupts from this port */ up->ier = 0; serial_out(up, UART_IER, 0); @@ -977,10 +960,6 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios, fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_32B; fcr |= UART_FCR_HSU_64B_FIFO; -#ifdef MFD_HSU_A0_STEPPING - /* A0 doesn't support half empty IRQ */ - fcr |= UART_FCR_FULL_EMPT_TXI; -#endif /* * Ok, we're now changing the port state. Do it with @@ -1343,28 +1322,6 @@ err_disable: return ret; } -static void hsu_dma_rx_timeout(unsigned long data) -{ - struct hsu_dma_chan *chan = (void *)data; - struct uart_hsu_port *up = chan->uport; - struct hsu_dma_buffer *dbuf = &up->rxbuf; - int count = 0; - unsigned long flags; - - spin_lock_irqsave(&up->port.lock, flags); - - count = chan_readl(chan, HSU_CH_D0SAR) - dbuf->dma_addr; - - if (!count) { - mod_timer(&chan->rx_timer, jiffies + HSU_DMA_TIMEOUT_CHECK_FREQ); - goto exit; - } - - hsu_dma_rx(up, 0); -exit: - spin_unlock_irqrestore(&up->port.lock, flags); -} - static void hsu_global_init(void) { struct hsu_port *hsu; @@ -1415,6 +1372,12 @@ static void hsu_global_init(void) serial_hsu_ports[i] = uport; uport->index = i; + + if (hsu_dma_enable & (1<<i)) + uport->use_dma = 1; + else + uport->use_dma = 0; + uport++; } @@ -1427,12 +1390,6 @@ static void hsu_global_init(void) dchan->reg = hsu->reg + HSU_DMA_CHANS_REG_OFFSET + i * HSU_DMA_CHANS_REG_LENGTH; - /* Work around for RX */ - if (dchan->dirt == DMA_FROM_DEVICE) { - init_timer(&dchan->rx_timer); - dchan->rx_timer.function = hsu_dma_rx_timeout; - dchan->rx_timer.data = (unsigned long)dchan; - } dchan++; } |