aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2005-11-23 01:57:25 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 22:49:54 -0500
commit51d3082fe6e55aecfa17113dbe98077c749f724c (patch)
tree9a1e2355d5988d8cc1ca511d53c1bb24b0baa17f
parent463ce0e103f419f51b1769111e73fe8bb305d0ec (diff)
[PATCH] powerpc: Unify udbg (#2)
This patch unifies udbg for both ppc32 and ppc64 when building the merged achitecture. xmon now has a single "back end". The powermac udbg stuff gets enriched with some ADB capabilities and btext output. In addition, the early_init callback is now called on ppc32 as well, approx. in the same order as ppc64 regarding device-tree manipulations. The init sequences of ppc32 and ppc64 are getting closer, I'll unify them in a later patch. For now, you can force udbg to the scc using "sccdbg" or to btext using "btextdbg" on powermacs. I'll implement a cleaner way of forcing udbg output to something else than the autodetected OF output device in a later patch. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/Kconfig2
-rw-r--r--arch/powerpc/kernel/Makefile7
-rw-r--r--arch/powerpc/kernel/btext.c130
-rw-r--r--arch/powerpc/kernel/head_32.S29
-rw-r--r--arch/powerpc/kernel/setup_32.c28
-rw-r--r--arch/powerpc/kernel/setup_64.c4
-rw-r--r--arch/powerpc/kernel/udbg.c8
-rw-r--r--arch/powerpc/kernel/udbg_16550.c4
-rw-r--r--arch/powerpc/mm/init_32.c5
-rw-r--r--arch/powerpc/platforms/powermac/Makefile1
-rw-r--r--arch/powerpc/platforms/powermac/feature.c68
-rw-r--r--arch/powerpc/platforms/powermac/low_i2c.c27
-rw-r--r--arch/powerpc/platforms/powermac/pic.c2
-rw-r--r--arch/powerpc/platforms/powermac/setup.c52
-rw-r--r--arch/powerpc/platforms/powermac/udbg_adb.c218
-rw-r--r--arch/powerpc/platforms/powermac/udbg_scc.c (renamed from arch/powerpc/kernel/udbg_scc.c)64
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c8
-rw-r--r--arch/powerpc/xmon/Makefile8
-rw-r--r--arch/powerpc/xmon/start.c (renamed from arch/powerpc/xmon/start_64.c)0
-rw-r--r--arch/powerpc/xmon/start_32.c441
-rw-r--r--arch/powerpc/xmon/start_8xx.c44
-rw-r--r--arch/ppc/kernel/setup.c3
-rw-r--r--drivers/i2c/busses/i2c-keywest.c25
-rw-r--r--drivers/macintosh/via-cuda.c48
-rw-r--r--drivers/macintosh/via-pmu.c87
-rw-r--r--include/asm-powerpc/btext.h19
-rw-r--r--include/asm-powerpc/udbg.h9
-rw-r--r--include/asm-ppc/btext.h2
-rw-r--r--include/asm-ppc/machdep.h4
29 files changed, 627 insertions, 720 deletions
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 39ca7b9da369..0e4617104f8c 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -50,7 +50,7 @@ config PPC
50 50
51config EARLY_PRINTK 51config EARLY_PRINTK
52 bool 52 bool
53 default y if PPC64 53 default y
54 54
55config COMPAT 55config COMPAT
56 bool 56 bool
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index bf3fd6f02249..89714929f444 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -18,7 +18,7 @@ obj-y += vdso32/
18obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ 18obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
19 signal_64.o ptrace32.o systbl.o \ 19 signal_64.o ptrace32.o systbl.o \
20 paca.o ioctl32.o cpu_setup_power4.o \ 20 paca.o ioctl32.o cpu_setup_power4.o \
21 firmware.o sysfs.o udbg.o idle_64.o 21 firmware.o sysfs.o idle_64.o
22obj-$(CONFIG_PPC64) += vdso64/ 22obj-$(CONFIG_PPC64) += vdso64/
23obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o 23obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
24obj-$(CONFIG_POWER4) += idle_power4.o 24obj-$(CONFIG_POWER4) += idle_power4.o
@@ -46,7 +46,7 @@ extra-$(CONFIG_8xx) := head_8xx.o
46extra-y += vmlinux.lds 46extra-y += vmlinux.lds
47 47
48obj-y += process.o init_task.o time.o \ 48obj-y += process.o init_task.o time.o \
49 prom.o traps.o setup-common.o 49 prom.o traps.o setup-common.o udbg.o
50obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o systbl.o 50obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o systbl.o
51obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o 51obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o
52obj-$(CONFIG_PPC_OF) += prom_init.o 52obj-$(CONFIG_PPC_OF) += prom_init.o
@@ -56,8 +56,7 @@ obj-$(CONFIG_6xx) += idle_6xx.o
56obj-$(CONFIG_SMP) += smp.o 56obj-$(CONFIG_SMP) += smp.o
57obj-$(CONFIG_KPROBES) += kprobes.o 57obj-$(CONFIG_KPROBES) += kprobes.o
58obj-$(CONFIG_PPC_MULTIPLATFORM) += legacy_serial.o 58obj-$(CONFIG_PPC_MULTIPLATFORM) += legacy_serial.o
59obj64-$(CONFIG_PPC_MULTIPLATFORM) += udbg_16550.o 59obj-$(CONFIG_PPC_MULTIPLATFORM) += udbg_16550.o
60obj64-$(CONFIG_PPC_PMAC) += udbg_scc.o
61module-$(CONFIG_PPC64) += module_64.o 60module-$(CONFIG_PPC64) += module_64.o
62obj-$(CONFIG_MODULES) += $(module-y) 61obj-$(CONFIG_MODULES) += $(module-y)
63 62
diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c
index bdfba92b2b38..893dd24a9f67 100644
--- a/arch/powerpc/kernel/btext.c
+++ b/arch/powerpc/kernel/btext.c
@@ -31,15 +31,18 @@ static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb);
31static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb); 31static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb);
32static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb); 32static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb);
33 33
34static int g_loc_X; 34#define __force_data __attribute__((__section__(".data")))
35static int g_loc_Y;
36static int g_max_loc_X;
37static int g_max_loc_Y;
38 35
39static int dispDeviceRowBytes; 36static int g_loc_X __force_data;
40static int dispDeviceDepth; 37static int g_loc_Y __force_data;
41static int dispDeviceRect[4]; 38static int g_max_loc_X __force_data;
42static unsigned char *dispDeviceBase, *logicalDisplayBase; 39static int g_max_loc_Y __force_data;
40
41static int dispDeviceRowBytes __force_data;
42static int dispDeviceDepth __force_data;
43static int dispDeviceRect[4] __force_data;
44static unsigned char *dispDeviceBase __force_data;
45static unsigned char *logicalDisplayBase __force_data;
43 46
44unsigned long disp_BAT[2] __initdata = {0, 0}; 47unsigned long disp_BAT[2] __initdata = {0, 0};
45 48
@@ -47,7 +50,7 @@ unsigned long disp_BAT[2] __initdata = {0, 0};
47 50
48static unsigned char vga_font[cmapsz]; 51static unsigned char vga_font[cmapsz];
49 52
50int boot_text_mapped; 53int boot_text_mapped __force_data = 0;
51int force_printk_to_btext = 0; 54int force_printk_to_btext = 0;
52 55
53#ifdef CONFIG_PPC32 56#ifdef CONFIG_PPC32
@@ -66,8 +69,7 @@ int force_printk_to_btext = 0;
66 * is really badly aligned, but I didn't encounter this case 69 * is really badly aligned, but I didn't encounter this case
67 * yet. 70 * yet.
68 */ 71 */
69void __init 72void __init btext_prepare_BAT(void)
70btext_prepare_BAT(void)
71{ 73{
72 unsigned long vaddr = KERNELBASE + 0x10000000; 74 unsigned long vaddr = KERNELBASE + 0x10000000;
73 unsigned long addr; 75 unsigned long addr;
@@ -95,12 +97,13 @@ btext_prepare_BAT(void)
95} 97}
96#endif 98#endif
97 99
98/* This function will enable the early boot text when doing OF booting. This 100
99 * way, xmon output should work too 101/* This function can be used to enable the early boot text when doing
102 * OF booting or within bootx init. It must be followed by a btext_unmap()
103 * call before the logical address becomes unuseable
100 */ 104 */
101void __init 105void __init btext_setup_display(int width, int height, int depth, int pitch,
102btext_setup_display(int width, int height, int depth, int pitch, 106 unsigned long address)
103 unsigned long address)
104{ 107{
105 g_loc_X = 0; 108 g_loc_X = 0;
106 g_loc_Y = 0; 109 g_loc_Y = 0;
@@ -116,6 +119,11 @@ btext_setup_display(int width, int height, int depth, int pitch,
116 boot_text_mapped = 1; 119 boot_text_mapped = 1;
117} 120}
118 121
122void __init btext_unmap(void)
123{
124 boot_text_mapped = 0;
125}
126
119/* Here's a small text engine to use during early boot 127/* Here's a small text engine to use during early boot
120 * or for debugging purposes 128 * or for debugging purposes
121 * 129 *
@@ -127,7 +135,7 @@ btext_setup_display(int width, int height, int depth, int pitch,
127 * changes. 135 * changes.
128 */ 136 */
129 137
130void map_boot_text(void) 138static void map_boot_text(void)
131{ 139{
132 unsigned long base, offset, size; 140 unsigned long base, offset, size;
133 unsigned char *vbase; 141 unsigned char *vbase;
@@ -175,8 +183,9 @@ int btext_initialize(struct device_node *np)
175 if (prop) 183 if (prop)
176 address = *prop; 184 address = *prop;
177 185
178 /* FIXME: Add support for PCI reg properties */ 186 /* FIXME: Add support for PCI reg properties. Right now, only
179 187 * reliable on macs
188 */
180 if (address == 0) 189 if (address == 0)
181 return -EINVAL; 190 return -EINVAL;
182 191
@@ -184,7 +193,6 @@ int btext_initialize(struct device_node *np)
184 g_loc_Y = 0; 193 g_loc_Y = 0;
185 g_max_loc_X = width / 8; 194 g_max_loc_X = width / 8;
186 g_max_loc_Y = height / 16; 195 g_max_loc_Y = height / 16;
187 logicalDisplayBase = (unsigned char *)address;
188 dispDeviceBase = (unsigned char *)address; 196 dispDeviceBase = (unsigned char *)address;
189 dispDeviceRowBytes = pitch; 197 dispDeviceRowBytes = pitch;
190 dispDeviceDepth = depth; 198 dispDeviceDepth = depth;
@@ -197,7 +205,7 @@ int btext_initialize(struct device_node *np)
197 return 0; 205 return 0;
198} 206}
199 207
200void __init init_boot_display(void) 208int __init btext_find_display(int allow_nonstdout)
201{ 209{
202 char *name; 210 char *name;
203 struct device_node *np = NULL; 211 struct device_node *np = NULL;
@@ -218,8 +226,8 @@ void __init init_boot_display(void)
218 } 226 }
219 if (np) 227 if (np)
220 rc = btext_initialize(np); 228 rc = btext_initialize(np);
221 if (rc == 0) 229 if (rc == 0 || !allow_nonstdout)
222 return; 230 return rc;
223 231
224 for (np = NULL; (np = of_find_node_by_type(np, "display"));) { 232 for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
225 if (get_property(np, "linux,opened", NULL)) { 233 if (get_property(np, "linux,opened", NULL)) {
@@ -228,8 +236,9 @@ void __init init_boot_display(void)
228 printk("result: %d\n", rc); 236 printk("result: %d\n", rc);
229 } 237 }
230 if (rc == 0) 238 if (rc == 0)
231 return; 239 break;
232 } 240 }
241 return rc;
233} 242}
234 243
235/* Calc the base address of a given point (x,y) */ 244/* Calc the base address of a given point (x,y) */
@@ -277,44 +286,83 @@ EXPORT_SYMBOL(btext_update_display);
277 286
278void btext_clearscreen(void) 287void btext_clearscreen(void)
279{ 288{
280 unsigned long *base = (unsigned long *)calc_base(0, 0); 289 unsigned int *base = (unsigned int *)calc_base(0, 0);
281 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) * 290 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
282 (dispDeviceDepth >> 3)) >> 3; 291 (dispDeviceDepth >> 3)) >> 2;
283 int i,j; 292 int i,j;
284 293
285 for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++) 294 for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
286 { 295 {
287 unsigned long *ptr = base; 296 unsigned int *ptr = base;
288 for(j=width; j; --j) 297 for(j=width; j; --j)
289 *(ptr++) = 0; 298 *(ptr++) = 0;
290 base += (dispDeviceRowBytes >> 3); 299 base += (dispDeviceRowBytes >> 2);
300 }
301}
302
303void btext_flushscreen(void)
304{
305 unsigned int *base = (unsigned int *)calc_base(0, 0);
306 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
307 (dispDeviceDepth >> 3)) >> 2;
308 int i,j;
309
310 for (i=0; i < (dispDeviceRect[3] - dispDeviceRect[1]); i++)
311 {
312 unsigned int *ptr = base;
313 for(j = width; j > 0; j -= 8) {
314 __asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
315 ptr += 8;
316 }
317 base += (dispDeviceRowBytes >> 2);
291 } 318 }
319 __asm__ __volatile__ ("sync" ::: "memory");
292} 320}
293 321
322void btext_flushline(void)
323{
324 unsigned int *base = (unsigned int *)calc_base(0, g_loc_Y << 4);
325 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
326 (dispDeviceDepth >> 3)) >> 2;
327 int i,j;
328
329 for (i=0; i < 16; i++)
330 {
331 unsigned int *ptr = base;
332 for(j = width; j > 0; j -= 8) {
333 __asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
334 ptr += 8;
335 }
336 base += (dispDeviceRowBytes >> 2);
337 }
338 __asm__ __volatile__ ("sync" ::: "memory");
339}
340
341
294#ifndef NO_SCROLL 342#ifndef NO_SCROLL
295static void scrollscreen(void) 343static void scrollscreen(void)
296{ 344{
297 unsigned long *src = (unsigned long *)calc_base(0,16); 345 unsigned int *src = (unsigned int *)calc_base(0,16);
298 unsigned long *dst = (unsigned long *)calc_base(0,0); 346 unsigned int *dst = (unsigned int *)calc_base(0,0);
299 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) * 347 unsigned long width = ((dispDeviceRect[2] - dispDeviceRect[0]) *
300 (dispDeviceDepth >> 3)) >> 3; 348 (dispDeviceDepth >> 3)) >> 2;
301 int i,j; 349 int i,j;
302 350
303 for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++) 351 for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
304 { 352 {
305 unsigned long *src_ptr = src; 353 unsigned int *src_ptr = src;
306 unsigned long *dst_ptr = dst; 354 unsigned int *dst_ptr = dst;
307 for(j=width; j; --j) 355 for(j=width; j; --j)
308 *(dst_ptr++) = *(src_ptr++); 356 *(dst_ptr++) = *(src_ptr++);
309 src += (dispDeviceRowBytes >> 3); 357 src += (dispDeviceRowBytes >> 2);
310 dst += (dispDeviceRowBytes >> 3); 358 dst += (dispDeviceRowBytes >> 2);
311 } 359 }
312 for (i=0; i<16; i++) 360 for (i=0; i<16; i++)
313 { 361 {
314 unsigned long *dst_ptr = dst; 362 unsigned int *dst_ptr = dst;
315 for(j=width; j; --j) 363 for(j=width; j; --j)
316 *(dst_ptr++) = 0; 364 *(dst_ptr++) = 0;
317 dst += (dispDeviceRowBytes >> 3); 365 dst += (dispDeviceRowBytes >> 2);
318 } 366 }
319} 367}
320#endif /* ndef NO_SCROLL */ 368#endif /* ndef NO_SCROLL */
@@ -377,6 +425,14 @@ void btext_drawstring(const char *c)
377 btext_drawchar(*c++); 425 btext_drawchar(*c++);
378} 426}
379 427
428void btext_drawtext(const char *c, unsigned int len)
429{
430 if (!boot_text_mapped)
431 return;
432 while (len--)
433 btext_drawchar(*c++);
434}
435
380void btext_drawhex(unsigned long v) 436void btext_drawhex(unsigned long v)
381{ 437{
382 char *hex_table = "0123456789abcdef"; 438 char *hex_table = "0123456789abcdef";
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index ccdf94731e30..fdd34dbd8797 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -153,6 +153,9 @@ __after_mmu_off:
153 bl flush_tlbs 153 bl flush_tlbs
154 154
155 bl initial_bats 155 bl initial_bats
156#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
157 bl setup_disp_bat
158#endif
156 159
157/* 160/*
158 * Call setup_cpu for CPU 0 and initialize 6xx Idle 161 * Call setup_cpu for CPU 0 and initialize 6xx Idle
@@ -1306,6 +1309,32 @@ initial_bats:
1306 blr 1309 blr
1307 1310
1308 1311
1312#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
1313setup_disp_bat:
1314 /*
1315 * setup the display bat prepared for us in prom.c
1316 */
1317 mflr r8
1318 bl reloc_offset
1319 mtlr r8
1320 addis r8,r3,disp_BAT@ha
1321 addi r8,r8,disp_BAT@l
1322 cmpwi cr0,r8,0
1323 beqlr
1324 lwz r11,0(r8)
1325 lwz r8,4(r8)
1326 mfspr r9,SPRN_PVR
1327 rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
1328 cmpwi 0,r9,1
1329 beq 1f
1330 mtspr SPRN_DBAT3L,r8
1331 mtspr SPRN_DBAT3U,r11
1332 blr
13331: mtspr SPRN_IBAT3L,r8
1334 mtspr SPRN_IBAT3U,r11
1335 blr
1336#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */
1337
1309#ifdef CONFIG_8260 1338#ifdef CONFIG_8260
1310/* Jump into the system reset for the rom. 1339/* Jump into the system reset for the rom.
1311 * We first disable the MMU, and then jump to the ROM reset address. 1340 * We first disable the MMU, and then jump to the ROM reset address.
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 02baacf04366..79d434fc14d2 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -40,6 +40,7 @@
40#include <asm/xmon.h> 40#include <asm/xmon.h>
41#include <asm/time.h> 41#include <asm/time.h>
42#include <asm/serial.h> 42#include <asm/serial.h>
43#include <asm/udbg.h>
43 44
44#include "setup.h" 45#include "setup.h"
45 46
@@ -173,12 +174,23 @@ void __init platform_init(void)
173 */ 174 */
174void __init machine_init(unsigned long dt_ptr, unsigned long phys) 175void __init machine_init(unsigned long dt_ptr, unsigned long phys)
175{ 176{
177 /* If btext is enabled, we might have a BAT setup for early display,
178 * thus we do enable some very basic udbg output
179 */
180#ifdef CONFIG_BOOTX_TEXT
181 udbg_putc = btext_drawchar;
182#endif
183
184 /* Do some early initialization based on the flat device tree */
176 early_init_devtree(__va(dt_ptr)); 185 early_init_devtree(__va(dt_ptr));
177 186
187 /* Check default command line */
178#ifdef CONFIG_CMDLINE 188#ifdef CONFIG_CMDLINE
179 strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); 189 if (cmd_line[0] == 0)
190 strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
180#endif /* CONFIG_CMDLINE */ 191#endif /* CONFIG_CMDLINE */
181 192
193 /* Base init based on machine type */
182 platform_init(); 194 platform_init();
183 195
184#ifdef CONFIG_6xx 196#ifdef CONFIG_6xx
@@ -294,21 +306,11 @@ void __init setup_arch(char **cmdline_p)
294 306
295 smp_setup_cpu_maps(); 307 smp_setup_cpu_maps();
296 308
297#ifdef CONFIG_BOOTX_TEXT
298 init_boot_display();
299#endif
300
301#ifdef CONFIG_PPC_PMAC
302 /* This could be called "early setup arch", it must be done
303 * now because xmon need it
304 */
305 if (_machine == _MACH_Pmac)
306 pmac_feature_init(); /* New cool way */
307#endif
308
309#ifdef CONFIG_XMON_DEFAULT 309#ifdef CONFIG_XMON_DEFAULT
310 xmon_init(1); 310 xmon_init(1);
311#endif 311#endif
312 /* Register early console */
313 register_early_udbg_console();
312 314
313#if defined(CONFIG_KGDB) 315#if defined(CONFIG_KGDB)
314 if (ppc_md.kgdb_map_scc) 316 if (ppc_md.kgdb_map_scc)
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 0fc442ad1d26..65603e9af984 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -474,10 +474,6 @@ void __init setup_system(void)
474 */ 474 */
475 finish_device_tree(); 475 finish_device_tree();
476 476
477#ifdef CONFIG_BOOTX_TEXT
478 init_boot_display();
479#endif
480
481 /* 477 /*
482 * Initialize xmon 478 * Initialize xmon
483 */ 479 */
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 2e372477d22a..cc2df5e61bb0 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -16,8 +16,8 @@
16#include <linux/console.h> 16#include <linux/console.h>
17#include <asm/processor.h> 17#include <asm/processor.h>
18 18
19void (*udbg_putc)(unsigned char c); 19void (*udbg_putc)(char c);
20unsigned char (*udbg_getc)(void); 20char (*udbg_getc)(void);
21int (*udbg_getc_poll)(void); 21int (*udbg_getc_poll)(void);
22 22
23/* udbg library, used by xmon et al */ 23/* udbg library, used by xmon et al */
@@ -78,7 +78,7 @@ int udbg_read(char *buf, int buflen)
78#define UDBG_BUFSIZE 256 78#define UDBG_BUFSIZE 256
79void udbg_printf(const char *fmt, ...) 79void udbg_printf(const char *fmt, ...)
80{ 80{
81 unsigned char buf[UDBG_BUFSIZE]; 81 char buf[UDBG_BUFSIZE];
82 va_list args; 82 va_list args;
83 83
84 va_start(args, fmt); 84 va_start(args, fmt);
@@ -116,6 +116,8 @@ void __init disable_early_printk(void)
116/* called by setup_system */ 116/* called by setup_system */
117void register_early_udbg_console(void) 117void register_early_udbg_console(void)
118{ 118{
119 if (early_console_initialized)
120 return;
119 early_console_initialized = 1; 121 early_console_initialized = 1;
120 register_console(&udbg_console); 122 register_console(&udbg_console);
121} 123}
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c
index 50fd376446c9..28a58da5592c 100644
--- a/arch/powerpc/kernel/udbg_16550.c
+++ b/arch/powerpc/kernel/udbg_16550.c
@@ -47,7 +47,7 @@ struct NS16550 {
47 47
48static volatile struct NS16550 __iomem *udbg_comport; 48static volatile struct NS16550 __iomem *udbg_comport;
49 49
50static void udbg_550_putc(unsigned char c) 50static void udbg_550_putc(char c)
51{ 51{
52 if (udbg_comport) { 52 if (udbg_comport) {
53 while ((in_8(&udbg_comport->lsr) & LSR_THRE) == 0) 53 while ((in_8(&udbg_comport->lsr) & LSR_THRE) == 0)
@@ -69,7 +69,7 @@ static int udbg_550_getc_poll(void)
69 return -1; 69 return -1;
70} 70}
71 71
72static unsigned char udbg_550_getc(void) 72static char udbg_550_getc(void)
73{ 73{
74 if (udbg_comport) { 74 if (udbg_comport) {
75 while ((in_8(&udbg_comport->lsr) & LSR_DR) == 0) 75 while ((in_8(&udbg_comport->lsr) & LSR_DR) == 0)
diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c
index 7d4b8b5f0606..7d0d75c11848 100644
--- a/arch/powerpc/mm/init_32.c
+++ b/arch/powerpc/mm/init_32.c
@@ -188,6 +188,11 @@ void __init MMU_init(void)
188 188
189 if (ppc_md.progress) 189 if (ppc_md.progress)
190 ppc_md.progress("MMU:exit", 0x211); 190 ppc_md.progress("MMU:exit", 0x211);
191
192 /* From now on, btext is no longer BAT mapped if it was at all */
193#ifdef CONFIG_BOOTX_TEXT
194 btext_unmap();
195#endif
191} 196}
192 197
193/* This is only called until mem_init is done. */ 198/* This is only called until mem_init is done. */
diff --git a/arch/powerpc/platforms/powermac/Makefile b/arch/powerpc/platforms/powermac/Makefile
index c9df44fcf571..3e5370eeb1b7 100644
--- a/arch/powerpc/platforms/powermac/Makefile
+++ b/arch/powerpc/platforms/powermac/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_NVRAM) += nvram.o
7# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff 7# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff
8obj-$(CONFIG_PPC64) += nvram.o 8obj-$(CONFIG_PPC64) += nvram.o
9obj-$(CONFIG_SMP) += smp.o 9obj-$(CONFIG_SMP) += smp.o
10obj-$(CONFIG_PPC_MERGE) += udbg_scc.o udbg_adb.o
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index f6e22da2a5da..52a9d0c1b8b8 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -2607,6 +2607,8 @@ found:
2607 */ 2607 */
2608static void __init probe_uninorth(void) 2608static void __init probe_uninorth(void)
2609{ 2609{
2610 u32 *addrp;
2611 phys_addr_t address;
2610 unsigned long actrl; 2612 unsigned long actrl;
2611 2613
2612 /* Locate core99 Uni-N */ 2614 /* Locate core99 Uni-N */
@@ -2616,20 +2618,23 @@ static void __init probe_uninorth(void)
2616 uninorth_node = of_find_node_by_name(NULL, "u3"); 2618 uninorth_node = of_find_node_by_name(NULL, "u3");
2617 uninorth_u3 = 1; 2619 uninorth_u3 = 1;
2618 } 2620 }
2619 if (uninorth_node && uninorth_node->n_addrs > 0) { 2621 if (uninorth_node == NULL)
2620 unsigned long address = uninorth_node->addrs[0].address;
2621 uninorth_base = ioremap(address, 0x40000);
2622 uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
2623 if (uninorth_u3)
2624 u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
2625 } else
2626 uninorth_node = NULL;
2627
2628 if (!uninorth_node)
2629 return; 2622 return;
2630 2623
2631 printk(KERN_INFO "Found %s memory controller & host bridge, revision: %d\n", 2624 addrp = (u32 *)get_property(uninorth_node, "reg", NULL);
2632 uninorth_u3 ? "U3" : "UniNorth", uninorth_rev); 2625 if (addrp == NULL)
2626 return;
2627 address = of_translate_address(uninorth_node, addrp);
2628 if (address == 0)
2629 return;
2630 uninorth_base = ioremap(address, 0x40000);
2631 uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
2632 if (uninorth_u3)
2633 u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
2634
2635 printk(KERN_INFO "Found %s memory controller & host bridge,"
2636 " revision: %d\n", uninorth_u3 ? "U3" : "UniNorth",
2637 uninorth_rev);
2633 printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base); 2638 printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base);
2634 2639
2635 /* Set the arbitrer QAck delay according to what Apple does 2640 /* Set the arbitrer QAck delay according to what Apple does
@@ -2653,18 +2658,17 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ
2653{ 2658{
2654 struct device_node* node; 2659 struct device_node* node;
2655 int i; 2660 int i;
2656 volatile u32 __iomem * base; 2661 volatile u32 __iomem *base;
2657 u32* revp; 2662 u32 *addrp, *revp;
2663 phys_addr_t addr;
2664 u64 size;
2658 2665
2659 node = find_devices(name); 2666 for (node = NULL; (node = of_find_node_by_name(node, name)) != NULL;) {
2660 if (!node || !node->n_addrs) 2667 if (!compat)
2661 return; 2668 break;
2662 if (compat) 2669 if (device_is_compatible(node, compat))
2663 do { 2670 break;
2664 if (device_is_compatible(node, compat)) 2671 }
2665 break;
2666 node = node->next;
2667 } while (node);
2668 if (!node) 2672 if (!node)
2669 return; 2673 return;
2670 for(i=0; i<MAX_MACIO_CHIPS; i++) { 2674 for(i=0; i<MAX_MACIO_CHIPS; i++) {
@@ -2673,14 +2677,28 @@ static void __init probe_one_macio(const char *name, const char *compat, int typ
2673 if (macio_chips[i].of_node == node) 2677 if (macio_chips[i].of_node == node)
2674 return; 2678 return;
2675 } 2679 }
2680
2676 if (i >= MAX_MACIO_CHIPS) { 2681 if (i >= MAX_MACIO_CHIPS) {
2677 printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n"); 2682 printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n");
2678 printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name); 2683 printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);
2679 return; 2684 return;
2680 } 2685 }
2681 base = ioremap(node->addrs[0].address, node->addrs[0].size); 2686 addrp = of_get_pci_address(node, 0, &size);
2687 if (addrp == NULL) {
2688 printk(KERN_ERR "pmac_feature: %s: can't find base !\n",
2689 node->full_name);
2690 return;
2691 }
2692 addr = of_translate_address(node, addrp);
2693 if (addr == 0) {
2694 printk(KERN_ERR "pmac_feature: %s, can't translate base !\n",
2695 node->full_name);
2696 return;
2697 }
2698 base = ioremap(addr, (unsigned long)size);
2682 if (!base) { 2699 if (!base) {
2683 printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n"); 2700 printk(KERN_ERR "pmac_feature: %s, can't map mac-io chip !\n",
2701 node->full_name);
2684 return; 2702 return;
2685 } 2703 }
2686 if (type == macio_keylargo) { 2704 if (type == macio_keylargo) {
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
index f3f39e8e337a..606e0ed13731 100644
--- a/arch/powerpc/platforms/powermac/low_i2c.c
+++ b/arch/powerpc/platforms/powermac/low_i2c.c
@@ -36,7 +36,7 @@
36 36
37#ifdef DEBUG 37#ifdef DEBUG
38#define DBG(x...) do {\ 38#define DBG(x...) do {\
39 printk(KERN_DEBUG "KW:" x); \ 39 printk(KERN_DEBUG "low_i2c:" x); \
40 } while(0) 40 } while(0)
41#else 41#else
42#define DBG(x...) 42#define DBG(x...)
@@ -342,7 +342,7 @@ static int keywest_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 subaddr,
342static void keywest_low_i2c_add(struct device_node *np) 342static void keywest_low_i2c_add(struct device_node *np)
343{ 343{
344 struct low_i2c_host *host = find_low_i2c_host(NULL); 344 struct low_i2c_host *host = find_low_i2c_host(NULL);
345 u32 *psteps, *prate, steps, aoffset = 0; 345 u32 *psteps, *prate, *addrp, steps;
346 struct device_node *parent; 346 struct device_node *parent;
347 347
348 if (host == NULL) { 348 if (host == NULL) {
@@ -352,6 +352,16 @@ static void keywest_low_i2c_add(struct device_node *np)
352 } 352 }
353 memset(host, 0, sizeof(*host)); 353 memset(host, 0, sizeof(*host));
354 354
355 /* Apple is kind enough to provide a valid AAPL,address property
356 * on all i2c keywest nodes so far ... we would have to fallback
357 * to macio parsing if that wasn't the case
358 */
359 addrp = (u32 *)get_property(np, "AAPL,address", NULL);
360 if (addrp == NULL) {
361 printk(KERN_ERR "low_i2c: Can't find address for %s\n",
362 np->full_name);
363 return;
364 }
355 init_MUTEX(&host->mutex); 365 init_MUTEX(&host->mutex);
356 host->np = of_node_get(np); 366 host->np = of_node_get(np);
357 psteps = (u32 *)get_property(np, "AAPL,address-step", NULL); 367 psteps = (u32 *)get_property(np, "AAPL,address-step", NULL);
@@ -360,12 +370,10 @@ static void keywest_low_i2c_add(struct device_node *np)
360 steps >>= 1; 370 steps >>= 1;
361 parent = of_get_parent(np); 371 parent = of_get_parent(np);
362 host->num_channels = 1; 372 host->num_channels = 1;
363 if (parent && parent->name[0] == 'u') { 373 if (parent && parent->name[0] == 'u')
364 host->num_channels = 2; 374 host->num_channels = 2;
365 aoffset = 3;
366 }
367 /* Select interface rate */ 375 /* Select interface rate */
368 host->speed = KW_I2C_MODE_100KHZ; 376 host->speed = KW_I2C_MODE_25KHZ;
369 prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL); 377 prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL);
370 if (prate) switch(*prate) { 378 if (prate) switch(*prate) {
371 case 100: 379 case 100:
@@ -379,9 +387,12 @@ static void keywest_low_i2c_add(struct device_node *np)
379 break; 387 break;
380 } 388 }
381 389
390 printk(KERN_INFO "low_i2c: Bus %s found at 0x%08x, %d channels,"
391 " speed = %d KHz\n",
392 np->full_name, *addrp, host->num_channels, prate ? *prate : 25);
393
382 host->mode = pmac_low_i2c_mode_std; 394 host->mode = pmac_low_i2c_mode_std;
383 host->base = ioremap(np->addrs[0].address + aoffset, 395 host->base = ioremap((*addrp), 0x1000);
384 np->addrs[0].size);
385 host->func = keywest_low_i2c_func; 396 host->func = keywest_low_i2c_func;
386} 397}
387 398
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 90040c49494d..ff78eeac10f2 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -459,7 +459,7 @@ void __init pmac_pic_init(void)
459 mpic_setup_cascade(irqctrler2->intrs[0].line, 459 mpic_setup_cascade(irqctrler2->intrs[0].line,
460 pmac_u3_cascade, mpic2); 460 pmac_u3_cascade, mpic2);
461 } 461 }
462#if defined(CONFIG_XMON) && defined(CONFIG_PPC32) 462#ifdef CONFIG_XMON
463 { 463 {
464 struct device_node* pswitch; 464 struct device_node* pswitch;
465 int nmi_irq; 465 int nmi_irq;
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 3b7a492d9b68..6ee620fe5195 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -77,6 +77,7 @@
77#include <asm/pmc.h> 77#include <asm/pmc.h>
78#include <asm/mpic.h> 78#include <asm/mpic.h>
79#include <asm/lmb.h> 79#include <asm/lmb.h>
80#include <asm/udbg.h>
80 81
81#include "pmac.h" 82#include "pmac.h"
82 83
@@ -322,16 +323,6 @@ void __init pmac_setup_arch(void)
322 l2cr_init(); 323 l2cr_init();
323#endif /* CONFIG_PPC32 */ 324#endif /* CONFIG_PPC32 */
324 325
325#ifdef CONFIG_PPC64
326 /* Probe motherboard chipset */
327 /* this is done earlier in setup_arch for 32-bit */
328 pmac_feature_init();
329
330 /* We can NAP */
331 powersave_nap = 1;
332 printk(KERN_INFO "Using native/NAP idle loop\n");
333#endif
334
335#ifdef CONFIG_KGDB 326#ifdef CONFIG_KGDB
336 zs_kgdb_hook(0); 327 zs_kgdb_hook(0);
337#endif 328#endif
@@ -622,13 +613,26 @@ static void __init pmac_init_early(void)
622 * and call ioremap 613 * and call ioremap
623 */ 614 */
624 hpte_init_native(); 615 hpte_init_native();
616#endif
625 617
626 /* Init SCC */ 618 /* Enable early btext debug if requested */
627 if (strstr(cmd_line, "sccdbg")) { 619 if (strstr(cmd_line, "btextdbg")) {
628 sccdbg = 1; 620 udbg_adb_init_early();
629 udbg_init_scc(NULL); 621 register_early_udbg_console();
630 } 622 }
631 623
624 /* Probe motherboard chipset */
625 pmac_feature_init();
626
627 /* We can NAP */
628 powersave_nap = 1;
629 printk(KERN_INFO "Using native/NAP idle loop\n");
630
631 /* Initialize debug stuff */
632 udbg_scc_init(!!strstr(cmd_line, "sccdbg"));
633 udbg_adb_init(!!strstr(cmd_line, "btextdbg"));
634
635#ifdef CONFIG_PPC64
632 /* Setup interrupt mapping options */ 636 /* Setup interrupt mapping options */
633 ppc64_interrupt_controller = IC_OPEN_PIC; 637 ppc64_interrupt_controller = IC_OPEN_PIC;
634 638
@@ -638,19 +642,8 @@ static void __init pmac_init_early(void)
638 642
639static void __init pmac_progress(char *s, unsigned short hex) 643static void __init pmac_progress(char *s, unsigned short hex)
640{ 644{
641#ifdef CONFIG_PPC64 645 udbg_puts(s);
642 if (sccdbg) { 646 udbg_puts("\n");
643 udbg_puts(s);
644 udbg_puts("\n");
645 return;
646 }
647#endif
648#ifdef CONFIG_BOOTX_TEXT
649 if (boot_text_mapped) {
650 btext_drawstring(s);
651 btext_drawchar('\n');
652 }
653#endif /* CONFIG_BOOTX_TEXT */
654} 647}
655 648
656/* 649/*
@@ -735,7 +728,8 @@ static int __init pmac_probe(int platform)
735} 728}
736 729
737#ifdef CONFIG_PPC64 730#ifdef CONFIG_PPC64
738static int pmac_probe_mode(struct pci_bus *bus) 731/* Move that to pci.c */
732static int pmac_pci_probe_mode(struct pci_bus *bus)
739{ 733{
740 struct device_node *node = bus->sysdata; 734 struct device_node *node = bus->sysdata;
741 735
@@ -771,7 +765,7 @@ struct machdep_calls __initdata pmac_md = {
771 .check_legacy_ioport = pmac_check_legacy_ioport, 765 .check_legacy_ioport = pmac_check_legacy_ioport,
772 .progress = pmac_progress, 766 .progress = pmac_progress,
773#ifdef CONFIG_PPC64 767#ifdef CONFIG_PPC64
774 .pci_probe_mode = pmac_probe_mode, 768 .pci_probe_mode = pmac_pci_probe_mode,
775 .idle_loop = native_idle, 769 .idle_loop = native_idle,
776 .enable_pmcs = power4_enable_pmcs, 770 .enable_pmcs = power4_enable_pmcs,
777#ifdef CONFIG_KEXEC 771#ifdef CONFIG_KEXEC
diff --git a/arch/powerpc/platforms/powermac/udbg_adb.c b/arch/powerpc/platforms/powermac/udbg_adb.c
new file mode 100644
index 000000000000..e51de55b2d6e
--- /dev/null
+++ b/arch/powerpc/platforms/powermac/udbg_adb.c
@@ -0,0 +1,218 @@
1#include <linux/config.h>
2#include <linux/string.h>
3#include <linux/kernel.h>
4#include <linux/errno.h>
5#include <linux/bitops.h>
6#include <linux/ptrace.h>
7#include <linux/adb.h>
8#include <linux/pmu.h>
9#include <linux/cuda.h>
10#include <asm/machdep.h>
11#include <asm/io.h>
12#include <asm/page.h>
13#include <asm/xmon.h>
14#include <asm/prom.h>
15#include <asm/bootx.h>
16#include <asm/machdep.h>
17#include <asm/errno.h>
18#include <asm/pmac_feature.h>
19#include <asm/processor.h>
20#include <asm/delay.h>
21#include <asm/btext.h>
22#include <asm/time.h>
23#include <asm/udbg.h>
24
25/*
26 * This implementation is "special", it can "patch" the current
27 * udbg implementation and work on top of it. It must thus be
28 * initialized last
29 */
30
31static void (*udbg_adb_old_putc)(char c);
32static char (*udbg_adb_old_getc)(void);
33static int (*udbg_adb_old_getc_poll)(void);
34
35static enum {
36 input_adb_none,
37 input_adb_pmu,
38 input_adb_cuda,
39} input_type = input_adb_none;
40
41static int udbg_adb_use_btext;
42
43int xmon_wants_key, xmon_adb_keycode;
44
45static inline void udbg_adb_poll(void)
46{
47#ifdef CONFIG_ADB_PMU
48 if (input_type == input_adb_pmu)
49 pmu_poll_adb();
50#endif /* CONFIG_ADB_PMU */
51#ifdef CONFIG_ADB_CUDA
52 if (input_type == input_adb_cuda)
53 cuda_poll();
54#endif /* CONFIG_ADB_CUDA */
55}
56
57#ifdef CONFIG_BOOTX_TEXT
58static int xmon_adb_shiftstate;
59
60static unsigned char xmon_keytab[128] =
61 "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */
62 "yt123465=97-80]o" /* 0x10 - 0x1f */
63 "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */
64 "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
65 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
66 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
67
68static unsigned char xmon_shift_keytab[128] =
69 "ASDFHGZXCV\000BQWER" /* 0x00 - 0x0f */
70 "YT!@#$^%+(&_*)}O" /* 0x10 - 0x1f */
71 "U{IP\rLJ\"K:|<?NM>" /* 0x20 - 0x2f */
72 "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
73 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
74 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
75
76static char udbg_adb_local_getc(void)
77{
78 int k, t, on;
79
80 xmon_wants_key = 1;
81 for (;;) {
82 xmon_adb_keycode = -1;
83 t = 0;
84 on = 0;
85 k = -1;
86 do {
87 if (--t < 0) {
88 on = 1 - on;
89 btext_drawchar(on? 0xdb: 0x20);
90 btext_drawchar('\b');
91 t = 200000;
92 }
93 udbg_adb_poll();
94 if (udbg_adb_old_getc_poll)
95 k = udbg_adb_old_getc_poll();
96 } while (k == -1 && xmon_adb_keycode == -1);
97 if (on)
98 btext_drawstring(" \b");
99 if (k != -1)
100 return k;
101 k = xmon_adb_keycode;
102
103 /* test for shift keys */
104 if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
105 xmon_adb_shiftstate = (k & 0x80) == 0;
106 continue;
107 }
108 if (k >= 0x80)
109 continue; /* ignore up transitions */
110 k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
111 if (k != 0)
112 break;
113 }
114 xmon_wants_key = 0;
115 return k;
116}
117#endif /* CONFIG_BOOTX_TEXT */
118
119static char udbg_adb_getc(void)
120{
121#ifdef CONFIG_BOOTX_TEXT
122 if (udbg_adb_use_btext && input_type != input_adb_none)
123 return udbg_adb_local_getc();
124#endif
125 if (udbg_adb_old_getc)
126 return udbg_adb_old_getc();
127 return -1;
128}
129
130/* getc_poll() is not really used, unless you have the xmon-over modem
131 * hack that doesn't quite concern us here, thus we just poll the low level
132 * ADB driver to prevent it from timing out and call back the original poll
133 * routine.
134 */
135static int udbg_adb_getc_poll(void)
136{
137 udbg_adb_poll();
138
139 if (udbg_adb_old_getc_poll)
140 return udbg_adb_old_getc_poll();
141 return -1;
142}
143
144static void udbg_adb_putc(char c)
145{
146#ifdef CONFIG_BOOTX_TEXT
147 if (udbg_adb_use_btext)
148 btext_drawchar(c);
149#endif
150 if (udbg_adb_old_putc)
151 return udbg_adb_old_putc(c);
152}
153
154void udbg_adb_init_early(void)
155{
156#ifdef CONFIG_BOOTX_TEXT
157 if (btext_find_display(1) == 0) {
158 udbg_adb_use_btext = 1;
159 udbg_putc = udbg_adb_putc;
160 }
161#endif
162}
163
164int udbg_adb_init(int force_btext)
165{
166 struct device_node *np;
167
168 /* Capture existing callbacks */
169 udbg_adb_old_putc = udbg_putc;
170 udbg_adb_old_getc = udbg_getc;
171 udbg_adb_old_getc_poll = udbg_getc_poll;
172
173 /* Check if our early init was already called */
174 if (udbg_adb_old_putc == udbg_adb_putc ||
175 udbg_adb_old_putc == btext_drawchar)
176 udbg_adb_old_putc = NULL;
177
178 /* Set ours as output */
179 udbg_putc = udbg_adb_putc;
180 udbg_getc = udbg_adb_getc;
181 udbg_getc_poll = udbg_adb_getc_poll;
182
183#ifdef CONFIG_BOOTX_TEXT
184 /* Check if we should use btext output */
185 if (btext_find_display(force_btext) == 0)
186 udbg_adb_use_btext = 1;
187#endif
188
189 /* See if there is a keyboard in the device tree with a parent
190 * of type "adb". If not, we return a failure, but we keep the
191 * bext output set for now
192 */
193 for (np = NULL; (np = of_find_node_by_name(np, "keyboard")) != NULL;) {
194 struct device_node *parent = of_get_parent(np);
195 int found = (parent && !strcmp(parent->type, "adb") == 0);
196 of_node_put(parent);
197 if (found)
198 break;
199 }
200 if (np == NULL)
201 return -ENODEV;
202 of_node_put(np);
203
204#ifdef CONFIG_ADB_PMU
205 if (find_via_pmu())
206 input_type = input_adb_pmu;
207#endif
208#ifdef CONFIG_ADB_CUDA
209 if (find_via_cuda())
210 input_type = input_adb_cuda;
211#endif
212
213 /* Same as above: nothing found, keep btext set for output */
214 if (input_type == input_adb_none)
215 return -ENODEV;
216
217 return 0;
218}
diff --git a/arch/powerpc/kernel/udbg_scc.c b/arch/powerpc/platforms/powermac/udbg_scc.c
index 820c53551507..df6dec49c4c7 100644
--- a/arch/powerpc/kernel/udbg_scc.c
+++ b/arch/powerpc/platforms/powermac/udbg_scc.c
@@ -25,7 +25,7 @@ extern void real_writeb(u8 data, volatile u8 __iomem *addr);
25static volatile u8 __iomem *sccc; 25static volatile u8 __iomem *sccc;
26static volatile u8 __iomem *sccd; 26static volatile u8 __iomem *sccd;
27 27
28static void udbg_scc_putc(unsigned char c) 28static void udbg_scc_putc(char c)
29{ 29{
30 if (sccc) { 30 if (sccc) {
31 while ((in_8(sccc) & SCC_TXRDY) == 0) 31 while ((in_8(sccc) & SCC_TXRDY) == 0)
@@ -47,7 +47,7 @@ static int udbg_scc_getc_poll(void)
47 return -1; 47 return -1;
48} 48}
49 49
50static unsigned char udbg_scc_getc(void) 50static char udbg_scc_getc(void)
51{ 51{
52 if (sccc) { 52 if (sccc) {
53 while ((in_8(sccc) & SCC_RXRDY) == 0) 53 while ((in_8(sccc) & SCC_RXRDY) == 0)
@@ -67,38 +67,59 @@ static unsigned char scc_inittab[] = {
67 3, 0xc1, /* rx enable, 8 bits */ 67 3, 0xc1, /* rx enable, 8 bits */
68}; 68};
69 69
70void udbg_init_scc(struct device_node *np) 70void udbg_scc_init(int force_scc)
71{ 71{
72 u32 *reg; 72 u32 *reg;
73 unsigned long addr; 73 unsigned long addr;
74 struct device_node *stdout = NULL, *escc = NULL, *macio = NULL;
75 struct device_node *ch, *ch_def = NULL, *ch_a = NULL;
76 char *path;
74 int i, x; 77 int i, x;
75 78
76 if (np == NULL) 79 escc = of_find_node_by_name(NULL, "escc");
77 np = of_find_node_by_name(NULL, "escc"); 80 if (escc == NULL)
78 if (np == NULL || np->parent == NULL) 81 goto bail;
79 return; 82 macio = of_get_parent(escc);
83 if (macio == NULL)
84 goto bail;
85 path = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
86 if (path != NULL)
87 stdout = of_find_node_by_path(path);
88 for (ch = NULL; (ch = of_get_next_child(escc, ch)) != NULL;) {
89 if (ch == stdout)
90 ch_def = of_node_get(ch);
91 if (strcmp(ch->name, "ch-a") == 0)
92 ch_a = of_node_get(ch);
93 }
94 if (ch_def == NULL && !force_scc)
95 goto bail;
96
97 ch = ch_def ? ch_def : ch_a;
80 98
81 udbg_printf("found SCC...\n");
82 /* Get address within mac-io ASIC */ 99 /* Get address within mac-io ASIC */
83 reg = (u32 *)get_property(np, "reg", NULL); 100 reg = (u32 *)get_property(escc, "reg", NULL);
84 if (reg == NULL) 101 if (reg == NULL)
85 return; 102 goto bail;
86 addr = reg[0]; 103 addr = reg[0];
87 udbg_printf("local addr: %lx\n", addr); 104
88 /* Get address of mac-io PCI itself */ 105 /* Get address of mac-io PCI itself */
89 reg = (u32 *)get_property(np->parent, "assigned-addresses", NULL); 106 reg = (u32 *)get_property(macio, "assigned-addresses", NULL);
90 if (reg == NULL) 107 if (reg == NULL)
91 return; 108 goto bail;
92 addr += reg[2]; 109 addr += reg[2];
93 udbg_printf("final addr: %lx\n", addr); 110
111 /* Lock the serial port */
112 pmac_call_feature(PMAC_FTR_SCC_ENABLE, ch,
113 PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
114
94 115
95 /* Setup for 57600 8N1 */ 116 /* Setup for 57600 8N1 */
96 addr += 0x20; 117 if (ch == ch_a)
118 addr += 0x20;
97 sccc = (volatile u8 * __iomem) ioremap(addr & PAGE_MASK, PAGE_SIZE) ; 119 sccc = (volatile u8 * __iomem) ioremap(addr & PAGE_MASK, PAGE_SIZE) ;
98 sccc += addr & ~PAGE_MASK; 120 sccc += addr & ~PAGE_MASK;
99 sccd = sccc + 0x10; 121 sccd = sccc + 0x10;
100 122
101 udbg_printf("ioremap result sccc: %p\n", sccc);
102 mb(); 123 mb();
103 124
104 for (i = 20000; i != 0; --i) 125 for (i = 20000; i != 0; --i)
@@ -113,9 +134,17 @@ void udbg_init_scc(struct device_node *np)
113 udbg_getc_poll = udbg_scc_getc_poll; 134 udbg_getc_poll = udbg_scc_getc_poll;
114 135
115 udbg_puts("Hello World !\n"); 136 udbg_puts("Hello World !\n");
137
138 bail:
139 of_node_put(macio);
140 of_node_put(escc);
141 of_node_put(stdout);
142 of_node_put(ch_def);
143 of_node_put(ch_a);
116} 144}
117 145
118static void udbg_real_scc_putc(unsigned char c) 146#ifdef CONFIG_PPC64
147static void udbg_real_scc_putc(char c)
119{ 148{
120 while ((real_readb(sccc) & SCC_TXRDY) == 0) 149 while ((real_readb(sccc) & SCC_TXRDY) == 0)
121 ; 150 ;
@@ -133,3 +162,4 @@ void udbg_init_pmac_realmode(void)
133 udbg_getc = NULL; 162 udbg_getc = NULL;
134 udbg_getc_poll = NULL; 163 udbg_getc_poll = NULL;
135} 164}
165#endif /* CONFIG_PPC64 */
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index cc0939d4cad1..615ffb961059 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -61,7 +61,7 @@ extern void pSeries_find_serial_port(void);
61int vtermno; /* virtual terminal# for udbg */ 61int vtermno; /* virtual terminal# for udbg */
62 62
63#define __ALIGNED__ __attribute__((__aligned__(sizeof(long)))) 63#define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))
64static void udbg_hvsi_putc(unsigned char c) 64static void udbg_hvsi_putc(char c)
65{ 65{
66 /* packet's seqno isn't used anyways */ 66 /* packet's seqno isn't used anyways */
67 uint8_t packet[] __ALIGNED__ = { 0xff, 5, 0, 0, c }; 67 uint8_t packet[] __ALIGNED__ = { 0xff, 5, 0, 0, c };
@@ -112,7 +112,7 @@ static int udbg_hvsi_getc_poll(void)
112 return ch; 112 return ch;
113} 113}
114 114
115static unsigned char udbg_hvsi_getc(void) 115static char udbg_hvsi_getc(void)
116{ 116{
117 int ch; 117 int ch;
118 for (;;) { 118 for (;;) {
@@ -128,7 +128,7 @@ static unsigned char udbg_hvsi_getc(void)
128 } 128 }
129} 129}
130 130
131static void udbg_putcLP(unsigned char c) 131static void udbg_putcLP(char c)
132{ 132{
133 char buf[16]; 133 char buf[16];
134 unsigned long rc; 134 unsigned long rc;
@@ -173,7 +173,7 @@ static int udbg_getc_pollLP(void)
173 return ch; 173 return ch;
174} 174}
175 175
176static unsigned char udbg_getcLP(void) 176static char udbg_getcLP(void)
177{ 177{
178 int ch; 178 int ch;
179 for (;;) { 179 for (;;) {
diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
index b20312e5ed27..109d874ecfbe 100644
--- a/arch/powerpc/xmon/Makefile
+++ b/arch/powerpc/xmon/Makefile
@@ -3,9 +3,5 @@
3ifdef CONFIG_PPC64 3ifdef CONFIG_PPC64
4EXTRA_CFLAGS += -mno-minimal-toc 4EXTRA_CFLAGS += -mno-minimal-toc
5endif 5endif
6 6obj-y += xmon.o ppc-dis.o ppc-opc.o setjmp.o start.o \
7obj-$(CONFIG_8xx) += start_8xx.o 7 nonstdio.o
8obj-$(CONFIG_6xx) += start_32.o
9obj-$(CONFIG_4xx) += start_32.o
10obj-$(CONFIG_PPC64) += start_64.o
11obj-y += xmon.o ppc-dis.o ppc-opc.o setjmp.o nonstdio.o
diff --git a/arch/powerpc/xmon/start_64.c b/arch/powerpc/xmon/start.c
index 712552c4f242..712552c4f242 100644
--- a/arch/powerpc/xmon/start_64.c
+++ b/arch/powerpc/xmon/start.c
diff --git a/arch/powerpc/xmon/start_32.c b/arch/powerpc/xmon/start_32.c
deleted file mode 100644
index c2464df4217e..000000000000
--- a/arch/powerpc/xmon/start_32.c
+++ /dev/null
@@ -1,441 +0,0 @@
1/*
2 * Copyright (C) 1996 Paul Mackerras.
3 */
4#include <linux/config.h>
5#include <linux/string.h>
6#include <asm/machdep.h>
7#include <asm/io.h>
8#include <asm/page.h>
9#include <linux/adb.h>
10#include <linux/pmu.h>
11#include <linux/cuda.h>
12#include <linux/kernel.h>
13#include <linux/errno.h>
14#include <linux/bitops.h>
15#include <asm/xmon.h>
16#include <asm/prom.h>
17#include <asm/bootx.h>
18#include <asm/machdep.h>
19#include <asm/errno.h>
20#include <asm/pmac_feature.h>
21#include <asm/processor.h>
22#include <asm/delay.h>
23#include <asm/btext.h>
24#include <asm/time.h>
25#include "nonstdio.h"
26
27static volatile unsigned char __iomem *sccc, *sccd;
28unsigned int TXRDY, RXRDY, DLAB;
29
30static int use_serial;
31static int use_screen;
32static int via_modem;
33static int xmon_use_sccb;
34static struct device_node *channel_node;
35
36void buf_access(void)
37{
38 if (DLAB)
39 sccd[3] &= ~DLAB; /* reset DLAB */
40}
41
42extern int adb_init(void);
43
44#ifdef CONFIG_PPC_CHRP
45/*
46 * This looks in the "ranges" property for the primary PCI host bridge
47 * to find the physical address of the start of PCI/ISA I/O space.
48 * It is basically a cut-down version of pci_process_bridge_OF_ranges.
49 */
50static unsigned long chrp_find_phys_io_base(void)
51{
52 struct device_node *node;
53 unsigned int *ranges;
54 unsigned long base = CHRP_ISA_IO_BASE;
55 int rlen = 0;
56 int np;
57
58 node = find_devices("isa");
59 if (node != NULL) {
60 node = node->parent;
61 if (node == NULL || node->type == NULL
62 || strcmp(node->type, "pci") != 0)
63 node = NULL;
64 }
65 if (node == NULL)
66 node = find_devices("pci");
67 if (node == NULL)
68 return base;
69
70 ranges = (unsigned int *) get_property(node, "ranges", &rlen);
71 np = prom_n_addr_cells(node) + 5;
72 while ((rlen -= np * sizeof(unsigned int)) >= 0) {
73 if ((ranges[0] >> 24) == 1 && ranges[2] == 0) {
74 /* I/O space starting at 0, grab the phys base */
75 base = ranges[np - 3];
76 break;
77 }
78 ranges += np;
79 }
80 return base;
81}
82#endif /* CONFIG_PPC_CHRP */
83
84void xmon_map_scc(void)
85{
86#ifdef CONFIG_PPC_MULTIPLATFORM
87 volatile unsigned char __iomem *base;
88
89 if (_machine == _MACH_Pmac) {
90 struct device_node *np;
91 unsigned long addr;
92#ifdef CONFIG_BOOTX_TEXT
93 if (!use_screen && !use_serial
94 && !machine_is_compatible("iMac")) {
95 /* see if there is a keyboard in the device tree
96 with a parent of type "adb" */
97 for (np = find_devices("keyboard"); np; np = np->next)
98 if (np->parent && np->parent->type
99 && strcmp(np->parent->type, "adb") == 0)
100 break;
101
102 /* needs to be hacked if xmon_printk is to be used
103 from within find_via_pmu() */
104#ifdef CONFIG_ADB_PMU
105 if (np != NULL && boot_text_mapped && find_via_pmu())
106 use_screen = 1;
107#endif
108#ifdef CONFIG_ADB_CUDA
109 if (np != NULL && boot_text_mapped && find_via_cuda())
110 use_screen = 1;
111#endif
112 }
113 if (!use_screen && (np = find_devices("escc")) != NULL) {
114 /*
115 * look for the device node for the serial port
116 * we're using and see if it says it has a modem
117 */
118 char *name = xmon_use_sccb? "ch-b": "ch-a";
119 char *slots;
120 int l;
121
122 np = np->child;
123 while (np != NULL && strcmp(np->name, name) != 0)
124 np = np->sibling;
125 if (np != NULL) {
126 /* XXX should parse this properly */
127 channel_node = np;
128 slots = get_property(np, "slot-names", &l);
129 if (slots != NULL && l >= 10
130 && strcmp(slots+4, "Modem") == 0)
131 via_modem = 1;
132 }
133 }
134 btext_drawstring("xmon uses ");
135 if (use_screen)
136 btext_drawstring("screen and keyboard\n");
137 else {
138 if (via_modem)
139 btext_drawstring("modem on ");
140 btext_drawstring(xmon_use_sccb? "printer": "modem");
141 btext_drawstring(" port\n");
142 }
143
144#endif /* CONFIG_BOOTX_TEXT */
145
146#ifdef CHRP_ESCC
147 addr = 0xc1013020;
148#else
149 addr = 0xf3013020;
150#endif
151 TXRDY = 4;
152 RXRDY = 1;
153
154 np = find_devices("mac-io");
155 if (np && np->n_addrs)
156 addr = np->addrs[0].address + 0x13020;
157 base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
158 sccc = base + (addr & ~PAGE_MASK);
159 sccd = sccc + 0x10;
160
161 } else {
162 base = (volatile unsigned char *) isa_io_base;
163
164#ifdef CONFIG_PPC_CHRP
165 if (_machine == _MACH_chrp)
166 base = (volatile unsigned char __iomem *)
167 ioremap(chrp_find_phys_io_base(), 0x1000);
168#endif
169
170 sccc = base + 0x3fd;
171 sccd = base + 0x3f8;
172 if (xmon_use_sccb) {
173 sccc -= 0x100;
174 sccd -= 0x100;
175 }
176 TXRDY = 0x20;
177 RXRDY = 1;
178 DLAB = 0x80;
179 }
180#elif defined(CONFIG_GEMINI)
181 /* should already be mapped by the kernel boot */
182 sccc = (volatile unsigned char __iomem *) 0xffeffb0d;
183 sccd = (volatile unsigned char __iomem *) 0xffeffb08;
184 TXRDY = 0x20;
185 RXRDY = 1;
186 DLAB = 0x80;
187#elif defined(CONFIG_405GP)
188 sccc = (volatile unsigned char __iomem *)0xef600305;
189 sccd = (volatile unsigned char __iomem *)0xef600300;
190 TXRDY = 0x20;
191 RXRDY = 1;
192 DLAB = 0x80;
193#endif /* platform */
194}
195
196static int scc_initialized = 0;
197
198void xmon_init_scc(void);
199extern void cuda_poll(void);
200
201static inline void do_poll_adb(void)
202{
203#ifdef CONFIG_ADB_PMU
204 if (sys_ctrler == SYS_CTRLER_PMU)
205 pmu_poll_adb();
206#endif /* CONFIG_ADB_PMU */
207#ifdef CONFIG_ADB_CUDA
208 if (sys_ctrler == SYS_CTRLER_CUDA)
209 cuda_poll();
210#endif /* CONFIG_ADB_CUDA */
211}
212
213int xmon_write(void *ptr, int nb)
214{
215 char *p = ptr;
216 int i, c, ct;
217
218#ifdef CONFIG_SMP
219 static unsigned long xmon_write_lock;
220 int lock_wait = 1000000;
221 int locked;
222
223 while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0)
224 if (--lock_wait == 0)
225 break;
226#endif
227
228#ifdef CONFIG_BOOTX_TEXT
229 if (use_screen) {
230 /* write it on the screen */
231 for (i = 0; i < nb; ++i)
232 btext_drawchar(*p++);
233 goto out;
234 }
235#endif
236 if (!scc_initialized)
237 xmon_init_scc();
238 ct = 0;
239 for (i = 0; i < nb; ++i) {
240 while ((*sccc & TXRDY) == 0)
241 do_poll_adb();
242 c = p[i];
243 if (c == '\n' && !ct) {
244 c = '\r';
245 ct = 1;
246 --i;
247 } else {
248 ct = 0;
249 }
250 buf_access();
251 *sccd = c;
252 eieio();
253 }
254
255 out:
256#ifdef CONFIG_SMP
257 if (!locked)
258 clear_bit(0, &xmon_write_lock);
259#endif
260 return nb;
261}
262
263int xmon_wants_key;
264int xmon_adb_keycode;
265
266#ifdef CONFIG_BOOTX_TEXT
267static int xmon_adb_shiftstate;
268
269static unsigned char xmon_keytab[128] =
270 "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */
271 "yt123465=97-80]o" /* 0x10 - 0x1f */
272 "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */
273 "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
274 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
275 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
276
277static unsigned char xmon_shift_keytab[128] =
278 "ASDFHGZXCV\000BQWER" /* 0x00 - 0x0f */
279 "YT!@#$^%+(&_*)}O" /* 0x10 - 0x1f */
280 "U{IP\rLJ\"K:|<?NM>" /* 0x20 - 0x2f */
281 "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
282 "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
283 "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
284
285static int xmon_get_adb_key(void)
286{
287 int k, t, on;
288
289 xmon_wants_key = 1;
290 for (;;) {
291 xmon_adb_keycode = -1;
292 t = 0;
293 on = 0;
294 do {
295 if (--t < 0) {
296 on = 1 - on;
297 btext_drawchar(on? 0xdb: 0x20);
298 btext_drawchar('\b');
299 t = 200000;
300 }
301 do_poll_adb();
302 } while (xmon_adb_keycode == -1);
303 k = xmon_adb_keycode;
304 if (on)
305 btext_drawstring(" \b");
306
307 /* test for shift keys */
308 if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
309 xmon_adb_shiftstate = (k & 0x80) == 0;
310 continue;
311 }
312 if (k >= 0x80)
313 continue; /* ignore up transitions */
314 k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
315 if (k != 0)
316 break;
317 }
318 xmon_wants_key = 0;
319 return k;
320}
321#endif /* CONFIG_BOOTX_TEXT */
322
323int xmon_readchar(void)
324{
325#ifdef CONFIG_BOOTX_TEXT
326 if (use_screen)
327 return xmon_get_adb_key();
328#endif
329 if (!scc_initialized)
330 xmon_init_scc();
331 while ((*sccc & RXRDY) == 0)
332 do_poll_adb();
333 buf_access();
334 return *sccd;
335}
336
337int xmon_read_poll(void)
338{
339 if ((*sccc & RXRDY) == 0) {
340 do_poll_adb();
341 return -1;
342 }
343 buf_access();
344 return *sccd;
345}
346
347static unsigned char scc_inittab[] = {
348 13, 0, /* set baud rate divisor */
349 12, 1,
350 14, 1, /* baud rate gen enable, src=rtxc */
351 11, 0x50, /* clocks = br gen */
352 5, 0xea, /* tx 8 bits, assert DTR & RTS */
353 4, 0x46, /* x16 clock, 1 stop */
354 3, 0xc1, /* rx enable, 8 bits */
355};
356
357void xmon_init_scc(void)
358{
359 if ( _machine == _MACH_chrp )
360 {
361 sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */
362 sccd[0] = 12; eieio(); /* DLL = 9600 baud */
363 sccd[1] = 0; eieio();
364 sccd[2] = 0; eieio(); /* FCR = 0 */
365 sccd[3] = 3; eieio(); /* LCR = 8N1 */
366 sccd[1] = 0; eieio(); /* IER = 0 */
367 }
368 else if ( _machine == _MACH_Pmac )
369 {
370 int i, x;
371 unsigned long timeout;
372
373 if (channel_node != 0)
374 pmac_call_feature(
375 PMAC_FTR_SCC_ENABLE,
376 channel_node,
377 PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
378 printk(KERN_INFO "Serial port locked ON by debugger !\n");
379 if (via_modem && channel_node != 0) {
380 unsigned int t0;
381
382 pmac_call_feature(
383 PMAC_FTR_MODEM_ENABLE,
384 channel_node, 0, 1);
385 printk(KERN_INFO "Modem powered up by debugger !\n");
386 t0 = get_tbl();
387 timeout = 3 * tb_ticks_per_sec;
388 if (timeout == 0)
389 /* assume 25MHz if tb_ticks_per_sec not set */
390 timeout = 75000000;
391 while (get_tbl() - t0 < timeout)
392 eieio();
393 }
394 /* use the B channel if requested */
395 if (xmon_use_sccb) {
396 sccc = (volatile unsigned char *)
397 ((unsigned long)sccc & ~0x20);
398 sccd = sccc + 0x10;
399 }
400 for (i = 20000; i != 0; --i) {
401 x = *sccc; eieio();
402 }
403 *sccc = 9; eieio(); /* reset A or B side */
404 *sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio();
405 for (i = 0; i < sizeof(scc_inittab); ++i) {
406 *sccc = scc_inittab[i];
407 eieio();
408 }
409 }
410 scc_initialized = 1;
411 if (via_modem) {
412 for (;;) {
413 xmon_write("ATE1V1\r", 7);
414 if (xmon_expect("OK", 5)) {
415 xmon_write("ATA\r", 4);
416 if (xmon_expect("CONNECT", 40))
417 break;
418 }
419 xmon_write("+++", 3);
420 xmon_expect("OK", 3);
421 }
422 }
423}
424
425void xmon_enter(void)
426{
427#ifdef CONFIG_ADB_PMU
428 if (_machine == _MACH_Pmac) {
429 pmu_suspend();
430 }
431#endif
432}
433
434void xmon_leave(void)
435{
436#ifdef CONFIG_ADB_PMU
437 if (_machine == _MACH_Pmac) {
438 pmu_resume();
439 }
440#endif
441}
diff --git a/arch/powerpc/xmon/start_8xx.c b/arch/powerpc/xmon/start_8xx.c
deleted file mode 100644
index 4c17b0486ad5..000000000000
--- a/arch/powerpc/xmon/start_8xx.c
+++ /dev/null
@@ -1,44 +0,0 @@
1/*
2 * Copyright (C) 1996 Paul Mackerras.
3 * Copyright (C) 2000 Dan Malek.
4 * Quick hack of Paul's code to make XMON work on 8xx processors. Lots
5 * of assumptions, like the SMC1 is used, it has been initialized by the
6 * loader at some point, and we can just stuff and suck bytes.
7 * We rely upon the 8xx uart driver to support us, as the interface
8 * changes between boot up and operational phases of the kernel.
9 */
10#include <linux/string.h>
11#include <asm/machdep.h>
12#include <asm/io.h>
13#include <asm/page.h>
14#include <linux/kernel.h>
15#include <asm/8xx_immap.h>
16#include <asm/mpc8xx.h>
17#include <asm/commproc.h>
18#include "nonstdio.h"
19
20extern int xmon_8xx_write(char *str, int nb);
21extern int xmon_8xx_read_poll(void);
22extern int xmon_8xx_read_char(void);
23
24void xmon_map_scc(void)
25{
26 cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
27}
28
29void xmon_init_scc(void);
30
31int xmon_write(void *ptr, int nb)
32{
33 return(xmon_8xx_write(ptr, nb));
34}
35
36int xmon_readchar(void)
37{
38 return xmon_8xx_read_char();
39}
40
41int xmon_read_poll(void)
42{
43 return(xmon_8xx_read_poll());
44}
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 0eb0b7085e6a..e707c6f6e61b 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -744,6 +744,9 @@ void __init setup_arch(char **cmdline_p)
744 /* so udelay does something sensible, assume <= 1000 bogomips */ 744 /* so udelay does something sensible, assume <= 1000 bogomips */
745 loops_per_jiffy = 500000000 / HZ; 745 loops_per_jiffy = 500000000 / HZ;
746 746
747 if (ppc_md.init_early)
748 ppc_md.init_early();
749
747#ifdef CONFIG_PPC_MULTIPLATFORM 750#ifdef CONFIG_PPC_MULTIPLATFORM
748 /* This could be called "early setup arch", it must be done 751 /* This could be called "early setup arch", it must be done
749 * now because xmon need it 752 * now because xmon need it
diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c
index d61f748278fc..93e7080e3bc5 100644
--- a/drivers/i2c/busses/i2c-keywest.c
+++ b/drivers/i2c/busses/i2c-keywest.c
@@ -505,16 +505,23 @@ static int
505create_iface(struct device_node *np, struct device *dev) 505create_iface(struct device_node *np, struct device *dev)
506{ 506{
507 unsigned long steps; 507 unsigned long steps;
508 unsigned bsteps, tsize, i, nchan, addroffset; 508 unsigned bsteps, tsize, i, nchan;
509 struct keywest_iface* iface; 509 struct keywest_iface* iface;
510 u32 *psteps, *prate; 510 u32 *psteps, *prate, *addrp;
511 int rc; 511 int rc;
512 512
513 if (np->n_intrs < 1 || np->n_addrs < 1) { 513 if (np->n_intrs < 1) {
514 printk(KERN_ERR "%s: Missing interrupt or address !\n", 514 printk(KERN_ERR "%s: Missing interrupt !\n",
515 np->full_name); 515 np->full_name);
516 return -ENODEV; 516 return -ENODEV;
517 } 517 }
518 addrp = (u32 *)get_property(np, "AAPL,address", NULL);
519 if (addrp == NULL) {
520 printk(KERN_ERR "%s: Can't find address !\n",
521 np->full_name);
522 return -ENODEV;
523 }
524
518 if (pmac_low_i2c_lock(np)) 525 if (pmac_low_i2c_lock(np))
519 return -ENODEV; 526 return -ENODEV;
520 527
@@ -525,13 +532,10 @@ create_iface(struct device_node *np, struct device *dev)
525 for (bsteps = 0; (steps & 0x01) == 0; bsteps++) 532 for (bsteps = 0; (steps & 0x01) == 0; bsteps++)
526 steps >>= 1; 533 steps >>= 1;
527 534
528 if (np->parent->name[0] == 'u') { 535 if (np->parent->name[0] == 'u')
529 nchan = 2; 536 nchan = 2;
530 addroffset = 3; 537 else
531 } else {
532 addroffset = 0;
533 nchan = 1; 538 nchan = 1;
534 }
535 539
536 tsize = sizeof(struct keywest_iface) + 540 tsize = sizeof(struct keywest_iface) +
537 (sizeof(struct keywest_chan) + 4) * nchan; 541 (sizeof(struct keywest_chan) + 4) * nchan;
@@ -550,8 +554,7 @@ create_iface(struct device_node *np, struct device *dev)
550 iface->irq = np->intrs[0].line; 554 iface->irq = np->intrs[0].line;
551 iface->channels = (struct keywest_chan *) 555 iface->channels = (struct keywest_chan *)
552 (((unsigned long)(iface + 1) + 3UL) & ~3UL); 556 (((unsigned long)(iface + 1) + 3UL) & ~3UL);
553 iface->base = ioremap(np->addrs[0].address + addroffset, 557 iface->base = ioremap(*addrp, 0x1000);
554 np->addrs[0].size);
555 if (!iface->base) { 558 if (!iface->base) {
556 printk(KERN_ERR "i2c-keywest: can't map inteface !\n"); 559 printk(KERN_ERR "i2c-keywest: can't map inteface !\n");
557 kfree(iface); 560 kfree(iface);
diff --git a/drivers/macintosh/via-cuda.c b/drivers/macintosh/via-cuda.c
index d843a6c9c6df..18ff770ea668 100644
--- a/drivers/macintosh/via-cuda.c
+++ b/drivers/macintosh/via-cuda.c
@@ -127,39 +127,34 @@ struct adb_driver via_cuda_driver = {
127#endif /* CONFIG_ADB */ 127#endif /* CONFIG_ADB */
128 128
129#ifdef CONFIG_PPC 129#ifdef CONFIG_PPC
130int __init 130int __init find_via_cuda(void)
131find_via_cuda(void)
132{ 131{
133 int err;
134 struct adb_request req; 132 struct adb_request req;
133 phys_addr_t taddr;
134 u32 *reg;
135 int err;
135 136
136 if (vias != 0) 137 if (vias != 0)
137 return 1; 138 return 1;
138 vias = find_devices("via-cuda"); 139 vias = of_find_node_by_name(NULL, "via-cuda");
139 if (vias == 0) 140 if (vias == 0)
140 return 0; 141 return 0;
141 if (vias->next != 0)
142 printk(KERN_WARNING "Warning: only using 1st via-cuda\n");
143
144#if 0
145 { int i;
146
147 printk("find_via_cuda: node = %p, addrs =", vias->node);
148 for (i = 0; i < vias->n_addrs; ++i)
149 printk(" %x(%x)", vias->addrs[i].address, vias->addrs[i].size);
150 printk(", intrs =");
151 for (i = 0; i < vias->n_intrs; ++i)
152 printk(" %x", vias->intrs[i].line);
153 printk("\n"); }
154#endif
155 142
156 if (vias->n_addrs != 1 || vias->n_intrs != 1) { 143 reg = (u32 *)get_property(vias, "reg", NULL);
157 printk(KERN_ERR "via-cuda: expecting 1 address (%d) and 1 interrupt (%d)\n", 144 if (reg == NULL) {
158 vias->n_addrs, vias->n_intrs); 145 printk(KERN_ERR "via-cuda: No \"reg\" property !\n");
159 if (vias->n_addrs < 1 || vias->n_intrs < 1) 146 goto fail;
160 return 0; 147 }
148 taddr = of_translate_address(vias, reg);
149 if (taddr == 0) {
150 printk(KERN_ERR "via-cuda: Can't translate address !\n");
151 goto fail;
152 }
153 via = ioremap(taddr, 0x2000);
154 if (via == NULL) {
155 printk(KERN_ERR "via-cuda: Can't map address !\n");
156 goto fail;
161 } 157 }
162 via = ioremap(vias->addrs->address, 0x2000);
163 158
164 cuda_state = idle; 159 cuda_state = idle;
165 sys_ctrler = SYS_CTRLER_CUDA; 160 sys_ctrler = SYS_CTRLER_CUDA;
@@ -185,6 +180,11 @@ find_via_cuda(void)
185 cuda_poll(); 180 cuda_poll();
186 181
187 return 1; 182 return 1;
183
184 fail:
185 of_node_put(vias);
186 vias = NULL;
187 return 0;
188} 188}
189#endif /* CONFIG_PPC */ 189#endif /* CONFIG_PPC */
190 190
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 564043508569..13881f199607 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -147,6 +147,7 @@ static struct device_node *vias;
147static int pmu_kind = PMU_UNKNOWN; 147static int pmu_kind = PMU_UNKNOWN;
148static int pmu_fully_inited = 0; 148static int pmu_fully_inited = 0;
149static int pmu_has_adb; 149static int pmu_has_adb;
150static struct device_node *gpio_node;
150static unsigned char __iomem *gpio_reg = NULL; 151static unsigned char __iomem *gpio_reg = NULL;
151static int gpio_irq = -1; 152static int gpio_irq = -1;
152static int gpio_irq_enabled = -1; 153static int gpio_irq_enabled = -1;
@@ -295,22 +296,26 @@ static struct backlight_controller pmu_backlight_controller = {
295}; 296};
296#endif /* CONFIG_PMAC_BACKLIGHT */ 297#endif /* CONFIG_PMAC_BACKLIGHT */
297 298
298int 299int __init find_via_pmu(void)
299find_via_pmu(void)
300{ 300{
301 phys_addr_t taddr;
302 u32 *reg;
303
301 if (via != 0) 304 if (via != 0)
302 return 1; 305 return 1;
303 vias = find_devices("via-pmu"); 306 vias = of_find_node_by_name(NULL, "via-pmu");
304 if (vias == 0) 307 if (vias == NULL)
305 return 0; 308 return 0;
306 if (vias->next != 0)
307 printk(KERN_WARNING "Warning: only using 1st via-pmu\n");
308 309
309 if (vias->n_addrs < 1 || vias->n_intrs < 1) { 310 reg = (u32 *)get_property(vias, "reg", NULL);
310 printk(KERN_ERR "via-pmu: %d addresses, %d interrupts!\n", 311 if (reg == NULL) {
311 vias->n_addrs, vias->n_intrs); 312 printk(KERN_ERR "via-pmu: No \"reg\" property !\n");
312 if (vias->n_addrs < 1 || vias->n_intrs < 1) 313 goto fail;
313 return 0; 314 }
315 taddr = of_translate_address(vias, reg);
316 if (taddr == 0) {
317 printk(KERN_ERR "via-pmu: Can't translate address !\n");
318 goto fail;
314 } 319 }
315 320
316 spin_lock_init(&pmu_lock); 321 spin_lock_init(&pmu_lock);
@@ -331,7 +336,8 @@ find_via_pmu(void)
331 pmu_kind = PMU_HEATHROW_BASED; 336 pmu_kind = PMU_HEATHROW_BASED;
332 else if (device_is_compatible(vias->parent, "Keylargo") 337 else if (device_is_compatible(vias->parent, "Keylargo")
333 || device_is_compatible(vias->parent, "K2-Keylargo")) { 338 || device_is_compatible(vias->parent, "K2-Keylargo")) {
334 struct device_node *gpio, *gpiop; 339 struct device_node *gpiop;
340 phys_addr_t gaddr = 0;
335 341
336 pmu_kind = PMU_KEYLARGO_BASED; 342 pmu_kind = PMU_KEYLARGO_BASED;
337 pmu_has_adb = (find_type_devices("adb") != NULL); 343 pmu_has_adb = (find_type_devices("adb") != NULL);
@@ -341,19 +347,24 @@ find_via_pmu(void)
341 PMU_INT_TICK | 347 PMU_INT_TICK |
342 PMU_INT_ENVIRONMENT; 348 PMU_INT_ENVIRONMENT;
343 349
344 gpiop = find_devices("gpio"); 350 gpiop = of_find_node_by_name(NULL, "gpio");
345 if (gpiop && gpiop->n_addrs) { 351 if (gpiop) {
346 gpio_reg = ioremap(gpiop->addrs->address, 0x10); 352 reg = (u32 *)get_property(gpiop, "reg", NULL);
347 gpio = find_devices("extint-gpio1"); 353 if (reg)
348 if (gpio == NULL) 354 gaddr = of_translate_address(gpiop, reg);
349 gpio = find_devices("pmu-interrupt"); 355 if (gaddr != 0)
350 if (gpio && gpio->parent == gpiop && gpio->n_intrs) 356 gpio_reg = ioremap(gaddr, 0x10);
351 gpio_irq = gpio->intrs[0].line;
352 } 357 }
358 if (gpio_reg == NULL)
359 printk(KERN_ERR "via-pmu: Can't find GPIO reg !\n");
353 } else 360 } else
354 pmu_kind = PMU_UNKNOWN; 361 pmu_kind = PMU_UNKNOWN;
355 362
356 via = ioremap(vias->addrs->address, 0x2000); 363 via = ioremap(taddr, 0x2000);
364 if (via == NULL) {
365 printk(KERN_ERR "via-pmu: Can't map address !\n");
366 goto fail;
367 }
357 368
358 out_8(&via[IER], IER_CLR | 0x7f); /* disable all intrs */ 369 out_8(&via[IER], IER_CLR | 0x7f); /* disable all intrs */
359 out_8(&via[IFR], 0x7f); /* clear IFR */ 370 out_8(&via[IFR], 0x7f); /* clear IFR */
@@ -371,17 +382,19 @@ find_via_pmu(void)
371 sys_ctrler = SYS_CTRLER_PMU; 382 sys_ctrler = SYS_CTRLER_PMU;
372 383
373 return 1; 384 return 1;
385 fail:
386 of_node_put(vias);
387 vias = NULL;
388 return 0;
374} 389}
375 390
376#ifdef CONFIG_ADB 391#ifdef CONFIG_ADB
377static int 392static int pmu_probe(void)
378pmu_probe(void)
379{ 393{
380 return vias == NULL? -ENODEV: 0; 394 return vias == NULL? -ENODEV: 0;
381} 395}
382 396
383static int __init 397static int __init pmu_init(void)
384pmu_init(void)
385{ 398{
386 if (vias == NULL) 399 if (vias == NULL)
387 return -ENODEV; 400 return -ENODEV;
@@ -405,7 +418,7 @@ static int __init via_pmu_start(void)
405 bright_req_2.complete = 1; 418 bright_req_2.complete = 1;
406 batt_req.complete = 1; 419 batt_req.complete = 1;
407 420
408#if defined(CONFIG_PPC32) && !defined(CONFIG_PPC_MERGE) 421#ifndef CONFIG_PPC_MERGE
409 if (pmu_kind == PMU_KEYLARGO_BASED) 422 if (pmu_kind == PMU_KEYLARGO_BASED)
410 openpic_set_irq_priority(vias->intrs[0].line, 423 openpic_set_irq_priority(vias->intrs[0].line,
411 OPENPIC_PRIORITY_DEFAULT + 1); 424 OPENPIC_PRIORITY_DEFAULT + 1);
@@ -418,10 +431,22 @@ static int __init via_pmu_start(void)
418 return -EAGAIN; 431 return -EAGAIN;
419 } 432 }
420 433
421 if (pmu_kind == PMU_KEYLARGO_BASED && gpio_irq != -1) { 434 if (pmu_kind == PMU_KEYLARGO_BASED) {
422 if (request_irq(gpio_irq, gpio1_interrupt, 0, "GPIO1 ADB", (void *)0)) 435 gpio_node = of_find_node_by_name(NULL, "extint-gpio1");
423 printk(KERN_ERR "pmu: can't get irq %d (GPIO1)\n", gpio_irq); 436 if (gpio_node == NULL)
424 gpio_irq_enabled = 1; 437 gpio_node = of_find_node_by_name(NULL,
438 "pmu-interrupt");
439 if (gpio_node && gpio_node->n_intrs > 0)
440 gpio_irq = gpio_node->intrs[0].line;
441
442 if (gpio_irq != -1) {
443 if (request_irq(gpio_irq, gpio1_interrupt, 0,
444 "GPIO1 ADB", (void *)0))
445 printk(KERN_ERR "pmu: can't get irq %d"
446 " (GPIO1)\n", gpio_irq);
447 else
448 gpio_irq_enabled = 1;
449 }
425 } 450 }
426 451
427 /* Enable interrupts */ 452 /* Enable interrupts */
@@ -1371,7 +1396,6 @@ next:
1371 } 1396 }
1372 pmu_done(req); 1397 pmu_done(req);
1373 } else { 1398 } else {
1374#if defined(CONFIG_XMON) && !defined(CONFIG_PPC64)
1375 if (len == 4 && data[1] == 0x2c) { 1399 if (len == 4 && data[1] == 0x2c) {
1376 extern int xmon_wants_key, xmon_adb_keycode; 1400 extern int xmon_wants_key, xmon_adb_keycode;
1377 if (xmon_wants_key) { 1401 if (xmon_wants_key) {
@@ -1379,7 +1403,6 @@ next:
1379 return; 1403 return;
1380 } 1404 }
1381 } 1405 }
1382#endif /* defined(CONFIG_XMON) && !defined(CONFIG_PPC64) */
1383#ifdef CONFIG_ADB 1406#ifdef CONFIG_ADB
1384 /* 1407 /*
1385 * XXX On the [23]400 the PMU gives us an up 1408 * XXX On the [23]400 the PMU gives us an up
diff --git a/include/asm-powerpc/btext.h b/include/asm-powerpc/btext.h
index 71cce36bc630..906f46e31006 100644
--- a/include/asm-powerpc/btext.h
+++ b/include/asm-powerpc/btext.h
@@ -7,21 +7,22 @@
7#define __PPC_BTEXT_H 7#define __PPC_BTEXT_H
8#ifdef __KERNEL__ 8#ifdef __KERNEL__
9 9
10extern void btext_clearscreen(void); 10extern int btext_find_display(int allow_nonstdout);
11extern void btext_flushscreen(void);
12
13extern int boot_text_mapped;
14
15extern int btext_initialize(struct device_node *np);
16
17extern void map_boot_text(void);
18extern void init_boot_display(void);
19extern void btext_update_display(unsigned long phys, int width, int height, 11extern void btext_update_display(unsigned long phys, int width, int height,
20 int depth, int pitch); 12 int depth, int pitch);
13extern void btext_setup_display(int width, int height, int depth, int pitch,
14 unsigned long address);
15extern void btext_prepare_BAT(void);
16extern void btext_unmap(void);
21 17
22extern void btext_drawchar(char c); 18extern void btext_drawchar(char c);
23extern void btext_drawstring(const char *str); 19extern void btext_drawstring(const char *str);
24extern void btext_drawhex(unsigned long v); 20extern void btext_drawhex(unsigned long v);
21extern void btext_drawtext(const char *c, unsigned int len);
22
23extern void btext_clearscreen(void);
24extern void btext_flushscreen(void);
25extern void btext_flushline(void);
25 26
26#endif /* __KERNEL__ */ 27#endif /* __KERNEL__ */
27#endif /* __PPC_BTEXT_H */ 28#endif /* __PPC_BTEXT_H */
diff --git a/include/asm-powerpc/udbg.h b/include/asm-powerpc/udbg.h
index 4049a96dc43d..8d6b44c8f35d 100644
--- a/include/asm-powerpc/udbg.h
+++ b/include/asm-powerpc/udbg.h
@@ -13,8 +13,8 @@
13#include <linux/compiler.h> 13#include <linux/compiler.h>
14#include <linux/init.h> 14#include <linux/init.h>
15 15
16extern void (*udbg_putc)(unsigned char c); 16extern void (*udbg_putc)(char c);
17extern unsigned char (*udbg_getc)(void); 17extern char (*udbg_getc)(void);
18extern int (*udbg_getc_poll)(void); 18extern int (*udbg_getc_poll)(void);
19 19
20extern void udbg_puts(const char *s); 20extern void udbg_puts(const char *s);
@@ -30,5 +30,8 @@ extern unsigned int udbg_probe_uart_speed(void __iomem *comport,
30 unsigned int clock); 30 unsigned int clock);
31 31
32struct device_node; 32struct device_node;
33extern void udbg_init_scc(struct device_node *np); 33extern void udbg_scc_init(int force_scc);
34extern int udbg_adb_init(int force_btext);
35extern void udbg_adb_init_early(void);
36
34#endif /* _ASM_POWERPC_UDBG_H */ 37#endif /* _ASM_POWERPC_UDBG_H */
diff --git a/include/asm-ppc/btext.h b/include/asm-ppc/btext.h
index ccaefabe0bf5..ed3630251b3b 100644
--- a/include/asm-ppc/btext.h
+++ b/include/asm-ppc/btext.h
@@ -17,7 +17,7 @@ extern unsigned long disp_BAT[2];
17extern boot_infos_t disp_bi; 17extern boot_infos_t disp_bi;
18extern int boot_text_mapped; 18extern int boot_text_mapped;
19 19
20extern void init_boot_display(void); 20extern void btext_init(boot_infos_t *bi);
21extern void btext_welcome(void); 21extern void btext_welcome(void);
22extern void btext_prepare_BAT(void); 22extern void btext_prepare_BAT(void);
23extern void btext_setup_display(int width, int height, int depth, int pitch, 23extern void btext_setup_display(int width, int height, int depth, int pitch,
diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h
index f01255bd1dc3..39200def8d11 100644
--- a/include/asm-ppc/machdep.h
+++ b/include/asm-ppc/machdep.h
@@ -35,8 +35,10 @@ struct machdep_calls {
35 int (*get_irq)(struct pt_regs *); 35 int (*get_irq)(struct pt_regs *);
36 36
37 /* A general init function, called by ppc_init in init/main.c. 37 /* A general init function, called by ppc_init in init/main.c.
38 May be NULL. */ 38 May be NULL. DEPRECATED ! */
39 void (*init)(void); 39 void (*init)(void);
40 /* For compatibility with merged platforms */
41 void (*init_early)(void);
40 42
41 void (*restart)(char *cmd); 43 void (*restart)(char *cmd);
42 void (*power_off)(void); 44 void (*power_off)(void);