diff options
Diffstat (limited to 'arch/powerpc/platforms/powermac/setup.c')
-rw-r--r-- | arch/powerpc/platforms/powermac/setup.c | 663 |
1 files changed, 663 insertions, 0 deletions
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c new file mode 100644 index 000000000000..1b12bf9956cb --- /dev/null +++ b/arch/powerpc/platforms/powermac/setup.c | |||
@@ -0,0 +1,663 @@ | |||
1 | /* | ||
2 | * arch/ppc/platforms/setup.c | ||
3 | * | ||
4 | * PowerPC version | ||
5 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | ||
6 | * | ||
7 | * Adapted for Power Macintosh by Paul Mackerras | ||
8 | * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) | ||
9 | * | ||
10 | * Derived from "arch/alpha/kernel/setup.c" | ||
11 | * Copyright (C) 1995 Linus Torvalds | ||
12 | * | ||
13 | * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org) | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License | ||
17 | * as published by the Free Software Foundation; either version | ||
18 | * 2 of the License, or (at your option) any later version. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * bootup setup stuff.. | ||
24 | */ | ||
25 | |||
26 | #include <linux/config.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/errno.h> | ||
29 | #include <linux/sched.h> | ||
30 | #include <linux/kernel.h> | ||
31 | #include <linux/mm.h> | ||
32 | #include <linux/stddef.h> | ||
33 | #include <linux/unistd.h> | ||
34 | #include <linux/ptrace.h> | ||
35 | #include <linux/slab.h> | ||
36 | #include <linux/user.h> | ||
37 | #include <linux/a.out.h> | ||
38 | #include <linux/tty.h> | ||
39 | #include <linux/string.h> | ||
40 | #include <linux/delay.h> | ||
41 | #include <linux/ioport.h> | ||
42 | #include <linux/major.h> | ||
43 | #include <linux/initrd.h> | ||
44 | #include <linux/vt_kern.h> | ||
45 | #include <linux/console.h> | ||
46 | #include <linux/ide.h> | ||
47 | #include <linux/pci.h> | ||
48 | #include <linux/adb.h> | ||
49 | #include <linux/cuda.h> | ||
50 | #include <linux/pmu.h> | ||
51 | #include <linux/irq.h> | ||
52 | #include <linux/seq_file.h> | ||
53 | #include <linux/root_dev.h> | ||
54 | #include <linux/bitops.h> | ||
55 | #include <linux/suspend.h> | ||
56 | |||
57 | #include <asm/reg.h> | ||
58 | #include <asm/sections.h> | ||
59 | #include <asm/prom.h> | ||
60 | #include <asm/system.h> | ||
61 | #include <asm/pgtable.h> | ||
62 | #include <asm/io.h> | ||
63 | #include <asm/pci-bridge.h> | ||
64 | #include <asm/ohare.h> | ||
65 | #include <asm/mediabay.h> | ||
66 | #include <asm/machdep.h> | ||
67 | #include <asm/dma.h> | ||
68 | #include <asm/bootx.h> | ||
69 | #include <asm/cputable.h> | ||
70 | #include <asm/btext.h> | ||
71 | #include <asm/pmac_feature.h> | ||
72 | #include <asm/time.h> | ||
73 | #include <asm/of_device.h> | ||
74 | #include <asm/mmu_context.h> | ||
75 | |||
76 | #include "pmac_pic.h" | ||
77 | |||
78 | #undef SHOW_GATWICK_IRQS | ||
79 | |||
80 | extern long pmac_time_init(void); | ||
81 | extern unsigned long pmac_get_rtc_time(void); | ||
82 | extern int pmac_set_rtc_time(unsigned long nowtime); | ||
83 | extern void pmac_read_rtc_time(void); | ||
84 | extern void pmac_calibrate_decr(void); | ||
85 | extern void pmac_pcibios_fixup(void); | ||
86 | extern void pmac_find_bridges(void); | ||
87 | extern unsigned long pmac_ide_get_base(int index); | ||
88 | extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, | ||
89 | unsigned long data_port, unsigned long ctrl_port, int *irq); | ||
90 | |||
91 | extern void pmac_nvram_update(void); | ||
92 | extern unsigned char pmac_nvram_read_byte(int addr); | ||
93 | extern void pmac_nvram_write_byte(int addr, unsigned char val); | ||
94 | extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial); | ||
95 | extern void pmac_pcibios_after_init(void); | ||
96 | extern int of_show_percpuinfo(struct seq_file *m, int i); | ||
97 | |||
98 | unsigned char drive_info; | ||
99 | |||
100 | int ppc_override_l2cr = 0; | ||
101 | int ppc_override_l2cr_value; | ||
102 | int has_l2cache = 0; | ||
103 | |||
104 | int pmac_newworld = 1; | ||
105 | |||
106 | static int current_root_goodness = -1; | ||
107 | |||
108 | extern int pmac_newworld; | ||
109 | |||
110 | #define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */ | ||
111 | |||
112 | extern void zs_kgdb_hook(int tty_num); | ||
113 | static void ohare_init(void); | ||
114 | #ifdef CONFIG_BOOTX_TEXT | ||
115 | static void pmac_progress(char *s, unsigned short hex); | ||
116 | #endif | ||
117 | |||
118 | sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN; | ||
119 | |||
120 | #ifdef CONFIG_SMP | ||
121 | extern struct smp_ops_t psurge_smp_ops; | ||
122 | extern struct smp_ops_t core99_smp_ops; | ||
123 | #endif /* CONFIG_SMP */ | ||
124 | |||
125 | static int | ||
126 | pmac_show_cpuinfo(struct seq_file *m) | ||
127 | { | ||
128 | struct device_node *np; | ||
129 | char *pp; | ||
130 | int plen; | ||
131 | int mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, | ||
132 | NULL, PMAC_MB_INFO_MODEL, 0); | ||
133 | unsigned int mbflags = (unsigned int)pmac_call_feature(PMAC_FTR_GET_MB_INFO, | ||
134 | NULL, PMAC_MB_INFO_FLAGS, 0); | ||
135 | char* mbname; | ||
136 | |||
137 | if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, (int)&mbname) != 0) | ||
138 | mbname = "Unknown"; | ||
139 | |||
140 | /* find motherboard type */ | ||
141 | seq_printf(m, "machine\t\t: "); | ||
142 | np = find_devices("device-tree"); | ||
143 | if (np != NULL) { | ||
144 | pp = (char *) get_property(np, "model", NULL); | ||
145 | if (pp != NULL) | ||
146 | seq_printf(m, "%s\n", pp); | ||
147 | else | ||
148 | seq_printf(m, "PowerMac\n"); | ||
149 | pp = (char *) get_property(np, "compatible", &plen); | ||
150 | if (pp != NULL) { | ||
151 | seq_printf(m, "motherboard\t:"); | ||
152 | while (plen > 0) { | ||
153 | int l = strlen(pp) + 1; | ||
154 | seq_printf(m, " %s", pp); | ||
155 | plen -= l; | ||
156 | pp += l; | ||
157 | } | ||
158 | seq_printf(m, "\n"); | ||
159 | } | ||
160 | } else | ||
161 | seq_printf(m, "PowerMac\n"); | ||
162 | |||
163 | /* print parsed model */ | ||
164 | seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname); | ||
165 | seq_printf(m, "pmac flags\t: %08x\n", mbflags); | ||
166 | |||
167 | /* find l2 cache info */ | ||
168 | np = find_devices("l2-cache"); | ||
169 | if (np == 0) | ||
170 | np = find_type_devices("cache"); | ||
171 | if (np != 0) { | ||
172 | unsigned int *ic = (unsigned int *) | ||
173 | get_property(np, "i-cache-size", NULL); | ||
174 | unsigned int *dc = (unsigned int *) | ||
175 | get_property(np, "d-cache-size", NULL); | ||
176 | seq_printf(m, "L2 cache\t:"); | ||
177 | has_l2cache = 1; | ||
178 | if (get_property(np, "cache-unified", NULL) != 0 && dc) { | ||
179 | seq_printf(m, " %dK unified", *dc / 1024); | ||
180 | } else { | ||
181 | if (ic) | ||
182 | seq_printf(m, " %dK instruction", *ic / 1024); | ||
183 | if (dc) | ||
184 | seq_printf(m, "%s %dK data", | ||
185 | (ic? " +": ""), *dc / 1024); | ||
186 | } | ||
187 | pp = get_property(np, "ram-type", NULL); | ||
188 | if (pp) | ||
189 | seq_printf(m, " %s", pp); | ||
190 | seq_printf(m, "\n"); | ||
191 | } | ||
192 | |||
193 | /* find ram info */ | ||
194 | np = find_devices("memory"); | ||
195 | if (np != 0) { | ||
196 | int n; | ||
197 | struct reg_property *reg = (struct reg_property *) | ||
198 | get_property(np, "reg", &n); | ||
199 | |||
200 | if (reg != 0) { | ||
201 | unsigned long total = 0; | ||
202 | |||
203 | for (n /= sizeof(struct reg_property); n > 0; --n) | ||
204 | total += (reg++)->size; | ||
205 | seq_printf(m, "memory\t\t: %luMB\n", total >> 20); | ||
206 | } | ||
207 | } | ||
208 | |||
209 | /* Checks "l2cr-value" property in the registry */ | ||
210 | np = find_devices("cpus"); | ||
211 | if (np == 0) | ||
212 | np = find_type_devices("cpu"); | ||
213 | if (np != 0) { | ||
214 | unsigned int *l2cr = (unsigned int *) | ||
215 | get_property(np, "l2cr-value", NULL); | ||
216 | if (l2cr != 0) { | ||
217 | seq_printf(m, "l2cr override\t: 0x%x\n", *l2cr); | ||
218 | } | ||
219 | } | ||
220 | |||
221 | /* Indicate newworld/oldworld */ | ||
222 | seq_printf(m, "pmac-generation\t: %s\n", | ||
223 | pmac_newworld ? "NewWorld" : "OldWorld"); | ||
224 | |||
225 | |||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | static int | ||
230 | pmac_show_percpuinfo(struct seq_file *m, int i) | ||
231 | { | ||
232 | #ifdef CONFIG_CPU_FREQ_PMAC | ||
233 | extern unsigned int pmac_get_one_cpufreq(int i); | ||
234 | unsigned int freq = pmac_get_one_cpufreq(i); | ||
235 | if (freq != 0) { | ||
236 | seq_printf(m, "clock\t\t: %dMHz\n", freq/1000); | ||
237 | return 0; | ||
238 | } | ||
239 | #endif /* CONFIG_CPU_FREQ_PMAC */ | ||
240 | return of_show_percpuinfo(m, i); | ||
241 | } | ||
242 | |||
243 | static volatile u32 *sysctrl_regs; | ||
244 | |||
245 | void __init | ||
246 | pmac_setup_arch(void) | ||
247 | { | ||
248 | struct device_node *cpu; | ||
249 | int *fp; | ||
250 | unsigned long pvr; | ||
251 | |||
252 | pvr = PVR_VER(mfspr(SPRN_PVR)); | ||
253 | |||
254 | /* Set loops_per_jiffy to a half-way reasonable value, | ||
255 | for use until calibrate_delay gets called. */ | ||
256 | cpu = find_type_devices("cpu"); | ||
257 | if (cpu != 0) { | ||
258 | fp = (int *) get_property(cpu, "clock-frequency", NULL); | ||
259 | if (fp != 0) { | ||
260 | if (pvr == 4 || pvr >= 8) | ||
261 | /* 604, G3, G4 etc. */ | ||
262 | loops_per_jiffy = *fp / HZ; | ||
263 | else | ||
264 | /* 601, 603, etc. */ | ||
265 | loops_per_jiffy = *fp / (2*HZ); | ||
266 | } else | ||
267 | loops_per_jiffy = 50000000 / HZ; | ||
268 | } | ||
269 | |||
270 | /* this area has the CPU identification register | ||
271 | and some registers used by smp boards */ | ||
272 | sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000); | ||
273 | ohare_init(); | ||
274 | |||
275 | /* Lookup PCI hosts */ | ||
276 | pmac_find_bridges(); | ||
277 | |||
278 | /* Checks "l2cr-value" property in the registry */ | ||
279 | if (cpu_has_feature(CPU_FTR_L2CR)) { | ||
280 | struct device_node *np = find_devices("cpus"); | ||
281 | if (np == 0) | ||
282 | np = find_type_devices("cpu"); | ||
283 | if (np != 0) { | ||
284 | unsigned int *l2cr = (unsigned int *) | ||
285 | get_property(np, "l2cr-value", NULL); | ||
286 | if (l2cr != 0) { | ||
287 | ppc_override_l2cr = 1; | ||
288 | ppc_override_l2cr_value = *l2cr; | ||
289 | _set_L2CR(0); | ||
290 | _set_L2CR(ppc_override_l2cr_value); | ||
291 | } | ||
292 | } | ||
293 | } | ||
294 | |||
295 | if (ppc_override_l2cr) | ||
296 | printk(KERN_INFO "L2CR overriden (0x%x), backside cache is %s\n", | ||
297 | ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000) | ||
298 | ? "enabled" : "disabled"); | ||
299 | |||
300 | #ifdef CONFIG_KGDB | ||
301 | zs_kgdb_hook(0); | ||
302 | #endif | ||
303 | |||
304 | #ifdef CONFIG_ADB_CUDA | ||
305 | find_via_cuda(); | ||
306 | #else | ||
307 | if (find_devices("via-cuda")) { | ||
308 | printk("WARNING ! Your machine is Cuda based but your kernel\n"); | ||
309 | printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n"); | ||
310 | } | ||
311 | #endif | ||
312 | #ifdef CONFIG_ADB_PMU | ||
313 | find_via_pmu(); | ||
314 | #else | ||
315 | if (find_devices("via-pmu")) { | ||
316 | printk("WARNING ! Your machine is PMU based but your kernel\n"); | ||
317 | printk(" wasn't compiled with CONFIG_ADB_PMU option !\n"); | ||
318 | } | ||
319 | #endif | ||
320 | #ifdef CONFIG_NVRAM | ||
321 | pmac_nvram_init(); | ||
322 | #endif | ||
323 | #ifdef CONFIG_BLK_DEV_INITRD | ||
324 | if (initrd_start) | ||
325 | ROOT_DEV = Root_RAM0; | ||
326 | else | ||
327 | #endif | ||
328 | ROOT_DEV = DEFAULT_ROOT_DEVICE; | ||
329 | |||
330 | #ifdef CONFIG_SMP | ||
331 | /* Check for Core99 */ | ||
332 | if (find_devices("uni-n") || find_devices("u3")) | ||
333 | ppc_md.smp_ops = &core99_smp_ops; | ||
334 | else | ||
335 | ppc_md.smp_ops = &psurge_smp_ops; | ||
336 | #endif /* CONFIG_SMP */ | ||
337 | |||
338 | pci_create_OF_bus_map(); | ||
339 | } | ||
340 | |||
341 | static void __init ohare_init(void) | ||
342 | { | ||
343 | /* | ||
344 | * Turn on the L2 cache. | ||
345 | * We assume that we have a PSX memory controller iff | ||
346 | * we have an ohare I/O controller. | ||
347 | */ | ||
348 | if (find_devices("ohare") != NULL) { | ||
349 | if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) { | ||
350 | if (sysctrl_regs[4] & 0x10) | ||
351 | sysctrl_regs[4] |= 0x04000020; | ||
352 | else | ||
353 | sysctrl_regs[4] |= 0x04000000; | ||
354 | if(has_l2cache) | ||
355 | printk(KERN_INFO "Level 2 cache enabled\n"); | ||
356 | } | ||
357 | } | ||
358 | } | ||
359 | |||
360 | char *bootpath; | ||
361 | char *bootdevice; | ||
362 | void *boot_host; | ||
363 | int boot_target; | ||
364 | int boot_part; | ||
365 | extern dev_t boot_dev; | ||
366 | |||
367 | #ifdef CONFIG_SCSI | ||
368 | void __init | ||
369 | note_scsi_host(struct device_node *node, void *host) | ||
370 | { | ||
371 | int l; | ||
372 | char *p; | ||
373 | |||
374 | l = strlen(node->full_name); | ||
375 | if (bootpath != NULL && bootdevice != NULL | ||
376 | && strncmp(node->full_name, bootdevice, l) == 0 | ||
377 | && (bootdevice[l] == '/' || bootdevice[l] == 0)) { | ||
378 | boot_host = host; | ||
379 | /* | ||
380 | * There's a bug in OF 1.0.5. (Why am I not surprised.) | ||
381 | * If you pass a path like scsi/sd@1:0 to canon, it returns | ||
382 | * something like /bandit@F2000000/gc@10/53c94@10000/sd@0,0 | ||
383 | * That is, the scsi target number doesn't get preserved. | ||
384 | * So we pick the target number out of bootpath and use that. | ||
385 | */ | ||
386 | p = strstr(bootpath, "/sd@"); | ||
387 | if (p != NULL) { | ||
388 | p += 4; | ||
389 | boot_target = simple_strtoul(p, NULL, 10); | ||
390 | p = strchr(p, ':'); | ||
391 | if (p != NULL) | ||
392 | boot_part = simple_strtoul(p + 1, NULL, 10); | ||
393 | } | ||
394 | } | ||
395 | } | ||
396 | EXPORT_SYMBOL(note_scsi_host); | ||
397 | #endif | ||
398 | |||
399 | #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) | ||
400 | static dev_t __init | ||
401 | find_ide_boot(void) | ||
402 | { | ||
403 | char *p; | ||
404 | int n; | ||
405 | dev_t __init pmac_find_ide_boot(char *bootdevice, int n); | ||
406 | |||
407 | if (bootdevice == NULL) | ||
408 | return 0; | ||
409 | p = strrchr(bootdevice, '/'); | ||
410 | if (p == NULL) | ||
411 | return 0; | ||
412 | n = p - bootdevice; | ||
413 | |||
414 | return pmac_find_ide_boot(bootdevice, n); | ||
415 | } | ||
416 | #endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */ | ||
417 | |||
418 | static void __init | ||
419 | find_boot_device(void) | ||
420 | { | ||
421 | #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) | ||
422 | boot_dev = find_ide_boot(); | ||
423 | #endif | ||
424 | } | ||
425 | |||
426 | static int initializing = 1; | ||
427 | /* TODO: Merge the suspend-to-ram with the common code !!! | ||
428 | * currently, this is a stub implementation for suspend-to-disk | ||
429 | * only | ||
430 | */ | ||
431 | |||
432 | #ifdef CONFIG_SOFTWARE_SUSPEND | ||
433 | |||
434 | static int pmac_pm_prepare(suspend_state_t state) | ||
435 | { | ||
436 | printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); | ||
437 | |||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | static int pmac_pm_enter(suspend_state_t state) | ||
442 | { | ||
443 | printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); | ||
444 | |||
445 | /* Giveup the lazy FPU & vec so we don't have to back them | ||
446 | * up from the low level code | ||
447 | */ | ||
448 | enable_kernel_fp(); | ||
449 | |||
450 | #ifdef CONFIG_ALTIVEC | ||
451 | if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) | ||
452 | enable_kernel_altivec(); | ||
453 | #endif /* CONFIG_ALTIVEC */ | ||
454 | |||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | static int pmac_pm_finish(suspend_state_t state) | ||
459 | { | ||
460 | printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); | ||
461 | |||
462 | /* Restore userland MMU context */ | ||
463 | set_context(current->active_mm->context, current->active_mm->pgd); | ||
464 | |||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | static struct pm_ops pmac_pm_ops = { | ||
469 | .pm_disk_mode = PM_DISK_SHUTDOWN, | ||
470 | .prepare = pmac_pm_prepare, | ||
471 | .enter = pmac_pm_enter, | ||
472 | .finish = pmac_pm_finish, | ||
473 | }; | ||
474 | |||
475 | #endif /* CONFIG_SOFTWARE_SUSPEND */ | ||
476 | |||
477 | static int pmac_late_init(void) | ||
478 | { | ||
479 | initializing = 0; | ||
480 | #ifdef CONFIG_SOFTWARE_SUSPEND | ||
481 | pm_set_ops(&pmac_pm_ops); | ||
482 | #endif /* CONFIG_SOFTWARE_SUSPEND */ | ||
483 | return 0; | ||
484 | } | ||
485 | |||
486 | late_initcall(pmac_late_init); | ||
487 | |||
488 | /* can't be __init - can be called whenever a disk is first accessed */ | ||
489 | void | ||
490 | note_bootable_part(dev_t dev, int part, int goodness) | ||
491 | { | ||
492 | static int found_boot = 0; | ||
493 | char *p; | ||
494 | |||
495 | if (!initializing) | ||
496 | return; | ||
497 | if ((goodness <= current_root_goodness) && | ||
498 | ROOT_DEV != DEFAULT_ROOT_DEVICE) | ||
499 | return; | ||
500 | p = strstr(saved_command_line, "root="); | ||
501 | if (p != NULL && (p == saved_command_line || p[-1] == ' ')) | ||
502 | return; | ||
503 | |||
504 | if (!found_boot) { | ||
505 | find_boot_device(); | ||
506 | found_boot = 1; | ||
507 | } | ||
508 | if (!boot_dev || dev == boot_dev) { | ||
509 | ROOT_DEV = dev + part; | ||
510 | boot_dev = 0; | ||
511 | current_root_goodness = goodness; | ||
512 | } | ||
513 | } | ||
514 | |||
515 | static void | ||
516 | pmac_restart(char *cmd) | ||
517 | { | ||
518 | #ifdef CONFIG_ADB_CUDA | ||
519 | struct adb_request req; | ||
520 | #endif /* CONFIG_ADB_CUDA */ | ||
521 | |||
522 | switch (sys_ctrler) { | ||
523 | #ifdef CONFIG_ADB_CUDA | ||
524 | case SYS_CTRLER_CUDA: | ||
525 | cuda_request(&req, NULL, 2, CUDA_PACKET, | ||
526 | CUDA_RESET_SYSTEM); | ||
527 | for (;;) | ||
528 | cuda_poll(); | ||
529 | break; | ||
530 | #endif /* CONFIG_ADB_CUDA */ | ||
531 | #ifdef CONFIG_ADB_PMU | ||
532 | case SYS_CTRLER_PMU: | ||
533 | pmu_restart(); | ||
534 | break; | ||
535 | #endif /* CONFIG_ADB_PMU */ | ||
536 | default: ; | ||
537 | } | ||
538 | } | ||
539 | |||
540 | static void | ||
541 | pmac_power_off(void) | ||
542 | { | ||
543 | #ifdef CONFIG_ADB_CUDA | ||
544 | struct adb_request req; | ||
545 | #endif /* CONFIG_ADB_CUDA */ | ||
546 | |||
547 | switch (sys_ctrler) { | ||
548 | #ifdef CONFIG_ADB_CUDA | ||
549 | case SYS_CTRLER_CUDA: | ||
550 | cuda_request(&req, NULL, 2, CUDA_PACKET, | ||
551 | CUDA_POWERDOWN); | ||
552 | for (;;) | ||
553 | cuda_poll(); | ||
554 | break; | ||
555 | #endif /* CONFIG_ADB_CUDA */ | ||
556 | #ifdef CONFIG_ADB_PMU | ||
557 | case SYS_CTRLER_PMU: | ||
558 | pmu_shutdown(); | ||
559 | break; | ||
560 | #endif /* CONFIG_ADB_PMU */ | ||
561 | default: ; | ||
562 | } | ||
563 | } | ||
564 | |||
565 | static void | ||
566 | pmac_halt(void) | ||
567 | { | ||
568 | pmac_power_off(); | ||
569 | } | ||
570 | |||
571 | void __init pmac_init(void) | ||
572 | { | ||
573 | /* isa_io_base gets set in pmac_find_bridges */ | ||
574 | isa_mem_base = PMAC_ISA_MEM_BASE; | ||
575 | pci_dram_offset = PMAC_PCI_DRAM_OFFSET; | ||
576 | ISA_DMA_THRESHOLD = ~0L; | ||
577 | DMA_MODE_READ = 1; | ||
578 | DMA_MODE_WRITE = 2; | ||
579 | |||
580 | ppc_md.setup_arch = pmac_setup_arch; | ||
581 | ppc_md.show_cpuinfo = pmac_show_cpuinfo; | ||
582 | ppc_md.show_percpuinfo = pmac_show_percpuinfo; | ||
583 | ppc_md.irq_canonicalize = NULL; | ||
584 | ppc_md.init_IRQ = pmac_pic_init; | ||
585 | ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */ | ||
586 | |||
587 | ppc_md.pcibios_fixup = pmac_pcibios_fixup; | ||
588 | ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook; | ||
589 | ppc_md.pcibios_after_init = pmac_pcibios_after_init; | ||
590 | ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; | ||
591 | |||
592 | ppc_md.restart = pmac_restart; | ||
593 | ppc_md.power_off = pmac_power_off; | ||
594 | ppc_md.halt = pmac_halt; | ||
595 | |||
596 | ppc_md.time_init = pmac_time_init; | ||
597 | ppc_md.set_rtc_time = pmac_set_rtc_time; | ||
598 | ppc_md.get_rtc_time = pmac_get_rtc_time; | ||
599 | ppc_md.calibrate_decr = pmac_calibrate_decr; | ||
600 | |||
601 | ppc_md.feature_call = pmac_do_feature_call; | ||
602 | |||
603 | #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) | ||
604 | #ifdef CONFIG_BLK_DEV_IDE_PMAC | ||
605 | ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; | ||
606 | ppc_ide_md.default_io_base = pmac_ide_get_base; | ||
607 | #endif /* CONFIG_BLK_DEV_IDE_PMAC */ | ||
608 | #endif /* defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) */ | ||
609 | |||
610 | #ifdef CONFIG_BOOTX_TEXT | ||
611 | ppc_md.progress = pmac_progress; | ||
612 | #endif /* CONFIG_BOOTX_TEXT */ | ||
613 | |||
614 | if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0); | ||
615 | |||
616 | } | ||
617 | |||
618 | #ifdef CONFIG_BOOTX_TEXT | ||
619 | static void __init | ||
620 | pmac_progress(char *s, unsigned short hex) | ||
621 | { | ||
622 | if (boot_text_mapped) { | ||
623 | btext_drawstring(s); | ||
624 | btext_drawchar('\n'); | ||
625 | } | ||
626 | } | ||
627 | #endif /* CONFIG_BOOTX_TEXT */ | ||
628 | |||
629 | static int __init | ||
630 | pmac_declare_of_platform_devices(void) | ||
631 | { | ||
632 | struct device_node *np; | ||
633 | |||
634 | np = find_devices("uni-n"); | ||
635 | if (np) { | ||
636 | for (np = np->child; np != NULL; np = np->sibling) | ||
637 | if (strncmp(np->name, "i2c", 3) == 0) { | ||
638 | of_platform_device_create(np, "uni-n-i2c", | ||
639 | NULL); | ||
640 | break; | ||
641 | } | ||
642 | } | ||
643 | np = find_devices("u3"); | ||
644 | if (np) { | ||
645 | for (np = np->child; np != NULL; np = np->sibling) | ||
646 | if (strncmp(np->name, "i2c", 3) == 0) { | ||
647 | of_platform_device_create(np, "u3-i2c", | ||
648 | NULL); | ||
649 | break; | ||
650 | } | ||
651 | } | ||
652 | |||
653 | np = find_devices("valkyrie"); | ||
654 | if (np) | ||
655 | of_platform_device_create(np, "valkyrie", NULL); | ||
656 | np = find_devices("platinum"); | ||
657 | if (np) | ||
658 | of_platform_device_create(np, "platinum", NULL); | ||
659 | |||
660 | return 0; | ||
661 | } | ||
662 | |||
663 | device_initcall(pmac_declare_of_platform_devices); | ||