aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial
diff options
context:
space:
mode:
authorChunyan Zhang <chunyan.zhang@spreadtrum.com>2015-01-28 06:08:44 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-02-02 13:11:28 -0500
commitb7396a38fb28db4ebbbf35da1057eb5206b4ad6c (patch)
treea104e2bf3008ee6bf1e5f790d52dd4bf67c77a6e /drivers/tty/serial
parente570f6bca4a5d23a4cff4746257fb06666d1d8d4 (diff)
tty/serial: Add Spreadtrum sc9836-uart driver support
Add a full sc9836-uart driver for SC9836 SoC which is based on the spreadtrum sharkl64 platform. This driver also support earlycon. Originally-by: Lanqing Liu <lanqing.liu@spreadtrum.com> Signed-off-by: Orson Zhai <orson.zhai@spreadtrum.com> Signed-off-by: Chunyan Zhang <chunyan.zhang@spreadtrum.com> Acked-by: Arnd Bergmann <arnd@arndb.de> Reviewed-by: Peter Hurley <peter@hurleysoftware.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r--drivers/tty/serial/Kconfig18
-rw-r--r--drivers/tty/serial/Makefile1
-rw-r--r--drivers/tty/serial/sprd_serial.c793
3 files changed, 812 insertions, 0 deletions
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index c63317e87c33..ddcc0a4c659c 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1583,6 +1583,24 @@ config SERIAL_MEN_Z135
1583 This driver can also be build as a module. If so, the module will be called 1583 This driver can also be build as a module. If so, the module will be called
1584 men_z135_uart.ko 1584 men_z135_uart.ko
1585 1585
1586config SERIAL_SPRD
1587 tristate "Support for Spreadtrum serial"
1588 depends on ARCH_SPRD
1589 select SERIAL_CORE
1590 help
1591 This enables the driver for the Spreadtrum's serial.
1592
1593config SERIAL_SPRD_CONSOLE
1594 bool "Spreadtrum UART console support"
1595 depends on SERIAL_SPRD=y
1596 select SERIAL_CORE_CONSOLE
1597 select SERIAL_EARLYCON
1598 help
1599 Support for early debug console using Spreadtrum's serial. This enables
1600 the console before standard serial driver is probed. This is enabled
1601 with "earlycon" on the kernel command line. The console is
1602 enabled when early_param is processed.
1603
1586endmenu 1604endmenu
1587 1605
1588config SERIAL_MCTRL_GPIO 1606config SERIAL_MCTRL_GPIO
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index a1c1085ef75c..431879003ccd 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -93,6 +93,7 @@ obj-$(CONFIG_SERIAL_RP2) += rp2.o
93obj-$(CONFIG_SERIAL_FSL_LPUART) += fsl_lpuart.o 93obj-$(CONFIG_SERIAL_FSL_LPUART) += fsl_lpuart.o
94obj-$(CONFIG_SERIAL_CONEXANT_DIGICOLOR) += digicolor-usart.o 94obj-$(CONFIG_SERIAL_CONEXANT_DIGICOLOR) += digicolor-usart.o
95obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o 95obj-$(CONFIG_SERIAL_MEN_Z135) += men_z135_uart.o
96obj-$(CONFIG_SERIAL_SPRD) += sprd_serial.o
96 97
97# GPIOLIB helpers for modem control lines 98# GPIOLIB helpers for modem control lines
98obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o 99obj-$(CONFIG_SERIAL_MCTRL_GPIO) += serial_mctrl_gpio.o
diff --git a/drivers/tty/serial/sprd_serial.c b/drivers/tty/serial/sprd_serial.c
new file mode 100644
index 000000000000..594b63331ef4
--- /dev/null
+++ b/drivers/tty/serial/sprd_serial.c
@@ -0,0 +1,793 @@
1/*
2 * Copyright (C) 2012-2015 Spreadtrum Communications Inc.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14#if defined(CONFIG_SERIAL_SPRD_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
15#define SUPPORT_SYSRQ
16#endif
17
18#include <linux/clk.h>
19#include <linux/console.h>
20#include <linux/delay.h>
21#include <linux/io.h>
22#include <linux/ioport.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/of.h>
26#include <linux/platform_device.h>
27#include <linux/serial_core.h>
28#include <linux/serial.h>
29#include <linux/slab.h>
30#include <linux/tty.h>
31#include <linux/tty_flip.h>
32
33/* device name */
34#define UART_NR_MAX 8
35#define SPRD_TTY_NAME "ttyS"
36#define SPRD_FIFO_SIZE 128
37#define SPRD_DEF_RATE 26000000
38#define SPRD_BAUD_IO_LIMIT 3000000
39#define SPRD_TIMEOUT 256
40
41/* the offset of serial registers and BITs for them */
42/* data registers */
43#define SPRD_TXD 0x0000
44#define SPRD_RXD 0x0004
45
46/* line status register and its BITs */
47#define SPRD_LSR 0x0008
48#define SPRD_LSR_OE BIT(4)
49#define SPRD_LSR_FE BIT(3)
50#define SPRD_LSR_PE BIT(2)
51#define SPRD_LSR_BI BIT(7)
52#define SPRD_LSR_TX_OVER BIT(15)
53
54/* data number in TX and RX fifo */
55#define SPRD_STS1 0x000C
56
57/* interrupt enable register and its BITs */
58#define SPRD_IEN 0x0010
59#define SPRD_IEN_RX_FULL BIT(0)
60#define SPRD_IEN_TX_EMPTY BIT(1)
61#define SPRD_IEN_BREAK_DETECT BIT(7)
62#define SPRD_IEN_TIMEOUT BIT(13)
63
64/* interrupt clear register */
65#define SPRD_ICLR 0x0014
66
67/* line control register */
68#define SPRD_LCR 0x0018
69#define SPRD_LCR_STOP_1BIT 0x10
70#define SPRD_LCR_STOP_2BIT 0x30
71#define SPRD_LCR_DATA_LEN (BIT(2) | BIT(3))
72#define SPRD_LCR_DATA_LEN5 0x0
73#define SPRD_LCR_DATA_LEN6 0x4
74#define SPRD_LCR_DATA_LEN7 0x8
75#define SPRD_LCR_DATA_LEN8 0xc
76#define SPRD_LCR_PARITY (BIT(0) | BIT(1))
77#define SPRD_LCR_PARITY_EN 0x2
78#define SPRD_LCR_EVEN_PAR 0x0
79#define SPRD_LCR_ODD_PAR 0x1
80
81/* control register 1 */
82#define SPRD_CTL1 0x001C
83#define RX_HW_FLOW_CTL_THLD BIT(6)
84#define RX_HW_FLOW_CTL_EN BIT(7)
85#define TX_HW_FLOW_CTL_EN BIT(8)
86#define RX_TOUT_THLD_DEF 0x3E00
87#define RX_HFC_THLD_DEF 0x40
88
89/* fifo threshold register */
90#define SPRD_CTL2 0x0020
91#define THLD_TX_EMPTY 0x40
92#define THLD_RX_FULL 0x40
93
94/* config baud rate register */
95#define SPRD_CLKD0 0x0024
96#define SPRD_CLKD1 0x0028
97
98/* interrupt mask status register */
99#define SPRD_IMSR 0x002C
100#define SPRD_IMSR_RX_FIFO_FULL BIT(0)
101#define SPRD_IMSR_TX_FIFO_EMPTY BIT(1)
102#define SPRD_IMSR_BREAK_DETECT BIT(7)
103#define SPRD_IMSR_TIMEOUT BIT(13)
104
105struct reg_backup {
106 u32 ien;
107 u32 ctrl0;
108 u32 ctrl1;
109 u32 ctrl2;
110 u32 clkd0;
111 u32 clkd1;
112 u32 dspwait;
113};
114
115struct sprd_uart_port {
116 struct uart_port port;
117 struct reg_backup reg_bak;
118 char name[16];
119};
120
121static struct sprd_uart_port *sprd_port[UART_NR_MAX];
122static int sprd_ports_num;
123
124static inline unsigned int serial_in(struct uart_port *port, int offset)
125{
126 return readl_relaxed(port->membase + offset);
127}
128
129static inline void serial_out(struct uart_port *port, int offset, int value)
130{
131 writel_relaxed(value, port->membase + offset);
132}
133
134static unsigned int sprd_tx_empty(struct uart_port *port)
135{
136 if (serial_in(port, SPRD_STS1) & 0xff00)
137 return 0;
138 else
139 return TIOCSER_TEMT;
140}
141
142static unsigned int sprd_get_mctrl(struct uart_port *port)
143{
144 return TIOCM_DSR | TIOCM_CTS;
145}
146
147static void sprd_set_mctrl(struct uart_port *port, unsigned int mctrl)
148{
149 /* nothing to do */
150}
151
152static void sprd_stop_tx(struct uart_port *port)
153{
154 unsigned int ien, iclr;
155
156 iclr = serial_in(port, SPRD_ICLR);
157 ien = serial_in(port, SPRD_IEN);
158
159 iclr |= SPRD_IEN_TX_EMPTY;
160 ien &= ~SPRD_IEN_TX_EMPTY;
161
162 serial_out(port, SPRD_ICLR, iclr);
163 serial_out(port, SPRD_IEN, ien);
164}
165
166static void sprd_start_tx(struct uart_port *port)
167{
168 unsigned int ien;
169
170 ien = serial_in(port, SPRD_IEN);
171 if (!(ien & SPRD_IEN_TX_EMPTY)) {
172 ien |= SPRD_IEN_TX_EMPTY;
173 serial_out(port, SPRD_IEN, ien);
174 }
175}
176
177static void sprd_stop_rx(struct uart_port *port)
178{
179 unsigned int ien, iclr;
180
181 iclr = serial_in(port, SPRD_ICLR);
182 ien = serial_in(port, SPRD_IEN);
183
184 ien &= ~(SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT);
185 iclr |= SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT;
186
187 serial_out(port, SPRD_IEN, ien);
188 serial_out(port, SPRD_ICLR, iclr);
189}
190
191/* The Sprd serial does not support this function. */
192static void sprd_break_ctl(struct uart_port *port, int break_state)
193{
194 /* nothing to do */
195}
196
197static int handle_lsr_errors(struct uart_port *port,
198 unsigned int *flag,
199 unsigned int *lsr)
200{
201 int ret = 0;
202
203 /* statistics */
204 if (*lsr & SPRD_LSR_BI) {
205 *lsr &= ~(SPRD_LSR_FE | SPRD_LSR_PE);
206 port->icount.brk++;
207 ret = uart_handle_break(port);
208 if (ret)
209 return ret;
210 } else if (*lsr & SPRD_LSR_PE)
211 port->icount.parity++;
212 else if (*lsr & SPRD_LSR_FE)
213 port->icount.frame++;
214 if (*lsr & SPRD_LSR_OE)
215 port->icount.overrun++;
216
217 /* mask off conditions which should be ignored */
218 *lsr &= port->read_status_mask;
219 if (*lsr & SPRD_LSR_BI)
220 *flag = TTY_BREAK;
221 else if (*lsr & SPRD_LSR_PE)
222 *flag = TTY_PARITY;
223 else if (*lsr & SPRD_LSR_FE)
224 *flag = TTY_FRAME;
225
226 return ret;
227}
228
229static inline void sprd_rx(struct uart_port *port)
230{
231 struct tty_port *tty = &port->state->port;
232 unsigned int ch, flag, lsr, max_count = SPRD_TIMEOUT;
233
234 while ((serial_in(port, SPRD_STS1) & 0x00ff) && max_count--) {
235 lsr = serial_in(port, SPRD_LSR);
236 ch = serial_in(port, SPRD_RXD);
237 flag = TTY_NORMAL;
238 port->icount.rx++;
239
240 if (lsr & (SPRD_LSR_BI | SPRD_LSR_PE |
241 SPRD_LSR_FE | SPRD_LSR_OE))
242 if (handle_lsr_errors(port, &lsr, &flag))
243 continue;
244 if (uart_handle_sysrq_char(port, ch))
245 continue;
246
247 uart_insert_char(port, lsr, SPRD_LSR_OE, ch, flag);
248 }
249
250 tty_flip_buffer_push(tty);
251}
252
253static inline void sprd_tx(struct uart_port *port)
254{
255 struct circ_buf *xmit = &port->state->xmit;
256 int count;
257
258 if (port->x_char) {
259 serial_out(port, SPRD_TXD, port->x_char);
260 port->icount.tx++;
261 port->x_char = 0;
262 return;
263 }
264
265 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
266 sprd_stop_tx(port);
267 return;
268 }
269
270 count = THLD_TX_EMPTY;
271 do {
272 serial_out(port, SPRD_TXD, xmit->buf[xmit->tail]);
273 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
274 port->icount.tx++;
275 if (uart_circ_empty(xmit))
276 break;
277 } while (--count > 0);
278
279 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
280 uart_write_wakeup(port);
281
282 if (uart_circ_empty(xmit))
283 sprd_stop_tx(port);
284}
285
286/* this handles the interrupt from one port */
287static irqreturn_t sprd_handle_irq(int irq, void *dev_id)
288{
289 struct uart_port *port = dev_id;
290 unsigned int ims;
291
292 spin_lock(&port->lock);
293
294 ims = serial_in(port, SPRD_IMSR);
295
296 if (!ims)
297 return IRQ_NONE;
298
299 serial_out(port, SPRD_ICLR, ~0);
300
301 if (ims & (SPRD_IMSR_RX_FIFO_FULL |
302 SPRD_IMSR_BREAK_DETECT | SPRD_IMSR_TIMEOUT))
303 sprd_rx(port);
304
305 if (ims & SPRD_IMSR_TX_FIFO_EMPTY)
306 sprd_tx(port);
307
308 spin_unlock(&port->lock);
309
310 return IRQ_HANDLED;
311}
312
313static int sprd_startup(struct uart_port *port)
314{
315 int ret = 0;
316 unsigned int ien, fc;
317 unsigned int timeout;
318 struct sprd_uart_port *sp;
319 unsigned long flags;
320
321 serial_out(port, SPRD_CTL2, ((THLD_TX_EMPTY << 8) | THLD_RX_FULL));
322
323 /* clear rx fifo */
324 timeout = SPRD_TIMEOUT;
325 while (timeout-- && serial_in(port, SPRD_STS1) & 0x00ff)
326 serial_in(port, SPRD_RXD);
327
328 /* clear tx fifo */
329 timeout = SPRD_TIMEOUT;
330 while (timeout-- && serial_in(port, SPRD_STS1) & 0xff00)
331 cpu_relax();
332
333 /* clear interrupt */
334 serial_out(port, SPRD_IEN, 0);
335 serial_out(port, SPRD_ICLR, ~0);
336
337 /* allocate irq */
338 sp = container_of(port, struct sprd_uart_port, port);
339 snprintf(sp->name, sizeof(sp->name), "sprd_serial%d", port->line);
340 ret = devm_request_irq(port->dev, port->irq, sprd_handle_irq,
341 IRQF_SHARED, sp->name, port);
342 if (ret) {
343 dev_err(port->dev, "fail to request serial irq %d, ret=%d\n",
344 port->irq, ret);
345 return ret;
346 }
347 fc = serial_in(port, SPRD_CTL1);
348 fc |= RX_TOUT_THLD_DEF | RX_HFC_THLD_DEF;
349 serial_out(port, SPRD_CTL1, fc);
350
351 /* enable interrupt */
352 spin_lock_irqsave(&port->lock, flags);
353 ien = serial_in(port, SPRD_IEN);
354 ien |= SPRD_IEN_RX_FULL | SPRD_IEN_BREAK_DETECT | SPRD_IEN_TIMEOUT;
355 serial_out(port, SPRD_IEN, ien);
356 spin_unlock_irqrestore(&port->lock, flags);
357
358 return 0;
359}
360
361static void sprd_shutdown(struct uart_port *port)
362{
363 serial_out(port, SPRD_IEN, 0);
364 serial_out(port, SPRD_ICLR, ~0);
365 devm_free_irq(port->dev, port->irq, port);
366}
367
368static void sprd_set_termios(struct uart_port *port,
369 struct ktermios *termios,
370 struct ktermios *old)
371{
372 unsigned int baud, quot;
373 unsigned int lcr = 0, fc;
374 unsigned long flags;
375
376 /* ask the core to calculate the divisor for us */
377 baud = uart_get_baud_rate(port, termios, old, 0, SPRD_BAUD_IO_LIMIT);
378
379 quot = (unsigned int)((port->uartclk + baud / 2) / baud);
380
381 /* set data length */
382 switch (termios->c_cflag & CSIZE) {
383 case CS5:
384 lcr |= SPRD_LCR_DATA_LEN5;
385 break;
386 case CS6:
387 lcr |= SPRD_LCR_DATA_LEN6;
388 break;
389 case CS7:
390 lcr |= SPRD_LCR_DATA_LEN7;
391 break;
392 case CS8:
393 default:
394 lcr |= SPRD_LCR_DATA_LEN8;
395 break;
396 }
397
398 /* calculate stop bits */
399 lcr &= ~(SPRD_LCR_STOP_1BIT | SPRD_LCR_STOP_2BIT);
400 if (termios->c_cflag & CSTOPB)
401 lcr |= SPRD_LCR_STOP_2BIT;
402 else
403 lcr |= SPRD_LCR_STOP_1BIT;
404
405 /* calculate parity */
406 lcr &= ~SPRD_LCR_PARITY;
407 termios->c_cflag &= ~CMSPAR; /* no support mark/space */
408 if (termios->c_cflag & PARENB) {
409 lcr |= SPRD_LCR_PARITY_EN;
410 if (termios->c_cflag & PARODD)
411 lcr |= SPRD_LCR_ODD_PAR;
412 else
413 lcr |= SPRD_LCR_EVEN_PAR;
414 }
415
416 spin_lock_irqsave(&port->lock, flags);
417
418 /* update the per-port timeout */
419 uart_update_timeout(port, termios->c_cflag, baud);
420
421 port->read_status_mask = SPRD_LSR_OE;
422 if (termios->c_iflag & INPCK)
423 port->read_status_mask |= SPRD_LSR_FE | SPRD_LSR_PE;
424 if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
425 port->read_status_mask |= SPRD_LSR_BI;
426
427 /* characters to ignore */
428 port->ignore_status_mask = 0;
429 if (termios->c_iflag & IGNPAR)
430 port->ignore_status_mask |= SPRD_LSR_PE | SPRD_LSR_FE;
431 if (termios->c_iflag & IGNBRK) {
432 port->ignore_status_mask |= SPRD_LSR_BI;
433 /*
434 * If we're ignoring parity and break indicators,
435 * ignore overruns too (for real raw support).
436 */
437 if (termios->c_iflag & IGNPAR)
438 port->ignore_status_mask |= SPRD_LSR_OE;
439 }
440
441 /* flow control */
442 fc = serial_in(port, SPRD_CTL1);
443 fc &= ~(RX_HW_FLOW_CTL_THLD | RX_HW_FLOW_CTL_EN | TX_HW_FLOW_CTL_EN);
444 if (termios->c_cflag & CRTSCTS) {
445 fc |= RX_HW_FLOW_CTL_THLD;
446 fc |= RX_HW_FLOW_CTL_EN;
447 fc |= TX_HW_FLOW_CTL_EN;
448 }
449
450 /* clock divider bit0~bit15 */
451 serial_out(port, SPRD_CLKD0, quot & 0xffff);
452
453 /* clock divider bit16~bit20 */
454 serial_out(port, SPRD_CLKD1, (quot & 0x1f0000) >> 16);
455 serial_out(port, SPRD_LCR, lcr);
456 fc |= RX_TOUT_THLD_DEF | RX_HFC_THLD_DEF;
457 serial_out(port, SPRD_CTL1, fc);
458
459 spin_unlock_irqrestore(&port->lock, flags);
460
461 /* Don't rewrite B0 */
462 if (tty_termios_baud_rate(termios))
463 tty_termios_encode_baud_rate(termios, baud, baud);
464}
465
466static const char *sprd_type(struct uart_port *port)
467{
468 return "SPX";
469}
470
471static void sprd_release_port(struct uart_port *port)
472{
473 /* nothing to do */
474}
475
476static int sprd_request_port(struct uart_port *port)
477{
478 return 0;
479}
480
481static void sprd_config_port(struct uart_port *port, int flags)
482{
483 if (flags & UART_CONFIG_TYPE)
484 port->type = PORT_SPRD;
485}
486
487static int sprd_verify_port(struct uart_port *port,
488 struct serial_struct *ser)
489{
490 if (ser->type != PORT_SPRD)
491 return -EINVAL;
492 if (port->irq != ser->irq)
493 return -EINVAL;
494 return 0;
495}
496
497static struct uart_ops serial_sprd_ops = {
498 .tx_empty = sprd_tx_empty,
499 .get_mctrl = sprd_get_mctrl,
500 .set_mctrl = sprd_set_mctrl,
501 .stop_tx = sprd_stop_tx,
502 .start_tx = sprd_start_tx,
503 .stop_rx = sprd_stop_rx,
504 .break_ctl = sprd_break_ctl,
505 .startup = sprd_startup,
506 .shutdown = sprd_shutdown,
507 .set_termios = sprd_set_termios,
508 .type = sprd_type,
509 .release_port = sprd_release_port,
510 .request_port = sprd_request_port,
511 .config_port = sprd_config_port,
512 .verify_port = sprd_verify_port,
513};
514
515#ifdef CONFIG_SERIAL_SPRD_CONSOLE
516static inline void wait_for_xmitr(struct uart_port *port)
517{
518 unsigned int status, tmout = 10000;
519
520 /* wait up to 10ms for the character(s) to be sent */
521 do {
522 status = serial_in(port, SPRD_STS1);
523 if (--tmout == 0)
524 break;
525 udelay(1);
526 } while (status & 0xff00);
527}
528
529static void sprd_console_putchar(struct uart_port *port, int ch)
530{
531 wait_for_xmitr(port);
532 serial_out(port, SPRD_TXD, ch);
533}
534
535static void sprd_console_write(struct console *co, const char *s,
536 unsigned int count)
537{
538 struct uart_port *port = &sprd_port[co->index]->port;
539 int locked = 1;
540 unsigned long flags;
541
542 if (port->sysrq)
543 locked = 0;
544 else if (oops_in_progress)
545 locked = spin_trylock_irqsave(&port->lock, flags);
546 else
547 spin_lock_irqsave(&port->lock, flags);
548
549 uart_console_write(port, s, count, sprd_console_putchar);
550
551 /* wait for transmitter to become empty */
552 wait_for_xmitr(port);
553
554 if (locked)
555 spin_unlock_irqrestore(&port->lock, flags);
556}
557
558static int __init sprd_console_setup(struct console *co, char *options)
559{
560 struct uart_port *port;
561 int baud = 115200;
562 int bits = 8;
563 int parity = 'n';
564 int flow = 'n';
565
566 if (co->index >= UART_NR_MAX || co->index < 0)
567 co->index = 0;
568
569 port = &sprd_port[co->index]->port;
570 if (port == NULL) {
571 pr_info("serial port %d not yet initialized\n", co->index);
572 return -ENODEV;
573 }
574 if (options)
575 uart_parse_options(options, &baud, &parity, &bits, &flow);
576
577 return uart_set_options(port, co, baud, parity, bits, flow);
578}
579
580static struct uart_driver sprd_uart_driver;
581static struct console sprd_console = {
582 .name = SPRD_TTY_NAME,
583 .write = sprd_console_write,
584 .device = uart_console_device,
585 .setup = sprd_console_setup,
586 .flags = CON_PRINTBUFFER,
587 .index = -1,
588 .data = &sprd_uart_driver,
589};
590
591#define SPRD_CONSOLE (&sprd_console)
592
593/* Support for earlycon */
594static void sprd_putc(struct uart_port *port, int c)
595{
596 unsigned int timeout = SPRD_TIMEOUT;
597
598 while (timeout-- &&
599 !(readl(port->membase + SPRD_LSR) & SPRD_LSR_TX_OVER))
600 cpu_relax();
601
602 writeb(c, port->membase + SPRD_TXD);
603}
604
605static void sprd_early_write(struct console *con, const char *s,
606 unsigned n)
607{
608 struct earlycon_device *dev = con->data;
609
610 uart_console_write(&dev->port, s, n, sprd_putc);
611}
612
613static int __init sprd_early_console_setup(
614 struct earlycon_device *device,
615 const char *opt)
616{
617 if (!device->port.membase)
618 return -ENODEV;
619
620 device->con->write = sprd_early_write;
621 return 0;
622}
623
624EARLYCON_DECLARE(sprd_serial, sprd_early_console_setup);
625OF_EARLYCON_DECLARE(sprd_serial, "sprd,sc9836-uart",
626 sprd_early_console_setup);
627
628#else /* !CONFIG_SERIAL_SPRD_CONSOLE */
629#define SPRD_CONSOLE NULL
630#endif
631
632static struct uart_driver sprd_uart_driver = {
633 .owner = THIS_MODULE,
634 .driver_name = "sprd_serial",
635 .dev_name = SPRD_TTY_NAME,
636 .major = 0,
637 .minor = 0,
638 .nr = UART_NR_MAX,
639 .cons = SPRD_CONSOLE,
640};
641
642static int sprd_probe_dt_alias(int index, struct device *dev)
643{
644 struct device_node *np;
645 int ret = index;
646
647 if (!IS_ENABLED(CONFIG_OF))
648 return ret;
649
650 np = dev->of_node;
651 if (!np)
652 return ret;
653
654 ret = of_alias_get_id(np, "serial");
655 if (IS_ERR_VALUE(ret))
656 ret = index;
657 else if (ret >= ARRAY_SIZE(sprd_port) || sprd_port[ret] != NULL) {
658 dev_warn(dev, "requested serial port %d not available.\n", ret);
659 ret = index;
660 }
661
662 return ret;
663}
664
665static int sprd_remove(struct platform_device *dev)
666{
667 struct sprd_uart_port *sup = platform_get_drvdata(dev);
668
669 if (sup) {
670 uart_remove_one_port(&sprd_uart_driver, &sup->port);
671 sprd_port[sup->port.line] = NULL;
672 sprd_ports_num--;
673 }
674
675 if (!sprd_ports_num)
676 uart_unregister_driver(&sprd_uart_driver);
677
678 return 0;
679}
680
681static int sprd_probe(struct platform_device *pdev)
682{
683 struct resource *res;
684 struct uart_port *up;
685 struct clk *clk;
686 int irq;
687 int index;
688 int ret;
689
690 for (index = 0; index < ARRAY_SIZE(sprd_port); index++)
691 if (sprd_port[index] == NULL)
692 break;
693
694 if (index == ARRAY_SIZE(sprd_port))
695 return -EBUSY;
696
697 index = sprd_probe_dt_alias(index, &pdev->dev);
698
699 sprd_port[index] = devm_kzalloc(&pdev->dev,
700 sizeof(*sprd_port[index]), GFP_KERNEL);
701 if (!sprd_port[index])
702 return -ENOMEM;
703
704 up = &sprd_port[index]->port;
705 up->dev = &pdev->dev;
706 up->line = index;
707 up->type = PORT_SPRD;
708 up->iotype = SERIAL_IO_PORT;
709 up->uartclk = SPRD_DEF_RATE;
710 up->fifosize = SPRD_FIFO_SIZE;
711 up->ops = &serial_sprd_ops;
712 up->flags = UPF_BOOT_AUTOCONF;
713
714 clk = devm_clk_get(&pdev->dev, NULL);
715 if (!IS_ERR(clk))
716 up->uartclk = clk_get_rate(clk);
717
718 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
719 if (!res) {
720 dev_err(&pdev->dev, "not provide mem resource\n");
721 return -ENODEV;
722 }
723 up->mapbase = res->start;
724 up->membase = devm_ioremap_resource(&pdev->dev, res);
725 if (IS_ERR(up->membase))
726 return PTR_ERR(up->membase);
727
728 irq = platform_get_irq(pdev, 0);
729 if (irq < 0) {
730 dev_err(&pdev->dev, "not provide irq resource\n");
731 return -ENODEV;
732 }
733 up->irq = irq;
734
735 if (!sprd_ports_num) {
736 ret = uart_register_driver(&sprd_uart_driver);
737 if (ret < 0) {
738 pr_err("Failed to register SPRD-UART driver\n");
739 return ret;
740 }
741 }
742 sprd_ports_num++;
743
744 ret = uart_add_one_port(&sprd_uart_driver, up);
745 if (ret) {
746 sprd_port[index] = NULL;
747 sprd_remove(pdev);
748 }
749
750 platform_set_drvdata(pdev, up);
751
752 return ret;
753}
754
755static int sprd_suspend(struct device *dev)
756{
757 struct sprd_uart_port *sup = dev_get_drvdata(dev);
758
759 uart_suspend_port(&sprd_uart_driver, &sup->port);
760
761 return 0;
762}
763
764static int sprd_resume(struct device *dev)
765{
766 struct sprd_uart_port *sup = dev_get_drvdata(dev);
767
768 uart_resume_port(&sprd_uart_driver, &sup->port);
769
770 return 0;
771}
772
773static SIMPLE_DEV_PM_OPS(sprd_pm_ops, sprd_suspend, sprd_resume);
774
775static const struct of_device_id serial_ids[] = {
776 {.compatible = "sprd,sc9836-uart",},
777 {}
778};
779
780static struct platform_driver sprd_platform_driver = {
781 .probe = sprd_probe,
782 .remove = sprd_remove,
783 .driver = {
784 .name = "sprd_serial",
785 .of_match_table = of_match_ptr(serial_ids),
786 .pm = &sprd_pm_ops,
787 },
788};
789
790module_platform_driver(sprd_platform_driver);
791
792MODULE_LICENSE("GPL v2");
793MODULE_DESCRIPTION("Spreadtrum SoC serial driver series");