aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDale Farnsworth <dale@farnsworth.org>2007-05-11 20:55:53 -0400
committerPaul Mackerras <paulus@samba.org>2007-05-11 21:32:49 -0400
commit52d3aff903171af13b56c5a4d6fb828461406c65 (patch)
tree65786487dce618d0fcac5783952e112cefe30c0b
parente44b8941908ec9ccf03b52713c9e7d3471bada8c (diff)
[POWERPC] Create Marvell mv64x60 MPSC (serial) platform_data
This patch creates platform_device entries for the Marvell mv64x60 MPSC (multi-protocol serial controller) ports, based on information contained in the device tree. This driver (like the other mv64x60 drivers) are unusual in that it works on both the MIPS and PowerPC architectures. Because of that, the drivers do not support the normal PowerPC of_platform_bus_type. They support platform_bus_type instead. Signed-off-by: Dale Farnsworth <dale@farnsworth.org> Acked-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/platforms/embedded6xx/Kconfig3
-rw-r--r--arch/powerpc/sysdev/Makefile2
-rw-r--r--arch/powerpc/sysdev/mv64x60_dev.c221
3 files changed, 225 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
index 8f3c2a73e165..abb27c97afe9 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -46,6 +46,9 @@ config MPC10X_BRIDGE
46 select PPC_INDIRECT_PCI 46 select PPC_INDIRECT_PCI
47 default y 47 default y
48 48
49config MV64X60
50 bool
51
49config MPC10X_OPENPIC 52config MPC10X_OPENPIC
50 bool 53 bool
51 depends on LINKSTATION 54 depends on LINKSTATION
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 041c832bc407..452ff5636e41 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -16,7 +16,7 @@ obj-$(CONFIG_FSL_SOC) += fsl_soc.o
16obj-$(CONFIG_FSL_PCIE) += fsl_pcie.o 16obj-$(CONFIG_FSL_PCIE) += fsl_pcie.o
17obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o 17obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
18obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ 18obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
19obj-$(CONFIG_MV64X60) += mv64x60_pic.o 19obj-$(CONFIG_MV64X60) += mv64x60_pic.o mv64x60_dev.o
20 20
21# contains only the suspend handler for time 21# contains only the suspend handler for time
22obj-$(CONFIG_PM) += timer.o 22obj-$(CONFIG_PM) += timer.o
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c
new file mode 100644
index 000000000000..735d20fa586b
--- /dev/null
+++ b/arch/powerpc/sysdev/mv64x60_dev.c
@@ -0,0 +1,221 @@
1/*
2 * Platform device setup for Marvell mv64360/mv64460 host bridges (Discovery)
3 *
4 * Author: Dale Farnsworth <dale@farnsworth.org>
5 *
6 * 2007 (c) MontaVista, Software, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 */
11
12#include <linux/stddef.h>
13#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/mv643xx.h>
16#include <linux/platform_device.h>
17
18#include <asm/prom.h>
19
20/*
21 * These functions provide the necessary setup for the mv64x60 drivers.
22 * These drivers are unusual in that they work on both the MIPS and PowerPC
23 * architectures. Because of that, the drivers do not support the normal
24 * PowerPC of_platform_bus_type. They support platform_bus_type instead.
25 */
26
27/*
28 * Create MPSC platform devices
29 */
30static int __init mv64x60_mpsc_register_shared_pdev(struct device_node *np)
31{
32 struct platform_device *pdev;
33 struct resource r[2];
34 struct mpsc_shared_pdata pdata;
35 const phandle *ph;
36 struct device_node *mpscrouting, *mpscintr;
37 int err;
38
39 ph = of_get_property(np, "mpscrouting", NULL);
40 mpscrouting = of_find_node_by_phandle(*ph);
41 if (!mpscrouting)
42 return -ENODEV;
43
44 err = of_address_to_resource(mpscrouting, 0, &r[0]);
45 of_node_put(mpscrouting);
46 if (err)
47 return err;
48
49 ph = of_get_property(np, "mpscintr", NULL);
50 mpscintr = of_find_node_by_phandle(*ph);
51 if (!mpscintr)
52 return -ENODEV;
53
54 err = of_address_to_resource(mpscintr, 0, &r[1]);
55 of_node_put(mpscintr);
56 if (err)
57 return err;
58
59 memset(&pdata, 0, sizeof(pdata));
60
61 pdev = platform_device_alloc(MPSC_SHARED_NAME, 0);
62 if (!pdev)
63 return -ENOMEM;
64
65 err = platform_device_add_resources(pdev, r, 2);
66 if (err)
67 goto error;
68
69 err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
70 if (err)
71 goto error;
72
73 err = platform_device_add(pdev);
74 if (err)
75 goto error;
76
77 return 0;
78
79error:
80 platform_device_put(pdev);
81 return err;
82}
83
84
85static int __init mv64x60_mpsc_device_setup(struct device_node *np, int id)
86{
87 struct resource r[5];
88 struct mpsc_pdata pdata;
89 struct platform_device *pdev;
90 const unsigned int *prop;
91 const phandle *ph;
92 struct device_node *sdma, *brg;
93 int err;
94 int port_number;
95
96 /* only register the shared platform device the first time through */
97 if (id == 0 && (err = mv64x60_mpsc_register_shared_pdev(np)))
98 return err;
99
100 memset(r, 0, sizeof(r));
101
102 err = of_address_to_resource(np, 0, &r[0]);
103 if (err)
104 return err;
105
106 of_irq_to_resource(np, 0, &r[4]);
107
108 ph = of_get_property(np, "sdma", NULL);
109 sdma = of_find_node_by_phandle(*ph);
110 if (!sdma)
111 return -ENODEV;
112
113 of_irq_to_resource(sdma, 0, &r[3]);
114 err = of_address_to_resource(sdma, 0, &r[1]);
115 of_node_put(sdma);
116 if (err)
117 return err;
118
119 ph = of_get_property(np, "brg", NULL);
120 brg = of_find_node_by_phandle(*ph);
121 if (!brg)
122 return -ENODEV;
123
124 err = of_address_to_resource(brg, 0, &r[2]);
125 of_node_put(brg);
126 if (err)
127 return err;
128
129 prop = of_get_property(np, "block-index", NULL);
130 if (!prop)
131 return -ENODEV;
132 port_number = *(int *)prop;
133
134 memset(&pdata, 0, sizeof(pdata));
135
136 pdata.cache_mgmt = 1; /* All current revs need this set */
137
138 prop = of_get_property(np, "max_idle", NULL);
139 if (prop)
140 pdata.max_idle = *prop;
141
142 prop = of_get_property(brg, "current-speed", NULL);
143 if (prop)
144 pdata.default_baud = *prop;
145
146 /* Default is 8 bits, no parity, no flow control */
147 pdata.default_bits = 8;
148 pdata.default_parity = 'n';
149 pdata.default_flow = 'n';
150
151 prop = of_get_property(np, "chr_1", NULL);
152 if (prop)
153 pdata.chr_1_val = *prop;
154
155 prop = of_get_property(np, "chr_2", NULL);
156 if (prop)
157 pdata.chr_2_val = *prop;
158
159 prop = of_get_property(np, "chr_10", NULL);
160 if (prop)
161 pdata.chr_10_val = *prop;
162
163 prop = of_get_property(np, "mpcr", NULL);
164 if (prop)
165 pdata.mpcr_val = *prop;
166
167 prop = of_get_property(brg, "bcr", NULL);
168 if (prop)
169 pdata.bcr_val = *prop;
170
171 pdata.brg_can_tune = 1; /* All current revs need this set */
172
173 prop = of_get_property(brg, "clock-src", NULL);
174 if (prop)
175 pdata.brg_clk_src = *prop;
176
177 prop = of_get_property(brg, "clock-frequency", NULL);
178 if (prop)
179 pdata.brg_clk_freq = *prop;
180
181 pdev = platform_device_alloc(MPSC_CTLR_NAME, port_number);
182 if (!pdev)
183 return -ENOMEM;
184
185 err = platform_device_add_resources(pdev, r, 5);
186 if (err)
187 goto error;
188
189 err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
190 if (err)
191 goto error;
192
193 err = platform_device_add(pdev);
194 if (err)
195 goto error;
196
197 return 0;
198
199error:
200 platform_device_put(pdev);
201 return err;
202}
203
204static int __init mv64x60_device_setup(void)
205{
206 struct device_node *np = NULL;
207 int id;
208 int err;
209
210 for (id = 0;
211 (np = of_find_compatible_node(np, "serial", "marvell,mpsc")); id++)
212 if ((err = mv64x60_mpsc_device_setup(np, id)))
213 goto error;
214
215 return 0;
216
217error:
218 of_node_put(np);
219 return err;
220}
221arch_initcall(mv64x60_device_setup);