diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/serial/sh-sci.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/serial/sh-sci.c')
-rw-r--r-- | drivers/serial/sh-sci.c | 748 |
1 files changed, 637 insertions, 111 deletions
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 6498bd1fb6dd..8eb094c1f61b 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -48,9 +48,11 @@ | |||
48 | #include <linux/ctype.h> | 48 | #include <linux/ctype.h> |
49 | #include <linux/err.h> | 49 | #include <linux/err.h> |
50 | #include <linux/list.h> | 50 | #include <linux/list.h> |
51 | #include <linux/dmaengine.h> | ||
52 | #include <linux/scatterlist.h> | ||
53 | #include <linux/slab.h> | ||
51 | 54 | ||
52 | #ifdef CONFIG_SUPERH | 55 | #ifdef CONFIG_SUPERH |
53 | #include <asm/clock.h> | ||
54 | #include <asm/sh_bios.h> | 56 | #include <asm/sh_bios.h> |
55 | #endif | 57 | #endif |
56 | 58 | ||
@@ -79,22 +81,39 @@ struct sci_port { | |||
79 | struct timer_list break_timer; | 81 | struct timer_list break_timer; |
80 | int break_flag; | 82 | int break_flag; |
81 | 83 | ||
82 | #ifdef CONFIG_HAVE_CLK | ||
83 | /* Interface clock */ | 84 | /* Interface clock */ |
84 | struct clk *iclk; | 85 | struct clk *iclk; |
85 | /* Data clock */ | 86 | /* Data clock */ |
86 | struct clk *dclk; | 87 | struct clk *dclk; |
87 | #endif | 88 | |
88 | struct list_head node; | 89 | struct list_head node; |
90 | struct dma_chan *chan_tx; | ||
91 | struct dma_chan *chan_rx; | ||
92 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
93 | struct device *dma_dev; | ||
94 | enum sh_dmae_slave_chan_id slave_tx; | ||
95 | enum sh_dmae_slave_chan_id slave_rx; | ||
96 | struct dma_async_tx_descriptor *desc_tx; | ||
97 | struct dma_async_tx_descriptor *desc_rx[2]; | ||
98 | dma_cookie_t cookie_tx; | ||
99 | dma_cookie_t cookie_rx[2]; | ||
100 | dma_cookie_t active_rx; | ||
101 | struct scatterlist sg_tx; | ||
102 | unsigned int sg_len_tx; | ||
103 | struct scatterlist sg_rx[2]; | ||
104 | size_t buf_len_rx; | ||
105 | struct sh_dmae_slave param_tx; | ||
106 | struct sh_dmae_slave param_rx; | ||
107 | struct work_struct work_tx; | ||
108 | struct work_struct work_rx; | ||
109 | struct timer_list rx_timer; | ||
110 | #endif | ||
89 | }; | 111 | }; |
90 | 112 | ||
91 | struct sh_sci_priv { | 113 | struct sh_sci_priv { |
92 | spinlock_t lock; | 114 | spinlock_t lock; |
93 | struct list_head ports; | 115 | struct list_head ports; |
94 | |||
95 | #ifdef CONFIG_HAVE_CLK | ||
96 | struct notifier_block clk_nb; | 116 | struct notifier_block clk_nb; |
97 | #endif | ||
98 | }; | 117 | }; |
99 | 118 | ||
100 | /* Function prototypes */ | 119 | /* Function prototypes */ |
@@ -156,32 +175,6 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c) | |||
156 | } | 175 | } |
157 | #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */ | 176 | #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */ |
158 | 177 | ||
159 | #if defined(__H8300S__) | ||
160 | enum { sci_disable, sci_enable }; | ||
161 | |||
162 | static void h8300_sci_config(struct uart_port *port, unsigned int ctrl) | ||
163 | { | ||
164 | volatile unsigned char *mstpcrl = (volatile unsigned char *)MSTPCRL; | ||
165 | int ch = (port->mapbase - SMR0) >> 3; | ||
166 | unsigned char mask = 1 << (ch+1); | ||
167 | |||
168 | if (ctrl == sci_disable) | ||
169 | *mstpcrl |= mask; | ||
170 | else | ||
171 | *mstpcrl &= ~mask; | ||
172 | } | ||
173 | |||
174 | static void h8300_sci_enable(struct uart_port *port) | ||
175 | { | ||
176 | h8300_sci_config(port, sci_enable); | ||
177 | } | ||
178 | |||
179 | static void h8300_sci_disable(struct uart_port *port) | ||
180 | { | ||
181 | h8300_sci_config(port, sci_disable); | ||
182 | } | ||
183 | #endif | ||
184 | |||
185 | #if defined(__H8300H__) || defined(__H8300S__) | 178 | #if defined(__H8300H__) || defined(__H8300S__) |
186 | static void sci_init_pins(struct uart_port *port, unsigned int cflag) | 179 | static void sci_init_pins(struct uart_port *port, unsigned int cflag) |
187 | { | 180 | { |
@@ -253,9 +246,9 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | |||
253 | Set SCP6MD1,0 = {01} (output) */ | 246 | Set SCP6MD1,0 = {01} (output) */ |
254 | __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); | 247 | __raw_writew((data & 0x0fcf) | 0x1000, SCPCR); |
255 | 248 | ||
256 | data = ctrl_inb(SCPDR); | 249 | data = __raw_readb(SCPDR); |
257 | /* Set /RTS2 (bit6) = 0 */ | 250 | /* Set /RTS2 (bit6) = 0 */ |
258 | ctrl_outb(data & 0xbf, SCPDR); | 251 | __raw_writeb(data & 0xbf, SCPDR); |
259 | } | 252 | } |
260 | } | 253 | } |
261 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) | 254 | #elif defined(CONFIG_CPU_SUBTYPE_SH7722) |
@@ -300,29 +293,44 @@ static inline void sci_init_pins(struct uart_port *port, unsigned int cflag) | |||
300 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ | 293 | defined(CONFIG_CPU_SUBTYPE_SH7780) || \ |
301 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ | 294 | defined(CONFIG_CPU_SUBTYPE_SH7785) || \ |
302 | defined(CONFIG_CPU_SUBTYPE_SH7786) | 295 | defined(CONFIG_CPU_SUBTYPE_SH7786) |
303 | static inline int scif_txroom(struct uart_port *port) | 296 | static int scif_txfill(struct uart_port *port) |
297 | { | ||
298 | return sci_in(port, SCTFDR) & 0xff; | ||
299 | } | ||
300 | |||
301 | static int scif_txroom(struct uart_port *port) | ||
304 | { | 302 | { |
305 | return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff); | 303 | return SCIF_TXROOM_MAX - scif_txfill(port); |
306 | } | 304 | } |
307 | 305 | ||
308 | static inline int scif_rxroom(struct uart_port *port) | 306 | static int scif_rxfill(struct uart_port *port) |
309 | { | 307 | { |
310 | return sci_in(port, SCRFDR) & 0xff; | 308 | return sci_in(port, SCRFDR) & 0xff; |
311 | } | 309 | } |
312 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) | 310 | #elif defined(CONFIG_CPU_SUBTYPE_SH7763) |
313 | static inline int scif_txroom(struct uart_port *port) | 311 | static int scif_txfill(struct uart_port *port) |
314 | { | 312 | { |
315 | if ((port->mapbase == 0xffe00000) || | 313 | if (port->mapbase == 0xffe00000 || |
316 | (port->mapbase == 0xffe08000)) { | 314 | port->mapbase == 0xffe08000) |
317 | /* SCIF0/1*/ | 315 | /* SCIF0/1*/ |
318 | return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff); | 316 | return sci_in(port, SCTFDR) & 0xff; |
319 | } else { | 317 | else |
320 | /* SCIF2 */ | 318 | /* SCIF2 */ |
321 | return SCIF2_TXROOM_MAX - (sci_in(port, SCFDR) >> 8); | 319 | return sci_in(port, SCFDR) >> 8; |
322 | } | 320 | } |
321 | |||
322 | static int scif_txroom(struct uart_port *port) | ||
323 | { | ||
324 | if (port->mapbase == 0xffe00000 || | ||
325 | port->mapbase == 0xffe08000) | ||
326 | /* SCIF0/1*/ | ||
327 | return SCIF_TXROOM_MAX - scif_txfill(port); | ||
328 | else | ||
329 | /* SCIF2 */ | ||
330 | return SCIF2_TXROOM_MAX - scif_txfill(port); | ||
323 | } | 331 | } |
324 | 332 | ||
325 | static inline int scif_rxroom(struct uart_port *port) | 333 | static int scif_rxfill(struct uart_port *port) |
326 | { | 334 | { |
327 | if ((port->mapbase == 0xffe00000) || | 335 | if ((port->mapbase == 0xffe00000) || |
328 | (port->mapbase == 0xffe08000)) { | 336 | (port->mapbase == 0xffe08000)) { |
@@ -334,23 +342,33 @@ static inline int scif_rxroom(struct uart_port *port) | |||
334 | } | 342 | } |
335 | } | 343 | } |
336 | #else | 344 | #else |
337 | static inline int scif_txroom(struct uart_port *port) | 345 | static int scif_txfill(struct uart_port *port) |
346 | { | ||
347 | return sci_in(port, SCFDR) >> 8; | ||
348 | } | ||
349 | |||
350 | static int scif_txroom(struct uart_port *port) | ||
338 | { | 351 | { |
339 | return SCIF_TXROOM_MAX - (sci_in(port, SCFDR) >> 8); | 352 | return SCIF_TXROOM_MAX - scif_txfill(port); |
340 | } | 353 | } |
341 | 354 | ||
342 | static inline int scif_rxroom(struct uart_port *port) | 355 | static int scif_rxfill(struct uart_port *port) |
343 | { | 356 | { |
344 | return sci_in(port, SCFDR) & SCIF_RFDC_MASK; | 357 | return sci_in(port, SCFDR) & SCIF_RFDC_MASK; |
345 | } | 358 | } |
346 | #endif | 359 | #endif |
347 | 360 | ||
348 | static inline int sci_txroom(struct uart_port *port) | 361 | static int sci_txfill(struct uart_port *port) |
349 | { | 362 | { |
350 | return (sci_in(port, SCxSR) & SCI_TDRE) != 0; | 363 | return !(sci_in(port, SCxSR) & SCI_TDRE); |
351 | } | 364 | } |
352 | 365 | ||
353 | static inline int sci_rxroom(struct uart_port *port) | 366 | static int sci_txroom(struct uart_port *port) |
367 | { | ||
368 | return !sci_txfill(port); | ||
369 | } | ||
370 | |||
371 | static int sci_rxfill(struct uart_port *port) | ||
354 | { | 372 | { |
355 | return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; | 373 | return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0; |
356 | } | 374 | } |
@@ -437,9 +455,9 @@ static inline void sci_receive_chars(struct uart_port *port) | |||
437 | 455 | ||
438 | while (1) { | 456 | while (1) { |
439 | if (port->type == PORT_SCI) | 457 | if (port->type == PORT_SCI) |
440 | count = sci_rxroom(port); | 458 | count = sci_rxfill(port); |
441 | else | 459 | else |
442 | count = scif_rxroom(port); | 460 | count = scif_rxfill(port); |
443 | 461 | ||
444 | /* Don't copy more bytes than there is room for in the buffer */ | 462 | /* Don't copy more bytes than there is room for in the buffer */ |
445 | count = tty_buffer_request_room(tty, count); | 463 | count = tty_buffer_request_room(tty, count); |
@@ -484,10 +502,10 @@ static inline void sci_receive_chars(struct uart_port *port) | |||
484 | } | 502 | } |
485 | 503 | ||
486 | /* Store data and status */ | 504 | /* Store data and status */ |
487 | if (status&SCxSR_FER(port)) { | 505 | if (status & SCxSR_FER(port)) { |
488 | flag = TTY_FRAME; | 506 | flag = TTY_FRAME; |
489 | dev_notice(port->dev, "frame error\n"); | 507 | dev_notice(port->dev, "frame error\n"); |
490 | } else if (status&SCxSR_PER(port)) { | 508 | } else if (status & SCxSR_PER(port)) { |
491 | flag = TTY_PARITY; | 509 | flag = TTY_PARITY; |
492 | dev_notice(port->dev, "parity error\n"); | 510 | dev_notice(port->dev, "parity error\n"); |
493 | } else | 511 | } else |
@@ -649,13 +667,39 @@ static inline int sci_handle_breaks(struct uart_port *port) | |||
649 | return copied; | 667 | return copied; |
650 | } | 668 | } |
651 | 669 | ||
652 | static irqreturn_t sci_rx_interrupt(int irq, void *port) | 670 | static irqreturn_t sci_rx_interrupt(int irq, void *ptr) |
653 | { | 671 | { |
672 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
673 | struct uart_port *port = ptr; | ||
674 | struct sci_port *s = to_sci_port(port); | ||
675 | |||
676 | if (s->chan_rx) { | ||
677 | unsigned long tout; | ||
678 | u16 scr = sci_in(port, SCSCR); | ||
679 | u16 ssr = sci_in(port, SCxSR); | ||
680 | |||
681 | /* Disable future Rx interrupts */ | ||
682 | sci_out(port, SCSCR, scr & ~SCI_CTRL_FLAGS_RIE); | ||
683 | /* Clear current interrupt */ | ||
684 | sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port))); | ||
685 | /* Calculate delay for 1.5 DMA buffers */ | ||
686 | tout = (port->timeout - HZ / 50) * s->buf_len_rx * 3 / | ||
687 | port->fifosize / 2; | ||
688 | dev_dbg(port->dev, "Rx IRQ: setup timeout in %lu ms\n", | ||
689 | tout * 1000 / HZ); | ||
690 | if (tout < 2) | ||
691 | tout = 2; | ||
692 | mod_timer(&s->rx_timer, jiffies + tout); | ||
693 | |||
694 | return IRQ_HANDLED; | ||
695 | } | ||
696 | #endif | ||
697 | |||
654 | /* I think sci_receive_chars has to be called irrespective | 698 | /* I think sci_receive_chars has to be called irrespective |
655 | * of whether the I_IXOFF is set, otherwise, how is the interrupt | 699 | * of whether the I_IXOFF is set, otherwise, how is the interrupt |
656 | * to be disabled? | 700 | * to be disabled? |
657 | */ | 701 | */ |
658 | sci_receive_chars(port); | 702 | sci_receive_chars(ptr); |
659 | 703 | ||
660 | return IRQ_HANDLED; | 704 | return IRQ_HANDLED; |
661 | } | 705 | } |
@@ -711,6 +755,7 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | |||
711 | { | 755 | { |
712 | unsigned short ssr_status, scr_status, err_enabled; | 756 | unsigned short ssr_status, scr_status, err_enabled; |
713 | struct uart_port *port = ptr; | 757 | struct uart_port *port = ptr; |
758 | struct sci_port *s = to_sci_port(port); | ||
714 | irqreturn_t ret = IRQ_NONE; | 759 | irqreturn_t ret = IRQ_NONE; |
715 | 760 | ||
716 | ssr_status = sci_in(port, SCxSR); | 761 | ssr_status = sci_in(port, SCxSR); |
@@ -718,10 +763,15 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | |||
718 | err_enabled = scr_status & (SCI_CTRL_FLAGS_REIE | SCI_CTRL_FLAGS_RIE); | 763 | err_enabled = scr_status & (SCI_CTRL_FLAGS_REIE | SCI_CTRL_FLAGS_RIE); |
719 | 764 | ||
720 | /* Tx Interrupt */ | 765 | /* Tx Interrupt */ |
721 | if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCI_CTRL_FLAGS_TIE)) | 766 | if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCI_CTRL_FLAGS_TIE) && |
767 | !s->chan_tx) | ||
722 | ret = sci_tx_interrupt(irq, ptr); | 768 | ret = sci_tx_interrupt(irq, ptr); |
723 | /* Rx Interrupt */ | 769 | /* |
724 | if ((ssr_status & SCxSR_RDxF(port)) && (scr_status & SCI_CTRL_FLAGS_RIE)) | 770 | * Rx Interrupt: if we're using DMA, the DMA controller clears RDF / |
771 | * DR flags | ||
772 | */ | ||
773 | if (((ssr_status & SCxSR_RDxF(port)) || s->chan_rx) && | ||
774 | (scr_status & SCI_CTRL_FLAGS_RIE)) | ||
725 | ret = sci_rx_interrupt(irq, ptr); | 775 | ret = sci_rx_interrupt(irq, ptr); |
726 | /* Error Interrupt */ | 776 | /* Error Interrupt */ |
727 | if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled) | 777 | if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled) |
@@ -733,7 +783,6 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) | |||
733 | return ret; | 783 | return ret; |
734 | } | 784 | } |
735 | 785 | ||
736 | #ifdef CONFIG_HAVE_CLK | ||
737 | /* | 786 | /* |
738 | * Here we define a transistion notifier so that we can update all of our | 787 | * Here we define a transistion notifier so that we can update all of our |
739 | * ports' baud rate when the peripheral clock changes. | 788 | * ports' baud rate when the peripheral clock changes. |
@@ -751,7 +800,6 @@ static int sci_notifier(struct notifier_block *self, | |||
751 | spin_lock_irqsave(&priv->lock, flags); | 800 | spin_lock_irqsave(&priv->lock, flags); |
752 | list_for_each_entry(sci_port, &priv->ports, node) | 801 | list_for_each_entry(sci_port, &priv->ports, node) |
753 | sci_port->port.uartclk = clk_get_rate(sci_port->dclk); | 802 | sci_port->port.uartclk = clk_get_rate(sci_port->dclk); |
754 | |||
755 | spin_unlock_irqrestore(&priv->lock, flags); | 803 | spin_unlock_irqrestore(&priv->lock, flags); |
756 | } | 804 | } |
757 | 805 | ||
@@ -778,7 +826,6 @@ static void sci_clk_disable(struct uart_port *port) | |||
778 | 826 | ||
779 | clk_disable(sci_port->dclk); | 827 | clk_disable(sci_port->dclk); |
780 | } | 828 | } |
781 | #endif | ||
782 | 829 | ||
783 | static int sci_request_irq(struct sci_port *port) | 830 | static int sci_request_irq(struct sci_port *port) |
784 | { | 831 | { |
@@ -833,8 +880,10 @@ static void sci_free_irq(struct sci_port *port) | |||
833 | 880 | ||
834 | static unsigned int sci_tx_empty(struct uart_port *port) | 881 | static unsigned int sci_tx_empty(struct uart_port *port) |
835 | { | 882 | { |
836 | /* Can't detect */ | 883 | unsigned short status = sci_in(port, SCxSR); |
837 | return TIOCSER_TEMT; | 884 | unsigned short in_tx_fifo = scif_txfill(port); |
885 | |||
886 | return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0; | ||
838 | } | 887 | } |
839 | 888 | ||
840 | static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) | 889 | static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) |
@@ -846,16 +895,297 @@ static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
846 | 895 | ||
847 | static unsigned int sci_get_mctrl(struct uart_port *port) | 896 | static unsigned int sci_get_mctrl(struct uart_port *port) |
848 | { | 897 | { |
849 | /* This routine is used for geting signals of: DTR, DCD, DSR, RI, | 898 | /* This routine is used for getting signals of: DTR, DCD, DSR, RI, |
850 | and CTS/RTS */ | 899 | and CTS/RTS */ |
851 | 900 | ||
852 | return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR; | 901 | return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR; |
853 | } | 902 | } |
854 | 903 | ||
904 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
905 | static void sci_dma_tx_complete(void *arg) | ||
906 | { | ||
907 | struct sci_port *s = arg; | ||
908 | struct uart_port *port = &s->port; | ||
909 | struct circ_buf *xmit = &port->state->xmit; | ||
910 | unsigned long flags; | ||
911 | |||
912 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | ||
913 | |||
914 | spin_lock_irqsave(&port->lock, flags); | ||
915 | |||
916 | xmit->tail += s->sg_tx.length; | ||
917 | xmit->tail &= UART_XMIT_SIZE - 1; | ||
918 | |||
919 | port->icount.tx += s->sg_tx.length; | ||
920 | |||
921 | async_tx_ack(s->desc_tx); | ||
922 | s->cookie_tx = -EINVAL; | ||
923 | s->desc_tx = NULL; | ||
924 | |||
925 | spin_unlock_irqrestore(&port->lock, flags); | ||
926 | |||
927 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
928 | uart_write_wakeup(port); | ||
929 | |||
930 | if (uart_circ_chars_pending(xmit)) | ||
931 | schedule_work(&s->work_tx); | ||
932 | } | ||
933 | |||
934 | /* Locking: called with port lock held */ | ||
935 | static int sci_dma_rx_push(struct sci_port *s, struct tty_struct *tty, | ||
936 | size_t count) | ||
937 | { | ||
938 | struct uart_port *port = &s->port; | ||
939 | int i, active, room; | ||
940 | |||
941 | room = tty_buffer_request_room(tty, count); | ||
942 | |||
943 | if (s->active_rx == s->cookie_rx[0]) { | ||
944 | active = 0; | ||
945 | } else if (s->active_rx == s->cookie_rx[1]) { | ||
946 | active = 1; | ||
947 | } else { | ||
948 | dev_err(port->dev, "cookie %d not found!\n", s->active_rx); | ||
949 | return 0; | ||
950 | } | ||
951 | |||
952 | if (room < count) | ||
953 | dev_warn(port->dev, "Rx overrun: dropping %u bytes\n", | ||
954 | count - room); | ||
955 | if (!room) | ||
956 | return room; | ||
957 | |||
958 | for (i = 0; i < room; i++) | ||
959 | tty_insert_flip_char(tty, ((u8 *)sg_virt(&s->sg_rx[active]))[i], | ||
960 | TTY_NORMAL); | ||
961 | |||
962 | port->icount.rx += room; | ||
963 | |||
964 | return room; | ||
965 | } | ||
966 | |||
967 | static void sci_dma_rx_complete(void *arg) | ||
968 | { | ||
969 | struct sci_port *s = arg; | ||
970 | struct uart_port *port = &s->port; | ||
971 | struct tty_struct *tty = port->state->port.tty; | ||
972 | unsigned long flags; | ||
973 | int count; | ||
974 | |||
975 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | ||
976 | |||
977 | spin_lock_irqsave(&port->lock, flags); | ||
978 | |||
979 | count = sci_dma_rx_push(s, tty, s->buf_len_rx); | ||
980 | |||
981 | mod_timer(&s->rx_timer, jiffies + msecs_to_jiffies(5)); | ||
982 | |||
983 | spin_unlock_irqrestore(&port->lock, flags); | ||
984 | |||
985 | if (count) | ||
986 | tty_flip_buffer_push(tty); | ||
987 | |||
988 | schedule_work(&s->work_rx); | ||
989 | } | ||
990 | |||
991 | static void sci_start_rx(struct uart_port *port); | ||
992 | static void sci_start_tx(struct uart_port *port); | ||
993 | |||
994 | static void sci_rx_dma_release(struct sci_port *s, bool enable_pio) | ||
995 | { | ||
996 | struct dma_chan *chan = s->chan_rx; | ||
997 | struct uart_port *port = &s->port; | ||
998 | |||
999 | s->chan_rx = NULL; | ||
1000 | s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL; | ||
1001 | dma_release_channel(chan); | ||
1002 | dma_free_coherent(port->dev, s->buf_len_rx * 2, | ||
1003 | sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0])); | ||
1004 | if (enable_pio) | ||
1005 | sci_start_rx(port); | ||
1006 | } | ||
1007 | |||
1008 | static void sci_tx_dma_release(struct sci_port *s, bool enable_pio) | ||
1009 | { | ||
1010 | struct dma_chan *chan = s->chan_tx; | ||
1011 | struct uart_port *port = &s->port; | ||
1012 | |||
1013 | s->chan_tx = NULL; | ||
1014 | s->cookie_tx = -EINVAL; | ||
1015 | dma_release_channel(chan); | ||
1016 | if (enable_pio) | ||
1017 | sci_start_tx(port); | ||
1018 | } | ||
1019 | |||
1020 | static void sci_submit_rx(struct sci_port *s) | ||
1021 | { | ||
1022 | struct dma_chan *chan = s->chan_rx; | ||
1023 | int i; | ||
1024 | |||
1025 | for (i = 0; i < 2; i++) { | ||
1026 | struct scatterlist *sg = &s->sg_rx[i]; | ||
1027 | struct dma_async_tx_descriptor *desc; | ||
1028 | |||
1029 | desc = chan->device->device_prep_slave_sg(chan, | ||
1030 | sg, 1, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT); | ||
1031 | |||
1032 | if (desc) { | ||
1033 | s->desc_rx[i] = desc; | ||
1034 | desc->callback = sci_dma_rx_complete; | ||
1035 | desc->callback_param = s; | ||
1036 | s->cookie_rx[i] = desc->tx_submit(desc); | ||
1037 | } | ||
1038 | |||
1039 | if (!desc || s->cookie_rx[i] < 0) { | ||
1040 | if (i) { | ||
1041 | async_tx_ack(s->desc_rx[0]); | ||
1042 | s->cookie_rx[0] = -EINVAL; | ||
1043 | } | ||
1044 | if (desc) { | ||
1045 | async_tx_ack(desc); | ||
1046 | s->cookie_rx[i] = -EINVAL; | ||
1047 | } | ||
1048 | dev_warn(s->port.dev, | ||
1049 | "failed to re-start DMA, using PIO\n"); | ||
1050 | sci_rx_dma_release(s, true); | ||
1051 | return; | ||
1052 | } | ||
1053 | } | ||
1054 | |||
1055 | s->active_rx = s->cookie_rx[0]; | ||
1056 | |||
1057 | dma_async_issue_pending(chan); | ||
1058 | } | ||
1059 | |||
1060 | static void work_fn_rx(struct work_struct *work) | ||
1061 | { | ||
1062 | struct sci_port *s = container_of(work, struct sci_port, work_rx); | ||
1063 | struct uart_port *port = &s->port; | ||
1064 | struct dma_async_tx_descriptor *desc; | ||
1065 | int new; | ||
1066 | |||
1067 | if (s->active_rx == s->cookie_rx[0]) { | ||
1068 | new = 0; | ||
1069 | } else if (s->active_rx == s->cookie_rx[1]) { | ||
1070 | new = 1; | ||
1071 | } else { | ||
1072 | dev_err(port->dev, "cookie %d not found!\n", s->active_rx); | ||
1073 | return; | ||
1074 | } | ||
1075 | desc = s->desc_rx[new]; | ||
1076 | |||
1077 | if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) != | ||
1078 | DMA_SUCCESS) { | ||
1079 | /* Handle incomplete DMA receive */ | ||
1080 | struct tty_struct *tty = port->state->port.tty; | ||
1081 | struct dma_chan *chan = s->chan_rx; | ||
1082 | struct sh_desc *sh_desc = container_of(desc, struct sh_desc, | ||
1083 | async_tx); | ||
1084 | unsigned long flags; | ||
1085 | int count; | ||
1086 | |||
1087 | chan->device->device_terminate_all(chan); | ||
1088 | dev_dbg(port->dev, "Read %u bytes with cookie %d\n", | ||
1089 | sh_desc->partial, sh_desc->cookie); | ||
1090 | |||
1091 | spin_lock_irqsave(&port->lock, flags); | ||
1092 | count = sci_dma_rx_push(s, tty, sh_desc->partial); | ||
1093 | spin_unlock_irqrestore(&port->lock, flags); | ||
1094 | |||
1095 | if (count) | ||
1096 | tty_flip_buffer_push(tty); | ||
1097 | |||
1098 | sci_submit_rx(s); | ||
1099 | |||
1100 | return; | ||
1101 | } | ||
1102 | |||
1103 | s->cookie_rx[new] = desc->tx_submit(desc); | ||
1104 | if (s->cookie_rx[new] < 0) { | ||
1105 | dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n"); | ||
1106 | sci_rx_dma_release(s, true); | ||
1107 | return; | ||
1108 | } | ||
1109 | |||
1110 | dev_dbg(port->dev, "%s: cookie %d #%d\n", __func__, | ||
1111 | s->cookie_rx[new], new); | ||
1112 | |||
1113 | s->active_rx = s->cookie_rx[!new]; | ||
1114 | } | ||
1115 | |||
1116 | static void work_fn_tx(struct work_struct *work) | ||
1117 | { | ||
1118 | struct sci_port *s = container_of(work, struct sci_port, work_tx); | ||
1119 | struct dma_async_tx_descriptor *desc; | ||
1120 | struct dma_chan *chan = s->chan_tx; | ||
1121 | struct uart_port *port = &s->port; | ||
1122 | struct circ_buf *xmit = &port->state->xmit; | ||
1123 | struct scatterlist *sg = &s->sg_tx; | ||
1124 | |||
1125 | /* | ||
1126 | * DMA is idle now. | ||
1127 | * Port xmit buffer is already mapped, and it is one page... Just adjust | ||
1128 | * offsets and lengths. Since it is a circular buffer, we have to | ||
1129 | * transmit till the end, and then the rest. Take the port lock to get a | ||
1130 | * consistent xmit buffer state. | ||
1131 | */ | ||
1132 | spin_lock_irq(&port->lock); | ||
1133 | sg->offset = xmit->tail & (UART_XMIT_SIZE - 1); | ||
1134 | sg->dma_address = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) + | ||
1135 | sg->offset; | ||
1136 | sg->length = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE), | ||
1137 | CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE)); | ||
1138 | sg->dma_length = sg->length; | ||
1139 | spin_unlock_irq(&port->lock); | ||
1140 | |||
1141 | BUG_ON(!sg->length); | ||
1142 | |||
1143 | desc = chan->device->device_prep_slave_sg(chan, | ||
1144 | sg, s->sg_len_tx, DMA_TO_DEVICE, | ||
1145 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
1146 | if (!desc) { | ||
1147 | /* switch to PIO */ | ||
1148 | sci_tx_dma_release(s, true); | ||
1149 | return; | ||
1150 | } | ||
1151 | |||
1152 | dma_sync_sg_for_device(port->dev, sg, 1, DMA_TO_DEVICE); | ||
1153 | |||
1154 | spin_lock_irq(&port->lock); | ||
1155 | s->desc_tx = desc; | ||
1156 | desc->callback = sci_dma_tx_complete; | ||
1157 | desc->callback_param = s; | ||
1158 | spin_unlock_irq(&port->lock); | ||
1159 | s->cookie_tx = desc->tx_submit(desc); | ||
1160 | if (s->cookie_tx < 0) { | ||
1161 | dev_warn(port->dev, "Failed submitting Tx DMA descriptor\n"); | ||
1162 | /* switch to PIO */ | ||
1163 | sci_tx_dma_release(s, true); | ||
1164 | return; | ||
1165 | } | ||
1166 | |||
1167 | dev_dbg(port->dev, "%s: %p: %d...%d, cookie %d\n", __func__, | ||
1168 | xmit->buf, xmit->tail, xmit->head, s->cookie_tx); | ||
1169 | |||
1170 | dma_async_issue_pending(chan); | ||
1171 | } | ||
1172 | #endif | ||
1173 | |||
855 | static void sci_start_tx(struct uart_port *port) | 1174 | static void sci_start_tx(struct uart_port *port) |
856 | { | 1175 | { |
857 | unsigned short ctrl; | 1176 | unsigned short ctrl; |
858 | 1177 | ||
1178 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1179 | struct sci_port *s = to_sci_port(port); | ||
1180 | |||
1181 | if (s->chan_tx) { | ||
1182 | if (!uart_circ_empty(&s->port.state->xmit) && s->cookie_tx < 0) | ||
1183 | schedule_work(&s->work_tx); | ||
1184 | |||
1185 | return; | ||
1186 | } | ||
1187 | #endif | ||
1188 | |||
859 | /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ | 1189 | /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ |
860 | ctrl = sci_in(port, SCSCR); | 1190 | ctrl = sci_in(port, SCSCR); |
861 | ctrl |= SCI_CTRL_FLAGS_TIE; | 1191 | ctrl |= SCI_CTRL_FLAGS_TIE; |
@@ -872,13 +1202,12 @@ static void sci_stop_tx(struct uart_port *port) | |||
872 | sci_out(port, SCSCR, ctrl); | 1202 | sci_out(port, SCSCR, ctrl); |
873 | } | 1203 | } |
874 | 1204 | ||
875 | static void sci_start_rx(struct uart_port *port, unsigned int tty_start) | 1205 | static void sci_start_rx(struct uart_port *port) |
876 | { | 1206 | { |
877 | unsigned short ctrl; | 1207 | unsigned short ctrl = SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE; |
878 | 1208 | ||
879 | /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ | 1209 | /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ |
880 | ctrl = sci_in(port, SCSCR); | 1210 | ctrl |= sci_in(port, SCSCR); |
881 | ctrl |= SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE; | ||
882 | sci_out(port, SCSCR, ctrl); | 1211 | sci_out(port, SCSCR, ctrl); |
883 | } | 1212 | } |
884 | 1213 | ||
@@ -902,16 +1231,154 @@ static void sci_break_ctl(struct uart_port *port, int break_state) | |||
902 | /* Nothing here yet .. */ | 1231 | /* Nothing here yet .. */ |
903 | } | 1232 | } |
904 | 1233 | ||
1234 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1235 | static bool filter(struct dma_chan *chan, void *slave) | ||
1236 | { | ||
1237 | struct sh_dmae_slave *param = slave; | ||
1238 | |||
1239 | dev_dbg(chan->device->dev, "%s: slave ID %d\n", __func__, | ||
1240 | param->slave_id); | ||
1241 | |||
1242 | if (param->dma_dev == chan->device->dev) { | ||
1243 | chan->private = param; | ||
1244 | return true; | ||
1245 | } else { | ||
1246 | return false; | ||
1247 | } | ||
1248 | } | ||
1249 | |||
1250 | static void rx_timer_fn(unsigned long arg) | ||
1251 | { | ||
1252 | struct sci_port *s = (struct sci_port *)arg; | ||
1253 | struct uart_port *port = &s->port; | ||
1254 | |||
1255 | u16 scr = sci_in(port, SCSCR); | ||
1256 | sci_out(port, SCSCR, scr | SCI_CTRL_FLAGS_RIE); | ||
1257 | dev_dbg(port->dev, "DMA Rx timed out\n"); | ||
1258 | schedule_work(&s->work_rx); | ||
1259 | } | ||
1260 | |||
1261 | static void sci_request_dma(struct uart_port *port) | ||
1262 | { | ||
1263 | struct sci_port *s = to_sci_port(port); | ||
1264 | struct sh_dmae_slave *param; | ||
1265 | struct dma_chan *chan; | ||
1266 | dma_cap_mask_t mask; | ||
1267 | int nent; | ||
1268 | |||
1269 | dev_dbg(port->dev, "%s: port %d DMA %p\n", __func__, | ||
1270 | port->line, s->dma_dev); | ||
1271 | |||
1272 | if (!s->dma_dev) | ||
1273 | return; | ||
1274 | |||
1275 | dma_cap_zero(mask); | ||
1276 | dma_cap_set(DMA_SLAVE, mask); | ||
1277 | |||
1278 | param = &s->param_tx; | ||
1279 | |||
1280 | /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */ | ||
1281 | param->slave_id = s->slave_tx; | ||
1282 | param->dma_dev = s->dma_dev; | ||
1283 | |||
1284 | s->cookie_tx = -EINVAL; | ||
1285 | chan = dma_request_channel(mask, filter, param); | ||
1286 | dev_dbg(port->dev, "%s: TX: got channel %p\n", __func__, chan); | ||
1287 | if (chan) { | ||
1288 | s->chan_tx = chan; | ||
1289 | sg_init_table(&s->sg_tx, 1); | ||
1290 | /* UART circular tx buffer is an aligned page. */ | ||
1291 | BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK); | ||
1292 | sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf), | ||
1293 | UART_XMIT_SIZE, (int)port->state->xmit.buf & ~PAGE_MASK); | ||
1294 | nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE); | ||
1295 | if (!nent) | ||
1296 | sci_tx_dma_release(s, false); | ||
1297 | else | ||
1298 | dev_dbg(port->dev, "%s: mapped %d@%p to %x\n", __func__, | ||
1299 | sg_dma_len(&s->sg_tx), | ||
1300 | port->state->xmit.buf, sg_dma_address(&s->sg_tx)); | ||
1301 | |||
1302 | s->sg_len_tx = nent; | ||
1303 | |||
1304 | INIT_WORK(&s->work_tx, work_fn_tx); | ||
1305 | } | ||
1306 | |||
1307 | param = &s->param_rx; | ||
1308 | |||
1309 | /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */ | ||
1310 | param->slave_id = s->slave_rx; | ||
1311 | param->dma_dev = s->dma_dev; | ||
1312 | |||
1313 | chan = dma_request_channel(mask, filter, param); | ||
1314 | dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan); | ||
1315 | if (chan) { | ||
1316 | dma_addr_t dma[2]; | ||
1317 | void *buf[2]; | ||
1318 | int i; | ||
1319 | |||
1320 | s->chan_rx = chan; | ||
1321 | |||
1322 | s->buf_len_rx = 2 * max(16, (int)port->fifosize); | ||
1323 | buf[0] = dma_alloc_coherent(port->dev, s->buf_len_rx * 2, | ||
1324 | &dma[0], GFP_KERNEL); | ||
1325 | |||
1326 | if (!buf[0]) { | ||
1327 | dev_warn(port->dev, | ||
1328 | "failed to allocate dma buffer, using PIO\n"); | ||
1329 | sci_rx_dma_release(s, true); | ||
1330 | return; | ||
1331 | } | ||
1332 | |||
1333 | buf[1] = buf[0] + s->buf_len_rx; | ||
1334 | dma[1] = dma[0] + s->buf_len_rx; | ||
1335 | |||
1336 | for (i = 0; i < 2; i++) { | ||
1337 | struct scatterlist *sg = &s->sg_rx[i]; | ||
1338 | |||
1339 | sg_init_table(sg, 1); | ||
1340 | sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx, | ||
1341 | (int)buf[i] & ~PAGE_MASK); | ||
1342 | sg->dma_address = dma[i]; | ||
1343 | sg->dma_length = sg->length; | ||
1344 | } | ||
1345 | |||
1346 | INIT_WORK(&s->work_rx, work_fn_rx); | ||
1347 | setup_timer(&s->rx_timer, rx_timer_fn, (unsigned long)s); | ||
1348 | |||
1349 | sci_submit_rx(s); | ||
1350 | } | ||
1351 | } | ||
1352 | |||
1353 | static void sci_free_dma(struct uart_port *port) | ||
1354 | { | ||
1355 | struct sci_port *s = to_sci_port(port); | ||
1356 | |||
1357 | if (!s->dma_dev) | ||
1358 | return; | ||
1359 | |||
1360 | if (s->chan_tx) | ||
1361 | sci_tx_dma_release(s, false); | ||
1362 | if (s->chan_rx) | ||
1363 | sci_rx_dma_release(s, false); | ||
1364 | } | ||
1365 | #endif | ||
1366 | |||
905 | static int sci_startup(struct uart_port *port) | 1367 | static int sci_startup(struct uart_port *port) |
906 | { | 1368 | { |
907 | struct sci_port *s = to_sci_port(port); | 1369 | struct sci_port *s = to_sci_port(port); |
908 | 1370 | ||
1371 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | ||
1372 | |||
909 | if (s->enable) | 1373 | if (s->enable) |
910 | s->enable(port); | 1374 | s->enable(port); |
911 | 1375 | ||
912 | sci_request_irq(s); | 1376 | sci_request_irq(s); |
1377 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1378 | sci_request_dma(port); | ||
1379 | #endif | ||
913 | sci_start_tx(port); | 1380 | sci_start_tx(port); |
914 | sci_start_rx(port, 1); | 1381 | sci_start_rx(port); |
915 | 1382 | ||
916 | return 0; | 1383 | return 0; |
917 | } | 1384 | } |
@@ -920,8 +1387,13 @@ static void sci_shutdown(struct uart_port *port) | |||
920 | { | 1387 | { |
921 | struct sci_port *s = to_sci_port(port); | 1388 | struct sci_port *s = to_sci_port(port); |
922 | 1389 | ||
1390 | dev_dbg(port->dev, "%s(%d)\n", __func__, port->line); | ||
1391 | |||
923 | sci_stop_rx(port); | 1392 | sci_stop_rx(port); |
924 | sci_stop_tx(port); | 1393 | sci_stop_tx(port); |
1394 | #ifdef CONFIG_SERIAL_SH_SCI_DMA | ||
1395 | sci_free_dma(port); | ||
1396 | #endif | ||
925 | sci_free_irq(s); | 1397 | sci_free_irq(s); |
926 | 1398 | ||
927 | if (s->disable) | 1399 | if (s->disable) |
@@ -931,11 +1403,21 @@ static void sci_shutdown(struct uart_port *port) | |||
931 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | 1403 | static void sci_set_termios(struct uart_port *port, struct ktermios *termios, |
932 | struct ktermios *old) | 1404 | struct ktermios *old) |
933 | { | 1405 | { |
934 | unsigned int status, baud, smr_val; | 1406 | unsigned int status, baud, smr_val, max_baud; |
935 | int t = -1; | 1407 | int t = -1; |
936 | 1408 | ||
937 | baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); | 1409 | /* |
938 | if (likely(baud)) | 1410 | * earlyprintk comes here early on with port->uartclk set to zero. |
1411 | * the clock framework is not up and running at this point so here | ||
1412 | * we assume that 115200 is the maximum baud rate. please note that | ||
1413 | * the baud rate is not programmed during earlyprintk - it is assumed | ||
1414 | * that the previous boot loader has enabled required clocks and | ||
1415 | * setup the baud rate generator hardware for us already. | ||
1416 | */ | ||
1417 | max_baud = port->uartclk ? port->uartclk / 16 : 115200; | ||
1418 | |||
1419 | baud = uart_get_baud_rate(port, termios, old, 0, max_baud); | ||
1420 | if (likely(baud && port->uartclk)) | ||
939 | t = SCBRR_VALUE(baud, port->uartclk); | 1421 | t = SCBRR_VALUE(baud, port->uartclk); |
940 | 1422 | ||
941 | do { | 1423 | do { |
@@ -961,6 +1443,9 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
961 | 1443 | ||
962 | sci_out(port, SCSMR, smr_val); | 1444 | sci_out(port, SCSMR, smr_val); |
963 | 1445 | ||
1446 | dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t, | ||
1447 | SCSCR_INIT(port)); | ||
1448 | |||
964 | if (t > 0) { | 1449 | if (t > 0) { |
965 | if (t >= 256) { | 1450 | if (t >= 256) { |
966 | sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1); | 1451 | sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1); |
@@ -978,7 +1463,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, | |||
978 | sci_out(port, SCSCR, SCSCR_INIT(port)); | 1463 | sci_out(port, SCSCR, SCSCR_INIT(port)); |
979 | 1464 | ||
980 | if ((termios->c_cflag & CREAD) != 0) | 1465 | if ((termios->c_cflag & CREAD) != 0) |
981 | sci_start_rx(port, 0); | 1466 | sci_start_rx(port); |
982 | } | 1467 | } |
983 | 1468 | ||
984 | static const char *sci_type(struct uart_port *port) | 1469 | static const char *sci_type(struct uart_port *port) |
@@ -1073,40 +1558,53 @@ static void __devinit sci_init_single(struct platform_device *dev, | |||
1073 | unsigned int index, | 1558 | unsigned int index, |
1074 | struct plat_sci_port *p) | 1559 | struct plat_sci_port *p) |
1075 | { | 1560 | { |
1076 | sci_port->port.ops = &sci_uart_ops; | 1561 | struct uart_port *port = &sci_port->port; |
1077 | sci_port->port.iotype = UPIO_MEM; | ||
1078 | sci_port->port.line = index; | ||
1079 | sci_port->port.fifosize = 1; | ||
1080 | 1562 | ||
1081 | #if defined(__H8300H__) || defined(__H8300S__) | 1563 | port->ops = &sci_uart_ops; |
1082 | #ifdef __H8300S__ | 1564 | port->iotype = UPIO_MEM; |
1083 | sci_port->enable = h8300_sci_enable; | 1565 | port->line = index; |
1084 | sci_port->disable = h8300_sci_disable; | 1566 | |
1085 | #endif | 1567 | switch (p->type) { |
1086 | sci_port->port.uartclk = CONFIG_CPU_CLOCK; | 1568 | case PORT_SCIFA: |
1087 | #elif defined(CONFIG_HAVE_CLK) | 1569 | port->fifosize = 64; |
1088 | sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL; | 1570 | break; |
1089 | sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); | 1571 | case PORT_SCIF: |
1090 | sci_port->enable = sci_clk_enable; | 1572 | port->fifosize = 16; |
1091 | sci_port->disable = sci_clk_disable; | 1573 | break; |
1092 | #else | 1574 | default: |
1093 | #error "Need a valid uartclk" | 1575 | port->fifosize = 1; |
1094 | #endif | 1576 | break; |
1577 | } | ||
1578 | |||
1579 | if (dev) { | ||
1580 | sci_port->iclk = p->clk ? clk_get(&dev->dev, p->clk) : NULL; | ||
1581 | sci_port->dclk = clk_get(&dev->dev, "peripheral_clk"); | ||
1582 | sci_port->enable = sci_clk_enable; | ||
1583 | sci_port->disable = sci_clk_disable; | ||
1584 | port->dev = &dev->dev; | ||
1585 | } | ||
1095 | 1586 | ||
1096 | sci_port->break_timer.data = (unsigned long)sci_port; | 1587 | sci_port->break_timer.data = (unsigned long)sci_port; |
1097 | sci_port->break_timer.function = sci_break_timer; | 1588 | sci_port->break_timer.function = sci_break_timer; |
1098 | init_timer(&sci_port->break_timer); | 1589 | init_timer(&sci_port->break_timer); |
1099 | 1590 | ||
1100 | sci_port->port.mapbase = p->mapbase; | 1591 | port->mapbase = p->mapbase; |
1101 | sci_port->port.membase = p->membase; | 1592 | port->membase = p->membase; |
1102 | 1593 | ||
1103 | sci_port->port.irq = p->irqs[SCIx_TXI_IRQ]; | 1594 | port->irq = p->irqs[SCIx_TXI_IRQ]; |
1104 | sci_port->port.flags = p->flags; | 1595 | port->flags = p->flags; |
1105 | sci_port->port.dev = &dev->dev; | 1596 | sci_port->type = port->type = p->type; |
1106 | sci_port->type = sci_port->port.type = p->type; | ||
1107 | 1597 | ||
1108 | memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); | 1598 | #ifdef CONFIG_SERIAL_SH_SCI_DMA |
1599 | sci_port->dma_dev = p->dma_dev; | ||
1600 | sci_port->slave_tx = p->dma_slave_tx; | ||
1601 | sci_port->slave_rx = p->dma_slave_rx; | ||
1109 | 1602 | ||
1603 | dev_dbg(port->dev, "%s: DMA device %p, tx %d, rx %d\n", __func__, | ||
1604 | p->dma_dev, p->dma_slave_tx, p->dma_slave_rx); | ||
1605 | #endif | ||
1606 | |||
1607 | memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); | ||
1110 | } | 1608 | } |
1111 | 1609 | ||
1112 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | 1610 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE |
@@ -1147,7 +1645,7 @@ static void serial_console_write(struct console *co, const char *s, | |||
1147 | sci_port->disable(port); | 1645 | sci_port->disable(port); |
1148 | } | 1646 | } |
1149 | 1647 | ||
1150 | static int __init serial_console_setup(struct console *co, char *options) | 1648 | static int __devinit serial_console_setup(struct console *co, char *options) |
1151 | { | 1649 | { |
1152 | struct sci_port *sci_port; | 1650 | struct sci_port *sci_port; |
1153 | struct uart_port *port; | 1651 | struct uart_port *port; |
@@ -1165,9 +1663,14 @@ static int __init serial_console_setup(struct console *co, char *options) | |||
1165 | if (co->index >= SCI_NPORTS) | 1663 | if (co->index >= SCI_NPORTS) |
1166 | co->index = 0; | 1664 | co->index = 0; |
1167 | 1665 | ||
1168 | sci_port = &sci_ports[co->index]; | 1666 | if (co->data) { |
1169 | port = &sci_port->port; | 1667 | port = co->data; |
1170 | co->data = port; | 1668 | sci_port = to_sci_port(port); |
1669 | } else { | ||
1670 | sci_port = &sci_ports[co->index]; | ||
1671 | port = &sci_port->port; | ||
1672 | co->data = port; | ||
1673 | } | ||
1171 | 1674 | ||
1172 | /* | 1675 | /* |
1173 | * Also need to check port->type, we don't actually have any | 1676 | * Also need to check port->type, we don't actually have any |
@@ -1211,6 +1714,15 @@ static int __init sci_console_init(void) | |||
1211 | return 0; | 1714 | return 0; |
1212 | } | 1715 | } |
1213 | console_initcall(sci_console_init); | 1716 | console_initcall(sci_console_init); |
1717 | |||
1718 | static struct sci_port early_serial_port; | ||
1719 | static struct console early_serial_console = { | ||
1720 | .name = "early_ttySC", | ||
1721 | .write = serial_console_write, | ||
1722 | .flags = CON_PRINTBUFFER, | ||
1723 | }; | ||
1724 | static char early_serial_buf[32]; | ||
1725 | |||
1214 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ | 1726 | #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ |
1215 | 1727 | ||
1216 | #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) | 1728 | #if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) |
@@ -1239,14 +1751,11 @@ static int sci_remove(struct platform_device *dev) | |||
1239 | struct sci_port *p; | 1751 | struct sci_port *p; |
1240 | unsigned long flags; | 1752 | unsigned long flags; |
1241 | 1753 | ||
1242 | #ifdef CONFIG_HAVE_CLK | ||
1243 | cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); | 1754 | cpufreq_unregister_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); |
1244 | #endif | ||
1245 | 1755 | ||
1246 | spin_lock_irqsave(&priv->lock, flags); | 1756 | spin_lock_irqsave(&priv->lock, flags); |
1247 | list_for_each_entry(p, &priv->ports, node) | 1757 | list_for_each_entry(p, &priv->ports, node) |
1248 | uart_remove_one_port(&sci_uart_driver, &p->port); | 1758 | uart_remove_one_port(&sci_uart_driver, &p->port); |
1249 | |||
1250 | spin_unlock_irqrestore(&priv->lock, flags); | 1759 | spin_unlock_irqrestore(&priv->lock, flags); |
1251 | 1760 | ||
1252 | kfree(priv); | 1761 | kfree(priv); |
@@ -1299,6 +1808,21 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
1299 | struct sh_sci_priv *priv; | 1808 | struct sh_sci_priv *priv; |
1300 | int i, ret = -EINVAL; | 1809 | int i, ret = -EINVAL; |
1301 | 1810 | ||
1811 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | ||
1812 | if (is_early_platform_device(dev)) { | ||
1813 | if (dev->id == -1) | ||
1814 | return -ENOTSUPP; | ||
1815 | early_serial_console.index = dev->id; | ||
1816 | early_serial_console.data = &early_serial_port.port; | ||
1817 | sci_init_single(NULL, &early_serial_port, dev->id, p); | ||
1818 | serial_console_setup(&early_serial_console, early_serial_buf); | ||
1819 | if (!strstr(early_serial_buf, "keep")) | ||
1820 | early_serial_console.flags |= CON_BOOT; | ||
1821 | register_console(&early_serial_console); | ||
1822 | return 0; | ||
1823 | } | ||
1824 | #endif | ||
1825 | |||
1302 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 1826 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
1303 | if (!priv) | 1827 | if (!priv) |
1304 | return -ENOMEM; | 1828 | return -ENOMEM; |
@@ -1307,10 +1831,8 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
1307 | spin_lock_init(&priv->lock); | 1831 | spin_lock_init(&priv->lock); |
1308 | platform_set_drvdata(dev, priv); | 1832 | platform_set_drvdata(dev, priv); |
1309 | 1833 | ||
1310 | #ifdef CONFIG_HAVE_CLK | ||
1311 | priv->clk_nb.notifier_call = sci_notifier; | 1834 | priv->clk_nb.notifier_call = sci_notifier; |
1312 | cpufreq_register_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); | 1835 | cpufreq_register_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); |
1313 | #endif | ||
1314 | 1836 | ||
1315 | if (dev->id != -1) { | 1837 | if (dev->id != -1) { |
1316 | ret = sci_probe_single(dev, dev->id, p, &sci_ports[dev->id]); | 1838 | ret = sci_probe_single(dev, dev->id, p, &sci_ports[dev->id]); |
@@ -1363,14 +1885,14 @@ static int sci_resume(struct device *dev) | |||
1363 | return 0; | 1885 | return 0; |
1364 | } | 1886 | } |
1365 | 1887 | ||
1366 | static struct dev_pm_ops sci_dev_pm_ops = { | 1888 | static const struct dev_pm_ops sci_dev_pm_ops = { |
1367 | .suspend = sci_suspend, | 1889 | .suspend = sci_suspend, |
1368 | .resume = sci_resume, | 1890 | .resume = sci_resume, |
1369 | }; | 1891 | }; |
1370 | 1892 | ||
1371 | static struct platform_driver sci_driver = { | 1893 | static struct platform_driver sci_driver = { |
1372 | .probe = sci_probe, | 1894 | .probe = sci_probe, |
1373 | .remove = __devexit_p(sci_remove), | 1895 | .remove = sci_remove, |
1374 | .driver = { | 1896 | .driver = { |
1375 | .name = "sh-sci", | 1897 | .name = "sh-sci", |
1376 | .owner = THIS_MODULE, | 1898 | .owner = THIS_MODULE, |
@@ -1400,6 +1922,10 @@ static void __exit sci_exit(void) | |||
1400 | uart_unregister_driver(&sci_uart_driver); | 1922 | uart_unregister_driver(&sci_uart_driver); |
1401 | } | 1923 | } |
1402 | 1924 | ||
1925 | #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE | ||
1926 | early_platform_init_buffer("earlyprintk", &sci_driver, | ||
1927 | early_serial_buf, ARRAY_SIZE(early_serial_buf)); | ||
1928 | #endif | ||
1403 | module_init(sci_init); | 1929 | module_init(sci_init); |
1404 | module_exit(sci_exit); | 1930 | module_exit(sci_exit); |
1405 | 1931 | ||