2 * drivers/serial/msm_serial.c - driver for msm7k serial device and console
4 * Copyright (C) 2007 Google, Inc.
5 * Author: Robert Love <rlove@google.com>
7 * This software is licensed under the terms of the GNU General Public
8 * License version 2, as published by the Free Software Foundation, and
9 * may be copied, distributed, and modified under those terms.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #if defined(CONFIG_SERIAL_MSM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
18 # define SUPPORT_SYSRQ
21 #include <linux/hrtimer.h>
22 #include <linux/module.h>
24 #include <linux/ioport.h>
25 #include <linux/irq.h>
26 #include <linux/init.h>
27 #include <linux/console.h>
28 #include <linux/tty.h>
29 #include <linux/tty_flip.h>
30 #include <linux/serial_core.h>
31 #include <linux/serial.h>
32 #include <linux/clk.h>
33 #include <linux/platform_device.h>
35 #include "msm_serial.h"
38 struct uart_port uart
;
44 static void msm_stop_tx(struct uart_port
*port
)
46 struct msm_port
*msm_port
= UART_TO_MSM(port
);
48 msm_port
->imr
&= ~UART_IMR_TXLEV
;
49 msm_write(port
, msm_port
->imr
, UART_IMR
);
52 static void msm_start_tx(struct uart_port
*port
)
54 struct msm_port
*msm_port
= UART_TO_MSM(port
);
56 msm_port
->imr
|= UART_IMR_TXLEV
;
57 msm_write(port
, msm_port
->imr
, UART_IMR
);
60 static void msm_stop_rx(struct uart_port
*port
)
62 struct msm_port
*msm_port
= UART_TO_MSM(port
);
64 msm_port
->imr
&= ~(UART_IMR_RXLEV
| UART_IMR_RXSTALE
);
65 msm_write(port
, msm_port
->imr
, UART_IMR
);
68 static void msm_enable_ms(struct uart_port
*port
)
70 struct msm_port
*msm_port
= UART_TO_MSM(port
);
72 msm_port
->imr
|= UART_IMR_DELTA_CTS
;
73 msm_write(port
, msm_port
->imr
, UART_IMR
);
76 static void handle_rx(struct uart_port
*port
)
78 struct tty_struct
*tty
= port
->state
->port
.tty
;
82 * Handle overrun. My understanding of the hardware is that overrun
83 * is not tied to the RX buffer, so we handle the case out of band.
85 if ((msm_read(port
, UART_SR
) & UART_SR_OVERRUN
)) {
86 port
->icount
.overrun
++;
87 tty_insert_flip_char(tty
, 0, TTY_OVERRUN
);
88 msm_write(port
, UART_CR_CMD_RESET_ERR
, UART_CR
);
91 /* and now the main RX loop */
92 while ((sr
= msm_read(port
, UART_SR
)) & UART_SR_RX_READY
) {
94 char flag
= TTY_NORMAL
;
96 c
= msm_read(port
, UART_RF
);
98 if (sr
& UART_SR_RX_BREAK
) {
100 if (uart_handle_break(port
))
102 } else if (sr
& UART_SR_PAR_FRAME_ERR
) {
103 port
->icount
.frame
++;
108 /* Mask conditions we're ignorning. */
109 sr
&= port
->read_status_mask
;
111 if (sr
& UART_SR_RX_BREAK
) {
113 } else if (sr
& UART_SR_PAR_FRAME_ERR
) {
117 if (!uart_handle_sysrq_char(port
, c
))
118 tty_insert_flip_char(tty
, c
, flag
);
121 tty_flip_buffer_push(tty
);
124 static void handle_tx(struct uart_port
*port
)
126 struct circ_buf
*xmit
= &port
->state
->xmit
;
127 struct msm_port
*msm_port
= UART_TO_MSM(port
);
131 msm_write(port
, port
->x_char
, UART_TF
);
136 while (msm_read(port
, UART_SR
) & UART_SR_TX_READY
) {
137 if (uart_circ_empty(xmit
)) {
138 /* disable tx interrupts */
139 msm_port
->imr
&= ~UART_IMR_TXLEV
;
140 msm_write(port
, msm_port
->imr
, UART_IMR
);
144 msm_write(port
, xmit
->buf
[xmit
->tail
], UART_TF
);
146 xmit
->tail
= (xmit
->tail
+ 1) & (UART_XMIT_SIZE
- 1);
151 if (uart_circ_chars_pending(xmit
) < WAKEUP_CHARS
)
152 uart_write_wakeup(port
);
155 static void handle_delta_cts(struct uart_port
*port
)
157 msm_write(port
, UART_CR_CMD_RESET_CTS
, UART_CR
);
159 wake_up_interruptible(&port
->state
->port
.delta_msr_wait
);
162 static irqreturn_t
msm_irq(int irq
, void *dev_id
)
164 struct uart_port
*port
= dev_id
;
165 struct msm_port
*msm_port
= UART_TO_MSM(port
);
168 spin_lock(&port
->lock
);
169 misr
= msm_read(port
, UART_MISR
);
170 msm_write(port
, 0, UART_IMR
); /* disable interrupt */
172 if (misr
& (UART_IMR_RXLEV
| UART_IMR_RXSTALE
))
174 if (misr
& UART_IMR_TXLEV
)
176 if (misr
& UART_IMR_DELTA_CTS
)
177 handle_delta_cts(port
);
179 msm_write(port
, msm_port
->imr
, UART_IMR
); /* restore interrupt */
180 spin_unlock(&port
->lock
);
185 static unsigned int msm_tx_empty(struct uart_port
*port
)
187 return (msm_read(port
, UART_SR
) & UART_SR_TX_EMPTY
) ? TIOCSER_TEMT
: 0;
190 static unsigned int msm_get_mctrl(struct uart_port
*port
)
192 return TIOCM_CAR
| TIOCM_CTS
| TIOCM_DSR
| TIOCM_RTS
;
195 static void msm_set_mctrl(struct uart_port
*port
, unsigned int mctrl
)
199 mr
= msm_read(port
, UART_MR1
);
201 if (!(mctrl
& TIOCM_RTS
)) {
202 mr
&= ~UART_MR1_RX_RDY_CTL
;
203 msm_write(port
, mr
, UART_MR1
);
204 msm_write(port
, UART_CR_CMD_RESET_RFR
, UART_CR
);
206 mr
|= UART_MR1_RX_RDY_CTL
;
207 msm_write(port
, mr
, UART_MR1
);
211 static void msm_break_ctl(struct uart_port
*port
, int break_ctl
)
214 msm_write(port
, UART_CR_CMD_START_BREAK
, UART_CR
);
216 msm_write(port
, UART_CR_CMD_STOP_BREAK
, UART_CR
);
219 static int msm_set_baud_rate(struct uart_port
*port
, unsigned int baud
)
221 unsigned int baud_code
, rxstale
, watermark
;
225 baud_code
= UART_CSR_300
;
229 baud_code
= UART_CSR_600
;
233 baud_code
= UART_CSR_1200
;
237 baud_code
= UART_CSR_2400
;
241 baud_code
= UART_CSR_4800
;
245 baud_code
= UART_CSR_9600
;
249 baud_code
= UART_CSR_14400
;
253 baud_code
= UART_CSR_19200
;
257 baud_code
= UART_CSR_28800
;
261 baud_code
= UART_CSR_38400
;
265 baud_code
= UART_CSR_57600
;
270 baud_code
= UART_CSR_115200
;
276 msm_write(port
, baud_code
, UART_CSR
);
278 /* RX stale watermark */
279 watermark
= UART_IPR_STALE_LSB
& rxstale
;
280 watermark
|= UART_IPR_RXSTALE_LAST
;
281 watermark
|= UART_IPR_STALE_TIMEOUT_MSB
& (rxstale
<< 2);
282 msm_write(port
, watermark
, UART_IPR
);
284 /* set RX watermark */
285 watermark
= (port
->fifosize
* 3) / 4;
286 msm_write(port
, watermark
, UART_RFWR
);
288 /* set TX watermark */
289 msm_write(port
, 10, UART_TFWR
);
294 static void msm_reset(struct uart_port
*port
)
296 /* reset everything */
297 msm_write(port
, UART_CR_CMD_RESET_RX
, UART_CR
);
298 msm_write(port
, UART_CR_CMD_RESET_TX
, UART_CR
);
299 msm_write(port
, UART_CR_CMD_RESET_ERR
, UART_CR
);
300 msm_write(port
, UART_CR_CMD_RESET_BREAK_INT
, UART_CR
);
301 msm_write(port
, UART_CR_CMD_RESET_CTS
, UART_CR
);
302 msm_write(port
, UART_CR_CMD_SET_RFR
, UART_CR
);
305 static void msm_init_clock(struct uart_port
*port
)
307 struct msm_port
*msm_port
= UART_TO_MSM(port
);
309 clk_enable(msm_port
->clk
);
310 msm_serial_set_mnd_regs(port
);
313 static int msm_startup(struct uart_port
*port
)
315 struct msm_port
*msm_port
= UART_TO_MSM(port
);
316 unsigned int data
, rfr_level
;
319 snprintf(msm_port
->name
, sizeof(msm_port
->name
),
320 "msm_serial%d", port
->line
);
322 ret
= request_irq(port
->irq
, msm_irq
, IRQF_TRIGGER_HIGH
,
323 msm_port
->name
, port
);
327 msm_init_clock(port
);
329 if (likely(port
->fifosize
> 12))
330 rfr_level
= port
->fifosize
- 12;
332 rfr_level
= port
->fifosize
;
334 /* set automatic RFR level */
335 data
= msm_read(port
, UART_MR1
);
336 data
&= ~UART_MR1_AUTO_RFR_LEVEL1
;
337 data
&= ~UART_MR1_AUTO_RFR_LEVEL0
;
338 data
|= UART_MR1_AUTO_RFR_LEVEL1
& (rfr_level
<< 2);
339 data
|= UART_MR1_AUTO_RFR_LEVEL0
& rfr_level
;
340 msm_write(port
, data
, UART_MR1
);
342 /* make sure that RXSTALE count is non-zero */
343 data
= msm_read(port
, UART_IPR
);
344 if (unlikely(!data
)) {
345 data
|= UART_IPR_RXSTALE_LAST
;
346 data
|= UART_IPR_STALE_LSB
;
347 msm_write(port
, data
, UART_IPR
);
352 msm_write(port
, 0x05, UART_CR
); /* enable TX & RX */
354 /* turn on RX and CTS interrupts */
355 msm_port
->imr
= UART_IMR_RXLEV
| UART_IMR_RXSTALE
|
356 UART_IMR_CURRENT_CTS
;
357 msm_write(port
, msm_port
->imr
, UART_IMR
);
362 static void msm_shutdown(struct uart_port
*port
)
364 struct msm_port
*msm_port
= UART_TO_MSM(port
);
367 msm_write(port
, 0, UART_IMR
); /* disable interrupts */
369 clk_disable(msm_port
->clk
);
371 free_irq(port
->irq
, port
);
374 static void msm_set_termios(struct uart_port
*port
, struct ktermios
*termios
,
375 struct ktermios
*old
)
378 unsigned int baud
, mr
;
380 spin_lock_irqsave(&port
->lock
, flags
);
382 /* calculate and set baud rate */
383 baud
= uart_get_baud_rate(port
, termios
, old
, 300, 115200);
384 baud
= msm_set_baud_rate(port
, baud
);
385 if (tty_termios_baud_rate(termios
))
386 tty_termios_encode_baud_rate(termios
, baud
, baud
);
388 /* calculate parity */
389 mr
= msm_read(port
, UART_MR2
);
390 mr
&= ~UART_MR2_PARITY_MODE
;
391 if (termios
->c_cflag
& PARENB
) {
392 if (termios
->c_cflag
& PARODD
)
393 mr
|= UART_MR2_PARITY_MODE_ODD
;
394 else if (termios
->c_cflag
& CMSPAR
)
395 mr
|= UART_MR2_PARITY_MODE_SPACE
;
397 mr
|= UART_MR2_PARITY_MODE_EVEN
;
400 /* calculate bits per char */
401 mr
&= ~UART_MR2_BITS_PER_CHAR
;
402 switch (termios
->c_cflag
& CSIZE
) {
404 mr
|= UART_MR2_BITS_PER_CHAR_5
;
407 mr
|= UART_MR2_BITS_PER_CHAR_6
;
410 mr
|= UART_MR2_BITS_PER_CHAR_7
;
414 mr
|= UART_MR2_BITS_PER_CHAR_8
;
418 /* calculate stop bits */
419 mr
&= ~(UART_MR2_STOP_BIT_LEN_ONE
| UART_MR2_STOP_BIT_LEN_TWO
);
420 if (termios
->c_cflag
& CSTOPB
)
421 mr
|= UART_MR2_STOP_BIT_LEN_TWO
;
423 mr
|= UART_MR2_STOP_BIT_LEN_ONE
;
425 /* set parity, bits per char, and stop bit */
426 msm_write(port
, mr
, UART_MR2
);
428 /* calculate and set hardware flow control */
429 mr
= msm_read(port
, UART_MR1
);
430 mr
&= ~(UART_MR1_CTS_CTL
| UART_MR1_RX_RDY_CTL
);
431 if (termios
->c_cflag
& CRTSCTS
) {
432 mr
|= UART_MR1_CTS_CTL
;
433 mr
|= UART_MR1_RX_RDY_CTL
;
435 msm_write(port
, mr
, UART_MR1
);
437 /* Configure status bits to ignore based on termio flags. */
438 port
->read_status_mask
= 0;
439 if (termios
->c_iflag
& INPCK
)
440 port
->read_status_mask
|= UART_SR_PAR_FRAME_ERR
;
441 if (termios
->c_iflag
& (BRKINT
| PARMRK
))
442 port
->read_status_mask
|= UART_SR_RX_BREAK
;
444 uart_update_timeout(port
, termios
->c_cflag
, baud
);
446 spin_unlock_irqrestore(&port
->lock
, flags
);
449 static const char *msm_type(struct uart_port
*port
)
454 static void msm_release_port(struct uart_port
*port
)
456 struct platform_device
*pdev
= to_platform_device(port
->dev
);
457 struct resource
*resource
;
458 resource_size_t size
;
460 resource
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
461 if (unlikely(!resource
))
463 size
= resource
->end
- resource
->start
+ 1;
465 release_mem_region(port
->mapbase
, size
);
466 iounmap(port
->membase
);
467 port
->membase
= NULL
;
470 static int msm_request_port(struct uart_port
*port
)
472 struct platform_device
*pdev
= to_platform_device(port
->dev
);
473 struct resource
*resource
;
474 resource_size_t size
;
476 resource
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
477 if (unlikely(!resource
))
479 size
= resource
->end
- resource
->start
+ 1;
481 if (unlikely(!request_mem_region(port
->mapbase
, size
, "msm_serial")))
484 port
->membase
= ioremap(port
->mapbase
, size
);
485 if (!port
->membase
) {
486 release_mem_region(port
->mapbase
, size
);
493 static void msm_config_port(struct uart_port
*port
, int flags
)
495 if (flags
& UART_CONFIG_TYPE
) {
496 port
->type
= PORT_MSM
;
497 msm_request_port(port
);
501 static int msm_verify_port(struct uart_port
*port
, struct serial_struct
*ser
)
503 if (unlikely(ser
->type
!= PORT_UNKNOWN
&& ser
->type
!= PORT_MSM
))
505 if (unlikely(port
->irq
!= ser
->irq
))
510 static void msm_power(struct uart_port
*port
, unsigned int state
,
511 unsigned int oldstate
)
513 struct msm_port
*msm_port
= UART_TO_MSM(port
);
517 clk_enable(msm_port
->clk
);
520 clk_disable(msm_port
->clk
);
523 printk(KERN_ERR
"msm_serial: Unknown PM state %d\n", state
);
527 static struct uart_ops msm_uart_pops
= {
528 .tx_empty
= msm_tx_empty
,
529 .set_mctrl
= msm_set_mctrl
,
530 .get_mctrl
= msm_get_mctrl
,
531 .stop_tx
= msm_stop_tx
,
532 .start_tx
= msm_start_tx
,
533 .stop_rx
= msm_stop_rx
,
534 .enable_ms
= msm_enable_ms
,
535 .break_ctl
= msm_break_ctl
,
536 .startup
= msm_startup
,
537 .shutdown
= msm_shutdown
,
538 .set_termios
= msm_set_termios
,
540 .release_port
= msm_release_port
,
541 .request_port
= msm_request_port
,
542 .config_port
= msm_config_port
,
543 .verify_port
= msm_verify_port
,
547 static struct msm_port msm_uart_ports
[] = {
551 .ops
= &msm_uart_pops
,
552 .flags
= UPF_BOOT_AUTOCONF
,
560 .ops
= &msm_uart_pops
,
561 .flags
= UPF_BOOT_AUTOCONF
,
569 .ops
= &msm_uart_pops
,
570 .flags
= UPF_BOOT_AUTOCONF
,
577 #define UART_NR ARRAY_SIZE(msm_uart_ports)
579 static inline struct uart_port
*get_port_from_line(unsigned int line
)
581 return &msm_uart_ports
[line
].uart
;
584 #ifdef CONFIG_SERIAL_MSM_CONSOLE
586 static void msm_console_putchar(struct uart_port
*port
, int c
)
588 while (!(msm_read(port
, UART_SR
) & UART_SR_TX_READY
))
590 msm_write(port
, c
, UART_TF
);
593 static void msm_console_write(struct console
*co
, const char *s
,
596 struct uart_port
*port
;
597 struct msm_port
*msm_port
;
599 BUG_ON(co
->index
< 0 || co
->index
>= UART_NR
);
601 port
= get_port_from_line(co
->index
);
602 msm_port
= UART_TO_MSM(port
);
604 spin_lock(&port
->lock
);
605 uart_console_write(port
, s
, count
, msm_console_putchar
);
606 spin_unlock(&port
->lock
);
609 static int __init
msm_console_setup(struct console
*co
, char *options
)
611 struct uart_port
*port
;
612 int baud
, flow
, bits
, parity
;
614 if (unlikely(co
->index
>= UART_NR
|| co
->index
< 0))
617 port
= get_port_from_line(co
->index
);
619 if (unlikely(!port
->membase
))
624 msm_init_clock(port
);
627 uart_parse_options(options
, &baud
, &parity
, &bits
, &flow
);
632 msm_write(port
, UART_MR2_BITS_PER_CHAR_8
| UART_MR2_STOP_BIT_LEN_ONE
,
635 if (baud
< 300 || baud
> 115200)
637 msm_set_baud_rate(port
, baud
);
641 printk(KERN_INFO
"msm_serial: console setup on port #%d\n", port
->line
);
643 return uart_set_options(port
, co
, baud
, parity
, bits
, flow
);
646 static struct uart_driver msm_uart_driver
;
648 static struct console msm_console
= {
650 .write
= msm_console_write
,
651 .device
= uart_console_device
,
652 .setup
= msm_console_setup
,
653 .flags
= CON_PRINTBUFFER
,
655 .data
= &msm_uart_driver
,
658 #define MSM_CONSOLE (&msm_console)
661 #define MSM_CONSOLE NULL
664 static struct uart_driver msm_uart_driver
= {
665 .owner
= THIS_MODULE
,
666 .driver_name
= "msm_serial",
667 .dev_name
= "ttyMSM",
672 static int __init
msm_serial_probe(struct platform_device
*pdev
)
674 struct msm_port
*msm_port
;
675 struct resource
*resource
;
676 struct uart_port
*port
;
679 if (unlikely(pdev
->id
< 0 || pdev
->id
>= UART_NR
))
682 printk(KERN_INFO
"msm_serial: detected port #%d\n", pdev
->id
);
684 port
= get_port_from_line(pdev
->id
);
685 port
->dev
= &pdev
->dev
;
686 msm_port
= UART_TO_MSM(port
);
688 msm_port
->clk
= clk_get(&pdev
->dev
, "uart_clk");
689 if (unlikely(IS_ERR(msm_port
->clk
)))
690 return PTR_ERR(msm_port
->clk
);
691 port
->uartclk
= clk_get_rate(msm_port
->clk
);
692 printk(KERN_INFO
"uartclk = %d\n", port
->uartclk
);
695 resource
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
696 if (unlikely(!resource
))
698 port
->mapbase
= resource
->start
;
700 irq
= platform_get_irq(pdev
, 0);
701 if (unlikely(irq
< 0))
705 platform_set_drvdata(pdev
, port
);
707 return uart_add_one_port(&msm_uart_driver
, port
);
710 static int __devexit
msm_serial_remove(struct platform_device
*pdev
)
712 struct msm_port
*msm_port
= platform_get_drvdata(pdev
);
714 clk_put(msm_port
->clk
);
719 static struct platform_driver msm_platform_driver
= {
720 .remove
= msm_serial_remove
,
722 .name
= "msm_serial",
723 .owner
= THIS_MODULE
,
727 static int __init
msm_serial_init(void)
731 ret
= uart_register_driver(&msm_uart_driver
);
735 ret
= platform_driver_probe(&msm_platform_driver
, msm_serial_probe
);
737 uart_unregister_driver(&msm_uart_driver
);
739 printk(KERN_INFO
"msm_serial: driver initialized\n");
744 static void __exit
msm_serial_exit(void)
746 #ifdef CONFIG_SERIAL_MSM_CONSOLE
747 unregister_console(&msm_console
);
749 platform_driver_unregister(&msm_platform_driver
);
750 uart_unregister_driver(&msm_uart_driver
);
753 module_init(msm_serial_init
);
754 module_exit(msm_serial_exit
);
756 MODULE_AUTHOR("Robert Love <rlove@google.com>");
757 MODULE_DESCRIPTION("Driver for msm7x serial device");
758 MODULE_LICENSE("GPL");