Merge branch 'master' into 83xx
authorKumar Gala <galak@kernel.crashing.org>
Thu, 8 Feb 2007 06:41:56 +0000 (00:41 -0600)
committerKumar Gala <galak@kernel.crashing.org>
Thu, 8 Feb 2007 06:41:56 +0000 (00:41 -0600)
27 files changed:
arch/powerpc/Kconfig
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/kprobes.c
arch/powerpc/kernel/lparcfg.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/traps.c
arch/powerpc/lib/Makefile
arch/powerpc/lib/rheap.c
arch/powerpc/mm/mem.c
arch/powerpc/platforms/52xx/Makefile
arch/powerpc/platforms/52xx/lite5200.c
arch/powerpc/platforms/52xx/mpc52xx_pci.c [new file with mode: 0644]
arch/powerpc/platforms/pseries/firmware.c
arch/powerpc/platforms/pseries/lpar.c
arch/powerpc/xmon/ppc-opc.c
arch/powerpc/xmon/spu-opc.c
arch/ppc/8xx_io/cs4218_tdm.c
arch/ppc/lib/rheap.c
arch/ppc/syslib/m8260_pci_erratum9.c
arch/ppc/syslib/m8xx_setup.c
arch/ppc/xmon/ppc-opc.c
drivers/char/watchdog/booke_wdt.c
drivers/macintosh/windfarm_core.c
include/asm-powerpc/firmware.h
include/asm-powerpc/kprobes.h
include/asm-powerpc/mpc52xx.h
include/asm-powerpc/sstep.h

index aeb5309..abc6bd2 100644 (file)
@@ -436,6 +436,21 @@ config PPC_MPC52xx
        bool
        default n
 
+config PPC_MPC5200
+       bool
+       select PPC_MPC52xx
+       default n
+
+config PPC_MPC5200_BUGFIX
+       bool "MPC5200 (L25R) bugfix support"
+       depends on PPC_MPC5200
+       default n
+       help
+         Enable workarounds for original MPC5200 errata.  This is not required
+         for MPC5200B based boards.
+
+         It is safe to say 'Y' here
+
 config PPC_EFIKA
        bool "bPlan Efika 5k2. MPC5200B based computer"
        depends on PPC_MULTIPLATFORM && PPC32
@@ -448,7 +463,7 @@ config PPC_EFIKA
 config PPC_LITE5200
        bool "Freescale Lite5200 Eval Board"
        depends on PPC_MULTIPLATFORM && PPC32
-       select PPC_MPC52xx
+       select PPC_MPC5200
        default n
 
 config PPC_PMAC
@@ -1206,7 +1221,7 @@ source "arch/powerpc/oprofile/Kconfig"
 
 config KPROBES
        bool "Kprobes (EXPERIMENTAL)"
-       depends on PPC64 && KALLSYMS && EXPERIMENTAL && MODULES
+       depends on !BOOKE && !4xx && KALLSYMS && EXPERIMENTAL && MODULES
        help
          Kprobes allows you to trap at almost any kernel address and
          execute a callback function.  register_kprobe() establishes
index 34dc37e..919fbf5 100644 (file)
@@ -281,10 +281,10 @@ void do_IRQ(struct pt_regs *regs)
 
        /*
         * Every platform is required to implement ppc_md.get_irq.
-        * This function will either return an irq number or -1 to
+        * This function will either return an irq number or NO_IRQ to
         * indicate there are no more pending.
-        * The value -2 is for buggy hardware and means that this IRQ
-        * has already been handled. -- Tom
+        * The value NO_IRQ_IGNORE is for buggy hardware and means that this
+        * IRQ has already been handled. -- Tom
         */
        irq = ppc_md.get_irq();
 
index 4657563..dd2886f 100644 (file)
@@ -46,8 +46,8 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
        if ((unsigned long)p->addr & 0x03) {
                printk("Attempt to register kprobe at an unaligned address\n");
                ret = -EINVAL;
-       } else if (IS_MTMSRD(insn) || IS_RFID(insn)) {
-               printk("Cannot register a kprobe on rfid or mtmsrd\n");
+       } else if (IS_MTMSRD(insn) || IS_RFID(insn) || IS_RFI(insn)) {
+               printk("Cannot register a kprobe on rfi/rfid or mtmsr[d]\n");
                ret = -EINVAL;
        }
 
@@ -483,8 +483,12 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
        memcpy(&kcb->jprobe_saved_regs, regs, sizeof(struct pt_regs));
 
        /* setup return addr to the jprobe handler routine */
+#ifdef CONFIG_PPC64
        regs->nip = (unsigned long)(((func_descr_t *)jp->entry)->entry);
        regs->gpr[2] = (unsigned long)(((func_descr_t *)jp->entry)->toc);
+#else
+       regs->nip = (unsigned long)jp->entry;
+#endif
 
        return 1;
 }
index 41c05dc..0de5a08 100644 (file)
@@ -439,6 +439,10 @@ static ssize_t lparcfg_write(struct file *file, const char __user * buf,
 
        ssize_t retval = -ENOMEM;
 
+       if (!firmware_has_feature(FW_FEATURE_SPLPAR) ||
+                       firmware_has_feature(FW_FEATURE_ISERIES))
+               return -EINVAL;
+
        kbuf = kmalloc(count, GFP_KERNEL);
        if (!kbuf)
                goto out;
@@ -517,7 +521,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
 static ssize_t lparcfg_write(struct file *file, const char __user * buf,
                             size_t count, loff_t * off)
 {
-       return count;
+       return -EINVAL;
 }
 
 #endif                         /* CONFIG_PPC_PSERIES */
@@ -570,6 +574,7 @@ static int lparcfg_open(struct inode *inode, struct file *file)
 struct file_operations lparcfg_fops = {
        .owner          = THIS_MODULE,
        .read           = seq_read,
+       .write          = lparcfg_write,
        .open           = lparcfg_open,
        .release        = single_release,
 };
@@ -581,10 +586,8 @@ int __init lparcfg_init(void)
 
        /* Allow writing if we have FW_FEATURE_SPLPAR */
        if (firmware_has_feature(FW_FEATURE_SPLPAR) &&
-                       !firmware_has_feature(FW_FEATURE_ISERIES)) {
-               lparcfg_fops.write = lparcfg_write;
+                       !firmware_has_feature(FW_FEATURE_ISERIES))
                mode |= S_IWUSR;
-       }
 
        ent = create_proc_entry("ppc64/lparcfg", mode, NULL);
        if (ent) {
index 61c65d1..6a19fa4 100644 (file)
@@ -65,6 +65,7 @@ int have_of = 1;
 
 #ifdef CONFIG_VGA_CONSOLE
 unsigned long vgacon_remap_base;
+EXPORT_SYMBOL(vgacon_remap_base);
 #endif
 
 /*
index 6915b91..dcc6f15 100644 (file)
@@ -535,34 +535,40 @@ static void emulate_single_step(struct pt_regs *regs)
        }
 }
 
-static void parse_fpe(struct pt_regs *regs)
+static inline int __parse_fpscr(unsigned long fpscr)
 {
-       int code = 0;
-       unsigned long fpscr;
-
-       flush_fp_to_thread(current);
-
-       fpscr = current->thread.fpscr.val;
+       int ret = 0;
 
        /* Invalid operation */
        if ((fpscr & FPSCR_VE) && (fpscr & FPSCR_VX))
-               code = FPE_FLTINV;
+               ret = FPE_FLTINV;
 
        /* Overflow */
        else if ((fpscr & FPSCR_OE) && (fpscr & FPSCR_OX))
-               code = FPE_FLTOVF;
+               ret = FPE_FLTOVF;
 
        /* Underflow */
        else if ((fpscr & FPSCR_UE) && (fpscr & FPSCR_UX))
-               code = FPE_FLTUND;
+               ret = FPE_FLTUND;
 
        /* Divide by zero */
        else if ((fpscr & FPSCR_ZE) && (fpscr & FPSCR_ZX))
-               code = FPE_FLTDIV;
+               ret = FPE_FLTDIV;
 
        /* Inexact result */
        else if ((fpscr & FPSCR_XE) && (fpscr & FPSCR_XX))
-               code = FPE_FLTRES;
+               ret = FPE_FLTRES;
+
+       return ret;
+}
+
+static void parse_fpe(struct pt_regs *regs)
+{
+       int code = 0;
+
+       flush_fp_to_thread(current);
+
+       code = __parse_fpscr(current->thread.fpscr.val);
 
        _exception(SIGFPE, regs, code, regs->nip);
 }
@@ -739,20 +745,7 @@ void __kprobes program_check_exception(struct pt_regs *regs)
        extern int do_mathemu(struct pt_regs *regs);
 
        /* We can now get here via a FP Unavailable exception if the core
-        * has no FPU, in that case no reason flags will be set */
-#ifdef CONFIG_MATH_EMULATION
-       /* (reason & REASON_ILLEGAL) would be the obvious thing here,
-        * but there seems to be a hardware bug on the 405GP (RevD)
-        * that means ESR is sometimes set incorrectly - either to
-        * ESR_DST (!?) or 0.  In the process of chasing this with the
-        * hardware people - not sure if it can happen on any illegal
-        * instruction or only on FP instructions, whether there is a
-        * pattern to occurences etc. -dgibson 31/Mar/2003 */
-       if (!(reason & REASON_TRAP) && do_mathemu(regs) == 0) {
-               emulate_single_step(regs);
-               return;
-       }
-#endif /* CONFIG_MATH_EMULATION */
+        * has no FPU, in that case the reason flags will be 0 */
 
        if (reason & REASON_FP) {
                /* IEEE FP exception */
@@ -778,6 +771,31 @@ void __kprobes program_check_exception(struct pt_regs *regs)
 
        local_irq_enable();
 
+#ifdef CONFIG_MATH_EMULATION
+       /* (reason & REASON_ILLEGAL) would be the obvious thing here,
+        * but there seems to be a hardware bug on the 405GP (RevD)
+        * that means ESR is sometimes set incorrectly - either to
+        * ESR_DST (!?) or 0.  In the process of chasing this with the
+        * hardware people - not sure if it can happen on any illegal
+        * instruction or only on FP instructions, whether there is a
+        * pattern to occurences etc. -dgibson 31/Mar/2003 */
+       switch (do_mathemu(regs)) {
+       case 0:
+               emulate_single_step(regs);
+               return;
+       case 1: {
+                       int code = 0;
+                       code = __parse_fpscr(current->thread.fpscr.val);
+                       _exception(SIGFPE, regs, code, regs->nip);
+                       return;
+               }
+       case -EFAULT:
+               _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
+               return;
+       }
+       /* fall through on any other errors */
+#endif /* CONFIG_MATH_EMULATION */
+
        /* Try to emulate it if we should. */
        if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) {
                switch (emulate_instruction(regs)) {
@@ -891,18 +909,39 @@ void SoftwareEmulation(struct pt_regs *regs)
 
 #ifdef CONFIG_MATH_EMULATION
        errcode = do_mathemu(regs);
+
+       switch (errcode) {
+       case 0:
+               emulate_single_step(regs);
+               return;
+       case 1: {
+                       int code = 0;
+                       code = __parse_fpscr(current->thread.fpscr.val);
+                       _exception(SIGFPE, regs, code, regs->nip);
+                       return;
+               }
+       case -EFAULT:
+               _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
+               return;
+       default:
+               _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+               return;
+       }
+
 #else
        errcode = Soft_emulate_8xx(regs);
-#endif
-       if (errcode) {
-               if (errcode > 0)
-                       _exception(SIGFPE, regs, 0, 0);
-               else if (errcode == -EFAULT)
-                       _exception(SIGSEGV, regs, 0, 0);
-               else
-                       _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
-       } else
+       switch (errcode) {
+       case 0:
                emulate_single_step(regs);
+               return;
+       case 1:
+               _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
+               return;
+       case -EFAULT:
+               _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
+               return;
+       }
+#endif
 }
 #endif /* CONFIG_8xx */
 
index e2d4141..4b1ba49 100644 (file)
@@ -16,11 +16,11 @@ obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \
                           strcase.o
 obj-$(CONFIG_QUICC_ENGINE) += rheap.o
 obj-$(CONFIG_XMON)     += sstep.o
+obj-$(CONFIG_KPROBES)  += sstep.o
 obj-$(CONFIG_NOT_COHERENT_CACHE)       += dma-noncoherent.o
 
 ifeq ($(CONFIG_PPC64),y)
 obj-$(CONFIG_SMP)      += locks.o
-obj-$(CONFIG_DEBUG_KERNEL) += sstep.o
 endif
 
 # Temporary hack until we have migrated to asm-powerpc
index 4bbda6b..6c5c5dd 100644 (file)
@@ -14,6 +14,7 @@
  */
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
 
@@ -671,7 +672,7 @@ void rh_dump(rh_info_t * info)
        int maxnr;
        int i, nr;
 
-       maxnr = sizeof(st) / sizeof(st[0]);
+       maxnr = ARRAY_SIZE(st);
 
        printk(KERN_INFO
               "info @0x%p (%d slots empty / %d max)\n",
index c85eda6..77b4637 100644 (file)
@@ -61,10 +61,6 @@ unsigned long memory_limit;
 extern void hash_preload(struct mm_struct *mm, unsigned long ea,
                         unsigned long access, unsigned long trap);
 
-/*
- * This is called by /dev/mem to know if a given address has to
- * be mapped non-cacheable or not
- */
 int page_is_ram(unsigned long pfn)
 {
        unsigned long paddr = (pfn << PAGE_SHIFT);
index a46184a..795b713 100644 (file)
@@ -3,6 +3,7 @@
 #
 ifeq ($(CONFIG_PPC_MERGE),y)
 obj-y                          += mpc52xx_pic.o mpc52xx_common.o
+obj-$(CONFIG_PCI)              += mpc52xx_pci.o
 endif
 
 obj-$(CONFIG_PPC_EFIKA)                += efika-setup.o efika-pci.o
index 0f21bab..cdb16bf 100644 (file)
@@ -107,6 +107,12 @@ static void __init lite52xx_setup_arch(void)
        mpc52xx_setup_cpu();    /* Generic */
        lite52xx_setup_cpu();   /* Platorm specific */
 
+#ifdef CONFIG_PCI
+       np = of_find_node_by_type(np, "pci");
+       if (np)
+               mpc52xx_add_bridge(np);
+#endif
+
 #ifdef CONFIG_BLK_DEV_INITRD
        if (initrd_start)
                ROOT_DEV = Root_RAM0;
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
new file mode 100644 (file)
index 0000000..faf161b
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * PCI code for the Freescale MPC52xx embedded CPU.
+ *
+ * Copyright (C) 2006 Secret Lab Technologies Ltd.
+ *                        Grant Likely <grant.likely@secretlab.ca>
+ * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#undef DEBUG
+
+#include <asm/pci.h>
+#include <asm/mpc52xx.h>
+#include <asm/delay.h>
+#include <asm/machdep.h>
+#include <linux/kernel.h>
+
+
+/* ======================================================================== */
+/* PCI windows config                                                       */
+/* ======================================================================== */
+
+#define MPC52xx_PCI_TARGET_IO  0xf0000000
+#define MPC52xx_PCI_TARGET_MEM 0x00000000
+
+
+/* ======================================================================== */
+/* Structures mapping & Defines for PCI Unit                                */
+/* ======================================================================== */
+
+#define MPC52xx_PCI_GSCR_BM            0x40000000
+#define MPC52xx_PCI_GSCR_PE            0x20000000
+#define MPC52xx_PCI_GSCR_SE            0x10000000
+#define MPC52xx_PCI_GSCR_XLB2PCI_MASK  0x07000000
+#define MPC52xx_PCI_GSCR_XLB2PCI_SHIFT 24
+#define MPC52xx_PCI_GSCR_IPG2PCI_MASK  0x00070000
+#define MPC52xx_PCI_GSCR_IPG2PCI_SHIFT 16
+#define MPC52xx_PCI_GSCR_BME           0x00004000
+#define MPC52xx_PCI_GSCR_PEE           0x00002000
+#define MPC52xx_PCI_GSCR_SEE           0x00001000
+#define MPC52xx_PCI_GSCR_PR            0x00000001
+
+
+#define MPC52xx_PCI_IWBTAR_TRANSLATION(proc_ad,pci_ad,size)      \
+               ( ( (proc_ad) & 0xff000000 )                    | \
+                 ( (((size) - 1) >> 8) & 0x00ff0000 )          | \
+                 ( ((pci_ad) >> 16) & 0x0000ff00 ) )
+
+#define MPC52xx_PCI_IWCR_PACK(win0,win1,win2)  (((win0) << 24) | \
+                                                ((win1) << 16) | \
+                                                ((win2) <<  8))
+
+#define MPC52xx_PCI_IWCR_DISABLE       0x0
+#define MPC52xx_PCI_IWCR_ENABLE                0x1
+#define MPC52xx_PCI_IWCR_READ          0x0
+#define MPC52xx_PCI_IWCR_READ_LINE     0x2
+#define MPC52xx_PCI_IWCR_READ_MULTI    0x4
+#define MPC52xx_PCI_IWCR_MEM           0x0
+#define MPC52xx_PCI_IWCR_IO            0x8
+
+#define MPC52xx_PCI_TCR_P              0x01000000
+#define MPC52xx_PCI_TCR_LD             0x00010000
+
+#define MPC52xx_PCI_TBATR_DISABLE      0x0
+#define MPC52xx_PCI_TBATR_ENABLE       0x1
+
+struct mpc52xx_pci {
+       u32     idr;            /* PCI + 0x00 */
+       u32     scr;            /* PCI + 0x04 */
+       u32     ccrir;          /* PCI + 0x08 */
+       u32     cr1;            /* PCI + 0x0C */
+       u32     bar0;           /* PCI + 0x10 */
+       u32     bar1;           /* PCI + 0x14 */
+       u8      reserved1[16];  /* PCI + 0x18 */
+       u32     ccpr;           /* PCI + 0x28 */
+       u32     sid;            /* PCI + 0x2C */
+       u32     erbar;          /* PCI + 0x30 */
+       u32     cpr;            /* PCI + 0x34 */
+       u8      reserved2[4];   /* PCI + 0x38 */
+       u32     cr2;            /* PCI + 0x3C */
+       u8      reserved3[32];  /* PCI + 0x40 */
+       u32     gscr;           /* PCI + 0x60 */
+       u32     tbatr0;         /* PCI + 0x64 */
+       u32     tbatr1;         /* PCI + 0x68 */
+       u32     tcr;            /* PCI + 0x6C */
+       u32     iw0btar;        /* PCI + 0x70 */
+       u32     iw1btar;        /* PCI + 0x74 */
+       u32     iw2btar;        /* PCI + 0x78 */
+       u8      reserved4[4];   /* PCI + 0x7C */
+       u32     iwcr;           /* PCI + 0x80 */
+       u32     icr;            /* PCI + 0x84 */
+       u32     isr;            /* PCI + 0x88 */
+       u32     arb;            /* PCI + 0x8C */
+       u8      reserved5[104]; /* PCI + 0x90 */
+       u32     car;            /* PCI + 0xF8 */
+       u8      reserved6[4];   /* PCI + 0xFC */
+};
+
+
+/* ======================================================================== */
+/* PCI configuration acess                                                  */
+/* ======================================================================== */
+
+static int
+mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
+                               int offset, int len, u32 *val)
+{
+       struct pci_controller *hose = bus->sysdata;
+       u32 value;
+
+       if (ppc_md.pci_exclude_device)
+               if (ppc_md.pci_exclude_device(bus->number, devfn))
+                       return PCIBIOS_DEVICE_NOT_FOUND;
+
+       out_be32(hose->cfg_addr,
+               (1 << 31) |
+               ((bus->number - hose->bus_offset) << 16) |
+               (devfn << 8) |
+               (offset & 0xfc));
+       mb();
+
+#if defined(CONFIG_PPC_MPC5200_BUGFIX)
+       if (bus->number != hose->bus_offset) {
+               /* workaround for the bug 435 of the MPC5200 (L25R);
+                * Don't do 32 bits config access during type-1 cycles */
+               switch (len) {
+                     case 1:
+                       value = in_8(((u8 __iomem *)hose->cfg_data) +
+                                    (offset & 3));
+                       break;
+                     case 2:
+                       value = in_le16(((u16 __iomem *)hose->cfg_data) +
+                                       ((offset>>1) & 1));
+                       break;
+
+                     default:
+                       value = in_le16((u16 __iomem *)hose->cfg_data) |
+                               (in_le16(((u16 __iomem *)hose->cfg_data) + 1) << 16);
+                       break;
+               }
+       }
+       else
+#endif
+       {
+               value = in_le32(hose->cfg_data);
+
+               if (len != 4) {
+                       value >>= ((offset & 0x3) << 3);
+                       value &= 0xffffffff >> (32 - (len << 3));
+               }
+       }
+
+       *val = value;
+
+       out_be32(hose->cfg_addr, 0);
+       mb();
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
+                               int offset, int len, u32 val)
+{
+       struct pci_controller *hose = bus->sysdata;
+       u32 value, mask;
+
+       if (ppc_md.pci_exclude_device)
+               if (ppc_md.pci_exclude_device(bus->number, devfn))
+                       return PCIBIOS_DEVICE_NOT_FOUND;
+
+       out_be32(hose->cfg_addr,
+               (1 << 31) |
+               ((bus->number - hose->bus_offset) << 16) |
+               (devfn << 8) |
+               (offset & 0xfc));
+       mb();
+
+#if defined(CONFIG_PPC_MPC5200_BUGFIX)
+       if (bus->number != hose->bus_offset) {
+               /* workaround for the bug 435 of the MPC5200 (L25R);
+                * Don't do 32 bits config access during type-1 cycles */
+               switch (len) {
+                     case 1:
+                       out_8(((u8 __iomem *)hose->cfg_data) +
+                               (offset & 3), val);
+                       break;
+                     case 2:
+                       out_le16(((u16 __iomem *)hose->cfg_data) +
+                               ((offset>>1) & 1), val);
+                       break;
+
+                     default:
+                       out_le16((u16 __iomem *)hose->cfg_data,
+                               (u16)val);
+                       out_le16(((u16 __iomem *)hose->cfg_data) + 1,
+                               (u16)(val>>16));
+                       break;
+               }
+       }
+       else
+#endif
+       {
+               if (len != 4) {
+                       value = in_le32(hose->cfg_data);
+
+                       offset = (offset & 0x3) << 3;
+                       mask = (0xffffffff >> (32 - (len << 3)));
+                       mask <<= offset;
+
+                       value &= ~mask;
+                       val = value | ((val << offset) & mask);
+               }
+
+               out_le32(hose->cfg_data, val);
+       }
+       mb();
+
+       out_be32(hose->cfg_addr, 0);
+       mb();
+
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops mpc52xx_pci_ops = {
+       .read  = mpc52xx_pci_read_config,
+       .write = mpc52xx_pci_write_config
+};
+
+
+/* ======================================================================== */
+/* PCI setup                                                                */
+/* ======================================================================== */
+
+static void __init
+mpc52xx_pci_setup(struct pci_controller *hose,
+                  struct mpc52xx_pci __iomem *pci_regs)
+{
+       struct resource *res;
+       u32 tmp;
+       int iwcr0 = 0, iwcr1 = 0, iwcr2 = 0;
+
+       pr_debug("mpc52xx_pci_setup(hose=%p, pci_regs=%p)\n", hose, pci_regs);
+
+       /* pci_process_bridge_OF_ranges() found all our addresses for us;
+        * now store them in the right places */
+       hose->cfg_addr = &pci_regs->car;
+       hose->cfg_data = hose->io_base_virt;
+
+       /* Control regs */
+       tmp = in_be32(&pci_regs->scr);
+       tmp |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+       out_be32(&pci_regs->scr, tmp);
+
+       /* Memory windows */
+       res = &hose->mem_resources[0];
+       if (res->flags) {
+               pr_debug("mem_resource[0] = {.start=%x, .end=%x, .flags=%lx}\n",
+                        res->start, res->end, res->flags);
+               out_be32(&pci_regs->iw0btar,
+                        MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
+                                 res->end - res->start + 1));
+               iwcr0 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_MEM;
+               if (res->flags & IORESOURCE_PREFETCH)
+                       iwcr0 |= MPC52xx_PCI_IWCR_READ_MULTI;
+               else
+                       iwcr0 |= MPC52xx_PCI_IWCR_READ;
+       }
+
+       res = &hose->mem_resources[1];
+       if (res->flags) {
+               pr_debug("mem_resource[1] = {.start=%x, .end=%x, .flags=%lx}\n",
+                        res->start, res->end, res->flags);
+               out_be32(&pci_regs->iw1btar,
+                        MPC52xx_PCI_IWBTAR_TRANSLATION(res->start, res->start,
+                                 res->end - res->start + 1));
+               iwcr1 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_MEM;
+               if (res->flags & IORESOURCE_PREFETCH)
+                       iwcr1 |= MPC52xx_PCI_IWCR_READ_MULTI;
+               else
+                       iwcr1 |= MPC52xx_PCI_IWCR_READ;
+       }
+
+       /* IO resources */
+       res = &hose->io_resource;
+       if (!res) {
+               printk(KERN_ERR "%s: Didn't find IO resources\n", __FILE__);
+               return;
+       }
+       pr_debug(".io_resource={.start=%x,.end=%x,.flags=%lx} "
+                ".io_base_phys=0x%p\n",
+                res->start, res->end, res->flags, (void*)hose->io_base_phys);
+       out_be32(&pci_regs->iw2btar,
+                MPC52xx_PCI_IWBTAR_TRANSLATION(hose->io_base_phys,
+                                               res->start,
+                                               res->end - res->start + 1));
+       iwcr2 = MPC52xx_PCI_IWCR_ENABLE | MPC52xx_PCI_IWCR_IO;
+
+       /* Set all the IWCR fields at once; they're in the same reg */
+       out_be32(&pci_regs->iwcr, MPC52xx_PCI_IWCR_PACK(iwcr0, iwcr1, iwcr2));
+
+       out_be32(&pci_regs->tbatr0,
+               MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_IO );
+       out_be32(&pci_regs->tbatr1,
+               MPC52xx_PCI_TBATR_ENABLE | MPC52xx_PCI_TARGET_MEM );
+
+       out_be32(&pci_regs->tcr, MPC52xx_PCI_TCR_LD);
+
+       tmp = in_be32(&pci_regs->gscr);
+#if 0
+       /* Reset the exteral bus ( internal PCI controller is NOT resetted ) */
+       /* Not necessary and can be a bad thing if for example the bootloader
+          is displaying a splash screen or ... Just left here for
+          documentation purpose if anyone need it */
+       out_be32(&pci_regs->gscr, tmp | MPC52xx_PCI_GSCR_PR);
+       udelay(50);
+#endif
+
+       /* Make sure the PCI bridge is out of reset */
+       out_be32(&pci_regs->gscr, tmp & ~MPC52xx_PCI_GSCR_PR);
+}
+
+static void
+mpc52xx_pci_fixup_resources(struct pci_dev *dev)
+{
+       int i;
+
+       pr_debug("mpc52xx_pci_fixup_resources() %.4x:%.4x\n",
+                dev->vendor, dev->device);
+
+       /* We don't rely on boot loader for PCI and resets all
+          devices */
+       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+               struct resource *res = &dev->resource[i];
+               if (res->end > res->start) {    /* Only valid resources */
+                       res->end -= res->start;
+                       res->start = 0;
+                       res->flags |= IORESOURCE_UNSET;
+               }
+       }
+
+       /* The PCI Host bridge of MPC52xx has a prefetch memory resource
+          fixed to 1Gb. Doesn't fit in the resource system so we remove it */
+       if ( (dev->vendor == PCI_VENDOR_ID_MOTOROLA) &&
+            (   dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200
+             || dev->device == PCI_DEVICE_ID_MOTOROLA_MPC5200B) ) {
+               struct resource *res = &dev->resource[1];
+               res->start = res->end = res->flags = 0;
+       }
+}
+
+int __init
+mpc52xx_add_bridge(struct device_node *node)
+{
+       int len;
+       struct mpc52xx_pci __iomem *pci_regs;
+       struct pci_controller *hose;
+       const int *bus_range;
+       struct resource rsrc;
+
+       pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name);
+
+       pci_assign_all_buses = 1;
+
+       if (of_address_to_resource(node, 0, &rsrc) != 0) {
+               printk(KERN_ERR "Can't get %s resources\n", node->full_name);
+               return -EINVAL;
+       }
+
+       bus_range = get_property(node, "bus-range", &len);
+       if (bus_range == NULL || len < 2 * sizeof(int)) {
+               printk(KERN_WARNING "Can't get %s bus-range, assume bus 0\n",
+                      node->full_name);
+               bus_range = NULL;
+       }
+
+       /* There are some PCI quirks on the 52xx, register the hook to
+        * fix them. */
+       ppc_md.pcibios_fixup_resources = mpc52xx_pci_fixup_resources;
+
+       /* Alloc and initialize the pci controller.  Values in the device
+        * tree are needed to configure the 52xx PCI controller.  Rather
+        * than parse the tree here, let pci_process_bridge_OF_ranges()
+        * do it for us and extract the values after the fact */
+       hose = pcibios_alloc_controller();
+       if (!hose)
+               return -ENOMEM;
+
+       hose->arch_data = node;
+       hose->set_cfg_type = 1;
+
+       hose->first_busno = bus_range ? bus_range[0] : 0;
+       hose->last_busno = bus_range ? bus_range[1] : 0xff;
+
+       hose->bus_offset = 0;
+       hose->ops = &mpc52xx_pci_ops;
+
+       pci_regs = ioremap(rsrc.start, rsrc.end - rsrc.start + 1);
+       if (!pci_regs)
+               return -ENOMEM;
+
+       pci_process_bridge_OF_ranges(hose, node, 1);
+
+       /* Finish setting up PCI using values obtained by
+        * pci_proces_bridge_OF_ranges */
+       mpc52xx_pci_setup(hose, pci_regs);
+
+       return 0;
+}
index 1c7b2ba..90522e3 100644 (file)
@@ -59,6 +59,7 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = {
        {FW_FEATURE_XDABR,              "hcall-xdabr"},
        {FW_FEATURE_MULTITCE,           "hcall-multi-tce"},
        {FW_FEATURE_SPLPAR,             "hcall-splpar"},
+       {FW_FEATURE_BULK_REMOVE,        "hcall-bulk"},
 };
 
 /* Build up the firmware features bitmask using the contents of
index 5a684fb..7496005 100644 (file)
@@ -516,7 +516,7 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
 static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
 {
        unsigned long i, pix, rc;
-       unsigned long flags;
+       unsigned long flags = 0;
        struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
        int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
        unsigned long param[9];
@@ -540,16 +540,22 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
                                hash = ~hash;
                        slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
                        slot += hidx & _PTEIDX_GROUP_IX;
-                       param[pix] = HBR_REQUEST | HBR_AVPN | slot;
-                       param[pix+1] = hpte_encode_v(va, psize) & HPTE_V_AVPN;
-                       pix += 2;
-                       if (pix == 8) {
-                               rc = plpar_hcall9(H_BULK_REMOVE, param,
+                       if (!firmware_has_feature(FW_FEATURE_BULK_REMOVE)) {
+                               pSeries_lpar_hpte_invalidate(slot, va, psize,
+                                                            local);
+                       } else {
+                               param[pix] = HBR_REQUEST | HBR_AVPN | slot;
+                               param[pix+1] = hpte_encode_v(va, psize) &
+                                       HPTE_V_AVPN;
+                               pix += 2;
+                               if (pix == 8) {
+                                       rc = plpar_hcall9(H_BULK_REMOVE, param,
                                                param[0], param[1], param[2],
                                                param[3], param[4], param[5],
                                                param[6], param[7]);
-                               BUG_ON(rc != H_SUCCESS);
-                               pix = 0;
+                                       BUG_ON(rc != H_SUCCESS);
+                                       pix = 0;
+                               }
                        }
                } pte_iterate_hashed_end();
        }
index 5d841f4..af3780e 100644 (file)
@@ -21,6 +21,7 @@
    02110-1301, USA.  */
 
 #include <linux/stddef.h>
+#include <linux/kernel.h>
 #include "nonstdio.h"
 #include "ppc.h"
 
@@ -4932,8 +4933,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 
 };
 
-const int powerpc_num_opcodes =
-  sizeof (powerpc_opcodes) / sizeof (powerpc_opcodes[0]);
+const int powerpc_num_opcodes = ARRAY_SIZE(powerpc_opcodes);
 \f
 /* The macro table.  This is only used by the assembler.  */
 
@@ -4989,5 +4989,4 @@ const struct powerpc_macro powerpc_macros[] = {
 { "clrlslwi.",4,  PPCCOM,      "rlwinm. %0,%1,%3,(%2)-(%3),31-(%3)" },
 };
 
-const int powerpc_num_macros =
-  sizeof (powerpc_macros) / sizeof (powerpc_macros[0]);
+const int powerpc_num_macros = ARRAY_SIZE(powerpc_macros);
index efffde9..530df3d 100644 (file)
@@ -18,6 +18,7 @@
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
 
+#include <linux/kernel.h>
 #include "spu.h"
 
 /* This file holds the Spu opcode table */
@@ -40,5 +41,4 @@ const struct spu_opcode spu_opcodes[] = {
 #undef APUOPFB
 };
 
-const int spu_num_opcodes =
-  sizeof (spu_opcodes) / sizeof (spu_opcodes[0]);
+const int spu_num_opcodes = ARRAY_SIZE(spu_opcodes);
index b7bb5f0..684ed04 100644 (file)
@@ -1379,7 +1379,6 @@ static void cs_nosound(unsigned long xx)
 }
 
 static DEFINE_TIMER(beep_timer, cs_nosound, 0, 0);
-};
 
 static void cs_mksound(unsigned int hz, unsigned int ticks)
 {
index 31e5118..d407007 100644 (file)
@@ -14,6 +14,7 @@
  */
 #include <linux/types.h>
 #include <linux/errno.h>
+#include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
 
@@ -654,7 +655,7 @@ void rh_dump(rh_info_t * info)
        int maxnr;
        int i, nr;
 
-       maxnr = sizeof(st) / sizeof(st[0]);
+       maxnr = ARRAY_SIZE(st);
 
        printk(KERN_INFO
               "info @0x%p (%d slots empty / %d max)\n",
index 5475709..ebb8c8f 100644 (file)
@@ -105,7 +105,8 @@ void idma_pci9_init(void)
        idma_reg[IDMA_CHAN].idmr = 0;           /* mask all IDMA interrupts */
        idma_reg[IDMA_CHAN].idsr = 0xff;        /* clear all event flags */
 
-       printk("<4>Using IDMA%d for MPC8260 device erratum PCI 9 workaround\n",
+       printk(KERN_WARNING
+               "Using IDMA%d for MPC8260 device erratum PCI 9 workaround\n",
                IDMA_CHAN + 1);
 
        return;
index d8d299b..01e48d8 100644 (file)
@@ -77,7 +77,7 @@ static struct mtd_partition mpc8xxads_partitions[] = {
        }
 };
 
-#define mpc8xxads_part_num (sizeof (mpc8xxads_partitions) / sizeof (mpc8xxads_partitions[0]))
+#define mpc8xxads_part_num ARRAY_SIZE(mpc8xxads_partitions)
 
 #endif
 
index 533a6c9..034313c 100644 (file)
@@ -19,6 +19,7 @@ along with this file; see the file COPYING.  If not, write to the Free
 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include <linux/posix_types.h>
+#include <linux/kernel.h>
 #include "ansidecl.h"
 #include "ppc.h"
 
@@ -2669,8 +2670,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
 
 };
 
-const int powerpc_num_opcodes =
-  sizeof (powerpc_opcodes) / sizeof (powerpc_opcodes[0]);
+const int powerpc_num_opcodes = ARRAY_SIZE(powerpc_opcodes);
 \f
 /* The macro table.  This is only used by the assembler.  */
 
@@ -2717,5 +2717,4 @@ const struct powerpc_macro powerpc_macros[] = {
 
 };
 
-const int powerpc_num_macros =
-  sizeof (powerpc_macros) / sizeof (powerpc_macros[0]);
+const int powerpc_num_macros = ARRAY_SIZE(powerpc_macros);
index 4889022..0e23f29 100644 (file)
@@ -35,7 +35,7 @@
 #ifdef CONFIG_FSL_BOOKE
 #define WDT_PERIOD_DEFAULT 63  /* Ex. wdt_period=28 bus=333Mhz , reset=~40sec */
 #else
-#define WDT_PERIOD_DEFAULT 4   /* Refer to the PPC40x and PPC4xx manuals */
+#define WDT_PERIOD_DEFAULT 3   /* Refer to the PPC40x and PPC4xx manuals */
 #endif                         /* for timing information */
 
 u32 booke_wdt_enabled = 0;
@@ -47,6 +47,14 @@ u32 booke_wdt_period = WDT_PERIOD_DEFAULT;
 #define WDTP(x)                (TCR_WP(x))
 #endif
 
+/*
+ * booke_wdt_ping:
+ */
+static __inline__ void booke_wdt_ping(void)
+{
+       mtspr(SPRN_TSR, TSR_ENW|TSR_WIS);
+}
+
 /*
  * booke_wdt_enable:
  */
@@ -54,20 +62,14 @@ static __inline__ void booke_wdt_enable(void)
 {
        u32 val;
 
+       /* clear status before enabling watchdog */
+       booke_wdt_ping();
        val = mfspr(SPRN_TCR);
        val |= (TCR_WIE|TCR_WRC(WRC_CHIP)|WDTP(booke_wdt_period));
 
        mtspr(SPRN_TCR, val);
 }
 
-/*
- * booke_wdt_ping:
- */
-static __inline__ void booke_wdt_ping(void)
-{
-       mtspr(SPRN_TSR, TSR_ENW|TSR_WIS);
-}
-
 /*
  * booke_wdt_write:
  */
index e947af9..94c117e 100644 (file)
@@ -94,8 +94,6 @@ static int wf_thread_func(void *data)
        DBG("wf: thread started\n");
 
        while(!kthread_should_stop()) {
-               try_to_freeze();
-
                if (time_after_eq(jiffies, next)) {
                        wf_notify(WF_EVENT_TICK, NULL);
                        if (wf_overtemp) {
@@ -118,8 +116,8 @@ static int wf_thread_func(void *data)
                if (delay <= HZ)
                        schedule_timeout_interruptible(delay);
 
-               /* there should be no signal, but oh well */
-               if (signal_pending(current)) {
+               /* there should be no non-suspend signal, but oh well */
+               if (signal_pending(current) && !try_to_freeze()) {
                        printk(KERN_WARNING "windfarm: thread got sigl !\n");
                        break;
                }
index abba808..3671c12 100644 (file)
@@ -44,6 +44,7 @@
 #define FW_FEATURE_LPAR                ASM_CONST(0x0000000000400000)
 #define FW_FEATURE_PS3_LV1     ASM_CONST(0x0000000000800000)
 #define FW_FEATURE_BEAT                ASM_CONST(0x0000000001000000)
+#define FW_FEATURE_BULK_REMOVE ASM_CONST(0x0000000002000000)
 
 #ifndef __ASSEMBLY__
 
index 2dafa37..3a5dd49 100644 (file)
@@ -44,6 +44,7 @@ typedef unsigned int kprobe_opcode_t;
 #define IS_TDI(instr)          (((instr) & 0xfc000000) == 0x08000000)
 #define IS_TWI(instr)          (((instr) & 0xfc000000) == 0x0c000000)
 
+#ifdef CONFIG_PPC64
 /*
  * 64bit powerpc uses function descriptors.
  * Handle cases where:
@@ -67,9 +68,13 @@ typedef unsigned int kprobe_opcode_t;
 }
 
 #define JPROBE_ENTRY(pentry)   (kprobe_opcode_t *)((func_descr_t *)pentry)
-
 #define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \
                        IS_TWI(instr) || IS_TDI(instr))
+#else
+/* Use stock kprobe_lookup_name since ppc32 doesn't use function descriptors */
+#define JPROBE_ENTRY(pentry)   (kprobe_opcode_t *)(pentry)
+#define is_trap(instr) (IS_TW(instr) || IS_TWI(instr))
+#endif
 
 #define ARCH_SUPPORTS_KRETPROBES
 #define  ARCH_INACTIVE_KPROBE_COUNT 1
index 4560d72..7afd5bf 100644 (file)
@@ -249,6 +249,8 @@ extern void mpc52xx_declare_of_platform_devices(void);
 extern void mpc52xx_init_irq(void);
 extern unsigned int mpc52xx_get_irq(void);
 
+extern int __init mpc52xx_add_bridge(struct device_node *node);
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __ASM_POWERPC_MPC52xx_H__ */
index 630a988..f593b0f 100644 (file)
@@ -21,6 +21,7 @@ struct pt_regs;
  */
 #define IS_MTMSRD(instr)       (((instr) & 0xfc0007be) == 0x7c000124)
 #define IS_RFID(instr)         (((instr) & 0xfc0007fe) == 0x4c000024)
+#define IS_RFI(instr)          (((instr) & 0xfc0007fe) == 0x4c000064)
 
 /* Emulate instructions that cause a transfer of control. */
 extern int emulate_step(struct pt_regs *regs, unsigned int instr);