]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 12 Nov 2013 05:34:19 +0000 (14:34 +0900)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 12 Nov 2013 05:34:19 +0000 (14:34 +0900)
Pull powerpc updates from Benjamin Herrenschmidt:
 "The bulk of this is LE updates.  One should now be able to build an LE
  kernel and even run some things in it.

  I'm still sitting on a handful of patches to enable the new ABI that I
  *might* still send this merge window around, but due to the
  incertainty (they are pretty fresh) I want to keep them separate.

  Other notable changes are some infrastructure bits to better handle
  PCI pass-through under KVM, some bits and pieces added to the new
  PowerNV platform support such as access to the CPU SCOM bus via sysfs,
  and support for EEH error handling on PHB3 (Power8 PCIe).

  We also grew arch_get_random_long() for both pseries and powernv when
  running on P7+ and P8, exploiting the HW rng.

  And finally various embedded updates from freescale"

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (154 commits)
  powerpc: Fix fatal SLB miss when restoring PPR
  powerpc/powernv: Reserve the correct PE number
  powerpc/powernv: Add PE to its own PELTV
  powerpc/powernv: Add support for indirect XSCOM via debugfs
  powerpc/scom: Improve debugfs interface
  powerpc/scom: Enable 64-bit addresses
  powerpc/boot: Properly handle the base "of" boot wrapper
  powerpc/bpf: Support MOD operation
  powerpc/bpf: Fix DIVWU instruction opcode
  of: Move definition of of_find_next_cache_node into common code.
  powerpc: Remove big endianness assumption in of_find_next_cache_node
  powerpc/tm: Remove interrupt disable in __switch_to()
  powerpc: word-at-a-time optimization for 64-bit Little Endian
  powerpc/bpf: BPF JIT compiler for 64-bit Little Endian
  powerpc: Only save/restore SDR1 if in hypervisor mode
  powerpc/pmu: Fix ADB_PMU_LED_IDE dependencies
  powerpc/nvram: Fix endian issue when using the partition length
  powerpc/nvram: Fix endian issue when reading the NVRAM size
  powerpc/nvram: Scan partitions only once
  powerpc/mpc512x: remove unnecessary #if
  ...

168 files changed:
arch/powerpc/Kconfig
arch/powerpc/Makefile
arch/powerpc/boot/Makefile
arch/powerpc/boot/dts/b4860emu.dts [new file with mode: 0644]
arch/powerpc/boot/dts/b4qds.dtsi
arch/powerpc/boot/dts/c293pcie.dts
arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi
arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi
arch/powerpc/boot/dts/fsl/bsc9131si-post.dtsi
arch/powerpc/boot/dts/fsl/bsc9131si-pre.dtsi
arch/powerpc/boot/dts/t4240emu.dts [new file with mode: 0644]
arch/powerpc/boot/dts/t4240qds.dts
arch/powerpc/boot/wrapper
arch/powerpc/configs/corenet32_smp_defconfig
arch/powerpc/configs/corenet64_smp_defconfig
arch/powerpc/configs/mpc85xx_defconfig
arch/powerpc/configs/mpc85xx_smp_defconfig
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/configs/ppc64e_defconfig
arch/powerpc/configs/ppc6xx_defconfig
arch/powerpc/configs/pseries_defconfig
arch/powerpc/include/asm/archrandom.h [new file with mode: 0644]
arch/powerpc/include/asm/checksum.h
arch/powerpc/include/asm/emulated_ops.h
arch/powerpc/include/asm/hvsi.h
arch/powerpc/include/asm/io.h
arch/powerpc/include/asm/lppaca.h
arch/powerpc/include/asm/machdep.h
arch/powerpc/include/asm/mmu-hash64.h
arch/powerpc/include/asm/opal.h
arch/powerpc/include/asm/page.h
arch/powerpc/include/asm/pgtable-ppc64.h
arch/powerpc/include/asm/ppc-opcode.h
arch/powerpc/include/asm/ppc_asm.h
arch/powerpc/include/asm/processor.h
arch/powerpc/include/asm/prom.h
arch/powerpc/include/asm/reg.h
arch/powerpc/include/asm/reg_booke.h
arch/powerpc/include/asm/scom.h
arch/powerpc/include/asm/setup.h
arch/powerpc/include/asm/sfp-machine.h
arch/powerpc/include/asm/string.h
arch/powerpc/include/asm/switch_to.h
arch/powerpc/include/asm/word-at-a-time.h
arch/powerpc/include/asm/xor.h
arch/powerpc/include/uapi/asm/byteorder.h
arch/powerpc/kernel/align.c
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/eeh.c
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/exceptions-64e.S
arch/powerpc/kernel/fpu.S
arch/powerpc/kernel/ftrace.c
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/head_8xx.S
arch/powerpc/kernel/head_fsl_booke.S
arch/powerpc/kernel/kgdb.c
arch/powerpc/kernel/legacy_serial.c
arch/powerpc/kernel/machine_kexec_64.c
arch/powerpc/kernel/misc_32.S
arch/powerpc/kernel/module.c
arch/powerpc/kernel/module_32.c
arch/powerpc/kernel/module_64.c
arch/powerpc/kernel/nvram_64.c
arch/powerpc/kernel/paca.c
arch/powerpc/kernel/pci_of_scan.c
arch/powerpc/kernel/ppc_ksyms.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/prom_init.c
arch/powerpc/kernel/ptrace.c
arch/powerpc/kernel/ptrace32.c
arch/powerpc/kernel/rtas_pci.c
arch/powerpc/kernel/setup-common.c
arch/powerpc/kernel/setup.h [deleted file]
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/signal_32.c
arch/powerpc/kernel/signal_64.c
arch/powerpc/kernel/swsusp_asm64.S
arch/powerpc/kernel/tm.S
arch/powerpc/kernel/traps.c
arch/powerpc/kernel/vdso.c
arch/powerpc/kernel/vdso32/vdso32.lds.S
arch/powerpc/kernel/vdso64/vdso64.lds.S
arch/powerpc/kernel/vecemu.c
arch/powerpc/kernel/vector.S
arch/powerpc/kernel/vio.c
arch/powerpc/kvm/Kconfig
arch/powerpc/kvm/book3s_pr.c
arch/powerpc/kvm/booke.c
arch/powerpc/lib/Makefile
arch/powerpc/lib/copyuser_power7.S
arch/powerpc/lib/memcpy_power7.S
arch/powerpc/lib/sstep.c
arch/powerpc/lib/xor_vmx.c [new file with mode: 0644]
arch/powerpc/mm/hash_native_64.c
arch/powerpc/mm/hash_utils_64.c
arch/powerpc/mm/init_32.c
arch/powerpc/mm/init_64.c
arch/powerpc/mm/numa.c
arch/powerpc/mm/pgtable.c
arch/powerpc/net/bpf_jit.h
arch/powerpc/net/bpf_jit_64.S
arch/powerpc/net/bpf_jit_comp.c
arch/powerpc/platforms/512x/mpc512x_shared.c
arch/powerpc/platforms/52xx/Kconfig
arch/powerpc/platforms/52xx/mpc52xx_pic.c
arch/powerpc/platforms/83xx/mcu_mpc8349emitx.c
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/85xx/Makefile
arch/powerpc/platforms/85xx/b4_qds.c [deleted file]
arch/powerpc/platforms/85xx/corenet_ds.c [deleted file]
arch/powerpc/platforms/85xx/corenet_ds.h [deleted file]
arch/powerpc/platforms/85xx/corenet_generic.c [new file with mode: 0644]
arch/powerpc/platforms/85xx/p1010rdb.c
arch/powerpc/platforms/85xx/p2041_rdb.c [deleted file]
arch/powerpc/platforms/85xx/p3041_ds.c [deleted file]
arch/powerpc/platforms/85xx/p4080_ds.c [deleted file]
arch/powerpc/platforms/85xx/p5020_ds.c [deleted file]
arch/powerpc/platforms/85xx/p5040_ds.c [deleted file]
arch/powerpc/platforms/85xx/t4240_qds.c [deleted file]
arch/powerpc/platforms/8xx/tqm8xx_setup.c
arch/powerpc/platforms/Kconfig.cputype
arch/powerpc/platforms/chrp/nvram.c
arch/powerpc/platforms/embedded6xx/hlwd-pic.c
arch/powerpc/platforms/powernv/Kconfig
arch/powerpc/platforms/powernv/Makefile
arch/powerpc/platforms/powernv/eeh-ioda.c
arch/powerpc/platforms/powernv/eeh-powernv.c
arch/powerpc/platforms/powernv/opal-flash.c [new file with mode: 0644]
arch/powerpc/platforms/powernv/opal-nvram.c
arch/powerpc/platforms/powernv/opal-rtc.c
arch/powerpc/platforms/powernv/opal-wrappers.S
arch/powerpc/platforms/powernv/opal-xscom.c [new file with mode: 0644]
arch/powerpc/platforms/powernv/opal.c
arch/powerpc/platforms/powernv/pci-ioda.c
arch/powerpc/platforms/powernv/pci-p5ioc2.c
arch/powerpc/platforms/powernv/pci.c
arch/powerpc/platforms/powernv/pci.h
arch/powerpc/platforms/powernv/rng.c [new file with mode: 0644]
arch/powerpc/platforms/pseries/Makefile
arch/powerpc/platforms/pseries/iommu.c
arch/powerpc/platforms/pseries/nvram.c
arch/powerpc/platforms/pseries/rng.c [new file with mode: 0644]
arch/powerpc/platforms/wsp/scom_smp.c
arch/powerpc/platforms/wsp/scom_wsp.c
arch/powerpc/platforms/wsp/wsp.c
arch/powerpc/sysdev/Kconfig
arch/powerpc/sysdev/fsl_pci.c
arch/powerpc/sysdev/fsl_soc.h
arch/powerpc/sysdev/mpic.c
arch/powerpc/sysdev/mv64x60_dev.c
arch/powerpc/sysdev/scom.c
arch/powerpc/sysdev/xics/ics-opal.c
drivers/char/hw_random/Kconfig
drivers/char/hw_random/Makefile
drivers/char/hw_random/powernv-rng.c [new file with mode: 0644]
drivers/char/hw_random/pseries-rng.c
drivers/macintosh/Kconfig
drivers/of/base.c
drivers/tty/hvc/hvc_opal.c
drivers/tty/hvc/hvsi_lib.c
include/linux/hashtable.h
include/linux/mm.h
include/linux/of.h
include/linux/page-flags.h

index b365d5cbb722ce9ef712a6066695a409f9e0c627..2f898d63eb96ad4fb5b0cf0528aa69dfb54633cc 100644 (file)
@@ -97,7 +97,7 @@ config PPC
        select VIRT_TO_BUS if !PPC64
        select HAVE_IDE
        select HAVE_IOREMAP_PROT
-       select HAVE_EFFICIENT_UNALIGNED_ACCESS
+       select HAVE_EFFICIENT_UNALIGNED_ACCESS if !CPU_LITTLE_ENDIAN
        select HAVE_KPROBES
        select HAVE_ARCH_KGDB
        select HAVE_KRETPROBES
@@ -140,6 +140,9 @@ config PPC
        select HAVE_DEBUG_STACKOVERFLOW
        select HAVE_IRQ_EXIT_ON_IRQ_STACK
 
+config GENERIC_CSUM
+       def_bool CPU_LITTLE_ENDIAN
+
 config EARLY_PRINTK
        bool
        default y
@@ -405,7 +408,7 @@ config CRASH_DUMP
 
 config FA_DUMP
        bool "Firmware-assisted dump"
-       depends on PPC64 && PPC_RTAS && CRASH_DUMP
+       depends on PPC64 && PPC_RTAS && CRASH_DUMP && KEXEC
        help
          A robust mechanism to get reliable kernel crash dump with
          assistance from firmware. This approach does not use kexec,
@@ -418,7 +421,7 @@ config FA_DUMP
 
 config IRQ_ALL_CPUS
        bool "Distribute interrupts on all CPUs by default"
-       depends on SMP && !MV64360
+       depends on SMP
        help
          This option gives the kernel permission to distribute IRQs across
          multiple CPUs.  Saying N here will route all IRQs to the first
@@ -1010,6 +1013,9 @@ config PHYSICAL_START
        default "0x00000000"
 endif
 
+config ARCH_RANDOM
+       def_bool n
+
 source "net/Kconfig"
 
 source "drivers/Kconfig"
index 51cfb78d4061d30781b916fe7a21a3fd81daec8c..607acf54a425b2b50913ea6b4f48024a5d21aadc 100644 (file)
@@ -36,17 +36,26 @@ KBUILD_DEFCONFIG := ppc64_defconfig
 endif
 
 ifeq ($(CONFIG_PPC64),y)
-OLDARCH        := ppc64
-
 new_nm := $(shell if $(NM) --help 2>&1 | grep -- '--synthetic' > /dev/null; then echo y; else echo n; fi)
 
 ifeq ($(new_nm),y)
 NM             := $(NM) --synthetic
 endif
+endif
 
+ifeq ($(CONFIG_PPC64),y)
+ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y)
+OLDARCH        := ppc64le
+else
+OLDARCH        := ppc64
+endif
+else
+ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y)
+OLDARCH        := ppcle
 else
 OLDARCH        := ppc
 endif
+endif
 
 # It seems there are times we use this Makefile without
 # including the config file, but this replicates the old behaviour
@@ -56,11 +65,29 @@ endif
 
 UTS_MACHINE := $(OLDARCH)
 
+ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y)
+override CC    += -mlittle-endian -mno-strict-align
+override AS    += -mlittle-endian
+override LD    += -EL
+override CROSS32CC += -mlittle-endian
+override CROSS32AS += -mlittle-endian
+LDEMULATION    := lppc
+GNUTARGET      := powerpcle
+MULTIPLEWORD   := -mno-multiple
+else
+override CC    += -mbig-endian
+override AS    += -mbig-endian
+override LD    += -EB
+LDEMULATION    := ppc
+GNUTARGET      := powerpc
+MULTIPLEWORD   := -mmultiple
+endif
+
 ifeq ($(HAS_BIARCH),y)
 override AS    += -a$(CONFIG_WORD_SIZE)
-override LD    += -m elf$(CONFIG_WORD_SIZE)ppc
+override LD    += -m elf$(CONFIG_WORD_SIZE)$(LDEMULATION)
 override CC    += -m$(CONFIG_WORD_SIZE)
-override AR    := GNUTARGET=elf$(CONFIG_WORD_SIZE)-powerpc $(AR)
+override AR    := GNUTARGET=elf$(CONFIG_WORD_SIZE)-$(GNUTARGET) $(AR)
 endif
 
 LDFLAGS_vmlinux-y := -Bstatic
@@ -86,7 +113,7 @@ endif
 CFLAGS-$(CONFIG_PPC64) := -mtraceback=no -mcall-aixdesc
 CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mcmodel=medium,-mminimal-toc)
 CFLAGS-$(CONFIG_PPC64) += $(call cc-option,-mno-pointers-to-nested-functions)
-CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 -mmultiple
+CFLAGS-$(CONFIG_PPC32) := -ffixed-r2 $(MULTIPLEWORD)
 
 ifeq ($(CONFIG_PPC_BOOK3S_64),y)
 CFLAGS-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=power7,-mtune=power4)
index 15ca2255f43853945789c1fdc58f4a5bc5a82dbf..ca7f08cc4afd770b528931bbab92edc55ad5e8db 100644 (file)
@@ -22,7 +22,8 @@ all: $(obj)/zImage
 BOOTCFLAGS    := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
                 -fno-strict-aliasing -Os -msoft-float -pipe \
                 -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \
-                -isystem $(shell $(CROSS32CC) -print-file-name=include)
+                -isystem $(shell $(CROSS32CC) -print-file-name=include) \
+                -mbig-endian
 BOOTAFLAGS     := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc
 
 ifdef CONFIG_DEBUG_INFO
diff --git a/arch/powerpc/boot/dts/b4860emu.dts b/arch/powerpc/boot/dts/b4860emu.dts
new file mode 100644 (file)
index 0000000..7290021
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * B4860 emulator Device Tree Source
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * This software is provided by Freescale Semiconductor "as is" and any
+ * express or implied warranties, including, but not limited to, the implied
+ * warranties of merchantability and fitness for a particular purpose are
+ * disclaimed. In no event shall Freescale Semiconductor be liable for any
+ * direct, indirect, incidental, special, exemplary, or consequential damages
+ * (including, but not limited to, procurement of substitute goods or services;
+ * loss of use, data, or profits; or business interruption) however caused and
+ * on any theory of liability, whether in contract, strict liability, or tort
+ * (including negligence or otherwise) arising in any way out of the use of
+ * this software, even if advised of the possibility of such damage.
+ */
+
+/dts-v1/;
+
+/include/ "fsl/e6500_power_isa.dtsi"
+
+/ {
+       compatible = "fsl,B4860";
+       #address-cells = <2>;
+       #size-cells = <2>;
+       interrupt-parent = <&mpic>;
+
+       aliases {
+               ccsr = &soc;
+
+               serial0 = &serial0;
+               serial1 = &serial1;
+               serial2 = &serial2;
+               serial3 = &serial3;
+               dma0 = &dma0;
+               dma1 = &dma1;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: PowerPC,e6500@0 {
+                       device_type = "cpu";
+                       reg = <0 1>;
+                       next-level-cache = <&L2>;
+               };
+               cpu1: PowerPC,e6500@2 {
+                       device_type = "cpu";
+                       reg = <2 3>;
+                       next-level-cache = <&L2>;
+               };
+               cpu2: PowerPC,e6500@4 {
+                       device_type = "cpu";
+                       reg = <4 5>;
+                       next-level-cache = <&L2>;
+               };
+               cpu3: PowerPC,e6500@6 {
+                       device_type = "cpu";
+                       reg = <6 7>;
+                       next-level-cache = <&L2>;
+               };
+       };
+};
+
+/ {
+       model = "fsl,B4860QDS";
+       compatible = "fsl,B4860EMU", "fsl,B4860QDS";
+       #address-cells = <2>;
+       #size-cells = <2>;
+       interrupt-parent = <&mpic>;
+
+       ifc: localbus@ffe124000 {
+               reg = <0xf 0xfe124000 0 0x2000>;
+               ranges = <0 0 0xf 0xe8000000 0x08000000
+                         2 0 0xf 0xff800000 0x00010000
+                         3 0 0xf 0xffdf0000 0x00008000>;
+
+               nor@0,0 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "cfi-flash";
+                       reg = <0x0 0x0 0x8000000>;
+                       bank-width = <2>;
+                       device-width = <1>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+       };
+
+       soc: soc@ffe000000 {
+               ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+               reg = <0xf 0xfe000000 0 0x00001000>;
+       };
+};
+
+&ifc {
+       #address-cells = <2>;
+       #size-cells = <1>;
+       compatible = "fsl,ifc", "simple-bus";
+       interrupts = <25 2 0 0>;
+};
+
+&soc {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       device_type = "soc";
+       compatible = "simple-bus";
+
+       soc-sram-error {
+               compatible = "fsl,soc-sram-error";
+               interrupts = <16 2 1 2>;
+       };
+
+       corenet-law@0 {
+               compatible = "fsl,corenet-law";
+               reg = <0x0 0x1000>;
+               fsl,num-laws = <32>;
+       };
+
+       ddr1: memory-controller@8000 {
+               compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller";
+               reg = <0x8000 0x1000>;
+               interrupts = <16 2 1 8>;
+       };
+
+       ddr2: memory-controller@9000 {
+               compatible = "fsl,qoriq-memory-controller-v4.5","fsl,qoriq-memory-controller";
+               reg = <0x9000 0x1000>;
+               interrupts = <16 2 1 9>;
+       };
+
+       cpc: l3-cache-controller@10000 {
+               compatible = "fsl,b4-l3-cache-controller", "cache";
+               reg = <0x10000 0x1000
+                      0x11000 0x1000>;
+               interrupts = <16 2 1 4>;
+       };
+
+       corenet-cf@18000 {
+               compatible = "fsl,b4-corenet-cf";
+               reg = <0x18000 0x1000>;
+               interrupts = <16 2 1 0>;
+               fsl,ccf-num-csdids = <32>;
+               fsl,ccf-num-snoopids = <32>;
+       };
+
+       iommu@20000 {
+               compatible = "fsl,pamu-v1.0", "fsl,pamu";
+               reg = <0x20000 0x4000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               interrupts = <
+                       24 2 0 0
+                       16 2 1 1>;
+               pamu0: pamu@0 {
+                       reg = <0 0x1000>;
+                       fsl,primary-cache-geometry = <8 1>;
+                       fsl,secondary-cache-geometry = <32 2>;
+               };
+       };
+
+/include/ "fsl/qoriq-mpic.dtsi"
+
+       guts: global-utilities@e0000 {
+               compatible = "fsl,b4-device-config";
+               reg = <0xe0000 0xe00>;
+               fsl,has-rstcr;
+               fsl,liodn-bits = <12>;
+       };
+
+       clockgen: global-utilities@e1000 {
+               compatible = "fsl,b4-clockgen", "fsl,qoriq-clockgen-2.0";
+               reg = <0xe1000 0x1000>;
+       };
+
+/include/ "fsl/qoriq-dma-0.dtsi"
+       dma@100300 {
+               fsl,iommu-parent = <&pamu0>;
+               fsl,liodn-reg = <&guts 0x580>; /* DMA1LIODNR */
+       };
+
+/include/ "fsl/qoriq-dma-1.dtsi"
+       dma@101300 {
+               fsl,iommu-parent = <&pamu0>;
+               fsl,liodn-reg = <&guts 0x584>; /* DMA2LIODNR */
+       };
+
+/include/ "fsl/qoriq-i2c-0.dtsi"
+/include/ "fsl/qoriq-i2c-1.dtsi"
+/include/ "fsl/qoriq-duart-0.dtsi"
+/include/ "fsl/qoriq-duart-1.dtsi"
+
+       L2: l2-cache-controller@c20000 {
+               compatible = "fsl,b4-l2-cache-controller";
+               reg = <0xc20000 0x1000>;
+               next-level-cache = <&cpc>;
+       };
+};
index e6d2f8f9054463e567a4f0202147474496a0dadb..8b47edcfabf0716c8747773533cd882554bae620 100644 (file)
                };
 
                i2c@118000 {
-                       eeprom@50 {
-                               compatible = "at24,24c64";
-                               reg = <0x50>;
-                       };
-                       eeprom@51 {
-                               compatible = "at24,24c256";
-                               reg = <0x51>;
-                       };
-                       eeprom@53 {
-                               compatible = "at24,24c256";
-                               reg = <0x53>;
-                       };
-                       eeprom@57 {
-                               compatible = "at24,24c256";
-                               reg = <0x57>;
-                       };
-                       rtc@68 {
-                               compatible = "dallas,ds3232";
-                               reg = <0x68>;
+                       mux@77 {
+                               compatible = "nxp,pca9547";
+                               reg = <0x77>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               i2c@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <0>;
+
+                                       eeprom@50 {
+                                               compatible = "at24,24c64";
+                                               reg = <0x50>;
+                                       };
+                                       eeprom@51 {
+                                               compatible = "at24,24c256";
+                                               reg = <0x51>;
+                                       };
+                                       eeprom@53 {
+                                               compatible = "at24,24c256";
+                                               reg = <0x53>;
+                                       };
+                                       eeprom@57 {
+                                               compatible = "at24,24c256";
+                                               reg = <0x57>;
+                                       };
+                                       rtc@68 {
+                                               compatible = "dallas,ds3232";
+                                               reg = <0x68>;
+                                       };
+                               };
                        };
                };
 
index 1238bda8901f34a4d59fe76825c1282c45abc121..6681cc21030bda283cd2960d64e2f48cdc510861 100644 (file)
@@ -45,6 +45,7 @@
        ifc: ifc@fffe1e000 {
                reg = <0xf 0xffe1e000 0 0x2000>;
                ranges = <0x0 0x0 0xf 0xec000000 0x04000000
+                         0x1 0x0 0xf 0xff800000 0x00010000
                          0x2 0x0 0xf 0xffdf0000 0x00010000>;
 
        };
index 7b4426e0a5a578a6be24e800b1423ce7580668b6..c6e451affb055958b3943378878d6dc4c4a59284 100644 (file)
@@ -34,6 +34,8 @@
 
 /dts-v1/;
 
+/include/ "e6500_power_isa.dtsi"
+
 / {
        compatible = "fsl,B4420";
        #address-cells = <2>;
index e5cf6c81dd6644bc8f4dc26c097102d5e5de3e65..981397518fc6243919e78118944d8dda2f763f6b 100644 (file)
@@ -41,7 +41,7 @@
 
 &rio {
        compatible = "fsl,srio";
-       interrupts = <16 2 1 11>;
+       interrupts = <16 2 1 20>;
        #address-cells = <2>;
        #size-cells = <2>;
        fsl,iommu-parent = <&pamu0>;
index 5263fa46a3fb30ff042d44b26dc0afa01c8fb758..9bc26b14790061ea3793f7b3f4afa7c06efd09d3 100644 (file)
@@ -34,6 +34,8 @@
 
 /dts-v1/;
 
+/include/ "e6500_power_isa.dtsi"
+
 / {
        compatible = "fsl,B4860";
        #address-cells = <2>;
index 5180d9d37989000f37e4b45ad98fcb766d39c500..0c0efa94cfb4e958473c671f6dd6c64d6707bc55 100644 (file)
@@ -130,7 +130,7 @@ usb@22000 {
 
 /include/ "pq3-esdhc-0.dtsi"
        sdhc@2e000 {
-               fsl,sdhci-auto-cmd12;
+               sdhci,auto-cmd12;
                interrupts = <41 0x2 0 0>;
        };
 
index 743e4aeda349b7dbdc14a29fb2d049bc2d1d5fb5..f6ec4a67560c1a7cdda55027d2e777a43a0f33d6 100644 (file)
@@ -33,6 +33,9 @@
  */
 
 /dts-v1/;
+
+/include/ "e500v2_power_isa.dtsi"
+
 / {
        compatible = "fsl,BSC9131";
        #address-cells = <2>;
diff --git a/arch/powerpc/boot/dts/t4240emu.dts b/arch/powerpc/boot/dts/t4240emu.dts
new file mode 100644 (file)
index 0000000..ee24ab3
--- /dev/null
@@ -0,0 +1,268 @@
+/*
+ * T4240 emulator Device Tree Source
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+/include/ "fsl/e6500_power_isa.dtsi"
+/ {
+       compatible = "fsl,T4240";
+       #address-cells = <2>;
+       #size-cells = <2>;
+       interrupt-parent = <&mpic>;
+
+       aliases {
+               ccsr = &soc;
+
+               serial0 = &serial0;
+               serial1 = &serial1;
+               serial2 = &serial2;
+               serial3 = &serial3;
+               dma0 = &dma0;
+               dma1 = &dma1;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               cpu0: PowerPC,e6500@0 {
+                       device_type = "cpu";
+                       reg = <0 1>;
+                       next-level-cache = <&L2_1>;
+               };
+               cpu1: PowerPC,e6500@2 {
+                       device_type = "cpu";
+                       reg = <2 3>;
+                       next-level-cache = <&L2_1>;
+               };
+               cpu2: PowerPC,e6500@4 {
+                       device_type = "cpu";
+                       reg = <4 5>;
+                       next-level-cache = <&L2_1>;
+               };
+               cpu3: PowerPC,e6500@6 {
+                       device_type = "cpu";
+                       reg = <6 7>;
+                       next-level-cache = <&L2_1>;
+               };
+
+               cpu4: PowerPC,e6500@8 {
+                       device_type = "cpu";
+                       reg = <8 9>;
+                       next-level-cache = <&L2_2>;
+               };
+               cpu5: PowerPC,e6500@10 {
+                       device_type = "cpu";
+                       reg = <10 11>;
+                       next-level-cache = <&L2_2>;
+               };
+               cpu6: PowerPC,e6500@12 {
+                       device_type = "cpu";
+                       reg = <12 13>;
+                       next-level-cache = <&L2_2>;
+               };
+               cpu7: PowerPC,e6500@14 {
+                       device_type = "cpu";
+                       reg = <14 15>;
+                       next-level-cache = <&L2_2>;
+               };
+
+               cpu8: PowerPC,e6500@16 {
+                       device_type = "cpu";
+                       reg = <16 17>;
+                       next-level-cache = <&L2_3>;
+               };
+               cpu9: PowerPC,e6500@18 {
+                       device_type = "cpu";
+                       reg = <18 19>;
+                       next-level-cache = <&L2_3>;
+               };
+               cpu10: PowerPC,e6500@20 {
+                       device_type = "cpu";
+                       reg = <20 21>;
+                       next-level-cache = <&L2_3>;
+               };
+               cpu11: PowerPC,e6500@22 {
+                       device_type = "cpu";
+                       reg = <22 23>;
+                       next-level-cache = <&L2_3>;
+               };
+       };
+};
+
+/ {
+       model = "fsl,T4240QDS";
+       compatible = "fsl,T4240EMU", "fsl,T4240QDS";
+       #address-cells = <2>;
+       #size-cells = <2>;
+       interrupt-parent = <&mpic>;
+
+       ifc: localbus@ffe124000 {
+               reg = <0xf 0xfe124000 0 0x2000>;
+               ranges = <0 0 0xf 0xe8000000 0x08000000
+                         2 0 0xf 0xff800000 0x00010000
+                         3 0 0xf 0xffdf0000 0x00008000>;
+
+               nor@0,0 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "cfi-flash";
+                       reg = <0x0 0x0 0x8000000>;
+
+                       bank-width = <2>;
+                       device-width = <1>;
+               };
+
+       };
+
+       memory {
+               device_type = "memory";
+       };
+
+       soc: soc@ffe000000 {
+               ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+               reg = <0xf 0xfe000000 0 0x00001000>;
+
+       };
+};
+
+&ifc {
+       #address-cells = <2>;
+       #size-cells = <1>;
+       compatible = "fsl,ifc", "simple-bus";
+       interrupts = <25 2 0 0>;
+};
+
+&soc {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       device_type = "soc";
+       compatible = "simple-bus";
+
+       soc-sram-error {
+               compatible = "fsl,soc-sram-error";
+               interrupts = <16 2 1 29>;
+       };
+
+       corenet-law@0 {
+               compatible = "fsl,corenet-law";
+               reg = <0x0 0x1000>;
+               fsl,num-laws = <32>;
+       };
+
+       ddr1: memory-controller@8000 {
+               compatible = "fsl,qoriq-memory-controller-v4.7",
+                               "fsl,qoriq-memory-controller";
+               reg = <0x8000 0x1000>;
+               interrupts = <16 2 1 23>;
+       };
+
+       ddr2: memory-controller@9000 {
+               compatible = "fsl,qoriq-memory-controller-v4.7",
+                               "fsl,qoriq-memory-controller";
+               reg = <0x9000 0x1000>;
+               interrupts = <16 2 1 22>;
+       };
+
+       ddr3: memory-controller@a000 {
+               compatible = "fsl,qoriq-memory-controller-v4.7",
+                               "fsl,qoriq-memory-controller";
+               reg = <0xa000 0x1000>;
+               interrupts = <16 2 1 21>;
+       };
+
+       cpc: l3-cache-controller@10000 {
+               compatible = "fsl,t4240-l3-cache-controller", "cache";
+               reg = <0x10000 0x1000
+                      0x11000 0x1000
+                      0x12000 0x1000>;
+               interrupts = <16 2 1 27
+                             16 2 1 26
+                             16 2 1 25>;
+       };
+
+       corenet-cf@18000 {
+               compatible = "fsl,corenet-cf";
+               reg = <0x18000 0x1000>;
+               interrupts = <16 2 1 31>;
+               fsl,ccf-num-csdids = <32>;
+               fsl,ccf-num-snoopids = <32>;
+       };
+
+       iommu@20000 {
+               compatible = "fsl,pamu-v1.0", "fsl,pamu";
+               reg = <0x20000 0x6000>;
+               interrupts = <
+                       24 2 0 0
+                       16 2 1 30>;
+       };
+
+/include/ "fsl/qoriq-mpic.dtsi"
+
+       guts: global-utilities@e0000 {
+               compatible = "fsl,t4240-device-config", "fsl,qoriq-device-config-2.0";
+               reg = <0xe0000 0xe00>;
+               fsl,has-rstcr;
+               fsl,liodn-bits = <12>;
+       };
+
+       clockgen: global-utilities@e1000 {
+               compatible = "fsl,t4240-clockgen", "fsl,qoriq-clockgen-2.0";
+               reg = <0xe1000 0x1000>;
+       };
+
+/include/ "fsl/qoriq-dma-0.dtsi"
+/include/ "fsl/qoriq-dma-1.dtsi"
+
+/include/ "fsl/qoriq-i2c-0.dtsi"
+/include/ "fsl/qoriq-i2c-1.dtsi"
+/include/ "fsl/qoriq-duart-0.dtsi"
+/include/ "fsl/qoriq-duart-1.dtsi"
+
+       L2_1: l2-cache-controller@c20000 {
+               compatible = "fsl,t4240-l2-cache-controller";
+               reg = <0xc20000 0x40000>;
+               next-level-cache = <&cpc>;
+       };
+       L2_2: l2-cache-controller@c60000 {
+               compatible = "fsl,t4240-l2-cache-controller";
+               reg = <0xc60000 0x40000>;
+               next-level-cache = <&cpc>;
+       };
+       L2_3: l2-cache-controller@ca0000 {
+               compatible = "fsl,t4240-l2-cache-controller";
+               reg = <0xca0000 0x40000>;
+               next-level-cache = <&cpc>;
+       };
+};
index 0555976dd0f34b0b1c5b9b916a17369c2c0520f4..63e81b010804f4e552dc14da69632211f2769403 100644 (file)
                };
 
                i2c@118000 {
-                       eeprom@51 {
-                               compatible = "at24,24c256";
-                               reg = <0x51>;
-                       };
-                       eeprom@52 {
-                               compatible = "at24,24c256";
-                               reg = <0x52>;
-                       };
-                       eeprom@53 {
-                               compatible = "at24,24c256";
-                               reg = <0x53>;
-                       };
-                       eeprom@54 {
-                               compatible = "at24,24c256";
-                               reg = <0x54>;
-                       };
-                       eeprom@55 {
-                               compatible = "at24,24c256";
-                               reg = <0x55>;
-                       };
-                       eeprom@56 {
-                               compatible = "at24,24c256";
-                               reg = <0x56>;
-                       };
-                       rtc@68 {
-                               compatible = "dallas,ds3232";
-                               reg = <0x68>;
-                               interrupts = <0x1 0x1 0 0>;
+                       mux@77 {
+                               compatible = "nxp,pca9547";
+                               reg = <0x77>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               i2c@0 {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       reg = <0>;
+
+                                       eeprom@51 {
+                                               compatible = "at24,24c256";
+                                               reg = <0x51>;
+                                       };
+                                       eeprom@52 {
+                                               compatible = "at24,24c256";
+                                               reg = <0x52>;
+                                       };
+                                       eeprom@53 {
+                                               compatible = "at24,24c256";
+                                               reg = <0x53>;
+                                       };
+                                       eeprom@54 {
+                                               compatible = "at24,24c256";
+                                               reg = <0x54>;
+                                       };
+                                       eeprom@55 {
+                                               compatible = "at24,24c256";
+                                               reg = <0x55>;
+                                       };
+                                       eeprom@56 {
+                                               compatible = "at24,24c256";
+                                               reg = <0x56>;
+                                       };
+                                       rtc@68 {
+                                               compatible = "dallas,ds3232";
+                                               reg = <0x68>;
+                                               interrupts = <0x1 0x1 0 0>;
+                                       };
+                               };
                        };
                };
+
+               sdhc@114000 {
+                       voltage-ranges = <1800 1800 3300 3300>;
+               };
        };
 
        pci0: pcie@ffe240000 {
index cd7af841ba051f8725e8ab33dffae1a23201fc60..2e1af74a64bec5ba3a53ccde16350520ed3f532a 100755 (executable)
@@ -147,21 +147,29 @@ link_address='0x400000'
 make_space=y
 
 case "$platform" in
+of)
+    platformo="$object/of.o $object/epapr.o"
+    make_space=n
+    ;;
 pseries)
     platformo="$object/of.o $object/epapr.o"
     link_address='0x4000000'
+    make_space=n
     ;;
 maple)
     platformo="$object/of.o $object/epapr.o"
     link_address='0x400000'
+    make_space=n
     ;;
 pmac|chrp)
     platformo="$object/of.o $object/epapr.o"
+    make_space=n
     ;;
 coff)
     platformo="$object/crt0.o $object/of.o $object/epapr.o"
     lds=$object/zImage.coff.lds
     link_address='0x500000'
+    make_space=n
     pie=
     ;;
 miboot|uboot*)
index 3dfab4c40c76117ae6664d2af8d4a1e9a0eb8e8a..bbd794deb6eb13a471d4097996ec57f9f9c7a092 100644 (file)
@@ -23,11 +23,7 @@ CONFIG_MODVERSIONS=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_MAC_PARTITION=y
-CONFIG_P2041_RDB=y
-CONFIG_P3041_DS=y
-CONFIG_P4080_DS=y
-CONFIG_P5020_DS=y
-CONFIG_P5040_DS=y
+CONFIG_CORENET_GENERIC=y
 CONFIG_HIGHMEM=y
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_BINFMT_MISC=m
@@ -104,6 +100,7 @@ CONFIG_FSL_PQ_MDIO=y
 CONFIG_E1000=y
 CONFIG_E1000E=y
 CONFIG_VITESSE_PHY=y
+CONFIG_AT803X_PHY=y
 CONFIG_FIXED_PHY=y
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_KEYBOARD is not set
index fa94fb3bb44db843e41a99c3f97799b99cac811f..63508ddee11c899b7fd0aade515b9ee7e32bd9df 100644 (file)
@@ -21,10 +21,7 @@ CONFIG_MODVERSIONS=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_MAC_PARTITION=y
-CONFIG_B4_QDS=y
-CONFIG_P5020_DS=y
-CONFIG_P5040_DS=y
-CONFIG_T4240_QDS=y
+CONFIG_CORENET_GENERIC=y
 # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
 CONFIG_BINFMT_MISC=m
 CONFIG_MATH_EMULATION=y
index dc098d9882111263bb07fbe7e19202d8cf25e180..d2e0fab5ee5b3ec5ac315fe1e9af261cc24ab567 100644 (file)
@@ -138,6 +138,7 @@ CONFIG_MARVELL_PHY=y
 CONFIG_DAVICOM_PHY=y
 CONFIG_CICADA_PHY=y
 CONFIG_VITESSE_PHY=y
+CONFIG_AT803X_PHY=y
 CONFIG_FIXED_PHY=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_MOUSEDEV is not set
index 5bca60161bb339490ce0d6d44b18ae63a86f123a..4cb7b59e98bd84259aefb48d8515fd3a4d8da32d 100644 (file)
@@ -138,6 +138,7 @@ CONFIG_MARVELL_PHY=y
 CONFIG_DAVICOM_PHY=y
 CONFIG_CICADA_PHY=y
 CONFIG_VITESSE_PHY=y
+CONFIG_AT803X_PHY=y
 CONFIG_FIXED_PHY=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_MOUSEDEV is not set
index 0e8cfd09da2f65dd95197c2e8ca86d5ae6dfbf24..581a3bcae7283607bed819cb9d26f7a2b6c6b96f 100644 (file)
@@ -2,7 +2,6 @@ CONFIG_PPC64=y
 CONFIG_ALTIVEC=y
 CONFIG_VSX=y
 CONFIG_SMP=y
-CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_IRQ_DOMAIN_DEBUG=y
@@ -25,7 +24,6 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_PARTITION_ADVANCED=y
-CONFIG_EFI_PARTITION=y
 CONFIG_PPC_SPLPAR=y
 CONFIG_SCANLOG=m
 CONFIG_PPC_SMLPAR=y
@@ -50,12 +48,10 @@ CONFIG_CPU_FREQ_PMAC64=y
 CONFIG_HZ_100=y
 CONFIG_BINFMT_MISC=m
 CONFIG_PPC_TRANSACTIONAL_MEM=y
-CONFIG_HOTPLUG_CPU=y
 CONFIG_KEXEC=y
 CONFIG_IRQ_ALL_CPUS=y
 CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_SCHED_SMT=y
-CONFIG_PPC_DENORMALISATION=y
 CONFIG_PCCARD=y
 CONFIG_ELECTRA_CF=y
 CONFIG_HOTPLUG_PCI=y
@@ -89,7 +85,6 @@ CONFIG_NF_CONNTRACK_PPTP=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CONNTRACK_TFTP=m
 CONFIG_NF_CT_NETLINK=m
-CONFIG_NETFILTER_TPROXY=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
@@ -131,7 +126,6 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_U32=m
 CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
@@ -157,6 +151,7 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_VIRTIO_BLK=m
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_GENERIC=y
@@ -185,6 +180,10 @@ CONFIG_SCSI_IPR=y
 CONFIG_SCSI_QLA_FC=m
 CONFIG_SCSI_QLA_ISCSI=m
 CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_VIRTIO=m
+CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_ALUA=m
 CONFIG_ATA=y
 CONFIG_SATA_SIL24=y
 CONFIG_SATA_SVW=y
@@ -203,6 +202,9 @@ CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+CONFIG_DM_UEVENT=y
 CONFIG_ADB_PMU=y
 CONFIG_PMAC_SMU=y
 CONFIG_THERM_PM72=y
@@ -216,6 +218,8 @@ CONFIG_DUMMY=m
 CONFIG_NETCONSOLE=y
 CONFIG_NETPOLL_TRAP=y
 CONFIG_TUN=m
+CONFIG_VIRTIO_NET=m
+CONFIG_VHOST_NET=m
 CONFIG_VORTEX=y
 CONFIG_ACENIC=m
 CONFIG_ACENIC_OMIT_TIGON_I=y
@@ -262,6 +266,7 @@ CONFIG_HVC_CONSOLE=y
 CONFIG_HVC_RTAS=y
 CONFIG_HVC_BEAT=y
 CONFIG_HVCS=m
+CONFIG_VIRTIO_CONSOLE=m
 CONFIG_IBM_BSR=m
 CONFIG_RAW_DRIVER=y
 CONFIG_I2C_CHARDEV=y
@@ -301,7 +306,6 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_PANTHERLORD=y
 CONFIG_HID_PETALYNX=y
 CONFIG_HID_SAMSUNG=y
-CONFIG_HID_SONY=y
 CONFIG_HID_SUNPLUS=y
 CONFIG_USB_HIDDEV=y
 CONFIG_USB=y
@@ -328,6 +332,8 @@ CONFIG_EDAC_MM_EDAC=y
 CONFIG_EDAC_PASEMI=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_DS1307=y
+CONFIG_VIRTIO_PCI=m
+CONFIG_VIRTIO_BALLOON=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
@@ -386,21 +392,19 @@ CONFIG_NLS_UTF8=y
 CONFIG_CRC_T10DIF=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_LOCKUP_DETECTOR=y
 CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_LATENCYTOP=y
 CONFIG_SCHED_TRACER=y
 CONFIG_BLK_DEV_IO_TRACE=y
-CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_CODE_PATCHING_SELFTEST=y
 CONFIG_FTR_FIXUP_SELFTEST=y
 CONFIG_MSI_BITMAP_SELFTEST=y
 CONFIG_XMON=y
 CONFIG_BOOTX_TEXT=y
 CONFIG_PPC_EARLY_DEBUG=y
-CONFIG_PPC_EARLY_DEBUG_BOOTX=y
-CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_HMAC=y
@@ -422,4 +426,3 @@ CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM_BOOK3S_64=m
 CONFIG_KVM_BOOK3S_64_HV=y
-CONFIG_VHOST_NET=m
index 0085dc4642c5bb107b61bcbe80c9935449d64b8d..f627fda0895303061ee4fc199641fbc6a2a7272b 100644 (file)
@@ -1,7 +1,6 @@
 CONFIG_PPC64=y
 CONFIG_PPC_BOOK3E_64=y
 CONFIG_SMP=y
-CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_NO_HZ=y
@@ -23,7 +22,7 @@ CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_MAC_PARTITION=y
 CONFIG_EFI_PARTITION=y
-CONFIG_P5020_DS=y
+CONFIG_CORENET_GENERIC=y
 CONFIG_CPU_FREQ=y
 CONFIG_CPU_FREQ_GOV_POWERSAVE=y
 CONFIG_CPU_FREQ_GOV_USERSPACE=y
@@ -61,7 +60,6 @@ CONFIG_NF_CONNTRACK_PPTP=m
 CONFIG_NF_CONNTRACK_SIP=m
 CONFIG_NF_CONNTRACK_TFTP=m
 CONFIG_NF_CT_NETLINK=m
-CONFIG_NETFILTER_TPROXY=m
 CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
 CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
 CONFIG_NETFILTER_XT_TARGET_DSCP=m
@@ -103,7 +101,6 @@ CONFIG_NETFILTER_XT_MATCH_STRING=m
 CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_U32=m
 CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
@@ -193,7 +190,6 @@ CONFIG_PPP_SYNC_TTY=m
 CONFIG_INPUT_EVDEV=m
 CONFIG_INPUT_MISC=y
 # CONFIG_SERIO_SERPORT is not set
-CONFIG_VT_HW_CONSOLE_BINDING=y
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 # CONFIG_HW_RANDOM is not set
@@ -230,7 +226,6 @@ CONFIG_HID_NTRIG=y
 CONFIG_HID_PANTHERLORD=y
 CONFIG_HID_PETALYNX=y
 CONFIG_HID_SAMSUNG=y
-CONFIG_HID_SONY=y
 CONFIG_HID_SUNPLUS=y
 CONFIG_HID_GREENASIA=y
 CONFIG_HID_SMARTJOYPLUS=y
@@ -302,19 +297,18 @@ CONFIG_NLS_UTF8=y
 CONFIG_CRC_T10DIF=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_STACK_USAGE=y
 CONFIG_LATENCYTOP=y
 CONFIG_IRQSOFF_TRACER=y
 CONFIG_SCHED_TRACER=y
 CONFIG_BLK_DEV_IO_TRACE=y
-CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_CODE_PATCHING_SELFTEST=y
 CONFIG_FTR_FIXUP_SELFTEST=y
 CONFIG_MSI_BITMAP_SELFTEST=y
 CONFIG_XMON=y
-CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_CCM=m
 CONFIG_CRYPTO_GCM=m
index 20ebfaf7234b1976c3889cb5d32a6015c2e39dcf..c2353bf059fd49ac95525a90aedd432c8a61701b 100644 (file)
@@ -71,7 +71,7 @@ CONFIG_QUICC_ENGINE=y
 CONFIG_QE_GPIO=y
 CONFIG_PPC_BESTCOMM=y
 CONFIG_GPIO_MPC8XXX=y
-CONFIG_MCU_MPC8349EMITX=m
+CONFIG_MCU_MPC8349EMITX=y
 CONFIG_HIGHMEM=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
index 1d4b9763895df77dafcfd61bb4eea7bed6a18621..e9a8b4e0a0f6309fb7a8a037d01615dc1018ffa1 100644 (file)
@@ -3,7 +3,6 @@ CONFIG_ALTIVEC=y
 CONFIG_VSX=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2048
-CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_POSIX_MQUEUE=y
 CONFIG_AUDIT=y
@@ -33,7 +32,6 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_PARTITION_ADVANCED=y
-CONFIG_EFI_PARTITION=y
 CONFIG_PPC_SPLPAR=y
 CONFIG_SCANLOG=m
 CONFIG_PPC_SMLPAR=y
@@ -44,7 +42,6 @@ CONFIG_IBMEBUS=y
 CONFIG_HZ_100=y
 CONFIG_BINFMT_MISC=m
 CONFIG_PPC_TRANSACTIONAL_MEM=y
-CONFIG_HOTPLUG_CPU=y
 CONFIG_KEXEC=y
 CONFIG_IRQ_ALL_CPUS=y
 CONFIG_MEMORY_HOTPLUG=y
@@ -52,7 +49,6 @@ CONFIG_MEMORY_HOTREMOVE=y
 CONFIG_PPC_64K_PAGES=y
 CONFIG_PPC_SUBPAGE_PROT=y
 CONFIG_SCHED_SMT=y
-CONFIG_PPC_DENORMALISATION=y
 CONFIG_HOTPLUG_PCI=y
 CONFIG_HOTPLUG_PCI_RPA=m
 CONFIG_HOTPLUG_PCI_RPA_DLPAR=m
@@ -113,7 +109,6 @@ CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
 CONFIG_NETFILTER_XT_MATCH_TIME=m
 CONFIG_NETFILTER_XT_MATCH_U32=m
 CONFIG_NF_CONNTRACK_IPV4=m
-CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
 CONFIG_IP_NF_MATCH_AH=m
 CONFIG_IP_NF_MATCH_ECN=m
@@ -132,6 +127,7 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_NBD=m
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_VIRTIO_BLK=m
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDECD=y
 CONFIG_BLK_DEV_GENERIC=y
@@ -157,6 +153,10 @@ CONFIG_SCSI_IPR=y
 CONFIG_SCSI_QLA_FC=m
 CONFIG_SCSI_QLA_ISCSI=m
 CONFIG_SCSI_LPFC=m
+CONFIG_SCSI_VIRTIO=m
+CONFIG_SCSI_DH=m
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_ALUA=m
 CONFIG_ATA=y
 # CONFIG_ATA_SFF is not set
 CONFIG_MD=y
@@ -174,11 +174,16 @@ CONFIG_DM_SNAPSHOT=m
 CONFIG_DM_MIRROR=m
 CONFIG_DM_ZERO=m
 CONFIG_DM_MULTIPATH=m
+CONFIG_DM_MULTIPATH_QL=m
+CONFIG_DM_MULTIPATH_ST=m
+CONFIG_DM_UEVENT=y
 CONFIG_BONDING=m
 CONFIG_DUMMY=m
 CONFIG_NETCONSOLE=y
 CONFIG_NETPOLL_TRAP=y
 CONFIG_TUN=m
+CONFIG_VIRTIO_NET=m
+CONFIG_VHOST_NET=m
 CONFIG_VORTEX=y
 CONFIG_ACENIC=m
 CONFIG_ACENIC_OMIT_TIGON_I=y
@@ -216,6 +221,7 @@ CONFIG_SERIAL_JSM=m
 CONFIG_HVC_CONSOLE=y
 CONFIG_HVC_RTAS=y
 CONFIG_HVCS=m
+CONFIG_VIRTIO_CONSOLE=m
 CONFIG_IBM_BSR=m
 CONFIG_GEN_RTC=y
 CONFIG_RAW_DRIVER=y
@@ -237,7 +243,6 @@ CONFIG_HID_GYRATION=y
 CONFIG_HID_PANTHERLORD=y
 CONFIG_HID_PETALYNX=y
 CONFIG_HID_SAMSUNG=y
-CONFIG_HID_SONY=y
 CONFIG_HID_SUNPLUS=y
 CONFIG_USB_HIDDEV=y
 CONFIG_USB=y
@@ -258,6 +263,8 @@ CONFIG_INFINIBAND_IPOIB=m
 CONFIG_INFINIBAND_IPOIB_CM=y
 CONFIG_INFINIBAND_SRP=m
 CONFIG_INFINIBAND_ISER=m
+CONFIG_VIRTIO_PCI=m
+CONFIG_VIRTIO_BALLOON=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_POSIX_ACL=y
@@ -314,18 +321,17 @@ CONFIG_NLS_UTF8=y
 CONFIG_CRC_T10DIF=y
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_KERNEL=y
-CONFIG_LOCKUP_DETECTOR=y
 CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_LOCKUP_DETECTOR=y
 CONFIG_LATENCYTOP=y
 CONFIG_SCHED_TRACER=y
 CONFIG_BLK_DEV_IO_TRACE=y
-CONFIG_DEBUG_STACKOVERFLOW=y
 CONFIG_CODE_PATCHING_SELFTEST=y
 CONFIG_FTR_FIXUP_SELFTEST=y
 CONFIG_MSI_BITMAP_SELFTEST=y
 CONFIG_XMON=y
 CONFIG_XMON_DEFAULT=y
-CONFIG_CRYPTO_NULL=m
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_HMAC=y
@@ -347,4 +353,3 @@ CONFIG_CRYPTO_DEV_NX_ENCRYPT=m
 CONFIG_VIRTUALIZATION=y
 CONFIG_KVM_BOOK3S_64=m
 CONFIG_KVM_BOOK3S_64_HV=y
-CONFIG_VHOST_NET=m
diff --git a/arch/powerpc/include/asm/archrandom.h b/arch/powerpc/include/asm/archrandom.h
new file mode 100644 (file)
index 0000000..d853d16
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef _ASM_POWERPC_ARCHRANDOM_H
+#define _ASM_POWERPC_ARCHRANDOM_H
+
+#ifdef CONFIG_ARCH_RANDOM
+
+#include <asm/machdep.h>
+
+static inline int arch_get_random_long(unsigned long *v)
+{
+       if (ppc_md.get_random_long)
+               return ppc_md.get_random_long(v);
+
+       return 0;
+}
+
+static inline int arch_get_random_int(unsigned int *v)
+{
+       unsigned long val;
+       int rc;
+
+       rc = arch_get_random_long(&val);
+       if (rc)
+               *v = val;
+
+       return rc;
+}
+
+int powernv_get_random_long(unsigned long *v);
+
+#endif /* CONFIG_ARCH_RANDOM */
+
+#endif /* _ASM_POWERPC_ARCHRANDOM_H */
index ce0c28495f9a0416450a33a4ceee4b3a33be45c2..8251a3ba870f8cfd27a5b1c84c794ac719e34ace 100644 (file)
@@ -14,6 +14,9 @@
  * which always checksum on 4 octet boundaries.  ihl is the number
  * of 32-bit words and is always >= 5.
  */
+#ifdef CONFIG_GENERIC_CSUM
+#include <asm-generic/checksum.h>
+#else
 extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
 
 /*
@@ -123,5 +126,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
        return sum;
 #endif
 }
+
+#endif
 #endif /* __KERNEL__ */
 #endif
index 5a8b82aa7241c1d6fae279ebf80864a94db32558..4358e3002f35a3c40c481f9680d891ec94502c2e 100644 (file)
@@ -43,6 +43,7 @@ extern struct ppc_emulated {
        struct ppc_emulated_entry popcntb;
        struct ppc_emulated_entry spe;
        struct ppc_emulated_entry string;
+       struct ppc_emulated_entry sync;
        struct ppc_emulated_entry unaligned;
 #ifdef CONFIG_MATH_EMULATION
        struct ppc_emulated_entry math;
index d3f64f361814cf4210ad9e968ccb747fe8c87048..d4a5315718ca454a6a4d01ceab9d4a0e767ac267 100644 (file)
@@ -25,7 +25,7 @@
 struct hvsi_header {
        uint8_t  type;
        uint8_t  len;
-       uint16_t seqno;
+       __be16 seqno;
 } __attribute__((packed));
 
 struct hvsi_data {
@@ -35,24 +35,24 @@ struct hvsi_data {
 
 struct hvsi_control {
        struct hvsi_header hdr;
-       uint16_t verb;
+       __be16 verb;
        /* optional depending on verb: */
-       uint32_t word;
-       uint32_t mask;
+       __be32 word;
+       __be32 mask;
 } __attribute__((packed));
 
 struct hvsi_query {
        struct hvsi_header hdr;
-       uint16_t verb;
+       __be16 verb;
 } __attribute__((packed));
 
 struct hvsi_query_response {
        struct hvsi_header hdr;
-       uint16_t verb;
-       uint16_t query_seqno;
+       __be16 verb;
+       __be16 query_seqno;
        union {
                uint8_t  version;
-               uint32_t mctrl_word;
+               __be32 mctrl_word;
        } u;
 } __attribute__((packed));
 
index 5a64757dc0d1eb0206f2499a7e26e39fec7cda21..575fbf81fad02dcd8e946cecfa9c5d5c35e11810 100644 (file)
@@ -21,7 +21,7 @@ extern struct pci_dev *isa_bridge_pcidev;
 /*
  * has legacy ISA devices ?
  */
-#define arch_has_dev_port()    (isa_bridge_pcidev != NULL)
+#define arch_has_dev_port()    (isa_bridge_pcidev != NULL || isa_io_special)
 #endif
 
 #include <linux/device.h>
@@ -113,7 +113,7 @@ extern bool isa_io_special;
 
 /* gcc 4.0 and older doesn't have 'Z' constraint */
 #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 0)
-#define DEF_MMIO_IN_LE(name, size, insn)                               \
+#define DEF_MMIO_IN_X(name, size, insn)                                \
 static inline u##size name(const volatile u##size __iomem *addr)       \
 {                                                                      \
        u##size ret;                                                    \
@@ -122,7 +122,7 @@ static inline u##size name(const volatile u##size __iomem *addr)    \
        return ret;                                                     \
 }
 
-#define DEF_MMIO_OUT_LE(name, size, insn)                              \
+#define DEF_MMIO_OUT_X(name, size, insn)                               \
 static inline void name(volatile u##size __iomem *addr, u##size val)   \
 {                                                                      \
        __asm__ __volatile__("sync;"#insn" %1,0,%2"                     \
@@ -130,7 +130,7 @@ static inline void name(volatile u##size __iomem *addr, u##size val)        \
        IO_SET_SYNC_FLAG();                                             \
 }
 #else /* newer gcc */
-#define DEF_MMIO_IN_LE(name, size, insn)                               \
+#define DEF_MMIO_IN_X(name, size, insn)                                \
 static inline u##size name(const volatile u##size __iomem *addr)       \
 {                                                                      \
        u##size ret;                                                    \
@@ -139,7 +139,7 @@ static inline u##size name(const volatile u##size __iomem *addr)    \
        return ret;                                                     \
 }
 
-#define DEF_MMIO_OUT_LE(name, size, insn)                              \
+#define DEF_MMIO_OUT_X(name, size, insn)                               \
 static inline void name(volatile u##size __iomem *addr, u##size val)   \
 {                                                                      \
        __asm__ __volatile__("sync;"#insn" %1,%y0"                      \
@@ -148,7 +148,7 @@ static inline void name(volatile u##size __iomem *addr, u##size val)        \
 }
 #endif
 
-#define DEF_MMIO_IN_BE(name, size, insn)                               \
+#define DEF_MMIO_IN_D(name, size, insn)                                \
 static inline u##size name(const volatile u##size __iomem *addr)       \
 {                                                                      \
        u##size ret;                                                    \
@@ -157,7 +157,7 @@ static inline u##size name(const volatile u##size __iomem *addr)    \
        return ret;                                                     \
 }
 
-#define DEF_MMIO_OUT_BE(name, size, insn)                              \
+#define DEF_MMIO_OUT_D(name, size, insn)                               \
 static inline void name(volatile u##size __iomem *addr, u##size val)   \
 {                                                                      \
        __asm__ __volatile__("sync;"#insn"%U0%X0 %1,%0"                 \
@@ -165,22 +165,37 @@ static inline void name(volatile u##size __iomem *addr, u##size val)      \
        IO_SET_SYNC_FLAG();                                             \
 }
 
+DEF_MMIO_IN_D(in_8,     8, lbz);
+DEF_MMIO_OUT_D(out_8,   8, stb);
 
-DEF_MMIO_IN_BE(in_8,     8, lbz);
-DEF_MMIO_IN_BE(in_be16, 16, lhz);
-DEF_MMIO_IN_BE(in_be32, 32, lwz);
-DEF_MMIO_IN_LE(in_le16, 16, lhbrx);
-DEF_MMIO_IN_LE(in_le32, 32, lwbrx);
+#ifdef __BIG_ENDIAN__
+DEF_MMIO_IN_D(in_be16, 16, lhz);
+DEF_MMIO_IN_D(in_be32, 32, lwz);
+DEF_MMIO_IN_X(in_le16, 16, lhbrx);
+DEF_MMIO_IN_X(in_le32, 32, lwbrx);
 
-DEF_MMIO_OUT_BE(out_8,     8, stb);
-DEF_MMIO_OUT_BE(out_be16, 16, sth);
-DEF_MMIO_OUT_BE(out_be32, 32, stw);
-DEF_MMIO_OUT_LE(out_le16, 16, sthbrx);
-DEF_MMIO_OUT_LE(out_le32, 32, stwbrx);
+DEF_MMIO_OUT_D(out_be16, 16, sth);
+DEF_MMIO_OUT_D(out_be32, 32, stw);
+DEF_MMIO_OUT_X(out_le16, 16, sthbrx);
+DEF_MMIO_OUT_X(out_le32, 32, stwbrx);
+#else
+DEF_MMIO_IN_X(in_be16, 16, lhbrx);
+DEF_MMIO_IN_X(in_be32, 32, lwbrx);
+DEF_MMIO_IN_D(in_le16, 16, lhz);
+DEF_MMIO_IN_D(in_le32, 32, lwz);
+
+DEF_MMIO_OUT_X(out_be16, 16, sthbrx);
+DEF_MMIO_OUT_X(out_be32, 32, stwbrx);
+DEF_MMIO_OUT_D(out_le16, 16, sth);
+DEF_MMIO_OUT_D(out_le32, 32, stw);
+
+#endif /* __BIG_ENDIAN */
 
 #ifdef __powerpc64__
-DEF_MMIO_OUT_BE(out_be64, 64, std);
-DEF_MMIO_IN_BE(in_be64, 64, ld);
+
+#ifdef __BIG_ENDIAN__
+DEF_MMIO_OUT_D(out_be64, 64, std);
+DEF_MMIO_IN_D(in_be64, 64, ld);
 
 /* There is no asm instructions for 64 bits reverse loads and stores */
 static inline u64 in_le64(const volatile u64 __iomem *addr)
@@ -192,6 +207,22 @@ static inline void out_le64(volatile u64 __iomem *addr, u64 val)
 {
        out_be64(addr, swab64(val));
 }
+#else
+DEF_MMIO_OUT_D(out_le64, 64, std);
+DEF_MMIO_IN_D(in_le64, 64, ld);
+
+/* There is no asm instructions for 64 bits reverse loads and stores */
+static inline u64 in_be64(const volatile u64 __iomem *addr)
+{
+       return swab64(in_le64(addr));
+}
+
+static inline void out_be64(volatile u64 __iomem *addr, u64 val)
+{
+       out_le64(addr, swab64(val));
+}
+
+#endif
 #endif /* __powerpc64__ */
 
 /*
index 4470d1e34d23174d8ec33cb1d9b32fd5ea8dd78c..844c28de7ec05e96f4578701a9d46c6dda6d2ecb 100644 (file)
@@ -84,8 +84,8 @@ struct lppaca {
         * the processor is yielded (either because of an OS yield or a
         * hypervisor preempt).  An even value implies that the processor is
         * currently executing.
-        * NOTE: This value will ALWAYS be zero for dedicated processors and
-        * will NEVER be zero for shared processors (ie, initialized to a 1).
+        * NOTE: Even dedicated processor partitions can yield so this
+        * field cannot be used to determine if we are shared or dedicated.
         */
        volatile __be32 yield_count;
        volatile __be32 dispersion_count; /* dispatch changed physical cpu */
@@ -106,15 +106,15 @@ extern struct lppaca lppaca[];
 #define lppaca_of(cpu) (*paca[cpu].lppaca_ptr)
 
 /*
- * Old kernels used a reserved bit in the VPA to determine if it was running
- * in shared processor mode. New kernels look for a non zero yield count
- * but KVM still needs to set the bit to keep the old stuff happy.
+ * We are using a non architected field to determine if a partition is
+ * shared or dedicated. This currently works on both KVM and PHYP, but
+ * we will have to transition to something better.
  */
 #define LPPACA_OLD_SHARED_PROC         2
 
 static inline bool lppaca_shared_proc(struct lppaca *l)
 {
-       return l->yield_count != 0;
+       return !!(l->__old_status & LPPACA_OLD_SHARED_PROC);
 }
 
 /*
index 8b480901165a5222634c60c81408651e3da76a38..ad3025d0880b1c709d073e9d42f55a71a9a8159a 100644 (file)
@@ -78,6 +78,18 @@ struct machdep_calls {
                                    long index);
        void            (*tce_flush)(struct iommu_table *tbl);
 
+       /* _rm versions are for real mode use only */
+       int             (*tce_build_rm)(struct iommu_table *tbl,
+                                    long index,
+                                    long npages,
+                                    unsigned long uaddr,
+                                    enum dma_data_direction direction,
+                                    struct dma_attrs *attrs);
+       void            (*tce_free_rm)(struct iommu_table *tbl,
+                                   long index,
+                                   long npages);
+       void            (*tce_flush_rm)(struct iommu_table *tbl);
+
        void __iomem *  (*ioremap)(phys_addr_t addr, unsigned long size,
                                   unsigned long flags, void *caller);
        void            (*iounmap)(volatile void __iomem *token);
@@ -263,6 +275,10 @@ struct machdep_calls {
        ssize_t (*cpu_probe)(const char *, size_t);
        ssize_t (*cpu_release)(const char *, size_t);
 #endif
+
+#ifdef CONFIG_ARCH_RANDOM
+       int (*get_random_long)(unsigned long *v);
+#endif
 };
 
 extern void e500_idle(void);
index c4cf01197273f8a88203d35c34b1516e356040a4..807014dde821058429b41a5d825759d50d4d9ed7 100644 (file)
@@ -135,8 +135,8 @@ extern char initial_stab[];
 #ifndef __ASSEMBLY__
 
 struct hash_pte {
-       unsigned long v;
-       unsigned long r;
+       __be64 v;
+       __be64 r;
 };
 
 extern struct hash_pte *htab_address;
index c5cd72833d6e7f29daba00655296750b0c560b16..033c06be1d840da02423d596121940d0aa11adb5 100644 (file)
@@ -129,6 +129,9 @@ extern int opal_enter_rtas(struct rtas_args *args,
 #define OPAL_LPC_READ                          67
 #define OPAL_LPC_WRITE                         68
 #define OPAL_RETURN_CPU                                69
+#define OPAL_FLASH_VALIDATE                    76
+#define OPAL_FLASH_MANAGE                      77
+#define OPAL_FLASH_UPDATE                      78
 
 #ifndef __ASSEMBLY__
 
@@ -460,10 +463,12 @@ enum {
 
 enum {
        OPAL_PHB_ERROR_DATA_TYPE_P7IOC = 1,
+       OPAL_PHB_ERROR_DATA_TYPE_PHB3 = 2
 };
 
 enum {
        OPAL_P7IOC_NUM_PEST_REGS = 128,
+       OPAL_PHB3_NUM_PEST_REGS = 256
 };
 
 struct OpalIoPhbErrorCommon {
@@ -531,28 +536,94 @@ struct OpalIoP7IOCPhbErrorData {
        uint64_t pestB[OPAL_P7IOC_NUM_PEST_REGS];
 };
 
+struct OpalIoPhb3ErrorData {
+       struct OpalIoPhbErrorCommon common;
+
+       uint32_t brdgCtl;
+
+       /* PHB3 UTL regs */
+       uint32_t portStatusReg;
+       uint32_t rootCmplxStatus;
+       uint32_t busAgentStatus;
+
+       /* PHB3 cfg regs */
+       uint32_t deviceStatus;
+       uint32_t slotStatus;
+       uint32_t linkStatus;
+       uint32_t devCmdStatus;
+       uint32_t devSecStatus;
+
+       /* cfg AER regs */
+       uint32_t rootErrorStatus;
+       uint32_t uncorrErrorStatus;
+       uint32_t corrErrorStatus;
+       uint32_t tlpHdr1;
+       uint32_t tlpHdr2;
+       uint32_t tlpHdr3;
+       uint32_t tlpHdr4;
+       uint32_t sourceId;
+
+       uint32_t rsv3;
+
+       /* Record data about the call to allocate a buffer */
+       uint64_t errorClass;
+       uint64_t correlator;
+
+       uint64_t nFir;                  /* 000 */
+       uint64_t nFirMask;              /* 003 */
+       uint64_t nFirWOF;               /* 008 */
+
+       /* PHB3 MMIO Error Regs */
+       uint64_t phbPlssr;              /* 120 */
+       uint64_t phbCsr;                /* 110 */
+       uint64_t lemFir;                /* C00 */
+       uint64_t lemErrorMask;          /* C18 */
+       uint64_t lemWOF;                /* C40 */
+       uint64_t phbErrorStatus;        /* C80 */
+       uint64_t phbFirstErrorStatus;   /* C88 */
+       uint64_t phbErrorLog0;          /* CC0 */
+       uint64_t phbErrorLog1;          /* CC8 */
+       uint64_t mmioErrorStatus;       /* D00 */
+       uint64_t mmioFirstErrorStatus;  /* D08 */
+       uint64_t mmioErrorLog0;         /* D40 */
+       uint64_t mmioErrorLog1;         /* D48 */
+       uint64_t dma0ErrorStatus;       /* D80 */
+       uint64_t dma0FirstErrorStatus;  /* D88 */
+       uint64_t dma0ErrorLog0;         /* DC0 */
+       uint64_t dma0ErrorLog1;         /* DC8 */
+       uint64_t dma1ErrorStatus;       /* E00 */
+       uint64_t dma1FirstErrorStatus;  /* E08 */
+       uint64_t dma1ErrorLog0;         /* E40 */
+       uint64_t dma1ErrorLog1;         /* E48 */
+       uint64_t pestA[OPAL_PHB3_NUM_PEST_REGS];
+       uint64_t pestB[OPAL_PHB3_NUM_PEST_REGS];
+};
+
 typedef struct oppanel_line {
        const char *    line;
        uint64_t        line_len;
 } oppanel_line_t;
 
+/* /sys/firmware/opal */
+extern struct kobject *opal_kobj;
+
 /* API functions */
-int64_t opal_console_write(int64_t term_number, int64_t *length,
+int64_t opal_console_write(int64_t term_number, __be64 *length,
                           const uint8_t *buffer);
-int64_t opal_console_read(int64_t term_number, int64_t *length,
+int64_t opal_console_read(int64_t term_number, __be64 *length,
                          uint8_t *buffer);
 int64_t opal_console_write_buffer_space(int64_t term_number,
-                                       int64_t *length);
-int64_t opal_rtc_read(uint32_t *year_month_day,
-                     uint64_t *hour_minute_second_millisecond);
+                                       __be64 *length);
+int64_t opal_rtc_read(__be32 *year_month_day,
+                     __be64 *hour_minute_second_millisecond);
 int64_t opal_rtc_write(uint32_t year_month_day,
                       uint64_t hour_minute_second_millisecond);
 int64_t opal_cec_power_down(uint64_t request);
 int64_t opal_cec_reboot(void);
 int64_t opal_read_nvram(uint64_t buffer, uint64_t size, uint64_t offset);
 int64_t opal_write_nvram(uint64_t buffer, uint64_t size, uint64_t offset);
-int64_t opal_handle_interrupt(uint64_t isn, uint64_t *outstanding_event_mask);
-int64_t opal_poll_events(uint64_t *outstanding_event_mask);
+int64_t opal_handle_interrupt(uint64_t isn, __be64 *outstanding_event_mask);
+int64_t opal_poll_events(__be64 *outstanding_event_mask);
 int64_t opal_pci_set_hub_tce_memory(uint64_t hub_id, uint64_t tce_mem_addr,
                                    uint64_t tce_mem_size);
 int64_t opal_pci_set_phb_tce_memory(uint64_t phb_id, uint64_t tce_mem_addr,
@@ -560,9 +631,9 @@ int64_t opal_pci_set_phb_tce_memory(uint64_t phb_id, uint64_t tce_mem_addr,
 int64_t opal_pci_config_read_byte(uint64_t phb_id, uint64_t bus_dev_func,
                                  uint64_t offset, uint8_t *data);
 int64_t opal_pci_config_read_half_word(uint64_t phb_id, uint64_t bus_dev_func,
-                                      uint64_t offset, uint16_t *data);
+                                      uint64_t offset, __be16 *data);
 int64_t opal_pci_config_read_word(uint64_t phb_id, uint64_t bus_dev_func,
-                                 uint64_t offset, uint32_t *data);
+                                 uint64_t offset, __be32 *data);
 int64_t opal_pci_config_write_byte(uint64_t phb_id, uint64_t bus_dev_func,
                                   uint64_t offset, uint8_t data);
 int64_t opal_pci_config_write_half_word(uint64_t phb_id, uint64_t bus_dev_func,
@@ -570,14 +641,14 @@ int64_t opal_pci_config_write_half_word(uint64_t phb_id, uint64_t bus_dev_func,
 int64_t opal_pci_config_write_word(uint64_t phb_id, uint64_t bus_dev_func,
                                   uint64_t offset, uint32_t data);
 int64_t opal_set_xive(uint32_t isn, uint16_t server, uint8_t priority);
-int64_t opal_get_xive(uint32_t isn, uint16_t *server, uint8_t *priority);
+int64_t opal_get_xive(uint32_t isn, __be16 *server, uint8_t *priority);
 int64_t opal_register_exception_handler(uint64_t opal_exception,
                                        uint64_t handler_address,
                                        uint64_t glue_cache_line);
 int64_t opal_pci_eeh_freeze_status(uint64_t phb_id, uint64_t pe_number,
                                   uint8_t *freeze_state,
-                                  uint16_t *pci_error_type,
-                                  uint64_t *phb_status);
+                                  __be16 *pci_error_type,
+                                  __be64 *phb_status);
 int64_t opal_pci_eeh_freeze_clear(uint64_t phb_id, uint64_t pe_number,
                                  uint64_t eeh_action_token);
 int64_t opal_pci_shpc(uint64_t phb_id, uint64_t shpc_action, uint8_t *state);
@@ -614,13 +685,13 @@ int64_t opal_pci_msi_eoi(uint64_t phb_id, uint32_t hw_irq);
 int64_t opal_pci_set_xive_pe(uint64_t phb_id, uint32_t pe_number,
                             uint32_t xive_num);
 int64_t opal_get_xive_source(uint64_t phb_id, uint32_t xive_num,
-                            int32_t *interrupt_source_number);
+                            __be32 *interrupt_source_number);
 int64_t opal_get_msi_32(uint64_t phb_id, uint32_t mve_number, uint32_t xive_num,
-                       uint8_t msi_range, uint32_t *msi_address,
-                       uint32_t *message_data);
+                       uint8_t msi_range, __be32 *msi_address,
+                       __be32 *message_data);
 int64_t opal_get_msi_64(uint64_t phb_id, uint32_t mve_number,
                        uint32_t xive_num, uint8_t msi_range,
-                       uint64_t *msi_address, uint32_t *message_data);
+                       __be64 *msi_address, __be32 *message_data);
 int64_t opal_start_cpu(uint64_t thread_number, uint64_t start_address);
 int64_t opal_query_cpu_status(uint64_t thread_number, uint8_t *thread_status);
 int64_t opal_write_oppanel(oppanel_line_t *lines, uint64_t num_lines);
@@ -642,7 +713,7 @@ int64_t opal_pci_fence_phb(uint64_t phb_id);
 int64_t opal_pci_reinit(uint64_t phb_id, uint8_t reinit_scope);
 int64_t opal_pci_mask_pe_error(uint64_t phb_id, uint16_t pe_number, uint8_t error_type, uint8_t mask_action);
 int64_t opal_set_slot_led_status(uint64_t phb_id, uint64_t slot_id, uint8_t led_type, uint8_t led_action);
-int64_t opal_get_epow_status(uint64_t *status);
+int64_t opal_get_epow_status(__be64 *status);
 int64_t opal_set_system_attention_led(uint8_t led_action);
 int64_t opal_pci_next_error(uint64_t phb_id, uint64_t *first_frozen_pe,
                            uint16_t *pci_error_type, uint16_t *severity);
@@ -656,6 +727,9 @@ int64_t opal_lpc_write(uint32_t chip_id, enum OpalLPCAddressType addr_type,
                       uint32_t addr, uint32_t data, uint32_t sz);
 int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type,
                      uint32_t addr, uint32_t *data, uint32_t sz);
+int64_t opal_validate_flash(uint64_t buffer, uint32_t *size, uint32_t *result);
+int64_t opal_manage_flash(uint8_t op);
+int64_t opal_update_flash(uint64_t blk_list);
 
 /* Internal functions */
 extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data);
@@ -684,6 +758,7 @@ extern int opal_set_rtc_time(struct rtc_time *tm);
 extern void opal_get_rtc_time(struct rtc_time *tm);
 extern unsigned long opal_get_boot_time(void);
 extern void opal_nvram_init(void);
+extern void opal_flash_init(void);
 
 extern int opal_machine_check(struct pt_regs *regs);
 
index b9f426212d3ab3afff006938089cf609fe3c785a..32e4e212b9c1a3c14e941d211dd5f5d2e2cf6aba 100644 (file)
@@ -78,7 +78,7 @@ extern unsigned int HPAGE_SHIFT;
  *
  * Also, KERNELBASE >= PAGE_OFFSET and PHYSICAL_START >= MEMORY_START
  *
- * There are two was to determine a physical address from a virtual one:
+ * There are two ways to determine a physical address from a virtual one:
  * va = pa + PAGE_OFFSET - MEMORY_START
  * va = pa + KERNELBASE - PHYSICAL_START
  *
@@ -403,7 +403,7 @@ void arch_free_page(struct page *page, int order);
 
 struct vm_area_struct;
 
-#ifdef CONFIG_PPC_64K_PAGES
+#if defined(CONFIG_PPC_64K_PAGES) && defined(CONFIG_PPC64)
 typedef pte_t *pgtable_t;
 #else
 typedef struct page *pgtable_t;
index 46db09414a1063415fccc9ef74b9f4b664de02f3..4a191c47286748c65cf2e7eb8753239af4c3b5d5 100644 (file)
@@ -394,6 +394,8 @@ static inline void mark_hpte_slot_valid(unsigned char *hpte_slot_array,
        hpte_slot_array[index] = hidx << 4 | 0x1 << 3;
 }
 
+struct page *realmode_pfn_to_page(unsigned long pfn);
+
 static inline char *get_hpte_slot_array(pmd_t *pmdp)
 {
        /*
index d7fe9f5b46d457cf0895c7dee542bc2e40fb3e49..3132bb9365f33788771c610aea90e25384f736d0 100644 (file)
 #define PPC_INST_LSWX                  0x7c00042a
 #define PPC_INST_LWARX                 0x7c000028
 #define PPC_INST_LWSYNC                        0x7c2004ac
+#define PPC_INST_SYNC                  0x7c0004ac
+#define PPC_INST_SYNC_MASK             0xfc0007fe
 #define PPC_INST_LXVD2X                        0x7c000698
 #define PPC_INST_MCRXR                 0x7c000400
 #define PPC_INST_MCRXR_MASK            0xfc0007fe
 #define PPC_INST_TLBIVAX               0x7c000624
 #define PPC_INST_TLBSRX_DOT            0x7c0006a5
 #define PPC_INST_XXLOR                 0xf0000510
+#define PPC_INST_XXSWAPD               0xf0000250
 #define PPC_INST_XVCPSGNDP             0xf0000780
 #define PPC_INST_TRECHKPT              0x7c0007dd
 #define PPC_INST_TRECLAIM              0x7c00075d
 /* Misc instructions for BPF compiler */
 #define PPC_INST_LD                    0xe8000000
 #define PPC_INST_LHZ                   0xa0000000
+#define PPC_INST_LHBRX                 0x7c00062c
 #define PPC_INST_LWZ                   0x80000000
 #define PPC_INST_STD                   0xf8000000
 #define PPC_INST_STDU                  0xf8000001
 #define PPC_INST_MULLW                 0x7c0001d6
 #define PPC_INST_MULHWU                        0x7c000016
 #define PPC_INST_MULLI                 0x1c000000
-#define PPC_INST_DIVWU                 0x7c0003d6
+#define PPC_INST_DIVWU                 0x7c000396
 #define PPC_INST_RLWINM                        0x54000000
 #define PPC_INST_RLDICR                        0x78000004
 #define PPC_INST_SLW                   0x7c000030
                                               VSX_XX1((s), a, b))
 #define XXLOR(t, a, b)         stringify_in_c(.long PPC_INST_XXLOR | \
                                               VSX_XX3((t), a, b))
+#define XXSWAPD(t, a)          stringify_in_c(.long PPC_INST_XXSWAPD | \
+                                              VSX_XX3((t), a, a))
 #define XVCPSGNDP(t, a, b)     stringify_in_c(.long (PPC_INST_XVCPSGNDP | \
                                               VSX_XX3((t), (a), (b))))
 
index 599545738af3e2354b137221cf1c07cf68e25440..3c1acc31a09280bdc8c706813879571587f3d75e 100644 (file)
@@ -98,123 +98,51 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_SPLPAR)
 #define REST_8GPRS(n, base)    REST_4GPRS(n, base); REST_4GPRS(n+4, base)
 #define REST_10GPRS(n, base)   REST_8GPRS(n, base); REST_2GPRS(n+8, base)
 
-#define SAVE_FPR(n, base)      stfd    n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+#define SAVE_FPR(n, base)      stfd    n,8*TS_FPRWIDTH*(n)(base)
 #define SAVE_2FPRS(n, base)    SAVE_FPR(n, base); SAVE_FPR(n+1, base)
 #define SAVE_4FPRS(n, base)    SAVE_2FPRS(n, base); SAVE_2FPRS(n+2, base)
 #define SAVE_8FPRS(n, base)    SAVE_4FPRS(n, base); SAVE_4FPRS(n+4, base)
 #define SAVE_16FPRS(n, base)   SAVE_8FPRS(n, base); SAVE_8FPRS(n+8, base)
 #define SAVE_32FPRS(n, base)   SAVE_16FPRS(n, base); SAVE_16FPRS(n+16, base)
-#define REST_FPR(n, base)      lfd     n,THREAD_FPR0+8*TS_FPRWIDTH*(n)(base)
+#define REST_FPR(n, base)      lfd     n,8*TS_FPRWIDTH*(n)(base)
 #define REST_2FPRS(n, base)    REST_FPR(n, base); REST_FPR(n+1, base)
 #define REST_4FPRS(n, base)    REST_2FPRS(n, base); REST_2FPRS(n+2, base)
 #define REST_8FPRS(n, base)    REST_4FPRS(n, base); REST_4FPRS(n+4, base)
 #define REST_16FPRS(n, base)   REST_8FPRS(n, base); REST_8FPRS(n+8, base)
 #define REST_32FPRS(n, base)   REST_16FPRS(n, base); REST_16FPRS(n+16, base)
 
-#define SAVE_VR(n,b,base)      li b,THREAD_VR0+(16*(n));  stvx n,base,b
+#define SAVE_VR(n,b,base)      li b,16*(n);  stvx n,base,b
 #define SAVE_2VRS(n,b,base)    SAVE_VR(n,b,base); SAVE_VR(n+1,b,base)
 #define SAVE_4VRS(n,b,base)    SAVE_2VRS(n,b,base); SAVE_2VRS(n+2,b,base)
 #define SAVE_8VRS(n,b,base)    SAVE_4VRS(n,b,base); SAVE_4VRS(n+4,b,base)
 #define SAVE_16VRS(n,b,base)   SAVE_8VRS(n,b,base); SAVE_8VRS(n+8,b,base)
 #define SAVE_32VRS(n,b,base)   SAVE_16VRS(n,b,base); SAVE_16VRS(n+16,b,base)
-#define REST_VR(n,b,base)      li b,THREAD_VR0+(16*(n)); lvx n,base,b
+#define REST_VR(n,b,base)      li b,16*(n); lvx n,base,b
 #define REST_2VRS(n,b,base)    REST_VR(n,b,base); REST_VR(n+1,b,base)
 #define REST_4VRS(n,b,base)    REST_2VRS(n,b,base); REST_2VRS(n+2,b,base)
 #define REST_8VRS(n,b,base)    REST_4VRS(n,b,base); REST_4VRS(n+4,b,base)
 #define REST_16VRS(n,b,base)   REST_8VRS(n,b,base); REST_8VRS(n+8,b,base)
 #define REST_32VRS(n,b,base)   REST_16VRS(n,b,base); REST_16VRS(n+16,b,base)
 
-/* Save/restore FPRs, VRs and VSRs from their checkpointed backups in
- * thread_struct:
- */
-#define SAVE_FPR_TRANSACT(n, base)     stfd n,THREAD_TRANSACT_FPR0+    \
-                                       8*TS_FPRWIDTH*(n)(base)
-#define SAVE_2FPRS_TRANSACT(n, base)   SAVE_FPR_TRANSACT(n, base);     \
-                                       SAVE_FPR_TRANSACT(n+1, base)
-#define SAVE_4FPRS_TRANSACT(n, base)   SAVE_2FPRS_TRANSACT(n, base);   \
-                                       SAVE_2FPRS_TRANSACT(n+2, base)
-#define SAVE_8FPRS_TRANSACT(n, base)   SAVE_4FPRS_TRANSACT(n, base);   \
-                                       SAVE_4FPRS_TRANSACT(n+4, base)
-#define SAVE_16FPRS_TRANSACT(n, base)  SAVE_8FPRS_TRANSACT(n, base);   \
-                                       SAVE_8FPRS_TRANSACT(n+8, base)
-#define SAVE_32FPRS_TRANSACT(n, base)  SAVE_16FPRS_TRANSACT(n, base);  \
-                                       SAVE_16FPRS_TRANSACT(n+16, base)
-
-#define REST_FPR_TRANSACT(n, base)     lfd     n,THREAD_TRANSACT_FPR0+ \
-                                       8*TS_FPRWIDTH*(n)(base)
-#define REST_2FPRS_TRANSACT(n, base)   REST_FPR_TRANSACT(n, base);     \
-                                       REST_FPR_TRANSACT(n+1, base)
-#define REST_4FPRS_TRANSACT(n, base)   REST_2FPRS_TRANSACT(n, base);   \
-                                       REST_2FPRS_TRANSACT(n+2, base)
-#define REST_8FPRS_TRANSACT(n, base)   REST_4FPRS_TRANSACT(n, base);   \
-                                       REST_4FPRS_TRANSACT(n+4, base)
-#define REST_16FPRS_TRANSACT(n, base)  REST_8FPRS_TRANSACT(n, base);   \
-                                       REST_8FPRS_TRANSACT(n+8, base)
-#define REST_32FPRS_TRANSACT(n, base)  REST_16FPRS_TRANSACT(n, base);  \
-                                       REST_16FPRS_TRANSACT(n+16, base)
-
-
-#define SAVE_VR_TRANSACT(n,b,base)     li b,THREAD_TRANSACT_VR0+(16*(n)); \
-                                       stvx n,b,base
-#define SAVE_2VRS_TRANSACT(n,b,base)   SAVE_VR_TRANSACT(n,b,base);     \
-                                       SAVE_VR_TRANSACT(n+1,b,base)
-#define SAVE_4VRS_TRANSACT(n,b,base)   SAVE_2VRS_TRANSACT(n,b,base);   \
-                                       SAVE_2VRS_TRANSACT(n+2,b,base)
-#define SAVE_8VRS_TRANSACT(n,b,base)   SAVE_4VRS_TRANSACT(n,b,base);   \
-                                       SAVE_4VRS_TRANSACT(n+4,b,base)
-#define SAVE_16VRS_TRANSACT(n,b,base)  SAVE_8VRS_TRANSACT(n,b,base);   \
-                                       SAVE_8VRS_TRANSACT(n+8,b,base)
-#define SAVE_32VRS_TRANSACT(n,b,base)  SAVE_16VRS_TRANSACT(n,b,base);  \
-                                       SAVE_16VRS_TRANSACT(n+16,b,base)
-
-#define REST_VR_TRANSACT(n,b,base)     li b,THREAD_TRANSACT_VR0+(16*(n)); \
-                                       lvx n,b,base
-#define REST_2VRS_TRANSACT(n,b,base)   REST_VR_TRANSACT(n,b,base);     \
-                                       REST_VR_TRANSACT(n+1,b,base)
-#define REST_4VRS_TRANSACT(n,b,base)   REST_2VRS_TRANSACT(n,b,base);   \
-                                       REST_2VRS_TRANSACT(n+2,b,base)
-#define REST_8VRS_TRANSACT(n,b,base)   REST_4VRS_TRANSACT(n,b,base);   \
-                                       REST_4VRS_TRANSACT(n+4,b,base)
-#define REST_16VRS_TRANSACT(n,b,base)  REST_8VRS_TRANSACT(n,b,base);   \
-                                       REST_8VRS_TRANSACT(n+8,b,base)
-#define REST_32VRS_TRANSACT(n,b,base)  REST_16VRS_TRANSACT(n,b,base);  \
-                                       REST_16VRS_TRANSACT(n+16,b,base)
-
-
-#define SAVE_VSR_TRANSACT(n,b,base)    li b,THREAD_TRANSACT_VSR0+(16*(n)); \
-                                       STXVD2X(n,R##base,R##b)
-#define SAVE_2VSRS_TRANSACT(n,b,base)  SAVE_VSR_TRANSACT(n,b,base);    \
-                                       SAVE_VSR_TRANSACT(n+1,b,base)
-#define SAVE_4VSRS_TRANSACT(n,b,base)  SAVE_2VSRS_TRANSACT(n,b,base);  \
-                                       SAVE_2VSRS_TRANSACT(n+2,b,base)
-#define SAVE_8VSRS_TRANSACT(n,b,base)  SAVE_4VSRS_TRANSACT(n,b,base);  \
-                                       SAVE_4VSRS_TRANSACT(n+4,b,base)
-#define SAVE_16VSRS_TRANSACT(n,b,base) SAVE_8VSRS_TRANSACT(n,b,base);  \
-                                       SAVE_8VSRS_TRANSACT(n+8,b,base)
-#define SAVE_32VSRS_TRANSACT(n,b,base) SAVE_16VSRS_TRANSACT(n,b,base); \
-                                       SAVE_16VSRS_TRANSACT(n+16,b,base)
-
-#define REST_VSR_TRANSACT(n,b,base)    li b,THREAD_TRANSACT_VSR0+(16*(n)); \
-                                       LXVD2X(n,R##base,R##b)
-#define REST_2VSRS_TRANSACT(n,b,base)  REST_VSR_TRANSACT(n,b,base);    \
-                                       REST_VSR_TRANSACT(n+1,b,base)
-#define REST_4VSRS_TRANSACT(n,b,base)  REST_2VSRS_TRANSACT(n,b,base);  \
-                                       REST_2VSRS_TRANSACT(n+2,b,base)
-#define REST_8VSRS_TRANSACT(n,b,base)  REST_4VSRS_TRANSACT(n,b,base);  \
-                                       REST_4VSRS_TRANSACT(n+4,b,base)
-#define REST_16VSRS_TRANSACT(n,b,base) REST_8VSRS_TRANSACT(n,b,base);  \
-                                       REST_8VSRS_TRANSACT(n+8,b,base)
-#define REST_32VSRS_TRANSACT(n,b,base) REST_16VSRS_TRANSACT(n,b,base); \
-                                       REST_16VSRS_TRANSACT(n+16,b,base)
+#ifdef __BIG_ENDIAN__
+#define STXVD2X_ROT(n,b,base)          STXVD2X(n,b,base)
+#define LXVD2X_ROT(n,b,base)           LXVD2X(n,b,base)
+#else
+#define STXVD2X_ROT(n,b,base)          XXSWAPD(n,n);           \
+                                       STXVD2X(n,b,base);      \
+                                       XXSWAPD(n,n)
 
+#define LXVD2X_ROT(n,b,base)           LXVD2X(n,b,base);       \
+                                       XXSWAPD(n,n)
+#endif
 /* Save the lower 32 VSRs in the thread VSR region */
-#define SAVE_VSR(n,b,base)     li b,THREAD_VSR0+(16*(n));  STXVD2X(n,R##base,R##b)
+#define SAVE_VSR(n,b,base)     li b,16*(n);  STXVD2X_ROT(n,R##base,R##b)
 #define SAVE_2VSRS(n,b,base)   SAVE_VSR(n,b,base); SAVE_VSR(n+1,b,base)
 #define SAVE_4VSRS(n,b,base)   SAVE_2VSRS(n,b,base); SAVE_2VSRS(n+2,b,base)
 #define SAVE_8VSRS(n,b,base)   SAVE_4VSRS(n,b,base); SAVE_4VSRS(n+4,b,base)
 #define SAVE_16VSRS(n,b,base)  SAVE_8VSRS(n,b,base); SAVE_8VSRS(n+8,b,base)
 #define SAVE_32VSRS(n,b,base)  SAVE_16VSRS(n,b,base); SAVE_16VSRS(n+16,b,base)
-#define REST_VSR(n,b,base)     li b,THREAD_VSR0+(16*(n)); LXVD2X(n,R##base,R##b)
+#define REST_VSR(n,b,base)     li b,16*(n); LXVD2X_ROT(n,R##base,R##b)
 #define REST_2VSRS(n,b,base)   REST_VSR(n,b,base); REST_VSR(n+1,b,base)
 #define REST_4VSRS(n,b,base)   REST_2VSRS(n,b,base); REST_2VSRS(n+2,b,base)
 #define REST_8VSRS(n,b,base)   REST_4VSRS(n,b,base); REST_4VSRS(n+4,b,base)
@@ -478,13 +406,6 @@ BEGIN_FTR_SECTION_NESTED(945)                                              \
        std     ra,TASKTHREADPPR(rb);                                   \
 END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,945)
 
-#define RESTORE_PPR(ra, rb)                                            \
-BEGIN_FTR_SECTION_NESTED(946)                                          \
-       ld      ra,PACACURRENT(r13);                                    \
-       ld      rb,TASKTHREADPPR(ra);                                   \
-       mtspr   SPRN_PPR,rb;    /* Restore PPR */                       \
-END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,946)
-
 #endif
 
 /*
@@ -832,6 +753,35 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,946)
 #define N_SLINE        68
 #define N_SO   100
 
-#endif /*  __ASSEMBLY__ */
+/*
+ * Create an endian fixup trampoline
+ *
+ * This starts with a "tdi 0,0,0x48" instruction which is
+ * essentially a "trap never", and thus akin to a nop.
+ *
+ * The opcode for this instruction read with the wrong endian
+ * however results in a b . + 8
+ *
+ * So essentially we use that trick to execute the following
+ * trampoline in "reverse endian" if we are running with the
+ * MSR_LE bit set the "wrong" way for whatever endianness the
+ * kernel is built for.
+ */
 
+#ifdef CONFIG_PPC_BOOK3E
+#define FIXUP_ENDIAN
+#else
+#define FIXUP_ENDIAN                                              \
+       tdi   0,0,0x48;   /* Reverse endian of b . + 8          */ \
+       b     $+36;       /* Skip trampoline if endian is good  */ \
+       .long 0x05009f42; /* bcl 20,31,$+4                      */ \
+       .long 0xa602487d; /* mflr r10                           */ \
+       .long 0x1c004a39; /* addi r10,r10,28                    */ \
+       .long 0xa600607d; /* mfmsr r11                          */ \
+       .long 0x01006b69; /* xori r11,r11,1                     */ \
+       .long 0xa6035a7d; /* mtsrr0 r10                         */ \
+       .long 0xa6037b7d; /* mtsrr1 r11                         */ \
+       .long 0x2400004c  /* rfid                               */
+#endif /* !CONFIG_PPC_BOOK3E */
+#endif /*  __ASSEMBLY__ */
 #endif /* _ASM_POWERPC_PPC_ASM_H */
index ce4de5aed7b5c302b292bd38c69f21bd2f059038..7794b2b04eb2eceb04bda53adbda99b9c721f784 100644 (file)
 
 #ifdef CONFIG_VSX
 #define TS_FPRWIDTH 2
+
+#ifdef __BIG_ENDIAN__
+#define TS_FPROFFSET 0
+#define TS_VSRLOWOFFSET 1
+#else
+#define TS_FPROFFSET 1
+#define TS_VSRLOWOFFSET 0
+#endif
+
 #else
 #define TS_FPRWIDTH 1
+#define TS_FPROFFSET 0
 #endif
 
 #ifdef CONFIG_PPC64
@@ -142,26 +152,22 @@ typedef struct {
        unsigned long seg;
 } mm_segment_t;
 
-#define TS_FPROFFSET 0
-#define TS_VSRLOWOFFSET 1
-#define TS_FPR(i) fpr[i][TS_FPROFFSET]
-#define TS_TRANS_FPR(i) transact_fpr[i][TS_FPROFFSET]
+#define TS_FPR(i) fp_state.fpr[i][TS_FPROFFSET]
+#define TS_TRANS_FPR(i) transact_fp.fpr[i][TS_FPROFFSET]
 
-struct thread_struct {
-       unsigned long   ksp;            /* Kernel stack pointer */
-#ifdef CONFIG_PPC64
-       unsigned long   ksp_vsid;
-#endif
-       struct pt_regs  *regs;          /* Pointer to saved register state */
-       mm_segment_t    fs;             /* for get_fs() validation */
-#ifdef CONFIG_BOOKE
-       /* BookE base exception scratch space; align on cacheline */
-       unsigned long   normsave[8] ____cacheline_aligned;
-#endif
-#ifdef CONFIG_PPC32
-       void            *pgdir;         /* root of page-table tree */
-       unsigned long   ksp_limit;      /* if ksp <= ksp_limit stack overflow */
-#endif
+/* FP and VSX 0-31 register set */
+struct thread_fp_state {
+       u64     fpr[32][TS_FPRWIDTH] __attribute__((aligned(16)));
+       u64     fpscr;          /* Floating point status */
+};
+
+/* Complete AltiVec register set including VSCR */
+struct thread_vr_state {
+       vector128       vr[32] __attribute__((aligned(16)));
+       vector128       vscr __attribute__((aligned(16)));
+};
+
+struct debug_reg {
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
        /*
         * The following help to manage the use of Debug Control Registers
@@ -198,13 +204,26 @@ struct thread_struct {
        unsigned long   dvc2;
 #endif
 #endif
-       /* FP and VSX 0-31 register set */
-       double          fpr[32][TS_FPRWIDTH] __attribute__((aligned(16)));
-       struct {
+};
 
-               unsigned int pad;
-               unsigned int val;       /* Floating point status */
-       } fpscr;
+struct thread_struct {
+       unsigned long   ksp;            /* Kernel stack pointer */
+#ifdef CONFIG_PPC64
+       unsigned long   ksp_vsid;
+#endif
+       struct pt_regs  *regs;          /* Pointer to saved register state */
+       mm_segment_t    fs;             /* for get_fs() validation */
+#ifdef CONFIG_BOOKE
+       /* BookE base exception scratch space; align on cacheline */
+       unsigned long   normsave[8] ____cacheline_aligned;
+#endif
+#ifdef CONFIG_PPC32
+       void            *pgdir;         /* root of page-table tree */
+       unsigned long   ksp_limit;      /* if ksp <= ksp_limit stack overflow */
+#endif
+       struct debug_reg debug;
+       struct thread_fp_state  fp_state;
+       struct thread_fp_state  *fp_save_area;
        int             fpexc_mode;     /* floating-point exception mode */
        unsigned int    align_ctl;      /* alignment handling control */
 #ifdef CONFIG_PPC64
@@ -222,10 +241,8 @@ struct thread_struct {
        struct arch_hw_breakpoint hw_brk; /* info on the hardware breakpoint */
        unsigned long   trap_nr;        /* last trap # on this thread */
 #ifdef CONFIG_ALTIVEC
-       /* Complete AltiVec register set */
-       vector128       vr[32] __attribute__((aligned(16)));
-       /* AltiVec status */
-       vector128       vscr __attribute__((aligned(16)));
+       struct thread_vr_state vr_state;
+       struct thread_vr_state *vr_save_area;
        unsigned long   vrsave;
        int             used_vr;        /* set if process has used altivec */
 #endif /* CONFIG_ALTIVEC */
@@ -262,13 +279,8 @@ struct thread_struct {
         * transact_fpr[] is the new set of transactional values.
         * VRs work the same way.
         */
-       double          transact_fpr[32][TS_FPRWIDTH];
-       struct {
-               unsigned int pad;
-               unsigned int val;       /* Floating point status */
-       } transact_fpscr;
-       vector128       transact_vr[32] __attribute__((aligned(16)));
-       vector128       transact_vscr __attribute__((aligned(16)));
+       struct thread_fp_state transact_fp;
+       struct thread_vr_state transact_vr;
        unsigned long   transact_vrsave;
 #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
 #ifdef CONFIG_KVM_BOOK3S_32_HANDLER
@@ -322,8 +334,6 @@ struct thread_struct {
        .ksp = INIT_SP, \
        .regs = (struct pt_regs *)INIT_SP - 1, /* XXX bogus, I think */ \
        .fs = KERNEL_DS, \
-       .fpr = {{0}}, \
-       .fpscr = { .val = 0, }, \
        .fpexc_mode = 0, \
        .ppr = INIT_PPR, \
 }
@@ -361,6 +371,11 @@ extern int set_endian(struct task_struct *tsk, unsigned int val);
 extern int get_unalign_ctl(struct task_struct *tsk, unsigned long adr);
 extern int set_unalign_ctl(struct task_struct *tsk, unsigned int val);
 
+extern void load_fp_state(struct thread_fp_state *fp);
+extern void store_fp_state(struct thread_fp_state *fp);
+extern void load_vr_state(struct thread_vr_state *vr);
+extern void store_vr_state(struct thread_vr_state *vr);
+
 static inline unsigned int __unpack_fe01(unsigned long msr_bits)
 {
        return ((msr_bits & MSR_FE0) >> 10) | ((msr_bits & MSR_FE1) >> 8);
index 7d0c7f3a7171e98ce262ed4054c38af101032043..bf09e5a065b809b033a31969f4817b66d4fd66a1 100644 (file)
@@ -44,9 +44,6 @@ void of_parse_dma_window(struct device_node *dn, const __be32 *dma_window,
 
 extern void kdump_move_device_tree(void);
 
-/* cache lookup */
-struct device_node *of_find_next_cache_node(struct device_node *np);
-
 #ifdef CONFIG_NUMA
 extern int of_node_to_nid(struct device_node *device);
 #else
index 10d1ef016bf1b73f199387b9640cf9ffb8429b6f..126f6e98f84de687d1d26d2ab83ff4b1d2a6fc86 100644 (file)
 #define MSR_64BIT      MSR_SF
 
 /* Server variant */
-#define MSR_           (MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF |MSR_HV)
+#define __MSR          (MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF |MSR_HV)
+#ifdef __BIG_ENDIAN__
+#define MSR_           __MSR
+#else
+#define MSR_           (__MSR | MSR_LE)
+#endif
 #define MSR_KERNEL     (MSR_ | MSR_64BIT)
 #define MSR_USER32     (MSR_ | MSR_PR | MSR_EE)
 #define MSR_USER64     (MSR_USER32 | MSR_64BIT)
index ed8f836da094a428088c76cdb2e3def321774821..2e31aacd8accaf4bf7742d7a708766a63e1f07d8 100644 (file)
 #define DBCR0_IA34T    0x00004000      /* Instr Addr 3-4 range Toggle */
 #define DBCR0_FT       0x00000001      /* Freeze Timers on debug event */
 
-#define dbcr_iac_range(task)   ((task)->thread.dbcr0)
+#define dbcr_iac_range(task)   ((task)->thread.debug.dbcr0)
 #define DBCR_IAC12I    DBCR0_IA12                      /* Range Inclusive */
 #define DBCR_IAC12X    (DBCR0_IA12 | DBCR0_IA12X)      /* Range Exclusive */
 #define DBCR_IAC12MODE (DBCR0_IA12 | DBCR0_IA12X)      /* IAC 1-2 Mode Bits */
 #define DBCR1_DAC1W    0x20000000      /* DAC1 Write Debug Event */
 #define DBCR1_DAC2W    0x10000000      /* DAC2 Write Debug Event */
 
-#define dbcr_dac(task) ((task)->thread.dbcr1)
+#define dbcr_dac(task) ((task)->thread.debug.dbcr1)
 #define DBCR_DAC1R     DBCR1_DAC1R
 #define DBCR_DAC1W     DBCR1_DAC1W
 #define DBCR_DAC2R     DBCR1_DAC2R
 #define DBCR0_CRET     0x00000020      /* Critical Return Debug Event */
 #define DBCR0_FT       0x00000001      /* Freeze Timers on debug event */
 
-#define dbcr_dac(task) ((task)->thread.dbcr0)
+#define dbcr_dac(task) ((task)->thread.debug.dbcr0)
 #define DBCR_DAC1R     DBCR0_DAC1R
 #define DBCR_DAC1W     DBCR0_DAC1W
 #define DBCR_DAC2R     DBCR0_DAC2R
 #define DBCR1_IAC34MX  0x000000C0      /* Instr Addr 3-4 range eXclusive */
 #define DBCR1_IAC34AT  0x00000001      /* Instr Addr 3-4 range Toggle */
 
-#define dbcr_iac_range(task)   ((task)->thread.dbcr1)
+#define dbcr_iac_range(task)   ((task)->thread.debug.dbcr1)
 #define DBCR_IAC12I    DBCR1_IAC12M    /* Range Inclusive */
 #define DBCR_IAC12X    DBCR1_IAC12MX   /* Range Exclusive */
 #define DBCR_IAC12MODE DBCR1_IAC12MX   /* IAC 1-2 Mode Bits */
index 0cabfd7bc2d1e5603d1cfa64e49c3cbd4557224e..f5cde45b116120fe4550ad47e56390ef39430c3b 100644 (file)
@@ -54,8 +54,8 @@ struct scom_controller {
        scom_map_t (*map)(struct device_node *ctrl_dev, u64 reg, u64 count);
        void (*unmap)(scom_map_t map);
 
-       u64 (*read)(scom_map_t map, u32 reg);
-       void (*write)(scom_map_t map, u32 reg, u64 value);
+       int (*read)(scom_map_t map, u64 reg, u64 *value);
+       int (*write)(scom_map_t map, u64 reg, u64 value);
 };
 
 extern const struct scom_controller *scom_controller;
@@ -133,10 +133,18 @@ static inline void scom_unmap(scom_map_t map)
  * scom_read - Read a SCOM register
  * @map: Result of scom_map
  * @reg: Register index within that map
+ * @value: Updated with the value read
+ *
+ * Returns 0 (success) or a negative error code
  */
-static inline u64 scom_read(scom_map_t map, u32 reg)
+static inline int scom_read(scom_map_t map, u64 reg, u64 *value)
 {
-       return scom_controller->read(map, reg);
+       int rc;
+
+       rc = scom_controller->read(map, reg, value);
+       if (rc)
+               *value = 0xfffffffffffffffful;
+       return rc;
 }
 
 /**
@@ -144,12 +152,15 @@ static inline u64 scom_read(scom_map_t map, u32 reg)
  * @map: Result of scom_map
  * @reg: Register index within that map
  * @value: Value to write
+ *
+ * Returns 0 (success) or a negative error code
  */
-static inline void scom_write(scom_map_t map, u32 reg, u64 value)
+static inline int scom_write(scom_map_t map, u64 reg, u64 value)
 {
-       scom_controller->write(map, reg, value);
+       return scom_controller->write(map, reg, value);
 }
 
+
 #endif /* CONFIG_PPC_SCOM */
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL__ */
index d3ca85529b8b73a134d6e97811c8cd8a73a3845a..703a8412dac28e2a567b4d1b4da5586ae890c34a 100644 (file)
@@ -23,6 +23,10 @@ extern void reloc_got2(unsigned long);
 
 #define PTRRELOC(x)    ((typeof(x)) add_reloc_offset((unsigned long)(x)))
 
+void check_for_initrd(void);
+void do_init_bootmem(void);
+void setup_panic(void);
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_SETUP_H */
index 3a7a67a0d006cfe24d0b2bd626e7361d771dde1b..d89beaba26ff95d2ab0ed48cdaf1ba7fc8f3bd73 100644 (file)
 #define FP_EX_DIVZERO         (1 << (31 - 5))
 #define FP_EX_INEXACT         (1 << (31 - 6))
 
-#define __FPU_FPSCR    (current->thread.fpscr.val)
+#define __FPU_FPSCR    (current->thread.fp_state.fpscr)
 
 /* We only actually write to the destination register
  * if exceptions signalled (if any) will not trap.
index e40010abcaf134f53bbcf639bf6999b856a42a2a..0dffad6bcc846725a273daff18593c7b03305060 100644 (file)
@@ -10,7 +10,9 @@
 #define __HAVE_ARCH_STRNCMP
 #define __HAVE_ARCH_STRCAT
 #define __HAVE_ARCH_MEMSET
+#ifdef __BIG_ENDIAN__
 #define __HAVE_ARCH_MEMCPY
+#endif
 #define __HAVE_ARCH_MEMMOVE
 #define __HAVE_ARCH_MEMCMP
 #define __HAVE_ARCH_MEMCHR
@@ -22,7 +24,9 @@ extern int strcmp(const char *,const char *);
 extern int strncmp(const char *, const char *, __kernel_size_t);
 extern char * strcat(char *, const char *);
 extern void * memset(void *,int,__kernel_size_t);
+#ifdef __BIG_ENDIAN__
 extern void * memcpy(void *,const void *,__kernel_size_t);
+#endif
 extern void * memmove(void *,const void *,__kernel_size_t);
 extern int memcmp(const void *,const void *,__kernel_size_t);
 extern void * memchr(const void *,int,__kernel_size_t);
index 2be5618cdec6874d79315de6f8f2ecf3e2e8d938..9ee12610af02bdca7fd61b9b7f6b16f2c74d36d0 100644 (file)
@@ -35,6 +35,7 @@ extern void giveup_vsx(struct task_struct *);
 extern void enable_kernel_spe(void);
 extern void giveup_spe(struct task_struct *);
 extern void load_up_spe(struct task_struct *);
+extern void switch_booke_debug_regs(struct thread_struct *new_thread);
 
 #ifndef CONFIG_SMP
 extern void discard_lazy_cpu_state(void);
index d0b6d4ac6dda58c99d7fc6c884f0bbc11d4561e0..9a5c928bb3c64ea8cb021da323c46b1d59dc6446 100644 (file)
@@ -8,6 +8,8 @@
 #include <linux/kernel.h>
 #include <asm/asm-compat.h>
 
+#ifdef __BIG_ENDIAN__
+
 struct word_at_a_time {
        const unsigned long high_bits, low_bits;
 };
@@ -38,4 +40,80 @@ static inline bool has_zero(unsigned long val, unsigned long *data, const struct
        return (val + c->high_bits) & ~rhs;
 }
 
+#else
+
+struct word_at_a_time {
+       const unsigned long one_bits, high_bits;
+};
+
+#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) }
+
+#ifdef CONFIG_64BIT
+
+/* Alan Modra's little-endian strlen tail for 64-bit */
+#define create_zero_mask(mask) (mask)
+
+static inline unsigned long find_zero(unsigned long mask)
+{
+       unsigned long leading_zero_bits;
+       long trailing_zero_bit_mask;
+
+       asm ("addi %1,%2,-1\n\t"
+            "andc %1,%1,%2\n\t"
+            "popcntd %0,%1"
+            : "=r" (leading_zero_bits), "=&r" (trailing_zero_bit_mask)
+            : "r" (mask));
+       return leading_zero_bits >> 3;
+}
+
+#else  /* 32-bit case */
+
+/*
+ * This is largely generic for little-endian machines, but the
+ * optimal byte mask counting is probably going to be something
+ * that is architecture-specific. If you have a reliably fast
+ * bit count instruction, that might be better than the multiply
+ * and shift, for example.
+ */
+
+/* Carl Chatfield / Jan Achrenius G+ version for 32-bit */
+static inline long count_masked_bytes(long mask)
+{
+       /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */
+       long a = (0x0ff0001+mask) >> 23;
+       /* Fix the 1 for 00 case */
+       return a & mask;
+}
+
+static inline unsigned long create_zero_mask(unsigned long bits)
+{
+       bits = (bits - 1) & ~bits;
+       return bits >> 7;
+}
+
+static inline unsigned long find_zero(unsigned long mask)
+{
+       return count_masked_bytes(mask);
+}
+
+#endif
+
+/* Return nonzero if it has a zero */
+static inline unsigned long has_zero(unsigned long a, unsigned long *bits, const struct word_at_a_time *c)
+{
+       unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits;
+       *bits = mask;
+       return mask;
+}
+
+static inline unsigned long prep_zero_mask(unsigned long a, unsigned long bits, const struct word_at_a_time *c)
+{
+       return bits;
+}
+
+/* The mask we created is directly usable as a bytemask */
+#define zero_bytemask(mask) (mask)
+
+#endif
+
 #endif /* _ASM_WORD_AT_A_TIME_H */
index c82eb12a5b1810e059e72db19b124e0078a3cbce..0abb97f3be106700e224fbcc2c37d7ee783f3a72 100644 (file)
@@ -1 +1,68 @@
+/*
+ * 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.
+ *
+ * Copyright (C) IBM Corporation, 2012
+ *
+ * Author: Anton Blanchard <anton@au.ibm.com>
+ */
+#ifndef _ASM_POWERPC_XOR_H
+#define _ASM_POWERPC_XOR_H
+
+#ifdef CONFIG_ALTIVEC
+
+#include <asm/cputable.h>
+
+void xor_altivec_2(unsigned long bytes, unsigned long *v1_in,
+                  unsigned long *v2_in);
+void xor_altivec_3(unsigned long bytes, unsigned long *v1_in,
+                  unsigned long *v2_in, unsigned long *v3_in);
+void xor_altivec_4(unsigned long bytes, unsigned long *v1_in,
+                  unsigned long *v2_in, unsigned long *v3_in,
+                  unsigned long *v4_in);
+void xor_altivec_5(unsigned long bytes, unsigned long *v1_in,
+                  unsigned long *v2_in, unsigned long *v3_in,
+                  unsigned long *v4_in, unsigned long *v5_in);
+
+static struct xor_block_template xor_block_altivec = {
+       .name = "altivec",
+       .do_2 = xor_altivec_2,
+       .do_3 = xor_altivec_3,
+       .do_4 = xor_altivec_4,
+       .do_5 = xor_altivec_5,
+};
+
+#define XOR_SPEED_ALTIVEC()                            \
+       do {                                            \
+               if (cpu_has_feature(CPU_FTR_ALTIVEC))   \
+                       xor_speed(&xor_block_altivec);  \
+       } while (0)
+#else
+#define XOR_SPEED_ALTIVEC()
+#endif
+
+/* Also try the generic routines. */
 #include <asm-generic/xor.h>
+
+#undef XOR_TRY_TEMPLATES
+#define XOR_TRY_TEMPLATES                              \
+do {                                                   \
+       xor_speed(&xor_block_8regs);                    \
+       xor_speed(&xor_block_8regs_p);                  \
+       xor_speed(&xor_block_32regs);                   \
+       xor_speed(&xor_block_32regs_p);                 \
+       XOR_SPEED_ALTIVEC();                            \
+} while (0)
+
+#endif /* _ASM_POWERPC_XOR_H */
index aa6cc4fac9651326b69a7648b13009f30dd93774..ca931d0740003e71f786fcb15db16cdf53aaadb4 100644 (file)
@@ -7,6 +7,10 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  */
+#ifdef __LITTLE_ENDIAN__
+#include <linux/byteorder/little_endian.h>
+#else
 #include <linux/byteorder/big_endian.h>
+#endif
 
 #endif /* _ASM_POWERPC_BYTEORDER_H */
index a27ccd5dc6b9a5bb18435af2a862d7b5ddb619be..de91f3ae631eef5ccc15cf8966b6882288579b11 100644 (file)
@@ -54,8 +54,6 @@ struct aligninfo {
 /* DSISR bits reported for a DCBZ instruction: */
 #define DCBZ   0x5f    /* 8xx/82xx dcbz faults when cache not enabled */
 
-#define SWAP(a, b)     (t = (a), (a) = (b), (b) = t)
-
 /*
  * The PowerPC stores certain bits of the instruction that caused the
  * alignment exception in the DSISR register.  This array maps those
@@ -256,11 +254,17 @@ static int emulate_dcbz(struct pt_regs *regs, unsigned char __user *addr)
  * bottom 4 bytes of each register, and the loads clear the
  * top 4 bytes of the affected register.
  */
+#ifdef __BIG_ENDIAN__
 #ifdef CONFIG_PPC64
 #define REG_BYTE(rp, i)                *((u8 *)((rp) + ((i) >> 2)) + ((i) & 3) + 4)
 #else
 #define REG_BYTE(rp, i)                *((u8 *)(rp) + (i))
 #endif
+#endif
+
+#ifdef __LITTLE_ENDIAN__
+#define REG_BYTE(rp, i)                (*(((u8 *)((rp) + ((i)>>2)) + ((i)&3))))
+#endif
 
 #define SWIZ_PTR(p)            ((unsigned char __user *)((p) ^ swiz))
 
@@ -305,6 +309,15 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr,
                        nb0 = nb + reg * 4 - 128;
                        nb = 128 - reg * 4;
                }
+#ifdef __LITTLE_ENDIAN__
+               /*
+                *  String instructions are endian neutral but the code
+                *  below is not.  Force byte swapping on so that the
+                *  effects of swizzling are undone in the load/store
+                *  loops below.
+                */
+               flags ^= SW;
+#endif
        } else {
                /* lwm, stmw */
                nb = (32 - reg) * 4;
@@ -458,7 +471,7 @@ static struct aligninfo spe_aligninfo[32] = {
 static int emulate_spe(struct pt_regs *regs, unsigned int reg,
                       unsigned int instr)
 {
-       int t, ret;
+       int ret;
        union {
                u64 ll;
                u32 w[2];
@@ -581,24 +594,18 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg,
        if (flags & SW) {
                switch (flags & 0xf0) {
                case E8:
-                       SWAP(data.v[0], data.v[7]);
-                       SWAP(data.v[1], data.v[6]);
-                       SWAP(data.v[2], data.v[5]);
-                       SWAP(data.v[3], data.v[4]);
+                       data.ll = swab64(data.ll);
                        break;
                case E4:
-
-                       SWAP(data.v[0], data.v[3]);
-                       SWAP(data.v[1], data.v[2]);
-                       SWAP(data.v[4], data.v[7]);
-                       SWAP(data.v[5], data.v[6]);
+                       data.w[0] = swab32(data.w[0]);
+                       data.w[1] = swab32(data.w[1]);
                        break;
                /* Its half word endian */
                default:
-                       SWAP(data.v[0], data.v[1]);
-                       SWAP(data.v[2], data.v[3]);
-                       SWAP(data.v[4], data.v[5]);
-                       SWAP(data.v[6], data.v[7]);
+                       data.h[0] = swab16(data.h[0]);
+                       data.h[1] = swab16(data.h[1]);
+                       data.h[2] = swab16(data.h[2]);
+                       data.h[3] = swab16(data.h[3]);
                        break;
                }
        }
@@ -658,14 +665,31 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg,
        flush_vsx_to_thread(current);
 
        if (reg < 32)
-               ptr = (char *) &current->thread.TS_FPR(reg);
+               ptr = (char *) &current->thread.fp_state.fpr[reg][0];
        else
-               ptr = (char *) &current->thread.vr[reg - 32];
+               ptr = (char *) &current->thread.vr_state.vr[reg - 32];
 
        lptr = (unsigned long *) ptr;
 
+#ifdef __LITTLE_ENDIAN__
+       if (flags & SW) {
+               elsize = length;
+               sw = length-1;
+       } else {
+               /*
+                * The elements are BE ordered, even in LE mode, so process
+                * them in reverse order.
+                */
+               addr += length - elsize;
+
+               /* 8 byte memory accesses go in the top 8 bytes of the VR */
+               if (length == 8)
+                       ptr += 8;
+       }
+#else
        if (flags & SW)
                sw = elsize-1;
+#endif
 
        for (j = 0; j < length; j += elsize) {
                for (i = 0; i < elsize; ++i) {
@@ -675,19 +699,31 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg,
                                ret |= __get_user(ptr[i^sw], addr + i);
                }
                ptr  += elsize;
+#ifdef __LITTLE_ENDIAN__
+               addr -= elsize;
+#else
                addr += elsize;
+#endif
        }
 
+#ifdef __BIG_ENDIAN__
+#define VSX_HI 0
+#define VSX_LO 1
+#else
+#define VSX_HI 1
+#define VSX_LO 0
+#endif
+
        if (!ret) {
                if (flags & U)
                        regs->gpr[areg] = regs->dar;
 
                /* Splat load copies the same data to top and bottom 8 bytes */
                if (flags & SPLT)
-                       lptr[1] = lptr[0];
-               /* For 8 byte loads, zero the top 8 bytes */
+                       lptr[VSX_LO] = lptr[VSX_HI];
+               /* For 8 byte loads, zero the low 8 bytes */
                else if (!(flags & ST) && (8 == length))
-                       lptr[1] = 0;
+                       lptr[VSX_LO] = 0;
        } else
                return -EFAULT;
 
@@ -710,18 +746,28 @@ int fix_alignment(struct pt_regs *regs)
        unsigned int dsisr;
        unsigned char __user *addr;
        unsigned long p, swiz;
-       int ret, t;
-       union {
+       int ret, i;
+       union data {
                u64 ll;
                double dd;
                unsigned char v[8];
                struct {
+#ifdef __LITTLE_ENDIAN__
+                       int      low32;
+                       unsigned hi32;
+#else
                        unsigned hi32;
                        int      low32;
+#endif
                } x32;
                struct {
+#ifdef __LITTLE_ENDIAN__
+                       short         low16;
+                       unsigned char hi48[6];
+#else
                        unsigned char hi48[6];
                        short         low16;
+#endif
                } x16;
        } data;
 
@@ -780,8 +826,9 @@ int fix_alignment(struct pt_regs *regs)
 
        /* Byteswap little endian loads and stores */
        swiz = 0;
-       if (regs->msr & MSR_LE) {
+       if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) {
                flags ^= SW;
+#ifdef __BIG_ENDIAN__
                /*
                 * So-called "PowerPC little endian" mode works by
                 * swizzling addresses rather than by actually doing
@@ -794,6 +841,7 @@ int fix_alignment(struct pt_regs *regs)
                 */
                if (cpu_has_feature(CPU_FTR_PPC_LE))
                        swiz = 7;
+#endif
        }
 
        /* DAR has the operand effective address */
@@ -818,7 +866,7 @@ int fix_alignment(struct pt_regs *regs)
                        elsize = 8;
 
                flags = 0;
-               if (regs->msr & MSR_LE)
+               if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE))
                        flags |= SW;
                if (instruction & 0x100)
                        flags |= ST;
@@ -878,32 +926,36 @@ int fix_alignment(struct pt_regs *regs)
         * get it from register values
         */
        if (!(flags & ST)) {
-               data.ll = 0;
-               ret = 0;
-               p = (unsigned long) addr;
+               unsigned int start = 0;
+
                switch (nb) {
-               case 8:
-                       ret |= __get_user_inatomic(data.v[0], SWIZ_PTR(p++));
-                       ret |= __get_user_inatomic(data.v[1], SWIZ_PTR(p++));
-                       ret |= __get_user_inatomic(data.v[2], SWIZ_PTR(p++));
-                       ret |= __get_user_inatomic(data.v[3], SWIZ_PTR(p++));
                case 4:
-                       ret |= __get_user_inatomic(data.v[4], SWIZ_PTR(p++));
-                       ret |= __get_user_inatomic(data.v[5], SWIZ_PTR(p++));
+                       start = offsetof(union data, x32.low32);
+                       break;
                case 2:
-                       ret |= __get_user_inatomic(data.v[6], SWIZ_PTR(p++));
-                       ret |= __get_user_inatomic(data.v[7], SWIZ_PTR(p++));
-                       if (unlikely(ret))
-                               return -EFAULT;
+                       start = offsetof(union data, x16.low16);
+                       break;
                }
+
+               data.ll = 0;
+               ret = 0;
+               p = (unsigned long)addr;
+
+               for (i = 0; i < nb; i++)
+                       ret |= __get_user_inatomic(data.v[start + i],
+                                                  SWIZ_PTR(p++));
+
+               if (unlikely(ret))
+                       return -EFAULT;
+
        } else if (flags & F) {
-               data.dd = current->thread.TS_FPR(reg);
+               data.ll = current->thread.TS_FPR(reg);
                if (flags & S) {
                        /* Single-precision FP store requires conversion... */
 #ifdef CONFIG_PPC_FPU
                        preempt_disable();
                        enable_kernel_fp();
-                       cvt_df(&data.dd, (float *)&data.v[4]);
+                       cvt_df(&data.dd, (float *)&data.x32.low32);
                        preempt_enable();
 #else
                        return 0;
@@ -915,17 +967,13 @@ int fix_alignment(struct pt_regs *regs)
        if (flags & SW) {
                switch (nb) {
                case 8:
-                       SWAP(data.v[0], data.v[7]);
-                       SWAP(data.v[1], data.v[6]);
-                       SWAP(data.v[2], data.v[5]);
-                       SWAP(data.v[3], data.v[4]);
+                       data.ll = swab64(data.ll);
                        break;
                case 4:
-                       SWAP(data.v[4], data.v[7]);
-                       SWAP(data.v[5], data.v[6]);
+                       data.x32.low32 = swab32(data.x32.low32);
                        break;
                case 2:
-                       SWAP(data.v[6], data.v[7]);
+                       data.x16.low16 = swab16(data.x16.low16);
                        break;
                }
        }
@@ -947,7 +995,7 @@ int fix_alignment(struct pt_regs *regs)
 #ifdef CONFIG_PPC_FPU
                preempt_disable();
                enable_kernel_fp();
-               cvt_fd((float *)&data.v[4], &data.dd);
+               cvt_fd((float *)&data.x32.low32, &data.dd);
                preempt_enable();
 #else
                return 0;
@@ -957,25 +1005,28 @@ int fix_alignment(struct pt_regs *regs)
 
        /* Store result to memory or update registers */
        if (flags & ST) {
-               ret = 0;
-               p = (unsigned long) addr;
+               unsigned int start = 0;
+
                switch (nb) {
-               case 8:
-                       ret |= __put_user_inatomic(data.v[0], SWIZ_PTR(p++));
-                       ret |= __put_user_inatomic(data.v[1], SWIZ_PTR(p++));
-                       ret |= __put_user_inatomic(data.v[2], SWIZ_PTR(p++));
-                       ret |= __put_user_inatomic(data.v[3], SWIZ_PTR(p++));
                case 4:
-                       ret |= __put_user_inatomic(data.v[4], SWIZ_PTR(p++));
-                       ret |= __put_user_inatomic(data.v[5], SWIZ_PTR(p++));
+                       start = offsetof(union data, x32.low32);
+                       break;
                case 2:
-                       ret |= __put_user_inatomic(data.v[6], SWIZ_PTR(p++));
-                       ret |= __put_user_inatomic(data.v[7], SWIZ_PTR(p++));
+                       start = offsetof(union data, x16.low16);
+                       break;
                }
+
+               ret = 0;
+               p = (unsigned long)addr;
+
+               for (i = 0; i < nb; i++)
+                       ret |= __put_user_inatomic(data.v[start + i],
+                                                  SWIZ_PTR(p++));
+
                if (unlikely(ret))
                        return -EFAULT;
        } else if (flags & F)
-               current->thread.TS_FPR(reg) = data.dd;
+               current->thread.TS_FPR(reg) = data.ll;
        else
                regs->gpr[reg] = data.ll;
 
index 502c7a4e73f70dc1008754b7f55e5ae164f25a76..e60a3697932caea31a7a0c2ab1c63f86c6c45240 100644 (file)
@@ -90,16 +90,17 @@ int main(void)
        DEFINE(THREAD_NORMSAVES, offsetof(struct thread_struct, normsave[0]));
 #endif
        DEFINE(THREAD_FPEXC_MODE, offsetof(struct thread_struct, fpexc_mode));
-       DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));
-       DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr));
+       DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fp_state));
+       DEFINE(THREAD_FPSAVEAREA, offsetof(struct thread_struct, fp_save_area));
+       DEFINE(FPSTATE_FPSCR, offsetof(struct thread_fp_state, fpscr));
 #ifdef CONFIG_ALTIVEC
-       DEFINE(THREAD_VR0, offsetof(struct thread_struct, vr[0]));
+       DEFINE(THREAD_VRSTATE, offsetof(struct thread_struct, vr_state));
+       DEFINE(THREAD_VRSAVEAREA, offsetof(struct thread_struct, vr_save_area));
        DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
-       DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr));
        DEFINE(THREAD_USED_VR, offsetof(struct thread_struct, used_vr));
+       DEFINE(VRSTATE_VSCR, offsetof(struct thread_vr_state, vscr));
 #endif /* CONFIG_ALTIVEC */
 #ifdef CONFIG_VSX
-       DEFINE(THREAD_VSR0, offsetof(struct thread_struct, fpr));
        DEFINE(THREAD_USED_VSR, offsetof(struct thread_struct, used_vsr));
 #endif /* CONFIG_VSX */
 #ifdef CONFIG_PPC64
@@ -114,7 +115,7 @@ int main(void)
 #endif /* CONFIG_SPE */
 #endif /* CONFIG_PPC64 */
 #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE)
-       DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, dbcr0));
+       DEFINE(THREAD_DBCR0, offsetof(struct thread_struct, debug.dbcr0));
 #endif
 #ifdef CONFIG_KVM_BOOK3S_32_HANDLER
        DEFINE(THREAD_KVM_SVCPU, offsetof(struct thread_struct, kvm_shadow_vcpu));
@@ -143,20 +144,12 @@ int main(void)
        DEFINE(THREAD_TM_PPR, offsetof(struct thread_struct, tm_ppr));
        DEFINE(THREAD_TM_DSCR, offsetof(struct thread_struct, tm_dscr));
        DEFINE(PT_CKPT_REGS, offsetof(struct thread_struct, ckpt_regs));
-       DEFINE(THREAD_TRANSACT_VR0, offsetof(struct thread_struct,
-                                        transact_vr[0]));
-       DEFINE(THREAD_TRANSACT_VSCR, offsetof(struct thread_struct,
-                                         transact_vscr));
+       DEFINE(THREAD_TRANSACT_VRSTATE, offsetof(struct thread_struct,
+                                                transact_vr));
        DEFINE(THREAD_TRANSACT_VRSAVE, offsetof(struct thread_struct,
                                            transact_vrsave));
-       DEFINE(THREAD_TRANSACT_FPR0, offsetof(struct thread_struct,
-                                         transact_fpr[0]));
-       DEFINE(THREAD_TRANSACT_FPSCR, offsetof(struct thread_struct,
-                                          transact_fpscr));
-#ifdef CONFIG_VSX
-       DEFINE(THREAD_TRANSACT_VSR0, offsetof(struct thread_struct,
-                                         transact_fpr[0]));
-#endif
+       DEFINE(THREAD_TRANSACT_FPSTATE, offsetof(struct thread_struct,
+                                                transact_fp));
        /* Local pt_regs on stack for Transactional Memory funcs. */
        DEFINE(TM_FRAME_SIZE, STACK_FRAME_OVERHEAD +
               sizeof(struct pt_regs) + 16);
index 55593ee2d5aacfee6ef9e86c5adfd4057c5cab10..1fb331db34c848a899f5652623cdd2e5bf71d7d9 100644 (file)
@@ -327,11 +327,11 @@ static int eeh_phb_check_failure(struct eeh_pe *pe)
        /* Isolate the PHB and send event */
        eeh_pe_state_mark(phb_pe, EEH_PE_ISOLATED);
        eeh_serialize_unlock(flags);
-       eeh_send_failure_event(phb_pe);
 
        pr_err("EEH: PHB#%x failure detected\n",
                phb_pe->phb->global_number);
        dump_stack();
+       eeh_send_failure_event(phb_pe);
 
        return 1;
 out:
@@ -454,8 +454,6 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
        eeh_pe_state_mark(pe, EEH_PE_ISOLATED);
        eeh_serialize_unlock(flags);
 
-       eeh_send_failure_event(pe);
-
        /* Most EEH events are due to device driver bugs.  Having
         * a stack trace will help the device-driver authors figure
         * out what happened.  So print that out.
@@ -464,6 +462,8 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
                pe->addr, pe->phb->global_number);
        dump_stack();
 
+       eeh_send_failure_event(pe);
+
        return 1;
 
 dn_unlock:
index c04cdf70d487536614899da24fe88beac50a0f54..bbfb0294b3544072ac22b2fcfee486620ae1479e 100644 (file)
@@ -673,9 +673,7 @@ _GLOBAL(ret_from_except_lite)
 
 resume_kernel:
        /* check current_thread_info, _TIF_EMULATE_STACK_STORE */
-       CURRENT_THREAD_INFO(r9, r1)
-       ld      r8,TI_FLAGS(r9)
-       andis.  r8,r8,_TIF_EMULATE_STACK_STORE@h
+       andis.  r8,r4,_TIF_EMULATE_STACK_STORE@h
        beq+    1f
 
        addi    r8,r1,INT_FRAME_SIZE    /* Get the kprobed function entry */
@@ -820,6 +818,12 @@ fast_exception_return:
        andi.   r0,r3,MSR_RI
        beq-    unrecov_restore
 
+       /* Load PPR from thread struct before we clear MSR:RI */
+BEGIN_FTR_SECTION
+       ld      r2,PACACURRENT(r13)
+       ld      r2,TASKTHREADPPR(r2)
+END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
+
        /*
         * Clear RI before restoring r13.  If we are returning to
         * userspace and we take an exception after restoring r13,
@@ -840,8 +844,10 @@ fast_exception_return:
         */
        andi.   r0,r3,MSR_PR
        beq     1f
+BEGIN_FTR_SECTION
+       mtspr   SPRN_PPR,r2     /* Restore PPR */
+END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
        ACCOUNT_CPU_USER_EXIT(r2, r4)
-       RESTORE_PPR(r2, r4)
        REST_GPR(13, r1)
 1:
        mtspr   SPRN_SRR1,r3
@@ -1017,7 +1023,7 @@ _GLOBAL(enter_rtas)
        
         li      r9,1
         rldicr  r9,r9,MSR_SF_LG,(63-MSR_SF_LG)
-       ori     r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP|MSR_RI
+       ori     r9,r9,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP|MSR_RI|MSR_LE
        andc    r6,r0,r9
        sync                            /* disable interrupts so SRR0/1 */
        mtmsrd  r0                      /* don't get trashed */
@@ -1032,6 +1038,8 @@ _GLOBAL(enter_rtas)
        b       .       /* prevent speculative execution */
 
 _STATIC(rtas_return_loc)
+       FIXUP_ENDIAN
+
        /* relocation is off at this point */
        GET_PACA(r4)
        clrldi  r4,r4,2                 /* convert to realmode address */
@@ -1103,28 +1111,30 @@ _GLOBAL(enter_prom)
        std     r10,_CCR(r1)
        std     r11,_MSR(r1)
 
-       /* Get the PROM entrypoint */
-       mtlr    r4
+       /* Put PROM address in SRR0 */
+       mtsrr0  r4
 
-       /* Switch MSR to 32 bits mode
+       /* Setup our trampoline return addr in LR */
+       bcl     20,31,$+4
+0:     mflr    r4
+       addi    r4,r4,(1f - 0b)
+               mtlr    r4
+
+       /* Prepare a 32-bit mode big endian MSR
         */
 #ifdef CONFIG_PPC_BOOK3E
        rlwinm  r11,r11,0,1,31
-       mtmsr   r11
+       mtsrr1  r11
+       rfi
 #else /* CONFIG_PPC_BOOK3E */
-        mfmsr   r11
-        li      r12,1
-        rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
-        andc    r11,r11,r12
-        li      r12,1
-        rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
-        andc    r11,r11,r12
-        mtmsrd  r11
+       LOAD_REG_IMMEDIATE(r12, MSR_SF | MSR_ISF | MSR_LE)
+       andc    r11,r11,r12
+       mtsrr1  r11
+       rfid
 #endif /* CONFIG_PPC_BOOK3E */
-        isync
 
-       /* Enter PROM here... */
-       blrl
+1:     /* Return from OF */
+       FIXUP_ENDIAN
 
        /* Just make sure that r1 top 32 bits didn't get
         * corrupt by OF
index 2d067049db27f1e56ca421c0a223e958125f60ad..e7751561fd1d6cb75f88a703edfb3581a0146d3a 100644 (file)
@@ -399,7 +399,7 @@ interrupt_end_book3e:
 
 /* Altivec Unavailable Interrupt */
        START_EXCEPTION(altivec_unavailable);
-       NORMAL_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_ALTIVEC_UNAVAIL,
+       NORMAL_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_SPE_ALTIVEC_UNAVAIL,
                                PROLOG_ADDITION_NONE)
        /* we can probably do a shorter exception entry for that one... */
        EXCEPTION_COMMON(0x200, PACA_EXGEN, INTS_KEEP)
@@ -421,7 +421,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 
 /* AltiVec Assist */
        START_EXCEPTION(altivec_assist);
-       NORMAL_EXCEPTION_PROLOG(0x220, BOOKE_INTERRUPT_ALTIVEC_ASSIST,
+       NORMAL_EXCEPTION_PROLOG(0x220,
+                               BOOKE_INTERRUPT_SPE_FP_DATA_ALTIVEC_ASSIST,
                                PROLOG_ADDITION_NONE)
        EXCEPTION_COMMON(0x220, PACA_EXGEN, INTS_DISABLE)
        bl      .save_nvgprs
@@ -607,6 +608,7 @@ kernel_dbg_exc:
        NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR,
                                PROLOG_ADDITION_NONE)
        EXCEPTION_COMMON(0x260, PACA_EXGEN, INTS_DISABLE)
+       CHECK_NAPPING()
        addi    r3,r1,STACK_FRAME_OVERHEAD
        bl      .performance_monitor_exception
        b       .ret_from_except_lite
index caeaabf11a2fbb3cd7d63555a19600f4e13e2618..f7f5b8bed68f59500964f75ff9f7d9b2aa211d0c 100644 (file)
@@ -35,15 +35,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX);                                  \
 2:     REST_32VSRS(n,c,base);                                          \
 3:
 
-#define __REST_32FPVSRS_TRANSACT(n,c,base)                             \
-BEGIN_FTR_SECTION                                                      \
-       b       2f;                                                     \
-END_FTR_SECTION_IFSET(CPU_FTR_VSX);                                    \
-       REST_32FPRS_TRANSACT(n,base);                                   \
-       b       3f;                                                     \
-2:     REST_32VSRS_TRANSACT(n,c,base);                                 \
-3:
-
 #define __SAVE_32FPVSRS(n,c,base)                                      \
 BEGIN_FTR_SECTION                                                      \
        b       2f;                                                     \
@@ -54,40 +45,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX);                                 \
 3:
 #else
 #define __REST_32FPVSRS(n,b,base)      REST_32FPRS(n, base)
-#define __REST_32FPVSRS_TRANSACT(n,b,base)     REST_32FPRS(n, base)
 #define __SAVE_32FPVSRS(n,b,base)      SAVE_32FPRS(n, base)
 #endif
 #define REST_32FPVSRS(n,c,base) __REST_32FPVSRS(n,__REG_##c,__REG_##base)
-#define REST_32FPVSRS_TRANSACT(n,c,base) \
-       __REST_32FPVSRS_TRANSACT(n,__REG_##c,__REG_##base)
 #define SAVE_32FPVSRS(n,c,base) __SAVE_32FPVSRS(n,__REG_##c,__REG_##base)
 
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-/*
- * Wrapper to call load_up_fpu from C.
- * void do_load_up_fpu(struct pt_regs *regs);
- */
-_GLOBAL(do_load_up_fpu)
-       mflr    r0
-       std     r0, 16(r1)
-       stdu    r1, -112(r1)
-
-       subi    r6, r3, STACK_FRAME_OVERHEAD
-       /* load_up_fpu expects r12=MSR, r13=PACA, and returns
-        * with r12 = new MSR.
-        */
-       ld      r12,_MSR(r6)
-       GET_PACA(r13)
-
-       bl      load_up_fpu
-       std     r12,_MSR(r6)
-
-       ld      r0, 112+16(r1)
-       addi    r1, r1, 112
-       mtlr    r0
-       blr
-
-
 /* void do_load_up_transact_fpu(struct thread_struct *thread)
  *
  * This is similar to load_up_fpu but for the transactional version of the FP
@@ -105,9 +68,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
        SYNC
        MTMSRD(r5)
 
-       lfd     fr0,THREAD_TRANSACT_FPSCR(r3)
+       addi    r7,r3,THREAD_TRANSACT_FPSTATE
+       lfd     fr0,FPSTATE_FPSCR(r7)
        MTFSF_L(fr0)
-       REST_32FPVSRS_TRANSACT(0, R4, R3)
+       REST_32FPVSRS(0, R4, R7)
 
        /* FP/VSX off again */
        MTMSRD(r6)
@@ -116,12 +80,34 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
        blr
 #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
 
+/*
+ * Load state from memory into FP registers including FPSCR.
+ * Assumes the caller has enabled FP in the MSR.
+ */
+_GLOBAL(load_fp_state)
+       lfd     fr0,FPSTATE_FPSCR(r3)
+       MTFSF_L(fr0)
+       REST_32FPVSRS(0, R4, R3)
+       blr
+
+/*
+ * Store FP state into memory, including FPSCR
+ * Assumes the caller has enabled FP in the MSR.
+ */
+_GLOBAL(store_fp_state)
+       SAVE_32FPVSRS(0, R4, R3)
+       mffs    fr0
+       stfd    fr0,FPSTATE_FPSCR(r3)
+       blr
+
 /*
  * This task wants to use the FPU now.
  * On UP, disable FP for the task which had the FPU previously,
  * and save its floating-point registers in its thread_struct.
  * Load up this task's FP registers from its thread_struct,
  * enable the FPU for the current task and return to the task.
+ * Note that on 32-bit this can only use registers that will be
+ * restored by fast_exception_return, i.e. r3 - r6, r10 and r11.
  */
 _GLOBAL(load_up_fpu)
        mfmsr   r5
@@ -147,9 +133,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
        beq     1f
        toreal(r4)
        addi    r4,r4,THREAD            /* want last_task_used_math->thread */
-       SAVE_32FPVSRS(0, R5, R4)
+       addi    r10,r4,THREAD_FPSTATE
+       SAVE_32FPVSRS(0, R5, R10)
        mffs    fr0
-       stfd    fr0,THREAD_FPSCR(r4)
+       stfd    fr0,FPSTATE_FPSCR(r10)
        PPC_LL  r5,PT_REGS(r4)
        toreal(r5)
        PPC_LL  r4,_MSR-STACK_FRAME_OVERHEAD(r5)
@@ -160,7 +147,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
 #endif /* CONFIG_SMP */
        /* enable use of FP after return */
 #ifdef CONFIG_PPC32
-       mfspr   r5,SPRN_SPRG_THREAD             /* current task's THREAD (phys) */
+       mfspr   r5,SPRN_SPRG_THREAD     /* current task's THREAD (phys) */
        lwz     r4,THREAD_FPEXC_MODE(r5)
        ori     r9,r9,MSR_FP            /* enable FP for current */
        or      r9,r9,r4
@@ -172,9 +159,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
        or      r12,r12,r4
        std     r12,_MSR(r1)
 #endif
-       lfd     fr0,THREAD_FPSCR(r5)
+       addi    r10,r5,THREAD_FPSTATE
+       lfd     fr0,FPSTATE_FPSCR(r10)
        MTFSF_L(fr0)
-       REST_32FPVSRS(0, R4, R5)
+       REST_32FPVSRS(0, R4, R10)
 #ifndef CONFIG_SMP
        subi    r4,r5,THREAD
        fromreal(r4)
@@ -206,11 +194,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
        PPC_LCMPI       0,r3,0
        beqlr-                          /* if no previous owner, done */
        addi    r3,r3,THREAD            /* want THREAD of task */
+       PPC_LL  r6,THREAD_FPSAVEAREA(r3)
        PPC_LL  r5,PT_REGS(r3)
-       PPC_LCMPI       0,r5,0
-       SAVE_32FPVSRS(0, R4 ,R3)
+       PPC_LCMPI       0,r6,0
+       bne     2f
+       addi    r6,r3,THREAD_FPSTATE
+2:     PPC_LCMPI       0,r5,0
+       SAVE_32FPVSRS(0, R4, R6)
        mffs    fr0
-       stfd    fr0,THREAD_FPSCR(r3)
+       stfd    fr0,FPSTATE_FPSCR(r6)
        beq     1f
        PPC_LL  r4,_MSR-STACK_FRAME_OVERHEAD(r5)
        li      r3,MSR_FP|MSR_FE0|MSR_FE1
index 1fb78561096accfff7e60062a4fbc0bddfcfec55..9b27b293a9226903c81529a4f01aee64a7f07d23 100644 (file)
@@ -174,7 +174,11 @@ __ftrace_make_nop(struct module *mod,
 
        pr_devel(" %08x %08x\n", jmp[0], jmp[1]);
 
+#ifdef __LITTLE_ENDIAN__
+       ptr = ((unsigned long)jmp[1] << 32) + jmp[0];
+#else
        ptr = ((unsigned long)jmp[0] << 32) + jmp[1];
+#endif
 
        /* This should match what was called */
        if (ptr != ppc_function_entry((void *)addr)) {
index 3d11d8038deec122ad9735202e98f4567998a070..2ae41aba40530f7facf916f6ce101ad3196a7363 100644 (file)
@@ -68,6 +68,7 @@ _stext:
 _GLOBAL(__start)
        /* NOP this out unconditionally */
 BEGIN_FTR_SECTION
+       FIXUP_ENDIAN
        b       .__start_initialization_multiplatform
 END_FTR_SECTION(0, 1)
 
@@ -115,6 +116,7 @@ __run_at_load:
  */
        .globl  __secondary_hold
 __secondary_hold:
+       FIXUP_ENDIAN
 #ifndef CONFIG_PPC_BOOK3E
        mfmsr   r24
        ori     r24,r24,MSR_RI
@@ -205,6 +207,7 @@ _GLOBAL(generic_secondary_thread_init)
  * as SCOM before entry).
  */
 _GLOBAL(generic_secondary_smp_init)
+       FIXUP_ENDIAN
        mr      r24,r3
        mr      r25,r4
 
index 1b92a97b1b046d3721c9aed9912775de27dccd6d..7ee876d2adb57c6cc1e78d1d3204ab240238c02d 100644 (file)
@@ -858,6 +858,9 @@ initial_mmu:
        addis   r11, r11, 0x0080        /* Add 8M */
        mtspr   SPRN_MD_RPN, r11
 
+       addi    r10, r10, 0x0100
+       mtspr   SPRN_MD_CTR, r10
+
        addis   r8, r8, 0x0080          /* Add 8M */
        mtspr   SPRN_MD_EPN, r8
        mtspr   SPRN_MD_TWC, r9
index 289afaffbbb5df2ecba595e01646a5b5d4bfd964..f45726a1d963ddae9591fa1210736f124ac6a5b4 100644 (file)
@@ -555,27 +555,27 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
 #ifdef CONFIG_SPE
        /* SPE Unavailable */
        START_EXCEPTION(SPEUnavailable)
-       NORMAL_EXCEPTION_PROLOG(SPE_UNAVAIL)
+       NORMAL_EXCEPTION_PROLOG(SPE_ALTIVEC_UNAVAIL)
        beq     1f
        bl      load_up_spe
        b       fast_exception_return
 1:     addi    r3,r1,STACK_FRAME_OVERHEAD
        EXC_XFER_EE_LITE(0x2010, KernelSPE)
 #else
-       EXCEPTION(0x2020, SPE_UNAVAIL, SPEUnavailable, \
+       EXCEPTION(0x2020, SPE_ALTIVEC_UNAVAIL, SPEUnavailable, \
                  unknown_exception, EXC_XFER_EE)
 #endif /* CONFIG_SPE */
 
        /* SPE Floating Point Data */
 #ifdef CONFIG_SPE
-       EXCEPTION(0x2030, SPE_FP_DATA, SPEFloatingPointData, \
-                 SPEFloatingPointException, EXC_XFER_EE);
+       EXCEPTION(0x2030, SPE_FP_DATA_ALTIVEC_ASSIST, SPEFloatingPointData,
+                 SPEFloatingPointException, EXC_XFER_EE)
 
        /* SPE Floating Point Round */
        EXCEPTION(0x2050, SPE_FP_ROUND, SPEFloatingPointRound, \
                  SPEFloatingPointRoundException, EXC_XFER_EE)
 #else
-       EXCEPTION(0x2040, SPE_FP_DATA, SPEFloatingPointData, \
+       EXCEPTION(0x2040, SPE_FP_DATA_ALTIVEC_ASSIST, SPEFloatingPointData,
                  unknown_exception, EXC_XFER_EE)
        EXCEPTION(0x2050, SPE_FP_ROUND, SPEFloatingPointRound, \
                  unknown_exception, EXC_XFER_EE)
index c1eef241017a1224bd424398d05b95f03cd38079..83e89d310734f676274f819f2897777ce9ad3f72 100644 (file)
@@ -151,15 +151,16 @@ static int kgdb_handle_breakpoint(struct pt_regs *regs)
        return 1;
 }
 
+static DEFINE_PER_CPU(struct thread_info, kgdb_thread_info);
 static int kgdb_singlestep(struct pt_regs *regs)
 {
        struct thread_info *thread_info, *exception_thread_info;
-       struct thread_info *backup_current_thread_info;
+       struct thread_info *backup_current_thread_info =
+               &__get_cpu_var(kgdb_thread_info);
 
        if (user_mode(regs))
                return 0;
 
-       backup_current_thread_info = kmalloc(sizeof(struct thread_info), GFP_KERNEL);
        /*
         * On Book E and perhaps other processors, singlestep is handled on
         * the critical exception stack.  This causes current_thread_info()
@@ -185,7 +186,6 @@ static int kgdb_singlestep(struct pt_regs *regs)
                /* Restore current_thread_info lastly. */
                memcpy(exception_thread_info, backup_current_thread_info, sizeof *thread_info);
 
-       kfree(backup_current_thread_info);
        return 1;
 }
 
index 22e88dd2f34ad7b43c27fe1361f8ed9213f9f960..40bd7bd4e19a88ee9b573c37deea8bc8694375b9 100644 (file)
@@ -35,7 +35,7 @@ static struct legacy_serial_info {
        phys_addr_t                     taddr;
 } legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS];
 
-static struct __initdata of_device_id legacy_serial_parents[] = {
+static struct of_device_id legacy_serial_parents[] __initdata = {
        {.type = "soc",},
        {.type = "tsi-bridge",},
        {.type = "opb", },
index 611acdf30096643a1d94bc3111b685e28d290453..be4e6d648f6093d4efe7fe84155ebe9653a3baea 100644 (file)
@@ -312,7 +312,7 @@ static union thread_union kexec_stack __init_task_data =
  */
 struct paca_struct kexec_paca;
 
-/* Our assembly helper, in kexec_stub.S */
+/* Our assembly helper, in misc_64.S */
 extern void kexec_sequence(void *newstack, unsigned long start,
                           void *image, void *control,
                           void (*clear_all)(void)) __noreturn;
index 2b0ad984536333d7a15a3b39e6c9234c11b4b669..e47d268727a4a8ed87948a4d3ab5f87ad00793b1 100644 (file)
@@ -658,6 +658,20 @@ _GLOBAL(__lshrdi3)
        or      r4,r4,r7        # LSW |= t2
        blr
 
+/*
+ * 64-bit comparison: __cmpdi2(s64 a, s64 b)
+ * Returns 0 if a < b, 1 if a == b, 2 if a > b.
+ */
+_GLOBAL(__cmpdi2)
+       cmpw    r3,r5
+       li      r3,1
+       bne     1f
+       cmplw   r4,r6
+       beqlr
+1:     li      r3,0
+       bltlr
+       li      r3,2
+       blr
 /*
  * 64-bit comparison: __ucmpdi2(u64 a, u64 b)
  * Returns 0 if a < b, 1 if a == b, 2 if a > b.
index 2d275707f419db519910a5b8549a3f9f016d8eab..9547381b631a587b6d520b22f414039d6d458525 100644 (file)
@@ -25,8 +25,7 @@
 #include <asm/uaccess.h>
 #include <asm/firmware.h>
 #include <linux/sort.h>
-
-#include "setup.h"
+#include <asm/setup.h>
 
 LIST_HEAD(module_bug_list);
 
index 2e3200ca485f7bab8aba23f4d02948f74eacee69..6cff040bf4565ae618e801a7159e2e5871b2c1e1 100644 (file)
@@ -26,8 +26,7 @@
 #include <linux/cache.h>
 #include <linux/bug.h>
 #include <linux/sort.h>
-
-#include "setup.h"
+#include <asm/setup.h>
 
 #if 0
 #define DEBUGP printk
index 6ee59a0eb268b8614ef13b6745c3555bfdd7aebd..12664c130d73dd2d62fac4300f033de1a5242b7c 100644 (file)
@@ -26,8 +26,7 @@
 #include <asm/firmware.h>
 #include <asm/code-patching.h>
 #include <linux/sort.h>
-
-#include "setup.h"
+#include <asm/setup.h>
 
 /* FIXME: We don't do .init separately.  To do this, we'd need to have
    a separate r2 value in the init and core section, and stub between
@@ -62,6 +61,16 @@ struct ppc64_stub_entry
    r2) into the stub. */
 static struct ppc64_stub_entry ppc64_stub =
 { .jump = {
+#ifdef __LITTLE_ENDIAN__
+       0x00, 0x00, 0x82, 0x3d, /* addis   r12,r2, <high> */
+       0x00, 0x00, 0x8c, 0x39, /* addi    r12,r12, <low> */
+       /* Save current r2 value in magic place on the stack. */
+       0x28, 0x00, 0x41, 0xf8, /* std     r2,40(r1) */
+       0x20, 0x00, 0x6c, 0xe9, /* ld      r11,32(r12) */
+       0x28, 0x00, 0x4c, 0xe8, /* ld      r2,40(r12) */
+       0xa6, 0x03, 0x69, 0x7d, /* mtctr   r11 */
+       0x20, 0x04, 0x80, 0x4e  /* bctr */
+#else
        0x3d, 0x82, 0x00, 0x00, /* addis   r12,r2, <high> */
        0x39, 0x8c, 0x00, 0x00, /* addi    r12,r12, <low> */
        /* Save current r2 value in magic place on the stack. */
@@ -70,6 +79,7 @@ static struct ppc64_stub_entry ppc64_stub =
        0xe8, 0x4c, 0x00, 0x28, /* ld      r2,40(r12) */
        0x7d, 0x69, 0x03, 0xa6, /* mtctr   r11 */
        0x4e, 0x80, 0x04, 0x20  /* bctr */
+#endif
 } };
 
 /* Count how many different 24-bit relocations (different symbol,
@@ -269,8 +279,13 @@ static inline int create_stub(Elf64_Shdr *sechdrs,
 
        *entry = ppc64_stub;
 
+#ifdef __LITTLE_ENDIAN__
+       loc1 = (Elf64_Half *)&entry->jump[0];
+       loc2 = (Elf64_Half *)&entry->jump[4];
+#else
        loc1 = (Elf64_Half *)&entry->jump[2];
        loc2 = (Elf64_Half *)&entry->jump[6];
+#endif
 
        /* Stub uses address relative to r2. */
        reladdr = (unsigned long)entry - my_r2(sechdrs, me);
index 8213ee1eb05abc39e8da6502ec565b4a38180e7e..fd82c289ab1c1c76c52c9fe147503d277870874c 100644 (file)
@@ -223,9 +223,13 @@ static int __init nvram_write_header(struct nvram_partition * part)
 {
        loff_t tmp_index;
        int rc;
-       
+       struct nvram_header phead;
+
+       memcpy(&phead, &part->header, NVRAM_HEADER_LEN);
+       phead.length = cpu_to_be16(phead.length);
+
        tmp_index = part->index;
-       rc = ppc_md.nvram_write((char *)&part->header, NVRAM_HEADER_LEN, &tmp_index); 
+       rc = ppc_md.nvram_write((char *)&phead, NVRAM_HEADER_LEN, &tmp_index);
 
        return rc;
 }
@@ -505,6 +509,8 @@ int __init nvram_scan_partitions(void)
 
                memcpy(&phead, header, NVRAM_HEADER_LEN);
 
+               phead.length = be16_to_cpu(phead.length);
+
                err = 0;
                c_sum = nvram_checksum(&phead);
                if (c_sum != phead.checksum) {
index 3fc16e3beb9f8dca2ea5f260bb59d2dc20bef3f3..0620eaaaad45b419c70475485a9d052c0ddbe246 100644 (file)
@@ -46,7 +46,7 @@ struct lppaca lppaca[] = {
 static struct lppaca *extra_lppacas;
 static long __initdata lppaca_size;
 
-static void allocate_lppacas(int nr_cpus, unsigned long limit)
+static void __init allocate_lppacas(int nr_cpus, unsigned long limit)
 {
        if (nr_cpus <= NR_LPPACAS)
                return;
@@ -57,7 +57,7 @@ static void allocate_lppacas(int nr_cpus, unsigned long limit)
                                                 PAGE_SIZE, limit));
 }
 
-static struct lppaca *new_lppaca(int cpu)
+static struct lppaca * __init new_lppaca(int cpu)
 {
        struct lppaca *lp;
 
@@ -70,7 +70,7 @@ static struct lppaca *new_lppaca(int cpu)
        return lp;
 }
 
-static void free_lppacas(void)
+static void __init free_lppacas(void)
 {
        long new_size = 0, nr;
 
index 4368ec6fdc8c4084c149150a45e6ee2f3150fdcf..ac0b034f9ae0fb389a450fab78bd2da8bc737a63 100644 (file)
@@ -302,7 +302,7 @@ static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus,
                            struct device_node *dn)
 {
        struct pci_dev *dev = NULL;
-       const u32 *reg;
+       const __be32 *reg;
        int reglen, devfn;
 
        pr_debug("  * %s\n", dn->full_name);
@@ -312,7 +312,7 @@ static struct pci_dev *of_scan_pci_dev(struct pci_bus *bus,
        reg = of_get_property(dn, "reg", &reglen);
        if (reg == NULL || reglen < 20)
                return NULL;
-       devfn = (reg[0] >> 8) & 0xff;
+       devfn = (of_read_number(reg, 1) >> 8) & 0xff;
 
        /* Check if the PCI device is already there */
        dev = pci_get_slot(bus, devfn);
index 21646dbe1bb3c7a48df59ba14dea18431abe12be..3bd77edd7610ce20267a880069972624eafed62e 100644 (file)
@@ -79,10 +79,12 @@ EXPORT_SYMBOL(strlen);
 EXPORT_SYMBOL(strcmp);
 EXPORT_SYMBOL(strncmp);
 
+#ifndef CONFIG_GENERIC_CSUM
 EXPORT_SYMBOL(csum_partial);
 EXPORT_SYMBOL(csum_partial_copy_generic);
 EXPORT_SYMBOL(ip_fast_csum);
 EXPORT_SYMBOL(csum_tcpudp_magic);
+#endif
 
 EXPORT_SYMBOL(__copy_tofrom_user);
 EXPORT_SYMBOL(__clear_user);
@@ -98,9 +100,13 @@ EXPORT_SYMBOL(start_thread);
 
 #ifdef CONFIG_PPC_FPU
 EXPORT_SYMBOL(giveup_fpu);
+EXPORT_SYMBOL(load_fp_state);
+EXPORT_SYMBOL(store_fp_state);
 #endif
 #ifdef CONFIG_ALTIVEC
 EXPORT_SYMBOL(giveup_altivec);
+EXPORT_SYMBOL(load_vr_state);
+EXPORT_SYMBOL(store_vr_state);
 #endif /* CONFIG_ALTIVEC */
 #ifdef CONFIG_VSX
 EXPORT_SYMBOL(giveup_vsx);
@@ -143,10 +149,14 @@ EXPORT_SYMBOL(__ashldi3);
 EXPORT_SYMBOL(__lshrdi3);
 int __ucmpdi2(unsigned long long, unsigned long long);
 EXPORT_SYMBOL(__ucmpdi2);
+int __cmpdi2(long long, long long);
+EXPORT_SYMBOL(__cmpdi2);
 #endif
 long long __bswapdi2(long long);
 EXPORT_SYMBOL(__bswapdi2);
+#ifdef __BIG_ENDIAN__
 EXPORT_SYMBOL(memcpy);
+#endif
 EXPORT_SYMBOL(memset);
 EXPORT_SYMBOL(memmove);
 EXPORT_SYMBOL(memcmp);
index 96d2fdf3aa9ebe3bba547fd567c5a232be20ec9a..75c2d1009985eb8dbd9f3995fc900f9f21227d01 100644 (file)
@@ -314,28 +314,28 @@ static DEFINE_PER_CPU(struct arch_hw_breakpoint, current_brk);
  */
 static void set_debug_reg_defaults(struct thread_struct *thread)
 {
-       thread->iac1 = thread->iac2 = 0;
+       thread->debug.iac1 = thread->debug.iac2 = 0;
 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
-       thread->iac3 = thread->iac4 = 0;
+       thread->debug.iac3 = thread->debug.iac4 = 0;
 #endif
-       thread->dac1 = thread->dac2 = 0;
+       thread->debug.dac1 = thread->debug.dac2 = 0;
 #if CONFIG_PPC_ADV_DEBUG_DVCS > 0
-       thread->dvc1 = thread->dvc2 = 0;
+       thread->debug.dvc1 = thread->debug.dvc2 = 0;
 #endif
-       thread->dbcr0 = 0;
+       thread->debug.dbcr0 = 0;
 #ifdef CONFIG_BOOKE
        /*
         * Force User/Supervisor bits to b11 (user-only MSR[PR]=1)
         */
-       thread->dbcr1 = DBCR1_IAC1US | DBCR1_IAC2US |   \
+       thread->debug.dbcr1 = DBCR1_IAC1US | DBCR1_IAC2US |
                        DBCR1_IAC3US | DBCR1_IAC4US;
        /*
         * Force Data Address Compare User/Supervisor bits to be User-only
         * (0b11 MSR[PR]=1) and set all other bits in DBCR2 register to be 0.
         */
-       thread->dbcr2 = DBCR2_DAC1US | DBCR2_DAC2US;
+       thread->debug.dbcr2 = DBCR2_DAC1US | DBCR2_DAC2US;
 #else
-       thread->dbcr1 = 0;
+       thread->debug.dbcr1 = 0;
 #endif
 }
 
@@ -348,22 +348,22 @@ static void prime_debug_regs(struct thread_struct *thread)
         */
        mtmsr(mfmsr() & ~MSR_DE);
 
-       mtspr(SPRN_IAC1, thread->iac1);
-       mtspr(SPRN_IAC2, thread->iac2);
+       mtspr(SPRN_IAC1, thread->debug.iac1);
+       mtspr(SPRN_IAC2, thread->debug.iac2);
 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
-       mtspr(SPRN_IAC3, thread->iac3);
-       mtspr(SPRN_IAC4, thread->iac4);
+       mtspr(SPRN_IAC3, thread->debug.iac3);
+       mtspr(SPRN_IAC4, thread->debug.iac4);
 #endif
-       mtspr(SPRN_DAC1, thread->dac1);
-       mtspr(SPRN_DAC2, thread->dac2);
+       mtspr(SPRN_DAC1, thread->debug.dac1);
+       mtspr(SPRN_DAC2, thread->debug.dac2);
 #if CONFIG_PPC_ADV_DEBUG_DVCS > 0
-       mtspr(SPRN_DVC1, thread->dvc1);
-       mtspr(SPRN_DVC2, thread->dvc2);
+       mtspr(SPRN_DVC1, thread->debug.dvc1);
+       mtspr(SPRN_DVC2, thread->debug.dvc2);
 #endif
-       mtspr(SPRN_DBCR0, thread->dbcr0);
-       mtspr(SPRN_DBCR1, thread->dbcr1);
+       mtspr(SPRN_DBCR0, thread->debug.dbcr0);
+       mtspr(SPRN_DBCR1, thread->debug.dbcr1);
 #ifdef CONFIG_BOOKE
-       mtspr(SPRN_DBCR2, thread->dbcr2);
+       mtspr(SPRN_DBCR2, thread->debug.dbcr2);
 #endif
 }
 /*
@@ -371,12 +371,13 @@ static void prime_debug_regs(struct thread_struct *thread)
  * debug registers, set the debug registers from the values
  * stored in the new thread.
  */
-static void switch_booke_debug_regs(struct thread_struct *new_thread)
+void switch_booke_debug_regs(struct thread_struct *new_thread)
 {
-       if ((current->thread.dbcr0 & DBCR0_IDM)
-               || (new_thread->dbcr0 & DBCR0_IDM))
+       if ((current->thread.debug.dbcr0 & DBCR0_IDM)
+               || (new_thread->debug.dbcr0 & DBCR0_IDM))
                        prime_debug_regs(new_thread);
 }
+EXPORT_SYMBOL_GPL(switch_booke_debug_regs);
 #else  /* !CONFIG_PPC_ADV_DEBUG_REGS */
 #ifndef CONFIG_HAVE_HW_BREAKPOINT
 static void set_debug_reg_defaults(struct thread_struct *thread)
@@ -596,12 +597,13 @@ struct task_struct *__switch_to(struct task_struct *prev,
        struct task_struct *new)
 {
        struct thread_struct *new_thread, *old_thread;
-       unsigned long flags;
        struct task_struct *last;
 #ifdef CONFIG_PPC_BOOK3S_64
        struct ppc64_tlb_batch *batch;
 #endif
 
+       WARN_ON(!irqs_disabled());
+
        /* Back up the TAR across context switches.
         * Note that the TAR is not available for use in the kernel.  (To
         * provide this, the TAR should be backed up/restored on exception
@@ -721,8 +723,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
        }
 #endif /* CONFIG_PPC_BOOK3S_64 */
 
-       local_irq_save(flags);
-
        /*
         * We can't take a PMU exception inside _switch() since there is a
         * window where the kernel stack SLB and the kernel stack are out
@@ -742,8 +742,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
        }
 #endif /* CONFIG_PPC_BOOK3S_64 */
 
-       local_irq_restore(flags);
-
        return last;
 }
 
@@ -1008,6 +1006,11 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
        p->thread.ptrace_bps[0] = NULL;
 #endif
 
+       p->thread.fp_save_area = NULL;
+#ifdef CONFIG_ALTIVEC
+       p->thread.vr_save_area = NULL;
+#endif
+
 #ifdef CONFIG_PPC_STD_MMU_64
        if (mmu_has_feature(MMU_FTR_SLB)) {
                unsigned long sp_vsid;
@@ -1113,12 +1116,12 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
 #ifdef CONFIG_VSX
        current->thread.used_vsr = 0;
 #endif
-       memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
-       current->thread.fpscr.val = 0;
+       memset(&current->thread.fp_state, 0, sizeof(current->thread.fp_state));
+       current->thread.fp_save_area = NULL;
 #ifdef CONFIG_ALTIVEC
-       memset(current->thread.vr, 0, sizeof(current->thread.vr));
-       memset(&current->thread.vscr, 0, sizeof(current->thread.vscr));
-       current->thread.vscr.u[3] = 0x00010000; /* Java mode disabled */
+       memset(&current->thread.vr_state, 0, sizeof(current->thread.vr_state));
+       current->thread.vr_state.vscr.u[3] = 0x00010000; /* Java mode disabled */
+       current->thread.vr_save_area = NULL;
        current->thread.vrsave = 0;
        current->thread.used_vr = 0;
 #endif /* CONFIG_ALTIVEC */
index b7634ce41dbc92bd67cd5ed1c6c7cd584924ccc4..4432fd86a6d2a69dce59d935e6213eeea4c623e3 100644 (file)
@@ -760,37 +760,6 @@ void __init early_init_devtree(void *params)
  *
  *******/
 
-/**
- *     of_find_next_cache_node - Find a node's subsidiary cache
- *     @np:    node of type "cpu" or "cache"
- *
- *     Returns a node pointer with refcount incremented, use
- *     of_node_put() on it when done.  Caller should hold a reference
- *     to np.
- */
-struct device_node *of_find_next_cache_node(struct device_node *np)
-{
-       struct device_node *child;
-       const phandle *handle;
-
-       handle = of_get_property(np, "l2-cache", NULL);
-       if (!handle)
-               handle = of_get_property(np, "next-level-cache", NULL);
-
-       if (handle)
-               return of_find_node_by_phandle(*handle);
-
-       /* OF on pmac has nodes instead of properties named "l2-cache"
-        * beneath CPU nodes.
-        */
-       if (!strcmp(np->type, "cpu"))
-               for_each_child_of_node(np, child)
-                       if (!strcmp(child->type, "cache"))
-                               return child;
-
-       return NULL;
-}
-
 /**
  * of_get_ibm_chip_id - Returns the IBM "chip-id" of a device
  * @np: device node of the device
index 5fe2842e8bab7cc4013c987c74791c00005c51ee..cb64a6e1dc5186918b4d2052e52e961cfb14eedb 100644 (file)
@@ -858,7 +858,8 @@ static void __init prom_send_capabilities(void)
 {
        ihandle root;
        prom_arg_t ret;
-       __be32 *cores;
+       u32 cores;
+       unsigned char *ptcores;
 
        root = call_prom("open", 1, 1, ADDR("/"));
        if (root != 0) {
@@ -868,15 +869,30 @@ static void __init prom_send_capabilities(void)
                 * (we assume this is the same for all cores) and use it to
                 * divide NR_CPUS.
                 */
-               cores = (__be32 *)&ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET];
-               if (be32_to_cpup(cores) != NR_CPUS) {
+
+               /* The core value may start at an odd address. If such a word
+                * access is made at a cache line boundary, this leads to an
+                * exception which may not be handled at this time.
+                * Forcing a per byte access to avoid exception.
+                */
+               ptcores = &ibm_architecture_vec[IBM_ARCH_VEC_NRCORES_OFFSET];
+               cores = 0;
+               cores |= ptcores[0] << 24;
+               cores |= ptcores[1] << 16;
+               cores |= ptcores[2] << 8;
+               cores |= ptcores[3];
+               if (cores != NR_CPUS) {
                        prom_printf("WARNING ! "
                                    "ibm_architecture_vec structure inconsistent: %lu!\n",
-                                   be32_to_cpup(cores));
+                                   cores);
                } else {
-                       *cores = cpu_to_be32(DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads()));
+                       cores = DIV_ROUND_UP(NR_CPUS, prom_count_smt_threads());
                        prom_printf("Max number of cores passed to firmware: %lu (NR_CPUS = %lu)\n",
-                                   be32_to_cpup(cores), NR_CPUS);
+                                   cores, NR_CPUS);
+                       ptcores[0] = (cores >> 24) & 0xff;
+                       ptcores[1] = (cores >> 16) & 0xff;
+                       ptcores[2] = (cores >> 8) & 0xff;
+                       ptcores[3] = cores & 0xff;
                }
 
                /* try calling the ibm,client-architecture-support method */
index 9a0d24c390a3535e16c934f80ec19695da04d095..75fb40498b419c3e8c1f2c639acfaa4f61f419d2 100644 (file)
@@ -362,7 +362,7 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
                   void *kbuf, void __user *ubuf)
 {
 #ifdef CONFIG_VSX
-       double buf[33];
+       u64 buf[33];
        int i;
 #endif
        flush_fp_to_thread(target);
@@ -371,15 +371,15 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset,
        /* copy to local buffer then write that out */
        for (i = 0; i < 32 ; i++)
                buf[i] = target->thread.TS_FPR(i);
-       memcpy(&buf[32], &target->thread.fpscr, sizeof(double));
+       buf[32] = target->thread.fp_state.fpscr;
        return user_regset_copyout(&pos, &count, &kbuf, &ubuf, buf, 0, -1);
 
 #else
-       BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) !=
-                    offsetof(struct thread_struct, TS_FPR(32)));
+       BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
+                    offsetof(struct thread_fp_state, fpr[32][0]));
 
        return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                  &target->thread.fpr, 0, -1);
+                                  &target->thread.fp_state, 0, -1);
 #endif
 }
 
@@ -388,7 +388,7 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
                   const void *kbuf, const void __user *ubuf)
 {
 #ifdef CONFIG_VSX
-       double buf[33];
+       u64 buf[33];
        int i;
 #endif
        flush_fp_to_thread(target);
@@ -400,14 +400,14 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset,
                return i;
        for (i = 0; i < 32 ; i++)
                target->thread.TS_FPR(i) = buf[i];
-       memcpy(&target->thread.fpscr, &buf[32], sizeof(double));
+       target->thread.fp_state.fpscr = buf[32];
        return 0;
 #else
-       BUILD_BUG_ON(offsetof(struct thread_struct, fpscr) !=
-                    offsetof(struct thread_struct, TS_FPR(32)));
+       BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) !=
+                    offsetof(struct thread_fp_state, fpr[32][0]));
 
        return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-                                 &target->thread.fpr, 0, -1);
+                                 &target->thread.fp_state, 0, -1);
 #endif
 }
 
@@ -440,11 +440,11 @@ static int vr_get(struct task_struct *target, const struct user_regset *regset,
 
        flush_altivec_to_thread(target);
 
-       BUILD_BUG_ON(offsetof(struct thread_struct, vscr) !=
-                    offsetof(struct thread_struct, vr[32]));
+       BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
+                    offsetof(struct thread_vr_state, vr[32]));
 
        ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                 &target->thread.vr, 0,
+                                 &target->thread.vr_state, 0,
                                  33 * sizeof(vector128));
        if (!ret) {
                /*
@@ -471,11 +471,12 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset,
 
        flush_altivec_to_thread(target);
 
-       BUILD_BUG_ON(offsetof(struct thread_struct, vscr) !=
-                    offsetof(struct thread_struct, vr[32]));
+       BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
+                    offsetof(struct thread_vr_state, vr[32]));
 
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-                                &target->thread.vr, 0, 33 * sizeof(vector128));
+                                &target->thread.vr_state, 0,
+                                33 * sizeof(vector128));
        if (!ret && count > 0) {
                /*
                 * We use only the first word of vrsave.
@@ -514,13 +515,13 @@ static int vsr_get(struct task_struct *target, const struct user_regset *regset,
                   unsigned int pos, unsigned int count,
                   void *kbuf, void __user *ubuf)
 {
-       double buf[32];
+       u64 buf[32];
        int ret, i;
 
        flush_vsx_to_thread(target);
 
        for (i = 0; i < 32 ; i++)
-               buf[i] = target->thread.fpr[i][TS_VSRLOWOFFSET];
+               buf[i] = target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
        ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
                                  buf, 0, 32 * sizeof(double));
 
@@ -531,7 +532,7 @@ static int vsr_set(struct task_struct *target, const struct user_regset *regset,
                   unsigned int pos, unsigned int count,
                   const void *kbuf, const void __user *ubuf)
 {
-       double buf[32];
+       u64 buf[32];
        int ret,i;
 
        flush_vsx_to_thread(target);
@@ -539,7 +540,7 @@ static int vsr_set(struct task_struct *target, const struct user_regset *regset,
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                 buf, 0, 32 * sizeof(double));
        for (i = 0; i < 32 ; i++)
-               target->thread.fpr[i][TS_VSRLOWOFFSET] = buf[i];
+               target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
 
 
        return ret;
@@ -657,7 +658,7 @@ static const struct user_regset native_regsets[] = {
 #endif
 #ifdef CONFIG_SPE
        [REGSET_SPE] = {
-               .n = 35,
+               .core_note_type = NT_PPC_SPE, .n = 35,
                .size = sizeof(u32), .align = sizeof(u32),
                .active = evr_active, .get = evr_get, .set = evr_set
        },
@@ -854,8 +855,8 @@ void user_enable_single_step(struct task_struct *task)
 
        if (regs != NULL) {
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
-               task->thread.dbcr0 &= ~DBCR0_BT;
-               task->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC;
+               task->thread.debug.dbcr0 &= ~DBCR0_BT;
+               task->thread.debug.dbcr0 |= DBCR0_IDM | DBCR0_IC;
                regs->msr |= MSR_DE;
 #else
                regs->msr &= ~MSR_BE;
@@ -871,8 +872,8 @@ void user_enable_block_step(struct task_struct *task)
 
        if (regs != NULL) {
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
-               task->thread.dbcr0 &= ~DBCR0_IC;
-               task->thread.dbcr0 = DBCR0_IDM | DBCR0_BT;
+               task->thread.debug.dbcr0 &= ~DBCR0_IC;
+               task->thread.debug.dbcr0 = DBCR0_IDM | DBCR0_BT;
                regs->msr |= MSR_DE;
 #else
                regs->msr &= ~MSR_SE;
@@ -894,16 +895,16 @@ void user_disable_single_step(struct task_struct *task)
                 * And, after doing so, if all debug flags are off, turn
                 * off DBCR0(IDM) and MSR(DE) .... Torez
                 */
-               task->thread.dbcr0 &= ~DBCR0_IC;
+               task->thread.debug.dbcr0 &= ~(DBCR0_IC|DBCR0_BT);
                /*
                 * Test to see if any of the DBCR_ACTIVE_EVENTS bits are set.
                 */
-               if (!DBCR_ACTIVE_EVENTS(task->thread.dbcr0,
-                                       task->thread.dbcr1)) {
+               if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0,
+                                       task->thread.debug.dbcr1)) {
                        /*
                         * All debug events were off.....
                         */
-                       task->thread.dbcr0 &= ~DBCR0_IDM;
+                       task->thread.debug.dbcr0 &= ~DBCR0_IDM;
                        regs->msr &= ~MSR_DE;
                }
 #else
@@ -1022,14 +1023,14 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
         */
 
        /* DAC's hold the whole address without any mode flags */
-       task->thread.dac1 = data & ~0x3UL;
+       task->thread.debug.dac1 = data & ~0x3UL;
 
-       if (task->thread.dac1 == 0) {
+       if (task->thread.debug.dac1 == 0) {
                dbcr_dac(task) &= ~(DBCR_DAC1R | DBCR_DAC1W);
-               if (!DBCR_ACTIVE_EVENTS(task->thread.dbcr0,
-                                       task->thread.dbcr1)) {
+               if (!DBCR_ACTIVE_EVENTS(task->thread.debug.dbcr0,
+                                       task->thread.debug.dbcr1)) {
                        task->thread.regs->msr &= ~MSR_DE;
-                       task->thread.dbcr0 &= ~DBCR0_IDM;
+                       task->thread.debug.dbcr0 &= ~DBCR0_IDM;
                }
                return 0;
        }
@@ -1041,7 +1042,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
 
        /* Set the Internal Debugging flag (IDM bit 1) for the DBCR0
           register */
-       task->thread.dbcr0 |= DBCR0_IDM;
+       task->thread.debug.dbcr0 |= DBCR0_IDM;
 
        /* Check for write and read flags and set DBCR0
           accordingly */
@@ -1071,10 +1072,10 @@ static long set_instruction_bp(struct task_struct *child,
                              struct ppc_hw_breakpoint *bp_info)
 {
        int slot;
-       int slot1_in_use = ((child->thread.dbcr0 & DBCR0_IAC1) != 0);
-       int slot2_in_use = ((child->thread.dbcr0 & DBCR0_IAC2) != 0);
-       int slot3_in_use = ((child->thread.dbcr0 & DBCR0_IAC3) != 0);
-       int slot4_in_use = ((child->thread.dbcr0 & DBCR0_IAC4) != 0);
+       int slot1_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC1) != 0);
+       int slot2_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC2) != 0);
+       int slot3_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC3) != 0);
+       int slot4_in_use = ((child->thread.debug.dbcr0 & DBCR0_IAC4) != 0);
 
        if (dbcr_iac_range(child) & DBCR_IAC12MODE)
                slot2_in_use = 1;
@@ -1093,9 +1094,9 @@ static long set_instruction_bp(struct task_struct *child,
                /* We need a pair of IAC regsisters */
                if ((!slot1_in_use) && (!slot2_in_use)) {
                        slot = 1;
-                       child->thread.iac1 = bp_info->addr;
-                       child->thread.iac2 = bp_info->addr2;
-                       child->thread.dbcr0 |= DBCR0_IAC1;
+                       child->thread.debug.iac1 = bp_info->addr;
+                       child->thread.debug.iac2 = bp_info->addr2;
+                       child->thread.debug.dbcr0 |= DBCR0_IAC1;
                        if (bp_info->addr_mode ==
                                        PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
                                dbcr_iac_range(child) |= DBCR_IAC12X;
@@ -1104,9 +1105,9 @@ static long set_instruction_bp(struct task_struct *child,
 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
                } else if ((!slot3_in_use) && (!slot4_in_use)) {
                        slot = 3;
-                       child->thread.iac3 = bp_info->addr;
-                       child->thread.iac4 = bp_info->addr2;
-                       child->thread.dbcr0 |= DBCR0_IAC3;
+                       child->thread.debug.iac3 = bp_info->addr;
+                       child->thread.debug.iac4 = bp_info->addr2;
+                       child->thread.debug.dbcr0 |= DBCR0_IAC3;
                        if (bp_info->addr_mode ==
                                        PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
                                dbcr_iac_range(child) |= DBCR_IAC34X;
@@ -1126,30 +1127,30 @@ static long set_instruction_bp(struct task_struct *child,
                         */
                        if (slot2_in_use || (slot3_in_use == slot4_in_use)) {
                                slot = 1;
-                               child->thread.iac1 = bp_info->addr;
-                               child->thread.dbcr0 |= DBCR0_IAC1;
+                               child->thread.debug.iac1 = bp_info->addr;
+                               child->thread.debug.dbcr0 |= DBCR0_IAC1;
                                goto out;
                        }
                }
                if (!slot2_in_use) {
                        slot = 2;
-                       child->thread.iac2 = bp_info->addr;
-                       child->thread.dbcr0 |= DBCR0_IAC2;
+                       child->thread.debug.iac2 = bp_info->addr;
+                       child->thread.debug.dbcr0 |= DBCR0_IAC2;
 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
                } else if (!slot3_in_use) {
                        slot = 3;
-                       child->thread.iac3 = bp_info->addr;
-                       child->thread.dbcr0 |= DBCR0_IAC3;
+                       child->thread.debug.iac3 = bp_info->addr;
+                       child->thread.debug.dbcr0 |= DBCR0_IAC3;
                } else if (!slot4_in_use) {
                        slot = 4;
-                       child->thread.iac4 = bp_info->addr;
-                       child->thread.dbcr0 |= DBCR0_IAC4;
+                       child->thread.debug.iac4 = bp_info->addr;
+                       child->thread.debug.dbcr0 |= DBCR0_IAC4;
 #endif
                } else
                        return -ENOSPC;
        }
 out:
-       child->thread.dbcr0 |= DBCR0_IDM;
+       child->thread.debug.dbcr0 |= DBCR0_IDM;
        child->thread.regs->msr |= MSR_DE;
 
        return slot;
@@ -1159,49 +1160,49 @@ static int del_instruction_bp(struct task_struct *child, int slot)
 {
        switch (slot) {
        case 1:
-               if ((child->thread.dbcr0 & DBCR0_IAC1) == 0)
+               if ((child->thread.debug.dbcr0 & DBCR0_IAC1) == 0)
                        return -ENOENT;
 
                if (dbcr_iac_range(child) & DBCR_IAC12MODE) {
                        /* address range - clear slots 1 & 2 */
-                       child->thread.iac2 = 0;
+                       child->thread.debug.iac2 = 0;
                        dbcr_iac_range(child) &= ~DBCR_IAC12MODE;
                }
-               child->thread.iac1 = 0;
-               child->thread.dbcr0 &= ~DBCR0_IAC1;
+               child->thread.debug.iac1 = 0;
+               child->thread.debug.dbcr0 &= ~DBCR0_IAC1;
                break;
        case 2:
-               if ((child->thread.dbcr0 & DBCR0_IAC2) == 0)
+               if ((child->thread.debug.dbcr0 & DBCR0_IAC2) == 0)
                        return -ENOENT;
 
                if (dbcr_iac_range(child) & DBCR_IAC12MODE)
                        /* used in a range */
                        return -EINVAL;
-               child->thread.iac2 = 0;
-               child->thread.dbcr0 &= ~DBCR0_IAC2;
+               child->thread.debug.iac2 = 0;
+               child->thread.debug.dbcr0 &= ~DBCR0_IAC2;
                break;
 #if CONFIG_PPC_ADV_DEBUG_IACS > 2
        case 3:
-               if ((child->thread.dbcr0 & DBCR0_IAC3) == 0)
+               if ((child->thread.debug.dbcr0 & DBCR0_IAC3) == 0)
                        return -ENOENT;
 
                if (dbcr_iac_range(child) & DBCR_IAC34MODE) {
                        /* address range - clear slots 3 & 4 */
-                       child->thread.iac4 = 0;
+                       child->thread.debug.iac4 = 0;
                        dbcr_iac_range(child) &= ~DBCR_IAC34MODE;
                }
-               child->thread.iac3 = 0;
-               child->thread.dbcr0 &= ~DBCR0_IAC3;
+               child->thread.debug.iac3 = 0;
+               child->thread.debug.dbcr0 &= ~DBCR0_IAC3;
                break;
        case 4:
-               if ((child->thread.dbcr0 & DBCR0_IAC4) == 0)
+               if ((child->thread.debug.dbcr0 & DBCR0_IAC4) == 0)
                        return -ENOENT;
 
                if (dbcr_iac_range(child) & DBCR_IAC34MODE)
                        /* Used in a range */
                        return -EINVAL;
-               child->thread.iac4 = 0;
-               child->thread.dbcr0 &= ~DBCR0_IAC4;
+               child->thread.debug.iac4 = 0;
+               child->thread.debug.dbcr0 &= ~DBCR0_IAC4;
                break;
 #endif
        default:
@@ -1231,18 +1232,18 @@ static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info)
                        dbcr_dac(child) |= DBCR_DAC1R;
                if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
                        dbcr_dac(child) |= DBCR_DAC1W;
-               child->thread.dac1 = (unsigned long)bp_info->addr;
+               child->thread.debug.dac1 = (unsigned long)bp_info->addr;
 #if CONFIG_PPC_ADV_DEBUG_DVCS > 0
                if (byte_enable) {
-                       child->thread.dvc1 =
+                       child->thread.debug.dvc1 =
                                (unsigned long)bp_info->condition_value;
-                       child->thread.dbcr2 |=
+                       child->thread.debug.dbcr2 |=
                                ((byte_enable << DBCR2_DVC1BE_SHIFT) |
                                 (condition_mode << DBCR2_DVC1M_SHIFT));
                }
 #endif
 #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
-       } else if (child->thread.dbcr2 & DBCR2_DAC12MODE) {
+       } else if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) {
                /* Both dac1 and dac2 are part of a range */
                return -ENOSPC;
 #endif
@@ -1252,19 +1253,19 @@ static int set_dac(struct task_struct *child, struct ppc_hw_breakpoint *bp_info)
                        dbcr_dac(child) |= DBCR_DAC2R;
                if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
                        dbcr_dac(child) |= DBCR_DAC2W;
-               child->thread.dac2 = (unsigned long)bp_info->addr;
+               child->thread.debug.dac2 = (unsigned long)bp_info->addr;
 #if CONFIG_PPC_ADV_DEBUG_DVCS > 0
                if (byte_enable) {
-                       child->thread.dvc2 =
+                       child->thread.debug.dvc2 =
                                (unsigned long)bp_info->condition_value;
-                       child->thread.dbcr2 |=
+                       child->thread.debug.dbcr2 |=
                                ((byte_enable << DBCR2_DVC2BE_SHIFT) |
                                 (condition_mode << DBCR2_DVC2M_SHIFT));
                }
 #endif
        } else
                return -ENOSPC;
-       child->thread.dbcr0 |= DBCR0_IDM;
+       child->thread.debug.dbcr0 |= DBCR0_IDM;
        child->thread.regs->msr |= MSR_DE;
 
        return slot + 4;
@@ -1276,32 +1277,32 @@ static int del_dac(struct task_struct *child, int slot)
                if ((dbcr_dac(child) & (DBCR_DAC1R | DBCR_DAC1W)) == 0)
                        return -ENOENT;
 
-               child->thread.dac1 = 0;
+               child->thread.debug.dac1 = 0;
                dbcr_dac(child) &= ~(DBCR_DAC1R | DBCR_DAC1W);
 #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
-               if (child->thread.dbcr2 & DBCR2_DAC12MODE) {
-                       child->thread.dac2 = 0;
-                       child->thread.dbcr2 &= ~DBCR2_DAC12MODE;
+               if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE) {
+                       child->thread.debug.dac2 = 0;
+                       child->thread.debug.dbcr2 &= ~DBCR2_DAC12MODE;
                }
-               child->thread.dbcr2 &= ~(DBCR2_DVC1M | DBCR2_DVC1BE);
+               child->thread.debug.dbcr2 &= ~(DBCR2_DVC1M | DBCR2_DVC1BE);
 #endif
 #if CONFIG_PPC_ADV_DEBUG_DVCS > 0
-               child->thread.dvc1 = 0;
+               child->thread.debug.dvc1 = 0;
 #endif
        } else if (slot == 2) {
                if ((dbcr_dac(child) & (DBCR_DAC2R | DBCR_DAC2W)) == 0)
                        return -ENOENT;
 
 #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
-               if (child->thread.dbcr2 & DBCR2_DAC12MODE)
+               if (child->thread.debug.dbcr2 & DBCR2_DAC12MODE)
                        /* Part of a range */
                        return -EINVAL;
-               child->thread.dbcr2 &= ~(DBCR2_DVC2M | DBCR2_DVC2BE);
+               child->thread.debug.dbcr2 &= ~(DBCR2_DVC2M | DBCR2_DVC2BE);
 #endif
 #if CONFIG_PPC_ADV_DEBUG_DVCS > 0
-               child->thread.dvc2 = 0;
+               child->thread.debug.dvc2 = 0;
 #endif
-               child->thread.dac2 = 0;
+               child->thread.debug.dac2 = 0;
                dbcr_dac(child) &= ~(DBCR_DAC2R | DBCR_DAC2W);
        } else
                return -EINVAL;
@@ -1343,22 +1344,22 @@ static int set_dac_range(struct task_struct *child,
                        return -EIO;
        }
 
-       if (child->thread.dbcr0 &
+       if (child->thread.debug.dbcr0 &
            (DBCR0_DAC1R | DBCR0_DAC1W | DBCR0_DAC2R | DBCR0_DAC2W))
                return -ENOSPC;
 
        if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
-               child->thread.dbcr0 |= (DBCR0_DAC1R | DBCR0_IDM);
+               child->thread.debug.dbcr0 |= (DBCR0_DAC1R | DBCR0_IDM);
        if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
-               child->thread.dbcr0 |= (DBCR0_DAC1W | DBCR0_IDM);
-       child->thread.dac1 = bp_info->addr;
-       child->thread.dac2 = bp_info->addr2;
+               child->thread.debug.dbcr0 |= (DBCR0_DAC1W | DBCR0_IDM);
+       child->thread.debug.dac1 = bp_info->addr;
+       child->thread.debug.dac2 = bp_info->addr2;
        if (mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE)
-               child->thread.dbcr2  |= DBCR2_DAC12M;
+               child->thread.debug.dbcr2  |= DBCR2_DAC12M;
        else if (mode == PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE)
-               child->thread.dbcr2  |= DBCR2_DAC12MX;
+               child->thread.debug.dbcr2  |= DBCR2_DAC12MX;
        else    /* PPC_BREAKPOINT_MODE_MASK */
-               child->thread.dbcr2  |= DBCR2_DAC12MM;
+               child->thread.debug.dbcr2  |= DBCR2_DAC12MM;
        child->thread.regs->msr |= MSR_DE;
 
        return 5;
@@ -1489,9 +1490,9 @@ static long ppc_del_hwdebug(struct task_struct *child, long data)
                rc = del_dac(child, (int)data - 4);
 
        if (!rc) {
-               if (!DBCR_ACTIVE_EVENTS(child->thread.dbcr0,
-                                       child->thread.dbcr1)) {
-                       child->thread.dbcr0 &= ~DBCR0_IDM;
+               if (!DBCR_ACTIVE_EVENTS(child->thread.debug.dbcr0,
+                                       child->thread.debug.dbcr1)) {
+                       child->thread.debug.dbcr0 &= ~DBCR0_IDM;
                        child->thread.regs->msr &= ~MSR_DE;
                }
        }
@@ -1554,10 +1555,10 @@ long arch_ptrace(struct task_struct *child, long request,
 
                        flush_fp_to_thread(child);
                        if (fpidx < (PT_FPSCR - PT_FPR0))
-                               tmp = ((unsigned long *)child->thread.fpr)
-                                       [fpidx * TS_FPRWIDTH];
+                               memcpy(&tmp, &child->thread.fp_state.fpr,
+                                      sizeof(long));
                        else
-                               tmp = child->thread.fpscr.val;
+                               tmp = child->thread.fp_state.fpscr;
                }
                ret = put_user(tmp, datalp);
                break;
@@ -1587,10 +1588,10 @@ long arch_ptrace(struct task_struct *child, long request,
 
                        flush_fp_to_thread(child);
                        if (fpidx < (PT_FPSCR - PT_FPR0))
-                               ((unsigned long *)child->thread.fpr)
-                                       [fpidx * TS_FPRWIDTH] = data;
+                               memcpy(&child->thread.fp_state.fpr, &data,
+                                      sizeof(long));
                        else
-                               child->thread.fpscr.val = data;
+                               child->thread.fp_state.fpscr = data;
                        ret = 0;
                }
                break;
@@ -1669,7 +1670,7 @@ long arch_ptrace(struct task_struct *child, long request,
                if (addr > 0)
                        break;
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
-               ret = put_user(child->thread.dac1, datalp);
+               ret = put_user(child->thread.debug.dac1, datalp);
 #else
                dabr_fake = ((child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) |
                             (child->thread.hw_brk.type & HW_BRK_TYPE_DABR));
index f51599e941c7661b281a5130570b2f5e9d701ec3..f52b7db327c80a3b603fb2a7179a2f97d6a054be 100644 (file)
@@ -43,7 +43,6 @@
 #define FPRNUMBER(i) (((i) - PT_FPR0) >> 1)
 #define FPRHALF(i) (((i) - PT_FPR0) & 1)
 #define FPRINDEX(i) TS_FPRWIDTH * FPRNUMBER(i) * 2 + FPRHALF(i)
-#define FPRINDEX_3264(i) (TS_FPRWIDTH * ((i) - PT_FPR0))
 
 long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                        compat_ulong_t caddr, compat_ulong_t cdata)
@@ -105,7 +104,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                         * to be an array of unsigned int (32 bits) - the
                         * index passed in is based on this assumption.
                         */
-                       tmp = ((unsigned int *)child->thread.fpr)
+                       tmp = ((unsigned int *)child->thread.fp_state.fpr)
                                [FPRINDEX(index)];
                }
                ret = put_user((unsigned int)tmp, (u32 __user *)data);
@@ -147,8 +146,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                if (numReg >= PT_FPR0) {
                        flush_fp_to_thread(child);
                        /* get 64 bit FPR */
-                       tmp = ((u64 *)child->thread.fpr)
-                               [FPRINDEX_3264(numReg)];
+                       tmp = child->thread.fp_state.fpr[numReg - PT_FPR0][0];
                } else { /* register within PT_REGS struct */
                        unsigned long tmp2;
                        ret = ptrace_get_reg(child, numReg, &tmp2);
@@ -207,7 +205,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                         * to be an array of unsigned int (32 bits) - the
                         * index passed in is based on this assumption.
                         */
-                       ((unsigned int *)child->thread.fpr)
+                       ((unsigned int *)child->thread.fp_state.fpr)
                                [FPRINDEX(index)] = data;
                        ret = 0;
                }
@@ -251,8 +249,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                        u64 *tmp;
                        flush_fp_to_thread(child);
                        /* get 64 bit FPR ... */
-                       tmp = &(((u64 *)child->thread.fpr)
-                               [FPRINDEX_3264(numReg)]);
+                       tmp = &child->thread.fp_state.fpr[numReg - PT_FPR0][0];
                        /* ... write the 32 bit part we want */
                        ((u32 *)tmp)[index % 2] = data;
                        ret = 0;
@@ -269,7 +266,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                if (addr > 0)
                        break;
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
-               ret = put_user(child->thread.dac1, (u32 __user *)data);
+               ret = put_user(child->thread.debug.dac1, (u32 __user *)data);
 #else
                dabr_fake = (
                        (child->thread.hw_brk.address & (~HW_BRK_TYPE_DABR)) |
index 6e7b7cdeec6541135dad27df9f23bf64ac16395b..7d4c7172f38ed43d85873c23f5b1e63e733ea093 100644 (file)
@@ -223,7 +223,7 @@ unsigned long get_phb_buid(struct device_node *phb)
 static int phb_set_bus_ranges(struct device_node *dev,
                              struct pci_controller *phb)
 {
-       const int *bus_range;
+       const __be32 *bus_range;
        unsigned int len;
 
        bus_range = of_get_property(dev, "bus-range", &len);
@@ -231,8 +231,8 @@ static int phb_set_bus_ranges(struct device_node *dev,
                return 1;
        }
 
-       phb->first_busno =  bus_range[0];
-       phb->last_busno  =  bus_range[1];
+       phb->first_busno = be32_to_cpu(bus_range[0]);
+       phb->last_busno  = be32_to_cpu(bus_range[1]);
 
        return 0;
 }
index 3d261c071fc88b9ed7a1ac7de43c7587d5a9b60e..febc80445d25850acf2578943c60357d8436b1c2 100644 (file)
@@ -62,8 +62,6 @@
 #include <mm/mmu_decl.h>
 #include <asm/fadump.h>
 
-#include "setup.h"
-
 #ifdef DEBUG
 #include <asm/udbg.h>
 #define DBG(fmt...) udbg_printf(fmt)
diff --git a/arch/powerpc/kernel/setup.h b/arch/powerpc/kernel/setup.h
deleted file mode 100644 (file)
index 4c67ad7..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _POWERPC_KERNEL_SETUP_H
-#define _POWERPC_KERNEL_SETUP_H
-
-void check_for_initrd(void);
-void do_init_bootmem(void);
-void setup_panic(void);
-extern int do_early_xmon;
-
-#endif /* _POWERPC_KERNEL_SETUP_H */
index a4bbcae72578617688f510d05aaed2883aef7c10..b903dc5cf944aee99fc36629fdb974f3e26b6888 100644 (file)
@@ -40,8 +40,6 @@
 #include <asm/mmu_context.h>
 #include <asm/epapr_hcalls.h>
 
-#include "setup.h"
-
 #define DBG(fmt...)
 
 extern void bootx_init(unsigned long r4, unsigned long phys);
index 278ca93e1f283464cc8f378b6c55c60f08b25220..4085aaa9478fd90eff1f1ce149d661bc7488284f 100644 (file)
@@ -68,8 +68,6 @@
 #include <asm/hugetlb.h>
 #include <asm/epapr_hcalls.h>
 
-#include "setup.h"
-
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
 #else
index bebdf1a1a5403df741ea389102f1b69b80daf60e..1a410aa57fb7615b5f683713a15e3614e61e2c6e 100644 (file)
@@ -265,27 +265,27 @@ struct rt_sigframe {
 unsigned long copy_fpr_to_user(void __user *to,
                               struct task_struct *task)
 {
-       double buf[ELF_NFPREG];
+       u64 buf[ELF_NFPREG];
        int i;
 
        /* save FPR copy to local buffer then write to the thread_struct */
        for (i = 0; i < (ELF_NFPREG - 1) ; i++)
                buf[i] = task->thread.TS_FPR(i);
-       memcpy(&buf[i], &task->thread.fpscr, sizeof(double));
+       buf[i] = task->thread.fp_state.fpscr;
        return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
 }
 
 unsigned long copy_fpr_from_user(struct task_struct *task,
                                 void __user *from)
 {
-       double buf[ELF_NFPREG];
+       u64 buf[ELF_NFPREG];
        int i;
 
        if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
                return 1;
        for (i = 0; i < (ELF_NFPREG - 1) ; i++)
                task->thread.TS_FPR(i) = buf[i];
-       memcpy(&task->thread.fpscr, &buf[i], sizeof(double));
+       task->thread.fp_state.fpscr = buf[i];
 
        return 0;
 }
@@ -293,25 +293,25 @@ unsigned long copy_fpr_from_user(struct task_struct *task,
 unsigned long copy_vsx_to_user(void __user *to,
                               struct task_struct *task)
 {
-       double buf[ELF_NVSRHALFREG];
+       u64 buf[ELF_NVSRHALFREG];
        int i;
 
        /* save FPR copy to local buffer then write to the thread_struct */
        for (i = 0; i < ELF_NVSRHALFREG; i++)
-               buf[i] = task->thread.fpr[i][TS_VSRLOWOFFSET];
+               buf[i] = task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
        return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
 }
 
 unsigned long copy_vsx_from_user(struct task_struct *task,
                                 void __user *from)
 {
-       double buf[ELF_NVSRHALFREG];
+       u64 buf[ELF_NVSRHALFREG];
        int i;
 
        if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
                return 1;
        for (i = 0; i < ELF_NVSRHALFREG ; i++)
-               task->thread.fpr[i][TS_VSRLOWOFFSET] = buf[i];
+               task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
        return 0;
 }
 
@@ -319,27 +319,27 @@ unsigned long copy_vsx_from_user(struct task_struct *task,
 unsigned long copy_transact_fpr_to_user(void __user *to,
                                  struct task_struct *task)
 {
-       double buf[ELF_NFPREG];
+       u64 buf[ELF_NFPREG];
        int i;
 
        /* save FPR copy to local buffer then write to the thread_struct */
        for (i = 0; i < (ELF_NFPREG - 1) ; i++)
                buf[i] = task->thread.TS_TRANS_FPR(i);
-       memcpy(&buf[i], &task->thread.transact_fpscr, sizeof(double));
+       buf[i] = task->thread.transact_fp.fpscr;
        return __copy_to_user(to, buf, ELF_NFPREG * sizeof(double));
 }
 
 unsigned long copy_transact_fpr_from_user(struct task_struct *task,
                                          void __user *from)
 {
-       double buf[ELF_NFPREG];
+       u64 buf[ELF_NFPREG];
        int i;
 
        if (__copy_from_user(buf, from, ELF_NFPREG * sizeof(double)))
                return 1;
        for (i = 0; i < (ELF_NFPREG - 1) ; i++)
                task->thread.TS_TRANS_FPR(i) = buf[i];
-       memcpy(&task->thread.transact_fpscr, &buf[i], sizeof(double));
+       task->thread.transact_fp.fpscr = buf[i];
 
        return 0;
 }
@@ -347,25 +347,25 @@ unsigned long copy_transact_fpr_from_user(struct task_struct *task,
 unsigned long copy_transact_vsx_to_user(void __user *to,
                                  struct task_struct *task)
 {
-       double buf[ELF_NVSRHALFREG];
+       u64 buf[ELF_NVSRHALFREG];
        int i;
 
        /* save FPR copy to local buffer then write to the thread_struct */
        for (i = 0; i < ELF_NVSRHALFREG; i++)
-               buf[i] = task->thread.transact_fpr[i][TS_VSRLOWOFFSET];
+               buf[i] = task->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET];
        return __copy_to_user(to, buf, ELF_NVSRHALFREG * sizeof(double));
 }
 
 unsigned long copy_transact_vsx_from_user(struct task_struct *task,
                                          void __user *from)
 {
-       double buf[ELF_NVSRHALFREG];
+       u64 buf[ELF_NVSRHALFREG];
        int i;
 
        if (__copy_from_user(buf, from, ELF_NVSRHALFREG * sizeof(double)))
                return 1;
        for (i = 0; i < ELF_NVSRHALFREG ; i++)
-               task->thread.transact_fpr[i][TS_VSRLOWOFFSET] = buf[i];
+               task->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET] = buf[i];
        return 0;
 }
 #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
@@ -373,14 +373,14 @@ unsigned long copy_transact_vsx_from_user(struct task_struct *task,
 inline unsigned long copy_fpr_to_user(void __user *to,
                                      struct task_struct *task)
 {
-       return __copy_to_user(to, task->thread.fpr,
+       return __copy_to_user(to, task->thread.fp_state.fpr,
                              ELF_NFPREG * sizeof(double));
 }
 
 inline unsigned long copy_fpr_from_user(struct task_struct *task,
                                        void __user *from)
 {
-       return __copy_from_user(task->thread.fpr, from,
+       return __copy_from_user(task->thread.fp_state.fpr, from,
                              ELF_NFPREG * sizeof(double));
 }
 
@@ -388,14 +388,14 @@ inline unsigned long copy_fpr_from_user(struct task_struct *task,
 inline unsigned long copy_transact_fpr_to_user(void __user *to,
                                         struct task_struct *task)
 {
-       return __copy_to_user(to, task->thread.transact_fpr,
+       return __copy_to_user(to, task->thread.transact_fp.fpr,
                              ELF_NFPREG * sizeof(double));
 }
 
 inline unsigned long copy_transact_fpr_from_user(struct task_struct *task,
                                                 void __user *from)
 {
-       return __copy_from_user(task->thread.transact_fpr, from,
+       return __copy_from_user(task->thread.transact_fp.fpr, from,
                                ELF_NFPREG * sizeof(double));
 }
 #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
@@ -423,7 +423,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
        /* save altivec registers */
        if (current->thread.used_vr) {
                flush_altivec_to_thread(current);
-               if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
+               if (__copy_to_user(&frame->mc_vregs, &current->thread.vr_state,
                                   ELF_NVRREG * sizeof(vector128)))
                        return 1;
                /* set MSR_VEC in the saved MSR value to indicate that
@@ -534,17 +534,17 @@ static int save_tm_user_regs(struct pt_regs *regs,
        /* save altivec registers */
        if (current->thread.used_vr) {
                flush_altivec_to_thread(current);
-               if (__copy_to_user(&frame->mc_vregs, current->thread.vr,
+               if (__copy_to_user(&frame->mc_vregs, &current->thread.vr_state,
                                   ELF_NVRREG * sizeof(vector128)))
                        return 1;
                if (msr & MSR_VEC) {
                        if (__copy_to_user(&tm_frame->mc_vregs,
-                                          current->thread.transact_vr,
+                                          &current->thread.transact_vr,
                                           ELF_NVRREG * sizeof(vector128)))
                                return 1;
                } else {
                        if (__copy_to_user(&tm_frame->mc_vregs,
-                                          current->thread.vr,
+                                          &current->thread.vr_state,
                                           ELF_NVRREG * sizeof(vector128)))
                                return 1;
                }
@@ -692,11 +692,12 @@ static long restore_user_regs(struct pt_regs *regs,
        regs->msr &= ~MSR_VEC;
        if (msr & MSR_VEC) {
                /* restore altivec registers from the stack */
-               if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
+               if (__copy_from_user(&current->thread.vr_state, &sr->mc_vregs,
                                     sizeof(sr->mc_vregs)))
                        return 1;
        } else if (current->thread.used_vr)
-               memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128));
+               memset(&current->thread.vr_state, 0,
+                      ELF_NVRREG * sizeof(vector128));
 
        /* Always get VRSAVE back */
        if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32]))
@@ -722,7 +723,7 @@ static long restore_user_regs(struct pt_regs *regs,
                        return 1;
        } else if (current->thread.used_vsr)
                for (i = 0; i < 32 ; i++)
-                       current->thread.fpr[i][TS_VSRLOWOFFSET] = 0;
+                       current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
 #endif /* CONFIG_VSX */
        /*
         * force the process to reload the FP registers from
@@ -798,15 +799,16 @@ static long restore_tm_user_regs(struct pt_regs *regs,
        regs->msr &= ~MSR_VEC;
        if (msr & MSR_VEC) {
                /* restore altivec registers from the stack */
-               if (__copy_from_user(current->thread.vr, &sr->mc_vregs,
+               if (__copy_from_user(&current->thread.vr_state, &sr->mc_vregs,
                                     sizeof(sr->mc_vregs)) ||
-                   __copy_from_user(current->thread.transact_vr,
+                   __copy_from_user(&current->thread.transact_vr,
                                     &tm_sr->mc_vregs,
                                     sizeof(sr->mc_vregs)))
                        return 1;
        } else if (current->thread.used_vr) {
-               memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128));
-               memset(current->thread.transact_vr, 0,
+               memset(&current->thread.vr_state, 0,
+                      ELF_NVRREG * sizeof(vector128));
+               memset(&current->thread.transact_vr, 0,
                       ELF_NVRREG * sizeof(vector128));
        }
 
@@ -838,8 +840,8 @@ static long restore_tm_user_regs(struct pt_regs *regs,
                        return 1;
        } else if (current->thread.used_vsr)
                for (i = 0; i < 32 ; i++) {
-                       current->thread.fpr[i][TS_VSRLOWOFFSET] = 0;
-                       current->thread.transact_fpr[i][TS_VSRLOWOFFSET] = 0;
+                       current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
+                       current->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET] = 0;
                }
 #endif /* CONFIG_VSX */
 
@@ -1030,7 +1032,7 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
                if (__put_user(0, &rt_sf->uc.uc_link))
                        goto badframe;
 
-       current->thread.fpscr.val = 0;  /* turn off all fp exceptions */
+       current->thread.fp_state.fpscr = 0;     /* turn off all fp exceptions */
 
        /* create a stack frame for the caller of the handler */
        newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16);
@@ -1045,8 +1047,9 @@ int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka,
        regs->gpr[5] = (unsigned long) &rt_sf->uc;
        regs->gpr[6] = (unsigned long) rt_sf;
        regs->nip = (unsigned long) ka->sa.sa_handler;
-       /* enter the signal handler in big-endian mode */
+       /* enter the signal handler in native-endian mode */
        regs->msr &= ~MSR_LE;
+       regs->msr |= (MSR_KERNEL & MSR_LE);
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
        /* Remove TM bits from thread's MSR.  The MSR in the sigcontext
         * just indicates to userland that we were doing a transaction, but we
@@ -1309,7 +1312,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
        unsigned char tmp;
        unsigned long new_msr = regs->msr;
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
-       unsigned long new_dbcr0 = current->thread.dbcr0;
+       unsigned long new_dbcr0 = current->thread.debug.dbcr0;
 #endif
 
        for (i=0; i<ndbg; i++) {
@@ -1324,7 +1327,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
                        } else {
                                new_dbcr0 &= ~DBCR0_IC;
                                if (!DBCR_ACTIVE_EVENTS(new_dbcr0,
-                                               current->thread.dbcr1)) {
+                                               current->thread.debug.dbcr1)) {
                                        new_msr &= ~MSR_DE;
                                        new_dbcr0 &= ~DBCR0_IDM;
                                }
@@ -1359,7 +1362,7 @@ int sys_debug_setcontext(struct ucontext __user *ctx,
           the user is really doing something wrong. */
        regs->msr = new_msr;
 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
-       current->thread.dbcr0 = new_dbcr0;
+       current->thread.debug.dbcr0 = new_dbcr0;
 #endif
 
        if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx))
@@ -1462,7 +1465,7 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka,
 
        regs->link = tramp;
 
-       current->thread.fpscr.val = 0;  /* turn off all fp exceptions */
+       current->thread.fp_state.fpscr = 0;     /* turn off all fp exceptions */
 
        /* create a stack frame for the caller of the handler */
        newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
index f93ec2835a13f01294a9b3d5c225686a04666702..b3c615764c9b97bcb510d017bd9c8ff33e6d69ec 100644 (file)
@@ -103,7 +103,8 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
        if (current->thread.used_vr) {
                flush_altivec_to_thread(current);
                /* Copy 33 vec registers (vr0..31 and vscr) to the stack */
-               err |= __copy_to_user(v_regs, current->thread.vr, 33 * sizeof(vector128));
+               err |= __copy_to_user(v_regs, &current->thread.vr_state,
+                                     33 * sizeof(vector128));
                /* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg)
                 * contains valid data.
                 */
@@ -195,18 +196,18 @@ static long setup_tm_sigcontexts(struct sigcontext __user *sc,
        if (current->thread.used_vr) {
                flush_altivec_to_thread(current);
                /* Copy 33 vec registers (vr0..31 and vscr) to the stack */
-               err |= __copy_to_user(v_regs, current->thread.vr,
+               err |= __copy_to_user(v_regs, &current->thread.vr_state,
                                      33 * sizeof(vector128));
                /* If VEC was enabled there are transactional VRs valid too,
                 * else they're a copy of the checkpointed VRs.
                 */
                if (msr & MSR_VEC)
                        err |= __copy_to_user(tm_v_regs,
-                                             current->thread.transact_vr,
+                                             &current->thread.transact_vr,
                                              33 * sizeof(vector128));
                else
                        err |= __copy_to_user(tm_v_regs,
-                                             current->thread.vr,
+                                             &current->thread.vr_state,
                                              33 * sizeof(vector128));
 
                /* set MSR_VEC in the MSR value in the frame to indicate
@@ -349,10 +350,10 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
                return -EFAULT;
        /* Copy 33 vec registers (vr0..31 and vscr) from the stack */
        if (v_regs != NULL && (msr & MSR_VEC) != 0)
-               err |= __copy_from_user(current->thread.vr, v_regs,
+               err |= __copy_from_user(&current->thread.vr_state, v_regs,
                                        33 * sizeof(vector128));
        else if (current->thread.used_vr)
-               memset(current->thread.vr, 0, 33 * sizeof(vector128));
+               memset(&current->thread.vr_state, 0, 33 * sizeof(vector128));
        /* Always get VRSAVE back */
        if (v_regs != NULL)
                err |= __get_user(current->thread.vrsave, (u32 __user *)&v_regs[33]);
@@ -374,7 +375,7 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
                err |= copy_vsx_from_user(current, v_regs);
        else
                for (i = 0; i < 32 ; i++)
-                       current->thread.fpr[i][TS_VSRLOWOFFSET] = 0;
+                       current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
 #endif
        return err;
 }
@@ -468,14 +469,14 @@ static long restore_tm_sigcontexts(struct pt_regs *regs,
                return -EFAULT;
        /* Copy 33 vec registers (vr0..31 and vscr) from the stack */
        if (v_regs != NULL && tm_v_regs != NULL && (msr & MSR_VEC) != 0) {
-               err |= __copy_from_user(current->thread.vr, v_regs,
+               err |= __copy_from_user(&current->thread.vr_state, v_regs,
                                        33 * sizeof(vector128));
-               err |= __copy_from_user(current->thread.transact_vr, tm_v_regs,
+               err |= __copy_from_user(&current->thread.transact_vr, tm_v_regs,
                                        33 * sizeof(vector128));
        }
        else if (current->thread.used_vr) {
-               memset(current->thread.vr, 0, 33 * sizeof(vector128));
-               memset(current->thread.transact_vr, 0, 33 * sizeof(vector128));
+               memset(&current->thread.vr_state, 0, 33 * sizeof(vector128));
+               memset(&current->thread.transact_vr, 0, 33 * sizeof(vector128));
        }
        /* Always get VRSAVE back */
        if (v_regs != NULL && tm_v_regs != NULL) {
@@ -507,8 +508,8 @@ static long restore_tm_sigcontexts(struct pt_regs *regs,
                err |= copy_transact_vsx_from_user(current, tm_v_regs);
        } else {
                for (i = 0; i < 32 ; i++) {
-                       current->thread.fpr[i][TS_VSRLOWOFFSET] = 0;
-                       current->thread.transact_fpr[i][TS_VSRLOWOFFSET] = 0;
+                       current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0;
+                       current->thread.transact_fp.fpr[i][TS_VSRLOWOFFSET] = 0;
                }
        }
 #endif
@@ -747,7 +748,7 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
                goto badframe;
 
        /* Make sure signal handler doesn't get spurious FP exceptions */
-       current->thread.fpscr.val = 0;
+       current->thread.fp_state.fpscr = 0;
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
        /* Remove TM bits from thread's MSR.  The MSR in the sigcontext
         * just indicates to userland that we were doing a transaction, but we
@@ -773,8 +774,9 @@ int handle_rt_signal64(int signr, struct k_sigaction *ka, siginfo_t *info,
 
        /* Set up "regs" so we "return" to the signal handler. */
        err |= get_user(regs->nip, &funct_desc_ptr->entry);
-       /* enter the signal handler in big-endian mode */
+       /* enter the signal handler in native-endian mode */
        regs->msr &= ~MSR_LE;
+       regs->msr |= (MSR_KERNEL & MSR_LE);
        regs->gpr[1] = newsp;
        err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
        regs->gpr[3] = signr;
index 22045984835f2078ce020e11e85a2e87b2401860..988f38dced0fb02e4d8b95c4d51df7d581e471ce 100644 (file)
@@ -114,7 +114,9 @@ _GLOBAL(swsusp_arch_suspend)
        SAVE_SPECIAL(MSR)
        SAVE_SPECIAL(XER)
 #ifdef CONFIG_PPC_BOOK3S_64
+BEGIN_FW_FTR_SECTION
        SAVE_SPECIAL(SDR1)
+END_FW_FTR_SECTION_IFCLR(FW_FEATURE_LPAR)
 #else
        SAVE_SPR(TCR)
 
@@ -231,7 +233,9 @@ nothing_to_copy:
        /* can't use RESTORE_SPECIAL(MSR) */
        ld      r0, SL_MSR(r11)
        mtmsrd  r0, 0
+BEGIN_FW_FTR_SECTION
        RESTORE_SPECIAL(SDR1)
+END_FW_FTR_SECTION_IFCLR(FW_FEATURE_LPAR)
 #else
        /* Restore SPRG1, be used to save paca */
        ld      r0, SL_SPRG1(r11)
index cd809eaa8b5c4bec7d00497e0edaa614501f13e0..ef47bcbd4352055638a1b74a831c0c2cdc037a1b 100644 (file)
 #include <asm/reg.h>
 
 #ifdef CONFIG_VSX
-/* See fpu.S, this is very similar but to save/restore checkpointed FPRs/VSRs */
-#define __SAVE_32FPRS_VSRS_TRANSACT(n,c,base)  \
+/* See fpu.S, this is borrowed from there */
+#define __SAVE_32FPRS_VSRS(n,c,base)           \
 BEGIN_FTR_SECTION                              \
        b       2f;                             \
 END_FTR_SECTION_IFSET(CPU_FTR_VSX);            \
-       SAVE_32FPRS_TRANSACT(n,base);           \
+       SAVE_32FPRS(n,base);                    \
        b       3f;                             \
-2:     SAVE_32VSRS_TRANSACT(n,c,base);         \
+2:     SAVE_32VSRS(n,c,base);                  \
 3:
-/* ...and this is just plain borrowed from there. */
 #define __REST_32FPRS_VSRS(n,c,base)           \
 BEGIN_FTR_SECTION                              \
        b       2f;                             \
@@ -31,11 +30,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX);         \
 2:     REST_32VSRS(n,c,base);                  \
 3:
 #else
-#define __SAVE_32FPRS_VSRS_TRANSACT(n,c,base) SAVE_32FPRS_TRANSACT(n, base)
-#define __REST_32FPRS_VSRS(n,c,base)         REST_32FPRS(n, base)
+#define __SAVE_32FPRS_VSRS(n,c,base)   SAVE_32FPRS(n, base)
+#define __REST_32FPRS_VSRS(n,c,base)   REST_32FPRS(n, base)
 #endif
-#define SAVE_32FPRS_VSRS_TRANSACT(n,c,base) \
-       __SAVE_32FPRS_VSRS_TRANSACT(n,__REG_##c,__REG_##base)
+#define SAVE_32FPRS_VSRS(n,c,base) \
+       __SAVE_32FPRS_VSRS(n,__REG_##c,__REG_##base)
 #define REST_32FPRS_VSRS(n,c,base) \
        __REST_32FPRS_VSRS(n,__REG_##c,__REG_##base)
 
@@ -107,7 +106,7 @@ DSCR_DEFAULT:
 _GLOBAL(tm_reclaim)
        mfcr    r6
        mflr    r0
-       std     r6, 8(r1)
+       stw     r6, 8(r1)
        std     r0, 16(r1)
        std     r2, 40(r1)
        stdu    r1, -TM_FRAME_SIZE(r1)
@@ -157,10 +156,11 @@ _GLOBAL(tm_reclaim)
        andis.          r0, r4, MSR_VEC@h
        beq     dont_backup_vec
 
-       SAVE_32VRS_TRANSACT(0, r6, r3)  /* r6 scratch, r3 thread */
+       addi    r7, r3, THREAD_TRANSACT_VRSTATE
+       SAVE_32VRS(0, r6, r7)   /* r6 scratch, r7 transact vr state */
        mfvscr  vr0
-       li      r6, THREAD_TRANSACT_VSCR
-       stvx    vr0, r3, r6
+       li      r6, VRSTATE_VSCR
+       stvx    vr0, r7, r6
 dont_backup_vec:
        mfspr   r0, SPRN_VRSAVE
        std     r0, THREAD_TRANSACT_VRSAVE(r3)
@@ -168,10 +168,11 @@ dont_backup_vec:
        andi.   r0, r4, MSR_FP
        beq     dont_backup_fp
 
-       SAVE_32FPRS_VSRS_TRANSACT(0, R6, R3)    /* r6 scratch, r3 thread */
+       addi    r7, r3, THREAD_TRANSACT_FPSTATE
+       SAVE_32FPRS_VSRS(0, R6, R7)     /* r6 scratch, r7 transact fp state */
 
        mffs    fr0
-       stfd    fr0,THREAD_TRANSACT_FPSCR(r3)
+       stfd    fr0,FPSTATE_FPSCR(r7)
 
 dont_backup_fp:
        /* The moment we treclaim, ALL of our GPRs will switch
@@ -284,7 +285,7 @@ dont_backup_fp:
        REST_NVGPRS(r1)
 
        addi    r1, r1, TM_FRAME_SIZE
-       l     r4, 8(r1)
+       lwz     r4, 8(r1)
        ld      r0, 16(r1)
        mtcr    r4
        mtlr    r0
@@ -309,7 +310,7 @@ dont_backup_fp:
 _GLOBAL(tm_recheckpoint)
        mfcr    r5
        mflr    r0
-       std     r5, 8(r1)
+       stw     r5, 8(r1)
        std     r0, 16(r1)
        std     r2, 40(r1)
        stdu    r1, -TM_FRAME_SIZE(r1)
@@ -358,10 +359,11 @@ _GLOBAL(tm_recheckpoint)
        andis.  r0, r4, MSR_VEC@h
        beq     dont_restore_vec
 
-       li      r5, THREAD_VSCR
-       lvx     vr0, r3, r5
+       addi    r8, r3, THREAD_VRSTATE
+       li      r5, VRSTATE_VSCR
+       lvx     vr0, r8, r5
        mtvscr  vr0
-       REST_32VRS(0, r5, r3)                   /* r5 scratch, r3 THREAD ptr */
+       REST_32VRS(0, r5, r8)                   /* r5 scratch, r8 ptr */
 dont_restore_vec:
        ld      r5, THREAD_VRSAVE(r3)
        mtspr   SPRN_VRSAVE, r5
@@ -370,9 +372,10 @@ dont_restore_vec:
        andi.   r0, r4, MSR_FP
        beq     dont_restore_fp
 
-       lfd     fr0, THREAD_FPSCR(r3)
+       addi    r8, r3, THREAD_FPSTATE
+       lfd     fr0, FPSTATE_FPSCR(r8)
        MTFSF_L(fr0)
-       REST_32FPRS_VSRS(0, R4, R3)
+       REST_32FPRS_VSRS(0, R4, R8)
 
 dont_restore_fp:
        mtmsr   r6                              /* FP/Vec off again! */
@@ -441,7 +444,7 @@ restore_gprs:
        REST_NVGPRS(r1)
 
        addi    r1, r1, TM_FRAME_SIZE
-       l     r4, 8(r1)
+       lwz     r4, 8(r1)
        ld      r0, 16(r1)
        mtcr    r4
        mtlr    r0
index f783c932faeb3717eca6136cab5ab350f01e9a6e..62c3dd8c69f21d3d5373d7c79d0ea6ab1a69ed0f 100644 (file)
@@ -351,8 +351,8 @@ static inline int check_io_access(struct pt_regs *regs)
 #define REASON_TRAP            ESR_PTR
 
 /* single-step stuff */
-#define single_stepping(regs)  (current->thread.dbcr0 & DBCR0_IC)
-#define clear_single_step(regs)        (current->thread.dbcr0 &= ~DBCR0_IC)
+#define single_stepping(regs)  (current->thread.debug.dbcr0 & DBCR0_IC)
+#define clear_single_step(regs)        (current->thread.debug.dbcr0 &= ~DBCR0_IC)
 
 #else
 /* On non-4xx, the reason for the machine check or program
@@ -816,7 +816,7 @@ static void parse_fpe(struct pt_regs *regs)
 
        flush_fp_to_thread(current);
 
-       code = __parse_fpscr(current->thread.fpscr.val);
+       code = __parse_fpscr(current->thread.fp_state.fpscr);
 
        _exception(SIGFPE, regs, code, regs->nip);
 }
@@ -1018,6 +1018,13 @@ static int emulate_instruction(struct pt_regs *regs)
                return emulate_isel(regs, instword);
        }
 
+       /* Emulate sync instruction variants */
+       if ((instword & PPC_INST_SYNC_MASK) == PPC_INST_SYNC) {
+               PPC_WARN_EMULATED(sync, regs);
+               asm volatile("sync");
+               return 0;
+       }
+
 #ifdef CONFIG_PPC64
        /* Emulate the mfspr rD, DSCR. */
        if ((((instword & PPC_INST_MFSPR_DSCR_USER_MASK) ==
@@ -1069,7 +1076,7 @@ static int emulate_math(struct pt_regs *regs)
                return 0;
        case 1: {
                        int code = 0;
-                       code = __parse_fpscr(current->thread.fpscr.val);
+                       code = __parse_fpscr(current->thread.fp_state.fpscr);
                        _exception(SIGFPE, regs, code, regs->nip);
                        return 0;
                }
@@ -1371,8 +1378,6 @@ void facility_unavailable_exception(struct pt_regs *regs)
 
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
 
-extern void do_load_up_fpu(struct pt_regs *regs);
-
 void fp_unavailable_tm(struct pt_regs *regs)
 {
        /* Note:  This does not handle any kind of FP laziness. */
@@ -1403,8 +1408,6 @@ void fp_unavailable_tm(struct pt_regs *regs)
 }
 
 #ifdef CONFIG_ALTIVEC
-extern void do_load_up_altivec(struct pt_regs *regs);
-
 void altivec_unavailable_tm(struct pt_regs *regs)
 {
        /* See the comments in fp_unavailable_tm().  This function operates
@@ -1465,7 +1468,8 @@ void SoftwareEmulation(struct pt_regs *regs)
 
        if (!user_mode(regs)) {
                debugger(regs);
-               die("Kernel Mode Software FPU Emulation", regs, SIGFPE);
+               die("Kernel Mode Unimplemented Instruction or SW FPU Emulation",
+                       regs, SIGFPE);
        }
 
        if (!emulate_math(regs))
@@ -1486,7 +1490,7 @@ static void handle_debug(struct pt_regs *regs, unsigned long debug_status)
        if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) {
                dbcr_dac(current) &= ~(DBCR_DAC1R | DBCR_DAC1W);
 #ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
-               current->thread.dbcr2 &= ~DBCR2_DAC12MODE;
+               current->thread.debug.dbcr2 &= ~DBCR2_DAC12MODE;
 #endif
                do_send_trap(regs, mfspr(SPRN_DAC1), debug_status, TRAP_HWBKPT,
                             5);
@@ -1497,24 +1501,24 @@ static void handle_debug(struct pt_regs *regs, unsigned long debug_status)
                             6);
                changed |= 0x01;
        }  else if (debug_status & DBSR_IAC1) {
-               current->thread.dbcr0 &= ~DBCR0_IAC1;
+               current->thread.debug.dbcr0 &= ~DBCR0_IAC1;
                dbcr_iac_range(current) &= ~DBCR_IAC12MODE;
                do_send_trap(regs, mfspr(SPRN_IAC1), debug_status, TRAP_HWBKPT,
                             1);
                changed |= 0x01;
        }  else if (debug_status & DBSR_IAC2) {
-               current->thread.dbcr0 &= ~DBCR0_IAC2;
+               current->thread.debug.dbcr0 &= ~DBCR0_IAC2;
                do_send_trap(regs, mfspr(SPRN_IAC2), debug_status, TRAP_HWBKPT,
                             2);
                changed |= 0x01;
        }  else if (debug_status & DBSR_IAC3) {
-               current->thread.dbcr0 &= ~DBCR0_IAC3;
+               current->thread.debug.dbcr0 &= ~DBCR0_IAC3;
                dbcr_iac_range(current) &= ~DBCR_IAC34MODE;
                do_send_trap(regs, mfspr(SPRN_IAC3), debug_status, TRAP_HWBKPT,
                             3);
                changed |= 0x01;
        }  else if (debug_status & DBSR_IAC4) {
-               current->thread.dbcr0 &= ~DBCR0_IAC4;
+               current->thread.debug.dbcr0 &= ~DBCR0_IAC4;
                do_send_trap(regs, mfspr(SPRN_IAC4), debug_status, TRAP_HWBKPT,
                             4);
                changed |= 0x01;
@@ -1524,19 +1528,20 @@ static void handle_debug(struct pt_regs *regs, unsigned long debug_status)
         * Check all other debug flags and see if that bit needs to be turned
         * back on or not.
         */
-       if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0, current->thread.dbcr1))
+       if (DBCR_ACTIVE_EVENTS(current->thread.debug.dbcr0,
+           current->thread.debug.dbcr1))
                regs->msr |= MSR_DE;
        else
                /* Make sure the IDM flag is off */
-               current->thread.dbcr0 &= ~DBCR0_IDM;
+               current->thread.debug.dbcr0 &= ~DBCR0_IDM;
 
        if (changed & 0x01)
-               mtspr(SPRN_DBCR0, current->thread.dbcr0);
+               mtspr(SPRN_DBCR0, current->thread.debug.dbcr0);
 }
 
 void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
 {
-       current->thread.dbsr = debug_status;
+       current->thread.debug.dbsr = debug_status;
 
        /* Hack alert: On BookE, Branch Taken stops on the branch itself, while
         * on server, it stops on the target of the branch. In order to simulate
@@ -1553,8 +1558,8 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
 
                /* Do the single step trick only when coming from userspace */
                if (user_mode(regs)) {
-                       current->thread.dbcr0 &= ~DBCR0_BT;
-                       current->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC;
+                       current->thread.debug.dbcr0 &= ~DBCR0_BT;
+                       current->thread.debug.dbcr0 |= DBCR0_IDM | DBCR0_IC;
                        regs->msr |= MSR_DE;
                        return;
                }
@@ -1582,13 +1587,13 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
                        return;
 
                if (user_mode(regs)) {
-                       current->thread.dbcr0 &= ~DBCR0_IC;
-                       if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0,
-                                              current->thread.dbcr1))
+                       current->thread.debug.dbcr0 &= ~DBCR0_IC;
+                       if (DBCR_ACTIVE_EVENTS(current->thread.debug.dbcr0,
+                                              current->thread.debug.dbcr1))
                                regs->msr |= MSR_DE;
                        else
                                /* Make sure the IDM bit is off */
-                               current->thread.dbcr0 &= ~DBCR0_IDM;
+                               current->thread.debug.dbcr0 &= ~DBCR0_IDM;
                }
 
                _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
@@ -1634,7 +1639,7 @@ void altivec_assist_exception(struct pt_regs *regs)
                /* XXX quick hack for now: set the non-Java bit in the VSCR */
                printk_ratelimited(KERN_ERR "Unrecognized altivec instruction "
                                   "in %s at %lx\n", current->comm, regs->nip);
-               current->thread.vscr.u[3] |= 0x10000;
+               current->thread.vr_state.vscr.u[3] |= 0x10000;
        }
 }
 #endif /* CONFIG_ALTIVEC */
@@ -1815,6 +1820,7 @@ struct ppc_emulated ppc_emulated = {
        WARN_EMULATED_SETUP(popcntb),
        WARN_EMULATED_SETUP(spe),
        WARN_EMULATED_SETUP(string),
+       WARN_EMULATED_SETUP(sync),
        WARN_EMULATED_SETUP(unaligned),
 #ifdef CONFIG_MATH_EMULATION
        WARN_EMULATED_SETUP(math),
index 1d9c92621b36f4be1eeaa0dcf5ebab5c926c9259..094e45c16a17032e36e33f3ef1fb5182fb4dd958 100644 (file)
@@ -34,8 +34,7 @@
 #include <asm/firmware.h>
 #include <asm/vdso.h>
 #include <asm/vdso_datapage.h>
-
-#include "setup.h"
+#include <asm/setup.h>
 
 #undef DEBUG
 
index f223409629b9c768891f54a4f117ed964a25a0e2..e58ee10fa5c0a41efbacaa9f10bc03665d18b8fb 100644 (file)
@@ -4,7 +4,11 @@
  */
 #include <asm/vdso.h>
 
+#ifdef __LITTLE_ENDIAN__
+OUTPUT_FORMAT("elf32-powerpcle", "elf32-powerpcle", "elf32-powerpcle")
+#else
 OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
+#endif
 OUTPUT_ARCH(powerpc:common)
 ENTRY(_start)
 
index e4863819663b35d0ca8658a5f1fd374c4b0da5c7..64fb183a47c2fff07bc385489db33bdc5c7799e3 100644 (file)
@@ -4,7 +4,11 @@
  */
 #include <asm/vdso.h>
 
+#ifdef __LITTLE_ENDIAN__
+OUTPUT_FORMAT("elf64-powerpcle", "elf64-powerpcle", "elf64-powerpcle")
+#else
 OUTPUT_FORMAT("elf64-powerpc", "elf64-powerpc", "elf64-powerpc")
+#endif
 OUTPUT_ARCH(powerpc:common64)
 ENTRY(_start)
 
index 604d0947cb20cd87dcad9f7e512dd5a63ddd05d4..c4bfadb2606bcc6a5cb92b456ae0903e1ea5b86c 100644 (file)
@@ -271,7 +271,7 @@ int emulate_altivec(struct pt_regs *regs)
        vb = (instr >> 11) & 0x1f;
        vc = (instr >> 6) & 0x1f;
 
-       vrs = current->thread.vr;
+       vrs = current->thread.vr_state.vr;
        switch (instr & 0x3f) {
        case 10:
                switch (vc) {
@@ -320,12 +320,12 @@ int emulate_altivec(struct pt_regs *regs)
                case 14:        /* vctuxs */
                        for (i = 0; i < 4; ++i)
                                vrs[vd].u[i] = ctuxs(vrs[vb].u[i], va,
-                                               &current->thread.vscr.u[3]);
+                                       &current->thread.vr_state.vscr.u[3]);
                        break;
                case 15:        /* vctsxs */
                        for (i = 0; i < 4; ++i)
                                vrs[vd].u[i] = ctsxs(vrs[vb].u[i], va,
-                                               &current->thread.vscr.u[3]);
+                                       &current->thread.vr_state.vscr.u[3]);
                        break;
                default:
                        return -EINVAL;
index 9e20999aaef289169dd79feb42871647d4c6dd5c..0458a9aaba9d135867d6a4263404a8264148a7cd 100644 (file)
@@ -8,29 +8,6 @@
 #include <asm/ptrace.h>
 
 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-/*
- * Wrapper to call load_up_altivec from C.
- * void do_load_up_altivec(struct pt_regs *regs);
- */
-_GLOBAL(do_load_up_altivec)
-       mflr    r0
-       std     r0, 16(r1)
-       stdu    r1, -112(r1)
-
-       subi    r6, r3, STACK_FRAME_OVERHEAD
-       /* load_up_altivec expects r12=MSR, r13=PACA, and returns
-        * with r12 = new MSR.
-        */
-       ld      r12,_MSR(r6)
-       GET_PACA(r13)
-       bl      load_up_altivec
-       std     r12,_MSR(r6)
-
-       ld      r0, 112+16(r1)
-       addi    r1, r1, 112
-       mtlr    r0
-       blr
-
 /* void do_load_up_transact_altivec(struct thread_struct *thread)
  *
  * This is similar to load_up_altivec but for the transactional version of the
@@ -46,10 +23,11 @@ _GLOBAL(do_load_up_transact_altivec)
        li      r4,1
        stw     r4,THREAD_USED_VR(r3)
 
-       li      r10,THREAD_TRANSACT_VSCR
+       li      r10,THREAD_TRANSACT_VRSTATE+VRSTATE_VSCR
        lvx     vr0,r10,r3
        mtvscr  vr0
-       REST_32VRS_TRANSACT(0,r4,r3)
+       addi    r10,r3,THREAD_TRANSACT_VRSTATE
+       REST_32VRS(0,r4,r10)
 
        /* Disable VEC again. */
        MTMSRD(r6)
@@ -59,12 +37,36 @@ _GLOBAL(do_load_up_transact_altivec)
 #endif
 
 /*
- * load_up_altivec(unused, unused, tsk)
+ * Load state from memory into VMX registers including VSCR.
+ * Assumes the caller has enabled VMX in the MSR.
+ */
+_GLOBAL(load_vr_state)
+       li      r4,VRSTATE_VSCR
+       lvx     vr0,r4,r3
+       mtvscr  vr0
+       REST_32VRS(0,r4,r3)
+       blr
+
+/*
+ * Store VMX state into memory, including VSCR.
+ * Assumes the caller has enabled VMX in the MSR.
+ */
+_GLOBAL(store_vr_state)
+       SAVE_32VRS(0, r4, r3)
+       mfvscr  vr0
+       li      r4, VRSTATE_VSCR
+       stvx    vr0, r4, r3
+       blr
+
+/*
  * Disable VMX for the task which had it previously,
  * and save its vector registers in its thread_struct.
  * Enables the VMX for use in the kernel on return.
  * On SMP we know the VMX is free, since we give it up every
  * switch (ie, no lazy save of the vector registers).
+ *
+ * Note that on 32-bit this can only use registers that will be
+ * restored by fast_exception_return, i.e. r3 - r6, r10 and r11.
  */
 _GLOBAL(load_up_altivec)
        mfmsr   r5                      /* grab the current MSR */
@@ -90,10 +92,11 @@ _GLOBAL(load_up_altivec)
        /* Save VMX state to last_task_used_altivec's THREAD struct */
        toreal(r4)
        addi    r4,r4,THREAD
-       SAVE_32VRS(0,r5,r4)
+       addi    r6,r4,THREAD_VRSTATE
+       SAVE_32VRS(0,r5,r6)
        mfvscr  vr0
-       li      r10,THREAD_VSCR
-       stvx    vr0,r10,r4
+       li      r10,VRSTATE_VSCR
+       stvx    vr0,r10,r6
        /* Disable VMX for last_task_used_altivec */
        PPC_LL  r5,PT_REGS(r4)
        toreal(r5)
@@ -125,12 +128,13 @@ _GLOBAL(load_up_altivec)
        oris    r12,r12,MSR_VEC@h
        std     r12,_MSR(r1)
 #endif
+       addi    r6,r5,THREAD_VRSTATE
        li      r4,1
-       li      r10,THREAD_VSCR
+       li      r10,VRSTATE_VSCR
        stw     r4,THREAD_USED_VR(r5)
-       lvx     vr0,r10,r5
+       lvx     vr0,r10,r6
        mtvscr  vr0
-       REST_32VRS(0,r4,r5)
+       REST_32VRS(0,r4,r6)
 #ifndef CONFIG_SMP
        /* Update last_task_used_altivec to 'current' */
        subi    r4,r5,THREAD            /* Back to 'current' */
@@ -165,12 +169,16 @@ _GLOBAL(giveup_altivec)
        PPC_LCMPI       0,r3,0
        beqlr                           /* if no previous owner, done */
        addi    r3,r3,THREAD            /* want THREAD of task */
+       PPC_LL  r7,THREAD_VRSAVEAREA(r3)
        PPC_LL  r5,PT_REGS(r3)
-       PPC_LCMPI       0,r5,0
-       SAVE_32VRS(0,r4,r3)
+       PPC_LCMPI       0,r7,0
+       bne     2f
+       addi    r7,r3,THREAD_VRSTATE
+2:     PPC_LCMPI       0,r5,0
+       SAVE_32VRS(0,r4,r7)
        mfvscr  vr0
-       li      r4,THREAD_VSCR
-       stvx    vr0,r4,r3
+       li      r4,VRSTATE_VSCR
+       stvx    vr0,r4,r7
        beq     1f
        PPC_LL  r4,_MSR-STACK_FRAME_OVERHEAD(r5)
 #ifdef CONFIG_VSX
index 408956fbf4f617b67a284e9bd19f22c2fb86abd4..f99cefbd84e3666550b12aaae4b941314c3928fa 100644 (file)
@@ -1537,12 +1537,12 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
 
        dn = dev->of_node;
        if (!dn) {
-               strcat(buf, "\n");
+               strcpy(buf, "\n");
                return strlen(buf);
        }
        cp = of_get_property(dn, "compatible", NULL);
        if (!cp) {
-               strcat(buf, "\n");
+               strcpy(buf, "\n");
                return strlen(buf);
        }
 
index ffaef2cb101a4ef50c77f1dc58c3cdac1f2da105..e593ff257bd300461d8a6e487e0fb448e5d86936 100644 (file)
@@ -6,6 +6,7 @@ source "virt/kvm/Kconfig"
 
 menuconfig VIRTUALIZATION
        bool "Virtualization"
+       depends on !CPU_LITTLE_ENDIAN
        ---help---
          Say Y here to get to see options for using your Linux host to run
          other operating systems inside virtual machines (guests).
index 27db1e66595987a99e2f387819345af30baad739..c0b48f96a91c9817b17e80b6b32f3f4e6aac0167 100644 (file)
@@ -444,7 +444,7 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr)
 #ifdef CONFIG_VSX
        u64 *vcpu_vsx = vcpu->arch.vsr;
 #endif
-       u64 *thread_fpr = (u64*)t->fpr;
+       u64 *thread_fpr = &t->fp_state.fpr[0][0];
        int i;
 
        /*
@@ -466,14 +466,14 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr)
                /*
                 * Note that on CPUs with VSX, giveup_fpu stores
                 * both the traditional FP registers and the added VSX
-                * registers into thread.fpr[].
+                * registers into thread.fp_state.fpr[].
                 */
                if (current->thread.regs->msr & MSR_FP)
                        giveup_fpu(current);
                for (i = 0; i < ARRAY_SIZE(vcpu->arch.fpr); i++)
                        vcpu_fpr[i] = thread_fpr[get_fpr_index(i)];
 
-               vcpu->arch.fpscr = t->fpscr.val;
+               vcpu->arch.fpscr = t->fp_state.fpscr;
 
 #ifdef CONFIG_VSX
                if (cpu_has_feature(CPU_FTR_VSX))
@@ -486,8 +486,8 @@ void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr)
        if (msr & MSR_VEC) {
                if (current->thread.regs->msr & MSR_VEC)
                        giveup_altivec(current);
-               memcpy(vcpu->arch.vr, t->vr, sizeof(vcpu->arch.vr));
-               vcpu->arch.vscr = t->vscr;
+               memcpy(vcpu->arch.vr, t->vr_state.vr, sizeof(vcpu->arch.vr));
+               vcpu->arch.vscr = t->vr_state.vscr;
        }
 #endif
 
@@ -539,7 +539,7 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
 #ifdef CONFIG_VSX
        u64 *vcpu_vsx = vcpu->arch.vsr;
 #endif
-       u64 *thread_fpr = (u64*)t->fpr;
+       u64 *thread_fpr = &t->fp_state.fpr[0][0];
        int i;
 
        /* When we have paired singles, we emulate in software */
@@ -584,15 +584,15 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
                for (i = 0; i < ARRAY_SIZE(vcpu->arch.vsr) / 2; i++)
                        thread_fpr[get_fpr_index(i) + 1] = vcpu_vsx[i];
 #endif
-               t->fpscr.val = vcpu->arch.fpscr;
+               t->fp_state.fpscr = vcpu->arch.fpscr;
                t->fpexc_mode = 0;
                kvmppc_load_up_fpu();
        }
 
        if (msr & MSR_VEC) {
 #ifdef CONFIG_ALTIVEC
-               memcpy(t->vr, vcpu->arch.vr, sizeof(vcpu->arch.vr));
-               t->vscr = vcpu->arch.vscr;
+               memcpy(t->vr_state.vr, vcpu->arch.vr, sizeof(vcpu->arch.vr));
+               t->vr_state.vscr = vcpu->arch.vscr;
                t->vrsave = -1;
                kvmppc_load_up_altivec();
 #endif
@@ -1116,12 +1116,10 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
 int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 {
        int ret;
-       double fpr[32][TS_FPRWIDTH];
-       unsigned int fpscr;
+       struct thread_fp_state fp;
        int fpexc_mode;
 #ifdef CONFIG_ALTIVEC
-       vector128 vr[32];
-       vector128 vscr;
+       struct thread_vr_state vr;
        unsigned long uninitialized_var(vrsave);
        int used_vr;
 #endif
@@ -1153,8 +1151,7 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
        /* Save FPU state in stack */
        if (current->thread.regs->msr & MSR_FP)
                giveup_fpu(current);
-       memcpy(fpr, current->thread.fpr, sizeof(current->thread.fpr));
-       fpscr = current->thread.fpscr.val;
+       fp = current->thread.fp_state;
        fpexc_mode = current->thread.fpexc_mode;
 
 #ifdef CONFIG_ALTIVEC
@@ -1163,8 +1160,7 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
        if (used_vr) {
                if (current->thread.regs->msr & MSR_VEC)
                        giveup_altivec(current);
-               memcpy(vr, current->thread.vr, sizeof(current->thread.vr));
-               vscr = current->thread.vscr;
+               vr = current->thread.vr_state;
                vrsave = current->thread.vrsave;
        }
 #endif
@@ -1196,15 +1192,13 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
        current->thread.regs->msr = ext_msr;
 
        /* Restore FPU/VSX state from stack */
-       memcpy(current->thread.fpr, fpr, sizeof(current->thread.fpr));
-       current->thread.fpscr.val = fpscr;
+       current->thread.fp_state = fp;
        current->thread.fpexc_mode = fpexc_mode;
 
 #ifdef CONFIG_ALTIVEC
        /* Restore Altivec state from stack */
        if (used_vr && current->thread.used_vr) {
-               memcpy(current->thread.vr, vr, sizeof(current->thread.vr));
-               current->thread.vscr = vscr;
+               current->thread.vr_state = vr;
                current->thread.vrsave = vrsave;
        }
        current->thread.used_vr = used_vr;
index 17722d82f1d1f500bd5579f544cf29b18e6cbd80..5133199f6cb7b6cab1feca199f434bfd69a89e1a 100644 (file)
@@ -656,9 +656,8 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 {
        int ret, s;
 #ifdef CONFIG_PPC_FPU
-       unsigned int fpscr;
+       struct thread_fp_state fp;
        int fpexc_mode;
-       u64 fpr[32];
 #endif
 
        if (!vcpu->arch.sane) {
@@ -677,13 +676,13 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
 #ifdef CONFIG_PPC_FPU
        /* Save userspace FPU state in stack */
        enable_kernel_fp();
-       memcpy(fpr, current->thread.fpr, sizeof(current->thread.fpr));
-       fpscr = current->thread.fpscr.val;
+       fp = current->thread.fp_state;
        fpexc_mode = current->thread.fpexc_mode;
 
        /* Restore guest FPU state to thread */
-       memcpy(current->thread.fpr, vcpu->arch.fpr, sizeof(vcpu->arch.fpr));
-       current->thread.fpscr.val = vcpu->arch.fpscr;
+       memcpy(current->thread.fp_state.fpr, vcpu->arch.fpr,
+              sizeof(vcpu->arch.fpr));
+       current->thread.fp_state.fpscr = vcpu->arch.fpscr;
 
        /*
         * Since we can't trap on MSR_FP in GS-mode, we consider the guest
@@ -709,12 +708,12 @@ int kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
        vcpu->fpu_active = 0;
 
        /* Save guest FPU state from thread */
-       memcpy(vcpu->arch.fpr, current->thread.fpr, sizeof(vcpu->arch.fpr));
-       vcpu->arch.fpscr = current->thread.fpscr.val;
+       memcpy(vcpu->arch.fpr, current->thread.fp_state.fpr,
+              sizeof(vcpu->arch.fpr));
+       vcpu->arch.fpscr = current->thread.fp_state.fpscr;
 
        /* Restore userspace FPU state from stack */
-       memcpy(current->thread.fpr, fpr, sizeof(current->thread.fpr));
-       current->thread.fpscr.val = fpscr;
+       current->thread.fp_state = fp;
        current->thread.fpexc_mode = fpexc_mode;
 #endif
 
index 4504332766990147fdbfef302baac7919ec179fa..95a20e17dbff2c79557a18dba8f553a0f3a323d2 100644 (file)
@@ -10,15 +10,23 @@ CFLAGS_REMOVE_code-patching.o = -pg
 CFLAGS_REMOVE_feature-fixups.o = -pg
 
 obj-y                  := string.o alloc.o \
-                          checksum_$(CONFIG_WORD_SIZE).o crtsavres.o
+                          crtsavres.o
 obj-$(CONFIG_PPC32)    += div64.o copy_32.o
 obj-$(CONFIG_HAS_IOMEM)        += devres.o
 
 obj-$(CONFIG_PPC64)    += copypage_64.o copyuser_64.o \
-                          memcpy_64.o usercopy_64.o mem_64.o string.o \
-                          checksum_wrappers_64.o hweight_64.o \
-                          copyuser_power7.o string_64.o copypage_power7.o \
-                          memcpy_power7.o
+                          usercopy_64.o mem_64.o string.o \
+                          hweight_64.o \
+                          copyuser_power7.o string_64.o copypage_power7.o
+ifeq ($(CONFIG_GENERIC_CSUM),)
+obj-y                  += checksum_$(CONFIG_WORD_SIZE).o
+obj-$(CONFIG_PPC64)    += checksum_wrappers_64.o
+endif
+
+ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),)
+obj-$(CONFIG_PPC64)            += memcpy_power7.o memcpy_64.o 
+endif
+
 obj-$(CONFIG_PPC_EMULATE_SSTEP)        += sstep.o ldstfp.o
 
 ifeq ($(CONFIG_PPC64),y)
@@ -31,3 +39,6 @@ obj-$(CONFIG_PPC_LIB_RHEAP) += rheap.o
 obj-y                  += code-patching.o
 obj-y                  += feature-fixups.o
 obj-$(CONFIG_FTR_FIXUP_SELFTEST) += feature-fixups-test.o
+
+obj-$(CONFIG_ALTIVEC)  += xor_vmx.o
+CFLAGS_xor_vmx.o += -maltivec -mabi=altivec
index d1f11795a7ad64bd6bd05beb522e07e44eb46498..e8e9c36dc7844455c4b24356cdff5f9ed9e70aff 100644 (file)
  */
 #include <asm/ppc_asm.h>
 
+#ifdef __BIG_ENDIAN__
+#define LVS(VRT,RA,RB)         lvsl    VRT,RA,RB
+#define VPERM(VRT,VRA,VRB,VRC) vperm   VRT,VRA,VRB,VRC
+#else
+#define LVS(VRT,RA,RB)         lvsr    VRT,RA,RB
+#define VPERM(VRT,VRA,VRB,VRC) vperm   VRT,VRB,VRA,VRC
+#endif
+
        .macro err1
 100:
        .section __ex_table,"a"
@@ -552,13 +560,13 @@ err3;     stw     r7,4(r3)
        li      r10,32
        li      r11,48
 
-       lvsl    vr16,0,r4       /* Setup permute control vector */
+       LVS(vr16,0,r4)          /* Setup permute control vector */
 err3;  lvx     vr0,0,r4
        addi    r4,r4,16
 
        bf      cr7*4+3,5f
 err3;  lvx     vr1,r0,r4
-       vperm   vr8,vr0,vr1,vr16
+       VPERM(vr8,vr0,vr1,vr16)
        addi    r4,r4,16
 err3;  stvx    vr8,r0,r3
        addi    r3,r3,16
@@ -566,9 +574,9 @@ err3;       stvx    vr8,r0,r3
 
 5:     bf      cr7*4+2,6f
 err3;  lvx     vr1,r0,r4
-       vperm   vr8,vr0,vr1,vr16
+       VPERM(vr8,vr0,vr1,vr16)
 err3;  lvx     vr0,r4,r9
-       vperm   vr9,vr1,vr0,vr16
+       VPERM(vr9,vr1,vr0,vr16)
        addi    r4,r4,32
 err3;  stvx    vr8,r0,r3
 err3;  stvx    vr9,r3,r9
@@ -576,13 +584,13 @@ err3;     stvx    vr9,r3,r9
 
 6:     bf      cr7*4+1,7f
 err3;  lvx     vr3,r0,r4
-       vperm   vr8,vr0,vr3,vr16
+       VPERM(vr8,vr0,vr3,vr16)
 err3;  lvx     vr2,r4,r9
-       vperm   vr9,vr3,vr2,vr16
+       VPERM(vr9,vr3,vr2,vr16)
 err3;  lvx     vr1,r4,r10
-       vperm   vr10,vr2,vr1,vr16
+       VPERM(vr10,vr2,vr1,vr16)
 err3;  lvx     vr0,r4,r11
-       vperm   vr11,vr1,vr0,vr16
+       VPERM(vr11,vr1,vr0,vr16)
        addi    r4,r4,64
 err3;  stvx    vr8,r0,r3
 err3;  stvx    vr9,r3,r9
@@ -611,21 +619,21 @@ err3;     stvx    vr11,r3,r11
        .align  5
 8:
 err4;  lvx     vr7,r0,r4
-       vperm   vr8,vr0,vr7,vr16
+       VPERM(vr8,vr0,vr7,vr16)
 err4;  lvx     vr6,r4,r9
-       vperm   vr9,vr7,vr6,vr16
+       VPERM(vr9,vr7,vr6,vr16)
 err4;  lvx     vr5,r4,r10
-       vperm   vr10,vr6,vr5,vr16
+       VPERM(vr10,vr6,vr5,vr16)
 err4;  lvx     vr4,r4,r11
-       vperm   vr11,vr5,vr4,vr16
+       VPERM(vr11,vr5,vr4,vr16)
 err4;  lvx     vr3,r4,r12
-       vperm   vr12,vr4,vr3,vr16
+       VPERM(vr12,vr4,vr3,vr16)
 err4;  lvx     vr2,r4,r14
-       vperm   vr13,vr3,vr2,vr16
+       VPERM(vr13,vr3,vr2,vr16)
 err4;  lvx     vr1,r4,r15
-       vperm   vr14,vr2,vr1,vr16
+       VPERM(vr14,vr2,vr1,vr16)
 err4;  lvx     vr0,r4,r16
-       vperm   vr15,vr1,vr0,vr16
+       VPERM(vr15,vr1,vr0,vr16)
        addi    r4,r4,128
 err4;  stvx    vr8,r0,r3
 err4;  stvx    vr9,r3,r9
@@ -649,13 +657,13 @@ err4;     stvx    vr15,r3,r16
 
        bf      cr7*4+1,9f
 err3;  lvx     vr3,r0,r4
-       vperm   vr8,vr0,vr3,vr16
+       VPERM(vr8,vr0,vr3,vr16)
 err3;  lvx     vr2,r4,r9
-       vperm   vr9,vr3,vr2,vr16
+       VPERM(vr9,vr3,vr2,vr16)
 err3;  lvx     vr1,r4,r10
-       vperm   vr10,vr2,vr1,vr16
+       VPERM(vr10,vr2,vr1,vr16)
 err3;  lvx     vr0,r4,r11
-       vperm   vr11,vr1,vr0,vr16
+       VPERM(vr11,vr1,vr0,vr16)
        addi    r4,r4,64
 err3;  stvx    vr8,r0,r3
 err3;  stvx    vr9,r3,r9
@@ -665,9 +673,9 @@ err3;       stvx    vr11,r3,r11
 
 9:     bf      cr7*4+2,10f
 err3;  lvx     vr1,r0,r4
-       vperm   vr8,vr0,vr1,vr16
+       VPERM(vr8,vr0,vr1,vr16)
 err3;  lvx     vr0,r4,r9
-       vperm   vr9,vr1,vr0,vr16
+       VPERM(vr9,vr1,vr0,vr16)
        addi    r4,r4,32
 err3;  stvx    vr8,r0,r3
 err3;  stvx    vr9,r3,r9
@@ -675,7 +683,7 @@ err3;       stvx    vr9,r3,r9
 
 10:    bf      cr7*4+3,11f
 err3;  lvx     vr1,r0,r4
-       vperm   vr8,vr0,vr1,vr16
+       VPERM(vr8,vr0,vr1,vr16)
        addi    r4,r4,16
 err3;  stvx    vr8,r0,r3
        addi    r3,r3,16
index 0663630baf3b46373905d60d96e989fee6637aa8..e4177dbea6bd6a9e59e1cfc548195b1223b8eb0d 100644 (file)
 #include <asm/ppc_asm.h>
 
 _GLOBAL(memcpy_power7)
+
+#ifdef __BIG_ENDIAN__
+#define LVS(VRT,RA,RB)         lvsl    VRT,RA,RB
+#define VPERM(VRT,VRA,VRB,VRC) vperm   VRT,VRA,VRB,VRC
+#else
+#define LVS(VRT,RA,RB)         lvsr    VRT,RA,RB
+#define VPERM(VRT,VRA,VRB,VRC) vperm   VRT,VRB,VRA,VRC
+#endif
+
 #ifdef CONFIG_ALTIVEC
        cmpldi  r5,16
        cmpldi  cr1,r5,4096
@@ -485,13 +494,13 @@ _GLOBAL(memcpy_power7)
        li      r10,32
        li      r11,48
 
-       lvsl    vr16,0,r4       /* Setup permute control vector */
+       LVS(vr16,0,r4)          /* Setup permute control vector */
        lvx     vr0,0,r4
        addi    r4,r4,16
 
        bf      cr7*4+3,5f
        lvx     vr1,r0,r4
-       vperm   vr8,vr0,vr1,vr16
+       VPERM(vr8,vr0,vr1,vr16)
        addi    r4,r4,16
        stvx    vr8,r0,r3
        addi    r3,r3,16
@@ -499,9 +508,9 @@ _GLOBAL(memcpy_power7)
 
 5:     bf      cr7*4+2,6f
        lvx     vr1,r0,r4
-       vperm   vr8,vr0,vr1,vr16
+       VPERM(vr8,vr0,vr1,vr16)
        lvx     vr0,r4,r9
-       vperm   vr9,vr1,vr0,vr16
+       VPERM(vr9,vr1,vr0,vr16)
        addi    r4,r4,32
        stvx    vr8,r0,r3
        stvx    vr9,r3,r9
@@ -509,13 +518,13 @@ _GLOBAL(memcpy_power7)
 
 6:     bf      cr7*4+1,7f
        lvx     vr3,r0,r4
-       vperm   vr8,vr0,vr3,vr16
+       VPERM(vr8,vr0,vr3,vr16)
        lvx     vr2,r4,r9
-       vperm   vr9,vr3,vr2,vr16
+       VPERM(vr9,vr3,vr2,vr16)
        lvx     vr1,r4,r10
-       vperm   vr10,vr2,vr1,vr16
+       VPERM(vr10,vr2,vr1,vr16)
        lvx     vr0,r4,r11
-       vperm   vr11,vr1,vr0,vr16
+       VPERM(vr11,vr1,vr0,vr16)
        addi    r4,r4,64
        stvx    vr8,r0,r3
        stvx    vr9,r3,r9
@@ -544,21 +553,21 @@ _GLOBAL(memcpy_power7)
        .align  5
 8:
        lvx     vr7,r0,r4
-       vperm   vr8,vr0,vr7,vr16
+       VPERM(vr8,vr0,vr7,vr16)
        lvx     vr6,r4,r9
-       vperm   vr9,vr7,vr6,vr16
+       VPERM(vr9,vr7,vr6,vr16)
        lvx     vr5,r4,r10
-       vperm   vr10,vr6,vr5,vr16
+       VPERM(vr10,vr6,vr5,vr16)
        lvx     vr4,r4,r11
-       vperm   vr11,vr5,vr4,vr16
+       VPERM(vr11,vr5,vr4,vr16)
        lvx     vr3,r4,r12
-       vperm   vr12,vr4,vr3,vr16
+       VPERM(vr12,vr4,vr3,vr16)
        lvx     vr2,r4,r14
-       vperm   vr13,vr3,vr2,vr16
+       VPERM(vr13,vr3,vr2,vr16)
        lvx     vr1,r4,r15
-       vperm   vr14,vr2,vr1,vr16
+       VPERM(vr14,vr2,vr1,vr16)
        lvx     vr0,r4,r16
-       vperm   vr15,vr1,vr0,vr16
+       VPERM(vr15,vr1,vr0,vr16)
        addi    r4,r4,128
        stvx    vr8,r0,r3
        stvx    vr9,r3,r9
@@ -582,13 +591,13 @@ _GLOBAL(memcpy_power7)
 
        bf      cr7*4+1,9f
        lvx     vr3,r0,r4
-       vperm   vr8,vr0,vr3,vr16
+       VPERM(vr8,vr0,vr3,vr16)
        lvx     vr2,r4,r9
-       vperm   vr9,vr3,vr2,vr16
+       VPERM(vr9,vr3,vr2,vr16)
        lvx     vr1,r4,r10
-       vperm   vr10,vr2,vr1,vr16
+       VPERM(vr10,vr2,vr1,vr16)
        lvx     vr0,r4,r11
-       vperm   vr11,vr1,vr0,vr16
+       VPERM(vr11,vr1,vr0,vr16)
        addi    r4,r4,64
        stvx    vr8,r0,r3
        stvx    vr9,r3,r9
@@ -598,9 +607,9 @@ _GLOBAL(memcpy_power7)
 
 9:     bf      cr7*4+2,10f
        lvx     vr1,r0,r4
-       vperm   vr8,vr0,vr1,vr16
+       VPERM(vr8,vr0,vr1,vr16)
        lvx     vr0,r4,r9
-       vperm   vr9,vr1,vr0,vr16
+       VPERM(vr9,vr1,vr0,vr16)
        addi    r4,r4,32
        stvx    vr8,r0,r3
        stvx    vr9,r3,r9
@@ -608,7 +617,7 @@ _GLOBAL(memcpy_power7)
 
 10:    bf      cr7*4+3,11f
        lvx     vr1,r0,r4
-       vperm   vr8,vr0,vr1,vr16
+       VPERM(vr8,vr0,vr1,vr16)
        addi    r4,r4,16
        stvx    vr8,r0,r3
        addi    r3,r3,16
index b1faa1593c9067e68995e1cdc54dbb8465dce587..c0511c27a7337d757c450361a0682c8d3ef8d68e 100644 (file)
@@ -212,11 +212,19 @@ static int __kprobes read_mem_unaligned(unsigned long *dest, unsigned long ea,
 {
        int err;
        unsigned long x, b, c;
+#ifdef __LITTLE_ENDIAN__
+       int len = nb; /* save a copy of the length for byte reversal */
+#endif
 
        /* unaligned, do this in pieces */
        x = 0;
        for (; nb > 0; nb -= c) {
+#ifdef __LITTLE_ENDIAN__
+               c = 1;
+#endif
+#ifdef __BIG_ENDIAN__
                c = max_align(ea);
+#endif
                if (c > nb)
                        c = max_align(nb);
                err = read_mem_aligned(&b, ea, c);
@@ -225,7 +233,24 @@ static int __kprobes read_mem_unaligned(unsigned long *dest, unsigned long ea,
                x = (x << (8 * c)) + b;
                ea += c;
        }
+#ifdef __LITTLE_ENDIAN__
+       switch (len) {
+       case 2:
+               *dest = byterev_2(x);
+               break;
+       case 4:
+               *dest = byterev_4(x);
+               break;
+#ifdef __powerpc64__
+       case 8:
+               *dest = byterev_8(x);
+               break;
+#endif
+       }
+#endif
+#ifdef __BIG_ENDIAN__
        *dest = x;
+#endif
        return 0;
 }
 
@@ -273,9 +298,29 @@ static int __kprobes write_mem_unaligned(unsigned long val, unsigned long ea,
        int err;
        unsigned long c;
 
+#ifdef __LITTLE_ENDIAN__
+       switch (nb) {
+       case 2:
+               val = byterev_2(val);
+               break;
+       case 4:
+               val = byterev_4(val);
+               break;
+#ifdef __powerpc64__
+       case 8:
+               val = byterev_8(val);
+               break;
+#endif
+       }
+#endif
        /* unaligned or little-endian, do this in pieces */
        for (; nb > 0; nb -= c) {
+#ifdef __LITTLE_ENDIAN__
+               c = 1;
+#endif
+#ifdef __BIG_ENDIAN__
                c = max_align(ea);
+#endif
                if (c > nb)
                        c = max_align(nb);
                err = write_mem_aligned(val >> (nb - c) * 8, ea, c);
@@ -310,22 +355,36 @@ static int __kprobes do_fp_load(int rn, int (*func)(int, unsigned long),
                                struct pt_regs *regs)
 {
        int err;
-       unsigned long val[sizeof(double) / sizeof(long)];
+       union {
+               double dbl;
+               unsigned long ul[2];
+               struct {
+#ifdef __BIG_ENDIAN__
+                       unsigned _pad_;
+                       unsigned word;
+#endif
+#ifdef __LITTLE_ENDIAN__
+                       unsigned word;
+                       unsigned _pad_;
+#endif
+               } single;
+       } data;
        unsigned long ptr;
 
        if (!address_ok(regs, ea, nb))
                return -EFAULT;
        if ((ea & 3) == 0)
                return (*func)(rn, ea);
-       ptr = (unsigned long) &val[0];
+       ptr = (unsigned long) &data.ul;
        if (sizeof(unsigned long) == 8 || nb == 4) {
-               err = read_mem_unaligned(&val[0], ea, nb, regs);
-               ptr += sizeof(unsigned long) - nb;
+               err = read_mem_unaligned(&data.ul[0], ea, nb, regs);
+               if (nb == 4)
+                       ptr = (unsigned long)&(data.single.word);
        } else {
                /* reading a double on 32-bit */
-               err = read_mem_unaligned(&val[0], ea, 4, regs);
+               err = read_mem_unaligned(&data.ul[0], ea, 4, regs);
                if (!err)
-                       err = read_mem_unaligned(&val[1], ea + 4, 4, regs);
+                       err = read_mem_unaligned(&data.ul[1], ea + 4, 4, regs);
        }
        if (err)
                return err;
@@ -337,28 +396,42 @@ static int __kprobes do_fp_store(int rn, int (*func)(int, unsigned long),
                                 struct pt_regs *regs)
 {
        int err;
-       unsigned long val[sizeof(double) / sizeof(long)];
+       union {
+               double dbl;
+               unsigned long ul[2];
+               struct {
+#ifdef __BIG_ENDIAN__
+                       unsigned _pad_;
+                       unsigned word;
+#endif
+#ifdef __LITTLE_ENDIAN__
+                       unsigned word;
+                       unsigned _pad_;
+#endif
+               } single;
+       } data;
        unsigned long ptr;
 
        if (!address_ok(regs, ea, nb))
                return -EFAULT;
        if ((ea & 3) == 0)
                return (*func)(rn, ea);
-       ptr = (unsigned long) &val[0];
+       ptr = (unsigned long) &data.ul[0];
        if (sizeof(unsigned long) == 8 || nb == 4) {
-               ptr += sizeof(unsigned long) - nb;
+               if (nb == 4)
+                       ptr = (unsigned long)&(data.single.word);
                err = (*func)(rn, ptr);
                if (err)
                        return err;
-               err = write_mem_unaligned(val[0], ea, nb, regs);
+               err = write_mem_unaligned(data.ul[0], ea, nb, regs);
        } else {
                /* writing a double on 32-bit */
                err = (*func)(rn, ptr);
                if (err)
                        return err;
-               err = write_mem_unaligned(val[0], ea, 4, regs);
+               err = write_mem_unaligned(data.ul[0], ea, 4, regs);
                if (!err)
-                       err = write_mem_unaligned(val[1], ea + 4, 4, regs);
+                       err = write_mem_unaligned(data.ul[1], ea + 4, 4, regs);
        }
        return err;
 }
diff --git a/arch/powerpc/lib/xor_vmx.c b/arch/powerpc/lib/xor_vmx.c
new file mode 100644 (file)
index 0000000..e905f7c
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * 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.
+ *
+ * Copyright (C) IBM Corporation, 2012
+ *
+ * Author: Anton Blanchard <anton@au.ibm.com>
+ */
+#include <altivec.h>
+
+#include <linux/preempt.h>
+#include <linux/export.h>
+#include <linux/sched.h>
+#include <asm/switch_to.h>
+
+typedef vector signed char unative_t;
+
+#define DEFINE(V)                              \
+       unative_t *V = (unative_t *)V##_in;     \
+       unative_t V##_0, V##_1, V##_2, V##_3
+
+#define LOAD(V)                        \
+       do {                    \
+               V##_0 = V[0];   \
+               V##_1 = V[1];   \
+               V##_2 = V[2];   \
+               V##_3 = V[3];   \
+       } while (0)
+
+#define STORE(V)               \
+       do {                    \
+               V[0] = V##_0;   \
+               V[1] = V##_1;   \
+               V[2] = V##_2;   \
+               V[3] = V##_3;   \
+       } while (0)
+
+#define XOR(V1, V2)                                    \
+       do {                                            \
+               V1##_0 = vec_xor(V1##_0, V2##_0);       \
+               V1##_1 = vec_xor(V1##_1, V2##_1);       \
+               V1##_2 = vec_xor(V1##_2, V2##_2);       \
+               V1##_3 = vec_xor(V1##_3, V2##_3);       \
+       } while (0)
+
+void xor_altivec_2(unsigned long bytes, unsigned long *v1_in,
+                  unsigned long *v2_in)
+{
+       DEFINE(v1);
+       DEFINE(v2);
+       unsigned long lines = bytes / (sizeof(unative_t)) / 4;
+
+       preempt_disable();
+       enable_kernel_altivec();
+
+       do {
+               LOAD(v1);
+               LOAD(v2);
+               XOR(v1, v2);
+               STORE(v1);
+
+               v1 += 4;
+               v2 += 4;
+       } while (--lines > 0);
+
+       preempt_enable();
+}
+EXPORT_SYMBOL(xor_altivec_2);
+
+void xor_altivec_3(unsigned long bytes, unsigned long *v1_in,
+                  unsigned long *v2_in, unsigned long *v3_in)
+{
+       DEFINE(v1);
+       DEFINE(v2);
+       DEFINE(v3);
+       unsigned long lines = bytes / (sizeof(unative_t)) / 4;
+
+       preempt_disable();
+       enable_kernel_altivec();
+
+       do {
+               LOAD(v1);
+               LOAD(v2);
+               LOAD(v3);
+               XOR(v1, v2);
+               XOR(v1, v3);
+               STORE(v1);
+
+               v1 += 4;
+               v2 += 4;
+               v3 += 4;
+       } while (--lines > 0);
+
+       preempt_enable();
+}
+EXPORT_SYMBOL(xor_altivec_3);
+
+void xor_altivec_4(unsigned long bytes, unsigned long *v1_in,
+                  unsigned long *v2_in, unsigned long *v3_in,
+                  unsigned long *v4_in)
+{
+       DEFINE(v1);
+       DEFINE(v2);
+       DEFINE(v3);
+       DEFINE(v4);
+       unsigned long lines = bytes / (sizeof(unative_t)) / 4;
+
+       preempt_disable();
+       enable_kernel_altivec();
+
+       do {
+               LOAD(v1);
+               LOAD(v2);
+               LOAD(v3);
+               LOAD(v4);
+               XOR(v1, v2);
+               XOR(v3, v4);
+               XOR(v1, v3);
+               STORE(v1);
+
+               v1 += 4;
+               v2 += 4;
+               v3 += 4;
+               v4 += 4;
+       } while (--lines > 0);
+
+       preempt_enable();
+}
+EXPORT_SYMBOL(xor_altivec_4);
+
+void xor_altivec_5(unsigned long bytes, unsigned long *v1_in,
+                  unsigned long *v2_in, unsigned long *v3_in,
+                  unsigned long *v4_in, unsigned long *v5_in)
+{
+       DEFINE(v1);
+       DEFINE(v2);
+       DEFINE(v3);
+       DEFINE(v4);
+       DEFINE(v5);
+       unsigned long lines = bytes / (sizeof(unative_t)) / 4;
+
+       preempt_disable();
+       enable_kernel_altivec();
+
+       do {
+               LOAD(v1);
+               LOAD(v2);
+               LOAD(v3);
+               LOAD(v4);
+               LOAD(v5);
+               XOR(v1, v2);
+               XOR(v3, v4);
+               XOR(v1, v5);
+               XOR(v1, v3);
+               STORE(v1);
+
+               v1 += 4;
+               v2 += 4;
+               v3 += 4;
+               v4 += 4;
+               v5 += 4;
+       } while (--lines > 0);
+
+       preempt_enable();
+}
+EXPORT_SYMBOL(xor_altivec_5);
index c33d939120c970f3f800b42b5dfa3739e28ac16f..3ea26c25590be1dabe4a057882f35b77f5dfe7c1 100644 (file)
 #define DBG_LOW(fmt...)
 #endif
 
+#ifdef __BIG_ENDIAN__
 #define HPTE_LOCK_BIT 3
+#else
+#define HPTE_LOCK_BIT (56+3)
+#endif
 
 DEFINE_RAW_SPINLOCK(native_tlbie_lock);
 
@@ -172,7 +176,7 @@ static inline void tlbie(unsigned long vpn, int psize, int apsize,
 
 static inline void native_lock_hpte(struct hash_pte *hptep)
 {
-       unsigned long *word = &hptep->v;
+       unsigned long *word = (unsigned long *)&hptep->v;
 
        while (1) {
                if (!test_and_set_bit_lock(HPTE_LOCK_BIT, word))
@@ -184,7 +188,7 @@ static inline void native_lock_hpte(struct hash_pte *hptep)
 
 static inline void native_unlock_hpte(struct hash_pte *hptep)
 {
-       unsigned long *word = &hptep->v;
+       unsigned long *word = (unsigned long *)&hptep->v;
 
        clear_bit_unlock(HPTE_LOCK_BIT, word);
 }
@@ -204,10 +208,10 @@ static long native_hpte_insert(unsigned long hpte_group, unsigned long vpn,
        }
 
        for (i = 0; i < HPTES_PER_GROUP; i++) {
-               if (! (hptep->v & HPTE_V_VALID)) {
+               if (! (be64_to_cpu(hptep->v) & HPTE_V_VALID)) {
                        /* retry with lock held */
                        native_lock_hpte(hptep);
-                       if (! (hptep->v & HPTE_V_VALID))
+                       if (! (be64_to_cpu(hptep->v) & HPTE_V_VALID))
                                break;
                        native_unlock_hpte(hptep);
                }
@@ -226,14 +230,14 @@ static long native_hpte_insert(unsigned long hpte_group, unsigned long vpn,
                        i, hpte_v, hpte_r);
        }
 
-       hptep->r = hpte_r;
+       hptep->r = cpu_to_be64(hpte_r);
        /* Guarantee the second dword is visible before the valid bit */
        eieio();
        /*
         * Now set the first dword including the valid bit
         * NOTE: this also unlocks the hpte
         */
-       hptep->v = hpte_v;
+       hptep->v = cpu_to_be64(hpte_v);
 
        __asm__ __volatile__ ("ptesync" : : : "memory");
 
@@ -254,12 +258,12 @@ static long native_hpte_remove(unsigned long hpte_group)
 
        for (i = 0; i < HPTES_PER_GROUP; i++) {
                hptep = htab_address + hpte_group + slot_offset;
-               hpte_v = hptep->v;
+               hpte_v = be64_to_cpu(hptep->v);
 
                if ((hpte_v & HPTE_V_VALID) && !(hpte_v & HPTE_V_BOLTED)) {
                        /* retry with lock held */
                        native_lock_hpte(hptep);
-                       hpte_v = hptep->v;
+                       hpte_v = be64_to_cpu(hptep->v);
                        if ((hpte_v & HPTE_V_VALID)
                            && !(hpte_v & HPTE_V_BOLTED))
                                break;
@@ -294,7 +298,7 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
 
        native_lock_hpte(hptep);
 
-       hpte_v = hptep->v;
+       hpte_v = be64_to_cpu(hptep->v);
        /*
         * We need to invalidate the TLB always because hpte_remove doesn't do
         * a tlb invalidate. If a hash bucket gets full, we "evict" a more/less
@@ -308,8 +312,8 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
        } else {
                DBG_LOW(" -> hit\n");
                /* Update the HPTE */
-               hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) |
-                       (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C));
+               hptep->r = cpu_to_be64((be64_to_cpu(hptep->r) & ~(HPTE_R_PP | HPTE_R_N)) |
+                       (newpp & (HPTE_R_PP | HPTE_R_N | HPTE_R_C)));
        }
        native_unlock_hpte(hptep);
 
@@ -334,7 +338,7 @@ static long native_hpte_find(unsigned long vpn, int psize, int ssize)
        slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
        for (i = 0; i < HPTES_PER_GROUP; i++) {
                hptep = htab_address + slot;
-               hpte_v = hptep->v;
+               hpte_v = be64_to_cpu(hptep->v);
 
                if (HPTE_V_COMPARE(hpte_v, want_v) && (hpte_v & HPTE_V_VALID))
                        /* HPTE matches */
@@ -369,8 +373,9 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
        hptep = htab_address + slot;
 
        /* Update the HPTE */
-       hptep->r = (hptep->r & ~(HPTE_R_PP | HPTE_R_N)) |
-               (newpp & (HPTE_R_PP | HPTE_R_N));
+       hptep->r = cpu_to_be64((be64_to_cpu(hptep->r) &
+                       ~(HPTE_R_PP | HPTE_R_N)) |
+               (newpp & (HPTE_R_PP | HPTE_R_N)));
        /*
         * Ensure it is out of the tlb too. Bolted entries base and
         * actual page size will be same.
@@ -392,7 +397,7 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn,
 
        want_v = hpte_encode_avpn(vpn, bpsize, ssize);
        native_lock_hpte(hptep);
-       hpte_v = hptep->v;
+       hpte_v = be64_to_cpu(hptep->v);
 
        /*
         * We need to invalidate the TLB always because hpte_remove doesn't do
@@ -458,7 +463,7 @@ static void native_hugepage_invalidate(struct mm_struct *mm,
                hptep = htab_address + slot;
                want_v = hpte_encode_avpn(vpn, psize, ssize);
                native_lock_hpte(hptep);
-               hpte_v = hptep->v;
+               hpte_v = be64_to_cpu(hptep->v);
 
                /* Even if we miss, we need to invalidate the TLB */
                if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID))
@@ -519,11 +524,12 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
                        int *psize, int *apsize, int *ssize, unsigned long *vpn)
 {
        unsigned long avpn, pteg, vpi;
-       unsigned long hpte_v = hpte->v;
+       unsigned long hpte_v = be64_to_cpu(hpte->v);
+       unsigned long hpte_r = be64_to_cpu(hpte->r);
        unsigned long vsid, seg_off;
        int size, a_size, shift;
        /* Look at the 8 bit LP value */
-       unsigned int lp = (hpte->r >> LP_SHIFT) & ((1 << LP_BITS) - 1);
+       unsigned int lp = (hpte_r >> LP_SHIFT) & ((1 << LP_BITS) - 1);
 
        if (!(hpte_v & HPTE_V_LARGE)) {
                size   = MMU_PAGE_4K;
@@ -612,7 +618,7 @@ static void native_hpte_clear(void)
                 * running,  right?  and for crash dump, we probably
                 * don't want to wait for a maybe bad cpu.
                 */
-               hpte_v = hptep->v;
+               hpte_v = be64_to_cpu(hptep->v);
 
                /*
                 * Call __tlbie() here rather than tlbie() since we
@@ -664,7 +670,7 @@ static void native_flush_hash_range(unsigned long number, int local)
                        hptep = htab_address + slot;
                        want_v = hpte_encode_avpn(vpn, psize, ssize);
                        native_lock_hpte(hptep);
-                       hpte_v = hptep->v;
+                       hpte_v = be64_to_cpu(hptep->v);
                        if (!HPTE_V_COMPARE(hpte_v, want_v) ||
                            !(hpte_v & HPTE_V_VALID))
                                native_unlock_hpte(hptep);
index bde8b55897551a60b15ad6017c7910a6cd3278b8..6176b3cdf57991590df2b26f42f27eed593096bb 100644 (file)
@@ -251,19 +251,18 @@ static int __init htab_dt_scan_seg_sizes(unsigned long node,
                                         void *data)
 {
        char *type = of_get_flat_dt_prop(node, "device_type", NULL);
-       u32 *prop;
+       __be32 *prop;
        unsigned long size = 0;
 
        /* We are scanning "cpu" nodes only */
        if (type == NULL || strcmp(type, "cpu") != 0)
                return 0;
 
-       prop = (u32 *)of_get_flat_dt_prop(node, "ibm,processor-segment-sizes",
-                                         &size);
+       prop = of_get_flat_dt_prop(node, "ibm,processor-segment-sizes", &size);
        if (prop == NULL)
                return 0;
        for (; size >= 4; size -= 4, ++prop) {
-               if (prop[0] == 40) {
+               if (be32_to_cpu(prop[0]) == 40) {
                        DBG("1T segment support detected\n");
                        cur_cpu_spec->mmu_features |= MMU_FTR_1T_SEGMENT;
                        return 1;
@@ -307,23 +306,22 @@ static int __init htab_dt_scan_page_sizes(unsigned long node,
                                          void *data)
 {
        char *type = of_get_flat_dt_prop(node, "device_type", NULL);
-       u32 *prop;
+       __be32 *prop;
        unsigned long size = 0;
 
        /* We are scanning "cpu" nodes only */
        if (type == NULL || strcmp(type, "cpu") != 0)
                return 0;
 
-       prop = (u32 *)of_get_flat_dt_prop(node,
-                                         "ibm,segment-page-sizes", &size);
+       prop = of_get_flat_dt_prop(node, "ibm,segment-page-sizes", &size);
        if (prop != NULL) {
                pr_info("Page sizes from device-tree:\n");
                size /= 4;
                cur_cpu_spec->mmu_features &= ~(MMU_FTR_16M_PAGE);
                while(size > 0) {
-                       unsigned int base_shift = prop[0];
-                       unsigned int slbenc = prop[1];
-                       unsigned int lpnum = prop[2];
+                       unsigned int base_shift = be32_to_cpu(prop[0]);
+                       unsigned int slbenc = be32_to_cpu(prop[1]);
+                       unsigned int lpnum = be32_to_cpu(prop[2]);
                        struct mmu_psize_def *def;
                        int idx, base_idx;
 
@@ -356,8 +354,8 @@ static int __init htab_dt_scan_page_sizes(unsigned long node,
                                def->tlbiel = 0;
 
                        while (size > 0 && lpnum) {
-                               unsigned int shift = prop[0];
-                               int penc  = prop[1];
+                               unsigned int shift = be32_to_cpu(prop[0]);
+                               int penc  = be32_to_cpu(prop[1]);
 
                                prop += 2; size -= 2;
                                lpnum--;
@@ -390,8 +388,8 @@ static int __init htab_dt_scan_hugepage_blocks(unsigned long node,
                                        const char *uname, int depth,
                                        void *data) {
        char *type = of_get_flat_dt_prop(node, "device_type", NULL);
-       unsigned long *addr_prop;
-       u32 *page_count_prop;
+       __be64 *addr_prop;
+       __be32 *page_count_prop;
        unsigned int expected_pages;
        long unsigned int phys_addr;
        long unsigned int block_size;
@@ -405,12 +403,12 @@ static int __init htab_dt_scan_hugepage_blocks(unsigned long node,
        page_count_prop = of_get_flat_dt_prop(node, "ibm,expected#pages", NULL);
        if (page_count_prop == NULL)
                return 0;
-       expected_pages = (1 << page_count_prop[0]);
+       expected_pages = (1 << be32_to_cpu(page_count_prop[0]));
        addr_prop = of_get_flat_dt_prop(node, "reg", NULL);
        if (addr_prop == NULL)
                return 0;
-       phys_addr = addr_prop[0];
-       block_size = addr_prop[1];
+       phys_addr = be64_to_cpu(addr_prop[0]);
+       block_size = be64_to_cpu(addr_prop[1]);
        if (block_size != (16 * GB))
                return 0;
        printk(KERN_INFO "Huge page(16GB) memory: "
@@ -534,16 +532,16 @@ static int __init htab_dt_scan_pftsize(unsigned long node,
                                       void *data)
 {
        char *type = of_get_flat_dt_prop(node, "device_type", NULL);
-       u32 *prop;
+       __be32 *prop;
 
        /* We are scanning "cpu" nodes only */
        if (type == NULL || strcmp(type, "cpu") != 0)
                return 0;
 
-       prop = (u32 *)of_get_flat_dt_prop(node, "ibm,pft-size", NULL);
+       prop = of_get_flat_dt_prop(node, "ibm,pft-size", NULL);
        if (prop != NULL) {
                /* pft_size[0] is the NUMA CEC cookie */
-               ppc64_pft_size = prop[1];
+               ppc64_pft_size = be32_to_cpu(prop[1]);
                return 1;
        }
        return 0;
index d47d3dab4870988c77540de11030f747b085fc22..cff59f1bec238bd41fbcd246d6a732ccc357e1ce 100644 (file)
@@ -213,7 +213,12 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
         */
        BUG_ON(first_memblock_base != 0);
 
+#ifdef CONFIG_PIN_TLB
+       /* 8xx can only access 24MB at the moment */
+       memblock_set_current_limit(min_t(u64, first_memblock_size, 0x01800000));
+#else
        /* 8xx can only access 8MB at the moment */
        memblock_set_current_limit(min_t(u64, first_memblock_size, 0x00800000));
+#endif
 }
 #endif /* CONFIG_8xx */
index 8ed035d2edb5a51540d580e4b6a6a5a106b3a5f9..e3734edffa697ac42cf9d4563fb754b8602d3bcd 100644 (file)
@@ -304,5 +304,54 @@ void register_page_bootmem_memmap(unsigned long section_nr,
                                  struct page *start_page, unsigned long size)
 {
 }
-#endif /* CONFIG_SPARSEMEM_VMEMMAP */
 
+/*
+ * We do not have access to the sparsemem vmemmap, so we fallback to
+ * walking the list of sparsemem blocks which we already maintain for
+ * the sake of crashdump. In the long run, we might want to maintain
+ * a tree if performance of that linear walk becomes a problem.
+ *
+ * realmode_pfn_to_page functions can fail due to:
+ * 1) As real sparsemem blocks do not lay in RAM continously (they
+ * are in virtual address space which is not available in the real mode),
+ * the requested page struct can be split between blocks so get_page/put_page
+ * may fail.
+ * 2) When huge pages are used, the get_page/put_page API will fail
+ * in real mode as the linked addresses in the page struct are virtual
+ * too.
+ */
+struct page *realmode_pfn_to_page(unsigned long pfn)
+{
+       struct vmemmap_backing *vmem_back;
+       struct page *page;
+       unsigned long page_size = 1 << mmu_psize_defs[mmu_vmemmap_psize].shift;
+       unsigned long pg_va = (unsigned long) pfn_to_page(pfn);
+
+       for (vmem_back = vmemmap_list; vmem_back; vmem_back = vmem_back->list) {
+               if (pg_va < vmem_back->virt_addr)
+                       continue;
+
+               /* Check that page struct is not split between real pages */
+               if ((pg_va + sizeof(struct page)) >
+                               (vmem_back->virt_addr + page_size))
+                       return NULL;
+
+               page = (struct page *) (vmem_back->phys + pg_va -
+                               vmem_back->virt_addr);
+               return page;
+       }
+
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(realmode_pfn_to_page);
+
+#elif defined(CONFIG_FLATMEM)
+
+struct page *realmode_pfn_to_page(unsigned long pfn)
+{
+       struct page *page = pfn_to_page(pfn);
+       return page;
+}
+EXPORT_SYMBOL_GPL(realmode_pfn_to_page);
+
+#endif /* CONFIG_SPARSEMEM_VMEMMAP/CONFIG_FLATMEM */
index c916127f10c363e68731ec30eb5f98a799a24313..33d67844062cbd6b1923052144aeb7945e528b35 100644 (file)
@@ -195,7 +195,7 @@ static const __be32 *of_get_usable_memory(struct device_node *memory)
        u32 len;
        prop = of_get_property(memory, "linux,drconf-usable-memory", &len);
        if (!prop || len < sizeof(unsigned int))
-               return 0;
+               return NULL;
        return prop;
 }
 
@@ -1154,7 +1154,7 @@ static int hot_add_drconf_scn_to_nid(struct device_node *memory,
  * represented in the device tree as a node (i.e. memory@XXXX) for
  * each memblock.
  */
-int hot_add_node_scn_to_nid(unsigned long scn_addr)
+static int hot_add_node_scn_to_nid(unsigned long scn_addr)
 {
        struct device_node *memory;
        int nid = -1;
@@ -1235,7 +1235,7 @@ static u64 hot_add_drconf_memory_max(void)
         struct device_node *memory = NULL;
         unsigned int drconf_cell_cnt = 0;
         u64 lmb_size = 0;
-       const __be32 *dm = 0;
+       const __be32 *dm = NULL;
 
         memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory");
         if (memory) {
@@ -1535,7 +1535,7 @@ static void topology_work_fn(struct work_struct *work)
 }
 static DECLARE_WORK(topology_work, topology_work_fn);
 
-void topology_schedule_update(void)
+static void topology_schedule_update(void)
 {
        schedule_work(&topology_work);
 }
index edda589795c3e30c09a900261aa11da6f6fea0fe..841e0d00863c94d99cac5c139b887dc97c21cfe1 100644 (file)
@@ -32,8 +32,6 @@
 #include <asm/tlbflush.h>
 #include <asm/tlb.h>
 
-#include "mmu_decl.h"
-
 static inline int is_exec_fault(void)
 {
        return current->thread.regs && TRAP(current->thread.regs) == 0x400;
@@ -72,7 +70,7 @@ struct page * maybe_pte_to_page(pte_t pte)
  * support falls into the same category.
  */
 
-static pte_t set_pte_filter(pte_t pte, unsigned long addr)
+static pte_t set_pte_filter(pte_t pte)
 {
        pte = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS);
        if (pte_looks_normal(pte) && !(cpu_has_feature(CPU_FTR_COHERENT_ICACHE) ||
@@ -81,17 +79,6 @@ static pte_t set_pte_filter(pte_t pte, unsigned long addr)
                if (!pg)
                        return pte;
                if (!test_bit(PG_arch_1, &pg->flags)) {
-#ifdef CONFIG_8xx
-                       /* On 8xx, cache control instructions (particularly
-                        * "dcbst" from flush_dcache_icache) fault as write
-                        * operation if there is an unpopulated TLB entry
-                        * for the address in question. To workaround that,
-                        * we invalidate the TLB here, thus avoiding dcbst
-                        * misbehaviour.
-                        */
-                       /* 8xx doesn't care about PID, size or ind args */
-                       _tlbil_va(addr, 0, 0, 0);
-#endif /* CONFIG_8xx */
                        flush_dcache_icache_page(pg);
                        set_bit(PG_arch_1, &pg->flags);
                }
@@ -111,7 +98,7 @@ static pte_t set_access_flags_filter(pte_t pte, struct vm_area_struct *vma,
  * as we don't have two bits to spare for _PAGE_EXEC and _PAGE_HWEXEC so
  * instead we "filter out" the exec permission for non clean pages.
  */
-static pte_t set_pte_filter(pte_t pte, unsigned long addr)
+static pte_t set_pte_filter(pte_t pte)
 {
        struct page *pg;
 
@@ -193,7 +180,7 @@ void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep,
         * this context might not have been activated yet when this
         * is called.
         */
-       pte = set_pte_filter(pte, addr);
+       pte = set_pte_filter(pte);
 
        /* Perform the setting of the PTE */
        __set_pte_at(mm, addr, ptep, pte, 0);
index 8a5dfaf5c6b73fc94c7ceab634d1bf679a4f06b1..9aee27c582dcbcbd34a7f9acd2f0aabe6ffb3445 100644 (file)
@@ -39,6 +39,7 @@
 #define r_X            5
 #define r_addr         6
 #define r_scratch1     7
+#define r_scratch2     8
 #define r_D            14
 #define r_HL           15
 #define r_M            16
@@ -92,6 +93,8 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
                                     ___PPC_RA(base) | IMM_L(i))
 #define PPC_LHZ(r, base, i)    EMIT(PPC_INST_LHZ | ___PPC_RT(r) |            \
                                     ___PPC_RA(base) | IMM_L(i))
+#define PPC_LHBRX(r, base, b)  EMIT(PPC_INST_LHBRX | ___PPC_RT(r) |          \
+                                    ___PPC_RA(base) | ___PPC_RB(b))
 /* Convenience helpers for the above with 'far' offsets: */
 #define PPC_LD_OFFS(r, base, i) do { if ((i) < 32768) PPC_LD(r, base, i);     \
                else {  PPC_ADDIS(r, base, IMM_HA(i));                        \
@@ -186,6 +189,14 @@ DECLARE_LOAD_FUNC(sk_load_byte_msh);
                                PPC_ORI(d, d, (uintptr_t)(i) & 0xffff);       \
                } } while (0);
 
+#define PPC_LHBRX_OFFS(r, base, i) \
+               do { PPC_LI32(r, i); PPC_LHBRX(r, r, base); } while(0)
+#ifdef __LITTLE_ENDIAN__
+#define PPC_NTOHS_OFFS(r, base, i)     PPC_LHBRX_OFFS(r, base, i)
+#else
+#define PPC_NTOHS_OFFS(r, base, i)     PPC_LHZ_OFFS(r, base, i)
+#endif
+
 static inline bool is_nearbranch(int offset)
 {
        return (offset < 32768) && (offset >= -32768);
index 7d3a3b5619a2b8f2528b61dc7077b4dd84c594d2..e76eba74d9da8972afeed2525c755959c304dd6f 100644 (file)
@@ -43,8 +43,11 @@ sk_load_word_positive_offset:
        cmpd    r_scratch1, r_addr
        blt     bpf_slow_path_word
        /* Nope, just hitting the header.  cr0 here is eq or gt! */
+#ifdef __LITTLE_ENDIAN__
+       lwbrx   r_A, r_D, r_addr
+#else
        lwzx    r_A, r_D, r_addr
-       /* When big endian we don't need to byteswap. */
+#endif
        blr     /* Return success, cr0 != LT */
 
        .globl  sk_load_half
@@ -56,7 +59,11 @@ sk_load_half_positive_offset:
        subi    r_scratch1, r_HL, 2
        cmpd    r_scratch1, r_addr
        blt     bpf_slow_path_half
+#ifdef __LITTLE_ENDIAN__
+       lhbrx   r_A, r_D, r_addr
+#else
        lhzx    r_A, r_D, r_addr
+#endif
        blr
 
        .globl  sk_load_byte
index 2345bdb4d91784bb2bbdd8ce05d9c3566e48f309..ac3c2a10dafda9e73145dabfbc7181548f288fd5 100644 (file)
 
 #include "bpf_jit.h"
 
-#ifndef __BIG_ENDIAN
-/* There are endianness assumptions herein. */
-#error "Little-endian PPC not supported in BPF compiler"
-#endif
-
 int bpf_jit_enable __read_mostly;
 
-
 static inline void bpf_flush_icache(void *start, void *end)
 {
        smp_wmb();
@@ -193,6 +187,26 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
                                PPC_MUL(r_A, r_A, r_scratch1);
                        }
                        break;
+               case BPF_S_ALU_MOD_X: /* A %= X; */
+                       ctx->seen |= SEEN_XREG;
+                       PPC_CMPWI(r_X, 0);
+                       if (ctx->pc_ret0 != -1) {
+                               PPC_BCC(COND_EQ, addrs[ctx->pc_ret0]);
+                       } else {
+                               PPC_BCC_SHORT(COND_NE, (ctx->idx*4)+12);
+                               PPC_LI(r_ret, 0);
+                               PPC_JMP(exit_addr);
+                       }
+                       PPC_DIVWU(r_scratch1, r_A, r_X);
+                       PPC_MUL(r_scratch1, r_X, r_scratch1);
+                       PPC_SUB(r_A, r_A, r_scratch1);
+                       break;
+               case BPF_S_ALU_MOD_K: /* A %= K; */
+                       PPC_LI32(r_scratch2, K);
+                       PPC_DIVWU(r_scratch1, r_A, r_scratch2);
+                       PPC_MUL(r_scratch1, r_scratch2, r_scratch1);
+                       PPC_SUB(r_A, r_A, r_scratch1);
+                       break;
                case BPF_S_ALU_DIV_X: /* A /= X; */
                        ctx->seen |= SEEN_XREG;
                        PPC_CMPWI(r_X, 0);
@@ -346,18 +360,11 @@ static int bpf_jit_build_body(struct sk_filter *fp, u32 *image,
                        break;
 
                        /*** Ancillary info loads ***/
-
-                       /* None of the BPF_S_ANC* codes appear to be passed by
-                        * sk_chk_filter().  The interpreter and the x86 BPF
-                        * compiler implement them so we do too -- they may be
-                        * planted in future.
-                        */
                case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol); */
                        BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
                                                  protocol) != 2);
-                       PPC_LHZ_OFFS(r_A, r_skb, offsetof(struct sk_buff,
-                                                         protocol));
-                       /* ntohs is a NOP with BE loads. */
+                       PPC_NTOHS_OFFS(r_A, r_skb, offsetof(struct sk_buff,
+                                                           protocol));
                        break;
                case BPF_S_ANC_IFINDEX:
                        PPC_LD_OFFS(r_scratch1, r_skb, offsetof(struct sk_buff,
index a82a41b4fd917895631104627f6b05b333dff8fe..36b5652aada200cc05fe7e12a99e84b989a9d434 100644 (file)
@@ -60,8 +60,6 @@ void mpc512x_restart(char *cmd)
                ;
 }
 
-#if IS_ENABLED(CONFIG_FB_FSL_DIU)
-
 struct fsl_diu_shared_fb {
        u8              gamma[0x300];   /* 32-bit aligned! */
        struct diu_ad   ad0;            /* 32-bit aligned! */
@@ -71,7 +69,7 @@ struct fsl_diu_shared_fb {
 };
 
 #define DIU_DIV_MASK   0x000000ff
-void mpc512x_set_pixel_clock(unsigned int pixclock)
+static void mpc512x_set_pixel_clock(unsigned int pixclock)
 {
        unsigned long bestval, bestfreq, speed, busfreq;
        unsigned long minpixclock, maxpixclock, pixval;
@@ -164,7 +162,7 @@ void mpc512x_set_pixel_clock(unsigned int pixclock)
        iounmap(ccm);
 }
 
-enum fsl_diu_monitor_port
+static enum fsl_diu_monitor_port
 mpc512x_valid_monitor_port(enum fsl_diu_monitor_port port)
 {
        return FSL_DIU_PORT_DVI;
@@ -179,7 +177,7 @@ static inline void mpc512x_free_bootmem(struct page *page)
        free_reserved_page(page);
 }
 
-void mpc512x_release_bootmem(void)
+static void mpc512x_release_bootmem(void)
 {
        unsigned long addr = diu_shared_fb.fb_phys & PAGE_MASK;
        unsigned long size = diu_shared_fb.fb_len;
@@ -205,7 +203,7 @@ void mpc512x_release_bootmem(void)
  * address range will be reserved in setup_arch() after bootmem
  * allocator is up.
  */
-void __init mpc512x_init_diu(void)
+static void __init mpc512x_init_diu(void)
 {
        struct device_node *np;
        struct diu __iomem *diu_reg;
@@ -274,7 +272,7 @@ out:
        iounmap(diu_reg);
 }
 
-void __init mpc512x_setup_diu(void)
+static void __init mpc512x_setup_diu(void)
 {
        int ret;
 
@@ -303,8 +301,6 @@ void __init mpc512x_setup_diu(void)
        diu_ops.release_bootmem         = mpc512x_release_bootmem;
 }
 
-#endif
-
 void __init mpc512x_init_IRQ(void)
 {
        struct device_node *np;
@@ -337,7 +333,7 @@ static struct of_device_id __initdata of_bus_ids[] = {
        {},
 };
 
-void __init mpc512x_declare_of_platform_devices(void)
+static void __init mpc512x_declare_of_platform_devices(void)
 {
        if (of_platform_bus_probe(NULL, of_bus_ids, NULL))
                printk(KERN_ERR __FILE__ ": "
@@ -387,7 +383,7 @@ static unsigned int __init get_fifo_size(struct device_node *np,
                    ((u32)(_base) + sizeof(struct mpc52xx_psc)))
 
 /* Init PSC FIFO space for TX and RX slices */
-void __init mpc512x_psc_fifo_init(void)
+static void __init mpc512x_psc_fifo_init(void)
 {
        struct device_node *np;
        void __iomem *psc;
index 90f4496017e417a2e7952d132c8eb87cba7fcb35..af54174801f7aa9042f12487e5fe94530f8d089a 100644 (file)
@@ -57,5 +57,5 @@ config PPC_MPC5200_BUGFIX
 
 config PPC_MPC5200_LPBFIFO
        tristate "MPC5200 LocalPlus bus FIFO driver"
-       depends on PPC_MPC52xx
+       depends on PPC_MPC52xx && PPC_BESTCOMM
        select PPC_BESTCOMM_GEN_BD
index b69221ba07fd21868dc7c1892384969fb6c03d53..2898b737deb79e5015c7658568a696254d6f23b5 100644 (file)
@@ -340,7 +340,7 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq,
 {
        int l1irq;
        int l2irq;
-       struct irq_chip *irqchip;
+       struct irq_chip *uninitialized_var(irqchip);
        void *hndlr;
        int type;
        u32 reg;
@@ -373,9 +373,8 @@ static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq,
        case MPC52xx_IRQ_L1_PERP: irqchip = &mpc52xx_periph_irqchip; break;
        case MPC52xx_IRQ_L1_SDMA: irqchip = &mpc52xx_sdma_irqchip; break;
        case MPC52xx_IRQ_L1_CRIT:
-       default:
                pr_warn("%s: Critical IRQ #%d is unsupported! Nopping it.\n",
-                       __func__, l1irq);
+                       __func__, l2irq);
                irq_set_chip(virq, &no_irq_chip);
                return 0;
        }
index 7bc3158229357f4e182a2d0f6b3a6c06204e0184..fd71cfdf23802e56f121d6c5dbc6144d3dcbd11f 100644 (file)
@@ -204,7 +204,6 @@ static int mcu_remove(struct i2c_client *client)
        ret = mcu_gpiochip_remove(mcu);
        if (ret)
                return ret;
-       i2c_set_clientdata(client, NULL);
        kfree(mcu);
        return 0;
 }
index de2eb9320993defb0af098ac9ffcc4ae93a96860..4d4634958cfb09107a37829dc19ee65b427a6bab 100644 (file)
@@ -218,83 +218,16 @@ config GE_IMP3A
          This board is a 3U CompactPCI Single Board Computer with a Freescale
          P2020 processor.
 
-config P2041_RDB
-       bool "Freescale P2041 RDB"
-       select DEFAULT_UIMAGE
-       select PPC_E500MC
-       select PHYS_64BIT
-       select SWIOTLB
-       select ARCH_REQUIRE_GPIOLIB
-       select GPIO_MPC8XXX
-       select HAS_RAPIDIO
-       select PPC_EPAPR_HV_PIC
-       help
-         This option enables support for the P2041 RDB board
-
-config P3041_DS
-       bool "Freescale P3041 DS"
-       select DEFAULT_UIMAGE
-       select PPC_E500MC
-       select PHYS_64BIT
-       select SWIOTLB
-       select ARCH_REQUIRE_GPIOLIB
-       select GPIO_MPC8XXX
-       select HAS_RAPIDIO
-       select PPC_EPAPR_HV_PIC
-       help
-         This option enables support for the P3041 DS board
-
-config P4080_DS
-       bool "Freescale P4080 DS"
-       select DEFAULT_UIMAGE
-       select PPC_E500MC
-       select PHYS_64BIT
-       select SWIOTLB
-       select ARCH_REQUIRE_GPIOLIB
-       select GPIO_MPC8XXX
-       select HAS_RAPIDIO
-       select PPC_EPAPR_HV_PIC
-       help
-         This option enables support for the P4080 DS board
-
 config SGY_CTS1000
        tristate "Servergy CTS-1000 support"
        select GPIOLIB
        select OF_GPIO
-       depends on P4080_DS
+       depends on CORENET_GENERIC
        help
          Enable this to support functionality in Servergy's CTS-1000 systems.
 
 endif # PPC32
 
-config P5020_DS
-       bool "Freescale P5020 DS"
-       select DEFAULT_UIMAGE
-       select E500
-       select PPC_E500MC
-       select PHYS_64BIT
-       select SWIOTLB
-       select ARCH_REQUIRE_GPIOLIB
-       select GPIO_MPC8XXX
-       select HAS_RAPIDIO
-       select PPC_EPAPR_HV_PIC
-       help
-         This option enables support for the P5020 DS board
-
-config P5040_DS
-       bool "Freescale P5040 DS"
-       select DEFAULT_UIMAGE
-       select E500
-       select PPC_E500MC
-       select PHYS_64BIT
-       select SWIOTLB
-       select ARCH_REQUIRE_GPIOLIB
-       select GPIO_MPC8XXX
-       select HAS_RAPIDIO
-       select PPC_EPAPR_HV_PIC
-       help
-         This option enables support for the P5040 DS board
-
 config PPC_QEMU_E500
        bool "QEMU generic e500 platform"
        select DEFAULT_UIMAGE
@@ -310,10 +243,8 @@ config PPC_QEMU_E500
          unset based on the emulated CPU (or actual host CPU in the case
          of KVM).
 
-if PPC64
-
-config T4240_QDS
-       bool "Freescale T4240 QDS"
+config CORENET_GENERIC
+       bool "Freescale CoreNet Generic"
        select DEFAULT_UIMAGE
        select E500
        select PPC_E500MC
@@ -324,26 +255,14 @@ config T4240_QDS
        select HAS_RAPIDIO
        select PPC_EPAPR_HV_PIC
        help
-         This option enables support for the T4240 QDS board
-
-config B4_QDS
-       bool "Freescale B4 QDS"
-       select DEFAULT_UIMAGE
-       select E500
-       select PPC_E500MC
-       select PHYS_64BIT
-       select SWIOTLB
-       select GPIOLIB
-       select ARCH_REQUIRE_GPIOLIB
-       select HAS_RAPIDIO
-       select PPC_EPAPR_HV_PIC
-       help
-         This option enables support for the B4 QDS board
-         The B4 application development system B4 QDS is a complete
-         debugging environment intended for engineers developing
-         applications for the B4.
+         This option enables support for the FSL CoreNet based boards.
+         For 32bit kernel, the following boards are supported:
+           P2041 RDB, P3041 DS and P4080 DS
+         For 64bit kernel, the following boards are supported:
+           T4240 QDS and B4 QDS
+         The following boards are supported for both 32bit and 64bit kernel:
+           P5020 DS and P5040 DS
 
-endif
 endif # FSL_SOC_BOOKE
 
 config TQM85xx
index 53c9f75a690733701607999bf24c8925940abc90..dd4c0b59577bb98f0574f5eca765f46a5a5b287c 100644 (file)
@@ -18,13 +18,7 @@ obj-$(CONFIG_P1010_RDB)   += p1010rdb.o
 obj-$(CONFIG_P1022_DS)    += p1022_ds.o
 obj-$(CONFIG_P1022_RDK)   += p1022_rdk.o
 obj-$(CONFIG_P1023_RDS)   += p1023_rds.o
-obj-$(CONFIG_P2041_RDB)   += p2041_rdb.o corenet_ds.o
-obj-$(CONFIG_P3041_DS)    += p3041_ds.o corenet_ds.o
-obj-$(CONFIG_P4080_DS)    += p4080_ds.o corenet_ds.o
-obj-$(CONFIG_P5020_DS)    += p5020_ds.o corenet_ds.o
-obj-$(CONFIG_P5040_DS)    += p5040_ds.o corenet_ds.o
-obj-$(CONFIG_T4240_QDS)   += t4240_qds.o corenet_ds.o
-obj-$(CONFIG_B4_QDS)     += b4_qds.o corenet_ds.o
+obj-$(CONFIG_CORENET_GENERIC)   += corenet_generic.o
 obj-$(CONFIG_STX_GP3)    += stx_gp3.o
 obj-$(CONFIG_TQM85xx)    += tqm85xx.o
 obj-$(CONFIG_SBC8548)     += sbc8548.o
diff --git a/arch/powerpc/platforms/85xx/b4_qds.c b/arch/powerpc/platforms/85xx/b4_qds.c
deleted file mode 100644 (file)
index 0c6702f..0000000
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * B4 QDS Setup
- * Should apply for QDS platform of B4860 and it's personalities.
- * viz B4860/B4420/B4220QDS
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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/kernel.h>
-#include <linux/pci.h>
-#include <linux/kdev_t.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/phy.h>
-
-#include <asm/time.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <mm/mmu_decl.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/mpic.h>
-
-#include <linux/of_platform.h>
-#include <sysdev/fsl_soc.h>
-#include <sysdev/fsl_pci.h>
-#include <asm/ehv_pic.h>
-
-#include "corenet_ds.h"
-
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init b4_qds_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-#ifdef CONFIG_SMP
-       extern struct smp_ops_t smp_85xx_ops;
-#endif
-
-       if ((of_flat_dt_is_compatible(root, "fsl,B4860QDS")) ||
-               (of_flat_dt_is_compatible(root, "fsl,B4420QDS")) ||
-                       (of_flat_dt_is_compatible(root, "fsl,B4220QDS")))
-               return 1;
-
-       /* Check if we're running under the Freescale hypervisor */
-       if ((of_flat_dt_is_compatible(root, "fsl,B4860QDS-hv")) ||
-               (of_flat_dt_is_compatible(root, "fsl,B4420QDS-hv")) ||
-                       (of_flat_dt_is_compatible(root, "fsl,B4220QDS-hv"))) {
-               ppc_md.init_IRQ = ehv_pic_init;
-               ppc_md.get_irq = ehv_pic_get_irq;
-               ppc_md.restart = fsl_hv_restart;
-               ppc_md.power_off = fsl_hv_halt;
-               ppc_md.halt = fsl_hv_halt;
-#ifdef CONFIG_SMP
-               /*
-                * Disable the timebase sync operations because we can't write
-                * to the timebase registers under the hypervisor.
-                 */
-               smp_85xx_ops.give_timebase = NULL;
-               smp_85xx_ops.take_timebase = NULL;
-#endif
-               return 1;
-       }
-
-       return 0;
-}
-
-define_machine(b4_qds) {
-       .name                   = "B4 QDS",
-       .probe                  = b4_qds_probe,
-       .setup_arch             = corenet_ds_setup_arch,
-       .init_IRQ               = corenet_ds_pic_init,
-#ifdef CONFIG_PCI
-       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
-#endif
-/* coreint doesn't play nice with lazy EE, use legacy mpic for now */
-#ifdef CONFIG_PPC64
-       .get_irq                = mpic_get_irq,
-#else
-       .get_irq                = mpic_get_coreint_irq,
-#endif
-       .restart                = fsl_rstcr_restart,
-       .calibrate_decr         = generic_calibrate_decr,
-       .progress               = udbg_progress,
-#ifdef CONFIG_PPC64
-       .power_save             = book3e_idle,
-#else
-       .power_save             = e500_idle,
-#endif
-};
-
-machine_arch_initcall(b4_qds, corenet_ds_publish_devices);
-
-#ifdef CONFIG_SWIOTLB
-machine_arch_initcall(b4_qds, swiotlb_setup_bus_notifier);
-#endif
diff --git a/arch/powerpc/platforms/85xx/corenet_ds.c b/arch/powerpc/platforms/85xx/corenet_ds.c
deleted file mode 100644 (file)
index aa3690b..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Corenet based SoC DS Setup
- *
- * Maintained by Kumar Gala (see MAINTAINERS for contact information)
- *
- * Copyright 2009-2011 Freescale Semiconductor Inc.
- *
- * 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/kernel.h>
-#include <linux/pci.h>
-#include <linux/kdev_t.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-
-#include <asm/time.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <asm/ppc-pci.h>
-#include <mm/mmu_decl.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/mpic.h>
-
-#include <linux/of_platform.h>
-#include <sysdev/fsl_soc.h>
-#include <sysdev/fsl_pci.h>
-#include "smp.h"
-
-void __init corenet_ds_pic_init(void)
-{
-       struct mpic *mpic;
-       unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU |
-               MPIC_NO_RESET;
-
-       if (ppc_md.get_irq == mpic_get_coreint_irq)
-               flags |= MPIC_ENABLE_COREINT;
-
-       mpic = mpic_alloc(NULL, 0, flags, 0, 512, " OpenPIC  ");
-       BUG_ON(mpic == NULL);
-
-       mpic_init(mpic);
-}
-
-/*
- * Setup the architecture
- */
-void __init corenet_ds_setup_arch(void)
-{
-       mpc85xx_smp_init();
-
-       swiotlb_detect_4g();
-
-       pr_info("%s board from Freescale Semiconductor\n", ppc_md.name);
-}
-
-static const struct of_device_id of_device_ids[] = {
-       {
-               .compatible     = "simple-bus"
-       },
-       {
-               .compatible     = "fsl,srio",
-       },
-       {
-               .compatible     = "fsl,p4080-pcie",
-       },
-       {
-               .compatible     = "fsl,qoriq-pcie-v2.2",
-       },
-       {
-               .compatible     = "fsl,qoriq-pcie-v2.3",
-       },
-       {
-               .compatible     = "fsl,qoriq-pcie-v2.4",
-       },
-       {
-               .compatible     = "fsl,qoriq-pcie-v3.0",
-       },
-       /* The following two are for the Freescale hypervisor */
-       {
-               .name           = "hypervisor",
-       },
-       {
-               .name           = "handles",
-       },
-       {}
-};
-
-int __init corenet_ds_publish_devices(void)
-{
-       return of_platform_bus_probe(NULL, of_device_ids, NULL);
-}
diff --git a/arch/powerpc/platforms/85xx/corenet_ds.h b/arch/powerpc/platforms/85xx/corenet_ds.h
deleted file mode 100644 (file)
index ddd700b..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Corenet based SoC DS Setup
- *
- * Copyright 2009 Freescale Semiconductor Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#ifndef CORENET_DS_H
-#define CORENET_DS_H
-
-extern void __init corenet_ds_pic_init(void);
-extern void __init corenet_ds_setup_arch(void);
-extern int __init corenet_ds_publish_devices(void);
-
-#endif
diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c
new file mode 100644 (file)
index 0000000..fbd871e
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * Corenet based SoC DS Setup
+ *
+ * Maintained by Kumar Gala (see MAINTAINERS for contact information)
+ *
+ * Copyright 2009-2011 Freescale Semiconductor Inc.
+ *
+ * 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/kernel.h>
+#include <linux/pci.h>
+#include <linux/kdev_t.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/ppc-pci.h>
+#include <mm/mmu_decl.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+#include <asm/mpic.h>
+#include <asm/ehv_pic.h>
+
+#include <linux/of_platform.h>
+#include <sysdev/fsl_soc.h>
+#include <sysdev/fsl_pci.h>
+#include "smp.h"
+
+void __init corenet_gen_pic_init(void)
+{
+       struct mpic *mpic;
+       unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU |
+               MPIC_NO_RESET;
+
+       if (ppc_md.get_irq == mpic_get_coreint_irq)
+               flags |= MPIC_ENABLE_COREINT;
+
+       mpic = mpic_alloc(NULL, 0, flags, 0, 512, " OpenPIC  ");
+       BUG_ON(mpic == NULL);
+
+       mpic_init(mpic);
+}
+
+/*
+ * Setup the architecture
+ */
+void __init corenet_gen_setup_arch(void)
+{
+       mpc85xx_smp_init();
+
+       swiotlb_detect_4g();
+
+       pr_info("%s board from Freescale Semiconductor\n", ppc_md.name);
+}
+
+static const struct of_device_id of_device_ids[] = {
+       {
+               .compatible     = "simple-bus"
+       },
+       {
+               .compatible     = "fsl,srio",
+       },
+       {
+               .compatible     = "fsl,p4080-pcie",
+       },
+       {
+               .compatible     = "fsl,qoriq-pcie-v2.2",
+       },
+       {
+               .compatible     = "fsl,qoriq-pcie-v2.3",
+       },
+       {
+               .compatible     = "fsl,qoriq-pcie-v2.4",
+       },
+       {
+               .compatible     = "fsl,qoriq-pcie-v3.0",
+       },
+       /* The following two are for the Freescale hypervisor */
+       {
+               .name           = "hypervisor",
+       },
+       {
+               .name           = "handles",
+       },
+       {}
+};
+
+int __init corenet_gen_publish_devices(void)
+{
+       return of_platform_bus_probe(NULL, of_device_ids, NULL);
+}
+
+static const char * const boards[] __initconst = {
+       "fsl,P2041RDB",
+       "fsl,P3041DS",
+       "fsl,P4080DS",
+       "fsl,P5020DS",
+       "fsl,P5040DS",
+       "fsl,T4240QDS",
+       "fsl,B4860QDS",
+       "fsl,B4420QDS",
+       "fsl,B4220QDS",
+       NULL
+};
+
+static const char * const hv_boards[] __initconst = {
+       "fsl,P2041RDB-hv",
+       "fsl,P3041DS-hv",
+       "fsl,P4080DS-hv",
+       "fsl,P5020DS-hv",
+       "fsl,P5040DS-hv",
+       "fsl,T4240QDS-hv",
+       "fsl,B4860QDS-hv",
+       "fsl,B4420QDS-hv",
+       "fsl,B4220QDS-hv",
+       NULL
+};
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init corenet_generic_probe(void)
+{
+       unsigned long root = of_get_flat_dt_root();
+#ifdef CONFIG_SMP
+       extern struct smp_ops_t smp_85xx_ops;
+#endif
+
+       if (of_flat_dt_match(root, boards))
+               return 1;
+
+       /* Check if we're running under the Freescale hypervisor */
+       if (of_flat_dt_match(root, hv_boards)) {
+               ppc_md.init_IRQ = ehv_pic_init;
+               ppc_md.get_irq = ehv_pic_get_irq;
+               ppc_md.restart = fsl_hv_restart;
+               ppc_md.power_off = fsl_hv_halt;
+               ppc_md.halt = fsl_hv_halt;
+#ifdef CONFIG_SMP
+               /*
+                * Disable the timebase sync operations because we can't write
+                * to the timebase registers under the hypervisor.
+                 */
+               smp_85xx_ops.give_timebase = NULL;
+               smp_85xx_ops.take_timebase = NULL;
+#endif
+               return 1;
+       }
+
+       return 0;
+}
+
+define_machine(corenet_generic) {
+       .name                   = "CoreNet Generic",
+       .probe                  = corenet_generic_probe,
+       .setup_arch             = corenet_gen_setup_arch,
+       .init_IRQ               = corenet_gen_pic_init,
+#ifdef CONFIG_PCI
+       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+#endif
+       .get_irq                = mpic_get_coreint_irq,
+       .restart                = fsl_rstcr_restart,
+       .calibrate_decr         = generic_calibrate_decr,
+       .progress               = udbg_progress,
+#ifdef CONFIG_PPC64
+       .power_save             = book3e_idle,
+#else
+       .power_save             = e500_idle,
+#endif
+};
+
+machine_arch_initcall(corenet_generic, corenet_gen_publish_devices);
+
+#ifdef CONFIG_SWIOTLB
+machine_arch_initcall(corenet_generic, swiotlb_setup_bus_notifier);
+#endif
index 0252961392d53f308c326b3afab18ef90b68cdbd..d6a3dd3114945676eb89fa4e3e3d91a34a0b1c6c 100644 (file)
@@ -66,6 +66,8 @@ static int __init p1010_rdb_probe(void)
 
        if (of_flat_dt_is_compatible(root, "fsl,P1010RDB"))
                return 1;
+       if (of_flat_dt_is_compatible(root, "fsl,P1010RDB-PB"))
+               return 1;
        return 0;
 }
 
diff --git a/arch/powerpc/platforms/85xx/p2041_rdb.c b/arch/powerpc/platforms/85xx/p2041_rdb.c
deleted file mode 100644 (file)
index 000c089..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * P2041 RDB Setup
- *
- * Copyright 2011 Freescale Semiconductor Inc.
- *
- * 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/kernel.h>
-#include <linux/pci.h>
-#include <linux/kdev_t.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/phy.h>
-
-#include <asm/time.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <mm/mmu_decl.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/mpic.h>
-
-#include <linux/of_platform.h>
-#include <sysdev/fsl_soc.h>
-#include <sysdev/fsl_pci.h>
-#include <asm/ehv_pic.h>
-
-#include "corenet_ds.h"
-
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init p2041_rdb_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-#ifdef CONFIG_SMP
-       extern struct smp_ops_t smp_85xx_ops;
-#endif
-
-       if (of_flat_dt_is_compatible(root, "fsl,P2041RDB"))
-               return 1;
-
-       /* Check if we're running under the Freescale hypervisor */
-       if (of_flat_dt_is_compatible(root, "fsl,P2041RDB-hv")) {
-               ppc_md.init_IRQ = ehv_pic_init;
-               ppc_md.get_irq = ehv_pic_get_irq;
-               ppc_md.restart = fsl_hv_restart;
-               ppc_md.power_off = fsl_hv_halt;
-               ppc_md.halt = fsl_hv_halt;
-#ifdef CONFIG_SMP
-               /*
-                * Disable the timebase sync operations because we can't write
-                * to the timebase registers under the hypervisor.
-                 */
-               smp_85xx_ops.give_timebase = NULL;
-               smp_85xx_ops.take_timebase = NULL;
-#endif
-               return 1;
-       }
-
-       return 0;
-}
-
-define_machine(p2041_rdb) {
-       .name                   = "P2041 RDB",
-       .probe                  = p2041_rdb_probe,
-       .setup_arch             = corenet_ds_setup_arch,
-       .init_IRQ               = corenet_ds_pic_init,
-#ifdef CONFIG_PCI
-       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
-#endif
-       .get_irq                = mpic_get_coreint_irq,
-       .restart                = fsl_rstcr_restart,
-       .calibrate_decr         = generic_calibrate_decr,
-       .progress               = udbg_progress,
-       .power_save             = e500_idle,
-};
-
-machine_arch_initcall(p2041_rdb, corenet_ds_publish_devices);
-
-#ifdef CONFIG_SWIOTLB
-machine_arch_initcall(p2041_rdb, swiotlb_setup_bus_notifier);
-#endif
diff --git a/arch/powerpc/platforms/85xx/p3041_ds.c b/arch/powerpc/platforms/85xx/p3041_ds.c
deleted file mode 100644 (file)
index b3edc20..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * P3041 DS Setup
- *
- * Maintained by Kumar Gala (see MAINTAINERS for contact information)
- *
- * Copyright 2009-2010 Freescale Semiconductor Inc.
- *
- * 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/kernel.h>
-#include <linux/pci.h>
-#include <linux/kdev_t.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/phy.h>
-
-#include <asm/time.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <mm/mmu_decl.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/mpic.h>
-
-#include <linux/of_platform.h>
-#include <sysdev/fsl_soc.h>
-#include <sysdev/fsl_pci.h>
-#include <asm/ehv_pic.h>
-
-#include "corenet_ds.h"
-
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init p3041_ds_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-#ifdef CONFIG_SMP
-       extern struct smp_ops_t smp_85xx_ops;
-#endif
-
-       if (of_flat_dt_is_compatible(root, "fsl,P3041DS"))
-               return 1;
-
-       /* Check if we're running under the Freescale hypervisor */
-       if (of_flat_dt_is_compatible(root, "fsl,P3041DS-hv")) {
-               ppc_md.init_IRQ = ehv_pic_init;
-               ppc_md.get_irq = ehv_pic_get_irq;
-               ppc_md.restart = fsl_hv_restart;
-               ppc_md.power_off = fsl_hv_halt;
-               ppc_md.halt = fsl_hv_halt;
-#ifdef CONFIG_SMP
-               /*
-                * Disable the timebase sync operations because we can't write
-                * to the timebase registers under the hypervisor.
-                 */
-               smp_85xx_ops.give_timebase = NULL;
-               smp_85xx_ops.take_timebase = NULL;
-#endif
-               return 1;
-       }
-
-       return 0;
-}
-
-define_machine(p3041_ds) {
-       .name                   = "P3041 DS",
-       .probe                  = p3041_ds_probe,
-       .setup_arch             = corenet_ds_setup_arch,
-       .init_IRQ               = corenet_ds_pic_init,
-#ifdef CONFIG_PCI
-       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
-#endif
-       .get_irq                = mpic_get_coreint_irq,
-       .restart                = fsl_rstcr_restart,
-       .calibrate_decr         = generic_calibrate_decr,
-       .progress               = udbg_progress,
-       .power_save             = e500_idle,
-};
-
-machine_arch_initcall(p3041_ds, corenet_ds_publish_devices);
-
-#ifdef CONFIG_SWIOTLB
-machine_arch_initcall(p3041_ds, swiotlb_setup_bus_notifier);
-#endif
diff --git a/arch/powerpc/platforms/85xx/p4080_ds.c b/arch/powerpc/platforms/85xx/p4080_ds.c
deleted file mode 100644 (file)
index 54df106..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * P4080 DS Setup
- *
- * Maintained by Kumar Gala (see MAINTAINERS for contact information)
- *
- * Copyright 2009 Freescale Semiconductor Inc.
- *
- * 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/kernel.h>
-#include <linux/pci.h>
-#include <linux/kdev_t.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-
-#include <asm/time.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <mm/mmu_decl.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/mpic.h>
-
-#include <linux/of_platform.h>
-#include <sysdev/fsl_soc.h>
-#include <sysdev/fsl_pci.h>
-#include <asm/ehv_pic.h>
-
-#include "corenet_ds.h"
-
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init p4080_ds_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-#ifdef CONFIG_SMP
-       extern struct smp_ops_t smp_85xx_ops;
-#endif
-
-       if (of_flat_dt_is_compatible(root, "fsl,P4080DS"))
-               return 1;
-
-       /* Check if we're running under the Freescale hypervisor */
-       if (of_flat_dt_is_compatible(root, "fsl,P4080DS-hv")) {
-               ppc_md.init_IRQ = ehv_pic_init;
-               ppc_md.get_irq = ehv_pic_get_irq;
-               ppc_md.restart = fsl_hv_restart;
-               ppc_md.power_off = fsl_hv_halt;
-               ppc_md.halt = fsl_hv_halt;
-#ifdef CONFIG_SMP
-               /*
-                * Disable the timebase sync operations because we can't write
-                * to the timebase registers under the hypervisor.
-                 */
-               smp_85xx_ops.give_timebase = NULL;
-               smp_85xx_ops.take_timebase = NULL;
-#endif
-               return 1;
-       }
-
-       return 0;
-}
-
-define_machine(p4080_ds) {
-       .name                   = "P4080 DS",
-       .probe                  = p4080_ds_probe,
-       .setup_arch             = corenet_ds_setup_arch,
-       .init_IRQ               = corenet_ds_pic_init,
-#ifdef CONFIG_PCI
-       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
-#endif
-       .get_irq                = mpic_get_coreint_irq,
-       .restart                = fsl_rstcr_restart,
-       .calibrate_decr         = generic_calibrate_decr,
-       .progress               = udbg_progress,
-       .power_save             = e500_idle,
-};
-
-machine_arch_initcall(p4080_ds, corenet_ds_publish_devices);
-#ifdef CONFIG_SWIOTLB
-machine_arch_initcall(p4080_ds, swiotlb_setup_bus_notifier);
-#endif
diff --git a/arch/powerpc/platforms/85xx/p5020_ds.c b/arch/powerpc/platforms/85xx/p5020_ds.c
deleted file mode 100644 (file)
index 39cfa40..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * P5020 DS Setup
- *
- * Maintained by Kumar Gala (see MAINTAINERS for contact information)
- *
- * Copyright 2009-2010 Freescale Semiconductor Inc.
- *
- * 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/kernel.h>
-#include <linux/pci.h>
-#include <linux/kdev_t.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/phy.h>
-
-#include <asm/time.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <mm/mmu_decl.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/mpic.h>
-
-#include <linux/of_platform.h>
-#include <sysdev/fsl_soc.h>
-#include <sysdev/fsl_pci.h>
-#include <asm/ehv_pic.h>
-
-#include "corenet_ds.h"
-
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init p5020_ds_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-#ifdef CONFIG_SMP
-       extern struct smp_ops_t smp_85xx_ops;
-#endif
-
-       if (of_flat_dt_is_compatible(root, "fsl,P5020DS"))
-               return 1;
-
-       /* Check if we're running under the Freescale hypervisor */
-       if (of_flat_dt_is_compatible(root, "fsl,P5020DS-hv")) {
-               ppc_md.init_IRQ = ehv_pic_init;
-               ppc_md.get_irq = ehv_pic_get_irq;
-               ppc_md.restart = fsl_hv_restart;
-               ppc_md.power_off = fsl_hv_halt;
-               ppc_md.halt = fsl_hv_halt;
-#ifdef CONFIG_SMP
-               /*
-                * Disable the timebase sync operations because we can't write
-                * to the timebase registers under the hypervisor.
-                 */
-               smp_85xx_ops.give_timebase = NULL;
-               smp_85xx_ops.take_timebase = NULL;
-#endif
-               return 1;
-       }
-
-       return 0;
-}
-
-define_machine(p5020_ds) {
-       .name                   = "P5020 DS",
-       .probe                  = p5020_ds_probe,
-       .setup_arch             = corenet_ds_setup_arch,
-       .init_IRQ               = corenet_ds_pic_init,
-#ifdef CONFIG_PCI
-       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
-#endif
-       .get_irq                = mpic_get_coreint_irq,
-       .restart                = fsl_rstcr_restart,
-       .calibrate_decr         = generic_calibrate_decr,
-       .progress               = udbg_progress,
-#ifdef CONFIG_PPC64
-       .power_save             = book3e_idle,
-#else
-       .power_save             = e500_idle,
-#endif
-};
-
-machine_arch_initcall(p5020_ds, corenet_ds_publish_devices);
-
-#ifdef CONFIG_SWIOTLB
-machine_arch_initcall(p5020_ds, swiotlb_setup_bus_notifier);
-#endif
diff --git a/arch/powerpc/platforms/85xx/p5040_ds.c b/arch/powerpc/platforms/85xx/p5040_ds.c
deleted file mode 100644 (file)
index f70e74c..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * P5040 DS Setup
- *
- * Copyright 2009-2010 Freescale Semiconductor Inc.
- *
- * 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/kernel.h>
-#include <linux/pci.h>
-
-#include <asm/machdep.h>
-#include <asm/udbg.h>
-#include <asm/mpic.h>
-
-#include <linux/of_fdt.h>
-
-#include <sysdev/fsl_soc.h>
-#include <sysdev/fsl_pci.h>
-#include <asm/ehv_pic.h>
-
-#include "corenet_ds.h"
-
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init p5040_ds_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-#ifdef CONFIG_SMP
-       extern struct smp_ops_t smp_85xx_ops;
-#endif
-
-       if (of_flat_dt_is_compatible(root, "fsl,P5040DS"))
-               return 1;
-
-       /* Check if we're running under the Freescale hypervisor */
-       if (of_flat_dt_is_compatible(root, "fsl,P5040DS-hv")) {
-               ppc_md.init_IRQ = ehv_pic_init;
-               ppc_md.get_irq = ehv_pic_get_irq;
-               ppc_md.restart = fsl_hv_restart;
-               ppc_md.power_off = fsl_hv_halt;
-               ppc_md.halt = fsl_hv_halt;
-#ifdef CONFIG_SMP
-               /*
-                * Disable the timebase sync operations because we can't write
-                * to the timebase registers under the hypervisor.
-                 */
-               smp_85xx_ops.give_timebase = NULL;
-               smp_85xx_ops.take_timebase = NULL;
-#endif
-               return 1;
-       }
-
-       return 0;
-}
-
-define_machine(p5040_ds) {
-       .name                   = "P5040 DS",
-       .probe                  = p5040_ds_probe,
-       .setup_arch             = corenet_ds_setup_arch,
-       .init_IRQ               = corenet_ds_pic_init,
-#ifdef CONFIG_PCI
-       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
-#endif
-       .get_irq                = mpic_get_coreint_irq,
-       .restart                = fsl_rstcr_restart,
-       .calibrate_decr         = generic_calibrate_decr,
-       .progress               = udbg_progress,
-#ifdef CONFIG_PPC64
-       .power_save             = book3e_idle,
-#else
-       .power_save             = e500_idle,
-#endif
-};
-
-machine_arch_initcall(p5040_ds, corenet_ds_publish_devices);
-
-#ifdef CONFIG_SWIOTLB
-machine_arch_initcall(p5040_ds, swiotlb_setup_bus_notifier);
-#endif
diff --git a/arch/powerpc/platforms/85xx/t4240_qds.c b/arch/powerpc/platforms/85xx/t4240_qds.c
deleted file mode 100644 (file)
index 91ead6b..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * T4240 QDS Setup
- *
- * Maintained by Kumar Gala (see MAINTAINERS for contact information)
- *
- * Copyright 2012 Freescale Semiconductor Inc.
- *
- * 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/kernel.h>
-#include <linux/pci.h>
-#include <linux/kdev_t.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/phy.h>
-
-#include <asm/time.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <mm/mmu_decl.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/mpic.h>
-
-#include <linux/of_platform.h>
-#include <sysdev/fsl_soc.h>
-#include <sysdev/fsl_pci.h>
-#include <asm/ehv_pic.h>
-
-#include "corenet_ds.h"
-
-/*
- * Called very early, device-tree isn't unflattened
- */
-static int __init t4240_qds_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-#ifdef CONFIG_SMP
-       extern struct smp_ops_t smp_85xx_ops;
-#endif
-
-       if (of_flat_dt_is_compatible(root, "fsl,T4240QDS"))
-               return 1;
-
-       /* Check if we're running under the Freescale hypervisor */
-       if (of_flat_dt_is_compatible(root, "fsl,T4240QDS-hv")) {
-               ppc_md.init_IRQ = ehv_pic_init;
-               ppc_md.get_irq = ehv_pic_get_irq;
-               ppc_md.restart = fsl_hv_restart;
-               ppc_md.power_off = fsl_hv_halt;
-               ppc_md.halt = fsl_hv_halt;
-#ifdef CONFIG_SMP
-               /*
-                * Disable the timebase sync operations because we can't write
-                * to the timebase registers under the hypervisor.
-                 */
-               smp_85xx_ops.give_timebase = NULL;
-               smp_85xx_ops.take_timebase = NULL;
-#endif
-               return 1;
-       }
-
-       return 0;
-}
-
-define_machine(t4240_qds) {
-       .name                   = "T4240 QDS",
-       .probe                  = t4240_qds_probe,
-       .setup_arch             = corenet_ds_setup_arch,
-       .init_IRQ               = corenet_ds_pic_init,
-#ifdef CONFIG_PCI
-       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
-#endif
-       .get_irq                = mpic_get_coreint_irq,
-       .restart                = fsl_rstcr_restart,
-       .calibrate_decr         = generic_calibrate_decr,
-       .progress               = udbg_progress,
-#ifdef CONFIG_PPC64
-       .power_save             = book3e_idle,
-#else
-       .power_save             = e500_idle,
-#endif
-};
-
-machine_arch_initcall(t4240_qds, corenet_ds_publish_devices);
-
-#ifdef CONFIG_SWIOTLB
-machine_arch_initcall(t4240_qds, swiotlb_setup_bus_notifier);
-#endif
index 8d21ab70e06c4aec26f55f67fc4d0f1574811970..ef0778a0ca8f996ef0b8d6c86a032c6eb05899f7 100644 (file)
@@ -48,7 +48,7 @@ struct cpm_pin {
        int port, pin, flags;
 };
 
-static struct __initdata cpm_pin tqm8xx_pins[] = {
+static struct cpm_pin tqm8xx_pins[] __initdata = {
        /* SMC1 */
        {CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */
        {CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */
@@ -63,7 +63,7 @@ static struct __initdata cpm_pin tqm8xx_pins[] = {
        {CPM_PORTC, 11, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO},
 };
 
-static struct __initdata cpm_pin tqm8xx_fec_pins[] = {
+static struct cpm_pin tqm8xx_fec_pins[] __initdata = {
        /* MII */
        {CPM_PORTD, 3, CPM_PIN_OUTPUT},
        {CPM_PORTD, 4, CPM_PIN_OUTPUT},
index 6704e2e20e6be1598cf92a990fac17c52144dc51..c2a566fb8bb89cc816b8841fe47fcdf35b222836 100644 (file)
@@ -93,22 +93,23 @@ choice
 
 config GENERIC_CPU
        bool "Generic"
+       depends on !CPU_LITTLE_ENDIAN
 
 config CELL_CPU
        bool "Cell Broadband Engine"
-       depends on PPC_BOOK3S_64
+       depends on PPC_BOOK3S_64 && !CPU_LITTLE_ENDIAN
 
 config POWER4_CPU
        bool "POWER4"
-       depends on PPC_BOOK3S_64
+       depends on PPC_BOOK3S_64 && !CPU_LITTLE_ENDIAN
 
 config POWER5_CPU
        bool "POWER5"
-       depends on PPC_BOOK3S_64
+       depends on PPC_BOOK3S_64 && !CPU_LITTLE_ENDIAN
 
 config POWER6_CPU
        bool "POWER6"
-       depends on PPC_BOOK3S_64
+       depends on PPC_BOOK3S_64 && !CPU_LITTLE_ENDIAN
 
 config POWER7_CPU
        bool "POWER7"
index d3ceff04ffc79c6832b8b96087913e4fa02692e0..9ef8cc3378d0dae581ba8abd19a21bcf6f63a266 100644 (file)
@@ -66,7 +66,7 @@ static void chrp_nvram_write(int addr, unsigned char val)
 void __init chrp_nvram_init(void)
 {
        struct device_node *nvram;
-       const unsigned int *nbytes_p;
+       const __be32 *nbytes_p;
        unsigned int proplen;
 
        nvram = of_find_node_by_type(NULL, "nvram");
@@ -79,7 +79,7 @@ void __init chrp_nvram_init(void)
                return;
        }
 
-       nvram_size = *nbytes_p;
+       nvram_size = be32_to_cpup(nbytes_p);
 
        printk(KERN_INFO "CHRP nvram contains %u bytes\n", nvram_size);
        of_node_put(nvram);
index 3006b5117ec6cab1c7737ae12c5aa8a59f5a8fd3..6f61e21b3617d20ce4503d3713508e48d8bd0230 100644 (file)
@@ -181,6 +181,7 @@ struct irq_domain *hlwd_pic_init(struct device_node *np)
                                           &hlwd_irq_domain_ops, io_base);
        if (!irq_domain) {
                pr_err("failed to allocate irq_domain\n");
+               iounmap(io_base);
                return NULL;
        }
 
index 6fae5eb99ea6febff2fdd465fcf19c64d9114643..9fced3f6d2dcfadbf0f26c71d57693d79b1c78ba 100644 (file)
@@ -9,6 +9,8 @@ config PPC_POWERNV
        select EPAPR_BOOT
        select PPC_INDIRECT_PIO
        select PPC_UDBG_16550
+       select PPC_SCOM
+       select ARCH_RANDOM
        default y
 
 config POWERNV_MSI
index 300c437d713cf1a6b4c73d2b2bb58830483219fe..873fa1370dc44c1b0b3994e7555c4fac450adcbd 100644 (file)
@@ -1,6 +1,8 @@
 obj-y                  += setup.o opal-takeover.o opal-wrappers.o opal.o
-obj-y                  += opal-rtc.o opal-nvram.o opal-lpc.o
+obj-y                  += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
+obj-y                  += rng.o
 
 obj-$(CONFIG_SMP)      += smp.o
 obj-$(CONFIG_PCI)      += pci.o pci-p5ioc2.o pci-ioda.o
 obj-$(CONFIG_EEH)      += eeh-ioda.o eeh-powernv.o
+obj-$(CONFIG_PPC_SCOM) += opal-xscom.o
index cf42e74514fa192e3a8d64ed0d41ada445a974e3..02245cee78183852d52f3a907023dcd9a63529bf 100644 (file)
@@ -59,26 +59,60 @@ static struct notifier_block ioda_eeh_nb = {
 };
 
 #ifdef CONFIG_DEBUG_FS
-static int ioda_eeh_dbgfs_set(void *data, u64 val)
+static int ioda_eeh_dbgfs_set(void *data, int offset, u64 val)
 {
        struct pci_controller *hose = data;
        struct pnv_phb *phb = hose->private_data;
 
-       out_be64(phb->regs + 0xD10, val);
+       out_be64(phb->regs + offset, val);
        return 0;
 }
 
-static int ioda_eeh_dbgfs_get(void *data, u64 *val)
+static int ioda_eeh_dbgfs_get(void *data, int offset, u64 *val)
 {
        struct pci_controller *hose = data;
        struct pnv_phb *phb = hose->private_data;
 
-       *val = in_be64(phb->regs + 0xD10);
+       *val = in_be64(phb->regs + offset);
        return 0;
 }
 
-DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_dbgfs_ops, ioda_eeh_dbgfs_get,
-                       ioda_eeh_dbgfs_set, "0x%llx\n");
+static int ioda_eeh_outb_dbgfs_set(void *data, u64 val)
+{
+       return ioda_eeh_dbgfs_set(data, 0xD10, val);
+}
+
+static int ioda_eeh_outb_dbgfs_get(void *data, u64 *val)
+{
+       return ioda_eeh_dbgfs_get(data, 0xD10, val);
+}
+
+static int ioda_eeh_inbA_dbgfs_set(void *data, u64 val)
+{
+       return ioda_eeh_dbgfs_set(data, 0xD90, val);
+}
+
+static int ioda_eeh_inbA_dbgfs_get(void *data, u64 *val)
+{
+       return ioda_eeh_dbgfs_get(data, 0xD90, val);
+}
+
+static int ioda_eeh_inbB_dbgfs_set(void *data, u64 val)
+{
+       return ioda_eeh_dbgfs_set(data, 0xE10, val);
+}
+
+static int ioda_eeh_inbB_dbgfs_get(void *data, u64 *val)
+{
+       return ioda_eeh_dbgfs_get(data, 0xE10, val);
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_outb_dbgfs_ops, ioda_eeh_outb_dbgfs_get,
+                       ioda_eeh_outb_dbgfs_set, "0x%llx\n");
+DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_inbA_dbgfs_ops, ioda_eeh_inbA_dbgfs_get,
+                       ioda_eeh_inbA_dbgfs_set, "0x%llx\n");
+DEFINE_SIMPLE_ATTRIBUTE(ioda_eeh_inbB_dbgfs_ops, ioda_eeh_inbB_dbgfs_get,
+                       ioda_eeh_inbB_dbgfs_set, "0x%llx\n");
 #endif /* CONFIG_DEBUG_FS */
 
 /**
@@ -106,27 +140,30 @@ static int ioda_eeh_post_init(struct pci_controller *hose)
                ioda_eeh_nb_init = 1;
        }
 
-       /* FIXME: Enable it for PHB3 later */
-       if (phb->type == PNV_PHB_IODA1) {
+       /* We needn't HUB diag-data on PHB3 */
+       if (phb->type == PNV_PHB_IODA1 && !hub_diag) {
+               hub_diag = (char *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
                if (!hub_diag) {
-                       hub_diag = (char *)__get_free_page(GFP_KERNEL |
-                                                          __GFP_ZERO);
-                       if (!hub_diag) {
-                               pr_err("%s: Out of memory !\n",
-                                      __func__);
-                               return -ENOMEM;
-                       }
+                       pr_err("%s: Out of memory !\n", __func__);
+                       return -ENOMEM;
                }
+       }
 
 #ifdef CONFIG_DEBUG_FS
-               if (phb->dbgfs)
-                       debugfs_create_file("err_injct", 0600,
-                                           phb->dbgfs, hose,
-                                           &ioda_eeh_dbgfs_ops);
+       if (phb->dbgfs) {
+               debugfs_create_file("err_injct_outbound", 0600,
+                                   phb->dbgfs, hose,
+                                   &ioda_eeh_outb_dbgfs_ops);
+               debugfs_create_file("err_injct_inboundA", 0600,
+                                   phb->dbgfs, hose,
+                                   &ioda_eeh_inbA_dbgfs_ops);
+               debugfs_create_file("err_injct_inboundB", 0600,
+                                   phb->dbgfs, hose,
+                                   &ioda_eeh_inbB_dbgfs_ops);
+       }
 #endif
 
-               phb->eeh_state |= PNV_EEH_STATE_ENABLED;
-       }
+       phb->eeh_state |= PNV_EEH_STATE_ENABLED;
 
        return 0;
 }
@@ -546,8 +583,8 @@ static int ioda_eeh_get_log(struct eeh_pe *pe, int severity,
                        phb->diag.blob, PNV_PCI_DIAG_BUF_SIZE);
        if (ret) {
                spin_unlock_irqrestore(&phb->lock, flags);
-               pr_warning("%s: Failed to get log for PHB#%x-PE#%x\n",
-                          __func__, hose->global_number, pe->addr);
+               pr_warning("%s: Can't get log for PHB#%x-PE#%x (%lld)\n",
+                          __func__, hose->global_number, pe->addr, ret);
                return -EIO;
        }
 
@@ -710,6 +747,73 @@ static void ioda_eeh_p7ioc_phb_diag(struct pci_controller *hose,
        }
 }
 
+static void ioda_eeh_phb3_phb_diag(struct pci_controller *hose,
+                                   struct OpalIoPhbErrorCommon *common)
+{
+       struct OpalIoPhb3ErrorData *data;
+       int i;
+
+       data = (struct OpalIoPhb3ErrorData*)common;
+       pr_info("PHB3 PHB#%x Diag-data (Version: %d)\n\n",
+               hose->global_number, common->version);
+
+       pr_info("  brdgCtl:              %08x\n", data->brdgCtl);
+
+       pr_info("  portStatusReg:        %08x\n", data->portStatusReg);
+       pr_info("  rootCmplxStatus:      %08x\n", data->rootCmplxStatus);
+       pr_info("  busAgentStatus:       %08x\n", data->busAgentStatus);
+
+       pr_info("  deviceStatus:         %08x\n", data->deviceStatus);
+       pr_info("  slotStatus:           %08x\n", data->slotStatus);
+       pr_info("  linkStatus:           %08x\n", data->linkStatus);
+       pr_info("  devCmdStatus:         %08x\n", data->devCmdStatus);
+       pr_info("  devSecStatus:         %08x\n", data->devSecStatus);
+
+       pr_info("  rootErrorStatus:      %08x\n", data->rootErrorStatus);
+       pr_info("  uncorrErrorStatus:    %08x\n", data->uncorrErrorStatus);
+       pr_info("  corrErrorStatus:      %08x\n", data->corrErrorStatus);
+       pr_info("  tlpHdr1:              %08x\n", data->tlpHdr1);
+       pr_info("  tlpHdr2:              %08x\n", data->tlpHdr2);
+       pr_info("  tlpHdr3:              %08x\n", data->tlpHdr3);
+       pr_info("  tlpHdr4:              %08x\n", data->tlpHdr4);
+       pr_info("  sourceId:             %08x\n", data->sourceId);
+       pr_info("  errorClass:           %016llx\n", data->errorClass);
+       pr_info("  correlator:           %016llx\n", data->correlator);
+       pr_info("  nFir:                 %016llx\n", data->nFir);
+       pr_info("  nFirMask:             %016llx\n", data->nFirMask);
+       pr_info("  nFirWOF:              %016llx\n", data->nFirWOF);
+       pr_info("  PhbPlssr:             %016llx\n", data->phbPlssr);
+       pr_info("  PhbCsr:               %016llx\n", data->phbCsr);
+       pr_info("  lemFir:               %016llx\n", data->lemFir);
+       pr_info("  lemErrorMask:         %016llx\n", data->lemErrorMask);
+       pr_info("  lemWOF:               %016llx\n", data->lemWOF);
+       pr_info("  phbErrorStatus:       %016llx\n", data->phbErrorStatus);
+       pr_info("  phbFirstErrorStatus:  %016llx\n", data->phbFirstErrorStatus);
+       pr_info("  phbErrorLog0:         %016llx\n", data->phbErrorLog0);
+       pr_info("  phbErrorLog1:         %016llx\n", data->phbErrorLog1);
+       pr_info("  mmioErrorStatus:      %016llx\n", data->mmioErrorStatus);
+       pr_info("  mmioFirstErrorStatus: %016llx\n", data->mmioFirstErrorStatus);
+       pr_info("  mmioErrorLog0:        %016llx\n", data->mmioErrorLog0);
+       pr_info("  mmioErrorLog1:        %016llx\n", data->mmioErrorLog1);
+       pr_info("  dma0ErrorStatus:      %016llx\n", data->dma0ErrorStatus);
+       pr_info("  dma0FirstErrorStatus: %016llx\n", data->dma0FirstErrorStatus);
+       pr_info("  dma0ErrorLog0:        %016llx\n", data->dma0ErrorLog0);
+       pr_info("  dma0ErrorLog1:        %016llx\n", data->dma0ErrorLog1);
+       pr_info("  dma1ErrorStatus:      %016llx\n", data->dma1ErrorStatus);
+       pr_info("  dma1FirstErrorStatus: %016llx\n", data->dma1FirstErrorStatus);
+       pr_info("  dma1ErrorLog0:        %016llx\n", data->dma1ErrorLog0);
+       pr_info("  dma1ErrorLog1:        %016llx\n", data->dma1ErrorLog1);
+
+       for (i = 0; i < OPAL_PHB3_NUM_PEST_REGS; i++) {
+               if ((data->pestA[i] >> 63) == 0 &&
+                   (data->pestB[i] >> 63) == 0)
+                       continue;
+
+               pr_info("  PE[%3d] PESTA:        %016llx\n", i, data->pestA[i]);
+               pr_info("          PESTB:        %016llx\n", data->pestB[i]);
+       }
+}
+
 static void ioda_eeh_phb_diag(struct pci_controller *hose)
 {
        struct pnv_phb *phb = hose->private_data;
@@ -728,6 +832,9 @@ static void ioda_eeh_phb_diag(struct pci_controller *hose)
        case OPAL_PHB_ERROR_DATA_TYPE_P7IOC:
                ioda_eeh_p7ioc_phb_diag(hose, common);
                break;
+       case OPAL_PHB_ERROR_DATA_TYPE_PHB3:
+               ioda_eeh_phb3_phb_diag(hose, common);
+               break;
        default:
                pr_warning("%s: Unrecognized I/O chip %d\n",
                           __func__, common->ioType);
index 79663d26e6eaa1de8749c6994316737f991106ab..73b981438cc583e0ba4345129046d56b72a8b9c1 100644 (file)
@@ -144,11 +144,8 @@ static int powernv_eeh_dev_probe(struct pci_dev *dev, void *flag)
        /*
         * Enable EEH explicitly so that we will do EEH check
         * while accessing I/O stuff
-        *
-        * FIXME: Enable that for PHB3 later
         */
-       if (phb->type == PNV_PHB_IODA1)
-               eeh_subsystem_enabled = 1;
+       eeh_subsystem_enabled = 1;
 
        /* Save memory bars */
        eeh_save_bars(edev);
diff --git a/arch/powerpc/platforms/powernv/opal-flash.c b/arch/powerpc/platforms/powernv/opal-flash.c
new file mode 100644 (file)
index 0000000..6ffa6b1
--- /dev/null
@@ -0,0 +1,667 @@
+/*
+ * PowerNV OPAL Firmware Update Interface
+ *
+ * Copyright 2013 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define DEBUG
+
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/init.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/pagemap.h>
+
+#include <asm/opal.h>
+
+/* FLASH status codes */
+#define FLASH_NO_OP            -1099   /* No operation initiated by user */
+#define FLASH_NO_AUTH          -9002   /* Not a service authority partition */
+
+/* Validate image status values */
+#define VALIDATE_IMG_READY     -1001   /* Image ready for validation */
+#define VALIDATE_IMG_INCOMPLETE        -1002   /* User copied < VALIDATE_BUF_SIZE */
+
+/* Manage image status values */
+#define MANAGE_ACTIVE_ERR      -9001   /* Cannot overwrite active img */
+
+/* Flash image status values */
+#define FLASH_IMG_READY                0       /* Img ready for flash on reboot */
+#define FLASH_INVALID_IMG      -1003   /* Flash image shorter than expected */
+#define FLASH_IMG_NULL_DATA    -1004   /* Bad data in sg list entry */
+#define FLASH_IMG_BAD_LEN      -1005   /* Bad length in sg list entry */
+
+/* Manage operation tokens */
+#define FLASH_REJECT_TMP_SIDE  0       /* Reject temporary fw image */
+#define FLASH_COMMIT_TMP_SIDE  1       /* Commit temporary fw image */
+
+/* Update tokens */
+#define FLASH_UPDATE_CANCEL    0       /* Cancel update request */
+#define FLASH_UPDATE_INIT      1       /* Initiate update */
+
+/* Validate image update result tokens */
+#define VALIDATE_TMP_UPDATE    0     /* T side will be updated */
+#define VALIDATE_FLASH_AUTH    1     /* Partition does not have authority */
+#define VALIDATE_INVALID_IMG   2     /* Candidate image is not valid */
+#define VALIDATE_CUR_UNKNOWN   3     /* Current fixpack level is unknown */
+/*
+ * Current T side will be committed to P side before being replace with new
+ * image, and the new image is downlevel from current image
+ */
+#define VALIDATE_TMP_COMMIT_DL 4
+/*
+ * Current T side will be committed to P side before being replaced with new
+ * image
+ */
+#define VALIDATE_TMP_COMMIT    5
+/*
+ * T side will be updated with a downlevel image
+ */
+#define VALIDATE_TMP_UPDATE_DL 6
+/*
+ * The candidate image's release date is later than the system's firmware
+ * service entitlement date - service warranty period has expired
+ */
+#define VALIDATE_OUT_OF_WRNTY  7
+
+/* Validate buffer size */
+#define VALIDATE_BUF_SIZE      4096
+
+/* XXX: Assume candidate image size is <= 256MB */
+#define MAX_IMAGE_SIZE 0x10000000
+
+/* Flash sg list version */
+#define SG_LIST_VERSION (1UL)
+
+/* Image status */
+enum {
+       IMAGE_INVALID,
+       IMAGE_LOADING,
+       IMAGE_READY,
+};
+
+/* Candidate image data */
+struct image_data_t {
+       int             status;
+       void            *data;
+       uint32_t        size;
+};
+
+/* Candidate image header */
+struct image_header_t {
+       uint16_t        magic;
+       uint16_t        version;
+       uint32_t        size;
+};
+
+/* Scatter/gather entry */
+struct opal_sg_entry {
+       void    *data;
+       long    length;
+};
+
+/* We calculate number of entries based on PAGE_SIZE */
+#define SG_ENTRIES_PER_NODE ((PAGE_SIZE - 16) / sizeof(struct opal_sg_entry))
+
+/*
+ * This struct is very similar but not identical to that
+ * needed by the opal flash update. All we need to do for
+ * opal is rewrite num_entries into a version/length and
+ * translate the pointers to absolute.
+ */
+struct opal_sg_list {
+       unsigned long num_entries;
+       struct opal_sg_list *next;
+       struct opal_sg_entry entry[SG_ENTRIES_PER_NODE];
+};
+
+struct validate_flash_t {
+       int             status;         /* Return status */
+       void            *buf;           /* Candiate image buffer */
+       uint32_t        buf_size;       /* Image size */
+       uint32_t        result;         /* Update results token */
+};
+
+struct manage_flash_t {
+       int status;             /* Return status */
+};
+
+struct update_flash_t {
+       int status;             /* Return status */
+};
+
+static struct image_header_t   image_header;
+static struct image_data_t     image_data;
+static struct validate_flash_t validate_flash_data;
+static struct manage_flash_t   manage_flash_data;
+static struct update_flash_t   update_flash_data;
+
+static DEFINE_MUTEX(image_data_mutex);
+
+/*
+ * Validate candidate image
+ */
+static inline void opal_flash_validate(void)
+{
+       struct validate_flash_t *args_buf = &validate_flash_data;
+
+       args_buf->status = opal_validate_flash(__pa(args_buf->buf),
+                                              &(args_buf->buf_size),
+                                              &(args_buf->result));
+}
+
+/*
+ * Validate output format:
+ *     validate result token
+ *     current image version details
+ *     new image version details
+ */
+static ssize_t validate_show(struct kobject *kobj,
+                            struct kobj_attribute *attr, char *buf)
+{
+       struct validate_flash_t *args_buf = &validate_flash_data;
+       int len;
+
+       /* Candidate image is not validated */
+       if (args_buf->status < VALIDATE_TMP_UPDATE) {
+               len = sprintf(buf, "%d\n", args_buf->status);
+               goto out;
+       }
+
+       /* Result token */
+       len = sprintf(buf, "%d\n", args_buf->result);
+
+       /* Current and candidate image version details */
+       if ((args_buf->result != VALIDATE_TMP_UPDATE) &&
+           (args_buf->result < VALIDATE_CUR_UNKNOWN))
+               goto out;
+
+       if (args_buf->buf_size > (VALIDATE_BUF_SIZE - len)) {
+               memcpy(buf + len, args_buf->buf, VALIDATE_BUF_SIZE - len);
+               len = VALIDATE_BUF_SIZE;
+       } else {
+               memcpy(buf + len, args_buf->buf, args_buf->buf_size);
+               len += args_buf->buf_size;
+       }
+out:
+       /* Set status to default */
+       args_buf->status = FLASH_NO_OP;
+       return len;
+}
+
+/*
+ * Validate candidate firmware image
+ *
+ * Note:
+ *   We are only interested in first 4K bytes of the
+ *   candidate image.
+ */
+static ssize_t validate_store(struct kobject *kobj,
+                             struct kobj_attribute *attr,
+                             const char *buf, size_t count)
+{
+       struct validate_flash_t *args_buf = &validate_flash_data;
+
+       if (buf[0] != '1')
+               return -EINVAL;
+
+       mutex_lock(&image_data_mutex);
+
+       if (image_data.status != IMAGE_READY ||
+           image_data.size < VALIDATE_BUF_SIZE) {
+               args_buf->result = VALIDATE_INVALID_IMG;
+               args_buf->status = VALIDATE_IMG_INCOMPLETE;
+               goto out;
+       }
+
+       /* Copy first 4k bytes of candidate image */
+       memcpy(args_buf->buf, image_data.data, VALIDATE_BUF_SIZE);
+
+       args_buf->status = VALIDATE_IMG_READY;
+       args_buf->buf_size = VALIDATE_BUF_SIZE;
+
+       /* Validate candidate image */
+       opal_flash_validate();
+
+out:
+       mutex_unlock(&image_data_mutex);
+       return count;
+}
+
+/*
+ * Manage flash routine
+ */
+static inline void opal_flash_manage(uint8_t op)
+{
+       struct manage_flash_t *const args_buf = &manage_flash_data;
+
+       args_buf->status = opal_manage_flash(op);
+}
+
+/*
+ * Show manage flash status
+ */
+static ssize_t manage_show(struct kobject *kobj,
+                          struct kobj_attribute *attr, char *buf)
+{
+       struct manage_flash_t *const args_buf = &manage_flash_data;
+       int rc;
+
+       rc = sprintf(buf, "%d\n", args_buf->status);
+       /* Set status to default*/
+       args_buf->status = FLASH_NO_OP;
+       return rc;
+}
+
+/*
+ * Manage operations:
+ *   0 - Reject
+ *   1 - Commit
+ */
+static ssize_t manage_store(struct kobject *kobj,
+                           struct kobj_attribute *attr,
+                           const char *buf, size_t count)
+{
+       uint8_t op;
+       switch (buf[0]) {
+       case '0':
+               op = FLASH_REJECT_TMP_SIDE;
+               break;
+       case '1':
+               op = FLASH_COMMIT_TMP_SIDE;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* commit/reject temporary image */
+       opal_flash_manage(op);
+       return count;
+}
+
+/*
+ * Free sg list
+ */
+static void free_sg_list(struct opal_sg_list *list)
+{
+       struct opal_sg_list *sg1;
+       while (list) {
+               sg1 = list->next;
+               kfree(list);
+               list = sg1;
+       }
+       list = NULL;
+}
+
+/*
+ * Build candidate image scatter gather list
+ *
+ * list format:
+ *   -----------------------------------
+ *  |  VER (8) | Entry length in bytes  |
+ *   -----------------------------------
+ *  |  Pointer to next entry            |
+ *   -----------------------------------
+ *  |  Address of memory area 1         |
+ *   -----------------------------------
+ *  |  Length of memory area 1          |
+ *   -----------------------------------
+ *  |   .........                       |
+ *   -----------------------------------
+ *  |   .........                       |
+ *   -----------------------------------
+ *  |  Address of memory area N         |
+ *   -----------------------------------
+ *  |  Length of memory area N          |
+ *   -----------------------------------
+ */
+static struct opal_sg_list *image_data_to_sglist(void)
+{
+       struct opal_sg_list *sg1, *list = NULL;
+       void *addr;
+       int size;
+
+       addr = image_data.data;
+       size = image_data.size;
+
+       sg1 = kzalloc((sizeof(struct opal_sg_list)), GFP_KERNEL);
+       if (!sg1)
+               return NULL;
+
+       list = sg1;
+       sg1->num_entries = 0;
+       while (size > 0) {
+               /* Translate virtual address to physical address */
+               sg1->entry[sg1->num_entries].data =
+                       (void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT);
+
+               if (size > PAGE_SIZE)
+                       sg1->entry[sg1->num_entries].length = PAGE_SIZE;
+               else
+                       sg1->entry[sg1->num_entries].length = size;
+
+               sg1->num_entries++;
+               if (sg1->num_entries >= SG_ENTRIES_PER_NODE) {
+                       sg1->next = kzalloc((sizeof(struct opal_sg_list)),
+                                           GFP_KERNEL);
+                       if (!sg1->next) {
+                               pr_err("%s : Failed to allocate memory\n",
+                                      __func__);
+                               goto nomem;
+                       }
+
+                       sg1 = sg1->next;
+                       sg1->num_entries = 0;
+               }
+               addr += PAGE_SIZE;
+               size -= PAGE_SIZE;
+       }
+       return list;
+nomem:
+       free_sg_list(list);
+       return NULL;
+}
+
+/*
+ * OPAL update flash
+ */
+static int opal_flash_update(int op)
+{
+       struct opal_sg_list *sg, *list, *next;
+       unsigned long addr;
+       int64_t rc = OPAL_PARAMETER;
+
+       if (op == FLASH_UPDATE_CANCEL) {
+               pr_alert("FLASH: Image update cancelled\n");
+               addr = '\0';
+               goto flash;
+       }
+
+       list = image_data_to_sglist();
+       if (!list)
+               goto invalid_img;
+
+       /* First entry address */
+       addr = __pa(list);
+
+       /* Translate sg list address to absolute */
+       for (sg = list; sg; sg = next) {
+               next = sg->next;
+               /* Don't translate NULL pointer for last entry */
+               if (sg->next)
+                       sg->next = (struct opal_sg_list *)__pa(sg->next);
+               else
+                       sg->next = NULL;
+
+               /* Make num_entries into the version/length field */
+               sg->num_entries = (SG_LIST_VERSION << 56) |
+                       (sg->num_entries * sizeof(struct opal_sg_entry) + 16);
+       }
+
+       pr_alert("FLASH: Image is %u bytes\n", image_data.size);
+       pr_alert("FLASH: Image update requested\n");
+       pr_alert("FLASH: Image will be updated during system reboot\n");
+       pr_alert("FLASH: This will take several minutes. Do not power off!\n");
+
+flash:
+       rc = opal_update_flash(addr);
+
+invalid_img:
+       return rc;
+}
+
+/*
+ * Show candidate image status
+ */
+static ssize_t update_show(struct kobject *kobj,
+                          struct kobj_attribute *attr, char *buf)
+{
+       struct update_flash_t *const args_buf = &update_flash_data;
+       return sprintf(buf, "%d\n", args_buf->status);
+}
+
+/*
+ * Set update image flag
+ *  1 - Flash new image
+ *  0 - Cancel flash request
+ */
+static ssize_t update_store(struct kobject *kobj,
+                           struct kobj_attribute *attr,
+                           const char *buf, size_t count)
+{
+       struct update_flash_t *const args_buf = &update_flash_data;
+       int rc = count;
+
+       mutex_lock(&image_data_mutex);
+
+       switch (buf[0]) {
+       case '0':
+               if (args_buf->status == FLASH_IMG_READY)
+                       opal_flash_update(FLASH_UPDATE_CANCEL);
+               args_buf->status = FLASH_NO_OP;
+               break;
+       case '1':
+               /* Image is loaded? */
+               if (image_data.status == IMAGE_READY)
+                       args_buf->status =
+                               opal_flash_update(FLASH_UPDATE_INIT);
+               else
+                       args_buf->status = FLASH_INVALID_IMG;
+               break;
+       default:
+               rc = -EINVAL;
+       }
+
+       mutex_unlock(&image_data_mutex);
+       return rc;
+}
+
+/*
+ * Free image buffer
+ */
+static void free_image_buf(void)
+{
+       void *addr;
+       int size;
+
+       addr = image_data.data;
+       size = PAGE_ALIGN(image_data.size);
+       while (size > 0) {
+               ClearPageReserved(vmalloc_to_page(addr));
+               addr += PAGE_SIZE;
+               size -= PAGE_SIZE;
+       }
+       vfree(image_data.data);
+       image_data.data = NULL;
+       image_data.status = IMAGE_INVALID;
+}
+
+/*
+ * Allocate image buffer.
+ */
+static int alloc_image_buf(char *buffer, size_t count)
+{
+       void *addr;
+       int size;
+
+       if (count < sizeof(struct image_header_t)) {
+               pr_warn("FLASH: Invalid candidate image\n");
+               return -EINVAL;
+       }
+
+       memcpy(&image_header, (void *)buffer, sizeof(struct image_header_t));
+       image_data.size = be32_to_cpu(image_header.size);
+       pr_debug("FLASH: Candiate image size = %u\n", image_data.size);
+
+       if (image_data.size > MAX_IMAGE_SIZE) {
+               pr_warn("FLASH: Too large image\n");
+               return -EINVAL;
+       }
+       if (image_data.size < VALIDATE_BUF_SIZE) {
+               pr_warn("FLASH: Image is shorter than expected\n");
+               return -EINVAL;
+       }
+
+       image_data.data = vzalloc(PAGE_ALIGN(image_data.size));
+       if (!image_data.data) {
+               pr_err("%s : Failed to allocate memory\n", __func__);
+               return -ENOMEM;
+       }
+
+       /* Pin memory */
+       addr = image_data.data;
+       size = PAGE_ALIGN(image_data.size);
+       while (size > 0) {
+               SetPageReserved(vmalloc_to_page(addr));
+               addr += PAGE_SIZE;
+               size -= PAGE_SIZE;
+       }
+
+       image_data.status = IMAGE_LOADING;
+       return 0;
+}
+
+/*
+ * Copy candidate image
+ *
+ * Parse candidate image header to get total image size
+ * and pre-allocate required memory.
+ */
+static ssize_t image_data_write(struct file *filp, struct kobject *kobj,
+                               struct bin_attribute *bin_attr,
+                               char *buffer, loff_t pos, size_t count)
+{
+       int rc;
+
+       mutex_lock(&image_data_mutex);
+
+       /* New image ? */
+       if (pos == 0) {
+               /* Free memory, if already allocated */
+               if (image_data.data)
+                       free_image_buf();
+
+               /* Cancel outstanding image update request */
+               if (update_flash_data.status == FLASH_IMG_READY)
+                       opal_flash_update(FLASH_UPDATE_CANCEL);
+
+               /* Allocate memory */
+               rc = alloc_image_buf(buffer, count);
+               if (rc)
+                       goto out;
+       }
+
+       if (image_data.status != IMAGE_LOADING) {
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       if ((pos + count) > image_data.size) {
+               rc = -EINVAL;
+               goto out;
+       }
+
+       memcpy(image_data.data + pos, (void *)buffer, count);
+       rc = count;
+
+       /* Set image status */
+       if ((pos + count) == image_data.size) {
+               pr_debug("FLASH: Candidate image loaded....\n");
+               image_data.status = IMAGE_READY;
+       }
+
+out:
+       mutex_unlock(&image_data_mutex);
+       return rc;
+}
+
+/*
+ * sysfs interface :
+ *  OPAL uses below sysfs files for code update.
+ *  We create these files under /sys/firmware/opal.
+ *
+ *   image             : Interface to load candidate firmware image
+ *   validate_flash    : Validate firmware image
+ *   manage_flash      : Commit/Reject firmware image
+ *   update_flash      : Flash new firmware image
+ *
+ */
+static struct bin_attribute image_data_attr = {
+       .attr = {.name = "image", .mode = 0200},
+       .size = MAX_IMAGE_SIZE, /* Limit image size */
+       .write = image_data_write,
+};
+
+static struct kobj_attribute validate_attribute =
+       __ATTR(validate_flash, 0600, validate_show, validate_store);
+
+static struct kobj_attribute manage_attribute =
+       __ATTR(manage_flash, 0600, manage_show, manage_store);
+
+static struct kobj_attribute update_attribute =
+       __ATTR(update_flash, 0600, update_show, update_store);
+
+static struct attribute *image_op_attrs[] = {
+       &validate_attribute.attr,
+       &manage_attribute.attr,
+       &update_attribute.attr,
+       NULL    /* need to NULL terminate the list of attributes */
+};
+
+static struct attribute_group image_op_attr_group = {
+       .attrs = image_op_attrs,
+};
+
+void __init opal_flash_init(void)
+{
+       int ret;
+
+       /* Allocate validate image buffer */
+       validate_flash_data.buf = kzalloc(VALIDATE_BUF_SIZE, GFP_KERNEL);
+       if (!validate_flash_data.buf) {
+               pr_err("%s : Failed to allocate memory\n", __func__);
+               return;
+       }
+
+       /* Make sure /sys/firmware/opal directory is created */
+       if (!opal_kobj) {
+               pr_warn("FLASH: opal kobject is not available\n");
+               goto nokobj;
+       }
+
+       /* Create the sysfs files */
+       ret = sysfs_create_group(opal_kobj, &image_op_attr_group);
+       if (ret) {
+               pr_warn("FLASH: Failed to create sysfs files\n");
+               goto nokobj;
+       }
+
+       ret = sysfs_create_bin_file(opal_kobj, &image_data_attr);
+       if (ret) {
+               pr_warn("FLASH: Failed to create sysfs files\n");
+               goto nosysfs_file;
+       }
+
+       /* Set default status */
+       validate_flash_data.status = FLASH_NO_OP;
+       manage_flash_data.status = FLASH_NO_OP;
+       update_flash_data.status = FLASH_NO_OP;
+       image_data.status = IMAGE_INVALID;
+       return;
+
+nosysfs_file:
+       sysfs_remove_group(opal_kobj, &image_op_attr_group);
+
+nokobj:
+       kfree(validate_flash_data.buf);
+       return;
+}
index 3f83e1ae26acb591fbf3614bd9afbb6ae4ffa3d3..acd9f7e96678256e2620b24494fded8e90b08ebb 100644 (file)
@@ -65,7 +65,7 @@ static ssize_t opal_nvram_write(char *buf, size_t count, loff_t *index)
 void __init opal_nvram_init(void)
 {
        struct device_node *np;
-       const u32 *nbytes_p;
+       const __be32 *nbytes_p;
 
        np = of_find_compatible_node(NULL, NULL, "ibm,opal-nvram");
        if (np == NULL)
@@ -76,7 +76,7 @@ void __init opal_nvram_init(void)
                of_node_put(np);
                return;
        }
-       nvram_size = *nbytes_p;
+       nvram_size = be32_to_cpup(nbytes_p);
 
        printk(KERN_INFO "OPAL nvram setup, %u bytes\n", nvram_size);
        of_node_put(np);
index 2aa7641aac9bd8080e2e42b3c0ed98ba7920c0ea..7d07c7e80ec09e9232b3cafd9c41a104992b5331 100644 (file)
@@ -37,10 +37,12 @@ unsigned long __init opal_get_boot_time(void)
        struct rtc_time tm;
        u32 y_m_d;
        u64 h_m_s_ms;
+       __be32 __y_m_d;
+       __be64 __h_m_s_ms;
        long rc = OPAL_BUSY;
 
        while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
-               rc = opal_rtc_read(&y_m_d, &h_m_s_ms);
+               rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms);
                if (rc == OPAL_BUSY_EVENT)
                        opal_poll_events(NULL);
                else
@@ -48,6 +50,8 @@ unsigned long __init opal_get_boot_time(void)
        }
        if (rc != OPAL_SUCCESS)
                return 0;
+       y_m_d = be32_to_cpu(__y_m_d);
+       h_m_s_ms = be64_to_cpu(__h_m_s_ms);
        opal_to_tm(y_m_d, h_m_s_ms, &tm);
        return mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
                      tm.tm_hour, tm.tm_min, tm.tm_sec);
@@ -58,9 +62,11 @@ void opal_get_rtc_time(struct rtc_time *tm)
        long rc = OPAL_BUSY;
        u32 y_m_d;
        u64 h_m_s_ms;
+       __be32 __y_m_d;
+       __be64 __h_m_s_ms;
 
        while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
-               rc = opal_rtc_read(&y_m_d, &h_m_s_ms);
+               rc = opal_rtc_read(&__y_m_d, &__h_m_s_ms);
                if (rc == OPAL_BUSY_EVENT)
                        opal_poll_events(NULL);
                else
@@ -68,6 +74,8 @@ void opal_get_rtc_time(struct rtc_time *tm)
        }
        if (rc != OPAL_SUCCESS)
                return;
+       y_m_d = be32_to_cpu(__y_m_d);
+       h_m_s_ms = be64_to_cpu(__h_m_s_ms);
        opal_to_tm(y_m_d, h_m_s_ms, tm);
 }
 
index 8f3844535fbb2e4167ced361831e6c2aeab9a190..e7806504e9769162f921e704cf55d0b3e210cf6c 100644 (file)
@@ -24,7 +24,7 @@
        mflr    r0;                     \
        mfcr    r12;                    \
        std     r0,16(r1);              \
-       std     r12,8(r1);              \
+       stw     r12,8(r1);              \
        std     r1,PACAR1(r13);         \
        li      r0,0;                   \
        mfmsr   r12;                    \
@@ -34,7 +34,7 @@
        mtmsrd  r12,1;                  \
        LOAD_REG_ADDR(r0,.opal_return); \
        mtlr    r0;                     \
-       li      r0,MSR_DR|MSR_IR;       \
+       li      r0,MSR_DR|MSR_IR|MSR_LE;\
        andc    r12,r12,r0;             \
        li      r0,token;               \
        mtspr   SPRN_HSRR1,r12;         \
        hrfid
 
 _STATIC(opal_return)
+       /*
+        * Fixup endian on OPAL return... we should be able to simplify
+        * this by instead converting the below trampoline to a set of
+        * bytes (always BE) since MSR:LE will end up fixed up as a side
+        * effect of the rfid.
+        */
+       FIXUP_ENDIAN
        ld      r2,PACATOC(r13);
-       l     r4,8(r1);
+       lwz     r4,8(r1);
        ld      r5,16(r1);
        ld      r6,PACASAVEDMSR(r13);
        mtspr   SPRN_SRR0,r5;
@@ -116,3 +123,6 @@ OPAL_CALL(opal_xscom_write,                 OPAL_XSCOM_WRITE);
 OPAL_CALL(opal_lpc_read,                       OPAL_LPC_READ);
 OPAL_CALL(opal_lpc_write,                      OPAL_LPC_WRITE);
 OPAL_CALL(opal_return_cpu,                     OPAL_RETURN_CPU);
+OPAL_CALL(opal_validate_flash,                 OPAL_FLASH_VALIDATE);
+OPAL_CALL(opal_manage_flash,                   OPAL_FLASH_MANAGE);
+OPAL_CALL(opal_update_flash,                   OPAL_FLASH_UPDATE);
diff --git a/arch/powerpc/platforms/powernv/opal-xscom.c b/arch/powerpc/platforms/powernv/opal-xscom.c
new file mode 100644 (file)
index 0000000..4d99a8f
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * PowerNV LPC bus handling.
+ *
+ * Copyright 2013 IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/bug.h>
+#include <linux/gfp.h>
+#include <linux/slab.h>
+
+#include <asm/machdep.h>
+#include <asm/firmware.h>
+#include <asm/opal.h>
+#include <asm/scom.h>
+
+/*
+ * We could probably fit that inside the scom_map_t
+ * which is a void* after all but it's really too ugly
+ * so let's kmalloc it for now
+ */
+struct opal_scom_map {
+       uint32_t chip;
+       uint64_t addr;
+};
+
+static scom_map_t opal_scom_map(struct device_node *dev, u64 reg, u64 count)
+{
+       struct opal_scom_map *m;
+       const __be32 *gcid;
+
+       if (!of_get_property(dev, "scom-controller", NULL)) {
+               pr_err("%s: device %s is not a SCOM controller\n",
+                       __func__, dev->full_name);
+               return SCOM_MAP_INVALID;
+       }
+       gcid = of_get_property(dev, "ibm,chip-id", NULL);
+       if (!gcid) {
+               pr_err("%s: device %s has no ibm,chip-id\n",
+                       __func__, dev->full_name);
+               return SCOM_MAP_INVALID;
+       }
+       m = kmalloc(sizeof(struct opal_scom_map), GFP_KERNEL);
+       if (!m)
+               return NULL;
+       m->chip = be32_to_cpup(gcid);
+       m->addr = reg;
+
+       return (scom_map_t)m;
+}
+
+static void opal_scom_unmap(scom_map_t map)
+{
+       kfree(map);
+}
+
+static int opal_xscom_err_xlate(int64_t rc)
+{
+       switch(rc) {
+       case 0:
+               return 0;
+       /* Add more translations if necessary */
+       default:
+               return -EIO;
+       }
+}
+
+static u64 opal_scom_unmangle(u64 reg)
+{
+       /*
+        * XSCOM indirect addresses have the top bit set. Additionally
+        * the reset of the top 3 nibbles is always 0.
+        *
+        * Because the debugfs interface uses signed offsets and shifts
+        * the address left by 3, we basically cannot use the top 4 bits
+        * of the 64-bit address, and thus cannot use the indirect bit.
+        *
+        * To deal with that, we support the indirect bit being in bit
+        * 4 (IBM notation) instead of bit 0 in this API, we do the
+        * conversion here. To leave room for further xscom address
+        * expansion, we only clear out the top byte
+        *
+        */
+       if (reg & (1ull << 59))
+               reg = (reg & ~(0xffull << 56)) | (1ull << 63);
+       return reg;
+}
+
+static int opal_scom_read(scom_map_t map, u64 reg, u64 *value)
+{
+       struct opal_scom_map *m = map;
+       int64_t rc;
+
+       reg = opal_scom_unmangle(reg);
+       rc = opal_xscom_read(m->chip, m->addr + reg, (uint64_t *)__pa(value));
+       return opal_xscom_err_xlate(rc);
+}
+
+static int opal_scom_write(scom_map_t map, u64 reg, u64 value)
+{
+       struct opal_scom_map *m = map;
+       int64_t rc;
+
+       reg = opal_scom_unmangle(reg);
+       rc = opal_xscom_write(m->chip, m->addr + reg, value);
+       return opal_xscom_err_xlate(rc);
+}
+
+static const struct scom_controller opal_scom_controller = {
+       .map    = opal_scom_map,
+       .unmap  = opal_scom_unmap,
+       .read   = opal_scom_read,
+       .write  = opal_scom_write
+};
+
+static int opal_xscom_init(void)
+{
+       if (firmware_has_feature(FW_FEATURE_OPALv3))
+               scom_init(&opal_scom_controller);
+       return 0;
+}
+arch_initcall(opal_xscom_init);
index 2911abe550f1d9182ce793f0ec4777b0c85295b7..b56c243aaee93907741d59aee9090dcd7e000ec7 100644 (file)
 #include <linux/interrupt.h>
 #include <linux/notifier.h>
 #include <linux/slab.h>
+#include <linux/kobject.h>
 #include <asm/opal.h>
 #include <asm/firmware.h>
 
 #include "powernv.h"
 
+/* /sys/firmware/opal */
+struct kobject *opal_kobj;
+
 struct opal {
        u64 base;
        u64 entry;
@@ -77,6 +81,7 @@ int __init early_init_dt_scan_opal(unsigned long node,
 
 static int __init opal_register_exception_handlers(void)
 {
+#ifdef __BIG_ENDIAN__
        u64 glue;
 
        if (!(powerpc_firmware_features & FW_FEATURE_OPAL))
@@ -94,6 +99,7 @@ static int __init opal_register_exception_handlers(void)
                                        0, glue);
        glue += 128;
        opal_register_exception_handler(OPAL_SOFTPATCH_HANDLER, 0, glue);
+#endif
 
        return 0;
 }
@@ -164,27 +170,28 @@ void opal_notifier_disable(void)
 
 int opal_get_chars(uint32_t vtermno, char *buf, int count)
 {
-       s64 len, rc;
-       u64 evt;
+       s64 rc;
+       __be64 evt, len;
 
        if (!opal.entry)
                return -ENODEV;
        opal_poll_events(&evt);
-       if ((evt & OPAL_EVENT_CONSOLE_INPUT) == 0)
+       if ((be64_to_cpu(evt) & OPAL_EVENT_CONSOLE_INPUT) == 0)
                return 0;
-       len = count;
-       rc = opal_console_read(vtermno, &len, buf);
+       len = cpu_to_be64(count);
+       rc = opal_console_read(vtermno, &len, buf);     
        if (rc == OPAL_SUCCESS)
-               return len;
+               return be64_to_cpu(len);
        return 0;
 }
 
 int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
 {
        int written = 0;
+       __be64 olen;
        s64 len, rc;
        unsigned long flags;
-       u64 evt;
+       __be64 evt;
 
        if (!opal.entry)
                return -ENODEV;
@@ -199,13 +206,14 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
         */
        spin_lock_irqsave(&opal_write_lock, flags);
        if (firmware_has_feature(FW_FEATURE_OPALv2)) {
-               rc = opal_console_write_buffer_space(vtermno, &len);
+               rc = opal_console_write_buffer_space(vtermno, &olen);
+               len = be64_to_cpu(olen);
                if (rc || len < total_len) {
                        spin_unlock_irqrestore(&opal_write_lock, flags);
                        /* Closed -> drop characters */
                        if (rc)
                                return total_len;
-                       opal_poll_events(&evt);
+                       opal_poll_events(NULL);
                        return -EAGAIN;
                }
        }
@@ -216,8 +224,9 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
        rc = OPAL_BUSY;
        while(total_len > 0 && (rc == OPAL_BUSY ||
                                rc == OPAL_BUSY_EVENT || rc == OPAL_SUCCESS)) {
-               len = total_len;
-               rc = opal_console_write(vtermno, &len, data);
+               olen = cpu_to_be64(total_len);
+               rc = opal_console_write(vtermno, &olen, data);
+               len = be64_to_cpu(olen);
 
                /* Closed or other error drop */
                if (rc != OPAL_SUCCESS && rc != OPAL_BUSY &&
@@ -237,7 +246,8 @@ int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
                 */
                do
                        opal_poll_events(&evt);
-               while(rc == OPAL_SUCCESS && (evt & OPAL_EVENT_CONSOLE_OUTPUT));
+               while(rc == OPAL_SUCCESS &&
+                       (be64_to_cpu(evt) & OPAL_EVENT_CONSOLE_OUTPUT));
        }
        spin_unlock_irqrestore(&opal_write_lock, flags);
        return written;
@@ -360,7 +370,7 @@ int opal_machine_check(struct pt_regs *regs)
 
 static irqreturn_t opal_interrupt(int irq, void *data)
 {
-       uint64_t events;
+       __be64 events;
 
        opal_handle_interrupt(virq_to_hw(irq), &events);
 
@@ -369,10 +379,21 @@ static irqreturn_t opal_interrupt(int irq, void *data)
        return IRQ_HANDLED;
 }
 
+static int opal_sysfs_init(void)
+{
+       opal_kobj = kobject_create_and_add("opal", firmware_kobj);
+       if (!opal_kobj) {
+               pr_warn("kobject_create_and_add opal failed\n");
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
 static int __init opal_init(void)
 {
        struct device_node *np, *consoles;
-       const u32 *irqs;
+       const __be32 *irqs;
        int rc, i, irqlen;
 
        opal_node = of_find_node_by_path("/ibm,opal");
@@ -414,6 +435,14 @@ static int __init opal_init(void)
                                   " (0x%x)\n", rc, irq, hwirq);
                opal_irqs[i] = irq;
        }
+
+       /* Create "opal" kobject under /sys/firmware */
+       rc = opal_sysfs_init();
+       if (rc == 0) {
+               /* Setup code update interface */
+               opal_flash_init();
+       }
+
        return 0;
 }
 subsys_initcall(opal_init);
index 74a5a5773b1fbce0c31f567ef6536e75038fff98..084cdfa40682b2be9f35fde51eb2e4e201accfe9 100644 (file)
@@ -70,6 +70,16 @@ define_pe_printk_level(pe_err, KERN_ERR);
 define_pe_printk_level(pe_warn, KERN_WARNING);
 define_pe_printk_level(pe_info, KERN_INFO);
 
+/*
+ * stdcix is only supposed to be used in hypervisor real mode as per
+ * the architecture spec
+ */
+static inline void __raw_rm_writeq(u64 val, volatile void __iomem *paddr)
+{
+       __asm__ __volatile__("stdcix %0,0,%1"
+               : : "r" (val), "r" (paddr) : "memory");
+}
+
 static int pnv_ioda_alloc_pe(struct pnv_phb *phb)
 {
        unsigned long pe;
@@ -153,13 +163,23 @@ static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe)
                rid_end = pe->rid + 1;
        }
 
-       /* Associate PE in PELT */
+       /*
+        * Associate PE in PELT. We need add the PE into the
+        * corresponding PELT-V as well. Otherwise, the error
+        * originated from the PE might contribute to other
+        * PEs.
+        */
        rc = opal_pci_set_pe(phb->opal_id, pe->pe_number, pe->rid,
                             bcomp, dcomp, fcomp, OPAL_MAP_PE);
        if (rc) {
                pe_err(pe, "OPAL error %ld trying to setup PELT table\n", rc);
                return -ENXIO;
        }
+
+       rc = opal_pci_set_peltv(phb->opal_id, pe->pe_number,
+                               pe->pe_number, OPAL_ADD_PE_TO_DOMAIN);
+       if (rc)
+               pe_warn(pe, "OPAL error %d adding self to PELTV\n", rc);
        opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number,
                                  OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
 
@@ -454,10 +474,13 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe, struct pci_bus *bus)
        }
 }
 
-static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl,
-                                        u64 *startp, u64 *endp)
+static void pnv_pci_ioda1_tce_invalidate(struct pnv_ioda_pe *pe,
+                                        struct iommu_table *tbl,
+                                        __be64 *startp, __be64 *endp, bool rm)
 {
-       u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index;
+       __be64 __iomem *invalidate = rm ?
+               (__be64 __iomem *)pe->tce_inval_reg_phys :
+               (__be64 __iomem *)tbl->it_index;
        unsigned long start, end, inc;
 
        start = __pa(startp);
@@ -484,7 +507,10 @@ static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl,
 
         mb(); /* Ensure above stores are visible */
         while (start <= end) {
-                __raw_writeq(start, invalidate);
+               if (rm)
+                       __raw_rm_writeq(cpu_to_be64(start), invalidate);
+               else
+                       __raw_writeq(cpu_to_be64(start), invalidate);
                 start += inc;
         }
 
@@ -496,10 +522,12 @@ static void pnv_pci_ioda1_tce_invalidate(struct iommu_table *tbl,
 
 static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe,
                                         struct iommu_table *tbl,
-                                        u64 *startp, u64 *endp)
+                                        __be64 *startp, __be64 *endp, bool rm)
 {
        unsigned long start, end, inc;
-       u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index;
+       __be64 __iomem *invalidate = rm ?
+               (__be64 __iomem *)pe->tce_inval_reg_phys :
+               (__be64 __iomem *)tbl->it_index;
 
        /* We'll invalidate DMA address in PE scope */
        start = 0x2ul << 60;
@@ -515,22 +543,25 @@ static void pnv_pci_ioda2_tce_invalidate(struct pnv_ioda_pe *pe,
        mb();
 
        while (start <= end) {
-               __raw_writeq(start, invalidate);
+               if (rm)
+                       __raw_rm_writeq(cpu_to_be64(start), invalidate);
+               else
+                       __raw_writeq(cpu_to_be64(start), invalidate);
                start += inc;
        }
 }
 
 void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl,
-                                u64 *startp, u64 *endp)
+                                __be64 *startp, __be64 *endp, bool rm)
 {
        struct pnv_ioda_pe *pe = container_of(tbl, struct pnv_ioda_pe,
                                              tce32_table);
        struct pnv_phb *phb = pe->phb;
 
        if (phb->type == PNV_PHB_IODA1)
-               pnv_pci_ioda1_tce_invalidate(tbl, startp, endp);
+               pnv_pci_ioda1_tce_invalidate(pe, tbl, startp, endp, rm);
        else
-               pnv_pci_ioda2_tce_invalidate(pe, tbl, startp, endp);
+               pnv_pci_ioda2_tce_invalidate(pe, tbl, startp, endp, rm);
 }
 
 static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
@@ -603,7 +634,9 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
                 * bus number, print that out instead.
                 */
                tbl->it_busno = 0;
-               tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8);
+               pe->tce_inval_reg_phys = be64_to_cpup(swinvp);
+               tbl->it_index = (unsigned long)ioremap(pe->tce_inval_reg_phys,
+                               8);
                tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE |
                               TCE_PCI_SWINV_PAIR;
        }
@@ -681,7 +714,9 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,
                 * bus number, print that out instead.
                 */
                tbl->it_busno = 0;
-               tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8);
+               pe->tce_inval_reg_phys = be64_to_cpup(swinvp);
+               tbl->it_index = (unsigned long)ioremap(pe->tce_inval_reg_phys,
+                               8);
                tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE;
        }
        iommu_init_table(tbl, phb->hose->node);
@@ -786,8 +821,7 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
        struct irq_data *idata;
        struct irq_chip *ichip;
        unsigned int xive_num = hwirq - phb->msi_base;
-       uint64_t addr64;
-       uint32_t addr32, data;
+       __be32 data;
        int rc;
 
        /* No PE assigned ? bail out ... no MSI for you ! */
@@ -811,6 +845,8 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
        }
 
        if (is_64) {
+               __be64 addr64;
+
                rc = opal_get_msi_64(phb->opal_id, pe->mve_number, xive_num, 1,
                                     &addr64, &data);
                if (rc) {
@@ -818,9 +854,11 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
                                pci_name(dev), rc);
                        return -EIO;
                }
-               msg->address_hi = addr64 >> 32;
-               msg->address_lo = addr64 & 0xfffffffful;
+               msg->address_hi = be64_to_cpu(addr64) >> 32;
+               msg->address_lo = be64_to_cpu(addr64) & 0xfffffffful;
        } else {
+               __be32 addr32;
+
                rc = opal_get_msi_32(phb->opal_id, pe->mve_number, xive_num, 1,
                                     &addr32, &data);
                if (rc) {
@@ -829,9 +867,9 @@ static int pnv_pci_ioda_msi_setup(struct pnv_phb *phb, struct pci_dev *dev,
                        return -EIO;
                }
                msg->address_hi = 0;
-               msg->address_lo = addr32;
+               msg->address_lo = be32_to_cpu(addr32);
        }
-       msg->data = data;
+       msg->data = be32_to_cpu(data);
 
        /*
         * Change the IRQ chip for the MSI interrupts on PHB3.
@@ -1106,8 +1144,8 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
        struct pci_controller *hose;
        struct pnv_phb *phb;
        unsigned long size, m32map_off, iomap_off, pemap_off;
-       const u64 *prop64;
-       const u32 *prop32;
+       const __be64 *prop64;
+       const __be32 *prop32;
        int len;
        u64 phb_id;
        void *aux;
@@ -1142,8 +1180,8 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
        spin_lock_init(&phb->lock);
        prop32 = of_get_property(np, "bus-range", &len);
        if (prop32 && len == 8) {
-               hose->first_busno = prop32[0];
-               hose->last_busno = prop32[1];
+               hose->first_busno = be32_to_cpu(prop32[0]);
+               hose->last_busno = be32_to_cpu(prop32[1]);
        } else {
                pr_warn("  Broken <bus-range> on %s\n", np->full_name);
                hose->first_busno = 0;
@@ -1171,12 +1209,13 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
                pr_err("  Failed to map registers !\n");
 
        /* Initialize more IODA stuff */
+       phb->ioda.total_pe = 1;
        prop32 = of_get_property(np, "ibm,opal-num-pes", NULL);
-       if (!prop32)
-               phb->ioda.total_pe = 1;
-       else
-               phb->ioda.total_pe = *prop32;
-
+       if (prop32)
+               phb->ioda.total_pe = be32_to_cpup(prop32);
+       prop32 = of_get_property(np, "ibm,opal-reserved-pe", NULL);
+       if (prop32)
+               phb->ioda.reserved_pe = be32_to_cpup(prop32);
        phb->ioda.m32_size = resource_size(&hose->mem_resources[0]);
        /* FW Has already off top 64k of M32 space (MSI space) */
        phb->ioda.m32_size += 0x10000;
@@ -1205,7 +1244,7 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
        if (phb->type == PNV_PHB_IODA1)
                phb->ioda.io_segmap = aux + iomap_off;
        phb->ioda.pe_array = aux + pemap_off;
-       set_bit(0, phb->ioda.pe_alloc);
+       set_bit(phb->ioda.reserved_pe, phb->ioda.pe_alloc);
 
        INIT_LIST_HEAD(&phb->ioda.pe_dma_list);
        INIT_LIST_HEAD(&phb->ioda.pe_list);
@@ -1230,8 +1269,10 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
                                         segment_size);
 #endif
 
-       pr_info("  %d PE's M32: 0x%x [segment=0x%x] IO: 0x%x [segment=0x%x]\n",
+       pr_info("  %d (%d) PE's M32: 0x%x [segment=0x%x]"
+               " IO: 0x%x [segment=0x%x]\n",
                phb->ioda.total_pe,
+               phb->ioda.reserved_pe,
                phb->ioda.m32_size, phb->ioda.m32_segsize,
                phb->ioda.io_size, phb->ioda.io_segsize);
 
@@ -1268,13 +1309,6 @@ void __init pnv_pci_init_ioda_phb(struct device_node *np,
        rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET);
        if (rc)
                pr_warning("  OPAL Error %ld performing IODA table reset !\n", rc);
-
-       /*
-        * On IODA1 map everything to PE#0, on IODA2 we assume the IODA reset
-        * has cleared the RTT which has the same effect
-        */
-       if (ioda_type == PNV_PHB_IODA1)
-               opal_pci_set_pe(phb_id, 0, 0, 7, 1, 1 , OPAL_MAP_PE);
 }
 
 void __init pnv_pci_init_ioda2_phb(struct device_node *np)
@@ -1285,7 +1319,7 @@ void __init pnv_pci_init_ioda2_phb(struct device_node *np)
 void __init pnv_pci_init_ioda_hub(struct device_node *np)
 {
        struct device_node *phbn;
-       const u64 *prop64;
+       const __be64 *prop64;
        u64 hub_id;
 
        pr_info("Probing IODA IO-Hub %s\n", np->full_name);
index b68db6325c1b2a222f6045d5d7d5813c1c329a1a..f8b4bd8afb2e5da39cd8632c7a6a8eae54448aeb 100644 (file)
@@ -99,7 +99,7 @@ static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id,
                                           void *tce_mem, u64 tce_size)
 {
        struct pnv_phb *phb;
-       const u64 *prop64;
+       const __be64 *prop64;
        u64 phb_id;
        int64_t rc;
        static int primary = 1;
@@ -178,7 +178,7 @@ static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id,
 void __init pnv_pci_init_p5ioc2_hub(struct device_node *np)
 {
        struct device_node *phbn;
-       const u64 *prop64;
+       const __be64 *prop64;
        u64 hub_id;
        void *tce_mem;
        uint64_t tce_per_phb;
index a28d3b5e6393fa8b9d9d11bc81210ab9db13f38b..4eb33a9ed5325a3e84b2a7f1d4d58d5dc7fa7b22 100644 (file)
@@ -236,17 +236,21 @@ static void pnv_pci_config_check_eeh(struct pnv_phb *phb,
 {
        s64     rc;
        u8      fstate;
-       u16     pcierr;
+       __be16  pcierr;
        u32     pe_no;
 
        /*
         * Get the PE#. During the PCI probe stage, we might not
         * setup that yet. So all ER errors should be mapped to
-        * PE#0
+        * reserved PE.
         */
        pe_no = PCI_DN(dn)->pe_number;
-       if (pe_no == IODA_INVALID_PE)
-               pe_no = 0;
+       if (pe_no == IODA_INVALID_PE) {
+               if (phb->type == PNV_PHB_P5IOC2)
+                       pe_no = 0;
+               else
+                       pe_no = phb->ioda.reserved_pe;
+       }
 
        /* Read freeze status */
        rc = opal_pci_eeh_freeze_status(phb->opal_id, pe_no, &fstate, &pcierr,
@@ -283,16 +287,16 @@ int pnv_pci_cfg_read(struct device_node *dn,
                break;
        }
        case 2: {
-               u16 v16;
+               __be16 v16;
                rc = opal_pci_config_read_half_word(phb->opal_id, bdfn, where,
                                                   &v16);
-               *val = (rc == OPAL_SUCCESS) ? v16 : 0xffff;
+               *val = (rc == OPAL_SUCCESS) ? be16_to_cpu(v16) : 0xffff;
                break;
        }
        case 4: {
-               u32 v32;
+               __be32 v32;
                rc = opal_pci_config_read_word(phb->opal_id, bdfn, where, &v32);
-               *val = (rc == OPAL_SUCCESS) ? v32 : 0xffffffff;
+               *val = (rc == OPAL_SUCCESS) ? be32_to_cpu(v32) : 0xffffffff;
                break;
        }
        default:
@@ -401,10 +405,10 @@ struct pci_ops pnv_pci_ops = {
 
 static int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
                         unsigned long uaddr, enum dma_data_direction direction,
-                        struct dma_attrs *attrs)
+                        struct dma_attrs *attrs, bool rm)
 {
        u64 proto_tce;
-       u64 *tcep, *tces;
+       __be64 *tcep, *tces;
        u64 rpn;
 
        proto_tce = TCE_PCI_READ; // Read allowed
@@ -412,33 +416,48 @@ static int pnv_tce_build(struct iommu_table *tbl, long index, long npages,
        if (direction != DMA_TO_DEVICE)
                proto_tce |= TCE_PCI_WRITE;
 
-       tces = tcep = ((u64 *)tbl->it_base) + index - tbl->it_offset;
+       tces = tcep = ((__be64 *)tbl->it_base) + index - tbl->it_offset;
        rpn = __pa(uaddr) >> TCE_SHIFT;
 
        while (npages--)
-               *(tcep++) = proto_tce | (rpn++ << TCE_RPN_SHIFT);
+               *(tcep++) = cpu_to_be64(proto_tce | (rpn++ << TCE_RPN_SHIFT));
 
        /* Some implementations won't cache invalid TCEs and thus may not
         * need that flush. We'll probably turn it_type into a bit mask
         * of flags if that becomes the case
         */
        if (tbl->it_type & TCE_PCI_SWINV_CREATE)
-               pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1);
+               pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1, rm);
 
        return 0;
 }
 
-static void pnv_tce_free(struct iommu_table *tbl, long index, long npages)
+static int pnv_tce_build_vm(struct iommu_table *tbl, long index, long npages,
+                           unsigned long uaddr,
+                           enum dma_data_direction direction,
+                           struct dma_attrs *attrs)
 {
-       u64 *tcep, *tces;
+       return pnv_tce_build(tbl, index, npages, uaddr, direction, attrs,
+                       false);
+}
 
-       tces = tcep = ((u64 *)tbl->it_base) + index - tbl->it_offset;
+static void pnv_tce_free(struct iommu_table *tbl, long index, long npages,
+               bool rm)
+{
+       __be64 *tcep, *tces;
+
+       tces = tcep = ((__be64 *)tbl->it_base) + index - tbl->it_offset;
 
        while (npages--)
-               *(tcep++) = 0;
+               *(tcep++) = cpu_to_be64(0);
 
        if (tbl->it_type & TCE_PCI_SWINV_FREE)
-               pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1);
+               pnv_pci_ioda_tce_invalidate(tbl, tces, tcep - 1, rm);
+}
+
+static void pnv_tce_free_vm(struct iommu_table *tbl, long index, long npages)
+{
+       pnv_tce_free(tbl, index, npages, false);
 }
 
 static unsigned long pnv_tce_get(struct iommu_table *tbl, long index)
@@ -446,6 +465,19 @@ static unsigned long pnv_tce_get(struct iommu_table *tbl, long index)
        return ((u64 *)tbl->it_base)[index - tbl->it_offset];
 }
 
+static int pnv_tce_build_rm(struct iommu_table *tbl, long index, long npages,
+                           unsigned long uaddr,
+                           enum dma_data_direction direction,
+                           struct dma_attrs *attrs)
+{
+       return pnv_tce_build(tbl, index, npages, uaddr, direction, attrs, true);
+}
+
+static void pnv_tce_free_rm(struct iommu_table *tbl, long index, long npages)
+{
+       pnv_tce_free(tbl, index, npages, true);
+}
+
 void pnv_pci_setup_iommu_table(struct iommu_table *tbl,
                               void *tce_mem, u64 tce_size,
                               u64 dma_offset)
@@ -484,8 +516,8 @@ static struct iommu_table *pnv_pci_setup_bml_iommu(struct pci_controller *hose)
        swinvp = of_get_property(hose->dn, "linux,tce-sw-invalidate-info",
                                 NULL);
        if (swinvp) {
-               tbl->it_busno = swinvp[1];
-               tbl->it_index = (unsigned long)ioremap(swinvp[0], 8);
+               tbl->it_busno = be64_to_cpu(swinvp[1]);
+               tbl->it_index = (unsigned long)ioremap(be64_to_cpup(swinvp), 8);
                tbl->it_type = TCE_PCI_SWINV_CREATE | TCE_PCI_SWINV_FREE;
        }
        return tbl;
@@ -610,8 +642,10 @@ void __init pnv_pci_init(void)
 
        /* Configure IOMMU DMA hooks */
        ppc_md.pci_dma_dev_setup = pnv_pci_dma_dev_setup;
-       ppc_md.tce_build = pnv_tce_build;
-       ppc_md.tce_free = pnv_tce_free;
+       ppc_md.tce_build = pnv_tce_build_vm;
+       ppc_md.tce_free = pnv_tce_free_vm;
+       ppc_md.tce_build_rm = pnv_tce_build_rm;
+       ppc_md.tce_free_rm = pnv_tce_free_rm;
        ppc_md.tce_get = pnv_tce_get;
        ppc_md.pci_probe_mode = pnv_pci_probe_mode;
        set_pci_dma_ops(&dma_iommu_ops);
index d633c64e05a1ef9204924b48a132bb505cd5e0a8..911c24ef033e0ae207036e5d5cab8bceaf07e14a 100644 (file)
@@ -17,7 +17,7 @@ enum pnv_phb_model {
        PNV_PHB_MODEL_PHB3,
 };
 
-#define PNV_PCI_DIAG_BUF_SIZE  4096
+#define PNV_PCI_DIAG_BUF_SIZE  8192
 #define PNV_IODA_PE_DEV                (1 << 0)        /* PE has single PCI device     */
 #define PNV_IODA_PE_BUS                (1 << 1)        /* PE has primary PCI bus       */
 #define PNV_IODA_PE_BUS_ALL    (1 << 2)        /* PE has subordinate buses     */
@@ -52,6 +52,7 @@ struct pnv_ioda_pe {
        int                     tce32_seg;
        int                     tce32_segcount;
        struct iommu_table      tce32_table;
+       phys_addr_t             tce_inval_reg_phys;
 
        /* XXX TODO: Add support for additional 64-bit iommus */
 
@@ -124,6 +125,7 @@ struct pnv_phb {
                struct {
                        /* Global bridge info */
                        unsigned int            total_pe;
+                       unsigned int            reserved_pe;
                        unsigned int            m32_size;
                        unsigned int            m32_segsize;
                        unsigned int            m32_pci_base;
@@ -193,6 +195,6 @@ extern void pnv_pci_init_p5ioc2_hub(struct device_node *np);
 extern void pnv_pci_init_ioda_hub(struct device_node *np);
 extern void pnv_pci_init_ioda2_phb(struct device_node *np);
 extern void pnv_pci_ioda_tce_invalidate(struct iommu_table *tbl,
-                                       u64 *startp, u64 *endp);
+                                       __be64 *startp, __be64 *endp, bool rm);
 
 #endif /* __POWERNV_PCI_H */
diff --git a/arch/powerpc/platforms/powernv/rng.c b/arch/powerpc/platforms/powernv/rng.c
new file mode 100644 (file)
index 0000000..8844628
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2013, Michael Ellerman, 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.
+ */
+
+#define pr_fmt(fmt)    "powernv-rng: " fmt
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <asm/archrandom.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/machdep.h>
+
+
+struct powernv_rng {
+       void __iomem *regs;
+       unsigned long mask;
+};
+
+static DEFINE_PER_CPU(struct powernv_rng *, powernv_rng);
+
+
+static unsigned long rng_whiten(struct powernv_rng *rng, unsigned long val)
+{
+       unsigned long parity;
+
+       /* Calculate the parity of the value */
+       asm ("popcntd %0,%1" : "=r" (parity) : "r" (val));
+
+       /* xor our value with the previous mask */
+       val ^= rng->mask;
+
+       /* update the mask based on the parity of this value */
+       rng->mask = (rng->mask << 1) | (parity & 1);
+
+       return val;
+}
+
+int powernv_get_random_long(unsigned long *v)
+{
+       struct powernv_rng *rng;
+
+       rng = get_cpu_var(powernv_rng);
+
+       *v = rng_whiten(rng, in_be64(rng->regs));
+
+       put_cpu_var(rng);
+
+       return 1;
+}
+EXPORT_SYMBOL_GPL(powernv_get_random_long);
+
+static __init void rng_init_per_cpu(struct powernv_rng *rng,
+                                   struct device_node *dn)
+{
+       int chip_id, cpu;
+
+       chip_id = of_get_ibm_chip_id(dn);
+       if (chip_id == -1)
+               pr_warn("No ibm,chip-id found for %s.\n", dn->full_name);
+
+       for_each_possible_cpu(cpu) {
+               if (per_cpu(powernv_rng, cpu) == NULL ||
+                   cpu_to_chip_id(cpu) == chip_id) {
+                       per_cpu(powernv_rng, cpu) = rng;
+               }
+       }
+}
+
+static __init int rng_create(struct device_node *dn)
+{
+       struct powernv_rng *rng;
+       unsigned long val;
+
+       rng = kzalloc(sizeof(*rng), GFP_KERNEL);
+       if (!rng)
+               return -ENOMEM;
+
+       rng->regs = of_iomap(dn, 0);
+       if (!rng->regs) {
+               kfree(rng);
+               return -ENXIO;
+       }
+
+       val = in_be64(rng->regs);
+       rng->mask = val;
+
+       rng_init_per_cpu(rng, dn);
+
+       pr_info_once("Registering arch random hook.\n");
+
+       ppc_md.get_random_long = powernv_get_random_long;
+
+       return 0;
+}
+
+static __init int rng_init(void)
+{
+       struct device_node *dn;
+       int rc;
+
+       for_each_compatible_node(dn, NULL, "ibm,power-rng") {
+               rc = rng_create(dn);
+               if (rc) {
+                       pr_err("Failed creating rng for %s (%d).\n",
+                               dn->full_name, rc);
+                       continue;
+               }
+
+               /* Create devices for hwrng driver */
+               of_platform_device_create(dn, NULL, NULL);
+       }
+
+       return 0;
+}
+subsys_initcall(rng_init);
index 6c61ec5ee914aa559bff1834692ab8a59b12e87d..fbccac9cd2dc393c2828ccacfd70e8018efcfb10 100644 (file)
@@ -3,7 +3,7 @@ ccflags-$(CONFIG_PPC_PSERIES_DEBUG)     += -DDEBUG
 
 obj-y                  := lpar.o hvCall.o nvram.o reconfig.o \
                           setup.o iommu.o event_sources.o ras.o \
-                          firmware.o power.o dlpar.o mobility.o
+                          firmware.o power.o dlpar.o mobility.o rng.o
 obj-$(CONFIG_SMP)      += smp.o
 obj-$(CONFIG_SCANLOG)  += scanlog.o
 obj-$(CONFIG_EEH)      += eeh_pseries.o
index 0307901e41328ed8c77f0a32fdfed9d896ad084f..f253361552aee3fbc3c98f077790f89551b4ea74 100644 (file)
@@ -52,7 +52,7 @@
 
 
 static void tce_invalidate_pSeries_sw(struct iommu_table *tbl,
-                                     u64 *startp, u64 *endp)
+                                     __be64 *startp, __be64 *endp)
 {
        u64 __iomem *invalidate = (u64 __iomem *)tbl->it_index;
        unsigned long start, end, inc;
@@ -86,7 +86,7 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index,
                              struct dma_attrs *attrs)
 {
        u64 proto_tce;
-       u64 *tcep, *tces;
+       __be64 *tcep, *tces;
        u64 rpn;
 
        proto_tce = TCE_PCI_READ; // Read allowed
@@ -94,12 +94,12 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index,
        if (direction != DMA_TO_DEVICE)
                proto_tce |= TCE_PCI_WRITE;
 
-       tces = tcep = ((u64 *)tbl->it_base) + index;
+       tces = tcep = ((__be64 *)tbl->it_base) + index;
 
        while (npages--) {
                /* can't move this out since we might cross MEMBLOCK boundary */
                rpn = __pa(uaddr) >> TCE_SHIFT;
-               *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
+               *tcep = cpu_to_be64(proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT);
 
                uaddr += TCE_PAGE_SIZE;
                tcep++;
@@ -113,9 +113,9 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index,
 
 static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
 {
-       u64 *tcep, *tces;
+       __be64 *tcep, *tces;
 
-       tces = tcep = ((u64 *)tbl->it_base) + index;
+       tces = tcep = ((__be64 *)tbl->it_base) + index;
 
        while (npages--)
                *(tcep++) = 0;
@@ -126,11 +126,11 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages)
 
 static unsigned long tce_get_pseries(struct iommu_table *tbl, long index)
 {
-       u64 *tcep;
+       __be64 *tcep;
 
-       tcep = ((u64 *)tbl->it_base) + index;
+       tcep = ((__be64 *)tbl->it_base) + index;
 
-       return *tcep;
+       return be64_to_cpu(*tcep);
 }
 
 static void tce_free_pSeriesLP(struct iommu_table*, long, long);
@@ -177,7 +177,7 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
        return ret;
 }
 
-static DEFINE_PER_CPU(u64 *, tce_page);
+static DEFINE_PER_CPU(__be64 *, tce_page);
 
 static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
                                     long npages, unsigned long uaddr,
@@ -186,7 +186,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
 {
        u64 rc = 0;
        u64 proto_tce;
-       u64 *tcep;
+       __be64 *tcep;
        u64 rpn;
        long l, limit;
        long tcenum_start = tcenum, npages_start = npages;
@@ -206,7 +206,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
         * from iommu_alloc{,_sg}()
         */
        if (!tcep) {
-               tcep = (u64 *)__get_free_page(GFP_ATOMIC);
+               tcep = (__be64 *)__get_free_page(GFP_ATOMIC);
                /* If allocation fails, fall back to the loop implementation */
                if (!tcep) {
                        local_irq_restore(flags);
@@ -230,7 +230,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
                limit = min_t(long, npages, 4096/TCE_ENTRY_SIZE);
 
                for (l = 0; l < limit; l++) {
-                       tcep[l] = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
+                       tcep[l] = cpu_to_be64(proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT);
                        rpn++;
                }
 
@@ -329,16 +329,16 @@ struct direct_window {
 
 /* Dynamic DMA Window support */
 struct ddw_query_response {
-       u32 windows_available;
-       u32 largest_available_block;
-       u32 page_size;
-       u32 migration_capable;
+       __be32 windows_available;
+       __be32 largest_available_block;
+       __be32 page_size;
+       __be32 migration_capable;
 };
 
 struct ddw_create_response {
-       u32 liobn;
-       u32 addr_hi;
-       u32 addr_lo;
+       __be32 liobn;
+       __be32 addr_hi;
+       __be32 addr_lo;
 };
 
 static LIST_HEAD(direct_window_list);
@@ -392,7 +392,8 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
                                        unsigned long num_pfn, const void *arg)
 {
        const struct dynamic_dma_window_prop *maprange = arg;
-       u64 *tcep, tce_size, num_tce, dma_offset, next, proto_tce, liobn;
+       u64 tce_size, num_tce, dma_offset, next, proto_tce, liobn;
+       __be64 *tcep;
        u32 tce_shift;
        u64 rc = 0;
        long l, limit;
@@ -401,7 +402,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
        tcep = __get_cpu_var(tce_page);
 
        if (!tcep) {
-               tcep = (u64 *)__get_free_page(GFP_ATOMIC);
+               tcep = (__be64 *)__get_free_page(GFP_ATOMIC);
                if (!tcep) {
                        local_irq_enable();
                        return -ENOMEM;
@@ -435,7 +436,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
                dma_offset = next + be64_to_cpu(maprange->dma_base);
 
                for (l = 0; l < limit; l++) {
-                       tcep[l] = proto_tce | next;
+                       tcep[l] = cpu_to_be64(proto_tce | next);
                        next += tce_size;
                }
 
@@ -780,7 +781,7 @@ static u64 find_existing_ddw(struct device_node *pdn)
        list_for_each_entry(window, &direct_window_list, list) {
                if (window->device == pdn) {
                        direct64 = window->prop;
-                       dma_addr = direct64->dma_base;
+                       dma_addr = be64_to_cpu(direct64->dma_base);
                        break;
                }
        }
@@ -1045,11 +1046,11 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
                dev_dbg(&dev->dev, "no free dynamic windows");
                goto out_restore_window;
        }
-       if (query.page_size & 4) {
+       if (be32_to_cpu(query.page_size) & 4) {
                page_shift = 24; /* 16MB */
-       } else if (query.page_size & 2) {
+       } else if (be32_to_cpu(query.page_size) & 2) {
                page_shift = 16; /* 64kB */
-       } else if (query.page_size & 1) {
+       } else if (be32_to_cpu(query.page_size) & 1) {
                page_shift = 12; /* 4kB */
        } else {
                dev_dbg(&dev->dev, "no supported direct page size in mask %x",
@@ -1059,7 +1060,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
        /* verify the window * number of ptes will map the partition */
        /* check largest block * page size > max memory hotplug addr */
        max_addr = memory_hotplug_max();
-       if (query.largest_available_block < (max_addr >> page_shift)) {
+       if (be32_to_cpu(query.largest_available_block) < (max_addr >> page_shift)) {
                dev_dbg(&dev->dev, "can't map partiton max 0x%llx with %u "
                          "%llu-sized pages\n", max_addr,  query.largest_available_block,
                          1ULL << page_shift);
@@ -1085,7 +1086,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
        if (ret != 0)
                goto out_free_prop;
 
-       ddwprop->liobn = cpu_to_be32(create.liobn);
+       ddwprop->liobn = create.liobn;
        ddwprop->dma_base = cpu_to_be64(of_read_number(&create.addr_hi, 2));
        ddwprop->tce_shift = cpu_to_be32(page_shift);
        ddwprop->window_shift = cpu_to_be32(len);
index d276cd3edd8f51641db54dfb459cb2efe4fa7f91..057fc894be511342da4c914d28113b73a44752c0 100644 (file)
@@ -429,9 +429,6 @@ static int __init pseries_nvram_init_os_partition(struct nvram_os_partition
        loff_t p;
        int size;
 
-       /* Scan nvram for partitions */
-       nvram_scan_partitions();
-
        /* Look for ours */
        p = nvram_find_partition(part->name, NVRAM_SIG_OS, &size);
 
@@ -795,6 +792,9 @@ static int __init pseries_nvram_init_log_partitions(void)
 {
        int rc;
 
+       /* Scan nvram for partitions */
+       nvram_scan_partitions();
+
        rc = pseries_nvram_init_os_partition(&rtas_log_partition);
        nvram_init_oops_partition(rc == 0);
        return 0;
@@ -804,7 +804,7 @@ machine_arch_initcall(pseries, pseries_nvram_init_log_partitions);
 int __init pSeries_nvram_init(void)
 {
        struct device_node *nvram;
-       const unsigned int *nbytes_p;
+       const __be32 *nbytes_p;
        unsigned int proplen;
 
        nvram = of_find_node_by_type(NULL, "nvram");
@@ -817,7 +817,7 @@ int __init pSeries_nvram_init(void)
                return -EIO;
        }
 
-       nvram_size = *nbytes_p;
+       nvram_size = be32_to_cpup(nbytes_p);
 
        nvram_fetch = rtas_token("nvram-fetch");
        nvram_store = rtas_token("nvram-store");
diff --git a/arch/powerpc/platforms/pseries/rng.c b/arch/powerpc/platforms/pseries/rng.c
new file mode 100644 (file)
index 0000000..a702f1c
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2013, Michael Ellerman, 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.
+ */
+
+#define pr_fmt(fmt)    "pseries-rng: " fmt
+
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <asm/archrandom.h>
+#include <asm/machdep.h>
+
+
+static int pseries_get_random_long(unsigned long *v)
+{
+       unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+
+       if (plpar_hcall(H_RANDOM, retbuf) == H_SUCCESS) {
+               *v = retbuf[0];
+               return 1;
+       }
+
+       return 0;
+}
+
+static __init int rng_init(void)
+{
+       struct device_node *dn;
+
+       dn = of_find_compatible_node(NULL, NULL, "ibm,random");
+       if (!dn)
+               return -ENODEV;
+
+       pr_info("Registering arch random hook.\n");
+
+       ppc_md.get_random_long = pseries_get_random_long;
+
+       return 0;
+}
+subsys_initcall(rng_init);
index b56b70aeb4971c6f68a9c0815bfcadce906947ac..268bc899c1f7168ca5827920010af0b53595c228 100644 (file)
@@ -116,7 +116,14 @@ static int a2_scom_ram(scom_map_t scom, int thread, u32 insn, int extmask)
 
        scom_write(scom, SCOM_RAMIC, cmd);
 
-       while (!((val = scom_read(scom, SCOM_RAMC)) & mask)) {
+       for (;;) {
+               if (scom_read(scom, SCOM_RAMC, &val) != 0) {
+                       pr_err("SCOM error on instruction 0x%08x, thread %d\n",
+                              insn, thread);
+                       return -1;
+               }
+               if (val & mask)
+                       break;
                pr_devel("Waiting on RAMC = 0x%llx\n", val);
                if (++n == 3) {
                        pr_err("RAMC timeout on instruction 0x%08x, thread %d\n",
@@ -151,9 +158,7 @@ static int a2_scom_getgpr(scom_map_t scom, int thread, int gpr, int alt,
        if (rc)
                return rc;
 
-       *out_gpr = scom_read(scom, SCOM_RAMD);
-
-       return 0;
+       return scom_read(scom, SCOM_RAMD, out_gpr);
 }
 
 static int a2_scom_getspr(scom_map_t scom, int thread, int spr, u64 *out_spr)
@@ -353,7 +358,10 @@ int a2_scom_startup_cpu(unsigned int lcpu, int thr_idx, struct device_node *np)
 
        pr_devel("Bringing up CPU%d using SCOM...\n", lcpu);
 
-       pccr0 = scom_read(scom, SCOM_PCCR0);
+       if (scom_read(scom, SCOM_PCCR0, &pccr0) != 0) {
+               printk(KERN_ERR "XSCOM failure readng PCCR0 on CPU%d\n", lcpu);
+               return -1;
+       }
        scom_write(scom, SCOM_PCCR0, pccr0 | SCOM_PCCR0_ENABLE_DEBUG |
                                     SCOM_PCCR0_ENABLE_RAM);
 
index 4052e2259f3016d904a707ff3e2524e1f2f58ac6..8928507affead7aa3f9f128232af8d4822188331 100644 (file)
@@ -50,18 +50,22 @@ static void wsp_scom_unmap(scom_map_t map)
        iounmap((void *)map);
 }
 
-static u64 wsp_scom_read(scom_map_t map, u32 reg)
+static int wsp_scom_read(scom_map_t map, u64 reg, u64 *value)
 {
        u64 __iomem *addr = (u64 __iomem *)map;
 
-       return in_be64(addr + reg);
+       *value = in_be64(addr + reg);
+
+       return 0;
 }
 
-static void wsp_scom_write(scom_map_t map, u32 reg, u64 value)
+static int wsp_scom_write(scom_map_t map, u64 reg, u64 value)
 {
        u64 __iomem *addr = (u64 __iomem *)map;
 
-       return out_be64(addr + reg, value);
+       out_be64(addr + reg, value);
+
+       return 0;
 }
 
 static const struct scom_controller wsp_scom_controller = {
index d25cc96c21b82fda4dcb44872446ec9b206968c7..ddb6efe889144dd78e15e80150e7b8a75bbb2d89 100644 (file)
@@ -89,6 +89,7 @@ void wsp_halt(void)
        struct device_node *dn;
        struct device_node *mine;
        struct device_node *me;
+       int rc;
 
        me = of_get_cpu_node(smp_processor_id(), NULL);
        mine = scom_find_parent(me);
@@ -101,15 +102,15 @@ void wsp_halt(void)
 
                /* read-modify-write it so the HW probe does not get
                 * confused */
-               val = scom_read(m, 0);
-               val |= 1;
-               scom_write(m, 0, val);
+               rc = scom_read(m, 0, &val);
+               if (rc == 0)
+                       scom_write(m, 0, val | 1);
                scom_unmap(m);
        }
        m = scom_map(mine, 0, 1);
-       val = scom_read(m, 0);
-       val |= 1;
-       scom_write(m, 0, val);
+       rc = scom_read(m, 0, &val);
+       if (rc == 0)
+               scom_write(m, 0, val | 1);
        /* should never return */
        scom_unmap(m);
 }
index ab4cb54764721870b06e3b08ee42121fc7fb7ea4..13ec968be4c7a25ca79fc480a7aab26e514b3bb8 100644 (file)
@@ -28,7 +28,7 @@ config PPC_SCOM
 
 config SCOM_DEBUGFS
        bool "Expose SCOM controllers via debugfs"
-       depends on PPC_SCOM
+       depends on PPC_SCOM && DEBUG_FS
        default n
 
 config GE_FPGA
index ccfb50ddfe38f7242b071c6519aaa1eb43daf6a2..21039634d1d09bf0f9603c59f2baf61d4a95c2b9 100644 (file)
@@ -40,7 +40,7 @@
 
 static int fsl_pcie_bus_fixup, is_mpc83xx_pci;
 
-static void quirk_fsl_pcie_header(struct pci_dev *dev)
+static void quirk_fsl_pcie_early(struct pci_dev *dev)
 {
        u8 hdr_type;
 
@@ -562,7 +562,8 @@ no_bridge:
 }
 #endif /* CONFIG_FSL_SOC_BOOKE || CONFIG_PPC_86xx */
 
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID,
+                       quirk_fsl_pcie_early);
 
 #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)
 struct mpc83xx_pcie_priv {
index c6d00736f07f559f677e25344c15c09943a3b25e..4c5a19ef4f0bb806e8adcf9251aa63f6d365a7bb 100644 (file)
@@ -21,8 +21,6 @@ struct device_node;
 
 extern void fsl_rstcr_restart(char *cmd);
 
-#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
-
 /* The different ports that the DIU can be connected to */
 enum fsl_diu_monitor_port {
        FSL_DIU_PORT_DVI,       /* DVI */
@@ -43,7 +41,6 @@ struct platform_diu_data_ops {
 };
 
 extern struct platform_diu_data_ops diu_ops;
-#endif
 
 void fsl_hv_restart(char *cmd);
 void fsl_hv_halt(void);
index 1be54faf60dd8be75f9f149101733c4c1c92f299..bdcb8588e4926c42130935a0ef33d2d19cab4b99 100644 (file)
@@ -1088,8 +1088,14 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq,
         * is done here.
         */
        if (!mpic_is_ipi(mpic, hw) && (mpic->flags & MPIC_NO_RESET)) {
+               int cpu;
+
+               preempt_disable();
+               cpu = mpic_processor_id(mpic);
+               preempt_enable();
+
                mpic_set_vector(virq, hw);
-               mpic_set_destination(virq, mpic_processor_id(mpic));
+               mpic_set_destination(virq, cpu);
                mpic_irq_set_priority(virq, 8);
        }
 
index 4a25c26f0bf43e51ef5fe6d37c0fc1fcf788450d..a3a8fad8537d10c4efff7f17b515e8b20cab4947 100644 (file)
@@ -228,7 +228,7 @@ static struct platform_device * __init mv64x60_eth_register_shared_pdev(
 
        if (id == 0) {
                pdev = platform_device_register_simple("orion-mdio", -1, &r[1], 1);
-               if (!pdev)
+               if (IS_ERR(pdev))
                        return pdev;
        }
 
index 9193e12df6951ed570d0558d8d361f99af117153..6f5a8d177c427f038aa65d0a7af9ce5657459625 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/debug.h>
 #include <asm/prom.h>
 #include <asm/scom.h>
+#include <asm/uaccess.h>
 
 const struct scom_controller *scom_controller;
 EXPORT_SYMBOL_GPL(scom_controller);
@@ -53,7 +54,7 @@ scom_map_t scom_map_device(struct device_node *dev, int index)
 {
        struct device_node *parent;
        unsigned int cells, size;
-       const u32 *prop;
+       const __be32 *prop, *sprop;
        u64 reg, cnt;
        scom_map_t ret;
 
@@ -62,12 +63,24 @@ scom_map_t scom_map_device(struct device_node *dev, int index)
        if (parent == NULL)
                return 0;
 
-       prop = of_get_property(parent, "#scom-cells", NULL);
-       cells = prop ? *prop : 1;
-
+       /*
+        * We support "scom-reg" properties for adding scom registers
+        * to a random device-tree node with an explicit scom-parent
+        *
+        * We also support the simple "reg" property if the device is
+        * a direct child of a scom controller.
+        *
+        * In case both exist, "scom-reg" takes precedence.
+        */
        prop = of_get_property(dev, "scom-reg", &size);
+       sprop = of_get_property(parent, "#scom-cells", NULL);
+       if (!prop && parent == dev->parent) {
+               prop = of_get_property(dev, "reg", &size);
+               sprop = of_get_property(parent, "#address-cells", NULL);
+       }
        if (!prop)
-               return 0;
+               return NULL;
+       cells = sprop ? be32_to_cpup(sprop) : 1;
        size >>= 2;
 
        if (index >= (size / (2*cells)))
@@ -86,62 +99,89 @@ EXPORT_SYMBOL_GPL(scom_map_device);
 #ifdef CONFIG_SCOM_DEBUGFS
 struct scom_debug_entry {
        struct device_node *dn;
-       unsigned long addr;
-       scom_map_t map;
-       spinlock_t lock;
-       char name[8];
-       struct debugfs_blob_wrapper blob;
+       struct debugfs_blob_wrapper path;
+       char name[16];
 };
 
-static int scom_addr_set(void *data, u64 val)
+static ssize_t scom_debug_read(struct file *filp, char __user *ubuf,
+                              size_t count, loff_t *ppos)
 {
-       struct scom_debug_entry *ent = data;
-
-       ent->addr = 0;
-       scom_unmap(ent->map);
-
-       ent->map = scom_map(ent->dn, val, 1);
-       if (scom_map_ok(ent->map))
-               ent->addr = val;
-       else
-               return -EFAULT;
-
-       return 0;
-}
-
-static int scom_addr_get(void *data, u64 *val)
-{
-       struct scom_debug_entry *ent = data;
-       *val = ent->addr;
-       return 0;
+       struct scom_debug_entry *ent = filp->private_data;
+       u64 __user *ubuf64 = (u64 __user *)ubuf;
+       loff_t off = *ppos;
+       ssize_t done = 0; 
+       u64 reg, reg_cnt, val;
+       scom_map_t map;
+       int rc;
+
+       if (off < 0 || (off & 7) || (count & 7))
+               return -EINVAL;
+       reg = off >> 3;
+       reg_cnt = count >> 3;
+
+       map = scom_map(ent->dn, reg, reg_cnt);
+       if (!scom_map_ok(map))
+               return -ENXIO;
+
+       for (reg = 0; reg < reg_cnt; reg++) {
+               rc = scom_read(map, reg, &val);
+               if (!rc)
+                       rc = put_user(val, ubuf64);
+               if (rc) {
+                       if (!done)
+                               done = rc;
+                       break;
+               }
+               ubuf64++;
+               *ppos += 8;
+               done += 8;
+       }
+       scom_unmap(map);
+       return done;
 }
-DEFINE_SIMPLE_ATTRIBUTE(scom_addr_fops, scom_addr_get, scom_addr_set,
-                       "0x%llx\n");
 
-static int scom_val_set(void *data, u64 val)
+static ssize_t scom_debug_write(struct file* filp, const char __user *ubuf,
+                               size_t count, loff_t *ppos)
 {
-       struct scom_debug_entry *ent = data;
-
-       if (!scom_map_ok(ent->map))
-               return -EFAULT;
-
-       scom_write(ent->map, 0, val);
-
-       return 0;
+       struct scom_debug_entry *ent = filp->private_data;
+       u64 __user *ubuf64 = (u64 __user *)ubuf;
+       loff_t off = *ppos;
+       ssize_t done = 0; 
+       u64 reg, reg_cnt, val;
+       scom_map_t map;
+       int rc;
+
+       if (off < 0 || (off & 7) || (count & 7))
+               return -EINVAL;
+       reg = off >> 3;
+       reg_cnt = count >> 3;
+
+       map = scom_map(ent->dn, reg, reg_cnt);
+       if (!scom_map_ok(map))
+               return -ENXIO;
+
+       for (reg = 0; reg < reg_cnt; reg++) {
+               rc = get_user(val, ubuf64);
+               if (!rc)
+                       rc = scom_write(map, reg,  val);
+               if (rc) {
+                       if (!done)
+                               done = rc;
+                       break;
+               }
+               ubuf64++;
+               done += 8;
+       }
+       scom_unmap(map);
+       return done;
 }
 
-static int scom_val_get(void *data, u64 *val)
-{
-       struct scom_debug_entry *ent = data;
-
-       if (!scom_map_ok(ent->map))
-               return -EFAULT;
-
-       *val = scom_read(ent->map, 0);
-       return 0;
-}
-DEFINE_SIMPLE_ATTRIBUTE(scom_val_fops, scom_val_get, scom_val_set,
-                       "0x%llx\n");
+static const struct file_operations scom_debug_fops = {
+       .read =         scom_debug_read,
+       .write =        scom_debug_write,
+       .open =         simple_open,
+       .llseek =       default_llseek,
+};
 
 static int scom_debug_init_one(struct dentry *root, struct device_node *dn,
                               int i)
@@ -154,11 +194,9 @@ static int scom_debug_init_one(struct dentry *root, struct device_node *dn,
                return -ENOMEM;
 
        ent->dn = of_node_get(dn);
-       ent->map = SCOM_MAP_INVALID;
-       spin_lock_init(&ent->lock);
-       snprintf(ent->name, 8, "scom%d", i);
-       ent->blob.data = (void*) dn->full_name;
-       ent->blob.size = strlen(dn->full_name);
+       snprintf(ent->name, 16, "%08x", i);
+       ent->path.data = (void*) dn->full_name;
+       ent->path.size = strlen(dn->full_name);
 
        dir = debugfs_create_dir(ent->name, root);
        if (!dir) {
@@ -167,9 +205,8 @@ static int scom_debug_init_one(struct dentry *root, struct device_node *dn,
                return -1;
        }
 
-       debugfs_create_file("addr", 0600, dir, ent, &scom_addr_fops);
-       debugfs_create_file("value", 0600, dir, ent, &scom_val_fops);
-       debugfs_create_blob("path", 0400, dir, &ent->blob);
+       debugfs_create_blob("devspec", 0400, dir, &ent->path);
+       debugfs_create_file("access", 0600, dir, ent, &scom_debug_fops);
 
        return 0;
 }
@@ -185,8 +222,13 @@ static int scom_debug_init(void)
                return -1;
 
        i = rc = 0;
-       for_each_node_with_property(dn, "scom-controller")
-               rc |= scom_debug_init_one(root, dn, i++);
+       for_each_node_with_property(dn, "scom-controller") {
+               int id = of_get_ibm_chip_id(dn);
+               if (id == -1)
+                       id = i;
+               rc |= scom_debug_init_one(root, dn, id);
+               i++;
+       }
 
        return rc;
 }
index 39d72212655e3706ef5ca09dacd689156bc34399..3c6ee1b64e5d1eec2bf5d03679d537f1bc5c5d53 100644 (file)
@@ -112,6 +112,7 @@ static int ics_opal_set_affinity(struct irq_data *d,
                                 bool force)
 {
        unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
+       __be16 oserver;
        int16_t server;
        int8_t priority;
        int64_t rc;
@@ -120,13 +121,13 @@ static int ics_opal_set_affinity(struct irq_data *d,
        if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
                return -1;
 
-       rc = opal_get_xive(hw_irq, &server, &priority);
+       rc = opal_get_xive(hw_irq, &oserver, &priority);
        if (rc != OPAL_SUCCESS) {
-               pr_err("%s: opal_set_xive(irq=%d [hw 0x%x] server=%x)"
-                      " error %lld\n",
-                      __func__, d->irq, hw_irq, server, rc);
+               pr_err("%s: opal_get_xive(irq=%d [hw 0x%x]) error %lld\n",
+                      __func__, d->irq, hw_irq, rc);
                return -1;
        }
+       server = be16_to_cpu(oserver);
 
        wanted_server = xics_get_irq_server(d->irq, cpumask, 1);
        if (wanted_server < 0) {
@@ -181,7 +182,7 @@ static int ics_opal_map(struct ics *ics, unsigned int virq)
 {
        unsigned int hw_irq = (unsigned int)virq_to_hw(virq);
        int64_t rc;
-       int16_t server;
+       __be16 server;
        int8_t priority;
 
        if (WARN_ON(hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS))
@@ -201,7 +202,7 @@ static int ics_opal_map(struct ics *ics, unsigned int virq)
 static void ics_opal_mask_unknown(struct ics *ics, unsigned long vec)
 {
        int64_t rc;
-       int16_t server;
+       __be16 server;
        int8_t priority;
 
        /* Check if HAL knows about this interrupt */
@@ -215,14 +216,14 @@ static void ics_opal_mask_unknown(struct ics *ics, unsigned long vec)
 static long ics_opal_get_server(struct ics *ics, unsigned long vec)
 {
        int64_t rc;
-       int16_t server;
+       __be16 server;
        int8_t priority;
 
        /* Check if HAL knows about this interrupt */
        rc = opal_get_xive(vec, &server, &priority);
        if (rc != OPAL_SUCCESS)
                return -1;
-       return ics_opal_unmangle_server(server);
+       return ics_opal_unmangle_server(be16_to_cpu(server));
 }
 
 int __init ics_opal_init(void)
index 0aa9d91daef500486e999c8ce4ccb4cb90d2755d..c206de2951f20f086c099ab69e8a1a48286465be 100644 (file)
@@ -290,6 +290,19 @@ config HW_RANDOM_PSERIES
 
          If unsure, say Y.
 
+config HW_RANDOM_POWERNV
+       tristate "PowerNV Random Number Generator support"
+       depends on HW_RANDOM && PPC_POWERNV
+       default HW_RANDOM
+       ---help---
+         This is the driver for Random Number Generator hardware found
+         in POWER7+ and above machines for PowerNV platform.
+
+         To compile this driver as a module, choose M here: the
+         module will be called powernv-rng.
+
+         If unsure, say Y.
+
 config HW_RANDOM_EXYNOS
        tristate "EXYNOS HW random number generator support"
        depends on HW_RANDOM && HAS_IOMEM && HAVE_CLK
index bed467c9300e6ec99240a262585d6bf9409a0b94..d7d2435ff7fa8d38cd129d327c59ded717e3682a 100644 (file)
@@ -24,6 +24,7 @@ obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
 obj-$(CONFIG_HW_RANDOM_PICOXCELL) += picoxcell-rng.o
 obj-$(CONFIG_HW_RANDOM_PPC4XX) += ppc4xx-rng.o
 obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
+obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
 obj-$(CONFIG_HW_RANDOM_EXYNOS) += exynos-rng.o
 obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o
 obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
diff --git a/drivers/char/hw_random/powernv-rng.c b/drivers/char/hw_random/powernv-rng.c
new file mode 100644 (file)
index 0000000..3f4f632
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2013 Michael Ellerman, Guo Chao, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#define pr_fmt(fmt)    KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/random.h>
+#include <linux/hw_random.h>
+
+static int powernv_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
+{
+       unsigned long *buf;
+       int i, len;
+
+       /* We rely on rng_buffer_size() being >= sizeof(unsigned long) */
+       len = max / sizeof(unsigned long);
+
+       buf = (unsigned long *)data;
+
+       for (i = 0; i < len; i++)
+               powernv_get_random_long(buf++);
+
+       return len * sizeof(unsigned long);
+}
+
+static struct hwrng powernv_hwrng = {
+       .name = "powernv-rng",
+       .read = powernv_rng_read,
+};
+
+static int powernv_rng_remove(struct platform_device *pdev)
+{
+       hwrng_unregister(&powernv_hwrng);
+
+       return 0;
+}
+
+static int powernv_rng_probe(struct platform_device *pdev)
+{
+       int rc;
+
+       rc = hwrng_register(&powernv_hwrng);
+       if (rc) {
+               /* We only register one device, ignore any others */
+               if (rc == -EEXIST)
+                       rc = -ENODEV;
+
+               return rc;
+       }
+
+       pr_info("Registered powernv hwrng.\n");
+
+       return 0;
+}
+
+static struct of_device_id powernv_rng_match[] = {
+       { .compatible   = "ibm,power-rng",},
+       {},
+};
+MODULE_DEVICE_TABLE(of, powernv_rng_match);
+
+static struct platform_driver powernv_rng_driver = {
+       .driver = {
+               .name = "powernv_rng",
+               .of_match_table = powernv_rng_match,
+       },
+       .probe  = powernv_rng_probe,
+       .remove = powernv_rng_remove,
+};
+module_platform_driver(powernv_rng_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Bare metal HWRNG driver for POWER7+ and above");
index 5f1197929f0ceebaa2ca34632ca16be9046150dc..b761459a3436c25d31321f5bb46037f7faaf9292 100644 (file)
@@ -17,6 +17,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/hw_random.h>
 #include <asm/vio.h>
 
 static int pseries_rng_data_read(struct hwrng *rng, u32 *data)
 {
-       if (plpar_hcall(H_RANDOM, (unsigned long *)data) != H_SUCCESS) {
-               printk(KERN_ERR "pseries rng hcall error\n");
-               return 0;
+       int rc;
+
+       rc = plpar_hcall(H_RANDOM, (unsigned long *)data);
+       if (rc != H_SUCCESS) {
+               pr_err_ratelimited("H_RANDOM call failed %d\n", rc);
+               return -EIO;
        }
+
+       /* The hypervisor interface returns 64 bits */
        return 8;
 }
 
index 696238b9f0f7a2b6e9c24cd21f55052bf3e1b18e..d26a312f117aefbfa41dc8bbff377c5b53db345c 100644 (file)
@@ -103,6 +103,7 @@ config ADB_PMU_LED_IDE
        bool "Use front LED as IDE LED by default"
        depends on ADB_PMU_LED
        depends on LEDS_CLASS
+       depends on IDE_GD_ATA
        select LEDS_TRIGGERS
        select LEDS_TRIGGER_IDE_DISK
        help
index 7d4c70f859e30687bcd0892c195f9cbfc34826dc..aace017fc45210d04e795ecbb50c05d65989b23d 100644 (file)
@@ -1882,3 +1882,34 @@ int of_device_is_stdout_path(struct device_node *dn)
        return of_stdout == dn;
 }
 EXPORT_SYMBOL_GPL(of_device_is_stdout_path);
+
+/**
+ *     of_find_next_cache_node - Find a node's subsidiary cache
+ *     @np:    node of type "cpu" or "cache"
+ *
+ *     Returns a node pointer with refcount incremented, use
+ *     of_node_put() on it when done.  Caller should hold a reference
+ *     to np.
+ */
+struct device_node *of_find_next_cache_node(const struct device_node *np)
+{
+       struct device_node *child;
+       const phandle *handle;
+
+       handle = of_get_property(np, "l2-cache", NULL);
+       if (!handle)
+               handle = of_get_property(np, "next-level-cache", NULL);
+
+       if (handle)
+               return of_find_node_by_phandle(be32_to_cpup(handle));
+
+       /* OF on pmac has nodes instead of properties named "l2-cache"
+        * beneath CPU nodes.
+        */
+       if (!strcmp(np->type, "cpu"))
+               for_each_child_of_node(np, child)
+                       if (!strcmp(child->type, "cache"))
+                               return child;
+
+       return NULL;
+}
index cd69b48f6dfd390a8231f689b35f5d2588c16772..6496872e2e47c34c29ca75c79ce4d56bf7191146 100644 (file)
@@ -329,7 +329,7 @@ static void udbg_init_opal_common(void)
 void __init hvc_opal_init_early(void)
 {
        struct device_node *stdout_node = NULL;
-       const u32 *termno;
+       const __be32 *termno;
        const char *name = NULL;
        const struct hv_ops *ops;
        u32 index;
@@ -371,7 +371,7 @@ void __init hvc_opal_init_early(void)
        if (!stdout_node)
                return;
        termno = of_get_property(stdout_node, "reg", NULL);
-       index = termno ? *termno : 0;
+       index = termno ? be32_to_cpup(termno) : 0;
        if (index >= MAX_NR_HVC_CONSOLES)
                return;
        hvc_opal_privs[index] = &hvc_opal_boot_priv;
index ac2767100df56d3ef071f565ddfc7f4063432ca7..347050ea414a7f37e3962869f29437129cea1c75 100644 (file)
@@ -9,7 +9,7 @@
 
 static int hvsi_send_packet(struct hvsi_priv *pv, struct hvsi_header *packet)
 {
-       packet->seqno = atomic_inc_return(&pv->seqno);
+       packet->seqno = cpu_to_be16(atomic_inc_return(&pv->seqno));
 
        /* Assumes that always succeeds, works in practice */
        return pv->put_chars(pv->termno, (char *)packet, packet->len);
@@ -28,7 +28,7 @@ static void hvsi_start_handshake(struct hvsi_priv *pv)
        /* Send version query */
        q.hdr.type = VS_QUERY_PACKET_HEADER;
        q.hdr.len = sizeof(struct hvsi_query);
-       q.verb = VSV_SEND_VERSION_NUMBER;
+       q.verb = cpu_to_be16(VSV_SEND_VERSION_NUMBER);
        hvsi_send_packet(pv, &q.hdr);
 }
 
@@ -40,7 +40,7 @@ static int hvsi_send_close(struct hvsi_priv *pv)
 
        ctrl.hdr.type = VS_CONTROL_PACKET_HEADER;
        ctrl.hdr.len = sizeof(struct hvsi_control);
-       ctrl.verb = VSV_CLOSE_PROTOCOL;
+       ctrl.verb = cpu_to_be16(VSV_CLOSE_PROTOCOL);
        return hvsi_send_packet(pv, &ctrl.hdr);
 }
 
@@ -69,14 +69,14 @@ static void hvsi_got_control(struct hvsi_priv *pv)
 {
        struct hvsi_control *pkt = (struct hvsi_control *)pv->inbuf;
 
-       switch (pkt->verb) {
+       switch (be16_to_cpu(pkt->verb)) {
        case VSV_CLOSE_PROTOCOL:
                /* We restart the handshaking */
                hvsi_start_handshake(pv);
                break;
        case VSV_MODEM_CTL_UPDATE:
                /* Transition of carrier detect */
-               hvsi_cd_change(pv, pkt->word & HVSI_TSCD);
+               hvsi_cd_change(pv, be32_to_cpu(pkt->word) & HVSI_TSCD);
                break;
        }
 }
@@ -87,7 +87,7 @@ static void hvsi_got_query(struct hvsi_priv *pv)
        struct hvsi_query_response r;
 
        /* We only handle version queries */
-       if (pkt->verb != VSV_SEND_VERSION_NUMBER)
+       if (be16_to_cpu(pkt->verb) != VSV_SEND_VERSION_NUMBER)
                return;
 
        pr_devel("HVSI@%x: Got version query, sending response...\n",
@@ -96,7 +96,7 @@ static void hvsi_got_query(struct hvsi_priv *pv)
        /* Send version response */
        r.hdr.type = VS_QUERY_RESPONSE_PACKET_HEADER;
        r.hdr.len = sizeof(struct hvsi_query_response);
-       r.verb = VSV_SEND_VERSION_NUMBER;
+       r.verb = cpu_to_be16(VSV_SEND_VERSION_NUMBER);
        r.u.version = HVSI_VERSION;
        r.query_seqno = pkt->hdr.seqno;
        hvsi_send_packet(pv, &r.hdr);
@@ -112,7 +112,7 @@ static void hvsi_got_response(struct hvsi_priv *pv)
 
        switch(r->verb) {
        case VSV_SEND_MODEM_CTL_STATUS:
-               hvsi_cd_change(pv, r->u.mctrl_word & HVSI_TSCD);
+               hvsi_cd_change(pv, be32_to_cpu(r->u.mctrl_word) & HVSI_TSCD);
                pv->mctrl_update = 1;
                break;
        }
@@ -265,8 +265,7 @@ int hvsilib_read_mctrl(struct hvsi_priv *pv)
        pv->mctrl_update = 0;
        q.hdr.type = VS_QUERY_PACKET_HEADER;
        q.hdr.len = sizeof(struct hvsi_query);
-       q.hdr.seqno = atomic_inc_return(&pv->seqno);
-       q.verb = VSV_SEND_MODEM_CTL_STATUS;
+       q.verb = cpu_to_be16(VSV_SEND_MODEM_CTL_STATUS);
        rc = hvsi_send_packet(pv, &q.hdr);
        if (rc <= 0) {
                pr_devel("HVSI@%x: Error %d...\n", pv->termno, rc);
@@ -304,9 +303,9 @@ int hvsilib_write_mctrl(struct hvsi_priv *pv, int dtr)
 
        ctrl.hdr.type = VS_CONTROL_PACKET_HEADER,
        ctrl.hdr.len = sizeof(struct hvsi_control);
-       ctrl.verb = VSV_SET_MODEM_CTL;
-       ctrl.mask = HVSI_TSDTR;
-       ctrl.word = dtr ? HVSI_TSDTR : 0;
+       ctrl.verb = cpu_to_be16(VSV_SET_MODEM_CTL);
+       ctrl.mask = cpu_to_be32(HVSI_TSDTR);
+       ctrl.word = cpu_to_be32(dtr ? HVSI_TSDTR : 0);
        return hvsi_send_packet(pv, &ctrl.hdr);
 }
 
index a9df51f5d54c7b01ff0fc8cac9aa0afe803e8727..519b6e2d769ede04d120f6ea3bc5f848e4978148 100644 (file)
@@ -173,6 +173,21 @@ static inline void hash_del_rcu(struct hlist_node *node)
        hlist_for_each_entry_rcu(obj, &name[hash_min(key, HASH_BITS(name))],\
                member)
 
+/**
+ * hash_for_each_possible_rcu_notrace - iterate over all possible objects hashing
+ * to the same bucket in an rcu enabled hashtable in a rcu enabled hashtable
+ * @name: hashtable to iterate
+ * @obj: the type * to use as a loop cursor for each entry
+ * @member: the name of the hlist_node within the struct
+ * @key: the key of the objects to iterate over
+ *
+ * This is the same as hash_for_each_possible_rcu() except that it does
+ * not do any RCU debugging or tracing.
+ */
+#define hash_for_each_possible_rcu_notrace(name, obj, member, key) \
+       hlist_for_each_entry_rcu_notrace(obj, \
+               &name[hash_min(key, HASH_BITS(name))], member)
+
 /**
  * hash_for_each_possible_safe - iterate over all possible objects hashing to the
  * same bucket safe against removals
index 81443d557a2e179a7d3768c63abc2519d9d1ed19..8aa4006b9636e11dbcb4e32e988f43c30c865396 100644 (file)
@@ -297,12 +297,26 @@ static inline int put_page_testzero(struct page *page)
 /*
  * Try to grab a ref unless the page has a refcount of zero, return false if
  * that is the case.
+ * This can be called when MMU is off so it must not access
+ * any of the virtual mappings.
  */
 static inline int get_page_unless_zero(struct page *page)
 {
        return atomic_inc_not_zero(&page->_count);
 }
 
+/*
+ * Try to drop a ref unless the page has a refcount of one, return false if
+ * that is the case.
+ * This is to make sure that the refcount won't become zero after this drop.
+ * This can be called when MMU is off so it must not access
+ * any of the virtual mappings.
+ */
+static inline int put_page_unless_one(struct page *page)
+{
+       return atomic_add_unless(&page->_count, -1, 1);
+}
+
 extern int page_is_ram(unsigned long pfn);
 
 /* Support for virtually mapped pages */
index f95aee391e30fcb98eeec0f6569c0b4bc9b8ba31..c08c07e249b380544b09b63f9124d0c400f04df0 100644 (file)
@@ -226,6 +226,8 @@ static inline int of_get_child_count(const struct device_node *np)
        return num;
 }
 
+/* cache lookup */
+extern struct device_node *of_find_next_cache_node(const struct device_node *);
 extern struct device_node *of_find_node_with_property(
        struct device_node *from, const char *prop_name);
 #define for_each_node_with_property(dn, prop_name) \
index 6d53675c2b54691225b12f3f23c914aca86c35ac..98ada58f9942855b90583de9c5ed324993d39101 100644 (file)
@@ -329,7 +329,9 @@ static inline void set_page_writeback(struct page *page)
  * System with lots of page flags available. This allows separate
  * flags for PageHead() and PageTail() checks of compound pages so that bit
  * tests can be used in performance sensitive paths. PageCompound is
- * generally not used in hot code paths.
+ * generally not used in hot code paths except arch/powerpc/mm/init_64.c
+ * and arch/powerpc/kvm/book3s_64_vio_hv.c which use it to detect huge pages
+ * and avoid handling those in real mode.
  */
 __PAGEFLAG(Head, head) CLEARPAGEFLAG(Head, head)
 __PAGEFLAG(Tail, tail)