Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 21 May 2010 18:17:05 +0000 (11:17 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 21 May 2010 18:17:05 +0000 (11:17 -0700)
* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (92 commits)
  powerpc: Remove unused 'protect4gb' boot parameter
  powerpc: Build-in e1000e for pseries & ppc64_defconfig
  powerpc/pseries: Make request_ras_irqs() available to other pseries code
  powerpc/numa: Use ibm,architecture-vec-5 to detect form 1 affinity
  powerpc/numa: Set a smaller value for RECLAIM_DISTANCE to enable zone reclaim
  powerpc: Use smt_snooze_delay=-1 to always busy loop
  powerpc: Remove check of ibm,smt-snooze-delay OF property
  powerpc/kdump: Fix race in kdump shutdown
  powerpc/kexec: Fix race in kexec shutdown
  powerpc/kexec: Speedup kexec hash PTE tear down
  powerpc/pseries: Add hcall to read 4 ptes at a time in real mode
  powerpc: Use more accurate limit for first segment memory allocations
  powerpc/kdump: Use chip->shutdown to disable IRQs
  powerpc/kdump: CPUs assume the context of the oopsing CPU
  powerpc/crashdump: Do not fail on NULL pointer dereferencing
  powerpc/eeh: Fix oops when probing in early boot
  powerpc/pci: Check devices status property when scanning OF tree
  powerpc/vio: Switch VIO Bus PM to use generic helpers
  powerpc: Avoid bad relocations in iSeries code
  powerpc: Use common cpu_die (fixes SMP+SUSPEND build)
  ...

118 files changed:
Documentation/powerpc/dts-bindings/4xx/reboot.txt [new file with mode: 0644]
Documentation/powerpc/dts-bindings/fsl/8xxx_gpio.txt
arch/powerpc/Kconfig
arch/powerpc/Kconfig.debug
arch/powerpc/boot/Makefile
arch/powerpc/boot/dts/iss4xx-mpic.dts [new file with mode: 0644]
arch/powerpc/boot/dts/iss4xx.dts [new file with mode: 0644]
arch/powerpc/boot/dts/mpc8315erdb.dts
arch/powerpc/boot/dts/mpc8377_rdb.dts
arch/powerpc/boot/dts/mpc8378_rdb.dts
arch/powerpc/boot/dts/mpc8379_rdb.dts
arch/powerpc/boot/dts/p1020rdb.dts
arch/powerpc/boot/treeboot-iss4xx.c [new file with mode: 0644]
arch/powerpc/boot/wrapper
arch/powerpc/configs/44x/iss476-smp_defconfig [new file with mode: 0644]
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/configs/pseries_defconfig
arch/powerpc/include/asm/cache.h
arch/powerpc/include/asm/cputable.h
arch/powerpc/include/asm/hvcall.h
arch/powerpc/include/asm/kexec.h
arch/powerpc/include/asm/mmu-44x.h
arch/powerpc/include/asm/mmu.h
arch/powerpc/include/asm/mmzone.h
arch/powerpc/include/asm/mpic.h
arch/powerpc/include/asm/paca.h
arch/powerpc/include/asm/parport.h
arch/powerpc/include/asm/pgalloc-64.h
arch/powerpc/include/asm/pgtable-ppc32.h
arch/powerpc/include/asm/ptrace.h
arch/powerpc/include/asm/reg.h
arch/powerpc/include/asm/reg_booke.h
arch/powerpc/include/asm/smp.h
arch/powerpc/include/asm/topology.h
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/crash.c
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/head_44x.S
arch/powerpc/kernel/head_8xx.S
arch/powerpc/kernel/head_booke.h
arch/powerpc/kernel/head_fsl_booke.S
arch/powerpc/kernel/iommu.c
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/kprobes.c
arch/powerpc/kernel/lparcfg.c
arch/powerpc/kernel/machine_kexec_64.c
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/misc_64.S
arch/powerpc/kernel/paca.c
arch/powerpc/kernel/pci_of_scan.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/ptrace.c
arch/powerpc/kernel/rtas.c
arch/powerpc/kernel/rtasd.c
arch/powerpc/kernel/setup-common.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/smp.c
arch/powerpc/kernel/sysfs.c
arch/powerpc/kernel/traps.c
arch/powerpc/kernel/vio.c
arch/powerpc/lib/string.S
arch/powerpc/mm/44x_mmu.c
arch/powerpc/mm/fault.c
arch/powerpc/mm/fsl_booke_mmu.c
arch/powerpc/mm/init_64.c
arch/powerpc/mm/mmu_context_nohash.c
arch/powerpc/mm/mmu_decl.h
arch/powerpc/mm/numa.c
arch/powerpc/mm/pgtable_32.c
arch/powerpc/mm/pgtable_64.c
arch/powerpc/mm/tlb_nohash_low.S
arch/powerpc/platforms/44x/Kconfig
arch/powerpc/platforms/44x/Makefile
arch/powerpc/platforms/44x/iss4xx.c [new file with mode: 0644]
arch/powerpc/platforms/83xx/mpc831x_rdb.c
arch/powerpc/platforms/83xx/mpc837x_rdb.c
arch/powerpc/platforms/86xx/mpc8610_hpcd.c
arch/powerpc/platforms/Kconfig.cputype
arch/powerpc/platforms/cell/cbe_cpufreq.c
arch/powerpc/platforms/iseries/exception.S
arch/powerpc/platforms/iseries/pci.c
arch/powerpc/platforms/iseries/smp.c
arch/powerpc/platforms/pasemi/cpufreq.c
arch/powerpc/platforms/powermac/cpufreq_64.c
arch/powerpc/platforms/powermac/low_i2c.c
arch/powerpc/platforms/powermac/pmac.h
arch/powerpc/platforms/powermac/setup.c
arch/powerpc/platforms/powermac/smp.c
arch/powerpc/platforms/pseries/Makefile
arch/powerpc/platforms/pseries/dlpar.c
arch/powerpc/platforms/pseries/eeh.c
arch/powerpc/platforms/pseries/event_sources.c [new file with mode: 0644]
arch/powerpc/platforms/pseries/hotplug-cpu.c
arch/powerpc/platforms/pseries/hvCall.S
arch/powerpc/platforms/pseries/lpar.c
arch/powerpc/platforms/pseries/plpar_wrappers.h
arch/powerpc/platforms/pseries/pseries.h
arch/powerpc/platforms/pseries/ras.c
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/platforms/pseries/smp.c
arch/powerpc/platforms/pseries/xics.c
arch/powerpc/sysdev/mpc8xxx_gpio.c
arch/powerpc/sysdev/mpic.c
arch/powerpc/sysdev/ppc4xx_soc.c
drivers/macintosh/macio-adb.c
drivers/macintosh/smu.c
drivers/macintosh/therm_adt746x.c
drivers/macintosh/windfarm_pm81.c
drivers/macintosh/windfarm_pm91.c
drivers/misc/Makefile
drivers/misc/hdpuftrs/Makefile [deleted file]
drivers/misc/hdpuftrs/hdpu_cpustate.c [deleted file]
drivers/misc/hdpuftrs/hdpu_nexus.c [deleted file]
drivers/serial/mpsc.c
include/linux/hdpu_features.h [deleted file]
sound/aoa/core/gpio-pmf.c

diff --git a/Documentation/powerpc/dts-bindings/4xx/reboot.txt b/Documentation/powerpc/dts-bindings/4xx/reboot.txt
new file mode 100644 (file)
index 0000000..d721726
--- /dev/null
@@ -0,0 +1,18 @@
+Reboot property to control system reboot on PPC4xx systems:
+
+By setting "reset_type" to one of the following values, the default
+software reset mechanism may be overidden. Here the possible values of
+"reset_type":
+
+      1 - PPC4xx core reset
+      2 - PPC4xx chip reset
+      3 - PPC4xx system reset (default)
+
+Example:
+
+               cpu@0 {
+                       device_type = "cpu";
+                       model = "PowerPC,440SPe";
+                       ...
+                       reset-type = <2>;       /* Use chip-reset */
+               };
index d015dce..b0019eb 100644 (file)
@@ -11,7 +11,7 @@ Required properties:
   83xx, "fsl,mpc8572-gpio" for 85xx and "fsl,mpc8610-gpio" for 86xx.
 - #gpio-cells : Should be two. The first cell is the pin number and the
   second cell is used to specify optional parameters (currently unused).
- - interrupts : Interrupt mapping for GPIO IRQ (currently unused).
+ - interrupts : Interrupt mapping for GPIO IRQ.
  - interrupt-parent : Phandle for the interrupt controller that
    services interrupts for this device.
 - gpio-controller : Marks the port as GPIO controller.
@@ -38,3 +38,23 @@ Example of gpio-controller nodes for a MPC8347 SoC:
 
 See booting-without-of.txt for details of how to specify GPIO
 information for devices.
+
+To use GPIO pins as interrupt sources for peripherals, specify the
+GPIO controller as the interrupt parent and define GPIO number +
+trigger mode using the interrupts property, which is defined like
+this:
+
+interrupts = <number trigger>, where:
+ - number: GPIO pin (0..31)
+ - trigger: trigger mode:
+       2 = trigger on falling edge
+       3 = trigger on both edges
+
+Example of device using this is:
+
+       funkyfpga@0 {
+               compatible = "funky-fpga";
+               ...
+               interrupts = <4 3>;
+               interrupt-parent = <&gpio1>;
+       };
index 2e19500..c4c4549 100644 (file)
@@ -140,6 +140,7 @@ config PPC
        select HAVE_SYSCALL_WRAPPERS if PPC64
        select GENERIC_ATOMIC64 if PPC32
        select HAVE_PERF_EVENTS
+       select HAVE_REGS_AND_STACK_ACCESS_API
 
 config EARLY_PRINTK
        bool
index 5cdd7ed..53696da 100644 (file)
@@ -44,6 +44,18 @@ config DEBUG_STACK_USAGE
 
          This option will slow down process creation somewhat.
 
+config DEBUG_PER_CPU_MAPS
+       bool "Debug access to per_cpu maps"
+       depends on DEBUG_KERNEL
+       depends on SMP
+       default n
+       ---help---
+         Say Y to verify that the per_cpu map being accessed has
+         been setup.  Adds a fair amount of code to kernel memory
+         and decreases performance.
+
+         Say N if unsure.
+
 config HCALL_STATS
        bool "Hypervisor call instrumentation"
        depends on PPC_PSERIES && DEBUG_FS && TRACEPOINTS
index bb2465b..ad0df7d 100644 (file)
@@ -44,6 +44,7 @@ $(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405
 $(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405
 $(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405
 $(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405
+$(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405
 $(obj)/virtex405-head.o: BOOTAFLAGS += -mcpu=405
 
 
@@ -77,7 +78,7 @@ src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c
                cuboot-warp.c cuboot-85xx-cpm2.c cuboot-yosemite.c simpleboot.c \
                virtex405-head.S virtex.c redboot-83xx.c cuboot-sam440ep.c \
                cuboot-acadia.c cuboot-amigaone.c cuboot-kilauea.c \
-               gamecube-head.S gamecube.c wii-head.S wii.c
+               gamecube-head.S gamecube.c wii-head.S wii.c treeboot-iss4xx.c
 src-boot := $(src-wlib) $(src-plat) empty.c
 
 src-boot := $(addprefix $(obj)/, $(src-boot))
@@ -169,7 +170,7 @@ quiet_cmd_wrap      = WRAP    $@
                $(if $3, -s $3)$(if $4, -d $4)$(if $5, -i $5) vmlinux
 
 image-$(CONFIG_PPC_PSERIES)            += zImage.pseries
-image-$(CONFIG_PPC_MAPLE)              += zImage.pseries
+image-$(CONFIG_PPC_MAPLE)              += zImage.maple
 image-$(CONFIG_PPC_IBM_CELL_BLADE)     += zImage.pseries
 image-$(CONFIG_PPC_PS3)                        += dtbImage.ps3
 image-$(CONFIG_PPC_CELLEB)             += zImage.pseries
@@ -206,6 +207,8 @@ image-$(CONFIG_TAISHAN)                     += cuImage.taishan
 image-$(CONFIG_KATMAI)                 += cuImage.katmai
 image-$(CONFIG_WARP)                   += cuImage.warp
 image-$(CONFIG_YOSEMITE)               += cuImage.yosemite
+image-$(CONFIG_ISS4xx)                 += treeImage.iss4xx \
+                                          treeImage.iss4xx-mpic
 
 # Board ports in arch/powerpc/platform/8xx/Kconfig
 image-$(CONFIG_MPC86XADS)              += cuImage.mpc866ads
@@ -351,7 +354,7 @@ install: $(CONFIGURE) $(addprefix $(obj)/, $(image-y))
 clean-files += $(image-) $(initrd-) cuImage.* dtbImage.* treeImage.* \
        zImage zImage.initrd zImage.chrp zImage.coff zImage.holly \
        zImage.iseries zImage.miboot zImage.pmac zImage.pseries \
-       simpleImage.* otheros.bld *.dtb
+       zImage.maple simpleImage.* otheros.bld *.dtb
 
 # clean up files cached by wrapper
 clean-kernel := vmlinux.strip vmlinux.bin
diff --git a/arch/powerpc/boot/dts/iss4xx-mpic.dts b/arch/powerpc/boot/dts/iss4xx-mpic.dts
new file mode 100644 (file)
index 0000000..23e9d9b
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Device Tree Source for IBM Embedded PPC 476 Platform
+ *
+ * Copyright 2010 Torez Smith, IBM Corporation.
+ *
+ * Based on earlier code:
+ *     Copyright (c) 2006, 2007 IBM Corp.
+ *     Josh Boyer <jwboyer@linux.vnet.ibm.com>, David Gibson <dwg@au1.ibm.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.
+ */
+
+/dts-v1/;
+
+/memreserve/ 0x01f00000 0x00100000;
+
+/ {
+       #address-cells = <2>;
+       #size-cells = <1>;
+       model = "ibm,iss-4xx";
+       compatible = "ibm,iss-4xx";
+       dcr-parent = <&{/cpus/cpu@0}>;
+
+       aliases {
+               serial0 = &UART0;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       model = "PowerPC,4xx"; // real CPU changed in sim
+                       reg = <0>;
+                       clock-frequency = <100000000>; // 100Mhz :-)
+                       timebase-frequency = <100000000>;
+                       i-cache-line-size = <32>;
+                       d-cache-line-size = <32>;
+                       i-cache-size = <32768>;
+                       d-cache-size = <32768>;
+                       dcr-controller;
+                       dcr-access-method = "native";
+                       status = "ok";
+               };
+               cpu@1 {
+                       device_type = "cpu";
+                       model = "PowerPC,4xx"; // real CPU changed in sim
+                       reg = <1>;
+                       clock-frequency = <100000000>; // 100Mhz :-)
+                       timebase-frequency = <100000000>;
+                       i-cache-line-size = <32>;
+                       d-cache-line-size = <32>;
+                       i-cache-size = <32768>;
+                       d-cache-size = <32768>;
+                       dcr-controller;
+                       dcr-access-method = "native";
+                       status = "disabled";
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0 0x01f00100>;
+               };
+               cpu@2 {
+                       device_type = "cpu";
+                       model = "PowerPC,4xx"; // real CPU changed in sim
+                       reg = <2>;
+                       clock-frequency = <100000000>; // 100Mhz :-)
+                       timebase-frequency = <100000000>;
+                       i-cache-line-size = <32>;
+                       d-cache-line-size = <32>;
+                       i-cache-size = <32768>;
+                       d-cache-size = <32768>;
+                       dcr-controller;
+                       dcr-access-method = "native";
+                       status = "disabled";
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0 0x01f00200>;
+               };
+               cpu@3 {
+                       device_type = "cpu";
+                       model = "PowerPC,4xx"; // real CPU changed in sim
+                       reg = <3>;
+                       clock-frequency = <100000000>; // 100Mhz :-)
+                       timebase-frequency = <100000000>;
+                       i-cache-line-size = <32>;
+                       d-cache-line-size = <32>;
+                       i-cache-size = <32768>;
+                       d-cache-size = <32768>;
+                       dcr-controller;
+                       dcr-access-method = "native";
+                       status = "disabled";
+                       enable-method = "spin-table";
+                       cpu-release-addr = <0 0x01f00300>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg =  <0x00000000 0x00000000 0x00000000>; // Filled in by zImage
+
+       };
+
+       MPIC: interrupt-controller {
+               compatible = "chrp,open-pic";
+               interrupt-controller;
+               dcr-reg = <0xffc00000 0x00030000>;
+               #address-cells = <0>;
+               #size-cells = <0>;
+               #interrupt-cells = <2>;
+
+       };
+
+       plb {
+               compatible = "ibm,plb-4xx", "ibm,plb4"; /* Could be PLB6, doesn't matter */
+               #address-cells = <2>;
+               #size-cells = <1>;
+               ranges;
+               clock-frequency = <0>; // Filled in by zImage
+
+               POB0: opb {
+                       compatible = "ibm,opb-4xx", "ibm,opb";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       /* Wish there was a nicer way of specifying a full 32-bit
+                          range */
+                       ranges = <0x00000000 0x00000001 0x00000000 0x80000000
+                                 0x80000000 0x00000001 0x80000000 0x80000000>;
+                       clock-frequency = <0>; // Filled in by zImage
+                       UART0: serial@40000200 {
+                               device_type = "serial";
+                               compatible = "ns16550a";
+                               reg = <0x40000200 0x00000008>;
+                               virtual-reg = <0xe0000200>;
+                               clock-frequency = <11059200>;
+                               current-speed = <115200>;
+                               interrupt-parent = <&MPIC>;
+                               interrupts = <0x0 0x2>;
+                       };
+               };
+       };
+
+       nvrtc {
+               compatible = "ds1743-nvram", "ds1743", "rtc-ds1743";
+               reg = <0 0xEF703000 0x2000>;
+       };
+       iss-block {
+               compatible = "ibm,iss-sim-block-device";
+               reg = <0 0xEF701000 0x1000>;
+       };
+
+       chosen {
+               linux,stdout-path = "/plb/opb/serial@40000200";
+       };
+};
diff --git a/arch/powerpc/boot/dts/iss4xx.dts b/arch/powerpc/boot/dts/iss4xx.dts
new file mode 100644 (file)
index 0000000..4ff6555
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Device Tree Source for IBM Embedded PPC 476 Platform
+ *
+ * Copyright 2010 Torez Smith, IBM Corporation.
+ *
+ * Based on earlier code:
+ *    Copyright (c) 2006, 2007 IBM Corp.
+ *    Josh Boyer <jwboyer@linux.vnet.ibm.com>, David Gibson <dwg@au1.ibm.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.
+ */
+
+/dts-v1/;
+
+/ {
+       #address-cells = <2>;
+       #size-cells = <1>;
+       model = "ibm,iss-4xx";
+       compatible = "ibm,iss-4xx";
+       dcr-parent = <&{/cpus/cpu@0}>;
+
+       aliases {
+               serial0 = &UART0;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu@0 {
+                       device_type = "cpu";
+                       model = "PowerPC,4xx"; // real CPU changed in sim
+                       reg = <0x00000000>;
+                       clock-frequency = <100000000>; // 100Mhz :-)
+                       timebase-frequency = <100000000>;
+                       i-cache-line-size = <32>; // may need fixup in sim
+                       d-cache-line-size = <32>; // may need fixup in sim
+                       i-cache-size = <32768>; /* may need fixup in sim */
+                       d-cache-size = <32768>; /* may need fixup in sim */
+                       dcr-controller;
+                       dcr-access-method = "native";
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x00000000 0x00000000>; // Filled in by zImage
+       };
+
+       UIC0: interrupt-controller0 {
+               compatible = "ibm,uic-4xx", "ibm,uic";
+               interrupt-controller;
+               cell-index = <0>;
+               dcr-reg = <0x0c0 0x009>;
+               #address-cells = <0>;
+               #size-cells = <0>;
+               #interrupt-cells = <2>;
+
+       };
+
+       UIC1: interrupt-controller1 {
+               compatible = "ibm,uic-4xx", "ibm,uic";
+               interrupt-controller;
+               cell-index = <1>;
+               dcr-reg = <0x0d0 0x009>;
+               #address-cells = <0>;
+               #size-cells = <0>;
+               #interrupt-cells = <2>;
+               interrupts = <0x1e 0x4 0x1f 0x4>; /* cascade */
+               interrupt-parent = <&UIC0>;
+       };
+
+       plb {
+               compatible = "ibm,plb-4xx", "ibm,plb4"; /* Could be PLB6, doesn't matter */
+               #address-cells = <2>;
+               #size-cells = <1>;
+               ranges;
+               clock-frequency = <0>; // Filled in by zImage
+
+               POB0: opb {
+                       compatible = "ibm,opb-4xx", "ibm,opb";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       /* Wish there was a nicer way of specifying a full 32-bit
+                          range */
+                       ranges = <0x00000000 0x00000001 0x00000000 0x80000000
+                                 0x80000000 0x00000001 0x80000000 0x80000000>;
+                       clock-frequency = <0>; // Filled in by zImage
+                       UART0: serial@40000200 {
+                               device_type = "serial";
+                               compatible = "ns16550a";
+                               reg = <0x40000200 0x00000008>;
+                               virtual-reg = <0xe0000200>;
+                               clock-frequency = <11059200>;
+                               current-speed = <115200>;
+                               interrupt-parent = <&UIC0>;
+                               interrupts = <0x0 0x4>;
+                       };
+               };
+       };
+
+       nvrtc {
+               compatible = "ds1743-nvram", "ds1743", "rtc-ds1743";
+               reg = <0 0xEF703000 0x2000>;
+       };
+       iss-block {
+               compatible = "ibm,iss-sim-block-device";
+               reg = <0 0xEF701000 0x1000>;
+       };
+
+       chosen {
+               linux,stdout-path = "/plb/opb/serial@40000200";
+       };
+};
index 8a3a4f3..4dd08c3 100644 (file)
                        fsl,num-channels = <4>;
                        fsl,channel-fifo-len = <24>;
                        fsl,exec-units-mask = <0x97c>;
-                       fsl,descriptor-types-mask = <0x3ab0abf>;
+                       fsl,descriptor-types-mask = <0x3a30abf>;
                };
 
                sata@18000 {
                                  0 0x00800000>;
                };
        };
+
+       leds {
+               compatible = "gpio-leds";
+
+               pwr {
+                       gpios = <&mcu_pio 0 0>;
+                       default-state = "on";
+               };
+
+               hdd {
+                       gpios = <&mcu_pio 1 0>;
+                       linux,default-trigger = "ide-disk";
+               };
+       };
 };
index 9e2264b..dbc1b98 100644 (file)
                                  0 0x00800000>;
                };
        };
+
+       leds {
+               compatible = "gpio-leds";
+
+               pwr {
+                       gpios = <&mcu_pio 0 0>;
+                       default-state = "on";
+               };
+
+               hdd {
+                       gpios = <&mcu_pio 1 0>;
+                       linux,default-trigger = "ide-disk";
+               };
+       };
 };
index 4e6a1a4..3447eb9 100644 (file)
                                  0 0x00800000>;
                };
        };
+
+       leds {
+               compatible = "gpio-leds";
+
+               pwr {
+                       gpios = <&mcu_pio 0 0>;
+                       default-state = "on";
+               };
+
+               hdd {
+                       gpios = <&mcu_pio 1 0>;
+                       linux,default-trigger = "ide-disk";
+               };
+       };
 };
index 72336d5..15560c6 100644 (file)
                compatible = "fsl,mpc8349-pci";
                device_type = "pci";
        };
+
+       leds {
+               compatible = "gpio-leds";
+
+               pwr {
+                       gpios = <&mcu_pio 0 0>;
+                       default-state = "on";
+               };
+
+               hdd {
+                       gpios = <&mcu_pio 1 0>;
+                       linux,default-trigger = "ide-disk";
+               };
+       };
 };
index df52690..22f64b6 100644 (file)
@@ -19,6 +19,9 @@
        aliases {
                serial0 = &serial0;
                serial1 = &serial1;
+               ethernet0 = &enet0;
+               ethernet1 = &enet1;
+               ethernet2 = &enet2;
                pci0 = &pci0;
                pci1 = &pci1;
        };
                        };
                };
 
+               mdio@24000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,etsec2-mdio";
+                       reg = <0x24000 0x1000 0xb0030 0x4>;
+
+                       phy0: ethernet-phy@0 {
+                               interrupt-parent = <&mpic>;
+                               interrupts = <3 1>;
+                               reg = <0x0>;
+                       };
+
+                       phy1: ethernet-phy@1 {
+                               interrupt-parent = <&mpic>;
+                               interrupts = <2 1>;
+                               reg = <0x1>;
+                       };
+               };
+
+               mdio@25000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,etsec2-tbi";
+                       reg = <0x25000 0x1000 0xb1030 0x4>;
+
+                       tbi0: tbi-phy@11 {
+                               reg = <0x11>;
+                               device_type = "tbi-phy";
+                       };
+               };
+
+               enet0: ethernet@b0000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "fsl,etsec2";
+                       fsl,num_rx_queues = <0x8>;
+                       fsl,num_tx_queues = <0x8>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupt-parent = <&mpic>;
+                       fixed-link = <1 1 1000 0 0>;
+                       phy-connection-type = "rgmii-id";
+
+                       queue-group@0 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0xb0000 0x1000>;
+                               interrupts = <29 2 30 2 34 2>;
+                       };
+
+                       queue-group@1 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0xb4000 0x1000>;
+                               interrupts = <17 2 18 2 24 2>;
+                       };
+               };
+
+               enet1: ethernet@b1000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "fsl,etsec2";
+                       fsl,num_rx_queues = <0x8>;
+                       fsl,num_tx_queues = <0x8>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupt-parent = <&mpic>;
+                       phy-handle = <&phy0>;
+                       tbi-handle = <&tbi0>;
+                       phy-connection-type = "sgmii";
+
+                       queue-group@0 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0xb1000 0x1000>;
+                               interrupts = <35 2 36 2 40 2>;
+                       };
+
+                       queue-group@1 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0xb5000 0x1000>;
+                               interrupts = <51 2 52 2 67 2>;
+                       };
+               };
+
+               enet2: ethernet@b2000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "fsl,etsec2";
+                       fsl,num_rx_queues = <0x8>;
+                       fsl,num_tx_queues = <0x8>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupt-parent = <&mpic>;
+                       phy-handle = <&phy1>;
+                       phy-connection-type = "rgmii-id";
+
+                       queue-group@0 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0xb2000 0x1000>;
+                               interrupts = <31 2 32 2 33 2>;
+                       };
+
+                       queue-group@1 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0xb6000 0x1000>;
+                               interrupts = <25 2 26 2 27 2>;
+                       };
+               };
+
                usb@22000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        phy_type = "ulpi";
                };
 
+               /* USB2 is shared with localbus, so it must be disabled
+                  by default. We can't put 'status = "disabled";' here
+                  since U-Boot doesn't clear the status property when
+                  it enables USB2. OTOH, U-Boot does create a new node
+                  when there isn't any. So, just comment it out.
                usb@23000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
                        interrupts = <46 0x2>;
                        phy_type = "ulpi";
                };
+               */
 
                sdhci@2e000 {
                        compatible = "fsl,p1020-esdhc", "fsl,esdhc";
diff --git a/arch/powerpc/boot/treeboot-iss4xx.c b/arch/powerpc/boot/treeboot-iss4xx.c
new file mode 100644 (file)
index 0000000..fcc4495
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2010 Ben. Herrenschmidt, IBM Corporation.
+ *
+ * Based on earlier code:
+ *   Copyright (C) Paul Mackerras 1997.
+ *
+ *   Matt Porter <mporter@kernel.crashing.org>
+ *   Copyright 2002-2005 MontaVista Software Inc.
+ *
+ *   Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ *   Copyright (c) 2003, 2004 Zultys Technologies
+ *
+ *    Copyright 2007 David Gibson, IBM Corporation.
+ *
+ * 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 <stdarg.h>
+#include <stddef.h>
+#include "types.h"
+#include "elf.h"
+#include "string.h"
+#include "stdio.h"
+#include "page.h"
+#include "ops.h"
+#include "reg.h"
+#include "io.h"
+#include "dcr.h"
+#include "4xx.h"
+#include "44x.h"
+#include "libfdt.h"
+
+BSS_STACK(4096);
+
+static void iss_4xx_fixups(void)
+{
+       ibm4xx_sdram_fixup_memsize();
+}
+
+#define SPRN_PIR       0x11E   /* Processor Indentification Register */
+void platform_init(void)
+{
+       unsigned long end_of_ram = 0x08000000;
+       unsigned long avail_ram = end_of_ram - (unsigned long)_end;
+       u32 pir_reg;
+
+       simple_alloc_init(_end, avail_ram, 128, 64);
+       platform_ops.fixups = iss_4xx_fixups;
+       platform_ops.exit = ibm44x_dbcr_reset;
+       pir_reg = mfspr(SPRN_PIR);
+       fdt_set_boot_cpuid_phys(_dtb_start, pir_reg);
+       fdt_init(_dtb_start);
+       serial_console_init();
+}
index f4594ed..cb97e75 100755 (executable)
@@ -149,6 +149,10 @@ pseries)
     platformo=$object/of.o
     link_address='0x4000000'
     ;;
+maple)
+    platformo=$object/of.o
+    link_address='0x400000'
+    ;;
 pmac|chrp)
     platformo=$object/of.o
     ;;
@@ -237,6 +241,9 @@ gamecube|wii)
     link_address='0x600000'
     platformo="$object/$platform-head.o $object/$platform.o"
     ;;
+treeboot-iss4xx-mpic)
+    platformo="$object/treeboot-iss4xx.o"
+    ;;
 esac
 
 vmz="$tmpdir/`basename \"$kernel\"`.$ext"
@@ -321,7 +328,7 @@ fi
 
 # post-processing needed for some platforms
 case "$platform" in
-pseries|chrp)
+pseries|chrp|maple)
     $objbin/addnote "$ofile"
     ;;
 coff)
diff --git a/arch/powerpc/configs/44x/iss476-smp_defconfig b/arch/powerpc/configs/44x/iss476-smp_defconfig
new file mode 100644 (file)
index 0000000..8683cbc
--- /dev/null
@@ -0,0 +1,1026 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33
+# Thu Mar  4 11:50:12 2010
+#
+# CONFIG_PPC64 is not set
+
+#
+# Processor support
+#
+# CONFIG_PPC_BOOK3S_32 is not set
+# CONFIG_PPC_85xx is not set
+# CONFIG_PPC_8xx is not set
+# CONFIG_40x is not set
+CONFIG_44x=y
+# CONFIG_E200 is not set
+CONFIG_PPC_FPU=y
+CONFIG_4xx=y
+CONFIG_BOOKE=y
+CONFIG_PTE_64BIT=y
+CONFIG_PHYS_64BIT=y
+CONFIG_PPC_MMU_NOHASH=y
+CONFIG_PPC_MMU_NOHASH_32=y
+# CONFIG_PPC_MM_SLICES is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=4
+# CONFIG_NOT_COHERENT_CACHE is not set
+CONFIG_PPC32=y
+CONFIG_WORD_SIZE=32
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_TIME_VSYSCALL=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+# CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
+# CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK is not set
+CONFIG_IRQ_PER_CPU=y
+CONFIG_NR_IRQS=512
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_ARCH_HAS_ILOG2_U32=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
+CONFIG_PPC=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_ARCH_MAY_HAVE_PC_FDC=y
+CONFIG_PPC_OF=y
+CONFIG_OF=y
+CONFIG_PPC_UDBG_16550=y
+CONFIG_GENERIC_TBSYNC=y
+CONFIG_AUDIT_ARCH=y
+CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
+# CONFIG_DEFAULT_UIMAGE is not set
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_PPC_DCR_NATIVE=y
+# CONFIG_PPC_DCR_MMIO is not set
+CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_LZO is not set
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_HAVE_PERF_EVENTS=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+CONFIG_EVENT_PROFILE=y
+# CONFIG_PERF_COUNTERS is not set
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_TRACEPOINTS=y
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_HAVE_IOREMAP_PROT=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+CONFIG_MUTEX_SPIN_ON_OWNER=y
+# CONFIG_FREEZER is not set
+
+#
+# Platform support
+#
+# CONFIG_PPC_CELL is not set
+# CONFIG_PPC_CELL_NATIVE is not set
+# CONFIG_PQ2ADS is not set
+CONFIG_PPC_47x=y
+# CONFIG_BAMBOO is not set
+# CONFIG_EBONY is not set
+# CONFIG_SAM440EP is not set
+# CONFIG_SEQUOIA is not set
+# CONFIG_TAISHAN is not set
+# CONFIG_KATMAI is not set
+# CONFIG_RAINIER is not set
+# CONFIG_WARP is not set
+# CONFIG_ARCHES is not set
+# CONFIG_CANYONLANDS is not set
+# CONFIG_GLACIER is not set
+# CONFIG_REDWOOD is not set
+# CONFIG_EIGER is not set
+# CONFIG_YOSEMITE is not set
+CONFIG_ISS4xx=y
+# CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
+# CONFIG_PPC44x_SIMPLE is not set
+# CONFIG_PPC4xx_GPIO is not set
+# CONFIG_IPIC is not set
+CONFIG_MPIC=y
+# CONFIG_MPIC_WEIRD is not set
+# CONFIG_PPC_I8259 is not set
+# CONFIG_PPC_RTAS is not set
+# CONFIG_MMIO_NVRAM is not set
+# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
+# CONFIG_PPC_INDIRECT_IO is not set
+# CONFIG_GENERIC_IOMAP is not set
+# CONFIG_CPU_FREQ is not set
+# CONFIG_FSL_ULI1575 is not set
+CONFIG_OF_RTC=y
+# CONFIG_SIMPLE_GPIO is not set
+
+#
+# Kernel options
+#
+# CONFIG_HIGHMEM is not set
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+# CONFIG_SCHED_HRTICK is not set
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_MATH_EMULATION=y
+# CONFIG_IOMMU_HELPER is not set
+# CONFIG_SWIOTLB is not set
+CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
+CONFIG_IRQ_ALL_CPUS=y
+CONFIG_SPARSE_IRQ=y
+CONFIG_MAX_ACTIVE_REGIONS=32
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_MIGRATION=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_STDBINUTILS=y
+CONFIG_PPC_4K_PAGES=y
+# CONFIG_PPC_16K_PAGES is not set
+# CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_PROC_DEVICETREE=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="root=/dev/issblk0"
+CONFIG_EXTRA_TARGETS=""
+CONFIG_SECCOMP=y
+CONFIG_ISA_DMA_API=y
+
+#
+# Bus options
+#
+CONFIG_ZONE_DMA=y
+CONFIG_4xx_SOC=y
+CONFIG_PPC_PCI_CHOICE=y
+# CONFIG_PCI is not set
+# CONFIG_PCI_DOMAINS is not set
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+# CONFIG_HAS_RAPIDIO is not set
+
+#
+# Advanced setup
+#
+# CONFIG_ADVANCED_OPTIONS is not set
+
+#
+# Default settings for advanced configuration options are used
+#
+CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_PAGE_OFFSET=0xc0000000
+CONFIG_KERNEL_START=0xc0000000
+CONFIG_PHYSICAL_START=0x00000000
+CONFIG_TASK_SIZE=0xc0000000
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_NET_DROP_MONITOR is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+CONFIG_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_OF_PARTS=y
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+CONFIG_MTD_JEDECPROBE=y
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+CONFIG_MTD_PHYSMAP_OF=y
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+CONFIG_OF_DEVICE=y
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=35000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_XILINX_SYSACE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_MACINTOSH_DRIVERS is not set
+# CONFIG_NETDEVICES is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_UARTLITE is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_SERIAL_OF_PLATFORM=y
+# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
+# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_HVC_UDBG is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_NVRAM is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+CONFIG_THERMAL=y
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_EDAC is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+CONFIG_CRAMFS=y
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_NLS is not set
+# CONFIG_DLM is not set
+CONFIG_BINARY_PRINTF=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_NOP_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_RING_BUFFER=y
+CONFIG_EVENT_TRACING=y
+CONFIG_CONTEXT_SWITCH_TRACER=y
+CONFIG_RING_BUFFER_ALLOW_SWAP=y
+CONFIG_TRACING=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_FUNCTION_TRACER is not set
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+# CONFIG_BOOT_TRACER is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_STACK_TRACER is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_RING_BUFFER_BENCHMARK is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_PPC_DISABLE_WERROR is not set
+CONFIG_PPC_WERROR=y
+CONFIG_PRINT_STACK_DEPTH=64
+# CONFIG_DEBUG_STACKOVERFLOW is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_PPC_EMULATED_STATS is not set
+# CONFIG_CODE_PATCHING_SELFTEST is not set
+# CONFIG_FTR_FIXUP_SELFTEST is not set
+# CONFIG_MSI_BITMAP_SELFTEST is not set
+# CONFIG_XMON is not set
+# CONFIG_IRQSTACKS is not set
+# CONFIG_VIRQ_DEBUG is not set
+# CONFIG_BDI_SWITCH is not set
+CONFIG_PPC_EARLY_DEBUG=y
+# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
+# CONFIG_PPC_EARLY_DEBUG_G5 is not set
+# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set
+# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
+# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
+# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
+# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
+# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
+CONFIG_PPC_EARLY_DEBUG_44x=y
+# CONFIG_PPC_EARLY_DEBUG_40x is not set
+# CONFIG_PPC_EARLY_DEBUG_CPM is not set
+# CONFIG_PPC_EARLY_DEBUG_USBGECKO is not set
+CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0x40000200
+CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x1
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_LRW is not set
+CONFIG_CRYPTO_PCBC=y
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_PPC_CLOCK is not set
+# CONFIG_VIRTUALIZATION is not set
index 12980d5..dad617e 100644 (file)
@@ -988,7 +988,7 @@ CONFIG_ACENIC=m
 CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
-CONFIG_E1000E=m
+CONFIG_E1000E=y
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
 # CONFIG_NS83820 is not set
index 41de3dd..16a1458 100644 (file)
@@ -804,7 +804,7 @@ CONFIG_ACENIC=m
 CONFIG_ACENIC_OMIT_TIGON_I=y
 # CONFIG_DL2K is not set
 CONFIG_E1000=y
-CONFIG_E1000E=m
+CONFIG_E1000E=y
 # CONFIG_IP1000 is not set
 # CONFIG_IGB is not set
 # CONFIG_NS83820 is not set
index 81de6eb..725634f 100644 (file)
 #define L1_CACHE_SHIFT         6
 #define MAX_COPY_PREFETCH      4
 #elif defined(CONFIG_PPC32)
-#define L1_CACHE_SHIFT         5
 #define MAX_COPY_PREFETCH      4
+#if defined(CONFIG_PPC_47x)
+#define L1_CACHE_SHIFT         7
+#else
+#define L1_CACHE_SHIFT         5
+#endif
 #else /* CONFIG_PPC64 */
 #define L1_CACHE_SHIFT         7
 #endif
index abb833b..e3cba4e 100644 (file)
@@ -72,6 +72,7 @@ extern int machine_check_4xx(struct pt_regs *regs);
 extern int machine_check_440A(struct pt_regs *regs);
 extern int machine_check_e500(struct pt_regs *regs);
 extern int machine_check_e200(struct pt_regs *regs);
+extern int machine_check_47x(struct pt_regs *regs);
 
 /* NOTE WELL: Update identify_cpu() if fields are added or removed! */
 struct cpu_spec {
@@ -365,6 +366,7 @@ extern const char *powerpc_base_platform;
 #define CPU_FTRS_44X   (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE)
 #define CPU_FTRS_440x6 (CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | CPU_FTR_NOEXECUTE | \
            CPU_FTR_INDEXED_DCR)
+#define CPU_FTRS_47X   (CPU_FTRS_440x6)
 #define CPU_FTRS_E200  (CPU_FTR_USE_TB | CPU_FTR_SPE_COMP | \
            CPU_FTR_NODSISRALIGN | CPU_FTR_COHERENT_ICACHE | \
            CPU_FTR_UNIFIED_ID_CACHE | CPU_FTR_NOEXECUTE)
@@ -453,6 +455,9 @@ enum {
 #ifdef CONFIG_44x
            CPU_FTRS_44X | CPU_FTRS_440x6 |
 #endif
+#ifdef CONFIG_PPC_47x
+           CPU_FTRS_47X |
+#endif
 #ifdef CONFIG_E200
            CPU_FTRS_E200 |
 #endif
index f027581..5119b7d 100644 (file)
 #define H_JOIN                 0x298
 #define H_VASI_STATE            0x2A4
 #define H_ENABLE_CRQ           0x2B0
+#define H_GET_EM_PARMS         0x2B8
 #define H_SET_MPP              0x2D0
 #define H_GET_MPP              0x2D4
 #define MAX_HCALL_OPCODE       H_GET_MPP
@@ -281,6 +282,7 @@ long plpar_hcall_raw(unsigned long opcode, unsigned long *retbuf, ...);
  */
 #define PLPAR_HCALL9_BUFSIZE 9
 long plpar_hcall9(unsigned long opcode, unsigned long *retbuf, ...);
+long plpar_hcall9_raw(unsigned long opcode, unsigned long *retbuf, ...);
 
 /* For hcall instrumentation.  One structure per-hcall, per-CPU */
 struct hcall_stats {
index 7e06b43..a6ca6da 100644 (file)
 #define KEXEC_ARCH KEXEC_ARCH_PPC
 #endif
 
+#define KEXEC_STATE_NONE 0
+#define KEXEC_STATE_IRQS_OFF 1
+#define KEXEC_STATE_REAL_MODE 2
+
 #ifndef __ASSEMBLY__
 #include <linux/cpumask.h>
 #include <asm/reg.h>
index 0372669..bf52d70 100644 (file)
@@ -40,7 +40,7 @@
 #define PPC44x_TLB_I           0x00000400      /* Caching is inhibited */
 #define PPC44x_TLB_M           0x00000200      /* Memory is coherent */
 #define PPC44x_TLB_G           0x00000100      /* Memory is guarded */
-#define PPC44x_TLB_E           0x00000080      /* Memory is guarded */
+#define PPC44x_TLB_E           0x00000080      /* Memory is little endian */
 
 #define PPC44x_TLB_PERM_MASK   0x0000003f
 #define PPC44x_TLB_UX          0x00000020      /* User execution */
 /* Number of TLB entries */
 #define PPC44x_TLB_SIZE                64
 
+/* 47x bits */
+#define PPC47x_MMUCR_TID       0x0000ffff
+#define PPC47x_MMUCR_STS       0x00010000
+
+/* Page identification fields */
+#define PPC47x_TLB0_EPN_MASK   0xfffff000      /* Effective Page Number */
+#define PPC47x_TLB0_VALID      0x00000800      /* Valid flag */
+#define PPC47x_TLB0_TS         0x00000400      /* Translation address space */
+#define PPC47x_TLB0_4K         0x00000000
+#define PPC47x_TLB0_16K                0x00000010
+#define PPC47x_TLB0_64K                0x00000030
+#define PPC47x_TLB0_1M         0x00000070
+#define PPC47x_TLB0_16M                0x000000f0
+#define PPC47x_TLB0_256M       0x000001f0
+#define PPC47x_TLB0_1G         0x000003f0
+#define PPC47x_TLB0_BOLTED_R   0x00000008      /* tlbre only */
+
+/* Translation fields */
+#define PPC47x_TLB1_RPN_MASK   0xfffff000      /* Real Page Number */
+#define PPC47x_TLB1_ERPN_MASK  0x000003ff
+
+/* Storage attribute and access control fields */
+#define PPC47x_TLB2_ATTR_MASK  0x0003ff80
+#define PPC47x_TLB2_IL1I       0x00020000      /* Memory is guarded */
+#define PPC47x_TLB2_IL1D       0x00010000      /* Memory is guarded */
+#define PPC47x_TLB2_U0         0x00008000      /* User 0 */
+#define PPC47x_TLB2_U1         0x00004000      /* User 1 */
+#define PPC47x_TLB2_U2         0x00002000      /* User 2 */
+#define PPC47x_TLB2_U3         0x00001000      /* User 3 */
+#define PPC47x_TLB2_W          0x00000800      /* Caching is write-through */
+#define PPC47x_TLB2_I          0x00000400      /* Caching is inhibited */
+#define PPC47x_TLB2_M          0x00000200      /* Memory is coherent */
+#define PPC47x_TLB2_G          0x00000100      /* Memory is guarded */
+#define PPC47x_TLB2_E          0x00000080      /* Memory is little endian */
+#define PPC47x_TLB2_PERM_MASK  0x0000003f
+#define PPC47x_TLB2_UX         0x00000020      /* User execution */
+#define PPC47x_TLB2_UW         0x00000010      /* User write */
+#define PPC47x_TLB2_UR         0x00000008      /* User read */
+#define PPC47x_TLB2_SX         0x00000004      /* Super execution */
+#define PPC47x_TLB2_SW         0x00000002      /* Super write */
+#define PPC47x_TLB2_SR         0x00000001      /* Super read */
+#define PPC47x_TLB2_U_RWX      (PPC47x_TLB2_UX|PPC47x_TLB2_UW|PPC47x_TLB2_UR)
+#define PPC47x_TLB2_S_RWX      (PPC47x_TLB2_SX|PPC47x_TLB2_SW|PPC47x_TLB2_SR)
+#define PPC47x_TLB2_S_RW       (PPC47x_TLB2_SW | PPC47x_TLB2_SR)
+#define PPC47x_TLB2_IMG                (PPC47x_TLB2_I | PPC47x_TLB2_M | PPC47x_TLB2_G)
+
 #ifndef __ASSEMBLY__
 
 extern unsigned int tlb_44x_hwater;
@@ -79,12 +125,15 @@ typedef struct {
 
 #if (PAGE_SHIFT == 12)
 #define PPC44x_TLBE_SIZE       PPC44x_TLB_4K
+#define PPC47x_TLBE_SIZE       PPC47x_TLB0_4K
 #define mmu_virtual_psize      MMU_PAGE_4K
 #elif (PAGE_SHIFT == 14)
 #define PPC44x_TLBE_SIZE       PPC44x_TLB_16K
+#define PPC47x_TLBE_SIZE       PPC47x_TLB0_16K
 #define mmu_virtual_psize      MMU_PAGE_16K
 #elif (PAGE_SHIFT == 16)
 #define PPC44x_TLBE_SIZE       PPC44x_TLB_64K
+#define PPC47x_TLBE_SIZE       PPC47x_TLB0_64K
 #define mmu_virtual_psize      MMU_PAGE_64K
 #elif (PAGE_SHIFT == 18)
 #define PPC44x_TLBE_SIZE       PPC44x_TLB_256K
index 7ffbb65..7ebf42e 100644 (file)
@@ -18,6 +18,7 @@
 #define MMU_FTR_TYPE_44x               ASM_CONST(0x00000008)
 #define MMU_FTR_TYPE_FSL_E             ASM_CONST(0x00000010)
 #define MMU_FTR_TYPE_3E                        ASM_CONST(0x00000020)
+#define MMU_FTR_TYPE_47x               ASM_CONST(0x00000040)
 
 /*
  * This is individual features
index 35acac9..aac87cb 100644 (file)
@@ -30,7 +30,7 @@ extern struct pglist_data *node_data[];
  */
 
 extern int numa_cpu_lookup_table[];
-extern cpumask_t numa_cpumask_lookup_table[];
+extern cpumask_var_t node_to_cpumask_map[];
 #ifdef CONFIG_MEMORY_HOTPLUG
 extern unsigned long max_pfn;
 #endif
index 61913d9..e000cce 100644 (file)
@@ -463,9 +463,6 @@ extern void mpic_cpu_set_priority(int prio);
 /* Request IPIs on primary mpic */
 extern void mpic_request_ipis(void);
 
-/* Send an IPI (non offseted number 0..3) */
-extern void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask);
-
 /* Send a message (IPI) to a given target (cpu number or MSG_*) */
 void smp_mpic_message_pass(int target, int msg);
 
index a011603..971dfa4 100644 (file)
@@ -82,6 +82,7 @@ struct paca_struct {
        s16 hw_cpu_id;                  /* Physical processor number */
        u8 cpu_start;                   /* At startup, processor spins until */
                                        /* this becomes non-zero. */
+       u8 kexec_state;         /* set when kexec down has irqs off */
 #ifdef CONFIG_PPC_STD_MMU_64
        struct slb_shadow *slb_shadow_ptr;
 
index 94942d6..1ca1102 100644 (file)
@@ -19,6 +19,8 @@ static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
        u32 io1, io2;
        int propsize;
        int count = 0;
+       int virq;
+
        for (np = NULL; (np = of_find_compatible_node(np,
                                                      "parallel",
                                                      "pnpPNP,400")) != NULL;) {
@@ -26,10 +28,13 @@ static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma)
                if (!prop || propsize > 6*sizeof(u32))
                        continue;
                io1 = prop[1]; io2 = prop[2];
-               prop = of_get_property(np, "interrupts", NULL);
-               if (!prop)
+
+               virq = irq_of_parse_and_map(np, 0);
+               if (virq == NO_IRQ)
                        continue;
-               if (parport_pc_probe_port(io1, io2, prop[0], autodma, NULL, 0) != NULL)
+
+               if (parport_pc_probe_port(io1, io2, virq, autodma, NULL, 0)
+                               != NULL)
                        count++;
        }
        return count;
index 605f5c5..292725c 100644 (file)
 #include <linux/cpumask.h>
 #include <linux/percpu.h>
 
+struct vmemmap_backing {
+       struct vmemmap_backing *list;
+       unsigned long phys;
+       unsigned long virt_addr;
+};
+
 /*
  * Functions that deal with pagetables that could be at any level of
  * the table need to be passed an "index_size" so they know how to
index 55646ad..a7db96f 100644 (file)
@@ -287,7 +287,7 @@ static inline void __ptep_set_access_flags(pte_t *ptep, pte_t entry)
 #define pmd_page_vaddr(pmd)    \
        ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
 #define pmd_page(pmd)          \
-       (mem_map + (pmd_val(pmd) >> PAGE_SHIFT))
+       pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
 #else
 #define pmd_page_vaddr(pmd)    \
        ((unsigned long) (pmd_val(pmd) & PAGE_MASK))
index 9e2d84c..5d8be04 100644 (file)
@@ -89,6 +89,7 @@ struct pt_regs {
 
 #define instruction_pointer(regs) ((regs)->nip)
 #define user_stack_pointer(regs) ((regs)->gpr[1])
+#define kernel_stack_pointer(regs) ((regs)->gpr[1])
 #define regs_return_value(regs) ((regs)->gpr[3])
 
 #ifdef CONFIG_SMP
@@ -141,6 +142,69 @@ do {                                                                             \
 #define arch_has_block_step()  (!cpu_has_feature(CPU_FTR_601))
 #define ARCH_HAS_USER_SINGLE_STEP_INFO
 
+/*
+ * kprobe-based event tracer support
+ */
+
+#include <linux/stddef.h>
+#include <linux/thread_info.h>
+extern int regs_query_register_offset(const char *name);
+extern const char *regs_query_register_name(unsigned int offset);
+#define MAX_REG_OFFSET (offsetof(struct pt_regs, dsisr))
+
+/**
+ * regs_get_register() - get register value from its offset
+ * @regs:         pt_regs from which register value is gotten
+ * @offset:    offset number of the register.
+ *
+ * regs_get_register returns the value of a register whose offset from @regs.
+ * The @offset is the offset of the register in struct pt_regs.
+ * If @offset is bigger than MAX_REG_OFFSET, this returns 0.
+ */
+static inline unsigned long regs_get_register(struct pt_regs *regs,
+                                               unsigned int offset)
+{
+       if (unlikely(offset > MAX_REG_OFFSET))
+               return 0;
+       return *(unsigned long *)((unsigned long)regs + offset);
+}
+
+/**
+ * regs_within_kernel_stack() - check the address in the stack
+ * @regs:      pt_regs which contains kernel stack pointer.
+ * @addr:      address which is checked.
+ *
+ * regs_within_kernel_stack() checks @addr is within the kernel stack page(s).
+ * If @addr is within the kernel stack, it returns true. If not, returns false.
+ */
+
+static inline bool regs_within_kernel_stack(struct pt_regs *regs,
+                                               unsigned long addr)
+{
+       return ((addr & ~(THREAD_SIZE - 1))  ==
+               (kernel_stack_pointer(regs) & ~(THREAD_SIZE - 1)));
+}
+
+/**
+ * regs_get_kernel_stack_nth() - get Nth entry of the stack
+ * @regs:      pt_regs which contains kernel stack pointer.
+ * @n:         stack entry number.
+ *
+ * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which
+ * is specified by @regs. If the @n th entry is NOT in the kernel stack,
+ * this returns 0.
+ */
+static inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs,
+                                                     unsigned int n)
+{
+       unsigned long *addr = (unsigned long *)kernel_stack_pointer(regs);
+       addr += n;
+       if (regs_within_kernel_stack(regs, (unsigned long)addr))
+               return *addr;
+       else
+               return 0;
+}
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
index 5572e86..b68f025 100644 (file)
 #define PVR_403GC      0x00200200
 #define PVR_403GCX     0x00201400
 #define PVR_405GP      0x40110000
+#define PVR_476                0x11a52000
 #define PVR_STB03XXX   0x40310000
 #define PVR_NP405H     0x41410000
 #define PVR_NP405L     0x41610000
 #define PVR_8245       0x80811014
 #define PVR_8260       PVR_8240
 
+/* 476 Simulator seems to currently have the PVR of the 602... */
+#define PVR_476_ISS    0x00052000
+
 /* 64-bit processors */
 /* XXX the prefix should be PVR_, we'll do a global sweep to fix it one day */
 #define PV_NORTHSTAR   0x0033
index 414d434..5304a37 100644 (file)
 #define MCSR_DCFP      0x01000000 /* D-Cache Flush Parity Error */
 #define MCSR_IMPE      0x00800000 /* Imprecise Machine Check Exception */
 
+#define PPC47x_MCSR_GPR        0x01000000 /* GPR parity error */
+#define PPC47x_MCSR_FPR        0x00800000 /* FPR parity error */
+#define PPC47x_MCSR_IPR        0x00400000 /* Imprecise Machine Check Exception */
+
 #ifdef CONFIG_E500
 #define MCSR_MCP       0x80000000UL /* Machine Check Input Pin */
 #define MCSR_ICPERR    0x40000000UL /* I-Cache Parity Error */
 #define DBCR_JOI       0x00000002      /* JTAG Serial Outbound Int. Enable */
 #define DBCR_JII       0x00000001      /* JTAG Serial Inbound Int. Enable */
 #endif /* 403GCX */
+
+/* Some 476 specific registers */
+#define SPRN_SSPCR             830
+#define SPRN_USPCR             831
+#define SPRN_ISPCR             829
+#define SPRN_MMUBE0            820
+#define MMUBE0_IBE0_SHIFT      24
+#define MMUBE0_IBE1_SHIFT      16
+#define MMUBE0_IBE2_SHIFT      8
+#define MMUBE0_VBE0            0x00000004
+#define MMUBE0_VBE1            0x00000002
+#define MMUBE0_VBE2            0x00000001
+#define SPRN_MMUBE1            821
+#define MMUBE1_IBE3_SHIFT      24
+#define MMUBE1_IBE4_SHIFT      16
+#define MMUBE1_IBE5_SHIFT      8
+#define MMUBE1_VBE3            0x00000004
+#define MMUBE1_VBE4            0x00000002
+#define MMUBE1_VBE5            0x00000001
+
 #endif /* __ASM_POWERPC_REG_BOOKE_H__ */
 #endif /* __KERNEL__ */
index 1d3b270..66e237b 100644 (file)
@@ -40,7 +40,7 @@ extern void smp_message_recv(int);
 DECLARE_PER_CPU(unsigned int, cpu_pvr);
 
 #ifdef CONFIG_HOTPLUG_CPU
-extern void fixup_irqs(cpumask_t map);
+extern void fixup_irqs(const struct cpumask *map);
 int generic_cpu_disable(void);
 int generic_cpu_enable(unsigned int cpu);
 void generic_cpu_die(unsigned int cpu);
@@ -68,8 +68,19 @@ static inline void set_hard_smp_processor_id(int cpu, int phys)
 }
 #endif
 
-DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
-DECLARE_PER_CPU(cpumask_t, cpu_core_map);
+DECLARE_PER_CPU(cpumask_var_t, cpu_sibling_map);
+DECLARE_PER_CPU(cpumask_var_t, cpu_core_map);
+
+static inline struct cpumask *cpu_sibling_mask(int cpu)
+{
+       return per_cpu(cpu_sibling_map, cpu);
+}
+
+static inline struct cpumask *cpu_core_mask(int cpu)
+{
+       return per_cpu(cpu_core_map, cpu);
+}
+
 extern int cpu_to_core_id(int cpu);
 
 /* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
@@ -93,7 +104,6 @@ void smp_init_pSeries(void);
 void smp_init_cell(void);
 void smp_init_celleb(void);
 void smp_setup_cpu_maps(void);
-void smp_setup_cpu_sibling_map(void);
 
 extern int __cpu_disable(void);
 extern void __cpu_die(unsigned int cpu);
index 8eaec31..32adf72 100644 (file)
@@ -8,6 +8,26 @@ struct device_node;
 
 #ifdef CONFIG_NUMA
 
+/*
+ * Before going off node we want the VM to try and reclaim from the local
+ * node. It does this if the remote distance is larger than RECLAIM_DISTANCE.
+ * With the default REMOTE_DISTANCE of 20 and the default RECLAIM_DISTANCE of
+ * 20, we never reclaim and go off node straight away.
+ *
+ * To fix this we choose a smaller value of RECLAIM_DISTANCE.
+ */
+#define RECLAIM_DISTANCE 10
+
+/*
+ * Before going off node we want the VM to try and reclaim from the local
+ * node. It does this if the remote distance is larger than RECLAIM_DISTANCE.
+ * With the default REMOTE_DISTANCE of 20 and the default RECLAIM_DISTANCE of
+ * 20, we never reclaim and go off node straight away.
+ *
+ * To fix this we choose a smaller value of RECLAIM_DISTANCE.
+ */
+#define RECLAIM_DISTANCE 10
+
 #include <asm/mmzone.h>
 
 static inline int cpu_to_node(int cpu)
@@ -19,7 +39,7 @@ static inline int cpu_to_node(int cpu)
 
 #define cpumask_of_node(node) ((node) == -1 ?                          \
                               cpu_all_mask :                           \
-                              &numa_cpumask_lookup_table[node])
+                              node_to_cpumask_map[node])
 
 int of_node_to_nid(struct device_node *device);
 
@@ -102,8 +122,8 @@ static inline void sysfs_remove_device_from_node(struct sys_device *dev,
 #ifdef CONFIG_PPC64
 #include <asm/smp.h>
 
-#define topology_thread_cpumask(cpu)   (&per_cpu(cpu_sibling_map, cpu))
-#define topology_core_cpumask(cpu)     (&per_cpu(cpu_core_map, cpu))
+#define topology_thread_cpumask(cpu)   (per_cpu(cpu_sibling_map, cpu))
+#define topology_core_cpumask(cpu)     (per_cpu(cpu_core_map, cpu))
 #define topology_core_id(cpu)          (cpu_to_core_id(cpu))
 #endif
 #endif
index c09138d..28a686f 100644 (file)
@@ -183,6 +183,7 @@ int main(void)
 #endif /* CONFIG_PPC_STD_MMU_64 */
        DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
        DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
+       DEFINE(PACAKEXECSTATE, offsetof(struct paca_struct, kexec_state));
        DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
        DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr));
        DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
@@ -447,6 +448,14 @@ int main(void)
        DEFINE(PGD_T_LOG2, PGD_T_LOG2);
        DEFINE(PTE_T_LOG2, PTE_T_LOG2);
 #endif
+#ifdef CONFIG_FSL_BOOKE
+       DEFINE(TLBCAM_SIZE, sizeof(struct tlbcam));
+       DEFINE(TLBCAM_MAS0, offsetof(struct tlbcam, MAS0));
+       DEFINE(TLBCAM_MAS1, offsetof(struct tlbcam, MAS1));
+       DEFINE(TLBCAM_MAS2, offsetof(struct tlbcam, MAS2));
+       DEFINE(TLBCAM_MAS3, offsetof(struct tlbcam, MAS3));
+       DEFINE(TLBCAM_MAS7, offsetof(struct tlbcam, MAS7));
+#endif
 
 #ifdef CONFIG_KVM_EXIT_TIMING
        DEFINE(VCPU_TIMING_EXIT_TBU, offsetof(struct kvm_vcpu,
index 8af4949..9556be9 100644 (file)
@@ -1701,6 +1701,35 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .machine_check          = machine_check_440A,
                .platform               = "ppc440",
        },
+       { /* 476 core */
+               .pvr_mask               = 0xffff0000,
+               .pvr_value              = 0x11a50000,
+               .cpu_name               = "476",
+               .cpu_features           = CPU_FTRS_47X,
+               .cpu_user_features      = COMMON_USER_BOOKE |
+                       PPC_FEATURE_HAS_FPU,
+               .mmu_features           = MMU_FTR_TYPE_47x |
+                       MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL,
+               .icache_bsize           = 32,
+               .dcache_bsize           = 128,
+               .machine_check          = machine_check_47x,
+               .platform               = "ppc470",
+       },
+       { /* 476 iss */
+               .pvr_mask               = 0xffff0000,
+               .pvr_value              = 0x00050000,
+               .cpu_name               = "476",
+               .cpu_features           = CPU_FTRS_47X,
+               .cpu_user_features      = COMMON_USER_BOOKE |
+                       PPC_FEATURE_HAS_FPU,
+               .cpu_user_features      = COMMON_USER_BOOKE,
+               .mmu_features           = MMU_FTR_TYPE_47x |
+                       MMU_FTR_USE_TLBIVAX_BCAST | MMU_FTR_LOCK_BCAST_INVAL,
+               .icache_bsize           = 32,
+               .dcache_bsize           = 128,
+               .machine_check          = machine_check_47x,
+               .platform               = "ppc470",
+       },
        {       /* default match */
                .pvr_mask               = 0x00000000,
                .pvr_value              = 0x00000000,
index 6f4613d..8c066d6 100644 (file)
@@ -162,6 +162,32 @@ static void crash_kexec_prepare_cpus(int cpu)
        /* Leave the IPI callback set */
 }
 
+/* wait for all the CPUs to hit real mode but timeout if they don't come in */
+static void crash_kexec_wait_realmode(int cpu)
+{
+       unsigned int msecs;
+       int i;
+
+       msecs = 10000;
+       for (i=0; i < NR_CPUS && msecs > 0; i++) {
+               if (i == cpu)
+                       continue;
+
+               while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) {
+                       barrier();
+                       if (!cpu_possible(i)) {
+                               break;
+                       }
+                       if (!cpu_online(i)) {
+                               break;
+                       }
+                       msecs--;
+                       mdelay(1);
+               }
+       }
+       mb();
+}
+
 /*
  * This function will be called by secondary cpus or by kexec cpu
  * if soft-reset is activated to stop some CPUs.
@@ -347,10 +373,12 @@ int crash_shutdown_unregister(crash_shutdown_t handler)
 EXPORT_SYMBOL(crash_shutdown_unregister);
 
 static unsigned long crash_shutdown_buf[JMP_BUF_LEN];
+static int crash_shutdown_cpu = -1;
 
 static int handle_fault(struct pt_regs *regs)
 {
-       longjmp(crash_shutdown_buf, 1);
+       if (crash_shutdown_cpu == smp_processor_id())
+               longjmp(crash_shutdown_buf, 1);
        return 0;
 }
 
@@ -375,11 +403,14 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
        for_each_irq(i) {
                struct irq_desc *desc = irq_to_desc(i);
 
+               if (!desc || !desc->chip || !desc->chip->eoi)
+                       continue;
+
                if (desc->status & IRQ_INPROGRESS)
                        desc->chip->eoi(i);
 
                if (!(desc->status & IRQ_DISABLED))
-                       desc->chip->disable(i);
+                       desc->chip->shutdown(i);
        }
 
        /*
@@ -388,6 +419,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
         */
        old_handler = __debugger_fault_handler;
        __debugger_fault_handler = handle_fault;
+       crash_shutdown_cpu = smp_processor_id();
        for (i = 0; crash_shutdown_handles[i]; i++) {
                if (setjmp(crash_shutdown_buf) == 0) {
                        /*
@@ -401,6 +433,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
                        asm volatile("sync; isync");
                }
        }
+       crash_shutdown_cpu = -1;
        __debugger_fault_handler = old_handler;
 
        /*
@@ -412,6 +445,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
        crash_kexec_prepare_cpus(crashing_cpu);
        cpu_set(crashing_cpu, cpus_in_crash);
        crash_kexec_stop_spus();
+       crash_kexec_wait_realmode(crashing_cpu);
        if (ppc_md.kexec_cpu_down)
                ppc_md.kexec_cpu_down(1, 0);
 }
index 1175a85..ed4aeb9 100644 (file)
@@ -373,11 +373,13 @@ syscall_exit_cont:
        bnel-   load_dbcr0
 #endif
 #ifdef CONFIG_44x
+BEGIN_MMU_FTR_SECTION
        lis     r4,icache_44x_need_flush@ha
        lwz     r5,icache_44x_need_flush@l(r4)
        cmplwi  cr0,r5,0
        bne-    2f
 1:
+END_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_47x)
 #endif /* CONFIG_44x */
 BEGIN_FTR_SECTION
        lwarx   r7,0,r1
@@ -848,6 +850,9 @@ resume_kernel:
        /* interrupts are hard-disabled at this point */
 restore:
 #ifdef CONFIG_44x
+BEGIN_MMU_FTR_SECTION
+       b       1f
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
        lis     r4,icache_44x_need_flush@ha
        lwz     r5,icache_44x_need_flush@l(r4)
        cmplwi  cr0,r5,0
index e3be98f..3e423fb 100644 (file)
@@ -735,8 +735,11 @@ _STATIC(do_hash_page)
        std     r3,_DAR(r1)
        std     r4,_DSISR(r1)
 
-       andis.  r0,r4,0xa450            /* weird error? */
+       andis.  r0,r4,0xa410            /* weird error? */
        bne-    handle_page_fault       /* if not, try to insert a HPTE */
+       andis.  r0,r4,DSISR_DABRMATCH@h
+       bne-    handle_dabr_fault
+
 BEGIN_FTR_SECTION
        andis.  r0,r4,0x0020            /* Is it a segment table fault? */
        bne-    do_ste_alloc            /* If so handle it */
@@ -823,6 +826,14 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
        bl      .raw_local_irq_restore
        b       11f
 
+/* We have a data breakpoint exception - handle it */
+handle_dabr_fault:
+       ld      r4,_DAR(r1)
+       ld      r5,_DSISR(r1)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .do_dabr
+       b       .ret_from_except_lite
+
 /* Here we have a page fault that hash_page can't handle. */
 handle_page_fault:
        ENABLE_INTS
index 711368b..5ab484e 100644 (file)
@@ -37,6 +37,7 @@
 #include <asm/thread_info.h>
 #include <asm/ppc_asm.h>
 #include <asm/asm-offsets.h>
+#include <asm/synch.h>
 #include "head_booke.h"
 
 
@@ -69,165 +70,7 @@ _ENTRY(_start);
        mr      r27,r7
        li      r24,0           /* CPU number */
 
-/*
- * In case the firmware didn't do it, we apply some workarounds
- * that are good for all 440 core variants here
- */
-       mfspr   r3,SPRN_CCR0
-       rlwinm  r3,r3,0,0,27    /* disable icache prefetch */
-       isync
-       mtspr   SPRN_CCR0,r3
-       isync
-       sync
-
-/*
- * Set up the initial MMU state
- *
- * We are still executing code at the virtual address
- * mappings set by the firmware for the base of RAM.
- *
- * We first invalidate all TLB entries but the one
- * we are running from.  We then load the KERNELBASE
- * mappings so we can begin to use kernel addresses
- * natively and so the interrupt vector locations are
- * permanently pinned (necessary since Book E
- * implementations always have translation enabled).
- *
- * TODO: Use the known TLB entry we are running from to
- *      determine which physical region we are located
- *      in.  This can be used to determine where in RAM
- *      (on a shared CPU system) or PCI memory space
- *      (on a DRAMless system) we are located.
- *       For now, we assume a perfect world which means
- *      we are located at the base of DRAM (physical 0).
- */
-
-/*
- * Search TLB for entry that we are currently using.
- * Invalidate all entries but the one we are using.
- */
-       /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */
-       mfspr   r3,SPRN_PID                     /* Get PID */
-       mfmsr   r4                              /* Get MSR */
-       andi.   r4,r4,MSR_IS@l                  /* TS=1? */
-       beq     wmmucr                          /* If not, leave STS=0 */
-       oris    r3,r3,PPC44x_MMUCR_STS@h        /* Set STS=1 */
-wmmucr:        mtspr   SPRN_MMUCR,r3                   /* Put MMUCR */
-       sync
-
-       bl      invstr                          /* Find our address */
-invstr:        mflr    r5                              /* Make it accessible */
-       tlbsx   r23,0,r5                        /* Find entry we are in */
-       li      r4,0                            /* Start at TLB entry 0 */
-       li      r3,0                            /* Set PAGEID inval value */
-1:     cmpw    r23,r4                          /* Is this our entry? */
-       beq     skpinv                          /* If so, skip the inval */
-       tlbwe   r3,r4,PPC44x_TLB_PAGEID         /* If not, inval the entry */
-skpinv:        addi    r4,r4,1                         /* Increment */
-       cmpwi   r4,64                           /* Are we done? */
-       bne     1b                              /* If not, repeat */
-       isync                                   /* If so, context change */
-
-/*
- * Configure and load pinned entry into TLB slot 63.
- */
-
-       lis     r3,PAGE_OFFSET@h
-       ori     r3,r3,PAGE_OFFSET@l
-
-       /* Kernel is at the base of RAM */
-       li r4, 0                        /* Load the kernel physical address */
-
-       /* Load the kernel PID = 0 */
-       li      r0,0
-       mtspr   SPRN_PID,r0
-       sync
-
-       /* Initialize MMUCR */
-       li      r5,0
-       mtspr   SPRN_MMUCR,r5
-       sync
-
-       /* pageid fields */
-       clrrwi  r3,r3,10                /* Mask off the effective page number */
-       ori     r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M
-
-       /* xlat fields */
-       clrrwi  r4,r4,10                /* Mask off the real page number */
-                                       /* ERPN is 0 for first 4GB page */
-
-       /* attrib fields */
-       /* Added guarded bit to protect against speculative loads/stores */
-       li      r5,0
-       ori     r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G)
-
-        li      r0,63                    /* TLB slot 63 */
-
-       tlbwe   r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
-       tlbwe   r4,r0,PPC44x_TLB_XLAT   /* Load the translation fields */
-       tlbwe   r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
-
-       /* Force context change */
-       mfmsr   r0
-       mtspr   SPRN_SRR1, r0
-       lis     r0,3f@h
-       ori     r0,r0,3f@l
-       mtspr   SPRN_SRR0,r0
-       sync
-       rfi
-
-       /* If necessary, invalidate original entry we used */
-3:     cmpwi   r23,63
-       beq     4f
-       li      r6,0
-       tlbwe   r6,r23,PPC44x_TLB_PAGEID
-       isync
-
-4:
-#ifdef CONFIG_PPC_EARLY_DEBUG_44x
-       /* Add UART mapping for early debug. */
-
-       /* pageid fields */
-       lis     r3,PPC44x_EARLY_DEBUG_VIRTADDR@h
-       ori     r3,r3,PPC44x_TLB_VALID|PPC44x_TLB_TS|PPC44x_TLB_64K
-
-       /* xlat fields */
-       lis     r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW@h
-       ori     r4,r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH
-
-       /* attrib fields */
-       li      r5,(PPC44x_TLB_SW|PPC44x_TLB_SR|PPC44x_TLB_I|PPC44x_TLB_G)
-        li      r0,62                    /* TLB slot 0 */
-
-       tlbwe   r3,r0,PPC44x_TLB_PAGEID
-       tlbwe   r4,r0,PPC44x_TLB_XLAT
-       tlbwe   r5,r0,PPC44x_TLB_ATTRIB
-
-       /* Force context change */
-       isync
-#endif /* CONFIG_PPC_EARLY_DEBUG_44x */
-
-       /* Establish the interrupt vector offsets */
-       SET_IVOR(0,  CriticalInput);
-       SET_IVOR(1,  MachineCheck);
-       SET_IVOR(2,  DataStorage);
-       SET_IVOR(3,  InstructionStorage);
-       SET_IVOR(4,  ExternalInput);
-       SET_IVOR(5,  Alignment);
-       SET_IVOR(6,  Program);
-       SET_IVOR(7,  FloatingPointUnavailable);
-       SET_IVOR(8,  SystemCall);
-       SET_IVOR(9,  AuxillaryProcessorUnavailable);
-       SET_IVOR(10, Decrementer);
-       SET_IVOR(11, FixedIntervalTimer);
-       SET_IVOR(12, WatchdogTimer);
-       SET_IVOR(13, DataTLBError);
-       SET_IVOR(14, InstructionTLBError);
-       SET_IVOR(15, DebugCrit);
-
-       /* Establish the interrupt vector base */
-       lis     r4,interrupt_base@h     /* IVPR only uses the high 16-bits */
-       mtspr   SPRN_IVPR,r4
+       bl      init_cpu_state
 
        /*
         * This is where the main kernel code starts.
@@ -349,7 +192,7 @@ interrupt_base:
 #endif
 
        /* Data TLB Error Interrupt */
-       START_EXCEPTION(DataTLBError)
+       START_EXCEPTION(DataTLBError44x)
        mtspr   SPRN_SPRG_WSCRATCH0, r10                /* Save some working registers */
        mtspr   SPRN_SPRG_WSCRATCH1, r11
        mtspr   SPRN_SPRG_WSCRATCH2, r12
@@ -440,7 +283,7 @@ tlb_44x_patch_hwater_D:
        mfspr   r10,SPRN_DEAR
 
         /* Jump to common tlb load */
-       b       finish_tlb_load
+       b       finish_tlb_load_44x
 
 2:
        /* The bailout.  Restore registers to pre-exception conditions
@@ -460,7 +303,7 @@ tlb_44x_patch_hwater_D:
         * information from different registers and bailout
         * to a different point.
         */
-       START_EXCEPTION(InstructionTLBError)
+       START_EXCEPTION(InstructionTLBError44x)
        mtspr   SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */
        mtspr   SPRN_SPRG_WSCRATCH1, r11
        mtspr   SPRN_SPRG_WSCRATCH2, r12
@@ -536,7 +379,7 @@ tlb_44x_patch_hwater_I:
        mfspr   r10,SPRN_SRR0
 
        /* Jump to common TLB load point */
-       b       finish_tlb_load
+       b       finish_tlb_load_44x
 
 2:
        /* The bailout.  Restore registers to pre-exception conditions
@@ -550,15 +393,7 @@ tlb_44x_patch_hwater_I:
        mfspr   r10, SPRN_SPRG_RSCRATCH0
        b       InstructionStorage
 
-       /* Debug Interrupt */
-       DEBUG_CRIT_EXCEPTION
-
-/*
- * Local functions
-  */
-
 /*
-
  * Both the instruction and data TLB miss get to this
  * point to load the TLB.
  *     r10 - EA of fault
@@ -568,7 +403,7 @@ tlb_44x_patch_hwater_I:
  *     MMUCR - loaded with proper value when we get here
  *     Upon exit, we reload everything and RFI.
  */
-finish_tlb_load:
+finish_tlb_load_44x:
        /* Combine RPN & ERPN an write WS 0 */
        rlwimi  r11,r12,0,0,31-PAGE_SHIFT
        tlbwe   r11,r13,PPC44x_TLB_XLAT
@@ -601,73 +436,722 @@ finish_tlb_load:
        mfspr   r10, SPRN_SPRG_RSCRATCH0
        rfi                                     /* Force context change */
 
-/*
- * Global functions
+/* TLB error interrupts for 476
  */
+#ifdef CONFIG_PPC_47x
+       START_EXCEPTION(DataTLBError47x)
+       mtspr   SPRN_SPRG_WSCRATCH0,r10 /* Save some working registers */
+       mtspr   SPRN_SPRG_WSCRATCH1,r11
+       mtspr   SPRN_SPRG_WSCRATCH2,r12
+       mtspr   SPRN_SPRG_WSCRATCH3,r13
+       mfcr    r11
+       mtspr   SPRN_SPRG_WSCRATCH4,r11
+       mfspr   r10,SPRN_DEAR           /* Get faulting address */
 
-/*
- * Adjust the machine check IVOR on 440A cores
- */
-_GLOBAL(__fixup_440A_mcheck)
-       li      r3,MachineCheckA@l
-       mtspr   SPRN_IVOR1,r3
-       sync
-       blr
+       /* If we are faulting a kernel address, we have to use the
+        * kernel page tables.
+        */
+       lis     r11,PAGE_OFFSET@h
+       cmplw   cr0,r10,r11
+       blt+    3f
+       lis     r11,swapper_pg_dir@h
+       ori     r11,r11, swapper_pg_dir@l
+       li      r12,0                   /* MMUCR = 0 */
+       b       4f
 
-/*
- * extern void giveup_altivec(struct task_struct *prev)
- *
- * The 44x core does not have an AltiVec unit.
- */
-_GLOBAL(giveup_altivec)
-       blr
+       /* Get the PGD for the current thread and setup MMUCR */
+3:     mfspr   r11,SPRN_SPRG3
+       lwz     r11,PGDIR(r11)
+       mfspr   r12,SPRN_PID            /* Get PID */
+4:     mtspr   SPRN_MMUCR,r12          /* Set MMUCR */
 
-/*
- * extern void giveup_fpu(struct task_struct *prev)
- *
- * The 44x core does not have an FPU.
- */
-#ifndef CONFIG_PPC_FPU
-_GLOBAL(giveup_fpu)
-       blr
+       /* Mask of required permission bits. Note that while we
+        * do copy ESR:ST to _PAGE_RW position as trying to write
+        * to an RO page is pretty common, we don't do it with
+        * _PAGE_DIRTY. We could do it, but it's a fairly rare
+        * event so I'd rather take the overhead when it happens
+        * rather than adding an instruction here. We should measure
+        * whether the whole thing is worth it in the first place
+        * as we could avoid loading SPRN_ESR completely in the first
+        * place...
+        *
+        * TODO: Is it worth doing that mfspr & rlwimi in the first
+        *       place or can we save a couple of instructions here ?
+        */
+       mfspr   r12,SPRN_ESR
+       li      r13,_PAGE_PRESENT|_PAGE_ACCESSED
+       rlwimi  r13,r12,10,30,30
+
+       /* Load the PTE */
+       /* Compute pgdir/pmd offset */
+       rlwinm  r12,r10,PPC44x_PGD_OFF_SHIFT,PPC44x_PGD_OFF_MASK_BIT,29
+       lwzx    r11,r12,r11             /* Get pgd/pmd entry */
+
+       /* Word 0 is EPN,V,TS,DSIZ */
+       li      r12,PPC47x_TLB0_VALID | PPC47x_TLBE_SIZE
+       rlwimi  r10,r12,0,32-PAGE_SHIFT,31      /* Insert valid and page size*/
+       li      r12,0
+       tlbwe   r10,r12,0
+
+       /* XXX can we do better ? Need to make sure tlbwe has established
+        * latch V bit in MMUCR0 before the PTE is loaded further down */
+#ifdef CONFIG_SMP
+       isync
 #endif
 
-_GLOBAL(set_context)
+       rlwinm. r12,r11,0,0,20          /* Extract pt base address */
+       /* Compute pte address */
+       rlwimi  r12,r10,PPC44x_PTE_ADD_SHIFT,PPC44x_PTE_ADD_MASK_BIT,28
+       beq     2f                      /* Bail if no table */
+       lwz     r11,0(r12)              /* Get high word of pte entry */
 
-#ifdef CONFIG_BDI_SWITCH
-       /* Context switch the PTE pointer for the Abatron BDI2000.
-        * The PGDIR is the second parameter.
+       /* XXX can we do better ? maybe insert a known 0 bit from r11 into the
+        * bottom of r12 to create a data dependency... We can also use r10
+        * as destination nowadays
         */
-       lis     r5, abatron_pteptrs@h
-       ori     r5, r5, abatron_pteptrs@l
-       stw     r4, 0x4(r5)
+#ifdef CONFIG_SMP
+       lwsync
 #endif
-       mtspr   SPRN_PID,r3
-       isync                   /* Force context change */
-       blr
+       lwz     r12,4(r12)              /* Get low word of pte entry */
 
-/*
- * We put a few things here that have to be page-aligned. This stuff
- * goes at the beginning of the data segment, which is page-aligned.
- */
-       .data
-       .align  PAGE_SHIFT
-       .globl  sdata
-sdata:
-       .globl  empty_zero_page
-empty_zero_page:
-       .space  PAGE_SIZE
+       andc.   r13,r13,r12             /* Check permission */
 
-/*
- * To support >32-bit physical addresses, we use an 8KB pgdir.
- */
-       .globl  swapper_pg_dir
-swapper_pg_dir:
-       .space  PGD_TABLE_SIZE
+        /* Jump to common tlb load */
+       beq     finish_tlb_load_47x
 
-/*
- * Room for two PTE pointers, usually the kernel and current user pointers
- * to their respective root page table.
- */
-abatron_pteptrs:
-       .space  8
+2:     /* The bailout.  Restore registers to pre-exception conditions
+        * and call the heavyweights to help us out.
+        */
+       mfspr   r11,SPRN_SPRG_RSCRATCH4
+       mtcr    r11
+       mfspr   r13,SPRN_SPRG_RSCRATCH3
+       mfspr   r12,SPRN_SPRG_RSCRATCH2
+       mfspr   r11,SPRN_SPRG_RSCRATCH1
+       mfspr   r10,SPRN_SPRG_RSCRATCH0
+       b       DataStorage
+
+       /* Instruction TLB Error Interrupt */
+       /*
+        * Nearly the same as above, except we get our
+        * information from different registers and bailout
+        * to a different point.
+        */
+       START_EXCEPTION(InstructionTLBError47x)
+       mtspr   SPRN_SPRG_WSCRATCH0,r10 /* Save some working registers */
+       mtspr   SPRN_SPRG_WSCRATCH1,r11
+       mtspr   SPRN_SPRG_WSCRATCH2,r12
+       mtspr   SPRN_SPRG_WSCRATCH3,r13
+       mfcr    r11
+       mtspr   SPRN_SPRG_WSCRATCH4,r11
+       mfspr   r10,SPRN_SRR0           /* Get faulting address */
+
+       /* If we are faulting a kernel address, we have to use the
+        * kernel page tables.
+        */
+       lis     r11,PAGE_OFFSET@h
+       cmplw   cr0,r10,r11
+       blt+    3f
+       lis     r11,swapper_pg_dir@h
+       ori     r11,r11, swapper_pg_dir@l
+       li      r12,0                   /* MMUCR = 0 */
+       b       4f
+
+       /* Get the PGD for the current thread and setup MMUCR */
+3:     mfspr   r11,SPRN_SPRG_THREAD
+       lwz     r11,PGDIR(r11)
+       mfspr   r12,SPRN_PID            /* Get PID */
+4:     mtspr   SPRN_MMUCR,r12          /* Set MMUCR */
+
+       /* Make up the required permissions */
+       li      r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
+
+       /* Load PTE */
+       /* Compute pgdir/pmd offset */
+       rlwinm  r12,r10,PPC44x_PGD_OFF_SHIFT,PPC44x_PGD_OFF_MASK_BIT,29
+       lwzx    r11,r12,r11             /* Get pgd/pmd entry */
+
+       /* Word 0 is EPN,V,TS,DSIZ */
+       li      r12,PPC47x_TLB0_VALID | PPC47x_TLBE_SIZE
+       rlwimi  r10,r12,0,32-PAGE_SHIFT,31      /* Insert valid and page size*/
+       li      r12,0
+       tlbwe   r10,r12,0
+
+       /* XXX can we do better ? Need to make sure tlbwe has established
+        * latch V bit in MMUCR0 before the PTE is loaded further down */
+#ifdef CONFIG_SMP
+       isync
+#endif
+
+       rlwinm. r12,r11,0,0,20          /* Extract pt base address */
+       /* Compute pte address */
+       rlwimi  r12,r10,PPC44x_PTE_ADD_SHIFT,PPC44x_PTE_ADD_MASK_BIT,28
+       beq     2f                      /* Bail if no table */
+
+       lwz     r11,0(r12)              /* Get high word of pte entry */
+       /* XXX can we do better ? maybe insert a known 0 bit from r11 into the
+        * bottom of r12 to create a data dependency... We can also use r10
+        * as destination nowadays
+        */
+#ifdef CONFIG_SMP
+       lwsync
+#endif
+       lwz     r12,4(r12)              /* Get low word of pte entry */
+
+       andc.   r13,r13,r12             /* Check permission */
+
+       /* Jump to common TLB load point */
+       beq     finish_tlb_load_47x
+
+2:     /* The bailout.  Restore registers to pre-exception conditions
+        * and call the heavyweights to help us out.
+        */
+       mfspr   r11, SPRN_SPRG_RSCRATCH4
+       mtcr    r11
+       mfspr   r13, SPRN_SPRG_RSCRATCH3
+       mfspr   r12, SPRN_SPRG_RSCRATCH2
+       mfspr   r11, SPRN_SPRG_RSCRATCH1
+       mfspr   r10, SPRN_SPRG_RSCRATCH0
+       b       InstructionStorage
+
+/*
+ * Both the instruction and data TLB miss get to this
+ * point to load the TLB.
+ *     r10 - free to use
+ *     r11 - PTE high word value
+ *     r12 - PTE low word value
+ *      r13 - free to use
+ *     MMUCR - loaded with proper value when we get here
+ *     Upon exit, we reload everything and RFI.
+ */
+finish_tlb_load_47x:
+       /* Combine RPN & ERPN an write WS 1 */
+       rlwimi  r11,r12,0,0,31-PAGE_SHIFT
+       tlbwe   r11,r13,1
+
+       /* And make up word 2 */
+       li      r10,0xf85                       /* Mask to apply from PTE */
+       rlwimi  r10,r12,29,30,30                /* DIRTY -> SW position */
+       and     r11,r12,r10                     /* Mask PTE bits to keep */
+       andi.   r10,r12,_PAGE_USER              /* User page ? */
+       beq     1f                              /* nope, leave U bits empty */
+       rlwimi  r11,r11,3,26,28                 /* yes, copy S bits to U */
+1:     tlbwe   r11,r13,2
+
+       /* Done...restore registers and get out of here.
+       */
+       mfspr   r11, SPRN_SPRG_RSCRATCH4
+       mtcr    r11
+       mfspr   r13, SPRN_SPRG_RSCRATCH3
+       mfspr   r12, SPRN_SPRG_RSCRATCH2
+       mfspr   r11, SPRN_SPRG_RSCRATCH1
+       mfspr   r10, SPRN_SPRG_RSCRATCH0
+       rfi
+
+#endif /* CONFIG_PPC_47x */
+
+       /* Debug Interrupt */
+       /*
+        * This statement needs to exist at the end of the IVPR
+        * definition just in case you end up taking a debug
+        * exception within another exception.
+        */
+       DEBUG_CRIT_EXCEPTION
+
+/*
+ * Global functions
+ */
+
+/*
+ * Adjust the machine check IVOR on 440A cores
+ */
+_GLOBAL(__fixup_440A_mcheck)
+       li      r3,MachineCheckA@l
+       mtspr   SPRN_IVOR1,r3
+       sync
+       blr
+
+/*
+ * extern void giveup_altivec(struct task_struct *prev)
+ *
+ * The 44x core does not have an AltiVec unit.
+ */
+_GLOBAL(giveup_altivec)
+       blr
+
+/*
+ * extern void giveup_fpu(struct task_struct *prev)
+ *
+ * The 44x core does not have an FPU.
+ */
+#ifndef CONFIG_PPC_FPU
+_GLOBAL(giveup_fpu)
+       blr
+#endif
+
+_GLOBAL(set_context)
+
+#ifdef CONFIG_BDI_SWITCH
+       /* Context switch the PTE pointer for the Abatron BDI2000.
+        * The PGDIR is the second parameter.
+        */
+       lis     r5, abatron_pteptrs@h
+       ori     r5, r5, abatron_pteptrs@l
+       stw     r4, 0x4(r5)
+#endif
+       mtspr   SPRN_PID,r3
+       isync                   /* Force context change */
+       blr
+
+/*
+ * Init CPU state. This is called at boot time or for secondary CPUs
+ * to setup initial TLB entries, setup IVORs, etc...
+ *
+ */
+_GLOBAL(init_cpu_state)
+       mflr    r22
+#ifdef CONFIG_PPC_47x
+       /* We use the PVR to differenciate 44x cores from 476 */
+       mfspr   r3,SPRN_PVR
+       srwi    r3,r3,16
+       cmplwi  cr0,r3,PVR_476@h
+       beq     head_start_47x
+       cmplwi  cr0,r3,PVR_476_ISS@h
+       beq     head_start_47x
+#endif /* CONFIG_PPC_47x */
+
+/*
+ * In case the firmware didn't do it, we apply some workarounds
+ * that are good for all 440 core variants here
+ */
+       mfspr   r3,SPRN_CCR0
+       rlwinm  r3,r3,0,0,27    /* disable icache prefetch */
+       isync
+       mtspr   SPRN_CCR0,r3
+       isync
+       sync
+
+/*
+ * Set up the initial MMU state for 44x
+ *
+ * We are still executing code at the virtual address
+ * mappings set by the firmware for the base of RAM.
+ *
+ * We first invalidate all TLB entries but the one
+ * we are running from.  We then load the KERNELBASE
+ * mappings so we can begin to use kernel addresses
+ * natively and so the interrupt vector locations are
+ * permanently pinned (necessary since Book E
+ * implementations always have translation enabled).
+ *
+ * TODO: Use the known TLB entry we are running from to
+ *      determine which physical region we are located
+ *      in.  This can be used to determine where in RAM
+ *      (on a shared CPU system) or PCI memory space
+ *      (on a DRAMless system) we are located.
+ *       For now, we assume a perfect world which means
+ *      we are located at the base of DRAM (physical 0).
+ */
+
+/*
+ * Search TLB for entry that we are currently using.
+ * Invalidate all entries but the one we are using.
+ */
+       /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */
+       mfspr   r3,SPRN_PID                     /* Get PID */
+       mfmsr   r4                              /* Get MSR */
+       andi.   r4,r4,MSR_IS@l                  /* TS=1? */
+       beq     wmmucr                          /* If not, leave STS=0 */
+       oris    r3,r3,PPC44x_MMUCR_STS@h        /* Set STS=1 */
+wmmucr:        mtspr   SPRN_MMUCR,r3                   /* Put MMUCR */
+       sync
+
+       bl      invstr                          /* Find our address */
+invstr:        mflr    r5                              /* Make it accessible */
+       tlbsx   r23,0,r5                        /* Find entry we are in */
+       li      r4,0                            /* Start at TLB entry 0 */
+       li      r3,0                            /* Set PAGEID inval value */
+1:     cmpw    r23,r4                          /* Is this our entry? */
+       beq     skpinv                          /* If so, skip the inval */
+       tlbwe   r3,r4,PPC44x_TLB_PAGEID         /* If not, inval the entry */
+skpinv:        addi    r4,r4,1                         /* Increment */
+       cmpwi   r4,64                           /* Are we done? */
+       bne     1b                              /* If not, repeat */
+       isync                                   /* If so, context change */
+
+/*
+ * Configure and load pinned entry into TLB slot 63.
+ */
+
+       lis     r3,PAGE_OFFSET@h
+       ori     r3,r3,PAGE_OFFSET@l
+
+       /* Kernel is at the base of RAM */
+       li r4, 0                        /* Load the kernel physical address */
+
+       /* Load the kernel PID = 0 */
+       li      r0,0
+       mtspr   SPRN_PID,r0
+       sync
+
+       /* Initialize MMUCR */
+       li      r5,0
+       mtspr   SPRN_MMUCR,r5
+       sync
+
+       /* pageid fields */
+       clrrwi  r3,r3,10                /* Mask off the effective page number */
+       ori     r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M
+
+       /* xlat fields */
+       clrrwi  r4,r4,10                /* Mask off the real page number */
+                                       /* ERPN is 0 for first 4GB page */
+
+       /* attrib fields */
+       /* Added guarded bit to protect against speculative loads/stores */
+       li      r5,0
+       ori     r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G)
+
+        li      r0,63                    /* TLB slot 63 */
+
+       tlbwe   r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
+       tlbwe   r4,r0,PPC44x_TLB_XLAT   /* Load the translation fields */
+       tlbwe   r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
+
+       /* Force context change */
+       mfmsr   r0
+       mtspr   SPRN_SRR1, r0
+       lis     r0,3f@h
+       ori     r0,r0,3f@l
+       mtspr   SPRN_SRR0,r0
+       sync
+       rfi
+
+       /* If necessary, invalidate original entry we used */
+3:     cmpwi   r23,63
+       beq     4f
+       li      r6,0
+       tlbwe   r6,r23,PPC44x_TLB_PAGEID
+       isync
+
+4:
+#ifdef CONFIG_PPC_EARLY_DEBUG_44x
+       /* Add UART mapping for early debug. */
+
+       /* pageid fields */
+       lis     r3,PPC44x_EARLY_DEBUG_VIRTADDR@h
+       ori     r3,r3,PPC44x_TLB_VALID|PPC44x_TLB_TS|PPC44x_TLB_64K
+
+       /* xlat fields */
+       lis     r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW@h
+       ori     r4,r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH
+
+       /* attrib fields */
+       li      r5,(PPC44x_TLB_SW|PPC44x_TLB_SR|PPC44x_TLB_I|PPC44x_TLB_G)
+        li      r0,62                    /* TLB slot 0 */
+
+       tlbwe   r3,r0,PPC44x_TLB_PAGEID
+       tlbwe   r4,r0,PPC44x_TLB_XLAT
+       tlbwe   r5,r0,PPC44x_TLB_ATTRIB
+
+       /* Force context change */
+       isync
+#endif /* CONFIG_PPC_EARLY_DEBUG_44x */
+
+       /* Establish the interrupt vector offsets */
+       SET_IVOR(0,  CriticalInput);
+       SET_IVOR(1,  MachineCheck);
+       SET_IVOR(2,  DataStorage);
+       SET_IVOR(3,  InstructionStorage);
+       SET_IVOR(4,  ExternalInput);
+       SET_IVOR(5,  Alignment);
+       SET_IVOR(6,  Program);
+       SET_IVOR(7,  FloatingPointUnavailable);
+       SET_IVOR(8,  SystemCall);
+       SET_IVOR(9,  AuxillaryProcessorUnavailable);
+       SET_IVOR(10, Decrementer);
+       SET_IVOR(11, FixedIntervalTimer);
+       SET_IVOR(12, WatchdogTimer);
+       SET_IVOR(13, DataTLBError44x);
+       SET_IVOR(14, InstructionTLBError44x);
+       SET_IVOR(15, DebugCrit);
+
+       b       head_start_common
+
+
+#ifdef CONFIG_PPC_47x
+
+#ifdef CONFIG_SMP
+
+/* Entry point for secondary 47x processors */
+_GLOBAL(start_secondary_47x)
+        mr      r24,r3          /* CPU number */
+
+       bl      init_cpu_state
+
+       /* Now we need to bolt the rest of kernel memory which
+        * is done in C code. We must be careful because our task
+        * struct or our stack can (and will probably) be out
+        * of reach of the initial 256M TLB entry, so we use a
+        * small temporary stack in .bss for that. This works
+        * because only one CPU at a time can be in this code
+        */
+       lis     r1,temp_boot_stack@h
+       ori     r1,r1,temp_boot_stack@l
+       addi    r1,r1,1024-STACK_FRAME_OVERHEAD
+       li      r0,0
+       stw     r0,0(r1)
+       bl      mmu_init_secondary
+
+       /* Now we can get our task struct and real stack pointer */
+
+       /* Get current_thread_info and current */
+       lis     r1,secondary_ti@ha
+       lwz     r1,secondary_ti@l(r1)
+       lwz     r2,TI_TASK(r1)
+
+       /* Current stack pointer */
+       addi    r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+       li      r0,0
+       stw     r0,0(r1)
+
+       /* Kernel stack for exception entry in SPRG3 */
+       addi    r4,r2,THREAD    /* init task's THREAD */
+       mtspr   SPRN_SPRG3,r4
+
+       b       start_secondary
+
+#endif /* CONFIG_SMP */
+
+/*
+ * Set up the initial MMU state for 44x
+ *
+ * We are still executing code at the virtual address
+ * mappings set by the firmware for the base of RAM.
+ */
+
+head_start_47x:
+       /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */
+       mfspr   r3,SPRN_PID                     /* Get PID */
+       mfmsr   r4                              /* Get MSR */
+       andi.   r4,r4,MSR_IS@l                  /* TS=1? */
+       beq     1f                              /* If not, leave STS=0 */
+       oris    r3,r3,PPC47x_MMUCR_STS@h        /* Set STS=1 */
+1:     mtspr   SPRN_MMUCR,r3                   /* Put MMUCR */
+       sync
+
+       /* Find the entry we are running from */
+       bl      1f
+1:     mflr    r23
+       tlbsx   r23,0,r23
+       tlbre   r24,r23,0
+       tlbre   r25,r23,1
+       tlbre   r26,r23,2
+
+/*
+ * Cleanup time
+ */
+
+       /* Initialize MMUCR */
+       li      r5,0
+       mtspr   SPRN_MMUCR,r5
+       sync
+
+clear_all_utlb_entries:
+
+       #; Set initial values.
+
+       addis           r3,0,0x8000
+       addi            r4,0,0
+       addi            r5,0,0
+       b               clear_utlb_entry
+
+       #; Align the loop to speed things up.
+
+       .align          6
+
+clear_utlb_entry:
+
+       tlbwe           r4,r3,0
+       tlbwe           r5,r3,1
+       tlbwe           r5,r3,2
+       addis           r3,r3,0x2000
+       cmpwi           r3,0
+       bne             clear_utlb_entry
+       addis           r3,0,0x8000
+       addis           r4,r4,0x100
+       cmpwi           r4,0
+       bne             clear_utlb_entry
+
+       #; Restore original entry.
+
+       oris    r23,r23,0x8000  /* specify the way */
+       tlbwe           r24,r23,0
+       tlbwe           r25,r23,1
+       tlbwe           r26,r23,2
+
+/*
+ * Configure and load pinned entry into TLB for the kernel core
+ */
+
+       lis     r3,PAGE_OFFSET@h
+       ori     r3,r3,PAGE_OFFSET@l
+
+       /* Kernel is at the base of RAM */
+       li r4, 0                        /* Load the kernel physical address */
+
+       /* Load the kernel PID = 0 */
+       li      r0,0
+       mtspr   SPRN_PID,r0
+       sync
+
+       /* Word 0 */
+       clrrwi  r3,r3,12                /* Mask off the effective page number */
+       ori     r3,r3,PPC47x_TLB0_VALID | PPC47x_TLB0_256M
+
+       /* Word 1 */
+       clrrwi  r4,r4,12                /* Mask off the real page number */
+                                       /* ERPN is 0 for first 4GB page */
+       /* Word 2 */
+       li      r5,0
+       ori     r5,r5,PPC47x_TLB2_S_RWX
+#ifdef CONFIG_SMP
+       ori     r5,r5,PPC47x_TLB2_M
+#endif
+
+       /* We write to way 0 and bolted 0 */
+       lis     r0,0x8800
+       tlbwe   r3,r0,0
+       tlbwe   r4,r0,1
+       tlbwe   r5,r0,2
+
+/*
+ * Configure SSPCR, ISPCR and USPCR for now to search everything, we can fix
+ * them up later
+ */
+       LOAD_REG_IMMEDIATE(r3, 0x9abcdef0)
+       mtspr   SPRN_SSPCR,r3
+       mtspr   SPRN_USPCR,r3
+       LOAD_REG_IMMEDIATE(r3, 0x12345670)
+       mtspr   SPRN_ISPCR,r3
+
+       /* Force context change */
+       mfmsr   r0
+       mtspr   SPRN_SRR1, r0
+       lis     r0,3f@h
+       ori     r0,r0,3f@l
+       mtspr   SPRN_SRR0,r0
+       sync
+       rfi
+
+       /* Invalidate original entry we used */
+3:
+       rlwinm  r24,r24,0,21,19 /* clear the "valid" bit */
+       tlbwe   r24,r23,0
+       addi    r24,0,0
+       tlbwe   r24,r23,1
+       tlbwe   r24,r23,2
+       isync                   /* Clear out the shadow TLB entries */
+
+#ifdef CONFIG_PPC_EARLY_DEBUG_44x
+       /* Add UART mapping for early debug. */
+
+       /* Word 0 */
+       lis     r3,PPC44x_EARLY_DEBUG_VIRTADDR@h
+       ori     r3,r3,PPC47x_TLB0_VALID | PPC47x_TLB0_TS | PPC47x_TLB0_1M
+
+       /* Word 1 */
+       lis     r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW@h
+       ori     r4,r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH
+
+       /* Word 2 */
+       li      r5,(PPC47x_TLB2_S_RW | PPC47x_TLB2_IMG)
+
+       /* Bolted in way 0, bolt slot 5, we -hope- we don't hit the same
+        * congruence class as the kernel, we need to make sure of it at
+        * some point
+        */
+        lis    r0,0x8d00
+       tlbwe   r3,r0,0
+       tlbwe   r4,r0,1
+       tlbwe   r5,r0,2
+
+       /* Force context change */
+       isync
+#endif /* CONFIG_PPC_EARLY_DEBUG_44x */
+
+       /* Establish the interrupt vector offsets */
+       SET_IVOR(0,  CriticalInput);
+       SET_IVOR(1,  MachineCheckA);
+       SET_IVOR(2,  DataStorage);
+       SET_IVOR(3,  InstructionStorage);
+       SET_IVOR(4,  ExternalInput);
+       SET_IVOR(5,  Alignment);
+       SET_IVOR(6,  Program);
+       SET_IVOR(7,  FloatingPointUnavailable);
+       SET_IVOR(8,  SystemCall);
+       SET_IVOR(9,  AuxillaryProcessorUnavailable);
+       SET_IVOR(10, Decrementer);
+       SET_IVOR(11, FixedIntervalTimer);
+       SET_IVOR(12, WatchdogTimer);
+       SET_IVOR(13, DataTLBError47x);
+       SET_IVOR(14, InstructionTLBError47x);
+       SET_IVOR(15, DebugCrit);
+
+       /* We configure icbi to invalidate 128 bytes at a time since the
+        * current 32-bit kernel code isn't too happy with icache != dcache
+        * block size
+        */
+       mfspr   r3,SPRN_CCR0
+       oris    r3,r3,0x0020
+       mtspr   SPRN_CCR0,r3
+       isync
+
+#endif /* CONFIG_PPC_47x */
+
+/*
+ * Here we are back to code that is common between 44x and 47x
+ *
+ * We proceed to further kernel initialization and return to the
+ * main kernel entry
+ */
+head_start_common:
+       /* Establish the interrupt vector base */
+       lis     r4,interrupt_base@h     /* IVPR only uses the high 16-bits */
+       mtspr   SPRN_IVPR,r4
+
+       addis   r22,r22,KERNELBASE@h
+       mtlr    r22
+       isync
+       blr
+
+/*
+ * We put a few things here that have to be page-aligned. This stuff
+ * goes at the beginning of the data segment, which is page-aligned.
+ */
+       .data
+       .align  PAGE_SHIFT
+       .globl  sdata
+sdata:
+       .globl  empty_zero_page
+empty_zero_page:
+       .space  PAGE_SIZE
+
+/*
+ * To support >32-bit physical addresses, we use an 8KB pgdir.
+ */
+       .globl  swapper_pg_dir
+swapper_pg_dir:
+       .space  PGD_TABLE_SIZE
+
+/*
+ * Room for two PTE pointers, usually the kernel and current user pointers
+ * to their respective root page table.
+ */
+abatron_pteptrs:
+       .space  8
+
+#ifdef CONFIG_SMP
+       .align  12
+temp_boot_stack:
+       .space  1024
+#endif /* CONFIG_SMP */
index 3ef743f..1f1a04b 100644 (file)
@@ -71,9 +71,6 @@ _ENTRY(_start);
  * in the first level table, but that would require many changes to the
  * Linux page directory/table functions that I don't want to do right now.
  *
- * I used to use SPRG2 for a temporary register in the TLB handler, but it
- * has since been put to other uses.  I now use a hack to save a register
- * and the CCR at memory location 0.....Someday I'll fix this.....
  *     -- Dan
  */
        .globl  __start
@@ -302,8 +299,13 @@ InstructionTLBMiss:
        DO_8xx_CPU6(0x3f80, r3)
        mtspr   SPRN_M_TW, r10  /* Save a couple of working registers */
        mfcr    r10
+#ifdef CONFIG_8xx_CPU6
        stw     r10, 0(r0)
        stw     r11, 4(r0)
+#else
+       mtspr   SPRN_DAR, r10
+       mtspr   SPRN_SPRG2, r11
+#endif
        mfspr   r10, SPRN_SRR0  /* Get effective address of fault */
 #ifdef CONFIG_8xx_CPU15
        addi    r11, r10, 0x1000
@@ -318,12 +320,16 @@ InstructionTLBMiss:
        /* If we are faulting a kernel address, we have to use the
         * kernel page tables.
         */
+#ifdef CONFIG_MODULES
+       /* Only modules will cause ITLB Misses as we always
+        * pin the first 8MB of kernel memory */
        andi.   r11, r10, 0x0800        /* Address >= 0x80000000 */
        beq     3f
        lis     r11, swapper_pg_dir@h
        ori     r11, r11, swapper_pg_dir@l
        rlwimi  r10, r11, 0, 2, 19
 3:
+#endif
        lwz     r11, 0(r10)     /* Get the level 1 entry */
        rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
        beq     2f              /* If zero, don't try to find a pte */
@@ -339,31 +345,35 @@ InstructionTLBMiss:
        mfspr   r11, SPRN_MD_TWC        /* ....and get the pte address */
        lwz     r10, 0(r11)     /* Get the pte */
 
+#ifdef CONFIG_SWAP
        andi.   r11, r10, _PAGE_ACCESSED | _PAGE_PRESENT
        cmpwi   cr0, r11, _PAGE_ACCESSED | _PAGE_PRESENT
        bne-    cr0, 2f
-
-       /* Clear PP lsb, 0x400 */
-       rlwinm  r10, r10, 0, 22, 20
-
+#endif
        /* The Linux PTE won't go exactly into the MMU TLB.
-        * Software indicator bits 22 and 28 must be clear.
+        * Software indicator bits 21 and 28 must be clear.
         * Software indicator bits 24, 25, 26, and 27 must be
         * set.  All other Linux PTE bits control the behavior
         * of the MMU.
         */
        li      r11, 0x00f0
-       rlwimi  r10, r11, 0, 24, 28     /* Set 24-27, clear 28 */
+       rlwimi  r10, r11, 0, 0x07f8     /* Set 24-27, clear 21-23,28 */
        DO_8xx_CPU6(0x2d80, r3)
        mtspr   SPRN_MI_RPN, r10        /* Update TLB entry */
 
-       mfspr   r10, SPRN_M_TW  /* Restore registers */
+       /* Restore registers */
+#ifndef CONFIG_8xx_CPU6
+       mfspr   r10, SPRN_DAR
+       mtcr    r10
+       mtspr   SPRN_DAR, r11   /* Tag DAR */
+       mfspr   r11, SPRN_SPRG2
+#else
        lwz     r11, 0(r0)
        mtcr    r11
        lwz     r11, 4(r0)
-#ifdef CONFIG_8xx_CPU6
        lwz     r3, 8(r0)
 #endif
+       mfspr   r10, SPRN_M_TW
        rfi
 2:
        mfspr   r11, SPRN_SRR1
@@ -373,13 +383,20 @@ InstructionTLBMiss:
        rlwinm  r11, r11, 0, 0xffff
        mtspr   SPRN_SRR1, r11
 
-       mfspr   r10, SPRN_M_TW  /* Restore registers */
+       /* Restore registers */
+#ifndef CONFIG_8xx_CPU6
+       mfspr   r10, SPRN_DAR
+       mtcr    r10
+       li      r11, 0x00f0
+       mtspr   SPRN_DAR, r11   /* Tag DAR */
+       mfspr   r11, SPRN_SPRG2
+#else
        lwz     r11, 0(r0)
        mtcr    r11
        lwz     r11, 4(r0)
-#ifdef CONFIG_8xx_CPU6
        lwz     r3, 8(r0)
 #endif
+       mfspr   r10, SPRN_M_TW
        b       InstructionAccess
 
        . = 0x1200
@@ -390,8 +407,13 @@ DataStoreTLBMiss:
        DO_8xx_CPU6(0x3f80, r3)
        mtspr   SPRN_M_TW, r10  /* Save a couple of working registers */
        mfcr    r10
+#ifdef CONFIG_8xx_CPU6
        stw     r10, 0(r0)
        stw     r11, 4(r0)
+#else
+       mtspr   SPRN_DAR, r10
+       mtspr   SPRN_SPRG2, r11
+#endif
        mfspr   r10, SPRN_M_TWB /* Get level 1 table entry address */
 
        /* If we are faulting a kernel address, we have to use the
@@ -438,15 +460,14 @@ DataStoreTLBMiss:
         * r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5));
         * r10 = (r10 & ~PRESENT) | r11;
         */
+#ifdef CONFIG_SWAP
        rlwinm  r11, r10, 32-5, _PAGE_PRESENT
        and     r11, r11, r10
        rlwimi  r10, r11, 0, _PAGE_PRESENT
-
+#endif
        /* Honour kernel RO, User NA */
        /* 0x200 == Extended encoding, bit 22 */
-       /* r11 =  (r10 & _PAGE_USER) >> 2 */
-       rlwinm  r11, r10, 32-2, 0x200
-       or      r10, r11, r10
+       rlwimi  r10, r10, 32-2, 0x200 /* Copy USER to bit 22, 0x200 */
        /* r11 =  (r10 & _PAGE_RW) >> 1 */
        rlwinm  r11, r10, 32-1, 0x200
        or      r10, r11, r10
@@ -460,18 +481,24 @@ DataStoreTLBMiss:
         * of the MMU.
         */
 2:     li      r11, 0x00f0
-       mtspr   SPRN_DAR,r11    /* Tag DAR */
        rlwimi  r10, r11, 0, 24, 28     /* Set 24-27, clear 28 */
        DO_8xx_CPU6(0x3d80, r3)
        mtspr   SPRN_MD_RPN, r10        /* Update TLB entry */
 
-       mfspr   r10, SPRN_M_TW  /* Restore registers */
+       /* Restore registers */
+#ifndef CONFIG_8xx_CPU6
+       mfspr   r10, SPRN_DAR
+       mtcr    r10
+       mtspr   SPRN_DAR, r11   /* Tag DAR */
+       mfspr   r11, SPRN_SPRG2
+#else
+       mtspr   SPRN_DAR, r11   /* Tag DAR */
        lwz     r11, 0(r0)
        mtcr    r11
        lwz     r11, 4(r0)
-#ifdef CONFIG_8xx_CPU6
        lwz     r3, 8(r0)
 #endif
+       mfspr   r10, SPRN_M_TW
        rfi
 
 /* This is an instruction TLB error on the MPC8xx.  This could be due
@@ -683,9 +710,6 @@ start_here:
        tophys(r4,r2)
        addi    r4,r4,THREAD    /* init task's THREAD */
        mtspr   SPRN_SPRG_THREAD,r4
-       li      r3,0
-       /* XXX What is that for ? SPRG2 appears otherwise unused on 8xx */
-       mtspr   SPRN_SPRG2,r3   /* 0 => r1 has kernel sp */
 
        /* stack */
        lis     r1,init_thread_union@ha
index 50504ae..a0bf158 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __HEAD_BOOKE_H__
 #define __HEAD_BOOKE_H__
 
+#include <asm/ptrace.h>        /* for STACK_FRAME_REGS_MARKER */
 /*
  * Macros used for common Book-e exception handling
  */
@@ -48,6 +49,9 @@
        stw     r10,0(r11);                                                  \
        rlwinm  r9,r9,0,14,12;          /* clear MSR_WE (necessary?)       */\
        stw     r0,GPR0(r11);                                                \
+       lis     r10, STACK_FRAME_REGS_MARKER@ha;/* exception frame marker */ \
+       addi    r10, r10, STACK_FRAME_REGS_MARKER@l;                         \
+       stw     r10, 8(r11);                                                 \
        SAVE_4GPRS(3, r11);                                                  \
        SAVE_2GPRS(7, r11)
 
index 7255265..edd4a57 100644 (file)
@@ -639,6 +639,13 @@ interrupt_base:
        rlwinm  r12,r12,0,16,1
        mtspr   SPRN_MAS1,r12
 
+       /* Make up the required permissions for kernel code */
+#ifdef CONFIG_PTE_64BIT
+       li      r13,_PAGE_PRESENT | _PAGE_BAP_SX
+       oris    r13,r13,_PAGE_ACCESSED@h
+#else
+       li      r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
+#endif
        b       4f
 
        /* Get the PGD for the current thread */
@@ -646,15 +653,15 @@ interrupt_base:
        mfspr   r11,SPRN_SPRG_THREAD
        lwz     r11,PGDIR(r11)
 
-4:
-       /* Make up the required permissions */
+       /* Make up the required permissions for user code */
 #ifdef CONFIG_PTE_64BIT
-       li      r13,_PAGE_PRESENT | _PAGE_EXEC
+       li      r13,_PAGE_PRESENT | _PAGE_BAP_UX
        oris    r13,r13,_PAGE_ACCESSED@h
 #else
        li      r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
 #endif
 
+4:
        FIND_PTE
        andc.   r13,r13,r11             /* Check permission */
 
index ec94f90..d583917 100644 (file)
 #define DBG(...)
 
 static int novmerge;
-static int protect4gb = 1;
 
 static void __iommu_free(struct iommu_table *, dma_addr_t, unsigned int);
 
-static int __init setup_protect4gb(char *str)
-{
-       if (strcmp(str, "on") == 0)
-               protect4gb = 1;
-       else if (strcmp(str, "off") == 0)
-               protect4gb = 0;
-
-       return 1;
-}
-
 static int __init setup_iommu(char *str)
 {
        if (!strcmp(str, "novmerge"))
@@ -66,7 +55,6 @@ static int __init setup_iommu(char *str)
        return 1;
 }
 
-__setup("protect4gb=", setup_protect4gb);
 __setup("iommu=", setup_iommu);
 
 static unsigned long iommu_range_alloc(struct device *dev,
index 066bd31..30817d9 100644 (file)
@@ -284,30 +284,33 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-void fixup_irqs(cpumask_t map)
+void fixup_irqs(const struct cpumask *map)
 {
        struct irq_desc *desc;
        unsigned int irq;
        static int warned;
+       cpumask_var_t mask;
 
-       for_each_irq(irq) {
-               cpumask_t mask;
+       alloc_cpumask_var(&mask, GFP_KERNEL);
 
+       for_each_irq(irq) {
                desc = irq_to_desc(irq);
                if (desc && desc->status & IRQ_PER_CPU)
                        continue;
 
-               cpumask_and(&mask, desc->affinity, &map);
-               if (any_online_cpu(mask) == NR_CPUS) {
+               cpumask_and(mask, desc->affinity, map);
+               if (cpumask_any(mask) >= nr_cpu_ids) {
                        printk("Breaking affinity for irq %i\n", irq);
-                       mask = map;
+                       cpumask_copy(mask, map);
                }
                if (desc->chip->set_affinity)
-                       desc->chip->set_affinity(irq, &mask);
+                       desc->chip->set_affinity(irq, mask);
                else if (desc->action && !(warned++))
                        printk("Cannot set affinity for irq %i\n", irq);
        }
 
+       free_cpumask_var(mask);
+
        local_irq_enable();
        mdelay(1);
        local_irq_disable();
index b36f074..c533525 100644 (file)
@@ -114,6 +114,9 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
        regs->msr &= ~MSR_CE;
        mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_IC | DBCR0_IDM);
+#ifdef CONFIG_PPC_47x
+       isync();
+#endif
 #endif
 
        /*
index c2c70e1..50362b6 100644 (file)
@@ -38,7 +38,7 @@
 #include <asm/vio.h>
 #include <asm/mmu.h>
 
-#define MODULE_VERS "1.8"
+#define MODULE_VERS "1.9"
 #define MODULE_NAME "lparcfg"
 
 /* #define LPARCFG_DEBUG */
@@ -487,6 +487,14 @@ static void splpar_dispatch_data(struct seq_file *m)
        seq_printf(m, "dispatch_dispersions=%lu\n", dispatch_dispersions);
 }
 
+static void parse_em_data(struct seq_file *m)
+{
+       unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+
+       if (plpar_hcall(H_GET_EM_PARMS, retbuf) == H_SUCCESS)
+               seq_printf(m, "power_mode_data=%016lx\n", retbuf[0]);
+}
+
 static int pseries_lparcfg_data(struct seq_file *m, void *v)
 {
        int partition_potential_processors;
@@ -541,6 +549,8 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
 
        seq_printf(m, "slb_size=%d\n", mmu_slb_size);
 
+       parse_em_data(m);
+
        return 0;
 }
 
index 040bd1d..26f9900 100644 (file)
@@ -155,33 +155,38 @@ void kexec_copy_flush(struct kimage *image)
 
 #ifdef CONFIG_SMP
 
-/* FIXME: we should schedule this function to be called on all cpus based
- * on calling the interrupts, but we would like to call it off irq level
- * so that the interrupt controller is clean.
- */
+static int kexec_all_irq_disabled = 0;
+
 static void kexec_smp_down(void *arg)
 {
+       local_irq_disable();
+       mb(); /* make sure our irqs are disabled before we say they are */
+       get_paca()->kexec_state = KEXEC_STATE_IRQS_OFF;
+       while(kexec_all_irq_disabled == 0)
+               cpu_relax();
+       mb(); /* make sure all irqs are disabled before this */
+       /*
+        * Now every CPU has IRQs off, we can clear out any pending
+        * IPIs and be sure that no more will come in after this.
+        */
        if (ppc_md.kexec_cpu_down)
                ppc_md.kexec_cpu_down(0, 1);
 
-       local_irq_disable();
        kexec_smp_wait();
        /* NOTREACHED */
 }
 
-static void kexec_prepare_cpus(void)
+static void kexec_prepare_cpus_wait(int wait_state)
 {
        int my_cpu, i, notified=-1;
 
-       smp_call_function(kexec_smp_down, NULL, /* wait */0);
        my_cpu = get_cpu();
-
-       /* check the others cpus are now down (via paca hw cpu id == -1) */
+       /* Make sure each CPU has atleast made it to the state we need */
        for (i=0; i < NR_CPUS; i++) {
                if (i == my_cpu)
                        continue;
 
-               while (paca[i].hw_cpu_id != -1) {
+               while (paca[i].kexec_state < wait_state) {
                        barrier();
                        if (!cpu_possible(i)) {
                                printk("kexec: cpu %d hw_cpu_id %d is not"
@@ -201,20 +206,35 @@ static void kexec_prepare_cpus(void)
                        }
                        if (i != notified) {
                                printk( "kexec: waiting for cpu %d (physical"
-                                               " %d) to go down\n",
-                                               i, paca[i].hw_cpu_id);
+                                               " %d) to enter %i state\n",
+                                       i, paca[i].hw_cpu_id, wait_state);
                                notified = i;
                        }
                }
        }
+       mb();
+}
+
+static void kexec_prepare_cpus(void)
+{
+
+       smp_call_function(kexec_smp_down, NULL, /* wait */0);
+       local_irq_disable();
+       mb(); /* make sure IRQs are disabled before we say they are */
+       get_paca()->kexec_state = KEXEC_STATE_IRQS_OFF;
+
+       kexec_prepare_cpus_wait(KEXEC_STATE_IRQS_OFF);
+       /* we are sure every CPU has IRQs off at this point */
+       kexec_all_irq_disabled = 1;
 
        /* after we tell the others to go down */
        if (ppc_md.kexec_cpu_down)
                ppc_md.kexec_cpu_down(0, 0);
 
-       put_cpu();
+       /* Before removing MMU mapings make sure all CPUs have entered real mode */
+       kexec_prepare_cpus_wait(KEXEC_STATE_REAL_MODE);
 
-       local_irq_disable();
+       put_cpu();
 }
 
 #else /* ! SMP */
index 8649f53..8043d1b 100644 (file)
@@ -441,7 +441,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
        addi    r3,r3,L1_CACHE_BYTES
        bdnz    0b
        sync
-#ifndef CONFIG_44x
+#ifdef CONFIG_44x
        /* We don't flush the icache on 44x. Those have a virtual icache
         * and we don't have access to the virtual address here (it's
         * not the page vaddr but where it's mapped in user space). The
@@ -449,15 +449,19 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
         * a change in the address space occurs, before returning to
         * user space
         */
+BEGIN_MMU_FTR_SECTION
+       blr
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_44x)
+#endif /* CONFIG_44x */
        mtctr   r4
 1:     icbi    0,r6
        addi    r6,r6,L1_CACHE_BYTES
        bdnz    1b
        sync
        isync
-#endif /* CONFIG_44x */
        blr
 
+#ifndef CONFIG_BOOKE
 /*
  * Flush a particular page from the data cache to RAM, identified
  * by its physical address.  We turn off the MMU so we can just use
@@ -490,6 +494,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
        mtmsr   r10                             /* restore DR */
        isync
        blr
+#endif /* CONFIG_BOOKE */
 
 /*
  * Clear pages using the dcbz instruction, which doesn't cause any
index a5cf9c1..a2b18df 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/cputable.h>
 #include <asm/thread_info.h>
+#include <asm/kexec.h>
 
        .text
 
@@ -471,6 +472,10 @@ _GLOBAL(kexec_wait)
 1:     mflr    r5
        addi    r5,r5,kexec_flag-1b
 
+       li      r4,KEXEC_STATE_REAL_MODE
+       stb     r4,PACAKEXECSTATE(r13)
+       SYNC
+
 99:    HMT_LOW
 #ifdef CONFIG_KEXEC            /* use no memory without kexec */
        lwz     r4,0(r5)
@@ -494,14 +499,11 @@ kexec_flag:
  * note: this is a terminal routine, it does not save lr
  *
  * get phys id from paca
- * set paca id to -1 to say we got here
  * switch to real mode
  * join other cpus in kexec_wait(phys_id)
  */
 _GLOBAL(kexec_smp_wait)
        lhz     r3,PACAHWCPUID(r13)
-       li      r4,-1
-       sth     r4,PACAHWCPUID(r13)     /* let others know we left */
        bl      real_mode
        b       .kexec_wait
 
index 0c40c6f..f88acf0 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/pgtable.h>
 #include <asm/iseries/lpar_map.h>
 #include <asm/iseries/hv_types.h>
+#include <asm/kexec.h>
 
 /* This symbol is provided by the linker - let it fill in the paca
  * field correctly */
@@ -97,6 +98,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
        new_paca->kernelbase = (unsigned long) _stext;
        new_paca->kernel_msr = MSR_KERNEL;
        new_paca->hw_cpu_id = 0xffff;
+       new_paca->kexec_state = KEXEC_STATE_NONE;
        new_paca->__current = &init_task;
 #ifdef CONFIG_PPC_STD_MMU_64
        new_paca->slb_shadow_ptr = &slb_shadow[cpu];
index cd11d5c..6ddb795 100644 (file)
@@ -310,6 +310,8 @@ static void __devinit __of_scan_bus(struct device_node *node,
        /* Scan direct children */
        for_each_child_of_node(node, child) {
                pr_debug("  * %s\n", child->full_name);
+               if (!of_device_is_available(child))
+                       continue;
                reg = of_get_property(child, "reg", &reglen);
                if (reg == NULL || reglen < 20)
                        continue;
index e4d71ce..9d255b4 100644 (file)
@@ -371,6 +371,9 @@ int set_dabr(unsigned long dabr)
        /* XXX should we have a CPU_FTR_HAS_DABR ? */
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
        mtspr(SPRN_DAC1, dabr);
+#ifdef CONFIG_PPC_47x
+       isync();
+#endif
 #elif defined(CONFIG_PPC_BOOK3S)
        mtspr(SPRN_DABR, dabr);
 #endif
index ed2cfe1..7a0c019 100644 (file)
 #include <asm/pgtable.h>
 #include <asm/system.h>
 
+/*
+ * The parameter save area on the stack is used to store arguments being passed
+ * to callee function and is located at fixed offset from stack pointer.
+ */
+#ifdef CONFIG_PPC32
+#define PARAMETER_SAVE_AREA_OFFSET     24  /* bytes */
+#else /* CONFIG_PPC32 */
+#define PARAMETER_SAVE_AREA_OFFSET     48  /* bytes */
+#endif
+
+struct pt_regs_offset {
+       const char *name;
+       int offset;
+};
+
+#define STR(s) #s                      /* convert to string */
+#define REG_OFFSET_NAME(r) {.name = #r, .offset = offsetof(struct pt_regs, r)}
+#define GPR_OFFSET_NAME(num)   \
+       {.name = STR(gpr##num), .offset = offsetof(struct pt_regs, gpr[num])}
+#define REG_OFFSET_END {.name = NULL, .offset = 0}
+
+static const struct pt_regs_offset regoffset_table[] = {
+       GPR_OFFSET_NAME(0),
+       GPR_OFFSET_NAME(1),
+       GPR_OFFSET_NAME(2),
+       GPR_OFFSET_NAME(3),
+       GPR_OFFSET_NAME(4),
+       GPR_OFFSET_NAME(5),
+       GPR_OFFSET_NAME(6),
+       GPR_OFFSET_NAME(7),
+       GPR_OFFSET_NAME(8),
+       GPR_OFFSET_NAME(9),
+       GPR_OFFSET_NAME(10),
+       GPR_OFFSET_NAME(11),
+       GPR_OFFSET_NAME(12),
+       GPR_OFFSET_NAME(13),
+       GPR_OFFSET_NAME(14),
+       GPR_OFFSET_NAME(15),
+       GPR_OFFSET_NAME(16),
+       GPR_OFFSET_NAME(17),
+       GPR_OFFSET_NAME(18),
+       GPR_OFFSET_NAME(19),
+       GPR_OFFSET_NAME(20),
+       GPR_OFFSET_NAME(21),
+       GPR_OFFSET_NAME(22),
+       GPR_OFFSET_NAME(23),
+       GPR_OFFSET_NAME(24),
+       GPR_OFFSET_NAME(25),
+       GPR_OFFSET_NAME(26),
+       GPR_OFFSET_NAME(27),
+       GPR_OFFSET_NAME(28),
+       GPR_OFFSET_NAME(29),
+       GPR_OFFSET_NAME(30),
+       GPR_OFFSET_NAME(31),
+       REG_OFFSET_NAME(nip),
+       REG_OFFSET_NAME(msr),
+       REG_OFFSET_NAME(ctr),
+       REG_OFFSET_NAME(link),
+       REG_OFFSET_NAME(xer),
+       REG_OFFSET_NAME(ccr),
+#ifdef CONFIG_PPC64
+       REG_OFFSET_NAME(softe),
+#else
+       REG_OFFSET_NAME(mq),
+#endif
+       REG_OFFSET_NAME(trap),
+       REG_OFFSET_NAME(dar),
+       REG_OFFSET_NAME(dsisr),
+       REG_OFFSET_END,
+};
+
+/**
+ * regs_query_register_offset() - query register offset from its name
+ * @name:      the name of a register
+ *
+ * regs_query_register_offset() returns the offset of a register in struct
+ * pt_regs from its name. If the name is invalid, this returns -EINVAL;
+ */
+int regs_query_register_offset(const char *name)
+{
+       const struct pt_regs_offset *roff;
+       for (roff = regoffset_table; roff->name != NULL; roff++)
+               if (!strcmp(roff->name, name))
+                       return roff->offset;
+       return -EINVAL;
+}
+
+/**
+ * regs_query_register_name() - query register name from its offset
+ * @offset:    the offset of a register in struct pt_regs.
+ *
+ * regs_query_register_name() returns the name of a register from its
+ * offset in struct pt_regs. If the @offset is invalid, this returns NULL;
+ */
+const char *regs_query_register_name(unsigned int offset)
+{
+       const struct pt_regs_offset *roff;
+       for (roff = regoffset_table; roff->name != NULL; roff++)
+               if (roff->offset == offset)
+                       return roff->name;
+       return NULL;
+}
+
 /*
  * does not yet catch signals sent when the child dies.
  * in exit.c or in signal.c.
index 7436784..0e1ec6f 100644 (file)
@@ -691,10 +691,14 @@ void rtas_os_term(char *str)
 {
        int status;
 
-       if (panic_timeout)
-               return;
-
-       if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term"))
+       /*
+        * Firmware with the ibm,extended-os-term property is guaranteed
+        * to always return from an ibm,os-term call. Earlier versions without
+        * this property may terminate the partition which we want to avoid
+        * since it interferes with panic_timeout.
+        */
+       if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term") ||
+           RTAS_UNKNOWN_SERVICE == rtas_token("ibm,extended-os-term"))
                return;
 
        snprintf(rtas_os_term_buf, 2048, "OS panic: %s", str);
@@ -705,8 +709,7 @@ void rtas_os_term(char *str)
        } while (rtas_busy_delay(status));
 
        if (status != 0)
-               printk(KERN_EMERG "ibm,os-term call failed %d\n",
-                              status);
+               printk(KERN_EMERG "ibm,os-term call failed %d\n", status);
 }
 
 static int ibm_suspend_me_token = RTAS_UNKNOWN_SERVICE;
index 4190eae..638883e 100644 (file)
@@ -411,9 +411,9 @@ static void rtas_event_scan(struct work_struct *w)
 
        get_online_cpus();
 
-       cpu = next_cpu(smp_processor_id(), cpu_online_map);
-       if (cpu == NR_CPUS) {
-               cpu = first_cpu(cpu_online_map);
+       cpu = cpumask_next(smp_processor_id(), cpu_online_mask);
+        if (cpu >= nr_cpu_ids) {
+               cpu = cpumask_first(cpu_online_mask);
 
                if (first_pass) {
                        first_pass = 0;
@@ -466,8 +466,8 @@ static void start_event_scan(void)
        /* Retreive errors from nvram if any */
        retreive_nvram_error_log();
 
-       schedule_delayed_work_on(first_cpu(cpu_online_map), &event_scan_work,
-                                event_scan_delay);
+       schedule_delayed_work_on(cpumask_first(cpu_online_mask),
+                                &event_scan_work, event_scan_delay);
 }
 
 static int __init rtas_init(void)
@@ -490,6 +490,12 @@ static int __init rtas_init(void)
                return -ENODEV;
        }
 
+       if (!rtas_event_scan_rate) {
+               /* Broken firmware: take a rate of zero to mean don't scan */
+               printk(KERN_DEBUG "rtasd: scan rate is 0, not scanning\n");
+               return 0;
+       }
+
        /* Make room for the sequence number */
        rtas_error_log_max = rtas_get_error_log_max();
        rtas_error_log_buffer_max = rtas_error_log_max + sizeof(int);
index 48f0a00..5e4d852 100644 (file)
@@ -161,45 +161,44 @@ extern u32 cpu_temp_both(unsigned long cpu);
 DEFINE_PER_CPU(unsigned int, cpu_pvr);
 #endif
 
-static int show_cpuinfo(struct seq_file *m, void *v)
+static void show_cpuinfo_summary(struct seq_file *m)
 {
-       unsigned long cpu_id = (unsigned long)v - 1;
-       unsigned int pvr;
-       unsigned short maj;
-       unsigned short min;
-
-       if (cpu_id == NR_CPUS) {
-               struct device_node *root;
-               const char *model = NULL;
+       struct device_node *root;
+       const char *model = NULL;
 #if defined(CONFIG_SMP) && defined(CONFIG_PPC32)
-               unsigned long bogosum = 0;
-               int i;
-               for_each_online_cpu(i)
-                       bogosum += loops_per_jiffy;
-               seq_printf(m, "total bogomips\t: %lu.%02lu\n",
-                          bogosum/(500000/HZ), bogosum/(5000/HZ) % 100);
+       unsigned long bogosum = 0;
+       int i;
+       for_each_online_cpu(i)
+               bogosum += loops_per_jiffy;
+       seq_printf(m, "total bogomips\t: %lu.%02lu\n",
+                  bogosum/(500000/HZ), bogosum/(5000/HZ) % 100);
 #endif /* CONFIG_SMP && CONFIG_PPC32 */
-               seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq);
-               if (ppc_md.name)
-                       seq_printf(m, "platform\t: %s\n", ppc_md.name);
-               root = of_find_node_by_path("/");
-               if (root)
-                       model = of_get_property(root, "model", NULL);
-               if (model)
-                       seq_printf(m, "model\t\t: %s\n", model);
-               of_node_put(root);
-
-               if (ppc_md.show_cpuinfo != NULL)
-                       ppc_md.show_cpuinfo(m);
+       seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq);
+       if (ppc_md.name)
+               seq_printf(m, "platform\t: %s\n", ppc_md.name);
+       root = of_find_node_by_path("/");
+       if (root)
+               model = of_get_property(root, "model", NULL);
+       if (model)
+               seq_printf(m, "model\t\t: %s\n", model);
+       of_node_put(root);
+
+       if (ppc_md.show_cpuinfo != NULL)
+               ppc_md.show_cpuinfo(m);
 
 #ifdef CONFIG_PPC32
-               /* Display the amount of memory */
-               seq_printf(m, "Memory\t\t: %d MB\n",
-                          (unsigned int)(total_memory / (1024 * 1024)));
+       /* Display the amount of memory */
+       seq_printf(m, "Memory\t\t: %d MB\n",
+                  (unsigned int)(total_memory / (1024 * 1024)));
 #endif
+}
 
-               return 0;
-       }
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+       unsigned long cpu_id = (unsigned long)v - 1;
+       unsigned int pvr;
+       unsigned short maj;
+       unsigned short min;
 
        /* We only show online cpus: disable preempt (overzealous, I
         * knew) to prevent cpu going down. */
@@ -308,19 +307,28 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 #endif
 
        preempt_enable();
+
+       /* If this is the last cpu, print the summary */
+       if (cpumask_next(cpu_id, cpu_online_mask) >= nr_cpu_ids)
+               show_cpuinfo_summary(m);
+
        return 0;
 }
 
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
-       unsigned long i = *pos;
-
-       return i <= NR_CPUS ? (void *)(i + 1) : NULL;
+       if (*pos == 0)  /* just in case, cpu 0 is not the first */
+               *pos = cpumask_first(cpu_online_mask);
+       else
+               *pos = cpumask_next(*pos - 1, cpu_online_mask);
+       if ((*pos) < nr_cpu_ids)
+               return (void *)(unsigned long)(*pos + 1);
+       return NULL;
 }
 
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 {
-       ++*pos;
+       (*pos)++;
        return c_start(m, pos);
 }
 
@@ -386,14 +394,14 @@ static void __init cpu_init_thread_core_maps(int tpc)
 
 /**
  * setup_cpu_maps - initialize the following cpu maps:
- *                  cpu_possible_map
- *                  cpu_present_map
+ *                  cpu_possible_mask
+ *                  cpu_present_mask
  *
  * Having the possible map set up early allows us to restrict allocations
  * of things like irqstacks to num_possible_cpus() rather than NR_CPUS.
  *
  * We do not initialize the online map here; cpus set their own bits in
- * cpu_online_map as they come up.
+ * cpu_online_mask as they come up.
  *
  * This function is valid only for Open Firmware systems.  finish_device_tree
  * must be called before using this.
index 9143891..f3fb5a7 100644 (file)
@@ -424,9 +424,18 @@ void __init setup_system(void)
        DBG(" <- setup_system()\n");
 }
 
+static u64 slb0_limit(void)
+{
+       if (cpu_has_feature(CPU_FTR_1T_SEGMENT)) {
+               return 1UL << SID_SHIFT_1T;
+       }
+       return 1UL << SID_SHIFT;
+}
+
 #ifdef CONFIG_IRQSTACKS
 static void __init irqstack_early_init(void)
 {
+       u64 limit = slb0_limit();
        unsigned int i;
 
        /*
@@ -436,10 +445,10 @@ static void __init irqstack_early_init(void)
        for_each_possible_cpu(i) {
                softirq_ctx[i] = (struct thread_info *)
                        __va(lmb_alloc_base(THREAD_SIZE,
-                                           THREAD_SIZE, 0x10000000));
+                                           THREAD_SIZE, limit));
                hardirq_ctx[i] = (struct thread_info *)
                        __va(lmb_alloc_base(THREAD_SIZE,
-                                           THREAD_SIZE, 0x10000000));
+                                           THREAD_SIZE, limit));
        }
 }
 #else
@@ -470,7 +479,7 @@ static void __init exc_lvl_early_init(void)
  */
 static void __init emergency_stack_init(void)
 {
-       unsigned long limit;
+       u64 limit;
        unsigned int i;
 
        /*
@@ -482,7 +491,7 @@ static void __init emergency_stack_init(void)
         * bringup, we need to get at them in real mode. This means they
         * must also be within the RMO region.
         */
-       limit = min(0x10000000ULL, lmb.rmo_size);
+       limit = min(slb0_limit(), lmb.rmo_size);
 
        for_each_possible_cpu(i) {
                unsigned long sp;
@@ -573,12 +582,6 @@ void ppc64_boot_msg(unsigned int src, const char *msg)
        printk("[boot]%04x %s\n", src, msg);
 }
 
-void cpu_die(void)
-{
-       if (ppc_md.cpu_die)
-               ppc_md.cpu_die();
-}
-
 #ifdef CONFIG_SMP
 #define PCPU_DYN_SIZE          ()
 
index c2ee144..5c196d1 100644 (file)
@@ -59,8 +59,8 @@
 
 struct thread_info *secondary_ti;
 
-DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE;
-DEFINE_PER_CPU(cpumask_t, cpu_core_map) = CPU_MASK_NONE;
+DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map);
+DEFINE_PER_CPU(cpumask_var_t, cpu_core_map);
 
 EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
 EXPORT_PER_CPU_SYMBOL(cpu_core_map);
@@ -271,6 +271,16 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
        smp_store_cpu_info(boot_cpuid);
        cpu_callin_map[boot_cpuid] = 1;
 
+       for_each_possible_cpu(cpu) {
+               zalloc_cpumask_var_node(&per_cpu(cpu_sibling_map, cpu),
+                                       GFP_KERNEL, cpu_to_node(cpu));
+               zalloc_cpumask_var_node(&per_cpu(cpu_core_map, cpu),
+                                       GFP_KERNEL, cpu_to_node(cpu));
+       }
+
+       cpumask_set_cpu(boot_cpuid, cpu_sibling_mask(boot_cpuid));
+       cpumask_set_cpu(boot_cpuid, cpu_core_mask(boot_cpuid));
+
        if (smp_ops)
                if (smp_ops->probe)
                        max_cpus = smp_ops->probe();
@@ -289,10 +299,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
 void __devinit smp_prepare_boot_cpu(void)
 {
        BUG_ON(smp_processor_id() != boot_cpuid);
-
-       set_cpu_online(boot_cpuid, true);
-       cpu_set(boot_cpuid, per_cpu(cpu_sibling_map, boot_cpuid));
-       cpu_set(boot_cpuid, per_cpu(cpu_core_map, boot_cpuid));
 #ifdef CONFIG_PPC64
        paca[boot_cpuid].__current = current;
 #endif
@@ -313,7 +319,7 @@ int generic_cpu_disable(void)
        set_cpu_online(cpu, false);
 #ifdef CONFIG_PPC64
        vdso_data->processorCount--;
-       fixup_irqs(cpu_online_map);
+       fixup_irqs(cpu_online_mask);
 #endif
        return 0;
 }
@@ -333,7 +339,7 @@ int generic_cpu_enable(unsigned int cpu)
                cpu_relax();
 
 #ifdef CONFIG_PPC64
-       fixup_irqs(cpu_online_map);
+       fixup_irqs(cpu_online_mask);
        /* counter the irq disable in fixup_irqs */
        local_irq_enable();
 #endif
@@ -462,7 +468,7 @@ out:
        return id;
 }
 
-/* Must be called when no change can occur to cpu_present_map,
+/* Must be called when no change can occur to cpu_present_mask,
  * i.e. during cpu online or offline.
  */
 static struct device_node *cpu_to_l2cache(int cpu)
@@ -495,6 +501,14 @@ int __devinit start_secondary(void *unused)
        current->active_mm = &init_mm;
 
        smp_store_cpu_info(cpu);
+
+#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
+       /* Clear any pending timer interrupts */
+       mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_DIS | TSR_FIS);
+
+       /* Enable decrementer interrupt */
+       mtspr(SPRN_TCR, TCR_DIE);
+#endif
        set_dec(tb_ticks_per_jiffy);
        preempt_disable();
        cpu_callin_map[cpu] = 1;
@@ -517,15 +531,15 @@ int __devinit start_secondary(void *unused)
        for (i = 0; i < threads_per_core; i++) {
                if (cpu_is_offline(base + i))
                        continue;
-               cpu_set(cpu, per_cpu(cpu_sibling_map, base + i));
-               cpu_set(base + i, per_cpu(cpu_sibling_map, cpu));
+               cpumask_set_cpu(cpu, cpu_sibling_mask(base + i));
+               cpumask_set_cpu(base + i, cpu_sibling_mask(cpu));
 
                /* cpu_core_map should be a superset of
                 * cpu_sibling_map even if we don't have cache
                 * information, so update the former here, too.
                 */
-               cpu_set(cpu, per_cpu(cpu_core_map, base +i));
-               cpu_set(base + i, per_cpu(cpu_core_map, cpu));
+               cpumask_set_cpu(cpu, cpu_core_mask(base + i));
+               cpumask_set_cpu(base + i, cpu_core_mask(cpu));
        }
        l2_cache = cpu_to_l2cache(cpu);
        for_each_online_cpu(i) {
@@ -533,8 +547,8 @@ int __devinit start_secondary(void *unused)
                if (!np)
                        continue;
                if (np == l2_cache) {
-                       cpu_set(cpu, per_cpu(cpu_core_map, i));
-                       cpu_set(i, per_cpu(cpu_core_map, cpu));
+                       cpumask_set_cpu(cpu, cpu_core_mask(i));
+                       cpumask_set_cpu(i, cpu_core_mask(cpu));
                }
                of_node_put(np);
        }
@@ -554,19 +568,22 @@ int setup_profiling_timer(unsigned int multiplier)
 
 void __init smp_cpus_done(unsigned int max_cpus)
 {
-       cpumask_t old_mask;
+       cpumask_var_t old_mask;
 
        /* We want the setup_cpu() here to be called from CPU 0, but our
         * init thread may have been "borrowed" by another CPU in the meantime
         * se we pin us down to CPU 0 for a short while
         */
-       old_mask = current->cpus_allowed;
-       set_cpus_allowed(current, cpumask_of_cpu(boot_cpuid));
+       alloc_cpumask_var(&old_mask, GFP_NOWAIT);
+       cpumask_copy(old_mask, &current->cpus_allowed);
+       set_cpus_allowed_ptr(current, cpumask_of(boot_cpuid));
        
        if (smp_ops && smp_ops->setup_cpu)
                smp_ops->setup_cpu(boot_cpuid);
 
-       set_cpus_allowed(current, old_mask);
+       set_cpus_allowed_ptr(current, old_mask);
+
+       free_cpumask_var(old_mask);
 
        snapshot_timebases();
 
@@ -591,10 +608,10 @@ int __cpu_disable(void)
        /* Update sibling maps */
        base = cpu_first_thread_in_core(cpu);
        for (i = 0; i < threads_per_core; i++) {
-               cpu_clear(cpu, per_cpu(cpu_sibling_map, base + i));
-               cpu_clear(base + i, per_cpu(cpu_sibling_map, cpu));
-               cpu_clear(cpu, per_cpu(cpu_core_map, base +i));
-               cpu_clear(base + i, per_cpu(cpu_core_map, cpu));
+               cpumask_clear_cpu(cpu, cpu_sibling_mask(base + i));
+               cpumask_clear_cpu(base + i, cpu_sibling_mask(cpu));
+               cpumask_clear_cpu(cpu, cpu_core_mask(base + i));
+               cpumask_clear_cpu(base + i, cpu_core_mask(cpu));
        }
 
        l2_cache = cpu_to_l2cache(cpu);
@@ -603,8 +620,8 @@ int __cpu_disable(void)
                if (!np)
                        continue;
                if (np == l2_cache) {
-                       cpu_clear(cpu, per_cpu(cpu_core_map, i));
-                       cpu_clear(i, per_cpu(cpu_core_map, cpu));
+                       cpumask_clear_cpu(cpu, cpu_core_mask(i));
+                       cpumask_clear_cpu(i, cpu_core_mask(cpu));
                }
                of_node_put(np);
        }
@@ -631,4 +648,10 @@ void cpu_hotplug_driver_unlock()
 {
        mutex_unlock(&powerpc_cpu_hotplug_driver_mutex);
 }
+
+void cpu_die(void)
+{
+       if (ppc_md.cpu_die)
+               ppc_md.cpu_die();
+}
 #endif
index e235e52..c0d8c20 100644 (file)
@@ -35,7 +35,7 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices);
 #ifdef CONFIG_PPC64
 
 /* Time in microseconds we delay before sleeping in the idle loop */
-DEFINE_PER_CPU(unsigned long, smt_snooze_delay) = { 100 };
+DEFINE_PER_CPU(long, smt_snooze_delay) = { 100 };
 
 static ssize_t store_smt_snooze_delay(struct sys_device *dev,
                                      struct sysdev_attribute *attr,
@@ -44,9 +44,9 @@ static ssize_t store_smt_snooze_delay(struct sys_device *dev,
 {
        struct cpu *cpu = container_of(dev, struct cpu, sysdev);
        ssize_t ret;
-       unsigned long snooze;
+       long snooze;
 
-       ret = sscanf(buf, "%lu", &snooze);
+       ret = sscanf(buf, "%ld", &snooze);
        if (ret != 1)
                return -EINVAL;
 
@@ -61,53 +61,23 @@ static ssize_t show_smt_snooze_delay(struct sys_device *dev,
 {
        struct cpu *cpu = container_of(dev, struct cpu, sysdev);
 
-       return sprintf(buf, "%lu\n", per_cpu(smt_snooze_delay, cpu->sysdev.id));
+       return sprintf(buf, "%ld\n", per_cpu(smt_snooze_delay, cpu->sysdev.id));
 }
 
 static SYSDEV_ATTR(smt_snooze_delay, 0644, show_smt_snooze_delay,
                   store_smt_snooze_delay);
 
-/* Only parse OF options if the matching cmdline option was not specified */
-static int smt_snooze_cmdline;
-
-static int __init smt_setup(void)
-{
-       struct device_node *options;
-       const unsigned int *val;
-       unsigned int cpu;
-
-       if (!cpu_has_feature(CPU_FTR_SMT))
-               return -ENODEV;
-
-       options = of_find_node_by_path("/options");
-       if (!options)
-               return -ENODEV;
-
-       val = of_get_property(options, "ibm,smt-snooze-delay", NULL);
-       if (!smt_snooze_cmdline && val) {
-               for_each_possible_cpu(cpu)
-                       per_cpu(smt_snooze_delay, cpu) = *val;
-       }
-
-       of_node_put(options);
-       return 0;
-}
-__initcall(smt_setup);
-
 static int __init setup_smt_snooze_delay(char *str)
 {
        unsigned int cpu;
-       int snooze;
+       long snooze;
 
        if (!cpu_has_feature(CPU_FTR_SMT))
                return 1;
 
-       smt_snooze_cmdline = 1;
-
-       if (get_option(&str, &snooze)) {
-               for_each_possible_cpu(cpu)
-                       per_cpu(smt_snooze_delay, cpu) = snooze;
-       }
+       snooze = simple_strtol(str, NULL, 10);
+       for_each_possible_cpu(cpu)
+               per_cpu(smt_snooze_delay, cpu) = snooze;
 
        return 1;
 }
index b6859aa..3031fc7 100644 (file)
@@ -380,6 +380,46 @@ int machine_check_440A(struct pt_regs *regs)
        }
        return 0;
 }
+
+int machine_check_47x(struct pt_regs *regs)
+{
+       unsigned long reason = get_mc_reason(regs);
+       u32 mcsr;
+
+       printk(KERN_ERR "Machine check in kernel mode.\n");
+       if (reason & ESR_IMCP) {
+               printk(KERN_ERR
+                      "Instruction Synchronous Machine Check exception\n");
+               mtspr(SPRN_ESR, reason & ~ESR_IMCP);
+               return 0;
+       }
+       mcsr = mfspr(SPRN_MCSR);
+       if (mcsr & MCSR_IB)
+               printk(KERN_ERR "Instruction Read PLB Error\n");
+       if (mcsr & MCSR_DRB)
+               printk(KERN_ERR "Data Read PLB Error\n");
+       if (mcsr & MCSR_DWB)
+               printk(KERN_ERR "Data Write PLB Error\n");
+       if (mcsr & MCSR_TLBP)
+               printk(KERN_ERR "TLB Parity Error\n");
+       if (mcsr & MCSR_ICP) {
+               flush_instruction_cache();
+               printk(KERN_ERR "I-Cache Parity Error\n");
+       }
+       if (mcsr & MCSR_DCSP)
+               printk(KERN_ERR "D-Cache Search Parity Error\n");
+       if (mcsr & PPC47x_MCSR_GPR)
+               printk(KERN_ERR "GPR Parity Error\n");
+       if (mcsr & PPC47x_MCSR_FPR)
+               printk(KERN_ERR "FPR Parity Error\n");
+       if (mcsr & PPC47x_MCSR_IPR)
+               printk(KERN_ERR "Machine Check exception is imprecise\n");
+
+       /* Clear MCSR */
+       mtspr(SPRN_MCSR, mcsr);
+
+       return 0;
+}
 #elif defined(CONFIG_E500)
 int machine_check_e500(struct pt_regs *regs)
 {
index 8223717..9ce7b62 100644 (file)
@@ -645,8 +645,10 @@ void vio_cmo_set_dev_desired(struct vio_dev *viodev, size_t desired)
                        found = 1;
                        break;
                }
-       if (!found)
+       if (!found) {
+               spin_unlock_irqrestore(&vio_cmo.lock, flags);
                return;
+       }
 
        /* Increase/decrease in desired device entitlement */
        if (desired >= viodev->cmo.desired) {
@@ -958,9 +960,12 @@ viodev_cmo_rd_attr(allocated);
 
 static ssize_t name_show(struct device *, struct device_attribute *, char *);
 static ssize_t devspec_show(struct device *, struct device_attribute *, char *);
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
+                            char *buf);
 static struct device_attribute vio_cmo_dev_attrs[] = {
        __ATTR_RO(name),
        __ATTR_RO(devspec),
+       __ATTR_RO(modalias),
        __ATTR(cmo_desired,       S_IWUSR|S_IRUSR|S_IWGRP|S_IRGRP|S_IROTH,
               viodev_cmo_desired_show, viodev_cmo_desired_set),
        __ATTR(cmo_entitled,      S_IRUGO, viodev_cmo_entitled_show,      NULL),
@@ -1320,9 +1325,27 @@ static ssize_t devspec_show(struct device *dev,
        return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none");
 }
 
+static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
+                            char *buf)
+{
+       const struct vio_dev *vio_dev = to_vio_dev(dev);
+       struct device_node *dn;
+       const char *cp;
+
+       dn = dev->archdata.of_node;
+       if (!dn)
+               return -ENODEV;
+       cp = of_get_property(dn, "compatible", NULL);
+       if (!cp)
+               return -ENODEV;
+
+       return sprintf(buf, "vio:T%sS%s\n", vio_dev->type, cp);
+}
+
 static struct device_attribute vio_dev_attrs[] = {
        __ATTR_RO(name),
        __ATTR_RO(devspec),
+       __ATTR_RO(modalias),
        __ATTR_NULL
 };
 
@@ -1365,6 +1388,7 @@ static struct bus_type vio_bus_type = {
        .match = vio_bus_match,
        .probe = vio_bus_probe,
        .remove = vio_bus_remove,
+       .pm = GENERIC_SUBSYS_PM_OPS,
 };
 
 /**
index 64e2e49..455881a 100644 (file)
@@ -28,7 +28,7 @@ _GLOBAL(strcpy)
 /* This clears out any unused part of the destination buffer,
    just as the libc version does.  -- paulus */
 _GLOBAL(strncpy)
-       cmpwi   0,r5,0
+       PPC_LCMPI 0,r5,0
        beqlr
        mtctr   r5
        addi    r6,r3,-1
@@ -39,7 +39,7 @@ _GLOBAL(strncpy)
        bdnzf   2,1b            /* dec ctr, branch if ctr != 0 && !cr0.eq */
        bnelr                   /* if we didn't hit a null char, we're done */
        mfctr   r5
-       cmpwi   0,r5,0          /* any space left in destination buffer? */
+       PPC_LCMPI 0,r5,0        /* any space left in destination buffer? */
        beqlr                   /* we know r0 == 0 here */
 2:     stbu    r0,1(r6)        /* clear it out if so */
        bdnz    2b
@@ -70,8 +70,8 @@ _GLOBAL(strcmp)
        blr
 
 _GLOBAL(strncmp)
-       PPC_LCMPI r5,0
-       beqlr
+       PPC_LCMPI 0,r5,0
+       beq-    2f
        mtctr   r5
        addi    r5,r3,-1
        addi    r4,r4,-1
@@ -82,6 +82,8 @@ _GLOBAL(strncmp)
        beqlr   1
        bdnzt   eq,1b
        blr
+2:     li      r3,0
+       blr
 
 _GLOBAL(strlen)
        addi    r4,r3,-1
@@ -92,8 +94,8 @@ _GLOBAL(strlen)
        blr
 
 _GLOBAL(memcmp)
-       cmpwi   0,r5,0
-       ble-    2f
+       PPC_LCMPI 0,r5,0
+       beq-    2f
        mtctr   r5
        addi    r6,r3,-1
        addi    r4,r4,-1
@@ -106,8 +108,8 @@ _GLOBAL(memcmp)
        blr
 
 _GLOBAL(memchr)
-       cmpwi   0,r5,0
-       ble-    2f
+       PPC_LCMPI 0,r5,0
+       beq-    2f
        mtctr   r5
        addi    r3,r3,-1
 1:     lbzu    r0,1(r3)
index 3986264..d8c6efb 100644 (file)
@@ -38,7 +38,9 @@ unsigned int tlb_44x_index; /* = 0 */
 unsigned int tlb_44x_hwater = PPC44x_TLB_SIZE - 1 - PPC44x_EARLY_TLBS;
 int icache_44x_need_flush;
 
-static void __init ppc44x_update_tlb_hwater(void)
+unsigned long tlb_47x_boltmap[1024/8];
+
+static void __cpuinit ppc44x_update_tlb_hwater(void)
 {
        extern unsigned int tlb_44x_patch_hwater_D[];
        extern unsigned int tlb_44x_patch_hwater_I[];
@@ -59,7 +61,7 @@ static void __init ppc44x_update_tlb_hwater(void)
 }
 
 /*
- * "Pins" a 256MB TLB entry in AS0 for kernel lowmem
+ * "Pins" a 256MB TLB entry in AS0 for kernel lowmem for 44x type MMU
  */
 static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys)
 {
@@ -67,12 +69,18 @@ static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys)
 
        ppc44x_update_tlb_hwater();
 
+       mtspr(SPRN_MMUCR, 0);
+
        __asm__ __volatile__(
                "tlbwe  %2,%3,%4\n"
                "tlbwe  %1,%3,%5\n"
                "tlbwe  %0,%3,%6\n"
        :
+#ifdef CONFIG_PPC47x
+       : "r" (PPC47x_TLB2_S_RWX),
+#else
        : "r" (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G),
+#endif
          "r" (phys),
          "r" (virt | PPC44x_TLB_VALID | PPC44x_TLB_256M),
          "r" (entry),
@@ -81,8 +89,93 @@ static void __init ppc44x_pin_tlb(unsigned int virt, unsigned int phys)
          "i" (PPC44x_TLB_ATTRIB));
 }
 
+static int __init ppc47x_find_free_bolted(void)
+{
+       unsigned int mmube0 = mfspr(SPRN_MMUBE0);
+       unsigned int mmube1 = mfspr(SPRN_MMUBE1);
+
+       if (!(mmube0 & MMUBE0_VBE0))
+               return 0;
+       if (!(mmube0 & MMUBE0_VBE1))
+               return 1;
+       if (!(mmube0 & MMUBE0_VBE2))
+               return 2;
+       if (!(mmube1 & MMUBE1_VBE3))
+               return 3;
+       if (!(mmube1 & MMUBE1_VBE4))
+               return 4;
+       if (!(mmube1 & MMUBE1_VBE5))
+               return 5;
+       return -1;
+}
+
+static void __init ppc47x_update_boltmap(void)
+{
+       unsigned int mmube0 = mfspr(SPRN_MMUBE0);
+       unsigned int mmube1 = mfspr(SPRN_MMUBE1);
+
+       if (mmube0 & MMUBE0_VBE0)
+               __set_bit((mmube0 >> MMUBE0_IBE0_SHIFT) & 0xff,
+                         tlb_47x_boltmap);
+       if (mmube0 & MMUBE0_VBE1)
+               __set_bit((mmube0 >> MMUBE0_IBE1_SHIFT) & 0xff,
+                         tlb_47x_boltmap);
+       if (mmube0 & MMUBE0_VBE2)
+               __set_bit((mmube0 >> MMUBE0_IBE2_SHIFT) & 0xff,
+                         tlb_47x_boltmap);
+       if (mmube1 & MMUBE1_VBE3)
+               __set_bit((mmube1 >> MMUBE1_IBE3_SHIFT) & 0xff,
+                         tlb_47x_boltmap);
+       if (mmube1 & MMUBE1_VBE4)
+               __set_bit((mmube1 >> MMUBE1_IBE4_SHIFT) & 0xff,
+                         tlb_47x_boltmap);
+       if (mmube1 & MMUBE1_VBE5)
+               __set_bit((mmube1 >> MMUBE1_IBE5_SHIFT) & 0xff,
+                         tlb_47x_boltmap);
+}
+
+/*
+ * "Pins" a 256MB TLB entry in AS0 for kernel lowmem for 47x type MMU
+ */
+static void __cpuinit ppc47x_pin_tlb(unsigned int virt, unsigned int phys)
+{
+       unsigned int rA;
+       int bolted;
+
+       /* Base rA is HW way select, way 0, bolted bit set */
+       rA = 0x88000000;
+
+       /* Look for a bolted entry slot */
+       bolted = ppc47x_find_free_bolted();
+       BUG_ON(bolted < 0);
+
+       /* Insert bolted slot number */
+       rA |= bolted << 24;
+
+       pr_debug("256M TLB entry for 0x%08x->0x%08x in bolt slot %d\n",
+                virt, phys, bolted);
+
+       mtspr(SPRN_MMUCR, 0);
+
+       __asm__ __volatile__(
+               "tlbwe  %2,%3,0\n"
+               "tlbwe  %1,%3,1\n"
+               "tlbwe  %0,%3,2\n"
+               :
+               : "r" (PPC47x_TLB2_SW | PPC47x_TLB2_SR |
+                      PPC47x_TLB2_SX
+#ifdef CONFIG_SMP
+                      | PPC47x_TLB2_M
+#endif
+                      ),
+                 "r" (phys),
+                 "r" (virt | PPC47x_TLB0_VALID | PPC47x_TLB0_256M),
+                 "r" (rA));
+}
+
 void __init MMU_init_hw(void)
 {
+       /* This is not useful on 47x but won't hurt either */
        ppc44x_update_tlb_hwater();
 
        flush_instruction_cache();
@@ -95,8 +188,51 @@ unsigned long __init mmu_mapin_ram(unsigned long top)
        /* Pin in enough TLBs to cover any lowmem not covered by the
         * initial 256M mapping established in head_44x.S */
        for (addr = PPC_PIN_SIZE; addr < lowmem_end_addr;
-            addr += PPC_PIN_SIZE)
-               ppc44x_pin_tlb(addr + PAGE_OFFSET, addr);
+            addr += PPC_PIN_SIZE) {
+               if (mmu_has_feature(MMU_FTR_TYPE_47x))
+                       ppc47x_pin_tlb(addr + PAGE_OFFSET, addr);
+               else
+                       ppc44x_pin_tlb(addr + PAGE_OFFSET, addr);
+       }
+       if (mmu_has_feature(MMU_FTR_TYPE_47x)) {
+               ppc47x_update_boltmap();
 
+#ifdef DEBUG
+               {
+                       int i;
+
+                       printk(KERN_DEBUG "bolted entries: ");
+                       for (i = 0; i < 255; i++) {
+                               if (test_bit(i, tlb_47x_boltmap))
+                                       printk("%d ", i);
+                       }
+                       printk("\n");
+               }
+#endif /* DEBUG */
+       }
        return total_lowmem;
 }
+
+#ifdef CONFIG_SMP
+void __cpuinit mmu_init_secondary(int cpu)
+{
+       unsigned long addr;
+
+       /* Pin in enough TLBs to cover any lowmem not covered by the
+        * initial 256M mapping established in head_44x.S
+        *
+        * WARNING: This is called with only the first 256M of the
+        * linear mapping in the TLB and we can't take faults yet
+        * so beware of what this code uses. It runs off a temporary
+        * stack. current (r2) isn't initialized, smp_processor_id()
+        * will not work, current thread info isn't accessible, ...
+        */
+       for (addr = PPC_PIN_SIZE; addr < lowmem_end_addr;
+            addr += PPC_PIN_SIZE) {
+               if (mmu_has_feature(MMU_FTR_TYPE_47x))
+                       ppc47x_pin_tlb(addr + PAGE_OFFSET, addr);
+               else
+                       ppc44x_pin_tlb(addr + PAGE_OFFSET, addr);
+       }
+}
+#endif /* CONFIG_SMP */
index 26fb6b9..1bd712c 100644 (file)
@@ -151,13 +151,14 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
        if (!user_mode(regs) && (address >= TASK_SIZE))
                return SIGSEGV;
 
-#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
+#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE) || \
+                            defined(CONFIG_PPC_BOOK3S_64))
        if (error_code & DSISR_DABRMATCH) {
                /* DABR match */
                do_dabr(regs, address, error_code);
                return 0;
        }
-#endif /* !(CONFIG_4xx || CONFIG_BOOKE)*/
+#endif
 
        if (in_atomic() || mm == NULL) {
                if (!user_mode(regs))
@@ -307,7 +308,6 @@ good_area:
         * make sure we exit gracefully rather than endlessly redo
         * the fault.
         */
- survive:
        ret = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0);
        if (unlikely(ret & VM_FAULT_ERROR)) {
                if (ret & VM_FAULT_OOM)
@@ -359,15 +359,10 @@ bad_area_nosemaphore:
  */
 out_of_memory:
        up_read(&mm->mmap_sem);
-       if (is_global_init(current)) {
-               yield();
-               down_read(&mm->mmap_sem);
-               goto survive;
-       }
-       printk("VM: killing process %s\n", current->comm);
-       if (user_mode(regs))
-               do_group_exit(SIGKILL);
-       return SIGKILL;
+       if (!user_mode(regs))
+               return SIGKILL;
+       pagefault_out_of_memory();
+       return 0;
 
 do_sigbus:
        up_read(&mm->mmap_sem);
index 1ed6b52..cdc7526 100644 (file)
@@ -2,7 +2,7 @@
  * Modifications by Kumar Gala (galak@kernel.crashing.org) to support
  * E500 Book E processors.
  *
- * Copyright 2004 Freescale Semiconductor, Inc
+ * Copyright 2004,2010 Freescale Semiconductor, Inc.
  *
  * This file contains the routines for initializing the MMU
  * on the 4xx series of chips.
 
 unsigned int tlbcam_index;
 
-#define NUM_TLBCAMS    (64)
 
 #if defined(CONFIG_LOWMEM_CAM_NUM_BOOL) && (CONFIG_LOWMEM_CAM_NUM >= NUM_TLBCAMS)
 #error "LOWMEM_CAM_NUM must be less than NUM_TLBCAMS"
 #endif
 
-struct tlbcam {
-       u32     MAS0;
-       u32     MAS1;
-       unsigned long   MAS2;
-       u32     MAS3;
-       u32     MAS7;
-} TLBCAM[NUM_TLBCAMS];
+#define NUM_TLBCAMS    (64)
+struct tlbcam TLBCAM[NUM_TLBCAMS];
 
 struct tlbcamrange {
        unsigned long start;
@@ -109,19 +103,6 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa)
        return 0;
 }
 
-void loadcam_entry(int idx)
-{
-       mtspr(SPRN_MAS0, TLBCAM[idx].MAS0);
-       mtspr(SPRN_MAS1, TLBCAM[idx].MAS1);
-       mtspr(SPRN_MAS2, TLBCAM[idx].MAS2);
-       mtspr(SPRN_MAS3, TLBCAM[idx].MAS3);
-
-       if (mmu_has_feature(MMU_FTR_BIG_PHYS))
-               mtspr(SPRN_MAS7, TLBCAM[idx].MAS7);
-
-       asm volatile("isync;tlbwe;isync" : : : "memory");
-}
-
 /*
  * Set up one of the I/D BAT (block address translation) register pairs.
  * The parameters are not checked; in particular size must be a power
index d7fa50b..e267f22 100644 (file)
@@ -252,6 +252,47 @@ static void __meminit vmemmap_create_mapping(unsigned long start,
 }
 #endif /* CONFIG_PPC_BOOK3E */
 
+struct vmemmap_backing *vmemmap_list;
+
+static __meminit struct vmemmap_backing * vmemmap_list_alloc(int node)
+{
+       static struct vmemmap_backing *next;
+       static int num_left;
+
+       /* allocate a page when required and hand out chunks */
+       if (!next || !num_left) {
+               next = vmemmap_alloc_block(PAGE_SIZE, node);
+               if (unlikely(!next)) {
+                       WARN_ON(1);
+                       return NULL;
+               }
+               num_left = PAGE_SIZE / sizeof(struct vmemmap_backing);
+       }
+
+       num_left--;
+
+       return next++;
+}
+
+static __meminit void vmemmap_list_populate(unsigned long phys,
+                                           unsigned long start,
+                                           int node)
+{
+       struct vmemmap_backing *vmem_back;
+
+       vmem_back = vmemmap_list_alloc(node);
+       if (unlikely(!vmem_back)) {
+               WARN_ON(1);
+               return;
+       }
+
+       vmem_back->phys = phys;
+       vmem_back->virt_addr = start;
+       vmem_back->list = vmemmap_list;
+
+       vmemmap_list = vmem_back;
+}
+
 int __meminit vmemmap_populate(struct page *start_page,
                               unsigned long nr_pages, int node)
 {
@@ -276,6 +317,8 @@ int __meminit vmemmap_populate(struct page *start_page,
                if (!p)
                        return -ENOMEM;
 
+               vmemmap_list_populate(__pa(p), start, node);
+
                pr_debug("      * %016lx..%016lx allocated at %p\n",
                         start, start + page_size, p);
 
index 1f2d9ff..ddfd7ad 100644 (file)
@@ -395,10 +395,18 @@ void __init mmu_context_init(void)
         * the PID/TID comparison is disabled, so we can use a TID of zero
         * to represent all kernel pages as shared among all contexts.
         *      -- Dan
+        *
+        * The IBM 47x core supports 16-bit PIDs, thus 65535 contexts. We
+        * should normally never have to steal though the facility is
+        * present if needed.
+        *      -- BenH
         */
        if (mmu_has_feature(MMU_FTR_TYPE_8xx)) {
                first_context = 0;
                last_context = 15;
+       } else if (mmu_has_feature(MMU_FTR_TYPE_47x)) {
+               first_context = 1;
+               last_context = 65535;
        } else {
                first_context = 1;
                last_context = 255;
index d49a775..63b84a0 100644 (file)
@@ -69,12 +69,7 @@ static inline void _tlbil_va(unsigned long address, unsigned int pid,
 }
 #endif /* CONIFG_8xx */
 
-/*
- * As of today, we don't support tlbivax broadcast on any
- * implementation. When that becomes the case, this will be
- * an extern.
- */
-#ifdef CONFIG_PPC_BOOK3E
+#if defined(CONFIG_PPC_BOOK3E) || defined(CONFIG_PPC_47x)
 extern void _tlbivax_bcast(unsigned long address, unsigned int pid,
                           unsigned int tsize, unsigned int ind);
 #else
@@ -149,7 +144,15 @@ extern unsigned long mmu_mapin_ram(unsigned long top);
 extern void MMU_init_hw(void);
 extern unsigned long mmu_mapin_ram(unsigned long top);
 extern void adjust_total_lowmem(void);
-
+extern void loadcam_entry(unsigned int index);
+
+struct tlbcam {
+       u32     MAS0;
+       u32     MAS1;
+       unsigned long   MAS2;
+       u32     MAS3;
+       u32     MAS7;
+};
 #elif defined(CONFIG_PPC32)
 /* anything 32-bit except 4xx or 8xx */
 extern void MMU_init_hw(void);
index eaa7633..80d1106 100644 (file)
@@ -33,16 +33,41 @@ static int numa_debug;
 #define dbg(args...) if (numa_debug) { printk(KERN_INFO args); }
 
 int numa_cpu_lookup_table[NR_CPUS];
-cpumask_t numa_cpumask_lookup_table[MAX_NUMNODES];
+cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
 struct pglist_data *node_data[MAX_NUMNODES];
 
 EXPORT_SYMBOL(numa_cpu_lookup_table);
-EXPORT_SYMBOL(numa_cpumask_lookup_table);
+EXPORT_SYMBOL(node_to_cpumask_map);
 EXPORT_SYMBOL(node_data);
 
 static int min_common_depth;
 static int n_mem_addr_cells, n_mem_size_cells;
 
+/*
+ * Allocate node_to_cpumask_map based on number of available nodes
+ * Requires node_possible_map to be valid.
+ *
+ * Note: node_to_cpumask() is not valid until after this is done.
+ */
+static void __init setup_node_to_cpumask_map(void)
+{
+       unsigned int node, num = 0;
+
+       /* setup nr_node_ids if not done yet */
+       if (nr_node_ids == MAX_NUMNODES) {
+               for_each_node_mask(node, node_possible_map)
+                       num = node;
+               nr_node_ids = num + 1;
+       }
+
+       /* allocate the map */
+       for (node = 0; node < nr_node_ids; node++)
+               alloc_bootmem_cpumask_var(&node_to_cpumask_map[node]);
+
+       /* cpumask_of_node() will now work */
+       dbg("Node to cpumask map for %d nodes\n", nr_node_ids);
+}
+
 static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn,
                                                unsigned int *nid)
 {
@@ -138,8 +163,8 @@ static void __cpuinit map_cpu_to_node(int cpu, int node)
 
        dbg("adding cpu %d to node %d\n", cpu, node);
 
-       if (!(cpu_isset(cpu, numa_cpumask_lookup_table[node])))
-               cpu_set(cpu, numa_cpumask_lookup_table[node]);
+       if (!(cpumask_test_cpu(cpu, node_to_cpumask_map[node])))
+               cpumask_set_cpu(cpu, node_to_cpumask_map[node]);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -149,8 +174,8 @@ static void unmap_cpu_from_node(unsigned long cpu)
 
        dbg("removing cpu %lu from node %d\n", cpu, node);
 
-       if (cpu_isset(cpu, numa_cpumask_lookup_table[node])) {
-               cpu_clear(cpu, numa_cpumask_lookup_table[node]);
+       if (cpumask_test_cpu(cpu, node_to_cpumask_map[node])) {
+               cpumask_set_cpu(cpu, node_to_cpumask_map[node]);
        } else {
                printk(KERN_ERR "WARNING: cpu %lu not found in node %d\n",
                       cpu, node);
@@ -246,7 +271,8 @@ static int __init find_min_common_depth(void)
        const unsigned int *ref_points;
        struct device_node *rtas_root;
        unsigned int len;
-       struct device_node *options;
+       struct device_node *chosen;
+       const char *vec5;
 
        rtas_root = of_find_node_by_path("/rtas");
 
@@ -264,14 +290,17 @@ static int __init find_min_common_depth(void)
                        "ibm,associativity-reference-points", &len);
 
        /*
-        * For type 1 affinity information we want the first field
+        * For form 1 affinity information we want the first field
         */
-       options = of_find_node_by_path("/options");
-       if (options) {
-               const char *str;
-               str = of_get_property(options, "ibm,associativity-form", NULL);
-               if (str && !strcmp(str, "1"))
-                        index = 0;
+#define VEC5_AFFINITY_BYTE     5
+#define VEC5_AFFINITY          0x80
+       chosen = of_find_node_by_path("/chosen");
+       if (chosen) {
+               vec5 = of_get_property(chosen, "ibm,architecture-vec-5", NULL);
+               if (vec5 && (vec5[VEC5_AFFINITY_BYTE] & VEC5_AFFINITY)) {
+                       dbg("Using form 1 affinity\n");
+                       index = 0;
+               }
        }
 
        if ((len >= 2 * sizeof(unsigned int)) && ref_points) {
@@ -750,8 +779,9 @@ void __init dump_numa_cpu_topology(void)
                 * If we used a CPU iterator here we would miss printing
                 * the holes in the cpumap.
                 */
-               for (cpu = 0; cpu < NR_CPUS; cpu++) {
-                       if (cpu_isset(cpu, numa_cpumask_lookup_table[node])) {
+               for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
+                       if (cpumask_test_cpu(cpu,
+                                       node_to_cpumask_map[node])) {
                                if (count == 0)
                                        printk(" %u", cpu);
                                ++count;
@@ -763,7 +793,7 @@ void __init dump_numa_cpu_topology(void)
                }
 
                if (count > 1)
-                       printk("-%u", NR_CPUS - 1);
+                       printk("-%u", nr_cpu_ids - 1);
                printk("\n");
        }
 }
@@ -939,10 +969,6 @@ void __init do_init_bootmem(void)
        else
                dump_numa_memory_topology();
 
-       register_cpu_notifier(&ppc64_numa_nb);
-       cpu_numa_callback(&ppc64_numa_nb, CPU_UP_PREPARE,
-                         (void *)(unsigned long)boot_cpuid);
-
        for_each_online_node(nid) {
                unsigned long start_pfn, end_pfn;
                void *bootmem_vaddr;
@@ -996,6 +1022,16 @@ void __init do_init_bootmem(void)
        }
 
        init_bootmem_done = 1;
+
+       /*
+        * Now bootmem is initialised we can create the node to cpumask
+        * lookup tables and setup the cpu callback to populate them.
+        */
+       setup_node_to_cpumask_map();
+
+       register_cpu_notifier(&ppc64_numa_nb);
+       cpu_numa_callback(&ppc64_numa_nb, CPU_UP_PREPARE,
+                         (void *)(unsigned long)boot_cpuid);
 }
 
 void __init paging_init(void)
index b9243e7..9fc02dc 100644 (file)
@@ -146,6 +146,14 @@ ioremap_flags(phys_addr_t addr, unsigned long size, unsigned long flags)
        /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
        flags &= ~(_PAGE_USER | _PAGE_EXEC);
 
+#ifdef _PAGE_BAP_SR
+       /* _PAGE_USER contains _PAGE_BAP_SR on BookE using the new PTE format
+        * which means that we just cleared supervisor access... oops ;-) This
+        * restores it
+        */
+       flags |= _PAGE_BAP_SR;
+#endif
+
        return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
 }
 EXPORT_SYMBOL(ioremap_flags);
@@ -385,11 +393,7 @@ static int __change_page_attr(struct page *page, pgprot_t prot)
                return -EINVAL;
        __set_pte_at(&init_mm, address, kpte, mk_pte(page, prot), 0);
        wmb();
-#ifdef CONFIG_PPC_STD_MMU
-       flush_hash_pages(0, address, pmd_val(*kpmd), 1);
-#else
        flush_tlb_page(NULL, address);
-#endif
        pte_unmap(kpte);
 
        return 0;
index d95679a..d050fc8 100644 (file)
@@ -265,6 +265,14 @@ void __iomem * ioremap_flags(phys_addr_t addr, unsigned long size,
        /* we don't want to let _PAGE_USER and _PAGE_EXEC leak out */
        flags &= ~(_PAGE_USER | _PAGE_EXEC);
 
+#ifdef _PAGE_BAP_SR
+       /* _PAGE_USER contains _PAGE_BAP_SR on BookE using the new PTE format
+        * which means that we just cleared supervisor access... oops ;-) This
+        * restores it
+        */
+       flags |= _PAGE_BAP_SR;
+#endif
+
        if (ppc_md.ioremap)
                return ppc_md.ioremap(addr, size, flags, caller);
        return __ioremap_caller(addr, size, flags, caller);
index bbdc5b5..cfa7682 100644 (file)
@@ -10,7 +10,7 @@
  *     - tlbil_va
  *     - tlbil_pid
  *     - tlbil_all
- *     - tlbivax_bcast (not yet)
+ *     - tlbivax_bcast
  *
  * Code mostly moved over from misc_32.S
  *
@@ -33,6 +33,7 @@
 #include <asm/ppc_asm.h>
 #include <asm/asm-offsets.h>
 #include <asm/processor.h>
+#include <asm/bug.h>
 
 #if defined(CONFIG_40x)
 
@@ -65,7 +66,7 @@ _GLOBAL(__tlbil_va)
  * Nothing to do for 8xx, everything is inline
  */
 
-#elif defined(CONFIG_44x)
+#elif defined(CONFIG_44x) /* Includes 47x */
 
 /*
  * 440 implementation uses tlbsx/we for tlbil_va and a full sweep
@@ -73,7 +74,13 @@ _GLOBAL(__tlbil_va)
  */
 _GLOBAL(__tlbil_va)
        mfspr   r5,SPRN_MMUCR
-       rlwimi  r5,r4,0,24,31                   /* Set TID */
+       mfmsr   r10
+
+       /*
+        * We write 16 bits of STID since 47x supports that much, we
+        * will never be passed out of bounds values on 440 (hopefully)
+        */
+       rlwimi  r5,r4,0,16,31
 
        /* We have to run the search with interrupts disabled, otherwise
         * an interrupt which causes a TLB miss can clobber the MMUCR
@@ -83,24 +90,41 @@ _GLOBAL(__tlbil_va)
         * and restoring MMUCR, so only normal interrupts have to be
         * taken care of.
         */
-       mfmsr   r4
        wrteei  0
        mtspr   SPRN_MMUCR,r5
-       tlbsx.  r3, 0, r3
-       wrtee   r4
-       bne     1f
+       tlbsx.  r6,0,r3
+       bne     10f
        sync
-       /* There are only 64 TLB entries, so r3 < 64,
-        * which means bit 22, is clear.  Since 22 is
-        * the V bit in the TLB_PAGEID, loading this
+BEGIN_MMU_FTR_SECTION
+       b       2f
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
+       /* On 440 There are only 64 TLB entries, so r3 < 64, which means bit
+        * 22, is clear.  Since 22 is the V bit in the TLB_PAGEID, loading this
         * value will invalidate the TLB entry.
         */
-       tlbwe   r3, r3, PPC44x_TLB_PAGEID
+       tlbwe   r6,r6,PPC44x_TLB_PAGEID
        isync
-1:     blr
+10:    wrtee   r10
+       blr
+2:
+#ifdef CONFIG_PPC_47x
+       oris    r7,r6,0x8000    /* specify way explicitely */
+       clrrwi  r4,r3,12        /* get an EPN for the hashing with V = 0 */
+       ori     r4,r4,PPC47x_TLBE_SIZE
+       tlbwe   r4,r7,0         /* write it */
+       isync
+       wrtee   r10
+       blr
+#else /* CONFIG_PPC_47x */
+1:     trap
+       EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0;
+#endif /* !CONFIG_PPC_47x */
 
 _GLOBAL(_tlbil_all)
 _GLOBAL(_tlbil_pid)
+BEGIN_MMU_FTR_SECTION
+       b       2f
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x)
        li      r3,0
        sync
 
@@ -115,6 +139,76 @@ _GLOBAL(_tlbil_pid)
 
        isync
        blr
+2:
+#ifdef CONFIG_PPC_47x
+       /* 476 variant. There's not simple way to do this, hopefully we'll
+        * try to limit the amount of such full invalidates
+        */
+       mfmsr   r11             /* Interrupts off */
+       wrteei  0
+       li      r3,-1           /* Current set */
+       lis     r10,tlb_47x_boltmap@h
+       ori     r10,r10,tlb_47x_boltmap@l
+       lis     r7,0x8000       /* Specify way explicitely */
+
+       b       9f              /* For each set */
+
+1:     li      r9,4            /* Number of ways */
+       li      r4,0            /* Current way */
+       li      r6,0            /* Default entry value 0 */
+       andi.   r0,r8,1         /* Check if way 0 is bolted */
+       mtctr   r9              /* Load way counter */
+       bne-    3f              /* Bolted, skip loading it */
+
+2:     /* For each way */
+       or      r5,r3,r4        /* Make way|index for tlbre */
+       rlwimi  r5,r5,16,8,15   /* Copy index into position */
+       tlbre   r6,r5,0         /* Read entry */
+3:     addis   r4,r4,0x2000    /* Next way */
+       andi.   r0,r6,PPC47x_TLB0_VALID /* Valid entry ? */
+       beq     4f              /* Nope, skip it */
+       rlwimi  r7,r5,0,1,2     /* Insert way number */
+       rlwinm  r6,r6,0,21,19   /* Clear V */
+       tlbwe   r6,r7,0         /* Write it */
+4:     bdnz    2b              /* Loop for each way */
+       srwi    r8,r8,1         /* Next boltmap bit */
+9:     cmpwi   cr1,r3,255      /* Last set done ? */
+       addi    r3,r3,1         /* Next set */
+       beq     cr1,1f          /* End of loop */
+       andi.   r0,r3,0x1f      /* Need to load a new boltmap word ? */
+       bne     1b              /* No, loop */
+       lwz     r8,0(r10)       /* Load boltmap entry */
+       addi    r10,r10,4       /* Next word */
+       b       1b              /* Then loop */
+1:     isync                   /* Sync shadows */
+       wrtee   r11
+#else /* CONFIG_PPC_47x */
+1:     trap
+       EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0;
+#endif /* !CONFIG_PPC_47x */
+       blr
+
+#ifdef CONFIG_PPC_47x
+/*
+ * _tlbivax_bcast is only on 47x. We don't bother doing a runtime
+ * check though, it will blow up soon enough if we mistakenly try
+ * to use it on a 440.
+ */
+_GLOBAL(_tlbivax_bcast)
+       mfspr   r5,SPRN_MMUCR
+       mfmsr   r10
+       rlwimi  r5,r4,0,16,31
+       wrteei  0
+       mtspr   SPRN_MMUCR,r5
+/*     tlbivax 0,r3 - use .long to avoid binutils deps */
+       .long 0x7c000624 | (r3 << 11)
+       isync
+       eieio
+       tlbsync
+       sync
+       wrtee   r10
+       blr
+#endif /* CONFIG_PPC_47x */
 
 #elif defined(CONFIG_FSL_BOOKE)
 /*
@@ -271,3 +365,31 @@ _GLOBAL(set_context)
 #else
 #error Unsupported processor type !
 #endif
+
+#if defined(CONFIG_FSL_BOOKE)
+/*
+ * extern void loadcam_entry(unsigned int index)
+ *
+ * Load TLBCAM[index] entry in to the L2 CAM MMU
+ */
+_GLOBAL(loadcam_entry)
+       LOAD_REG_ADDR(r4, TLBCAM)
+       mulli   r5,r3,TLBCAM_SIZE
+       add     r3,r5,r4
+       lwz     r4,TLBCAM_MAS0(r3)
+       mtspr   SPRN_MAS0,r4
+       lwz     r4,TLBCAM_MAS1(r3)
+       mtspr   SPRN_MAS1,r4
+       PPC_LL  r4,TLBCAM_MAS2(r3)
+       mtspr   SPRN_MAS2,r4
+       lwz     r4,TLBCAM_MAS3(r3)
+       mtspr   SPRN_MAS3,r4
+BEGIN_MMU_FTR_SECTION
+       lwz     r4,TLBCAM_MAS7(r3)
+       mtspr   SPRN_MAS7,r4
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
+       isync
+       tlbwe
+       isync
+       blr
+#endif
index 7486bff..eeba0a7 100644 (file)
@@ -1,3 +1,12 @@
+config PPC_47x
+       bool "Support for 47x variant"
+       depends on 44x
+       default n
+       select MPIC
+       help
+         This option enables support for the 47x family of processors and is
+         not currently compatible with other 44x or 46x varients
+
 config BAMBOO
        bool "Bamboo"
        depends on 44x
@@ -151,6 +160,17 @@ config YOSEMITE
        help
          This option enables support for the AMCC PPC440EP evaluation board.
 
+config ISS4xx
+       bool "ISS 4xx Simulator"
+       depends on (44x || 40x)
+       default n
+       select 405GP if 40x
+       select 440GP if 44x && !PPC_47x
+       select PPC_FPU
+       select OF_RTC
+       help
+         This option enables support for the IBM ISS simulation environment
+
 #config LUAN
 #      bool "Luan"
 #      depends on 44x
index ee6185a..82ff326 100644 (file)
@@ -5,3 +5,4 @@ obj-$(CONFIG_SAM440EP)  += sam440ep.o
 obj-$(CONFIG_WARP)     += warp.o
 obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o
 obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o
+obj-$(CONFIG_ISS4xx)   += iss4xx.o
diff --git a/arch/powerpc/platforms/44x/iss4xx.c b/arch/powerpc/platforms/44x/iss4xx.c
new file mode 100644 (file)
index 0000000..aa46e9d
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * PPC476 board specific routines
+ *
+ * Copyright 2010 Torez Smith, IBM Corporation.
+ *
+ * Based on earlier code:
+ *    Matt Porter <mporter@kernel.crashing.org>
+ *    Copyright 2002-2005 MontaVista Software Inc.
+ *
+ *    Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
+ *    Copyright (c) 2003-2005 Zultys Technologies
+ *
+ *    Rewritten and ported to the merged powerpc tree:
+ *    Copyright 2007 David Gibson <dwg@au1.ibm.com>, IBM Corporation.
+ *
+ * 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/init.h>
+#include <linux/of_platform.h>
+#include <linux/rtc.h>
+
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/time.h>
+#include <asm/uic.h>
+#include <asm/ppc4xx.h>
+#include <asm/mpic.h>
+#include <asm/mmu.h>
+
+static __initdata struct of_device_id iss4xx_of_bus[] = {
+       { .compatible = "ibm,plb4", },
+       { .compatible = "ibm,plb6", },
+       { .compatible = "ibm,opb", },
+       { .compatible = "ibm,ebc", },
+       {},
+};
+
+static int __init iss4xx_device_probe(void)
+{
+       of_platform_bus_probe(NULL, iss4xx_of_bus, NULL);
+       of_instantiate_rtc();
+
+       return 0;
+}
+machine_device_initcall(iss4xx, iss4xx_device_probe);
+
+/* We can have either UICs or MPICs */
+static void __init iss4xx_init_irq(void)
+{
+       struct device_node *np;
+
+       /* Find top level interrupt controller */
+       for_each_node_with_property(np, "interrupt-controller") {
+               if (of_get_property(np, "interrupts", NULL) == NULL)
+                       break;
+       }
+       if (np == NULL)
+               panic("Can't find top level interrupt controller");
+
+       /* Check type and do appropriate initialization */
+       if (of_device_is_compatible(np, "ibm,uic")) {
+               uic_init_tree();
+               ppc_md.get_irq = uic_get_irq;
+#ifdef CONFIG_MPIC
+       } else if (of_device_is_compatible(np, "chrp,open-pic")) {
+               /* The MPIC driver will get everything it needs from the
+                * device-tree, just pass 0 to all arguments
+                */
+               struct mpic *mpic = mpic_alloc(np, 0, MPIC_PRIMARY, 0, 0,
+                                              " MPIC     ");
+               BUG_ON(mpic == NULL);
+               mpic_init(mpic);
+               ppc_md.get_irq = mpic_get_irq;
+#endif
+       } else
+               panic("Unrecognized top level interrupt controller");
+}
+
+#ifdef CONFIG_SMP
+static void __cpuinit smp_iss4xx_setup_cpu(int cpu)
+{
+       mpic_setup_this_cpu();
+}
+
+static void __cpuinit smp_iss4xx_kick_cpu(int cpu)
+{
+       struct device_node *cpunode = of_get_cpu_node(cpu, NULL);
+       const u64 *spin_table_addr_prop;
+       u32 *spin_table;
+       extern void start_secondary_47x(void);
+
+       BUG_ON(cpunode == NULL);
+
+       /* Assume spin table. We could test for the enable-method in
+        * the device-tree but currently there's little point as it's
+        * our only supported method
+        */
+       spin_table_addr_prop = of_get_property(cpunode, "cpu-release-addr",
+                                              NULL);
+       if (spin_table_addr_prop == NULL) {
+               pr_err("CPU%d: Can't start, missing cpu-release-addr !\n", cpu);
+               return;
+       }
+
+       /* Assume it's mapped as part of the linear mapping. This is a bit
+        * fishy but will work fine for now
+        */
+       spin_table = (u32 *)__va(*spin_table_addr_prop);
+       pr_debug("CPU%d: Spin table mapped at %p\n", cpu, spin_table);
+
+       spin_table[3] = cpu;
+       smp_wmb();
+       spin_table[1] = __pa(start_secondary_47x);
+       mb();
+}
+
+static struct smp_ops_t iss_smp_ops = {
+       .probe          = smp_mpic_probe,
+       .message_pass   = smp_mpic_message_pass,
+       .setup_cpu      = smp_iss4xx_setup_cpu,
+       .kick_cpu       = smp_iss4xx_kick_cpu,
+       .give_timebase  = smp_generic_give_timebase,
+       .take_timebase  = smp_generic_take_timebase,
+};
+
+static void __init iss4xx_smp_init(void)
+{
+       if (mmu_has_feature(MMU_FTR_TYPE_47x))
+               smp_ops = &iss_smp_ops;
+}
+
+#else /* CONFIG_SMP */
+static void __init iss4xx_smp_init(void) { }
+#endif /* CONFIG_SMP */
+
+static void __init iss4xx_setup_arch(void)
+{
+       iss4xx_smp_init();
+}
+
+/*
+ * Called very early, MMU is off, device-tree isn't unflattened
+ */
+static int __init iss4xx_probe(void)
+{
+       unsigned long root = of_get_flat_dt_root();
+
+       if (!of_flat_dt_is_compatible(root, "ibm,iss-4xx"))
+               return 0;
+
+       return 1;
+}
+
+define_machine(iss4xx) {
+       .name                   = "ISS-4xx",
+       .probe                  = iss4xx_probe,
+       .progress               = udbg_progress,
+       .init_IRQ               = iss4xx_init_irq,
+       .setup_arch             = iss4xx_setup_arch,
+       .restart                = ppc4xx_reset_system,
+       .calibrate_decr         = generic_calibrate_decr,
+};
index 0b4f883..ae525e4 100644 (file)
@@ -74,6 +74,7 @@ static int __init mpc831x_rdb_probe(void)
 static struct of_device_id __initdata of_bus_ids[] = {
        { .compatible = "simple-bus" },
        { .compatible = "gianfar" },
+       { .compatible = "gpio-leds", },
        {},
 };
 
index a1908d2..e00801c 100644 (file)
@@ -72,6 +72,7 @@ static struct of_device_id mpc837x_ids[] = {
        { .compatible = "soc", },
        { .compatible = "simple-bus", },
        { .compatible = "gianfar", },
+       { .compatible = "gpio-leds", },
        {},
 };
 
index 5abe137..018cc67 100644 (file)
@@ -83,7 +83,8 @@ static struct of_device_id __initdata mpc8610_ids[] = {
        { .compatible = "fsl,mpc8610-immr", },
        { .compatible = "fsl,mpc8610-guts", },
        { .compatible = "simple-bus", },
-       { .compatible = "gianfar", },
+       /* So that the DMA channel nodes can be probed individually: */
+       { .compatible = "fsl,eloplus-dma", },
        {}
 };
 
index a8aae0b..d361f81 100644 (file)
@@ -43,7 +43,7 @@ config 40x
        select PPC_PCI_CHOICE
 
 config 44x
-       bool "AMCC 44x"
+       bool "AMCC 44x, 46x or 47x"
        select PPC_DCR_NATIVE
        select PPC_UDBG_16550
        select 4xx_SOC
@@ -294,7 +294,7 @@ config PPC_PERF_CTRS
          This enables the powerpc-specific perf_event back-end.
 
 config SMP
-       depends on PPC_BOOK3S || PPC_BOOK3E || FSL_BOOKE
+       depends on PPC_BOOK3S || PPC_BOOK3E || FSL_BOOKE || PPC_47x
        bool "Symmetric multi-processing support"
        ---help---
          This enables support for systems with more than one CPU. If you have
@@ -322,6 +322,7 @@ config NR_CPUS
 config NOT_COHERENT_CACHE
        bool
        depends on 4xx || 8xx || E200 || PPC_MPC512x || GAMECUBE_COMMON
+       default n if PPC_47x
        default y
 
 config CHECK_CACHE_COHERENCY
index e6506cd..bfa2c0c 100644 (file)
@@ -118,7 +118,7 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
        policy->cur = cbe_freqs[cur_pmode].frequency;
 
 #ifdef CONFIG_SMP
-       cpumask_copy(policy->cpus, &per_cpu(cpu_sibling_map, policy->cpu));
+       cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu));
 #endif
 
        cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu);
index fba5bf9..32a56c6 100644 (file)
@@ -252,8 +252,8 @@ decrementer_iSeries_masked:
        li      r11,1
        ld      r12,PACALPPACAPTR(r13)
        stb     r11,LPPACADECRINT(r12)
-       LOAD_REG_IMMEDIATE(r12, tb_ticks_per_jiffy)
-       lwz     r12,0(r12)
+       li      r12,-1
+       clrldi  r12,r12,33      /* set DEC to 0x7fffffff */
        mtspr   SPRN_DEC,r12
        /* fall through */
 
index b841c9a..3fc2e64 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/of.h>
+#include <linux/ratelimit.h>
 
 #include <asm/types.h>
 #include <asm/io.h>
@@ -584,14 +585,9 @@ static inline struct device_node *xlate_iomm_address(
 
        orig_addr = (unsigned long __force)addr;
        if ((orig_addr < BASE_IO_MEMORY) || (orig_addr >= max_io_memory)) {
-               static unsigned long last_jiffies;
-               static int num_printed;
+               static DEFINE_RATELIMIT_STATE(ratelimit, 60 * HZ, 10);
 
-               if (time_after(jiffies, last_jiffies + 60 * HZ)) {
-                       last_jiffies = jiffies;
-                       num_printed = 0;
-               }
-               if (num_printed++ < 10)
+               if (__ratelimit(&ratelimit))
                        printk(KERN_ERR
                                "iSeries_%s: invalid access at IO address %p\n",
                                func, addr);
index 722335e..6590850 100644 (file)
@@ -83,7 +83,7 @@ static void smp_iSeries_message_pass(int target, int msg)
 
 static int smp_iSeries_probe(void)
 {
-       return cpus_weight(cpu_possible_map);
+       return cpumask_weight(cpu_possible_mask);
 }
 
 static void smp_iSeries_kick_cpu(int nr)
index d35e052..c16537b 100644 (file)
@@ -213,7 +213,7 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
        pr_debug("current astate is at %d\n",cur_astate);
 
        policy->cur = pas_freqs[cur_astate].frequency;
-       cpumask_copy(policy->cpus, &cpu_online_map);
+       cpumask_copy(policy->cpus, cpu_online_mask);
 
        ppc_proc_freq = policy->cur * 1000ul;
 
index 3ca09d3..9650c60 100644 (file)
@@ -362,7 +362,7 @@ static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy)
        /* secondary CPUs are tied to the primary one by the
         * cpufreq core if in the secondary policy we tell it that
         * it actually must be one policy together with all others. */
-       cpumask_copy(policy->cpus, &cpu_online_map);
+       cpumask_copy(policy->cpus, cpu_online_mask);
        cpufreq_frequency_table_get_attr(g5_cpu_freqs, policy->cpu);
 
        return cpufreq_frequency_table_cpuinfo(policy,
index f45331a..06a137c 100644 (file)
@@ -592,7 +592,7 @@ static void __init kw_i2c_probe(void)
        /* Probe keywest-i2c busses */
        for_each_compatible_node(np, "i2c","keywest-i2c") {
                struct pmac_i2c_host_kw *host;
-               int multibus, chans, i;
+               int multibus;
 
                /* Found one, init a host structure */
                host = kw_i2c_host_init(np);
@@ -614,6 +614,8 @@ static void __init kw_i2c_probe(void)
                 * parent type
                 */
                if (multibus) {
+                       int chans, i;
+
                        parent = of_get_parent(np);
                        if (parent == NULL)
                                continue;
@@ -1258,8 +1260,7 @@ static void pmac_i2c_do_end(struct pmf_function *func, void *instdata)
        if (inst == NULL)
                return;
        pmac_i2c_close(inst->bus);
-       if (inst)
-               kfree(inst);
+       kfree(inst);
 }
 
 static int pmac_i2c_do_read(PMF_STD_ARGS, u32 len)
index 3362e78..f0bc08f 100644 (file)
@@ -33,6 +33,8 @@ extern void pmac_setup_pci_dma(void);
 extern void pmac_check_ht_link(void);
 
 extern void pmac_setup_smp(void);
+extern void pmac32_cpu_die(void);
+extern void low_cpu_die(void) __attribute__((noreturn));
 
 extern int pmac_nvram_init(void);
 extern void pmac_pic_init(void);
index 15c2241..f1d0132 100644 (file)
@@ -480,7 +480,7 @@ static void __init pmac_init_early(void)
 #endif
 
        /* SMP Init has to be done early as we need to patch up
-        * cpu_possible_map before interrupt stacks are allocated
+        * cpu_possible_mask before interrupt stacks are allocated
         * or kaboom...
         */
 #ifdef CONFIG_SMP
@@ -646,7 +646,7 @@ static int pmac_pci_probe_mode(struct pci_bus *bus)
 /* access per cpu vars from generic smp.c */
 DECLARE_PER_CPU(int, cpu_state);
 
-static void pmac_cpu_die(void)
+static void pmac64_cpu_die(void)
 {
        /*
         * turn off as much as possible, we'll be
@@ -717,8 +717,13 @@ define_machine(powermac) {
        .pcibios_after_init     = pmac_pcibios_after_init,
        .phys_mem_access_prot   = pci_phys_mem_access_prot,
 #endif
-#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64)
-       .cpu_die                = pmac_cpu_die,
+#ifdef CONFIG_HOTPLUG_CPU
+#ifdef CONFIG_PPC64
+       .cpu_die                = pmac64_cpu_die,
+#endif
+#ifdef CONFIG_PPC32
+       .cpu_die                = pmac32_cpu_die,
+#endif
 #endif
 #if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
        .cpu_die                = generic_mach_cpu_die,
index 6898e82..c95215f 100644 (file)
@@ -53,6 +53,8 @@
 #include <asm/pmac_low_i2c.h>
 #include <asm/pmac_pfunc.h>
 
+#include "pmac.h"
+
 #undef DEBUG
 
 #ifdef DEBUG
@@ -315,7 +317,7 @@ static int __init smp_psurge_probe(void)
        /* This is necessary because OF doesn't know about the
         * secondary cpu(s), and thus there aren't nodes in the
         * device tree for them, and smp_setup_cpu_maps hasn't
-        * set their bits in cpu_present_map.
+        * set their bits in cpu_present_mask.
         */
        if (ncpus > NR_CPUS)
                ncpus = NR_CPUS;
@@ -878,10 +880,9 @@ int smp_core99_cpu_disable(void)
        return 0;
 }
 
-extern void low_cpu_die(void) __attribute__((noreturn)); /* in sleep.S */
 static int cpu_dead[NR_CPUS];
 
-void cpu_die(void)
+void pmac32_cpu_die(void)
 {
        local_irq_disable();
        cpu_dead[smp_processor_id()] = 1;
@@ -944,7 +945,7 @@ void __init pmac_setup_smp(void)
        }
 #ifdef CONFIG_PPC32
        else {
-               /* We have to set bits in cpu_possible_map here since the
+               /* We have to set bits in cpu_possible_mask here since the
                 * secondary CPU(s) aren't in the device tree. Various
                 * things won't be initialized for CPUs not in the possible
                 * map, so we really need to fix it up here.
index 0ff5174..3dbef30 100644 (file)
@@ -7,7 +7,7 @@ EXTRA_CFLAGS            += -DDEBUG
 endif
 
 obj-y                  := lpar.o hvCall.o nvram.o reconfig.o \
-                          setup.o iommu.o ras.o \
+                          setup.o iommu.o event_sources.o ras.o \
                           firmware.o power.o dlpar.o
 obj-$(CONFIG_SMP)      += smp.o
 obj-$(CONFIG_XICS)     += xics.o
index e1682bc..d71e585 100644 (file)
@@ -79,13 +79,12 @@ static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa)
         * prepend this to the full_name.
         */
        name = (char *)ccwa + ccwa->name_offset;
-       dn->full_name = kmalloc(strlen(name) + 2, GFP_KERNEL);
+       dn->full_name = kasprintf(GFP_KERNEL, "/%s", name);
        if (!dn->full_name) {
                kfree(dn);
                return NULL;
        }
 
-       sprintf(dn->full_name, "/%s", name);
        return dn;
 }
 
@@ -410,15 +409,13 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
         * directory of the device tree.  CPUs actually live in the
         * cpus directory so we need to fixup the full_name.
         */
-       cpu_name = kzalloc(strlen(dn->full_name) + strlen("/cpus") + 1,
-                          GFP_KERNEL);
+       cpu_name = kasprintf(GFP_KERNEL, "/cpus%s", dn->full_name);
        if (!cpu_name) {
                dlpar_free_cc_nodes(dn);
                rc = -ENOMEM;
                goto out;
        }
 
-       sprintf(cpu_name, "/cpus%s", dn->full_name);
        kfree(dn->full_name);
        dn->full_name = cpu_name;
 
@@ -433,6 +430,7 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
        if (rc) {
                dlpar_release_drc(drc_index);
                dlpar_free_cc_nodes(dn);
+               goto out;
        }
 
        rc = dlpar_online_cpu(dn);
index 7df7fbb..34b7dc1 100644 (file)
@@ -749,7 +749,7 @@ static void __rtas_set_slot_reset(struct pci_dn *pdn)
        /* Determine type of EEH reset required by device,
         * default hot reset or fundamental reset
         */
-       if (dev->needs_freset)
+       if (dev && dev->needs_freset)
                rtas_pci_slot_reset(pdn, 3);
        else
                rtas_pci_slot_reset(pdn, 1);
diff --git a/arch/powerpc/platforms/pseries/event_sources.c b/arch/powerpc/platforms/pseries/event_sources.c
new file mode 100644 (file)
index 0000000..e889c9d
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2001 Dave Engebretsen IBM Corporation
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <asm/prom.h>
+
+#include "pseries.h"
+
+void request_event_sources_irqs(struct device_node *np,
+                               irq_handler_t handler,
+                               const char *name)
+{
+       int i, index, count = 0;
+       struct of_irq oirq;
+       const u32 *opicprop;
+       unsigned int opicplen;
+       unsigned int virqs[16];
+
+       /* Check for obsolete "open-pic-interrupt" property. If present, then
+        * map those interrupts using the default interrupt host and default
+        * trigger
+        */
+       opicprop = of_get_property(np, "open-pic-interrupt", &opicplen);
+       if (opicprop) {
+               opicplen /= sizeof(u32);
+               for (i = 0; i < opicplen; i++) {
+                       if (count > 15)
+                               break;
+                       virqs[count] = irq_create_mapping(NULL, *(opicprop++));
+                       if (virqs[count] == NO_IRQ)
+                               printk(KERN_ERR "Unable to allocate interrupt "
+                                      "number for %s\n", np->full_name);
+                       else
+                               count++;
+
+               }
+       }
+       /* Else use normal interrupt tree parsing */
+       else {
+               /* First try to do a proper OF tree parsing */
+               for (index = 0; of_irq_map_one(np, index, &oirq) == 0;
+                    index++) {
+                       if (count > 15)
+                               break;
+                       virqs[count] = irq_create_of_mapping(oirq.controller,
+                                                           oirq.specifier,
+                                                           oirq.size);
+                       if (virqs[count] == NO_IRQ)
+                               printk(KERN_ERR "Unable to allocate interrupt "
+                                      "number for %s\n", np->full_name);
+                       else
+                               count++;
+               }
+       }
+
+       /* Now request them */
+       for (i = 0; i < count; i++) {
+               if (request_irq(virqs[i], handler, 0, name, NULL)) {
+                       printk(KERN_ERR "Unable to request interrupt %d for "
+                              "%s\n", virqs[i], np->full_name);
+                       return;
+               }
+       }
+}
+
index a8e1d5d..8f85f39 100644 (file)
@@ -154,30 +154,6 @@ static void pseries_mach_cpu_die(void)
        for(;;);
 }
 
-static int qcss_tok;   /* query-cpu-stopped-state token */
-
-/* Get state of physical CPU.
- * Return codes:
- *     0       - The processor is in the RTAS stopped state
- *     1       - stop-self is in progress
- *     2       - The processor is not in the RTAS stopped state
- *     -1      - Hardware Error
- *     -2      - Hardware Busy, Try again later.
- */
-static int query_cpu_stopped(unsigned int pcpu)
-{
-       int cpu_status, status;
-
-       status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu);
-       if (status != 0) {
-               printk(KERN_ERR
-                      "RTAS query-cpu-stopped-state failed: %i\n", status);
-               return status;
-       }
-
-       return cpu_status;
-}
-
 static int pseries_cpu_disable(void)
 {
        int cpu = smp_processor_id();
@@ -187,7 +163,7 @@ static int pseries_cpu_disable(void)
 
        /*fix boot_cpuid here*/
        if (cpu == boot_cpuid)
-               boot_cpuid = any_online_cpu(cpu_online_map);
+               boot_cpuid = cpumask_any(cpu_online_mask);
 
        /* FIXME: abstract this to not be platform specific later on */
        xics_migrate_irqs_away();
@@ -224,8 +200,9 @@ static void pseries_cpu_die(unsigned int cpu)
        } else if (get_preferred_offline_state(cpu) == CPU_STATE_OFFLINE) {
 
                for (tries = 0; tries < 25; tries++) {
-                       cpu_status = query_cpu_stopped(pcpu);
-                       if (cpu_status == 0 || cpu_status == -1)
+                       cpu_status = smp_query_cpu_stopped(pcpu);
+                       if (cpu_status == QCSS_STOPPED ||
+                           cpu_status == QCSS_HARDWARE_ERROR)
                                break;
                        cpu_relax();
                }
@@ -245,7 +222,7 @@ static void pseries_cpu_die(unsigned int cpu)
 }
 
 /*
- * Update cpu_present_map and paca(s) for a new cpu node.  The wrinkle
+ * Update cpu_present_mask and paca(s) for a new cpu node.  The wrinkle
  * here is that a cpu device node may represent up to two logical cpus
  * in the SMT case.  We must honor the assumption in other code that
  * the logical ids for sibling SMT threads x and y are adjacent, such
@@ -254,7 +231,7 @@ static void pseries_cpu_die(unsigned int cpu)
 static int pseries_add_processor(struct device_node *np)
 {
        unsigned int cpu;
-       cpumask_t candidate_map, tmp = CPU_MASK_NONE;
+       cpumask_var_t candidate_mask, tmp;
        int err = -ENOSPC, len, nthreads, i;
        const u32 *intserv;
 
@@ -262,48 +239,53 @@ static int pseries_add_processor(struct device_node *np)
        if (!intserv)
                return 0;
 
+       zalloc_cpumask_var(&candidate_mask, GFP_KERNEL);
+       zalloc_cpumask_var(&tmp, GFP_KERNEL);
+
        nthreads = len / sizeof(u32);
        for (i = 0; i < nthreads; i++)
-               cpu_set(i, tmp);
+               cpumask_set_cpu(i, tmp);
 
        cpu_maps_update_begin();
 
-       BUG_ON(!cpus_subset(cpu_present_map, cpu_possible_map));
+       BUG_ON(!cpumask_subset(cpu_present_mask, cpu_possible_mask));
 
        /* Get a bitmap of unoccupied slots. */
-       cpus_xor(candidate_map, cpu_possible_map, cpu_present_map);
-       if (cpus_empty(candidate_map)) {
+       cpumask_xor(candidate_mask, cpu_possible_mask, cpu_present_mask);
+       if (cpumask_empty(candidate_mask)) {
                /* If we get here, it most likely means that NR_CPUS is
                 * less than the partition's max processors setting.
                 */
                printk(KERN_ERR "Cannot add cpu %s; this system configuration"
                       " supports %d logical cpus.\n", np->full_name,
-                      cpus_weight(cpu_possible_map));
+                      cpumask_weight(cpu_possible_mask));
                goto out_unlock;
        }
 
-       while (!cpus_empty(tmp))
-               if (cpus_subset(tmp, candidate_map))
+       while (!cpumask_empty(tmp))
+               if (cpumask_subset(tmp, candidate_mask))
                        /* Found a range where we can insert the new cpu(s) */
                        break;
                else
-                       cpus_shift_left(tmp, tmp, nthreads);
+                       cpumask_shift_left(tmp, tmp, nthreads);
 
-       if (cpus_empty(tmp)) {
-               printk(KERN_ERR "Unable to find space in cpu_present_map for"
+       if (cpumask_empty(tmp)) {
+               printk(KERN_ERR "Unable to find space in cpu_present_mask for"
                       " processor %s with %d thread(s)\n", np->name,
                       nthreads);
                goto out_unlock;
        }
 
-       for_each_cpu_mask(cpu, tmp) {
-               BUG_ON(cpu_isset(cpu, cpu_present_map));
+       for_each_cpu(cpu, tmp) {
+               BUG_ON(cpumask_test_cpu(cpu, cpu_present_mask));
                set_cpu_present(cpu, true);
                set_hard_smp_processor_id(cpu, *intserv++);
        }
        err = 0;
 out_unlock:
        cpu_maps_update_done();
+       free_cpumask_var(candidate_mask);
+       free_cpumask_var(tmp);
        return err;
 }
 
@@ -334,7 +316,7 @@ static void pseries_remove_processor(struct device_node *np)
                        set_hard_smp_processor_id(cpu, -1);
                        break;
                }
-               if (cpu == NR_CPUS)
+               if (cpu >= nr_cpu_ids)
                        printk(KERN_WARNING "Could not find cpu to remove "
                               "with physical id 0x%x\n", intserv[i]);
        }
@@ -388,6 +370,7 @@ static int __init pseries_cpu_hotplug_init(void)
        struct device_node *np;
        const char *typep;
        int cpu;
+       int qcss_tok;
 
        for_each_node_by_name(np, "interrupt-controller") {
                typep = of_get_property(np, "compatible", NULL);
index 383a5d0..48d2057 100644 (file)
@@ -228,3 +228,41 @@ _GLOBAL(plpar_hcall9)
        mtcrf   0xff,r0
 
        blr                             /* return r3 = status */
+
+/* See plpar_hcall_raw to see why this is needed */
+_GLOBAL(plpar_hcall9_raw)
+       HMT_MEDIUM
+
+       mfcr    r0
+       stw     r0,8(r1)
+
+       std     r4,STK_PARM(r4)(r1)     /* Save ret buffer */
+
+       mr      r4,r5
+       mr      r5,r6
+       mr      r6,r7
+       mr      r7,r8
+       mr      r8,r9
+       mr      r9,r10
+       ld      r10,STK_PARM(r11)(r1)    /* put arg7 in R10 */
+       ld      r11,STK_PARM(r12)(r1)    /* put arg8 in R11 */
+       ld      r12,STK_PARM(r13)(r1)    /* put arg9 in R12 */
+
+       HVSC                            /* invoke the hypervisor */
+
+       mr      r0,r12
+       ld      r12,STK_PARM(r4)(r1)
+       std     r4,  0(r12)
+       std     r5,  8(r12)
+       std     r6, 16(r12)
+       std     r7, 24(r12)
+       std     r8, 32(r12)
+       std     r9, 40(r12)
+       std     r10,48(r12)
+       std     r11,56(r12)
+       std     r0, 64(r12)
+
+       lwz     r0,8(r1)
+       mtcrf   0xff,r0
+
+       blr                             /* return r3 = status */
index 0707653..cf79b46 100644 (file)
@@ -367,21 +367,28 @@ static void pSeries_lpar_hptab_clear(void)
 {
        unsigned long size_bytes = 1UL << ppc64_pft_size;
        unsigned long hpte_count = size_bytes >> 4;
-       unsigned long dummy1, dummy2, dword0;
+       struct {
+               unsigned long pteh;
+               unsigned long ptel;
+       } ptes[4];
        long lpar_rc;
-       int i;
+       int i, j;
 
-       /* TODO: Use bulk call */
-       for (i = 0; i < hpte_count; i++) {
-               /* dont remove HPTEs with VRMA mappings */
-               lpar_rc = plpar_pte_remove_raw(H_ANDCOND, i, HPTE_V_1TB_SEG,
-                                               &dummy1, &dummy2);
-               if (lpar_rc == H_NOT_FOUND) {
-                       lpar_rc = plpar_pte_read_raw(0, i, &dword0, &dummy1);
-                       if (!lpar_rc && ((dword0 & HPTE_V_VRMA_MASK)
-                               != HPTE_V_VRMA_MASK))
-                               /* Can be hpte for 1TB Seg. So remove it */
-                               plpar_pte_remove_raw(0, i, 0, &dummy1, &dummy2);
+       /* Read in batches of 4,
+        * invalidate only valid entries not in the VRMA
+        * hpte_count will be a multiple of 4
+         */
+       for (i = 0; i < hpte_count; i += 4) {
+               lpar_rc = plpar_pte_read_4_raw(0, i, (void *)ptes);
+               if (lpar_rc != H_SUCCESS)
+                       continue;
+               for (j = 0; j < 4; j++){
+                       if ((ptes[j].pteh & HPTE_V_VRMA_MASK) ==
+                               HPTE_V_VRMA_MASK)
+                               continue;
+                       if (ptes[j].pteh & HPTE_V_VALID)
+                               plpar_pte_remove_raw(0, i + j, 0,
+                                       &(ptes[j].pteh), &(ptes[j].ptel));
                }
        }
 }
index a05f8d4..d980111 100644 (file)
@@ -4,6 +4,14 @@
 #include <asm/hvcall.h>
 #include <asm/page.h>
 
+/* Get state of physical CPU from query_cpu_stopped */
+int smp_query_cpu_stopped(unsigned int pcpu);
+#define QCSS_STOPPED 0
+#define QCSS_STOPPING 1
+#define QCSS_NOT_STOPPED 2
+#define QCSS_HARDWARE_ERROR -1
+#define QCSS_HARDWARE_BUSY -2
+
 static inline long poll_pending(void)
 {
        return plpar_hcall_norets(H_POLL_PENDING);
@@ -183,6 +191,24 @@ static inline long plpar_pte_read_raw(unsigned long flags, unsigned long ptex,
        return rc;
 }
 
+/*
+ * plpar_pte_read_4_raw can be called in real mode.
+ * ptes must be 8*sizeof(unsigned long)
+ */
+static inline long plpar_pte_read_4_raw(unsigned long flags, unsigned long ptex,
+                                       unsigned long *ptes)
+
+{
+       long rc;
+       unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
+
+       rc = plpar_hcall9_raw(H_READ, retbuf, flags | H_READ_4, ptex);
+
+       memcpy(ptes, retbuf, 8*sizeof(unsigned long));
+
+       return rc;
+}
+
 static inline long plpar_pte_protect(unsigned long flags, unsigned long ptex,
                unsigned long avpn)
 {
index 9e17c0d..40c93ca 100644 (file)
 #ifndef _PSERIES_PSERIES_H
 #define _PSERIES_PSERIES_H
 
+#include <linux/interrupt.h>
+
+struct device_node;
+
+extern void request_event_sources_irqs(struct device_node *np,
+                                      irq_handler_t handler, const char *name);
+
 extern void __init fw_feature_init(const char *hypertas, unsigned long len);
 
 struct pt_regs;
index db940d2..41a3e9a 100644 (file)
@@ -67,63 +67,6 @@ static irqreturn_t ras_epow_interrupt(int irq, void *dev_id);
 static irqreturn_t ras_error_interrupt(int irq, void *dev_id);
 
 
-static void request_ras_irqs(struct device_node *np,
-                       irq_handler_t handler,
-                       const char *name)
-{
-       int i, index, count = 0;
-       struct of_irq oirq;
-       const u32 *opicprop;
-       unsigned int opicplen;
-       unsigned int virqs[16];
-
-       /* Check for obsolete "open-pic-interrupt" property. If present, then
-        * map those interrupts using the default interrupt host and default
-        * trigger
-        */
-       opicprop = of_get_property(np, "open-pic-interrupt", &opicplen);
-       if (opicprop) {
-               opicplen /= sizeof(u32);
-               for (i = 0; i < opicplen; i++) {
-                       if (count > 15)
-                               break;
-                       virqs[count] = irq_create_mapping(NULL, *(opicprop++));
-                       if (virqs[count] == NO_IRQ)
-                               printk(KERN_ERR "Unable to allocate interrupt "
-                                      "number for %s\n", np->full_name);
-                       else
-                               count++;
-
-               }
-       }
-       /* Else use normal interrupt tree parsing */
-       else {
-               /* First try to do a proper OF tree parsing */
-               for (index = 0; of_irq_map_one(np, index, &oirq) == 0;
-                    index++) {
-                       if (count > 15)
-                               break;
-                       virqs[count] = irq_create_of_mapping(oirq.controller,
-                                                           oirq.specifier,
-                                                           oirq.size);
-                       if (virqs[count] == NO_IRQ)
-                               printk(KERN_ERR "Unable to allocate interrupt "
-                                      "number for %s\n", np->full_name);
-                       else
-                               count++;
-               }
-       }
-
-       /* Now request them */
-       for (i = 0; i < count; i++) {
-               if (request_irq(virqs[i], handler, 0, name, NULL)) {
-                       printk(KERN_ERR "Unable to request interrupt %d for "
-                              "%s\n", virqs[i], np->full_name);
-                       return;
-               }
-       }
-}
-
 /*
  * Initialize handlers for the set of interrupts caused by hardware errors
  * and power system events.
@@ -138,14 +81,15 @@ static int __init init_ras_IRQ(void)
        /* Internal Errors */
        np = of_find_node_by_path("/event-sources/internal-errors");
        if (np != NULL) {
-               request_ras_irqs(np, ras_error_interrupt, "RAS_ERROR");
+               request_event_sources_irqs(np, ras_error_interrupt,
+                                          "RAS_ERROR");
                of_node_put(np);
        }
 
        /* EPOW Events */
        np = of_find_node_by_path("/event-sources/epow-events");
        if (np != NULL) {
-               request_ras_irqs(np, ras_epow_interrupt, "RAS_EPOW");
+               request_event_sources_irqs(np, ras_epow_interrupt, "RAS_EPOW");
                of_node_put(np);
        }
 
index 6710761..a6d19e3 100644 (file)
@@ -496,13 +496,14 @@ static int __init pSeries_probe(void)
 }
 
 
-DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
+DECLARE_PER_CPU(long, smt_snooze_delay);
 
 static void pseries_dedicated_idle_sleep(void)
 { 
        unsigned int cpu = smp_processor_id();
        unsigned long start_snooze;
        unsigned long in_purr, out_purr;
+       long snooze = __get_cpu_var(smt_snooze_delay);
 
        /*
         * Indicate to the HV that we are idle. Now would be
@@ -517,13 +518,12 @@ static void pseries_dedicated_idle_sleep(void)
         * has been checked recently.  If we should poll for a little
         * while, do so.
         */
-       if (__get_cpu_var(smt_snooze_delay)) {
-               start_snooze = get_tb() +
-                       __get_cpu_var(smt_snooze_delay) * tb_ticks_per_usec;
+       if (snooze) {
+               start_snooze = get_tb() + snooze * tb_ticks_per_usec;
                local_irq_enable();
                set_thread_flag(TIF_POLLING_NRFLAG);
 
-               while (get_tb() < start_snooze) {
+               while ((snooze < 0) || (get_tb() < start_snooze)) {
                        if (need_resched() || cpu_is_offline(cpu))
                                goto out;
                        ppc64_runlatch_off();
index 4e7f89a..3b1bf61 100644 (file)
  * The Primary thread of each non-boot processor was started from the OF client
  * interface by prom_hold_cpus and is spinning on secondary_hold_spinloop.
  */
-static cpumask_t of_spin_map;
+static cpumask_var_t of_spin_mask;
+
+/* Query where a cpu is now.  Return codes #defined in plpar_wrappers.h */
+int smp_query_cpu_stopped(unsigned int pcpu)
+{
+       int cpu_status, status;
+       int qcss_tok = rtas_token("query-cpu-stopped-state");
+
+       if (qcss_tok == RTAS_UNKNOWN_SERVICE) {
+               printk(KERN_INFO "Firmware doesn't support "
+                               "query-cpu-stopped-state\n");
+               return QCSS_HARDWARE_ERROR;
+       }
+
+       status = rtas_call(qcss_tok, 1, 2, &cpu_status, pcpu);
+       if (status != 0) {
+               printk(KERN_ERR
+                      "RTAS query-cpu-stopped-state failed: %i\n", status);
+               return status;
+       }
+
+       return cpu_status;
+}
 
 /**
  * smp_startup_cpu() - start the given cpu
@@ -76,12 +98,18 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
        unsigned int pcpu;
        int start_cpu;
 
-       if (cpu_isset(lcpu, of_spin_map))
+       if (cpumask_test_cpu(lcpu, of_spin_mask))
                /* Already started by OF and sitting in spin loop */
                return 1;
 
        pcpu = get_hard_smp_processor_id(lcpu);
 
+       /* Check to see if the CPU out of FW already for kexec */
+       if (smp_query_cpu_stopped(pcpu) == QCSS_NOT_STOPPED){
+               cpumask_set_cpu(lcpu, of_spin_mask);
+               return 1;
+       }
+
        /* Fixup atomic count: it exited inside IRQ handler. */
        task_thread_info(paca[lcpu].__current)->preempt_count   = 0;
 
@@ -115,7 +143,7 @@ static void __devinit smp_xics_setup_cpu(int cpu)
        if (firmware_has_feature(FW_FEATURE_SPLPAR))
                vpa_init(cpu);
 
-       cpu_clear(cpu, of_spin_map);
+       cpumask_clear_cpu(cpu, of_spin_mask);
        set_cpu_current_state(cpu, CPU_STATE_ONLINE);
        set_default_offline_state(cpu);
 
@@ -186,17 +214,19 @@ static void __init smp_init_pseries(void)
 
        pr_debug(" -> smp_init_pSeries()\n");
 
+       alloc_bootmem_cpumask_var(&of_spin_mask);
+
        /* Mark threads which are still spinning in hold loops. */
        if (cpu_has_feature(CPU_FTR_SMT)) {
                for_each_present_cpu(i) { 
                        if (cpu_thread_in_core(i) == 0)
-                               cpu_set(i, of_spin_map);
+                               cpumask_set_cpu(i, of_spin_mask);
                }
        } else {
-               of_spin_map = cpu_present_map;
+               cpumask_copy(of_spin_mask, cpu_present_mask);
        }
 
-       cpu_clear(boot_cpuid, of_spin_map);
+       cpumask_clear_cpu(boot_cpuid, of_spin_mask);
 
        /* Non-lpar has additional take/give timebase */
        if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
index 1bcedd8..f19d194 100644 (file)
@@ -163,29 +163,37 @@ static inline void lpar_qirr_info(int n_cpu , u8 value)
 /* Interface to generic irq subsystem */
 
 #ifdef CONFIG_SMP
-static int get_irq_server(unsigned int virq, cpumask_t cpumask,
+/*
+ * For the moment we only implement delivery to all cpus or one cpu.
+ *
+ * If the requested affinity is cpu_all_mask, we set global affinity.
+ * If not we set it to the first cpu in the mask, even if multiple cpus
+ * are set. This is so things like irqbalance (which set core and package
+ * wide affinities) do the right thing.
+ */
+static int get_irq_server(unsigned int virq, const struct cpumask *cpumask,
                          unsigned int strict_check)
 {
-       int server;
-       /* For the moment only implement delivery to all cpus or one cpu */
-       cpumask_t tmp = CPU_MASK_NONE;
 
        if (!distribute_irqs)
                return default_server;
 
-       if (!cpus_equal(cpumask, CPU_MASK_ALL)) {
-               cpus_and(tmp, cpu_online_map, cpumask);
-
-               server = first_cpu(tmp);
+       if (!cpumask_equal(cpumask, cpu_all_mask)) {
+               int server = cpumask_first_and(cpu_online_mask, cpumask);
 
-               if (server < NR_CPUS)
+               if (server < nr_cpu_ids)
                        return get_hard_smp_processor_id(server);
 
                if (strict_check)
                        return -1;
        }
 
-       if (cpus_equal(cpu_online_map, cpu_present_map))
+       /*
+        * Workaround issue with some versions of JS20 firmware that
+        * deliver interrupts to cpus which haven't been started. This
+        * happens when using the maxcpus= boot option.
+        */
+       if (cpumask_equal(cpu_online_mask, cpu_present_mask))
                return default_distrib_server;
 
        return default_server;
@@ -207,7 +215,7 @@ static void xics_unmask_irq(unsigned int virq)
        if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
                return;
 
-       server = get_irq_server(virq, *(irq_to_desc(virq)->affinity), 0);
+       server = get_irq_server(virq, irq_to_desc(virq)->affinity, 0);
 
        call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
                                DEFAULT_PRIORITY);
@@ -398,11 +406,7 @@ static int xics_set_affinity(unsigned int virq, const struct cpumask *cpumask)
                return -1;
        }
 
-       /*
-        * For the moment only implement delivery to all cpus or one cpu.
-        * Get current irq_server for the given irq
-        */
-       irq_server = get_irq_server(virq, *cpumask, 1);
+       irq_server = get_irq_server(virq, cpumask, 1);
        if (irq_server == -1) {
                char cpulist[128];
                cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
@@ -611,7 +615,7 @@ int __init smp_xics_probe(void)
 {
        xics_request_ipi();
 
-       return cpus_weight(cpu_possible_map);
+       return cpumask_weight(cpu_possible_mask);
 }
 
 #endif /* CONFIG_SMP */
index 6478eb1..83f5196 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/of_gpio.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
+#include <linux/irq.h>
 
 #define MPC8XXX_GPIO_PINS      32
 
@@ -35,6 +36,7 @@ struct mpc8xxx_gpio_chip {
         * open drain mode safely
         */
        u32 data;
+       struct irq_host *irq;
 };
 
 static inline u32 mpc8xxx_gpio2mask(unsigned int gpio)
@@ -128,12 +130,136 @@ static int mpc8xxx_gpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val
        return 0;
 }
 
+static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
+{
+       struct of_mm_gpio_chip *mm = to_of_mm_gpio_chip(gc);
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = to_mpc8xxx_gpio_chip(mm);
+
+       if (mpc8xxx_gc->irq && offset < MPC8XXX_GPIO_PINS)
+               return irq_create_mapping(mpc8xxx_gc->irq, offset);
+       else
+               return -ENXIO;
+}
+
+static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc)
+{
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_desc_data(desc);
+       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+       unsigned int mask;
+
+       mask = in_be32(mm->regs + GPIO_IER) & in_be32(mm->regs + GPIO_IMR);
+       if (mask)
+               generic_handle_irq(irq_linear_revmap(mpc8xxx_gc->irq,
+                                                    32 - ffs(mask)));
+}
+
+static void mpc8xxx_irq_unmask(unsigned int virq)
+{
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq);
+       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+       unsigned long flags;
+
+       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+
+       setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(virq)));
+
+       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+}
+
+static void mpc8xxx_irq_mask(unsigned int virq)
+{
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq);
+       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+       unsigned long flags;
+
+       spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+
+       clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(virq)));
+
+       spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+}
+
+static void mpc8xxx_irq_ack(unsigned int virq)
+{
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq);
+       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+
+       out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(virq_to_hw(virq)));
+}
+
+static int mpc8xxx_irq_set_type(unsigned int virq, unsigned int flow_type)
+{
+       struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq);
+       struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
+       unsigned long flags;
+
+       switch (flow_type) {
+       case IRQ_TYPE_EDGE_FALLING:
+               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+               setbits32(mm->regs + GPIO_ICR,
+                         mpc8xxx_gpio2mask(virq_to_hw(virq)));
+               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+               break;
+
+       case IRQ_TYPE_EDGE_BOTH:
+               spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
+               clrbits32(mm->regs + GPIO_ICR,
+                         mpc8xxx_gpio2mask(virq_to_hw(virq)));
+               spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static struct irq_chip mpc8xxx_irq_chip = {
+       .name           = "mpc8xxx-gpio",
+       .unmask         = mpc8xxx_irq_unmask,
+       .mask           = mpc8xxx_irq_mask,
+       .ack            = mpc8xxx_irq_ack,
+       .set_type       = mpc8xxx_irq_set_type,
+};
+
+static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
+                               irq_hw_number_t hw)
+{
+       set_irq_chip_data(virq, h->host_data);
+       set_irq_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq);
+       set_irq_type(virq, IRQ_TYPE_NONE);
+
+       return 0;
+}
+
+static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct,
+                                 const u32 *intspec, unsigned int intsize,
+                                 irq_hw_number_t *out_hwirq,
+                                 unsigned int *out_flags)
+
+{
+       /* interrupt sense values coming from the device tree equal either
+        * EDGE_FALLING or EDGE_BOTH
+        */
+       *out_hwirq = intspec[0];
+       *out_flags = intspec[1];
+
+       return 0;
+}
+
+static struct irq_host_ops mpc8xxx_gpio_irq_ops = {
+       .map    = mpc8xxx_gpio_irq_map,
+       .xlate  = mpc8xxx_gpio_irq_xlate,
+};
+
 static void __init mpc8xxx_add_controller(struct device_node *np)
 {
        struct mpc8xxx_gpio_chip *mpc8xxx_gc;
        struct of_mm_gpio_chip *mm_gc;
        struct of_gpio_chip *of_gc;
        struct gpio_chip *gc;
+       unsigned hwirq;
        int ret;
 
        mpc8xxx_gc = kzalloc(sizeof(*mpc8xxx_gc), GFP_KERNEL);
@@ -158,11 +284,32 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
        else
                gc->get = mpc8xxx_gpio_get;
        gc->set = mpc8xxx_gpio_set;
+       gc->to_irq = mpc8xxx_gpio_to_irq;
 
        ret = of_mm_gpiochip_add(np, mm_gc);
        if (ret)
                goto err;
 
+       hwirq = irq_of_parse_and_map(np, 0);
+       if (hwirq == NO_IRQ)
+               goto skip_irq;
+
+       mpc8xxx_gc->irq =
+               irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS,
+                              &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS);
+       if (!mpc8xxx_gc->irq)
+               goto skip_irq;
+
+       mpc8xxx_gc->irq->host_data = mpc8xxx_gc;
+
+       /* ack and mask all irqs */
+       out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
+       out_be32(mm_gc->regs + GPIO_IMR, 0);
+
+       set_irq_data(hwirq, mpc8xxx_gc);
+       set_irq_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade);
+
+skip_irq:
        return;
 
 err:
index 260295b..2102487 100644 (file)
@@ -568,12 +568,12 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic)
 #endif /* CONFIG_MPIC_U3_HT_IRQS */
 
 #ifdef CONFIG_SMP
-static int irq_choose_cpu(const cpumask_t *mask)
+static int irq_choose_cpu(const struct cpumask *mask)
 {
        int cpuid;
 
        if (cpumask_equal(mask, cpu_all_mask)) {
-               static int irq_rover;
+               static int irq_rover = 0;
                static DEFINE_RAW_SPINLOCK(irq_rover_lock);
                unsigned long flags;
 
@@ -581,15 +581,11 @@ static int irq_choose_cpu(const cpumask_t *mask)
        do_round_robin:
                raw_spin_lock_irqsave(&irq_rover_lock, flags);
 
-               while (!cpu_online(irq_rover)) {
-                       if (++irq_rover >= NR_CPUS)
-                               irq_rover = 0;
-               }
+               irq_rover = cpumask_next(irq_rover, cpu_online_mask);
+               if (irq_rover >= nr_cpu_ids)
+                       irq_rover = cpumask_first(cpu_online_mask);
+
                cpuid = irq_rover;
-               do {
-                       if (++irq_rover >= NR_CPUS)
-                               irq_rover = 0;
-               } while (!cpu_online(irq_rover));
 
                raw_spin_unlock_irqrestore(&irq_rover_lock, flags);
        } else {
@@ -601,7 +597,7 @@ static int irq_choose_cpu(const cpumask_t *mask)
        return get_hard_smp_processor_id(cpuid);
 }
 #else
-static int irq_choose_cpu(const cpumask_t *mask)
+static int irq_choose_cpu(const struct cpumask *mask)
 {
        return hard_smp_processor_id();
 }
@@ -814,12 +810,16 @@ int mpic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
 
                mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid);
        } else {
-               cpumask_t tmp;
+               cpumask_var_t tmp;
 
-               cpumask_and(&tmp, cpumask, cpu_online_mask);
+               alloc_cpumask_var(&tmp, GFP_KERNEL);
+
+               cpumask_and(tmp, cpumask, cpu_online_mask);
 
                mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
-                              mpic_physmask(cpus_addr(tmp)[0]));
+                              mpic_physmask(cpumask_bits(tmp)[0]));
+
+               free_cpumask_var(tmp);
        }
 
        return 0;
@@ -1479,21 +1479,6 @@ void mpic_teardown_this_cpu(int secondary)
 }
 
 
-void mpic_send_ipi(unsigned int ipi_no, unsigned int cpu_mask)
-{
-       struct mpic *mpic = mpic_primary;
-
-       BUG_ON(mpic == NULL);
-
-#ifdef DEBUG_IPI
-       DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
-#endif
-
-       mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) +
-                      ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE),
-                      mpic_physmask(cpu_mask & cpus_addr(cpu_online_map)[0]));
-}
-
 static unsigned int _mpic_get_one_irq(struct mpic *mpic, int reg)
 {
        u32 src;
@@ -1589,8 +1574,25 @@ void mpic_request_ipis(void)
        }
 }
 
+static void mpic_send_ipi(unsigned int ipi_no, const struct cpumask *cpu_mask)
+{
+       struct mpic *mpic = mpic_primary;
+
+       BUG_ON(mpic == NULL);
+
+#ifdef DEBUG_IPI
+       DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
+#endif
+
+       mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) +
+                      ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE),
+                      mpic_physmask(cpumask_bits(cpu_mask)[0]));
+}
+
 void smp_mpic_message_pass(int target, int msg)
 {
+       cpumask_var_t tmp;
+
        /* make sure we're sending something that translates to an IPI */
        if ((unsigned int)msg > 3) {
                printk("SMP %d: smp_message_pass: unknown msg %d\n",
@@ -1599,13 +1601,17 @@ void smp_mpic_message_pass(int target, int msg)
        }
        switch (target) {
        case MSG_ALL:
-               mpic_send_ipi(msg, 0xffffffff);
+               mpic_send_ipi(msg, cpu_online_mask);
                break;
        case MSG_ALL_BUT_SELF:
-               mpic_send_ipi(msg, 0xffffffff & ~(1 << smp_processor_id()));
+               alloc_cpumask_var(&tmp, GFP_NOWAIT);
+               cpumask_andnot(tmp, cpu_online_mask,
+                              cpumask_of(smp_processor_id()));
+               mpic_send_ipi(msg, tmp);
+               free_cpumask_var(tmp);
                break;
        default:
-               mpic_send_ipi(msg, 1 << target);
+               mpic_send_ipi(msg, cpumask_of(target));
                break;
        }
 }
@@ -1616,7 +1622,7 @@ int __init smp_mpic_probe(void)
 
        DBG("smp_mpic_probe()...\n");
 
-       nr_cpus = cpus_weight(cpu_possible_map);
+       nr_cpus = cpumask_weight(cpu_possible_mask);
 
        DBG("nr_cpus: %d\n", nr_cpus);
 
index 5c01435..d3d6ce3 100644 (file)
@@ -191,11 +191,31 @@ static int __init ppc4xx_l2c_probe(void)
 arch_initcall(ppc4xx_l2c_probe);
 
 /*
- * At present, this routine just applies a system reset.
+ * Apply a system reset. Alternatively a board specific value may be
+ * provided via the "reset-type" property in the cpu node.
  */
 void ppc4xx_reset_system(char *cmd)
 {
-       mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | DBCR0_RST_SYSTEM);
+       struct device_node *np;
+       u32 reset_type = DBCR0_RST_SYSTEM;
+       const u32 *prop;
+
+       np = of_find_node_by_type(NULL, "cpu");
+       if (np) {
+               prop = of_get_property(np, "reset-type", NULL);
+
+               /*
+                * Check if property exists and if it is in range:
+                * 1 - PPC4xx core reset
+                * 2 - PPC4xx chip reset
+                * 3 - PPC4xx system reset (default)
+                */
+               if ((prop) && ((prop[0] >= 1) && (prop[0] <= 3)))
+                       reset_type = prop[0] << 28;
+       }
+
+       mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) | reset_type);
+
        while (1)
                ;       /* Just in case the reset doesn't work */
 }
index 79119f5..bd6da7a 100644 (file)
@@ -155,6 +155,7 @@ static int macio_adb_reset_bus(void)
        while ((in_8(&adb->ctrl.r) & ADB_RST) != 0) {
                if (--timeout == 0) {
                        out_8(&adb->ctrl.r, in_8(&adb->ctrl.r) & ~ADB_RST);
+                       spin_unlock_irqrestore(&macio_lock, flags);
                        return -1;
                }
        }
index 888448c..c9da5c4 100644 (file)
@@ -1183,8 +1183,10 @@ static ssize_t smu_read_command(struct file *file, struct smu_private *pp,
                return -EOVERFLOW;
        spin_lock_irqsave(&pp->lock, flags);
        if (pp->cmd.status == 1) {
-               if (file->f_flags & O_NONBLOCK)
+               if (file->f_flags & O_NONBLOCK) {
+                       spin_unlock_irqrestore(&pp->lock, flags);
                        return -EAGAIN;
+               }
                add_wait_queue(&pp->wait, &wait);
                for (;;) {
                        set_current_state(TASK_INTERRUPTIBLE);
index c42eeb4..16d82f1 100644 (file)
@@ -182,6 +182,7 @@ remove_thermostat(struct i2c_client *client)
 
        thermostat = NULL;
 
+       i2c_set_clientdata(client, NULL);
        kfree(th);
 
        return 0;
@@ -399,6 +400,7 @@ static int probe_thermostat(struct i2c_client *client,
        rc = read_reg(th, CONFIG_REG);
        if (rc < 0) {
                dev_err(&client->dev, "Thermostat failed to read config!\n");
+               i2c_set_clientdata(client, NULL);
                kfree(th);
                return -ENODEV;
        }
index 129cda7..749d174 100644 (file)
@@ -757,10 +757,8 @@ static int __devexit wf_smu_remove(struct platform_device *ddev)
                wf_put_control(cpufreq_clamp);
 
        /* Destroy control loops state structures */
-       if (wf_smu_sys_fans)
-               kfree(wf_smu_sys_fans);
-       if (wf_smu_cpu_fans)
-               kfree(wf_smu_cpu_fans);
+       kfree(wf_smu_sys_fans);
+       kfree(wf_smu_cpu_fans);
 
        return 0;
 }
index bea9916..3442732 100644 (file)
@@ -687,12 +687,9 @@ static int __devexit wf_smu_remove(struct platform_device *ddev)
                wf_put_control(cpufreq_clamp);
 
        /* Destroy control loops state structures */
-       if (wf_smu_slots_fans)
-               kfree(wf_smu_cpu_fans);
-       if (wf_smu_drive_fans)
-               kfree(wf_smu_cpu_fans);
-       if (wf_smu_cpu_fans)
-               kfree(wf_smu_cpu_fans);
+       kfree(wf_smu_slots_fans);
+       kfree(wf_smu_drive_fans);
+       kfree(wf_smu_cpu_fans);
 
        return 0;
 }
index 7b6f7ee..f12dc3e 100644 (file)
@@ -3,7 +3,6 @@
 #
 
 obj-$(CONFIG_IBM_ASM)          += ibmasm/
-obj-$(CONFIG_HDPU_FEATURES)    += hdpuftrs/
 obj-$(CONFIG_AD525X_DPOT)      += ad525x_dpot.o
 obj-$(CONFIG_ATMEL_PWM)                += atmel_pwm.o
 obj-$(CONFIG_ATMEL_SSC)                += atmel-ssc.o
diff --git a/drivers/misc/hdpuftrs/Makefile b/drivers/misc/hdpuftrs/Makefile
deleted file mode 100644 (file)
index ac74ae6..0000000
+++ /dev/null
@@ -1 +0,0 @@
-obj-$(CONFIG_HDPU_FEATURES) := hdpu_cpustate.o hdpu_nexus.o
diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c
deleted file mode 100644 (file)
index 176fe4e..0000000
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- *     Sky CPU State Driver
- *
- *     Copyright (C) 2002 Brian Waite
- *
- *     This driver allows use of the CPU state bits
- *     It exports the /dev/sky_cpustate and also
- *     /proc/sky_cpustate pseudo-file for status information.
- *
- *     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/module.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/smp_lock.h>
-#include <linux/miscdevice.h>
-#include <linux/proc_fs.h>
-#include <linux/hdpu_features.h>
-#include <linux/platform_device.h>
-#include <asm/uaccess.h>
-#include <linux/seq_file.h>
-#include <asm/io.h>
-
-#define SKY_CPUSTATE_VERSION           "1.1"
-
-static int hdpu_cpustate_probe(struct platform_device *pdev);
-static int hdpu_cpustate_remove(struct platform_device *pdev);
-
-static unsigned char cpustate_get_state(void);
-static int cpustate_proc_open(struct inode *inode, struct file *file);
-static int cpustate_proc_read(struct seq_file *seq, void *offset);
-
-static struct cpustate_t cpustate;
-
-static const struct file_operations proc_cpustate = {
-       .open = cpustate_proc_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-       .owner = THIS_MODULE,
-};
-
-static int cpustate_proc_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, cpustate_proc_read, NULL);
-}
-
-static int cpustate_proc_read(struct seq_file *seq, void *offset)
-{
-       seq_printf(seq, "CPU State: %04x\n", cpustate_get_state());
-       return 0;
-}
-
-static int cpustate_get_ref(int excl)
-{
-
-       int retval = -EBUSY;
-
-       spin_lock(&cpustate.lock);
-
-       if (cpustate.excl)
-               goto out_busy;
-
-       if (excl) {
-               if (cpustate.open_count)
-                       goto out_busy;
-               cpustate.excl = 1;
-       }
-
-       cpustate.open_count++;
-       retval = 0;
-
-      out_busy:
-       spin_unlock(&cpustate.lock);
-       return retval;
-}
-
-static int cpustate_free_ref(void)
-{
-
-       spin_lock(&cpustate.lock);
-
-       cpustate.excl = 0;
-       cpustate.open_count--;
-
-       spin_unlock(&cpustate.lock);
-       return 0;
-}
-
-static unsigned char cpustate_get_state(void)
-{
-
-       return cpustate.cached_val;
-}
-
-static void cpustate_set_state(unsigned char new_state)
-{
-       unsigned int state = (new_state << 21);
-
-#ifdef DEBUG_CPUSTATE
-       printk("CPUSTATE -> 0x%x\n", new_state);
-#endif
-       spin_lock(&cpustate.lock);
-       cpustate.cached_val = new_state;
-       writel((0xff << 21), cpustate.clr_addr);
-       writel(state, cpustate.set_addr);
-       spin_unlock(&cpustate.lock);
-}
-
-/*
- *     Now all the various file operations that we export.
- */
-
-static ssize_t cpustate_read(struct file *file, char *buf,
-                            size_t count, loff_t * ppos)
-{
-       unsigned char data;
-
-       if (count < 0)
-               return -EFAULT;
-       if (count == 0)
-               return 0;
-
-       data = cpustate_get_state();
-       if (copy_to_user(buf, &data, sizeof(unsigned char)))
-               return -EFAULT;
-       return sizeof(unsigned char);
-}
-
-static ssize_t cpustate_write(struct file *file, const char *buf,
-                             size_t count, loff_t * ppos)
-{
-       unsigned char data;
-
-       if (count < 0)
-               return -EFAULT;
-
-       if (count == 0)
-               return 0;
-
-       if (copy_from_user((unsigned char *)&data, buf, sizeof(unsigned char)))
-               return -EFAULT;
-
-       cpustate_set_state(data);
-       return sizeof(unsigned char);
-}
-
-static int cpustate_open(struct inode *inode, struct file *file)
-{
-       int ret;
-
-       lock_kernel();
-       ret = cpustate_get_ref((file->f_flags & O_EXCL));
-       unlock_kernel();
-
-       return ret;
-}
-
-static int cpustate_release(struct inode *inode, struct file *file)
-{
-       return cpustate_free_ref();
-}
-
-static struct platform_driver hdpu_cpustate_driver = {
-       .probe = hdpu_cpustate_probe,
-       .remove = hdpu_cpustate_remove,
-       .driver = {
-               .name = HDPU_CPUSTATE_NAME,
-               .owner = THIS_MODULE,
-       },
-};
-
-/*
- *     The various file operations we support.
- */
-static const struct file_operations cpustate_fops = {
-      .owner   = THIS_MODULE,
-      .open    = cpustate_open,
-      .release = cpustate_release,
-      .read    = cpustate_read,
-      .write   = cpustate_write,
-      .llseek  = no_llseek,
-};
-
-static struct miscdevice cpustate_dev = {
-       .minor  = MISC_DYNAMIC_MINOR,
-       .name   = "sky_cpustate",
-       .fops   = &cpustate_fops,
-};
-
-static int hdpu_cpustate_probe(struct platform_device *pdev)
-{
-       struct resource *res;
-       struct proc_dir_entry *proc_de;
-       int ret;
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               printk(KERN_ERR "sky_cpustate: "
-                      "Invalid memory resource.\n");
-               return -EINVAL;
-       }
-       cpustate.set_addr = (unsigned long *)res->start;
-       cpustate.clr_addr = (unsigned long *)res->end - 1;
-
-       ret = misc_register(&cpustate_dev);
-       if (ret) {
-               printk(KERN_WARNING "sky_cpustate: "
-                      "Unable to register misc device.\n");
-               cpustate.set_addr = NULL;
-               cpustate.clr_addr = NULL;
-               return ret;
-       }
-
-       proc_de = proc_create("sky_cpustate", 0666, NULL, &proc_cpustate);
-       if (!proc_de) {
-               printk(KERN_WARNING "sky_cpustate: "
-                      "Unable to create proc entry\n");
-       }
-
-       printk(KERN_INFO "Sky CPU State Driver v" SKY_CPUSTATE_VERSION "\n");
-       return 0;
-}
-
-static int hdpu_cpustate_remove(struct platform_device *pdev)
-{
-       cpustate.set_addr = NULL;
-       cpustate.clr_addr = NULL;
-
-       remove_proc_entry("sky_cpustate", NULL);
-       misc_deregister(&cpustate_dev);
-
-       return 0;
-}
-
-static int __init cpustate_init(void)
-{
-       return platform_driver_register(&hdpu_cpustate_driver);
-}
-
-static void __exit cpustate_exit(void)
-{
-       platform_driver_unregister(&hdpu_cpustate_driver);
-}
-
-module_init(cpustate_init);
-module_exit(cpustate_exit);
-
-MODULE_AUTHOR("Brian Waite");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" HDPU_CPUSTATE_NAME);
diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c
deleted file mode 100644 (file)
index ce39fa5..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- *     Sky Nexus Register Driver
- *
- *     Copyright (C) 2002 Brian Waite
- *
- *     This driver allows reading the Nexus register
- *     It exports the /proc/sky_chassis_id and also
- *     /proc/sky_slot_id pseudo-file for status information.
- *
- *     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/module.h>
-#include <linux/kernel.h>
-#include <linux/proc_fs.h>
-#include <linux/hdpu_features.h>
-#include <linux/platform_device.h>
-#include <linux/seq_file.h>
-#include <asm/io.h>
-
-static int hdpu_nexus_probe(struct platform_device *pdev);
-static int hdpu_nexus_remove(struct platform_device *pdev);
-static int hdpu_slot_id_open(struct inode *inode, struct file *file);
-static int hdpu_slot_id_read(struct seq_file *seq, void *offset);
-static int hdpu_chassis_id_open(struct inode *inode, struct file *file);
-static int hdpu_chassis_id_read(struct seq_file *seq, void *offset);
-
-static struct proc_dir_entry *hdpu_slot_id;
-static struct proc_dir_entry *hdpu_chassis_id;
-static int slot_id = -1;
-static int chassis_id = -1;
-
-static const struct file_operations proc_slot_id = {
-       .open = hdpu_slot_id_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-       .owner = THIS_MODULE,
-};
-
-static const struct file_operations proc_chassis_id = {
-       .open = hdpu_chassis_id_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
-       .owner = THIS_MODULE,
-};
-
-static struct platform_driver hdpu_nexus_driver = {
-       .probe = hdpu_nexus_probe,
-       .remove = hdpu_nexus_remove,
-       .driver = {
-               .name = HDPU_NEXUS_NAME,
-               .owner = THIS_MODULE,
-       },
-};
-
-static int hdpu_slot_id_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, hdpu_slot_id_read, NULL);
-}
-
-static int hdpu_slot_id_read(struct seq_file *seq, void *offset)
-{
-       seq_printf(seq, "%d\n", slot_id);
-       return 0;
-}
-
-static int hdpu_chassis_id_open(struct inode *inode, struct file *file)
-{
-       return single_open(file, hdpu_chassis_id_read, NULL);
-}
-
-static int hdpu_chassis_id_read(struct seq_file *seq, void *offset)
-{
-       seq_printf(seq, "%d\n", chassis_id);
-       return 0;
-}
-
-static int hdpu_nexus_probe(struct platform_device *pdev)
-{
-       struct resource *res;
-       int *nexus_id_addr;
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res) {
-               printk(KERN_ERR "sky_nexus: "
-                      "Invalid memory resource.\n");
-               return -EINVAL;
-       }
-       nexus_id_addr = ioremap(res->start,
-                               (unsigned long)(res->end - res->start));
-       if (nexus_id_addr) {
-               slot_id = (*nexus_id_addr >> 8) & 0x1f;
-               chassis_id = *nexus_id_addr & 0xff;
-               iounmap(nexus_id_addr);
-       } else {
-               printk(KERN_ERR "sky_nexus: Could not map slot id\n");
-       }
-
-       hdpu_slot_id = proc_create("sky_slot_id", 0666, NULL, &proc_slot_id);
-       if (!hdpu_slot_id) {
-               printk(KERN_WARNING "sky_nexus: "
-                      "Unable to create proc dir entry: sky_slot_id\n");
-       }
-
-       hdpu_chassis_id = proc_create("sky_chassis_id", 0666, NULL,
-                                     &proc_chassis_id);
-       if (!hdpu_chassis_id)
-               printk(KERN_WARNING "sky_nexus: "
-                      "Unable to create proc dir entry: sky_chassis_id\n");
-
-       return 0;
-}
-
-static int hdpu_nexus_remove(struct platform_device *pdev)
-{
-       slot_id = -1;
-       chassis_id = -1;
-
-       remove_proc_entry("sky_slot_id", NULL);
-       remove_proc_entry("sky_chassis_id", NULL);
-
-       hdpu_slot_id = 0;
-       hdpu_chassis_id = 0;
-
-       return 0;
-}
-
-static int __init nexus_init(void)
-{
-       return platform_driver_register(&hdpu_nexus_driver);
-}
-
-static void __exit nexus_exit(void)
-{
-       platform_driver_unregister(&hdpu_nexus_driver);
-}
-
-module_init(nexus_init);
-module_exit(nexus_exit);
-
-MODULE_AUTHOR("Brian Waite");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:" HDPU_NEXUS_NAME);
index 55e113a..6a9c660 100644 (file)
@@ -2071,6 +2071,7 @@ static int mpsc_drv_probe(struct platform_device *dev)
 
                if (!(rc = mpsc_drv_map_regs(pi, dev))) {
                        mpsc_drv_get_platform_data(pi, dev, dev->id);
+                       pi->port.dev = &dev->dev;
 
                        if (!(rc = mpsc_make_ready(pi))) {
                                spin_lock_init(&pi->tx_lock);
diff --git a/include/linux/hdpu_features.h b/include/linux/hdpu_features.h
deleted file mode 100644 (file)
index 6a87154..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <linux/spinlock.h>
-
-struct cpustate_t {
-       spinlock_t lock;
-       int excl;
-        int open_count;
-       unsigned char cached_val;
-       int inited;
-       unsigned long *set_addr;
-       unsigned long *clr_addr;
-};
-
-
-#define HDPU_CPUSTATE_NAME "hdpu cpustate"
-#define HDPU_NEXUS_NAME "hdpu nexus"
-
-#define CPUSTATE_KERNEL_MAJOR  0x10
-
-#define CPUSTATE_KERNEL_INIT_DRV   0 /* CPU State Driver Initialized */
-#define CPUSTATE_KERNEL_INIT_PCI   1 /* 64360 PCI Busses Init */
-#define CPUSTATE_KERNEL_INIT_REG   2 /* 64360 Bridge Init */
-#define CPUSTATE_KERNEL_CPU1_KICK  3 /* Boot cpu 1 */
-#define CPUSTATE_KERNEL_CPU1_OK    4  /* Cpu 1 has checked in */
-#define CPUSTATE_KERNEL_OK         5 /* Terminal state */
-#define CPUSTATE_KERNEL_RESET   14 /* Board reset via SW*/
-#define CPUSTATE_KERNEL_HALT   15 /* Board halted via SW*/
index 6776d1c..7e267c9 100644 (file)
@@ -116,12 +116,9 @@ static void pmf_gpio_exit(struct gpio_runtime *rt)
        mutex_destroy(&rt->line_in_notify.mutex);
        mutex_destroy(&rt->line_out_notify.mutex);
 
-       if (rt->headphone_notify.gpio_private)
-               kfree(rt->headphone_notify.gpio_private);
-       if (rt->line_in_notify.gpio_private)
-               kfree(rt->line_in_notify.gpio_private);
-       if (rt->line_out_notify.gpio_private)
-               kfree(rt->line_out_notify.gpio_private);
+       kfree(rt->headphone_notify.gpio_private);
+       kfree(rt->line_in_notify.gpio_private);
+       kfree(rt->line_out_notify.gpio_private);
 }
 
 static void pmf_handle_notify_irq(void *data)