diff options
-rw-r--r-- | drivers/serial/cpm_uart/cpm_uart.h | 10 | ||||
-rw-r--r-- | drivers/serial/cpm_uart/cpm_uart_core.c | 118 | ||||
-rw-r--r-- | drivers/serial/cpm_uart/cpm_uart_cpm1.c | 53 |
3 files changed, 116 insertions, 65 deletions
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h index 5f6187baad86..73c8a088c160 100644 --- a/drivers/serial/cpm_uart/cpm_uart.h +++ b/drivers/serial/cpm_uart/cpm_uart.h | |||
@@ -40,13 +40,15 @@ | |||
40 | #define TX_NUM_FIFO 4 | 40 | #define TX_NUM_FIFO 4 |
41 | #define TX_BUF_SIZE 32 | 41 | #define TX_BUF_SIZE 32 |
42 | 42 | ||
43 | #define SCC_WAIT_CLOSING 100 | ||
44 | |||
43 | struct uart_cpm_port { | 45 | struct uart_cpm_port { |
44 | struct uart_port port; | 46 | struct uart_port port; |
45 | u16 rx_nrfifos; | 47 | u16 rx_nrfifos; |
46 | u16 rx_fifosize; | 48 | u16 rx_fifosize; |
47 | u16 tx_nrfifos; | 49 | u16 tx_nrfifos; |
48 | u16 tx_fifosize; | 50 | u16 tx_fifosize; |
49 | smc_t *smcp; | 51 | smc_t *smcp; |
50 | smc_uart_t *smcup; | 52 | smc_uart_t *smcup; |
51 | scc_t *sccp; | 53 | scc_t *sccp; |
52 | scc_uart_t *sccup; | 54 | scc_uart_t *sccup; |
@@ -67,6 +69,8 @@ struct uart_cpm_port { | |||
67 | int bits; | 69 | int bits; |
68 | /* Keep track of 'odd' SMC2 wirings */ | 70 | /* Keep track of 'odd' SMC2 wirings */ |
69 | int is_portb; | 71 | int is_portb; |
72 | /* wait on close if needed */ | ||
73 | int wait_closing; | ||
70 | }; | 74 | }; |
71 | 75 | ||
72 | extern int cpm_uart_port_map[UART_NR]; | 76 | extern int cpm_uart_port_map[UART_NR]; |
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index 29db677d4284..8bd2885b0d32 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -9,9 +9,10 @@ | |||
9 | * | 9 | * |
10 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2) | 10 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2) |
11 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) | 11 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) |
12 | * | 12 | * |
13 | * Copyright (C) 2004 Freescale Semiconductor, Inc. | 13 | * Copyright (C) 2004 Freescale Semiconductor, Inc. |
14 | * (C) 2004 Intracom, S.A. | 14 | * (C) 2004 Intracom, S.A. |
15 | * (C) 2005 MontaVista Software, Inc. by Vitaly Bordug <vbordug@ru.mvista.com> | ||
15 | * | 16 | * |
16 | * This program is free software; you can redistribute it and/or modify | 17 | * This program is free software; you can redistribute it and/or modify |
17 | * it under the terms of the GNU General Public License as published by | 18 | * it under the terms of the GNU General Public License as published by |
@@ -70,8 +71,22 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo); | |||
70 | 71 | ||
71 | /**************************************************************/ | 72 | /**************************************************************/ |
72 | 73 | ||
74 | static inline unsigned long cpu2cpm_addr(void *addr) | ||
75 | { | ||
76 | if ((unsigned long)addr >= CPM_ADDR) | ||
77 | return (unsigned long)addr; | ||
78 | return virt_to_bus(addr); | ||
79 | } | ||
80 | |||
81 | static inline void *cpm2cpu_addr(unsigned long addr) | ||
82 | { | ||
83 | if (addr >= CPM_ADDR) | ||
84 | return (void *)addr; | ||
85 | return bus_to_virt(addr); | ||
86 | } | ||
87 | |||
73 | /* | 88 | /* |
74 | * Check, if transmit buffers are processed | 89 | * Check, if transmit buffers are processed |
75 | */ | 90 | */ |
76 | static unsigned int cpm_uart_tx_empty(struct uart_port *port) | 91 | static unsigned int cpm_uart_tx_empty(struct uart_port *port) |
77 | { | 92 | { |
@@ -143,15 +158,18 @@ static void cpm_uart_start_tx(struct uart_port *port, unsigned int tty_start) | |||
143 | } | 158 | } |
144 | 159 | ||
145 | if (cpm_uart_tx_pump(port) != 0) { | 160 | if (cpm_uart_tx_pump(port) != 0) { |
146 | if (IS_SMC(pinfo)) | 161 | if (IS_SMC(pinfo)) { |
147 | smcp->smc_smcm |= SMCM_TX; | 162 | smcp->smc_smcm |= SMCM_TX; |
148 | else | 163 | smcp->smc_smcmr |= SMCMR_TEN; |
164 | } else { | ||
149 | sccp->scc_sccm |= UART_SCCM_TX; | 165 | sccp->scc_sccm |= UART_SCCM_TX; |
166 | pinfo->sccp->scc_gsmrl |= SCC_GSMRL_ENT; | ||
167 | } | ||
150 | } | 168 | } |
151 | } | 169 | } |
152 | 170 | ||
153 | /* | 171 | /* |
154 | * Stop receiver | 172 | * Stop receiver |
155 | */ | 173 | */ |
156 | static void cpm_uart_stop_rx(struct uart_port *port) | 174 | static void cpm_uart_stop_rx(struct uart_port *port) |
157 | { | 175 | { |
@@ -176,7 +194,7 @@ static void cpm_uart_enable_ms(struct uart_port *port) | |||
176 | } | 194 | } |
177 | 195 | ||
178 | /* | 196 | /* |
179 | * Generate a break. | 197 | * Generate a break. |
180 | */ | 198 | */ |
181 | static void cpm_uart_break_ctl(struct uart_port *port, int break_state) | 199 | static void cpm_uart_break_ctl(struct uart_port *port, int break_state) |
182 | { | 200 | { |
@@ -231,7 +249,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) | |||
231 | /* get number of characters, and check spce in flip-buffer */ | 249 | /* get number of characters, and check spce in flip-buffer */ |
232 | i = bdp->cbd_datlen; | 250 | i = bdp->cbd_datlen; |
233 | 251 | ||
234 | /* If we have not enough room in tty flip buffer, then we try | 252 | /* If we have not enough room in tty flip buffer, then we try |
235 | * later, which will be the next rx-interrupt or a timeout | 253 | * later, which will be the next rx-interrupt or a timeout |
236 | */ | 254 | */ |
237 | if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { | 255 | if ((tty->flip.count + i) >= TTY_FLIPBUF_SIZE) { |
@@ -243,7 +261,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) | |||
243 | } | 261 | } |
244 | 262 | ||
245 | /* get pointer */ | 263 | /* get pointer */ |
246 | cp = (unsigned char *)bus_to_virt(bdp->cbd_bufaddr); | 264 | cp = cpm2cpu_addr(bdp->cbd_bufaddr); |
247 | 265 | ||
248 | /* loop through the buffer */ | 266 | /* loop through the buffer */ |
249 | while (i-- > 0) { | 267 | while (i-- > 0) { |
@@ -265,13 +283,14 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs) | |||
265 | } /* End while (i--) */ | 283 | } /* End while (i--) */ |
266 | 284 | ||
267 | /* This BD is ready to be used again. Clear status. get next */ | 285 | /* This BD is ready to be used again. Clear status. get next */ |
268 | bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV); | 286 | bdp->cbd_sc &= ~(BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID); |
269 | bdp->cbd_sc |= BD_SC_EMPTY; | 287 | bdp->cbd_sc |= BD_SC_EMPTY; |
270 | 288 | ||
271 | if (bdp->cbd_sc & BD_SC_WRAP) | 289 | if (bdp->cbd_sc & BD_SC_WRAP) |
272 | bdp = pinfo->rx_bd_base; | 290 | bdp = pinfo->rx_bd_base; |
273 | else | 291 | else |
274 | bdp++; | 292 | bdp++; |
293 | |||
275 | } /* End for (;;) */ | 294 | } /* End for (;;) */ |
276 | 295 | ||
277 | /* Write back buffer pointer */ | 296 | /* Write back buffer pointer */ |
@@ -336,22 +355,22 @@ static irqreturn_t cpm_uart_int(int irq, void *data, struct pt_regs *regs) | |||
336 | 355 | ||
337 | if (IS_SMC(pinfo)) { | 356 | if (IS_SMC(pinfo)) { |
338 | events = smcp->smc_smce; | 357 | events = smcp->smc_smce; |
358 | smcp->smc_smce = events; | ||
339 | if (events & SMCM_BRKE) | 359 | if (events & SMCM_BRKE) |
340 | uart_handle_break(port); | 360 | uart_handle_break(port); |
341 | if (events & SMCM_RX) | 361 | if (events & SMCM_RX) |
342 | cpm_uart_int_rx(port, regs); | 362 | cpm_uart_int_rx(port, regs); |
343 | if (events & SMCM_TX) | 363 | if (events & SMCM_TX) |
344 | cpm_uart_int_tx(port, regs); | 364 | cpm_uart_int_tx(port, regs); |
345 | smcp->smc_smce = events; | ||
346 | } else { | 365 | } else { |
347 | events = sccp->scc_scce; | 366 | events = sccp->scc_scce; |
367 | sccp->scc_scce = events; | ||
348 | if (events & UART_SCCM_BRKE) | 368 | if (events & UART_SCCM_BRKE) |
349 | uart_handle_break(port); | 369 | uart_handle_break(port); |
350 | if (events & UART_SCCM_RX) | 370 | if (events & UART_SCCM_RX) |
351 | cpm_uart_int_rx(port, regs); | 371 | cpm_uart_int_rx(port, regs); |
352 | if (events & UART_SCCM_TX) | 372 | if (events & UART_SCCM_TX) |
353 | cpm_uart_int_tx(port, regs); | 373 | cpm_uart_int_tx(port, regs); |
354 | sccp->scc_scce = events; | ||
355 | } | 374 | } |
356 | return (events) ? IRQ_HANDLED : IRQ_NONE; | 375 | return (events) ? IRQ_HANDLED : IRQ_NONE; |
357 | } | 376 | } |
@@ -360,6 +379,7 @@ static int cpm_uart_startup(struct uart_port *port) | |||
360 | { | 379 | { |
361 | int retval; | 380 | int retval; |
362 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 381 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
382 | int line = pinfo - cpm_uart_ports; | ||
363 | 383 | ||
364 | pr_debug("CPM uart[%d]:startup\n", port->line); | 384 | pr_debug("CPM uart[%d]:startup\n", port->line); |
365 | 385 | ||
@@ -376,9 +396,19 @@ static int cpm_uart_startup(struct uart_port *port) | |||
376 | pinfo->sccp->scc_sccm |= UART_SCCM_RX; | 396 | pinfo->sccp->scc_sccm |= UART_SCCM_RX; |
377 | } | 397 | } |
378 | 398 | ||
399 | if (!(pinfo->flags & FLAG_CONSOLE)) | ||
400 | cpm_line_cr_cmd(line,CPM_CR_INIT_TRX); | ||
379 | return 0; | 401 | return 0; |
380 | } | 402 | } |
381 | 403 | ||
404 | inline void cpm_uart_wait_until_send(struct uart_cpm_port *pinfo) | ||
405 | { | ||
406 | unsigned long target_jiffies = jiffies + pinfo->wait_closing; | ||
407 | |||
408 | while (!time_after(jiffies, target_jiffies)) | ||
409 | schedule(); | ||
410 | } | ||
411 | |||
382 | /* | 412 | /* |
383 | * Shutdown the uart | 413 | * Shutdown the uart |
384 | */ | 414 | */ |
@@ -394,6 +424,12 @@ static void cpm_uart_shutdown(struct uart_port *port) | |||
394 | 424 | ||
395 | /* If the port is not the console, disable Rx and Tx. */ | 425 | /* If the port is not the console, disable Rx and Tx. */ |
396 | if (!(pinfo->flags & FLAG_CONSOLE)) { | 426 | if (!(pinfo->flags & FLAG_CONSOLE)) { |
427 | /* Wait for all the BDs marked sent */ | ||
428 | while(!cpm_uart_tx_empty(port)) | ||
429 | schedule_timeout(2); | ||
430 | if(pinfo->wait_closing) | ||
431 | cpm_uart_wait_until_send(pinfo); | ||
432 | |||
397 | /* Stop uarts */ | 433 | /* Stop uarts */ |
398 | if (IS_SMC(pinfo)) { | 434 | if (IS_SMC(pinfo)) { |
399 | volatile smc_t *smcp = pinfo->smcp; | 435 | volatile smc_t *smcp = pinfo->smcp; |
@@ -502,7 +538,7 @@ static void cpm_uart_set_termios(struct uart_port *port, | |||
502 | */ | 538 | */ |
503 | if ((termios->c_cflag & CREAD) == 0) | 539 | if ((termios->c_cflag & CREAD) == 0) |
504 | port->read_status_mask &= ~BD_SC_EMPTY; | 540 | port->read_status_mask &= ~BD_SC_EMPTY; |
505 | 541 | ||
506 | spin_lock_irqsave(&port->lock, flags); | 542 | spin_lock_irqsave(&port->lock, flags); |
507 | 543 | ||
508 | /* Start bit has not been added (so don't, because we would just | 544 | /* Start bit has not been added (so don't, because we would just |
@@ -569,7 +605,8 @@ static int cpm_uart_tx_pump(struct uart_port *port) | |||
569 | /* Pick next descriptor and fill from buffer */ | 605 | /* Pick next descriptor and fill from buffer */ |
570 | bdp = pinfo->tx_cur; | 606 | bdp = pinfo->tx_cur; |
571 | 607 | ||
572 | p = bus_to_virt(bdp->cbd_bufaddr); | 608 | p = cpm2cpu_addr(bdp->cbd_bufaddr); |
609 | |||
573 | *p++ = xmit->buf[xmit->tail]; | 610 | *p++ = xmit->buf[xmit->tail]; |
574 | bdp->cbd_datlen = 1; | 611 | bdp->cbd_datlen = 1; |
575 | bdp->cbd_sc |= BD_SC_READY; | 612 | bdp->cbd_sc |= BD_SC_READY; |
@@ -595,7 +632,7 @@ static int cpm_uart_tx_pump(struct uart_port *port) | |||
595 | 632 | ||
596 | while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) { | 633 | while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) { |
597 | count = 0; | 634 | count = 0; |
598 | p = bus_to_virt(bdp->cbd_bufaddr); | 635 | p = cpm2cpu_addr(bdp->cbd_bufaddr); |
599 | while (count < pinfo->tx_fifosize) { | 636 | while (count < pinfo->tx_fifosize) { |
600 | *p++ = xmit->buf[xmit->tail]; | 637 | *p++ = xmit->buf[xmit->tail]; |
601 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 638 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
@@ -606,6 +643,7 @@ static int cpm_uart_tx_pump(struct uart_port *port) | |||
606 | } | 643 | } |
607 | bdp->cbd_datlen = count; | 644 | bdp->cbd_datlen = count; |
608 | bdp->cbd_sc |= BD_SC_READY; | 645 | bdp->cbd_sc |= BD_SC_READY; |
646 | __asm__("eieio"); | ||
609 | /* Get next BD. */ | 647 | /* Get next BD. */ |
610 | if (bdp->cbd_sc & BD_SC_WRAP) | 648 | if (bdp->cbd_sc & BD_SC_WRAP) |
611 | bdp = pinfo->tx_bd_base; | 649 | bdp = pinfo->tx_bd_base; |
@@ -643,12 +681,12 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo) | |||
643 | mem_addr = pinfo->mem_addr; | 681 | mem_addr = pinfo->mem_addr; |
644 | bdp = pinfo->rx_cur = pinfo->rx_bd_base; | 682 | bdp = pinfo->rx_cur = pinfo->rx_bd_base; |
645 | for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) { | 683 | for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) { |
646 | bdp->cbd_bufaddr = virt_to_bus(mem_addr); | 684 | bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); |
647 | bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT; | 685 | bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT; |
648 | mem_addr += pinfo->rx_fifosize; | 686 | mem_addr += pinfo->rx_fifosize; |
649 | } | 687 | } |
650 | 688 | ||
651 | bdp->cbd_bufaddr = virt_to_bus(mem_addr); | 689 | bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); |
652 | bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; | 690 | bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT; |
653 | 691 | ||
654 | /* Set the physical address of the host memory | 692 | /* Set the physical address of the host memory |
@@ -658,12 +696,12 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo) | |||
658 | mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); | 696 | mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize); |
659 | bdp = pinfo->tx_cur = pinfo->tx_bd_base; | 697 | bdp = pinfo->tx_cur = pinfo->tx_bd_base; |
660 | for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) { | 698 | for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) { |
661 | bdp->cbd_bufaddr = virt_to_bus(mem_addr); | 699 | bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); |
662 | bdp->cbd_sc = BD_SC_INTRPT; | 700 | bdp->cbd_sc = BD_SC_INTRPT; |
663 | mem_addr += pinfo->tx_fifosize; | 701 | mem_addr += pinfo->tx_fifosize; |
664 | } | 702 | } |
665 | 703 | ||
666 | bdp->cbd_bufaddr = virt_to_bus(mem_addr); | 704 | bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr); |
667 | bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT; | 705 | bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT; |
668 | } | 706 | } |
669 | 707 | ||
@@ -763,6 +801,8 @@ static void cpm_uart_init_smc(struct uart_cpm_port *pinfo) | |||
763 | /* Using idle charater time requires some additional tuning. */ | 801 | /* Using idle charater time requires some additional tuning. */ |
764 | up->smc_mrblr = pinfo->rx_fifosize; | 802 | up->smc_mrblr = pinfo->rx_fifosize; |
765 | up->smc_maxidl = pinfo->rx_fifosize; | 803 | up->smc_maxidl = pinfo->rx_fifosize; |
804 | up->smc_brklen = 0; | ||
805 | up->smc_brkec = 0; | ||
766 | up->smc_brkcr = 1; | 806 | up->smc_brkcr = 1; |
767 | 807 | ||
768 | cpm_line_cr_cmd(line, CPM_CR_INIT_TRX); | 808 | cpm_line_cr_cmd(line, CPM_CR_INIT_TRX); |
@@ -796,7 +836,7 @@ static int cpm_uart_request_port(struct uart_port *port) | |||
796 | /* | 836 | /* |
797 | * Setup any port IO, connect any baud rate generators, | 837 | * Setup any port IO, connect any baud rate generators, |
798 | * etc. This is expected to be handled by board | 838 | * etc. This is expected to be handled by board |
799 | * dependant code | 839 | * dependant code |
800 | */ | 840 | */ |
801 | if (pinfo->set_lineif) | 841 | if (pinfo->set_lineif) |
802 | pinfo->set_lineif(pinfo); | 842 | pinfo->set_lineif(pinfo); |
@@ -815,6 +855,10 @@ static int cpm_uart_request_port(struct uart_port *port) | |||
815 | return ret; | 855 | return ret; |
816 | 856 | ||
817 | cpm_uart_initbd(pinfo); | 857 | cpm_uart_initbd(pinfo); |
858 | if (IS_SMC(pinfo)) | ||
859 | cpm_uart_init_smc(pinfo); | ||
860 | else | ||
861 | cpm_uart_init_scc(pinfo); | ||
818 | 862 | ||
819 | return 0; | 863 | return 0; |
820 | } | 864 | } |
@@ -869,7 +913,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
869 | .flags = FLAG_SMC, | 913 | .flags = FLAG_SMC, |
870 | .tx_nrfifos = TX_NUM_FIFO, | 914 | .tx_nrfifos = TX_NUM_FIFO, |
871 | .tx_fifosize = TX_BUF_SIZE, | 915 | .tx_fifosize = TX_BUF_SIZE, |
872 | .rx_nrfifos = RX_NUM_FIFO, | 916 | .rx_nrfifos = RX_NUM_FIFO, |
873 | .rx_fifosize = RX_BUF_SIZE, | 917 | .rx_fifosize = RX_BUF_SIZE, |
874 | .set_lineif = smc1_lineif, | 918 | .set_lineif = smc1_lineif, |
875 | }, | 919 | }, |
@@ -883,7 +927,7 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
883 | .flags = FLAG_SMC, | 927 | .flags = FLAG_SMC, |
884 | .tx_nrfifos = TX_NUM_FIFO, | 928 | .tx_nrfifos = TX_NUM_FIFO, |
885 | .tx_fifosize = TX_BUF_SIZE, | 929 | .tx_fifosize = TX_BUF_SIZE, |
886 | .rx_nrfifos = RX_NUM_FIFO, | 930 | .rx_nrfifos = RX_NUM_FIFO, |
887 | .rx_fifosize = RX_BUF_SIZE, | 931 | .rx_fifosize = RX_BUF_SIZE, |
888 | .set_lineif = smc2_lineif, | 932 | .set_lineif = smc2_lineif, |
889 | #ifdef CONFIG_SERIAL_CPM_ALT_SMC2 | 933 | #ifdef CONFIG_SERIAL_CPM_ALT_SMC2 |
@@ -899,9 +943,10 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
899 | }, | 943 | }, |
900 | .tx_nrfifos = TX_NUM_FIFO, | 944 | .tx_nrfifos = TX_NUM_FIFO, |
901 | .tx_fifosize = TX_BUF_SIZE, | 945 | .tx_fifosize = TX_BUF_SIZE, |
902 | .rx_nrfifos = RX_NUM_FIFO, | 946 | .rx_nrfifos = RX_NUM_FIFO, |
903 | .rx_fifosize = RX_BUF_SIZE, | 947 | .rx_fifosize = RX_BUF_SIZE, |
904 | .set_lineif = scc1_lineif, | 948 | .set_lineif = scc1_lineif, |
949 | .wait_closing = SCC_WAIT_CLOSING, | ||
905 | }, | 950 | }, |
906 | [UART_SCC2] = { | 951 | [UART_SCC2] = { |
907 | .port = { | 952 | .port = { |
@@ -912,9 +957,10 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
912 | }, | 957 | }, |
913 | .tx_nrfifos = TX_NUM_FIFO, | 958 | .tx_nrfifos = TX_NUM_FIFO, |
914 | .tx_fifosize = TX_BUF_SIZE, | 959 | .tx_fifosize = TX_BUF_SIZE, |
915 | .rx_nrfifos = RX_NUM_FIFO, | 960 | .rx_nrfifos = RX_NUM_FIFO, |
916 | .rx_fifosize = RX_BUF_SIZE, | 961 | .rx_fifosize = RX_BUF_SIZE, |
917 | .set_lineif = scc2_lineif, | 962 | .set_lineif = scc2_lineif, |
963 | .wait_closing = SCC_WAIT_CLOSING, | ||
918 | }, | 964 | }, |
919 | [UART_SCC3] = { | 965 | [UART_SCC3] = { |
920 | .port = { | 966 | .port = { |
@@ -925,9 +971,10 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
925 | }, | 971 | }, |
926 | .tx_nrfifos = TX_NUM_FIFO, | 972 | .tx_nrfifos = TX_NUM_FIFO, |
927 | .tx_fifosize = TX_BUF_SIZE, | 973 | .tx_fifosize = TX_BUF_SIZE, |
928 | .rx_nrfifos = RX_NUM_FIFO, | 974 | .rx_nrfifos = RX_NUM_FIFO, |
929 | .rx_fifosize = RX_BUF_SIZE, | 975 | .rx_fifosize = RX_BUF_SIZE, |
930 | .set_lineif = scc3_lineif, | 976 | .set_lineif = scc3_lineif, |
977 | .wait_closing = SCC_WAIT_CLOSING, | ||
931 | }, | 978 | }, |
932 | [UART_SCC4] = { | 979 | [UART_SCC4] = { |
933 | .port = { | 980 | .port = { |
@@ -938,9 +985,10 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = { | |||
938 | }, | 985 | }, |
939 | .tx_nrfifos = TX_NUM_FIFO, | 986 | .tx_nrfifos = TX_NUM_FIFO, |
940 | .tx_fifosize = TX_BUF_SIZE, | 987 | .tx_fifosize = TX_BUF_SIZE, |
941 | .rx_nrfifos = RX_NUM_FIFO, | 988 | .rx_nrfifos = RX_NUM_FIFO, |
942 | .rx_fifosize = RX_BUF_SIZE, | 989 | .rx_fifosize = RX_BUF_SIZE, |
943 | .set_lineif = scc4_lineif, | 990 | .set_lineif = scc4_lineif, |
991 | .wait_closing = SCC_WAIT_CLOSING, | ||
944 | }, | 992 | }, |
945 | }; | 993 | }; |
946 | 994 | ||
@@ -983,11 +1031,8 @@ static void cpm_uart_console_write(struct console *co, const char *s, | |||
983 | * If the buffer address is in the CPM DPRAM, don't | 1031 | * If the buffer address is in the CPM DPRAM, don't |
984 | * convert it. | 1032 | * convert it. |
985 | */ | 1033 | */ |
986 | if ((uint) (bdp->cbd_bufaddr) > (uint) CPM_ADDR) | 1034 | cp = cpm2cpu_addr(bdp->cbd_bufaddr); |
987 | cp = (unsigned char *) (bdp->cbd_bufaddr); | 1035 | |
988 | else | ||
989 | cp = bus_to_virt(bdp->cbd_bufaddr); | ||
990 | |||
991 | *cp = *s; | 1036 | *cp = *s; |
992 | 1037 | ||
993 | bdp->cbd_datlen = 1; | 1038 | bdp->cbd_datlen = 1; |
@@ -1003,10 +1048,7 @@ static void cpm_uart_console_write(struct console *co, const char *s, | |||
1003 | while ((bdp->cbd_sc & BD_SC_READY) != 0) | 1048 | while ((bdp->cbd_sc & BD_SC_READY) != 0) |
1004 | ; | 1049 | ; |
1005 | 1050 | ||
1006 | if ((uint) (bdp->cbd_bufaddr) > (uint) CPM_ADDR) | 1051 | cp = cpm2cpu_addr(bdp->cbd_bufaddr); |
1007 | cp = (unsigned char *) (bdp->cbd_bufaddr); | ||
1008 | else | ||
1009 | cp = bus_to_virt(bdp->cbd_bufaddr); | ||
1010 | 1052 | ||
1011 | *cp = 13; | 1053 | *cp = 13; |
1012 | bdp->cbd_datlen = 1; | 1054 | bdp->cbd_datlen = 1; |
@@ -1045,7 +1087,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) | |||
1045 | port = | 1087 | port = |
1046 | (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]]; | 1088 | (struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]]; |
1047 | pinfo = (struct uart_cpm_port *)port; | 1089 | pinfo = (struct uart_cpm_port *)port; |
1048 | 1090 | ||
1049 | pinfo->flags |= FLAG_CONSOLE; | 1091 | pinfo->flags |= FLAG_CONSOLE; |
1050 | 1092 | ||
1051 | if (options) { | 1093 | if (options) { |
@@ -1062,7 +1104,7 @@ static int __init cpm_uart_console_setup(struct console *co, char *options) | |||
1062 | /* | 1104 | /* |
1063 | * Setup any port IO, connect any baud rate generators, | 1105 | * Setup any port IO, connect any baud rate generators, |
1064 | * etc. This is expected to be handled by board | 1106 | * etc. This is expected to be handled by board |
1065 | * dependant code | 1107 | * dependant code |
1066 | */ | 1108 | */ |
1067 | if (pinfo->set_lineif) | 1109 | if (pinfo->set_lineif) |
1068 | pinfo->set_lineif(pinfo); | 1110 | pinfo->set_lineif(pinfo); |
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index 8efbd6d1d6a4..4b0786e7eb7f 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2) | 6 | * Maintainer: Kumar Gala (kumar.gala@freescale.com) (CPM2) |
7 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) | 7 | * Pantelis Antoniou (panto@intracom.gr) (CPM1) |
8 | * | 8 | * |
9 | * Copyright (C) 2004 Freescale Semiconductor, Inc. | 9 | * Copyright (C) 2004 Freescale Semiconductor, Inc. |
10 | * (C) 2004 Intracom, S.A. | 10 | * (C) 2004 Intracom, S.A. |
11 | * | 11 | * |
@@ -82,6 +82,17 @@ void cpm_line_cr_cmd(int line, int cmd) | |||
82 | void smc1_lineif(struct uart_cpm_port *pinfo) | 82 | void smc1_lineif(struct uart_cpm_port *pinfo) |
83 | { | 83 | { |
84 | volatile cpm8xx_t *cp = cpmp; | 84 | volatile cpm8xx_t *cp = cpmp; |
85 | |||
86 | (void)cp; /* fix warning */ | ||
87 | #if defined (CONFIG_MPC885ADS) | ||
88 | /* Enable SMC1 transceivers */ | ||
89 | { | ||
90 | cp->cp_pepar |= 0x000000c0; | ||
91 | cp->cp_pedir &= ~0x000000c0; | ||
92 | cp->cp_peso &= ~0x00000040; | ||
93 | cp->cp_peso |= 0x00000080; | ||
94 | } | ||
95 | #elif defined (CONFIG_MPC86XADS) | ||
85 | unsigned int iobits = 0x000000c0; | 96 | unsigned int iobits = 0x000000c0; |
86 | 97 | ||
87 | if (!pinfo->is_portb) { | 98 | if (!pinfo->is_portb) { |
@@ -93,41 +104,33 @@ void smc1_lineif(struct uart_cpm_port *pinfo) | |||
93 | ((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits; | 104 | ((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits; |
94 | ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits; | 105 | ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits; |
95 | } | 106 | } |
96 | |||
97 | #ifdef CONFIG_MPC885ADS | ||
98 | /* Enable SMC1 transceivers */ | ||
99 | { | ||
100 | volatile uint __iomem *bcsr1 = ioremap(BCSR1, 4); | ||
101 | uint tmp; | ||
102 | |||
103 | tmp = in_be32(bcsr1); | ||
104 | tmp &= ~BCSR1_RS232EN_1; | ||
105 | out_be32(bcsr1, tmp); | ||
106 | iounmap(bcsr1); | ||
107 | } | ||
108 | #endif | 107 | #endif |
109 | |||
110 | pinfo->brg = 1; | 108 | pinfo->brg = 1; |
111 | } | 109 | } |
112 | 110 | ||
113 | void smc2_lineif(struct uart_cpm_port *pinfo) | 111 | void smc2_lineif(struct uart_cpm_port *pinfo) |
114 | { | 112 | { |
115 | #ifdef CONFIG_MPC885ADS | ||
116 | volatile cpm8xx_t *cp = cpmp; | 113 | volatile cpm8xx_t *cp = cpmp; |
117 | volatile uint __iomem *bcsr1; | ||
118 | uint tmp; | ||
119 | 114 | ||
115 | (void)cp; /* fix warning */ | ||
116 | #if defined (CONFIG_MPC885ADS) | ||
120 | cp->cp_pepar |= 0x00000c00; | 117 | cp->cp_pepar |= 0x00000c00; |
121 | cp->cp_pedir &= ~0x00000c00; | 118 | cp->cp_pedir &= ~0x00000c00; |
122 | cp->cp_peso &= ~0x00000400; | 119 | cp->cp_peso &= ~0x00000400; |
123 | cp->cp_peso |= 0x00000800; | 120 | cp->cp_peso |= 0x00000800; |
121 | #elif defined (CONFIG_MPC86XADS) | ||
122 | unsigned int iobits = 0x00000c00; | ||
123 | |||
124 | if (!pinfo->is_portb) { | ||
125 | cp->cp_pbpar |= iobits; | ||
126 | cp->cp_pbdir &= ~iobits; | ||
127 | cp->cp_pbodr &= ~iobits; | ||
128 | } else { | ||
129 | ((immap_t *)IMAP_ADDR)->im_ioport.iop_papar |= iobits; | ||
130 | ((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits; | ||
131 | ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits; | ||
132 | } | ||
124 | 133 | ||
125 | /* Enable SMC2 transceivers */ | ||
126 | bcsr1 = ioremap(BCSR1, 4); | ||
127 | tmp = in_be32(bcsr1); | ||
128 | tmp &= ~BCSR1_RS232EN_2; | ||
129 | out_be32(bcsr1, tmp); | ||
130 | iounmap(bcsr1); | ||
131 | #endif | 134 | #endif |
132 | 135 | ||
133 | pinfo->brg = 2; | 136 | pinfo->brg = 2; |
@@ -158,7 +161,7 @@ void scc4_lineif(struct uart_cpm_port *pinfo) | |||
158 | } | 161 | } |
159 | 162 | ||
160 | /* | 163 | /* |
161 | * Allocate DP-Ram and memory buffers. We need to allocate a transmit and | 164 | * Allocate DP-Ram and memory buffers. We need to allocate a transmit and |
162 | * receive buffer descriptors from dual port ram, and a character | 165 | * receive buffer descriptors from dual port ram, and a character |
163 | * buffer area from host mem. If we are allocating for the console we need | 166 | * buffer area from host mem. If we are allocating for the console we need |
164 | * to do it from bootmem | 167 | * to do it from bootmem |
@@ -185,6 +188,8 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con) | |||
185 | memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + | 188 | memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) + |
186 | L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); | 189 | L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize); |
187 | if (is_con) { | 190 | if (is_con) { |
191 | /* was hostalloc but changed cause it blows away the */ | ||
192 | /* large tlb mapping when pinning the kernel area */ | ||
188 | mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8)); | 193 | mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8)); |
189 | dma_addr = 0; | 194 | dma_addr = 0; |
190 | } else | 195 | } else |