aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/Kconfig2
-rw-r--r--arch/powerpc/boot/dts/mpc5121ads.dts122
-rw-r--r--arch/powerpc/platforms/512x/Kconfig20
-rw-r--r--arch/powerpc/platforms/512x/Makefile4
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_ads.c104
-rw-r--r--arch/powerpc/platforms/Kconfig1
-rw-r--r--arch/powerpc/platforms/Kconfig.cputype6
-rw-r--r--arch/powerpc/platforms/Makefile1
-rw-r--r--drivers/serial/Kconfig12
-rw-r--r--drivers/serial/mpc52xx_uart.c431
-rw-r--r--include/asm-powerpc/mpc512x.h22
-rw-r--r--include/asm-powerpc/mpc52xx_psc.h48
12 files changed, 694 insertions, 79 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index cf030b004415..1348bbc92510 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -512,7 +512,7 @@ config PCI
512 bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \ 512 bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \
513 || PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \ 513 || PPC_MPC52xx || (EMBEDDED && (PPC_PSERIES || PPC_ISERIES)) \
514 || PPC_PS3 || 44x 514 || PPC_PS3 || 44x
515 default y if !40x && !CPM2 && !8xx && !PPC_83xx \ 515 default y if !40x && !CPM2 && !8xx && !PPC_MPC512x && !PPC_83xx \
516 && !PPC_85xx && !PPC_86xx 516 && !PPC_85xx && !PPC_86xx
517 default PCI_PERMEDIA if !4xx && !CPM2 && !8xx 517 default PCI_PERMEDIA if !4xx && !CPM2 && !8xx
518 default PCI_QSPAN if !4xx && !CPM2 && 8xx 518 default PCI_QSPAN if !4xx && !CPM2 && 8xx
diff --git a/arch/powerpc/boot/dts/mpc5121ads.dts b/arch/powerpc/boot/dts/mpc5121ads.dts
new file mode 100644
index 000000000000..94ad7b2b241e
--- /dev/null
+++ b/arch/powerpc/boot/dts/mpc5121ads.dts
@@ -0,0 +1,122 @@
1/*
2 * MPC5121E MDS Device Tree Source
3 *
4 * Copyright 2007 Freescale Semiconductor Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12/dts-v1/;
13
14/ {
15 model = "mpc5121ads";
16 compatible = "fsl,mpc5121ads";
17 #address-cells = <1>;
18 #size-cells = <1>;
19
20 cpus {
21 #address-cells = <1>;
22 #size-cells = <0>;
23
24 PowerPC,5121@0 {
25 device_type = "cpu";
26 reg = <0>;
27 d-cache-line-size = <0x20>; // 32 bytes
28 i-cache-line-size = <0x20>; // 32 bytes
29 d-cache-size = <0x8000>; // L1, 32K
30 i-cache-size = <0x8000>; // L1, 32K
31 timebase-frequency = <49500000>;// 49.5 MHz (csb/4)
32 bus-frequency = <198000000>; // 198 MHz csb bus
33 clock-frequency = <396000000>; // 396 MHz ppc core
34 };
35 };
36
37 memory {
38 device_type = "memory";
39 reg = <0x00000000 0x10000000>; // 256MB at 0
40 };
41
42 localbus@80000020 {
43 compatible = "fsl,mpc5121ads-localbus";
44 #address-cells = <2>;
45 #size-cells = <1>;
46 reg = <0x80000020 0x40>;
47
48 ranges = <0x0 0x0 0xfc000000 0x04000000
49 0x2 0x0 0x82000000 0x00008000>;
50
51 flash@0,0 {
52 compatible = "cfi-flash";
53 reg = <0 0x0 0x4000000>;
54 bank-width = <4>;
55 device-width = <1>;
56 };
57
58 board-control@2,0 {
59 compatible = "fsl,mpc5121ads-cpld";
60 reg = <0x2 0x0 0x8000>;
61 };
62 };
63
64 soc@80000000 {
65 compatible = "fsl,mpc5121-immr";
66 #address-cells = <1>;
67 #size-cells = <1>;
68 #interrupt-cells = <2>;
69 ranges = <0x0 0x80000000 0x400000>;
70 reg = <0x80000000 0x400000>;
71 bus-frequency = <66000000>; // 66 MHz ips bus
72
73
74 // IPIC
75 // interrupts cell = <intr #, sense>
76 // sense values match linux IORESOURCE_IRQ_* defines:
77 // sense == 8: Level, low assertion
78 // sense == 2: Edge, high-to-low change
79 //
80 ipic: interrupt-controller@c00 {
81 compatible = "fsl,mpc5121-ipic", "fsl,ipic";
82 interrupt-controller;
83 #address-cells = <0>;
84 #interrupt-cells = <2>;
85 reg = <0xc00 0x100>;
86 };
87
88 // 512x PSCs are not 52xx PSCs compatible
89 // PSC3 serial port A aka ttyPSC0
90 serial@11300 {
91 device_type = "serial";
92 compatible = "fsl,mpc5121-psc-uart";
93 // Logical port assignment needed until driver
94 // learns to use aliases
95 port-number = <0>;
96 cell-index = <3>;
97 reg = <0x11300 0x100>;
98 interrupts = <0x28 0x8>; // actually the fifo irq
99 interrupt-parent = < &ipic >;
100 };
101
102 // PSC4 serial port B aka ttyPSC1
103 serial@11400 {
104 device_type = "serial";
105 compatible = "fsl,mpc5121-psc-uart";
106 // Logical port assignment needed until driver
107 // learns to use aliases
108 port-number = <1>;
109 cell-index = <4>;
110 reg = <0x11400 0x100>;
111 interrupts = <0x28 0x8>; // actually the fifo irq
112 interrupt-parent = < &ipic >;
113 };
114
115 pscsfifo@11f00 {
116 compatible = "fsl,mpc5121-psc-fifo";
117 reg = <0x11f00 0x100>;
118 interrupts = <0x28 0x8>;
119 interrupt-parent = < &ipic >;
120 };
121 };
122};
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig
new file mode 100644
index 000000000000..c6fa49e23dc0
--- /dev/null
+++ b/arch/powerpc/platforms/512x/Kconfig
@@ -0,0 +1,20 @@
1config PPC_MPC512x
2 bool
3 select FSL_SOC
4 select IPIC
5 default n
6
7config PPC_MPC5121
8 bool
9 select PPC_MPC512x
10 default n
11
12config MPC5121_ADS
13 bool "Freescale MPC5121E ADS"
14 depends on PPC_MULTIPLATFORM && PPC32
15 select DEFAULT_UIMAGE
16 select WANT_DEVICE_TREE
17 select PPC_MPC5121
18 help
19 This option enables support for the MPC5121E ADS board.
20 default n
diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile
new file mode 100644
index 000000000000..232c89f2039a
--- /dev/null
+++ b/arch/powerpc/platforms/512x/Makefile
@@ -0,0 +1,4 @@
1#
2# Makefile for the Freescale PowerPC 512x linux kernel.
3#
4obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads.c b/arch/powerpc/platforms/512x/mpc5121_ads.c
new file mode 100644
index 000000000000..50bd3a319022
--- /dev/null
+++ b/arch/powerpc/platforms/512x/mpc5121_ads.c
@@ -0,0 +1,104 @@
1/*
2 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: John Rigby, <jrigby@freescale.com>, Thur Mar 29 2007
5 *
6 * Description:
7 * MPC5121 ADS board setup
8 *
9 * This is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 */
15
16#include <linux/kernel.h>
17#include <linux/io.h>
18#include <linux/irq.h>
19#include <linux/of_platform.h>
20
21#include <asm/machdep.h>
22#include <asm/ipic.h>
23#include <asm/prom.h>
24#include <asm/time.h>
25
26/**
27 * mpc512x_find_ips_freq - Find the IPS bus frequency for a device
28 * @node: device node
29 *
30 * Returns IPS bus frequency, or 0 if the bus frequency cannot be found.
31 */
32unsigned long
33mpc512x_find_ips_freq(struct device_node *node)
34{
35 struct device_node *np;
36 const unsigned int *p_ips_freq = NULL;
37
38 of_node_get(node);
39 while (node) {
40 p_ips_freq = of_get_property(node, "bus-frequency", NULL);
41 if (p_ips_freq)
42 break;
43
44 np = of_get_parent(node);
45 of_node_put(node);
46 node = np;
47 }
48 if (node)
49 of_node_put(node);
50
51 return p_ips_freq ? *p_ips_freq : 0;
52}
53EXPORT_SYMBOL(mpc512x_find_ips_freq);
54
55static struct of_device_id __initdata of_bus_ids[] = {
56 { .name = "soc", },
57 { .name = "localbus", },
58 {},
59};
60
61static void __init mpc5121_ads_declare_of_platform_devices(void)
62{
63 /* Find every child of the SOC node and add it to of_platform */
64 if (of_platform_bus_probe(NULL, of_bus_ids, NULL))
65 printk(KERN_ERR __FILE__ ": "
66 "Error while probing of_platform bus\n");
67}
68
69static void __init mpc5121_ads_init_IRQ(void)
70{
71 struct device_node *np;
72
73 np = of_find_compatible_node(NULL, NULL, "fsl,ipic");
74 if (!np)
75 return;
76
77 ipic_init(np, 0);
78 of_node_put(np);
79
80 /*
81 * Initialize the default interrupt mapping priorities,
82 * in case the boot rom changed something on us.
83 */
84 ipic_set_default_priority();
85}
86
87/*
88 * Called very early, MMU is off, device-tree isn't unflattened
89 */
90static int __init mpc5121_ads_probe(void)
91{
92 unsigned long root = of_get_flat_dt_root();
93
94 return of_flat_dt_is_compatible(root, "fsl,mpc5121ads");
95}
96
97define_machine(mpc5121_ads) {
98 .name = "MPC5121 ADS",
99 .probe = mpc5121_ads_probe,
100 .init = mpc5121_ads_declare_of_platform_devices,
101 .init_IRQ = mpc5121_ads_init_IRQ,
102 .get_irq = ipic_get_irq,
103 .calibrate_decr = generic_calibrate_decr,
104};
diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig
index 045b8c80eeaf..fcedbec07f94 100644
--- a/arch/powerpc/platforms/Kconfig
+++ b/arch/powerpc/platforms/Kconfig
@@ -42,6 +42,7 @@ config CLASSIC32
42source "arch/powerpc/platforms/pseries/Kconfig" 42source "arch/powerpc/platforms/pseries/Kconfig"
43source "arch/powerpc/platforms/iseries/Kconfig" 43source "arch/powerpc/platforms/iseries/Kconfig"
44source "arch/powerpc/platforms/chrp/Kconfig" 44source "arch/powerpc/platforms/chrp/Kconfig"
45source "arch/powerpc/platforms/512x/Kconfig"
45source "arch/powerpc/platforms/52xx/Kconfig" 46source "arch/powerpc/platforms/52xx/Kconfig"
46source "arch/powerpc/platforms/powermac/Kconfig" 47source "arch/powerpc/platforms/powermac/Kconfig"
47source "arch/powerpc/platforms/prep/Kconfig" 48source "arch/powerpc/platforms/prep/Kconfig"
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index eea2e7049fed..69941ba70975 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -14,7 +14,7 @@ choice
14 There are five families of 32 bit PowerPC chips supported. 14 There are five families of 32 bit PowerPC chips supported.
15 The most common ones are the desktop and server CPUs (601, 603, 15 The most common ones are the desktop and server CPUs (601, 603,
16 604, 740, 750, 74xx) CPUs from Freescale and IBM, with their 16 604, 740, 750, 74xx) CPUs from Freescale and IBM, with their
17 embedded 52xx/82xx/83xx/86xx counterparts. 17 embedded 512x/52xx/82xx/83xx/86xx counterparts.
18 The other embeeded parts, namely 4xx, 8xx, e200 (55xx) and e500 18 The other embeeded parts, namely 4xx, 8xx, e200 (55xx) and e500
19 (85xx) each form a family of their own that is not compatible 19 (85xx) each form a family of their own that is not compatible
20 with the others. 20 with the others.
@@ -22,7 +22,7 @@ choice
22 If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx. 22 If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx.
23 23
24config 6xx 24config 6xx
25 bool "52xx/6xx/7xx/74xx/82xx/83xx/86xx" 25 bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx"
26 select PPC_FPU 26 select PPC_FPU
27 27
28config PPC_85xx 28config PPC_85xx
@@ -225,7 +225,7 @@ config NR_CPUS
225 225
226config NOT_COHERENT_CACHE 226config NOT_COHERENT_CACHE
227 bool 227 bool
228 depends on 4xx || 8xx || E200 228 depends on 4xx || 8xx || E200 || PPC_MPC512x
229 default y 229 default y
230 230
231config CHECK_CACHE_COHERENCY 231config CHECK_CACHE_COHERENCY
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index 6d9079da5f5a..a984894466d9 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -11,6 +11,7 @@ endif
11obj-$(CONFIG_PPC_CHRP) += chrp/ 11obj-$(CONFIG_PPC_CHRP) += chrp/
12obj-$(CONFIG_40x) += 40x/ 12obj-$(CONFIG_40x) += 40x/
13obj-$(CONFIG_44x) += 44x/ 13obj-$(CONFIG_44x) += 44x/
14obj-$(CONFIG_PPC_MPC512x) += 512x/
14obj-$(CONFIG_PPC_MPC52xx) += 52xx/ 15obj-$(CONFIG_PPC_MPC52xx) += 52xx/
15obj-$(CONFIG_PPC_8xx) += 8xx/ 16obj-$(CONFIG_PPC_8xx) += 8xx/
16obj-$(CONFIG_PPC_82xx) += 82xx/ 17obj-$(CONFIG_PPC_82xx) += 82xx/
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 4fa7927997ad..ddfb1eab7363 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -1138,17 +1138,17 @@ config SERIAL_SGI_L1_CONSOLE
1138 say Y. Otherwise, say N. 1138 say Y. Otherwise, say N.
1139 1139
1140config SERIAL_MPC52xx 1140config SERIAL_MPC52xx
1141 tristate "Freescale MPC52xx family PSC serial support" 1141 tristate "Freescale MPC52xx/MPC512x family PSC serial support"
1142 depends on PPC_MPC52xx 1142 depends on PPC_MPC52xx || PPC_MPC512x
1143 select SERIAL_CORE 1143 select SERIAL_CORE
1144 help 1144 help
1145 This drivers support the MPC52xx PSC serial ports. If you would 1145 This driver supports MPC52xx and MPC512x PSC serial ports. If you would
1146 like to use them, you must answer Y or M to this option. Not that 1146 like to use them, you must answer Y or M to this option. Note that
1147 for use as console, it must be included in kernel and not as a 1147 for use as console, it must be included in kernel and not as a
1148 module. 1148 module.
1149 1149
1150config SERIAL_MPC52xx_CONSOLE 1150config SERIAL_MPC52xx_CONSOLE
1151 bool "Console on a Freescale MPC52xx family PSC serial port" 1151 bool "Console on a Freescale MPC52xx/MPC512x family PSC serial port"
1152 depends on SERIAL_MPC52xx=y 1152 depends on SERIAL_MPC52xx=y
1153 select SERIAL_CORE_CONSOLE 1153 select SERIAL_CORE_CONSOLE
1154 help 1154 help
@@ -1156,7 +1156,7 @@ config SERIAL_MPC52xx_CONSOLE
1156 of the Freescale MPC52xx family as a console. 1156 of the Freescale MPC52xx family as a console.
1157 1157
1158config SERIAL_MPC52xx_CONSOLE_BAUD 1158config SERIAL_MPC52xx_CONSOLE_BAUD
1159 int "Freescale MPC52xx family PSC serial port baud" 1159 int "Freescale MPC52xx/MPC512x family PSC serial port baud"
1160 depends on SERIAL_MPC52xx_CONSOLE=y 1160 depends on SERIAL_MPC52xx_CONSOLE=y
1161 default "9600" 1161 default "9600"
1162 help 1162 help
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 3c4d29e59b2c..821facd10bbc 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -16,6 +16,9 @@
16 * Some of the code has been inspired/copied from the 2.4 code written 16 * Some of the code has been inspired/copied from the 2.4 code written
17 * by Dale Farnsworth <dfarnsworth@mvista.com>. 17 * by Dale Farnsworth <dfarnsworth@mvista.com>.
18 * 18 *
19 * Copyright (C) 2008 Freescale Semiconductor Inc.
20 * John Rigby <jrigby@gmail.com>
21 * Added support for MPC5121
19 * Copyright (C) 2006 Secret Lab Technologies Ltd. 22 * Copyright (C) 2006 Secret Lab Technologies Ltd.
20 * Grant Likely <grant.likely@secretlab.ca> 23 * Grant Likely <grant.likely@secretlab.ca>
21 * Copyright (C) 2004-2006 Sylvain Munaut <tnt@246tNt.com> 24 * Copyright (C) 2004-2006 Sylvain Munaut <tnt@246tNt.com>
@@ -67,7 +70,6 @@
67#include <linux/serial.h> 70#include <linux/serial.h>
68#include <linux/sysrq.h> 71#include <linux/sysrq.h>
69#include <linux/console.h> 72#include <linux/console.h>
70
71#include <linux/delay.h> 73#include <linux/delay.h>
72#include <linux/io.h> 74#include <linux/io.h>
73 75
@@ -79,6 +81,7 @@
79#endif 81#endif
80 82
81#include <asm/mpc52xx.h> 83#include <asm/mpc52xx.h>
84#include <asm/mpc512x.h>
82#include <asm/mpc52xx_psc.h> 85#include <asm/mpc52xx_psc.h>
83 86
84#if defined(CONFIG_SERIAL_MPC52xx_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 87#if defined(CONFIG_SERIAL_MPC52xx_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
@@ -111,8 +114,8 @@ static struct device_node *mpc52xx_uart_nodes[MPC52xx_PSC_MAXNUM];
111static void mpc52xx_uart_of_enumerate(void); 114static void mpc52xx_uart_of_enumerate(void);
112#endif 115#endif
113 116
117
114#define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase)) 118#define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase))
115#define FIFO(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1))
116 119
117 120
118/* Forward declaration of the interruption handling routine */ 121/* Forward declaration of the interruption handling routine */
@@ -130,13 +133,324 @@ static irqreturn_t mpc52xx_uart_int(int irq, void *dev_id);
130 133
131#if defined(CONFIG_PPC_MERGE) 134#if defined(CONFIG_PPC_MERGE)
132static struct of_device_id mpc52xx_uart_of_match[] = { 135static struct of_device_id mpc52xx_uart_of_match[] = {
133 { .type = "serial", .compatible = "fsl,mpc5200-psc-uart", }, 136#ifdef CONFIG_PPC_MPC52xx
134 { .type = "serial", .compatible = "mpc5200-psc-uart", }, /* lite5200 */ 137 { .compatible = "fsl,mpc5200-psc-uart", .data = &mpc52xx_psc_ops, },
135 { .type = "serial", .compatible = "mpc5200-serial", }, /* efika */ 138 /* binding used by old lite5200 device trees: */
139 { .compatible = "mpc5200-psc-uart", .data = &mpc52xx_psc_ops, },
140 /* binding used by efika: */
141 { .compatible = "mpc5200-serial", .data = &mpc52xx_psc_ops, },
142#endif
143#ifdef CONFIG_PPC_MPC512x
144 { .compatible = "fsl,mpc5121-psc-uart", .data = &mpc512x_psc_ops, },
145 {},
146#endif
147};
148#if defined(CONFIG_PPC_MERGE)
149static const struct of_device_id mpc52xx_uart_of_match[] = {
150 {.type = "serial",
151 .compatible = "mpc5200-psc-uart",
152#endif
136 {}, 153 {},
137}; 154};
138#endif 155#endif
139 156
157#endif
158
159/* ======================================================================== */
160/* PSC fifo operations for isolating differences between 52xx and 512x */
161/* ======================================================================== */
162
163struct psc_ops {
164 void (*fifo_init)(struct uart_port *port);
165 int (*raw_rx_rdy)(struct uart_port *port);
166 int (*raw_tx_rdy)(struct uart_port *port);
167 int (*rx_rdy)(struct uart_port *port);
168 int (*tx_rdy)(struct uart_port *port);
169 int (*tx_empty)(struct uart_port *port);
170 void (*stop_rx)(struct uart_port *port);
171 void (*start_tx)(struct uart_port *port);
172 void (*stop_tx)(struct uart_port *port);
173 void (*rx_clr_irq)(struct uart_port *port);
174 void (*tx_clr_irq)(struct uart_port *port);
175 void (*write_char)(struct uart_port *port, unsigned char c);
176 unsigned char (*read_char)(struct uart_port *port);
177 void (*cw_disable_ints)(struct uart_port *port);
178 void (*cw_restore_ints)(struct uart_port *port);
179 unsigned long (*getuartclk)(void *p);
180};
181
182#ifdef CONFIG_PPC_MPC52xx
183#define FIFO_52xx(port) ((struct mpc52xx_psc_fifo __iomem *)(PSC(port)+1))
184static void mpc52xx_psc_fifo_init(struct uart_port *port)
185{
186 struct mpc52xx_psc __iomem *psc = PSC(port);
187 struct mpc52xx_psc_fifo __iomem *fifo = FIFO_52xx(port);
188
189 /* /32 prescaler */
190 out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00);
191
192 out_8(&fifo->rfcntl, 0x00);
193 out_be16(&fifo->rfalarm, 0x1ff);
194 out_8(&fifo->tfcntl, 0x07);
195 out_be16(&fifo->tfalarm, 0x80);
196
197 port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY;
198 out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
199}
200
201static int mpc52xx_psc_raw_rx_rdy(struct uart_port *port)
202{
203 return in_be16(&PSC(port)->mpc52xx_psc_status)
204 & MPC52xx_PSC_SR_RXRDY;
205}
206
207static int mpc52xx_psc_raw_tx_rdy(struct uart_port *port)
208{
209 return in_be16(&PSC(port)->mpc52xx_psc_status)
210 & MPC52xx_PSC_SR_TXRDY;
211}
212
213
214static int mpc52xx_psc_rx_rdy(struct uart_port *port)
215{
216 return in_be16(&PSC(port)->mpc52xx_psc_isr)
217 & port->read_status_mask
218 & MPC52xx_PSC_IMR_RXRDY;
219}
220
221static int mpc52xx_psc_tx_rdy(struct uart_port *port)
222{
223 return in_be16(&PSC(port)->mpc52xx_psc_isr)
224 & port->read_status_mask
225 & MPC52xx_PSC_IMR_TXRDY;
226}
227
228static int mpc52xx_psc_tx_empty(struct uart_port *port)
229{
230 return in_be16(&PSC(port)->mpc52xx_psc_status)
231 & MPC52xx_PSC_SR_TXEMP;
232}
233
234static void mpc52xx_psc_start_tx(struct uart_port *port)
235{
236 port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY;
237 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
238}
239
240static void mpc52xx_psc_stop_tx(struct uart_port *port)
241{
242 port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY;
243 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
244}
245
246static void mpc52xx_psc_stop_rx(struct uart_port *port)
247{
248 port->read_status_mask &= ~MPC52xx_PSC_IMR_RXRDY;
249 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
250}
251
252static void mpc52xx_psc_rx_clr_irq(struct uart_port *port)
253{
254}
255
256static void mpc52xx_psc_tx_clr_irq(struct uart_port *port)
257{
258}
259
260static void mpc52xx_psc_write_char(struct uart_port *port, unsigned char c)
261{
262 out_8(&PSC(port)->mpc52xx_psc_buffer_8, c);
263}
264
265static unsigned char mpc52xx_psc_read_char(struct uart_port *port)
266{
267 return in_8(&PSC(port)->mpc52xx_psc_buffer_8);
268}
269
270static void mpc52xx_psc_cw_disable_ints(struct uart_port *port)
271{
272 out_be16(&PSC(port)->mpc52xx_psc_imr, 0);
273}
274
275static void mpc52xx_psc_cw_restore_ints(struct uart_port *port)
276{
277 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
278}
279
280/* Search for bus-frequency property in this node or a parent */
281static unsigned long mpc52xx_getuartclk(void *p)
282{
283#if defined(CONFIG_PPC_MERGE)
284 /*
285 * 5200 UARTs have a / 32 prescaler
286 * but the generic serial code assumes 16
287 * so return ipb freq / 2
288 */
289 return mpc52xx_find_ipb_freq(p) / 2;
290#else
291 pr_debug("unexpected call to mpc52xx_getuartclk with arch/ppc\n");
292 return NULL;
293#endif
294}
295
296static struct psc_ops mpc52xx_psc_ops = {
297 .fifo_init = mpc52xx_psc_fifo_init,
298 .raw_rx_rdy = mpc52xx_psc_raw_rx_rdy,
299 .raw_tx_rdy = mpc52xx_psc_raw_tx_rdy,
300 .rx_rdy = mpc52xx_psc_rx_rdy,
301 .tx_rdy = mpc52xx_psc_tx_rdy,
302 .tx_empty = mpc52xx_psc_tx_empty,
303 .stop_rx = mpc52xx_psc_stop_rx,
304 .start_tx = mpc52xx_psc_start_tx,
305 .stop_tx = mpc52xx_psc_stop_tx,
306 .rx_clr_irq = mpc52xx_psc_rx_clr_irq,
307 .tx_clr_irq = mpc52xx_psc_tx_clr_irq,
308 .write_char = mpc52xx_psc_write_char,
309 .read_char = mpc52xx_psc_read_char,
310 .cw_disable_ints = mpc52xx_psc_cw_disable_ints,
311 .cw_restore_ints = mpc52xx_psc_cw_restore_ints,
312 .getuartclk = mpc52xx_getuartclk,
313};
314
315#endif /* CONFIG_MPC52xx */
316
317#ifdef CONFIG_PPC_MPC512x
318#define FIFO_512x(port) ((struct mpc512x_psc_fifo __iomem *)(PSC(port)+1))
319static void mpc512x_psc_fifo_init(struct uart_port *port)
320{
321 out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_RESET_SLICE);
322 out_be32(&FIFO_512x(port)->txcmd, MPC512x_PSC_FIFO_ENABLE_SLICE);
323 out_be32(&FIFO_512x(port)->txalarm, 1);
324 out_be32(&FIFO_512x(port)->tximr, 0);
325
326 out_be32(&FIFO_512x(port)->rxcmd, MPC512x_PSC_FIFO_RESET_SLICE);
327 out_be32(&FIFO_512x(port)->rxcmd, MPC512x_PSC_FIFO_ENABLE_SLICE);
328 out_be32(&FIFO_512x(port)->rxalarm, 1);
329 out_be32(&FIFO_512x(port)->rximr, 0);
330
331 out_be32(&FIFO_512x(port)->tximr, MPC512x_PSC_FIFO_ALARM);
332 out_be32(&FIFO_512x(port)->rximr, MPC512x_PSC_FIFO_ALARM);
333}
334
335static int mpc512x_psc_raw_rx_rdy(struct uart_port *port)
336{
337 return !(in_be32(&FIFO_512x(port)->rxsr) & MPC512x_PSC_FIFO_EMPTY);
338}
339
340static int mpc512x_psc_raw_tx_rdy(struct uart_port *port)
341{
342 return !(in_be32(&FIFO_512x(port)->txsr) & MPC512x_PSC_FIFO_FULL);
343}
344
345static int mpc512x_psc_rx_rdy(struct uart_port *port)
346{
347 return in_be32(&FIFO_512x(port)->rxsr)
348 & in_be32(&FIFO_512x(port)->rximr)
349 & MPC512x_PSC_FIFO_ALARM;
350}
351
352static int mpc512x_psc_tx_rdy(struct uart_port *port)
353{
354 return in_be32(&FIFO_512x(port)->txsr)
355 & in_be32(&FIFO_512x(port)->tximr)
356 & MPC512x_PSC_FIFO_ALARM;
357}
358
359static int mpc512x_psc_tx_empty(struct uart_port *port)
360{
361 return in_be32(&FIFO_512x(port)->txsr)
362 & MPC512x_PSC_FIFO_EMPTY;
363}
364
365static void mpc512x_psc_stop_rx(struct uart_port *port)
366{
367 unsigned long rx_fifo_imr;
368
369 rx_fifo_imr = in_be32(&FIFO_512x(port)->rximr);
370 rx_fifo_imr &= ~MPC512x_PSC_FIFO_ALARM;
371 out_be32(&FIFO_512x(port)->rximr, rx_fifo_imr);
372}
373
374static void mpc512x_psc_start_tx(struct uart_port *port)
375{
376 unsigned long tx_fifo_imr;
377
378 tx_fifo_imr = in_be32(&FIFO_512x(port)->tximr);
379 tx_fifo_imr |= MPC512x_PSC_FIFO_ALARM;
380 out_be32(&FIFO_512x(port)->tximr, tx_fifo_imr);
381}
382
383static void mpc512x_psc_stop_tx(struct uart_port *port)
384{
385 unsigned long tx_fifo_imr;
386
387 tx_fifo_imr = in_be32(&FIFO_512x(port)->tximr);
388 tx_fifo_imr &= ~MPC512x_PSC_FIFO_ALARM;
389 out_be32(&FIFO_512x(port)->tximr, tx_fifo_imr);
390}
391
392static void mpc512x_psc_rx_clr_irq(struct uart_port *port)
393{
394 out_be32(&FIFO_512x(port)->rxisr, in_be32(&FIFO_512x(port)->rxisr));
395}
396
397static void mpc512x_psc_tx_clr_irq(struct uart_port *port)
398{
399 out_be32(&FIFO_512x(port)->txisr, in_be32(&FIFO_512x(port)->txisr));
400}
401
402static void mpc512x_psc_write_char(struct uart_port *port, unsigned char c)
403{
404 out_8(&FIFO_512x(port)->txdata_8, c);
405}
406
407static unsigned char mpc512x_psc_read_char(struct uart_port *port)
408{
409 return in_8(&FIFO_512x(port)->rxdata_8);
410}
411
412static void mpc512x_psc_cw_disable_ints(struct uart_port *port)
413{
414 port->read_status_mask =
415 in_be32(&FIFO_512x(port)->tximr) << 16 |
416 in_be32(&FIFO_512x(port)->rximr);
417 out_be32(&FIFO_512x(port)->tximr, 0);
418 out_be32(&FIFO_512x(port)->rximr, 0);
419}
420
421static void mpc512x_psc_cw_restore_ints(struct uart_port *port)
422{
423 out_be32(&FIFO_512x(port)->tximr,
424 (port->read_status_mask >> 16) & 0x7f);
425 out_be32(&FIFO_512x(port)->rximr, port->read_status_mask & 0x7f);
426}
427
428static unsigned long mpc512x_getuartclk(void *p)
429{
430 return mpc512x_find_ips_freq(p);
431}
432
433static struct psc_ops mpc512x_psc_ops = {
434 .fifo_init = mpc512x_psc_fifo_init,
435 .raw_rx_rdy = mpc512x_psc_raw_rx_rdy,
436 .raw_tx_rdy = mpc512x_psc_raw_tx_rdy,
437 .rx_rdy = mpc512x_psc_rx_rdy,
438 .tx_rdy = mpc512x_psc_tx_rdy,
439 .tx_empty = mpc512x_psc_tx_empty,
440 .stop_rx = mpc512x_psc_stop_rx,
441 .start_tx = mpc512x_psc_start_tx,
442 .stop_tx = mpc512x_psc_stop_tx,
443 .rx_clr_irq = mpc512x_psc_rx_clr_irq,
444 .tx_clr_irq = mpc512x_psc_tx_clr_irq,
445 .write_char = mpc512x_psc_write_char,
446 .read_char = mpc512x_psc_read_char,
447 .cw_disable_ints = mpc512x_psc_cw_disable_ints,
448 .cw_restore_ints = mpc512x_psc_cw_restore_ints,
449 .getuartclk = mpc512x_getuartclk,
450};
451#endif
452
453static struct psc_ops *psc_ops;
140 454
141/* ======================================================================== */ 455/* ======================================================================== */
142/* UART operations */ 456/* UART operations */
@@ -145,8 +459,7 @@ static struct of_device_id mpc52xx_uart_of_match[] = {
145static unsigned int 459static unsigned int
146mpc52xx_uart_tx_empty(struct uart_port *port) 460mpc52xx_uart_tx_empty(struct uart_port *port)
147{ 461{
148 int status = in_be16(&PSC(port)->mpc52xx_psc_status); 462 return psc_ops->tx_empty(port) ? TIOCSER_TEMT : 0;
149 return (status & MPC52xx_PSC_SR_TXEMP) ? TIOCSER_TEMT : 0;
150} 463}
151 464
152static void 465static void
@@ -166,16 +479,14 @@ static void
166mpc52xx_uart_stop_tx(struct uart_port *port) 479mpc52xx_uart_stop_tx(struct uart_port *port)
167{ 480{
168 /* port->lock taken by caller */ 481 /* port->lock taken by caller */
169 port->read_status_mask &= ~MPC52xx_PSC_IMR_TXRDY; 482 psc_ops->stop_tx(port);
170 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
171} 483}
172 484
173static void 485static void
174mpc52xx_uart_start_tx(struct uart_port *port) 486mpc52xx_uart_start_tx(struct uart_port *port)
175{ 487{
176 /* port->lock taken by caller */ 488 /* port->lock taken by caller */
177 port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; 489 psc_ops->start_tx(port);
178 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
179} 490}
180 491
181static void 492static void
@@ -188,8 +499,7 @@ mpc52xx_uart_send_xchar(struct uart_port *port, char ch)
188 if (ch) { 499 if (ch) {
189 /* Make sure tx interrupts are on */ 500 /* Make sure tx interrupts are on */
190 /* Truly necessary ??? They should be anyway */ 501 /* Truly necessary ??? They should be anyway */
191 port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; 502 psc_ops->start_tx(port);
192 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
193 } 503 }
194 504
195 spin_unlock_irqrestore(&port->lock, flags); 505 spin_unlock_irqrestore(&port->lock, flags);
@@ -199,8 +509,7 @@ static void
199mpc52xx_uart_stop_rx(struct uart_port *port) 509mpc52xx_uart_stop_rx(struct uart_port *port)
200{ 510{
201 /* port->lock taken by caller */ 511 /* port->lock taken by caller */
202 port->read_status_mask &= ~MPC52xx_PSC_IMR_RXRDY; 512 psc_ops->stop_rx(port);
203 out_be16(&PSC(port)->mpc52xx_psc_imr, port->read_status_mask);
204} 513}
205 514
206static void 515static void
@@ -227,12 +536,12 @@ static int
227mpc52xx_uart_startup(struct uart_port *port) 536mpc52xx_uart_startup(struct uart_port *port)
228{ 537{
229 struct mpc52xx_psc __iomem *psc = PSC(port); 538 struct mpc52xx_psc __iomem *psc = PSC(port);
230 struct mpc52xx_psc_fifo __iomem *fifo = FIFO(port);
231 int ret; 539 int ret;
232 540
233 /* Request IRQ */ 541 /* Request IRQ */
234 ret = request_irq(port->irq, mpc52xx_uart_int, 542 ret = request_irq(port->irq, mpc52xx_uart_int,
235 IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "mpc52xx_psc_uart", port); 543 IRQF_DISABLED | IRQF_SAMPLE_RANDOM | IRQF_SHARED,
544 "mpc52xx_psc_uart", port);
236 if (ret) 545 if (ret)
237 return ret; 546 return ret;
238 547
@@ -242,15 +551,7 @@ mpc52xx_uart_startup(struct uart_port *port)
242 551
243 out_be32(&psc->sicr, 0); /* UART mode DCD ignored */ 552 out_be32(&psc->sicr, 0); /* UART mode DCD ignored */
244 553
245 out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /16 prescaler on */ 554 psc_ops->fifo_init(port);
246
247 out_8(&fifo->rfcntl, 0x00);
248 out_be16(&fifo->rfalarm, 0x1ff);
249 out_8(&fifo->tfcntl, 0x07);
250 out_be16(&fifo->tfalarm, 0x80);
251
252 port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY;
253 out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
254 555
255 out_8(&psc->command, MPC52xx_PSC_TX_ENABLE); 556 out_8(&psc->command, MPC52xx_PSC_TX_ENABLE);
256 out_8(&psc->command, MPC52xx_PSC_RX_ENABLE); 557 out_8(&psc->command, MPC52xx_PSC_RX_ENABLE);
@@ -333,8 +634,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct ktermios *new,
333 * boot for the console, all stuff is not yet ready to receive at that 634 * boot for the console, all stuff is not yet ready to receive at that
334 * time and that just makes the kernel oops */ 635 * time and that just makes the kernel oops */
335 /* while (j-- && mpc52xx_uart_int_rx_chars(port)); */ 636 /* while (j-- && mpc52xx_uart_int_rx_chars(port)); */
336 while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) && 637 while (!mpc52xx_uart_tx_empty(port) && --j)
337 --j)
338 udelay(1); 638 udelay(1);
339 639
340 if (!j) 640 if (!j)
@@ -462,11 +762,9 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
462 unsigned short status; 762 unsigned short status;
463 763
464 /* While we can read, do so ! */ 764 /* While we can read, do so ! */
465 while ((status = in_be16(&PSC(port)->mpc52xx_psc_status)) & 765 while (psc_ops->raw_rx_rdy(port)) {
466 MPC52xx_PSC_SR_RXRDY) {
467
468 /* Get the char */ 766 /* Get the char */
469 ch = in_8(&PSC(port)->mpc52xx_psc_buffer_8); 767 ch = psc_ops->read_char(port);
470 768
471 /* Handle sysreq char */ 769 /* Handle sysreq char */
472#ifdef SUPPORT_SYSRQ 770#ifdef SUPPORT_SYSRQ
@@ -481,6 +779,8 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
481 flag = TTY_NORMAL; 779 flag = TTY_NORMAL;
482 port->icount.rx++; 780 port->icount.rx++;
483 781
782 status = in_be16(&PSC(port)->mpc52xx_psc_status);
783
484 if (status & (MPC52xx_PSC_SR_PE | 784 if (status & (MPC52xx_PSC_SR_PE |
485 MPC52xx_PSC_SR_FE | 785 MPC52xx_PSC_SR_FE |
486 MPC52xx_PSC_SR_RB)) { 786 MPC52xx_PSC_SR_RB)) {
@@ -510,7 +810,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
510 810
511 tty_flip_buffer_push(tty); 811 tty_flip_buffer_push(tty);
512 812
513 return in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY; 813 return psc_ops->raw_rx_rdy(port);
514} 814}
515 815
516static inline int 816static inline int
@@ -520,7 +820,7 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port)
520 820
521 /* Process out of band chars */ 821 /* Process out of band chars */
522 if (port->x_char) { 822 if (port->x_char) {
523 out_8(&PSC(port)->mpc52xx_psc_buffer_8, port->x_char); 823 psc_ops->write_char(port, port->x_char);
524 port->icount.tx++; 824 port->icount.tx++;
525 port->x_char = 0; 825 port->x_char = 0;
526 return 1; 826 return 1;
@@ -533,8 +833,8 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port)
533 } 833 }
534 834
535 /* Send chars */ 835 /* Send chars */
536 while (in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXRDY) { 836 while (psc_ops->raw_tx_rdy(port)) {
537 out_8(&PSC(port)->mpc52xx_psc_buffer_8, xmit->buf[xmit->tail]); 837 psc_ops->write_char(port, xmit->buf[xmit->tail]);
538 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 838 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
539 port->icount.tx++; 839 port->icount.tx++;
540 if (uart_circ_empty(xmit)) 840 if (uart_circ_empty(xmit))
@@ -560,7 +860,6 @@ mpc52xx_uart_int(int irq, void *dev_id)
560 struct uart_port *port = dev_id; 860 struct uart_port *port = dev_id;
561 unsigned long pass = ISR_PASS_LIMIT; 861 unsigned long pass = ISR_PASS_LIMIT;
562 unsigned int keepgoing; 862 unsigned int keepgoing;
563 unsigned short status;
564 863
565 spin_lock(&port->lock); 864 spin_lock(&port->lock);
566 865
@@ -569,18 +868,12 @@ mpc52xx_uart_int(int irq, void *dev_id)
569 /* If we don't find anything to do, we stop */ 868 /* If we don't find anything to do, we stop */
570 keepgoing = 0; 869 keepgoing = 0;
571 870
572 /* Read status */ 871 psc_ops->rx_clr_irq(port);
573 status = in_be16(&PSC(port)->mpc52xx_psc_isr); 872 if (psc_ops->rx_rdy(port))
574 status &= port->read_status_mask;
575
576 /* Do we need to receive chars ? */
577 /* For this RX interrupts must be on and some chars waiting */
578 if (status & MPC52xx_PSC_IMR_RXRDY)
579 keepgoing |= mpc52xx_uart_int_rx_chars(port); 873 keepgoing |= mpc52xx_uart_int_rx_chars(port);
580 874
581 /* Do we need to send chars ? */ 875 psc_ops->tx_clr_irq(port);
582 /* For this, TX must be ready and TX interrupt enabled */ 876 if (psc_ops->tx_rdy(port))
583 if (status & MPC52xx_PSC_IMR_TXRDY)
584 keepgoing |= mpc52xx_uart_int_tx_chars(port); 877 keepgoing |= mpc52xx_uart_int_tx_chars(port);
585 878
586 /* Limit number of iteration */ 879 /* Limit number of iteration */
@@ -647,36 +940,33 @@ static void
647mpc52xx_console_write(struct console *co, const char *s, unsigned int count) 940mpc52xx_console_write(struct console *co, const char *s, unsigned int count)
648{ 941{
649 struct uart_port *port = &mpc52xx_uart_ports[co->index]; 942 struct uart_port *port = &mpc52xx_uart_ports[co->index];
650 struct mpc52xx_psc __iomem *psc = PSC(port);
651 unsigned int i, j; 943 unsigned int i, j;
652 944
653 /* Disable interrupts */ 945 /* Disable interrupts */
654 out_be16(&psc->mpc52xx_psc_imr, 0); 946 psc_ops->cw_disable_ints(port);
655 947
656 /* Wait the TX buffer to be empty */ 948 /* Wait the TX buffer to be empty */
657 j = 5000000; /* Maximum wait */ 949 j = 5000000; /* Maximum wait */
658 while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) && 950 while (!mpc52xx_uart_tx_empty(port) && --j)
659 --j)
660 udelay(1); 951 udelay(1);
661 952
662 /* Write all the chars */ 953 /* Write all the chars */
663 for (i = 0; i < count; i++, s++) { 954 for (i = 0; i < count; i++, s++) {
664 /* Line return handling */ 955 /* Line return handling */
665 if (*s == '\n') 956 if (*s == '\n')
666 out_8(&psc->mpc52xx_psc_buffer_8, '\r'); 957 psc_ops->write_char(port, '\r');
667 958
668 /* Send the char */ 959 /* Send the char */
669 out_8(&psc->mpc52xx_psc_buffer_8, *s); 960 psc_ops->write_char(port, *s);
670 961
671 /* Wait the TX buffer to be empty */ 962 /* Wait the TX buffer to be empty */
672 j = 20000; /* Maximum wait */ 963 j = 20000; /* Maximum wait */
673 while (!(in_be16(&psc->mpc52xx_psc_status) & 964 while (!mpc52xx_uart_tx_empty(port) && --j)
674 MPC52xx_PSC_SR_TXEMP) && --j)
675 udelay(1); 965 udelay(1);
676 } 966 }
677 967
678 /* Restore interrupt state */ 968 /* Restore interrupt state */
679 out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); 969 psc_ops->cw_restore_ints(port);
680} 970}
681 971
682#if !defined(CONFIG_PPC_MERGE) 972#if !defined(CONFIG_PPC_MERGE)
@@ -721,7 +1011,7 @@ mpc52xx_console_setup(struct console *co, char *options)
721{ 1011{
722 struct uart_port *port = &mpc52xx_uart_ports[co->index]; 1012 struct uart_port *port = &mpc52xx_uart_ports[co->index];
723 struct device_node *np = mpc52xx_uart_nodes[co->index]; 1013 struct device_node *np = mpc52xx_uart_nodes[co->index];
724 unsigned int ipb_freq; 1014 unsigned int uartclk;
725 struct resource res; 1015 struct resource res;
726 int ret; 1016 int ret;
727 1017
@@ -753,17 +1043,16 @@ mpc52xx_console_setup(struct console *co, char *options)
753 return ret; 1043 return ret;
754 } 1044 }
755 1045
756 /* Search for bus-frequency property in this node or a parent */ 1046 uartclk = psc_ops->getuartclk(np);
757 ipb_freq = mpc52xx_find_ipb_freq(np); 1047 if (uartclk == 0) {
758 if (ipb_freq == 0) { 1048 pr_debug("Could not find uart clock frequency!\n");
759 pr_debug("Could not find IPB bus frequency!\n");
760 return -EINVAL; 1049 return -EINVAL;
761 } 1050 }
762 1051
763 /* Basic port init. Needed since we use some uart_??? func before 1052 /* Basic port init. Needed since we use some uart_??? func before
764 * real init for early access */ 1053 * real init for early access */
765 spin_lock_init(&port->lock); 1054 spin_lock_init(&port->lock);
766 port->uartclk = ipb_freq / 2; 1055 port->uartclk = uartclk;
767 port->ops = &mpc52xx_uart_ops; 1056 port->ops = &mpc52xx_uart_ops;
768 port->mapbase = res.start; 1057 port->mapbase = res.start;
769 port->membase = ioremap(res.start, sizeof(struct mpc52xx_psc)); 1058 port->membase = ioremap(res.start, sizeof(struct mpc52xx_psc));
@@ -949,7 +1238,7 @@ static int __devinit
949mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match) 1238mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
950{ 1239{
951 int idx = -1; 1240 int idx = -1;
952 unsigned int ipb_freq; 1241 unsigned int uartclk;
953 struct uart_port *port = NULL; 1242 struct uart_port *port = NULL;
954 struct resource res; 1243 struct resource res;
955 int ret; 1244 int ret;
@@ -965,10 +1254,9 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
965 pr_debug("Found %s assigned to ttyPSC%x\n", 1254 pr_debug("Found %s assigned to ttyPSC%x\n",
966 mpc52xx_uart_nodes[idx]->full_name, idx); 1255 mpc52xx_uart_nodes[idx]->full_name, idx);
967 1256
968 /* Search for bus-frequency property in this node or a parent */ 1257 uartclk = psc_ops->getuartclk(op->node);
969 ipb_freq = mpc52xx_find_ipb_freq(op->node); 1258 if (uartclk == 0) {
970 if (ipb_freq == 0) { 1259 dev_dbg(&op->dev, "Could not find uart clock frequency!\n");
971 dev_dbg(&op->dev, "Could not find IPB bus frequency!\n");
972 return -EINVAL; 1260 return -EINVAL;
973 } 1261 }
974 1262
@@ -976,7 +1264,7 @@ mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
976 port = &mpc52xx_uart_ports[idx]; 1264 port = &mpc52xx_uart_ports[idx];
977 1265
978 spin_lock_init(&port->lock); 1266 spin_lock_init(&port->lock);
979 port->uartclk = ipb_freq / 2; 1267 port->uartclk = uartclk;
980 port->fifosize = 512; 1268 port->fifosize = 512;
981 port->iotype = UPIO_MEM; 1269 port->iotype = UPIO_MEM;
982 port->flags = UPF_BOOT_AUTOCONF | 1270 port->flags = UPF_BOOT_AUTOCONF |
@@ -1080,15 +1368,19 @@ mpc52xx_uart_of_enumerate(void)
1080 static int enum_done; 1368 static int enum_done;
1081 struct device_node *np; 1369 struct device_node *np;
1082 const unsigned int *devno; 1370 const unsigned int *devno;
1371 const struct of_device_id *match;
1083 int i; 1372 int i;
1084 1373
1085 if (enum_done) 1374 if (enum_done)
1086 return; 1375 return;
1087 1376
1088 for_each_node_by_type(np, "serial") { 1377 for_each_node_by_type(np, "serial") {
1089 if (!of_match_node(mpc52xx_uart_of_match, np)) 1378 match = of_match_node(mpc52xx_uart_of_match, np);
1379 if (!match)
1090 continue; 1380 continue;
1091 1381
1382 psc_ops = match->data;
1383
1092 /* Is a particular device number requested? */ 1384 /* Is a particular device number requested? */
1093 devno = of_get_property(np, "port-number", NULL); 1385 devno = of_get_property(np, "port-number", NULL);
1094 mpc52xx_uart_of_assign(np, devno ? *devno : -1); 1386 mpc52xx_uart_of_assign(np, devno ? *devno : -1);
@@ -1149,6 +1441,7 @@ mpc52xx_uart_init(void)
1149 return ret; 1441 return ret;
1150 } 1442 }
1151#else 1443#else
1444 psc_ops = &mpc52xx_psc_ops;
1152 ret = platform_driver_register(&mpc52xx_uart_platform_driver); 1445 ret = platform_driver_register(&mpc52xx_uart_platform_driver);
1153 if (ret) { 1446 if (ret) {
1154 printk(KERN_ERR "%s: platform_driver_register failed (%i)\n", 1447 printk(KERN_ERR "%s: platform_driver_register failed (%i)\n",
diff --git a/include/asm-powerpc/mpc512x.h b/include/asm-powerpc/mpc512x.h
new file mode 100644
index 000000000000..c48a1658eeac
--- /dev/null
+++ b/include/asm-powerpc/mpc512x.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
3 *
4 * Author: John Rigby, <jrigby@freescale.com>, Friday Apr 13 2007
5 *
6 * Description:
7 * MPC5121 Prototypes and definitions
8 *
9 * This is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 */
15
16#ifndef __ASM_POWERPC_MPC512x_H__
17#define __ASM_POWERPC_MPC512x_H__
18
19extern unsigned long mpc512x_find_ips_freq(struct device_node *node);
20
21#endif /* __ASM_POWERPC_MPC512x_H__ */
22
diff --git a/include/asm-powerpc/mpc52xx_psc.h b/include/asm-powerpc/mpc52xx_psc.h
index bea42b95390f..710c5d36efaa 100644
--- a/include/asm-powerpc/mpc52xx_psc.h
+++ b/include/asm-powerpc/mpc52xx_psc.h
@@ -190,5 +190,53 @@ struct mpc52xx_psc_fifo {
190 u16 tflwfptr; /* PSC + 0x9e */ 190 u16 tflwfptr; /* PSC + 0x9e */
191}; 191};
192 192
193#define MPC512x_PSC_FIFO_RESET_SLICE 0x80
194#define MPC512x_PSC_FIFO_ENABLE_SLICE 0x01
195#define MPC512x_PSC_FIFO_ENABLE_DMA 0x04
196
197#define MPC512x_PSC_FIFO_EMPTY 0x1
198#define MPC512x_PSC_FIFO_FULL 0x2
199#define MPC512x_PSC_FIFO_ALARM 0x4
200#define MPC512x_PSC_FIFO_URERR 0x8
201#define MPC512x_PSC_FIFO_ORERR 0x01
202#define MPC512x_PSC_FIFO_MEMERROR 0x02
203
204struct mpc512x_psc_fifo {
205 u32 reserved1[10];
206 u32 txcmd; /* PSC + 0x80 */
207 u32 txalarm; /* PSC + 0x84 */
208 u32 txsr; /* PSC + 0x88 */
209 u32 txisr; /* PSC + 0x8c */
210 u32 tximr; /* PSC + 0x90 */
211 u32 txcnt; /* PSC + 0x94 */
212 u32 txptr; /* PSC + 0x98 */
213 u32 txsz; /* PSC + 0x9c */
214 u32 reserved2[7];
215 union {
216 u8 txdata_8;
217 u16 txdata_16;
218 u32 txdata_32;
219 } txdata; /* PSC + 0xbc */
220#define txdata_8 txdata.txdata_8
221#define txdata_16 txdata.txdata_16
222#define txdata_32 txdata.txdata_32
223 u32 rxcmd; /* PSC + 0xc0 */
224 u32 rxalarm; /* PSC + 0xc4 */
225 u32 rxsr; /* PSC + 0xc8 */
226 u32 rxisr; /* PSC + 0xcc */
227 u32 rximr; /* PSC + 0xd0 */
228 u32 rxcnt; /* PSC + 0xd4 */
229 u32 rxptr; /* PSC + 0xd8 */
230 u32 rxsz; /* PSC + 0xdc */
231 u32 reserved3[7];
232 union {
233 u8 rxdata_8;
234 u16 rxdata_16;
235 u32 rxdata_32;
236 } rxdata; /* PSC + 0xfc */
237#define rxdata_8 rxdata.rxdata_8
238#define rxdata_16 rxdata.rxdata_16
239#define rxdata_32 rxdata.rxdata_32
240};
193 241
194#endif /* __ASM_MPC52xx_PSC_H__ */ 242#endif /* __ASM_MPC52xx_PSC_H__ */