MPC5125 PSC controller has different registers than MPC5121.
This patch was originally created by Vladimir Ermakov
https://lists.ozlabs.org/pipermail/linuxppc-dev/2011-March/088954.html
Signed-off-by: Vladimir Ermakov vooon...@gmail.com
Signed-off-by: Matteo Facchinetti matteo.facchine...@sirius-es.it
---
arch/powerpc/include/asm/mpc52xx_psc.h | 49
drivers/tty/serial/mpc52xx_uart.c | 407
2 files changed, 414 insertions(+), 42 deletions(-)
diff --git a/arch/powerpc/include/asm/mpc52xx_psc.h
b/arch/powerpc/include/asm/mpc52xx_psc.h
index 2966df6..d0ece25 100644
--- a/arch/powerpc/include/asm/mpc52xx_psc.h
+++ b/arch/powerpc/include/asm/mpc52xx_psc.h
@@ -299,4 +299,53 @@ struct mpc512x_psc_fifo {
#define rxdata_32 rxdata.rxdata_32
};
+struct mpc5125_psc {
+ u8 mr1;/* PSC + 0x00 */
+ u8 reserved0[3];
+ u8 mr2;/* PSC + 0x04 */
+ u8 reserved1[3];
+ struct {
+ u16 status; /* PSC + 0x08 */
+ u8 reserved2[2];
+ u8 clock_select; /* PSC + 0x0c */
+ u8 reserved3[3];
+ } sr_csr;
+ u8 command;/* PSC + 0x10 */
+ u8 reserved4[3];
+ union { /* PSC + 0x14 */
+ u8 buffer_8;
+ u16 buffer_16;
+ u32 buffer_32;
+ } buffer;
+ struct {
+ u8 ipcr; /* PSC + 0x18 */
+ u8 reserved5[3];
+ u8 acr;/* PSC + 0x1c */
+ u8 reserved6[3];
+ } ipcr_acr;
+ struct {
+ u16 isr;/* PSC + 0x20 */
+ u8 reserved7[2];
+ u16 imr;/* PSC + 0x24 */
+ u8 reserved8[2];
+ } isr_imr;
+ u8 ctur; /* PSC + 0x28 */
+ u8 reserved9[3];
+ u8 ctlr; /* PSC + 0x2c */
+ u8 reserved10[3];
+ u32 ccr;/* PSC + 0x30 */
+ u32 ac97slots; /* PSC + 0x34 */
+ u32 ac97cmd;/* PSC + 0x38 */
+ u32 ac97data; /* PSC + 0x3c */
+ u8 reserved11[4];
+ u8 ip; /* PSC + 0x44 */
+ u8 reserved12[3];
+ u8 op1;/* PSC + 0x48 */
+ u8 reserved13[3];
+ u8 op0;/* PSC + 0x4c */
+ u8 reserved14[3];
+ u32 sicr; /* PSC + 0x50 */
+ u8 reserved15[4]; /* make eq. sizeof(mpc52xx_psc) */
+};
+
#endif /* __ASM_MPC52xx_PSC_H__ */
diff --git a/drivers/tty/serial/mpc52xx_uart.c
b/drivers/tty/serial/mpc52xx_uart.c
index 018bad9..3f77b9d 100644
--- a/drivers/tty/serial/mpc52xx_uart.c
+++ b/drivers/tty/serial/mpc52xx_uart.c
@@ -122,6 +122,15 @@ struct psc_ops {
void(*fifoc_uninit)(void);
void(*get_irq)(struct uart_port *, struct device_node *);
irqreturn_t (*handle_irq)(struct uart_port *port);
+ u16 (*get_status)(struct uart_port *port);
+ u8 (*get_ipcr)(struct uart_port *port);
+ void(*command)(struct uart_port *port, u8 cmd);
+ void(*set_mode)(struct uart_port *port, u8 mr1, u8 mr2);
+ void(*set_rts)(struct uart_port *port, int state);
+ void(*enable_ms)(struct uart_port *port);
+ void(*set_sicr)(struct uart_port *port, u32 val);
+ void(*set_imr)(struct uart_port *port, u16 val);
+ u8 (*get_mr1)(struct uart_port *port);
};
/* setting the prescaler and divisor reg is common for all chips */
@@ -134,6 +143,74 @@ static inline void mpc52xx_set_divisor(struct mpc52xx_psc
__iomem *psc,
out_8(psc-ctlr, divisor 0xff);
}
+static inline void mpc5125_set_divisor(struct mpc5125_psc __iomem *psc,
+ u8 prescaler, unsigned int divisor)
+{
+ /* select prescaler */
+ out_8(psc-mpc52xx_psc_clock_select, prescaler);
+ out_8(psc-ctur, divisor 8);
+ out_8(psc-ctlr, divisor 0xff);
+}
+
+static u16 mpc52xx_psc_get_status(struct uart_port *port)
+{
+ return in_be16(PSC(port)-mpc52xx_psc_status);
+}
+
+static u8 mpc52xx_psc_get_ipcr(struct uart_port *port)
+{
+ return in_8(PSC(port)-mpc52xx_psc_ipcr);
+}
+
+static void mpc52xx_psc_command(struct uart_port *port, u8 cmd)
+{
+ out_8(PSC(port)-command, cmd);
+}
+