aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ppc/syslib/ppc_sys.c177
-rw-r--r--include/asm-ppc/mpc10x.h1
-rw-r--r--include/asm-ppc/mpc52xx.h1
-rw-r--r--include/asm-ppc/mpc8260.h1
-rw-r--r--include/asm-ppc/mpc83xx.h1
-rw-r--r--include/asm-ppc/mpc85xx.h1
-rw-r--r--include/asm-ppc/mpc8xx.h1
-rw-r--r--include/asm-ppc/ppc_sys.h32
8 files changed, 212 insertions, 3 deletions
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
index c0b93c4191ee..879783a41cfd 100644
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -15,11 +15,22 @@
15 */ 15 */
16 16
17#include <linux/string.h> 17#include <linux/string.h>
18#include <linux/bootmem.h>
18#include <asm/ppc_sys.h> 19#include <asm/ppc_sys.h>
19 20
20int (*ppc_sys_device_fixup) (struct platform_device * pdev); 21int (*ppc_sys_device_fixup) (struct platform_device * pdev);
21 22
22static int ppc_sys_inited; 23static int ppc_sys_inited;
24static int ppc_sys_func_inited;
25
26static const char *ppc_sys_func_names[] = {
27 [PPC_SYS_FUNC_DUMMY] = "dummy",
28 [PPC_SYS_FUNC_ETH] = "eth",
29 [PPC_SYS_FUNC_UART] = "uart",
30 [PPC_SYS_FUNC_HLDC] = "hldc",
31 [PPC_SYS_FUNC_USB] = "usb",
32 [PPC_SYS_FUNC_IRDA] = "irda",
33};
23 34
24void __init identify_ppc_sys_by_id(u32 id) 35void __init identify_ppc_sys_by_id(u32 id)
25{ 36{
@@ -38,13 +49,13 @@ void __init identify_ppc_sys_by_id(u32 id)
38void __init identify_ppc_sys_by_name(char *name) 49void __init identify_ppc_sys_by_name(char *name)
39{ 50{
40 unsigned int i = 0; 51 unsigned int i = 0;
41 while (ppc_sys_specs[i].ppc_sys_name[0]) 52 while (ppc_sys_specs[i].ppc_sys_name[0]) {
42 {
43 if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name)) 53 if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
44 break; 54 break;
45 i++; 55 i++;
46 } 56 }
47 cur_ppc_sys_spec = &ppc_sys_specs[i]; 57 cur_ppc_sys_spec = &ppc_sys_specs[i];
58
48 return; 59 return;
49} 60}
50 61
@@ -128,6 +139,165 @@ void ppc_sys_device_remove(enum ppc_sys_devices dev)
128 } 139 }
129} 140}
130 141
142/* Platform-notify mapping
143 * Helper function for BSP code to assign board-specific platfom-divice bits
144 */
145
146void platform_notify_map(const struct platform_notify_dev_map *map,
147 struct device *dev)
148{
149 struct platform_device *pdev;
150 int len, idx;
151 const char *s;
152
153 /* do nothing if no device or no bus_id */
154 if (!dev || !dev->bus_id)
155 return;
156
157 /* call per device map */
158 while (map->bus_id != NULL) {
159 idx = -1;
160 s = strrchr(dev->bus_id, '.');
161 if (s != NULL)
162 idx = (int)simple_strtol(s + 1, NULL, 10);
163 else
164 s = dev->bus_id;
165
166 len = s - dev->bus_id;
167
168 if (!strncmp(dev->bus_id, map->bus_id, len)) {
169 pdev = container_of(dev, struct platform_device, dev);
170 map->rtn(pdev, idx);
171 }
172 map++;
173 }
174}
175
176/*
177 Function assignment stuff.
178 Intended to work as follows:
179 the device name defined in foo_devices.c will be concatenated with :"func",
180 where func is string map of respective function from platfom_device_func enum
181
182 The PPC_SYS_FUNC_DUMMY function is intended to remove all assignments, making the device to appear
183 in platform bus with unmodified name.
184 */
185
186/*
187 Here we'll replace .name pointers with fixed-lenght strings
188 Hereby, this should be called *before* any func stuff triggeded.
189 */
190void ppc_sys_device_initfunc(void)
191{
192 int i;
193 const char *name;
194 static char new_names[NUM_PPC_SYS_DEVS][BUS_ID_SIZE];
195 enum ppc_sys_devices cur_dev;
196
197 /* If inited yet, do nothing */
198 if (ppc_sys_func_inited)
199 return;
200
201 for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
202 if ((cur_dev = cur_ppc_sys_spec->device_list[i]) < 0)
203 continue;
204
205 if (ppc_sys_platform_devices[cur_dev].name) {
206 /*backup name */
207 name = ppc_sys_platform_devices[cur_dev].name;
208 strlcpy(new_names[i], name, BUS_ID_SIZE);
209 ppc_sys_platform_devices[cur_dev].name = new_names[i];
210 }
211 }
212
213 ppc_sys_func_inited = 1;
214}
215
216/*The "engine" of the func stuff. Here we either concat specified function string description
217 to the name, or remove it if PPC_SYS_FUNC_DUMMY parameter is passed here*/
218void ppc_sys_device_setfunc(enum ppc_sys_devices dev,
219 enum platform_device_func func)
220{
221 char *s;
222 char *name = (char *)ppc_sys_platform_devices[dev].name;
223 char tmp[BUS_ID_SIZE];
224
225 if (!ppc_sys_func_inited) {
226 printk(KERN_ERR "Unable to alter function - not inited!\n");
227 return;
228 }
229
230 if (ppc_sys_inited) {
231 platform_device_unregister(&ppc_sys_platform_devices[dev]);
232 }
233
234 if ((s = (char *)strchr(name, ':')) != NULL) { /* reassign */
235 /* Either change the name after ':' or remove func modifications */
236 if (func != PPC_SYS_FUNC_DUMMY)
237 strlcpy(s + 1, ppc_sys_func_names[func], BUS_ID_SIZE);
238 else
239 *s = 0;
240 } else if (func != PPC_SYS_FUNC_DUMMY) {
241 /* do assignment if it is not just "clear" request */
242 sprintf(tmp, "%s:%s", name, ppc_sys_func_names[func]);
243 strlcpy(name, tmp, BUS_ID_SIZE);
244 }
245
246 if (ppc_sys_inited) {
247 platform_device_register(&ppc_sys_platform_devices[dev]);
248 }
249}
250
251void ppc_sys_device_disable(enum ppc_sys_devices dev)
252{
253 BUG_ON(cur_ppc_sys_spec == NULL);
254
255 /*Check if it is enabled*/
256 if(!(cur_ppc_sys_spec->config[dev] & PPC_SYS_CONFIG_DISABLED)) {
257 if (ppc_sys_inited) {
258 platform_device_unregister(&ppc_sys_platform_devices[dev]);
259 }
260 cur_ppc_sys_spec->config[dev] |= PPC_SYS_CONFIG_DISABLED;
261 }
262}
263
264void ppc_sys_device_enable(enum ppc_sys_devices dev)
265{
266 BUG_ON(cur_ppc_sys_spec == NULL);
267
268 /*Check if it is disabled*/
269 if(cur_ppc_sys_spec->config[dev] & PPC_SYS_CONFIG_DISABLED) {
270 if (ppc_sys_inited) {
271 platform_device_register(&ppc_sys_platform_devices[dev]);
272 }
273 cur_ppc_sys_spec->config[dev] &= ~PPC_SYS_CONFIG_DISABLED;
274 }
275
276}
277
278void ppc_sys_device_enable_all(void)
279{
280 enum ppc_sys_devices cur_dev;
281 int i;
282
283 for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
284 cur_dev = cur_ppc_sys_spec->device_list[i];
285 ppc_sys_device_enable(cur_dev);
286 }
287}
288
289void ppc_sys_device_disable_all(void)
290{
291 enum ppc_sys_devices cur_dev;
292 int i;
293
294 for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
295 cur_dev = cur_ppc_sys_spec->device_list[i];
296 ppc_sys_device_disable(cur_dev);
297 }
298}
299
300
131static int __init ppc_sys_init(void) 301static int __init ppc_sys_init(void)
132{ 302{
133 unsigned int i, dev_id, ret = 0; 303 unsigned int i, dev_id, ret = 0;
@@ -136,7 +306,8 @@ static int __init ppc_sys_init(void)
136 306
137 for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) { 307 for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
138 dev_id = cur_ppc_sys_spec->device_list[i]; 308 dev_id = cur_ppc_sys_spec->device_list[i];
139 if (dev_id != -1) { 309 if ((dev_id != -1) &&
310 !(cur_ppc_sys_spec->config[dev_id] & PPC_SYS_CONFIG_DISABLED)) {
140 if (ppc_sys_device_fixup != NULL) 311 if (ppc_sys_device_fixup != NULL)
141 ppc_sys_device_fixup(&ppc_sys_platform_devices 312 ppc_sys_device_fixup(&ppc_sys_platform_devices
142 [dev_id]); 313 [dev_id]);
diff --git a/include/asm-ppc/mpc10x.h b/include/asm-ppc/mpc10x.h
index 77b1e092c206..976ad3d94f27 100644
--- a/include/asm-ppc/mpc10x.h
+++ b/include/asm-ppc/mpc10x.h
@@ -165,6 +165,7 @@ enum ppc_sys_devices {
165 MPC10X_DMA1, 165 MPC10X_DMA1,
166 MPC10X_UART0, 166 MPC10X_UART0,
167 MPC10X_UART1, 167 MPC10X_UART1,
168 NUM_PPC_SYS_DEVS,
168}; 169};
169 170
170int mpc10x_bridge_init(struct pci_controller *hose, 171int mpc10x_bridge_init(struct pci_controller *hose,
diff --git a/include/asm-ppc/mpc52xx.h b/include/asm-ppc/mpc52xx.h
index a055e0756b9d..6167f74635f7 100644
--- a/include/asm-ppc/mpc52xx.h
+++ b/include/asm-ppc/mpc52xx.h
@@ -60,6 +60,7 @@ enum ppc_sys_devices {
60 MPC52xx_ATA, 60 MPC52xx_ATA,
61 MPC52xx_I2C1, 61 MPC52xx_I2C1,
62 MPC52xx_I2C2, 62 MPC52xx_I2C2,
63 NUM_PPC_SYS_DEVS,
63}; 64};
64 65
65 66
diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h
index 321452695039..6ba69a86b9dd 100644
--- a/include/asm-ppc/mpc8260.h
+++ b/include/asm-ppc/mpc8260.h
@@ -83,6 +83,7 @@ enum ppc_sys_devices {
83 MPC82xx_CPM_SMC2, 83 MPC82xx_CPM_SMC2,
84 MPC82xx_CPM_USB, 84 MPC82xx_CPM_USB,
85 MPC82xx_SEC1, 85 MPC82xx_SEC1,
86 NUM_PPC_SYS_DEVS,
86}; 87};
87 88
88#ifndef __ASSEMBLY__ 89#ifndef __ASSEMBLY__
diff --git a/include/asm-ppc/mpc83xx.h b/include/asm-ppc/mpc83xx.h
index 7cdf60fa69b6..3c23fc43bfbc 100644
--- a/include/asm-ppc/mpc83xx.h
+++ b/include/asm-ppc/mpc83xx.h
@@ -108,6 +108,7 @@ enum ppc_sys_devices {
108 MPC83xx_USB2_DR, 108 MPC83xx_USB2_DR,
109 MPC83xx_USB2_MPH, 109 MPC83xx_USB2_MPH,
110 MPC83xx_MDIO, 110 MPC83xx_MDIO,
111 NUM_PPC_SYS_DEVS,
111}; 112};
112 113
113#endif /* CONFIG_83xx */ 114#endif /* CONFIG_83xx */
diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
index c8a96aa44fb7..f47002a60edf 100644
--- a/include/asm-ppc/mpc85xx.h
+++ b/include/asm-ppc/mpc85xx.h
@@ -139,6 +139,7 @@ enum ppc_sys_devices {
139 MPC85xx_eTSEC4, 139 MPC85xx_eTSEC4,
140 MPC85xx_IIC2, 140 MPC85xx_IIC2,
141 MPC85xx_MDIO, 141 MPC85xx_MDIO,
142 NUM_PPC_SYS_DEVS,
142}; 143};
143 144
144/* Internal interrupts are all Level Sensitive, and Positive Polarity */ 145/* Internal interrupts are all Level Sensitive, and Positive Polarity */
diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h
index 73ec9a6db0b1..3515a7fa6c89 100644
--- a/include/asm-ppc/mpc8xx.h
+++ b/include/asm-ppc/mpc8xx.h
@@ -111,6 +111,7 @@ enum ppc_sys_devices {
111 MPC8xx_CPM_SMC1, 111 MPC8xx_CPM_SMC1,
112 MPC8xx_CPM_SMC2, 112 MPC8xx_CPM_SMC2,
113 MPC8xx_CPM_USB, 113 MPC8xx_CPM_USB,
114 NUM_PPC_SYS_DEVS,
114}; 115};
115 116
116#define PPC_PIN_SIZE (24 * 1024 * 1024) /* 24Mbytes of data pinned */ 117#define PPC_PIN_SIZE (24 * 1024 * 1024) /* 24Mbytes of data pinned */
diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
index bdc4dde35edd..4b94f7059ebe 100644
--- a/include/asm-ppc/ppc_sys.h
+++ b/include/asm-ppc/ppc_sys.h
@@ -46,9 +46,26 @@ struct ppc_sys_spec {
46 u32 value; 46 u32 value;
47 u32 num_devices; 47 u32 num_devices;
48 char *ppc_sys_name; 48 char *ppc_sys_name;
49 u8 config[NUM_PPC_SYS_DEVS];
49 enum ppc_sys_devices *device_list; 50 enum ppc_sys_devices *device_list;
50}; 51};
51 52
53struct platform_notify_dev_map {
54 const char *bus_id;
55 void (*rtn)(struct platform_device * pdev, int idx);
56};
57
58enum platform_device_func {
59 PPC_SYS_FUNC_DUMMY = 0,
60 PPC_SYS_FUNC_ETH = 1,
61 PPC_SYS_FUNC_UART = 2,
62 PPC_SYS_FUNC_HLDC = 3,
63 PPC_SYS_FUNC_USB = 4,
64 PPC_SYS_FUNC_IRDA = 5,
65};
66
67#define PPC_SYS_CONFIG_DISABLED 1
68
52/* describes all specific chips and which devices they have on them */ 69/* describes all specific chips and which devices they have on them */
53extern struct ppc_sys_spec ppc_sys_specs[]; 70extern struct ppc_sys_spec ppc_sys_specs[];
54extern struct ppc_sys_spec *cur_ppc_sys_spec; 71extern struct ppc_sys_spec *cur_ppc_sys_spec;
@@ -74,5 +91,20 @@ extern void *ppc_sys_get_pdata(enum ppc_sys_devices dev) __init;
74/* remove a device from the system */ 91/* remove a device from the system */
75extern void ppc_sys_device_remove(enum ppc_sys_devices dev); 92extern void ppc_sys_device_remove(enum ppc_sys_devices dev);
76 93
94/* Function assignment stuff */
95void ppc_sys_device_initfunc(void);
96void ppc_sys_device_setfunc(enum ppc_sys_devices dev,
97 enum platform_device_func func);
98void ppc_sys_device_set_func_all(enum platform_device_func func);
99
100void platform_notify_map(const struct platform_notify_dev_map *map,
101 struct device *dev);
102
103/* Enable / disable stuff */
104void ppc_sys_device_disable(enum ppc_sys_devices dev);
105void ppc_sys_device_enable(enum ppc_sys_devices dev);
106void ppc_sys_device_enable_all(void);
107void ppc_sys_device_disable_all(void);
108
77#endif /* __ASM_PPC_SYS_H */ 109#endif /* __ASM_PPC_SYS_H */
78#endif /* __KERNEL__ */ 110#endif /* __KERNEL__ */