diff options
-rw-r--r-- | arch/ppc/syslib/ppc_sys.c | 177 | ||||
-rw-r--r-- | include/asm-ppc/mpc10x.h | 1 | ||||
-rw-r--r-- | include/asm-ppc/mpc52xx.h | 1 | ||||
-rw-r--r-- | include/asm-ppc/mpc8260.h | 1 | ||||
-rw-r--r-- | include/asm-ppc/mpc83xx.h | 1 | ||||
-rw-r--r-- | include/asm-ppc/mpc85xx.h | 1 | ||||
-rw-r--r-- | include/asm-ppc/mpc8xx.h | 1 | ||||
-rw-r--r-- | include/asm-ppc/ppc_sys.h | 32 |
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 | ||
20 | int (*ppc_sys_device_fixup) (struct platform_device * pdev); | 21 | int (*ppc_sys_device_fixup) (struct platform_device * pdev); |
21 | 22 | ||
22 | static int ppc_sys_inited; | 23 | static int ppc_sys_inited; |
24 | static int ppc_sys_func_inited; | ||
25 | |||
26 | static 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 | ||
24 | void __init identify_ppc_sys_by_id(u32 id) | 35 | void __init identify_ppc_sys_by_id(u32 id) |
25 | { | 36 | { |
@@ -38,13 +49,13 @@ void __init identify_ppc_sys_by_id(u32 id) | |||
38 | void __init identify_ppc_sys_by_name(char *name) | 49 | void __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 | |||
146 | void 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 | */ | ||
190 | void 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*/ | ||
218 | void 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 | |||
251 | void 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 | |||
264 | void 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 | |||
278 | void 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 | |||
289 | void 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 | |||
131 | static int __init ppc_sys_init(void) | 301 | static 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 | ||
170 | int mpc10x_bridge_init(struct pci_controller *hose, | 171 | int 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 | ||
53 | struct platform_notify_dev_map { | ||
54 | const char *bus_id; | ||
55 | void (*rtn)(struct platform_device * pdev, int idx); | ||
56 | }; | ||
57 | |||
58 | enum 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 */ |
53 | extern struct ppc_sys_spec ppc_sys_specs[]; | 70 | extern struct ppc_sys_spec ppc_sys_specs[]; |
54 | extern struct ppc_sys_spec *cur_ppc_sys_spec; | 71 | extern 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 */ |
75 | extern void ppc_sys_device_remove(enum ppc_sys_devices dev); | 92 | extern void ppc_sys_device_remove(enum ppc_sys_devices dev); |
76 | 93 | ||
94 | /* Function assignment stuff */ | ||
95 | void ppc_sys_device_initfunc(void); | ||
96 | void ppc_sys_device_setfunc(enum ppc_sys_devices dev, | ||
97 | enum platform_device_func func); | ||
98 | void ppc_sys_device_set_func_all(enum platform_device_func func); | ||
99 | |||
100 | void platform_notify_map(const struct platform_notify_dev_map *map, | ||
101 | struct device *dev); | ||
102 | |||
103 | /* Enable / disable stuff */ | ||
104 | void ppc_sys_device_disable(enum ppc_sys_devices dev); | ||
105 | void ppc_sys_device_enable(enum ppc_sys_devices dev); | ||
106 | void ppc_sys_device_enable_all(void); | ||
107 | void 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__ */ |