blob: bb27885ea2e520135d44b389437d501e4c679987 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * SuperH on-chip serial module support. (SCI with no FIFO / with FIFO)
3 *
Paul Mundtf43dc232011-01-13 15:06:28 +09004 * Copyright (C) 2002 - 2011 Paul Mundt
Markus Brunner3ea6bc32007-08-20 08:59:33 +09005 * Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Jul 2007).
Linus Torvalds1da177e2005-04-16 15:20:36 -07006 *
7 * based off of the old drivers/char/sh-sci.c by:
8 *
9 * Copyright (C) 1999, 2000 Niibe Yutaka
10 * Copyright (C) 2000 Sugioka Toshinobu
11 * Modified to support multiple serial ports. Stuart Menefy (May 2000).
12 * Modified to support SecureEdge. David McCullough (2002)
13 * Modified to support SH7300 SCIF. Takashi Kusuda (Jun 2003).
Magnus Dammd89ddd12007-07-25 11:42:56 +090014 * Removed SH7300 support (Jul 2007).
Linus Torvalds1da177e2005-04-16 15:20:36 -070015 *
16 * This file is subject to the terms and conditions of the GNU General Public
17 * License. See the file "COPYING" in the main directory of this archive
18 * for more details.
19 */
Paul Mundt0b3d4ef2007-03-14 13:22:37 +090020#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
21#define SUPPORT_SYSRQ
22#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070023
24#undef DEBUG
25
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include <linux/module.h>
27#include <linux/errno.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/timer.h>
29#include <linux/interrupt.h>
30#include <linux/tty.h>
31#include <linux/tty_flip.h>
32#include <linux/serial.h>
33#include <linux/major.h>
34#include <linux/string.h>
35#include <linux/sysrq.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070036#include <linux/ioport.h>
37#include <linux/mm.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <linux/init.h>
39#include <linux/delay.h>
40#include <linux/console.h>
Paul Mundte108b2c2006-09-27 16:32:13 +090041#include <linux/platform_device.h>
Paul Mundt96de1a82008-02-26 14:52:45 +090042#include <linux/serial_sci.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <linux/notifier.h>
Magnus Damm5e50d2d2011-04-19 10:38:25 +000044#include <linux/pm_runtime.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070045#include <linux/cpufreq.h>
Paul Mundt85f094e2008-04-25 16:04:20 +090046#include <linux/clk.h>
Paul Mundtfa5da2f2007-03-08 17:27:37 +090047#include <linux/ctype.h>
Paul Mundt7ff731a2008-10-01 15:46:58 +090048#include <linux/err.h>
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +090049#include <linux/dmaengine.h>
50#include <linux/scatterlist.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090051#include <linux/slab.h>
Paul Mundt85f094e2008-04-25 16:04:20 +090052
53#ifdef CONFIG_SUPERH
Paul Mundte108b2c2006-09-27 16:32:13 +090054#include <asm/sh_bios.h>
Paul Mundtb7a76e42006-02-01 03:06:06 -080055#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070056
Linus Torvalds1da177e2005-04-16 15:20:36 -070057#include "sh-sci.h"
58
Paul Mundte108b2c2006-09-27 16:32:13 +090059struct sci_port {
60 struct uart_port port;
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
Paul Mundtce6738b2011-01-19 15:24:40 +090062 /* Platform configuration */
63 struct plat_sci_port *cfg;
Paul Mundte108b2c2006-09-27 16:32:13 +090064
Paul Mundte108b2c2006-09-27 16:32:13 +090065 /* Port enable callback */
66 void (*enable)(struct uart_port *port);
67
68 /* Port disable callback */
69 void (*disable)(struct uart_port *port);
70
71 /* Break timer */
72 struct timer_list break_timer;
73 int break_flag;
dmitry pervushin1534a3b2007-04-24 13:41:12 +090074
Magnus Damm501b8252009-01-21 15:14:30 +000075 /* Interface clock */
76 struct clk *iclk;
Paul Mundtc7ed1ab2010-03-10 18:35:14 +090077 /* Function clock */
78 struct clk *fclk;
Paul Mundtedad1f22009-11-25 16:23:35 +090079
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +090080 struct dma_chan *chan_tx;
81 struct dma_chan *chan_rx;
Paul Mundtf43dc232011-01-13 15:06:28 +090082
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +090083#ifdef CONFIG_SERIAL_SH_SCI_DMA
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +090084 struct dma_async_tx_descriptor *desc_tx;
85 struct dma_async_tx_descriptor *desc_rx[2];
86 dma_cookie_t cookie_tx;
87 dma_cookie_t cookie_rx[2];
88 dma_cookie_t active_rx;
89 struct scatterlist sg_tx;
90 unsigned int sg_len_tx;
91 struct scatterlist sg_rx[2];
92 size_t buf_len_rx;
93 struct sh_dmae_slave param_tx;
94 struct sh_dmae_slave param_rx;
95 struct work_struct work_tx;
96 struct work_struct work_rx;
97 struct timer_list rx_timer;
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +000098 unsigned int rx_timeout;
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +090099#endif
Magnus Damme552de22009-01-21 15:13:42 +0000100
Paul Mundtd535a232011-01-19 17:19:35 +0900101 struct notifier_block freq_transition;
Paul Mundte108b2c2006-09-27 16:32:13 +0900102};
103
Linus Torvalds1da177e2005-04-16 15:20:36 -0700104/* Function prototypes */
Paul Mundtd535a232011-01-19 17:19:35 +0900105static void sci_start_tx(struct uart_port *port);
Russell Kingb129a8c2005-08-31 10:12:14 +0100106static void sci_stop_tx(struct uart_port *port);
Paul Mundtd535a232011-01-19 17:19:35 +0900107static void sci_start_rx(struct uart_port *port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108
Paul Mundte108b2c2006-09-27 16:32:13 +0900109#define SCI_NPORTS CONFIG_SERIAL_SH_SCI_NR_UARTS
110
111static struct sci_port sci_ports[SCI_NPORTS];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112static struct uart_driver sci_uart_driver;
113
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900114static inline struct sci_port *
115to_sci_port(struct uart_port *uart)
116{
117 return container_of(uart, struct sci_port, port);
118}
119
Paul Mundt07d2a1a2008-12-11 19:06:43 +0900120#if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_SH_SCI_CONSOLE)
Paul Mundt1f6fd5c2008-12-17 14:53:24 +0900121
122#ifdef CONFIG_CONSOLE_POLL
Paul Mundt07d2a1a2008-12-11 19:06:43 +0900123static int sci_poll_get_char(struct uart_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 unsigned short status;
126 int c;
127
Paul Mundte108b2c2006-09-27 16:32:13 +0900128 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 status = sci_in(port, SCxSR);
130 if (status & SCxSR_ERRORS(port)) {
Paul Mundt94c8b6d2011-01-20 23:26:18 +0900131 sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 continue;
133 }
Jason Wessel3f255eb2010-05-20 21:04:23 -0500134 break;
135 } while (1);
136
137 if (!(status & SCxSR_RDxF(port)))
138 return NO_POLL_CHAR;
Paul Mundt07d2a1a2008-12-11 19:06:43 +0900139
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140 c = sci_in(port, SCxRDR);
Paul Mundt07d2a1a2008-12-11 19:06:43 +0900141
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900142 /* Dummy read */
143 sci_in(port, SCxSR);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145
146 return c;
147}
Paul Mundt1f6fd5c2008-12-17 14:53:24 +0900148#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149
Paul Mundt07d2a1a2008-12-11 19:06:43 +0900150static void sci_poll_put_char(struct uart_port *port, unsigned char c)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152 unsigned short status;
153
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154 do {
155 status = sci_in(port, SCxSR);
156 } while (!(status & SCxSR_TDxE(port)));
157
Paul Mundt272966c2008-11-13 17:46:06 +0900158 sci_out(port, SCxTDR, c);
SUGIOKA Toshinobudd0a3e72009-06-01 03:53:41 +0000159 sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160}
Paul Mundt07d2a1a2008-12-11 19:06:43 +0900161#endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700162
Paul Mundtab7cfb52011-06-01 14:47:42 +0900163#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
Paul Mundtd5701642008-12-16 20:07:27 +0900164static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
Paul Mundte108b2c2006-09-27 16:32:13 +0900165{
Paul Mundtd5701642008-12-16 20:07:27 +0900166 if (port->mapbase == 0xA4400000) {
167 __raw_writew(__raw_readw(PACR) & 0xffc0, PACR);
168 __raw_writew(__raw_readw(PBCR) & 0x0fff, PBCR);
169 } else if (port->mapbase == 0xA4410000)
170 __raw_writew(__raw_readw(PBCR) & 0xf003, PBCR);
Nobuhiro Iwamatsu9465a542007-03-27 18:13:51 +0900171}
Yoshihiro Shimoda31a49c42007-12-26 11:45:06 +0900172#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7721)
Paul Mundtd5701642008-12-16 20:07:27 +0900173static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
Markus Brunner3ea6bc32007-08-20 08:59:33 +0900174{
Markus Brunner3ea6bc32007-08-20 08:59:33 +0900175 unsigned short data;
176
177 if (cflag & CRTSCTS) {
178 /* enable RTS/CTS */
179 if (port->mapbase == 0xa4430000) { /* SCIF0 */
180 /* Clear PTCR bit 9-2; enable all scif pins but sck */
Paul Mundtd5701642008-12-16 20:07:27 +0900181 data = __raw_readw(PORT_PTCR);
182 __raw_writew((data & 0xfc03), PORT_PTCR);
Markus Brunner3ea6bc32007-08-20 08:59:33 +0900183 } else if (port->mapbase == 0xa4438000) { /* SCIF1 */
184 /* Clear PVCR bit 9-2 */
Paul Mundtd5701642008-12-16 20:07:27 +0900185 data = __raw_readw(PORT_PVCR);
186 __raw_writew((data & 0xfc03), PORT_PVCR);
Markus Brunner3ea6bc32007-08-20 08:59:33 +0900187 }
Markus Brunner3ea6bc32007-08-20 08:59:33 +0900188 } else {
189 if (port->mapbase == 0xa4430000) { /* SCIF0 */
190 /* Clear PTCR bit 5-2; enable only tx and rx */
Paul Mundtd5701642008-12-16 20:07:27 +0900191 data = __raw_readw(PORT_PTCR);
192 __raw_writew((data & 0xffc3), PORT_PTCR);
Markus Brunner3ea6bc32007-08-20 08:59:33 +0900193 } else if (port->mapbase == 0xa4438000) { /* SCIF1 */
194 /* Clear PVCR bit 5-2 */
Paul Mundtd5701642008-12-16 20:07:27 +0900195 data = __raw_readw(PORT_PVCR);
196 __raw_writew((data & 0xffc3), PORT_PVCR);
Markus Brunner3ea6bc32007-08-20 08:59:33 +0900197 }
198 }
Markus Brunner3ea6bc32007-08-20 08:59:33 +0900199}
Paul Mundtb7a76e42006-02-01 03:06:06 -0800200#elif defined(CONFIG_CPU_SH3)
Paul Mundte108b2c2006-09-27 16:32:13 +0900201/* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */
Paul Mundtd5701642008-12-16 20:07:27 +0900202static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203{
Paul Mundtb7a76e42006-02-01 03:06:06 -0800204 unsigned short data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205
Paul Mundtb7a76e42006-02-01 03:06:06 -0800206 /* We need to set SCPCR to enable RTS/CTS */
Paul Mundtd5701642008-12-16 20:07:27 +0900207 data = __raw_readw(SCPCR);
Paul Mundtb7a76e42006-02-01 03:06:06 -0800208 /* Clear out SCP7MD1,0, SCP6MD1,0, SCP4MD1,0*/
Paul Mundtd5701642008-12-16 20:07:27 +0900209 __raw_writew(data & 0x0fcf, SCPCR);
Paul Mundtb7a76e42006-02-01 03:06:06 -0800210
Paul Mundtd5701642008-12-16 20:07:27 +0900211 if (!(cflag & CRTSCTS)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700212 /* We need to set SCPCR to enable RTS/CTS */
Paul Mundtd5701642008-12-16 20:07:27 +0900213 data = __raw_readw(SCPCR);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214 /* Clear out SCP7MD1,0, SCP4MD1,0,
215 Set SCP6MD1,0 = {01} (output) */
Paul Mundtd5701642008-12-16 20:07:27 +0900216 __raw_writew((data & 0x0fcf) | 0x1000, SCPCR);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217
Paul Mundt32b53072009-12-24 14:52:43 +0900218 data = __raw_readb(SCPDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219 /* Set /RTS2 (bit6) = 0 */
Paul Mundt32b53072009-12-24 14:52:43 +0900220 __raw_writeb(data & 0xbf, SCPDR);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222}
Paul Mundt41504c32006-12-11 20:28:03 +0900223#elif defined(CONFIG_CPU_SUBTYPE_SH7722)
Paul Mundtd5701642008-12-16 20:07:27 +0900224static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
Paul Mundt41504c32006-12-11 20:28:03 +0900225{
Magnus Damm346b7462008-04-23 21:25:29 +0900226 unsigned short data;
Paul Mundt41504c32006-12-11 20:28:03 +0900227
Magnus Damm346b7462008-04-23 21:25:29 +0900228 if (port->mapbase == 0xffe00000) {
Paul Mundtd5701642008-12-16 20:07:27 +0900229 data = __raw_readw(PSCR);
Magnus Damm346b7462008-04-23 21:25:29 +0900230 data &= ~0x03cf;
Paul Mundtd5701642008-12-16 20:07:27 +0900231 if (!(cflag & CRTSCTS))
Magnus Damm346b7462008-04-23 21:25:29 +0900232 data |= 0x0340;
Paul Mundt41504c32006-12-11 20:28:03 +0900233
Paul Mundtd5701642008-12-16 20:07:27 +0900234 __raw_writew(data, PSCR);
Paul Mundt41504c32006-12-11 20:28:03 +0900235 }
Paul Mundt41504c32006-12-11 20:28:03 +0900236}
Yoshihiro Shimodac01f0f12009-08-21 16:30:28 +0900237#elif defined(CONFIG_CPU_SUBTYPE_SH7757) || \
238 defined(CONFIG_CPU_SUBTYPE_SH7763) || \
Yoshihiro Shimoda7d740a02008-01-07 14:40:07 +0900239 defined(CONFIG_CPU_SUBTYPE_SH7780) || \
Paul Mundt2b1bd1a2007-06-20 18:27:10 +0900240 defined(CONFIG_CPU_SUBTYPE_SH7785) || \
Kuninori Morimoto55ba99e2009-03-03 15:40:25 +0900241 defined(CONFIG_CPU_SUBTYPE_SH7786) || \
Paul Mundt2b1bd1a2007-06-20 18:27:10 +0900242 defined(CONFIG_CPU_SUBTYPE_SHX3)
Paul Mundtd5701642008-12-16 20:07:27 +0900243static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
244{
245 if (!(cflag & CRTSCTS))
246 __raw_writew(0x0080, SCSPTR0); /* Set RTS = 1 */
247}
Paul Mundtb0c50ad2008-12-22 03:40:10 +0900248#elif defined(CONFIG_CPU_SH4) && !defined(CONFIG_CPU_SH4A)
Paul Mundtd5701642008-12-16 20:07:27 +0900249static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
250{
251 if (!(cflag & CRTSCTS))
252 __raw_writew(0x0080, SCSPTR2); /* Set RTS = 1 */
253}
Paul Mundtb7a76e42006-02-01 03:06:06 -0800254#else
Paul Mundtd5701642008-12-16 20:07:27 +0900255static inline void sci_init_pins(struct uart_port *port, unsigned int cflag)
256{
257 /* Nothing to do */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258}
Paul Mundte108b2c2006-09-27 16:32:13 +0900259#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260
Paul Mundt32351a22007-03-12 14:38:59 +0900261#if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
262 defined(CONFIG_CPU_SUBTYPE_SH7780) || \
Kuninori Morimoto55ba99e2009-03-03 15:40:25 +0900263 defined(CONFIG_CPU_SUBTYPE_SH7785) || \
264 defined(CONFIG_CPU_SUBTYPE_SH7786)
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900265static int scif_txfill(struct uart_port *port)
Paul Mundte108b2c2006-09-27 16:32:13 +0900266{
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900267 return sci_in(port, SCTFDR) & 0xff;
Paul Mundte108b2c2006-09-27 16:32:13 +0900268}
269
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900270static int scif_txroom(struct uart_port *port)
271{
272 return SCIF_TXROOM_MAX - scif_txfill(port);
273}
274
275static int scif_rxfill(struct uart_port *port)
Paul Mundte108b2c2006-09-27 16:32:13 +0900276{
Yutaro Ebiharacae167d2008-03-11 13:58:50 +0900277 return sci_in(port, SCRFDR) & 0xff;
Paul Mundte108b2c2006-09-27 16:32:13 +0900278}
Nobuhiro Iwamatsuc63847a2008-06-06 17:04:08 +0900279#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900280static int scif_txfill(struct uart_port *port)
Nobuhiro Iwamatsuc63847a2008-06-06 17:04:08 +0900281{
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900282 if (port->mapbase == 0xffe00000 ||
283 port->mapbase == 0xffe08000)
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900284 /* SCIF0/1*/
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900285 return sci_in(port, SCTFDR) & 0xff;
286 else
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900287 /* SCIF2 */
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900288 return sci_in(port, SCFDR) >> 8;
Nobuhiro Iwamatsuc63847a2008-06-06 17:04:08 +0900289}
290
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900291static int scif_txroom(struct uart_port *port)
292{
293 if (port->mapbase == 0xffe00000 ||
294 port->mapbase == 0xffe08000)
295 /* SCIF0/1*/
296 return SCIF_TXROOM_MAX - scif_txfill(port);
297 else
298 /* SCIF2 */
299 return SCIF2_TXROOM_MAX - scif_txfill(port);
300}
301
302static int scif_rxfill(struct uart_port *port)
Nobuhiro Iwamatsuc63847a2008-06-06 17:04:08 +0900303{
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900304 if ((port->mapbase == 0xffe00000) ||
305 (port->mapbase == 0xffe08000)) {
306 /* SCIF0/1*/
Nobuhiro Iwamatsuc63847a2008-06-06 17:04:08 +0900307 return sci_in(port, SCRFDR) & 0xff;
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900308 } else {
309 /* SCIF2 */
Nobuhiro Iwamatsuc63847a2008-06-06 17:04:08 +0900310 return sci_in(port, SCFDR) & SCIF2_RFDC_MASK;
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900311 }
Nobuhiro Iwamatsuc63847a2008-06-06 17:04:08 +0900312}
Guennadi Liakhovetskid1d4b102010-05-23 16:39:09 +0000313#elif defined(CONFIG_ARCH_SH7372)
314static int scif_txfill(struct uart_port *port)
Paul Mundte108b2c2006-09-27 16:32:13 +0900315{
Guennadi Liakhovetskid1d4b102010-05-23 16:39:09 +0000316 if (port->type == PORT_SCIFA)
317 return sci_in(port, SCFDR) >> 8;
318 else
319 return sci_in(port, SCTFDR);
Paul Mundte108b2c2006-09-27 16:32:13 +0900320}
321
Guennadi Liakhovetskid1d4b102010-05-23 16:39:09 +0000322static int scif_txroom(struct uart_port *port)
323{
324 return port->fifosize - scif_txfill(port);
325}
326
327static int scif_rxfill(struct uart_port *port)
328{
329 if (port->type == PORT_SCIFA)
330 return sci_in(port, SCFDR) & SCIF_RFDC_MASK;
331 else
332 return sci_in(port, SCRFDR);
333}
Paul Mundte108b2c2006-09-27 16:32:13 +0900334#else
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900335static int scif_txfill(struct uart_port *port)
Paul Mundte108b2c2006-09-27 16:32:13 +0900336{
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900337 return sci_in(port, SCFDR) >> 8;
Paul Mundte108b2c2006-09-27 16:32:13 +0900338}
339
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900340static int scif_txroom(struct uart_port *port)
341{
342 return SCIF_TXROOM_MAX - scif_txfill(port);
343}
344
345static int scif_rxfill(struct uart_port *port)
Paul Mundte108b2c2006-09-27 16:32:13 +0900346{
347 return sci_in(port, SCFDR) & SCIF_RFDC_MASK;
348}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700350
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900351static int sci_txfill(struct uart_port *port)
Paul Mundte108b2c2006-09-27 16:32:13 +0900352{
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900353 return !(sci_in(port, SCxSR) & SCI_TDRE);
Paul Mundte108b2c2006-09-27 16:32:13 +0900354}
355
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900356static int sci_txroom(struct uart_port *port)
357{
358 return !sci_txfill(port);
359}
360
361static int sci_rxfill(struct uart_port *port)
Paul Mundte108b2c2006-09-27 16:32:13 +0900362{
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900363 return (sci_in(port, SCxSR) & SCxSR_RDxF(port)) != 0;
Paul Mundte108b2c2006-09-27 16:32:13 +0900364}
365
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366/* ********************************************************************** *
367 * the interrupt related routines *
368 * ********************************************************************** */
369
370static void sci_transmit_chars(struct uart_port *port)
371{
Alan Coxebd2c8f2009-09-19 13:13:28 -0700372 struct circ_buf *xmit = &port->state->xmit;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 unsigned int stopped = uart_tx_stopped(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 unsigned short status;
375 unsigned short ctrl;
Paul Mundte108b2c2006-09-27 16:32:13 +0900376 int count;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377
378 status = sci_in(port, SCxSR);
379 if (!(status & SCxSR_TDxE(port))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 ctrl = sci_in(port, SCSCR);
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900381 if (uart_circ_empty(xmit))
Paul Mundt8e698612009-06-24 19:44:32 +0900382 ctrl &= ~SCSCR_TIE;
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900383 else
Paul Mundt8e698612009-06-24 19:44:32 +0900384 ctrl |= SCSCR_TIE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385 sci_out(port, SCSCR, ctrl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 return;
387 }
388
Yoshihiro Shimoda1a22f082008-11-11 12:19:05 +0900389 if (port->type == PORT_SCI)
Paul Mundte108b2c2006-09-27 16:32:13 +0900390 count = sci_txroom(port);
Yoshihiro Shimoda1a22f082008-11-11 12:19:05 +0900391 else
392 count = scif_txroom(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393
394 do {
395 unsigned char c;
396
397 if (port->x_char) {
398 c = port->x_char;
399 port->x_char = 0;
400 } else if (!uart_circ_empty(xmit) && !stopped) {
401 c = xmit->buf[xmit->tail];
402 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
403 } else {
404 break;
405 }
406
407 sci_out(port, SCxTDR, c);
408
409 port->icount.tx++;
410 } while (--count > 0);
411
412 sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
413
414 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
415 uart_write_wakeup(port);
416 if (uart_circ_empty(xmit)) {
Russell Kingb129a8c2005-08-31 10:12:14 +0100417 sci_stop_tx(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 ctrl = sci_in(port, SCSCR);
420
Yoshihiro Shimoda1a22f082008-11-11 12:19:05 +0900421 if (port->type != PORT_SCI) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 sci_in(port, SCxSR); /* Dummy read */
423 sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port));
424 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425
Paul Mundt8e698612009-06-24 19:44:32 +0900426 ctrl |= SCSCR_TIE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 sci_out(port, SCSCR, ctrl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700428 }
429}
430
431/* On SH3, SCIF may read end-of-break as a space->mark char */
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900432#define STEPFN(c) ({int __c = (c); (((__c-1)|(__c)) == -1); })
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433
Paul Mundt94c8b6d2011-01-20 23:26:18 +0900434static void sci_receive_chars(struct uart_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435{
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900436 struct sci_port *sci_port = to_sci_port(port);
Alan Coxebd2c8f2009-09-19 13:13:28 -0700437 struct tty_struct *tty = port->state->port.tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 int i, count, copied = 0;
439 unsigned short status;
Alan Cox33f0f882006-01-09 20:54:13 -0800440 unsigned char flag;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441
442 status = sci_in(port, SCxSR);
443 if (!(status & SCxSR_RDxF(port)))
444 return;
445
446 while (1) {
Yoshihiro Shimoda1a22f082008-11-11 12:19:05 +0900447 if (port->type == PORT_SCI)
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900448 count = sci_rxfill(port);
Yoshihiro Shimoda1a22f082008-11-11 12:19:05 +0900449 else
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900450 count = scif_rxfill(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451
452 /* Don't copy more bytes than there is room for in the buffer */
Alan Cox33f0f882006-01-09 20:54:13 -0800453 count = tty_buffer_request_room(tty, count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454
455 /* If for any reason we can't copy more data, we're done! */
456 if (count == 0)
457 break;
458
459 if (port->type == PORT_SCI) {
460 char c = sci_in(port, SCxRDR);
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900461 if (uart_handle_sysrq_char(port, c) ||
462 sci_port->break_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463 count = 0;
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900464 else
Paul Mundte108b2c2006-09-27 16:32:13 +0900465 tty_insert_flip_char(tty, c, TTY_NORMAL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700466 } else {
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900467 for (i = 0; i < count; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468 char c = sci_in(port, SCxRDR);
469 status = sci_in(port, SCxSR);
470#if defined(CONFIG_CPU_SH3)
471 /* Skip "chars" during break */
Paul Mundte108b2c2006-09-27 16:32:13 +0900472 if (sci_port->break_flag) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 if ((c == 0) &&
474 (status & SCxSR_FER(port))) {
475 count--; i--;
476 continue;
477 }
Paul Mundte108b2c2006-09-27 16:32:13 +0900478
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 /* Nonzero => end-of-break */
Paul Mundt762c69e2008-12-16 18:55:26 +0900480 dev_dbg(port->dev, "debounce<%02x>\n", c);
Paul Mundte108b2c2006-09-27 16:32:13 +0900481 sci_port->break_flag = 0;
482
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483 if (STEPFN(c)) {
484 count--; i--;
485 continue;
486 }
487 }
488#endif /* CONFIG_CPU_SH3 */
David Howells7d12e782006-10-05 14:55:46 +0100489 if (uart_handle_sysrq_char(port, c)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490 count--; i--;
491 continue;
492 }
493
494 /* Store data and status */
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900495 if (status & SCxSR_FER(port)) {
Alan Cox33f0f882006-01-09 20:54:13 -0800496 flag = TTY_FRAME;
Paul Mundt762c69e2008-12-16 18:55:26 +0900497 dev_notice(port->dev, "frame error\n");
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900498 } else if (status & SCxSR_PER(port)) {
Alan Cox33f0f882006-01-09 20:54:13 -0800499 flag = TTY_PARITY;
Paul Mundt762c69e2008-12-16 18:55:26 +0900500 dev_notice(port->dev, "parity error\n");
Alan Cox33f0f882006-01-09 20:54:13 -0800501 } else
502 flag = TTY_NORMAL;
Paul Mundt762c69e2008-12-16 18:55:26 +0900503
Alan Cox33f0f882006-01-09 20:54:13 -0800504 tty_insert_flip_char(tty, c, flag);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 }
506 }
507
508 sci_in(port, SCxSR); /* dummy read */
509 sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
510
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 copied += count;
512 port->icount.rx += count;
513 }
514
515 if (copied) {
516 /* Tell the rest of the system the news. New characters! */
517 tty_flip_buffer_push(tty);
518 } else {
519 sci_in(port, SCxSR); /* dummy read */
520 sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
521 }
522}
523
524#define SCI_BREAK_JIFFIES (HZ/20)
Paul Mundt94c8b6d2011-01-20 23:26:18 +0900525
526/*
527 * The sci generates interrupts during the break,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528 * 1 per millisecond or so during the break period, for 9600 baud.
529 * So dont bother disabling interrupts.
530 * But dont want more than 1 break event.
531 * Use a kernel timer to periodically poll the rx line until
532 * the break is finished.
533 */
Paul Mundt94c8b6d2011-01-20 23:26:18 +0900534static inline void sci_schedule_break_timer(struct sci_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535{
Paul Mundtbc9b3f52011-01-20 23:30:19 +0900536 mod_timer(&port->break_timer, jiffies + SCI_BREAK_JIFFIES);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537}
Paul Mundt94c8b6d2011-01-20 23:26:18 +0900538
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539/* Ensure that two consecutive samples find the break over. */
540static void sci_break_timer(unsigned long data)
541{
Paul Mundte108b2c2006-09-27 16:32:13 +0900542 struct sci_port *port = (struct sci_port *)data;
543
Magnus Damm5e50d2d2011-04-19 10:38:25 +0000544 if (port->enable)
545 port->enable(&port->port);
546
Paul Mundte108b2c2006-09-27 16:32:13 +0900547 if (sci_rxd_in(&port->port) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548 port->break_flag = 1;
Paul Mundte108b2c2006-09-27 16:32:13 +0900549 sci_schedule_break_timer(port);
550 } else if (port->break_flag == 1) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 /* break is over. */
552 port->break_flag = 2;
Paul Mundte108b2c2006-09-27 16:32:13 +0900553 sci_schedule_break_timer(port);
554 } else
555 port->break_flag = 0;
Magnus Damm5e50d2d2011-04-19 10:38:25 +0000556
557 if (port->disable)
558 port->disable(&port->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559}
560
Paul Mundt94c8b6d2011-01-20 23:26:18 +0900561static int sci_handle_errors(struct uart_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562{
563 int copied = 0;
564 unsigned short status = sci_in(port, SCxSR);
Alan Coxebd2c8f2009-09-19 13:13:28 -0700565 struct tty_struct *tty = port->state->port.tty;
Paul Mundtdebf9502011-06-08 18:19:37 +0900566 struct sci_port *s = to_sci_port(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567
Paul Mundtdebf9502011-06-08 18:19:37 +0900568 /*
569 * Handle overruns, if supported.
570 */
571 if (s->cfg->overrun_bit != SCIx_NOT_SUPPORTED) {
572 if (status & (1 << s->cfg->overrun_bit)) {
573 /* overrun error */
574 if (tty_insert_flip_char(tty, 0, TTY_OVERRUN))
575 copied++;
Paul Mundt762c69e2008-12-16 18:55:26 +0900576
Paul Mundtdebf9502011-06-08 18:19:37 +0900577 dev_notice(port->dev, "overrun error");
578 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 }
580
Paul Mundte108b2c2006-09-27 16:32:13 +0900581 if (status & SCxSR_FER(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 if (sci_rxd_in(port) == 0) {
583 /* Notify of BREAK */
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900584 struct sci_port *sci_port = to_sci_port(port);
Paul Mundte108b2c2006-09-27 16:32:13 +0900585
586 if (!sci_port->break_flag) {
587 sci_port->break_flag = 1;
588 sci_schedule_break_timer(sci_port);
589
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590 /* Do sysrq handling. */
Paul Mundte108b2c2006-09-27 16:32:13 +0900591 if (uart_handle_break(port))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592 return 0;
Paul Mundt762c69e2008-12-16 18:55:26 +0900593
594 dev_dbg(port->dev, "BREAK detected\n");
595
Paul Mundte108b2c2006-09-27 16:32:13 +0900596 if (tty_insert_flip_char(tty, 0, TTY_BREAK))
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900597 copied++;
598 }
599
Paul Mundte108b2c2006-09-27 16:32:13 +0900600 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601 /* frame error */
Paul Mundte108b2c2006-09-27 16:32:13 +0900602 if (tty_insert_flip_char(tty, 0, TTY_FRAME))
Alan Cox33f0f882006-01-09 20:54:13 -0800603 copied++;
Paul Mundt762c69e2008-12-16 18:55:26 +0900604
605 dev_notice(port->dev, "frame error\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 }
607 }
608
Paul Mundte108b2c2006-09-27 16:32:13 +0900609 if (status & SCxSR_PER(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 /* parity error */
Paul Mundte108b2c2006-09-27 16:32:13 +0900611 if (tty_insert_flip_char(tty, 0, TTY_PARITY))
612 copied++;
Paul Mundt762c69e2008-12-16 18:55:26 +0900613
614 dev_notice(port->dev, "parity error");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 }
616
Alan Cox33f0f882006-01-09 20:54:13 -0800617 if (copied)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 tty_flip_buffer_push(tty);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619
620 return copied;
621}
622
Paul Mundt94c8b6d2011-01-20 23:26:18 +0900623static int sci_handle_fifo_overrun(struct uart_port *port)
Paul Mundtd830fa42008-12-16 19:29:38 +0900624{
Alan Coxebd2c8f2009-09-19 13:13:28 -0700625 struct tty_struct *tty = port->state->port.tty;
Paul Mundtdebf9502011-06-08 18:19:37 +0900626 struct sci_port *s = to_sci_port(port);
Paul Mundtd830fa42008-12-16 19:29:38 +0900627 int copied = 0;
628
Paul Mundtdebf9502011-06-08 18:19:37 +0900629 /*
630 * XXX: Technically not limited to non-SCIFs, it's simply the
631 * SCLSR check that is for the moment SCIF-specific. This
632 * probably wants to be revisited for SCIFA/B as well as for
633 * factoring in SCI overrun detection.
634 */
Paul Mundtd830fa42008-12-16 19:29:38 +0900635 if (port->type != PORT_SCIF)
636 return 0;
637
Paul Mundtdebf9502011-06-08 18:19:37 +0900638 if ((sci_in(port, SCLSR) & (1 << s->cfg->overrun_bit))) {
Paul Mundtd830fa42008-12-16 19:29:38 +0900639 sci_out(port, SCLSR, 0);
640
641 tty_insert_flip_char(tty, 0, TTY_OVERRUN);
642 tty_flip_buffer_push(tty);
643
644 dev_notice(port->dev, "overrun error\n");
645 copied++;
646 }
647
648 return copied;
649}
650
Paul Mundt94c8b6d2011-01-20 23:26:18 +0900651static int sci_handle_breaks(struct uart_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652{
653 int copied = 0;
654 unsigned short status = sci_in(port, SCxSR);
Alan Coxebd2c8f2009-09-19 13:13:28 -0700655 struct tty_struct *tty = port->state->port.tty;
Magnus Damma5660ad2009-01-21 15:14:38 +0000656 struct sci_port *s = to_sci_port(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657
Paul Mundt0b3d4ef2007-03-14 13:22:37 +0900658 if (uart_handle_break(port))
659 return 0;
660
Paul Mundtb7a76e42006-02-01 03:06:06 -0800661 if (!s->break_flag && status & SCxSR_BRK(port)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662#if defined(CONFIG_CPU_SH3)
663 /* Debounce break */
664 s->break_flag = 1;
665#endif
666 /* Notify of BREAK */
Paul Mundte108b2c2006-09-27 16:32:13 +0900667 if (tty_insert_flip_char(tty, 0, TTY_BREAK))
Alan Cox33f0f882006-01-09 20:54:13 -0800668 copied++;
Paul Mundt762c69e2008-12-16 18:55:26 +0900669
670 dev_dbg(port->dev, "BREAK detected\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671 }
672
Alan Cox33f0f882006-01-09 20:54:13 -0800673 if (copied)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700674 tty_flip_buffer_push(tty);
Paul Mundte108b2c2006-09-27 16:32:13 +0900675
Paul Mundtd830fa42008-12-16 19:29:38 +0900676 copied += sci_handle_fifo_overrun(port);
677
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 return copied;
679}
680
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900681static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682{
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900683#ifdef CONFIG_SERIAL_SH_SCI_DMA
684 struct uart_port *port = ptr;
685 struct sci_port *s = to_sci_port(port);
686
687 if (s->chan_rx) {
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900688 u16 scr = sci_in(port, SCSCR);
689 u16 ssr = sci_in(port, SCxSR);
690
691 /* Disable future Rx interrupts */
Guennadi Liakhovetskid1d4b102010-05-23 16:39:09 +0000692 if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +0000693 disable_irq_nosync(irq);
694 scr |= 0x4000;
695 } else {
Paul Mundtf43dc232011-01-13 15:06:28 +0900696 scr &= ~SCSCR_RIE;
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +0000697 }
698 sci_out(port, SCSCR, scr);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900699 /* Clear current interrupt */
700 sci_out(port, SCxSR, ssr & ~(1 | SCxSR_RDxF(port)));
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +0000701 dev_dbg(port->dev, "Rx IRQ %lu: setup t-out in %u jiffies\n",
702 jiffies, s->rx_timeout);
703 mod_timer(&s->rx_timer, jiffies + s->rx_timeout);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900704
705 return IRQ_HANDLED;
706 }
707#endif
708
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 /* I think sci_receive_chars has to be called irrespective
710 * of whether the I_IXOFF is set, otherwise, how is the interrupt
711 * to be disabled?
712 */
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900713 sci_receive_chars(ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714
715 return IRQ_HANDLED;
716}
717
David Howells7d12e782006-10-05 14:55:46 +0100718static irqreturn_t sci_tx_interrupt(int irq, void *ptr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719{
720 struct uart_port *port = ptr;
Stuart Menefyfd78a762009-07-29 23:01:24 +0900721 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722
Stuart Menefyfd78a762009-07-29 23:01:24 +0900723 spin_lock_irqsave(&port->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 sci_transmit_chars(port);
Stuart Menefyfd78a762009-07-29 23:01:24 +0900725 spin_unlock_irqrestore(&port->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726
727 return IRQ_HANDLED;
728}
729
David Howells7d12e782006-10-05 14:55:46 +0100730static irqreturn_t sci_er_interrupt(int irq, void *ptr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731{
732 struct uart_port *port = ptr;
733
734 /* Handle errors */
735 if (port->type == PORT_SCI) {
736 if (sci_handle_errors(port)) {
737 /* discard character in rx buffer */
738 sci_in(port, SCxSR);
739 sci_out(port, SCxSR, SCxSR_RDxF_CLEAR(port));
740 }
741 } else {
Paul Mundtd830fa42008-12-16 19:29:38 +0900742 sci_handle_fifo_overrun(port);
David Howells7d12e782006-10-05 14:55:46 +0100743 sci_rx_interrupt(irq, ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744 }
745
746 sci_out(port, SCxSR, SCxSR_ERROR_CLEAR(port));
747
748 /* Kick the transmission */
David Howells7d12e782006-10-05 14:55:46 +0100749 sci_tx_interrupt(irq, ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750
751 return IRQ_HANDLED;
752}
753
David Howells7d12e782006-10-05 14:55:46 +0100754static irqreturn_t sci_br_interrupt(int irq, void *ptr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700755{
756 struct uart_port *port = ptr;
757
758 /* Handle BREAKs */
759 sci_handle_breaks(port);
760 sci_out(port, SCxSR, SCxSR_BREAK_CLEAR(port));
761
762 return IRQ_HANDLED;
763}
764
Paul Mundtf43dc232011-01-13 15:06:28 +0900765static inline unsigned long port_rx_irq_mask(struct uart_port *port)
766{
767 /*
768 * Not all ports (such as SCIFA) will support REIE. Rather than
769 * special-casing the port type, we check the port initialization
770 * IRQ enable mask to see whether the IRQ is desired at all. If
771 * it's unset, it's logically inferred that there's no point in
772 * testing for it.
773 */
Paul Mundtce6738b2011-01-19 15:24:40 +0900774 return SCSCR_RIE | (to_sci_port(port)->cfg->scscr & SCSCR_REIE);
Paul Mundtf43dc232011-01-13 15:06:28 +0900775}
776
David Howells7d12e782006-10-05 14:55:46 +0100777static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778{
Magnus Damm44e18e92009-07-03 08:39:34 +0000779 unsigned short ssr_status, scr_status, err_enabled;
Michael Trimarchia8884e32008-10-31 16:10:23 +0900780 struct uart_port *port = ptr;
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900781 struct sci_port *s = to_sci_port(port);
Michael Trimarchia8884e32008-10-31 16:10:23 +0900782 irqreturn_t ret = IRQ_NONE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783
Michael Trimarchie7c98dc2008-11-13 18:18:35 +0900784 ssr_status = sci_in(port, SCxSR);
785 scr_status = sci_in(port, SCSCR);
Paul Mundtf43dc232011-01-13 15:06:28 +0900786 err_enabled = scr_status & port_rx_irq_mask(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787
788 /* Tx Interrupt */
Paul Mundtf43dc232011-01-13 15:06:28 +0900789 if ((ssr_status & SCxSR_TDxE(port)) && (scr_status & SCSCR_TIE) &&
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900790 !s->chan_tx)
Michael Trimarchia8884e32008-10-31 16:10:23 +0900791 ret = sci_tx_interrupt(irq, ptr);
Paul Mundtf43dc232011-01-13 15:06:28 +0900792
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900793 /*
794 * Rx Interrupt: if we're using DMA, the DMA controller clears RDF /
795 * DR flags
796 */
797 if (((ssr_status & SCxSR_RDxF(port)) || s->chan_rx) &&
Paul Mundtf43dc232011-01-13 15:06:28 +0900798 (scr_status & SCSCR_RIE))
Michael Trimarchia8884e32008-10-31 16:10:23 +0900799 ret = sci_rx_interrupt(irq, ptr);
Paul Mundtf43dc232011-01-13 15:06:28 +0900800
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801 /* Error Interrupt */
SUGIOKA Toshinobudd4da3a2009-07-07 05:32:07 +0000802 if ((ssr_status & SCxSR_ERRORS(port)) && err_enabled)
Michael Trimarchia8884e32008-10-31 16:10:23 +0900803 ret = sci_er_interrupt(irq, ptr);
Paul Mundtf43dc232011-01-13 15:06:28 +0900804
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 /* Break Interrupt */
SUGIOKA Toshinobudd4da3a2009-07-07 05:32:07 +0000806 if ((ssr_status & SCxSR_BRK(port)) && err_enabled)
Michael Trimarchia8884e32008-10-31 16:10:23 +0900807 ret = sci_br_interrupt(irq, ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808
Michael Trimarchia8884e32008-10-31 16:10:23 +0900809 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810}
811
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812/*
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300813 * Here we define a transition notifier so that we can update all of our
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 * ports' baud rate when the peripheral clock changes.
815 */
Paul Mundte108b2c2006-09-27 16:32:13 +0900816static int sci_notifier(struct notifier_block *self,
817 unsigned long phase, void *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818{
Magnus Damme552de22009-01-21 15:13:42 +0000819 struct sci_port *sci_port;
820 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821
Paul Mundtd535a232011-01-19 17:19:35 +0900822 sci_port = container_of(self, struct sci_port, freq_transition);
823
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 if ((phase == CPUFREQ_POSTCHANGE) ||
Magnus Damme552de22009-01-21 15:13:42 +0000825 (phase == CPUFREQ_RESUMECHANGE)) {
Paul Mundtd535a232011-01-19 17:19:35 +0900826 struct uart_port *port = &sci_port->port;
Paul Mundt073e84c2011-01-19 17:30:53 +0900827
Paul Mundtd535a232011-01-19 17:19:35 +0900828 spin_lock_irqsave(&port->lock, flags);
829 port->uartclk = clk_get_rate(sci_port->iclk);
830 spin_unlock_irqrestore(&port->lock, flags);
Magnus Damme552de22009-01-21 15:13:42 +0000831 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833 return NOTIFY_OK;
834}
Magnus Damm501b8252009-01-21 15:14:30 +0000835
836static void sci_clk_enable(struct uart_port *port)
837{
838 struct sci_port *sci_port = to_sci_port(port);
839
Magnus Damm5e50d2d2011-04-19 10:38:25 +0000840 pm_runtime_get_sync(port->dev);
841
Paul Mundtc7ed1ab2010-03-10 18:35:14 +0900842 clk_enable(sci_port->iclk);
843 sci_port->port.uartclk = clk_get_rate(sci_port->iclk);
844 clk_enable(sci_port->fclk);
Magnus Damm501b8252009-01-21 15:14:30 +0000845}
846
847static void sci_clk_disable(struct uart_port *port)
848{
849 struct sci_port *sci_port = to_sci_port(port);
850
Paul Mundtc7ed1ab2010-03-10 18:35:14 +0900851 clk_disable(sci_port->fclk);
852 clk_disable(sci_port->iclk);
Magnus Damm5e50d2d2011-04-19 10:38:25 +0000853
854 pm_runtime_put_sync(port->dev);
Magnus Damm501b8252009-01-21 15:14:30 +0000855}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856
857static int sci_request_irq(struct sci_port *port)
858{
859 int i;
David Howells7d12e782006-10-05 14:55:46 +0100860 irqreturn_t (*handlers[4])(int irq, void *ptr) = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861 sci_er_interrupt, sci_rx_interrupt, sci_tx_interrupt,
862 sci_br_interrupt,
863 };
864 const char *desc[] = { "SCI Receive Error", "SCI Receive Data Full",
865 "SCI Transmit Data Empty", "SCI Break" };
866
Paul Mundtce6738b2011-01-19 15:24:40 +0900867 if (port->cfg->irqs[0] == port->cfg->irqs[1]) {
868 if (unlikely(!port->cfg->irqs[0]))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 return -ENODEV;
Paul Mundte108b2c2006-09-27 16:32:13 +0900870
Paul Mundtce6738b2011-01-19 15:24:40 +0900871 if (request_irq(port->cfg->irqs[0], sci_mpxed_interrupt,
Paul Mundt35f3c512006-10-06 15:31:16 +0900872 IRQF_DISABLED, "sci", port)) {
Paul Mundt762c69e2008-12-16 18:55:26 +0900873 dev_err(port->port.dev, "Can't allocate IRQ\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 return -ENODEV;
875 }
876 } else {
877 for (i = 0; i < ARRAY_SIZE(handlers); i++) {
Paul Mundtce6738b2011-01-19 15:24:40 +0900878 if (unlikely(!port->cfg->irqs[i]))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879 continue;
Paul Mundt762c69e2008-12-16 18:55:26 +0900880
Paul Mundtce6738b2011-01-19 15:24:40 +0900881 if (request_irq(port->cfg->irqs[i], handlers[i],
Paul Mundt35f3c512006-10-06 15:31:16 +0900882 IRQF_DISABLED, desc[i], port)) {
Paul Mundt762c69e2008-12-16 18:55:26 +0900883 dev_err(port->port.dev, "Can't allocate IRQ\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 return -ENODEV;
885 }
886 }
887 }
888
889 return 0;
890}
891
892static void sci_free_irq(struct sci_port *port)
893{
894 int i;
895
Paul Mundtce6738b2011-01-19 15:24:40 +0900896 if (port->cfg->irqs[0] == port->cfg->irqs[1])
897 free_irq(port->cfg->irqs[0], port);
Paul Mundt762c69e2008-12-16 18:55:26 +0900898 else {
Paul Mundtce6738b2011-01-19 15:24:40 +0900899 for (i = 0; i < ARRAY_SIZE(port->cfg->irqs); i++) {
900 if (!port->cfg->irqs[i])
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901 continue;
902
Paul Mundtce6738b2011-01-19 15:24:40 +0900903 free_irq(port->cfg->irqs[i], port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904 }
905 }
906}
907
908static unsigned int sci_tx_empty(struct uart_port *port)
909{
Guennadi Liakhovetskib1516802009-12-01 09:54:46 +0000910 unsigned short status = sci_in(port, SCxSR);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900911 unsigned short in_tx_fifo = scif_txfill(port);
912
913 return (status & SCxSR_TEND(port)) && !in_tx_fifo ? TIOCSER_TEMT : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700914}
915
916static void sci_set_mctrl(struct uart_port *port, unsigned int mctrl)
917{
918 /* This routine is used for seting signals of: DTR, DCD, CTS/RTS */
919 /* We use SCIF's hardware for CTS/RTS, so don't need any for that. */
920 /* If you have signals for DTR and DCD, please implement here. */
921}
922
923static unsigned int sci_get_mctrl(struct uart_port *port)
924{
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900925 /* This routine is used for getting signals of: DTR, DCD, DSR, RI,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 and CTS/RTS */
927
928 return TIOCM_DTR | TIOCM_RTS | TIOCM_DSR;
929}
930
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900931#ifdef CONFIG_SERIAL_SH_SCI_DMA
932static void sci_dma_tx_complete(void *arg)
933{
934 struct sci_port *s = arg;
935 struct uart_port *port = &s->port;
936 struct circ_buf *xmit = &port->state->xmit;
937 unsigned long flags;
938
939 dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
940
941 spin_lock_irqsave(&port->lock, flags);
942
Magnus Dammf354a382010-03-19 04:47:01 +0000943 xmit->tail += sg_dma_len(&s->sg_tx);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900944 xmit->tail &= UART_XMIT_SIZE - 1;
945
Magnus Dammf354a382010-03-19 04:47:01 +0000946 port->icount.tx += sg_dma_len(&s->sg_tx);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900947
948 async_tx_ack(s->desc_tx);
949 s->cookie_tx = -EINVAL;
950 s->desc_tx = NULL;
951
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900952 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
953 uart_write_wakeup(port);
954
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +0000955 if (!uart_circ_empty(xmit)) {
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900956 schedule_work(&s->work_tx);
Guennadi Liakhovetskid1d4b102010-05-23 16:39:09 +0000957 } else if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +0000958 u16 ctrl = sci_in(port, SCSCR);
Paul Mundtf43dc232011-01-13 15:06:28 +0900959 sci_out(port, SCSCR, ctrl & ~SCSCR_TIE);
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +0000960 }
961
962 spin_unlock_irqrestore(&port->lock, flags);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +0900963}
964
965/* Locking: called with port lock held */
966static int sci_dma_rx_push(struct sci_port *s, struct tty_struct *tty,
967 size_t count)
968{
969 struct uart_port *port = &s->port;
970 int i, active, room;
971
972 room = tty_buffer_request_room(tty, count);
973
974 if (s->active_rx == s->cookie_rx[0]) {
975 active = 0;
976 } else if (s->active_rx == s->cookie_rx[1]) {
977 active = 1;
978 } else {
979 dev_err(port->dev, "cookie %d not found!\n", s->active_rx);
980 return 0;
981 }
982
983 if (room < count)
984 dev_warn(port->dev, "Rx overrun: dropping %u bytes\n",
985 count - room);
986 if (!room)
987 return room;
988
989 for (i = 0; i < room; i++)
990 tty_insert_flip_char(tty, ((u8 *)sg_virt(&s->sg_rx[active]))[i],
991 TTY_NORMAL);
992
993 port->icount.rx += room;
994
995 return room;
996}
997
998static void sci_dma_rx_complete(void *arg)
999{
1000 struct sci_port *s = arg;
1001 struct uart_port *port = &s->port;
1002 struct tty_struct *tty = port->state->port.tty;
1003 unsigned long flags;
1004 int count;
1005
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001006 dev_dbg(port->dev, "%s(%d) active #%d\n", __func__, port->line, s->active_rx);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001007
1008 spin_lock_irqsave(&port->lock, flags);
1009
1010 count = sci_dma_rx_push(s, tty, s->buf_len_rx);
1011
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001012 mod_timer(&s->rx_timer, jiffies + s->rx_timeout);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001013
1014 spin_unlock_irqrestore(&port->lock, flags);
1015
1016 if (count)
1017 tty_flip_buffer_push(tty);
1018
1019 schedule_work(&s->work_rx);
1020}
1021
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001022static void sci_rx_dma_release(struct sci_port *s, bool enable_pio)
1023{
1024 struct dma_chan *chan = s->chan_rx;
1025 struct uart_port *port = &s->port;
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001026
1027 s->chan_rx = NULL;
1028 s->cookie_rx[0] = s->cookie_rx[1] = -EINVAL;
1029 dma_release_channel(chan);
Guennadi Liakhovetski85b8e3f2010-05-21 15:22:40 +00001030 if (sg_dma_address(&s->sg_rx[0]))
1031 dma_free_coherent(port->dev, s->buf_len_rx * 2,
1032 sg_virt(&s->sg_rx[0]), sg_dma_address(&s->sg_rx[0]));
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001033 if (enable_pio)
1034 sci_start_rx(port);
1035}
1036
1037static void sci_tx_dma_release(struct sci_port *s, bool enable_pio)
1038{
1039 struct dma_chan *chan = s->chan_tx;
1040 struct uart_port *port = &s->port;
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001041
1042 s->chan_tx = NULL;
1043 s->cookie_tx = -EINVAL;
1044 dma_release_channel(chan);
1045 if (enable_pio)
1046 sci_start_tx(port);
1047}
1048
1049static void sci_submit_rx(struct sci_port *s)
1050{
1051 struct dma_chan *chan = s->chan_rx;
1052 int i;
1053
1054 for (i = 0; i < 2; i++) {
1055 struct scatterlist *sg = &s->sg_rx[i];
1056 struct dma_async_tx_descriptor *desc;
1057
1058 desc = chan->device->device_prep_slave_sg(chan,
1059 sg, 1, DMA_FROM_DEVICE, DMA_PREP_INTERRUPT);
1060
1061 if (desc) {
1062 s->desc_rx[i] = desc;
1063 desc->callback = sci_dma_rx_complete;
1064 desc->callback_param = s;
1065 s->cookie_rx[i] = desc->tx_submit(desc);
1066 }
1067
1068 if (!desc || s->cookie_rx[i] < 0) {
1069 if (i) {
1070 async_tx_ack(s->desc_rx[0]);
1071 s->cookie_rx[0] = -EINVAL;
1072 }
1073 if (desc) {
1074 async_tx_ack(desc);
1075 s->cookie_rx[i] = -EINVAL;
1076 }
1077 dev_warn(s->port.dev,
1078 "failed to re-start DMA, using PIO\n");
1079 sci_rx_dma_release(s, true);
1080 return;
1081 }
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001082 dev_dbg(s->port.dev, "%s(): cookie %d to #%d\n", __func__,
1083 s->cookie_rx[i], i);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001084 }
1085
1086 s->active_rx = s->cookie_rx[0];
1087
1088 dma_async_issue_pending(chan);
1089}
1090
1091static void work_fn_rx(struct work_struct *work)
1092{
1093 struct sci_port *s = container_of(work, struct sci_port, work_rx);
1094 struct uart_port *port = &s->port;
1095 struct dma_async_tx_descriptor *desc;
1096 int new;
1097
1098 if (s->active_rx == s->cookie_rx[0]) {
1099 new = 0;
1100 } else if (s->active_rx == s->cookie_rx[1]) {
1101 new = 1;
1102 } else {
1103 dev_err(port->dev, "cookie %d not found!\n", s->active_rx);
1104 return;
1105 }
1106 desc = s->desc_rx[new];
1107
1108 if (dma_async_is_tx_complete(s->chan_rx, s->active_rx, NULL, NULL) !=
1109 DMA_SUCCESS) {
1110 /* Handle incomplete DMA receive */
1111 struct tty_struct *tty = port->state->port.tty;
1112 struct dma_chan *chan = s->chan_rx;
1113 struct sh_desc *sh_desc = container_of(desc, struct sh_desc,
1114 async_tx);
1115 unsigned long flags;
1116 int count;
1117
Linus Walleij05827632010-05-17 16:30:42 -07001118 chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001119 dev_dbg(port->dev, "Read %u bytes with cookie %d\n",
1120 sh_desc->partial, sh_desc->cookie);
1121
1122 spin_lock_irqsave(&port->lock, flags);
1123 count = sci_dma_rx_push(s, tty, sh_desc->partial);
1124 spin_unlock_irqrestore(&port->lock, flags);
1125
1126 if (count)
1127 tty_flip_buffer_push(tty);
1128
1129 sci_submit_rx(s);
1130
1131 return;
1132 }
1133
1134 s->cookie_rx[new] = desc->tx_submit(desc);
1135 if (s->cookie_rx[new] < 0) {
1136 dev_warn(port->dev, "Failed submitting Rx DMA descriptor\n");
1137 sci_rx_dma_release(s, true);
1138 return;
1139 }
1140
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001141 s->active_rx = s->cookie_rx[!new];
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001142
1143 dev_dbg(port->dev, "%s: cookie %d #%d, new active #%d\n", __func__,
1144 s->cookie_rx[new], new, s->active_rx);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001145}
1146
1147static void work_fn_tx(struct work_struct *work)
1148{
1149 struct sci_port *s = container_of(work, struct sci_port, work_tx);
1150 struct dma_async_tx_descriptor *desc;
1151 struct dma_chan *chan = s->chan_tx;
1152 struct uart_port *port = &s->port;
1153 struct circ_buf *xmit = &port->state->xmit;
1154 struct scatterlist *sg = &s->sg_tx;
1155
1156 /*
1157 * DMA is idle now.
1158 * Port xmit buffer is already mapped, and it is one page... Just adjust
1159 * offsets and lengths. Since it is a circular buffer, we have to
1160 * transmit till the end, and then the rest. Take the port lock to get a
1161 * consistent xmit buffer state.
1162 */
1163 spin_lock_irq(&port->lock);
1164 sg->offset = xmit->tail & (UART_XMIT_SIZE - 1);
Magnus Dammf354a382010-03-19 04:47:01 +00001165 sg_dma_address(sg) = (sg_dma_address(sg) & ~(UART_XMIT_SIZE - 1)) +
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001166 sg->offset;
Magnus Dammf354a382010-03-19 04:47:01 +00001167 sg_dma_len(sg) = min((int)CIRC_CNT(xmit->head, xmit->tail, UART_XMIT_SIZE),
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001168 CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE));
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001169 spin_unlock_irq(&port->lock);
1170
Magnus Dammf354a382010-03-19 04:47:01 +00001171 BUG_ON(!sg_dma_len(sg));
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001172
1173 desc = chan->device->device_prep_slave_sg(chan,
1174 sg, s->sg_len_tx, DMA_TO_DEVICE,
1175 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
1176 if (!desc) {
1177 /* switch to PIO */
1178 sci_tx_dma_release(s, true);
1179 return;
1180 }
1181
1182 dma_sync_sg_for_device(port->dev, sg, 1, DMA_TO_DEVICE);
1183
1184 spin_lock_irq(&port->lock);
1185 s->desc_tx = desc;
1186 desc->callback = sci_dma_tx_complete;
1187 desc->callback_param = s;
1188 spin_unlock_irq(&port->lock);
1189 s->cookie_tx = desc->tx_submit(desc);
1190 if (s->cookie_tx < 0) {
1191 dev_warn(port->dev, "Failed submitting Tx DMA descriptor\n");
1192 /* switch to PIO */
1193 sci_tx_dma_release(s, true);
1194 return;
1195 }
1196
1197 dev_dbg(port->dev, "%s: %p: %d...%d, cookie %d\n", __func__,
1198 xmit->buf, xmit->tail, xmit->head, s->cookie_tx);
1199
1200 dma_async_issue_pending(chan);
1201}
1202#endif
1203
Russell Kingb129a8c2005-08-31 10:12:14 +01001204static void sci_start_tx(struct uart_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205{
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001206 struct sci_port *s = to_sci_port(port);
Paul Mundte108b2c2006-09-27 16:32:13 +09001207 unsigned short ctrl;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001209#ifdef CONFIG_SERIAL_SH_SCI_DMA
Guennadi Liakhovetskid1d4b102010-05-23 16:39:09 +00001210 if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001211 u16 new, scr = sci_in(port, SCSCR);
1212 if (s->chan_tx)
1213 new = scr | 0x8000;
1214 else
1215 new = scr & ~0x8000;
1216 if (new != scr)
1217 sci_out(port, SCSCR, new);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001218 }
Paul Mundtf43dc232011-01-13 15:06:28 +09001219
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001220 if (s->chan_tx && !uart_circ_empty(&s->port.state->xmit) &&
1221 s->cookie_tx < 0)
1222 schedule_work(&s->work_tx);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001223#endif
Paul Mundtf43dc232011-01-13 15:06:28 +09001224
Guennadi Liakhovetskid1d4b102010-05-23 16:39:09 +00001225 if (!s->chan_tx || port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001226 /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */
1227 ctrl = sci_in(port, SCSCR);
Paul Mundtf43dc232011-01-13 15:06:28 +09001228 sci_out(port, SCSCR, ctrl | SCSCR_TIE);
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001229 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230}
1231
Russell Kingb129a8c2005-08-31 10:12:14 +01001232static void sci_stop_tx(struct uart_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234 unsigned short ctrl;
1235
1236 /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237 ctrl = sci_in(port, SCSCR);
Paul Mundtf43dc232011-01-13 15:06:28 +09001238
Guennadi Liakhovetskid1d4b102010-05-23 16:39:09 +00001239 if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001240 ctrl &= ~0x8000;
Paul Mundtf43dc232011-01-13 15:06:28 +09001241
Paul Mundt8e698612009-06-24 19:44:32 +09001242 ctrl &= ~SCSCR_TIE;
Paul Mundtf43dc232011-01-13 15:06:28 +09001243
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244 sci_out(port, SCSCR, ctrl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245}
1246
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001247static void sci_start_rx(struct uart_port *port)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001248{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249 unsigned short ctrl;
1250
Paul Mundtf43dc232011-01-13 15:06:28 +09001251 ctrl = sci_in(port, SCSCR) | port_rx_irq_mask(port);
1252
Guennadi Liakhovetskid1d4b102010-05-23 16:39:09 +00001253 if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001254 ctrl &= ~0x4000;
Paul Mundtf43dc232011-01-13 15:06:28 +09001255
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256 sci_out(port, SCSCR, ctrl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001257}
1258
1259static void sci_stop_rx(struct uart_port *port)
1260{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261 unsigned short ctrl;
1262
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263 ctrl = sci_in(port, SCSCR);
Paul Mundtf43dc232011-01-13 15:06:28 +09001264
Guennadi Liakhovetskid1d4b102010-05-23 16:39:09 +00001265 if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001266 ctrl &= ~0x4000;
Paul Mundtf43dc232011-01-13 15:06:28 +09001267
1268 ctrl &= ~port_rx_irq_mask(port);
1269
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 sci_out(port, SCSCR, ctrl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001271}
1272
1273static void sci_enable_ms(struct uart_port *port)
1274{
1275 /* Nothing here yet .. */
1276}
1277
1278static void sci_break_ctl(struct uart_port *port, int break_state)
1279{
1280 /* Nothing here yet .. */
1281}
1282
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001283#ifdef CONFIG_SERIAL_SH_SCI_DMA
1284static bool filter(struct dma_chan *chan, void *slave)
1285{
1286 struct sh_dmae_slave *param = slave;
1287
1288 dev_dbg(chan->device->dev, "%s: slave ID %d\n", __func__,
1289 param->slave_id);
1290
1291 if (param->dma_dev == chan->device->dev) {
1292 chan->private = param;
1293 return true;
1294 } else {
1295 return false;
1296 }
1297}
1298
1299static void rx_timer_fn(unsigned long arg)
1300{
1301 struct sci_port *s = (struct sci_port *)arg;
1302 struct uart_port *port = &s->port;
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001303 u16 scr = sci_in(port, SCSCR);
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001304
Guennadi Liakhovetskid1d4b102010-05-23 16:39:09 +00001305 if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001306 scr &= ~0x4000;
Paul Mundtce6738b2011-01-19 15:24:40 +09001307 enable_irq(s->cfg->irqs[1]);
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001308 }
Paul Mundtf43dc232011-01-13 15:06:28 +09001309 sci_out(port, SCSCR, scr | SCSCR_RIE);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001310 dev_dbg(port->dev, "DMA Rx timed out\n");
1311 schedule_work(&s->work_rx);
1312}
1313
1314static void sci_request_dma(struct uart_port *port)
1315{
1316 struct sci_port *s = to_sci_port(port);
1317 struct sh_dmae_slave *param;
1318 struct dma_chan *chan;
1319 dma_cap_mask_t mask;
1320 int nent;
1321
1322 dev_dbg(port->dev, "%s: port %d DMA %p\n", __func__,
Paul Mundtce6738b2011-01-19 15:24:40 +09001323 port->line, s->cfg->dma_dev);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001324
Paul Mundtce6738b2011-01-19 15:24:40 +09001325 if (!s->cfg->dma_dev)
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001326 return;
1327
1328 dma_cap_zero(mask);
1329 dma_cap_set(DMA_SLAVE, mask);
1330
1331 param = &s->param_tx;
1332
1333 /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_TX */
Paul Mundtce6738b2011-01-19 15:24:40 +09001334 param->slave_id = s->cfg->dma_slave_tx;
1335 param->dma_dev = s->cfg->dma_dev;
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001336
1337 s->cookie_tx = -EINVAL;
1338 chan = dma_request_channel(mask, filter, param);
1339 dev_dbg(port->dev, "%s: TX: got channel %p\n", __func__, chan);
1340 if (chan) {
1341 s->chan_tx = chan;
1342 sg_init_table(&s->sg_tx, 1);
1343 /* UART circular tx buffer is an aligned page. */
1344 BUG_ON((int)port->state->xmit.buf & ~PAGE_MASK);
1345 sg_set_page(&s->sg_tx, virt_to_page(port->state->xmit.buf),
1346 UART_XMIT_SIZE, (int)port->state->xmit.buf & ~PAGE_MASK);
1347 nent = dma_map_sg(port->dev, &s->sg_tx, 1, DMA_TO_DEVICE);
1348 if (!nent)
1349 sci_tx_dma_release(s, false);
1350 else
1351 dev_dbg(port->dev, "%s: mapped %d@%p to %x\n", __func__,
1352 sg_dma_len(&s->sg_tx),
1353 port->state->xmit.buf, sg_dma_address(&s->sg_tx));
1354
1355 s->sg_len_tx = nent;
1356
1357 INIT_WORK(&s->work_tx, work_fn_tx);
1358 }
1359
1360 param = &s->param_rx;
1361
1362 /* Slave ID, e.g., SHDMA_SLAVE_SCIF0_RX */
Paul Mundtce6738b2011-01-19 15:24:40 +09001363 param->slave_id = s->cfg->dma_slave_rx;
1364 param->dma_dev = s->cfg->dma_dev;
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001365
1366 chan = dma_request_channel(mask, filter, param);
1367 dev_dbg(port->dev, "%s: RX: got channel %p\n", __func__, chan);
1368 if (chan) {
1369 dma_addr_t dma[2];
1370 void *buf[2];
1371 int i;
1372
1373 s->chan_rx = chan;
1374
1375 s->buf_len_rx = 2 * max(16, (int)port->fifosize);
1376 buf[0] = dma_alloc_coherent(port->dev, s->buf_len_rx * 2,
1377 &dma[0], GFP_KERNEL);
1378
1379 if (!buf[0]) {
1380 dev_warn(port->dev,
1381 "failed to allocate dma buffer, using PIO\n");
1382 sci_rx_dma_release(s, true);
1383 return;
1384 }
1385
1386 buf[1] = buf[0] + s->buf_len_rx;
1387 dma[1] = dma[0] + s->buf_len_rx;
1388
1389 for (i = 0; i < 2; i++) {
1390 struct scatterlist *sg = &s->sg_rx[i];
1391
1392 sg_init_table(sg, 1);
1393 sg_set_page(sg, virt_to_page(buf[i]), s->buf_len_rx,
1394 (int)buf[i] & ~PAGE_MASK);
Magnus Dammf354a382010-03-19 04:47:01 +00001395 sg_dma_address(sg) = dma[i];
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001396 }
1397
1398 INIT_WORK(&s->work_rx, work_fn_rx);
1399 setup_timer(&s->rx_timer, rx_timer_fn, (unsigned long)s);
1400
1401 sci_submit_rx(s);
1402 }
1403}
1404
1405static void sci_free_dma(struct uart_port *port)
1406{
1407 struct sci_port *s = to_sci_port(port);
1408
Paul Mundtce6738b2011-01-19 15:24:40 +09001409 if (!s->cfg->dma_dev)
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001410 return;
1411
1412 if (s->chan_tx)
1413 sci_tx_dma_release(s, false);
1414 if (s->chan_rx)
1415 sci_rx_dma_release(s, false);
1416}
Paul Mundt27bd1072011-01-19 15:37:31 +09001417#else
1418static inline void sci_request_dma(struct uart_port *port)
1419{
1420}
1421
1422static inline void sci_free_dma(struct uart_port *port)
1423{
1424}
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001425#endif
1426
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427static int sci_startup(struct uart_port *port)
1428{
Magnus Damma5660ad2009-01-21 15:14:38 +00001429 struct sci_port *s = to_sci_port(port);
Paul Mundt073e84c2011-01-19 17:30:53 +09001430 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001432 dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
1433
Paul Mundte108b2c2006-09-27 16:32:13 +09001434 if (s->enable)
1435 s->enable(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436
Paul Mundt073e84c2011-01-19 17:30:53 +09001437 ret = sci_request_irq(s);
1438 if (unlikely(ret < 0))
1439 return ret;
1440
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001441 sci_request_dma(port);
Paul Mundt073e84c2011-01-19 17:30:53 +09001442
Yoshinori Satod6569012005-10-14 15:59:12 -07001443 sci_start_tx(port);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001444 sci_start_rx(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445
1446 return 0;
1447}
1448
1449static void sci_shutdown(struct uart_port *port)
1450{
Magnus Damma5660ad2009-01-21 15:14:38 +00001451 struct sci_port *s = to_sci_port(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001453 dev_dbg(port->dev, "%s(%d)\n", __func__, port->line);
1454
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455 sci_stop_rx(port);
Russell Kingb129a8c2005-08-31 10:12:14 +01001456 sci_stop_tx(port);
Paul Mundt073e84c2011-01-19 17:30:53 +09001457
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001458 sci_free_dma(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001459 sci_free_irq(s);
1460
Paul Mundte108b2c2006-09-27 16:32:13 +09001461 if (s->disable)
1462 s->disable(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463}
1464
Paul Mundt26c92f32009-06-24 18:23:52 +09001465static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps,
1466 unsigned long freq)
1467{
1468 switch (algo_id) {
1469 case SCBRR_ALGO_1:
1470 return ((freq + 16 * bps) / (16 * bps) - 1);
1471 case SCBRR_ALGO_2:
1472 return ((freq + 16 * bps) / (32 * bps) - 1);
1473 case SCBRR_ALGO_3:
1474 return (((freq * 2) + 16 * bps) / (16 * bps) - 1);
1475 case SCBRR_ALGO_4:
1476 return (((freq * 2) + 16 * bps) / (32 * bps) - 1);
1477 case SCBRR_ALGO_5:
1478 return (((freq * 1000 / 32) / bps) - 1);
1479 }
1480
1481 /* Warn, but use a safe default */
1482 WARN_ON(1);
Paul Mundte8183a62011-01-19 17:51:37 +09001483
Paul Mundt26c92f32009-06-24 18:23:52 +09001484 return ((freq + 16 * bps) / (32 * bps) - 1);
1485}
1486
Alan Cox606d0992006-12-08 02:38:45 -08001487static void sci_set_termios(struct uart_port *port, struct ktermios *termios,
1488 struct ktermios *old)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489{
Paul Mundt00b9de92009-06-24 17:53:33 +09001490 struct sci_port *s = to_sci_port(port);
Magnus Damm154280f2009-12-22 03:37:28 +00001491 unsigned int status, baud, smr_val, max_baud;
Paul Mundta2159b52008-10-02 19:09:13 +09001492 int t = -1;
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001493 u16 scfcr = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494
Magnus Damm154280f2009-12-22 03:37:28 +00001495 /*
1496 * earlyprintk comes here early on with port->uartclk set to zero.
1497 * the clock framework is not up and running at this point so here
1498 * we assume that 115200 is the maximum baud rate. please note that
1499 * the baud rate is not programmed during earlyprintk - it is assumed
1500 * that the previous boot loader has enabled required clocks and
1501 * setup the baud rate generator hardware for us already.
1502 */
1503 max_baud = port->uartclk ? port->uartclk / 16 : 115200;
1504
1505 baud = uart_get_baud_rate(port, termios, old, 0, max_baud);
1506 if (likely(baud && port->uartclk))
Paul Mundtce6738b2011-01-19 15:24:40 +09001507 t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508
Alexandre Courbot36003382011-03-03 08:04:42 +00001509 if (s->enable)
1510 s->enable(port);
1511
Paul Mundte108b2c2006-09-27 16:32:13 +09001512 do {
1513 status = sci_in(port, SCxSR);
1514 } while (!(status & SCxSR_TEND(port)));
1515
1516 sci_out(port, SCSCR, 0x00); /* TE=0, RE=0, CKE1=0 */
1517
Yoshihiro Shimoda1a22f082008-11-11 12:19:05 +09001518 if (port->type != PORT_SCI)
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001519 sci_out(port, SCFCR, scfcr | SCFCR_RFRST | SCFCR_TFRST);
Paul Mundte108b2c2006-09-27 16:32:13 +09001520
1521 smr_val = sci_in(port, SCSMR) & 3;
Paul Mundte8183a62011-01-19 17:51:37 +09001522
Paul Mundte108b2c2006-09-27 16:32:13 +09001523 if ((termios->c_cflag & CSIZE) == CS7)
1524 smr_val |= 0x40;
1525 if (termios->c_cflag & PARENB)
1526 smr_val |= 0x20;
1527 if (termios->c_cflag & PARODD)
1528 smr_val |= 0x30;
1529 if (termios->c_cflag & CSTOPB)
1530 smr_val |= 0x08;
1531
1532 uart_update_timeout(port, termios->c_cflag, baud);
1533
1534 sci_out(port, SCSMR, smr_val);
1535
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001536 dev_dbg(port->dev, "%s: SMR %x, t %x, SCSCR %x\n", __func__, smr_val, t,
Paul Mundtce6738b2011-01-19 15:24:40 +09001537 s->cfg->scscr);
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001538
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 if (t > 0) {
Michael Trimarchie7c98dc2008-11-13 18:18:35 +09001540 if (t >= 256) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 sci_out(port, SCSMR, (sci_in(port, SCSMR) & ~3) | 1);
1542 t >>= 2;
Michael Trimarchie7c98dc2008-11-13 18:18:35 +09001543 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544 sci_out(port, SCSMR, sci_in(port, SCSMR) & ~3);
Michael Trimarchie7c98dc2008-11-13 18:18:35 +09001545
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 sci_out(port, SCBRR, t);
1547 udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */
1548 }
1549
Paul Mundtd5701642008-12-16 20:07:27 +09001550 sci_init_pins(port, termios->c_cflag);
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001551 sci_out(port, SCFCR, scfcr | ((termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0));
Paul Mundtb7a76e42006-02-01 03:06:06 -08001552
Paul Mundtce6738b2011-01-19 15:24:40 +09001553 sci_out(port, SCSCR, s->cfg->scscr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554
Guennadi Liakhovetski3089f382010-03-19 13:53:04 +00001555#ifdef CONFIG_SERIAL_SH_SCI_DMA
1556 /*
1557 * Calculate delay for 1.5 DMA buffers: see
1558 * drivers/serial/serial_core.c::uart_update_timeout(). With 10 bits
1559 * (CS8), 250Hz, 115200 baud and 64 bytes FIFO, the above function
1560 * calculates 1 jiffie for the data plus 5 jiffies for the "slop(e)."
1561 * Then below we calculate 3 jiffies (12ms) for 1.5 DMA buffers (3 FIFO
1562 * sizes), but it has been found out experimentally, that this is not
1563 * enough: the driver too often needlessly runs on a DMA timeout. 20ms
1564 * as a minimum seem to work perfectly.
1565 */
1566 if (s->chan_rx) {
1567 s->rx_timeout = (port->timeout - HZ / 50) * s->buf_len_rx * 3 /
1568 port->fifosize / 2;
1569 dev_dbg(port->dev,
1570 "DMA Rx t-out %ums, tty t-out %u jiffies\n",
1571 s->rx_timeout * 1000 / HZ, port->timeout);
1572 if (s->rx_timeout < msecs_to_jiffies(20))
1573 s->rx_timeout = msecs_to_jiffies(20);
1574 }
1575#endif
1576
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 if ((termios->c_cflag & CREAD) != 0)
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001578 sci_start_rx(port);
Alexandre Courbot36003382011-03-03 08:04:42 +00001579
1580 if (s->disable)
1581 s->disable(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582}
1583
1584static const char *sci_type(struct uart_port *port)
1585{
1586 switch (port->type) {
Michael Trimarchie7c98dc2008-11-13 18:18:35 +09001587 case PORT_IRDA:
1588 return "irda";
1589 case PORT_SCI:
1590 return "sci";
1591 case PORT_SCIF:
1592 return "scif";
1593 case PORT_SCIFA:
1594 return "scifa";
Guennadi Liakhovetskid1d4b102010-05-23 16:39:09 +00001595 case PORT_SCIFB:
1596 return "scifb";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 }
1598
Paul Mundtfa439722008-09-04 18:53:58 +09001599 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600}
1601
Paul Mundte2651642011-01-20 21:24:03 +09001602static inline unsigned long sci_port_size(struct uart_port *port)
1603{
1604 /*
1605 * Pick an arbitrary size that encapsulates all of the base
1606 * registers by default. This can be optimized later, or derived
1607 * from platform resource data at such a time that ports begin to
1608 * behave more erratically.
1609 */
1610 return 64;
1611}
1612
Paul Mundtf6e94952011-01-21 15:25:36 +09001613static int sci_remap_port(struct uart_port *port)
1614{
1615 unsigned long size = sci_port_size(port);
1616
1617 /*
1618 * Nothing to do if there's already an established membase.
1619 */
1620 if (port->membase)
1621 return 0;
1622
1623 if (port->flags & UPF_IOREMAP) {
1624 port->membase = ioremap_nocache(port->mapbase, size);
1625 if (unlikely(!port->membase)) {
1626 dev_err(port->dev, "can't remap port#%d\n", port->line);
1627 return -ENXIO;
1628 }
1629 } else {
1630 /*
1631 * For the simple (and majority of) cases where we don't
1632 * need to do any remapping, just cast the cookie
1633 * directly.
1634 */
1635 port->membase = (void __iomem *)port->mapbase;
1636 }
1637
1638 return 0;
1639}
1640
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641static void sci_release_port(struct uart_port *port)
1642{
Paul Mundte2651642011-01-20 21:24:03 +09001643 if (port->flags & UPF_IOREMAP) {
1644 iounmap(port->membase);
1645 port->membase = NULL;
1646 }
1647
1648 release_mem_region(port->mapbase, sci_port_size(port));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001649}
1650
1651static int sci_request_port(struct uart_port *port)
1652{
Paul Mundte2651642011-01-20 21:24:03 +09001653 unsigned long size = sci_port_size(port);
1654 struct resource *res;
Paul Mundtf6e94952011-01-21 15:25:36 +09001655 int ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656
Paul Mundt10205202011-01-21 16:00:31 +09001657 res = request_mem_region(port->mapbase, size, dev_name(port->dev));
Paul Mundte2651642011-01-20 21:24:03 +09001658 if (unlikely(res == NULL))
1659 return -EBUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660
Paul Mundtf6e94952011-01-21 15:25:36 +09001661 ret = sci_remap_port(port);
1662 if (unlikely(ret != 0)) {
1663 release_resource(res);
1664 return ret;
Paul Mundt7ff731a2008-10-01 15:46:58 +09001665 }
Paul Mundte2651642011-01-20 21:24:03 +09001666
1667 return 0;
1668}
1669
1670static void sci_config_port(struct uart_port *port, int flags)
1671{
1672 if (flags & UART_CONFIG_TYPE) {
1673 struct sci_port *sport = to_sci_port(port);
1674
1675 port->type = sport->cfg->type;
1676 sci_request_port(port);
1677 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678}
1679
1680static int sci_verify_port(struct uart_port *port, struct serial_struct *ser)
1681{
Magnus Damma5660ad2009-01-21 15:14:38 +00001682 struct sci_port *s = to_sci_port(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683
Paul Mundtce6738b2011-01-19 15:24:40 +09001684 if (ser->irq != s->cfg->irqs[SCIx_TXI_IRQ] || ser->irq > nr_irqs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 return -EINVAL;
1686 if (ser->baud_base < 2400)
1687 /* No paper tape reader for Mitch.. */
1688 return -EINVAL;
1689
1690 return 0;
1691}
1692
1693static struct uart_ops sci_uart_ops = {
1694 .tx_empty = sci_tx_empty,
1695 .set_mctrl = sci_set_mctrl,
1696 .get_mctrl = sci_get_mctrl,
1697 .start_tx = sci_start_tx,
1698 .stop_tx = sci_stop_tx,
1699 .stop_rx = sci_stop_rx,
1700 .enable_ms = sci_enable_ms,
1701 .break_ctl = sci_break_ctl,
1702 .startup = sci_startup,
1703 .shutdown = sci_shutdown,
1704 .set_termios = sci_set_termios,
1705 .type = sci_type,
1706 .release_port = sci_release_port,
1707 .request_port = sci_request_port,
1708 .config_port = sci_config_port,
1709 .verify_port = sci_verify_port,
Paul Mundt07d2a1a2008-12-11 19:06:43 +09001710#ifdef CONFIG_CONSOLE_POLL
1711 .poll_get_char = sci_poll_get_char,
1712 .poll_put_char = sci_poll_put_char,
1713#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714};
1715
Paul Mundtc7ed1ab2010-03-10 18:35:14 +09001716static int __devinit sci_init_single(struct platform_device *dev,
1717 struct sci_port *sci_port,
1718 unsigned int index,
1719 struct plat_sci_port *p)
Paul Mundte108b2c2006-09-27 16:32:13 +09001720{
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001721 struct uart_port *port = &sci_port->port;
Paul Mundte108b2c2006-09-27 16:32:13 +09001722
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001723 port->ops = &sci_uart_ops;
1724 port->iotype = UPIO_MEM;
1725 port->line = index;
Markus Pietrek75136d42010-01-15 08:33:20 +09001726
1727 switch (p->type) {
Guennadi Liakhovetskid1d4b102010-05-23 16:39:09 +00001728 case PORT_SCIFB:
1729 port->fifosize = 256;
1730 break;
Markus Pietrek75136d42010-01-15 08:33:20 +09001731 case PORT_SCIFA:
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001732 port->fifosize = 64;
Markus Pietrek75136d42010-01-15 08:33:20 +09001733 break;
1734 case PORT_SCIF:
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001735 port->fifosize = 16;
Markus Pietrek75136d42010-01-15 08:33:20 +09001736 break;
1737 default:
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001738 port->fifosize = 1;
Markus Pietrek75136d42010-01-15 08:33:20 +09001739 break;
1740 }
Magnus Damm7b6fd3b2009-12-14 10:24:42 +00001741
1742 if (dev) {
Paul Mundtc7ed1ab2010-03-10 18:35:14 +09001743 sci_port->iclk = clk_get(&dev->dev, "sci_ick");
1744 if (IS_ERR(sci_port->iclk)) {
1745 sci_port->iclk = clk_get(&dev->dev, "peripheral_clk");
1746 if (IS_ERR(sci_port->iclk)) {
1747 dev_err(&dev->dev, "can't get iclk\n");
1748 return PTR_ERR(sci_port->iclk);
1749 }
1750 }
1751
1752 /*
1753 * The function clock is optional, ignore it if we can't
1754 * find it.
1755 */
1756 sci_port->fclk = clk_get(&dev->dev, "sci_fck");
1757 if (IS_ERR(sci_port->fclk))
1758 sci_port->fclk = NULL;
1759
Magnus Damm7b6fd3b2009-12-14 10:24:42 +00001760 sci_port->enable = sci_clk_enable;
1761 sci_port->disable = sci_clk_disable;
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001762 port->dev = &dev->dev;
Magnus Damm5e50d2d2011-04-19 10:38:25 +00001763
1764 pm_runtime_enable(&dev->dev);
Magnus Damm7b6fd3b2009-12-14 10:24:42 +00001765 }
Paul Mundte108b2c2006-09-27 16:32:13 +09001766
Magnus Damm7ed7e072009-01-21 15:14:14 +00001767 sci_port->break_timer.data = (unsigned long)sci_port;
1768 sci_port->break_timer.function = sci_break_timer;
1769 init_timer(&sci_port->break_timer);
Paul Mundte108b2c2006-09-27 16:32:13 +09001770
Paul Mundtdebf9502011-06-08 18:19:37 +09001771 /*
1772 * Establish some sensible defaults for the error detection.
1773 */
1774 if (!p->error_mask)
1775 p->error_mask = (p->type == PORT_SCI) ?
1776 SCI_DEFAULT_ERROR_MASK : SCIF_DEFAULT_ERROR_MASK;
1777
1778 /*
1779 * Establish sensible defaults for the overrun detection, unless
1780 * the part has explicitly disabled support for it.
1781 */
1782 if (p->overrun_bit != SCIx_NOT_SUPPORTED) {
1783 if (p->type == PORT_SCI)
1784 p->overrun_bit = 5;
1785 else if (p->scbrr_algo_id == SCBRR_ALGO_4)
1786 p->overrun_bit = 9;
1787 else
1788 p->overrun_bit = 0;
1789
1790 /*
1791 * Make the error mask inclusive of overrun detection, if
1792 * supported.
1793 */
1794 p->error_mask |= (1 << p->overrun_bit);
1795 }
1796
Paul Mundtce6738b2011-01-19 15:24:40 +09001797 sci_port->cfg = p;
Magnus Damm7ed7e072009-01-21 15:14:14 +00001798
Paul Mundtce6738b2011-01-19 15:24:40 +09001799 port->mapbase = p->mapbase;
1800 port->type = p->type;
Paul Mundtf43dc232011-01-13 15:06:28 +09001801 port->flags = p->flags;
Paul Mundtce6738b2011-01-19 15:24:40 +09001802
1803 /*
1804 * The UART port needs an IRQ value, so we peg this to the TX IRQ
1805 * for the multi-IRQ ports, which is where we are primarily
1806 * concerned with the shutdown path synchronization.
1807 *
1808 * For the muxed case there's nothing more to do.
1809 */
Magnus Damm54aa89e2011-04-21 13:08:46 +00001810 port->irq = p->irqs[SCIx_RXI_IRQ];
Guennadi Liakhovetski73a19e4c2010-03-02 11:39:15 +09001811
Paul Mundtce6738b2011-01-19 15:24:40 +09001812 if (p->dma_dev)
1813 dev_dbg(port->dev, "DMA device %p, tx %d, rx %d\n",
1814 p->dma_dev, p->dma_slave_tx, p->dma_slave_rx);
Magnus Damm7ed7e072009-01-21 15:14:14 +00001815
Paul Mundtc7ed1ab2010-03-10 18:35:14 +09001816 return 0;
Paul Mundte108b2c2006-09-27 16:32:13 +09001817}
1818
Linus Torvalds1da177e2005-04-16 15:20:36 -07001819#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
Magnus Dammdc8e6f52009-01-21 15:14:06 +00001820static void serial_console_putchar(struct uart_port *port, int ch)
1821{
1822 sci_poll_put_char(port, ch);
1823}
1824
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825/*
1826 * Print a string to the serial port trying not to disturb
1827 * any possible real use of the port...
1828 */
1829static void serial_console_write(struct console *co, const char *s,
1830 unsigned count)
1831{
Paul Mundt906b17d2011-01-21 16:19:53 +09001832 struct sci_port *sci_port = &sci_ports[co->index];
1833 struct uart_port *port = &sci_port->port;
Magnus Damm973e5d52009-02-24 15:57:12 +09001834 unsigned short bits;
Paul Mundt07d2a1a2008-12-11 19:06:43 +09001835
Magnus Damm501b8252009-01-21 15:14:30 +00001836 if (sci_port->enable)
1837 sci_port->enable(port);
1838
1839 uart_console_write(port, s, count, serial_console_putchar);
Magnus Damm973e5d52009-02-24 15:57:12 +09001840
1841 /* wait until fifo is empty and last bit has been transmitted */
1842 bits = SCxSR_TDxE(port) | SCxSR_TEND(port);
1843 while ((sci_in(port, SCxSR) & bits) != bits)
1844 cpu_relax();
Magnus Damm501b8252009-01-21 15:14:30 +00001845
Magnus Damm345e5a72009-11-05 14:34:57 +00001846 if (sci_port->disable)
Magnus Damm501b8252009-01-21 15:14:30 +00001847 sci_port->disable(port);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848}
1849
Magnus Damm7b6fd3b2009-12-14 10:24:42 +00001850static int __devinit serial_console_setup(struct console *co, char *options)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851{
Magnus Dammdc8e6f52009-01-21 15:14:06 +00001852 struct sci_port *sci_port;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 struct uart_port *port;
1854 int baud = 115200;
1855 int bits = 8;
1856 int parity = 'n';
1857 int flow = 'n';
1858 int ret;
1859
Paul Mundte108b2c2006-09-27 16:32:13 +09001860 /*
Paul Mundt906b17d2011-01-21 16:19:53 +09001861 * Refuse to handle any bogus ports.
Paul Mundte108b2c2006-09-27 16:32:13 +09001862 */
Paul Mundt906b17d2011-01-21 16:19:53 +09001863 if (co->index < 0 || co->index >= SCI_NPORTS)
Paul Mundte108b2c2006-09-27 16:32:13 +09001864 return -ENODEV;
Paul Mundte108b2c2006-09-27 16:32:13 +09001865
Paul Mundt906b17d2011-01-21 16:19:53 +09001866 sci_port = &sci_ports[co->index];
1867 port = &sci_port->port;
1868
Alexandre Courbotb2267a62011-02-09 03:18:46 +00001869 /*
1870 * Refuse to handle uninitialized ports.
1871 */
1872 if (!port->ops)
1873 return -ENODEV;
1874
Paul Mundtf6e94952011-01-21 15:25:36 +09001875 ret = sci_remap_port(port);
1876 if (unlikely(ret != 0))
1877 return ret;
Paul Mundte108b2c2006-09-27 16:32:13 +09001878
Magnus Dammdc8e6f52009-01-21 15:14:06 +00001879 if (sci_port->enable)
1880 sci_port->enable(port);
Paul Mundte108b2c2006-09-27 16:32:13 +09001881
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 if (options)
1883 uart_parse_options(options, &baud, &parity, &bits, &flow);
1884
Magnus Damm501b8252009-01-21 15:14:30 +00001885 /* TODO: disable clock */
Paul Mundtab7cfb52011-06-01 14:47:42 +09001886 return uart_set_options(port, co, baud, parity, bits, flow);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887}
1888
1889static struct console serial_console = {
1890 .name = "ttySC",
Paul Mundt906b17d2011-01-21 16:19:53 +09001891 .device = uart_console_device,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892 .write = serial_console_write,
1893 .setup = serial_console_setup,
Paul Mundtfa5da2f2007-03-08 17:27:37 +09001894 .flags = CON_PRINTBUFFER,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895 .index = -1,
Paul Mundt906b17d2011-01-21 16:19:53 +09001896 .data = &sci_uart_driver,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897};
1898
Magnus Damm7b6fd3b2009-12-14 10:24:42 +00001899static struct console early_serial_console = {
1900 .name = "early_ttySC",
1901 .write = serial_console_write,
1902 .flags = CON_PRINTBUFFER,
Paul Mundt906b17d2011-01-21 16:19:53 +09001903 .index = -1,
Magnus Damm7b6fd3b2009-12-14 10:24:42 +00001904};
Paul Mundtecdf8a42011-01-21 00:05:48 +09001905
Magnus Damm7b6fd3b2009-12-14 10:24:42 +00001906static char early_serial_buf[32];
1907
Paul Mundtecdf8a42011-01-21 00:05:48 +09001908static int __devinit sci_probe_earlyprintk(struct platform_device *pdev)
1909{
1910 struct plat_sci_port *cfg = pdev->dev.platform_data;
1911
1912 if (early_serial_console.data)
1913 return -EEXIST;
1914
1915 early_serial_console.index = pdev->id;
Paul Mundtecdf8a42011-01-21 00:05:48 +09001916
Paul Mundt906b17d2011-01-21 16:19:53 +09001917 sci_init_single(NULL, &sci_ports[pdev->id], pdev->id, cfg);
Paul Mundtecdf8a42011-01-21 00:05:48 +09001918
1919 serial_console_setup(&early_serial_console, early_serial_buf);
1920
1921 if (!strstr(early_serial_buf, "keep"))
1922 early_serial_console.flags |= CON_BOOT;
1923
1924 register_console(&early_serial_console);
1925 return 0;
1926}
Nobuhiro Iwamatsu6a8c9792011-03-24 02:20:56 +00001927
1928#define SCI_CONSOLE (&serial_console)
1929
Paul Mundtecdf8a42011-01-21 00:05:48 +09001930#else
1931static inline int __devinit sci_probe_earlyprintk(struct platform_device *pdev)
1932{
1933 return -EINVAL;
1934}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935
Nobuhiro Iwamatsu6a8c9792011-03-24 02:20:56 +00001936#define SCI_CONSOLE NULL
1937
1938#endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939
1940static char banner[] __initdata =
1941 KERN_INFO "SuperH SCI(F) driver initialized\n";
1942
1943static struct uart_driver sci_uart_driver = {
1944 .owner = THIS_MODULE,
1945 .driver_name = "sci",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 .dev_name = "ttySC",
1947 .major = SCI_MAJOR,
1948 .minor = SCI_MINOR_START,
Paul Mundte108b2c2006-09-27 16:32:13 +09001949 .nr = SCI_NPORTS,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001950 .cons = SCI_CONSOLE,
1951};
1952
Paul Mundt54507f62009-05-08 23:48:33 +09001953static int sci_remove(struct platform_device *dev)
Magnus Damme552de22009-01-21 15:13:42 +00001954{
Paul Mundtd535a232011-01-19 17:19:35 +09001955 struct sci_port *port = platform_get_drvdata(dev);
Magnus Damme552de22009-01-21 15:13:42 +00001956
Paul Mundtd535a232011-01-19 17:19:35 +09001957 cpufreq_unregister_notifier(&port->freq_transition,
1958 CPUFREQ_TRANSITION_NOTIFIER);
Magnus Damme552de22009-01-21 15:13:42 +00001959
Paul Mundtd535a232011-01-19 17:19:35 +09001960 uart_remove_one_port(&sci_uart_driver, &port->port);
Magnus Damme552de22009-01-21 15:13:42 +00001961
Paul Mundtd535a232011-01-19 17:19:35 +09001962 clk_put(port->iclk);
1963 clk_put(port->fclk);
1964
Magnus Damm5e50d2d2011-04-19 10:38:25 +00001965 pm_runtime_disable(&dev->dev);
Magnus Damme552de22009-01-21 15:13:42 +00001966 return 0;
1967}
1968
Magnus Damm0ee70712009-01-21 15:13:50 +00001969static int __devinit sci_probe_single(struct platform_device *dev,
1970 unsigned int index,
1971 struct plat_sci_port *p,
1972 struct sci_port *sciport)
1973{
Magnus Damm0ee70712009-01-21 15:13:50 +00001974 int ret;
1975
1976 /* Sanity check */
1977 if (unlikely(index >= SCI_NPORTS)) {
1978 dev_notice(&dev->dev, "Attempting to register port "
1979 "%d when only %d are available.\n",
1980 index+1, SCI_NPORTS);
1981 dev_notice(&dev->dev, "Consider bumping "
1982 "CONFIG_SERIAL_SH_SCI_NR_UARTS!\n");
1983 return 0;
1984 }
1985
Paul Mundtc7ed1ab2010-03-10 18:35:14 +09001986 ret = sci_init_single(dev, sciport, index, p);
1987 if (ret)
1988 return ret;
Magnus Damm0ee70712009-01-21 15:13:50 +00001989
Paul Mundtd535a232011-01-19 17:19:35 +09001990 return uart_add_one_port(&sci_uart_driver, &sciport->port);
Magnus Damm0ee70712009-01-21 15:13:50 +00001991}
1992
Paul Mundte108b2c2006-09-27 16:32:13 +09001993static int __devinit sci_probe(struct platform_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001994{
Paul Mundte108b2c2006-09-27 16:32:13 +09001995 struct plat_sci_port *p = dev->dev.platform_data;
Paul Mundtd535a232011-01-19 17:19:35 +09001996 struct sci_port *sp = &sci_ports[dev->id];
Paul Mundtecdf8a42011-01-21 00:05:48 +09001997 int ret;
Magnus Damme552de22009-01-21 15:13:42 +00001998
Paul Mundtecdf8a42011-01-21 00:05:48 +09001999 /*
2000 * If we've come here via earlyprintk initialization, head off to
2001 * the special early probe. We don't have sufficient device state
2002 * to make it beyond this yet.
2003 */
2004 if (is_early_platform_device(dev))
2005 return sci_probe_earlyprintk(dev);
Magnus Damm7b6fd3b2009-12-14 10:24:42 +00002006
Paul Mundtd535a232011-01-19 17:19:35 +09002007 platform_set_drvdata(dev, sp);
Magnus Damme552de22009-01-21 15:13:42 +00002008
Paul Mundt906b17d2011-01-21 16:19:53 +09002009 ret = sci_probe_single(dev, dev->id, p, sp);
Paul Mundtd535a232011-01-19 17:19:35 +09002010 if (ret)
2011 goto err_unreg;
Magnus Damme552de22009-01-21 15:13:42 +00002012
Paul Mundtd535a232011-01-19 17:19:35 +09002013 sp->freq_transition.notifier_call = sci_notifier;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002014
Paul Mundtd535a232011-01-19 17:19:35 +09002015 ret = cpufreq_register_notifier(&sp->freq_transition,
2016 CPUFREQ_TRANSITION_NOTIFIER);
2017 if (unlikely(ret < 0))
2018 goto err_unreg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002019
2020#ifdef CONFIG_SH_STANDARD_BIOS
2021 sh_bios_gdb_detach();
2022#endif
2023
Paul Mundte108b2c2006-09-27 16:32:13 +09002024 return 0;
Paul Mundt7ff731a2008-10-01 15:46:58 +09002025
2026err_unreg:
Magnus Damme552de22009-01-21 15:13:42 +00002027 sci_remove(dev);
Paul Mundt7ff731a2008-10-01 15:46:58 +09002028 return ret;
Paul Mundte108b2c2006-09-27 16:32:13 +09002029}
2030
Paul Mundt6daa79b2009-06-15 07:07:38 +09002031static int sci_suspend(struct device *dev)
Paul Mundte108b2c2006-09-27 16:32:13 +09002032{
Paul Mundtd535a232011-01-19 17:19:35 +09002033 struct sci_port *sport = dev_get_drvdata(dev);
Paul Mundte108b2c2006-09-27 16:32:13 +09002034
Paul Mundtd535a232011-01-19 17:19:35 +09002035 if (sport)
2036 uart_suspend_port(&sci_uart_driver, &sport->port);
Paul Mundte108b2c2006-09-27 16:32:13 +09002037
2038 return 0;
2039}
2040
Paul Mundt6daa79b2009-06-15 07:07:38 +09002041static int sci_resume(struct device *dev)
Paul Mundte108b2c2006-09-27 16:32:13 +09002042{
Paul Mundtd535a232011-01-19 17:19:35 +09002043 struct sci_port *sport = dev_get_drvdata(dev);
Paul Mundte108b2c2006-09-27 16:32:13 +09002044
Paul Mundtd535a232011-01-19 17:19:35 +09002045 if (sport)
2046 uart_resume_port(&sci_uart_driver, &sport->port);
Paul Mundte108b2c2006-09-27 16:32:13 +09002047
2048 return 0;
2049}
2050
Alexey Dobriyan47145212009-12-14 18:00:08 -08002051static const struct dev_pm_ops sci_dev_pm_ops = {
Paul Mundt6daa79b2009-06-15 07:07:38 +09002052 .suspend = sci_suspend,
2053 .resume = sci_resume,
2054};
2055
Paul Mundte108b2c2006-09-27 16:32:13 +09002056static struct platform_driver sci_driver = {
2057 .probe = sci_probe,
Uwe Kleine-Königb9e39c82009-11-24 22:07:32 +01002058 .remove = sci_remove,
Paul Mundte108b2c2006-09-27 16:32:13 +09002059 .driver = {
2060 .name = "sh-sci",
2061 .owner = THIS_MODULE,
Paul Mundt6daa79b2009-06-15 07:07:38 +09002062 .pm = &sci_dev_pm_ops,
Paul Mundte108b2c2006-09-27 16:32:13 +09002063 },
2064};
2065
2066static int __init sci_init(void)
2067{
2068 int ret;
2069
2070 printk(banner);
2071
Paul Mundte108b2c2006-09-27 16:32:13 +09002072 ret = uart_register_driver(&sci_uart_driver);
2073 if (likely(ret == 0)) {
2074 ret = platform_driver_register(&sci_driver);
2075 if (unlikely(ret))
2076 uart_unregister_driver(&sci_uart_driver);
2077 }
2078
Linus Torvalds1da177e2005-04-16 15:20:36 -07002079 return ret;
2080}
2081
2082static void __exit sci_exit(void)
2083{
Paul Mundte108b2c2006-09-27 16:32:13 +09002084 platform_driver_unregister(&sci_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085 uart_unregister_driver(&sci_uart_driver);
2086}
2087
Magnus Damm7b6fd3b2009-12-14 10:24:42 +00002088#ifdef CONFIG_SERIAL_SH_SCI_CONSOLE
2089early_platform_init_buffer("earlyprintk", &sci_driver,
2090 early_serial_buf, ARRAY_SIZE(early_serial_buf));
2091#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002092module_init(sci_init);
2093module_exit(sci_exit);
2094
Paul Mundte108b2c2006-09-27 16:32:13 +09002095MODULE_LICENSE("GPL");
Kay Sieverse169c132008-04-15 14:34:35 -07002096MODULE_ALIAS("platform:sh-sci");