aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVitaly Bordug <vbordug@ru.mvista.com>2006-01-20 14:22:34 -0500
committerPaul Mackerras <paulus@samba.org>2006-02-10 00:52:46 -0500
commit75288c78c69020a574d93770c3a941b785f3d93d (patch)
tree091bcfa5a507e5f1dd387980047854be448f415c
parent1965746bce49ddf001af52c7985e16343c768021 (diff)
[PATCH] ppc32: Make platform devices being able to assign functions
Implemented by modification of the .name field of the platform device, when PDs with the same names are to be used within different drivers, as <device_name> -> <device_name>:<function> Corresponding drivers should change the .name in struct device_driver to reflect upper of course. Added ppc_sys_device_disable/enable function set, making it easier to disable all the inexistent/not utilized platform device way pdevs. By the check of the "disabled" bit in the config field of ppc_sys_specs, disabled platform devices will be either added/removed from the bus, or simply not registered on it, depending on the time when disable/enable call asserted. The default behaviour when nothing is disabled/enabled will be "all devices are enabled", which is the same as before. Also helper platform_notify_map function added, making assignment of board-specific platform_info more consistent and generic. Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com> Signed-off-by: Marcelo Tosatti <marcelo.tosatti@cyclades.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
-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__ */