aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorMatteo Facchinetti <matteo.facchinetti@sirius-es.it>2013-05-24 14:24:58 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-06-03 13:22:35 -0400
commit2574b27eee4f00f2773d1c209218b3f4cf34a3ca (patch)
tree505b17eacf962c3e0be4a105b9c9bab72071fc7d /drivers/tty
parent696faedd616e202f5c510cd03dcc8853c11ca6db (diff)
serial/mpc52xx_uart: prepare for adding MPC5125 PSC UART support
MPC5125 PSC controller has different register layout than MPC5121. To support MPC5125 PSC in this driver we have to provide further psc_ops functions for SoC specific register accesses. Add new register access functions to the psc_ops structure and provide MPC52xx and MPC512x specific implementation for them. Then replace remaining direct register accesses in the driver by appropriate psc_ops function calls. The subsequent patch can now add MPC5125 specific set of psc_ops functions. Signed-off-by: Vladimir Ermakov <vooon341@gmail.com> Signed-off-by: Matteo Facchinetti <matteo.facchinetti@sirius-es.it> Signed-off-by: Anatolij Gustschin <agust@denx.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/serial/mpc52xx_uart.c161
1 files changed, 119 insertions, 42 deletions
diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c
index 2c03904359b9..019ecb1c6847 100644
--- a/drivers/tty/serial/mpc52xx_uart.c
+++ b/drivers/tty/serial/mpc52xx_uart.c
@@ -112,6 +112,15 @@ struct psc_ops {
112 void (*fifoc_uninit)(void); 112 void (*fifoc_uninit)(void);
113 void (*get_irq)(struct uart_port *, struct device_node *); 113 void (*get_irq)(struct uart_port *, struct device_node *);
114 irqreturn_t (*handle_irq)(struct uart_port *port); 114 irqreturn_t (*handle_irq)(struct uart_port *port);
115 u16 (*get_status)(struct uart_port *port);
116 u8 (*get_ipcr)(struct uart_port *port);
117 void (*command)(struct uart_port *port, u8 cmd);
118 void (*set_mode)(struct uart_port *port, u8 mr1, u8 mr2);
119 void (*set_rts)(struct uart_port *port, int state);
120 void (*enable_ms)(struct uart_port *port);
121 void (*set_sicr)(struct uart_port *port, u32 val);
122 void (*set_imr)(struct uart_port *port, u16 val);
123 u8 (*get_mr1)(struct uart_port *port);
115}; 124};
116 125
117/* setting the prescaler and divisor reg is common for all chips */ 126/* setting the prescaler and divisor reg is common for all chips */
@@ -124,6 +133,65 @@ static inline void mpc52xx_set_divisor(struct mpc52xx_psc __iomem *psc,
124 out_8(&psc->ctlr, divisor & 0xff); 133 out_8(&psc->ctlr, divisor & 0xff);
125} 134}
126 135
136static u16 mpc52xx_psc_get_status(struct uart_port *port)
137{
138 return in_be16(&PSC(port)->mpc52xx_psc_status);
139}
140
141static u8 mpc52xx_psc_get_ipcr(struct uart_port *port)
142{
143 return in_8(&PSC(port)->mpc52xx_psc_ipcr);
144}
145
146static void mpc52xx_psc_command(struct uart_port *port, u8 cmd)
147{
148 out_8(&PSC(port)->command, cmd);
149}
150
151static void mpc52xx_psc_set_mode(struct uart_port *port, u8 mr1, u8 mr2)
152{
153 out_8(&PSC(port)->command, MPC52xx_PSC_SEL_MODE_REG_1);
154 out_8(&PSC(port)->mode, mr1);
155 out_8(&PSC(port)->mode, mr2);
156}
157
158static void mpc52xx_psc_set_rts(struct uart_port *port, int state)
159{
160 if (state)
161 out_8(&PSC(port)->op1, MPC52xx_PSC_OP_RTS);
162 else
163 out_8(&PSC(port)->op0, MPC52xx_PSC_OP_RTS);
164}
165
166static void mpc52xx_psc_enable_ms(struct uart_port *port)
167{
168 struct mpc52xx_psc __iomem *psc = PSC(port);
169
170 /* clear D_*-bits by reading them */
171 in_8(&psc->mpc52xx_psc_ipcr);
172 /* enable CTS and DCD as IPC interrupts */
173 out_8(&psc->mpc52xx_psc_acr, MPC52xx_PSC_IEC_CTS | MPC52xx_PSC_IEC_DCD);
174
175 port->read_status_mask |= MPC52xx_PSC_IMR_IPC;
176 out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
177}
178
179static void mpc52xx_psc_set_sicr(struct uart_port *port, u32 val)
180{
181 out_be32(&PSC(port)->sicr, val);
182}
183
184static void mpc52xx_psc_set_imr(struct uart_port *port, u16 val)
185{
186 out_be16(&PSC(port)->mpc52xx_psc_imr, val);
187}
188
189static u8 mpc52xx_psc_get_mr1(struct uart_port *port)
190{
191 out_8(&PSC(port)->command, MPC52xx_PSC_SEL_MODE_REG_1);
192 return in_8(&PSC(port)->mode);
193}
194
127#ifdef CONFIG_PPC_MPC52xx 195#ifdef CONFIG_PPC_MPC52xx
128#define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1)) 196#define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1))
129static void mpc52xx_psc_fifo_init(struct uart_port *port) 197static void mpc52xx_psc_fifo_init(struct uart_port *port)
@@ -294,6 +362,15 @@ static struct psc_ops mpc52xx_psc_ops = {
294 .set_baudrate = mpc5200_psc_set_baudrate, 362 .set_baudrate = mpc5200_psc_set_baudrate,
295 .get_irq = mpc52xx_psc_get_irq, 363 .get_irq = mpc52xx_psc_get_irq,
296 .handle_irq = mpc52xx_psc_handle_irq, 364 .handle_irq = mpc52xx_psc_handle_irq,
365 .get_status = mpc52xx_psc_get_status,
366 .get_ipcr = mpc52xx_psc_get_ipcr,
367 .command = mpc52xx_psc_command,
368 .set_mode = mpc52xx_psc_set_mode,
369 .set_rts = mpc52xx_psc_set_rts,
370 .enable_ms = mpc52xx_psc_enable_ms,
371 .set_sicr = mpc52xx_psc_set_sicr,
372 .set_imr = mpc52xx_psc_set_imr,
373 .get_mr1 = mpc52xx_psc_get_mr1,
297}; 374};
298 375
299static struct psc_ops mpc5200b_psc_ops = { 376static struct psc_ops mpc5200b_psc_ops = {
@@ -315,6 +392,15 @@ static struct psc_ops mpc5200b_psc_ops = {
315 .set_baudrate = mpc5200b_psc_set_baudrate, 392 .set_baudrate = mpc5200b_psc_set_baudrate,
316 .get_irq = mpc52xx_psc_get_irq, 393 .get_irq = mpc52xx_psc_get_irq,
317 .handle_irq = mpc52xx_psc_handle_irq, 394 .handle_irq = mpc52xx_psc_handle_irq,
395 .get_status = mpc52xx_psc_get_status,
396 .get_ipcr = mpc52xx_psc_get_ipcr,
397 .command = mpc52xx_psc_command,
398 .set_mode = mpc52xx_psc_set_mode,
399 .set_rts = mpc52xx_psc_set_rts,
400 .enable_ms = mpc52xx_psc_enable_ms,
401 .set_sicr = mpc52xx_psc_set_sicr,
402 .set_imr = mpc52xx_psc_set_imr,
403 .get_mr1 = mpc52xx_psc_get_mr1,
318}; 404};
319 405
320#endif /* CONFIG_MPC52xx */ 406#endif /* CONFIG_MPC52xx */
@@ -585,8 +671,18 @@ static struct psc_ops mpc512x_psc_ops = {
585 .fifoc_uninit = mpc512x_psc_fifoc_uninit, 671 .fifoc_uninit = mpc512x_psc_fifoc_uninit,
586 .get_irq = mpc512x_psc_get_irq, 672 .get_irq = mpc512x_psc_get_irq,
587 .handle_irq = mpc512x_psc_handle_irq, 673 .handle_irq = mpc512x_psc_handle_irq,
674 .get_status = mpc52xx_psc_get_status,
675 .get_ipcr = mpc52xx_psc_get_ipcr,
676 .command = mpc52xx_psc_command,
677 .set_mode = mpc52xx_psc_set_mode,
678 .set_rts = mpc52xx_psc_set_rts,
679 .enable_ms = mpc52xx_psc_enable_ms,
680 .set_sicr = mpc52xx_psc_set_sicr,
681 .set_imr = mpc52xx_psc_set_imr,
682 .get_mr1 = mpc52xx_psc_get_mr1,
588}; 683};
589#endif 684#endif /* CONFIG_PPC_MPC512x */
685
590 686
591static const struct psc_ops *psc_ops; 687static const struct psc_ops *psc_ops;
592 688
@@ -603,17 +699,14 @@ mpc52xx_uart_tx_empty(struct uart_port *port)
603static void 699static void
604mpc52xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) 700mpc52xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
605{ 701{
606 if (mctrl & TIOCM_RTS) 702 psc_ops->set_rts(port, mctrl & TIOCM_RTS);
607 out_8(&PSC(port)->op1, MPC52xx_PSC_OP_RTS);
608 else
609 out_8(&PSC(port)->op0, MPC52xx_PSC_OP_RTS);
610} 703}
611 704
612static unsigned int 705static unsigned int
613mpc52xx_uart_get_mctrl(struct uart_port *port) 706mpc52xx_uart_get_mctrl(struct uart_port *port)
614{ 707{
615 unsigned int ret = TIOCM_DSR; 708 unsigned int ret = TIOCM_DSR;
616 u8 status = in_8(&PSC(port)->mpc52xx_psc_ipcr); 709 u8 status = psc_ops->get_ipcr(port);
617 710
618 if (!(status & MPC52xx_PSC_CTS)) 711 if (!(status & MPC52xx_PSC_CTS))
619 ret |= TIOCM_CTS; 712 ret |= TIOCM_CTS;
@@ -663,15 +756,7 @@ mpc52xx_uart_stop_rx(struct uart_port *port)
663static void 756static void
664mpc52xx_uart_enable_ms(struct uart_port *port) 757mpc52xx_uart_enable_ms(struct uart_port *port)
665{ 758{
666 struct mpc52xx_psc __iomem *psc = PSC(port); 759 psc_ops->enable_ms(port);
667
668 /* clear D_*-bits by reading them */
669 in_8(&psc->mpc52xx_psc_ipcr);
670 /* enable CTS and DCD as IPC interrupts */
671 out_8(&psc->mpc52xx_psc_acr, MPC52xx_PSC_IEC_CTS | MPC52xx_PSC_IEC_DCD);
672
673 port->read_status_mask |= MPC52xx_PSC_IMR_IPC;
674 out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
675} 760}
676 761
677static void 762static void
@@ -681,9 +766,9 @@ mpc52xx_uart_break_ctl(struct uart_port *port, int ctl)
681 spin_lock_irqsave(&port->lock, flags); 766 spin_lock_irqsave(&port->lock, flags);
682 767
683 if (ctl == -1) 768 if (ctl == -1)
684 out_8(&PSC(port)->command, MPC52xx_PSC_START_BRK); 769 psc_ops->command(port, MPC52xx_PSC_START_BRK);
685 else 770 else
686 out_8(&PSC(port)->command, MPC52xx_PSC_STOP_BRK); 771 psc_ops->command(port, MPC52xx_PSC_STOP_BRK);
687 772
688 spin_unlock_irqrestore(&port->lock, flags); 773 spin_unlock_irqrestore(&port->lock, flags);
689} 774}
@@ -691,7 +776,6 @@ mpc52xx_uart_break_ctl(struct uart_port *port, int ctl)
691static int 776static int
692mpc52xx_uart_startup(struct uart_port *port) 777mpc52xx_uart_startup(struct uart_port *port)
693{ 778{
694 struct mpc52xx_psc __iomem *psc = PSC(port);
695 int ret; 779 int ret;
696 780
697 if (psc_ops->clock) { 781 if (psc_ops->clock) {
@@ -707,15 +791,15 @@ mpc52xx_uart_startup(struct uart_port *port)
707 return ret; 791 return ret;
708 792
709 /* Reset/activate the port, clear and enable interrupts */ 793 /* Reset/activate the port, clear and enable interrupts */
710 out_8(&psc->command, MPC52xx_PSC_RST_RX); 794 psc_ops->command(port, MPC52xx_PSC_RST_RX);
711 out_8(&psc->command, MPC52xx_PSC_RST_TX); 795 psc_ops->command(port, MPC52xx_PSC_RST_TX);
712 796
713 out_be32(&psc->sicr, 0); /* UART mode DCD ignored */ 797 psc_ops->set_sicr(port, 0); /* UART mode DCD ignored */
714 798
715 psc_ops->fifo_init(port); 799 psc_ops->fifo_init(port);
716 800
717 out_8(&psc->command, MPC52xx_PSC_TX_ENABLE); 801 psc_ops->command(port, MPC52xx_PSC_TX_ENABLE);
718 out_8(&psc->command, MPC52xx_PSC_RX_ENABLE); 802 psc_ops->command(port, MPC52xx_PSC_RX_ENABLE);
719 803
720 return 0; 804 return 0;
721} 805}
@@ -723,15 +807,13 @@ mpc52xx_uart_startup(struct uart_port *port)
723static void 807static void
724mpc52xx_uart_shutdown(struct uart_port *port) 808mpc52xx_uart_shutdown(struct uart_port *port)
725{ 809{
726 struct mpc52xx_psc __iomem *psc = PSC(port);
727
728 /* Shut down the port. Leave TX active if on a console port */ 810 /* Shut down the port. Leave TX active if on a console port */
729 out_8(&psc->command, MPC52xx_PSC_RST_RX); 811 psc_ops->command(port, MPC52xx_PSC_RST_RX);
730 if (!uart_console(port)) 812 if (!uart_console(port))
731 out_8(&psc->command, MPC52xx_PSC_RST_TX); 813 psc_ops->command(port, MPC52xx_PSC_RST_TX);
732 814
733 port->read_status_mask = 0; 815 port->read_status_mask = 0;
734 out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); 816 psc_ops->set_imr(port, port->read_status_mask);
735 817
736 if (psc_ops->clock) 818 if (psc_ops->clock)
737 psc_ops->clock(port, 0); 819 psc_ops->clock(port, 0);
@@ -744,7 +826,6 @@ static void
744mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new, 826mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
745 struct ktermios *old) 827 struct ktermios *old)
746{ 828{
747 struct mpc52xx_psc __iomem *psc = PSC(port);
748 unsigned long flags; 829 unsigned long flags;
749 unsigned char mr1, mr2; 830 unsigned char mr1, mr2;
750 unsigned int j; 831 unsigned int j;
@@ -808,13 +889,11 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
808 "Some chars may have been lost.\n"); 889 "Some chars may have been lost.\n");
809 890
810 /* Reset the TX & RX */ 891 /* Reset the TX & RX */
811 out_8(&psc->command, MPC52xx_PSC_RST_RX); 892 psc_ops->command(port, MPC52xx_PSC_RST_RX);
812 out_8(&psc->command, MPC52xx_PSC_RST_TX); 893 psc_ops->command(port, MPC52xx_PSC_RST_TX);
813 894
814 /* Send new mode settings */ 895 /* Send new mode settings */
815 out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); 896 psc_ops->set_mode(port, mr1, mr2);
816 out_8(&psc->mode, mr1);
817 out_8(&psc->mode, mr2);
818 baud = psc_ops->set_baudrate(port, new, old); 897 baud = psc_ops->set_baudrate(port, new, old);
819 898
820 /* Update the per-port timeout */ 899 /* Update the per-port timeout */
@@ -824,8 +903,8 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
824 mpc52xx_uart_enable_ms(port); 903 mpc52xx_uart_enable_ms(port);
825 904
826 /* Reenable TX & RX */ 905 /* Reenable TX & RX */
827 out_8(&psc->command, MPC52xx_PSC_TX_ENABLE); 906 psc_ops->command(port, MPC52xx_PSC_TX_ENABLE);
828 out_8(&psc->command, MPC52xx_PSC_RX_ENABLE); 907 psc_ops->command(port, MPC52xx_PSC_RX_ENABLE);
829 908
830 /* We're all set, release the lock */ 909 /* We're all set, release the lock */
831 spin_unlock_irqrestore(&port->lock, flags); 910 spin_unlock_irqrestore(&port->lock, flags);
@@ -953,7 +1032,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
953 flag = TTY_NORMAL; 1032 flag = TTY_NORMAL;
954 port->icount.rx++; 1033 port->icount.rx++;
955 1034
956 status = in_be16(&PSC(port)->mpc52xx_psc_status); 1035 status = psc_ops->get_status(port);
957 1036
958 if (status & (MPC52xx_PSC_SR_PE | 1037 if (status & (MPC52xx_PSC_SR_PE |
959 MPC52xx_PSC_SR_FE | 1038 MPC52xx_PSC_SR_FE |
@@ -973,7 +1052,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
973 } 1052 }
974 1053
975 /* Clear error condition */ 1054 /* Clear error condition */
976 out_8(&PSC(port)->command, MPC52xx_PSC_RST_ERR_STAT); 1055 psc_ops->command(port, MPC52xx_PSC_RST_ERR_STAT);
977 1056
978 } 1057 }
979 tty_insert_flip_char(tport, ch, flag); 1058 tty_insert_flip_char(tport, ch, flag);
@@ -1056,7 +1135,7 @@ mpc5xxx_uart_process_int(struct uart_port *port)
1056 if (psc_ops->tx_rdy(port)) 1135 if (psc_ops->tx_rdy(port))
1057 keepgoing |= mpc52xx_uart_int_tx_chars(port); 1136 keepgoing |= mpc52xx_uart_int_tx_chars(port);
1058 1137
1059 status = in_8(&PSC(port)->mpc52xx_psc_ipcr); 1138 status = psc_ops->get_ipcr(port);
1060 if (status & MPC52xx_PSC_D_DCD) 1139 if (status & MPC52xx_PSC_D_DCD)
1061 uart_handle_dcd_change(port, !(status & MPC52xx_PSC_DCD)); 1140 uart_handle_dcd_change(port, !(status & MPC52xx_PSC_DCD));
1062 1141
@@ -1097,14 +1176,12 @@ static void __init
1097mpc52xx_console_get_options(struct uart_port *port, 1176mpc52xx_console_get_options(struct uart_port *port,
1098 int *baud, int *parity, int *bits, int *flow) 1177 int *baud, int *parity, int *bits, int *flow)
1099{ 1178{
1100 struct mpc52xx_psc __iomem *psc = PSC(port);
1101 unsigned char mr1; 1179 unsigned char mr1;
1102 1180
1103 pr_debug("mpc52xx_console_get_options(port=%p)\n", port); 1181 pr_debug("mpc52xx_console_get_options(port=%p)\n", port);
1104 1182
1105 /* Read the mode registers */ 1183 /* Read the mode registers */
1106 out_8(&psc->command, MPC52xx_PSC_SEL_MODE_REG_1); 1184 mr1 = psc_ops->get_mr1(port);
1107 mr1 = in_8(&psc->mode);
1108 1185
1109 /* CT{U,L}R are write-only ! */ 1186 /* CT{U,L}R are write-only ! */
1110 *baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD; 1187 *baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;