[PATCH] powerpc: Unify udbg (#2)
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Wed, 23 Nov 2005 06:57:25 +0000 (17:57 +1100)
committerPaul Mackerras <paulus@samba.org>
Mon, 9 Jan 2006 03:49:54 +0000 (14:49 +1100)
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>
31 files changed:
arch/powerpc/Kconfig
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/btext.c
arch/powerpc/kernel/head_32.S
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/udbg.c
arch/powerpc/kernel/udbg_16550.c
arch/powerpc/kernel/udbg_scc.c [deleted file]
arch/powerpc/mm/init_32.c
arch/powerpc/platforms/powermac/Makefile
arch/powerpc/platforms/powermac/feature.c
arch/powerpc/platforms/powermac/low_i2c.c
arch/powerpc/platforms/powermac/pic.c
arch/powerpc/platforms/powermac/setup.c
arch/powerpc/platforms/powermac/udbg_adb.c [new file with mode: 0644]
arch/powerpc/platforms/powermac/udbg_scc.c [new file with mode: 0644]
arch/powerpc/platforms/pseries/lpar.c
arch/powerpc/xmon/Makefile
arch/powerpc/xmon/start.c [new file with mode: 0644]
arch/powerpc/xmon/start_32.c [deleted file]
arch/powerpc/xmon/start_64.c [deleted file]
arch/powerpc/xmon/start_8xx.c [deleted file]
arch/ppc/kernel/setup.c
drivers/i2c/busses/i2c-keywest.c
drivers/macintosh/via-cuda.c
drivers/macintosh/via-pmu.c
include/asm-powerpc/btext.h
include/asm-powerpc/udbg.h
include/asm-ppc/btext.h
include/asm-ppc/machdep.h

index 39ca7b9da3697e22e13f61e7627e66db40b9b062..0e4617104f8caa29710f01fd9a0e5b1e2785e969 100644 (file)
@@ -50,7 +50,7 @@ config PPC
 
 config EARLY_PRINTK
        bool
-       default y if PPC64
+       default y
 
 config COMPAT
        bool
index bf3fd6f022496728cbfcb343ede495277f6c8ea8..89714929f444bc93b8eedc9bc3277657cfe78602 100644 (file)
@@ -18,7 +18,7 @@ obj-y                         += vdso32/
 obj-$(CONFIG_PPC64)            += setup_64.o binfmt_elf32.o sys_ppc32.o \
                                   signal_64.o ptrace32.o systbl.o \
                                   paca.o ioctl32.o cpu_setup_power4.o \
-                                  firmware.o sysfs.o udbg.o idle_64.o
+                                  firmware.o sysfs.o idle_64.o
 obj-$(CONFIG_PPC64)            += vdso64/
 obj-$(CONFIG_ALTIVEC)          += vecemu.o vector.o
 obj-$(CONFIG_POWER4)           += idle_power4.o
@@ -46,7 +46,7 @@ extra-$(CONFIG_8xx)           := head_8xx.o
 extra-y                                += vmlinux.lds
 
 obj-y                          += process.o init_task.o time.o \
-                                  prom.o traps.o setup-common.o
+                                  prom.o traps.o setup-common.o udbg.o
 obj-$(CONFIG_PPC32)            += entry_32.o setup_32.o misc_32.o systbl.o
 obj-$(CONFIG_PPC64)            += misc_64.o dma_64.o iommu.o
 obj-$(CONFIG_PPC_OF)           += prom_init.o
@@ -56,8 +56,7 @@ obj-$(CONFIG_6xx)             += idle_6xx.o
 obj-$(CONFIG_SMP)              += smp.o
 obj-$(CONFIG_KPROBES)          += kprobes.o
 obj-$(CONFIG_PPC_MULTIPLATFORM) += legacy_serial.o
-obj64-$(CONFIG_PPC_MULTIPLATFORM) += udbg_16550.o
-obj64-$(CONFIG_PPC_PMAC)       += udbg_scc.o
+obj-$(CONFIG_PPC_MULTIPLATFORM) += udbg_16550.o
 module-$(CONFIG_PPC64)         += module_64.o
 obj-$(CONFIG_MODULES)          += $(module-y)
 
index bdfba92b2b3869972a253f40f49a47f087d46f0d..893dd24a9f6731f4b9007f542ad5481559483921 100644 (file)
@@ -31,15 +31,18 @@ static void draw_byte_32(unsigned char *bits, unsigned int *base, int rb);
 static void draw_byte_16(unsigned char *bits, unsigned int *base, int rb);
 static void draw_byte_8(unsigned char *bits, unsigned int *base, int rb);
 
-static int g_loc_X;
-static int g_loc_Y;
-static int g_max_loc_X;
-static int g_max_loc_Y;
+#define __force_data __attribute__((__section__(".data")))
 
-static int dispDeviceRowBytes;
-static int dispDeviceDepth;
-static int dispDeviceRect[4];
-static unsigned char *dispDeviceBase, *logicalDisplayBase;
+static int g_loc_X __force_data;
+static int g_loc_Y __force_data;
+static int g_max_loc_X __force_data;
+static int g_max_loc_Y __force_data;
+
+static int dispDeviceRowBytes __force_data;
+static int dispDeviceDepth  __force_data;
+static int dispDeviceRect[4] __force_data;
+static unsigned char *dispDeviceBase __force_data;
+static unsigned char *logicalDisplayBase __force_data;
 
 unsigned long disp_BAT[2] __initdata = {0, 0};
 
@@ -47,7 +50,7 @@ unsigned long disp_BAT[2] __initdata = {0, 0};
 
 static unsigned char vga_font[cmapsz];
 
-int boot_text_mapped;
+int boot_text_mapped __force_data = 0;
 int force_printk_to_btext = 0;
 
 #ifdef CONFIG_PPC32
@@ -66,8 +69,7 @@ int force_printk_to_btext = 0;
  * is really badly aligned, but I didn't encounter this case
  * yet.
  */
-void __init
-btext_prepare_BAT(void)
+void __init btext_prepare_BAT(void)
 {
        unsigned long vaddr = KERNELBASE + 0x10000000;
        unsigned long addr;
@@ -95,12 +97,13 @@ btext_prepare_BAT(void)
 }
 #endif
 
-/* This function will enable the early boot text when doing OF booting. This
- * way, xmon output should work too
+
+/* This function can be used to enable the early boot text when doing
+ * OF booting or within bootx init. It must be followed by a btext_unmap()
+ * call before the logical address becomes unuseable
  */
-void __init
-btext_setup_display(int width, int height, int depth, int pitch,
-                   unsigned long address)
+void __init btext_setup_display(int width, int height, int depth, int pitch,
+                               unsigned long address)
 {
        g_loc_X = 0;
        g_loc_Y = 0;
@@ -116,6 +119,11 @@ btext_setup_display(int width, int height, int depth, int pitch,
        boot_text_mapped = 1;
 }
 
+void __init btext_unmap(void)
+{
+       boot_text_mapped = 0;
+}
+
 /* Here's a small text engine to use during early boot
  * or for debugging purposes
  *
@@ -127,7 +135,7 @@ btext_setup_display(int width, int height, int depth, int pitch,
  *    changes.
  */
 
-void map_boot_text(void)
+static void map_boot_text(void)
 {
        unsigned long base, offset, size;
        unsigned char *vbase;
@@ -175,8 +183,9 @@ int btext_initialize(struct device_node *np)
        if (prop)
                address = *prop;
 
-       /* FIXME: Add support for PCI reg properties */
-
+       /* FIXME: Add support for PCI reg properties. Right now, only
+        * reliable on macs
+        */
        if (address == 0)
                return -EINVAL;
 
@@ -184,7 +193,6 @@ int btext_initialize(struct device_node *np)
        g_loc_Y = 0;
        g_max_loc_X = width / 8;
        g_max_loc_Y = height / 16;
-       logicalDisplayBase = (unsigned char *)address;
        dispDeviceBase = (unsigned char *)address;
        dispDeviceRowBytes = pitch;
        dispDeviceDepth = depth;
@@ -197,7 +205,7 @@ int btext_initialize(struct device_node *np)
        return 0;
 }
 
-void __init init_boot_display(void)
+int __init btext_find_display(int allow_nonstdout)
 {
        char *name;
        struct device_node *np = NULL; 
@@ -218,8 +226,8 @@ void __init init_boot_display(void)
        }
        if (np)
                rc = btext_initialize(np);
-       if (rc == 0)
-               return;
+       if (rc == 0 || !allow_nonstdout)
+               return rc;
 
        for (np = NULL; (np = of_find_node_by_type(np, "display"));) {
                if (get_property(np, "linux,opened", NULL)) {
@@ -228,8 +236,9 @@ void __init init_boot_display(void)
                        printk("result: %d\n", rc);
                }
                if (rc == 0)
-                       return;
+                       break;
        }
+       return rc;
 }
 
 /* Calc the base address of a given point (x,y) */
@@ -277,44 +286,83 @@ EXPORT_SYMBOL(btext_update_display);
 
 void btext_clearscreen(void)
 {
-       unsigned long *base     = (unsigned long *)calc_base(0, 0);
+       unsigned int *base      = (unsigned int *)calc_base(0, 0);
        unsigned long width     = ((dispDeviceRect[2] - dispDeviceRect[0]) *
-                                       (dispDeviceDepth >> 3)) >> 3;
+                                       (dispDeviceDepth >> 3)) >> 2;
        int i,j;
 
        for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1]); i++)
        {
-               unsigned long *ptr = base;
+               unsigned int *ptr = base;
                for(j=width; j; --j)
                        *(ptr++) = 0;
-               base += (dispDeviceRowBytes >> 3);
+               base += (dispDeviceRowBytes >> 2);
+       }
+}
+
+void btext_flushscreen(void)
+{
+       unsigned int *base      = (unsigned int *)calc_base(0, 0);
+       unsigned long width     = ((dispDeviceRect[2] - dispDeviceRect[0]) *
+                                       (dispDeviceDepth >> 3)) >> 2;
+       int i,j;
+
+       for (i=0; i < (dispDeviceRect[3] - dispDeviceRect[1]); i++)
+       {
+               unsigned int *ptr = base;
+               for(j = width; j > 0; j -= 8) {
+                       __asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
+                       ptr += 8;
+               }
+               base += (dispDeviceRowBytes >> 2);
        }
+       __asm__ __volatile__ ("sync" ::: "memory");
 }
 
+void btext_flushline(void)
+{
+       unsigned int *base      = (unsigned int *)calc_base(0, g_loc_Y << 4);
+       unsigned long width     = ((dispDeviceRect[2] - dispDeviceRect[0]) *
+                                       (dispDeviceDepth >> 3)) >> 2;
+       int i,j;
+
+       for (i=0; i < 16; i++)
+       {
+               unsigned int *ptr = base;
+               for(j = width; j > 0; j -= 8) {
+                       __asm__ __volatile__ ("dcbst 0,%0" :: "r" (ptr));
+                       ptr += 8;
+               }
+               base += (dispDeviceRowBytes >> 2);
+       }
+       __asm__ __volatile__ ("sync" ::: "memory");
+}
+
+
 #ifndef NO_SCROLL
 static void scrollscreen(void)
 {
-       unsigned long *src      = (unsigned long *)calc_base(0,16);
-       unsigned long *dst      = (unsigned long *)calc_base(0,0);
+       unsigned int *src       = (unsigned int *)calc_base(0,16);
+       unsigned int *dst       = (unsigned int *)calc_base(0,0);
        unsigned long width     = ((dispDeviceRect[2] - dispDeviceRect[0]) *
-                                  (dispDeviceDepth >> 3)) >> 3;
+                                  (dispDeviceDepth >> 3)) >> 2;
        int i,j;
 
        for (i=0; i<(dispDeviceRect[3] - dispDeviceRect[1] - 16); i++)
        {
-               unsigned long *src_ptr = src;
-               unsigned long *dst_ptr = dst;
+               unsigned int *src_ptr = src;
+               unsigned int *dst_ptr = dst;
                for(j=width; j; --j)
                        *(dst_ptr++) = *(src_ptr++);
-               src += (dispDeviceRowBytes >> 3);
-               dst += (dispDeviceRowBytes >> 3);
+               src += (dispDeviceRowBytes >> 2);
+               dst += (dispDeviceRowBytes >> 2);
        }
        for (i=0; i<16; i++)
        {
-               unsigned long *dst_ptr = dst;
+               unsigned int *dst_ptr = dst;
                for(j=width; j; --j)
                        *(dst_ptr++) = 0;
-               dst += (dispDeviceRowBytes >> 3);
+               dst += (dispDeviceRowBytes >> 2);
        }
 }
 #endif /* ndef NO_SCROLL */
@@ -377,6 +425,14 @@ void btext_drawstring(const char *c)
                btext_drawchar(*c++);
 }
 
+void btext_drawtext(const char *c, unsigned int len)
+{
+       if (!boot_text_mapped)
+               return;
+       while (len--)
+               btext_drawchar(*c++);
+}
+
 void btext_drawhex(unsigned long v)
 {
        char *hex_table = "0123456789abcdef";
index ccdf94731e300c8d5f3160f5dd74d6eb9a7d3471..fdd34dbd879788b52758384a2995ed84dd425f57 100644 (file)
@@ -153,6 +153,9 @@ __after_mmu_off:
        bl      flush_tlbs
 
        bl      initial_bats
+#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
+       bl      setup_disp_bat
+#endif
 
 /*
  * Call setup_cpu for CPU 0 and initialize 6xx Idle
@@ -1306,6 +1309,32 @@ initial_bats:
        blr
 
 
+#if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
+setup_disp_bat:
+       /*
+        * setup the display bat prepared for us in prom.c
+        */
+       mflr    r8
+       bl      reloc_offset
+       mtlr    r8
+       addis   r8,r3,disp_BAT@ha
+       addi    r8,r8,disp_BAT@l
+       cmpwi   cr0,r8,0
+       beqlr
+       lwz     r11,0(r8)
+       lwz     r8,4(r8)
+       mfspr   r9,SPRN_PVR
+       rlwinm  r9,r9,16,16,31          /* r9 = 1 for 601, 4 for 604 */
+       cmpwi   0,r9,1
+       beq     1f
+       mtspr   SPRN_DBAT3L,r8
+       mtspr   SPRN_DBAT3U,r11
+       blr
+1:     mtspr   SPRN_IBAT3L,r8
+       mtspr   SPRN_IBAT3U,r11
+       blr
+#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */
+
 #ifdef CONFIG_8260
 /* Jump into the system reset for the rom.
  * We first disable the MMU, and then jump to the ROM reset address.
index 02baacf043662c35a3931fad06894f57891318b9..79d434fc14d2bcc2ff6e8c949b66e8e8dd34249c 100644 (file)
@@ -40,6 +40,7 @@
 #include <asm/xmon.h>
 #include <asm/time.h>
 #include <asm/serial.h>
+#include <asm/udbg.h>
 
 #include "setup.h"
 
@@ -173,12 +174,23 @@ void __init platform_init(void)
  */
 void __init machine_init(unsigned long dt_ptr, unsigned long phys)
 {
+       /* If btext is enabled, we might have a BAT setup for early display,
+        * thus we do enable some very basic udbg output
+        */
+#ifdef CONFIG_BOOTX_TEXT
+       udbg_putc = btext_drawchar;
+#endif
+
+       /* Do some early initialization based on the flat device tree */
        early_init_devtree(__va(dt_ptr));
 
+       /* Check default command line */
 #ifdef CONFIG_CMDLINE
-       strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
+       if (cmd_line[0] == 0)
+               strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line));
 #endif /* CONFIG_CMDLINE */
 
+       /* Base init based on machine type */
        platform_init();
 
 #ifdef CONFIG_6xx
@@ -294,21 +306,11 @@ void __init setup_arch(char **cmdline_p)
 
        smp_setup_cpu_maps();
 
-#ifdef CONFIG_BOOTX_TEXT
-       init_boot_display();
-#endif
-
-#ifdef CONFIG_PPC_PMAC
-       /* This could be called "early setup arch", it must be done
-        * now because xmon need it
-        */
-       if (_machine == _MACH_Pmac)
-               pmac_feature_init();    /* New cool way */
-#endif
-
 #ifdef CONFIG_XMON_DEFAULT
        xmon_init(1);
 #endif
+       /* Register early console */
+       register_early_udbg_console();
 
 #if defined(CONFIG_KGDB)
        if (ppc_md.kgdb_map_scc)
index 0fc442ad1d26c99a946d6c0a0495bfae5e4af72e..65603e9af984e44a4ad96d3c35da16b7116d66a3 100644 (file)
@@ -474,10 +474,6 @@ void __init setup_system(void)
         */
        finish_device_tree();
 
-#ifdef CONFIG_BOOTX_TEXT
-       init_boot_display();
-#endif
-
        /*
         * Initialize xmon
         */
index 2e372477d22a959c84a6641c959e2886943b6339..cc2df5e61bb068c50c0a5b2d6d71daf962d8e248 100644 (file)
@@ -16,8 +16,8 @@
 #include <linux/console.h>
 #include <asm/processor.h>
 
-void (*udbg_putc)(unsigned char c);
-unsigned char (*udbg_getc)(void);
+void (*udbg_putc)(char c);
+char (*udbg_getc)(void);
 int (*udbg_getc_poll)(void);
 
 /* udbg library, used by xmon et al */
@@ -78,7 +78,7 @@ int udbg_read(char *buf, int buflen)
 #define UDBG_BUFSIZE 256
 void udbg_printf(const char *fmt, ...)
 {
-       unsigned char buf[UDBG_BUFSIZE];
+       char buf[UDBG_BUFSIZE];
        va_list args;
 
        va_start(args, fmt);
@@ -116,6 +116,8 @@ void __init disable_early_printk(void)
 /* called by setup_system */
 void register_early_udbg_console(void)
 {
+       if (early_console_initialized)
+               return;
        early_console_initialized = 1;
        register_console(&udbg_console);
 }
index 50fd376446c9d091f7dfcfd3278db490bef42c0b..28a58da5592c85416bb81fe00579b085d5d40c47 100644 (file)
@@ -47,7 +47,7 @@ struct NS16550 {
 
 static volatile struct NS16550 __iomem *udbg_comport;
 
-static void udbg_550_putc(unsigned char c)
+static void udbg_550_putc(char c)
 {
        if (udbg_comport) {
                while ((in_8(&udbg_comport->lsr) & LSR_THRE) == 0)
@@ -69,7 +69,7 @@ static int udbg_550_getc_poll(void)
        return -1;
 }
 
-static unsigned char udbg_550_getc(void)
+static char udbg_550_getc(void)
 {
        if (udbg_comport) {
                while ((in_8(&udbg_comport->lsr) & LSR_DR) == 0)
diff --git a/arch/powerpc/kernel/udbg_scc.c b/arch/powerpc/kernel/udbg_scc.c
deleted file mode 100644 (file)
index 820c535..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * udbg for for zilog scc ports as found on Apple PowerMacs
- *
- * Copyright (C) 2001-2005 PPC 64 Team, IBM Corp
- *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
- */
-#include <linux/config.h>
-#include <linux/types.h>
-#include <asm/udbg.h>
-#include <asm/processor.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/pmac_feature.h>
-
-extern u8 real_readb(volatile u8 __iomem  *addr);
-extern void real_writeb(u8 data, volatile u8 __iomem *addr);
-
-#define        SCC_TXRDY       4
-#define SCC_RXRDY      1
-
-static volatile u8 __iomem *sccc;
-static volatile u8 __iomem *sccd;
-
-static void udbg_scc_putc(unsigned char c)
-{
-       if (sccc) {
-               while ((in_8(sccc) & SCC_TXRDY) == 0)
-                       ;
-               out_8(sccd,  c);
-               if (c == '\n')
-                       udbg_scc_putc('\r');
-       }
-}
-
-static int udbg_scc_getc_poll(void)
-{
-       if (sccc) {
-               if ((in_8(sccc) & SCC_RXRDY) != 0)
-                       return in_8(sccd);
-               else
-                       return -1;
-       }
-       return -1;
-}
-
-static unsigned char udbg_scc_getc(void)
-{
-       if (sccc) {
-               while ((in_8(sccc) & SCC_RXRDY) == 0)
-                       ;
-               return in_8(sccd);
-       }
-       return 0;
-}
-
-static unsigned char scc_inittab[] = {
-    13, 0,             /* set baud rate divisor */
-    12, 0,
-    14, 1,             /* baud rate gen enable, src=rtxc */
-    11, 0x50,          /* clocks = br gen */
-    5,  0xea,          /* tx 8 bits, assert DTR & RTS */
-    4,  0x46,          /* x16 clock, 1 stop */
-    3,  0xc1,          /* rx enable, 8 bits */
-};
-
-void udbg_init_scc(struct device_node *np)
-{
-       u32 *reg;
-       unsigned long addr;
-       int i, x;
-
-       if (np == NULL)
-               np = of_find_node_by_name(NULL, "escc");
-       if (np == NULL || np->parent == NULL)
-               return;
-
-       udbg_printf("found SCC...\n");
-       /* Get address within mac-io ASIC */
-       reg = (u32 *)get_property(np, "reg", NULL);
-       if (reg == NULL)
-               return;
-       addr = reg[0];
-       udbg_printf("local addr: %lx\n", addr);
-       /* Get address of mac-io PCI itself */
-       reg = (u32 *)get_property(np->parent, "assigned-addresses", NULL);
-       if (reg == NULL)
-               return;
-       addr += reg[2];
-       udbg_printf("final addr: %lx\n", addr);
-
-       /* Setup for 57600 8N1 */
-       addr += 0x20;
-       sccc = (volatile u8 * __iomem) ioremap(addr & PAGE_MASK, PAGE_SIZE) ;
-       sccc += addr & ~PAGE_MASK;
-       sccd = sccc + 0x10;
-
-       udbg_printf("ioremap result sccc: %p\n", sccc);
-       mb();
-
-       for (i = 20000; i != 0; --i)
-               x = in_8(sccc);
-       out_8(sccc, 0x09);              /* reset A or B side */
-       out_8(sccc, 0xc0);
-       for (i = 0; i < sizeof(scc_inittab); ++i)
-               out_8(sccc, scc_inittab[i]);
-
-       udbg_putc = udbg_scc_putc;
-       udbg_getc = udbg_scc_getc;
-       udbg_getc_poll = udbg_scc_getc_poll;
-
-       udbg_puts("Hello World !\n");
-}
-
-static void udbg_real_scc_putc(unsigned char c)
-{
-       while ((real_readb(sccc) & SCC_TXRDY) == 0)
-               ;
-       real_writeb(c, sccd);
-       if (c == '\n')
-               udbg_real_scc_putc('\r');
-}
-
-void udbg_init_pmac_realmode(void)
-{
-       sccc = (volatile u8 __iomem *)0x80013020ul;
-       sccd = (volatile u8 __iomem *)0x80013030ul;
-
-       udbg_putc = udbg_real_scc_putc;
-       udbg_getc = NULL;
-       udbg_getc_poll = NULL;
-}
index 7d4b8b5f06063cdf41e1fe56c06fe207974d22a8..7d0d75c11848ec7ca0e1c8b0468e7958e47a1331 100644 (file)
@@ -188,6 +188,11 @@ void __init MMU_init(void)
 
        if (ppc_md.progress)
                ppc_md.progress("MMU:exit", 0x211);
+
+       /* From now on, btext is no longer BAT mapped if it was at all */
+#ifdef CONFIG_BOOTX_TEXT
+       btext_unmap();
+#endif
 }
 
 /* This is only called until mem_init is done. */
index c9df44fcf5710f0ea558b39df6cb945efd090011..3e5370eeb1b7537e6d6379fb91e8f4fa104c0536 100644 (file)
@@ -7,3 +7,4 @@ obj-$(CONFIG_NVRAM)             += nvram.o
 # ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff
 obj-$(CONFIG_PPC64)            += nvram.o
 obj-$(CONFIG_SMP)              += smp.o
+obj-$(CONFIG_PPC_MERGE)                += udbg_scc.o udbg_adb.o
index f6e22da2a5daa8dd27a2bcade5b12ff19599b60f..52a9d0c1b8b865ad2fffabb8f2184def71e827b3 100644 (file)
@@ -2607,6 +2607,8 @@ found:
  */
 static void __init probe_uninorth(void)
 {
+       u32 *addrp;
+       phys_addr_t address;
        unsigned long actrl;
 
        /* Locate core99 Uni-N */
@@ -2616,20 +2618,23 @@ static void __init probe_uninorth(void)
                uninorth_node = of_find_node_by_name(NULL, "u3");
                uninorth_u3 = 1;
        }
-       if (uninorth_node && uninorth_node->n_addrs > 0) {
-               unsigned long address = uninorth_node->addrs[0].address;
-               uninorth_base = ioremap(address, 0x40000);
-               uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
-               if (uninorth_u3)
-                       u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
-       } else
-               uninorth_node = NULL;
-
-       if (!uninorth_node)
+       if (uninorth_node == NULL)
                return;
 
-       printk(KERN_INFO "Found %s memory controller & host bridge, revision: %d\n",
-              uninorth_u3 ? "U3" : "UniNorth", uninorth_rev);
+       addrp = (u32 *)get_property(uninorth_node, "reg", NULL);
+       if (addrp == NULL)
+               return;
+       address = of_translate_address(uninorth_node, addrp);
+       if (address == 0)
+               return;
+       uninorth_base = ioremap(address, 0x40000);
+       uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
+       if (uninorth_u3)
+               u3_ht = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
+
+       printk(KERN_INFO "Found %s memory controller & host bridge,"
+              " revision: %d\n", uninorth_u3 ? "U3" : "UniNorth",
+              uninorth_rev);
        printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base);
 
        /* 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
 {
        struct device_node*     node;
        int                     i;
-       volatile u32 __iomem *  base;
-       u32*                    revp;
+       volatile u32 __iomem    *base;
+       u32                     *addrp, *revp;
+       phys_addr_t             addr;
+       u64                     size;
 
-       node = find_devices(name);
-       if (!node || !node->n_addrs)
-               return;
-       if (compat)
-               do {
-                       if (device_is_compatible(node, compat))
-                               break;
-                       node = node->next;
-               } while (node);
+       for (node = NULL; (node = of_find_node_by_name(node, name)) != NULL;) {
+               if (!compat)
+                       break;
+               if (device_is_compatible(node, compat))
+                       break;
+       }
        if (!node)
                return;
        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
                if (macio_chips[i].of_node == node)
                        return;
        }
+
        if (i >= MAX_MACIO_CHIPS) {
                printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n");
                printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);
                return;
        }
-       base = ioremap(node->addrs[0].address, node->addrs[0].size);
+       addrp = of_get_pci_address(node, 0, &size);
+       if (addrp == NULL) {
+               printk(KERN_ERR "pmac_feature: %s: can't find base !\n",
+                      node->full_name);
+               return;
+       }
+       addr = of_translate_address(node, addrp);
+       if (addr == 0) {
+               printk(KERN_ERR "pmac_feature: %s, can't translate base !\n",
+                      node->full_name);
+               return;
+       }
+       base = ioremap(addr, (unsigned long)size);
        if (!base) {
-               printk(KERN_ERR "pmac_feature: Can't map mac-io chip !\n");
+               printk(KERN_ERR "pmac_feature: %s, can't map mac-io chip !\n",
+                      node->full_name);
                return;
        }
        if (type == macio_keylargo) {
index f3f39e8e337a632eda28e2103fef2042ae7901db..606e0ed13731a5b8601770bd549fe3ed2056715a 100644 (file)
@@ -36,7 +36,7 @@
 
 #ifdef DEBUG
 #define DBG(x...) do {\
-               printk(KERN_DEBUG "KW:" x);     \
+               printk(KERN_DEBUG "low_i2c:" x);        \
        } while(0)
 #else
 #define DBG(x...)
@@ -342,7 +342,7 @@ static int keywest_low_i2c_func(struct low_i2c_host *host, u8 addr, u8 subaddr,
 static void keywest_low_i2c_add(struct device_node *np)
 {
        struct low_i2c_host     *host = find_low_i2c_host(NULL);
-       u32                     *psteps, *prate, steps, aoffset = 0;
+       u32                     *psteps, *prate, *addrp, steps;
        struct device_node      *parent;
 
        if (host == NULL) {
@@ -352,6 +352,16 @@ static void keywest_low_i2c_add(struct device_node *np)
        }
        memset(host, 0, sizeof(*host));
 
+       /* Apple is kind enough to provide a valid AAPL,address property
+        * on all i2c keywest nodes so far ... we would have to fallback
+        * to macio parsing if that wasn't the case
+        */
+       addrp = (u32 *)get_property(np, "AAPL,address", NULL);
+       if (addrp == NULL) {
+               printk(KERN_ERR "low_i2c: Can't find address for %s\n",
+                      np->full_name);
+               return;
+       }
        init_MUTEX(&host->mutex);
        host->np = of_node_get(np);     
        psteps = (u32 *)get_property(np, "AAPL,address-step", NULL);
@@ -360,12 +370,10 @@ static void keywest_low_i2c_add(struct device_node *np)
                steps >>= 1;
        parent = of_get_parent(np);
        host->num_channels = 1;
-       if (parent && parent->name[0] == 'u') {
+       if (parent && parent->name[0] == 'u')
                host->num_channels = 2;
-               aoffset = 3;
-       }
        /* Select interface rate */
-       host->speed = KW_I2C_MODE_100KHZ;
+       host->speed = KW_I2C_MODE_25KHZ;
        prate = (u32 *)get_property(np, "AAPL,i2c-rate", NULL);
        if (prate) switch(*prate) {
        case 100:
@@ -379,9 +387,12 @@ static void keywest_low_i2c_add(struct device_node *np)
                break;
        }       
 
+       printk(KERN_INFO "low_i2c: Bus %s found at 0x%08x, %d channels,"
+              " speed = %d KHz\n",
+              np->full_name, *addrp, host->num_channels, prate ? *prate : 25);
+
        host->mode = pmac_low_i2c_mode_std;
-       host->base = ioremap(np->addrs[0].address + aoffset,
-                                               np->addrs[0].size);
+       host->base = ioremap((*addrp), 0x1000);
        host->func = keywest_low_i2c_func;
 }
 
index 90040c49494d62ce94d900d7e2380a7be15979c3..ff78eeac10f2b79625b0ac824d36d6e646df7642 100644 (file)
@@ -459,7 +459,7 @@ void __init pmac_pic_init(void)
                        mpic_setup_cascade(irqctrler2->intrs[0].line,
                                           pmac_u3_cascade, mpic2);
                }
-#if defined(CONFIG_XMON) && defined(CONFIG_PPC32)
+#ifdef CONFIG_XMON
                {
                        struct device_node* pswitch;
                        int nmi_irq;
index 3b7a492d9b682bb3d3100c0d063af0b386f157a6..6ee620fe51956120f55af92b89242b0615775331 100644 (file)
@@ -77,6 +77,7 @@
 #include <asm/pmc.h>
 #include <asm/mpic.h>
 #include <asm/lmb.h>
+#include <asm/udbg.h>
 
 #include "pmac.h"
 
@@ -322,16 +323,6 @@ void __init pmac_setup_arch(void)
        l2cr_init();
 #endif /* CONFIG_PPC32 */
 
-#ifdef CONFIG_PPC64
-       /* Probe motherboard chipset */
-       /* this is done earlier in setup_arch for 32-bit */
-       pmac_feature_init();
-
-       /* We can NAP */
-       powersave_nap = 1;
-       printk(KERN_INFO "Using native/NAP idle loop\n");
-#endif
-
 #ifdef CONFIG_KGDB
        zs_kgdb_hook(0);
 #endif
@@ -622,13 +613,26 @@ static void __init pmac_init_early(void)
         * and call ioremap
         */
        hpte_init_native();
+#endif
 
-       /* Init SCC */
-       if (strstr(cmd_line, "sccdbg")) {
-               sccdbg = 1;
-               udbg_init_scc(NULL);
+       /* Enable early btext debug if requested */
+       if (strstr(cmd_line, "btextdbg")) {
+               udbg_adb_init_early();
+               register_early_udbg_console();
        }
 
+       /* Probe motherboard chipset */
+       pmac_feature_init();
+
+       /* We can NAP */
+       powersave_nap = 1;
+       printk(KERN_INFO "Using native/NAP idle loop\n");
+
+       /* Initialize debug stuff */
+       udbg_scc_init(!!strstr(cmd_line, "sccdbg"));
+       udbg_adb_init(!!strstr(cmd_line, "btextdbg"));
+
+#ifdef CONFIG_PPC64
        /* Setup interrupt mapping options */
        ppc64_interrupt_controller = IC_OPEN_PIC;
 
@@ -638,19 +642,8 @@ static void __init pmac_init_early(void)
 
 static void __init pmac_progress(char *s, unsigned short hex)
 {
-#ifdef CONFIG_PPC64
-       if (sccdbg) {
-               udbg_puts(s);
-               udbg_puts("\n");
-               return;
-       }
-#endif
-#ifdef CONFIG_BOOTX_TEXT
-       if (boot_text_mapped) {
-               btext_drawstring(s);
-               btext_drawchar('\n');
-       }
-#endif /* CONFIG_BOOTX_TEXT */
+       udbg_puts(s);
+       udbg_puts("\n");
 }
 
 /*
@@ -735,7 +728,8 @@ static int __init pmac_probe(int platform)
 }
 
 #ifdef CONFIG_PPC64
-static int pmac_probe_mode(struct pci_bus *bus)
+/* Move that to pci.c */
+static int pmac_pci_probe_mode(struct pci_bus *bus)
 {
        struct device_node *node = bus->sysdata;
 
@@ -771,7 +765,7 @@ struct machdep_calls __initdata pmac_md = {
        .check_legacy_ioport    = pmac_check_legacy_ioport,
        .progress               = pmac_progress,
 #ifdef CONFIG_PPC64
-       .pci_probe_mode         = pmac_probe_mode,
+       .pci_probe_mode         = pmac_pci_probe_mode,
        .idle_loop              = native_idle,
        .enable_pmcs            = power4_enable_pmcs,
 #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 (file)
index 0000000..e51de55
--- /dev/null
@@ -0,0 +1,218 @@
+#include <linux/config.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/bitops.h>
+#include <linux/ptrace.h>
+#include <linux/adb.h>
+#include <linux/pmu.h>
+#include <linux/cuda.h>
+#include <asm/machdep.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/xmon.h>
+#include <asm/prom.h>
+#include <asm/bootx.h>
+#include <asm/machdep.h>
+#include <asm/errno.h>
+#include <asm/pmac_feature.h>
+#include <asm/processor.h>
+#include <asm/delay.h>
+#include <asm/btext.h>
+#include <asm/time.h>
+#include <asm/udbg.h>
+
+/*
+ * This implementation is "special", it can "patch" the current
+ * udbg implementation and work on top of it. It must thus be
+ * initialized last
+ */
+
+static void (*udbg_adb_old_putc)(char c);
+static char (*udbg_adb_old_getc)(void);
+static int (*udbg_adb_old_getc_poll)(void);
+
+static enum {
+       input_adb_none,
+       input_adb_pmu,
+       input_adb_cuda,
+} input_type = input_adb_none;
+
+static int udbg_adb_use_btext;
+
+int xmon_wants_key, xmon_adb_keycode;
+
+static inline void udbg_adb_poll(void)
+{
+#ifdef CONFIG_ADB_PMU
+       if (input_type == input_adb_pmu)
+               pmu_poll_adb();
+#endif /* CONFIG_ADB_PMU */
+#ifdef CONFIG_ADB_CUDA
+       if (input_type == input_adb_cuda)
+               cuda_poll();
+#endif /* CONFIG_ADB_CUDA */
+}
+
+#ifdef CONFIG_BOOTX_TEXT
+static int xmon_adb_shiftstate;
+
+static unsigned char xmon_keytab[128] =
+       "asdfhgzxcv\000bqwer"                           /* 0x00 - 0x0f */
+       "yt123465=97-80]o"                              /* 0x10 - 0x1f */
+       "u[ip\rlj'k;\\,/nm."                            /* 0x20 - 0x2f */
+       "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0"            /* 0x30 - 0x3f */
+       "\0.\0*\0+\0\0\0\0\0/\r\0-\0"                   /* 0x40 - 0x4f */
+       "\0\0000123456789\0\0\0";                       /* 0x50 - 0x5f */
+
+static unsigned char xmon_shift_keytab[128] =
+       "ASDFHGZXCV\000BQWER"                           /* 0x00 - 0x0f */
+       "YT!@#$^%+(&_*)}O"                              /* 0x10 - 0x1f */
+       "U{IP\rLJ\"K:|<?NM>"                            /* 0x20 - 0x2f */
+       "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0"            /* 0x30 - 0x3f */
+       "\0.\0*\0+\0\0\0\0\0/\r\0-\0"                   /* 0x40 - 0x4f */
+       "\0\0000123456789\0\0\0";                       /* 0x50 - 0x5f */
+
+static char udbg_adb_local_getc(void)
+{
+       int k, t, on;
+
+       xmon_wants_key = 1;
+       for (;;) {
+               xmon_adb_keycode = -1;
+               t = 0;
+               on = 0;
+               k = -1;
+               do {
+                       if (--t < 0) {
+                               on = 1 - on;
+                               btext_drawchar(on? 0xdb: 0x20);
+                               btext_drawchar('\b');
+                               t = 200000;
+                       }
+                       udbg_adb_poll();
+                       if (udbg_adb_old_getc_poll)
+                               k = udbg_adb_old_getc_poll();
+               } while (k == -1 && xmon_adb_keycode == -1);
+               if (on)
+                       btext_drawstring(" \b");
+               if (k != -1)
+                       return k;
+               k = xmon_adb_keycode;
+
+               /* test for shift keys */
+               if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
+                       xmon_adb_shiftstate = (k & 0x80) == 0;
+                       continue;
+               }
+               if (k >= 0x80)
+                       continue;       /* ignore up transitions */
+               k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
+               if (k != 0)
+                       break;
+       }
+       xmon_wants_key = 0;
+       return k;
+}
+#endif /* CONFIG_BOOTX_TEXT */
+
+static char udbg_adb_getc(void)
+{
+#ifdef CONFIG_BOOTX_TEXT
+       if (udbg_adb_use_btext && input_type != input_adb_none)
+               return udbg_adb_local_getc();
+#endif
+       if (udbg_adb_old_getc)
+               return udbg_adb_old_getc();
+       return -1;
+}
+
+/* getc_poll() is not really used, unless you have the xmon-over modem
+ * hack that doesn't quite concern us here, thus we just poll the low level
+ * ADB driver to prevent it from timing out and call back the original poll
+ * routine.
+ */
+static int udbg_adb_getc_poll(void)
+{
+       udbg_adb_poll();
+
+       if (udbg_adb_old_getc_poll)
+               return udbg_adb_old_getc_poll();
+       return -1;
+}
+
+static void udbg_adb_putc(char c)
+{
+#ifdef CONFIG_BOOTX_TEXT
+       if (udbg_adb_use_btext)
+               btext_drawchar(c);
+#endif
+       if (udbg_adb_old_putc)
+               return udbg_adb_old_putc(c);
+}
+
+void udbg_adb_init_early(void)
+{
+#ifdef CONFIG_BOOTX_TEXT
+       if (btext_find_display(1) == 0) {
+               udbg_adb_use_btext = 1;
+               udbg_putc = udbg_adb_putc;
+       }
+#endif
+}
+
+int udbg_adb_init(int force_btext)
+{
+       struct device_node *np;
+
+       /* Capture existing callbacks */
+       udbg_adb_old_putc = udbg_putc;
+       udbg_adb_old_getc = udbg_getc;
+       udbg_adb_old_getc_poll = udbg_getc_poll;
+
+       /* Check if our early init was already called */
+       if (udbg_adb_old_putc == udbg_adb_putc ||
+           udbg_adb_old_putc == btext_drawchar)
+               udbg_adb_old_putc = NULL;
+
+       /* Set ours as output */
+       udbg_putc = udbg_adb_putc;
+       udbg_getc = udbg_adb_getc;
+       udbg_getc_poll = udbg_adb_getc_poll;
+
+#ifdef CONFIG_BOOTX_TEXT
+       /* Check if we should use btext output */
+       if (btext_find_display(force_btext) == 0)
+               udbg_adb_use_btext = 1;
+#endif
+
+       /* See if there is a keyboard in the device tree with a parent
+        * of type "adb". If not, we return a failure, but we keep the
+        * bext output set for now
+        */
+       for (np = NULL; (np = of_find_node_by_name(np, "keyboard")) != NULL;) {
+               struct device_node *parent = of_get_parent(np);
+               int found = (parent && !strcmp(parent->type, "adb") == 0);
+               of_node_put(parent);
+               if (found)
+                       break;
+       }
+       if (np == NULL)
+               return -ENODEV;
+       of_node_put(np);
+
+#ifdef CONFIG_ADB_PMU
+       if (find_via_pmu())
+               input_type = input_adb_pmu;
+#endif
+#ifdef CONFIG_ADB_CUDA
+       if (find_via_cuda())
+               input_type = input_adb_cuda;
+#endif
+
+       /* Same as above: nothing found, keep btext set for output */
+       if (input_type == input_adb_none)
+               return -ENODEV;
+
+       return 0;
+}
diff --git a/arch/powerpc/platforms/powermac/udbg_scc.c b/arch/powerpc/platforms/powermac/udbg_scc.c
new file mode 100644 (file)
index 0000000..df6dec4
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * udbg for for zilog scc ports as found on Apple PowerMacs
+ *
+ * Copyright (C) 2001-2005 PPC 64 Team, IBM Corp
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/udbg.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pmac_feature.h>
+
+extern u8 real_readb(volatile u8 __iomem  *addr);
+extern void real_writeb(u8 data, volatile u8 __iomem *addr);
+
+#define        SCC_TXRDY       4
+#define SCC_RXRDY      1
+
+static volatile u8 __iomem *sccc;
+static volatile u8 __iomem *sccd;
+
+static void udbg_scc_putc(char c)
+{
+       if (sccc) {
+               while ((in_8(sccc) & SCC_TXRDY) == 0)
+                       ;
+               out_8(sccd,  c);
+               if (c == '\n')
+                       udbg_scc_putc('\r');
+       }
+}
+
+static int udbg_scc_getc_poll(void)
+{
+       if (sccc) {
+               if ((in_8(sccc) & SCC_RXRDY) != 0)
+                       return in_8(sccd);
+               else
+                       return -1;
+       }
+       return -1;
+}
+
+static char udbg_scc_getc(void)
+{
+       if (sccc) {
+               while ((in_8(sccc) & SCC_RXRDY) == 0)
+                       ;
+               return in_8(sccd);
+       }
+       return 0;
+}
+
+static unsigned char scc_inittab[] = {
+    13, 0,             /* set baud rate divisor */
+    12, 0,
+    14, 1,             /* baud rate gen enable, src=rtxc */
+    11, 0x50,          /* clocks = br gen */
+    5,  0xea,          /* tx 8 bits, assert DTR & RTS */
+    4,  0x46,          /* x16 clock, 1 stop */
+    3,  0xc1,          /* rx enable, 8 bits */
+};
+
+void udbg_scc_init(int force_scc)
+{
+       u32 *reg;
+       unsigned long addr;
+       struct device_node *stdout = NULL, *escc = NULL, *macio = NULL;
+       struct device_node *ch, *ch_def = NULL, *ch_a = NULL;
+       char *path;
+       int i, x;
+
+       escc = of_find_node_by_name(NULL, "escc");
+       if (escc == NULL)
+               goto bail;
+       macio = of_get_parent(escc);
+       if (macio == NULL)
+               goto bail;
+       path = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
+       if (path != NULL)
+               stdout = of_find_node_by_path(path);
+       for (ch = NULL; (ch = of_get_next_child(escc, ch)) != NULL;) {
+               if (ch == stdout)
+                       ch_def = of_node_get(ch);
+               if (strcmp(ch->name, "ch-a") == 0)
+                       ch_a = of_node_get(ch);
+       }
+       if (ch_def == NULL && !force_scc)
+               goto bail;
+
+       ch = ch_def ? ch_def : ch_a;
+
+       /* Get address within mac-io ASIC */
+       reg = (u32 *)get_property(escc, "reg", NULL);
+       if (reg == NULL)
+               goto bail;
+       addr = reg[0];
+
+       /* Get address of mac-io PCI itself */
+       reg = (u32 *)get_property(macio, "assigned-addresses", NULL);
+       if (reg == NULL)
+               goto bail;
+       addr += reg[2];
+
+       /* Lock the serial port */
+       pmac_call_feature(PMAC_FTR_SCC_ENABLE, ch,
+                         PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
+
+
+       /* Setup for 57600 8N1 */
+       if (ch == ch_a)
+               addr += 0x20;
+       sccc = (volatile u8 * __iomem) ioremap(addr & PAGE_MASK, PAGE_SIZE) ;
+       sccc += addr & ~PAGE_MASK;
+       sccd = sccc + 0x10;
+
+       mb();
+
+       for (i = 20000; i != 0; --i)
+               x = in_8(sccc);
+       out_8(sccc, 0x09);              /* reset A or B side */
+       out_8(sccc, 0xc0);
+       for (i = 0; i < sizeof(scc_inittab); ++i)
+               out_8(sccc, scc_inittab[i]);
+
+       udbg_putc = udbg_scc_putc;
+       udbg_getc = udbg_scc_getc;
+       udbg_getc_poll = udbg_scc_getc_poll;
+
+       udbg_puts("Hello World !\n");
+
+ bail:
+       of_node_put(macio);
+       of_node_put(escc);
+       of_node_put(stdout);
+       of_node_put(ch_def);
+       of_node_put(ch_a);
+}
+
+#ifdef CONFIG_PPC64
+static void udbg_real_scc_putc(char c)
+{
+       while ((real_readb(sccc) & SCC_TXRDY) == 0)
+               ;
+       real_writeb(c, sccd);
+       if (c == '\n')
+               udbg_real_scc_putc('\r');
+}
+
+void udbg_init_pmac_realmode(void)
+{
+       sccc = (volatile u8 __iomem *)0x80013020ul;
+       sccd = (volatile u8 __iomem *)0x80013030ul;
+
+       udbg_putc = udbg_real_scc_putc;
+       udbg_getc = NULL;
+       udbg_getc_poll = NULL;
+}
+#endif /* CONFIG_PPC64 */
index cc0939d4cad17675bd8a4d9dcc9efff3131db3cf..615ffb9610595c6adb5495ae38f1c10944e33be0 100644 (file)
@@ -61,7 +61,7 @@ extern void pSeries_find_serial_port(void);
 int vtermno;   /* virtual terminal# for udbg  */
 
 #define __ALIGNED__ __attribute__((__aligned__(sizeof(long))))
-static void udbg_hvsi_putc(unsigned char c)
+static void udbg_hvsi_putc(char c)
 {
        /* packet's seqno isn't used anyways */
        uint8_t packet[] __ALIGNED__ = { 0xff, 5, 0, 0, c };
@@ -112,7 +112,7 @@ static int udbg_hvsi_getc_poll(void)
        return ch;
 }
 
-static unsigned char udbg_hvsi_getc(void)
+static char udbg_hvsi_getc(void)
 {
        int ch;
        for (;;) {
@@ -128,7 +128,7 @@ static unsigned char udbg_hvsi_getc(void)
        }
 }
 
-static void udbg_putcLP(unsigned char c)
+static void udbg_putcLP(char c)
 {
        char buf[16];
        unsigned long rc;
@@ -173,7 +173,7 @@ static int udbg_getc_pollLP(void)
        return ch;
 }
 
-static unsigned char udbg_getcLP(void)
+static char udbg_getcLP(void)
 {
        int ch;
        for (;;) {
index b20312e5ed271784bbeb79495ca122541d68707a..109d874ecfbeaa7980381aba99081a8d9d56481a 100644 (file)
@@ -3,9 +3,5 @@
 ifdef CONFIG_PPC64
 EXTRA_CFLAGS += -mno-minimal-toc
 endif
-
-obj-$(CONFIG_8xx)      += start_8xx.o
-obj-$(CONFIG_6xx)      += start_32.o
-obj-$(CONFIG_4xx)      += start_32.o
-obj-$(CONFIG_PPC64)    += start_64.o
-obj-y                  += xmon.o ppc-dis.o ppc-opc.o setjmp.o nonstdio.o
+obj-y                  += xmon.o ppc-dis.o ppc-opc.o setjmp.o start.o \
+                          nonstdio.o
diff --git a/arch/powerpc/xmon/start.c b/arch/powerpc/xmon/start.c
new file mode 100644 (file)
index 0000000..712552c
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+#include <asm/machdep.h>
+#include <asm/udbg.h>
+#include "nonstdio.h"
+
+void xmon_map_scc(void)
+{
+}
+
+int xmon_write(void *ptr, int nb)
+{
+       return udbg_write(ptr, nb);
+}
+
+int xmon_readchar(void)
+{
+       if (udbg_getc)
+               return udbg_getc();
+       return -1;
+}
+
+int xmon_read_poll(void)
+{
+       if (udbg_getc_poll)
+               return udbg_getc_poll();
+       return -1;
+}
diff --git a/arch/powerpc/xmon/start_32.c b/arch/powerpc/xmon/start_32.c
deleted file mode 100644 (file)
index c2464df..0000000
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Copyright (C) 1996 Paul Mackerras.
- */
-#include <linux/config.h>
-#include <linux/string.h>
-#include <asm/machdep.h>
-#include <asm/io.h>
-#include <asm/page.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/cuda.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/bitops.h>
-#include <asm/xmon.h>
-#include <asm/prom.h>
-#include <asm/bootx.h>
-#include <asm/machdep.h>
-#include <asm/errno.h>
-#include <asm/pmac_feature.h>
-#include <asm/processor.h>
-#include <asm/delay.h>
-#include <asm/btext.h>
-#include <asm/time.h>
-#include "nonstdio.h"
-
-static volatile unsigned char __iomem *sccc, *sccd;
-unsigned int TXRDY, RXRDY, DLAB;
-
-static int use_serial;
-static int use_screen;
-static int via_modem;
-static int xmon_use_sccb;
-static struct device_node *channel_node;
-
-void buf_access(void)
-{
-       if (DLAB)
-               sccd[3] &= ~DLAB;       /* reset DLAB */
-}
-
-extern int adb_init(void);
-
-#ifdef CONFIG_PPC_CHRP
-/*
- * This looks in the "ranges" property for the primary PCI host bridge
- * to find the physical address of the start of PCI/ISA I/O space.
- * It is basically a cut-down version of pci_process_bridge_OF_ranges.
- */
-static unsigned long chrp_find_phys_io_base(void)
-{
-       struct device_node *node;
-       unsigned int *ranges;
-       unsigned long base = CHRP_ISA_IO_BASE;
-       int rlen = 0;
-       int np;
-
-       node = find_devices("isa");
-       if (node != NULL) {
-               node = node->parent;
-               if (node == NULL || node->type == NULL
-                   || strcmp(node->type, "pci") != 0)
-                       node = NULL;
-       }
-       if (node == NULL)
-               node = find_devices("pci");
-       if (node == NULL)
-               return base;
-
-       ranges = (unsigned int *) get_property(node, "ranges", &rlen);
-       np = prom_n_addr_cells(node) + 5;
-       while ((rlen -= np * sizeof(unsigned int)) >= 0) {
-               if ((ranges[0] >> 24) == 1 && ranges[2] == 0) {
-                       /* I/O space starting at 0, grab the phys base */
-                       base = ranges[np - 3];
-                       break;
-               }
-               ranges += np;
-       }
-       return base;
-}
-#endif /* CONFIG_PPC_CHRP */
-
-void xmon_map_scc(void)
-{
-#ifdef CONFIG_PPC_MULTIPLATFORM
-       volatile unsigned char __iomem *base;
-
-       if (_machine == _MACH_Pmac) {
-               struct device_node *np;
-               unsigned long addr;
-#ifdef CONFIG_BOOTX_TEXT
-               if (!use_screen && !use_serial
-                   && !machine_is_compatible("iMac")) {
-                       /* see if there is a keyboard in the device tree
-                          with a parent of type "adb" */
-                       for (np = find_devices("keyboard"); np; np = np->next)
-                               if (np->parent && np->parent->type
-                                   && strcmp(np->parent->type, "adb") == 0)
-                                       break;
-
-                       /* needs to be hacked if xmon_printk is to be used
-                          from within find_via_pmu() */
-#ifdef CONFIG_ADB_PMU
-                       if (np != NULL && boot_text_mapped && find_via_pmu())
-                               use_screen = 1;
-#endif
-#ifdef CONFIG_ADB_CUDA
-                       if (np != NULL && boot_text_mapped && find_via_cuda())
-                               use_screen = 1;
-#endif
-               }
-               if (!use_screen && (np = find_devices("escc")) != NULL) {
-                       /*
-                        * look for the device node for the serial port
-                        * we're using and see if it says it has a modem
-                        */
-                       char *name = xmon_use_sccb? "ch-b": "ch-a";
-                       char *slots;
-                       int l;
-
-                       np = np->child;
-                       while (np != NULL && strcmp(np->name, name) != 0)
-                               np = np->sibling;
-                       if (np != NULL) {
-                               /* XXX should parse this properly */
-                               channel_node = np;
-                               slots = get_property(np, "slot-names", &l);
-                               if (slots != NULL && l >= 10
-                                   && strcmp(slots+4, "Modem") == 0)
-                                       via_modem = 1;
-                       }
-               }
-               btext_drawstring("xmon uses ");
-               if (use_screen)
-                       btext_drawstring("screen and keyboard\n");
-               else {
-                       if (via_modem)
-                               btext_drawstring("modem on ");
-                       btext_drawstring(xmon_use_sccb? "printer": "modem");
-                       btext_drawstring(" port\n");
-               }
-
-#endif /* CONFIG_BOOTX_TEXT */
-
-#ifdef CHRP_ESCC
-               addr = 0xc1013020;
-#else
-               addr = 0xf3013020;
-#endif
-               TXRDY = 4;
-               RXRDY = 1;
-       
-               np = find_devices("mac-io");
-               if (np && np->n_addrs)
-                       addr = np->addrs[0].address + 0x13020;
-               base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
-               sccc = base + (addr & ~PAGE_MASK);
-               sccd = sccc + 0x10;
-
-       } else {
-               base = (volatile unsigned char *) isa_io_base;
-
-#ifdef CONFIG_PPC_CHRP
-               if (_machine == _MACH_chrp)
-                       base = (volatile unsigned char __iomem *)
-                               ioremap(chrp_find_phys_io_base(), 0x1000);
-#endif
-
-               sccc = base + 0x3fd;
-               sccd = base + 0x3f8;
-               if (xmon_use_sccb) {
-                       sccc -= 0x100;
-                       sccd -= 0x100;
-               }
-               TXRDY = 0x20;
-               RXRDY = 1;
-               DLAB = 0x80;
-       }
-#elif defined(CONFIG_GEMINI)
-       /* should already be mapped by the kernel boot */
-       sccc = (volatile unsigned char __iomem *) 0xffeffb0d;
-       sccd = (volatile unsigned char __iomem *) 0xffeffb08;
-       TXRDY = 0x20;
-       RXRDY = 1;
-       DLAB = 0x80;
-#elif defined(CONFIG_405GP)
-       sccc = (volatile unsigned char __iomem *)0xef600305;
-       sccd = (volatile unsigned char __iomem *)0xef600300;
-       TXRDY = 0x20;
-       RXRDY = 1;
-       DLAB = 0x80;
-#endif /* platform */
-}
-
-static int scc_initialized = 0;
-
-void xmon_init_scc(void);
-extern void cuda_poll(void);
-
-static inline void do_poll_adb(void)
-{
-#ifdef CONFIG_ADB_PMU
-       if (sys_ctrler == SYS_CTRLER_PMU)
-               pmu_poll_adb();
-#endif /* CONFIG_ADB_PMU */
-#ifdef CONFIG_ADB_CUDA
-       if (sys_ctrler == SYS_CTRLER_CUDA)
-               cuda_poll();
-#endif /* CONFIG_ADB_CUDA */
-}
-
-int xmon_write(void *ptr, int nb)
-{
-       char *p = ptr;
-       int i, c, ct;
-
-#ifdef CONFIG_SMP
-       static unsigned long xmon_write_lock;
-       int lock_wait = 1000000;
-       int locked;
-
-       while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0)
-               if (--lock_wait == 0)
-                       break;
-#endif
-
-#ifdef CONFIG_BOOTX_TEXT
-       if (use_screen) {
-               /* write it on the screen */
-               for (i = 0; i < nb; ++i)
-                       btext_drawchar(*p++);
-               goto out;
-       }
-#endif
-       if (!scc_initialized)
-               xmon_init_scc();
-       ct = 0;
-       for (i = 0; i < nb; ++i) {
-               while ((*sccc & TXRDY) == 0)
-                       do_poll_adb();
-               c = p[i];
-               if (c == '\n' && !ct) {
-                       c = '\r';
-                       ct = 1;
-                       --i;
-               } else {
-                       ct = 0;
-               }
-               buf_access();
-               *sccd = c;
-               eieio();
-       }
-
- out:
-#ifdef CONFIG_SMP
-       if (!locked)
-               clear_bit(0, &xmon_write_lock);
-#endif
-       return nb;
-}
-
-int xmon_wants_key;
-int xmon_adb_keycode;
-
-#ifdef CONFIG_BOOTX_TEXT
-static int xmon_adb_shiftstate;
-
-static unsigned char xmon_keytab[128] =
-       "asdfhgzxcv\000bqwer"                           /* 0x00 - 0x0f */
-       "yt123465=97-80]o"                              /* 0x10 - 0x1f */
-       "u[ip\rlj'k;\\,/nm."                            /* 0x20 - 0x2f */
-       "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0"            /* 0x30 - 0x3f */
-       "\0.\0*\0+\0\0\0\0\0/\r\0-\0"                   /* 0x40 - 0x4f */
-       "\0\0000123456789\0\0\0";                       /* 0x50 - 0x5f */
-
-static unsigned char xmon_shift_keytab[128] =
-       "ASDFHGZXCV\000BQWER"                           /* 0x00 - 0x0f */
-       "YT!@#$^%+(&_*)}O"                              /* 0x10 - 0x1f */
-       "U{IP\rLJ\"K:|<?NM>"                            /* 0x20 - 0x2f */
-       "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0"            /* 0x30 - 0x3f */
-       "\0.\0*\0+\0\0\0\0\0/\r\0-\0"                   /* 0x40 - 0x4f */
-       "\0\0000123456789\0\0\0";                       /* 0x50 - 0x5f */
-
-static int xmon_get_adb_key(void)
-{
-       int k, t, on;
-
-       xmon_wants_key = 1;
-       for (;;) {
-               xmon_adb_keycode = -1;
-               t = 0;
-               on = 0;
-               do {
-                       if (--t < 0) {
-                               on = 1 - on;
-                               btext_drawchar(on? 0xdb: 0x20);
-                               btext_drawchar('\b');
-                               t = 200000;
-                       }
-                       do_poll_adb();
-               } while (xmon_adb_keycode == -1);
-               k = xmon_adb_keycode;
-               if (on)
-                       btext_drawstring(" \b");
-
-               /* test for shift keys */
-               if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
-                       xmon_adb_shiftstate = (k & 0x80) == 0;
-                       continue;
-               }
-               if (k >= 0x80)
-                       continue;       /* ignore up transitions */
-               k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
-               if (k != 0)
-                       break;
-       }
-       xmon_wants_key = 0;
-       return k;
-}
-#endif /* CONFIG_BOOTX_TEXT */
-
-int xmon_readchar(void)
-{
-#ifdef CONFIG_BOOTX_TEXT
-       if (use_screen)
-               return xmon_get_adb_key();
-#endif
-       if (!scc_initialized)
-               xmon_init_scc();
-       while ((*sccc & RXRDY) == 0)
-               do_poll_adb();
-       buf_access();
-       return *sccd;
-}
-
-int xmon_read_poll(void)
-{
-       if ((*sccc & RXRDY) == 0) {
-               do_poll_adb();
-               return -1;
-       }
-       buf_access();
-       return *sccd;
-}
-
-static unsigned char scc_inittab[] = {
-    13, 0,             /* set baud rate divisor */
-    12, 1,
-    14, 1,             /* baud rate gen enable, src=rtxc */
-    11, 0x50,          /* clocks = br gen */
-    5,  0xea,          /* tx 8 bits, assert DTR & RTS */
-    4,  0x46,          /* x16 clock, 1 stop */
-    3,  0xc1,          /* rx enable, 8 bits */
-};
-
-void xmon_init_scc(void)
-{
-       if ( _machine == _MACH_chrp )
-       {
-               sccd[3] = 0x83; eieio();        /* LCR = 8N1 + DLAB */
-               sccd[0] = 12; eieio();          /* DLL = 9600 baud */
-               sccd[1] = 0; eieio();
-               sccd[2] = 0; eieio();           /* FCR = 0 */
-               sccd[3] = 3; eieio();           /* LCR = 8N1 */
-               sccd[1] = 0; eieio();           /* IER = 0 */
-       }
-       else if ( _machine == _MACH_Pmac )
-       {
-               int i, x;
-               unsigned long timeout;
-
-               if (channel_node != 0)
-                       pmac_call_feature(
-                               PMAC_FTR_SCC_ENABLE,
-                               channel_node,
-                               PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
-                       printk(KERN_INFO "Serial port locked ON by debugger !\n");
-               if (via_modem && channel_node != 0) {
-                       unsigned int t0;
-
-                       pmac_call_feature(
-                               PMAC_FTR_MODEM_ENABLE,
-                               channel_node, 0, 1);
-                       printk(KERN_INFO "Modem powered up by debugger !\n");
-                       t0 = get_tbl();
-                       timeout = 3 * tb_ticks_per_sec;
-                       if (timeout == 0)
-                               /* assume 25MHz if tb_ticks_per_sec not set */
-                               timeout = 75000000;
-                       while (get_tbl() - t0 < timeout)
-                               eieio();
-               }
-               /* use the B channel if requested */
-               if (xmon_use_sccb) {
-                       sccc = (volatile unsigned char *)
-                               ((unsigned long)sccc & ~0x20);
-                       sccd = sccc + 0x10;
-               }
-               for (i = 20000; i != 0; --i) {
-                       x = *sccc; eieio();
-               }
-               *sccc = 9; eieio();             /* reset A or B side */
-               *sccc = ((unsigned long)sccc & 0x20)? 0x80: 0x40; eieio();
-               for (i = 0; i < sizeof(scc_inittab); ++i) {
-                       *sccc = scc_inittab[i];
-                       eieio();
-               }
-       }
-       scc_initialized = 1;
-       if (via_modem) {
-               for (;;) {
-                       xmon_write("ATE1V1\r", 7);
-                       if (xmon_expect("OK", 5)) {
-                               xmon_write("ATA\r", 4);
-                               if (xmon_expect("CONNECT", 40))
-                                       break;
-                       }
-                       xmon_write("+++", 3);
-                       xmon_expect("OK", 3);
-               }
-       }
-}
-
-void xmon_enter(void)
-{
-#ifdef CONFIG_ADB_PMU
-       if (_machine == _MACH_Pmac) {
-               pmu_suspend();
-       }
-#endif
-}
-
-void xmon_leave(void)
-{
-#ifdef CONFIG_ADB_PMU
-       if (_machine == _MACH_Pmac) {
-               pmu_resume();
-       }
-#endif
-}
diff --git a/arch/powerpc/xmon/start_64.c b/arch/powerpc/xmon/start_64.c
deleted file mode 100644 (file)
index 712552c..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 1996 Paul Mackerras.
- *
- *      This program is free software; you can redistribute it and/or
- *      modify it under the terms of the GNU General Public License
- *      as published by the Free Software Foundation; either version
- *      2 of the License, or (at your option) any later version.
- */
-#include <asm/machdep.h>
-#include <asm/udbg.h>
-#include "nonstdio.h"
-
-void xmon_map_scc(void)
-{
-}
-
-int xmon_write(void *ptr, int nb)
-{
-       return udbg_write(ptr, nb);
-}
-
-int xmon_readchar(void)
-{
-       if (udbg_getc)
-               return udbg_getc();
-       return -1;
-}
-
-int xmon_read_poll(void)
-{
-       if (udbg_getc_poll)
-               return udbg_getc_poll();
-       return -1;
-}
diff --git a/arch/powerpc/xmon/start_8xx.c b/arch/powerpc/xmon/start_8xx.c
deleted file mode 100644 (file)
index 4c17b04..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 1996 Paul Mackerras.
- * Copyright (C) 2000 Dan Malek.
- * Quick hack of Paul's code to make XMON work on 8xx processors.  Lots
- * of assumptions, like the SMC1 is used, it has been initialized by the
- * loader at some point, and we can just stuff and suck bytes.
- * We rely upon the 8xx uart driver to support us, as the interface
- * changes between boot up and operational phases of the kernel.
- */
-#include <linux/string.h>
-#include <asm/machdep.h>
-#include <asm/io.h>
-#include <asm/page.h>
-#include <linux/kernel.h>
-#include <asm/8xx_immap.h>
-#include <asm/mpc8xx.h>
-#include <asm/commproc.h>
-#include "nonstdio.h"
-
-extern int xmon_8xx_write(char *str, int nb);
-extern int xmon_8xx_read_poll(void);
-extern int xmon_8xx_read_char(void);
-
-void xmon_map_scc(void)
-{
-       cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm);
-}
-
-void xmon_init_scc(void);
-
-int xmon_write(void *ptr, int nb)
-{
-       return(xmon_8xx_write(ptr, nb));
-}
-
-int xmon_readchar(void)
-{
-       return xmon_8xx_read_char();
-}
-
-int xmon_read_poll(void)
-{
-       return(xmon_8xx_read_poll());
-}
index 0eb0b7085e6a86f9e9b18df12dac6f0ad03d89f0..e707c6f6e61bdd729d2309befc78fc082083f300 100644 (file)
@@ -744,6 +744,9 @@ void __init setup_arch(char **cmdline_p)
        /* so udelay does something sensible, assume <= 1000 bogomips */
        loops_per_jiffy = 500000000 / HZ;
 
+       if (ppc_md.init_early)
+               ppc_md.init_early();
+
 #ifdef CONFIG_PPC_MULTIPLATFORM
        /* This could be called "early setup arch", it must be done
         * now because xmon need it
index d61f748278fc47de6e2e9a889b443cc308cbcd35..93e7080e3bc5af343204c5970f8ca993acb2f24e 100644 (file)
@@ -505,16 +505,23 @@ static int
 create_iface(struct device_node *np, struct device *dev)
 {
        unsigned long steps;
-       unsigned bsteps, tsize, i, nchan, addroffset;
+       unsigned bsteps, tsize, i, nchan;
        struct keywest_iface* iface;
-       u32 *psteps, *prate;
+       u32 *psteps, *prate, *addrp;
        int rc;
 
-       if (np->n_intrs < 1 || np->n_addrs < 1) {
-               printk(KERN_ERR "%s: Missing interrupt or address !\n",
+       if (np->n_intrs < 1) {
+               printk(KERN_ERR "%s: Missing interrupt !\n",
                       np->full_name);
                return -ENODEV;
        }
+       addrp = (u32 *)get_property(np, "AAPL,address", NULL);
+       if (addrp == NULL) {
+               printk(KERN_ERR "%s: Can't find address !\n",
+                      np->full_name);
+               return -ENODEV;
+       }
+
        if (pmac_low_i2c_lock(np))
                return -ENODEV;
 
@@ -525,13 +532,10 @@ create_iface(struct device_node *np, struct device *dev)
        for (bsteps = 0; (steps & 0x01) == 0; bsteps++)
                steps >>= 1;
 
-       if (np->parent->name[0] == 'u') {
+       if (np->parent->name[0] == 'u')
                nchan = 2;
-               addroffset = 3;
-       } else {
-               addroffset = 0;
+       else
                nchan = 1;
-       }
 
        tsize = sizeof(struct keywest_iface) +
                (sizeof(struct keywest_chan) + 4) * nchan;
@@ -550,8 +554,7 @@ create_iface(struct device_node *np, struct device *dev)
        iface->irq = np->intrs[0].line;
        iface->channels = (struct keywest_chan *)
                (((unsigned long)(iface + 1) + 3UL) & ~3UL);
-       iface->base = ioremap(np->addrs[0].address + addroffset,
-                                               np->addrs[0].size);
+       iface->base = ioremap(*addrp, 0x1000);
        if (!iface->base) {
                printk(KERN_ERR "i2c-keywest: can't map inteface !\n");
                kfree(iface);
index d843a6c9c6df8d44ec7ec0c979835cb23591a37b..18ff770ea668e80098a624167c481e24e58f6d72 100644 (file)
@@ -127,39 +127,34 @@ struct adb_driver via_cuda_driver = {
 #endif /* CONFIG_ADB */
 
 #ifdef CONFIG_PPC
-int __init
-find_via_cuda(void)
+int __init find_via_cuda(void)
 {
-    int err;
     struct adb_request req;
+    phys_addr_t taddr;
+    u32 *reg;
+    int err;
 
     if (vias != 0)
        return 1;
-    vias = find_devices("via-cuda");
+    vias = of_find_node_by_name(NULL, "via-cuda");
     if (vias == 0)
        return 0;
-    if (vias->next != 0)
-       printk(KERN_WARNING "Warning: only using 1st via-cuda\n");
-
-#if 0
-    { int i;
-
-    printk("find_via_cuda: node = %p, addrs =", vias->node);
-    for (i = 0; i < vias->n_addrs; ++i)
-       printk(" %x(%x)", vias->addrs[i].address, vias->addrs[i].size);
-    printk(", intrs =");
-    for (i = 0; i < vias->n_intrs; ++i)
-       printk(" %x", vias->intrs[i].line);
-    printk("\n"); }
-#endif
 
-    if (vias->n_addrs != 1 || vias->n_intrs != 1) {
-       printk(KERN_ERR "via-cuda: expecting 1 address (%d) and 1 interrupt (%d)\n",
-              vias->n_addrs, vias->n_intrs);
-       if (vias->n_addrs < 1 || vias->n_intrs < 1)
-           return 0;
+    reg = (u32 *)get_property(vias, "reg", NULL);
+    if (reg == NULL) {
+           printk(KERN_ERR "via-cuda: No \"reg\" property !\n");
+           goto fail;
+    }
+    taddr = of_translate_address(vias, reg);
+    if (taddr == 0) {
+           printk(KERN_ERR "via-cuda: Can't translate address !\n");
+           goto fail;
+    }
+    via = ioremap(taddr, 0x2000);
+    if (via == NULL) {
+           printk(KERN_ERR "via-cuda: Can't map address !\n");
+           goto fail;
     }
-    via = ioremap(vias->addrs->address, 0x2000);
 
     cuda_state = idle;
     sys_ctrler = SYS_CTRLER_CUDA;
@@ -185,6 +180,11 @@ find_via_cuda(void)
        cuda_poll();
 
     return 1;
+
+ fail:
+    of_node_put(vias);
+    vias = NULL;
+    return 0;
 }
 #endif /* CONFIG_PPC */
 
index 5640435085694fdbefddf0e7c1a18bef2e221b75..13881f1996079c990f7568dc70a50b3ae8b0e418 100644 (file)
@@ -147,6 +147,7 @@ static struct device_node *vias;
 static int pmu_kind = PMU_UNKNOWN;
 static int pmu_fully_inited = 0;
 static int pmu_has_adb;
+static struct device_node *gpio_node;
 static unsigned char __iomem *gpio_reg = NULL;
 static int gpio_irq = -1;
 static int gpio_irq_enabled = -1;
@@ -295,22 +296,26 @@ static struct backlight_controller pmu_backlight_controller = {
 };
 #endif /* CONFIG_PMAC_BACKLIGHT */
 
-int
-find_via_pmu(void)
+int __init find_via_pmu(void)
 {
+       phys_addr_t taddr;
+       u32 *reg;
+
        if (via != 0)
                return 1;
-       vias = find_devices("via-pmu");
-       if (vias == 0)
+       vias = of_find_node_by_name(NULL, "via-pmu");
+       if (vias == NULL)
                return 0;
-       if (vias->next != 0)
-               printk(KERN_WARNING "Warning: only using 1st via-pmu\n");
 
-       if (vias->n_addrs < 1 || vias->n_intrs < 1) {
-               printk(KERN_ERR "via-pmu: %d addresses, %d interrupts!\n",
-                      vias->n_addrs, vias->n_intrs);
-               if (vias->n_addrs < 1 || vias->n_intrs < 1)
-                       return 0;
+       reg = (u32 *)get_property(vias, "reg", NULL);
+       if (reg == NULL) {
+               printk(KERN_ERR "via-pmu: No \"reg\" property !\n");
+               goto fail;
+       }
+       taddr = of_translate_address(vias, reg);
+       if (taddr == 0) {
+               printk(KERN_ERR "via-pmu: Can't translate address !\n");
+               goto fail;
        }
 
        spin_lock_init(&pmu_lock);
@@ -331,7 +336,8 @@ find_via_pmu(void)
                pmu_kind = PMU_HEATHROW_BASED;
        else if (device_is_compatible(vias->parent, "Keylargo")
                 || device_is_compatible(vias->parent, "K2-Keylargo")) {
-               struct device_node *gpio, *gpiop;
+               struct device_node *gpiop;
+               phys_addr_t gaddr = 0;
 
                pmu_kind = PMU_KEYLARGO_BASED;
                pmu_has_adb = (find_type_devices("adb") != NULL);
@@ -341,19 +347,24 @@ find_via_pmu(void)
                                PMU_INT_TICK |
                                PMU_INT_ENVIRONMENT;
                
-               gpiop = find_devices("gpio");
-               if (gpiop && gpiop->n_addrs) {
-                       gpio_reg = ioremap(gpiop->addrs->address, 0x10);
-                       gpio = find_devices("extint-gpio1");
-                       if (gpio == NULL)
-                               gpio = find_devices("pmu-interrupt");
-                       if (gpio && gpio->parent == gpiop && gpio->n_intrs)
-                               gpio_irq = gpio->intrs[0].line;
+               gpiop = of_find_node_by_name(NULL, "gpio");
+               if (gpiop) {
+                       reg = (u32 *)get_property(gpiop, "reg", NULL);
+                       if (reg)
+                               gaddr = of_translate_address(gpiop, reg);
+                       if (gaddr != 0)
+                               gpio_reg = ioremap(gaddr, 0x10);
                }
+               if (gpio_reg == NULL)
+                       printk(KERN_ERR "via-pmu: Can't find GPIO reg !\n");
        } else
                pmu_kind = PMU_UNKNOWN;
 
-       via = ioremap(vias->addrs->address, 0x2000);
+       via = ioremap(taddr, 0x2000);
+       if (via == NULL) {
+               printk(KERN_ERR "via-pmu: Can't map address !\n");
+               goto fail;
+       }
        
        out_8(&via[IER], IER_CLR | 0x7f);       /* disable all intrs */
        out_8(&via[IFR], 0x7f);                 /* clear IFR */
@@ -371,17 +382,19 @@ find_via_pmu(void)
        sys_ctrler = SYS_CTRLER_PMU;
        
        return 1;
+ fail:
+       of_node_put(vias);
+       vias = NULL;
+       return 0;
 }
 
 #ifdef CONFIG_ADB
-static int
-pmu_probe(void)
+static int pmu_probe(void)
 {
        return vias == NULL? -ENODEV: 0;
 }
 
-static int __init
-pmu_init(void)
+static int __init pmu_init(void)
 {
        if (vias == NULL)
                return -ENODEV;
@@ -405,7 +418,7 @@ static int __init via_pmu_start(void)
        bright_req_2.complete = 1;
        batt_req.complete = 1;
 
-#if defined(CONFIG_PPC32) && !defined(CONFIG_PPC_MERGE)
+#ifndef CONFIG_PPC_MERGE
        if (pmu_kind == PMU_KEYLARGO_BASED)
                openpic_set_irq_priority(vias->intrs[0].line,
                                         OPENPIC_PRIORITY_DEFAULT + 1);
@@ -418,10 +431,22 @@ static int __init via_pmu_start(void)
                return -EAGAIN;
        }
 
-       if (pmu_kind == PMU_KEYLARGO_BASED && gpio_irq != -1) {
-               if (request_irq(gpio_irq, gpio1_interrupt, 0, "GPIO1 ADB", (void *)0))
-                       printk(KERN_ERR "pmu: can't get irq %d (GPIO1)\n", gpio_irq);
-               gpio_irq_enabled = 1;
+       if (pmu_kind == PMU_KEYLARGO_BASED) {
+               gpio_node = of_find_node_by_name(NULL, "extint-gpio1");
+               if (gpio_node == NULL)
+                       gpio_node = of_find_node_by_name(NULL,
+                                                        "pmu-interrupt");
+               if (gpio_node && gpio_node->n_intrs > 0)
+                       gpio_irq = gpio_node->intrs[0].line;
+
+               if (gpio_irq != -1) {
+                       if (request_irq(gpio_irq, gpio1_interrupt, 0,
+                                       "GPIO1 ADB", (void *)0))
+                               printk(KERN_ERR "pmu: can't get irq %d"
+                                      " (GPIO1)\n", gpio_irq);
+                       else
+                               gpio_irq_enabled = 1;
+               }
        }
 
        /* Enable interrupts */
@@ -1371,7 +1396,6 @@ next:
                        }
                        pmu_done(req);
                } else {
-#if defined(CONFIG_XMON) && !defined(CONFIG_PPC64)
                        if (len == 4 && data[1] == 0x2c) {
                                extern int xmon_wants_key, xmon_adb_keycode;
                                if (xmon_wants_key) {
@@ -1379,7 +1403,6 @@ next:
                                        return;
                                }
                        }
-#endif /* defined(CONFIG_XMON) && !defined(CONFIG_PPC64) */
 #ifdef CONFIG_ADB
                        /*
                         * XXX On the [23]400 the PMU gives us an up
index 71cce36bc63099e837b4081547acaa5c8f76442f..906f46e3100642455fef5ae957b68e7db9be0275 100644 (file)
@@ -7,21 +7,22 @@
 #define __PPC_BTEXT_H
 #ifdef __KERNEL__
 
-extern void btext_clearscreen(void);
-extern void btext_flushscreen(void);
-
-extern int boot_text_mapped;
-
-extern int btext_initialize(struct device_node *np);
-
-extern void map_boot_text(void);
-extern void init_boot_display(void);
+extern int btext_find_display(int allow_nonstdout);
 extern void btext_update_display(unsigned long phys, int width, int height,
                                 int depth, int pitch);
+extern void btext_setup_display(int width, int height, int depth, int pitch,
+                               unsigned long address);
+extern void btext_prepare_BAT(void);
+extern void btext_unmap(void);
 
 extern void btext_drawchar(char c);
 extern void btext_drawstring(const char *str);
 extern void btext_drawhex(unsigned long v);
+extern void btext_drawtext(const char *c, unsigned int len);
+
+extern void btext_clearscreen(void);
+extern void btext_flushscreen(void);
+extern void btext_flushline(void);
 
 #endif /* __KERNEL__ */
 #endif /* __PPC_BTEXT_H */
index 4049a96dc43dde51ca0c7299a142067dd0d0d819..8d6b44c8f35d6e5ecf8653210b1ccc128da9078a 100644 (file)
@@ -13,8 +13,8 @@
 #include <linux/compiler.h>
 #include <linux/init.h>
 
-extern void (*udbg_putc)(unsigned char c);
-extern unsigned char (*udbg_getc)(void);
+extern void (*udbg_putc)(char c);
+extern char (*udbg_getc)(void);
 extern int (*udbg_getc_poll)(void);
 
 extern void udbg_puts(const char *s);
@@ -30,5 +30,8 @@ extern unsigned int udbg_probe_uart_speed(void __iomem *comport,
                                          unsigned int clock);
 
 struct device_node;
-extern void udbg_init_scc(struct device_node *np);
+extern void udbg_scc_init(int force_scc);
+extern int udbg_adb_init(int force_btext);
+extern void udbg_adb_init_early(void);
+
 #endif /* _ASM_POWERPC_UDBG_H */
index ccaefabe0bf5a5442eebbc41758a06a6935ea3ac..ed3630251b3b58a3230f31ec005c69db2d135015 100644 (file)
@@ -17,7 +17,7 @@ extern unsigned long disp_BAT[2];
 extern boot_infos_t disp_bi;
 extern int boot_text_mapped;
 
-extern void init_boot_display(void);
+extern void btext_init(boot_infos_t *bi);
 extern void btext_welcome(void);
 extern void btext_prepare_BAT(void);
 extern void btext_setup_display(int width, int height, int depth, int pitch,
index f01255bd1dc3739e8c71c5e4c88198ca6884d13a..39200def8d116fc0c8e1043a242007e80b65182a 100644 (file)
@@ -35,8 +35,10 @@ struct machdep_calls {
        int             (*get_irq)(struct pt_regs *);
        
        /* A general init function, called by ppc_init in init/main.c.
-          May be NULL. */
+          May be NULL. DEPRECATED ! */
        void            (*init)(void);
+       /* For compatibility with merged platforms */
+       void            (*init_early)(void);
 
        void            (*restart)(char *cmd);
        void            (*power_off)(void);