Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 15 Jun 2009 16:40:05 +0000 (09:40 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 15 Jun 2009 16:40:05 +0000 (09:40 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1244 commits)
  pkt_sched: Rename PSCHED_US2NS and PSCHED_NS2US
  ipv4: Fix fib_trie rebalancing
  Bluetooth: Fix issue with uninitialized nsh.type in DTL-1 driver
  Bluetooth: Fix Kconfig issue with RFKILL integration
  PIM-SM: namespace changes
  ipv4: update ARPD help text
  net: use a deferred timer in rt_check_expire
  ieee802154: fix kconfig bool/tristate muckup
  bonding: initialization rework
  bonding: use is_zero_ether_addr
  bonding: network device names are case sensative
  bonding: elminate bad refcount code
  bonding: fix style issues
  bonding: fix destructor
  bonding: remove bonding read/write semaphore
  bonding: initialize before registration
  bonding: bond_create always called with default parameters
  x_tables: Convert printk to pr_err
  netfilter: conntrack: optional reliable conntrack event delivery
  list_nulls: add hlist_nulls_add_head and hlist_nulls_del
  ...

234 files changed:
Documentation/filesystems/nilfs2.txt
Documentation/kernel-parameters.txt
Documentation/powerpc/dts-bindings/ecm.txt [new file with mode: 0644]
Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt
Documentation/powerpc/dts-bindings/fsl/esdhc.txt
Documentation/powerpc/dts-bindings/fsl/mcm.txt [new file with mode: 0644]
arch/powerpc/Kconfig
arch/powerpc/Kconfig.debug
arch/powerpc/Makefile
arch/powerpc/boot/dts/gef_ppc9a.dts
arch/powerpc/boot/dts/gef_sbc310.dts
arch/powerpc/boot/dts/gef_sbc610.dts
arch/powerpc/boot/dts/ksi8560.dts
arch/powerpc/boot/dts/mpc832x_mds.dts
arch/powerpc/boot/dts/mpc832x_rdb.dts
arch/powerpc/boot/dts/mpc8349emitx.dts
arch/powerpc/boot/dts/mpc8349emitxgp.dts
arch/powerpc/boot/dts/mpc834x_mds.dts
arch/powerpc/boot/dts/mpc836x_mds.dts
arch/powerpc/boot/dts/mpc836x_rdk.dts
arch/powerpc/boot/dts/mpc8377_mds.dts
arch/powerpc/boot/dts/mpc8378_mds.dts
arch/powerpc/boot/dts/mpc8379_mds.dts
arch/powerpc/boot/dts/mpc8536ds.dts
arch/powerpc/boot/dts/mpc8540ads.dts
arch/powerpc/boot/dts/mpc8541cds.dts
arch/powerpc/boot/dts/mpc8544ds.dts
arch/powerpc/boot/dts/mpc8548cds.dts
arch/powerpc/boot/dts/mpc8555cds.dts
arch/powerpc/boot/dts/mpc8560ads.dts
arch/powerpc/boot/dts/mpc8568mds.dts
arch/powerpc/boot/dts/mpc8569mds.dts [new file with mode: 0644]
arch/powerpc/boot/dts/mpc8572ds.dts
arch/powerpc/boot/dts/mpc8572ds_36b.dts
arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts
arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts
arch/powerpc/boot/dts/mpc8610_hpcd.dts
arch/powerpc/boot/dts/mpc8641_hpcn.dts
arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts [new file with mode: 0644]
arch/powerpc/boot/dts/p2020ds.dts [new file with mode: 0644]
arch/powerpc/boot/dts/sbc8349.dts
arch/powerpc/boot/dts/sbc8548.dts
arch/powerpc/boot/dts/sbc8560.dts
arch/powerpc/boot/dts/sbc8641d.dts
arch/powerpc/boot/dts/sequoia.dts
arch/powerpc/boot/dts/socrates.dts
arch/powerpc/boot/dts/stx_gp3_8560.dts
arch/powerpc/boot/dts/tqm8540.dts
arch/powerpc/boot/dts/tqm8541.dts
arch/powerpc/boot/dts/tqm8548-bigflash.dts
arch/powerpc/boot/dts/tqm8548.dts
arch/powerpc/boot/dts/tqm8555.dts
arch/powerpc/boot/dts/tqm8560.dts
arch/powerpc/boot/dts/virtex440-ml510.dts [new file with mode: 0644]
arch/powerpc/boot/dts/warp.dts
arch/powerpc/configs/40x/acadia_defconfig
arch/powerpc/configs/40x/ep405_defconfig
arch/powerpc/configs/40x/kilauea_defconfig
arch/powerpc/configs/40x/makalu_defconfig
arch/powerpc/configs/40x/virtex_defconfig
arch/powerpc/configs/44x/arches_defconfig
arch/powerpc/configs/44x/bamboo_defconfig
arch/powerpc/configs/44x/canyonlands_defconfig
arch/powerpc/configs/44x/ebony_defconfig
arch/powerpc/configs/44x/katmai_defconfig
arch/powerpc/configs/44x/rainier_defconfig
arch/powerpc/configs/44x/redwood_defconfig
arch/powerpc/configs/44x/sam440ep_defconfig
arch/powerpc/configs/44x/sequoia_defconfig
arch/powerpc/configs/44x/taishan_defconfig
arch/powerpc/configs/44x/virtex5_defconfig
arch/powerpc/include/asm/cpm2.h
arch/powerpc/include/asm/dma-mapping.h
arch/powerpc/include/asm/elf.h
arch/powerpc/include/asm/emulated_ops.h [new file with mode: 0644]
arch/powerpc/include/asm/feature-fixups.h
arch/powerpc/include/asm/lppaca.h
arch/powerpc/include/asm/machdep.h
arch/powerpc/include/asm/mmu.h
arch/powerpc/include/asm/mpc86xx.h [deleted file]
arch/powerpc/include/asm/paca.h
arch/powerpc/include/asm/page.h
arch/powerpc/include/asm/pci-bridge.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/ptrace.h
arch/powerpc/include/asm/qe.h
arch/powerpc/include/asm/scatterlist.h
arch/powerpc/include/asm/swiotlb.h [new file with mode: 0644]
arch/powerpc/include/asm/system.h
arch/powerpc/include/asm/xilinx_pci.h [new file with mode: 0644]
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/align.c
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/dma-swiotlb.c [new file with mode: 0644]
arch/powerpc/kernel/dma.c
arch/powerpc/kernel/exceptions-64s.S [new file with mode: 0644]
arch/powerpc/kernel/ftrace.c
arch/powerpc/kernel/head_32.S
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/head_booke.h
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/lparcfg.c
arch/powerpc/kernel/misc_64.S
arch/powerpc/kernel/paca.c
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/pci_32.c
arch/powerpc/kernel/pci_64.c
arch/powerpc/kernel/pci_dn.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/ptrace.c
arch/powerpc/kernel/rtas_pci.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/time.c
arch/powerpc/kernel/traps.c
arch/powerpc/kernel/vector.S
arch/powerpc/mm/Makefile
arch/powerpc/mm/hash_native_64.c
arch/powerpc/mm/init_64.c
arch/powerpc/mm/mmu_context_nohash.c
arch/powerpc/mm/numa.c
arch/powerpc/oprofile/op_model_fsl_emb.c
arch/powerpc/platforms/40x/Kconfig
arch/powerpc/platforms/40x/Makefile
arch/powerpc/platforms/40x/kilauea.c [deleted file]
arch/powerpc/platforms/40x/makalu.c [deleted file]
arch/powerpc/platforms/40x/ppc40x_simple.c
arch/powerpc/platforms/40x/virtex.c
arch/powerpc/platforms/44x/Kconfig
arch/powerpc/platforms/44x/Makefile
arch/powerpc/platforms/44x/virtex.c
arch/powerpc/platforms/44x/virtex_ml510.c [new file with mode: 0644]
arch/powerpc/platforms/44x/warp.c
arch/powerpc/platforms/52xx/efika.c
arch/powerpc/platforms/52xx/mpc52xx_pci.c
arch/powerpc/platforms/82xx/pq2ads.h
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/85xx/mpc85xx_ds.c
arch/powerpc/platforms/85xx/mpc85xx_mds.c
arch/powerpc/platforms/86xx/gef_ppc9a.c
arch/powerpc/platforms/86xx/gef_sbc310.c
arch/powerpc/platforms/86xx/gef_sbc610.c
arch/powerpc/platforms/86xx/mpc8610_hpcd.c
arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
arch/powerpc/platforms/86xx/mpc86xx_smp.c
arch/powerpc/platforms/86xx/sbc8641d.c
arch/powerpc/platforms/8xx/mpc885ads.h
arch/powerpc/platforms/Kconfig
arch/powerpc/platforms/Kconfig.cputype
arch/powerpc/platforms/cell/celleb_pci.c
arch/powerpc/platforms/cell/celleb_scc_epci.c
arch/powerpc/platforms/cell/celleb_scc_pciex.c
arch/powerpc/platforms/cell/spufs/inode.c
arch/powerpc/platforms/chrp/pci.c
arch/powerpc/platforms/fsl_uli1575.c
arch/powerpc/platforms/iseries/iommu.c
arch/powerpc/platforms/iseries/pci.c
arch/powerpc/platforms/powermac/pic.c
arch/powerpc/platforms/powermac/setup.c
arch/powerpc/platforms/ps3/smp.c
arch/powerpc/platforms/pseries/iommu.c
arch/powerpc/platforms/pseries/lpar.c
arch/powerpc/platforms/pseries/rtasd.c
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/sysdev/Makefile
arch/powerpc/sysdev/cpm2.c
arch/powerpc/sysdev/fsl_msi.c
arch/powerpc/sysdev/fsl_pci.c
arch/powerpc/sysdev/fsl_pci.h
arch/powerpc/sysdev/fsl_rio.c
arch/powerpc/sysdev/fsl_soc.c
arch/powerpc/sysdev/indirect_pci.c
arch/powerpc/sysdev/mpic.c
arch/powerpc/sysdev/ppc4xx_pci.c
arch/powerpc/sysdev/qe_lib/qe.c
arch/powerpc/sysdev/tsi108_pci.c
arch/powerpc/sysdev/xilinx_intc.c
arch/powerpc/sysdev/xilinx_pci.c [new file with mode: 0644]
arch/powerpc/xmon/xmon.c
drivers/char/viotape.c
drivers/i2c/busses/i2c-ibm_iic.c
drivers/macintosh/therm_adt746x.c
drivers/net/ucc_geth.c
drivers/net/ucc_geth.h
drivers/of/base.c
drivers/pci/Makefile
drivers/rapidio/rio-scan.c
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/da903x.c
drivers/regulator/fixed.c
drivers/regulator/lp3971.c [new file with mode: 0644]
drivers/regulator/max1586.c [new file with mode: 0644]
drivers/regulator/pcf50633-regulator.c
drivers/regulator/userspace-consumer.c [new file with mode: 0644]
drivers/regulator/virtual.c
drivers/regulator/wm8350-regulator.c
drivers/regulator/wm8400-regulator.c
drivers/video/xilinxfb.c
fs/nilfs2/bmap.c
fs/nilfs2/bmap.h
fs/nilfs2/btnode.c
fs/nilfs2/btnode.h
fs/nilfs2/btree.c
fs/nilfs2/btree.h
fs/nilfs2/cpfile.c
fs/nilfs2/cpfile.h
fs/nilfs2/dat.c
fs/nilfs2/dat.h
fs/nilfs2/direct.c
fs/nilfs2/direct.h
fs/nilfs2/gcinode.c
fs/nilfs2/inode.c
fs/nilfs2/ioctl.c
fs/nilfs2/mdt.c
fs/nilfs2/nilfs.h
fs/nilfs2/recovery.c
fs/nilfs2/segbuf.c
fs/nilfs2/seglist.h [deleted file]
fs/nilfs2/segment.c
fs/nilfs2/segment.h
fs/nilfs2/sufile.c
fs/nilfs2/sufile.h
fs/nilfs2/super.c
fs/nilfs2/the_nilfs.c
fs/ramfs/inode.c
include/linux/pci_ids.h
include/linux/regulator/lp3971.h [new file with mode: 0644]
include/linux/regulator/max1586.h [new file with mode: 0644]
include/linux/regulator/userspace-consumer.h [new file with mode: 0644]

index 55c4300..01539f4 100644 (file)
@@ -39,9 +39,8 @@ Features which NILFS2 does not support yet:
        - extended attributes
        - POSIX ACLs
        - quotas
-       - writable snapshots
-       - remote backup (CDP)
-       - data integrity
+       - fsck
+       - resize
        - defragmentation
 
 Mount options
index 5f66ba2..ad38006 100644 (file)
@@ -491,6 +491,13 @@ and is between 256 and 4096 characters. It is defined in the file
                        Also note the kernel might malfunction if you disable
                        some critical bits.
 
+       cmo_free_hint=  [PPC] Format: { yes | no }
+                       Specify whether pages are marked as being inactive
+                       when they are freed.  This is used in CMO environments
+                       to determine OS memory pressure for page stealing by
+                       a hypervisor.
+                       Default: yes
+
        code_bytes      [X86] How many bytes of object code to print
                        in an oops report.
                        Range: 0 - 8192
diff --git a/Documentation/powerpc/dts-bindings/ecm.txt b/Documentation/powerpc/dts-bindings/ecm.txt
new file mode 100644 (file)
index 0000000..f514f29
--- /dev/null
@@ -0,0 +1,64 @@
+=====================================================================
+E500 LAW & Coherency Module Device Tree Binding
+Copyright (C) 2009 Freescale Semiconductor Inc.
+=====================================================================
+
+Local Access Window (LAW) Node
+
+The LAW node represents the region of CCSR space where local access
+windows are configured.  For ECM based devices this is the first 4k
+of CCSR space that includes CCSRBAR, ALTCBAR, ALTCAR, BPTR, and some
+number of local access windows as specified by fsl,num-laws.
+
+PROPERTIES
+
+  - compatible
+      Usage: required
+      Value type: <string>
+      Definition: Must include "fsl,ecm-law"
+
+  - reg
+      Usage: required
+      Value type: <prop-encoded-array>
+      Definition: A standard property.  The value specifies the
+          physical address offset and length of the CCSR space
+          registers.
+
+  - fsl,num-laws
+      Usage: required
+      Value type: <u32>
+      Definition: The value specifies the number of local access
+          windows for this device.
+
+=====================================================================
+
+E500 Coherency Module Node
+
+The E500 LAW node represents the region of CCSR space where ECM config
+and error reporting registers exist, this is the second 4k (0x1000)
+of CCSR space.
+
+PROPERTIES
+
+  - compatible
+      Usage: required
+      Value type: <string>
+      Definition: Must include "fsl,CHIP-ecm", "fsl,ecm" where
+      CHIP is the processor (mpc8572, mpc8544, etc.)
+
+  - reg
+      Usage: required
+      Value type: <prop-encoded-array>
+      Definition: A standard property.  The value specifies the
+          physical address offset and length of the CCSR space
+          registers.
+
+   - interrupts
+      Usage: required
+      Value type: <prop-encoded-array>
+
+   - interrupt-parent
+      Usage: required
+      Value type: <phandle>
+
+=====================================================================
index 78790d5..6e37be1 100644 (file)
@@ -17,6 +17,9 @@ Required properties:
 - model : precise model of the QE, Can be "QE", "CPM", or "CPM2"
 - reg : offset and length of the device registers.
 - bus-frequency : the clock frequency for QUICC Engine.
+- fsl,qe-num-riscs: define how many RISC engines the QE has.
+- fsl,qe-num-snums: define how many serial number(SNUM) the QE can use for the
+  threads.
 
 Recommended properties
 - brg-frequency : the internal clock source frequency for baud-rate
index 6008465..5093ddf 100644 (file)
@@ -5,8 +5,7 @@ for MMC, SD, and SDIO types of memory cards.
 
 Required properties:
   - compatible : should be
-    "fsl,<chip>-esdhc", "fsl,mpc8379-esdhc" for MPC83xx processors.
-    "fsl,<chip>-esdhc", "fsl,mpc8536-esdhc" for MPC85xx processors.
+    "fsl,<chip>-esdhc", "fsl,esdhc"
   - reg : should contain eSDHC registers location and length.
   - interrupts : should contain eSDHC interrupt.
   - interrupt-parent : interrupt source phandle.
@@ -15,7 +14,7 @@ Required properties:
 Example:
 
 sdhci@2e000 {
-       compatible = "fsl,mpc8378-esdhc", "fsl,mpc8379-esdhc";
+       compatible = "fsl,mpc8378-esdhc", "fsl,esdhc";
        reg = <0x2e000 0x1000>;
        interrupts = <42 0x8>;
        interrupt-parent = <&ipic>;
diff --git a/Documentation/powerpc/dts-bindings/fsl/mcm.txt b/Documentation/powerpc/dts-bindings/fsl/mcm.txt
new file mode 100644 (file)
index 0000000..4ceda9b
--- /dev/null
@@ -0,0 +1,64 @@
+=====================================================================
+MPX LAW & Coherency Module Device Tree Binding
+Copyright (C) 2009 Freescale Semiconductor Inc.
+=====================================================================
+
+Local Access Window (LAW) Node
+
+The LAW node represents the region of CCSR space where local access
+windows are configured.  For MCM based devices this is the first 4k
+of CCSR space that includes CCSRBAR, ALTCBAR, ALTCAR, BPTR, and some
+number of local access windows as specified by fsl,num-laws.
+
+PROPERTIES
+
+  - compatible
+      Usage: required
+      Value type: <string>
+      Definition: Must include "fsl,mcm-law"
+
+  - reg
+      Usage: required
+      Value type: <prop-encoded-array>
+      Definition: A standard property.  The value specifies the
+          physical address offset and length of the CCSR space
+          registers.
+
+  - fsl,num-laws
+      Usage: required
+      Value type: <u32>
+      Definition: The value specifies the number of local access
+          windows for this device.
+
+=====================================================================
+
+MPX Coherency Module Node
+
+The MPX LAW node represents the region of CCSR space where MCM config
+and error reporting registers exist, this is the second 4k (0x1000)
+of CCSR space.
+
+PROPERTIES
+
+  - compatible
+      Usage: required
+      Value type: <string>
+      Definition: Must include "fsl,CHIP-mcm", "fsl,mcm" where
+      CHIP is the processor (mpc8641, mpc8610, etc.)
+
+  - reg
+      Usage: required
+      Value type: <prop-encoded-array>
+      Definition: A standard property.  The value specifies the
+          physical address offset and length of the CCSR space
+          registers.
+
+   - interrupts
+      Usage: required
+      Value type: <prop-encoded-array>
+
+   - interrupt-parent
+      Usage: required
+      Value type: <phandle>
+
+=====================================================================
index cdc9a6f..93a6189 100644 (file)
@@ -42,6 +42,10 @@ config GENERIC_HARDIRQS
        bool
        default y
 
+config GENERIC_HARDIRQS_NO__DO_IRQ
+       bool
+       default y
+
 config HAVE_SETUP_PER_CPU_AREA
        def_bool PPC64
 
@@ -296,9 +300,19 @@ config IOMMU_VMERGE
 config IOMMU_HELPER
        def_bool PPC64
 
+config SWIOTLB
+       bool "SWIOTLB support"
+       default n
+       select IOMMU_HELPER
+       ---help---
+         Support for IO bounce buffering for systems without an IOMMU.
+         This allows us to DMA to the full physical address space on
+         platforms where the size of a physical address is larger
+         than the bus address.  Not all platforms support this.
+
 config PPC_NEED_DMA_SYNC_OPS
        def_bool y
-       depends on NOT_COHERENT_CACHE
+       depends on (NOT_COHERENT_CACHE || SWIOTLB)
 
 config HOTPLUG_CPU
        bool "Support for enabling/disabling CPUs"
index a1098e2..d79a902 100644 (file)
@@ -41,6 +41,19 @@ config HCALL_STATS
          This option will add a small amount of overhead to all hypervisor
          calls.
 
+config PPC_EMULATED_STATS
+       bool "Emulated instructions tracking"
+       depends on DEBUG_FS
+       help
+         Adds code to keep track of the number of instructions that are
+         emulated by the in-kernel emulator. Counters for the various classes
+         of emulated instructions are available under
+         powerpc/emulated_instructions/ in the root of the debugfs file
+         system. Optionally (controlled by
+         powerpc/emulated_instructions/do_warn in debugfs), rate-limited
+         warnings can be printed to the console when instructions are
+         emulated.
+
 config CODE_PATCHING_SELFTEST
        bool "Run self-tests of the code-patching code."
        depends on DEBUG_KERNEL
index 551fc58..bc35f4e 100644 (file)
@@ -142,6 +142,7 @@ head-$(CONFIG_FSL_BOOKE)    := arch/powerpc/kernel/head_fsl_booke.o
 
 head-$(CONFIG_PPC64)           += arch/powerpc/kernel/entry_64.o
 head-$(CONFIG_PPC_FPU)         += arch/powerpc/kernel/fpu.o
+head-$(CONFIG_ALTIVEC)         += arch/powerpc/kernel/vector.o
 
 core-y                         += arch/powerpc/kernel/ \
                                   arch/powerpc/mm/ \
index 53a7a62..910944e 100644 (file)
                device_type = "soc";
                compatible = "fsl,mpc8641-soc", "simple-bus";
                ranges = <0x0 0xfef00000 0x00100000>;
-               reg = <0xfef00000 0x100000>;    // CCSRBAR 1M
                bus-frequency = <33333333>;
 
+               mcm-law@0 {
+                       compatible = "fsl,mcm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               mcm@1000 {
+                       compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                i2c1: i2c@3000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
index 1569117..0f4c9ec 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xfef00000 0x00100000>;
-               reg = <0xfef00000 0x100000>;    // CCSRBAR 1M
                bus-frequency = <33333333>;
 
+               mcm-law@0 {
+                       compatible = "fsl,mcm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               mcm@1000 {
+                       compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                i2c1: i2c@3000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
index 6582dbd..217f8aa 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xfef00000 0x00100000>;
-               reg = <0xfef00000 0x100000>;    // CCSRBAR 1M
                bus-frequency = <33333333>;
 
+               mcm-law@0 {
+                       compatible = "fsl,mcm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               mcm@1000 {
+                       compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                i2c1: i2c@3000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
index c9cfd37..bdb7fc0 100644 (file)
                ranges = <0x00000000 0xfdf00000 0x00100000>;
                bus-frequency = <0>;                            /* Fixed by bootwrapper */
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8560-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8540-memory-controller";
                        reg = <0x2000 0x1000>;
index 57c595b..436c9c6 100644 (file)
                reg = <0xe0100000 0x480>;
                brg-frequency = <0>;
                bus-frequency = <198000000>;
+               fsl,qe-num-riscs = <1>;
+               fsl,qe-num-snums = <28>;
 
                muram@10000 {
                        #address-cells = <1>;
        };
 
        pci0: pci@e0008500 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                                /* IDSEL 0x11 AD17 */
index 4319bd7..9a0952f 100644 (file)
                reg = <0xe0100000 0x480>;
                brg-frequency = <0>;
                bus-frequency = <198000000>;
+               fsl,qe-num-riscs = <1>;
+               fsl,qe-num-snums = <28>;
 
                muram@10000 {
                        #address-cells = <1>;
        };
 
        pci0: pci@e0008500 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                                /* IDSEL 0x10 AD16 (USB) */
index 1ae38f0..e3eeaed 100644 (file)
        };
 
        pci0: pci@e0008500 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                                /* IDSEL 0x10 - SATA */
        };
 
        pci1: pci@e0008600 {
-               cell-index = <2>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                                /* IDSEL 0x0E - MiniPCI Slot */
index 662abe1..eb73211 100644 (file)
        };
 
        pci0: pci@e0008600 {
-               cell-index = <2>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                                /* IDSEL 0x0F - PCI Slot */
index d9f0a23..a2553a6 100644 (file)
        };
 
        pci0: pci@e0008500 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
        };
 
        pci1: pci@e0008600 {
-               cell-index = <2>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index 6e34f17..39ff4c8 100644 (file)
                reg = <0xe0100000 0x480>;
                brg-frequency = <0>;
                bus-frequency = <396000000>;
+               fsl,qe-num-riscs = <2>;
+               fsl,qe-num-snums = <28>;
 
                muram@10000 {
                        #address-cells = <1>;
        };
 
        pci0: pci@e0008500 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index 37b7895..6315d6f 100644 (file)
                        clock-frequency = <0>;
                        bus-frequency = <0>;
                        brg-frequency = <0>;
+                       fsl,qe-num-riscs = <2>;
+                       fsl,qe-num-snums = <28>;
 
                        muram@10000 {
                                #address-cells = <1>;
index 9637080..67bb372 100644 (file)
        };
 
        pci0: pci@e0008500 {
-               cell-index = <0>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index 651ff2f..a955a57 100644 (file)
        };
 
        pci0: pci@e0008500 {
-               cell-index = <0>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index d6f208b..d266ddb 100644 (file)
        };
 
        pci0: pci@e0008500 {
-               cell-index = <0>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index b31c504..e781ad2 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xffe00000 0x100000>;
-               reg = <0xffe00000 0x1000>;
                bus-frequency = <0>;            // Filled out by uboot.
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <12>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8536-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8536-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@ffe08000 {
-               cell-index = <0>;
                compatible = "fsl,mpc8540-pci";
                device_type = "pci";
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
        };
 
        pci1: pcie@ffe09000 {
-               cell-index = <1>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci2: pcie@ffe0a000 {
-               cell-index = <2>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci3: pcie@ffe0b000 {
-               cell-index = <3>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
index ddd67be..9dc2929 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x100000>;    // CCSRBAR 1M
                bus-frequency = <0>;
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8540-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,8540-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index e45097f..9a3ad31 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x1000>;      // CCSRBAR 1M
                bus-frequency = <0>;
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8541-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,8541-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                interrupt-map-mask = <0x1f800 0x0 0x0 0x7>;
                interrupt-map = <
 
        };
 
        pci1: pci@e0009000 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index 7c6932b..98e94b4 100644 (file)
                compatible = "simple-bus";
 
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x1000>;      // CCSRBAR 1M
                bus-frequency = <0>;            // Filled out by uboot.
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8544-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,8544-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                compatible = "fsl,mpc8540-pci";
                device_type = "pci";
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
        };
 
        pci1: pcie@e0009000 {
-               cell-index = <1>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci2: pcie@e000a000 {
-               cell-index = <2>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci3: pcie@e000b000 {
-               cell-index = <3>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
index 804e903..475be14 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x1000>;      // CCSRBAR
                bus-frequency = <0>;
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8548-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,8548-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                        /* IDSEL 0x4 (PCIX Slot 2) */
        };
 
        pci1: pci@e0009000 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
        };
 
        pci2: pcie@e000a000 {
-               cell-index = <2>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index 9484f07..065b2f0 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x1000>;      // CCSRBAR 1M
                bus-frequency = <0>;
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8555-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,8555-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                interrupt-map-mask = <0x1f800 0x0 0x0 0x7>;
                interrupt-map = <
 
        };
 
        pci1: pci@e0009000 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index cc2acf8..a5bb1ec 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x200>;
                bus-frequency = <330000000>;
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8560-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,8540-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
index 9d52e3b..00c2bbd 100644 (file)
@@ -26,6 +26,7 @@
                serial1 = &serial1;
                pci0 = &pci0;
                pci1 = &pci1;
+               rapidio0 = &rio0;
        };
 
        cpus {
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x1000>;
                bus-frequency = <0>;
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8568-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,8568-memory-controller";
                        reg = <0x2000 0x1000>;
                        device_type = "open-pic";
                };
 
+               msi@41600 {
+                       compatible = "fsl,mpc8568-msi", "fsl,mpic-msi";
+                       reg = <0x41600 0x80>;
+                       msi-available-ranges = <0 0x100>;
+                       interrupts = <
+                               0xe0 0
+                               0xe1 0
+                               0xe2 0
+                               0xe3 0
+                               0xe4 0
+                               0xe5 0
+                               0xe6 0
+                               0xe7 0>;
+                       interrupt-parent = <&mpic>;
+               };
+
                par_io@e0100 {
                        reg = <0xe0100 0x100>;
                        device_type = "par_io";
                reg = <0xe0080000 0x480>;
                brg-frequency = <0>;
                bus-frequency = <396000000>;
+               fsl,qe-num-riscs = <2>;
+               fsl,qe-num-snums = <28>;
 
                muram@10000 {
                        #address-cells = <1>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                        /* IDSEL 0x12 AD18 */
 
        /* PCI Express */
        pci1: pcie@e000a000 {
-               cell-index = <2>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
                                  0x0 0x800000>;
                };
        };
+
+       rio0: rapidio@e00c00000 {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               compatible = "fsl,mpc8568-rapidio", "fsl,rapidio-delta";
+               reg = <0xe00c0000 0x20000>;
+               ranges = <0x0 0x0 0xc0000000 0x0 0x20000000>;
+               interrupts = <48 2 /* error     */
+                             49 2 /* bell_outb */
+                             50 2 /* bell_inb  */
+                             53 2 /* msg1_tx   */
+                             54 2 /* msg1_rx   */
+                             55 2 /* msg2_tx   */
+                             56 2 /* msg2_rx   */>;
+               interrupt-parent = <&mpic>;
+       };
 };
diff --git a/arch/powerpc/boot/dts/mpc8569mds.dts b/arch/powerpc/boot/dts/mpc8569mds.dts
new file mode 100644 (file)
index 0000000..39c2927
--- /dev/null
@@ -0,0 +1,583 @@
+/*
+ * MPC8569E MDS Device Tree Source
+ *
+ * Copyright (C) 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.
+ */
+
+/dts-v1/;
+
+/ {
+       model = "MPC8569EMDS";
+       compatible = "fsl,MPC8569EMDS";
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       aliases {
+               serial0 = &serial0;
+               serial1 = &serial1;
+               ethernet0 = &enet0;
+               ethernet1 = &enet1;
+               ethernet2 = &enet2;
+               ethernet3 = &enet3;
+               pci1 = &pci1;
+               rapidio0 = &rio0;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               PowerPC,8569@0 {
+                       device_type = "cpu";
+                       reg = <0x0>;
+                       d-cache-line-size = <32>;       // 32 bytes
+                       i-cache-line-size = <32>;       // 32 bytes
+                       d-cache-size = <0x8000>;                // L1, 32K
+                       i-cache-size = <0x8000>;                // L1, 32K
+                       timebase-frequency = <0>;
+                       bus-frequency = <0>;
+                       clock-frequency = <0>;
+                       next-level-cache = <&L2>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+       };
+
+       localbus@e0005000 {
+               #address-cells = <2>;
+               #size-cells = <1>;
+               compatible = "fsl,mpc8569-elbc", "fsl,elbc", "simple-bus";
+               reg = <0xe0005000 0x1000>;
+               interrupts = <19 2>;
+               interrupt-parent = <&mpic>;
+
+               ranges = <0x0 0x0 0xfe000000 0x02000000
+                         0x1 0x0 0xf8000000 0x00008000
+                         0x2 0x0 0xf0000000 0x04000000
+                         0x3 0x0 0xfc000000 0x00008000
+                         0x4 0x0 0xf8008000 0x00008000
+                         0x5 0x0 0xf8010000 0x00008000>;
+
+               nor@0,0 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "cfi-flash";
+                       reg = <0x0 0x0 0x02000000>;
+                       bank-width = <2>;
+                       device-width = <1>;
+               };
+
+               bcsr@1,0 {
+                       compatible = "fsl,mpc8569mds-bcsr";
+                       reg = <1 0 0x8000>;
+               };
+
+               nand@3,0 {
+                       compatible = "fsl,mpc8569-fcm-nand",
+                                    "fsl,elbc-fcm-nand";
+                       reg = <3 0 0x8000>;
+               };
+
+               pib@4,0 {
+                       compatible = "fsl,mpc8569mds-pib";
+                       reg = <4 0 0x8000>;
+               };
+
+               pib@5,0 {
+                       compatible = "fsl,mpc8569mds-pib";
+                       reg = <5 0 0x8000>;
+               };
+       };
+
+       soc@e0000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               device_type = "soc";
+               compatible = "fsl,mpc8569-immr", "simple-bus";
+               ranges = <0x0 0xe0000000 0x100000>;
+               bus-frequency = <0>;
+
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8569-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               memory-controller@2000 {
+                       compatible = "fsl,mpc8569-memory-controller";
+                       reg = <0x2000 0x1000>;
+                       interrupt-parent = <&mpic>;
+                       interrupts = <18 2>;
+               };
+
+               i2c@3000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <0>;
+                       compatible = "fsl-i2c";
+                       reg = <0x3000 0x100>;
+                       interrupts = <43 2>;
+                       interrupt-parent = <&mpic>;
+                       dfsrr;
+
+                       rtc@68 {
+                               compatible = "dallas,ds1374";
+                               reg = <0x68>;
+                       };
+               };
+
+               i2c@3100 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <1>;
+                       compatible = "fsl-i2c";
+                       reg = <0x3100 0x100>;
+                       interrupts = <43 2>;
+                       interrupt-parent = <&mpic>;
+                       dfsrr;
+               };
+
+               serial0: serial@4500 {
+                       cell-index = <0>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x4500 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <42 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               serial1: serial@4600 {
+                       cell-index = <1>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x4600 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <42 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               L2: l2-cache-controller@20000 {
+                       compatible = "fsl,mpc8569-l2-cache-controller";
+                       reg = <0x20000 0x1000>;
+                       cache-line-size = <32>; // 32 bytes
+                       cache-size = <0x80000>; // L2, 512K
+                       interrupt-parent = <&mpic>;
+                       interrupts = <16 2>;
+               };
+
+               dma@21300 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,mpc8569-dma", "fsl,eloplus-dma";
+                       reg = <0x21300 0x4>;
+                       ranges = <0x0 0x21100 0x200>;
+                       cell-index = <0>;
+                       dma-channel@0 {
+                               compatible = "fsl,mpc8569-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x0 0x80>;
+                               cell-index = <0>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <20 2>;
+                       };
+                       dma-channel@80 {
+                               compatible = "fsl,mpc8569-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x80 0x80>;
+                               cell-index = <1>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <21 2>;
+                       };
+                       dma-channel@100 {
+                               compatible = "fsl,mpc8569-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x100 0x80>;
+                               cell-index = <2>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <22 2>;
+                       };
+                       dma-channel@180 {
+                               compatible = "fsl,mpc8569-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x180 0x80>;
+                               cell-index = <3>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <23 2>;
+                       };
+               };
+
+               sdhci@2e000 {
+                       compatible = "fsl,mpc8569-esdhc", "fsl,esdhc";
+                       reg = <0x2e000 0x1000>;
+                       interrupts = <72 0x8>;
+                       interrupt-parent = <&mpic>;
+                       /* Filled in by U-Boot */
+                       clock-frequency = <0>;
+                       status = "disabled";
+               };
+
+               crypto@30000 {
+                       compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
+                               "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+                       reg = <0x30000 0x10000>;
+                       interrupts = <45 2 58 2>;
+                       interrupt-parent = <&mpic>;
+                       fsl,num-channels = <4>;
+                       fsl,channel-fifo-len = <24>;
+                       fsl,exec-units-mask = <0xbfe>;
+                       fsl,descriptor-types-mask = <0x3ab0ebf>;
+               };
+
+               mpic: pic@40000 {
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       reg = <0x40000 0x40000>;
+                       compatible = "chrp,open-pic";
+                       device_type = "open-pic";
+               };
+
+               msi@41600 {
+                       compatible = "fsl,mpc8568-msi", "fsl,mpic-msi";
+                       reg = <0x41600 0x80>;
+                       msi-available-ranges = <0 0x100>;
+                       interrupts = <
+                               0xe0 0
+                               0xe1 0
+                               0xe2 0
+                               0xe3 0
+                               0xe4 0
+                               0xe5 0
+                               0xe6 0
+                               0xe7 0>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               global-utilities@e0000 {
+                       compatible = "fsl,mpc8569-guts";
+                       reg = <0xe0000 0x1000>;
+                       fsl,has-rstcr;
+               };
+
+               par_io@e0100 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0xe0100 0x100>;
+                       ranges = <0x0 0xe0100 0x100>;
+                       device_type = "par_io";
+                       num-ports = <7>;
+
+                       qe_pio_e: gpio-controller@80 {
+                               #gpio-cells = <2>;
+                               compatible = "fsl,mpc8569-qe-pario-bank",
+                                            "fsl,mpc8323-qe-pario-bank";
+                               reg = <0x80 0x18>;
+                               gpio-controller;
+                       };
+
+                       pio1: ucc_pin@01 {
+                               pio-map = <
+                       /* port  pin  dir  open_drain  assignment  has_irq */
+                                       0x2  0x1f 0x1  0x0  0x1  0x0    /* QE_MUX_MDC */
+                                       0x2  0x1e 0x3  0x0  0x2  0x0    /* QE_MUX_MDIO */
+                                       0x2  0x0b 0x2  0x0  0x1  0x0    /* CLK12*/
+                                       0x0  0x0  0x1  0x0  0x3  0x0    /* ENET1_TXD0_SER1_TXD0 */
+                                       0x0  0x1  0x1  0x0  0x3  0x0    /* ENET1_TXD1_SER1_TXD1 */
+                                       0x0  0x2  0x1  0x0  0x1  0x0    /* ENET1_TXD2_SER1_TXD2 */
+                                       0x0  0x3  0x1  0x0  0x2  0x0    /* ENET1_TXD3_SER1_TXD3 */
+                                       0x0  0x6  0x2  0x0  0x3  0x0    /* ENET1_RXD0_SER1_RXD0 */
+                                       0x0  0x7  0x2  0x0  0x1  0x0    /* ENET1_RXD1_SER1_RXD1 */
+                                       0x0  0x8  0x2  0x0  0x2  0x0    /* ENET1_RXD2_SER1_RXD2 */
+                                       0x0  0x9  0x2  0x0  0x2  0x0    /* ENET1_RXD3_SER1_RXD3 */
+                                       0x0  0x4  0x1  0x0  0x2  0x0    /* ENET1_TX_EN_SER1_RTS_B */
+                                       0x0  0xc  0x2  0x0  0x3  0x0    /* ENET1_RX_DV_SER1_CTS_B */
+                                       0x2  0x8  0x2  0x0  0x1  0x0    /* ENET1_GRXCLK */
+                                       0x2  0x14 0x1  0x0  0x2  0x0>;  /* ENET1_GTXCLK */
+                       };
+
+                       pio2: ucc_pin@02 {
+                               pio-map = <
+                       /* port  pin  dir  open_drain  assignment  has_irq */
+                                       0x2  0x1f 0x1  0x0  0x1  0x0    /* QE_MUX_MDC */
+                                       0x2  0x1e 0x3  0x0  0x2  0x0    /* QE_MUX_MDIO */
+                                       0x2  0x10 0x2  0x0  0x3  0x0    /* CLK17 */
+                                       0x0  0xe  0x1  0x0  0x2  0x0    /* ENET2_TXD0_SER2_TXD0 */
+                                       0x0  0xf  0x1  0x0  0x2  0x0    /* ENET2_TXD1_SER2_TXD1 */
+                                       0x0  0x10 0x1  0x0  0x1  0x0    /* ENET2_TXD2_SER2_TXD2 */
+                                       0x0  0x11 0x1  0x0  0x1  0x0    /* ENET2_TXD3_SER2_TXD3 */
+                                       0x0  0x14 0x2  0x0  0x2  0x0    /* ENET2_RXD0_SER2_RXD0 */
+                                       0x0  0x15 0x2  0x0  0x1  0x0    /* ENET2_RXD1_SER2_RXD1 */
+                                       0x0  0x16 0x2  0x0  0x1  0x0    /* ENET2_RXD2_SER2_RXD2 */
+                                       0x0  0x17 0x2  0x0  0x1  0x0    /* ENET2_RXD3_SER2_RXD3 */
+                                       0x0  0x12 0x1  0x0  0x2  0x0    /* ENET2_TX_EN_SER2_RTS_B */
+                                       0x0  0x1a 0x2  0x0  0x3  0x0    /* ENET2_RX_DV_SER2_CTS_B */
+                                       0x2  0x3  0x2  0x0  0x1  0x0    /* ENET2_GRXCLK */
+                                       0x2  0x2 0x1  0x0  0x2  0x0>;   /* ENET2_GTXCLK */
+                       };
+
+                       pio3: ucc_pin@03 {
+                               pio-map = <
+                       /* port  pin  dir  open_drain  assignment  has_irq */
+                                       0x2  0x1f 0x1  0x0  0x1  0x0    /* QE_MUX_MDC */
+                                       0x2  0x1e 0x3  0x0  0x2  0x0    /* QE_MUX_MDIO */
+                                       0x2  0x0b 0x2  0x0  0x1  0x0    /* CLK12*/
+                                       0x0  0x1d 0x1  0x0  0x2  0x0    /* ENET3_TXD0_SER3_TXD0 */
+                                       0x0  0x1e 0x1  0x0  0x3  0x0    /* ENET3_TXD1_SER3_TXD1 */
+                                       0x0  0x1f 0x1  0x0  0x2  0x0    /* ENET3_TXD2_SER3_TXD2 */
+                                       0x1  0x0  0x1  0x0  0x3  0x0    /* ENET3_TXD3_SER3_TXD3 */
+                                       0x1  0x3  0x2  0x0  0x3  0x0    /* ENET3_RXD0_SER3_RXD0 */
+                                       0x1  0x4  0x2  0x0  0x1  0x0    /* ENET3_RXD1_SER3_RXD1 */
+                                       0x1  0x5  0x2  0x0  0x2  0x0    /* ENET3_RXD2_SER3_RXD2 */
+                                       0x1  0x6  0x2  0x0  0x3  0x0    /* ENET3_RXD3_SER3_RXD3 */
+                                       0x1  0x1  0x1  0x0  0x1  0x0    /* ENET3_TX_EN_SER3_RTS_B */
+                                       0x1  0x9  0x2  0x0  0x3  0x0    /* ENET3_RX_DV_SER3_CTS_B */
+                                       0x2  0x9  0x2  0x0  0x2  0x0    /* ENET3_GRXCLK */
+                                       0x2  0x19 0x1  0x0  0x2  0x0>;  /* ENET3_GTXCLK */
+                       };
+
+                       pio4: ucc_pin@04 {
+                               pio-map = <
+                       /* port  pin  dir  open_drain  assignment  has_irq */
+                                       0x2  0x1f 0x1  0x0  0x1  0x0    /* QE_MUX_MDC */
+                                       0x2  0x1e 0x3  0x0  0x2  0x0    /* QE_MUX_MDIO */
+                                       0x2  0x10 0x2  0x0  0x3  0x0    /* CLK17 */
+                                       0x1  0xc  0x1  0x0  0x2  0x0    /* ENET4_TXD0_SER4_TXD0 */
+                                       0x1  0xd  0x1  0x0  0x2  0x0    /* ENET4_TXD1_SER4_TXD1 */
+                                       0x1  0xe  0x1  0x0  0x1  0x0    /* ENET4_TXD2_SER4_TXD2 */
+                                       0x1  0xf  0x1  0x0  0x2  0x0    /* ENET4_TXD3_SER4_TXD3 */
+                                       0x1  0x12 0x2  0x0  0x2  0x0    /* ENET4_RXD0_SER4_RXD0 */
+                                       0x1  0x13 0x2  0x0  0x1  0x0    /* ENET4_RXD1_SER4_RXD1 */
+                                       0x1  0x14 0x2  0x0  0x1  0x0    /* ENET4_RXD2_SER4_RXD2 */
+                                       0x1  0x15 0x2  0x0  0x2  0x0    /* ENET4_RXD3_SER4_RXD3 */
+                                       0x1  0x10 0x1  0x0  0x2  0x0    /* ENET4_TX_EN_SER4_RTS_B */
+                                       0x1  0x18 0x2  0x0  0x3  0x0    /* ENET4_RX_DV_SER4_CTS_B */
+                                       0x2  0x11 0x2  0x0  0x2  0x0    /* ENET4_GRXCLK */
+                                       0x2  0x18 0x1  0x0  0x2  0x0>;  /* ENET4_GTXCLK */
+                       };
+               };
+       };
+
+       qe@e0080000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               device_type = "qe";
+               compatible = "fsl,qe";
+               ranges = <0x0 0xe0080000 0x40000>;
+               reg = <0xe0080000 0x480>;
+               brg-frequency = <0>;
+               bus-frequency = <0>;
+               fsl,qe-num-riscs = <4>;
+               fsl,qe-num-snums = <46>;
+
+               qeic: interrupt-controller@80 {
+                       interrupt-controller;
+                       compatible = "fsl,qe-ic";
+                       #address-cells = <0>;
+                       #interrupt-cells = <1>;
+                       reg = <0x80 0x80>;
+                       interrupts = <46 2 46 2>; //high:30 low:30
+                       interrupt-parent = <&mpic>;
+               };
+
+               spi@4c0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,mpc8569-qe-spi", "fsl,spi";
+                       reg = <0x4c0 0x40>;
+                       cell-index = <0>;
+                       interrupts = <2>;
+                       interrupt-parent = <&qeic>;
+                       gpios = <&qe_pio_e 30 0>;
+                       mode = "cpu-qe";
+
+                       serial-flash@0 {
+                               compatible = "stm,m25p40";
+                               reg = <0>;
+                               spi-max-frequency = <25000000>;
+                       };
+               };
+
+               spi@500 {
+                       cell-index = <1>;
+                       compatible = "fsl,spi";
+                       reg = <0x500 0x40>;
+                       interrupts = <1>;
+                       interrupt-parent = <&qeic>;
+                       mode = "cpu";
+               };
+
+               enet0: ucc@2000 {
+                       device_type = "network";
+                       compatible = "ucc_geth";
+                       cell-index = <1>;
+                       reg = <0x2000 0x200>;
+                       interrupts = <32>;
+                       interrupt-parent = <&qeic>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       rx-clock-name = "none";
+                       tx-clock-name = "clk12";
+                       pio-handle = <&pio1>;
+                       phy-handle = <&qe_phy0>;
+                       phy-connection-type = "rgmii-id";
+               };
+
+               mdio@2120 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x2120 0x18>;
+                       compatible = "fsl,ucc-mdio";
+
+                       qe_phy0: ethernet-phy@07 {
+                               interrupt-parent = <&mpic>;
+                               interrupts = <1 1>;
+                               reg = <0x7>;
+                               device_type = "ethernet-phy";
+                       };
+                       qe_phy1: ethernet-phy@01 {
+                               interrupt-parent = <&mpic>;
+                               interrupts = <2 1>;
+                               reg = <0x1>;
+                               device_type = "ethernet-phy";
+                       };
+                       qe_phy2: ethernet-phy@02 {
+                               interrupt-parent = <&mpic>;
+                               interrupts = <3 1>;
+                               reg = <0x2>;
+                               device_type = "ethernet-phy";
+                       };
+                       qe_phy3: ethernet-phy@03 {
+                               interrupt-parent = <&mpic>;
+                               interrupts = <4 1>;
+                               reg = <0x3>;
+                               device_type = "ethernet-phy";
+                       };
+               };
+
+               enet2: ucc@2200 {
+                       device_type = "network";
+                       compatible = "ucc_geth";
+                       cell-index = <3>;
+                       reg = <0x2200 0x200>;
+                       interrupts = <34>;
+                       interrupt-parent = <&qeic>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       rx-clock-name = "none";
+                       tx-clock-name = "clk12";
+                       pio-handle = <&pio3>;
+                       phy-handle = <&qe_phy2>;
+                       phy-connection-type = "rgmii-id";
+               };
+
+               enet1: ucc@3000 {
+                       device_type = "network";
+                       compatible = "ucc_geth";
+                       cell-index = <2>;
+                       reg = <0x3000 0x200>;
+                       interrupts = <33>;
+                       interrupt-parent = <&qeic>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       rx-clock-name = "none";
+                       tx-clock-name = "clk17";
+                       pio-handle = <&pio2>;
+                       phy-handle = <&qe_phy1>;
+                       phy-connection-type = "rgmii-id";
+               };
+
+               enet3: ucc@3200 {
+                       device_type = "network";
+                       compatible = "ucc_geth";
+                       cell-index = <4>;
+                       reg = <0x3200 0x200>;
+                       interrupts = <35>;
+                       interrupt-parent = <&qeic>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       rx-clock-name = "none";
+                       tx-clock-name = "clk17";
+                       pio-handle = <&pio4>;
+                       phy-handle = <&qe_phy3>;
+                       phy-connection-type = "rgmii-id";
+               };
+
+               muram@10000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,qe-muram", "fsl,cpm-muram";
+                       ranges = <0x0 0x10000 0x20000>;
+
+                       data-only@0 {
+                               compatible = "fsl,qe-muram-data",
+                                            "fsl,cpm-muram-data";
+                               reg = <0x0 0x20000>;
+                       };
+               };
+
+       };
+
+       /* PCI Express */
+       pci1: pcie@e000a000 {
+               compatible = "fsl,mpc8548-pcie";
+               device_type = "pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0xe000a000 0x1000>;
+               interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+               interrupt-map = <
+                       /* IDSEL 0x0 (PEX) */
+                       00000 0x0 0x0 0x1 &mpic 0x0 0x1
+                       00000 0x0 0x0 0x2 &mpic 0x1 0x1
+                       00000 0x0 0x0 0x3 &mpic 0x2 0x1
+                       00000 0x0 0x0 0x4 &mpic 0x3 0x1>;
+
+               interrupt-parent = <&mpic>;
+               interrupts = <26 2>;
+               bus-range = <0 255>;
+               ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000
+                         0x1000000 0x0 0x00000000 0xe2800000 0x0 0x00800000>;
+               clock-frequency = <33333333>;
+               pcie@0 {
+                       reg = <0x0 0x0 0x0 0x0 0x0>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       ranges = <0x2000000 0x0 0xa0000000
+                                 0x2000000 0x0 0xa0000000
+                                 0x0 0x10000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x800000>;
+               };
+       };
+
+       rio0: rapidio@e00c00000 {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               compatible = "fsl,mpc8569-rapidio", "fsl,rapidio-delta";
+               reg = <0xe00c0000 0x20000>;
+               ranges = <0x0 0x0 0xc0000000 0x0 0x20000000>;
+               interrupts = <48 2 /* error     */
+                             49 2 /* bell_outb */
+                             50 2 /* bell_inb  */
+                             53 2 /* msg1_tx   */
+                             54 2 /* msg1_rx   */
+                             55 2 /* msg2_tx   */
+                             56 2 /* msg2_rx   */>;
+               interrupt-parent = <&mpic>;
+       };
+};
index 6e79a41..cafc128 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0 0xffe00000 0x100000>;
-               reg = <0 0xffe00000 0 0x1000>;  // CCSRBAR & soc regs, remove once parse code for immrbase fixed
                bus-frequency = <0>;            // Filled out by uboot.
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <12>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8572-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8572-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pcie@ffe08000 {
-               cell-index = <0>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci1: pcie@ffe09000 {
-               cell-index = <1>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci2: pcie@ffe0a000 {
-               cell-index = <2>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
index dbd81a7..f6365db 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xf 0xffe00000 0x100000>;
-               reg = <0xf 0xffe00000 0 0x1000>;        // CCSRBAR & soc regs, remove once parse code for immrbase fixed
                bus-frequency = <0>;            // Filled out by uboot.
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <12>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8572-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8572-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pcie@fffe08000 {
-               cell-index = <0>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
                #address-cells = <3>;
                reg = <0xf 0xffe08000 0 0x1000>;
                bus-range = <0 255>;
-               ranges = <0x2000000 0x0 0xc0000000 0xc 0x00000000 0x0 0x20000000
+               ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
                          0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x00010000>;
                clock-frequency = <33333333>;
                interrupt-parent = <&mpic>;
                        #size-cells = <2>;
                        #address-cells = <3>;
                        device_type = "pci";
-                       ranges = <0x2000000 0x0 0xc0000000
-                                 0x2000000 0x0 0xc0000000
+                       ranges = <0x2000000 0x0 0xe0000000
+                                 0x2000000 0x0 0xe0000000
                                  0x0 0x20000000
 
                                  0x1000000 0x0 0x0
                                reg = <0x0 0x0 0x0 0x0 0x0>;
                                #size-cells = <2>;
                                #address-cells = <3>;
-                               ranges = <0x2000000 0x0 0xc0000000
-                                         0x2000000 0x0 0xc0000000
+                               ranges = <0x2000000 0x0 0xe0000000
+                                         0x2000000 0x0 0xe0000000
                                          0x0 0x20000000
 
                                          0x1000000 0x0 0x0
        };
 
        pci1: pcie@fffe09000 {
-               cell-index = <1>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
                #address-cells = <3>;
                reg = <0xf 0xffe09000 0 0x1000>;
                bus-range = <0 255>;
-               ranges = <0x2000000 0x0 0xc0000000 0xc 0x20000000 0x0 0x20000000
+               ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
                          0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x00010000>;
                clock-frequency = <33333333>;
                interrupt-parent = <&mpic>;
                        #size-cells = <2>;
                        #address-cells = <3>;
                        device_type = "pci";
-                       ranges = <0x2000000 0x0 0xc0000000
-                                 0x2000000 0x0 0xc0000000
+                       ranges = <0x2000000 0x0 0xe0000000
+                                 0x2000000 0x0 0xe0000000
                                  0x0 0x20000000
 
                                  0x1000000 0x0 0x0
        };
 
        pci2: pcie@fffe0a000 {
-               cell-index = <2>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
                #address-cells = <3>;
                reg = <0xf 0xffe0a000 0 0x1000>;
                bus-range = <0 255>;
-               ranges = <0x2000000 0x0 0xc0000000 0xc 0x40000000 0x0 0x20000000
+               ranges = <0x2000000 0x0 0xe0000000 0xc 0x40000000 0x0 0x20000000
                          0x1000000 0x0 0x00000000 0xf 0xffc20000 0x0 0x00010000>;
                clock-frequency = <33333333>;
                interrupt-parent = <&mpic>;
                        #size-cells = <2>;
                        #address-cells = <3>;
                        device_type = "pci";
-                       ranges = <0x2000000 0x0 0xc0000000
-                                 0x2000000 0x0 0xc0000000
+                       ranges = <0x2000000 0x0 0xe0000000
+                                 0x2000000 0x0 0xe0000000
                                  0x0 0x20000000
 
                                  0x1000000 0x0 0x0
index 2bc0c71..5bd1011 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xffe00000 0x100000>;
-               reg = <0xffe00000 0x1000>;      // CCSRBAR & soc regs, remove once parse code for immrbase fixed
                bus-frequency = <0>;            // Filled out by uboot.
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <12>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8572-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8572-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pcie@ffe08000 {
-               cell-index = <0>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci1: pcie@ffe09000 {
-               cell-index = <1>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
index 159cb3a..0efc345 100644 (file)
@@ -58,7 +58,6 @@
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xffe00000 0x100000>;
-               reg = <0xffe00000 0x1000>;      // CCSRBAR & soc regs, remove once parse code for immrbase fixed
                bus-frequency = <0>;            // Filled out by uboot.
 
                L2: l2-cache-controller@20000 {
        };
 
        pci2: pcie@ffe0a000 {
-               cell-index = <2>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
index 1bd3ebe..cfc2c60 100644 (file)
                device_type = "soc";
                compatible = "fsl,mpc8610-immr", "simple-bus";
                ranges = <0x0 0xe0000000 0x00100000>;
-               reg = <0xe0000000 0x1000>;
                bus-frequency = <0>;
 
+               mcm-law@0 {
+                       compatible = "fsl,mcm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               mcm@1000 {
+                       compatible = "fsl,mpc8610-mcm", "fsl,mcm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                i2c@3000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                compatible = "fsl,mpc8610-pci";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci1: pcie@e000a000 {
-               cell-index = <1>;
                compatible = "fsl,mpc8641-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
index d72beb1..848320e 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x00000000 0xffe00000 0x00100000>;
-               reg = <0xffe00000 0x00001000>;  // CCSRBAR
                bus-frequency = <0>;
 
+               mcm-law@0 {
+                       compatible = "fsl,mcm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               mcm@1000 {
+                       compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                i2c@3000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
        };
 
        pci0: pcie@ffe08000 {
-               cell-index = <0>;
                compatible = "fsl,mpc8641-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci1: pcie@ffe09000 {
-               cell-index = <1>;
                compatible = "fsl,mpc8641-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts b/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts
new file mode 100644 (file)
index 0000000..8be8e70
--- /dev/null
@@ -0,0 +1,609 @@
+/*
+ * MPC8641 HPCN Device Tree Source
+ *
+ * Copyright 2008-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.
+ */
+
+/dts-v1/;
+
+/ {
+       model = "MPC8641HPCN";
+       compatible = "fsl,mpc8641hpcn";
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       aliases {
+               ethernet0 = &enet0;
+               ethernet1 = &enet1;
+               ethernet2 = &enet2;
+               ethernet3 = &enet3;
+               serial0 = &serial0;
+               serial1 = &serial1;
+               pci0 = &pci0;
+               pci1 = &pci1;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               PowerPC,8641@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <32>;       // 32 bytes
+                       i-cache-line-size = <32>;       // 32 bytes
+                       d-cache-size = <32768>;         // L1, 32K
+                       i-cache-size = <32768>;         // L1, 32K
+                       timebase-frequency = <0>;       // 33 MHz, from uboot
+                       bus-frequency = <0>;            // From uboot
+                       clock-frequency = <0>;          // From uboot
+               };
+               PowerPC,8641@1 {
+                       device_type = "cpu";
+                       reg = <1>;
+                       d-cache-line-size = <32>;       // 32 bytes
+                       i-cache-line-size = <32>;       // 32 bytes
+                       d-cache-size = <32768>;         // L1, 32K
+                       i-cache-size = <32768>;         // L1, 32K
+                       timebase-frequency = <0>;       // 33 MHz, from uboot
+                       bus-frequency = <0>;            // From uboot
+                       clock-frequency = <0>;          // From uboot
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x0 0x00000000 0x0 0x40000000>;  // 1G at 0x0
+       };
+
+       localbus@fffe05000 {
+               #address-cells = <2>;
+               #size-cells = <1>;
+               compatible = "fsl,mpc8641-localbus", "simple-bus";
+               reg = <0x0f 0xffe05000 0x0 0x1000>;
+               interrupts = <19 2>;
+               interrupt-parent = <&mpic>;
+
+               ranges = <0 0 0xf 0xef800000 0x00800000
+                         2 0 0xf 0xffdf8000 0x00008000
+                         3 0 0xf 0xffdf0000 0x00008000>;
+
+               flash@0,0 {
+                       compatible = "cfi-flash";
+                       reg = <0 0 0x00800000>;
+                       bank-width = <2>;
+                       device-width = <2>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       partition@0 {
+                               label = "kernel";
+                               reg = <0x00000000 0x00300000>;
+                       };
+                       partition@300000 {
+                               label = "firmware b";
+                               reg = <0x00300000 0x00100000>;
+                               read-only;
+                       };
+                       partition@400000 {
+                               label = "fs";
+                               reg = <0x00400000 0x00300000>;
+                       };
+                       partition@700000 {
+                               label = "firmware a";
+                               reg = <0x00700000 0x00100000>;
+                               read-only;
+                       };
+               };
+       };
+
+       soc8641@fffe00000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               device_type = "soc";
+               compatible = "simple-bus";
+               ranges = <0x00000000 0x0f 0xffe00000 0x00100000>;
+               bus-frequency = <0>;
+
+               mcm-law@0 {
+                       compatible = "fsl,mcm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               mcm@1000 {
+                       compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               i2c@3000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <0>;
+                       compatible = "fsl-i2c";
+                       reg = <0x3000 0x100>;
+                       interrupts = <43 2>;
+                       interrupt-parent = <&mpic>;
+                       dfsrr;
+               };
+
+               i2c@3100 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <1>;
+                       compatible = "fsl-i2c";
+                       reg = <0x3100 0x100>;
+                       interrupts = <43 2>;
+                       interrupt-parent = <&mpic>;
+                       dfsrr;
+               };
+
+               dma@21300 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
+                       reg = <0x21300 0x4>;
+                       ranges = <0x0 0x21100 0x200>;
+                       cell-index = <0>;
+                       dma-channel@0 {
+                               compatible = "fsl,mpc8641-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x0 0x80>;
+                               cell-index = <0>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <20 2>;
+                       };
+                       dma-channel@80 {
+                               compatible = "fsl,mpc8641-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x80 0x80>;
+                               cell-index = <1>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <21 2>;
+                       };
+                       dma-channel@100 {
+                               compatible = "fsl,mpc8641-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x100 0x80>;
+                               cell-index = <2>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <22 2>;
+                       };
+                       dma-channel@180 {
+                               compatible = "fsl,mpc8641-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x180 0x80>;
+                               cell-index = <3>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <23 2>;
+                       };
+               };
+
+               enet0: ethernet@24000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <0>;
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <0x24000 0x1000>;
+                       ranges = <0x0 0x24000 0x1000>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <29 2 30 2 34 2>;
+                       interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi0>;
+                       phy-handle = <&phy0>;
+                       phy-connection-type = "rgmii-id";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-mdio";
+                               reg = <0x520 0x20>;
+
+                               phy0: ethernet-phy@0 {
+                                       interrupt-parent = <&mpic>;
+                                       interrupts = <10 1>;
+                                       reg = <0>;
+                                       device_type = "ethernet-phy";
+                               };
+                               phy1: ethernet-phy@1 {
+                                       interrupt-parent = <&mpic>;
+                                       interrupts = <10 1>;
+                                       reg = <1>;
+                                       device_type = "ethernet-phy";
+                               };
+                               phy2: ethernet-phy@2 {
+                                       interrupt-parent = <&mpic>;
+                                       interrupts = <10 1>;
+                                       reg = <2>;
+                                       device_type = "ethernet-phy";
+                               };
+                               phy3: ethernet-phy@3 {
+                                       interrupt-parent = <&mpic>;
+                                       interrupts = <10 1>;
+                                       reg = <3>;
+                                       device_type = "ethernet-phy";
+                               };
+                               tbi0: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
+               };
+
+               enet1: ethernet@25000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <1>;
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <0x25000 0x1000>;
+                       ranges = <0x0 0x25000 0x1000>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <35 2 36 2 40 2>;
+                       interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi1>;
+                       phy-handle = <&phy1>;
+                       phy-connection-type = "rgmii-id";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-tbi";
+                               reg = <0x520 0x20>;
+
+                               tbi1: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
+               };
+
+               enet2: ethernet@26000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <2>;
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <0x26000 0x1000>;
+                       ranges = <0x0 0x26000 0x1000>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <31 2 32 2 33 2>;
+                       interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi2>;
+                       phy-handle = <&phy2>;
+                       phy-connection-type = "rgmii-id";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-tbi";
+                               reg = <0x520 0x20>;
+
+                               tbi2: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
+               };
+
+               enet3: ethernet@27000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <3>;
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <0x27000 0x1000>;
+                       ranges = <0x0 0x27000 0x1000>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <37 2 38 2 39 2>;
+                       interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi3>;
+                       phy-handle = <&phy3>;
+                       phy-connection-type = "rgmii-id";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-tbi";
+                               reg = <0x520 0x20>;
+
+                               tbi3: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
+               };
+
+               serial0: serial@4500 {
+                       cell-index = <0>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x4500 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <42 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               serial1: serial@4600 {
+                       cell-index = <1>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x4600 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <28 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               mpic: pic@40000 {
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       reg = <0x40000 0x40000>;
+                       compatible = "chrp,open-pic";
+                       device_type = "open-pic";
+               };
+
+               global-utilities@e0000 {
+                       compatible = "fsl,mpc8641-guts";
+                       reg = <0xe0000 0x1000>;
+                       fsl,has-rstcr;
+               };
+       };
+
+       pci0: pcie@fffe08000 {
+               cell-index = <0>;
+               compatible = "fsl,mpc8641-pcie";
+               device_type = "pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0x0f 0xffe08000 0x0 0x1000>;
+               bus-range = <0x0 0xff>;
+               ranges = <0x02000000 0x0 0xe0000000 0x0c 0x00000000 0x0 0x20000000
+                         0x01000000 0x0 0x00000000 0x0f 0xffc00000 0x0 0x00010000>;
+               clock-frequency = <33333333>;
+               interrupt-parent = <&mpic>;
+               interrupts = <24 2>;
+               interrupt-map-mask = <0xff00 0 0 7>;
+               interrupt-map = <
+                       /* IDSEL 0x11 func 0 - PCI slot 1 */
+                       0x8800 0 0 1 &mpic 2 1
+                       0x8800 0 0 2 &mpic 3 1
+                       0x8800 0 0 3 &mpic 4 1
+                       0x8800 0 0 4 &mpic 1 1
+
+                       /* IDSEL 0x11 func 1 - PCI slot 1 */
+                       0x8900 0 0 1 &mpic 2 1
+                       0x8900 0 0 2 &mpic 3 1
+                       0x8900 0 0 3 &mpic 4 1
+                       0x8900 0 0 4 &mpic 1 1
+
+                       /* IDSEL 0x11 func 2 - PCI slot 1 */
+                       0x8a00 0 0 1 &mpic 2 1
+                       0x8a00 0 0 2 &mpic 3 1
+                       0x8a00 0 0 3 &mpic 4 1
+                       0x8a00 0 0 4 &mpic 1 1
+
+                       /* IDSEL 0x11 func 3 - PCI slot 1 */
+                       0x8b00 0 0 1 &mpic 2 1
+                       0x8b00 0 0 2 &mpic 3 1
+                       0x8b00 0 0 3 &mpic 4 1
+                       0x8b00 0 0 4 &mpic 1 1
+
+                       /* IDSEL 0x11 func 4 - PCI slot 1 */
+                       0x8c00 0 0 1 &mpic 2 1
+                       0x8c00 0 0 2 &mpic 3 1
+                       0x8c00 0 0 3 &mpic 4 1
+                       0x8c00 0 0 4 &mpic 1 1
+
+                       /* IDSEL 0x11 func 5 - PCI slot 1 */
+                       0x8d00 0 0 1 &mpic 2 1
+                       0x8d00 0 0 2 &mpic 3 1
+                       0x8d00 0 0 3 &mpic 4 1
+                       0x8d00 0 0 4 &mpic 1 1
+
+                       /* IDSEL 0x11 func 6 - PCI slot 1 */
+                       0x8e00 0 0 1 &mpic 2 1
+                       0x8e00 0 0 2 &mpic 3 1
+                       0x8e00 0 0 3 &mpic 4 1
+                       0x8e00 0 0 4 &mpic 1 1
+
+                       /* IDSEL 0x11 func 7 - PCI slot 1 */
+                       0x8f00 0 0 1 &mpic 2 1
+                       0x8f00 0 0 2 &mpic 3 1
+                       0x8f00 0 0 3 &mpic 4 1
+                       0x8f00 0 0 4 &mpic 1 1
+
+                       /* IDSEL 0x12 func 0 - PCI slot 2 */
+                       0x9000 0 0 1 &mpic 3 1
+                       0x9000 0 0 2 &mpic 4 1
+                       0x9000 0 0 3 &mpic 1 1
+                       0x9000 0 0 4 &mpic 2 1
+
+                       /* IDSEL 0x12 func 1 - PCI slot 2 */
+                       0x9100 0 0 1 &mpic 3 1
+                       0x9100 0 0 2 &mpic 4 1
+                       0x9100 0 0 3 &mpic 1 1
+                       0x9100 0 0 4 &mpic 2 1
+
+                       /* IDSEL 0x12 func 2 - PCI slot 2 */
+                       0x9200 0 0 1 &mpic 3 1
+                       0x9200 0 0 2 &mpic 4 1
+                       0x9200 0 0 3 &mpic 1 1
+                       0x9200 0 0 4 &mpic 2 1
+
+                       /* IDSEL 0x12 func 3 - PCI slot 2 */
+                       0x9300 0 0 1 &mpic 3 1
+                       0x9300 0 0 2 &mpic 4 1
+                       0x9300 0 0 3 &mpic 1 1
+                       0x9300 0 0 4 &mpic 2 1
+
+                       /* IDSEL 0x12 func 4 - PCI slot 2 */
+                       0x9400 0 0 1 &mpic 3 1
+                       0x9400 0 0 2 &mpic 4 1
+                       0x9400 0 0 3 &mpic 1 1
+                       0x9400 0 0 4 &mpic 2 1
+
+                       /* IDSEL 0x12 func 5 - PCI slot 2 */
+                       0x9500 0 0 1 &mpic 3 1
+                       0x9500 0 0 2 &mpic 4 1
+                       0x9500 0 0 3 &mpic 1 1
+                       0x9500 0 0 4 &mpic 2 1
+
+                       /* IDSEL 0x12 func 6 - PCI slot 2 */
+                       0x9600 0 0 1 &mpic 3 1
+                       0x9600 0 0 2 &mpic 4 1
+                       0x9600 0 0 3 &mpic 1 1
+                       0x9600 0 0 4 &mpic 2 1
+
+                       /* IDSEL 0x12 func 7 - PCI slot 2 */
+                       0x9700 0 0 1 &mpic 3 1
+                       0x9700 0 0 2 &mpic 4 1
+                       0x9700 0 0 3 &mpic 1 1
+                       0x9700 0 0 4 &mpic 2 1
+
+                       // IDSEL 0x1c  USB
+                       0xe000 0 0 1 &i8259 12 2
+                       0xe100 0 0 2 &i8259 9 2
+                       0xe200 0 0 3 &i8259 10 2
+                       0xe300 0 0 4 &i8259 11 2
+
+                       // IDSEL 0x1d  Audio
+                       0xe800 0 0 1 &i8259 6 2
+
+                       // IDSEL 0x1e Legacy
+                       0xf000 0 0 1 &i8259 7 2
+                       0xf100 0 0 1 &i8259 7 2
+
+                       // IDSEL 0x1f IDE/SATA
+                       0xf800 0 0 1 &i8259 14 2
+                       0xf900 0 0 1 &i8259 5 2
+                       >;
+
+               pcie@0 {
+                       reg = <0 0 0 0 0>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       ranges = <0x02000000 0x0 0xe0000000
+                                 0x02000000 0x0 0xe0000000
+                                 0x0 0x20000000
+
+                                 0x01000000 0x0 0x00000000
+                                 0x01000000 0x0 0x00000000
+                                 0x0 0x00010000>;
+                       uli1575@0 {
+                               reg = <0 0 0 0 0>;
+                               #size-cells = <2>;
+                               #address-cells = <3>;
+                               ranges = <0x02000000 0x0 0xe0000000
+                                         0x02000000 0x0 0xe0000000
+                                         0x0 0x20000000
+                                         0x01000000 0x0 0x00000000
+                                         0x01000000 0x0 0x00000000
+                                         0x0 0x00010000>;
+                               isa@1e {
+                                       device_type = "isa";
+                                       #interrupt-cells = <2>;
+                                       #size-cells = <1>;
+                                       #address-cells = <2>;
+                                       reg = <0xf000 0 0 0 0>;
+                                       ranges = <1 0 0x01000000 0 0
+                                                 0x00001000>;
+                                       interrupt-parent = <&i8259>;
+
+                                       i8259: interrupt-controller@20 {
+                                               reg = <1 0x20 2
+                                                      1 0xa0 2
+                                                      1 0x4d0 2>;
+                                               interrupt-controller;
+                                               device_type = "interrupt-controller";
+                                               #address-cells = <0>;
+                                               #interrupt-cells = <2>;
+                                               compatible = "chrp,iic";
+                                               interrupts = <9 2>;
+                                               interrupt-parent = <&mpic>;
+                                       };
+
+                                       i8042@60 {
+                                               #size-cells = <0>;
+                                               #address-cells = <1>;
+                                               reg = <1 0x60 1 1 0x64 1>;
+                                               interrupts = <1 3 12 3>;
+                                               interrupt-parent =
+                                                       <&i8259>;
+
+                                               keyboard@0 {
+                                                       reg = <0>;
+                                                       compatible = "pnpPNP,303";
+                                               };
+
+                                               mouse@1 {
+                                                       reg = <1>;
+                                                       compatible = "pnpPNP,f03";
+                                               };
+                                       };
+
+                                       rtc@70 {
+                                               compatible =
+                                                       "pnpPNP,b00";
+                                               reg = <1 0x70 2>;
+                                       };
+
+                                       gpio@400 {
+                                               reg = <1 0x400 0x80>;
+                                       };
+                               };
+                       };
+               };
+
+       };
+
+       pci1: pcie@fffe09000 {
+               cell-index = <1>;
+               compatible = "fsl,mpc8641-pcie";
+               device_type = "pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0x0f 0xffe09000 0x0 0x1000>;
+               bus-range = <0x0 0xff>;
+               ranges = <0x02000000 0x0 0xe0000000 0x0c 0x20000000 0x0 0x20000000
+                         0x01000000 0x0 0x00000000 0x0f 0xffc10000 0x0 0x00010000>;
+               clock-frequency = <33333333>;
+               interrupt-parent = <&mpic>;
+               interrupts = <25 2>;
+               interrupt-map-mask = <0xf800 0 0 7>;
+               interrupt-map = <
+                       /* IDSEL 0x0 */
+                       0x0000 0 0 1 &mpic 4 1
+                       0x0000 0 0 2 &mpic 5 1
+                       0x0000 0 0 3 &mpic 6 1
+                       0x0000 0 0 4 &mpic 7 1
+                       >;
+               pcie@0 {
+                       reg = <0 0 0 0 0>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       ranges = <0x02000000 0x0 0xe0000000
+                                 0x02000000 0x0 0xe0000000
+                                 0x0 0x20000000
+
+                                 0x01000000 0x0 0x00000000
+                                 0x01000000 0x0 0x00000000
+                                 0x0 0x00010000>;
+               };
+       };
+};
diff --git a/arch/powerpc/boot/dts/p2020ds.dts b/arch/powerpc/boot/dts/p2020ds.dts
new file mode 100644 (file)
index 0000000..1101914
--- /dev/null
@@ -0,0 +1,704 @@
+/*
+ * P2020 DS Device Tree Source
+ *
+ * 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.
+ */
+
+/dts-v1/;
+/ {
+       model = "fsl,P2020";
+       compatible = "fsl,P2020DS";
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       aliases {
+               ethernet0 = &enet0;
+               ethernet1 = &enet1;
+               ethernet2 = &enet2;
+               serial0 = &serial0;
+               serial1 = &serial1;
+               pci0 = &pci0;
+               pci1 = &pci1;
+               pci2 = &pci2;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               PowerPC,P2020@0 {
+                       device_type = "cpu";
+                       reg = <0x0>;
+                       next-level-cache = <&L2>;
+               };
+
+               PowerPC,P2020@1 {
+                       device_type = "cpu";
+                       reg = <0x1>;
+                       next-level-cache = <&L2>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+       };
+
+       localbus@ffe05000 {
+               #address-cells = <2>;
+               #size-cells = <1>;
+               compatible = "fsl,elbc", "simple-bus";
+               reg = <0 0xffe05000 0 0x1000>;
+               interrupts = <19 2>;
+               interrupt-parent = <&mpic>;
+
+               ranges = <0x0 0x0 0x0 0xe8000000 0x08000000
+                         0x1 0x0 0x0 0xe0000000 0x08000000
+                         0x2 0x0 0x0 0xffa00000 0x00040000
+                         0x3 0x0 0x0 0xffdf0000 0x00008000
+                         0x4 0x0 0x0 0xffa40000 0x00040000
+                         0x5 0x0 0x0 0xffa80000 0x00040000
+                         0x6 0x0 0x0 0xffac0000 0x00040000>;
+
+               nor@0,0 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "cfi-flash";
+                       reg = <0x0 0x0 0x8000000>;
+                       bank-width = <2>;
+                       device-width = <1>;
+
+                       ramdisk@0 {
+                               reg = <0x0 0x03000000>;
+                               read-only;
+                       };
+
+                       diagnostic@3000000 {
+                               reg = <0x03000000 0x00e00000>;
+                               read-only;
+                       };
+
+                       dink@3e00000 {
+                               reg = <0x03e00000 0x00200000>;
+                               read-only;
+                       };
+
+                       kernel@4000000 {
+                               reg = <0x04000000 0x00400000>;
+                               read-only;
+                       };
+
+                       jffs2@4400000 {
+                               reg = <0x04400000 0x03b00000>;
+                       };
+
+                       dtb@7f00000 {
+                               reg = <0x07f00000 0x00080000>;
+                               read-only;
+                       };
+
+                       u-boot@7f80000 {
+                               reg = <0x07f80000 0x00080000>;
+                               read-only;
+                       };
+               };
+
+               nand@2,0 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,elbc-fcm-nand";
+                       reg = <0x2 0x0 0x40000>;
+
+                       u-boot@0 {
+                               reg = <0x0 0x02000000>;
+                               read-only;
+                       };
+
+                       jffs2@2000000 {
+                               reg = <0x02000000 0x10000000>;
+                       };
+
+                       ramdisk@12000000 {
+                               reg = <0x12000000 0x08000000>;
+                               read-only;
+                       };
+
+                       kernel@1a000000 {
+                               reg = <0x1a000000 0x04000000>;
+                       };
+
+                       dtb@1e000000 {
+                               reg = <0x1e000000 0x01000000>;
+                               read-only;
+                       };
+
+                       empty@1f000000 {
+                               reg = <0x1f000000 0x21000000>;
+                       };
+               };
+
+               nand@4,0 {
+                       compatible = "fsl,elbc-fcm-nand";
+                       reg = <0x4 0x0 0x40000>;
+               };
+
+               nand@5,0 {
+                       compatible = "fsl,elbc-fcm-nand";
+                       reg = <0x5 0x0 0x40000>;
+               };
+
+               nand@6,0 {
+                       compatible = "fsl,elbc-fcm-nand";
+                       reg = <0x6 0x0 0x40000>;
+               };
+       };
+
+       soc@ffe00000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               device_type = "soc";
+               compatible = "fsl,p2020-immr", "simple-bus";
+               ranges = <0x0 0 0xffe00000 0x100000>;
+               bus-frequency = <0>;            // Filled out by uboot.
+
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <12>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,p2020-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               memory-controller@2000 {
+                       compatible = "fsl,p2020-memory-controller";
+                       reg = <0x2000 0x1000>;
+                       interrupt-parent = <&mpic>;
+                       interrupts = <18 2>;
+               };
+
+               i2c@3000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <0>;
+                       compatible = "fsl-i2c";
+                       reg = <0x3000 0x100>;
+                       interrupts = <43 2>;
+                       interrupt-parent = <&mpic>;
+                       dfsrr;
+               };
+
+               i2c@3100 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <1>;
+                       compatible = "fsl-i2c";
+                       reg = <0x3100 0x100>;
+                       interrupts = <43 2>;
+                       interrupt-parent = <&mpic>;
+                       dfsrr;
+               };
+
+               serial0: serial@4500 {
+                       cell-index = <0>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x4500 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <42 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               serial1: serial@4600 {
+                       cell-index = <1>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x4600 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <42 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               spi@7000 {
+                       compatible = "fsl,espi";
+                       reg = <0x7000 0x1000>;
+                       interrupts = <59 0x2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               dma@c300 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,eloplus-dma";
+                       reg = <0xc300 0x4>;
+                       ranges = <0x0 0xc100 0x200>;
+                       cell-index = <1>;
+                       dma-channel@0 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x0 0x80>;
+                               cell-index = <0>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <76 2>;
+                       };
+                       dma-channel@80 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x80 0x80>;
+                               cell-index = <1>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <77 2>;
+                       };
+                       dma-channel@100 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x100 0x80>;
+                               cell-index = <2>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <78 2>;
+                       };
+                       dma-channel@180 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x180 0x80>;
+                               cell-index = <3>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <79 2>;
+                       };
+               };
+
+               gpio: gpio-controller@f000 {
+                       #gpio-cells = <2>;
+                       compatible = "fsl,mpc8572-gpio";
+                       reg = <0xf000 0x100>;
+                       interrupts = <47 0x2>;
+                       interrupt-parent = <&mpic>;
+                       gpio-controller;
+               };
+
+               L2: l2-cache-controller@20000 {
+                       compatible = "fsl,p2020-l2-cache-controller";
+                       reg = <0x20000 0x1000>;
+                       cache-line-size = <32>; // 32 bytes
+                       cache-size = <0x80000>; // L2, 512k
+                       interrupt-parent = <&mpic>;
+                       interrupts = <16 2>;
+               };
+
+               dma@21300 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,eloplus-dma";
+                       reg = <0x21300 0x4>;
+                       ranges = <0x0 0x21100 0x200>;
+                       cell-index = <0>;
+                       dma-channel@0 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x0 0x80>;
+                               cell-index = <0>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <20 2>;
+                       };
+                       dma-channel@80 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x80 0x80>;
+                               cell-index = <1>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <21 2>;
+                       };
+                       dma-channel@100 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x100 0x80>;
+                               cell-index = <2>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <22 2>;
+                       };
+                       dma-channel@180 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x180 0x80>;
+                               cell-index = <3>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <23 2>;
+                       };
+               };
+
+               usb@22000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl-usb2-dr";
+                       reg = <0x22000 0x1000>;
+                       interrupt-parent = <&mpic>;
+                       interrupts = <28 0x2>;
+                       phy_type = "ulpi";
+               };
+
+               enet0: ethernet@24000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <0>;
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "gianfar";
+                       reg = <0x24000 0x1000>;
+                       ranges = <0x0 0x24000 0x1000>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <29 2 30 2 34 2>;
+                       interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi0>;
+                       phy-handle = <&phy0>;
+                       phy-connection-type = "rgmii-id";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-mdio";
+                               reg = <0x520 0x20>;
+
+                               phy0: ethernet-phy@0 {
+                                       interrupt-parent = <&mpic>;
+                                       interrupts = <3 1>;
+                                       reg = <0x0>;
+                               };
+                               phy1: ethernet-phy@1 {
+                                       interrupt-parent = <&mpic>;
+                                       interrupts = <3 1>;
+                                       reg = <0x1>;
+                               };
+                               phy2: ethernet-phy@2 {
+                                       interrupt-parent = <&mpic>;
+                                       interrupts = <3 1>;
+                                       reg = <0x2>;
+                               };
+                               tbi0: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
+               };
+
+               enet1: ethernet@25000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <1>;
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "gianfar";
+                       reg = <0x25000 0x1000>;
+                       ranges = <0x0 0x25000 0x1000>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <35 2 36 2 40 2>;
+                       interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi1>;
+                       phy-handle = <&phy1>;
+                       phy-connection-type = "rgmii-id";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-tbi";
+                               reg = <0x520 0x20>;
+
+                               tbi1: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
+               };
+
+               enet2: ethernet@26000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <2>;
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "gianfar";
+                       reg = <0x26000 0x1000>;
+                       ranges = <0x0 0x26000 0x1000>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <31 2 32 2 33 2>;
+                       interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi2>;
+                       phy-handle = <&phy2>;
+                       phy-connection-type = "rgmii-id";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-tbi";
+                               reg = <0x520 0x20>;
+
+                               tbi2: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
+               };
+
+               sdhci@2e000 {
+                       compatible = "fsl,p2020-esdhc", "fsl,esdhc";
+                       reg = <0x2e000 0x1000>;
+                       interrupts = <72 0x2>;
+                       interrupt-parent = <&mpic>;
+                       /* Filled in by U-Boot */
+                       clock-frequency = <0>;
+               };
+
+               crypto@30000 {
+                       compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
+                                    "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+                       reg = <0x30000 0x10000>;
+                       interrupts = <45 2 58 2>;
+                       interrupt-parent = <&mpic>;
+                       fsl,num-channels = <4>;
+                       fsl,channel-fifo-len = <24>;
+                       fsl,exec-units-mask = <0xbfe>;
+                       fsl,descriptor-types-mask = <0x3ab0ebf>;
+               };
+
+               mpic: pic@40000 {
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       reg = <0x40000 0x40000>;
+                       compatible = "chrp,open-pic";
+                       device_type = "open-pic";
+               };
+
+               msi@41600 {
+                       compatible = "fsl,mpic-msi";
+                       reg = <0x41600 0x80>;
+                       msi-available-ranges = <0 0x100>;
+                       interrupts = <
+                               0xe0 0
+                               0xe1 0
+                               0xe2 0
+                               0xe3 0
+                               0xe4 0
+                               0xe5 0
+                               0xe6 0
+                               0xe7 0>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               global-utilities@e0000 {        //global utilities block
+                       compatible = "fsl,p2020-guts";
+                       reg = <0xe0000 0x1000>;
+                       fsl,has-rstcr;
+               };
+       };
+
+       pci0: pcie@ffe08000 {
+               compatible = "fsl,mpc8548-pcie";
+               device_type = "pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0 0xffe08000 0 0x1000>;
+               bus-range = <0 255>;
+               ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+               clock-frequency = <33333333>;
+               interrupt-parent = <&mpic>;
+               interrupts = <24 2>;
+               interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+               interrupt-map = <
+                       /* IDSEL 0x0 */
+                       0000 0x0 0x0 0x1 &mpic 0x8 0x1
+                       0000 0x0 0x0 0x2 &mpic 0x9 0x1
+                       0000 0x0 0x0 0x3 &mpic 0xa 0x1
+                       0000 0x0 0x0 0x4 &mpic 0xb 0x1
+                       >;
+               pcie@0 {
+                       reg = <0x0 0x0 0x0 0x0 0x0>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       ranges = <0x2000000 0x0 0x80000000
+                                 0x2000000 0x0 0x80000000
+                                 0x0 0x20000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x10000>;
+               };
+       };
+
+       pci1: pcie@ffe09000 {
+               compatible = "fsl,mpc8548-pcie";
+               device_type = "pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0 0xffe09000 0 0x1000>;
+               bus-range = <0 255>;
+               ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+               clock-frequency = <33333333>;
+               interrupt-parent = <&mpic>;
+               interrupts = <25 2>;
+               interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
+               interrupt-map = <
+
+                       // IDSEL 0x11 func 0 - PCI slot 1
+                       0x8800 0x0 0x0 0x1 &i8259 0x9 0x2
+                       0x8800 0x0 0x0 0x2 &i8259 0xa 0x2
+
+                       // IDSEL 0x11 func 1 - PCI slot 1
+                       0x8900 0x0 0x0 0x1 &i8259 0x9 0x2
+                       0x8900 0x0 0x0 0x2 &i8259 0xa 0x2
+
+                       // IDSEL 0x11 func 2 - PCI slot 1
+                       0x8a00 0x0 0x0 0x1 &i8259 0x9 0x2
+                       0x8a00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+                       // IDSEL 0x11 func 3 - PCI slot 1
+                       0x8b00 0x0 0x0 0x1 &i8259 0x9 0x2
+                       0x8b00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+                       // IDSEL 0x11 func 4 - PCI slot 1
+                       0x8c00 0x0 0x0 0x1 &i8259 0x9 0x2
+                       0x8c00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+                       // IDSEL 0x11 func 5 - PCI slot 1
+                       0x8d00 0x0 0x0 0x1 &i8259 0x9 0x2
+                       0x8d00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+                       // IDSEL 0x11 func 6 - PCI slot 1
+                       0x8e00 0x0 0x0 0x1 &i8259 0x9 0x2
+                       0x8e00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+                       // IDSEL 0x11 func 7 - PCI slot 1
+                       0x8f00 0x0 0x0 0x1 &i8259 0x9 0x2
+                       0x8f00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+                       // IDSEL 0x1d  Audio
+                       0xe800 0x0 0x0 0x1 &i8259 0x6 0x2
+
+                       // IDSEL 0x1e Legacy
+                       0xf000 0x0 0x0 0x1 &i8259 0x7 0x2
+                       0xf100 0x0 0x0 0x1 &i8259 0x7 0x2
+
+                       // IDSEL 0x1f IDE/SATA
+                       0xf800 0x0 0x0 0x1 &i8259 0xe 0x2
+                       0xf900 0x0 0x0 0x1 &i8259 0x5 0x2
+                       >;
+
+               pcie@0 {
+                       reg = <0x0 0x0 0x0 0x0 0x0>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       ranges = <0x2000000 0x0 0xa0000000
+                                 0x2000000 0x0 0xa0000000
+                                 0x0 0x20000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x10000>;
+                       uli1575@0 {
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               #size-cells = <2>;
+                               #address-cells = <3>;
+                               ranges = <0x2000000 0x0 0xa0000000
+                                         0x2000000 0x0 0xa0000000
+                                         0x0 0x20000000
+
+                                         0x1000000 0x0 0x0
+                                         0x1000000 0x0 0x0
+                                         0x0 0x10000>;
+                               isa@1e {
+                                       device_type = "isa";
+                                       #interrupt-cells = <2>;
+                                       #size-cells = <1>;
+                                       #address-cells = <2>;
+                                       reg = <0xf000 0x0 0x0 0x0 0x0>;
+                                       ranges = <0x1 0x0 0x1000000 0x0 0x0
+                                                 0x1000>;
+                                       interrupt-parent = <&i8259>;
+
+                                       i8259: interrupt-controller@20 {
+                                               reg = <0x1 0x20 0x2
+                                                      0x1 0xa0 0x2
+                                                      0x1 0x4d0 0x2>;
+                                               interrupt-controller;
+                                               device_type = "interrupt-controller";
+                                               #address-cells = <0>;
+                                               #interrupt-cells = <2>;
+                                               compatible = "chrp,iic";
+                                               interrupts = <4 1>;
+                                               interrupt-parent = <&mpic>;
+                                       };
+
+                                       i8042@60 {
+                                               #size-cells = <0>;
+                                               #address-cells = <1>;
+                                               reg = <0x1 0x60 0x1 0x1 0x64 0x1>;
+                                               interrupts = <1 3 12 3>;
+                                               interrupt-parent =
+                                                       <&i8259>;
+
+                                               keyboard@0 {
+                                                       reg = <0x0>;
+                                                       compatible = "pnpPNP,303";
+                                               };
+
+                                               mouse@1 {
+                                                       reg = <0x1>;
+                                                       compatible = "pnpPNP,f03";
+                                               };
+                                       };
+
+                                       rtc@70 {
+                                               compatible = "pnpPNP,b00";
+                                               reg = <0x1 0x70 0x2>;
+                                       };
+
+                                       gpio@400 {
+                                               reg = <0x1 0x400 0x80>;
+                                       };
+                               };
+                       };
+               };
+
+       };
+
+       pci2: pcie@ffe0a000 {
+               compatible = "fsl,mpc8548-pcie";
+               device_type = "pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0 0xffe0a000 0 0x1000>;
+               bus-range = <0 255>;
+               ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+               clock-frequency = <33333333>;
+               interrupt-parent = <&mpic>;
+               interrupts = <26 2>;
+               interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+               interrupt-map = <
+                       /* IDSEL 0x0 */
+                       0000 0x0 0x0 0x1 &mpic 0x0 0x1
+                       0000 0x0 0x0 0x2 &mpic 0x1 0x1
+                       0000 0x0 0x0 0x3 &mpic 0x2 0x1
+                       0000 0x0 0x0 0x4 &mpic 0x3 0x1
+                       >;
+               pcie@0 {
+                       reg = <0x0 0x0 0x0 0x0 0x0>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       ranges = <0x2000000 0x0 0xc0000000
+                                 0x2000000 0x0 0xc0000000
+                                 0x0 0x20000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x10000>;
+               };
+       };
+};
index a36dbbc..5fb6f66 100644 (file)
        };
 
        pci0: pci@e0008500 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index b1f1416..9eefe00 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0x00000000 0xe0000000 0x00100000>;
-               reg = <0xe0000000 0x00001000>;  // CCSRBAR
                bus-frequency = <0>;
                compatible = "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8548-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8548-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                        /* IDSEL 0x01 (PCI-X slot) @66MHz */
        };
 
        pci2: pcie@e000a000 {
-               cell-index = <2>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index c4564b8..239d57a 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0x0 0xff700000 0x00100000>;
-               reg = <0xff700000 0x00100000>;
                clock-frequency = <0>;
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8560-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8560-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@ff708000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
index e3e914e..ee5538f 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x00000000 0xf8000000 0x00100000>;
-               reg = <0xf8000000 0x00001000>;  // CCSRBAR
                bus-frequency = <0>;
 
+               mcm-law@0 {
+                       compatible = "fsl,mcm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               mcm@1000 {
+                       compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                i2c@3000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
        };
 
        pci0: pcie@f8008000 {
-               cell-index = <0>;
                compatible = "fsl,mpc8641-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci1: pcie@f8009000 {
-               cell-index = <1>;
                compatible = "fsl,mpc8641-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
index 43cc68b..739dd0d 100644 (file)
                                        };
                                };
 
+                               ndfc@3,0 {
+                                       compatible = "ibm,ndfc";
+                                       reg = <0x00000003 0x00000000 0x00002000>;
+                                       ccr = <0x00001000>;
+                                       bank-settings = <0x80002222>;
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+
+                                       nand {
+                                               #address-cells = <1>;
+                                               #size-cells = <1>;
+
+                                               partition@0 {
+                                                       label = "u-boot";
+                                                       reg = <0x00000000 0x00084000>;
+                                               };
+                                               partition@84000 {
+                                                       label = "user";
+                                                       reg = <0x00000000 0x01f7c000>;
+                                               };
+                                       };
+                               };
                        };
 
                        UART0: serial@ef600300 {
index 7a6ae75..feb4ef6 100644 (file)
                device_type = "soc";
 
                ranges = <0x00000000 0xe0000000 0x00100000>;
-               reg = <0xe0000000 0x00001000>;  // CCSRBAR 1M
                bus-frequency = <0>;            // Filled in by U-Boot
                compatible = "fsl,mpc8544-immr", "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8544-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8544-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
index ea6b151..b670d03 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0 0xfdf00000 0x100000>;
-               reg = <0xfdf00000 0x1000>;
                bus-frequency = <0>;
                compatible = "fsl,mpc8560-immr", "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8560-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8540-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@fdf08000 {
-               cell-index = <0>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index b6f1fc6..7134753 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x200>;
                bus-frequency = <0>;
                compatible = "fsl,mpc8540-immr", "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8540-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8540-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
index fa6a3d5..b30f637 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x200>;
                bus-frequency = <0>;
                compatible = "fsl,mpc8541-immr", "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8541-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8540-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
index 00f7ed7..61f25e1 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0x0 0xa0000000 0x100000>;
-               reg = <0xa0000000 0x1000>;      // CCSRBAR
                bus-frequency = <0>;
                compatible = "fsl,mpc8548-immr", "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8548-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8548-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@a0008000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
        };
 
        pci1: pcie@a000a000 {
-               cell-index = <2>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                        /* IDSEL 0x0 (PEX) */
index 673e4a7..025759c 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x1000>;      // CCSRBAR
                bus-frequency = <0>;
                compatible = "fsl,mpc8548-immr", "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8548-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8548-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
        };
 
        pci1: pcie@e000a000 {
-               cell-index = <2>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                        /* IDSEL 0x0 (PEX) */
index 6a99f1e..95e2873 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x200>;
                bus-frequency = <0>;
                compatible = "fsl,mpc8555-immr", "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8555-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8540-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
index b6c2d71..ff70580 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x200>;
                bus-frequency = <0>;
                compatible = "fsl,mpc8560-immr", "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8560-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8540-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
diff --git a/arch/powerpc/boot/dts/virtex440-ml510.dts b/arch/powerpc/boot/dts/virtex440-ml510.dts
new file mode 100644 (file)
index 0000000..81a8dc2
--- /dev/null
@@ -0,0 +1,465 @@
+/*
+ * Xilinx ML510 Reference Design support
+ *
+ * This DTS file was created for the ml510_bsb1_pcores_ppc440 reference design.
+ * The reference design contains a bug which prevent PCI DMA from working
+ * properly.  A description of the bug is given in the plbv46_pci section. It
+ * needs to be fixed by the user until Xilinx updates their reference design.
+ *
+ * Copyright 2009, Roderick Colenbrander
+ */
+
+/dts-v1/;
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "xlnx,ml510-ref-design", "xlnx,virtex440";
+       dcr-parent = <&ppc440_0>;
+       DDR2_SDRAM_DIMM0: memory@0 {
+               device_type = "memory";
+               reg = < 0x0 0x20000000 >;
+       } ;
+       alias {
+               ethernet0 = &Hard_Ethernet_MAC;
+               serial0 = &RS232_Uart_1;
+       } ;
+       chosen {
+               bootargs = "console=ttyS0 root=/dev/ram";
+               linux,stdout-path = "/plb@0/serial@83e00000";
+       } ;
+       cpus {
+               #address-cells = <1>;
+               #cpus = <0x1>;
+               #size-cells = <0>;
+               ppc440_0: cpu@0 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clock-frequency = <300000000>;
+                       compatible = "PowerPC,440", "ibm,ppc440";
+                       d-cache-line-size = <0x20>;
+                       d-cache-size = <0x8000>;
+                       dcr-access-method = "native";
+                       dcr-controller ;
+                       device_type = "cpu";
+                       i-cache-line-size = <0x20>;
+                       i-cache-size = <0x8000>;
+                       model = "PowerPC,440";
+                       reg = <0>;
+                       timebase-frequency = <300000000>;
+                       xlnx,apu-control = <0x2000>;
+                       xlnx,apu-udi-0 = <0x0>;
+                       xlnx,apu-udi-1 = <0x0>;
+                       xlnx,apu-udi-10 = <0x0>;
+                       xlnx,apu-udi-11 = <0x0>;
+                       xlnx,apu-udi-12 = <0x0>;
+                       xlnx,apu-udi-13 = <0x0>;
+                       xlnx,apu-udi-14 = <0x0>;
+                       xlnx,apu-udi-15 = <0x0>;
+                       xlnx,apu-udi-2 = <0x0>;
+                       xlnx,apu-udi-3 = <0x0>;
+                       xlnx,apu-udi-4 = <0x0>;
+                       xlnx,apu-udi-5 = <0x0>;
+                       xlnx,apu-udi-6 = <0x0>;
+                       xlnx,apu-udi-7 = <0x0>;
+                       xlnx,apu-udi-8 = <0x0>;
+                       xlnx,apu-udi-9 = <0x0>;
+                       xlnx,dcr-autolock-enable = <0x1>;
+                       xlnx,dcu-rd-ld-cache-plb-prio = <0x0>;
+                       xlnx,dcu-rd-noncache-plb-prio = <0x0>;
+                       xlnx,dcu-rd-touch-plb-prio = <0x0>;
+                       xlnx,dcu-rd-urgent-plb-prio = <0x0>;
+                       xlnx,dcu-wr-flush-plb-prio = <0x0>;
+                       xlnx,dcu-wr-store-plb-prio = <0x0>;
+                       xlnx,dcu-wr-urgent-plb-prio = <0x0>;
+                       xlnx,dma0-control = <0x0>;
+                       xlnx,dma0-plb-prio = <0x0>;
+                       xlnx,dma0-rxchannelctrl = <0x1010000>;
+                       xlnx,dma0-rxirqtimer = <0x3ff>;
+                       xlnx,dma0-txchannelctrl = <0x1010000>;
+                       xlnx,dma0-txirqtimer = <0x3ff>;
+                       xlnx,dma1-control = <0x0>;
+                       xlnx,dma1-plb-prio = <0x0>;
+                       xlnx,dma1-rxchannelctrl = <0x1010000>;
+                       xlnx,dma1-rxirqtimer = <0x3ff>;
+                       xlnx,dma1-txchannelctrl = <0x1010000>;
+                       xlnx,dma1-txirqtimer = <0x3ff>;
+                       xlnx,dma2-control = <0x0>;
+                       xlnx,dma2-plb-prio = <0x0>;
+                       xlnx,dma2-rxchannelctrl = <0x1010000>;
+                       xlnx,dma2-rxirqtimer = <0x3ff>;
+                       xlnx,dma2-txchannelctrl = <0x1010000>;
+                       xlnx,dma2-txirqtimer = <0x3ff>;
+                       xlnx,dma3-control = <0x0>;
+                       xlnx,dma3-plb-prio = <0x0>;
+                       xlnx,dma3-rxchannelctrl = <0x1010000>;
+                       xlnx,dma3-rxirqtimer = <0x3ff>;
+                       xlnx,dma3-txchannelctrl = <0x1010000>;
+                       xlnx,dma3-txirqtimer = <0x3ff>;
+                       xlnx,endian-reset = <0x0>;
+                       xlnx,generate-plb-timespecs = <0x1>;
+                       xlnx,icu-rd-fetch-plb-prio = <0x0>;
+                       xlnx,icu-rd-spec-plb-prio = <0x0>;
+                       xlnx,icu-rd-touch-plb-prio = <0x0>;
+                       xlnx,interconnect-imask = <0xffffffff>;
+                       xlnx,mplb-allow-lock-xfer = <0x1>;
+                       xlnx,mplb-arb-mode = <0x0>;
+                       xlnx,mplb-awidth = <0x20>;
+                       xlnx,mplb-counter = <0x500>;
+                       xlnx,mplb-dwidth = <0x80>;
+                       xlnx,mplb-max-burst = <0x8>;
+                       xlnx,mplb-native-dwidth = <0x80>;
+                       xlnx,mplb-p2p = <0x0>;
+                       xlnx,mplb-prio-dcur = <0x2>;
+                       xlnx,mplb-prio-dcuw = <0x3>;
+                       xlnx,mplb-prio-icu = <0x4>;
+                       xlnx,mplb-prio-splb0 = <0x1>;
+                       xlnx,mplb-prio-splb1 = <0x0>;
+                       xlnx,mplb-read-pipe-enable = <0x1>;
+                       xlnx,mplb-sync-tattribute = <0x0>;
+                       xlnx,mplb-wdog-enable = <0x1>;
+                       xlnx,mplb-write-pipe-enable = <0x1>;
+                       xlnx,mplb-write-post-enable = <0x1>;
+                       xlnx,num-dma = <0x0>;
+                       xlnx,pir = <0xf>;
+                       xlnx,ppc440mc-addr-base = <0x0>;
+                       xlnx,ppc440mc-addr-high = <0x1fffffff>;
+                       xlnx,ppc440mc-arb-mode = <0x0>;
+                       xlnx,ppc440mc-bank-conflict-mask = <0x1800000>;
+                       xlnx,ppc440mc-control = <0xf810008f>;
+                       xlnx,ppc440mc-max-burst = <0x8>;
+                       xlnx,ppc440mc-prio-dcur = <0x2>;
+                       xlnx,ppc440mc-prio-dcuw = <0x3>;
+                       xlnx,ppc440mc-prio-icu = <0x4>;
+                       xlnx,ppc440mc-prio-splb0 = <0x1>;
+                       xlnx,ppc440mc-prio-splb1 = <0x0>;
+                       xlnx,ppc440mc-row-conflict-mask = <0x7ffe00>;
+                       xlnx,ppcdm-asyncmode = <0x0>;
+                       xlnx,ppcds-asyncmode = <0x0>;
+                       xlnx,user-reset = <0x0>;
+               } ;
+       } ;
+       plb_v46_0: plb@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "xlnx,plb-v46-1.03.a", "simple-bus";
+               ranges ;
+               FLASH: flash@fc000000 {
+                       bank-width = <2>;
+                       compatible = "xlnx,xps-mch-emc-2.00.a", "cfi-flash";
+                       reg = < 0xfc000000 0x2000000 >;
+                       xlnx,family = "virtex5";
+                       xlnx,include-datawidth-matching-0 = <0x1>;
+                       xlnx,include-datawidth-matching-1 = <0x0>;
+                       xlnx,include-datawidth-matching-2 = <0x0>;
+                       xlnx,include-datawidth-matching-3 = <0x0>;
+                       xlnx,include-negedge-ioregs = <0x0>;
+                       xlnx,include-plb-ipif = <0x1>;
+                       xlnx,include-wrbuf = <0x1>;
+                       xlnx,max-mem-width = <0x10>;
+                       xlnx,mch-native-dwidth = <0x20>;
+                       xlnx,mch-plb-clk-period-ps = <0x2710>;
+                       xlnx,mch-splb-awidth = <0x20>;
+                       xlnx,mch0-accessbuf-depth = <0x10>;
+                       xlnx,mch0-protocol = <0x0>;
+                       xlnx,mch0-rddatabuf-depth = <0x10>;
+                       xlnx,mch1-accessbuf-depth = <0x10>;
+                       xlnx,mch1-protocol = <0x0>;
+                       xlnx,mch1-rddatabuf-depth = <0x10>;
+                       xlnx,mch2-accessbuf-depth = <0x10>;
+                       xlnx,mch2-protocol = <0x0>;
+                       xlnx,mch2-rddatabuf-depth = <0x10>;
+                       xlnx,mch3-accessbuf-depth = <0x10>;
+                       xlnx,mch3-protocol = <0x0>;
+                       xlnx,mch3-rddatabuf-depth = <0x10>;
+                       xlnx,mem0-width = <0x10>;
+                       xlnx,mem1-width = <0x20>;
+                       xlnx,mem2-width = <0x20>;
+                       xlnx,mem3-width = <0x20>;
+                       xlnx,num-banks-mem = <0x1>;
+                       xlnx,num-channels = <0x2>;
+                       xlnx,priority-mode = <0x0>;
+                       xlnx,synch-mem-0 = <0x0>;
+                       xlnx,synch-mem-1 = <0x0>;
+                       xlnx,synch-mem-2 = <0x0>;
+                       xlnx,synch-mem-3 = <0x0>;
+                       xlnx,synch-pipedelay-0 = <0x2>;
+                       xlnx,synch-pipedelay-1 = <0x2>;
+                       xlnx,synch-pipedelay-2 = <0x2>;
+                       xlnx,synch-pipedelay-3 = <0x2>;
+                       xlnx,tavdv-ps-mem-0 = <0x1adb0>;
+                       xlnx,tavdv-ps-mem-1 = <0x3a98>;
+                       xlnx,tavdv-ps-mem-2 = <0x3a98>;
+                       xlnx,tavdv-ps-mem-3 = <0x3a98>;
+                       xlnx,tcedv-ps-mem-0 = <0x1adb0>;
+                       xlnx,tcedv-ps-mem-1 = <0x3a98>;
+                       xlnx,tcedv-ps-mem-2 = <0x3a98>;
+                       xlnx,tcedv-ps-mem-3 = <0x3a98>;
+                       xlnx,thzce-ps-mem-0 = <0x88b8>;
+                       xlnx,thzce-ps-mem-1 = <0x1b58>;
+                       xlnx,thzce-ps-mem-2 = <0x1b58>;
+                       xlnx,thzce-ps-mem-3 = <0x1b58>;
+                       xlnx,thzoe-ps-mem-0 = <0x1b58>;
+                       xlnx,thzoe-ps-mem-1 = <0x1b58>;
+                       xlnx,thzoe-ps-mem-2 = <0x1b58>;
+                       xlnx,thzoe-ps-mem-3 = <0x1b58>;
+                       xlnx,tlzwe-ps-mem-0 = <0x88b8>;
+                       xlnx,tlzwe-ps-mem-1 = <0x0>;
+                       xlnx,tlzwe-ps-mem-2 = <0x0>;
+                       xlnx,tlzwe-ps-mem-3 = <0x0>;
+                       xlnx,twc-ps-mem-0 = <0x1adb0>;
+                       xlnx,twc-ps-mem-1 = <0x3a98>;
+                       xlnx,twc-ps-mem-2 = <0x3a98>;
+                       xlnx,twc-ps-mem-3 = <0x3a98>;
+                       xlnx,twp-ps-mem-0 = <0x11170>;
+                       xlnx,twp-ps-mem-1 = <0x2ee0>;
+                       xlnx,twp-ps-mem-2 = <0x2ee0>;
+                       xlnx,twp-ps-mem-3 = <0x2ee0>;
+                       xlnx,xcl0-linesize = <0x4>;
+                       xlnx,xcl0-writexfer = <0x1>;
+                       xlnx,xcl1-linesize = <0x4>;
+                       xlnx,xcl1-writexfer = <0x1>;
+                       xlnx,xcl2-linesize = <0x4>;
+                       xlnx,xcl2-writexfer = <0x1>;
+                       xlnx,xcl3-linesize = <0x4>;
+                       xlnx,xcl3-writexfer = <0x1>;
+               } ;
+               Hard_Ethernet_MAC: xps-ll-temac@81c00000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "xlnx,compound";
+                       ethernet@81c00000 {
+                               compatible = "xlnx,xps-ll-temac-1.01.b";
+                               device_type = "network";
+                               interrupt-parent = <&xps_intc_0>;
+                               interrupts = < 8 2 >;
+                               llink-connected = <&Hard_Ethernet_MAC_fifo>;
+                               local-mac-address = [ 02 00 00 00 00 00 ];
+                               reg = < 0x81c00000 0x40 >;
+                               xlnx,bus2core-clk-ratio = <0x1>;
+                               xlnx,phy-type = <0x3>;
+                               xlnx,phyaddr = <0x1>;
+                               xlnx,rxcsum = <0x0>;
+                               xlnx,rxfifo = <0x8000>;
+                               xlnx,temac-type = <0x0>;
+                               xlnx,txcsum = <0x0>;
+                               xlnx,txfifo = <0x8000>;
+                       } ;
+               } ;
+               Hard_Ethernet_MAC_fifo: xps-ll-fifo@81a00000 {
+                       compatible = "xlnx,xps-ll-fifo-1.01.a";
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupts = < 6 2 >;
+                       reg = < 0x81a00000 0x10000 >;
+                       xlnx,family = "virtex5";
+               } ;
+               IIC_EEPROM: i2c@81600000 {
+                       compatible = "xlnx,xps-iic-2.00.a";
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupts = < 9 2 >;
+                       reg = < 0x81600000 0x10000 >;
+                       xlnx,clk-freq = <0x5f5e100>;
+                       xlnx,family = "virtex5";
+                       xlnx,gpo-width = <0x1>;
+                       xlnx,iic-freq = <0x186a0>;
+                       xlnx,scl-inertial-delay = <0x5>;
+                       xlnx,sda-inertial-delay = <0x5>;
+                       xlnx,ten-bit-adr = <0x0>;
+               } ;
+               LCD_OPTIONAL: gpio@81420000 {
+                       compatible = "xlnx,xps-gpio-1.00.a";
+                       reg = < 0x81420000 0x10000 >;
+                       xlnx,all-inputs = <0x0>;
+                       xlnx,all-inputs-2 = <0x0>;
+                       xlnx,dout-default = <0x0>;
+                       xlnx,dout-default-2 = <0x0>;
+                       xlnx,family = "virtex5";
+                       xlnx,gpio-width = <0xb>;
+                       xlnx,interrupt-present = <0x0>;
+                       xlnx,is-bidir = <0x1>;
+                       xlnx,is-bidir-2 = <0x1>;
+                       xlnx,is-dual = <0x0>;
+                       xlnx,tri-default = <0xffffffff>;
+                       xlnx,tri-default-2 = <0xffffffff>;
+               } ;
+               LEDs_4Bit: gpio@81400000 {
+                       compatible = "xlnx,xps-gpio-1.00.a";
+                       reg = < 0x81400000 0x10000 >;
+                       xlnx,all-inputs = <0x0>;
+                       xlnx,all-inputs-2 = <0x0>;
+                       xlnx,dout-default = <0x0>;
+                       xlnx,dout-default-2 = <0x0>;
+                       xlnx,family = "virtex5";
+                       xlnx,gpio-width = <0x4>;
+                       xlnx,interrupt-present = <0x0>;
+                       xlnx,is-bidir = <0x1>;
+                       xlnx,is-bidir-2 = <0x1>;
+                       xlnx,is-dual = <0x0>;
+                       xlnx,tri-default = <0xffffffff>;
+                       xlnx,tri-default-2 = <0xffffffff>;
+               } ;
+               RS232_Uart_1: serial@83e00000 {
+                       clock-frequency = <100000000>;
+                       compatible = "xlnx,xps-uart16550-2.00.b", "ns16550";
+                       current-speed = <9600>;
+                       device_type = "serial";
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupts = < 11 2 >;
+                       reg = < 0x83e00000 0x10000 >;
+                       reg-offset = <0x1003>;
+                       reg-shift = <2>;
+                       xlnx,family = "virtex5";
+                       xlnx,has-external-rclk = <0x0>;
+                       xlnx,has-external-xin = <0x0>;
+                       xlnx,is-a-16550 = <0x1>;
+               } ;
+               SPI_EEPROM: xps-spi@feff8000 {
+                       compatible = "xlnx,xps-spi-2.00.b";
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupts = < 10 2 >;
+                       reg = < 0xfeff8000 0x80 >;
+                       xlnx,family = "virtex5";
+                       xlnx,fifo-exist = <0x1>;
+                       xlnx,num-ss-bits = <0x1>;
+                       xlnx,num-transfer-bits = <0x8>;
+                       xlnx,sck-ratio = <0x80>;
+               } ;
+               SysACE_CompactFlash: sysace@83600000 {
+                       compatible = "xlnx,xps-sysace-1.00.a";
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupts = < 7 2 >;
+                       reg = < 0x83600000 0x10000 >;
+                       xlnx,family = "virtex5";
+                       xlnx,mem-width = <0x10>;
+               } ;
+               plbv46_pci_0: plbv46-pci@85e00000 {
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       compatible = "xlnx,plbv46-pci-1.03.a";
+                       device_type = "pci";
+                       reg = < 0x85e00000 0x10000 >;
+
+                       /*
+                        * The default ML510 BSB has C_IPIFBAR2PCIBAR_0 set to
+                        * 0 which means that a read/write to the memory mapped
+                        * i/o region (which starts at 0xa0000000) for pci
+                        * bar 0 on the plb side translates to 0.
+                        * It is important to set this value to 0xa0000000, so
+                        * that inbound and outbound pci transactions work
+                        * properly including DMA.
+                        */
+                       ranges = <0x02000000 0 0xa0000000 0xa0000000 0 0x20000000
+                                 0x01000000 0 0x00000000 0xf0000000 0 0x00010000>;
+
+                       #interrupt-cells = <1>;
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
+                       interrupt-map = <
+                               /* IRQ mapping for pci slots and ALI M1533
+                                * periperhals. In total there are 5 interrupt
+                                * lines connected to a xps_intc controller.
+                                * Four of them are PCI IRQ A, B, C, D and
+                                * which correspond to respectively xpx_intc
+                                * 5, 4, 3 and 2.  The fifth interrupt line is
+                                * connected to the south bridge and this one
+                                * uses irq 1 and is active high instead of
+                                * active low.
+                                *
+                                * The M1533 contains various peripherals
+                                * including AC97 audio, a modem, USB, IDE and
+                                * some power management stuff. The modem
+                                * isn't connected on the ML510 and the power
+                                * management core also isn't used.
+                                */
+
+                               /* IDSEL 0x16 / dev=6, bus=0 / PCI slot 3 */
+                               0x3000 0 0 1 &xps_intc_0 3 2
+                               0x3000 0 0 2 &xps_intc_0 2 2
+                               0x3000 0 0 3 &xps_intc_0 5 2
+                               0x3000 0 0 4 &xps_intc_0 4 2
+
+                               /* IDSEL 0x13 / dev=3, bus=1 / PCI slot 4 */
+                               /*
+                               0x11800 0 0 1 &xps_intc_0 5 0 2
+                               0x11800 0 0 2 &xps_intc_0 4 0 2
+                               0x11800 0 0 3 &xps_intc_0 3 0 2
+                               0x11800 0 0 4 &xps_intc_0 2 0 2
+                               */
+
+                               /* According to the datasheet + schematic
+                                * ABCD [FPGA] of slot 5 is mapped to DABC.
+                                * Testing showed that at least A maps to B,
+                                * the mapping of the other pins is a guess
+                                * and for that reason the lines have been
+                                * commented out.
+                                */
+                               /* IDSEL 0x15 / dev=5, bus=0 / PCI slot 5 */
+                               0x2800 0 0 1 &xps_intc_0 4 2
+                               /*
+                               0x2800 0 0 2 &xps_intc_0 3 2
+                               0x2800 0 0 3 &xps_intc_0 2 2
+                               0x2800 0 0 4 &xps_intc_0 5 2
+                               */
+
+                               /* IDSEL 0x12 / dev=2, bus=1 / PCI slot 6 */
+                               /*
+                               0x11000 0 0 1 &xps_intc_0 4 0 2
+                               0x11000 0 0 2 &xps_intc_0 3 0 2
+                               0x11000 0 0 3 &xps_intc_0 2 0 2
+                               0x11000 0 0 4 &xps_intc_0 5 0 2
+                               */
+
+                               /* IDSEL 0x11 / dev=1, bus=0 / AC97 audio */
+                               0x0800 0 0 1 &i8259 7 2
+
+                               /* IDSEL 0x1b / dev=11, bus=0 / IDE */
+                               0x5800 0 0 1 &i8259 14 2
+
+                               /* IDSEL 0x1f / dev 15, bus=0 / 2x USB 1.1 */
+                               0x7800 0 0 1 &i8259 7 2
+                       >;
+                       ali_m1533 {
+                               #size-cells = <1>;
+                               #address-cells = <2>;
+                               i8259: interrupt-controller@20 {
+                                       reg = <1 0x20 2
+                                                       1 0xa0 2
+                                                       1 0x4d0 2>;
+                                       interrupt-controller;
+                                       device_type = "interrupt-controller";
+                                       #address-cells = <0>;
+                                       #interrupt-cells = <2>;
+                                       compatible = "chrp,iic";
+
+                                       /* south bridge irq is active high */
+                                       interrupts = <1 3>;
+                                       interrupt-parent = <&xps_intc_0>;
+                               };
+                       };
+               } ;
+               xps_bram_if_cntlr_1: xps-bram-if-cntlr@ffff0000 {
+                       compatible = "xlnx,xps-bram-if-cntlr-1.00.a";
+                       reg = < 0xffff0000 0x10000 >;
+                       xlnx,family = "virtex5";
+               } ;
+               xps_intc_0: interrupt-controller@81800000 {
+                       #interrupt-cells = <0x2>;
+                       compatible = "xlnx,xps-intc-1.00.a";
+                       interrupt-controller ;
+                       reg = < 0x81800000 0x10000 >;
+                       xlnx,num-intr-inputs = <0xc>;
+               } ;
+               xps_tft_0: tft@86e00000 {
+                       compatible = "xlnx,xps-tft-1.00.a";
+                       reg = < 0x86e00000 0x10000 >;
+                       xlnx,dcr-splb-slave-if = <0x1>;
+                       xlnx,default-tft-base-addr = <0x0>;
+                       xlnx,family = "virtex5";
+                       xlnx,i2c-slave-addr = <0x76>;
+                       xlnx,mplb-awidth = <0x20>;
+                       xlnx,mplb-dwidth = <0x80>;
+                       xlnx,mplb-native-dwidth = <0x40>;
+                       xlnx,mplb-smallest-slave = <0x20>;
+                       xlnx,tft-interface = <0x1>;
+               } ;
+       } ;
+}  ;
index 7e183ff..01bfb56 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Device Tree Source for PIKA Warp
  *
- * Copyright (c) 2008 PIKA Technologies
+ * Copyright (c) 2008-2009 PIKA Technologies
  *   Sean MacLennan <smaclennan@pikatech.com>
  *
  * This file is licensed under the terms of the GNU General Public
 
                                        partition@0 {
                                                label = "splash";
-                                               reg = <0x00000000 0x00020000>;
+                                               reg = <0x00000000 0x00010000>;
                                        };
                                        partition@300000 {
                                                label = "fpga";
                        };
 
                        GPIO0: gpio@ef600b00 {
-                               compatible = "ibm,gpio-440ep";
+                               compatible = "ibm,ppc4xx-gpio";
                                reg = <0xef600b00 0x00000048>;
                                #gpio-cells = <2>;
                                gpio-controller;
                        };
 
                        GPIO1: gpio@ef600c00 {
-                               compatible = "ibm,gpio-440ep";
+                               compatible = "ibm,ppc4xx-gpio";
                                reg = <0xef600c00 0x00000048>;
                                #gpio-cells = <2>;
                                gpio-controller;
+                       };
 
-                               led@31 {
-                                       compatible = "linux,gpio-led";
-                                       linux,name = ":green:";
-                                       gpios = <&GPIO1 31 0>;
-                               };              
-       
-                               led@30 {        
-                                       compatible = "linux,gpio-led";
-                                       linux,name = ":red:";
-                                       gpios = <&GPIO1 30 0>;
+                       power-leds {
+                               compatible = "gpio-leds";
+                               green {
+                                       gpios = <&GPIO1 0 0>;
+                                       default-state = "on";
+                               };
+                               red {
+                                       gpios = <&GPIO1 1 0>;
                                };
                        };
 
index a32ec8d..173a5bb 100644 (file)
@@ -252,7 +252,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index 4e9d85f..e9b8495 100644 (file)
@@ -254,7 +254,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index 9917a09..865725e 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:17:52 2009
+# Linux kernel version: 2.6.30-rc7
+# Wed Jun  3 10:18:16 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -27,6 +27,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -49,10 +50,12 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -67,9 +70,19 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -84,22 +97,24 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -109,10 +124,12 @@ CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -120,6 +137,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -132,7 +150,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -148,11 +165,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 CONFIG_PPC4xx_PCI_EXPRESS=y
 
@@ -170,7 +182,7 @@ CONFIG_KILAUEA=y
 # CONFIG_MAKALU is not set
 # CONFIG_WALNUT is not set
 # CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set
-# CONFIG_PPC40x_SIMPLE is not set
+CONFIG_PPC40x_SIMPLE=y
 CONFIG_405EX=y
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
@@ -228,9 +240,12 @@ CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -252,9 +267,10 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -272,14 +288,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -329,6 +343,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -341,7 +356,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
@@ -445,7 +459,6 @@ CONFIG_MTD_PHYSMAP_OF=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -498,6 +511,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -512,6 +526,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -540,7 +556,6 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -678,6 +693,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -706,6 +722,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -749,6 +770,7 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -760,7 +782,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -776,6 +797,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -790,11 +812,12 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -812,6 +835,9 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -841,9 +867,12 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -851,17 +880,21 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # CONFIG_FUNCTION_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -892,10 +925,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -964,6 +999,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -972,5 +1008,6 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
index 58bf2ac..1467475 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:17:53 2009
+# Linux kernel version: 2.6.30-rc7
+# Wed Jun  3 09:11:02 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -27,6 +27,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -49,10 +50,12 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -67,9 +70,19 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -84,22 +97,24 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -109,10 +124,12 @@ CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -120,6 +137,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -132,7 +150,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -148,11 +165,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 CONFIG_PPC4xx_PCI_EXPRESS=y
 
@@ -170,7 +182,7 @@ CONFIG_PPC4xx_PCI_EXPRESS=y
 CONFIG_MAKALU=y
 # CONFIG_WALNUT is not set
 # CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set
-# CONFIG_PPC40x_SIMPLE is not set
+CONFIG_PPC40x_SIMPLE=y
 CONFIG_405EX=y
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
@@ -228,9 +240,12 @@ CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -252,9 +267,10 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -272,14 +288,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -329,6 +343,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -341,7 +356,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
@@ -445,7 +459,6 @@ CONFIG_MTD_PHYSMAP_OF=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -498,6 +511,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -512,6 +526,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -540,7 +556,6 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -678,6 +693,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -706,6 +722,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -749,6 +770,7 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -760,7 +782,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -776,6 +797,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -790,11 +812,12 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -812,6 +835,9 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -841,9 +867,12 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -851,17 +880,21 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # CONFIG_FUNCTION_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -892,10 +925,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -964,6 +999,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -972,5 +1008,6 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
index f5698f9..416e79a 100644 (file)
@@ -258,7 +258,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index 1d72b0a..f7fd32c 100644 (file)
@@ -258,7 +258,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index 959bdc4..e57f1e4 100644 (file)
@@ -262,7 +262,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index f9a08ee..5e85412 100644 (file)
@@ -262,7 +262,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
@@ -716,7 +716,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multimedia drivers
 #
-CONFIG_DAB=y
+# CONFIG_DAB is not set
 # CONFIG_USB_DABUSB is not set
 
 #
@@ -725,7 +725,7 @@ CONFIG_DAB=y
 # CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
index be64aa6..b652f7d 100644 (file)
@@ -261,7 +261,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index f67250b..c23a4ef 100644 (file)
@@ -256,7 +256,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index 9348c12..b25fad1 100644 (file)
@@ -260,7 +260,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index e665433..ed31d4f 100644 (file)
@@ -265,7 +265,7 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index 70d5c3f..e14e89a 100644 (file)
@@ -262,7 +262,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
index a921fe3..6400aae 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:22:45 2009
+# Linux kernel version: 2.6.29
+# Tue Apr  7 17:04:52 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -57,6 +57,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -74,6 +75,15 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -88,8 +98,12 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
@@ -99,10 +113,8 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -112,10 +124,12 @@ CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -123,6 +137,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -135,7 +150,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -151,11 +165,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 # CONFIG_PPC4xx_PCI_EXPRESS is not set
 
@@ -176,6 +185,7 @@ CONFIG_SEQUOIA=y
 # CONFIG_ARCHES is not set
 # CONFIG_CANYONLANDS is not set
 # CONFIG_GLACIER is not set
+# CONFIG_REDWOOD is not set
 # CONFIG_YOSEMITE is not set
 # CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
 CONFIG_PPC44x_SIMPLE=y
@@ -238,9 +248,13 @@ CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 CONFIG_CMDLINE_BOOL=y
@@ -262,9 +276,10 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -278,18 +293,16 @@ CONFIG_PCI_LEGACY=y
 # Default settings for advanced configuration options are used
 #
 CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_LOWMEM_CAM_NUM=3
 CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
-CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -339,6 +352,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -351,7 +365,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
@@ -448,14 +461,23 @@ CONFIG_MTD_PHYSMAP_OF=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_NAND is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_NDFC=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_NAND_FSL_ELBC is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -483,12 +505,16 @@ CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -515,6 +541,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -529,6 +556,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -568,6 +597,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -577,6 +607,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_NIU is not set
@@ -586,6 +617,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 
 #
@@ -593,7 +625,6 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -734,7 +765,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
 
@@ -750,6 +781,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -778,6 +810,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_FUSE_FS is not set
 
 #
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
 # CD-ROM/DVD Filesystems
 #
 # CONFIG_ISO9660_FS is not set
@@ -842,7 +879,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -858,6 +894,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -873,11 +910,12 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -924,9 +962,12 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -934,17 +975,20 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # CONFIG_FUNCTION_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -952,20 +996,7 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_IRQSTACKS is not set
 # CONFIG_VIRQ_DEBUG is not set
 # CONFIG_BDI_SWITCH is not set
-CONFIG_PPC_EARLY_DEBUG=y
-# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
-# CONFIG_PPC_EARLY_DEBUG_G5 is not set
-# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set
-# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
-# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
-# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
-# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
-# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
-CONFIG_PPC_EARLY_DEBUG_44x=y
-# CONFIG_PPC_EARLY_DEBUG_40x is not set
-# CONFIG_PPC_EARLY_DEBUG_CPM is not set
-CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0xef600300
-CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x1
+# CONFIG_PPC_EARLY_DEBUG is not set
 
 #
 # Security options
@@ -988,10 +1019,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1060,6 +1093,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1068,5 +1102,6 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
index 8267008..ef32cc4 100644 (file)
@@ -260,7 +260,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index 1bf0a63..2518b85 100644 (file)
@@ -263,7 +263,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index 0f5e8ff..990ff19 100644 (file)
 #include <asm/cpm.h>
 #include <sysdev/fsl_soc.h>
 
-#ifdef CONFIG_PPC_85xx
-#define CPM_MAP_ADDR (get_immrbase() + 0x80000)
-#endif
-
 /* CPM Command register.
 */
 #define CPM_CR_RST     ((uint)0x80000000)
index cb448d6..3d9e887 100644 (file)
 #include <linux/scatterlist.h>
 #include <linux/dma-attrs.h>
 #include <asm/io.h>
+#include <asm/swiotlb.h>
 
 #define DMA_ERROR_CODE         (~(dma_addr_t)0x0)
 
+/* Some dma direct funcs must be visible for use in other dma_ops */
+extern void *dma_direct_alloc_coherent(struct device *dev, size_t size,
+                                      dma_addr_t *dma_handle, gfp_t flag);
+extern void dma_direct_free_coherent(struct device *dev, size_t size,
+                                    void *vaddr, dma_addr_t dma_handle);
+
+extern unsigned long get_dma_direct_offset(struct device *dev);
+
 #ifdef CONFIG_NOT_COHERENT_CACHE
 /*
  * DMA-consistent mapping functions for PowerPCs that don't support
@@ -78,6 +87,8 @@ struct dma_mapping_ops {
                                dma_addr_t dma_address, size_t size,
                                enum dma_data_direction direction,
                                struct dma_attrs *attrs);
+       int             (*addr_needs_map)(struct device *dev, dma_addr_t addr,
+                               size_t size);
 #ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS
        void            (*sync_single_range_for_cpu)(struct device *hwdev,
                                dma_addr_t dma_handle, unsigned long offset,
index d6b4a12..014a624 100644 (file)
@@ -256,11 +256,11 @@ do {                                                              \
  * even if we have an executable stack.
  */
 # define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \
-               (exec_stk != EXSTACK_DISABLE_X) : 0)
+               (exec_stk == EXSTACK_DEFAULT) : 0)
 #else 
 # define SET_PERSONALITY(ex) \
   set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
-# define elf_read_implies_exec(ex, exec_stk) (exec_stk != EXSTACK_DISABLE_X)
+# define elf_read_implies_exec(ex, exec_stk) (exec_stk == EXSTACK_DEFAULT)
 #endif /* __powerpc64__ */
 
 extern int dcache_bsize;
diff --git a/arch/powerpc/include/asm/emulated_ops.h b/arch/powerpc/include/asm/emulated_ops.h
new file mode 100644 (file)
index 0000000..9154e85
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  Copyright 2007 Sony 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; version 2 of the License.
+ *
+ *  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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ASM_POWERPC_EMULATED_OPS_H
+#define _ASM_POWERPC_EMULATED_OPS_H
+
+#include <asm/atomic.h>
+
+
+#ifdef CONFIG_PPC_EMULATED_STATS
+
+struct ppc_emulated_entry {
+       const char *name;
+       atomic_t val;
+};
+
+extern struct ppc_emulated {
+#ifdef CONFIG_ALTIVEC
+       struct ppc_emulated_entry altivec;
+#endif
+       struct ppc_emulated_entry dcba;
+       struct ppc_emulated_entry dcbz;
+       struct ppc_emulated_entry fp_pair;
+       struct ppc_emulated_entry isel;
+       struct ppc_emulated_entry mcrxr;
+       struct ppc_emulated_entry mfpvr;
+       struct ppc_emulated_entry multiple;
+       struct ppc_emulated_entry popcntb;
+       struct ppc_emulated_entry spe;
+       struct ppc_emulated_entry string;
+       struct ppc_emulated_entry unaligned;
+#ifdef CONFIG_MATH_EMULATION
+       struct ppc_emulated_entry math;
+#elif defined(CONFIG_8XX_MINIMAL_FPEMU)
+       struct ppc_emulated_entry 8xx;
+#endif
+#ifdef CONFIG_VSX
+       struct ppc_emulated_entry vsx;
+#endif
+} ppc_emulated;
+
+extern u32 ppc_warn_emulated;
+
+extern void ppc_warn_emulated_print(const char *type);
+
+#define PPC_WARN_EMULATED(type)                                                 \
+       do {                                                             \
+               atomic_inc(&ppc_emulated.type.val);                      \
+               if (ppc_warn_emulated)                                   \
+                       ppc_warn_emulated_print(ppc_emulated.type.name); \
+       } while (0)
+
+#else /* !CONFIG_PPC_EMULATED_STATS */
+
+#define PPC_WARN_EMULATED(type)        do { } while (0)
+
+#endif /* !CONFIG_PPC_EMULATED_STATS */
+
+#endif /* _ASM_POWERPC_EMULATED_OPS_H */
index e4094a5..cbd4dfa 100644 (file)
@@ -8,8 +8,6 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#ifdef __ASSEMBLY__
-
 /*
  * Feature section common macros
  *
 /* 64 bits kernel, 32 bits code (ie. vdso32) */
 #define FTR_ENTRY_LONG         .llong
 #define FTR_ENTRY_OFFSET       .long 0xffffffff; .long
+#elif defined(CONFIG_PPC64)
+#define FTR_ENTRY_LONG         .llong
+#define FTR_ENTRY_OFFSET       .llong
 #else
-/* 64 bit kernel 64 bit code, or 32 bit kernel 32 bit code */
-#define FTR_ENTRY_LONG         PPC_LONG
-#define FTR_ENTRY_OFFSET       PPC_LONG
+#define FTR_ENTRY_LONG         .long
+#define FTR_ENTRY_OFFSET       .long
 #endif
 
 #define START_FTR_SECTION(label)       label##1:
@@ -141,6 +141,21 @@ label##5:                                          \
 #define ALT_FW_FTR_SECTION_END_IFCLR(msk)      \
        ALT_FW_FTR_SECTION_END_NESTED_IFCLR(msk, 97)
 
+#ifndef __ASSEMBLY__
+
+#define ASM_MMU_FTR_IF(section_if, section_else, msk, val)     \
+       stringify_in_c(BEGIN_MMU_FTR_SECTION)                   \
+       section_if "; "                                         \
+       stringify_in_c(MMU_FTR_SECTION_ELSE)                    \
+       section_else "; "                                       \
+       stringify_in_c(ALT_MMU_FTR_SECTION_END((msk), (val)))
+
+#define ASM_MMU_FTR_IFSET(section_if, section_else, msk)       \
+       ASM_MMU_FTR_IF(section_if, section_else, (msk), (msk))
+
+#define ASM_MMU_FTR_IFCLR(section_if, section_else, msk)       \
+       ASM_MMU_FTR_IF(section_if, section_else, (msk), 0)
+
 #endif /* __ASSEMBLY__ */
 
 /* LWSYNC feature sections */
index d2a65e8..f78f65c 100644 (file)
 #define _ASM_POWERPC_LPPACA_H
 #ifdef __KERNEL__
 
+/* These definitions relate to hypervisors that only exist when using
+ * a server type processor
+ */
+#ifdef CONFIG_PPC_BOOK3S
+
 //=============================================================================
 //
 //     This control block contains the data that is shared between the
@@ -158,5 +163,6 @@ struct slb_shadow {
 
 extern struct slb_shadow slb_shadow[];
 
+#endif /* CONFIG_PPC_BOOK3S */
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_LPPACA_H */
index 0efdb1d..11d1fc3 100644 (file)
@@ -110,6 +110,10 @@ struct machdep_calls {
        void            (*show_percpuinfo)(struct seq_file *m, int i);
 
        void            (*init_IRQ)(void);
+
+       /* Return an irq, or NO_IRQ to indicate there are none pending.
+        * If for some reason there is no irq, but the interrupt
+        * shouldn't be counted as spurious, return NO_IRQ_IGNORE. */
        unsigned int    (*get_irq)(void);
 #ifdef CONFIG_KEXEC
        void            (*kexec_cpu_down)(int crash_shutdown, int secondary);
index cbf1543..fb57ded 100644 (file)
  */
 #define MMU_FTR_NEED_DTLB_SW_LRU       ASM_CONST(0x00200000)
 
+/* This indicates that the processor uses the ISA 2.06 server tlbie
+ * mnemonics
+ */
+#define MMU_FTR_TLBIE_206              ASM_CONST(0x00400000)
+
 #ifndef __ASSEMBLY__
 #include <asm/cputable.h>
 
@@ -69,10 +74,10 @@ extern void early_init_mmu_secondary(void);
 #endif /* !__ASSEMBLY__ */
 
 
-#ifdef CONFIG_PPC64
+#if defined(CONFIG_PPC_STD_MMU_64)
 /* 64-bit classic hash table MMU */
 #  include <asm/mmu-hash64.h>
-#elif defined(CONFIG_PPC_STD_MMU)
+#elif defined(CONFIG_PPC_STD_MMU_32)
 /* 32-bit classic hash table MMU */
 #  include <asm/mmu-hash32.h>
 #elif defined(CONFIG_40x)
diff --git a/arch/powerpc/include/asm/mpc86xx.h b/arch/powerpc/include/asm/mpc86xx.h
deleted file mode 100644 (file)
index 15f650f..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * MPC86xx definitions
- *
- * Author: Jeff Brown
- *
- * Copyright 2004 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.
- */
-
-#ifdef __KERNEL__
-#ifndef __ASM_POWERPC_MPC86xx_H__
-#define __ASM_POWERPC_MPC86xx_H__
-
-#include <asm/mmu.h>
-
-#ifdef CONFIG_PPC_86xx
-
-#define CPU0_BOOT_RELEASE 0x01000000
-#define CPU1_BOOT_RELEASE 0x02000000
-#define CPU_ALL_RELEASED (CPU0_BOOT_RELEASE | CPU1_BOOT_RELEASE)
-#define MCM_PORT_CONFIG_OFFSET 0x1010
-
-/* Offset from CCSRBAR */
-#define MPC86xx_MCM_OFFSET      (0x00000)
-#define MPC86xx_MCM_SIZE        (0x02000)
-
-#endif /* CONFIG_PPC_86xx */
-#endif /* __ASM_POWERPC_MPC86xx_H__ */
-#endif /* __KERNEL__ */
index 6ef0557..c8a3cbf 100644 (file)
@@ -43,6 +43,7 @@ struct task_struct;
  * processor.
  */
 struct paca_struct {
+#ifdef CONFIG_PPC_BOOK3S
        /*
         * Because hw_cpu_id, unlike other paca fields, is accessed
         * routinely from other CPUs (from the IRQ code), we stick to
@@ -51,7 +52,7 @@ struct paca_struct {
         */
 
        struct lppaca *lppaca_ptr;      /* Pointer to LpPaca for PLIC */
-
+#endif /* CONFIG_PPC_BOOK3S */
        /*
         * MAGIC: the spinlock functions in arch/powerpc/lib/locks.c 
         * load lock_token and paca_index with a single lwz
@@ -64,13 +65,16 @@ struct paca_struct {
        u64 kernel_toc;                 /* Kernel TOC address */
        u64 kernelbase;                 /* Base address of kernel */
        u64 kernel_msr;                 /* MSR while running in kernel */
+#ifdef CONFIG_PPC_STD_MMU_64
        u64 stab_real;                  /* Absolute address of segment table */
        u64 stab_addr;                  /* Virtual address of segment table */
+#endif /* CONFIG_PPC_STD_MMU_64 */
        void *emergency_sp;             /* pointer to emergency stack */
        u64 data_offset;                /* per cpu data offset */
        s16 hw_cpu_id;                  /* Physical processor number */
        u8 cpu_start;                   /* At startup, processor spins until */
                                        /* this becomes non-zero. */
+#ifdef CONFIG_PPC_STD_MMU_64
        struct slb_shadow *slb_shadow_ptr;
 
        /*
@@ -81,11 +85,13 @@ struct paca_struct {
        u64 exmc[10];           /* used for machine checks */
        u64 exslb[10];          /* used for SLB/segment table misses
                                 * on the linear mapping */
-
-       mm_context_t context;
+       /* SLB related definitions */
        u16 vmalloc_sllp;
        u16 slb_cache_ptr;
        u16 slb_cache[SLB_CACHE_ENTRIES];
+#endif /* CONFIG_PPC_STD_MMU_64 */
+
+       mm_context_t context;
 
        /*
         * then miscellaneous read-write fields
index 32cbf16..4940662 100644 (file)
@@ -231,6 +231,11 @@ extern void copy_user_page(void *to, void *from, unsigned long vaddr,
                struct page *p);
 extern int page_is_ram(unsigned long pfn);
 
+#ifdef CONFIG_PPC_SMLPAR
+void arch_free_page(struct page *page, int order);
+#define HAVE_ARCH_FREE_PAGE
+#endif
+
 struct vm_area_struct;
 
 typedef struct page *pgtable_t;
index 84007af..4c61fa0 100644 (file)
@@ -86,17 +86,12 @@ struct pci_controller {
        void *io_base_alloc;
 #endif
        resource_size_t io_base_phys;
-#ifndef CONFIG_PPC64
        resource_size_t pci_io_size;
-#endif
 
        /* Some machines (PReP) have a non 1:1 mapping of
         * the PCI memory space in the CPU bus space
         */
        resource_size_t pci_mem_offset;
-#ifdef CONFIG_PPC64
-       unsigned long pci_io_size;
-#endif
 
        /* Some machines have a special region to forward the ISA
         * "memory" cycles such as VGA memory regions. Left to 0
@@ -140,10 +135,12 @@ struct pci_controller {
        struct resource io_resource;
        struct resource mem_resources[3];
        int global_number;              /* PCI domain number */
+
+       resource_size_t dma_window_base_cur;
+       resource_size_t dma_window_size;
+
 #ifdef CONFIG_PPC64
        unsigned long buid;
-       unsigned long dma_window_base_cur;
-       unsigned long dma_window_size;
 
        void *private_data;
 #endif /* CONFIG_PPC64 */
@@ -185,7 +182,6 @@ extern int early_find_capability(struct pci_controller *hose, int bus,
 extern void setup_indirect_pci(struct pci_controller* hose,
                               resource_size_t cfg_addr,
                               resource_size_t cfg_data, u32 flags);
-extern void setup_grackle(struct pci_controller *hose);
 #else  /* CONFIG_PPC64 */
 
 /*
@@ -221,6 +217,7 @@ struct pci_dn {
 #define PCI_DN(dn)     ((struct pci_dn *) (dn)->data)
 
 extern struct device_node *fetch_dev_dn(struct pci_dev *dev);
+extern void * update_dn_pci_info(struct device_node *dn, void *data);
 
 /* Get a device_node from a pci_dev.  This code must be fast except
  * in the case where the sysdata is incorrect and needs to be fixed
index c40db05..8cd083c 100644 (file)
 #error TASK_SIZE_USER64 exceeds pagetable range
 #endif
 
+#ifdef CONFIG_PPC_STD_MMU_64
 #if TASK_SIZE_USER64 > (1UL << (USER_ESID_BITS + SID_SHIFT))
 #error TASK_SIZE_USER64 exceeds user VSID range
 #endif
+#endif
 
 /*
  * Define the address range of the vmalloc VM area.
@@ -199,8 +201,11 @@ static inline unsigned long pte_update(struct mm_struct *mm,
        if (!huge)
                assert_pte_locked(mm, addr);
 
+#ifdef CONFIG_PPC_STD_MMU_64
        if (old & _PAGE_HASHPTE)
                hpte_need_flush(mm, addr, ptep, old, huge);
+#endif
+
        return old;
 }
 
index 640ccbb..b74f16d 100644 (file)
@@ -25,6 +25,7 @@
 #define PPC_INST_LSWI                  0x7c0004aa
 #define PPC_INST_LSWX                  0x7c00042a
 #define PPC_INST_LWSYNC                        0x7c2004ac
+#define PPC_INST_LXVD2X                        0x7c000698
 #define PPC_INST_MCRXR                 0x7c000400
 #define PPC_INST_MCRXR_MASK            0xfc0007fe
 #define PPC_INST_MFSPR_PVR             0x7c1f42a6
 
 #define PPC_INST_STSWI                 0x7c0005aa
 #define PPC_INST_STSWX                 0x7c00052a
+#define PPC_INST_STXVD2X               0x7c000798
+#define PPC_INST_TLBIE                 0x7c000264
 #define PPC_INST_TLBILX                        0x7c000024
 #define PPC_INST_WAIT                  0x7c00007c
 
 /* macros to insert fields into opcodes */
-#define __PPC_RA(a)    ((a & 0x1f) << 16)
-#define __PPC_RB(b)    ((b & 0x1f) << 11)
-#define __PPC_T_TLB(t) ((t & 0x3) << 21)
-#define __PPC_WC(w)    ((w & 0x3) << 21)
+#define __PPC_RA(a)    (((a) & 0x1f) << 16)
+#define __PPC_RB(b)    (((b) & 0x1f) << 11)
+#define __PPC_RS(s)    (((s) & 0x1f) << 21)
+#define __PPC_XS(s)    ((((s) & 0x1f) << 21) | (((s) & 0x20) >> 5))
+#define __PPC_T_TLB(t) (((t) & 0x3) << 21)
+#define __PPC_WC(w)    (((w) & 0x3) << 21)
 
 /* Deal with instructions that older assemblers aren't aware of */
 #define        PPC_DCBAL(a, b)         stringify_in_c(.long PPC_INST_DCBAL | \
 #define PPC_TLBILX_VA(a, b)    PPC_TLBILX(3, a, b)
 #define PPC_WAIT(w)            stringify_in_c(.long PPC_INST_WAIT | \
                                        __PPC_WC(w))
+#define PPC_TLBIE(lp,a)        stringify_in_c(.long PPC_INST_TLBIE | \
+                                              __PPC_RB(a) | __PPC_RS(lp))
+
+/*
+ * Define what the VSX XX1 form instructions will look like, then add
+ * the 128 bit load store instructions based on that.
+ */
+#define VSX_XX1(s, a, b)       (__PPC_XS(s) | __PPC_RA(a) | __PPC_RB(b))
+#define STXVD2X(s, a, b)       stringify_in_c(.long PPC_INST_STXVD2X | \
+                                              VSX_XX1((s), (a), (b)))
+#define LXVD2X(s, a, b)                stringify_in_c(.long PPC_INST_LXVD2X | \
+                                              VSX_XX1((s), (a), (b)))
 
 #endif /* _ASM_POWERPC_PPC_OPCODE_H */
index 384d90c..f972952 100644 (file)
@@ -76,16 +76,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_PURR);                                 \
                                REST_10GPRS(22, base)
 #endif
 
-/*
- * Define what the VSX XX1 form instructions will look like, then add
- * the 128 bit load store instructions based on that.
- */
-#define VSX_XX1(xs, ra, rb)    (((xs) & 0x1f) << 21 | ((ra) << 16) |  \
-                                ((rb) << 11) | (((xs) >> 5)))
-
-#define STXVD2X(xs, ra, rb)    .long (0x7c000798 | VSX_XX1((xs), (ra), (rb)))
-#define LXVD2X(xs, ra, rb)     .long (0x7c000698 | VSX_XX1((xs), (ra), (rb)))
-
 #define SAVE_2GPRS(n, base)    SAVE_GPR(n, base); SAVE_GPR(n+1, base)
 #define SAVE_4GPRS(n, base)    SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
 #define SAVE_8GPRS(n, base)    SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
index c9c678f..8c34149 100644 (file)
@@ -135,7 +135,9 @@ do {                                                                              \
  * These are defined as per linux/ptrace.h, which see.
  */
 #define arch_has_single_step() (1)
+#define arch_has_block_step()  (!cpu_has_feature(CPU_FTR_601))
 extern void user_enable_single_step(struct task_struct *);
+extern void user_enable_block_step(struct task_struct *);
 extern void user_disable_single_step(struct task_struct *);
 
 #endif /* __ASSEMBLY__ */
@@ -288,4 +290,6 @@ extern void user_disable_single_step(struct task_struct *);
 #define PPC_PTRACE_PEEKUSR_3264  0x91
 #define PPC_PTRACE_POKEUSR_3264  0x90
 
+#define PTRACE_SINGLEBLOCK     0x100   /* resume execution until next branch */
+
 #endif /* _ASM_POWERPC_PTRACE_H */
index 4459d20..157c5ca 100644 (file)
@@ -22,7 +22,7 @@
 #include <asm/cpm.h>
 #include <asm/immap_qe.h>
 
-#define QE_NUM_OF_SNUM 28
+#define QE_NUM_OF_SNUM 256     /* There are 256 serial number in QE */
 #define QE_NUM_OF_BRGS 16
 #define QE_NUM_OF_PORTS        1024
 
@@ -152,6 +152,9 @@ unsigned int qe_get_brg_clk(void);
 int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier);
 int qe_get_snum(void);
 void qe_put_snum(u8 snum);
+unsigned int qe_get_num_of_risc(void);
+unsigned int qe_get_num_of_snums(void);
+
 /* we actually use cpm_muram implementation, define this for convenience */
 #define qe_muram_init cpm_muram_init
 #define qe_muram_alloc cpm_muram_alloc
@@ -231,12 +234,16 @@ struct qe_bd {
 #define QE_ALIGNMENT_OF_PRAM   64
 
 /* RISC allocation */
-enum qe_risc_allocation {
-       QE_RISC_ALLOCATION_RISC1 = 1,   /* RISC 1 */
-       QE_RISC_ALLOCATION_RISC2 = 2,   /* RISC 2 */
-       QE_RISC_ALLOCATION_RISC1_AND_RISC2 = 3  /* Dynamically choose
-                                                  RISC 1 or RISC 2 */
-};
+#define QE_RISC_ALLOCATION_RISC1       0x1  /* RISC 1 */
+#define QE_RISC_ALLOCATION_RISC2       0x2  /* RISC 2 */
+#define QE_RISC_ALLOCATION_RISC3       0x4  /* RISC 3 */
+#define QE_RISC_ALLOCATION_RISC4       0x8  /* RISC 4 */
+#define QE_RISC_ALLOCATION_RISC1_AND_RISC2     (QE_RISC_ALLOCATION_RISC1 | \
+                                                QE_RISC_ALLOCATION_RISC2)
+#define QE_RISC_ALLOCATION_FOUR_RISCS  (QE_RISC_ALLOCATION_RISC1 | \
+                                        QE_RISC_ALLOCATION_RISC2 | \
+                                        QE_RISC_ALLOCATION_RISC3 | \
+                                        QE_RISC_ALLOCATION_RISC4)
 
 /* QE extended filtering Table Lookup Key Size */
 enum qe_fltr_tbl_lookup_key_size {
index fcf7d55..912bf59 100644 (file)
@@ -21,7 +21,7 @@ struct scatterlist {
        unsigned int offset;
        unsigned int length;
 
-       /* For TCE support */
+       /* For TCE or SWIOTLB support */
        dma_addr_t dma_address;
        u32 dma_length;
 };
@@ -34,11 +34,7 @@ struct scatterlist {
  * is 0.
  */
 #define sg_dma_address(sg)     ((sg)->dma_address)
-#ifdef __powerpc64__
 #define sg_dma_len(sg)         ((sg)->dma_length)
-#else
-#define sg_dma_len(sg)         ((sg)->length)
-#endif
 
 #ifdef __powerpc64__
 #define ISA_DMA_THRESHOLD      (~0UL)
diff --git a/arch/powerpc/include/asm/swiotlb.h b/arch/powerpc/include/asm/swiotlb.h
new file mode 100644 (file)
index 0000000..30891d6
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009 Becky Bruce, Freescale Semiconductor
+ *
+ * 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.
+ *
+ */
+
+#ifndef __ASM_SWIOTLB_H
+#define __ASM_SWIOTLB_H
+
+#include <linux/swiotlb.h>
+
+extern struct dma_mapping_ops swiotlb_dma_ops;
+extern struct dma_mapping_ops swiotlb_pci_dma_ops;
+
+int swiotlb_arch_address_needs_mapping(struct device *, dma_addr_t,
+                                      size_t size);
+
+static inline void dma_mark_clean(void *addr, size_t size) {}
+
+extern unsigned int ppc_swiotlb_enable;
+int __init swiotlb_setup_bus_notifier(void);
+
+#endif /* __ASM_SWIOTLB_H */
index 2b2420a..bb8e006 100644 (file)
@@ -211,7 +211,7 @@ extern struct task_struct *_switch(struct thread_struct *prev,
 
 extern unsigned int rtas_data;
 extern int mem_init_done;      /* set on boot once kmalloc can be called */
-extern int init_bootmem_done;  /* set on !NUMA once bootmem is available */
+extern int init_bootmem_done;  /* set once bootmem is available */
 extern phys_addr_t memory_limit;
 extern unsigned long klimit;
 
diff --git a/arch/powerpc/include/asm/xilinx_pci.h b/arch/powerpc/include/asm/xilinx_pci.h
new file mode 100644 (file)
index 0000000..7a8275c
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Xilinx pci external definitions
+ *
+ * Copyright 2009 Roderick Colenbrander
+ * Copyright 2009 Secret Lab Technologies Ltd.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#ifndef INCLUDE_XILINX_PCI
+#define INCLUDE_XILINX_PCI
+
+#ifdef CONFIG_XILINX_PCI
+extern void __init xilinx_pci_init(void);
+#else
+static inline void __init xilinx_pci_init(void) { return; }
+#endif
+
+#endif /* INCLUDE_XILINX_PCI */
index a2c6834..a7def5f 100644 (file)
@@ -36,7 +36,7 @@ obj-$(CONFIG_PPC64)           += setup_64.o sys_ppc32.o \
                                   firmware.o nvram_64.o
 obj64-$(CONFIG_RELOCATABLE)    += reloc_64.o
 obj-$(CONFIG_PPC64)            += vdso64/
-obj-$(CONFIG_ALTIVEC)          += vecemu.o vector.o
+obj-$(CONFIG_ALTIVEC)          += vecemu.o
 obj-$(CONFIG_PPC_970_NAP)      += idle_power4.o
 obj-$(CONFIG_PPC_OF)           += of_device.o of_platform.o prom_parse.o
 obj-$(CONFIG_PPC_CLOCK)                += clock.o
@@ -82,6 +82,7 @@ obj-$(CONFIG_SMP)             += smp.o
 obj-$(CONFIG_KPROBES)          += kprobes.o
 obj-$(CONFIG_PPC_UDBG_16550)   += legacy_serial.o udbg_16550.o
 obj-$(CONFIG_STACKTRACE)       += stacktrace.o
+obj-$(CONFIG_SWIOTLB)          += dma-swiotlb.o
 
 pci64-$(CONFIG_PPC64)          += pci_dn.o isa-bridge.o
 obj-$(CONFIG_PCI)              += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \
@@ -111,6 +112,7 @@ obj-y                               += ppc_save_regs.o
 endif
 
 extra-$(CONFIG_PPC_FPU)                += fpu.o
+extra-$(CONFIG_ALTIVEC)                += vector.o
 extra-$(CONFIG_PPC64)          += entry_64.o
 
 extra-y                                += systbl_chk.i
index 5ffcfaa..a5b632e 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/system.h>
 #include <asm/cache.h>
 #include <asm/cputable.h>
+#include <asm/emulated_ops.h>
 
 struct aligninfo {
        unsigned char len;
@@ -730,8 +731,10 @@ int fix_alignment(struct pt_regs *regs)
        areg = dsisr & 0x1f;            /* register to update */
 
 #ifdef CONFIG_SPE
-       if ((instr >> 26) == 0x4)
+       if ((instr >> 26) == 0x4) {
+               PPC_WARN_EMULATED(spe);
                return emulate_spe(regs, reg, instr);
+       }
 #endif
 
        instr = (dsisr >> 10) & 0x7f;
@@ -783,23 +786,28 @@ int fix_alignment(struct pt_regs *regs)
                        flags |= SPLT;
                        nb = 8;
                }
+               PPC_WARN_EMULATED(vsx);
                return emulate_vsx(addr, reg, areg, regs, flags, nb);
        }
 #endif
        /* A size of 0 indicates an instruction we don't support, with
         * the exception of DCBZ which is handled as a special case here
         */
-       if (instr == DCBZ)
+       if (instr == DCBZ) {
+               PPC_WARN_EMULATED(dcbz);
                return emulate_dcbz(regs, addr);
+       }
        if (unlikely(nb == 0))
                return 0;
 
        /* Load/Store Multiple instructions are handled in their own
         * function
         */
-       if (flags & M)
+       if (flags & M) {
+               PPC_WARN_EMULATED(multiple);
                return emulate_multiple(regs, addr, reg, nb,
                                        flags, instr, swiz);
+       }
 
        /* Verify the address of the operand */
        if (unlikely(user_mode(regs) &&
@@ -816,8 +824,12 @@ int fix_alignment(struct pt_regs *regs)
        }
 
        /* Special case for 16-byte FP loads and stores */
-       if (nb == 16)
+       if (nb == 16) {
+               PPC_WARN_EMULATED(fp_pair);
                return emulate_fp_pair(addr, reg, flags);
+       }
+
+       PPC_WARN_EMULATED(unaligned);
 
        /* If we are loading, get the data from user space, else
         * get it from register values
index e981d1c..561b646 100644 (file)
@@ -122,8 +122,6 @@ int main(void)
        DEFINE(PACAKSAVE, offsetof(struct paca_struct, kstack));
        DEFINE(PACACURRENT, offsetof(struct paca_struct, __current));
        DEFINE(PACASAVEDMSR, offsetof(struct paca_struct, saved_msr));
-       DEFINE(PACASTABREAL, offsetof(struct paca_struct, stab_real));
-       DEFINE(PACASTABVIRT, offsetof(struct paca_struct, stab_addr));
        DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr));
        DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1));
        DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc));
@@ -132,35 +130,30 @@ int main(void)
        DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
        DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled));
        DEFINE(PACAPERFPEND, offsetof(struct paca_struct, perf_counter_pending));
-       DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
-       DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
        DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
-       DEFINE(PACAVMALLOCSLLP, offsetof(struct paca_struct, vmalloc_sllp));
 #ifdef CONFIG_PPC_MM_SLICES
        DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct,
                                            context.low_slices_psize));
        DEFINE(PACAHIGHSLICEPSIZE, offsetof(struct paca_struct,
                                            context.high_slices_psize));
        DEFINE(MMUPSIZEDEFSIZE, sizeof(struct mmu_psize_def));
+#endif /* CONFIG_PPC_MM_SLICES */
+#ifdef CONFIG_PPC_STD_MMU_64
+       DEFINE(PACASTABREAL, offsetof(struct paca_struct, stab_real));
+       DEFINE(PACASTABVIRT, offsetof(struct paca_struct, stab_addr));
+       DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
+       DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
+       DEFINE(PACAVMALLOCSLLP, offsetof(struct paca_struct, vmalloc_sllp));
+#ifdef CONFIG_PPC_MM_SLICES
        DEFINE(MMUPSIZESLLP, offsetof(struct mmu_psize_def, sllp));
 #else
        DEFINE(PACACONTEXTSLLP, offsetof(struct paca_struct, context.sllp));
-
 #endif /* CONFIG_PPC_MM_SLICES */
        DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
        DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
        DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb));
-       DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
        DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr));
-       DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
-       DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
-       DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr));
-       DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
-       DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
        DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr));
-       DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset));
-       DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
-
        DEFINE(SLBSHADOW_STACKVSID,
               offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].vsid));
        DEFINE(SLBSHADOW_STACKESID,
@@ -170,6 +163,15 @@ int main(void)
        DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
        DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
        DEFINE(SLBSHADOW_SAVEAREA, offsetof(struct slb_shadow, save_area));
+#endif /* CONFIG_PPC_STD_MMU_64 */
+       DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
+       DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
+       DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
+       DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr));
+       DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
+       DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
+       DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset));
+       DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
 #endif /* CONFIG_PPC64 */
 
        /* RTAS */
index 3e33fb9..4a24a2f 100644 (file)
@@ -427,7 +427,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .cpu_name               = "POWER7 (architected)",
                .cpu_features           = CPU_FTRS_POWER7,
                .cpu_user_features      = COMMON_USER_POWER7,
-               .mmu_features           = MMU_FTR_HPTE_TABLE,
+               .mmu_features           = MMU_FTR_HPTE_TABLE |
+                       MMU_FTR_TLBIE_206,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .machine_check          = machine_check_generic,
@@ -441,7 +442,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .cpu_name               = "POWER7 (raw)",
                .cpu_features           = CPU_FTRS_POWER7,
                .cpu_user_features      = COMMON_USER_POWER7,
-               .mmu_features           = MMU_FTR_HPTE_TABLE,
+               .mmu_features           = MMU_FTR_HPTE_TABLE |
+                       MMU_FTR_TLBIE_206,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 6,
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c
new file mode 100644 (file)
index 0000000..68ccf11
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Contains routines needed to support swiotlb for ppc.
+ *
+ * Copyright (C) 2009 Becky Bruce, Freescale Semiconductor
+ *
+ * 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/dma-mapping.h>
+#include <linux/pfn.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+
+#include <asm/machdep.h>
+#include <asm/swiotlb.h>
+#include <asm/dma.h>
+#include <asm/abs_addr.h>
+
+int swiotlb __read_mostly;
+unsigned int ppc_swiotlb_enable;
+
+void *swiotlb_bus_to_virt(struct device *hwdev, dma_addr_t addr)
+{
+       unsigned long pfn = PFN_DOWN(swiotlb_bus_to_phys(hwdev, addr));
+       void *pageaddr = page_address(pfn_to_page(pfn));
+
+       if (pageaddr != NULL)
+               return pageaddr + (addr % PAGE_SIZE);
+       return NULL;
+}
+
+dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr)
+{
+       return paddr + get_dma_direct_offset(hwdev);
+}
+
+phys_addr_t swiotlb_bus_to_phys(struct device *hwdev, dma_addr_t baddr)
+
+{
+       return baddr - get_dma_direct_offset(hwdev);
+}
+
+/*
+ * Determine if an address needs bounce buffering via swiotlb.
+ * Going forward I expect the swiotlb code to generalize on using
+ * a dma_ops->addr_needs_map, and this function will move from here to the
+ * generic swiotlb code.
+ */
+int
+swiotlb_arch_address_needs_mapping(struct device *hwdev, dma_addr_t addr,
+                                  size_t size)
+{
+       struct dma_mapping_ops *dma_ops = get_dma_ops(hwdev);
+
+       BUG_ON(!dma_ops);
+       return dma_ops->addr_needs_map(hwdev, addr, size);
+}
+
+/*
+ * Determine if an address is reachable by a pci device, or if we must bounce.
+ */
+static int
+swiotlb_pci_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size)
+{
+       u64 mask = dma_get_mask(hwdev);
+       dma_addr_t max;
+       struct pci_controller *hose;
+       struct pci_dev *pdev = to_pci_dev(hwdev);
+
+       hose = pci_bus_to_host(pdev->bus);
+       max = hose->dma_window_base_cur + hose->dma_window_size;
+
+       /* check that we're within mapped pci window space */
+       if ((addr + size > max) | (addr < hose->dma_window_base_cur))
+               return 1;
+
+       return !is_buffer_dma_capable(mask, addr, size);
+}
+
+static int
+swiotlb_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size)
+{
+       return !is_buffer_dma_capable(dma_get_mask(hwdev), addr, size);
+}
+
+
+/*
+ * At the moment, all platforms that use this code only require
+ * swiotlb to be used if we're operating on HIGHMEM.  Since
+ * we don't ever call anything other than map_sg, unmap_sg,
+ * map_page, and unmap_page on highmem, use normal dma_ops
+ * for everything else.
+ */
+struct dma_mapping_ops swiotlb_dma_ops = {
+       .alloc_coherent = dma_direct_alloc_coherent,
+       .free_coherent = dma_direct_free_coherent,
+       .map_sg = swiotlb_map_sg_attrs,
+       .unmap_sg = swiotlb_unmap_sg_attrs,
+       .dma_supported = swiotlb_dma_supported,
+       .map_page = swiotlb_map_page,
+       .unmap_page = swiotlb_unmap_page,
+       .addr_needs_map = swiotlb_addr_needs_map,
+       .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
+       .sync_single_range_for_device = swiotlb_sync_single_range_for_device,
+       .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+       .sync_sg_for_device = swiotlb_sync_sg_for_device
+};
+
+struct dma_mapping_ops swiotlb_pci_dma_ops = {
+       .alloc_coherent = dma_direct_alloc_coherent,
+       .free_coherent = dma_direct_free_coherent,
+       .map_sg = swiotlb_map_sg_attrs,
+       .unmap_sg = swiotlb_unmap_sg_attrs,
+       .dma_supported = swiotlb_dma_supported,
+       .map_page = swiotlb_map_page,
+       .unmap_page = swiotlb_unmap_page,
+       .addr_needs_map = swiotlb_pci_addr_needs_map,
+       .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
+       .sync_single_range_for_device = swiotlb_sync_single_range_for_device,
+       .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+       .sync_sg_for_device = swiotlb_sync_sg_for_device
+};
+
+static int ppc_swiotlb_bus_notify(struct notifier_block *nb,
+                                 unsigned long action, void *data)
+{
+       struct device *dev = data;
+
+       /* We are only intereted in device addition */
+       if (action != BUS_NOTIFY_ADD_DEVICE)
+               return 0;
+
+       /* May need to bounce if the device can't address all of DRAM */
+       if (dma_get_mask(dev) < lmb_end_of_DRAM())
+               set_dma_ops(dev, &swiotlb_dma_ops);
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block ppc_swiotlb_plat_bus_notifier = {
+       .notifier_call = ppc_swiotlb_bus_notify,
+       .priority = 0,
+};
+
+static struct notifier_block ppc_swiotlb_of_bus_notifier = {
+       .notifier_call = ppc_swiotlb_bus_notify,
+       .priority = 0,
+};
+
+int __init swiotlb_setup_bus_notifier(void)
+{
+       bus_register_notifier(&platform_bus_type,
+                             &ppc_swiotlb_plat_bus_notifier);
+       bus_register_notifier(&of_platform_bus_type,
+                             &ppc_swiotlb_of_bus_notifier);
+
+       return 0;
+}
index 6b02793..20a60d6 100644 (file)
@@ -19,7 +19,7 @@
  * default the offset is PCI_DRAM_OFFSET.
  */
 
-static unsigned long get_dma_direct_offset(struct device *dev)
+unsigned long get_dma_direct_offset(struct device *dev)
 {
        if (dev)
                return (unsigned long)dev->archdata.dma_data;
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
new file mode 100644 (file)
index 0000000..eb89811
--- /dev/null
@@ -0,0 +1,978 @@
+/*
+ * This file contains the 64-bit "server" PowerPC variant
+ * of the low level exception handling including exception
+ * vectors, exception return, part of the slb and stab
+ * handling and other fixed offset specific things.
+ *
+ * This file is meant to be #included from head_64.S due to
+ * position dependant assembly.
+ *
+ * Most of this originates from head_64.S and thus has the same
+ * copyright history.
+ *
+ */
+
+/*
+ * We layout physical memory as follows:
+ * 0x0000 - 0x00ff : Secondary processor spin code
+ * 0x0100 - 0x2fff : pSeries Interrupt prologs
+ * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt prologs
+ * 0x6000 - 0x6fff : Initial (CPU0) segment table
+ * 0x7000 - 0x7fff : FWNMI data area
+ * 0x8000 -        : Early init and support code
+ */
+
+
+/*
+ *   SPRG Usage
+ *
+ *   Register  Definition
+ *
+ *   SPRG0     reserved for hypervisor
+ *   SPRG1     temp - used to save gpr
+ *   SPRG2     temp - used to save gpr
+ *   SPRG3     virt addr of paca
+ */
+
+/*
+ * This is the start of the interrupt handlers for pSeries
+ * This code runs with relocation off.
+ * Code from here to __end_interrupts gets copied down to real
+ * address 0x100 when we are running a relocatable kernel.
+ * Therefore any relative branches in this section must only
+ * branch to labels in this section.
+ */
+       . = 0x100
+       .globl __start_interrupts
+__start_interrupts:
+
+       STD_EXCEPTION_PSERIES(0x100, system_reset)
+
+       . = 0x200
+_machine_check_pSeries:
+       HMT_MEDIUM
+       mtspr   SPRN_SPRG1,r13          /* save r13 */
+       EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+
+       . = 0x300
+       .globl data_access_pSeries
+data_access_pSeries:
+       HMT_MEDIUM
+       mtspr   SPRN_SPRG1,r13
+BEGIN_FTR_SECTION
+       mtspr   SPRN_SPRG2,r12
+       mfspr   r13,SPRN_DAR
+       mfspr   r12,SPRN_DSISR
+       srdi    r13,r13,60
+       rlwimi  r13,r12,16,0x20
+       mfcr    r12
+       cmpwi   r13,0x2c
+       beq     do_stab_bolted_pSeries
+       mtcrf   0x80,r12
+       mfspr   r12,SPRN_SPRG2
+END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
+
+       . = 0x380
+       .globl data_access_slb_pSeries
+data_access_slb_pSeries:
+       HMT_MEDIUM
+       mtspr   SPRN_SPRG1,r13
+       mfspr   r13,SPRN_SPRG3          /* get paca address into r13 */
+       std     r3,PACA_EXSLB+EX_R3(r13)
+       mfspr   r3,SPRN_DAR
+       std     r9,PACA_EXSLB+EX_R9(r13)        /* save r9 - r12 */
+       mfcr    r9
+#ifdef __DISABLED__
+       /* Keep that around for when we re-implement dynamic VSIDs */
+       cmpdi   r3,0
+       bge     slb_miss_user_pseries
+#endif /* __DISABLED__ */
+       std     r10,PACA_EXSLB+EX_R10(r13)
+       std     r11,PACA_EXSLB+EX_R11(r13)
+       std     r12,PACA_EXSLB+EX_R12(r13)
+       mfspr   r10,SPRN_SPRG1
+       std     r10,PACA_EXSLB+EX_R13(r13)
+       mfspr   r12,SPRN_SRR1           /* and SRR1 */
+#ifndef CONFIG_RELOCATABLE
+       b       .slb_miss_realmode
+#else
+       /*
+        * We can't just use a direct branch to .slb_miss_realmode
+        * because the distance from here to there depends on where
+        * the kernel ends up being put.
+        */
+       mfctr   r11
+       ld      r10,PACAKBASE(r13)
+       LOAD_HANDLER(r10, .slb_miss_realmode)
+       mtctr   r10
+       bctr
+#endif
+
+       STD_EXCEPTION_PSERIES(0x400, instruction_access)
+
+       . = 0x480
+       .globl instruction_access_slb_pSeries
+instruction_access_slb_pSeries:
+       HMT_MEDIUM
+       mtspr   SPRN_SPRG1,r13
+       mfspr   r13,SPRN_SPRG3          /* get paca address into r13 */
+       std     r3,PACA_EXSLB+EX_R3(r13)
+       mfspr   r3,SPRN_SRR0            /* SRR0 is faulting address */
+       std     r9,PACA_EXSLB+EX_R9(r13)        /* save r9 - r12 */
+       mfcr    r9
+#ifdef __DISABLED__
+       /* Keep that around for when we re-implement dynamic VSIDs */
+       cmpdi   r3,0
+       bge     slb_miss_user_pseries
+#endif /* __DISABLED__ */
+       std     r10,PACA_EXSLB+EX_R10(r13)
+       std     r11,PACA_EXSLB+EX_R11(r13)
+       std     r12,PACA_EXSLB+EX_R12(r13)
+       mfspr   r10,SPRN_SPRG1
+       std     r10,PACA_EXSLB+EX_R13(r13)
+       mfspr   r12,SPRN_SRR1           /* and SRR1 */
+#ifndef CONFIG_RELOCATABLE
+       b       .slb_miss_realmode
+#else
+       mfctr   r11
+       ld      r10,PACAKBASE(r13)
+       LOAD_HANDLER(r10, .slb_miss_realmode)
+       mtctr   r10
+       bctr
+#endif
+
+       MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt)
+       STD_EXCEPTION_PSERIES(0x600, alignment)
+       STD_EXCEPTION_PSERIES(0x700, program_check)
+       STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
+       MASKABLE_EXCEPTION_PSERIES(0x900, decrementer)
+       STD_EXCEPTION_PSERIES(0xa00, trap_0a)
+       STD_EXCEPTION_PSERIES(0xb00, trap_0b)
+
+       . = 0xc00
+       .globl  system_call_pSeries
+system_call_pSeries:
+       HMT_MEDIUM
+BEGIN_FTR_SECTION
+       cmpdi   r0,0x1ebe
+       beq-    1f
+END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
+       mr      r9,r13
+       mfspr   r13,SPRN_SPRG3
+       mfspr   r11,SPRN_SRR0
+       ld      r12,PACAKBASE(r13)
+       ld      r10,PACAKMSR(r13)
+       LOAD_HANDLER(r12, system_call_entry)
+       mtspr   SPRN_SRR0,r12
+       mfspr   r12,SPRN_SRR1
+       mtspr   SPRN_SRR1,r10
+       rfid
+       b       .       /* prevent speculative execution */
+
+/* Fast LE/BE switch system call */
+1:     mfspr   r12,SPRN_SRR1
+       xori    r12,r12,MSR_LE
+       mtspr   SPRN_SRR1,r12
+       rfid            /* return to userspace */
+       b       .
+
+       STD_EXCEPTION_PSERIES(0xd00, single_step)
+       STD_EXCEPTION_PSERIES(0xe00, trap_0e)
+
+       /* We need to deal with the Altivec unavailable exception
+        * here which is at 0xf20, thus in the middle of the
+        * prolog code of the PerformanceMonitor one. A little
+        * trickery is thus necessary
+        */
+       . = 0xf00
+       b       performance_monitor_pSeries
+
+       . = 0xf20
+       b       altivec_unavailable_pSeries
+
+       . = 0xf40
+       b       vsx_unavailable_pSeries
+
+#ifdef CONFIG_CBE_RAS
+       HSTD_EXCEPTION_PSERIES(0x1200, cbe_system_error)
+#endif /* CONFIG_CBE_RAS */
+       STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
+#ifdef CONFIG_CBE_RAS
+       HSTD_EXCEPTION_PSERIES(0x1600, cbe_maintenance)
+#endif /* CONFIG_CBE_RAS */
+       STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
+#ifdef CONFIG_CBE_RAS
+       HSTD_EXCEPTION_PSERIES(0x1800, cbe_thermal)
+#endif /* CONFIG_CBE_RAS */
+
+       . = 0x3000
+
+/*** pSeries interrupt support ***/
+
+       /* moved from 0xf00 */
+       STD_EXCEPTION_PSERIES(., performance_monitor)
+       STD_EXCEPTION_PSERIES(., altivec_unavailable)
+       STD_EXCEPTION_PSERIES(., vsx_unavailable)
+
+/*
+ * An interrupt came in while soft-disabled; clear EE in SRR1,
+ * clear paca->hard_enabled and return.
+ */
+masked_interrupt:
+       stb     r10,PACAHARDIRQEN(r13)
+       mtcrf   0x80,r9
+       ld      r9,PACA_EXGEN+EX_R9(r13)
+       mfspr   r10,SPRN_SRR1
+       rldicl  r10,r10,48,1            /* clear MSR_EE */
+       rotldi  r10,r10,16
+       mtspr   SPRN_SRR1,r10
+       ld      r10,PACA_EXGEN+EX_R10(r13)
+       mfspr   r13,SPRN_SPRG1
+       rfid
+       b       .
+
+       .align  7
+do_stab_bolted_pSeries:
+       mtcrf   0x80,r12
+       mfspr   r12,SPRN_SPRG2
+       EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
+
+#ifdef CONFIG_PPC_PSERIES
+/*
+ * Vectors for the FWNMI option.  Share common code.
+ */
+       .globl system_reset_fwnmi
+      .align 7
+system_reset_fwnmi:
+       HMT_MEDIUM
+       mtspr   SPRN_SPRG1,r13          /* save r13 */
+       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
+
+       .globl machine_check_fwnmi
+      .align 7
+machine_check_fwnmi:
+       HMT_MEDIUM
+       mtspr   SPRN_SPRG1,r13          /* save r13 */
+       EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+
+#endif /* CONFIG_PPC_PSERIES */
+
+#ifdef __DISABLED__
+/*
+ * This is used for when the SLB miss handler has to go virtual,
+ * which doesn't happen for now anymore but will once we re-implement
+ * dynamic VSIDs for shared page tables
+ */
+slb_miss_user_pseries:
+       std     r10,PACA_EXGEN+EX_R10(r13)
+       std     r11,PACA_EXGEN+EX_R11(r13)
+       std     r12,PACA_EXGEN+EX_R12(r13)
+       mfspr   r10,SPRG1
+       ld      r11,PACA_EXSLB+EX_R9(r13)
+       ld      r12,PACA_EXSLB+EX_R3(r13)
+       std     r10,PACA_EXGEN+EX_R13(r13)
+       std     r11,PACA_EXGEN+EX_R9(r13)
+       std     r12,PACA_EXGEN+EX_R3(r13)
+       clrrdi  r12,r13,32
+       mfmsr   r10
+       mfspr   r11,SRR0                        /* save SRR0 */
+       ori     r12,r12,slb_miss_user_common@l  /* virt addr of handler */
+       ori     r10,r10,MSR_IR|MSR_DR|MSR_RI
+       mtspr   SRR0,r12
+       mfspr   r12,SRR1                        /* and SRR1 */
+       mtspr   SRR1,r10
+       rfid
+       b       .                               /* prevent spec. execution */
+#endif /* __DISABLED__ */
+
+       .align  7
+       .globl  __end_interrupts
+__end_interrupts:
+
+/*
+ * Code from here down to __end_handlers is invoked from the
+ * exception prologs above.  Because the prologs assemble the
+ * addresses of these handlers using the LOAD_HANDLER macro,
+ * which uses an addi instruction, these handlers must be in
+ * the first 32k of the kernel image.
+ */
+
+/*** Common interrupt handlers ***/
+
+       STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception)
+
+       /*
+        * Machine check is different because we use a different
+        * save area: PACA_EXMC instead of PACA_EXGEN.
+        */
+       .align  7
+       .globl machine_check_common
+machine_check_common:
+       EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
+       FINISH_NAP
+       DISABLE_INTS
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .machine_check_exception
+       b       .ret_from_except
+
+       STD_EXCEPTION_COMMON_LITE(0x900, decrementer, .timer_interrupt)
+       STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)
+       STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
+       STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
+       STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
+       STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception)
+       STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
+#ifdef CONFIG_ALTIVEC
+       STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
+#else
+       STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception)
+#endif
+#ifdef CONFIG_CBE_RAS
+       STD_EXCEPTION_COMMON(0x1200, cbe_system_error, .cbe_system_error_exception)
+       STD_EXCEPTION_COMMON(0x1600, cbe_maintenance, .cbe_maintenance_exception)
+       STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception)
+#endif /* CONFIG_CBE_RAS */
+
+       .align  7
+system_call_entry:
+       b       system_call_common
+
+/*
+ * Here we have detected that the kernel stack pointer is bad.
+ * R9 contains the saved CR, r13 points to the paca,
+ * r10 contains the (bad) kernel stack pointer,
+ * r11 and r12 contain the saved SRR0 and SRR1.
+ * We switch to using an emergency stack, save the registers there,
+ * and call kernel_bad_stack(), which panics.
+ */
+bad_stack:
+       ld      r1,PACAEMERGSP(r13)
+       subi    r1,r1,64+INT_FRAME_SIZE
+       std     r9,_CCR(r1)
+       std     r10,GPR1(r1)
+       std     r11,_NIP(r1)
+       std     r12,_MSR(r1)
+       mfspr   r11,SPRN_DAR
+       mfspr   r12,SPRN_DSISR
+       std     r11,_DAR(r1)
+       std     r12,_DSISR(r1)
+       mflr    r10
+       mfctr   r11
+       mfxer   r12
+       std     r10,_LINK(r1)
+       std     r11,_CTR(r1)
+       std     r12,_XER(r1)
+       SAVE_GPR(0,r1)
+       SAVE_GPR(2,r1)
+       SAVE_4GPRS(3,r1)
+       SAVE_2GPRS(7,r1)
+       SAVE_10GPRS(12,r1)
+       SAVE_10GPRS(22,r1)
+       lhz     r12,PACA_TRAP_SAVE(r13)
+       std     r12,_TRAP(r1)
+       addi    r11,r1,INT_FRAME_SIZE
+       std     r11,0(r1)
+       li      r12,0
+       std     r12,0(r11)
+       ld      r2,PACATOC(r13)
+1:     addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .kernel_bad_stack
+       b       1b
+
+/*
+ * Here r13 points to the paca, r9 contains the saved CR,
+ * SRR0 and SRR1 are saved in r11 and r12,
+ * r9 - r13 are saved in paca->exgen.
+ */
+       .align  7
+       .globl data_access_common
+data_access_common:
+       mfspr   r10,SPRN_DAR
+       std     r10,PACA_EXGEN+EX_DAR(r13)
+       mfspr   r10,SPRN_DSISR
+       stw     r10,PACA_EXGEN+EX_DSISR(r13)
+       EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
+       ld      r3,PACA_EXGEN+EX_DAR(r13)
+       lwz     r4,PACA_EXGEN+EX_DSISR(r13)
+       li      r5,0x300
+       b       .do_hash_page           /* Try to handle as hpte fault */
+
+       .align  7
+       .globl instruction_access_common
+instruction_access_common:
+       EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
+       ld      r3,_NIP(r1)
+       andis.  r4,r12,0x5820
+       li      r5,0x400
+       b       .do_hash_page           /* Try to handle as hpte fault */
+
+/*
+ * Here is the common SLB miss user that is used when going to virtual
+ * mode for SLB misses, that is currently not used
+ */
+#ifdef __DISABLED__
+       .align  7
+       .globl  slb_miss_user_common
+slb_miss_user_common:
+       mflr    r10
+       std     r3,PACA_EXGEN+EX_DAR(r13)
+       stw     r9,PACA_EXGEN+EX_CCR(r13)
+       std     r10,PACA_EXGEN+EX_LR(r13)
+       std     r11,PACA_EXGEN+EX_SRR0(r13)
+       bl      .slb_allocate_user
+
+       ld      r10,PACA_EXGEN+EX_LR(r13)
+       ld      r3,PACA_EXGEN+EX_R3(r13)
+       lwz     r9,PACA_EXGEN+EX_CCR(r13)
+       ld      r11,PACA_EXGEN+EX_SRR0(r13)
+       mtlr    r10
+       beq-    slb_miss_fault
+
+       andi.   r10,r12,MSR_RI          /* check for unrecoverable exception */
+       beq-    unrecov_user_slb
+       mfmsr   r10
+
+.machine push
+.machine "power4"
+       mtcrf   0x80,r9
+.machine pop
+
+       clrrdi  r10,r10,2               /* clear RI before setting SRR0/1 */
+       mtmsrd  r10,1
+
+       mtspr   SRR0,r11
+       mtspr   SRR1,r12
+
+       ld      r9,PACA_EXGEN+EX_R9(r13)
+       ld      r10,PACA_EXGEN+EX_R10(r13)
+       ld      r11,PACA_EXGEN+EX_R11(r13)
+       ld      r12,PACA_EXGEN+EX_R12(r13)
+       ld      r13,PACA_EXGEN+EX_R13(r13)
+       rfid
+       b       .
+
+slb_miss_fault:
+       EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
+       ld      r4,PACA_EXGEN+EX_DAR(r13)
+       li      r5,0
+       std     r4,_DAR(r1)
+       std     r5,_DSISR(r1)
+       b       handle_page_fault
+
+unrecov_user_slb:
+       EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
+       DISABLE_INTS
+       bl      .save_nvgprs
+1:     addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .unrecoverable_exception
+       b       1b
+
+#endif /* __DISABLED__ */
+
+
+/*
+ * r13 points to the PACA, r9 contains the saved CR,
+ * r12 contain the saved SRR1, SRR0 is still ready for return
+ * r3 has the faulting address
+ * r9 - r13 are saved in paca->exslb.
+ * r3 is saved in paca->slb_r3
+ * We assume we aren't going to take any exceptions during this procedure.
+ */
+_GLOBAL(slb_miss_realmode)
+       mflr    r10
+#ifdef CONFIG_RELOCATABLE
+       mtctr   r11
+#endif
+
+       stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
+       std     r10,PACA_EXSLB+EX_LR(r13)       /* save LR */
+
+       bl      .slb_allocate_realmode
+
+       /* All done -- return from exception. */
+
+       ld      r10,PACA_EXSLB+EX_LR(r13)
+       ld      r3,PACA_EXSLB+EX_R3(r13)
+       lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
+#ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
+       ld      r11,PACALPPACAPTR(r13)
+       ld      r11,LPPACASRR0(r11)             /* get SRR0 value */
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
+#endif /* CONFIG_PPC_ISERIES */
+
+       mtlr    r10
+
+       andi.   r10,r12,MSR_RI  /* check for unrecoverable exception */
+       beq-    2f
+
+.machine       push
+.machine       "power4"
+       mtcrf   0x80,r9
+       mtcrf   0x01,r9         /* slb_allocate uses cr0 and cr7 */
+.machine       pop
+
+#ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
+       mtspr   SPRN_SRR0,r11
+       mtspr   SPRN_SRR1,r12
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
+#endif /* CONFIG_PPC_ISERIES */
+       ld      r9,PACA_EXSLB+EX_R9(r13)
+       ld      r10,PACA_EXSLB+EX_R10(r13)
+       ld      r11,PACA_EXSLB+EX_R11(r13)
+       ld      r12,PACA_EXSLB+EX_R12(r13)
+       ld      r13,PACA_EXSLB+EX_R13(r13)
+       rfid
+       b       .       /* prevent speculative execution */
+
+2:
+#ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
+       b       unrecov_slb
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
+#endif /* CONFIG_PPC_ISERIES */
+       mfspr   r11,SPRN_SRR0
+       ld      r10,PACAKBASE(r13)
+       LOAD_HANDLER(r10,unrecov_slb)
+       mtspr   SPRN_SRR0,r10
+       ld      r10,PACAKMSR(r13)
+       mtspr   SPRN_SRR1,r10
+       rfid
+       b       .
+
+unrecov_slb:
+       EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
+       DISABLE_INTS
+       bl      .save_nvgprs
+1:     addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .unrecoverable_exception
+       b       1b
+
+       .align  7
+       .globl hardware_interrupt_common
+       .globl hardware_interrupt_entry
+hardware_interrupt_common:
+       EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
+       FINISH_NAP
+hardware_interrupt_entry:
+       DISABLE_INTS
+BEGIN_FTR_SECTION
+       bl      .ppc64_runlatch_on
+END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .do_IRQ
+       b       .ret_from_except_lite
+
+#ifdef CONFIG_PPC_970_NAP
+power4_fixup_nap:
+       andc    r9,r9,r10
+       std     r9,TI_LOCAL_FLAGS(r11)
+       ld      r10,_LINK(r1)           /* make idle task do the */
+       std     r10,_NIP(r1)            /* equivalent of a blr */
+       blr
+#endif
+
+       .align  7
+       .globl alignment_common
+alignment_common:
+       mfspr   r10,SPRN_DAR
+       std     r10,PACA_EXGEN+EX_DAR(r13)
+       mfspr   r10,SPRN_DSISR
+       stw     r10,PACA_EXGEN+EX_DSISR(r13)
+       EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
+       ld      r3,PACA_EXGEN+EX_DAR(r13)
+       lwz     r4,PACA_EXGEN+EX_DSISR(r13)
+       std     r3,_DAR(r1)
+       std     r4,_DSISR(r1)
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       ENABLE_INTS
+       bl      .alignment_exception
+       b       .ret_from_except
+
+       .align  7
+       .globl program_check_common
+program_check_common:
+       EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       ENABLE_INTS
+       bl      .program_check_exception
+       b       .ret_from_except
+
+       .align  7
+       .globl fp_unavailable_common
+fp_unavailable_common:
+       EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
+       bne     1f                      /* if from user, just load it up */
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       ENABLE_INTS
+       bl      .kernel_fp_unavailable_exception
+       BUG_OPCODE
+1:     bl      .load_up_fpu
+       b       fast_exception_return
+
+       .align  7
+       .globl altivec_unavailable_common
+altivec_unavailable_common:
+       EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
+#ifdef CONFIG_ALTIVEC
+BEGIN_FTR_SECTION
+       beq     1f
+       bl      .load_up_altivec
+       b       fast_exception_return
+1:
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+#endif
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       ENABLE_INTS
+       bl      .altivec_unavailable_exception
+       b       .ret_from_except
+
+       .align  7
+       .globl vsx_unavailable_common
+vsx_unavailable_common:
+       EXCEPTION_PROLOG_COMMON(0xf40, PACA_EXGEN)
+#ifdef CONFIG_VSX
+BEGIN_FTR_SECTION
+       bne     .load_up_vsx
+1:
+END_FTR_SECTION_IFSET(CPU_FTR_VSX)
+#endif
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       ENABLE_INTS
+       bl      .vsx_unavailable_exception
+       b       .ret_from_except
+
+       .align  7
+       .globl  __end_handlers
+__end_handlers:
+
+/*
+ * Return from an exception with minimal checks.
+ * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
+ * If interrupts have been enabled, or anything has been
+ * done that might have changed the scheduling status of
+ * any task or sent any task a signal, you should use
+ * ret_from_except or ret_from_except_lite instead of this.
+ */
+fast_exc_return_irq:                   /* restores irq state too */
+       ld      r3,SOFTE(r1)
+       TRACE_AND_RESTORE_IRQ(r3);
+       ld      r12,_MSR(r1)
+       rldicl  r4,r12,49,63            /* get MSR_EE to LSB */
+       stb     r4,PACAHARDIRQEN(r13)   /* restore paca->hard_enabled */
+       b       1f
+
+       .globl  fast_exception_return
+fast_exception_return:
+       ld      r12,_MSR(r1)
+1:     ld      r11,_NIP(r1)
+       andi.   r3,r12,MSR_RI           /* check if RI is set */
+       beq-    unrecov_fer
+
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       andi.   r3,r12,MSR_PR
+       beq     2f
+       ACCOUNT_CPU_USER_EXIT(r3, r4)
+2:
+#endif
+
+       ld      r3,_CCR(r1)
+       ld      r4,_LINK(r1)
+       ld      r5,_CTR(r1)
+       ld      r6,_XER(r1)
+       mtcr    r3
+       mtlr    r4
+       mtctr   r5
+       mtxer   r6
+       REST_GPR(0, r1)
+       REST_8GPRS(2, r1)
+
+       mfmsr   r10
+       rldicl  r10,r10,48,1            /* clear EE */
+       rldicr  r10,r10,16,61           /* clear RI (LE is 0 already) */
+       mtmsrd  r10,1
+
+       mtspr   SPRN_SRR1,r12
+       mtspr   SPRN_SRR0,r11
+       REST_4GPRS(10, r1)
+       ld      r1,GPR1(r1)
+       rfid
+       b       .       /* prevent speculative execution */
+
+unrecov_fer:
+       bl      .save_nvgprs
+1:     addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .unrecoverable_exception
+       b       1b
+
+
+/*
+ * Hash table stuff
+ */
+       .align  7
+_STATIC(do_hash_page)
+       std     r3,_DAR(r1)
+       std     r4,_DSISR(r1)
+
+       andis.  r0,r4,0xa450            /* weird error? */
+       bne-    handle_page_fault       /* if not, try to insert a HPTE */
+BEGIN_FTR_SECTION
+       andis.  r0,r4,0x0020            /* Is it a segment table fault? */
+       bne-    do_ste_alloc            /* If so handle it */
+END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+
+       /*
+        * On iSeries, we soft-disable interrupts here, then
+        * hard-enable interrupts so that the hash_page code can spin on
+        * the hash_table_lock without problems on a shared processor.
+        */
+       DISABLE_INTS
+
+       /*
+        * Currently, trace_hardirqs_off() will be called by DISABLE_INTS
+        * and will clobber volatile registers when irq tracing is enabled
+        * so we need to reload them. It may be possible to be smarter here
+        * and move the irq tracing elsewhere but let's keep it simple for
+        * now
+        */
+#ifdef CONFIG_TRACE_IRQFLAGS
+       ld      r3,_DAR(r1)
+       ld      r4,_DSISR(r1)
+       ld      r5,_TRAP(r1)
+       ld      r12,_MSR(r1)
+       clrrdi  r5,r5,4
+#endif /* CONFIG_TRACE_IRQFLAGS */
+       /*
+        * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
+        * accessing a userspace segment (even from the kernel). We assume
+        * kernel addresses always have the high bit set.
+        */
+       rlwinm  r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */
+       rotldi  r0,r3,15                /* Move high bit into MSR_PR posn */
+       orc     r0,r12,r0               /* MSR_PR | ~high_bit */
+       rlwimi  r4,r0,32-13,30,30       /* becomes _PAGE_USER access bit */
+       ori     r4,r4,1                 /* add _PAGE_PRESENT */
+       rlwimi  r4,r5,22+2,31-2,31-2    /* Set _PAGE_EXEC if trap is 0x400 */
+
+       /*
+        * r3 contains the faulting address
+        * r4 contains the required access permissions
+        * r5 contains the trap number
+        *
+        * at return r3 = 0 for success
+        */
+       bl      .hash_page              /* build HPTE if possible */
+       cmpdi   r3,0                    /* see if hash_page succeeded */
+
+BEGIN_FW_FTR_SECTION
+       /*
+        * If we had interrupts soft-enabled at the point where the
+        * DSI/ISI occurred, and an interrupt came in during hash_page,
+        * handle it now.
+        * We jump to ret_from_except_lite rather than fast_exception_return
+        * because ret_from_except_lite will check for and handle pending
+        * interrupts if necessary.
+        */
+       beq     13f
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
+
+BEGIN_FW_FTR_SECTION
+       /*
+        * Here we have interrupts hard-disabled, so it is sufficient
+        * to restore paca->{soft,hard}_enable and get out.
+        */
+       beq     fast_exc_return_irq     /* Return from exception on success */
+END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
+
+       /* For a hash failure, we don't bother re-enabling interrupts */
+       ble-    12f
+
+       /*
+        * hash_page couldn't handle it, set soft interrupt enable back
+        * to what it was before the trap.  Note that .raw_local_irq_restore
+        * handles any interrupts pending at this point.
+        */
+       ld      r3,SOFTE(r1)
+       TRACE_AND_RESTORE_IRQ_PARTIAL(r3, 11f)
+       bl      .raw_local_irq_restore
+       b       11f
+
+/* Here we have a page fault that hash_page can't handle. */
+handle_page_fault:
+       ENABLE_INTS
+11:    ld      r4,_DAR(r1)
+       ld      r5,_DSISR(r1)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .do_page_fault
+       cmpdi   r3,0
+       beq+    13f
+       bl      .save_nvgprs
+       mr      r5,r3
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       lwz     r4,_DAR(r1)
+       bl      .bad_page_fault
+       b       .ret_from_except
+
+13:    b       .ret_from_except_lite
+
+/* We have a page fault that hash_page could handle but HV refused
+ * the PTE insertion
+ */
+12:    bl      .save_nvgprs
+       mr      r5,r3
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       ld      r4,_DAR(r1)
+       bl      .low_hash_fault
+       b       .ret_from_except
+
+       /* here we have a segment miss */
+do_ste_alloc:
+       bl      .ste_allocate           /* try to insert stab entry */
+       cmpdi   r3,0
+       bne-    handle_page_fault
+       b       fast_exception_return
+
+/*
+ * r13 points to the PACA, r9 contains the saved CR,
+ * r11 and r12 contain the saved SRR0 and SRR1.
+ * r9 - r13 are saved in paca->exslb.
+ * We assume we aren't going to take any exceptions during this procedure.
+ * We assume (DAR >> 60) == 0xc.
+ */
+       .align  7
+_GLOBAL(do_stab_bolted)
+       stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
+       std     r11,PACA_EXSLB+EX_SRR0(r13)     /* save SRR0 in exc. frame */
+
+       /* Hash to the primary group */
+       ld      r10,PACASTABVIRT(r13)
+       mfspr   r11,SPRN_DAR
+       srdi    r11,r11,28
+       rldimi  r10,r11,7,52    /* r10 = first ste of the group */
+
+       /* Calculate VSID */
+       /* This is a kernel address, so protovsid = ESID */
+       ASM_VSID_SCRAMBLE(r11, r9, 256M)
+       rldic   r9,r11,12,16    /* r9 = vsid << 12 */
+
+       /* Search the primary group for a free entry */
+1:     ld      r11,0(r10)      /* Test valid bit of the current ste    */
+       andi.   r11,r11,0x80
+       beq     2f
+       addi    r10,r10,16
+       andi.   r11,r10,0x70
+       bne     1b
+
+       /* Stick for only searching the primary group for now.          */
+       /* At least for now, we use a very simple random castout scheme */
+       /* Use the TB as a random number ;  OR in 1 to avoid entry 0    */
+       mftb    r11
+       rldic   r11,r11,4,57    /* r11 = (r11 << 4) & 0x70 */
+       ori     r11,r11,0x10
+
+       /* r10 currently points to an ste one past the group of interest */
+       /* make it point to the randomly selected entry                 */
+       subi    r10,r10,128
+       or      r10,r10,r11     /* r10 is the entry to invalidate       */
+
+       isync                   /* mark the entry invalid               */
+       ld      r11,0(r10)
+       rldicl  r11,r11,56,1    /* clear the valid bit */
+       rotldi  r11,r11,8
+       std     r11,0(r10)
+       sync
+
+       clrrdi  r11,r11,28      /* Get the esid part of the ste         */
+       slbie   r11
+
+2:     std     r9,8(r10)       /* Store the vsid part of the ste       */
+       eieio
+
+       mfspr   r11,SPRN_DAR            /* Get the new esid                     */
+       clrrdi  r11,r11,28      /* Permits a full 32b of ESID           */
+       ori     r11,r11,0x90    /* Turn on valid and kp                 */
+       std     r11,0(r10)      /* Put new entry back into the stab     */
+
+       sync
+
+       /* All done -- return from exception. */
+       lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
+       ld      r11,PACA_EXSLB+EX_SRR0(r13)     /* get saved SRR0 */
+
+       andi.   r10,r12,MSR_RI
+       beq-    unrecov_slb
+
+       mtcrf   0x80,r9                 /* restore CR */
+
+       mfmsr   r10
+       clrrdi  r10,r10,2
+       mtmsrd  r10,1
+
+       mtspr   SPRN_SRR0,r11
+       mtspr   SPRN_SRR1,r12
+       ld      r9,PACA_EXSLB+EX_R9(r13)
+       ld      r10,PACA_EXSLB+EX_R10(r13)
+       ld      r11,PACA_EXSLB+EX_R11(r13)
+       ld      r12,PACA_EXSLB+EX_R12(r13)
+       ld      r13,PACA_EXSLB+EX_R13(r13)
+       rfid
+       b       .       /* prevent speculative execution */
+
+/*
+ * Space for CPU0's segment table.
+ *
+ * On iSeries, the hypervisor must fill in at least one entry before
+ * we get control (with relocate on).  The address is given to the hv
+ * as a page number (see xLparMap below), so this must be at a
+ * fixed address (the linker can't compute (u64)&initial_stab >>
+ * PAGE_SHIFT).
+ */
+       . = STAB0_OFFSET        /* 0x6000 */
+       .globl initial_stab
+initial_stab:
+       .space  4096
+
+#ifdef CONFIG_PPC_PSERIES
+/*
+ * Data area reserved for FWNMI option.
+ * This address (0x7000) is fixed by the RPA.
+ */
+       .= 0x7000
+       .globl fwnmi_data_area
+fwnmi_data_area:
+#endif /* CONFIG_PPC_PSERIES */
+
+       /* iSeries does not use the FWNMI stuff, so it is safe to put
+        * this here, even if we later allow kernels that will boot on
+        * both pSeries and iSeries */
+#ifdef CONFIG_PPC_ISERIES
+        . = LPARMAP_PHYS
+       .globl xLparMap
+xLparMap:
+       .quad   HvEsidsToMap            /* xNumberEsids */
+       .quad   HvRangesToMap           /* xNumberRanges */
+       .quad   STAB0_PAGE              /* xSegmentTableOffs */
+       .zero   40                      /* xRsvd */
+       /* xEsids (HvEsidsToMap entries of 2 quads) */
+       .quad   PAGE_OFFSET_ESID        /* xKernelEsid */
+       .quad   PAGE_OFFSET_VSID        /* xKernelVsid */
+       .quad   VMALLOC_START_ESID      /* xKernelEsid */
+       .quad   VMALLOC_START_VSID      /* xKernelVsid */
+       /* xRanges (HvRangesToMap entries of 3 quads) */
+       .quad   HvPagesToMap            /* xPages */
+       .quad   0                       /* xOffset */
+       .quad   PAGE_OFFSET_VSID << (SID_SHIFT - HW_PAGE_SHIFT) /* xVPN */
+
+#endif /* CONFIG_PPC_ISERIES */
+
+#ifdef CONFIG_PPC_PSERIES
+        . = 0x8000
+#endif /* CONFIG_PPC_PSERIES */
index 2d182f1..1b12696 100644 (file)
 #include <asm/code-patching.h>
 #include <asm/ftrace.h>
 
-#ifdef CONFIG_PPC32
-# define GET_ADDR(addr) addr
-#else
-/* PowerPC64's functions are data that points to the functions */
-# define GET_ADDR(addr) (*(unsigned long *)addr)
-#endif
 
 #ifdef CONFIG_DYNAMIC_FTRACE
-static unsigned int ftrace_nop_replace(void)
-{
-       return PPC_INST_NOP;
-}
-
 static unsigned int
 ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
 {
        unsigned int op;
 
-       addr = GET_ADDR(addr);
+       addr = ppc_function_entry((void *)addr);
 
        /* if (link) set op to 'bl' else 'b' */
        op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
@@ -49,14 +38,6 @@ ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
        return op;
 }
 
-#ifdef CONFIG_PPC64
-# define _ASM_ALIGN    " .align 3 "
-# define _ASM_PTR      " .llong "
-#else
-# define _ASM_ALIGN    " .align 2 "
-# define _ASM_PTR      " .long "
-#endif
-
 static int
 ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
 {
@@ -197,7 +178,7 @@ __ftrace_make_nop(struct module *mod,
        ptr = ((unsigned long)jmp[0] << 32) + jmp[1];
 
        /* This should match what was called */
-       if (ptr != GET_ADDR(addr)) {
+       if (ptr != ppc_function_entry((void *)addr)) {
                printk(KERN_ERR "addr does not match %lx\n", ptr);
                return -EINVAL;
        }
@@ -328,7 +309,7 @@ int ftrace_make_nop(struct module *mod,
        if (test_24bit_addr(ip, addr)) {
                /* within range */
                old = ftrace_call_replace(ip, addr, 1);
-               new = ftrace_nop_replace();
+               new = PPC_INST_NOP;
                return ftrace_modify_code(ip, old, new);
        }
 
@@ -466,7 +447,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
         */
        if (test_24bit_addr(ip, addr)) {
                /* within range */
-               old = ftrace_nop_replace();
+               old = PPC_INST_NOP;
                new = ftrace_call_replace(ip, addr, 1);
                return ftrace_modify_code(ip, old, new);
        }
@@ -570,7 +551,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
                return_hooker = (unsigned long)&mod_return_to_handler;
 #endif
 
-       return_hooker = GET_ADDR(return_hooker);
+       return_hooker = ppc_function_entry((void *)return_hooker);
 
        /*
         * Protect against fault, even if it shouldn't
index c01467f..4846946 100644 (file)
@@ -733,9 +733,11 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
 AltiVecUnavailable:
        EXCEPTION_PROLOG
 #ifdef CONFIG_ALTIVEC
-       bne     load_up_altivec         /* if from user, just load it up */
+       beq     1f
+       bl      load_up_altivec         /* if from user, just load it up */
+       b       fast_exception_return
 #endif /* CONFIG_ALTIVEC */
-       addi    r3,r1,STACK_FRAME_OVERHEAD
+1:     addi    r3,r1,STACK_FRAME_OVERHEAD
        EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception)
 
 PerformanceMonitor:
@@ -743,101 +745,6 @@ PerformanceMonitor:
        addi    r3,r1,STACK_FRAME_OVERHEAD
        EXC_XFER_STD(0xf00, performance_monitor_exception)
 
-#ifdef CONFIG_ALTIVEC
-/* Note that the AltiVec support is closely modeled after the FP
- * support.  Changes to one are likely to be applicable to the
- * other!  */
-load_up_altivec:
-/*
- * Disable AltiVec for the task which had AltiVec previously,
- * and save its AltiVec registers in its thread_struct.
- * Enables AltiVec for use in the kernel on return.
- * On SMP we know the AltiVec units are free, since we give it up every
- * switch.  -- Kumar
- */
-       mfmsr   r5
-       oris    r5,r5,MSR_VEC@h
-       MTMSRD(r5)                      /* enable use of AltiVec now */
-       isync
-/*
- * For SMP, we don't do lazy AltiVec switching because it just gets too
- * horrendously complex, especially when a task switches from one CPU
- * to another.  Instead we call giveup_altivec in switch_to.
- */
-#ifndef CONFIG_SMP
-       tophys(r6,0)
-       addis   r3,r6,last_task_used_altivec@ha
-       lwz     r4,last_task_used_altivec@l(r3)
-       cmpwi   0,r4,0
-       beq     1f
-       add     r4,r4,r6
-       addi    r4,r4,THREAD    /* want THREAD of last_task_used_altivec */
-       SAVE_32VRS(0,r10,r4)
-       mfvscr  vr0
-       li      r10,THREAD_VSCR
-       stvx    vr0,r10,r4
-       lwz     r5,PT_REGS(r4)
-       add     r5,r5,r6
-       lwz     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-       lis     r10,MSR_VEC@h
-       andc    r4,r4,r10       /* disable altivec for previous task */
-       stw     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
-       /* enable use of AltiVec after return */
-       oris    r9,r9,MSR_VEC@h
-       mfspr   r5,SPRN_SPRG3           /* current task's THREAD (phys) */
-       li      r4,1
-       li      r10,THREAD_VSCR
-       stw     r4,THREAD_USED_VR(r5)
-       lvx     vr0,r10,r5
-       mtvscr  vr0
-       REST_32VRS(0,r10,r5)
-#ifndef CONFIG_SMP
-       subi    r4,r5,THREAD
-       sub     r4,r4,r6
-       stw     r4,last_task_used_altivec@l(r3)
-#endif /* CONFIG_SMP */
-       /* restore registers and return */
-       /* we haven't used ctr or xer or lr */
-       b       fast_exception_return
-
-/*
- * giveup_altivec(tsk)
- * Disable AltiVec for the task given as the argument,
- * and save the AltiVec registers in its thread_struct.
- * Enables AltiVec for use in the kernel on return.
- */
-
-       .globl  giveup_altivec
-giveup_altivec:
-       mfmsr   r5
-       oris    r5,r5,MSR_VEC@h
-       SYNC
-       MTMSRD(r5)                      /* enable use of AltiVec now */
-       isync
-       cmpwi   0,r3,0
-       beqlr-                          /* if no previous owner, done */
-       addi    r3,r3,THREAD            /* want THREAD of task */
-       lwz     r5,PT_REGS(r3)
-       cmpwi   0,r5,0
-       SAVE_32VRS(0, r4, r3)
-       mfvscr  vr0
-       li      r4,THREAD_VSCR
-       stvx    vr0,r4,r3
-       beq     1f
-       lwz     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-       lis     r3,MSR_VEC@h
-       andc    r4,r4,r3                /* disable AltiVec for previous task */
-       stw     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
-       li      r5,0
-       lis     r4,last_task_used_altivec@ha
-       stw     r5,last_task_used_altivec@l(r4)
-#endif /* CONFIG_SMP */
-       blr
-#endif /* CONFIG_ALTIVEC */
 
 /*
  * This code is jumped to from the startup code to copy
index 50ef505..012505e 100644 (file)
@@ -12,8 +12,9 @@
  *  Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
  *    Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
  *
- *  This file contains the low-level support and setup for the
- *  PowerPC-64 platform, including trap and interrupt dispatch.
+ *  This file contains the entry point for the 64-bit kernel along
+ *  with some early initialization code common to all 64-bit powerpc
+ *  variants.
  *
  *  This program is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU General Public License
 #include <asm/exception.h>
 #include <asm/irqflags.h>
 
-/*
- * We layout physical memory as follows:
- * 0x0000 - 0x00ff : Secondary processor spin code
- * 0x0100 - 0x2fff : pSeries Interrupt prologs
- * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt prologs
- * 0x6000 - 0x6fff : Initial (CPU0) segment table
- * 0x7000 - 0x7fff : FWNMI data area
- * 0x8000 -        : Early init and support code
- */
-
-/*
- *   SPRG Usage
- *
- *   Register  Definition
- *
- *   SPRG0     reserved for hypervisor
- *   SPRG1     temp - used to save gpr
- *   SPRG2     temp - used to save gpr
- *   SPRG3     virt addr of paca
+/* The physical memory is layed out such that the secondary processor
+ * spin code sits at 0x0000...0x00ff. On server, the vectors follow
+ * using the layout described in exceptions-64s.S
  */
 
 /*
  * Entering into this code we make the following assumptions:
- *  For pSeries:
+ *
+ *  For pSeries or server processors:
  *   1. The MMU is off & open firmware is running in real mode.
  *   2. The kernel is entered at __start
  *
  *  For iSeries:
  *   1. The MMU is on (as it always is for iSeries)
  *   2. The kernel is entered at system_reset_iSeries
+ *
+ *  For Book3E processors:
+ *   1. The MMU is on running in AS0 in a state defined in ePAPR
+ *   2. The kernel is entered at __start
  */
 
        .text
@@ -166,1065 +156,14 @@ exception_marker:
        .text
 
 /*
- * This is the start of the interrupt handlers for pSeries
- * This code runs with relocation off.
- * Code from here to __end_interrupts gets copied down to real
- * address 0x100 when we are running a relocatable kernel.
- * Therefore any relative branches in this section must only
- * branch to labels in this section.
- */
-       . = 0x100
-       .globl __start_interrupts
-__start_interrupts:
-
-       STD_EXCEPTION_PSERIES(0x100, system_reset)
-
-       . = 0x200
-_machine_check_pSeries:
-       HMT_MEDIUM
-       mtspr   SPRN_SPRG1,r13          /* save r13 */
-       EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
-
-       . = 0x300
-       .globl data_access_pSeries
-data_access_pSeries:
-       HMT_MEDIUM
-       mtspr   SPRN_SPRG1,r13
-BEGIN_FTR_SECTION
-       mtspr   SPRN_SPRG2,r12
-       mfspr   r13,SPRN_DAR
-       mfspr   r12,SPRN_DSISR
-       srdi    r13,r13,60
-       rlwimi  r13,r12,16,0x20
-       mfcr    r12
-       cmpwi   r13,0x2c
-       beq     do_stab_bolted_pSeries
-       mtcrf   0x80,r12
-       mfspr   r12,SPRN_SPRG2
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
-
-       . = 0x380
-       .globl data_access_slb_pSeries
-data_access_slb_pSeries:
-       HMT_MEDIUM
-       mtspr   SPRN_SPRG1,r13
-       mfspr   r13,SPRN_SPRG3          /* get paca address into r13 */
-       std     r3,PACA_EXSLB+EX_R3(r13)
-       mfspr   r3,SPRN_DAR
-       std     r9,PACA_EXSLB+EX_R9(r13)        /* save r9 - r12 */
-       mfcr    r9
-#ifdef __DISABLED__
-       /* Keep that around for when we re-implement dynamic VSIDs */
-       cmpdi   r3,0
-       bge     slb_miss_user_pseries
-#endif /* __DISABLED__ */
-       std     r10,PACA_EXSLB+EX_R10(r13)
-       std     r11,PACA_EXSLB+EX_R11(r13)
-       std     r12,PACA_EXSLB+EX_R12(r13)
-       mfspr   r10,SPRN_SPRG1
-       std     r10,PACA_EXSLB+EX_R13(r13)
-       mfspr   r12,SPRN_SRR1           /* and SRR1 */
-#ifndef CONFIG_RELOCATABLE
-       b       .slb_miss_realmode
-#else
-       /*
-        * We can't just use a direct branch to .slb_miss_realmode
-        * because the distance from here to there depends on where
-        * the kernel ends up being put.
-        */
-       mfctr   r11
-       ld      r10,PACAKBASE(r13)
-       LOAD_HANDLER(r10, .slb_miss_realmode)
-       mtctr   r10
-       bctr
-#endif
-
-       STD_EXCEPTION_PSERIES(0x400, instruction_access)
-
-       . = 0x480
-       .globl instruction_access_slb_pSeries
-instruction_access_slb_pSeries:
-       HMT_MEDIUM
-       mtspr   SPRN_SPRG1,r13
-       mfspr   r13,SPRN_SPRG3          /* get paca address into r13 */
-       std     r3,PACA_EXSLB+EX_R3(r13)
-       mfspr   r3,SPRN_SRR0            /* SRR0 is faulting address */
-       std     r9,PACA_EXSLB+EX_R9(r13)        /* save r9 - r12 */
-       mfcr    r9
-#ifdef __DISABLED__
-       /* Keep that around for when we re-implement dynamic VSIDs */
-       cmpdi   r3,0
-       bge     slb_miss_user_pseries
-#endif /* __DISABLED__ */
-       std     r10,PACA_EXSLB+EX_R10(r13)
-       std     r11,PACA_EXSLB+EX_R11(r13)
-       std     r12,PACA_EXSLB+EX_R12(r13)
-       mfspr   r10,SPRN_SPRG1
-       std     r10,PACA_EXSLB+EX_R13(r13)
-       mfspr   r12,SPRN_SRR1           /* and SRR1 */
-#ifndef CONFIG_RELOCATABLE
-       b       .slb_miss_realmode
-#else
-       mfctr   r11
-       ld      r10,PACAKBASE(r13)
-       LOAD_HANDLER(r10, .slb_miss_realmode)
-       mtctr   r10
-       bctr
-#endif
-
-       MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt)
-       STD_EXCEPTION_PSERIES(0x600, alignment)
-       STD_EXCEPTION_PSERIES(0x700, program_check)
-       STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
-       MASKABLE_EXCEPTION_PSERIES(0x900, decrementer)
-       STD_EXCEPTION_PSERIES(0xa00, trap_0a)
-       STD_EXCEPTION_PSERIES(0xb00, trap_0b)
-
-       . = 0xc00
-       .globl  system_call_pSeries
-system_call_pSeries:
-       HMT_MEDIUM
-BEGIN_FTR_SECTION
-       cmpdi   r0,0x1ebe
-       beq-    1f
-END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
-       mr      r9,r13
-       mfspr   r13,SPRN_SPRG3
-       mfspr   r11,SPRN_SRR0
-       ld      r12,PACAKBASE(r13)
-       ld      r10,PACAKMSR(r13)
-       LOAD_HANDLER(r12, system_call_entry)
-       mtspr   SPRN_SRR0,r12
-       mfspr   r12,SPRN_SRR1
-       mtspr   SPRN_SRR1,r10
-       rfid
-       b       .       /* prevent speculative execution */
-
-/* Fast LE/BE switch system call */
-1:     mfspr   r12,SPRN_SRR1
-       xori    r12,r12,MSR_LE
-       mtspr   SPRN_SRR1,r12
-       rfid            /* return to userspace */
-       b       .
-
-       STD_EXCEPTION_PSERIES(0xd00, single_step)
-       STD_EXCEPTION_PSERIES(0xe00, trap_0e)
-
-       /* We need to deal with the Altivec unavailable exception
-        * here which is at 0xf20, thus in the middle of the
-        * prolog code of the PerformanceMonitor one. A little
-        * trickery is thus necessary
-        */
-       . = 0xf00
-       b       performance_monitor_pSeries
-
-       . = 0xf20
-       b       altivec_unavailable_pSeries
-
-       . = 0xf40
-       b       vsx_unavailable_pSeries
-
-#ifdef CONFIG_CBE_RAS
-       HSTD_EXCEPTION_PSERIES(0x1200, cbe_system_error)
-#endif /* CONFIG_CBE_RAS */
-       STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
-#ifdef CONFIG_CBE_RAS
-       HSTD_EXCEPTION_PSERIES(0x1600, cbe_maintenance)
-#endif /* CONFIG_CBE_RAS */
-       STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
-#ifdef CONFIG_CBE_RAS
-       HSTD_EXCEPTION_PSERIES(0x1800, cbe_thermal)
-#endif /* CONFIG_CBE_RAS */
-
-       . = 0x3000
-
-/*** pSeries interrupt support ***/
-
-       /* moved from 0xf00 */
-       STD_EXCEPTION_PSERIES(., performance_monitor)
-       STD_EXCEPTION_PSERIES(., altivec_unavailable)
-       STD_EXCEPTION_PSERIES(., vsx_unavailable)
-
-/*
- * An interrupt came in while soft-disabled; clear EE in SRR1,
- * clear paca->hard_enabled and return.
- */
-masked_interrupt:
-       stb     r10,PACAHARDIRQEN(r13)
-       mtcrf   0x80,r9
-       ld      r9,PACA_EXGEN+EX_R9(r13)
-       mfspr   r10,SPRN_SRR1
-       rldicl  r10,r10,48,1            /* clear MSR_EE */
-       rotldi  r10,r10,16
-       mtspr   SPRN_SRR1,r10
-       ld      r10,PACA_EXGEN+EX_R10(r13)
-       mfspr   r13,SPRN_SPRG1
-       rfid
-       b       .
-
-       .align  7
-do_stab_bolted_pSeries:
-       mtcrf   0x80,r12
-       mfspr   r12,SPRN_SPRG2
-       EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
-
-#ifdef CONFIG_PPC_PSERIES
-/*
- * Vectors for the FWNMI option.  Share common code.
- */
-       .globl system_reset_fwnmi
-      .align 7
-system_reset_fwnmi:
-       HMT_MEDIUM
-       mtspr   SPRN_SPRG1,r13          /* save r13 */
-       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
-
-       .globl machine_check_fwnmi
-      .align 7
-machine_check_fwnmi:
-       HMT_MEDIUM
-       mtspr   SPRN_SPRG1,r13          /* save r13 */
-       EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
-
-#endif /* CONFIG_PPC_PSERIES */
-
-#ifdef __DISABLED__
-/*
- * This is used for when the SLB miss handler has to go virtual,
- * which doesn't happen for now anymore but will once we re-implement
- * dynamic VSIDs for shared page tables
- */
-slb_miss_user_pseries:
-       std     r10,PACA_EXGEN+EX_R10(r13)
-       std     r11,PACA_EXGEN+EX_R11(r13)
-       std     r12,PACA_EXGEN+EX_R12(r13)
-       mfspr   r10,SPRG1
-       ld      r11,PACA_EXSLB+EX_R9(r13)
-       ld      r12,PACA_EXSLB+EX_R3(r13)
-       std     r10,PACA_EXGEN+EX_R13(r13)
-       std     r11,PACA_EXGEN+EX_R9(r13)
-       std     r12,PACA_EXGEN+EX_R3(r13)
-       clrrdi  r12,r13,32
-       mfmsr   r10
-       mfspr   r11,SRR0                        /* save SRR0 */
-       ori     r12,r12,slb_miss_user_common@l  /* virt addr of handler */
-       ori     r10,r10,MSR_IR|MSR_DR|MSR_RI
-       mtspr   SRR0,r12
-       mfspr   r12,SRR1                        /* and SRR1 */
-       mtspr   SRR1,r10
-       rfid
-       b       .                               /* prevent spec. execution */
-#endif /* __DISABLED__ */
-
-       .align  7
-       .globl  __end_interrupts
-__end_interrupts:
-
-/*
- * Code from here down to __end_handlers is invoked from the
- * exception prologs above.  Because the prologs assemble the
- * addresses of these handlers using the LOAD_HANDLER macro,
- * which uses an addi instruction, these handlers must be in
- * the first 32k of the kernel image.
- */
-
-/*** Common interrupt handlers ***/
-
-       STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception)
-
-       /*
-        * Machine check is different because we use a different
-        * save area: PACA_EXMC instead of PACA_EXGEN.
-        */
-       .align  7
-       .globl machine_check_common
-machine_check_common:
-       EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
-       FINISH_NAP
-       DISABLE_INTS
-       bl      .save_nvgprs
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .machine_check_exception
-       b       .ret_from_except
-
-       STD_EXCEPTION_COMMON_LITE(0x900, decrementer, .timer_interrupt)
-       STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)
-       STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
-       STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
-       STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
-       STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception)
-       STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
-#ifdef CONFIG_ALTIVEC
-       STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
-#else
-       STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception)
-#endif
-#ifdef CONFIG_CBE_RAS
-       STD_EXCEPTION_COMMON(0x1200, cbe_system_error, .cbe_system_error_exception)
-       STD_EXCEPTION_COMMON(0x1600, cbe_maintenance, .cbe_maintenance_exception)
-       STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception)
-#endif /* CONFIG_CBE_RAS */
-
-       .align  7
-system_call_entry:
-       b       system_call_common
-
-/*
- * Here we have detected that the kernel stack pointer is bad.
- * R9 contains the saved CR, r13 points to the paca,
- * r10 contains the (bad) kernel stack pointer,
- * r11 and r12 contain the saved SRR0 and SRR1.
- * We switch to using an emergency stack, save the registers there,
- * and call kernel_bad_stack(), which panics.
- */
-bad_stack:
-       ld      r1,PACAEMERGSP(r13)
-       subi    r1,r1,64+INT_FRAME_SIZE
-       std     r9,_CCR(r1)
-       std     r10,GPR1(r1)
-       std     r11,_NIP(r1)
-       std     r12,_MSR(r1)
-       mfspr   r11,SPRN_DAR
-       mfspr   r12,SPRN_DSISR
-       std     r11,_DAR(r1)
-       std     r12,_DSISR(r1)
-       mflr    r10
-       mfctr   r11
-       mfxer   r12
-       std     r10,_LINK(r1)
-       std     r11,_CTR(r1)
-       std     r12,_XER(r1)
-       SAVE_GPR(0,r1)
-       SAVE_GPR(2,r1)
-       SAVE_4GPRS(3,r1)
-       SAVE_2GPRS(7,r1)
-       SAVE_10GPRS(12,r1)
-       SAVE_10GPRS(22,r1)
-       lhz     r12,PACA_TRAP_SAVE(r13)
-       std     r12,_TRAP(r1)
-       addi    r11,r1,INT_FRAME_SIZE
-       std     r11,0(r1)
-       li      r12,0
-       std     r12,0(r11)
-       ld      r2,PACATOC(r13)
-1:     addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .kernel_bad_stack
-       b       1b
-
-/*
- * Here r13 points to the paca, r9 contains the saved CR,
- * SRR0 and SRR1 are saved in r11 and r12,
- * r9 - r13 are saved in paca->exgen.
- */
-       .align  7
-       .globl data_access_common
-data_access_common:
-       mfspr   r10,SPRN_DAR
-       std     r10,PACA_EXGEN+EX_DAR(r13)
-       mfspr   r10,SPRN_DSISR
-       stw     r10,PACA_EXGEN+EX_DSISR(r13)
-       EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
-       ld      r3,PACA_EXGEN+EX_DAR(r13)
-       lwz     r4,PACA_EXGEN+EX_DSISR(r13)
-       li      r5,0x300
-       b       .do_hash_page           /* Try to handle as hpte fault */
-
-       .align  7
-       .globl instruction_access_common
-instruction_access_common:
-       EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
-       ld      r3,_NIP(r1)
-       andis.  r4,r12,0x5820
-       li      r5,0x400
-       b       .do_hash_page           /* Try to handle as hpte fault */
-
-/*
- * Here is the common SLB miss user that is used when going to virtual
- * mode for SLB misses, that is currently not used
- */
-#ifdef __DISABLED__
-       .align  7
-       .globl  slb_miss_user_common
-slb_miss_user_common:
-       mflr    r10
-       std     r3,PACA_EXGEN+EX_DAR(r13)
-       stw     r9,PACA_EXGEN+EX_CCR(r13)
-       std     r10,PACA_EXGEN+EX_LR(r13)
-       std     r11,PACA_EXGEN+EX_SRR0(r13)
-       bl      .slb_allocate_user
-
-       ld      r10,PACA_EXGEN+EX_LR(r13)
-       ld      r3,PACA_EXGEN+EX_R3(r13)
-       lwz     r9,PACA_EXGEN+EX_CCR(r13)
-       ld      r11,PACA_EXGEN+EX_SRR0(r13)
-       mtlr    r10
-       beq-    slb_miss_fault
-
-       andi.   r10,r12,MSR_RI          /* check for unrecoverable exception */
-       beq-    unrecov_user_slb
-       mfmsr   r10
-
-.machine push
-.machine "power4"
-       mtcrf   0x80,r9
-.machine pop
-
-       clrrdi  r10,r10,2               /* clear RI before setting SRR0/1 */
-       mtmsrd  r10,1
-
-       mtspr   SRR0,r11
-       mtspr   SRR1,r12
-
-       ld      r9,PACA_EXGEN+EX_R9(r13)
-       ld      r10,PACA_EXGEN+EX_R10(r13)
-       ld      r11,PACA_EXGEN+EX_R11(r13)
-       ld      r12,PACA_EXGEN+EX_R12(r13)
-       ld      r13,PACA_EXGEN+EX_R13(r13)
-       rfid
-       b       .
-
-slb_miss_fault:
-       EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
-       ld      r4,PACA_EXGEN+EX_DAR(r13)
-       li      r5,0
-       std     r4,_DAR(r1)
-       std     r5,_DSISR(r1)
-       b       handle_page_fault
-
-unrecov_user_slb:
-       EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
-       DISABLE_INTS
-       bl      .save_nvgprs
-1:     addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .unrecoverable_exception
-       b       1b
-
-#endif /* __DISABLED__ */
-
-
-/*
- * r13 points to the PACA, r9 contains the saved CR,
- * r12 contain the saved SRR1, SRR0 is still ready for return
- * r3 has the faulting address
- * r9 - r13 are saved in paca->exslb.
- * r3 is saved in paca->slb_r3
- * We assume we aren't going to take any exceptions during this procedure.
- */
-_GLOBAL(slb_miss_realmode)
-       mflr    r10
-#ifdef CONFIG_RELOCATABLE
-       mtctr   r11
-#endif
-
-       stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
-       std     r10,PACA_EXSLB+EX_LR(r13)       /* save LR */
-
-       bl      .slb_allocate_realmode
-
-       /* All done -- return from exception. */
-
-       ld      r10,PACA_EXSLB+EX_LR(r13)
-       ld      r3,PACA_EXSLB+EX_R3(r13)
-       lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
-#ifdef CONFIG_PPC_ISERIES
-BEGIN_FW_FTR_SECTION
-       ld      r11,PACALPPACAPTR(r13)
-       ld      r11,LPPACASRR0(r11)             /* get SRR0 value */
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
-#endif /* CONFIG_PPC_ISERIES */
-
-       mtlr    r10
-
-       andi.   r10,r12,MSR_RI  /* check for unrecoverable exception */
-       beq-    2f
-
-.machine       push
-.machine       "power4"
-       mtcrf   0x80,r9
-       mtcrf   0x01,r9         /* slb_allocate uses cr0 and cr7 */
-.machine       pop
-
-#ifdef CONFIG_PPC_ISERIES
-BEGIN_FW_FTR_SECTION
-       mtspr   SPRN_SRR0,r11
-       mtspr   SPRN_SRR1,r12
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
-#endif /* CONFIG_PPC_ISERIES */
-       ld      r9,PACA_EXSLB+EX_R9(r13)
-       ld      r10,PACA_EXSLB+EX_R10(r13)
-       ld      r11,PACA_EXSLB+EX_R11(r13)
-       ld      r12,PACA_EXSLB+EX_R12(r13)
-       ld      r13,PACA_EXSLB+EX_R13(r13)
-       rfid
-       b       .       /* prevent speculative execution */
-
-2:
-#ifdef CONFIG_PPC_ISERIES
-BEGIN_FW_FTR_SECTION
-       b       unrecov_slb
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
-#endif /* CONFIG_PPC_ISERIES */
-       mfspr   r11,SPRN_SRR0
-       ld      r10,PACAKBASE(r13)
-       LOAD_HANDLER(r10,unrecov_slb)
-       mtspr   SPRN_SRR0,r10
-       ld      r10,PACAKMSR(r13)
-       mtspr   SPRN_SRR1,r10
-       rfid
-       b       .
-
-unrecov_slb:
-       EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
-       DISABLE_INTS
-       bl      .save_nvgprs
-1:     addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .unrecoverable_exception
-       b       1b
-
-       .align  7
-       .globl hardware_interrupt_common
-       .globl hardware_interrupt_entry
-hardware_interrupt_common:
-       EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
-       FINISH_NAP
-hardware_interrupt_entry:
-       DISABLE_INTS
-BEGIN_FTR_SECTION
-       bl      .ppc64_runlatch_on
-END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .do_IRQ
-       b       .ret_from_except_lite
-
-#ifdef CONFIG_PPC_970_NAP
-power4_fixup_nap:
-       andc    r9,r9,r10
-       std     r9,TI_LOCAL_FLAGS(r11)
-       ld      r10,_LINK(r1)           /* make idle task do the */
-       std     r10,_NIP(r1)            /* equivalent of a blr */
-       blr
-#endif
-
-       .align  7
-       .globl alignment_common
-alignment_common:
-       mfspr   r10,SPRN_DAR
-       std     r10,PACA_EXGEN+EX_DAR(r13)
-       mfspr   r10,SPRN_DSISR
-       stw     r10,PACA_EXGEN+EX_DSISR(r13)
-       EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
-       ld      r3,PACA_EXGEN+EX_DAR(r13)
-       lwz     r4,PACA_EXGEN+EX_DSISR(r13)
-       std     r3,_DAR(r1)
-       std     r4,_DSISR(r1)
-       bl      .save_nvgprs
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       ENABLE_INTS
-       bl      .alignment_exception
-       b       .ret_from_except
-
-       .align  7
-       .globl program_check_common
-program_check_common:
-       EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
-       bl      .save_nvgprs
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       ENABLE_INTS
-       bl      .program_check_exception
-       b       .ret_from_except
-
-       .align  7
-       .globl fp_unavailable_common
-fp_unavailable_common:
-       EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
-       bne     1f                      /* if from user, just load it up */
-       bl      .save_nvgprs
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       ENABLE_INTS
-       bl      .kernel_fp_unavailable_exception
-       BUG_OPCODE
-1:     bl      .load_up_fpu
-       b       fast_exception_return
-
-       .align  7
-       .globl altivec_unavailable_common
-altivec_unavailable_common:
-       EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
-#ifdef CONFIG_ALTIVEC
-BEGIN_FTR_SECTION
-       beq     1f
-       bl      .load_up_altivec
-       b       fast_exception_return
-1:
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-#endif
-       bl      .save_nvgprs
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       ENABLE_INTS
-       bl      .altivec_unavailable_exception
-       b       .ret_from_except
-
-       .align  7
-       .globl vsx_unavailable_common
-vsx_unavailable_common:
-       EXCEPTION_PROLOG_COMMON(0xf40, PACA_EXGEN)
-#ifdef CONFIG_VSX
-BEGIN_FTR_SECTION
-       bne     .load_up_vsx
-1:
-END_FTR_SECTION_IFSET(CPU_FTR_VSX)
-#endif
-       bl      .save_nvgprs
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       ENABLE_INTS
-       bl      .vsx_unavailable_exception
-       b       .ret_from_except
-
-       .align  7
-       .globl  __end_handlers
-__end_handlers:
-
-/*
- * Return from an exception with minimal checks.
- * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
- * If interrupts have been enabled, or anything has been
- * done that might have changed the scheduling status of
- * any task or sent any task a signal, you should use
- * ret_from_except or ret_from_except_lite instead of this.
+ * On server, we include the exception vectors code here as it
+ * relies on absolute addressing which is only possible within
+ * this compilation unit
  */
-fast_exc_return_irq:                   /* restores irq state too */
-       ld      r3,SOFTE(r1)
-       TRACE_AND_RESTORE_IRQ(r3);
-       ld      r12,_MSR(r1)
-       rldicl  r4,r12,49,63            /* get MSR_EE to LSB */
-       stb     r4,PACAHARDIRQEN(r13)   /* restore paca->hard_enabled */
-       b       1f
-
-       .globl  fast_exception_return
-fast_exception_return:
-       ld      r12,_MSR(r1)
-1:     ld      r11,_NIP(r1)
-       andi.   r3,r12,MSR_RI           /* check if RI is set */
-       beq-    unrecov_fer
-
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING
-       andi.   r3,r12,MSR_PR
-       beq     2f
-       ACCOUNT_CPU_USER_EXIT(r3, r4)
-2:
+#ifdef CONFIG_PPC_BOOK3S
+#include "exceptions-64s.S"
 #endif
 
-       ld      r3,_CCR(r1)
-       ld      r4,_LINK(r1)
-       ld      r5,_CTR(r1)
-       ld      r6,_XER(r1)
-       mtcr    r3
-       mtlr    r4
-       mtctr   r5
-       mtxer   r6
-       REST_GPR(0, r1)
-       REST_8GPRS(2, r1)
-
-       mfmsr   r10
-       rldicl  r10,r10,48,1            /* clear EE */
-       rldicr  r10,r10,16,61           /* clear RI (LE is 0 already) */
-       mtmsrd  r10,1
-
-       mtspr   SPRN_SRR1,r12
-       mtspr   SPRN_SRR0,r11
-       REST_4GPRS(10, r1)
-       ld      r1,GPR1(r1)
-       rfid
-       b       .       /* prevent speculative execution */
-
-unrecov_fer:
-       bl      .save_nvgprs
-1:     addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .unrecoverable_exception
-       b       1b
-
-#ifdef CONFIG_ALTIVEC
-/*
- * load_up_altivec(unused, unused, tsk)
- * 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).
- * On entry: r13 == 'current' && last_task_used_altivec != 'current'
- */
-_STATIC(load_up_altivec)
-       mfmsr   r5                      /* grab the current MSR */
-       oris    r5,r5,MSR_VEC@h
-       mtmsrd  r5                      /* enable use of VMX now */
-       isync
-
-/*
- * For SMP, we don't do lazy VMX switching because it just gets too
- * horrendously complex, especially when a task switches from one CPU
- * to another.  Instead we call giveup_altvec in switch_to.
- * VRSAVE isn't dealt with here, that is done in the normal context
- * switch code. Note that we could rely on vrsave value to eventually
- * avoid saving all of the VREGs here...
- */
-#ifndef CONFIG_SMP
-       ld      r3,last_task_used_altivec@got(r2)
-       ld      r4,0(r3)
-       cmpdi   0,r4,0
-       beq     1f
-       /* Save VMX state to last_task_used_altivec's THREAD struct */
-       addi    r4,r4,THREAD
-       SAVE_32VRS(0,r5,r4)
-       mfvscr  vr0
-       li      r10,THREAD_VSCR
-       stvx    vr0,r10,r4
-       /* Disable VMX for last_task_used_altivec */
-       ld      r5,PT_REGS(r4)
-       ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-       lis     r6,MSR_VEC@h
-       andc    r4,r4,r6
-       std     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
-       /* Hack: if we get an altivec unavailable trap with VRSAVE
-        * set to all zeros, we assume this is a broken application
-        * that fails to set it properly, and thus we switch it to
-        * all 1's
-        */
-       mfspr   r4,SPRN_VRSAVE
-       cmpdi   0,r4,0
-       bne+    1f
-       li      r4,-1
-       mtspr   SPRN_VRSAVE,r4
-1:
-       /* enable use of VMX after return */
-       ld      r4,PACACURRENT(r13)
-       addi    r5,r4,THREAD            /* Get THREAD */
-       oris    r12,r12,MSR_VEC@h
-       std     r12,_MSR(r1)
-       li      r4,1
-       li      r10,THREAD_VSCR
-       stw     r4,THREAD_USED_VR(r5)
-       lvx     vr0,r10,r5
-       mtvscr  vr0
-       REST_32VRS(0,r4,r5)
-#ifndef CONFIG_SMP
-       /* Update last_task_used_math to 'current' */
-       subi    r4,r5,THREAD            /* Back to 'current' */
-       std     r4,0(r3)
-#endif /* CONFIG_SMP */
-       /* restore registers and return */
-       blr
-#endif /* CONFIG_ALTIVEC */
-
-#ifdef CONFIG_VSX
-/*
- * load_up_vsx(unused, unused, tsk)
- * Disable VSX for the task which had it previously,
- * and save its vector registers in its thread_struct.
- * Reuse the fp and vsx saves, but first check to see if they have
- * been saved already.
- * On entry: r13 == 'current' && last_task_used_vsx != 'current'
- */
-_STATIC(load_up_vsx)
-/* Load FP and VSX registers if they haven't been done yet */
-       andi.   r5,r12,MSR_FP
-       beql+   load_up_fpu             /* skip if already loaded */
-       andis.  r5,r12,MSR_VEC@h
-       beql+   load_up_altivec         /* skip if already loaded */
-
-#ifndef CONFIG_SMP
-       ld      r3,last_task_used_vsx@got(r2)
-       ld      r4,0(r3)
-       cmpdi   0,r4,0
-       beq     1f
-       /* Disable VSX for last_task_used_vsx */
-       addi    r4,r4,THREAD
-       ld      r5,PT_REGS(r4)
-       ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-       lis     r6,MSR_VSX@h
-       andc    r6,r4,r6
-       std     r6,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
-       ld      r4,PACACURRENT(r13)
-       addi    r4,r4,THREAD            /* Get THREAD */
-       li      r6,1
-       stw     r6,THREAD_USED_VSR(r4) /* ... also set thread used vsr */
-       /* enable use of VSX after return */
-       oris    r12,r12,MSR_VSX@h
-       std     r12,_MSR(r1)
-#ifndef CONFIG_SMP
-       /* Update last_task_used_math to 'current' */
-       ld      r4,PACACURRENT(r13)
-       std     r4,0(r3)
-#endif /* CONFIG_SMP */
-       b       fast_exception_return
-#endif /* CONFIG_VSX */
-
-/*
- * Hash table stuff
- */
-       .align  7
-_STATIC(do_hash_page)
-       std     r3,_DAR(r1)
-       std     r4,_DSISR(r1)
-
-       andis.  r0,r4,0xa450            /* weird error? */
-       bne-    handle_page_fault       /* if not, try to insert a HPTE */
-BEGIN_FTR_SECTION
-       andis.  r0,r4,0x0020            /* Is it a segment table fault? */
-       bne-    do_ste_alloc            /* If so handle it */
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-
-       /*
-        * On iSeries, we soft-disable interrupts here, then
-        * hard-enable interrupts so that the hash_page code can spin on
-        * the hash_table_lock without problems on a shared processor.
-        */
-       DISABLE_INTS
-
-       /*
-        * Currently, trace_hardirqs_off() will be called by DISABLE_INTS
-        * and will clobber volatile registers when irq tracing is enabled
-        * so we need to reload them. It may be possible to be smarter here
-        * and move the irq tracing elsewhere but let's keep it simple for
-        * now
-        */
-#ifdef CONFIG_TRACE_IRQFLAGS
-       ld      r3,_DAR(r1)
-       ld      r4,_DSISR(r1)
-       ld      r5,_TRAP(r1)
-       ld      r12,_MSR(r1)
-       clrrdi  r5,r5,4
-#endif /* CONFIG_TRACE_IRQFLAGS */
-       /*
-        * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
-        * accessing a userspace segment (even from the kernel). We assume
-        * kernel addresses always have the high bit set.
-        */
-       rlwinm  r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */
-       rotldi  r0,r3,15                /* Move high bit into MSR_PR posn */
-       orc     r0,r12,r0               /* MSR_PR | ~high_bit */
-       rlwimi  r4,r0,32-13,30,30       /* becomes _PAGE_USER access bit */
-       ori     r4,r4,1                 /* add _PAGE_PRESENT */
-       rlwimi  r4,r5,22+2,31-2,31-2    /* Set _PAGE_EXEC if trap is 0x400 */
-
-       /*
-        * r3 contains the faulting address
-        * r4 contains the required access permissions
-        * r5 contains the trap number
-        *
-        * at return r3 = 0 for success
-        */
-       bl      .hash_page              /* build HPTE if possible */
-       cmpdi   r3,0                    /* see if hash_page succeeded */
-
-BEGIN_FW_FTR_SECTION
-       /*
-        * If we had interrupts soft-enabled at the point where the
-        * DSI/ISI occurred, and an interrupt came in during hash_page,
-        * handle it now.
-        * We jump to ret_from_except_lite rather than fast_exception_return
-        * because ret_from_except_lite will check for and handle pending
-        * interrupts if necessary.
-        */
-       beq     13f
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
-
-BEGIN_FW_FTR_SECTION
-       /*
-        * Here we have interrupts hard-disabled, so it is sufficient
-        * to restore paca->{soft,hard}_enable and get out.
-        */
-       beq     fast_exc_return_irq     /* Return from exception on success */
-END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
-
-       /* For a hash failure, we don't bother re-enabling interrupts */
-       ble-    12f
-
-       /*
-        * hash_page couldn't handle it, set soft interrupt enable back
-        * to what it was before the trap.  Note that .raw_local_irq_restore
-        * handles any interrupts pending at this point.
-        */
-       ld      r3,SOFTE(r1)
-       TRACE_AND_RESTORE_IRQ_PARTIAL(r3, 11f)
-       bl      .raw_local_irq_restore
-       b       11f
-
-/* Here we have a page fault that hash_page can't handle. */
-handle_page_fault:
-       ENABLE_INTS
-11:    ld      r4,_DAR(r1)
-       ld      r5,_DSISR(r1)
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .do_page_fault
-       cmpdi   r3,0
-       beq+    13f
-       bl      .save_nvgprs
-       mr      r5,r3
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       lwz     r4,_DAR(r1)
-       bl      .bad_page_fault
-       b       .ret_from_except
-
-13:    b       .ret_from_except_lite
-
-/* We have a page fault that hash_page could handle but HV refused
- * the PTE insertion
- */
-12:    bl      .save_nvgprs
-       mr      r5,r3
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       ld      r4,_DAR(r1)
-       bl      .low_hash_fault
-       b       .ret_from_except
-
-       /* here we have a segment miss */
-do_ste_alloc:
-       bl      .ste_allocate           /* try to insert stab entry */
-       cmpdi   r3,0
-       bne-    handle_page_fault
-       b       fast_exception_return
-
-/*
- * r13 points to the PACA, r9 contains the saved CR,
- * r11 and r12 contain the saved SRR0 and SRR1.
- * r9 - r13 are saved in paca->exslb.
- * We assume we aren't going to take any exceptions during this procedure.
- * We assume (DAR >> 60) == 0xc.
- */
-       .align  7
-_GLOBAL(do_stab_bolted)
-       stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
-       std     r11,PACA_EXSLB+EX_SRR0(r13)     /* save SRR0 in exc. frame */
-
-       /* Hash to the primary group */
-       ld      r10,PACASTABVIRT(r13)
-       mfspr   r11,SPRN_DAR
-       srdi    r11,r11,28
-       rldimi  r10,r11,7,52    /* r10 = first ste of the group */
-
-       /* Calculate VSID */
-       /* This is a kernel address, so protovsid = ESID */
-       ASM_VSID_SCRAMBLE(r11, r9, 256M)
-       rldic   r9,r11,12,16    /* r9 = vsid << 12 */
-
-       /* Search the primary group for a free entry */
-1:     ld      r11,0(r10)      /* Test valid bit of the current ste    */
-       andi.   r11,r11,0x80
-       beq     2f
-       addi    r10,r10,16
-       andi.   r11,r10,0x70
-       bne     1b
-
-       /* Stick for only searching the primary group for now.          */
-       /* At least for now, we use a very simple random castout scheme */
-       /* Use the TB as a random number ;  OR in 1 to avoid entry 0    */
-       mftb    r11
-       rldic   r11,r11,4,57    /* r11 = (r11 << 4) & 0x70 */
-       ori     r11,r11,0x10
-
-       /* r10 currently points to an ste one past the group of interest */
-       /* make it point to the randomly selected entry                 */
-       subi    r10,r10,128
-       or      r10,r10,r11     /* r10 is the entry to invalidate       */
-
-       isync                   /* mark the entry invalid               */
-       ld      r11,0(r10)
-       rldicl  r11,r11,56,1    /* clear the valid bit */
-       rotldi  r11,r11,8
-       std     r11,0(r10)
-       sync
-
-       clrrdi  r11,r11,28      /* Get the esid part of the ste         */
-       slbie   r11
-
-2:     std     r9,8(r10)       /* Store the vsid part of the ste       */
-       eieio
-
-       mfspr   r11,SPRN_DAR            /* Get the new esid                     */
-       clrrdi  r11,r11,28      /* Permits a full 32b of ESID           */
-       ori     r11,r11,0x90    /* Turn on valid and kp                 */
-       std     r11,0(r10)      /* Put new entry back into the stab     */
-
-       sync
-
-       /* All done -- return from exception. */
-       lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
-       ld      r11,PACA_EXSLB+EX_SRR0(r13)     /* get saved SRR0 */
-
-       andi.   r10,r12,MSR_RI
-       beq-    unrecov_slb
-
-       mtcrf   0x80,r9                 /* restore CR */
-
-       mfmsr   r10
-       clrrdi  r10,r10,2
-       mtmsrd  r10,1
-
-       mtspr   SPRN_SRR0,r11
-       mtspr   SPRN_SRR1,r12
-       ld      r9,PACA_EXSLB+EX_R9(r13)
-       ld      r10,PACA_EXSLB+EX_R10(r13)
-       ld      r11,PACA_EXSLB+EX_R11(r13)
-       ld      r12,PACA_EXSLB+EX_R12(r13)
-       ld      r13,PACA_EXSLB+EX_R13(r13)
-       rfid
-       b       .       /* prevent speculative execution */
-
-/*
- * Space for CPU0's segment table.
- *
- * On iSeries, the hypervisor must fill in at least one entry before
- * we get control (with relocate on).  The address is given to the hv
- * as a page number (see xLparMap below), so this must be at a
- * fixed address (the linker can't compute (u64)&initial_stab >>
- * PAGE_SHIFT).
- */
-       . = STAB0_OFFSET        /* 0x6000 */
-       .globl initial_stab
-initial_stab:
-       .space  4096
-
-#ifdef CONFIG_PPC_PSERIES
-/*
- * Data area reserved for FWNMI option.
- * This address (0x7000) is fixed by the RPA.
- */
-       .= 0x7000
-       .globl fwnmi_data_area
-fwnmi_data_area:
-#endif /* CONFIG_PPC_PSERIES */
-
-       /* iSeries does not use the FWNMI stuff, so it is safe to put
-        * this here, even if we later allow kernels that will boot on
-        * both pSeries and iSeries */
-#ifdef CONFIG_PPC_ISERIES
-        . = LPARMAP_PHYS
-       .globl xLparMap
-xLparMap:
-       .quad   HvEsidsToMap            /* xNumberEsids */
-       .quad   HvRangesToMap           /* xNumberRanges */
-       .quad   STAB0_PAGE              /* xSegmentTableOffs */
-       .zero   40                      /* xRsvd */
-       /* xEsids (HvEsidsToMap entries of 2 quads) */
-       .quad   PAGE_OFFSET_ESID        /* xKernelEsid */
-       .quad   PAGE_OFFSET_VSID        /* xKernelVsid */
-       .quad   VMALLOC_START_ESID      /* xKernelEsid */
-       .quad   VMALLOC_START_VSID      /* xKernelVsid */
-       /* xRanges (HvRangesToMap entries of 3 quads) */
-       .quad   HvPagesToMap            /* xPages */
-       .quad   0                       /* xOffset */
-       .quad   PAGE_OFFSET_VSID << (SID_SHIFT - HW_PAGE_SHIFT) /* xVPN */
-
-#endif /* CONFIG_PPC_ISERIES */
-
-#ifdef CONFIG_PPC_PSERIES
-        . = 0x8000
-#endif /* CONFIG_PPC_PSERIES */
 
 /*
  * On pSeries and most other platforms, secondary processors spin
index 95f39f1..5f9febc 100644 (file)
@@ -256,7 +256,7 @@ label:
         * off DE in the DSRR1 value and clearing the debug status.           \
         */                                                                   \
        mfspr   r10,SPRN_DBSR;          /* check single-step/branch taken */  \
-       andis.  r10,r10,DBSR_IC@h;                                            \
+       andis.  r10,r10,(DBSR_IC|DBSR_BT)@h;                                  \
        beq+    2f;                                                           \
                                                                              \
        lis     r10,KERNELBASE@h;       /* check if exception in vectors */   \
@@ -271,7 +271,7 @@ label:
                                                                              \
        /* here it looks like we got an inappropriate debug exception. */     \
 1:     rlwinm  r9,r9,0,~MSR_DE;        /* clear DE in the CDRR1 value */     \
-       lis     r10,DBSR_IC@h;          /* clear the IC event */              \
+       lis     r10,(DBSR_IC|DBSR_BT)@h;        /* clear the IC event */      \
        mtspr   SPRN_DBSR,r10;                                                \
        /* restore state and get out */                                       \
        lwz     r10,_CCR(r11);                                                \
@@ -309,7 +309,7 @@ label:
         * off DE in the CSRR1 value and clearing the debug status.           \
         */                                                                   \
        mfspr   r10,SPRN_DBSR;          /* check single-step/branch taken */  \
-       andis.  r10,r10,DBSR_IC@h;                                            \
+       andis.  r10,r10,(DBSR_IC|DBSR_BT)@h;                                  \
        beq+    2f;                                                           \
                                                                              \
        lis     r10,KERNELBASE@h;       /* check if exception in vectors */   \
@@ -317,14 +317,14 @@ label:
        cmplw   r12,r10;                                                      \
        blt+    2f;                     /* addr below exception vectors */    \
                                                                              \
-       lis     r10,DebugCrit@h;                                                      \
+       lis     r10,DebugCrit@h;                                              \
        ori     r10,r10,DebugCrit@l;                                          \
        cmplw   r12,r10;                                                      \
        bgt+    2f;                     /* addr above exception vectors */    \
                                                                              \
        /* here it looks like we got an inappropriate debug exception. */     \
 1:     rlwinm  r9,r9,0,~MSR_DE;        /* clear DE in the CSRR1 value */     \
-       lis     r10,DBSR_IC@h;          /* clear the IC event */              \
+       lis     r10,(DBSR_IC|DBSR_BT)@h;        /* clear the IC event */      \
        mtspr   SPRN_DBSR,r10;                                                \
        /* restore state and get out */                                       \
        lwz     r10,_CCR(r11);                                                \
index 844d3f8..f7f376e 100644 (file)
@@ -118,6 +118,7 @@ notrace void raw_local_irq_restore(unsigned long en)
        if (!en)
                return;
 
+#ifdef CONFIG_PPC_STD_MMU_64
        if (firmware_has_feature(FW_FEATURE_ISERIES)) {
                /*
                 * Do we need to disable preemption here?  Not really: in the
@@ -135,6 +136,7 @@ notrace void raw_local_irq_restore(unsigned long en)
                if (local_paca->lppaca_ptr->int_dword.any_int)
                        iseries_handle_interrupts();
        }
+#endif /* CONFIG_PPC_STD_MMU_64 */
 
        if (test_perf_counter_pending()) {
                clear_perf_counter_pending();
@@ -254,77 +256,84 @@ void fixup_irqs(cpumask_t map)
 }
 #endif
 
-void do_IRQ(struct pt_regs *regs)
-{
-       struct pt_regs *old_regs = set_irq_regs(regs);
-       unsigned int irq;
 #ifdef CONFIG_IRQSTACKS
+static inline void handle_one_irq(unsigned int irq)
+{
        struct thread_info *curtp, *irqtp;
-#endif
+       unsigned long saved_sp_limit;
+       struct irq_desc *desc;
 
-       irq_enter();
+       /* Switch to the irq stack to handle this */
+       curtp = current_thread_info();
+       irqtp = hardirq_ctx[smp_processor_id()];
+
+       if (curtp == irqtp) {
+               /* We're already on the irq stack, just handle it */
+               generic_handle_irq(irq);
+               return;
+       }
+
+       desc = irq_desc + irq;
+       saved_sp_limit = current->thread.ksp_limit;
+
+       irqtp->task = curtp->task;
+       irqtp->flags = 0;
+
+       /* Copy the softirq bits in preempt_count so that the
+        * softirq checks work in the hardirq context. */
+       irqtp->preempt_count = (irqtp->preempt_count & ~SOFTIRQ_MASK) |
+                              (curtp->preempt_count & SOFTIRQ_MASK);
+
+       current->thread.ksp_limit = (unsigned long)irqtp +
+               _ALIGN_UP(sizeof(struct thread_info), 16);
+
+       call_handle_irq(irq, desc, irqtp, desc->handle_irq);
+       current->thread.ksp_limit = saved_sp_limit;
+       irqtp->task = NULL;
+
+       /* Set any flag that may have been set on the
+        * alternate stack
+        */
+       if (irqtp->flags)
+               set_bits(irqtp->flags, &curtp->flags);
+}
+#else
+static inline void handle_one_irq(unsigned int irq)
+{
+       generic_handle_irq(irq);
+}
+#endif
 
+static inline void check_stack_overflow(void)
+{
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
-       /* Debugging check for stack overflow: is there less than 2KB free? */
-       {
-               long sp;
+       long sp;
 
-               sp = __get_SP() & (THREAD_SIZE-1);
+       sp = __get_SP() & (THREAD_SIZE-1);
 
-               if (unlikely(sp < (sizeof(struct thread_info) + 2048))) {
-                       printk("do_IRQ: stack overflow: %ld\n",
-                               sp - sizeof(struct thread_info));
-                       dump_stack();
-               }
+       /* check for stack overflow: is there less than 2KB free? */
+       if (unlikely(sp < (sizeof(struct thread_info) + 2048))) {
+               printk("do_IRQ: stack overflow: %ld\n",
+                       sp - sizeof(struct thread_info));
+               dump_stack();
        }
 #endif
+}
 
-       /*
-        * Every platform is required to implement ppc_md.get_irq.
-        * This function will either return an irq number or NO_IRQ to
-        * indicate there are no more pending.
-        * The value NO_IRQ_IGNORE is for buggy hardware and means that this
-        * IRQ has already been handled. -- Tom
-        */
-       irq = ppc_md.get_irq();
+void do_IRQ(struct pt_regs *regs)
+{
+       struct pt_regs *old_regs = set_irq_regs(regs);
+       unsigned int irq;
 
-       if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) {
-#ifdef CONFIG_IRQSTACKS
-               /* Switch to the irq stack to handle this */
-               curtp = current_thread_info();
-               irqtp = hardirq_ctx[smp_processor_id()];
-               if (curtp != irqtp) {
-                       struct irq_desc *desc = irq_desc + irq;
-                       void *handler = desc->handle_irq;
-                       unsigned long saved_sp_limit = current->thread.ksp_limit;
-                       if (handler == NULL)
-                               handler = &__do_IRQ;
-                       irqtp->task = curtp->task;
-                       irqtp->flags = 0;
-
-                       /* Copy the softirq bits in preempt_count so that the
-                        * softirq checks work in the hardirq context.
-                        */
-                       irqtp->preempt_count =
-                               (irqtp->preempt_count & ~SOFTIRQ_MASK) |
-                               (curtp->preempt_count & SOFTIRQ_MASK);
+       irq_enter();
 
-                       current->thread.ksp_limit = (unsigned long)irqtp +
-                               _ALIGN_UP(sizeof(struct thread_info), 16);
-                       call_handle_irq(irq, desc, irqtp, handler);
-                       current->thread.ksp_limit = saved_sp_limit;
-                       irqtp->task = NULL;
+       check_stack_overflow();
 
+       irq = ppc_md.get_irq();
 
-                       /* Set any flag that may have been set on the
-                        * alternate stack
-                        */
-                       if (irqtp->flags)
-                               set_bits(irqtp->flags, &curtp->flags);
-               } else
-#endif
-                       generic_handle_irq(irq);
-       } else if (irq != NO_IRQ_IGNORE)
+       if (irq != NO_IRQ && irq != NO_IRQ_IGNORE)
+               handle_one_irq(irq);
+       else if (irq != NO_IRQ_IGNORE)
                /* That's not SMP safe ... but who cares ? */
                ppc_spurious_interrupts++;
 
index 78b3f78..2419cc7 100644 (file)
@@ -169,6 +169,9 @@ struct hvcall_ppp_data {
        u8      unallocated_weight;
        u16     active_procs_in_pool;
        u16     active_system_procs;
+       u16     phys_platform_procs;
+       u32     max_proc_cap_avail;
+       u32     entitled_proc_cap_avail;
 };
 
 /*
@@ -190,13 +193,18 @@ struct hvcall_ppp_data {
  *            XX - Unallocated Variable Processor Capacity Weight.
  *              XXXX - Active processors in Physical Processor Pool.
  *                  XXXX  - Processors active on platform.
+ *  R8 (QQQQRRRRRRSSSSSS). if ibm,partition-performance-parameters-level >= 1
+ *     XXXX - Physical platform procs allocated to virtualization.
+ *         XXXXXX - Max procs capacity % available to the partitions pool.
+ *               XXXXXX - Entitled procs capacity % available to the
+ *                        partitions pool.
  */
 static unsigned int h_get_ppp(struct hvcall_ppp_data *ppp_data)
 {
        unsigned long rc;
-       unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+       unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
 
-       rc = plpar_hcall(H_GET_PPP, retbuf);
+       rc = plpar_hcall9(H_GET_PPP, retbuf);
 
        ppp_data->entitlement = retbuf[0];
        ppp_data->unallocated_entitlement = retbuf[1];
@@ -210,6 +218,10 @@ static unsigned int h_get_ppp(struct hvcall_ppp_data *ppp_data)
        ppp_data->active_procs_in_pool = (retbuf[3] >> 2 * 8) & 0xffff;
        ppp_data->active_system_procs = retbuf[3] & 0xffff;
 
+       ppp_data->phys_platform_procs = retbuf[4] >> 6 * 8;
+       ppp_data->max_proc_cap_avail = (retbuf[4] >> 3 * 8) & 0xffffff;
+       ppp_data->entitled_proc_cap_avail = retbuf[4] & 0xffffff;
+
        return rc;
 }
 
@@ -234,6 +246,8 @@ static unsigned h_pic(unsigned long *pool_idle_time,
 static void parse_ppp_data(struct seq_file *m)
 {
        struct hvcall_ppp_data ppp_data;
+       struct device_node *root;
+       const int *perf_level;
        int rc;
 
        rc = h_get_ppp(&ppp_data);
@@ -267,6 +281,28 @@ static void parse_ppp_data(struct seq_file *m)
        seq_printf(m, "capped=%d\n", ppp_data.capped);
        seq_printf(m, "unallocated_capacity=%lld\n",
                   ppp_data.unallocated_entitlement);
+
+       /* The last bits of information returned from h_get_ppp are only
+        * valid if the ibm,partition-performance-parameters-level
+        * property is >= 1.
+        */
+       root = of_find_node_by_path("/");
+       if (root) {
+               perf_level = of_get_property(root,
+                               "ibm,partition-performance-parameters-level",
+                                            NULL);
+               if (perf_level && (*perf_level >= 1)) {
+                       seq_printf(m,
+                           "physical_procs_allocated_to_virtualization=%d\n",
+                                  ppp_data.phys_platform_procs);
+                       seq_printf(m, "max_proc_capacity_available=%d\n",
+                                  ppp_data.max_proc_cap_avail);
+                       seq_printf(m, "entitled_proc_capacity_available=%d\n",
+                                  ppp_data.entitled_proc_cap_avail);
+               }
+
+               of_node_put(root);
+       }
 }
 
 /**
index b9530b2..a5cf9c1 100644 (file)
@@ -457,98 +457,6 @@ _GLOBAL(disable_kernel_fp)
        isync
        blr
 
-#ifdef CONFIG_ALTIVEC
-
-#if 0 /* this has no callers for now */
-/*
- * disable_kernel_altivec()
- * Disable the VMX.
- */
-_GLOBAL(disable_kernel_altivec)
-       mfmsr   r3
-       rldicl  r0,r3,(63-MSR_VEC_LG),1
-       rldicl  r3,r0,(MSR_VEC_LG+1),0
-       mtmsrd  r3                      /* disable use of VMX now */
-       isync
-       blr
-#endif /* 0 */
-
-/*
- * giveup_altivec(tsk)
- * Disable VMX for the task given as the argument,
- * and save the vector registers in its thread_struct.
- * Enables the VMX for use in the kernel on return.
- */
-_GLOBAL(giveup_altivec)
-       mfmsr   r5
-       oris    r5,r5,MSR_VEC@h
-       mtmsrd  r5                      /* enable use of VMX now */
-       isync
-       cmpdi   0,r3,0
-       beqlr-                          /* if no previous owner, done */
-       addi    r3,r3,THREAD            /* want THREAD of task */
-       ld      r5,PT_REGS(r3)
-       cmpdi   0,r5,0
-       SAVE_32VRS(0,r4,r3)
-       mfvscr  vr0
-       li      r4,THREAD_VSCR
-       stvx    vr0,r4,r3
-       beq     1f
-       ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-#ifdef CONFIG_VSX
-BEGIN_FTR_SECTION
-       lis     r3,(MSR_VEC|MSR_VSX)@h
-FTR_SECTION_ELSE
-       lis     r3,MSR_VEC@h
-ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX)
-#else
-       lis     r3,MSR_VEC@h
-#endif
-       andc    r4,r4,r3                /* disable FP for previous task */
-       std     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
-       li      r5,0
-       ld      r4,last_task_used_altivec@got(r2)
-       std     r5,0(r4)
-#endif /* CONFIG_SMP */
-       blr
-
-#endif /* CONFIG_ALTIVEC */
-
-#ifdef CONFIG_VSX
-/*
- * __giveup_vsx(tsk)
- * Disable VSX for the task given as the argument.
- * Does NOT save vsx registers.
- * Enables the VSX for use in the kernel on return.
- */
-_GLOBAL(__giveup_vsx)
-       mfmsr   r5
-       oris    r5,r5,MSR_VSX@h
-       mtmsrd  r5                      /* enable use of VSX now */
-       isync
-
-       cmpdi   0,r3,0
-       beqlr-                          /* if no previous owner, done */
-       addi    r3,r3,THREAD            /* want THREAD of task */
-       ld      r5,PT_REGS(r3)
-       cmpdi   0,r5,0
-       beq     1f
-       ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-       lis     r3,MSR_VSX@h
-       andc    r4,r4,r3                /* disable VSX for previous task */
-       std     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
-       li      r5,0
-       ld      r4,last_task_used_vsx@got(r2)
-       std     r5,0(r4)
-#endif /* CONFIG_SMP */
-       blr
-
-#endif /* CONFIG_VSX */
-
 /* kexec_wait(phys_cpu)
  *
  * wait for the flag to change, indicating this kernel is going away but
index c744b32..e9962c7 100644 (file)
@@ -18,6 +18,8 @@
  * field correctly */
 extern unsigned long __toc_start;
 
+#ifdef CONFIG_PPC_BOOK3S
+
 /*
  * The structure which the hypervisor knows about - this structure
  * should not cross a page boundary.  The vpa_init/register_vpa call
@@ -41,6 +43,10 @@ struct lppaca lppaca[] = {
        },
 };
 
+#endif /* CONFIG_PPC_BOOK3S */
+
+#ifdef CONFIG_PPC_STD_MMU_64
+
 /*
  * 3 persistent SLBs are registered here.  The buffer will be zero
  * initially, hence will all be invaild until we actually write them.
@@ -52,6 +58,8 @@ struct slb_shadow slb_shadow[] __cacheline_aligned = {
        },
 };
 
+#endif /* CONFIG_PPC_STD_MMU_64 */
+
 /* The Paca is an array with one entry per processor.  Each contains an
  * lppaca, which contains the information shared between the
  * hypervisor and Linux.
@@ -77,15 +85,19 @@ void __init initialise_pacas(void)
        for (cpu = 0; cpu < NR_CPUS; cpu++) {
                struct paca_struct *new_paca = &paca[cpu];
 
+#ifdef CONFIG_PPC_BOOK3S
                new_paca->lppaca_ptr = &lppaca[cpu];
+#endif
                new_paca->lock_token = 0x8000;
                new_paca->paca_index = cpu;
                new_paca->kernel_toc = kernel_toc;
                new_paca->kernelbase = (unsigned long) _stext;
                new_paca->kernel_msr = MSR_KERNEL;
                new_paca->hw_cpu_id = 0xffff;
-               new_paca->slb_shadow_ptr = &slb_shadow[cpu];
                new_paca->__current = &init_task;
+#ifdef CONFIG_PPC_STD_MMU_64
+               new_paca->slb_shadow_ptr = &slb_shadow[cpu];
+#endif /* CONFIG_PPC_STD_MMU_64 */
 
        }
 }
index 4fee63c..5a56e97 100644 (file)
@@ -1505,7 +1505,7 @@ void __init pcibios_resource_survey(void)
  * rest of the code later, for now, keep it as-is as our main
  * resource allocation function doesn't deal with sub-trees yet.
  */
-void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
+void pcibios_claim_one_bus(struct pci_bus *bus)
 {
        struct pci_dev *dev;
        struct pci_bus *child_bus;
@@ -1533,7 +1533,6 @@ void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
        list_for_each_entry(child_bus, &bus->children, node)
                pcibios_claim_one_bus(child_bus);
 }
-EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
 
 
 /* pcibios_finish_adding_to_bus
index d473634..3ae1c66 100644 (file)
@@ -33,7 +33,6 @@ int pcibios_assign_bus_offset = 1;
 
 void pcibios_make_OF_bus_map(void);
 
-static void fixup_broken_pcnet32(struct pci_dev* dev);
 static void fixup_cpc710_pci64(struct pci_dev* dev);
 #ifdef CONFIG_PPC_OF
 static u8* pci_to_OF_bus_map;
@@ -72,16 +71,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MOTOROLA, PCI_ANY_ID, fixup_hide_host_res
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, fixup_hide_host_resource_fsl); 
 
 static void
-fixup_broken_pcnet32(struct pci_dev* dev)
-{
-       if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
-               dev->vendor = PCI_VENDOR_ID_AMD;
-               pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
-       }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT,        PCI_ANY_ID,                     fixup_broken_pcnet32);
-
-static void
 fixup_cpc710_pci64(struct pci_dev* dev)
 {
        /* Hide the PCI64 BARs from the kernel as their content doesn't
@@ -447,14 +436,6 @@ static int __init pcibios_init(void)
 
 subsys_initcall(pcibios_init);
 
-/* the next one is stolen from the alpha port... */
-void __init
-pcibios_update_irq(struct pci_dev *dev, int irq)
-{
-       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-       /* XXX FIXME - update OF device tree node interrupt property */
-}
-
 static struct pci_controller*
 pci_bus_to_hose(int bus)
 {
index 96edb6f..9e8902f 100644 (file)
@@ -43,16 +43,6 @@ unsigned long pci_probe_only = 1;
 unsigned long pci_io_base = ISA_IO_BASE;
 EXPORT_SYMBOL(pci_io_base);
 
-static void fixup_broken_pcnet32(struct pci_dev* dev)
-{
-       if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
-               dev->vendor = PCI_VENDOR_ID_AMD;
-               pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
-       }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32);
-
-
 static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
 {
        const u32 *prop;
@@ -430,6 +420,9 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
         * so flushing the hash table is the only sane way to make sure
         * that no hash entries are covering that removed bridge area
         * while still allowing other busses overlapping those pages
+        *
+        * Note: If we ever support P2P hotplug on Book3E, we'll have
+        * to do an appropriate TLB flush here too
         */
        if (bus->self) {
                struct resource *res = bus->resource[0];
@@ -437,8 +430,10 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
                pr_debug("IO unmapping for PCI-PCI bridge %s\n",
                         pci_name(bus->self));
 
+#ifdef CONFIG_PPC_STD_MMU_64
                __flush_hash_table_range(&init_mm, res->start + _IO_BASE,
                                         res->end + _IO_BASE + 1);
+#endif
                return 0;
        }
 
@@ -511,7 +506,7 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
        pr_debug("IO mapping for PHB %s\n", hose->dn->full_name);
        pr_debug("  phys=0x%016llx, virt=0x%p (alloc=0x%p)\n",
                 hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc);
-       pr_debug("  size=0x%016lx (alloc=0x%016lx)\n",
+       pr_debug("  size=0x%016llx (alloc=0x%016lx)\n",
                 hose->pci_io_size, size_page);
 
        /* Establish the mapping */
index 1c67de5..d5e36e5 100644 (file)
@@ -27,7 +27,6 @@
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
-#include <asm/pSeries_reconfig.h>
 #include <asm/ppc-pci.h>
 #include <asm/firmware.h>
 
@@ -35,7 +34,7 @@
  * Traverse_func that inits the PCI fields of the device node.
  * NOTE: this *must* be done before read/write config to the device.
  */
-static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
+void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
 {
        struct pci_controller *phb = data;
        const int *type =
@@ -184,29 +183,6 @@ struct device_node *fetch_dev_dn(struct pci_dev *dev)
 }
 EXPORT_SYMBOL(fetch_dev_dn);
 
-static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
-{
-       struct device_node *np = node;
-       struct pci_dn *pci = NULL;
-       int err = NOTIFY_OK;
-
-       switch (action) {
-       case PSERIES_RECONFIG_ADD:
-               pci = np->parent->data;
-               if (pci)
-                       update_dn_pci_info(np, pci->phb);
-               break;
-       default:
-               err = NOTIFY_DONE;
-               break;
-       }
-       return err;
-}
-
-static struct notifier_block pci_dn_reconfig_nb = {
-       .notifier_call = pci_dn_reconfig_notifier,
-};
-
 /** 
  * pci_devs_phb_init - Initialize phbs and pci devs under them.
  * 
@@ -223,6 +199,4 @@ void __init pci_devs_phb_init(void)
        /* This must be done first so the device nodes have valid pci info! */
        list_for_each_entry_safe(phb, tmp, &hose_list, list_node)
                pci_devs_phb_init_dynamic(phb);
-
-       pSeries_reconfig_notifier_register(&pci_dn_reconfig_nb);
 }
index 7b44a33..3e7135b 100644 (file)
@@ -650,7 +650,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
        p->thread.ksp_limit = (unsigned long)task_stack_page(p) +
                                _ALIGN_UP(sizeof(struct thread_info), 16);
 
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC_STD_MMU_64
        if (cpu_has_feature(CPU_FTR_SLB)) {
                unsigned long sp_vsid;
                unsigned long llp = mmu_psize_defs[mmu_linear_psize].sllp;
index ce01ff2..d4405b9 100644 (file)
@@ -585,7 +585,7 @@ static void __init check_cpu_pa_features(unsigned long node)
                      ibm_pa_features, ARRAY_SIZE(ibm_pa_features));
 }
 
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC_STD_MMU_64
 static void __init check_cpu_slb_size(unsigned long node)
 {
        u32 *slb_size_ptr;
index 3635be6..9fa2c7d 100644 (file)
@@ -704,15 +704,34 @@ void user_enable_single_step(struct task_struct *task)
 
        if (regs != NULL) {
 #if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+               task->thread.dbcr0 &= ~DBCR0_BT;
                task->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC;
                regs->msr |= MSR_DE;
 #else
+               regs->msr &= ~MSR_BE;
                regs->msr |= MSR_SE;
 #endif
        }
        set_tsk_thread_flag(task, TIF_SINGLESTEP);
 }
 
+void user_enable_block_step(struct task_struct *task)
+{
+       struct pt_regs *regs = task->thread.regs;
+
+       if (regs != NULL) {
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+               task->thread.dbcr0 &= ~DBCR0_IC;
+               task->thread.dbcr0 = DBCR0_IDM | DBCR0_BT;
+               regs->msr |= MSR_DE;
+#else
+               regs->msr &= ~MSR_SE;
+               regs->msr |= MSR_BE;
+#endif
+       }
+       set_tsk_thread_flag(task, TIF_SINGLESTEP);
+}
+
 void user_disable_single_step(struct task_struct *task)
 {
        struct pt_regs *regs = task->thread.regs;
@@ -726,10 +745,10 @@ void user_disable_single_step(struct task_struct *task)
 
        if (regs != NULL) {
 #if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
-               task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_IDM);
+               task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM);
                regs->msr &= ~MSR_DE;
 #else
-               regs->msr &= ~MSR_SE;
+               regs->msr &= ~(MSR_SE | MSR_BE);
 #endif
        }
        clear_tsk_thread_flag(task, TIF_SINGLESTEP);
index 8869001..54e66da 100644 (file)
@@ -93,10 +93,7 @@ static int rtas_pci_read_config(struct pci_bus *bus,
 {
        struct device_node *busdn, *dn;
 
-       if (bus->self)
-               busdn = pci_device_to_OF_node(bus->self);
-       else
-               busdn = bus->sysdata;   /* must be a phb */
+       busdn = pci_bus_to_OF_node(bus);
 
        /* Search only direct children of the bus */
        for (dn = busdn->child; dn; dn = dn->sibling) {
@@ -140,10 +137,7 @@ static int rtas_pci_write_config(struct pci_bus *bus,
 {
        struct device_node *busdn, *dn;
 
-       if (bus->self)
-               busdn = pci_device_to_OF_node(bus->self);
-       else
-               busdn = bus->sysdata;   /* must be a phb */
+       busdn = pci_bus_to_OF_node(bus);
 
        /* Search only direct children of the bus */
        for (dn = busdn->child; dn; dn = dn->sibling) {
index 9e1ca74..1d15424 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/serial.h>
 #include <asm/udbg.h>
 #include <asm/mmu_context.h>
+#include <asm/swiotlb.h>
 
 #include "setup.h"
 
@@ -332,6 +333,11 @@ void __init setup_arch(char **cmdline_p)
                ppc_md.setup_arch();
        if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
 
+#ifdef CONFIG_SWIOTLB
+       if (ppc_swiotlb_enable)
+               swiotlb_init();
+#endif
+
        paging_init();
 
        /* Initialize the MMU context management stuff */
index c410c60..f46548e 100644 (file)
@@ -61,6 +61,7 @@
 #include <asm/xmon.h>
 #include <asm/udbg.h>
 #include <asm/kexec.h>
+#include <asm/swiotlb.h>
 
 #include "setup.h"
 
@@ -417,9 +418,11 @@ void __init setup_system(void)
        if (ppc64_caches.iline_size != 0x80)
                printk("ppc64_caches.icache_line_size = 0x%x\n",
                       ppc64_caches.iline_size);
+#ifdef CONFIG_PPC_STD_MMU_64
        if (htab_address)
                printk("htab_address                  = 0x%p\n", htab_address);
        printk("htab_hash_mask                = 0x%lx\n", htab_hash_mask);
+#endif /* CONFIG_PPC_STD_MMU_64 */
        if (PHYSICAL_START > 0)
                printk("physical_start                = 0x%lx\n",
                       PHYSICAL_START);
@@ -511,8 +514,9 @@ void __init setup_arch(char **cmdline_p)
        irqstack_early_init();
        emergency_stack_init();
 
+#ifdef CONFIG_PPC_STD_MMU_64
        stabs_alloc();
-
+#endif
        /* set up the bootmem stuff with available memory */
        do_init_bootmem();
        sparse_init();
@@ -524,6 +528,11 @@ void __init setup_arch(char **cmdline_p)
        if (ppc_md.setup_arch)
                ppc_md.setup_arch();
 
+#ifdef CONFIG_SWIOTLB
+       if (ppc_swiotlb_enable)
+               swiotlb_init();
+#endif
+
        paging_init();
        ppc64_boot_msg(0x15, "Setup Done");
 }
index 48571ac..bee1443 100644 (file)
@@ -109,7 +109,7 @@ static void decrementer_set_mode(enum clock_event_mode mode,
 static struct clock_event_device decrementer_clockevent = {
        .name           = "decrementer",
        .rating         = 200,
-       .shift          = 16,
+       .shift          = 0,    /* To be filled in */
        .mult           = 0,    /* To be filled in */
        .irq            = 0,
        .set_next_event = decrementer_set_next_event,
@@ -843,6 +843,22 @@ static void decrementer_set_mode(enum clock_event_mode mode,
                decrementer_set_next_event(DECREMENTER_MAX, dev);
 }
 
+static void __init setup_clockevent_multiplier(unsigned long hz)
+{
+       u64 mult, shift = 32;
+
+       while (1) {
+               mult = div_sc(hz, NSEC_PER_SEC, shift);
+               if (mult && (mult >> 32UL) == 0UL)
+                       break;
+
+               shift--;
+       }
+
+       decrementer_clockevent.shift = shift;
+       decrementer_clockevent.mult = mult;
+}
+
 static void register_decrementer_clockevent(int cpu)
 {
        struct clock_event_device *dec = &per_cpu(decrementers, cpu).event;
@@ -860,8 +876,7 @@ static void __init init_decrementer_clockevent(void)
 {
        int cpu = smp_processor_id();
 
-       decrementer_clockevent.mult = div_sc(ppc_tb_freq, NSEC_PER_SEC,
-                                            decrementer_clockevent.shift);
+       setup_clockevent_multiplier(ppc_tb_freq);
        decrementer_clockevent.max_delta_ns =
                clockevent_delta2ns(DECREMENTER_MAX, &decrementer_clockevent);
        decrementer_clockevent.min_delta_ns =
index 678fbff..6f0ae1a 100644 (file)
@@ -33,7 +33,9 @@
 #include <linux/backlight.h>
 #include <linux/bug.h>
 #include <linux/kdebug.h>
+#include <linux/debugfs.h>
 
+#include <asm/emulated_ops.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -757,36 +759,44 @@ static int emulate_instruction(struct pt_regs *regs)
 
        /* Emulate the mfspr rD, PVR. */
        if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) {
+               PPC_WARN_EMULATED(mfpvr);
                rd = (instword >> 21) & 0x1f;
                regs->gpr[rd] = mfspr(SPRN_PVR);
                return 0;
        }
 
        /* Emulating the dcba insn is just a no-op.  */
-       if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA)
+       if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) {
+               PPC_WARN_EMULATED(dcba);
                return 0;
+       }
 
        /* Emulate the mcrxr insn.  */
        if ((instword & PPC_INST_MCRXR_MASK) == PPC_INST_MCRXR) {
                int shift = (instword >> 21) & 0x1c;
                unsigned long msk = 0xf0000000UL >> shift;
 
+               PPC_WARN_EMULATED(mcrxr);
                regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk);
                regs->xer &= ~0xf0000000UL;
                return 0;
        }
 
        /* Emulate load/store string insn. */
-       if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING)
+       if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) {
+               PPC_WARN_EMULATED(string);
                return emulate_string_inst(regs, instword);
+       }
 
        /* Emulate the popcntb (Population Count Bytes) instruction. */
        if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) {
+               PPC_WARN_EMULATED(popcntb);
                return emulate_popcntb_inst(regs, instword);
        }
 
        /* Emulate isel (Integer Select) instruction */
        if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) {
+               PPC_WARN_EMULATED(isel);
                return emulate_isel(regs, instword);
        }
 
@@ -984,6 +994,8 @@ void SoftwareEmulation(struct pt_regs *regs)
 
 #ifdef CONFIG_MATH_EMULATION
        errcode = do_mathemu(regs);
+       if (errcode >= 0)
+               PPC_WARN_EMULATED(math);
 
        switch (errcode) {
        case 0:
@@ -1005,6 +1017,9 @@ void SoftwareEmulation(struct pt_regs *regs)
 
 #elif defined(CONFIG_8XX_MINIMAL_FPEMU)
        errcode = Soft_emulate_8xx(regs);
+       if (errcode >= 0)
+               PPC_WARN_EMULATED(8xx);
+
        switch (errcode) {
        case 0:
                emulate_single_step(regs);
@@ -1026,7 +1041,34 @@ void SoftwareEmulation(struct pt_regs *regs)
 
 void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
 {
-       if (debug_status & DBSR_IC) {   /* instruction completion */
+       /* 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
+        * the server behaviour, we thus restart right away with a single step
+        * instead of stopping here when hitting a BT
+        */
+       if (debug_status & DBSR_BT) {
+               regs->msr &= ~MSR_DE;
+
+               /* Disable BT */
+               mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_BT);
+               /* Clear the BT event */
+               mtspr(SPRN_DBSR, DBSR_BT);
+
+               /* 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;
+                       regs->msr |= MSR_DE;
+                       return;
+               }
+
+               if (notify_die(DIE_SSTEP, "block_step", regs, 5,
+                              5, SIGTRAP) == NOTIFY_STOP) {
+                       return;
+               }
+               if (debugger_sstep(regs))
+                       return;
+       } else if (debug_status & DBSR_IC) {    /* Instruction complete */
                regs->msr &= ~MSR_DE;
 
                /* Disable instruction completion */
@@ -1042,9 +1084,8 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
                if (debugger_sstep(regs))
                        return;
 
-               if (user_mode(regs)) {
-                       current->thread.dbcr0 &= ~DBCR0_IC;
-               }
+               if (user_mode(regs))
+                       current->thread.dbcr0 &= ~(DBCR0_IC);
 
                _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
        } else if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) {
@@ -1088,6 +1129,7 @@ void altivec_assist_exception(struct pt_regs *regs)
 
        flush_altivec_to_thread(current);
 
+       PPC_WARN_EMULATED(altivec);
        err = emulate_altivec(regs);
        if (err == 0) {
                regs->nip += 4;         /* skip emulated instruction */
@@ -1286,3 +1328,79 @@ void kernel_bad_stack(struct pt_regs *regs)
 void __init trap_init(void)
 {
 }
+
+
+#ifdef CONFIG_PPC_EMULATED_STATS
+
+#define WARN_EMULATED_SETUP(type)      .type = { .name = #type }
+
+struct ppc_emulated ppc_emulated = {
+#ifdef CONFIG_ALTIVEC
+       WARN_EMULATED_SETUP(altivec),
+#endif
+       WARN_EMULATED_SETUP(dcba),
+       WARN_EMULATED_SETUP(dcbz),
+       WARN_EMULATED_SETUP(fp_pair),
+       WARN_EMULATED_SETUP(isel),
+       WARN_EMULATED_SETUP(mcrxr),
+       WARN_EMULATED_SETUP(mfpvr),
+       WARN_EMULATED_SETUP(multiple),
+       WARN_EMULATED_SETUP(popcntb),
+       WARN_EMULATED_SETUP(spe),
+       WARN_EMULATED_SETUP(string),
+       WARN_EMULATED_SETUP(unaligned),
+#ifdef CONFIG_MATH_EMULATION
+       WARN_EMULATED_SETUP(math),
+#elif defined(CONFIG_8XX_MINIMAL_FPEMU)
+       WARN_EMULATED_SETUP(8xx),
+#endif
+#ifdef CONFIG_VSX
+       WARN_EMULATED_SETUP(vsx),
+#endif
+};
+
+u32 ppc_warn_emulated;
+
+void ppc_warn_emulated_print(const char *type)
+{
+       if (printk_ratelimit())
+               pr_warning("%s used emulated %s instruction\n", current->comm,
+                          type);
+}
+
+static int __init ppc_warn_emulated_init(void)
+{
+       struct dentry *dir, *d;
+       unsigned int i;
+       struct ppc_emulated_entry *entries = (void *)&ppc_emulated;
+
+       if (!powerpc_debugfs_root)
+               return -ENODEV;
+
+       dir = debugfs_create_dir("emulated_instructions",
+                                powerpc_debugfs_root);
+       if (!dir)
+               return -ENOMEM;
+
+       d = debugfs_create_u32("do_warn", S_IRUGO | S_IWUSR, dir,
+                              &ppc_warn_emulated);
+       if (!d)
+               goto fail;
+
+       for (i = 0; i < sizeof(ppc_emulated)/sizeof(*entries); i++) {
+               d = debugfs_create_u32(entries[i].name, S_IRUGO | S_IWUSR, dir,
+                                      (u32 *)&entries[i].val.counter);
+               if (!d)
+                       goto fail;
+       }
+
+       return 0;
+
+fail:
+       debugfs_remove_recursive(dir);
+       return -ENOMEM;
+}
+
+device_initcall(ppc_warn_emulated_init);
+
+#endif /* CONFIG_PPC_EMULATED_STATS */
index 49ac3d6..ef36cbb 100644 (file)
@@ -1,5 +1,215 @@
+#include <asm/processor.h>
 #include <asm/ppc_asm.h>
 #include <asm/reg.h>
+#include <asm/asm-offsets.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/page.h>
+
+/*
+ * load_up_altivec(unused, unused, tsk)
+ * 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).
+ */
+_GLOBAL(load_up_altivec)
+       mfmsr   r5                      /* grab the current MSR */
+       oris    r5,r5,MSR_VEC@h
+       MTMSRD(r5)                      /* enable use of AltiVec now */
+       isync
+
+/*
+ * For SMP, we don't do lazy VMX switching because it just gets too
+ * horrendously complex, especially when a task switches from one CPU
+ * to another.  Instead we call giveup_altvec in switch_to.
+ * VRSAVE isn't dealt with here, that is done in the normal context
+ * switch code. Note that we could rely on vrsave value to eventually
+ * avoid saving all of the VREGs here...
+ */
+#ifndef CONFIG_SMP
+       LOAD_REG_ADDRBASE(r3, last_task_used_altivec)
+       toreal(r3)
+       PPC_LL  r4,ADDROFF(last_task_used_altivec)(r3)
+       PPC_LCMPI       0,r4,0
+       beq     1f
+
+       /* Save VMX state to last_task_used_altivec's THREAD struct */
+       toreal(r4)
+       addi    r4,r4,THREAD
+       SAVE_32VRS(0,r5,r4)
+       mfvscr  vr0
+       li      r10,THREAD_VSCR
+       stvx    vr0,r10,r4
+       /* Disable VMX for last_task_used_altivec */
+       PPC_LL  r5,PT_REGS(r4)
+       toreal(r5)
+       PPC_LL  r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+       lis     r10,MSR_VEC@h
+       andc    r4,r4,r10
+       PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#endif /* CONFIG_SMP */
+
+       /* Hack: if we get an altivec unavailable trap with VRSAVE
+        * set to all zeros, we assume this is a broken application
+        * that fails to set it properly, and thus we switch it to
+        * all 1's
+        */
+       mfspr   r4,SPRN_VRSAVE
+       cmpdi   0,r4,0
+       bne+    1f
+       li      r4,-1
+       mtspr   SPRN_VRSAVE,r4
+1:
+       /* enable use of VMX after return */
+#ifdef CONFIG_PPC32
+       mfspr   r5,SPRN_SPRG3           /* current task's THREAD (phys) */
+       oris    r9,r9,MSR_VEC@h
+#else
+       ld      r4,PACACURRENT(r13)
+       addi    r5,r4,THREAD            /* Get THREAD */
+       oris    r12,r12,MSR_VEC@h
+       std     r12,_MSR(r1)
+#endif
+       li      r4,1
+       li      r10,THREAD_VSCR
+       stw     r4,THREAD_USED_VR(r5)
+       lvx     vr0,r10,r5
+       mtvscr  vr0
+       REST_32VRS(0,r4,r5)
+#ifndef CONFIG_SMP
+       /* Update last_task_used_math to 'current' */
+       subi    r4,r5,THREAD            /* Back to 'current' */
+       fromreal(r4)
+       PPC_STL r4,ADDROFF(last_task_used_math)(r3)
+#endif /* CONFIG_SMP */
+       /* restore registers and return */
+       blr
+
+/*
+ * giveup_altivec(tsk)
+ * Disable VMX for the task given as the argument,
+ * and save the vector registers in its thread_struct.
+ * Enables the VMX for use in the kernel on return.
+ */
+_GLOBAL(giveup_altivec)
+       mfmsr   r5
+       oris    r5,r5,MSR_VEC@h
+       SYNC
+       MTMSRD(r5)                      /* enable use of VMX now */
+       isync
+       PPC_LCMPI       0,r3,0
+       beqlr-                          /* if no previous owner, done */
+       addi    r3,r3,THREAD            /* want THREAD of task */
+       PPC_LL  r5,PT_REGS(r3)
+       PPC_LCMPI       0,r5,0
+       SAVE_32VRS(0,r4,r3)
+       mfvscr  vr0
+       li      r4,THREAD_VSCR
+       stvx    vr0,r4,r3
+       beq     1f
+       PPC_LL  r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+#ifdef CONFIG_VSX
+BEGIN_FTR_SECTION
+       lis     r3,(MSR_VEC|MSR_VSX)@h
+FTR_SECTION_ELSE
+       lis     r3,MSR_VEC@h
+ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX)
+#else
+       lis     r3,MSR_VEC@h
+#endif
+       andc    r4,r4,r3                /* disable FP for previous task */
+       PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#ifndef CONFIG_SMP
+       li      r5,0
+       LOAD_REG_ADDRBASE(r4,last_task_used_altivec)
+       PPC_STL r5,ADDROFF(last_task_used_altivec)(r4)
+#endif /* CONFIG_SMP */
+       blr
+
+#ifdef CONFIG_VSX
+
+#ifdef CONFIG_PPC32
+#error This asm code isn't ready for 32-bit kernels
+#endif
+
+/*
+ * load_up_vsx(unused, unused, tsk)
+ * Disable VSX for the task which had it previously,
+ * and save its vector registers in its thread_struct.
+ * Reuse the fp and vsx saves, but first check to see if they have
+ * been saved already.
+ */
+_GLOBAL(load_up_vsx)
+/* Load FP and VSX registers if they haven't been done yet */
+       andi.   r5,r12,MSR_FP
+       beql+   load_up_fpu             /* skip if already loaded */
+       andis.  r5,r12,MSR_VEC@h
+       beql+   load_up_altivec         /* skip if already loaded */
+
+#ifndef CONFIG_SMP
+       ld      r3,last_task_used_vsx@got(r2)
+       ld      r4,0(r3)
+       cmpdi   0,r4,0
+       beq     1f
+       /* Disable VSX for last_task_used_vsx */
+       addi    r4,r4,THREAD
+       ld      r5,PT_REGS(r4)
+       ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+       lis     r6,MSR_VSX@h
+       andc    r6,r4,r6
+       std     r6,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#endif /* CONFIG_SMP */
+       ld      r4,PACACURRENT(r13)
+       addi    r4,r4,THREAD            /* Get THREAD */
+       li      r6,1
+       stw     r6,THREAD_USED_VSR(r4) /* ... also set thread used vsr */
+       /* enable use of VSX after return */
+       oris    r12,r12,MSR_VSX@h
+       std     r12,_MSR(r1)
+#ifndef CONFIG_SMP
+       /* Update last_task_used_math to 'current' */
+       ld      r4,PACACURRENT(r13)
+       std     r4,0(r3)
+#endif /* CONFIG_SMP */
+       b       fast_exception_return
+
+/*
+ * __giveup_vsx(tsk)
+ * Disable VSX for the task given as the argument.
+ * Does NOT save vsx registers.
+ * Enables the VSX for use in the kernel on return.
+ */
+_GLOBAL(__giveup_vsx)
+       mfmsr   r5
+       oris    r5,r5,MSR_VSX@h
+       mtmsrd  r5                      /* enable use of VSX now */
+       isync
+
+       cmpdi   0,r3,0
+       beqlr-                          /* if no previous owner, done */
+       addi    r3,r3,THREAD            /* want THREAD of task */
+       ld      r5,PT_REGS(r3)
+       cmpdi   0,r5,0
+       beq     1f
+       ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+       lis     r3,MSR_VSX@h
+       andc    r4,r4,r3                /* disable VSX for previous task */
+       std     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#ifndef CONFIG_SMP
+       li      r5,0
+       ld      r4,last_task_used_vsx@got(r2)
+       std     r5,0(r4)
+#endif /* CONFIG_SMP */
+       blr
+
+#endif /* CONFIG_VSX */
+
 
 /*
  * The routines below are in assembler so we can closely control the
index b746f4c..c4bcf07 100644 (file)
@@ -11,10 +11,11 @@ obj-y                               := fault.o mem.o pgtable.o gup.o \
                                   pgtable_$(CONFIG_WORD_SIZE).o
 obj-$(CONFIG_PPC_MMU_NOHASH)   += mmu_context_nohash.o tlb_nohash.o \
                                   tlb_nohash_low.o
-hash-$(CONFIG_PPC_NATIVE)      := hash_native_64.o
-obj-$(CONFIG_PPC64)            += hash_utils_64.o \
+obj-$(CONFIG_PPC64)            += mmap_64.o
+hash64-$(CONFIG_PPC_NATIVE)    := hash_native_64.o
+obj-$(CONFIG_PPC_STD_MMU_64)   += hash_utils_64.o \
                                   slb_low.o slb.o stab.o \
-                                  mmap_64.o $(hash-y)
+                                  mmap_64.o $(hash64-y)
 obj-$(CONFIG_PPC_STD_MMU_32)   += ppc_mmu_32.o
 obj-$(CONFIG_PPC_STD_MMU)      += hash_low_$(CONFIG_WORD_SIZE).o \
                                   tlb_hash$(CONFIG_WORD_SIZE).o \
index 34e5c0b..056d23a 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/cputable.h>
 #include <asm/udbg.h>
 #include <asm/kexec.h>
+#include <asm/ppc-opcode.h>
 
 #ifdef DEBUG_LOW
 #define DBG_LOW(fmt...) udbg_printf(fmt)
@@ -49,14 +50,21 @@ static inline void __tlbie(unsigned long va, int psize, int ssize)
        case MMU_PAGE_4K:
                va &= ~0xffful;
                va |= ssize << 8;
-               asm volatile("tlbie %0,0" : : "r" (va) : "memory");
+               asm volatile(ASM_MMU_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0),
+                                              %2)
+                            : : "r" (va), "r"(0), "i" (MMU_FTR_TLBIE_206)
+                            : "memory");
                break;
        default:
                penc = mmu_psize_defs[psize].penc;
                va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
                va |= penc << 12;
                va |= ssize << 8;
-               asm volatile("tlbie %0,1" : : "r" (va) : "memory");
+               va |= 1; /* L */
+               asm volatile(ASM_MMU_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0),
+                                              %2)
+                            : : "r" (va), "r"(0), "i" (MMU_FTR_TLBIE_206)
+                            : "memory");
                break;
        }
 }
@@ -80,6 +88,7 @@ static inline void __tlbiel(unsigned long va, int psize, int ssize)
                va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
                va |= penc << 12;
                va |= ssize << 8;
+               va |= 1; /* L */
                asm volatile(".long 0x7c000224 | (%0 << 11) | (1 << 21)"
                             : : "r"(va) : "memory");
                break;
index 3e6a654..68a821a 100644 (file)
@@ -66,6 +66,7 @@
 
 #include "mmu_decl.h"
 
+#ifdef CONFIG_PPC_STD_MMU_64
 #if PGTABLE_RANGE > USER_VSID_RANGE
 #warning Limited user VSID range means pagetable space is wasted
 #endif
@@ -73,6 +74,7 @@
 #if (TASK_SIZE_USER64 < PGTABLE_RANGE) && (TASK_SIZE_USER64 < USER_VSID_RANGE)
 #warning TASK_SIZE is smaller than it needs to be.
 #endif
+#endif /* CONFIG_PPC_STD_MMU_64 */
 
 phys_addr_t memstart_addr = ~0;
 phys_addr_t kernstart_addr;
index 030d000..8343986 100644 (file)
@@ -46,7 +46,7 @@ static unsigned int next_context, nr_free_contexts;
 static unsigned long *context_map;
 static unsigned long *stale_map[NR_CPUS];
 static struct mm_struct **context_mm;
-static spinlock_t context_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(context_lock);
 
 #define CTX_MAP_SIZE   \
        (sizeof(unsigned long) * (last_context / BITS_PER_LONG + 1))
@@ -73,7 +73,6 @@ static unsigned int steal_context_smp(unsigned int id)
        struct mm_struct *mm;
        unsigned int cpu, max;
 
- again:
        max = last_context - first_context;
 
        /* Attempt to free next_context first and then loop until we manage */
@@ -108,7 +107,9 @@ static unsigned int steal_context_smp(unsigned int id)
        spin_unlock(&context_lock);
        cpu_relax();
        spin_lock(&context_lock);
-       goto again;
+
+       /* This will cause the caller to try again */
+       return MMU_NO_CONTEXT;
 }
 #endif  /* CONFIG_SMP */
 
@@ -194,6 +195,8 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
                WARN_ON(prev->context.active < 1);
                prev->context.active--;
        }
+
+ again:
 #endif /* CONFIG_SMP */
 
        /* If we already have a valid assigned context, skip all that */
@@ -212,7 +215,8 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
 #ifdef CONFIG_SMP
                if (num_online_cpus() > 1) {
                        id = steal_context_smp(id);
-                       goto stolen;
+                       if (id == MMU_NO_CONTEXT)
+                               goto again;
                }
 #endif /* CONFIG_SMP */
                id = steal_context_up(id);
@@ -272,6 +276,7 @@ int init_new_context(struct task_struct *t, struct mm_struct *mm)
  */
 void destroy_context(struct mm_struct *mm)
 {
+       unsigned long flags;
        unsigned int id;
 
        if (mm->context.id == MMU_NO_CONTEXT)
@@ -279,18 +284,18 @@ void destroy_context(struct mm_struct *mm)
 
        WARN_ON(mm->context.active != 0);
 
-       spin_lock(&context_lock);
+       spin_lock_irqsave(&context_lock, flags);
        id = mm->context.id;
        if (id != MMU_NO_CONTEXT) {
                __clear_bit(id, context_map);
                mm->context.id = MMU_NO_CONTEXT;
 #ifdef DEBUG_MAP_CONSISTENCY
                mm->context.active = 0;
-               context_mm[id] = NULL;
 #endif
+               context_mm[id] = NULL;
                nr_free_contexts++;
        }
-       spin_unlock(&context_lock);
+       spin_unlock_irqrestore(&context_lock, flags);
 }
 
 #ifdef CONFIG_SMP
index 9047145..b037d95 100644 (file)
@@ -981,6 +981,8 @@ void __init do_init_bootmem(void)
                mark_reserved_regions_for_nid(nid);
                sparse_memory_present_with_active_regions(nid);
        }
+
+       init_bootmem_done = 1;
 }
 
 void __init paging_init(void)
index 91596f6..62312ab 100644 (file)
@@ -228,20 +228,6 @@ static void pmc_stop_ctrs(void)
        mtpmr(PMRN_PMGC0, pmgc0);
 }
 
-static void dump_pmcs(void)
-{
-       printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0));
-       printk("pmc\t\tpmlca\t\tpmlcb\n");
-       printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0),
-                       mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0));
-       printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1),
-                       mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1));
-       printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2),
-                       mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2));
-       printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3),
-                       mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3));
-}
-
 static int fsl_emb_cpu_setup(struct op_counter_config *ctr)
 {
        int i;
index f39c953..a6e43cb 100644 (file)
@@ -45,6 +45,7 @@ config KILAUEA
        depends on 40x
        default n
        select 405EX
+       select PPC40x_SIMPLE
        select PPC4xx_PCI_EXPRESS
        help
          This option enables support for the AMCC PPC405EX evaluation board.
@@ -56,6 +57,7 @@ config MAKALU
        select 405EX
        select PCI
        select PPC4xx_PCI_EXPRESS
+       select PPC40x_SIMPLE
        help
          This option enables support for the AMCC PPC405EX board.
 
index 9bab76a..56e8900 100644 (file)
@@ -1,6 +1,4 @@
-obj-$(CONFIG_KILAUEA)                          += kilauea.o
 obj-$(CONFIG_HCU4)                             += hcu4.o
-obj-$(CONFIG_MAKALU)                           += makalu.o
 obj-$(CONFIG_WALNUT)                           += walnut.o
 obj-$(CONFIG_XILINX_VIRTEX_GENERIC_BOARD)      += virtex.o
 obj-$(CONFIG_EP405)                            += ep405.o
diff --git a/arch/powerpc/platforms/40x/kilauea.c b/arch/powerpc/platforms/40x/kilauea.c
deleted file mode 100644 (file)
index fd7d934..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Kilauea board specific routines
- *
- * Copyright 2007-2008 DENX Software Engineering, Stefan Roese <sr@denx.de>
- *
- * Based on the Walnut code by
- * Josh Boyer <jwboyer@linux.vnet.ibm.com>
- * Copyright 2007 IBM Corporation
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#include <linux/init.h>
-#include <linux/of_platform.h>
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/time.h>
-#include <asm/uic.h>
-#include <asm/pci-bridge.h>
-#include <asm/ppc4xx.h>
-
-static __initdata struct of_device_id kilauea_of_bus[] = {
-       { .compatible = "ibm,plb4", },
-       { .compatible = "ibm,opb", },
-       { .compatible = "ibm,ebc", },
-       {},
-};
-
-static int __init kilauea_device_probe(void)
-{
-       of_platform_bus_probe(NULL, kilauea_of_bus, NULL);
-
-       return 0;
-}
-machine_device_initcall(kilauea, kilauea_device_probe);
-
-static int __init kilauea_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-
-       if (!of_flat_dt_is_compatible(root, "amcc,kilauea"))
-               return 0;
-
-       ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
-
-       return 1;
-}
-
-define_machine(kilauea) {
-       .name                           = "Kilauea",
-       .probe                          = kilauea_probe,
-       .progress                       = udbg_progress,
-       .init_IRQ                       = uic_init_tree,
-       .get_irq                        = uic_get_irq,
-       .restart                        = ppc4xx_reset_system,
-       .calibrate_decr                 = generic_calibrate_decr,
-};
diff --git a/arch/powerpc/platforms/40x/makalu.c b/arch/powerpc/platforms/40x/makalu.c
deleted file mode 100644 (file)
index a6a1d60..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Makalu board specific routines
- *
- * Copyright 2007 DENX Software Engineering, Stefan Roese <sr@denx.de>
- *
- * Based on the Walnut code by
- * Josh Boyer <jwboyer@linux.vnet.ibm.com>
- * Copyright 2007 IBM Corporation
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#include <linux/init.h>
-#include <linux/of_platform.h>
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-#include <asm/time.h>
-#include <asm/uic.h>
-#include <asm/pci-bridge.h>
-#include <asm/ppc4xx.h>
-
-static __initdata struct of_device_id makalu_of_bus[] = {
-       { .compatible = "ibm,plb4", },
-       { .compatible = "ibm,opb", },
-       { .compatible = "ibm,ebc", },
-       {},
-};
-
-static int __init makalu_device_probe(void)
-{
-       of_platform_bus_probe(NULL, makalu_of_bus, NULL);
-
-       return 0;
-}
-machine_device_initcall(makalu, makalu_device_probe);
-
-static int __init makalu_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-
-       if (!of_flat_dt_is_compatible(root, "amcc,makalu"))
-               return 0;
-
-       ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
-
-       return 1;
-}
-
-define_machine(makalu) {
-       .name                           = "Makalu",
-       .probe                          = makalu_probe,
-       .progress                       = udbg_progress,
-       .init_IRQ                       = uic_init_tree,
-       .get_irq                        = uic_get_irq,
-       .restart                        = ppc4xx_reset_system,
-       .calibrate_decr                 = generic_calibrate_decr,
-};
index f40ac9b..5fd5a59 100644 (file)
@@ -51,7 +51,10 @@ machine_device_initcall(ppc40x_simple, ppc40x_device_probe);
  * board.c file for it rather than adding it to this list.
  */
 static char *board[] __initdata = {
-       "amcc,acadia"
+       "amcc,acadia",
+       "amcc,haleakala",
+       "amcc,kilauea",
+       "amcc,makalu"
 };
 
 static int __init ppc40x_probe(void)
index fc7fb00..d0fc686 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/prom.h>
 #include <asm/time.h>
 #include <asm/xilinx_intc.h>
+#include <asm/xilinx_pci.h>
 #include <asm/ppc4xx.h>
 
 static struct of_device_id xilinx_of_bus_ids[] __initdata = {
@@ -47,6 +48,7 @@ static int __init virtex_probe(void)
 define_machine(virtex) {
        .name                   = "Xilinx Virtex",
        .probe                  = virtex_probe,
+       .setup_arch             = xilinx_pci_init,
        .init_IRQ               = xilinx_intc_init_tree,
        .get_irq                = xilinx_intc_get_irq,
        .restart                = ppc4xx_reset_system,
index 0d83a6a..90e3192 100644 (file)
@@ -156,7 +156,7 @@ config YOSEMITE
 #        This option enables support for the IBM PPC440GX evaluation board.
 
 config XILINX_VIRTEX440_GENERIC_BOARD
-       bool "Generic Xilinx Virtex 440 board"
+       bool "Generic Xilinx Virtex 5 FXT board support"
        depends on 44x
        default n
        select XILINX_VIRTEX_5_FXT
@@ -171,6 +171,17 @@ config XILINX_VIRTEX440_GENERIC_BOARD
          Most Virtex 5 designs should use this unless it needs to do some
          special configuration at board probe time.
 
+config XILINX_ML510
+       bool "Xilinx ML510 extra support"
+       depends on XILINX_VIRTEX440_GENERIC_BOARD
+       select PPC_PCI_CHOICE
+       select XILINX_PCI if PCI
+       select PPC_INDIRECT_PCI if PCI
+       select PPC_I8259 if PCI
+       help
+         This option enables extra support for features on the Xilinx ML510
+         board.  The ML510 has a PCI bus with ALI south bridge.
+
 config PPC44x_SIMPLE
        bool "Simple PowerPC 44x board support"
        depends on 44x
index 01f51da..ee6185a 100644 (file)
@@ -4,3 +4,4 @@ obj-$(CONFIG_EBONY)     += ebony.o
 obj-$(CONFIG_SAM440EP)         += sam440ep.o
 obj-$(CONFIG_WARP)     += warp.o
 obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o
+obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o
index 68637fa..cf96cca 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/prom.h>
 #include <asm/time.h>
 #include <asm/xilinx_intc.h>
+#include <asm/xilinx_pci.h>
 #include <asm/reg.h>
 #include <asm/ppc4xx.h>
 #include "44x.h"
@@ -53,6 +54,7 @@ static int __init virtex_probe(void)
 define_machine(virtex) {
        .name                   = "Xilinx Virtex440",
        .probe                  = virtex_probe,
+       .setup_arch             = xilinx_pci_init,
        .init_IRQ               = xilinx_intc_init_tree,
        .get_irq                = xilinx_intc_get_irq,
        .calibrate_decr         = generic_calibrate_decr,
diff --git a/arch/powerpc/platforms/44x/virtex_ml510.c b/arch/powerpc/platforms/44x/virtex_ml510.c
new file mode 100644 (file)
index 0000000..ba4a6e3
--- /dev/null
@@ -0,0 +1,29 @@
+#include <asm/i8259.h>
+#include <linux/pci.h>
+#include "44x.h"
+
+/**
+ * ml510_ail_quirk
+ */
+static void __devinit ml510_ali_quirk(struct pci_dev *dev)
+{
+       /* Enable the IDE controller */
+       pci_write_config_byte(dev, 0x58, 0x4c);
+       /* Assign irq 14 to the primary ide channel */
+       pci_write_config_byte(dev, 0x44, 0x0d);
+       /* Assign irq 15 to the secondary ide channel */
+       pci_write_config_byte(dev, 0x75, 0x0f);
+       /* Set the ide controller in native mode */
+       pci_write_config_byte(dev, 0x09, 0xff);
+
+       /* INTB = disabled, INTA = disabled */
+       pci_write_config_byte(dev, 0x48, 0x00);
+       /* INTD = disabled, INTC = disabled */
+       pci_write_config_byte(dev, 0x4a, 0x00);
+       /* Audio = INT7, Modem = disabled. */
+       pci_write_config_byte(dev, 0x4b, 0x60);
+       /* USB = INT7 */
+       pci_write_config_byte(dev, 0x74, 0x06);
+}
+DECLARE_PCI_FIXUP_EARLY(0x10b9, 0x1533, ml510_ali_quirk);
+
index 960edf8..c511880 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * PIKA Warp(tm) board specific routines
  *
- * Copyright (c) 2008 PIKA Technologies
+ * Copyright (c) 2008-2009 PIKA Technologies
  *   Sean MacLennan <smaclennan@pikatech.com>
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -15,6 +15,7 @@
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/of_gpio.h>
 
 #include <asm/machdep.h>
 #include <asm/prom.h>
@@ -23,6 +24,7 @@
 #include <asm/uic.h>
 #include <asm/ppc4xx.h>
 
+
 static __initdata struct of_device_id warp_of_bus[] = {
        { .compatible = "ibm,plb4", },
        { .compatible = "ibm,opb", },
@@ -55,6 +57,8 @@ define_machine(warp) {
 };
 
 
+static u32 post_info;
+
 /* I am not sure this is the best place for this... */
 static int __init warp_post_info(void)
 {
@@ -77,21 +81,21 @@ static int __init warp_post_info(void)
 
        iounmap(fpga);
 
-       if (post1 || post2)
+       if (post1 || post2) {
                printk(KERN_INFO "Warp POST %08x %08x\n", post1, post2);
-       else
+               post_info = 1;
+       } else
                printk(KERN_INFO "Warp POST OK\n");
 
        return 0;
 }
-machine_late_initcall(warp, warp_post_info);
 
 
 #ifdef CONFIG_SENSORS_AD7414
 
 static LIST_HEAD(dtm_shutdown_list);
 static void __iomem *dtm_fpga;
-static void __iomem *gpio_base;
+static unsigned green_led, red_led;
 
 
 struct dtm_shutdown {
@@ -134,14 +138,17 @@ int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
 static irqreturn_t temp_isr(int irq, void *context)
 {
        struct dtm_shutdown *shutdown;
+       int value = 1;
 
        local_irq_disable();
 
+       gpio_set_value(green_led, 0);
+
        /* Run through the shutdown list. */
        list_for_each_entry(shutdown, &dtm_shutdown_list, list)
                shutdown->func(shutdown->arg);
 
-       printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n");
+       printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n\n");
 
        while (1) {
                if (dtm_fpga) {
@@ -149,52 +156,34 @@ static irqreturn_t temp_isr(int irq, void *context)
                        out_be32(dtm_fpga + 0x14, reset);
                }
 
-               if (gpio_base) {
-                       unsigned leds = in_be32(gpio_base);
-
-                       /* green off, red toggle */
-                       leds &= ~0x80000000;
-                       leds ^=  0x40000000;
-
-                       out_be32(gpio_base, leds);
-               }
-
+               gpio_set_value(red_led, value);
+               value ^= 1;
                mdelay(500);
        }
 }
 
 static int pika_setup_leds(void)
 {
-       struct device_node *np;
-       const u32 *gpios;
-       int len;
+       struct device_node *np, *child;
 
-       np = of_find_compatible_node(NULL, NULL, "linux,gpio-led");
+       np = of_find_compatible_node(NULL, NULL, "gpio-leds");
        if (!np) {
-               printk(KERN_ERR __FILE__ ": Unable to find gpio-led\n");
-               return -ENOENT;
-       }
-
-       gpios = of_get_property(np, "gpios", &len);
-       of_node_put(np);
-       if (!gpios || len < 4) {
-               printk(KERN_ERR __FILE__
-                      ": Unable to get gpios property (%d)\n", len);
+               printk(KERN_ERR __FILE__ ": Unable to find leds\n");
                return -ENOENT;
        }
 
-       np = of_find_node_by_phandle(gpios[0]);
-       if (!np) {
-               printk(KERN_ERR __FILE__ ": Unable to find gpio\n");
-               return -ENOENT;
-       }
+       for_each_child_of_node(np, child)
+               if (strcmp(child->name, "green") == 0) {
+                       green_led = of_get_gpio(child, 0);
+                       /* Turn back on the green LED */
+                       gpio_set_value(green_led, 1);
+               } else if (strcmp(child->name, "red") == 0) {
+                       red_led = of_get_gpio(child, 0);
+                       /* Set based on post */
+                       gpio_set_value(red_led, post_info);
+               }
 
-       gpio_base = of_iomap(np, 0);
        of_node_put(np);
-       if (!gpio_base) {
-               printk(KERN_ERR __FILE__ ": Unable to map gpio");
-               return -ENOMEM;
-       }
 
        return 0;
 }
@@ -270,10 +259,10 @@ static int pika_dtm_thread(void __iomem *fpga)
        }
 
 found_it:
-       i2c_put_adapter(adap);
-
        pika_setup_critical_temp(client);
 
+       i2c_put_adapter(adap);
+
        printk(KERN_INFO "PIKA DTM thread running.\n");
 
        while (!kthread_should_stop()) {
@@ -311,6 +300,9 @@ static int __init pika_dtm_start(void)
        if (dtm_fpga == NULL)
                return -ENOENT;
 
+       /* Must get post info before thread starts. */
+       warp_post_info();
+
        dtm_thread = kthread_run(pika_dtm_thread, dtm_fpga, "pika-dtm");
        if (IS_ERR(dtm_thread)) {
                iounmap(dtm_fpga);
@@ -333,6 +325,8 @@ int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
        return 0;
 }
 
+machine_late_initcall(warp, warp_post_info);
+
 #endif
 
 EXPORT_SYMBOL(pika_dtm_register_shutdown);
index a2068fa..bcc69e1 100644 (file)
@@ -34,7 +34,7 @@
 static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
                            int len, u32 * val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
            | (((bus->number - hose->first_busno) & 0xff) << 16)
            | (hose->global_number << 24);
@@ -49,7 +49,7 @@ static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
 static int rtas_write_config(struct pci_bus *bus, unsigned int devfn,
                             int offset, int len, u32 val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
            | (((bus->number - hose->first_busno) & 0xff) << 16)
            | (hose->global_number << 24);
index 87ff522..dd43114 100644 (file)
@@ -107,7 +107,7 @@ static int
 mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
                                int offset, int len, u32 *val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        u32 value;
 
        if (ppc_md.pci_exclude_device)
@@ -164,7 +164,7 @@ static int
 mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
                                int offset, int len, u32 val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        u32 value, mask;
 
        if (ppc_md.pci_exclude_device)
index 984db42..6cf0f97 100644 (file)
 
 #include <linux/seq_file.h>
 
-/* Backword-compatibility stuff for the drivers */
-#define CPM_MAP_ADDR           ((uint)0xf0000000)
-#define CPM_IRQ_OFFSET 0
-
 /* The ADS8260 has 16, 32-bit wide control/status registers, accessed
  * only on word boundaries.
  * Not all are used (yet), or are interesting to us (yet).
 #define BCSR3_FETHIEN2         ((uint)0x10000000)      /* 0 == enable*/
 #define BCSR3_FETH2_RST                ((uint)0x80000000)      /* 0 == reset */
 
-/* cpm serial driver works with constants below */
-
-#define SIU_INT_SMC1           ((uint)0x04+CPM_IRQ_OFFSET)
-#define SIU_INT_SMC2           ((uint)0x05+CPM_IRQ_OFFSET)
-#define SIU_INT_SCC1           ((uint)0x28+CPM_IRQ_OFFSET)
-#define SIU_INT_SCC2           ((uint)0x29+CPM_IRQ_OFFSET)
-#define SIU_INT_SCC3           ((uint)0x2a+CPM_IRQ_OFFSET)
-#define SIU_INT_SCC4           ((uint)0x2b+CPM_IRQ_OFFSET)
-
 #endif /* __MACH_ADS8260_DEFS */
 #endif /* __KERNEL__ */
index 7f066ad..43d385c 100644 (file)
@@ -34,6 +34,7 @@ config MPC85xx_MDS
        bool "Freescale MPC85xx MDS"
        select DEFAULT_UIMAGE
        select PHYLIB
+       select HAS_RAPIDIO
        help
          This option enables support for the MPC85xx MDS board
 
index de66de7..53d5851 100644 (file)
@@ -163,7 +163,8 @@ static void __init mpc85xx_ds_setup_arch(void)
 #ifdef CONFIG_PCI
        for_each_node_by_type(np, "pci") {
                if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
-                   of_device_is_compatible(np, "fsl,mpc8548-pcie")) {
+                   of_device_is_compatible(np, "fsl,mpc8548-pcie") ||
+                   of_device_is_compatible(np, "fsl,p2020-pcie")) {
                        struct resource rsrc;
                        of_address_to_resource(np, 0, &rsrc);
                        if ((rsrc.start & 0xfffff) == primary_phb_addr)
@@ -195,9 +196,9 @@ static int __init mpc8544_ds_probe(void)
                primary_phb_addr = 0xb000;
 #endif
                return 1;
-       } else {
-               return 0;
        }
+
+       return 0;
 }
 
 static struct of_device_id __initdata mpc85xxds_ids[] = {
@@ -214,6 +215,7 @@ static int __init mpc85xxds_publish_devices(void)
 }
 machine_device_initcall(mpc8544_ds, mpc85xxds_publish_devices);
 machine_device_initcall(mpc8572_ds, mpc85xxds_publish_devices);
+machine_device_initcall(p2020_ds, mpc85xxds_publish_devices);
 
 /*
  * Called very early, device-tree isn't unflattened
@@ -227,9 +229,26 @@ static int __init mpc8572_ds_probe(void)
                primary_phb_addr = 0x8000;
 #endif
                return 1;
-       } else {
-               return 0;
        }
+
+       return 0;
+}
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init p2020_ds_probe(void)
+{
+       unsigned long root = of_get_flat_dt_root();
+
+       if (of_flat_dt_is_compatible(root, "fsl,P2020DS")) {
+#ifdef CONFIG_PCI
+               primary_phb_addr = 0x9000;
+#endif
+               return 1;
+       }
+
+       return 0;
 }
 
 define_machine(mpc8544_ds) {
@@ -259,3 +278,17 @@ define_machine(mpc8572_ds) {
        .calibrate_decr         = generic_calibrate_decr,
        .progress               = udbg_progress,
 };
+
+define_machine(p2020_ds) {
+       .name                   = "P2020 DS",
+       .probe                  = p2020_ds_probe,
+       .setup_arch             = mpc85xx_ds_setup_arch,
+       .init_IRQ               = mpc85xx_ds_pic_init,
+#ifdef CONFIG_PCI
+       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+#endif
+       .get_irq                = mpic_get_irq,
+       .restart                = fsl_rstcr_restart,
+       .calibrate_decr         = generic_calibrate_decr,
+       .progress               = udbg_progress,
+};
index 7dd0290..b2c0a43 100644 (file)
@@ -206,23 +206,24 @@ static void __init mpc85xx_mds_setup_arch(void)
        }
 
        if (bcsr_regs) {
+               if (machine_is(mpc8568_mds)) {
 #define BCSR_UCC1_GETH_EN      (0x1 << 7)
 #define BCSR_UCC2_GETH_EN      (0x1 << 7)
 #define BCSR_UCC1_MODE_MSK     (0x3 << 4)
 #define BCSR_UCC2_MODE_MSK     (0x3 << 0)
 
-               /* Turn off UCC1 & UCC2 */
-               clrbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
-               clrbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
+                       /* Turn off UCC1 & UCC2 */
+                       clrbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
+                       clrbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
 
-               /* Mode is RGMII, all bits clear */
-               clrbits8(&bcsr_regs[11], BCSR_UCC1_MODE_MSK |
-                                        BCSR_UCC2_MODE_MSK);
-
-               /* Turn UCC1 & UCC2 on */
-               setbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
-               setbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
+                       /* Mode is RGMII, all bits clear */
+                       clrbits8(&bcsr_regs[11], BCSR_UCC1_MODE_MSK |
+                                                BCSR_UCC2_MODE_MSK);
 
+                       /* Turn UCC1 & UCC2 on */
+                       setbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
+                       setbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
+               }
                iounmap(bcsr_regs);
        }
 #endif /* CONFIG_QUICC_ENGINE */
@@ -257,7 +258,8 @@ static int __init board_fixups(void)
 
        return 0;
 }
-machine_arch_initcall(mpc85xx_mds, board_fixups);
+machine_arch_initcall(mpc8568_mds, board_fixups);
+machine_arch_initcall(mpc8569_mds, board_fixups);
 
 static struct of_device_id mpc85xx_ids[] = {
        { .type = "soc", },
@@ -276,7 +278,8 @@ static int __init mpc85xx_publish_devices(void)
 
        return 0;
 }
-machine_device_initcall(mpc85xx_mds, mpc85xx_publish_devices);
+machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices);
+machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices);
 
 static void __init mpc85xx_mds_pic_init(void)
 {
@@ -321,8 +324,8 @@ static int __init mpc85xx_mds_probe(void)
         return of_flat_dt_is_compatible(root, "MPC85xxMDS");
 }
 
-define_machine(mpc85xx_mds) {
-       .name           = "MPC85xx MDS",
+define_machine(mpc8568_mds) {
+       .name           = "MPC8568 MDS",
        .probe          = mpc85xx_mds_probe,
        .setup_arch     = mpc85xx_mds_setup_arch,
        .init_IRQ       = mpc85xx_mds_pic_init,
@@ -334,3 +337,24 @@ define_machine(mpc85xx_mds) {
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 #endif
 };
+
+static int __init mpc8569_mds_probe(void)
+{
+       unsigned long root = of_get_flat_dt_root();
+
+       return of_flat_dt_is_compatible(root, "fsl,MPC8569EMDS");
+}
+
+define_machine(mpc8569_mds) {
+       .name           = "MPC8569 MDS",
+       .probe          = mpc8569_mds_probe,
+       .setup_arch     = mpc85xx_mds_setup_arch,
+       .init_IRQ       = mpc85xx_mds_pic_init,
+       .get_irq        = mpic_get_irq,
+       .restart        = fsl_rstcr_restart,
+       .calibrate_decr = generic_calibrate_decr,
+       .progress       = udbg_progress,
+#ifdef CONFIG_PCI
+       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+#endif
+};
index d791046..2efa052 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/time.h>
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
 #include <asm/prom.h>
 #include <mm/mmu_decl.h>
 #include <asm/udbg.h>
index af14f85..90754e7 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/time.h>
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
 #include <asm/prom.h>
 #include <mm/mmu_decl.h>
 #include <asm/udbg.h>
index ea23606..72b31a6 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/time.h>
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
 #include <asm/prom.h>
 #include <mm/mmu_decl.h>
 #include <asm/udbg.h>
index 3f49a6f..51eec0c 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/time.h>
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
 #include <asm/prom.h>
 #include <mm/mmu_decl.h>
 #include <asm/udbg.h>
index c4ec49b..7e9e83c 100644 (file)
@@ -24,7 +24,6 @@
 #include <asm/time.h>
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
 #include <asm/prom.h>
 #include <mm/mmu_decl.h>
 #include <asm/udbg.h>
index 014e26c..d84bbb5 100644 (file)
@@ -20,7 +20,6 @@
 #include <asm/pgtable.h>
 #include <asm/pci-bridge.h>
 #include <asm/mpic.h>
-#include <asm/mpc86xx.h>
 #include <asm/cacheflush.h>
 
 #include <sysdev/fsl_soc.h>
 extern void __secondary_start_mpc86xx(void);
 extern unsigned long __secondary_hold_acknowledge;
 
+#define MCM_PORT_CONFIG_OFFSET 0x10
+
+/* Offset from CCSRBAR */
+#define MPC86xx_MCM_OFFSET      (0x1000)
+#define MPC86xx_MCM_SIZE        (0x1000)
 
 static void __init
 smp_86xx_release_core(int nr)
@@ -48,6 +52,8 @@ smp_86xx_release_core(int nr)
        pcr = in_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2));
        pcr |= 1 << (nr + 24);
        out_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2), pcr);
+
+       iounmap(mcm_vaddr);
 }
 
 
index 2886a36..51c8f33 100644 (file)
@@ -25,7 +25,6 @@
 #include <asm/time.h>
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
 #include <asm/prom.h>
 #include <mm/mmu_decl.h>
 #include <asm/udbg.h>
index a507666..19412f7 100644 (file)
 
 #include <sysdev/fsl_soc.h>
 
-#define MPC8xx_CPM_OFFSET      (0x9c0)
-#define CPM_MAP_ADDR           (get_immrbase() + MPC8xx_CPM_OFFSET)
-#define CPM_IRQ_OFFSET         16     // for compability with cpm_uart driver
-
 /* Bits of interest in the BCSRs.
  */
 #define BCSR1_ETHEN            ((uint)0x20000000)
index e3e8707..04a8061 100644 (file)
@@ -329,4 +329,8 @@ config MCU_MPC8349EMITX
          also register MCU GPIOs with the generic GPIO API, so you'll able
          to use MCU pins as GPIOs.
 
+config XILINX_PCI
+       bool "Xilinx PCI host bridge support"
+       depends on PCI && XILINX_VIRTEX
+
 endmenu
index 732ee93..cca6b4f 100644 (file)
@@ -10,7 +10,6 @@ menu "Processor support"
 choice
        prompt "Processor Type"
        depends on PPC32
-       default 6xx
        help
          There are five families of 32 bit PowerPC chips supported.
          The most common ones are the desktop and server CPUs (601, 603,
@@ -22,7 +21,7 @@ choice
 
          If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx.
 
-config 6xx
+config PPC_BOOK3S
        bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx"
        select PPC_FPU
 
@@ -58,13 +57,11 @@ config E200
 
 endchoice
 
-# Until we have a choice of exclusive CPU types on 64-bit, we always
-# use PPC_BOOK3S. On 32-bit, this is equivalent to 6xx which is
-# "classic" MMU
-
 config PPC_BOOK3S
-       def_bool y
-       depends on PPC64 || 6xx
+       default y
+       depends on PPC64
+       select PPC_FPU
+
 
 config POWER4_ONLY
        bool "Optimize for POWER4"
@@ -75,6 +72,10 @@ config POWER4_ONLY
          The resulting binary will not work on POWER3 or RS64 processors
          when compiled with binutils 2.15 or later.
 
+config 6xx
+       def_bool y
+       depends on PPC32 && PPC_BOOK3S
+
 config POWER3
        bool
        depends on PPC64 && PPC_BOOK3S
@@ -203,9 +204,8 @@ config SPE
          If in doubt, say Y here.
 
 config PPC_STD_MMU
-       bool
-       depends on 6xx || PPC64
-       default y
+       def_bool y
+       depends on PPC_BOOK3S
 
 config PPC_STD_MMU_32
        def_bool y
@@ -263,8 +263,8 @@ config SMP
          If you don't know what to do here, say N.
 
 config NR_CPUS
-       int "Maximum number of CPUs (2-1024)"
-       range 2 1024
+       int "Maximum number of CPUs (2-8192)"
+       range 2 8192
        depends on SMP
        default "32" if PPC64
        default "4"
index f39a3b2..00eaaa7 100644 (file)
@@ -162,8 +162,7 @@ static int celleb_fake_pci_read_config(struct pci_bus *bus,
                unsigned int devfn, int where, int size, u32 *val)
 {
        char *config;
-       struct device_node *node;
-       struct pci_controller *hose;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        unsigned int devno = devfn >> 3;
        unsigned int fn = devfn & 0x7;
 
@@ -171,8 +170,6 @@ static int celleb_fake_pci_read_config(struct pci_bus *bus,
        BUG_ON(where % size);
 
        pr_debug("    fake read: bus=0x%x, ", bus->number);
-       node = (struct device_node *)bus->sysdata;
-       hose = pci_find_hose_for_OF_device(node);
        config = get_fake_config_start(hose, devno, fn);
 
        pr_debug("devno=0x%x, where=0x%x, size=0x%x, ", devno, where, size);
@@ -192,8 +189,7 @@ static int celleb_fake_pci_write_config(struct pci_bus *bus,
                unsigned int devfn, int where, int size, u32 val)
 {
        char *config;
-       struct device_node *node;
-       struct pci_controller *hose;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        struct celleb_pci_resource *res;
        unsigned int devno = devfn >> 3;
        unsigned int fn = devfn & 0x7;
@@ -201,8 +197,6 @@ static int celleb_fake_pci_write_config(struct pci_bus *bus,
        /* allignment check */
        BUG_ON(where % size);
 
-       node = (struct device_node *)bus->sysdata;
-       hose = pci_find_hose_for_OF_device(node);
        config = get_fake_config_start(hose, devno, fn);
 
        if (!config)
index 48ec88a..05b0db3 100644 (file)
@@ -134,15 +134,11 @@ static int celleb_epci_read_config(struct pci_bus *bus,
 {
        PCI_IO_ADDR epci_base;
        PCI_IO_ADDR addr;
-       struct device_node *node;
-       struct pci_controller *hose;
+       struct pci_controller *hose = pci_bus_to_host(bus);
 
        /* allignment check */
        BUG_ON(where % size);
 
-       node = (struct device_node *)bus->sysdata;
-       hose = pci_find_hose_for_OF_device(node);
-
        if (!celleb_epci_get_epci_cfg(hose))
                return PCIBIOS_DEVICE_NOT_FOUND;
 
@@ -198,16 +194,11 @@ static int celleb_epci_write_config(struct pci_bus *bus,
 {
        PCI_IO_ADDR epci_base;
        PCI_IO_ADDR addr;
-       struct device_node *node;
-       struct pci_controller *hose;
+       struct pci_controller *hose = pci_bus_to_host(bus);
 
        /* allignment check */
        BUG_ON(where % size);
 
-       node = (struct device_node *)bus->sysdata;
-       hose = pci_find_hose_for_OF_device(node);
-
-
        if (!celleb_epci_get_epci_cfg(hose))
                return PCIBIOS_DEVICE_NOT_FOUND;
 
index 3e7e0f1..7fca09f 100644 (file)
@@ -366,11 +366,7 @@ static void config_write_pciex_rc(unsigned int __iomem *base, uint32_t where,
 static int scc_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
                                 int where, int size, unsigned int *val)
 {
-       struct device_node *dn;
-       struct pci_controller *phb;
-
-       dn = bus->sysdata;
-       phb = pci_find_hose_for_OF_device(dn);
+       struct pci_controller *phb = pci_bus_to_host(bus);
 
        if (bus->number == phb->first_busno && PCI_SLOT(devfn) != 1) {
                *val = ~0;
@@ -389,11 +385,7 @@ static int scc_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
 static int scc_pciex_write_config(struct pci_bus *bus, unsigned int devfn,
                                  int where, int size, unsigned int val)
 {
-       struct device_node *dn;
-       struct pci_controller *phb;
-
-       dn = bus->sysdata;
-       phb = pci_find_hose_for_OF_device(dn);
+       struct pci_controller *phb = pci_bus_to_host(bus);
 
        if (bus->number == phb->first_busno && PCI_SLOT(devfn) != 1)
                return PCIBIOS_DEVICE_NOT_FOUND;
index 706eb5c..24b30b6 100644 (file)
@@ -631,10 +631,6 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode,
        if (IS_ERR(dentry))
                goto out_dir;
 
-       ret = -EEXIST;
-       if (dentry->d_inode)
-               goto out_dput;
-
        mode &= ~current_umask();
 
        if (flags & SPU_CREATE_GANG)
@@ -648,8 +644,6 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode,
                fsnotify_mkdir(nd->path.dentry->d_inode, dentry);
        return ret;
 
-out_dput:
-       dput(dentry);
 out_dir:
        mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
 out:
index f6b0c51..8f67a39 100644 (file)
@@ -34,7 +34,7 @@ int gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
                           int len, u32 *val)
 {
        volatile void __iomem *cfg_data;
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
 
        if (bus->number > 7)
                return PCIBIOS_DEVICE_NOT_FOUND;
@@ -61,7 +61,7 @@ int gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off,
                            int len, u32 val)
 {
        volatile void __iomem *cfg_data;
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
 
        if (bus->number > 7)
                return PCIBIOS_DEVICE_NOT_FOUND;
@@ -96,7 +96,7 @@ static struct pci_ops gg2_pci_ops =
 int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
                     int len, u32 *val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
                | (((bus->number - hose->first_busno) & 0xff) << 16)
                | (hose->global_number << 24);
@@ -111,7 +111,7 @@ int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
 int rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
                      int len, u32 val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
                | (((bus->number - hose->first_busno) & 0xff) << 16)
                | (hose->global_number << 24);
index 65a35f3..fd23a1d 100644 (file)
@@ -51,13 +51,20 @@ u8 uli_pirq_to_irq[8] = {
        ULI_8259_NONE,          /* PIRQH */
 };
 
+static inline bool is_quirk_valid(void)
+{
+       return (machine_is(mpc86xx_hpcn) ||
+               machine_is(mpc8544_ds) ||
+               machine_is(p2020_ds) ||
+               machine_is(mpc8572_ds));
+}
+
 /* Bridge */
 static void __devinit early_uli5249(struct pci_dev *dev)
 {
        unsigned char temp;
 
-       if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
-                       !machine_is(mpc8572_ds))
+       if (!is_quirk_valid())
                return;
 
        pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_IO |
@@ -80,8 +87,7 @@ static void __devinit quirk_uli1575(struct pci_dev *dev)
 {
        int i;
 
-       if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
-                       !machine_is(mpc8572_ds))
+       if (!is_quirk_valid())
                return;
 
        /*
@@ -149,8 +155,7 @@ static void __devinit quirk_final_uli1575(struct pci_dev *dev)
         * IRQ 14: Edge
         * IRQ 15: Edge
         */
-       if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
-                       !machine_is(mpc8572_ds))
+       if (!is_quirk_valid())
                return;
 
        outb(0xfa, 0x4d0);
@@ -176,8 +181,7 @@ static void __devinit quirk_uli5288(struct pci_dev *dev)
        unsigned char c;
        unsigned int d;
 
-       if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
-                       !machine_is(mpc8572_ds))
+       if (!is_quirk_valid())
                return;
 
        /* read/write lock */
@@ -201,8 +205,7 @@ static void __devinit quirk_uli5229(struct pci_dev *dev)
 {
        unsigned short temp;
 
-       if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
-                       !machine_is(mpc8572_ds))
+       if (!is_quirk_valid())
                return;
 
        pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE |
@@ -270,7 +273,6 @@ static void __devinit hpcd_quirk_uli1575(struct pci_dev *dev)
 static void __devinit hpcd_quirk_uli5288(struct pci_dev *dev)
 {
        unsigned char c;
-       unsigned short temp;
 
        if (!machine_is(mpc86xx_hpcd))
                return;
index 4021982..6c1e101 100644 (file)
@@ -177,7 +177,7 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
 static void pci_dma_dev_setup_iseries(struct pci_dev *pdev)
 {
        struct iommu_table *tbl;
-       struct device_node *dn = pdev->sysdata;
+       struct device_node *dn = pci_device_to_OF_node(pdev);
        struct pci_dn *pdn = PCI_DN(dn);
        const u32 *lsn = of_get_property(dn, "linux,logical-slot-number", NULL);
 
index 21cddc3..175aac8 100644 (file)
@@ -318,6 +318,7 @@ static void __init iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
 {
        struct resource *bar_res = &dev->resource[bar_num];
        long bar_size = pci_resource_len(dev, bar_num);
+       struct device_node *dn = pci_device_to_OF_node(dev);
 
        /*
         * No space to allocate, quick exit, skip Allocation.
@@ -335,9 +336,9 @@ static void __init iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
         * Allocate the number of table entries needed for BAR.
         */
        while (bar_size > 0 ) {
-               iomm_table[current_iomm_table_entry] = dev->sysdata;
+               iomm_table[current_iomm_table_entry] = dn;
                ds_addr_table[current_iomm_table_entry] =
-                       iseries_ds_addr(dev->sysdata) | (bar_num << 24);
+                       iseries_ds_addr(dn) | (bar_num << 24);
                bar_size -= IOMM_TABLE_ENTRY_SIZE;
                ++current_iomm_table_entry;
        }
@@ -410,7 +411,7 @@ void __init iSeries_pcibios_fixup_resources(struct pci_dev *pdev)
        struct device_node *node;
        int i;
 
-       node = find_device_node(bus, pdev->devfn);
+       node = pci_device_to_OF_node(pdev);
        pr_debug("PCI: iSeries %s, pdev %p, node %p\n",
                 pci_name(pdev), pdev, node);
        if (!node) {
@@ -441,7 +442,6 @@ void __init iSeries_pcibios_fixup_resources(struct pci_dev *pdev)
                }
        }
 
-       pdev->sysdata = node;
        allocate_device_bars(pdev);
        iseries_device_information(pdev, bus, *sub_bus);
 }
index 7039d8f..dce7363 100644 (file)
@@ -221,7 +221,7 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id)
                        continue;
                irq += __ilog2(bits);
                spin_unlock_irqrestore(&pmac_pic_lock, flags);
-               __do_IRQ(irq);
+               generic_handle_irq(irq);
                spin_lock_irqsave(&pmac_pic_lock, flags);
                rc = IRQ_HANDLED;
        }
index 45936c9..86f69a4 100644 (file)
@@ -655,7 +655,7 @@ static int __init pmac_probe(void)
 /* Move that to pci.c */
 static int pmac_pci_probe_mode(struct pci_bus *bus)
 {
-       struct device_node *node = bus->sysdata;
+       struct device_node *node = pci_bus_to_OF_node(bus);
 
        /* We need to use normal PCI probing for the AGP bus,
         * since the device for the AGP bridge isn't in the tree.
index a0927a3..f6e04bc 100644 (file)
 #define DBG pr_debug
 #endif
 
-static irqreturn_t ipi_function_handler(int irq, void *msg)
-{
-       smp_message_recv((int)(long)msg);
-       return IRQ_HANDLED;
-}
-
 /**
   * ps3_ipi_virqs - a per cpu array of virqs for ipi use
   */
@@ -45,13 +39,6 @@ static irqreturn_t ipi_function_handler(int irq, void *msg)
 #define MSG_COUNT 4
 static DEFINE_PER_CPU(unsigned int, ps3_ipi_virqs[MSG_COUNT]);
 
-static const char *names[MSG_COUNT] = {
-       "ipi call",
-       "ipi reschedule",
-       "ipi migrate",
-       "ipi debug brk"
-};
-
 static void do_message_pass(int target, int msg)
 {
        int result;
@@ -119,8 +106,7 @@ static void __init ps3_smp_setup_cpu(int cpu)
                DBG("%s:%d: (%d, %d) => virq %u\n",
                        __func__, __LINE__, cpu, i, virqs[i]);
 
-               result = request_irq(virqs[i], ipi_function_handler,
-                       IRQF_DISABLED, names[i], (void*)(long)i);
+               result = smp_request_message_ipi(virqs[i], i);
 
                if (result)
                        virqs[i] = NO_IRQ;
index 3ee01b4..661c8e0 100644 (file)
@@ -388,7 +388,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
 
                while (pci->phb->dma_window_size * children > 0x80000000ul)
                        pci->phb->dma_window_size >>= 1;
-               pr_debug("No ISA/IDE, window size is 0x%lx\n",
+               pr_debug("No ISA/IDE, window size is 0x%llx\n",
                         pci->phb->dma_window_size);
                pci->phb->dma_window_base_cur = 0;
 
@@ -414,7 +414,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
        while (pci->phb->dma_window_size * children > 0x70000000ul)
                pci->phb->dma_window_size >>= 1;
 
-       pr_debug("ISA/IDE, window size is 0x%lx\n", pci->phb->dma_window_size);
+       pr_debug("ISA/IDE, window size is 0x%llx\n", pci->phb->dma_window_size);
 }
 
 
index 52a80e5..e3139fa 100644 (file)
@@ -609,3 +609,55 @@ void __init hpte_init_lpar(void)
        ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range;
        ppc_md.hpte_clear_all   = pSeries_lpar_hptab_clear;
 }
+
+#ifdef CONFIG_PPC_SMLPAR
+#define CMO_FREE_HINT_DEFAULT 1
+static int cmo_free_hint_flag = CMO_FREE_HINT_DEFAULT;
+
+static int __init cmo_free_hint(char *str)
+{
+       char *parm;
+       parm = strstrip(str);
+
+       if (strcasecmp(parm, "no") == 0 || strcasecmp(parm, "off") == 0) {
+               printk(KERN_INFO "cmo_free_hint: CMO free page hinting is not active.\n");
+               cmo_free_hint_flag = 0;
+               return 1;
+       }
+
+       cmo_free_hint_flag = 1;
+       printk(KERN_INFO "cmo_free_hint: CMO free page hinting is active.\n");
+
+       if (strcasecmp(parm, "yes") == 0 || strcasecmp(parm, "on") == 0)
+               return 1;
+
+       return 0;
+}
+
+__setup("cmo_free_hint=", cmo_free_hint);
+
+static void pSeries_set_page_state(struct page *page, int order,
+                                  unsigned long state)
+{
+       int i, j;
+       unsigned long cmo_page_sz, addr;
+
+       cmo_page_sz = cmo_get_page_size();
+       addr = __pa((unsigned long)page_address(page));
+
+       for (i = 0; i < (1 << order); i++, addr += PAGE_SIZE) {
+               for (j = 0; j < PAGE_SIZE; j += cmo_page_sz)
+                       plpar_hcall_norets(H_PAGE_INIT, state, addr + j, 0);
+       }
+}
+
+void arch_free_page(struct page *page, int order)
+{
+       if (!cmo_free_hint_flag || !firmware_has_feature(FW_FEATURE_CMO))
+               return;
+
+       pSeries_set_page_state(page, order, H_PAGE_SET_UNUSED);
+}
+EXPORT_SYMBOL(arch_free_page);
+
+#endif
index afad9f5..b3cbac8 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/vmalloc.h>
 #include <linux/spinlock.h>
 #include <linux/cpu.h>
-#include <linux/delay.h>
+#include <linux/workqueue.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -387,36 +387,51 @@ static void do_event_scan(void)
        } while(error == 0);
 }
 
-static void do_event_scan_all_cpus(long delay)
+static void rtas_event_scan(struct work_struct *w);
+DECLARE_DELAYED_WORK(event_scan_work, rtas_event_scan);
+
+/*
+ * Delay should be at least one second since some machines have problems if
+ * we call event-scan too quickly.
+ */
+static unsigned long event_scan_delay = 1*HZ;
+static int first_pass = 1;
+
+static void rtas_event_scan(struct work_struct *w)
 {
-       int cpu;
+       unsigned int cpu;
+
+       do_event_scan();
 
        get_online_cpus();
-       cpu = first_cpu(cpu_online_map);
-       for (;;) {
-               set_cpus_allowed(current, cpumask_of_cpu(cpu));
-               do_event_scan();
-               set_cpus_allowed(current, CPU_MASK_ALL);
-
-               /* Drop hotplug lock, and sleep for the specified delay */
-               put_online_cpus();
-               msleep_interruptible(delay);
-               get_online_cpus();
-
-               cpu = next_cpu(cpu, cpu_online_map);
-               if (cpu == NR_CPUS)
-                       break;
+
+       cpu = next_cpu(smp_processor_id(), cpu_online_map);
+       if (cpu == NR_CPUS) {
+               cpu = first_cpu(cpu_online_map);
+
+               if (first_pass) {
+                       first_pass = 0;
+                       event_scan_delay = 30*HZ/rtas_event_scan_rate;
+
+                       if (surveillance_timeout != -1) {
+                               pr_debug("rtasd: enabling surveillance\n");
+                               enable_surveillance(surveillance_timeout);
+                               pr_debug("rtasd: surveillance enabled\n");
+                       }
+               }
        }
+
+       schedule_delayed_work_on(cpu, &event_scan_work,
+               __round_jiffies_relative(event_scan_delay, cpu));
+
        put_online_cpus();
 }
 
-static int rtasd(void *unused)
+static void start_event_scan(void)
 {
        unsigned int err_type;
        int rc;
 
-       daemonize("rtasd");
-
        printk(KERN_DEBUG "RTAS daemon started\n");
        pr_debug("rtasd: will sleep for %d milliseconds\n",
                 (30000 / rtas_event_scan_rate));
@@ -434,22 +449,8 @@ static int rtasd(void *unused)
                }
        }
 
-       /* First pass. */
-       do_event_scan_all_cpus(1000);
-
-       if (surveillance_timeout != -1) {
-               pr_debug("rtasd: enabling surveillance\n");
-               enable_surveillance(surveillance_timeout);
-               pr_debug("rtasd: surveillance enabled\n");
-       }
-
-       /* Delay should be at least one second since some
-        * machines have problems if we call event-scan too
-        * quickly. */
-       for (;;)
-               do_event_scan_all_cpus(30000/rtas_event_scan_rate);
-
-       return -EINVAL;
+       schedule_delayed_work_on(first_cpu(cpu_online_map), &event_scan_work,
+                                event_scan_delay);
 }
 
 static int __init rtas_init(void)
@@ -487,8 +488,7 @@ static int __init rtas_init(void)
        if (!entry)
                printk(KERN_ERR "Failed to create error_log proc entry\n");
 
-       if (kernel_thread(rtasd, NULL, CLONE_FS) < 0)
-               printk(KERN_ERR "Failed to start RTAS daemon\n");
+       start_event_scan();
 
        return 0;
 }
index ec34170..8d75ea2 100644 (file)
@@ -63,6 +63,7 @@
 #include <asm/smp.h>
 #include <asm/firmware.h>
 #include <asm/eeh.h>
+#include <asm/pSeries_reconfig.h>
 
 #include "plpar_wrappers.h"
 #include "pseries.h"
@@ -254,6 +255,29 @@ static void __init pseries_discover_pic(void)
               " interrupt-controller\n");
 }
 
+static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
+{
+       struct device_node *np = node;
+       struct pci_dn *pci = NULL;
+       int err = NOTIFY_OK;
+
+       switch (action) {
+       case PSERIES_RECONFIG_ADD:
+               pci = np->parent->data;
+               if (pci)
+                       update_dn_pci_info(np, pci->phb);
+               break;
+       default:
+               err = NOTIFY_DONE;
+               break;
+       }
+       return err;
+}
+
+static struct notifier_block pci_dn_reconfig_nb = {
+       .notifier_call = pci_dn_reconfig_notifier,
+};
+
 static void __init pSeries_setup_arch(void)
 {
        /* Discover PIC type and setup ppc_md accordingly */
@@ -271,6 +295,7 @@ static void __init pSeries_setup_arch(void)
        /* Find and initialize PCI host bridges */
        init_pci_config_tokens();
        find_and_init_phbs();
+       pSeries_reconfig_notifier_register(&pci_dn_reconfig_nb);
        eeh_init();
 
        pSeries_nvram_init();
index b33b28a..2d1c87d 100644 (file)
@@ -34,6 +34,7 @@ obj-$(CONFIG_IPIC)            += ipic.o
 obj-$(CONFIG_4xx)              += uic.o
 obj-$(CONFIG_4xx_SOC)          += ppc4xx_soc.o
 obj-$(CONFIG_XILINX_VIRTEX)    += xilinx_intc.o
+obj-$(CONFIG_XILINX_PCI)       += xilinx_pci.o
 obj-$(CONFIG_OF_RTC)           += of_rtc.o
 ifeq ($(CONFIG_PCI),y)
 obj-$(CONFIG_4xx)              += ppc4xx_pci.o
index fd969f0..eb59272 100644 (file)
@@ -61,7 +61,7 @@ EXPORT_SYMBOL(cpm2_immr);
 void __init cpm2_reset(void)
 {
 #ifdef CONFIG_PPC_85xx
-       cpm2_immr = ioremap(CPM_MAP_ADDR, CPM_MAP_SIZE);
+       cpm2_immr = ioremap(get_immrbase() + 0x80000, CPM_MAP_SIZE);
 #else
        cpm2_immr = ioremap(get_immrbase(), CPM_MAP_SIZE);
 #endif
index f25ce81..da38a1f 100644 (file)
@@ -113,8 +113,13 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
                                  struct msi_msg *msg)
 {
        struct fsl_msi *msi_data = fsl_msi;
+       struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+       u32 base = 0;
 
-       msg->address_lo = msi_data->msi_addr_lo;
+       pci_bus_read_config_dword(hose->bus,
+               PCI_DEVFN(0, 0), PCI_BASE_ADDRESS_0, &base);
+
+       msg->address_lo = msi_data->msi_addr_lo + base;
        msg->address_hi = msi_data->msi_addr_hi;
        msg->data = hwirq;
 
@@ -271,7 +276,7 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev,
        msi->irqhost->host_data = msi;
 
        msi->msi_addr_hi = 0x0;
-       msi->msi_addr_lo = res.start + features->msiir_offset;
+       msi->msi_addr_lo = features->msiir_offset + (res.start & 0xfffff);
 
        rc = fsl_msi_init_allocator(msi);
        if (rc) {
index 78021d8..ae88b14 100644 (file)
@@ -23,6 +23,8 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/lmb.h>
+#include <linux/log2.h>
 
 #include <asm/io.h>
 #include <asm/prom.h>
@@ -96,7 +98,13 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
                                  struct resource *rsrc)
 {
        struct ccsr_pci __iomem *pci;
-       int i, j, n;
+       int i, j, n, mem_log, win_idx = 2;
+       u64 mem, sz, paddr_hi = 0;
+       u64 paddr_lo = ULLONG_MAX;
+       u32 pcicsrbar = 0, pcicsrbar_sz;
+       u32 piwar = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL |
+                       PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP;
+       char *name = hose->dn->full_name;
 
        pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n",
                    (u64)rsrc->start, (u64)rsrc->end - (u64)rsrc->start + 1);
@@ -117,6 +125,9 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
                if (!(hose->mem_resources[i].flags & IORESOURCE_MEM))
                        continue;
 
+               paddr_lo = min(paddr_lo, (u64)hose->mem_resources[i].start);
+               paddr_hi = max(paddr_hi, (u64)hose->mem_resources[i].end);
+
                n = setup_one_atmu(pci, j, &hose->mem_resources[i],
                                   hose->pci_mem_offset);
 
@@ -147,10 +158,105 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
                }
        }
 
-       /* Setup 2G inbound Memory Window @ 1 */
-       out_be32(&pci->piw[2].pitar, 0x00000000);
-       out_be32(&pci->piw[2].piwbar,0x00000000);
-       out_be32(&pci->piw[2].piwar, PIWAR_2G);
+       /* convert to pci address space */
+       paddr_hi -= hose->pci_mem_offset;
+       paddr_lo -= hose->pci_mem_offset;
+
+       if (paddr_hi == paddr_lo) {
+               pr_err("%s: No outbound window space\n", name);
+               return ;
+       }
+
+       if (paddr_lo == 0) {
+               pr_err("%s: No space for inbound window\n", name);
+               return ;
+       }
+
+       /* setup PCSRBAR/PEXCSRBAR */
+       early_write_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, 0xffffffff);
+       early_read_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, &pcicsrbar_sz);
+       pcicsrbar_sz = ~pcicsrbar_sz + 1;
+
+       if (paddr_hi < (0x100000000ull - pcicsrbar_sz) ||
+               (paddr_lo > 0x100000000ull))
+               pcicsrbar = 0x100000000ull - pcicsrbar_sz;
+       else
+               pcicsrbar = (paddr_lo - pcicsrbar_sz) & -pcicsrbar_sz;
+       early_write_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, pcicsrbar);
+
+       paddr_lo = min(paddr_lo, (u64)pcicsrbar);
+
+       pr_info("%s: PCICSRBAR @ 0x%x\n", name, pcicsrbar);
+
+       /* Setup inbound mem window */
+       mem = lmb_end_of_DRAM();
+       sz = min(mem, paddr_lo);
+       mem_log = __ilog2_u64(sz);
+
+       /* PCIe can overmap inbound & outbound since RX & TX are separated */
+       if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
+               /* Size window to exact size if power-of-two or one size up */
+               if ((1ull << mem_log) != mem) {
+                       if ((1ull << mem_log) > mem)
+                               pr_info("%s: Setting PCI inbound window "
+                                       "greater than memory size\n", name);
+                       mem_log++;
+               }
+
+               piwar |= (mem_log - 1);
+
+               /* Setup inbound memory window */
+               out_be32(&pci->piw[win_idx].pitar,  0x00000000);
+               out_be32(&pci->piw[win_idx].piwbar, 0x00000000);
+               out_be32(&pci->piw[win_idx].piwar,  piwar);
+               win_idx--;
+
+               hose->dma_window_base_cur = 0x00000000;
+               hose->dma_window_size = (resource_size_t)sz;
+       } else {
+               u64 paddr = 0;
+
+               /* Setup inbound memory window */
+               out_be32(&pci->piw[win_idx].pitar,  paddr >> 12);
+               out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
+               out_be32(&pci->piw[win_idx].piwar,  (piwar | (mem_log - 1)));
+               win_idx--;
+
+               paddr += 1ull << mem_log;
+               sz -= 1ull << mem_log;
+
+               if (sz) {
+                       mem_log = __ilog2_u64(sz);
+                       piwar |= (mem_log - 1);
+
+                       out_be32(&pci->piw[win_idx].pitar,  paddr >> 12);
+                       out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
+                       out_be32(&pci->piw[win_idx].piwar,  piwar);
+                       win_idx--;
+
+                       paddr += 1ull << mem_log;
+               }
+
+               hose->dma_window_base_cur = 0x00000000;
+               hose->dma_window_size = (resource_size_t)paddr;
+       }
+
+       if (hose->dma_window_size < mem) {
+#ifndef CONFIG_SWIOTLB
+               pr_err("%s: ERROR: Memory size exceeds PCI ATMU ability to "
+                       "map - enable CONFIG_SWIOTLB to avoid dma errors.\n",
+                        name);
+#endif
+               /* adjusting outbound windows could reclaim space in mem map */
+               if (paddr_hi < 0xffffffffull)
+                       pr_warning("%s: WARNING: Outbound window cfg leaves "
+                               "gaps in memory map. Adjusting the memory map "
+                               "could reduce unnecessary bounce buffering.\n",
+                               name);
+
+               pr_info("%s: DMA window size is 0x%llx\n", name,
+                       (u64)hose->dma_window_size);
+       }
 
        iounmap(pci);
 }
@@ -176,19 +282,9 @@ static void __init setup_pci_cmd(struct pci_controller *hose)
        }
 }
 
-static void __init setup_pci_pcsrbar(struct pci_controller *hose)
-{
-#ifdef CONFIG_PCI_MSI
-       phys_addr_t immr_base;
-
-       immr_base = get_immrbase();
-       early_write_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, immr_base);
-#endif
-}
-
 void fsl_pcibios_fixup_bus(struct pci_bus *bus)
 {
-       struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        int i;
 
        if ((bus->parent == hose->bus) &&
@@ -269,8 +365,6 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
        /* Setup PEX window registers */
        setup_pci_atmu(hose, &rsrc);
 
-       /* Setup PEXCSRBAR */
-       setup_pci_pcsrbar(hose);
        return 0;
 }
 
@@ -281,6 +375,8 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8543, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8547E, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8545E, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8545, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8569E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8569, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8568E, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_header);
@@ -296,6 +392,8 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8536, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2020E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2020, quirk_fsl_pcie_header);
 #endif /* CONFIG_PPC_85xx || CONFIG_PPC_86xx */
 
 #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)
@@ -324,7 +422,7 @@ struct mpc83xx_pcie_priv {
 
 static int mpc83xx_pcie_exclude_device(struct pci_bus *bus, unsigned int devfn)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
 
        if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK)
                return PCIBIOS_DEVICE_NOT_FOUND;
@@ -350,7 +448,7 @@ static int mpc83xx_pcie_exclude_device(struct pci_bus *bus, unsigned int devfn)
 static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus,
                                            unsigned int devfn, int offset)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        struct mpc83xx_pcie_priv *pcie = hose->dn->data;
        u8 bus_no = bus->number - hose->first_busno;
        u32 dev_base = bus_no << 24 | devfn << 16;
index 13f30c2..a9d8bbe 100644 (file)
 
 #define PCIE_LTSSM     0x0404          /* PCIE Link Training and Status */
 #define PCIE_LTSSM_L0  0x16            /* L0 state */
-#define PIWAR_2G       0xa0f5501e      /* Enable, Prefetch, Local Mem, Snoop R/W, 2G */
+#define PIWAR_EN               0x80000000      /* Enable */
+#define PIWAR_PF               0x20000000      /* prefetch */
+#define PIWAR_TGI_LOCAL                0x00f00000      /* target - local memory */
+#define PIWAR_READ_SNOOP       0x00050000
+#define PIWAR_WRITE_SNOOP      0x00005000
 
 /* PCI/PCI Express outbound window reg */
 struct pci_outbound_window_regs {
index abdb124..39db9d1 100644 (file)
@@ -1026,8 +1026,7 @@ int fsl_rio_setup(struct of_device *dev)
                return -EFAULT;
        }
        dev_info(&dev->dev, "Of-device full name %s\n", dev->node->full_name);
-       dev_info(&dev->dev, "Regs start 0x%08x size 0x%08x\n",  regs.start,
-                                               regs.end - regs.start + 1);
+       dev_info(&dev->dev, "Regs: %pR\n", &regs);
 
        dt_range = of_get_property(dev->node, "ranges", &rlen);
        if (!dt_range) {
@@ -1077,8 +1076,9 @@ int fsl_rio_setup(struct of_device *dev)
 
        INIT_LIST_HEAD(&port->dbells);
        port->iores.start = law_start;
-       port->iores.end = law_start + law_size;
+       port->iores.end = law_start + law_size - 1;
        port->iores.flags = IORESOURCE_MEM;
+       port->iores.name = "rio_io_win";
 
        priv->bellirq = irq_of_parse_and_map(dev->node, 2);
        priv->txirq = irq_of_parse_and_map(dev->node, 3);
@@ -1156,14 +1156,15 @@ int fsl_rio_setup(struct of_device *dev)
                out_be32((priv->regs_win + RIO_ISR_AACR), RIO_ISR_AACR_AA);
 
        /* Configure maintenance transaction window */
-       out_be32(&priv->maint_atmu_regs->rowbar, 0x000c0000);
-       out_be32(&priv->maint_atmu_regs->rowar, 0x80077015);
+       out_be32(&priv->maint_atmu_regs->rowbar, law_start >> 12);
+       out_be32(&priv->maint_atmu_regs->rowar, 0x80077015);    /* 4M */
 
        priv->maint_win = ioremap(law_start, RIO_MAINT_WIN_SIZE);
 
        /* Configure outbound doorbell window */
-       out_be32(&priv->dbell_atmu_regs->rowbar, 0x000c0400);
-       out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b);
+       out_be32(&priv->dbell_atmu_regs->rowbar,
+                       (law_start + RIO_MAINT_WIN_SIZE) >> 12);
+       out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b);    /* 4k */
        fsl_rio_doorbell_init(port);
 
        return 0;
index 5c64ccd..95dbc64 100644 (file)
@@ -379,16 +379,10 @@ static int __init setup_rstcr(void)
        struct device_node *np;
        np = of_find_node_by_name(NULL, "global-utilities");
        if ((np && of_get_property(np, "fsl,has-rstcr", NULL))) {
-               const u32 *prop = of_get_property(np, "reg", NULL);
-               if (prop) {
-                       /* map reset control register
-                        * 0xE00B0 is offset of reset control register
-                        */
-                       rstcr = ioremap(get_immrbase() + *prop + 0xB0, 0xff);
-                       if (!rstcr)
-                               printk (KERN_EMERG "Error: reset control "
-                                               "register not mapped!\n");
-               }
+               rstcr = of_iomap(np, 0) + 0xb0;
+               if (!rstcr)
+                       printk (KERN_EMERG "Error: reset control register "
+                                       "not mapped!\n");
        } else
                printk (KERN_INFO "rstcr compatible register does not exist!\n");
        if (np)
index 7fd49c9..7ed8096 100644 (file)
@@ -24,7 +24,7 @@ static int
 indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
                     int len, u32 *val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        volatile void __iomem *cfg_data;
        u8 cfg_type = 0;
        u32 bus_no, reg;
@@ -82,7 +82,7 @@ static int
 indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
                      int len, u32 val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        volatile void __iomem *cfg_data;
        u8 cfg_type = 0;
        u32 bus_no, reg;
index 352d8c3..9c3af50 100644 (file)
@@ -613,23 +613,23 @@ static int irq_choose_cpu(unsigned int virt_irq)
 #define mpic_irq_to_hw(virq)   ((unsigned int)irq_map[virq].hwirq)
 
 /* Find an mpic associated with a given linux interrupt */
-static struct mpic *mpic_find(unsigned int irq, unsigned int *is_ipi)
+static struct mpic *mpic_find(unsigned int irq)
 {
-       unsigned int src = mpic_irq_to_hw(irq);
-       struct mpic *mpic;
-
        if (irq < NUM_ISA_INTERRUPTS)
                return NULL;
 
-       mpic = irq_desc[irq].chip_data;
+       return irq_desc[irq].chip_data;
+}
 
-       if (is_ipi)
-               *is_ipi = (src >= mpic->ipi_vecs[0] &&
-                          src <= mpic->ipi_vecs[3]);
+/* Determine if the linux irq is an IPI */
+static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int irq)
+{
+       unsigned int src = mpic_irq_to_hw(irq);
 
-       return mpic;
+       return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]);
 }
 
+
 /* Convert a cpu mask from logical to physical cpu numbers. */
 static inline u32 mpic_physmask(u32 cpumask)
 {
@@ -1383,8 +1383,7 @@ void __init mpic_set_serial_int(struct mpic *mpic, int enable)
 
 void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
 {
-       unsigned int is_ipi;
-       struct mpic *mpic = mpic_find(irq, &is_ipi);
+       struct mpic *mpic = mpic_find(irq);
        unsigned int src = mpic_irq_to_hw(irq);
        unsigned long flags;
        u32 reg;
@@ -1393,7 +1392,7 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
                return;
 
        spin_lock_irqsave(&mpic_lock, flags);
-       if (is_ipi) {
+       if (mpic_is_ipi(mpic, irq)) {
                reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) &
                        ~MPIC_VECPRI_PRIORITY_MASK;
                mpic_ipi_write(src - mpic->ipi_vecs[0],
index 6a2d473..daefc93 100644 (file)
@@ -1295,7 +1295,7 @@ static void __iomem *ppc4xx_pciex_get_config_base(struct ppc4xx_pciex_port *port
 static int ppc4xx_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
                                    int offset, int len, u32 *val)
 {
-       struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        struct ppc4xx_pciex_port *port =
                &ppc4xx_pciex_ports[hose->indirect_type];
        void __iomem *addr;
@@ -1352,7 +1352,7 @@ static int ppc4xx_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
 static int ppc4xx_pciex_write_config(struct pci_bus *bus, unsigned int devfn,
                                     int offset, int len, u32 val)
 {
-       struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        struct ppc4xx_pciex_port *port =
                &ppc4xx_pciex_ports[hose->indirect_type];
        void __iomem *addr;
index 01bce37..b28b0e5 100644 (file)
@@ -61,6 +61,7 @@ struct qe_immap __iomem *qe_immr;
 EXPORT_SYMBOL(qe_immr);
 
 static struct qe_snum snums[QE_NUM_OF_SNUM];   /* Dynamically allocated SNUMs */
+static unsigned int qe_num_of_snum;
 
 static phys_addr_t qebase = -1;
 
@@ -264,10 +265,14 @@ static void qe_snums_init(void)
                0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
                0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
                0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
-               0xD8, 0xD9, 0xE8, 0xE9,
+               0xD8, 0xD9, 0xE8, 0xE9, 0x08, 0x09, 0x18, 0x19,
+               0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,
+               0x68, 0x69, 0x78, 0x79, 0x80, 0x81,
        };
 
-       for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+       qe_num_of_snum = qe_get_num_of_snums();
+
+       for (i = 0; i < qe_num_of_snum; i++) {
                snums[i].num = snum_init[i];
                snums[i].state = QE_SNUM_STATE_FREE;
        }
@@ -280,7 +285,7 @@ int qe_get_snum(void)
        int i;
 
        spin_lock_irqsave(&qe_lock, flags);
-       for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+       for (i = 0; i < qe_num_of_snum; i++) {
                if (snums[i].state == QE_SNUM_STATE_FREE) {
                        snums[i].state = QE_SNUM_STATE_USED;
                        snum = snums[i].num;
@@ -297,7 +302,7 @@ void qe_put_snum(u8 snum)
 {
        int i;
 
-       for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+       for (i = 0; i < qe_num_of_snum; i++) {
                if (snums[i].num == snum) {
                        snums[i].state = QE_SNUM_STATE_FREE;
                        break;
@@ -575,3 +580,65 @@ struct qe_firmware_info *qe_get_firmware_info(void)
 }
 EXPORT_SYMBOL(qe_get_firmware_info);
 
+unsigned int qe_get_num_of_risc(void)
+{
+       struct device_node *qe;
+       int size;
+       unsigned int num_of_risc = 0;
+       const u32 *prop;
+
+       qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
+       if (!qe) {
+               /* Older devices trees did not have an "fsl,qe"
+                * compatible property, so we need to look for
+                * the QE node by name.
+                */
+               qe = of_find_node_by_type(NULL, "qe");
+               if (!qe)
+                       return num_of_risc;
+       }
+
+       prop = of_get_property(qe, "fsl,qe-num-riscs", &size);
+       if (prop && size == sizeof(*prop))
+               num_of_risc = *prop;
+
+       of_node_put(qe);
+
+       return num_of_risc;
+}
+EXPORT_SYMBOL(qe_get_num_of_risc);
+
+unsigned int qe_get_num_of_snums(void)
+{
+       struct device_node *qe;
+       int size;
+       unsigned int num_of_snums;
+       const u32 *prop;
+
+       num_of_snums = 28; /* The default number of snum for threads is 28 */
+       qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
+       if (!qe) {
+               /* Older devices trees did not have an "fsl,qe"
+                * compatible property, so we need to look for
+                * the QE node by name.
+                */
+               qe = of_find_node_by_type(NULL, "qe");
+               if (!qe)
+                       return num_of_snums;
+       }
+
+       prop = of_get_property(qe, "fsl,qe-num-snums", &size);
+       if (prop && size == sizeof(*prop)) {
+               num_of_snums = *prop;
+               if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) {
+                       /* No QE ever has fewer than 28 SNUMs */
+                       pr_err("QE: number of snum is invalid\n");
+                       return -EINVAL;
+               }
+       }
+
+       of_node_put(qe);
+
+       return num_of_snums;
+}
+EXPORT_SYMBOL(qe_get_num_of_snums);
index 24e1f5a..cf244a4 100644 (file)
@@ -63,7 +63,7 @@ tsi108_direct_write_config(struct pci_bus *bus, unsigned int devfunc,
                           int offset, int len, u32 val)
 {
        volatile unsigned char *cfg_addr;
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
 
        if (ppc_md.pci_exclude_device)
                if (ppc_md.pci_exclude_device(hose, bus->number, devfunc))
@@ -149,7 +149,7 @@ tsi108_direct_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
                          int len, u32 * val)
 {
        volatile unsigned char *cfg_addr;
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        u32 temp;
 
        if (ppc_md.pci_exclude_device)
index c658b41..3ee1fd3 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/of.h>
 #include <asm/io.h>
 #include <asm/processor.h>
+#include <asm/i8259.h>
 #include <asm/irq.h>
 
 /*
@@ -191,20 +192,14 @@ struct irq_host * __init
 xilinx_intc_init(struct device_node *np)
 {
        struct irq_host * irq;
-       struct resource res;
        void * regs;
-       int rc;
 
        /* Find and map the intc registers */
-       rc = of_address_to_resource(np, 0, &res);
-       if (rc) {
-               printk(KERN_ERR __FILE__ ": of_address_to_resource() failed\n");
+       regs = of_iomap(np, 0);
+       if (!regs) {
+               pr_err("xilinx_intc: could not map registers\n");
                return NULL;
        }
-       regs = ioremap(res.start, 32);
-
-       printk(KERN_INFO "Xilinx intc at 0x%08llx mapped to 0x%p\n",
-               (unsigned long long) res.start, regs);
 
        /* Setup interrupt controller */
        out_be32(regs + XINTC_IER, 0); /* disable all irqs */
@@ -217,6 +212,7 @@ xilinx_intc_init(struct device_node *np)
        if (!irq)
                panic(__FILE__ ": Cannot allocate IRQ host\n");
        irq->host_data = regs;
+
        return irq;
 }
 
@@ -227,23 +223,70 @@ int xilinx_intc_get_irq(void)
        return irq_linear_revmap(master_irqhost, in_be32(regs + XINTC_IVR));
 }
 
+#if defined(CONFIG_PPC_I8259)
+/*
+ * Support code for cascading to 8259 interrupt controllers
+ */
+static void xilinx_i8259_cascade(unsigned int irq, struct irq_desc *desc)
+{
+       unsigned int cascade_irq = i8259_irq();
+       if (cascade_irq)
+               generic_handle_irq(cascade_irq);
+
+       /* Let xilinx_intc end the interrupt */
+       desc->chip->ack(irq);
+       desc->chip->unmask(irq);
+}
+
+static void __init xilinx_i8259_setup_cascade(void)
+{
+       struct device_node *cascade_node;
+       int cascade_irq;
+
+       /* Initialize i8259 controller */
+       cascade_node = of_find_compatible_node(NULL, NULL, "chrp,iic");
+       if (!cascade_node)
+               return;
+
+       cascade_irq = irq_of_parse_and_map(cascade_node, 0);
+       if (!cascade_irq) {
+               pr_err("virtex_ml510: Failed to map cascade interrupt\n");
+               goto out;
+       }
+
+       i8259_init(cascade_node, 0);
+       set_irq_chained_handler(cascade_irq, xilinx_i8259_cascade);
+
+       /* Program irq 7 (usb/audio), 14/15 (ide) to level sensitive */
+       /* This looks like a dirty hack to me --gcl */
+       outb(0xc0, 0x4d0);
+       outb(0xc0, 0x4d1);
+
+ out:
+       of_node_put(cascade_node);
+}
+#else
+static inline void xilinx_i8259_setup_cascade(void) { return; }
+#endif /* defined(CONFIG_PPC_I8259) */
+
+static struct of_device_id xilinx_intc_match[] __initconst = {
+       { .compatible = "xlnx,opb-intc-1.00.c", },
+       { .compatible = "xlnx,xps-intc-1.00.a", },
+       {}
+};
+
+/*
+ * Initialize master Xilinx interrupt controller
+ */
 void __init xilinx_intc_init_tree(void)
 {
        struct device_node *np;
 
        /* find top level interrupt controller */
-       for_each_compatible_node(np, NULL, "xlnx,opb-intc-1.00.c") {
+       for_each_matching_node(np, xilinx_intc_match) {
                if (!of_get_property(np, "interrupts", NULL))
                        break;
        }
-       if (!np) {
-               for_each_compatible_node(np, NULL, "xlnx,xps-intc-1.00.a") {
-                       if (!of_get_property(np, "interrupts", NULL))
-                               break;
-               }
-       }
-
-       /* xilinx interrupt controller needs to be top level */
        BUG_ON(!np);
 
        master_irqhost = xilinx_intc_init(np);
@@ -251,4 +294,6 @@ void __init xilinx_intc_init_tree(void)
 
        irq_set_default_host(master_irqhost);
        of_node_put(np);
+
+       xilinx_i8259_setup_cascade();
 }
diff --git a/arch/powerpc/sysdev/xilinx_pci.c b/arch/powerpc/sysdev/xilinx_pci.c
new file mode 100644 (file)
index 0000000..1453b0e
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * PCI support for Xilinx plbv46_pci soft-core which can be used on
+ * Xilinx Virtex ML410 / ML510 boards.
+ *
+ * Copyright 2009 Roderick Colenbrander
+ * Copyright 2009 Secret Lab Technologies Ltd.
+ *
+ * The pci bridge fixup code was copied from ppc4xx_pci.c and was written
+ * by Benjamin Herrenschmidt.
+ * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/ioport.h>
+#include <linux/of.h>
+#include <linux/pci.h>
+#include <mm/mmu_decl.h>
+#include <asm/io.h>
+#include <asm/xilinx_pci.h>
+
+#define XPLB_PCI_ADDR 0x10c
+#define XPLB_PCI_DATA 0x110
+#define XPLB_PCI_BUS  0x114
+
+#define PCI_HOST_ENABLE_CMD PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY
+
+static struct of_device_id xilinx_pci_match[] = {
+       { .compatible = "xlnx,plbv46-pci-1.03.a", },
+       {}
+};
+
+/**
+ * xilinx_pci_fixup_bridge - Block Xilinx PHB configuration.
+ */
+static void xilinx_pci_fixup_bridge(struct pci_dev *dev)
+{
+       struct pci_controller *hose;
+       int i;
+
+       if (dev->devfn || dev->bus->self)
+               return;
+
+       hose = pci_bus_to_host(dev->bus);
+       if (!hose)
+               return;
+
+       if (!of_match_node(xilinx_pci_match, hose->dn))
+               return;
+
+       /* Hide the PCI host BARs from the kernel as their content doesn't
+        * fit well in the resource management
+        */
+       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+               dev->resource[i].start = 0;
+               dev->resource[i].end = 0;
+               dev->resource[i].flags = 0;
+       }
+
+       dev_info(&dev->dev, "Hiding Xilinx plb-pci host bridge resources %s\n",
+                pci_name(dev));
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, xilinx_pci_fixup_bridge);
+
+/**
+ * xilinx_pci_exclude_device - Don't do config access for non-root bus
+ *
+ * This is a hack.  Config access to any bus other than bus 0 does not
+ * currently work on the ML510 so we prevent it here.
+ */
+static int
+xilinx_pci_exclude_device(struct pci_controller *hose, u_char bus, u8 devfn)
+{
+       return (bus != 0);
+}
+
+/**
+ * xilinx_pci_init - Find and register a Xilinx PCI host bridge
+ */
+void __init xilinx_pci_init(void)
+{
+       struct pci_controller *hose;
+       struct resource r;
+       void __iomem *pci_reg;
+       struct device_node *pci_node;
+
+       pci_node = of_find_matching_node(NULL, xilinx_pci_match);
+       if(!pci_node)
+               return;
+
+       if (of_address_to_resource(pci_node, 0, &r)) {
+               pr_err("xilinx-pci: cannot resolve base address\n");
+               return;
+       }
+
+       hose = pcibios_alloc_controller(pci_node);
+       if (!hose) {
+               pr_err("xilinx-pci: pcibios_alloc_controller() failed\n");
+               return;
+       }
+
+       /* Setup config space */
+       setup_indirect_pci(hose, r.start + XPLB_PCI_ADDR,
+                          r.start + XPLB_PCI_DATA,
+                          PPC_INDIRECT_TYPE_SET_CFG_TYPE);
+
+       /* According to the xilinx plbv46_pci documentation the soft-core starts
+        * a self-init when the bus master enable bit is set. Without this bit
+        * set the pci bus can't be scanned.
+        */
+       early_write_config_word(hose, 0, 0, PCI_COMMAND, PCI_HOST_ENABLE_CMD);
+
+       /* Set the max latency timer to 255 */
+       early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0xff);
+
+       /* Set the max bus number to 255 */
+       pci_reg = of_iomap(pci_node, 0);
+       out_8(pci_reg + XPLB_PCI_BUS, 0xff);
+       iounmap(pci_reg);
+
+       /* Nothing past the root bridge is working right now.  By default
+        * exclude config access to anything except bus 0 */
+       if (!ppc_md.pci_exclude_device)
+               ppc_md.pci_exclude_device = xilinx_pci_exclude_device;
+
+       /* Register the host bridge with the linux kernel! */
+       pci_process_bridge_OF_ranges(hose, pci_node, 1);
+
+       pr_info("xilinx-pci: Registered PCI host bridge\n");
+}
index 8dfad7d..e1f33a8 100644 (file)
@@ -110,6 +110,7 @@ static int bsesc(void);
 static void dump(void);
 static void prdump(unsigned long, long);
 static int ppc_inst_dump(unsigned long, long, int);
+static void dump_log_buf(void);
 static void backtrace(struct pt_regs *);
 static void excprint(struct pt_regs *);
 static void prregs(struct pt_regs *);
@@ -197,6 +198,7 @@ Commands:\n\
   di   dump instructions\n\
   df   dump float values\n\
   dd   dump double values\n\
+  dl    dump the kernel log buffer\n\
   dr   dump stream of raw bytes\n\
   e    print exception information\n\
   f    flush cache\n\
@@ -2009,6 +2011,8 @@ dump(void)
                        nidump = MAX_DUMP;
                adrs += ppc_inst_dump(adrs, nidump, 1);
                last_cmd = "di\n";
+       } else if (c == 'l') {
+               dump_log_buf();
        } else if (c == 'r') {
                scanhex(&ndump);
                if (ndump == 0)
@@ -2122,6 +2126,49 @@ print_address(unsigned long addr)
        xmon_print_symbol(addr, "\t# ", "");
 }
 
+void
+dump_log_buf(void)
+{
+        const unsigned long size = 128;
+        unsigned long end, addr;
+        unsigned char buf[size + 1];
+
+        addr = 0;
+        buf[size] = '\0';
+
+        if (setjmp(bus_error_jmp) != 0) {
+                printf("Unable to lookup symbol __log_buf!\n");
+                return;
+        }
+
+        catch_memory_errors = 1;
+        sync();
+        addr = kallsyms_lookup_name("__log_buf");
+
+        if (! addr)
+                printf("Symbol __log_buf not found!\n");
+        else {
+                end = addr + (1 << CONFIG_LOG_BUF_SHIFT);
+                while (addr < end) {
+                        if (! mread(addr, buf, size)) {
+                                printf("Can't read memory at address 0x%lx\n", addr);
+                                break;
+                        }
+
+                        printf("%s", buf);
+
+                        if (strlen(buf) < size)
+                                break;
+
+                        addr += size;
+                }
+        }
+
+        sync();
+        /* wait a little while to see if we get a machine check */
+        __delay(200);
+        catch_memory_errors = 0;
+}
 
 /*
  * Memory operations - move, set, print differences
index ffc9254..042c814 100644 (file)
@@ -867,7 +867,7 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
        int j;
        struct device_node *node = vdev->dev.archdata.of_node;
 
-       if (i > VIOTAPE_MAX_TAPE)
+       if (i >= VIOTAPE_MAX_TAPE)
                return -ENODEV;
        if (!node)
                return -ENODEV;
index 8b92a46..e447674 100644 (file)
@@ -756,12 +756,12 @@ static int __devinit iic_probe(struct of_device *ofdev,
                goto error_cleanup;
        }
 
-       /* Now register all the child nodes */
-       of_register_i2c_devices(adap, np);
-
        dev_info(&ofdev->dev, "using %s mode\n",
                 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
 
+       /* Now register all the child nodes */
+       of_register_i2c_devices(adap, np);
+
        return 0;
 
 error_cleanup:
index c0621d5..0ddf904 100644 (file)
@@ -37,6 +37,7 @@
 #define CONFIG_REG   0x40
 #define MANUAL_MASK  0xe0
 #define AUTO_MASK    0x20
+#define INVERT_MASK  0x10
 
 static u8 TEMP_REG[3]    = {0x26, 0x25, 0x27}; /* local, sensor1, sensor2 */
 static u8 LIMIT_REG[3]   = {0x6b, 0x6a, 0x6c}; /* local, sensor1, sensor2 */
@@ -229,7 +230,8 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan)
        
        if (speed >= 0) {
                manual = read_reg(th, MANUAL_MODE[fan]);
-               write_reg(th, MANUAL_MODE[fan], manual|MANUAL_MASK);
+               write_reg(th, MANUAL_MODE[fan],
+                       (manual|MANUAL_MASK) & (~INVERT_MASK));
                write_reg(th, FAN_SPD_SET[fan], speed);
        } else {
                /* back to automatic */
index fd6140b..e2f2e91 100644 (file)
@@ -273,7 +273,7 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
                                  u8 num_entries,
                                  u32 thread_size,
                                  u32 thread_alignment,
-                                 enum qe_risc_allocation risc,
+                                 unsigned int risc,
                                  int skip_page_for_first_entry)
 {
        u32 init_enet_offset;
@@ -310,7 +310,7 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
 static int return_init_enet_entries(struct ucc_geth_private *ugeth,
                                    u32 *p_start,
                                    u8 num_entries,
-                                   enum qe_risc_allocation risc,
+                                   unsigned int risc,
                                    int skip_page_for_first_entry)
 {
        u32 init_enet_offset;
@@ -345,7 +345,7 @@ static int dump_init_enet_entries(struct ucc_geth_private *ugeth,
                                  u32 __iomem *p_start,
                                  u8 num_entries,
                                  u32 thread_size,
-                                 enum qe_risc_allocation risc,
+                                 unsigned int risc,
                                  int skip_page_for_first_entry)
 {
        u32 init_enet_offset;
@@ -2180,6 +2180,14 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
                return -ENOMEM;
        }
 
+       /* read the number of risc engines, update the riscTx and riscRx
+        * if there are 4 riscs in QE
+        */
+       if (qe_get_num_of_risc() == 4) {
+               ug_info->riscTx = QE_RISC_ALLOCATION_FOUR_RISCS;
+               ug_info->riscRx = QE_RISC_ALLOCATION_FOUR_RISCS;
+       }
+
        ugeth->ug_regs = ioremap(uf_info->regs, sizeof(*ugeth->ug_regs));
        if (!ugeth->ug_regs) {
                if (netif_msg_probe(ugeth))
@@ -3744,7 +3752,15 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
                ug_info->uf_info.utfet = UCC_GETH_UTFET_GIGA_INIT;
                ug_info->uf_info.utftt = UCC_GETH_UTFTT_GIGA_INIT;
                ug_info->numThreadsTx = UCC_GETH_NUM_OF_THREADS_4;
-               ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4;
+
+               /* If QE's snum number is 46 which means we need to support
+                * 4 UECs at 1000Base-T simultaneously, we need to allocate
+                * more Threads to Rx.
+                */
+               if (qe_get_num_of_snums() == 46)
+                       ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_6;
+               else
+                       ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4;
        }
 
        if (netif_msg_probe(&debug))
index deb962b..5beba4c 100644 (file)
@@ -1144,8 +1144,8 @@ struct ucc_geth_info {
        enum ucc_geth_maccfg2_pad_and_crc_mode padAndCrc;
        enum ucc_geth_num_of_threads numThreadsTx;
        enum ucc_geth_num_of_threads numThreadsRx;
-       enum qe_risc_allocation riscTx;
-       enum qe_risc_allocation riscRx;
+       unsigned int riscTx;
+       unsigned int riscRx;
 };
 
 /* structure representing UCC GETH */
index ddf224d..69f85c0 100644 (file)
@@ -447,6 +447,7 @@ struct of_modalias_table {
 static struct of_modalias_table of_modalias_table[] = {
        { "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" },
        { "mmc-spi-slot", "mmc_spi" },
+       { "stm,m25p40", "m25p80" },
 };
 
 /**
index ba6af16..b77ae67 100644 (file)
@@ -39,7 +39,6 @@ obj-$(CONFIG_ALPHA) += setup-bus.o setup-irq.o
 obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o
 obj-$(CONFIG_PARISC) += setup-bus.o
 obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o
-obj-$(CONFIG_PPC32) += setup-irq.o
 obj-$(CONFIG_PPC) += setup-bus.o
 obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
 obj-$(CONFIG_X86_VISWS) += setup-irq.o
index 74d0bfa..3b78540 100644 (file)
@@ -290,7 +290,7 @@ static void __devinit rio_add_device(struct rio_dev *rdev)
  * to a RIO device on success or NULL on failure.
  *
  */
-static struct rio_dev *rio_setup_device(struct rio_net *net,
+static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
                                        struct rio_mport *port, u16 destid,
                                        u8 hopcount, int do_enum)
 {
@@ -559,7 +559,7 @@ static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port)
  * Recursively enumerates a RIO network.  Transactions are sent via the
  * master port passed in @port.
  */
-static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
+static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
                         u8 hopcount)
 {
        int port_num;
@@ -718,7 +718,7 @@ static int rio_enum_complete(struct rio_mport *port)
  * Recursively discovers a RIO network.  Transactions are sent via the
  * master port passed in @port.
  */
-static int
+static int __devinit
 rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
              u8 hopcount)
 {
index e58c0ce..f431779 100644 (file)
@@ -47,6 +47,16 @@ config REGULATOR_VIRTUAL_CONSUMER
 
           If unsure, say no.
 
+config REGULATOR_USERSPACE_CONSUMER
+       tristate "Userspace regulator consumer support"
+       default n
+       help
+         There are some classes of devices that are controlled entirely
+         from user space. Usersapce consumer driver provides ability to
+         control power supplies for such devices.
+
+          If unsure, say no.
+
 config REGULATOR_BQ24022
        tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC"
        default n
@@ -56,6 +66,15 @@ config REGULATOR_BQ24022
          charging select between 100 mA and 500 mA charging current
          limit.
 
+config REGULATOR_MAX1586
+       tristate "Maxim 1586/1587 voltage regulator"
+       depends on I2C
+       default n
+       help
+         This driver controls a Maxim 1586 or 1587 voltage output
+         regulator via I2C bus. The provided regulator is suitable
+         for PXA27x chips to control VCC_CORE and VCC_USIM voltages.
+
 config REGULATOR_TWL4030
        bool "TI TWL4030/TWL5030/TPS695x0 PMIC"
        depends on TWL4030_CORE
@@ -91,4 +110,11 @@ config REGULATOR_PCF50633
         Say Y here to support the voltage regulators and convertors
         on PCF50633
 
+config REGULATOR_LP3971
+       tristate "National Semiconductors LP3971 PMIC regulator driver"
+       depends on I2C
+       help
+        Say Y here to support the voltage regulators and convertors
+        on National Semiconductors LP3971 PMIC
+
 endif
index bac133a..4d762c4 100644 (file)
@@ -6,8 +6,11 @@
 obj-$(CONFIG_REGULATOR) += core.o
 obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
 obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
+obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
 
 obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
+obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
+obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
 obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
 obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
 obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
index c6628f5..b8b89ef 100644 (file)
@@ -504,7 +504,7 @@ static int __init da903x_regulator_init(void)
 {
        return platform_driver_register(&da903x_regulator_driver);
 }
-module_init(da903x_regulator_init);
+subsys_initcall(da903x_regulator_init);
 
 static void __exit da903x_regulator_exit(void)
 {
index 23d5546..cdc674f 100644 (file)
@@ -44,10 +44,22 @@ static int fixed_voltage_get_voltage(struct regulator_dev *dev)
        return data->microvolts;
 }
 
+static int fixed_voltage_list_voltage(struct regulator_dev *dev,
+                                     unsigned selector)
+{
+       struct fixed_voltage_data *data = rdev_get_drvdata(dev);
+
+       if (selector != 0)
+               return -EINVAL;
+
+       return data->microvolts;
+}
+
 static struct regulator_ops fixed_voltage_ops = {
        .is_enabled = fixed_voltage_is_enabled,
        .enable = fixed_voltage_enable,
        .get_voltage = fixed_voltage_get_voltage,
+       .list_voltage = fixed_voltage_list_voltage,
 };
 
 static int regulator_fixed_voltage_probe(struct platform_device *pdev)
@@ -69,7 +81,8 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
        }
        drvdata->desc.type = REGULATOR_VOLTAGE;
        drvdata->desc.owner = THIS_MODULE;
-       drvdata->desc.ops = &fixed_voltage_ops,
+       drvdata->desc.ops = &fixed_voltage_ops;
+       drvdata->desc.n_voltages = 1;
 
        drvdata->microvolts = config->microvolts;
 
@@ -117,7 +130,7 @@ static int __init regulator_fixed_voltage_init(void)
 {
        return platform_driver_register(&regulator_fixed_voltage_driver);
 }
-module_init(regulator_fixed_voltage_init);
+subsys_initcall(regulator_fixed_voltage_init);
 
 static void __exit regulator_fixed_voltage_exit(void)
 {
@@ -128,3 +141,4 @@ module_exit(regulator_fixed_voltage_exit);
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_DESCRIPTION("Fixed voltage regulator");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:reg-fixed-voltage");
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c
new file mode 100644 (file)
index 0000000..a61018a
--- /dev/null
@@ -0,0 +1,562 @@
+/*
+ * Regulator driver for National Semiconductors LP3971 PMIC chip
+ *
+ *  Copyright (C) 2009 Samsung Electronics
+ *  Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * Based on wm8350.c
+ *
+ * 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.
+ *
+ */
+
+#include <linux/bug.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/lp3971.h>
+
+struct lp3971 {
+       struct device *dev;
+       struct mutex io_lock;
+       struct i2c_client *i2c;
+       int num_regulators;
+       struct regulator_dev **rdev;
+};
+
+static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg);
+static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val);
+
+#define LP3971_SYS_CONTROL1_REG 0x07
+
+/* System control register 1 initial value,
+   bits 4 and 5 are EPROM programmable */
+#define SYS_CONTROL1_INIT_VAL 0x40
+#define SYS_CONTROL1_INIT_MASK 0xCF
+
+#define LP3971_BUCK_VOL_ENABLE_REG 0x10
+#define LP3971_BUCK_VOL_CHANGE_REG 0x20
+
+/*     Voltage control registers shift:
+       LP3971_BUCK1 -> 0
+       LP3971_BUCK2 -> 4
+       LP3971_BUCK3 -> 6
+*/
+#define BUCK_VOL_CHANGE_SHIFT(x) (((1 << x) & ~0x01) << 1)
+#define BUCK_VOL_CHANGE_FLAG_GO 0x01
+#define BUCK_VOL_CHANGE_FLAG_TARGET 0x02
+#define BUCK_VOL_CHANGE_FLAG_MASK 0x03
+
+#define LP3971_BUCK1_BASE 0x23
+#define LP3971_BUCK2_BASE 0x29
+#define LP3971_BUCK3_BASE 0x32
+
+const static int buck_base_addr[] = {
+       LP3971_BUCK1_BASE,
+       LP3971_BUCK2_BASE,
+       LP3971_BUCK3_BASE,
+};
+
+#define LP3971_BUCK_TARGET_VOL1_REG(x) (buck_base_addr[x])
+#define LP3971_BUCK_TARGET_VOL2_REG(x) (buck_base_addr[x]+1)
+
+const static int buck_voltage_map[] = {
+          0,  800,  850,  900,  950, 1000, 1050, 1100,
+       1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500,
+       1550, 1600, 1650, 1700, 1800, 1900, 2500, 2800,
+       3000, 3300,
+};
+
+#define BUCK_TARGET_VOL_MASK 0x3f
+#define BUCK_TARGET_VOL_MIN_IDX 0x01
+#define BUCK_TARGET_VOL_MAX_IDX 0x19
+
+#define LP3971_BUCK_RAMP_REG(x)        (buck_base_addr[x]+2)
+
+#define LP3971_LDO_ENABLE_REG 0x12
+#define LP3971_LDO_VOL_CONTR_BASE 0x39
+
+/*     Voltage control registers:
+       LP3971_LDO1 -> LP3971_LDO_VOL_CONTR_BASE + 0
+       LP3971_LDO2 -> LP3971_LDO_VOL_CONTR_BASE + 0
+       LP3971_LDO3 -> LP3971_LDO_VOL_CONTR_BASE + 1
+       LP3971_LDO4 -> LP3971_LDO_VOL_CONTR_BASE + 1
+       LP3971_LDO5 -> LP3971_LDO_VOL_CONTR_BASE + 2
+*/
+#define LP3971_LDO_VOL_CONTR_REG(x)    (LP3971_LDO_VOL_CONTR_BASE + (x >> 1))
+
+/*     Voltage control registers shift:
+       LP3971_LDO1 -> 0, LP3971_LDO2 -> 4
+       LP3971_LDO3 -> 0, LP3971_LDO4 -> 4
+       LP3971_LDO5 -> 0
+*/
+#define LDO_VOL_CONTR_SHIFT(x) ((x & 1) << 2)
+#define LDO_VOL_CONTR_MASK 0x0f
+
+const static int ldo45_voltage_map[] = {
+       1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350,
+       1400, 1500, 1800, 1900, 2500, 2800, 3000, 3300,
+};
+
+const static int ldo123_voltage_map[] = {
+       1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500,
+       2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300,
+};
+
+const static int *ldo_voltage_map[] = {
+       ldo123_voltage_map, /* LDO1 */
+       ldo123_voltage_map, /* LDO2 */
+       ldo123_voltage_map, /* LDO3 */
+       ldo45_voltage_map, /* LDO4 */
+       ldo45_voltage_map, /* LDO5 */
+};
+
+#define LDO_VOL_VALUE_MAP(x) (ldo_voltage_map[(x - LP3971_LDO1)])
+
+#define LDO_VOL_MIN_IDX 0x00
+#define LDO_VOL_MAX_IDX 0x0f
+
+static int lp3971_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
+{
+       int ldo = rdev_get_id(dev) - LP3971_LDO1;
+       return 1000 * LDO_VOL_VALUE_MAP(ldo)[index];
+}
+
+static int lp3971_ldo_is_enabled(struct regulator_dev *dev)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int ldo = rdev_get_id(dev) - LP3971_LDO1;
+       u16 mask = 1 << (1 + ldo);
+       u16 val;
+
+       val = lp3971_reg_read(lp3971, LP3971_LDO_ENABLE_REG);
+       return (val & mask) != 0;
+}
+
+static int lp3971_ldo_enable(struct regulator_dev *dev)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int ldo = rdev_get_id(dev) - LP3971_LDO1;
+       u16 mask = 1 << (1 + ldo);
+
+       return lp3971_set_bits(lp3971, LP3971_LDO_ENABLE_REG, mask, mask);
+}
+
+static int lp3971_ldo_disable(struct regulator_dev *dev)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int ldo = rdev_get_id(dev) - LP3971_LDO1;
+       u16 mask = 1 << (1 + ldo);
+
+       return lp3971_set_bits(lp3971, LP3971_LDO_ENABLE_REG, mask, 0);
+}
+
+static int lp3971_ldo_get_voltage(struct regulator_dev *dev)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int ldo = rdev_get_id(dev) - LP3971_LDO1;
+       u16 val, reg;
+
+       reg = lp3971_reg_read(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo));
+       val = (reg >> LDO_VOL_CONTR_SHIFT(ldo)) & LDO_VOL_CONTR_MASK;
+
+       return 1000 * LDO_VOL_VALUE_MAP(ldo)[val];
+}
+
+static int lp3971_ldo_set_voltage(struct regulator_dev *dev,
+                                 int min_uV, int max_uV)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int ldo = rdev_get_id(dev) - LP3971_LDO1;
+       int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
+       const int *vol_map = LDO_VOL_VALUE_MAP(ldo);
+       u16 val;
+
+       if (min_vol < vol_map[LDO_VOL_MIN_IDX] ||
+           min_vol > vol_map[LDO_VOL_MAX_IDX])
+               return -EINVAL;
+
+       for (val = LDO_VOL_MIN_IDX; val <= LDO_VOL_MAX_IDX; val++)
+               if (vol_map[val] >= min_vol)
+                       break;
+
+       if (vol_map[val] > max_vol)
+               return -EINVAL;
+
+       return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo),
+               LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo), val);
+}
+
+static struct regulator_ops lp3971_ldo_ops = {
+       .list_voltage = lp3971_ldo_list_voltage,
+       .is_enabled = lp3971_ldo_is_enabled,
+       .enable = lp3971_ldo_enable,
+       .disable = lp3971_ldo_disable,
+       .get_voltage = lp3971_ldo_get_voltage,
+       .set_voltage = lp3971_ldo_set_voltage,
+};
+
+static int lp3971_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
+{
+       return 1000 * buck_voltage_map[index];
+}
+
+static int lp3971_dcdc_is_enabled(struct regulator_dev *dev)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - LP3971_DCDC1;
+       u16 mask = 1 << (buck * 2);
+       u16 val;
+
+       val = lp3971_reg_read(lp3971, LP3971_BUCK_VOL_ENABLE_REG);
+       return (val & mask) != 0;
+}
+
+static int lp3971_dcdc_enable(struct regulator_dev *dev)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - LP3971_DCDC1;
+       u16 mask = 1 << (buck * 2);
+
+       return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_ENABLE_REG, mask, mask);
+}
+
+static int lp3971_dcdc_disable(struct regulator_dev *dev)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - LP3971_DCDC1;
+       u16 mask = 1 << (buck * 2);
+
+       return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_ENABLE_REG, mask, 0);
+}
+
+static int lp3971_dcdc_get_voltage(struct regulator_dev *dev)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - LP3971_DCDC1;
+       u16 reg;
+       int val;
+
+       reg = lp3971_reg_read(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck));
+       reg &= BUCK_TARGET_VOL_MASK;
+
+       if (reg <= BUCK_TARGET_VOL_MAX_IDX)
+               val = 1000 * buck_voltage_map[reg];
+       else {
+               val = 0;
+               dev_warn(&dev->dev, "chip reported incorrect voltage value.\n");
+       }
+
+       return val;
+}
+
+static int lp3971_dcdc_set_voltage(struct regulator_dev *dev,
+                                 int min_uV, int max_uV)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - LP3971_DCDC1;
+       int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
+       const int *vol_map = buck_voltage_map;
+       u16 val;
+       int ret;
+
+       if (min_vol < vol_map[BUCK_TARGET_VOL_MIN_IDX] ||
+           min_vol > vol_map[BUCK_TARGET_VOL_MAX_IDX])
+               return -EINVAL;
+
+       for (val = BUCK_TARGET_VOL_MIN_IDX; val <= BUCK_TARGET_VOL_MAX_IDX;
+            val++)
+               if (vol_map[val] >= min_vol)
+                       break;
+
+       if (vol_map[val] > max_vol)
+               return -EINVAL;
+
+       ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck),
+              BUCK_TARGET_VOL_MASK, val);
+       if (ret)
+               return ret;
+
+       ret = lp3971_set_bits(lp3971, LP3971_BUCK_VOL_CHANGE_REG,
+              BUCK_VOL_CHANGE_FLAG_MASK << BUCK_VOL_CHANGE_SHIFT(buck),
+              BUCK_VOL_CHANGE_FLAG_GO << BUCK_VOL_CHANGE_SHIFT(buck));
+       if (ret)
+               return ret;
+
+       return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_CHANGE_REG,
+              BUCK_VOL_CHANGE_FLAG_MASK << BUCK_VOL_CHANGE_SHIFT(buck),
+              0 << BUCK_VOL_CHANGE_SHIFT(buck));
+}
+
+static struct regulator_ops lp3971_dcdc_ops = {
+       .list_voltage = lp3971_dcdc_list_voltage,
+       .is_enabled = lp3971_dcdc_is_enabled,
+       .enable = lp3971_dcdc_enable,
+       .disable = lp3971_dcdc_disable,
+       .get_voltage = lp3971_dcdc_get_voltage,
+       .set_voltage = lp3971_dcdc_set_voltage,
+};
+
+static struct regulator_desc regulators[] = {
+       {
+               .name = "LDO1",
+               .id = LP3971_LDO1,
+               .ops = &lp3971_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "LDO2",
+               .id = LP3971_LDO2,
+               .ops = &lp3971_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "LDO3",
+               .id = LP3971_LDO3,
+               .ops = &lp3971_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "LDO4",
+               .id = LP3971_LDO4,
+               .ops = &lp3971_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo45_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "LDO5",
+               .id = LP3971_LDO5,
+               .ops = &lp3971_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo45_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "DCDC1",
+               .id = LP3971_DCDC1,
+               .ops = &lp3971_dcdc_ops,
+               .n_voltages = ARRAY_SIZE(buck_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "DCDC2",
+               .id = LP3971_DCDC2,
+               .ops = &lp3971_dcdc_ops,
+               .n_voltages = ARRAY_SIZE(buck_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "DCDC3",
+               .id = LP3971_DCDC3,
+               .ops = &lp3971_dcdc_ops,
+               .n_voltages = ARRAY_SIZE(buck_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+};
+
+static int lp3971_i2c_read(struct i2c_client *i2c, char reg, int count,
+       u16 *dest)
+{
+       int ret;
+
+       if (count != 1)
+               return -EIO;
+       ret = i2c_smbus_read_byte_data(i2c, reg);
+       if (ret < 0 || count != 1)
+               return -EIO;
+
+       *dest = ret;
+       return 0;
+}
+
+static int lp3971_i2c_write(struct i2c_client *i2c, char reg, int count,
+       const u16 *src)
+{
+       int ret;
+
+       if (count != 1)
+               return -EIO;
+       ret = i2c_smbus_write_byte_data(i2c, reg, *src);
+       if (ret >= 0)
+               return 0;
+
+       return ret;
+}
+
+static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg)
+{
+       u16 val = 0;
+
+       mutex_lock(&lp3971->io_lock);
+
+       lp3971_i2c_read(lp3971->i2c, reg, 1, &val);
+
+       dev_dbg(lp3971->dev, "reg read 0x%02x -> 0x%02x\n", (int)reg,
+               (unsigned)val&0xff);
+
+       mutex_unlock(&lp3971->io_lock);
+
+       return val & 0xff;
+}
+
+static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val)
+{
+       u16 tmp;
+       int ret;
+
+       mutex_lock(&lp3971->io_lock);
+
+       ret = lp3971_i2c_read(lp3971->i2c, reg, 1, &tmp);
+       tmp = (tmp & ~mask) | val;
+       if (ret == 0) {
+               ret = lp3971_i2c_write(lp3971->i2c, reg, 1, &tmp);
+               dev_dbg(lp3971->dev, "reg write 0x%02x -> 0x%02x\n", (int)reg,
+                       (unsigned)val&0xff);
+       }
+       mutex_unlock(&lp3971->io_lock);
+
+       return ret;
+}
+
+static int setup_regulators(struct lp3971 *lp3971,
+       struct lp3971_platform_data *pdata)
+{
+       int i, err;
+       int num_regulators = pdata->num_regulators;
+       lp3971->num_regulators = num_regulators;
+       lp3971->rdev = kzalloc(sizeof(struct regulator_dev *) * num_regulators,
+               GFP_KERNEL);
+
+       /* Instantiate the regulators */
+       for (i = 0; i < num_regulators; i++) {
+               int id = pdata->regulators[i].id;
+               lp3971->rdev[i] = regulator_register(&regulators[id],
+                       lp3971->dev, pdata->regulators[i].initdata, lp3971);
+
+               err = IS_ERR(lp3971->rdev[i]);
+               if (err) {
+                       dev_err(lp3971->dev, "regulator init failed: %d\n",
+                               err);
+                       goto error;
+               }
+       }
+
+       return 0;
+error:
+       for (i = 0; i < num_regulators; i++)
+               if (lp3971->rdev[i])
+                       regulator_unregister(lp3971->rdev[i]);
+       kfree(lp3971->rdev);
+       lp3971->rdev = NULL;
+       return err;
+}
+
+static int __devinit lp3971_i2c_probe(struct i2c_client *i2c,
+                           const struct i2c_device_id *id)
+{
+       struct lp3971 *lp3971;
+       struct lp3971_platform_data *pdata = i2c->dev.platform_data;
+       int ret;
+       u16 val;
+
+       lp3971 = kzalloc(sizeof(struct lp3971), GFP_KERNEL);
+       if (lp3971 == NULL) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       lp3971->i2c = i2c;
+       lp3971->dev = &i2c->dev;
+       i2c_set_clientdata(i2c, lp3971);
+
+       mutex_init(&lp3971->io_lock);
+
+       /* Detect LP3971 */
+       ret = lp3971_i2c_read(i2c, LP3971_SYS_CONTROL1_REG, 1, &val);
+       if (ret == 0 && (val & SYS_CONTROL1_INIT_MASK) != SYS_CONTROL1_INIT_VAL)
+               ret = -ENODEV;
+       if (ret < 0) {
+               dev_err(&i2c->dev, "failed to detect device\n");
+               goto err_detect;
+       }
+
+       if (pdata) {
+               ret = setup_regulators(lp3971, pdata);
+               if (ret < 0)
+                       goto err_detect;
+       } else
+               dev_warn(lp3971->dev, "No platform init data supplied\n");
+
+       return 0;
+
+err_detect:
+       i2c_set_clientdata(i2c, NULL);
+       kfree(lp3971);
+err:
+       return ret;
+}
+
+static int __devexit lp3971_i2c_remove(struct i2c_client *i2c)
+{
+       struct lp3971 *lp3971 = i2c_get_clientdata(i2c);
+       int i;
+       for (i = 0; i < lp3971->num_regulators; i++)
+               if (lp3971->rdev[i])
+                       regulator_unregister(lp3971->rdev[i]);
+       kfree(lp3971->rdev);
+       i2c_set_clientdata(i2c, NULL);
+       kfree(lp3971);
+
+       return 0;
+}
+
+static const struct i2c_device_id lp3971_i2c_id[] = {
+       { "lp3971", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, lp3971_i2c_id);
+
+static struct i2c_driver lp3971_i2c_driver = {
+       .driver = {
+               .name = "LP3971",
+               .owner = THIS_MODULE,
+       },
+       .probe    = lp3971_i2c_probe,
+       .remove   = __devexit_p(lp3971_i2c_remove),
+       .id_table = lp3971_i2c_id,
+};
+
+static int __init lp3971_module_init(void)
+{
+       int ret = -ENODEV;
+
+       ret = i2c_add_driver(&lp3971_i2c_driver);
+       if (ret != 0)
+               pr_err("Failed to register I2C driver: %d\n", ret);
+
+       return ret;
+}
+module_init(lp3971_module_init);
+
+static void __exit lp3971_module_exit(void)
+{
+       i2c_del_driver(&lp3971_i2c_driver);
+}
+module_exit(lp3971_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marek Szyprowski <m.szyprowski@samsung.com>");
+MODULE_DESCRIPTION("LP3971 PMIC driver");
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
new file mode 100644 (file)
index 0000000..2c082d3
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * max1586.c  --  Voltage and current regulation for the Maxim 1586
+ *
+ * Copyright (C) 2008 Robert Jarzmik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/max1586.h>
+
+#define MAX1586_V3_MAX_VSEL 31
+#define MAX1586_V6_MAX_VSEL 3
+
+#define MAX1586_V3_MIN_UV   700000
+#define MAX1586_V3_MAX_UV  1475000
+
+#define MAX1586_V6_MIN_UV        0
+#define MAX1586_V6_MAX_UV  3000000
+
+#define I2C_V3_SELECT (0 << 5)
+#define I2C_V6_SELECT (1 << 5)
+
+struct max1586_data {
+       struct i2c_client *client;
+
+       /* min/max V3 voltage */
+       unsigned int min_uV;
+       unsigned int max_uV;
+
+       struct regulator_dev *rdev[0];
+};
+
+/*
+ * V3 voltage
+ * On I2C bus, sending a "x" byte to the max1586 means :
+ *   set V3 to 0.700V + (x & 0x1f) * 0.025V
+ * This voltage can be increased by external resistors
+ * R24 and R25=100kOhm as described in the data sheet.
+ * The gain is approximately: 1 + R24/R25 + R24/185.5kOhm
+ */
+static int max1586_v3_calc_voltage(struct max1586_data *max1586,
+       unsigned selector)
+{
+       unsigned range_uV = max1586->max_uV - max1586->min_uV;
+
+       return max1586->min_uV + (selector * range_uV / MAX1586_V3_MAX_VSEL);
+}
+
+static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+       struct max1586_data *max1586 = rdev_get_drvdata(rdev);
+       struct i2c_client *client = max1586->client;
+       unsigned range_uV = max1586->max_uV - max1586->min_uV;
+       unsigned selector;
+       u8 v3_prog;
+
+       if (min_uV > max1586->max_uV || max_uV < max1586->min_uV)
+               return -EINVAL;
+       if (min_uV < max1586->min_uV)
+               min_uV = max1586->min_uV;
+
+       selector = ((min_uV - max1586->min_uV) * MAX1586_V3_MAX_VSEL +
+                       range_uV - 1) / range_uV;
+       if (max1586_v3_calc_voltage(max1586, selector) > max_uV)
+               return -EINVAL;
+
+       dev_dbg(&client->dev, "changing voltage v3 to %dmv\n",
+               max1586_v3_calc_voltage(max1586, selector) / 1000);
+
+       v3_prog = I2C_V3_SELECT | (u8) selector;
+       return i2c_smbus_write_byte(client, v3_prog);
+}
+
+static int max1586_v3_list(struct regulator_dev *rdev, unsigned selector)
+{
+       struct max1586_data *max1586 = rdev_get_drvdata(rdev);
+
+       if (selector > MAX1586_V3_MAX_VSEL)
+               return -EINVAL;
+       return max1586_v3_calc_voltage(max1586, selector);
+}
+
+/*
+ * V6 voltage
+ * On I2C bus, sending a "x" byte to the max1586 means :
+ *   set V6 to either 0V, 1.8V, 2.5V, 3V depending on (x & 0x3)
+ * As regulator framework doesn't accept voltages to be 0V, we use 1uV.
+ */
+static int max1586_v6_calc_voltage(unsigned selector)
+{
+       static int voltages_uv[] = { 1, 1800000, 2500000, 3000000 };
+
+       return voltages_uv[selector];
+}
+
+static int max1586_v6_set(struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+       struct i2c_client *client = rdev_get_drvdata(rdev);
+       unsigned selector;
+       u8 v6_prog;
+
+       if (min_uV < MAX1586_V6_MIN_UV || min_uV > MAX1586_V6_MAX_UV)
+               return -EINVAL;
+       if (max_uV < MAX1586_V6_MIN_UV || max_uV > MAX1586_V6_MAX_UV)
+               return -EINVAL;
+
+       if (min_uV >= 3000000)
+               selector = 3;
+       if (min_uV < 3000000)
+               selector = 2;
+       if (min_uV < 2500000)
+               selector = 1;
+       if (min_uV < 1800000)
+               selector = 0;
+
+       if (max1586_v6_calc_voltage(selector) > max_uV)
+               return -EINVAL;
+
+       dev_dbg(&client->dev, "changing voltage v6 to %dmv\n",
+               max1586_v6_calc_voltage(selector) / 1000);
+
+       v6_prog = I2C_V6_SELECT | (u8) selector;
+       return i2c_smbus_write_byte(client, v6_prog);
+}
+
+static int max1586_v6_list(struct regulator_dev *rdev, unsigned selector)
+{
+       if (selector > MAX1586_V6_MAX_VSEL)
+               return -EINVAL;
+       return max1586_v6_calc_voltage(selector);
+}
+
+/*
+ * The Maxim 1586 controls V3 and V6 voltages, but offers no way of reading back
+ * the set up value.
+ */
+static struct regulator_ops max1586_v3_ops = {
+       .set_voltage = max1586_v3_set,
+       .list_voltage = max1586_v3_list,
+};
+
+static struct regulator_ops max1586_v6_ops = {
+       .set_voltage = max1586_v6_set,
+       .list_voltage = max1586_v6_list,
+};
+
+static struct regulator_desc max1586_reg[] = {
+       {
+               .name = "Output_V3",
+               .id = MAX1586_V3,
+               .ops = &max1586_v3_ops,
+               .type = REGULATOR_VOLTAGE,
+               .n_voltages = MAX1586_V3_MAX_VSEL + 1,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "Output_V6",
+               .id = MAX1586_V6,
+               .ops = &max1586_v6_ops,
+               .type = REGULATOR_VOLTAGE,
+               .n_voltages = MAX1586_V6_MAX_VSEL + 1,
+               .owner = THIS_MODULE,
+       },
+};
+
+static int max1586_pmic_probe(struct i2c_client *client,
+                             const struct i2c_device_id *i2c_id)
+{
+       struct regulator_dev **rdev;
+       struct max1586_platform_data *pdata = client->dev.platform_data;
+       struct max1586_data *max1586;
+       int i, id, ret = -ENOMEM;
+
+       max1586 = kzalloc(sizeof(struct max1586_data) +
+                       sizeof(struct regulator_dev *) * (MAX1586_V6 + 1),
+                       GFP_KERNEL);
+       if (!max1586)
+               goto out;
+
+       max1586->client = client;
+
+       if (!pdata->v3_gain) {
+               ret = -EINVAL;
+               goto out_unmap;
+       }
+       max1586->min_uV = MAX1586_V3_MIN_UV / 1000 * pdata->v3_gain / 1000;
+       max1586->max_uV = MAX1586_V3_MAX_UV / 1000 * pdata->v3_gain / 1000;
+
+       rdev = max1586->rdev;
+       for (i = 0; i < pdata->num_subdevs && i <= MAX1586_V6; i++) {
+               id = pdata->subdevs[i].id;
+               if (!pdata->subdevs[i].platform_data)
+                       continue;
+               if (id < MAX1586_V3 || id > MAX1586_V6) {
+                       dev_err(&client->dev, "invalid regulator id %d\n", id);
+                       goto err;
+               }
+               rdev[i] = regulator_register(&max1586_reg[id], &client->dev,
+                                            pdata->subdevs[i].platform_data,
+                                            max1586);
+               if (IS_ERR(rdev[i])) {
+                       ret = PTR_ERR(rdev[i]);
+                       dev_err(&client->dev, "failed to register %s\n",
+                               max1586_reg[id].name);
+                       goto err;
+               }
+       }
+
+       i2c_set_clientdata(client, rdev);
+       dev_info(&client->dev, "Maxim 1586 regulator driver loaded\n");
+       return 0;
+
+err:
+       while (--i >= 0)
+               regulator_unregister(rdev[i]);
+out_unmap:
+       kfree(max1586);
+out:
+       return ret;
+}
+
+static int max1586_pmic_remove(struct i2c_client *client)
+{
+       struct regulator_dev **rdev = i2c_get_clientdata(client);
+       int i;
+
+       for (i = 0; i <= MAX1586_V6; i++)
+               if (rdev[i])
+                       regulator_unregister(rdev[i]);
+       kfree(rdev);
+       i2c_set_clientdata(client, NULL);
+
+       return 0;
+}
+
+static const struct i2c_device_id max1586_id[] = {
+       { "max1586", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, max1586_id);
+
+static struct i2c_driver max1586_pmic_driver = {
+       .probe = max1586_pmic_probe,
+       .remove = max1586_pmic_remove,
+       .driver         = {
+               .name   = "max1586",
+       },
+       .id_table       = max1586_id,
+};
+
+static int __init max1586_pmic_init(void)
+{
+       return i2c_add_driver(&max1586_pmic_driver);
+}
+subsys_initcall(max1586_pmic_init);
+
+static void __exit max1586_pmic_exit(void)
+{
+       i2c_del_driver(&max1586_pmic_driver);
+}
+module_exit(max1586_pmic_exit);
+
+/* Module information */
+MODULE_DESCRIPTION("MAXIM 1586 voltage regulator driver");
+MODULE_AUTHOR("Robert Jarzmik");
+MODULE_LICENSE("GPL");
index cd761d8..8e14900 100644 (file)
@@ -316,7 +316,7 @@ static int __init pcf50633_regulator_init(void)
 {
        return platform_driver_register(&pcf50633_regulator_driver);
 }
-module_init(pcf50633_regulator_init);
+subsys_initcall(pcf50633_regulator_init);
 
 static void __exit pcf50633_regulator_exit(void)
 {
diff --git a/drivers/regulator/userspace-consumer.c b/drivers/regulator/userspace-consumer.c
new file mode 100644 (file)
index 0000000..06d2fa9
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * userspace-consumer.c
+ *
+ * Copyright 2009 CompuLab, Ltd.
+ *
+ * Author: Mike Rapoport <mike@compulab.co.il>
+ *
+ * Based of virtual consumer driver:
+ *   Copyright 2008 Wolfson Microelectronics PLC.
+ *   Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
+ *
+ * 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/err.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/userspace-consumer.h>
+
+struct userspace_consumer_data {
+       const char *name;
+
+       struct mutex lock;
+       bool enabled;
+
+       int num_supplies;
+       struct regulator_bulk_data *supplies;
+};
+
+static ssize_t reg_show_name(struct device *dev,
+                         struct device_attribute *attr, char *buf)
+{
+       struct userspace_consumer_data *data = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%s\n", data->name);
+}
+
+static ssize_t reg_show_state(struct device *dev,
+                         struct device_attribute *attr, char *buf)
+{
+       struct userspace_consumer_data *data = dev_get_drvdata(dev);
+
+       if (data->enabled)
+               return sprintf(buf, "enabled\n");
+
+       return sprintf(buf, "disabled\n");
+}
+
+static ssize_t reg_set_state(struct device *dev, struct device_attribute *attr,
+                        const char *buf, size_t count)
+{
+       struct userspace_consumer_data *data = dev_get_drvdata(dev);
+       bool enabled;
+       int ret;
+
+       /*
+        * sysfs_streq() doesn't need the \n's, but we add them so the strings
+        * will be shared with show_state(), above.
+        */
+       if (sysfs_streq(buf, "enabled\n") || sysfs_streq(buf, "1"))
+               enabled = true;
+       else if (sysfs_streq(buf, "disabled\n") || sysfs_streq(buf, "0"))
+               enabled = false;
+       else {
+               dev_err(dev, "Configuring invalid mode\n");
+               return count;
+       }
+
+       mutex_lock(&data->lock);
+       if (enabled != data->enabled) {
+               if (enabled)
+                       ret = regulator_bulk_enable(data->num_supplies,
+                                                   data->supplies);
+               else
+                       ret = regulator_bulk_disable(data->num_supplies,
+                                                    data->supplies);
+
+               if (ret == 0)
+                       data->enabled = enabled;
+               else
+                       dev_err(dev, "Failed to configure state: %d\n", ret);
+       }
+       mutex_unlock(&data->lock);
+
+       return count;
+}
+
+static DEVICE_ATTR(name, 0444, reg_show_name, NULL);
+static DEVICE_ATTR(state, 0644, reg_show_state, reg_set_state);
+
+static struct device_attribute *attributes[] = {
+       &dev_attr_name,
+       &dev_attr_state,
+};
+
+static int regulator_userspace_consumer_probe(struct platform_device *pdev)
+{
+       struct regulator_userspace_consumer_data *pdata;
+       struct userspace_consumer_data *drvdata;
+       int ret, i;
+
+       pdata = pdev->dev.platform_data;
+       if (!pdata)
+               return -EINVAL;
+
+       drvdata = kzalloc(sizeof(struct userspace_consumer_data), GFP_KERNEL);
+       if (drvdata == NULL)
+               return -ENOMEM;
+
+       drvdata->name = pdata->name;
+       drvdata->num_supplies = pdata->num_supplies;
+       drvdata->supplies = pdata->supplies;
+
+       mutex_init(&drvdata->lock);
+
+       ret = regulator_bulk_get(&pdev->dev, drvdata->num_supplies,
+                                drvdata->supplies);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to get supplies: %d\n", ret);
+               goto err_alloc_supplies;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(attributes); i++) {
+               ret = device_create_file(&pdev->dev, attributes[i]);
+               if (ret != 0)
+                       goto err_create_attrs;
+       }
+
+       if (pdata->init_on)
+               ret = regulator_bulk_enable(drvdata->num_supplies,
+                                           drvdata->supplies);
+
+       drvdata->enabled = pdata->init_on;
+
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to set initial state: %d\n", ret);
+               goto err_create_attrs;
+       }
+
+       platform_set_drvdata(pdev, drvdata);
+
+       return 0;
+
+err_create_attrs:
+       for (i = 0; i < ARRAY_SIZE(attributes); i++)
+               device_remove_file(&pdev->dev, attributes[i]);
+
+       regulator_bulk_free(drvdata->num_supplies, drvdata->supplies);
+
+err_alloc_supplies:
+       kfree(drvdata);
+       return ret;
+}
+
+static int regulator_userspace_consumer_remove(struct platform_device *pdev)
+{
+       struct userspace_consumer_data *data = platform_get_drvdata(pdev);
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(attributes); i++)
+               device_remove_file(&pdev->dev, attributes[i]);
+
+       if (data->enabled)
+               regulator_bulk_disable(data->num_supplies, data->supplies);
+
+       regulator_bulk_free(data->num_supplies, data->supplies);
+       kfree(data);
+
+       return 0;
+}
+
+static struct platform_driver regulator_userspace_consumer_driver = {
+       .probe          = regulator_userspace_consumer_probe,
+       .remove         = regulator_userspace_consumer_remove,
+       .driver         = {
+               .name           = "reg-userspace-consumer",
+       },
+};
+
+
+static int __init regulator_userspace_consumer_init(void)
+{
+       return platform_driver_register(&regulator_userspace_consumer_driver);
+}
+module_init(regulator_userspace_consumer_init);
+
+static void __exit regulator_userspace_consumer_exit(void)
+{
+       platform_driver_unregister(&regulator_userspace_consumer_driver);
+}
+module_exit(regulator_userspace_consumer_exit);
+
+MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
+MODULE_DESCRIPTION("Userspace consumer for voltage and current regulators");
+MODULE_LICENSE("GPL");
index 71403fa..e7db566 100644 (file)
@@ -347,3 +347,4 @@ module_exit(regulator_virtual_consumer_exit);
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_DESCRIPTION("Virtual regulator consumer");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:reg-virt-consumer");
index 771eca1..17a00b0 100644 (file)
@@ -1570,3 +1570,4 @@ module_exit(wm8350_regulator_exit);
 MODULE_AUTHOR("Liam Girdwood");
 MODULE_DESCRIPTION("WM8350 voltage and current regulator driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm8350-regulator");
index 1574260..d9a2c98 100644 (file)
@@ -320,7 +320,7 @@ static int __devinit wm8400_regulator_probe(struct platform_device *pdev)
        struct regulator_dev *rdev;
 
        rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
-               pdev->dev.platform_data, pdev->dev.driver_data);
+               pdev->dev.platform_data, dev_get_drvdata(&pdev->dev));
 
        if (IS_ERR(rdev))
                return PTR_ERR(rdev);
@@ -359,7 +359,7 @@ static struct platform_driver wm8400_regulator_driver = {
 int wm8400_register_regulator(struct device *dev, int reg,
                              struct regulator_init_data *initdata)
 {
-       struct wm8400 *wm8400 = dev->driver_data;
+       struct wm8400 *wm8400 = dev_get_drvdata(dev);
 
        if (wm8400->regulators[reg].name)
                return -EBUSY;
@@ -369,8 +369,8 @@ int wm8400_register_regulator(struct device *dev, int reg,
        wm8400->regulators[reg].name = "wm8400-regulator";
        wm8400->regulators[reg].id = reg;
        wm8400->regulators[reg].dev.parent = dev;
-       wm8400->regulators[reg].dev.driver_data = wm8400;
        wm8400->regulators[reg].dev.platform_data = initdata;
+       dev_set_drvdata(&wm8400->regulators[reg].dev, wm8400);
 
        return platform_device_register(&wm8400->regulators[reg]);
 }
@@ -380,7 +380,7 @@ static int __init wm8400_regulator_init(void)
 {
        return platform_driver_register(&wm8400_regulator_driver);
 }
-module_init(wm8400_regulator_init);
+subsys_initcall(wm8400_regulator_init);
 
 static void __exit wm8400_regulator_exit(void)
 {
index 40a3a2a..7a868bd 100644 (file)
@@ -1,13 +1,12 @@
 /*
- * xilinxfb.c
- *
- * Xilinx TFT LCD frame buffer driver
+ * Xilinx TFT frame buffer driver
  *
  * Author: MontaVista Software, Inc.
  *         source@mvista.com
  *
  * 2002-2007 (c) MontaVista Software, Inc.
  * 2007 (c) Secret Lab Technologies, Ltd.
+ * 2009 (c) Xilinx Inc.
  *
  * This file is licensed under the terms of the GNU General Public License
  * version 2.  This program is licensed "as is" without any warranty of any
 #include <linux/device.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/version.h>
 #include <linux/errno.h>
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#if defined(CONFIG_OF)
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
-#endif
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/xilinxfb.h>
+#include <asm/dcr.h>
 
 #define DRIVER_NAME            "xilinxfb"
-#define DRIVER_DESCRIPTION     "Xilinx TFT LCD frame buffer driver"
+
 
 /*
  * Xilinx calls it "PLB TFT LCD Controller" though it can also be used for
- * the VGA port on the Xilinx ML40x board. This is a hardware display controller
- * for a 640x480 resolution TFT or VGA screen.
+ * the VGA port on the Xilinx ML40x board. This is a hardware display
+ * controller for a 640x480 resolution TFT or VGA screen.
  *
  * The interface to the framebuffer is nice and simple.  There are two
  * control registers.  The first tells the LCD interface where in memory
  * the frame buffer is (only the 11 most significant bits are used, so
  * don't start thinking about scrolling).  The second allows the LCD to
  * be turned on or off as well as rotated 180 degrees.
+ *
+ * In case of direct PLB access the second control register will be at
+ * an offset of 4 as compared to the DCR access where the offset is 1
+ * i.e. REG_CTRL. So this is taken care in the function
+ * xilinx_fb_out_be32 where it left shifts the offset 2 times in case of
+ * direct PLB access.
  */
 #define NUM_REGS       2
 #define REG_FB_ADDR    0
@@ -107,17 +111,28 @@ static struct fb_var_screeninfo xilinx_fb_var = {
        .activate =     FB_ACTIVATE_NOW
 };
 
+
+#define PLB_ACCESS_FLAG        0x1             /* 1 = PLB, 0 = DCR */
+
 struct xilinxfb_drvdata {
 
        struct fb_info  info;           /* FB driver info record */
 
-       u32             regs_phys;      /* phys. address of the control registers */
-       u32 __iomem     *regs;          /* virt. address of the control registers */
+       phys_addr_t     regs_phys;      /* phys. address of the control
+                                               registers */
+       void __iomem    *regs;          /* virt. address of the control
+                                               registers */
+
+       dcr_host_t      dcr_host;
+       unsigned int    dcr_start;
+       unsigned int    dcr_len;
 
        void            *fb_virt;       /* virt. address of the frame buffer */
        dma_addr_t      fb_phys;        /* phys. address of the frame buffer */
        int             fb_alloced;     /* Flag, was the fb memory alloced? */
 
+       u8              flags;          /* features of the driver */
+
        u32             reg_ctrl_default;
 
        u32             pseudo_palette[PALETTE_ENTRIES_NO];
@@ -128,14 +143,19 @@ struct xilinxfb_drvdata {
        container_of(_info, struct xilinxfb_drvdata, info)
 
 /*
- * The LCD controller has DCR interface to its registers, but all
- * the boards and configurations the driver has been tested with
- * use opb2dcr bridge. So the registers are seen as memory mapped.
- * This macro is to make it simple to add the direct DCR access
- * when it's needed.
+ * The XPS TFT Controller can be accessed through PLB or DCR interface.
+ * To perform the read/write on the registers we need to check on
+ * which bus its connected and call the appropriate write API.
  */
-#define xilinx_fb_out_be32(driverdata, offset, val) \
-       out_be32(driverdata->regs + offset, val)
+static void xilinx_fb_out_be32(struct xilinxfb_drvdata *drvdata, u32 offset,
+                               u32 val)
+{
+       if (drvdata->flags & PLB_ACCESS_FLAG)
+               out_be32(drvdata->regs + (offset << 2), val);
+       else
+               dcr_write(drvdata->dcr_host, offset, val);
+
+}
 
 static int
 xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
@@ -203,35 +223,34 @@ static struct fb_ops xilinxfb_ops =
  * Bus independent setup/teardown
  */
 
-static int xilinxfb_assign(struct device *dev, unsigned long physaddr,
+static int xilinxfb_assign(struct device *dev,
+                          struct xilinxfb_drvdata *drvdata,
+                          unsigned long physaddr,
                           struct xilinxfb_platform_data *pdata)
 {
-       struct xilinxfb_drvdata *drvdata;
        int rc;
        int fbsize = pdata->xvirt * pdata->yvirt * BYTES_PER_PIXEL;
 
-       /* Allocate the driver data region */
-       drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
-       if (!drvdata) {
-               dev_err(dev, "Couldn't allocate device private record\n");
-               return -ENOMEM;
-       }
-       dev_set_drvdata(dev, drvdata);
-
-       /* Map the control registers in */
-       if (!request_mem_region(physaddr, 8, DRIVER_NAME)) {
-               dev_err(dev, "Couldn't lock memory region at 0x%08lX\n",
-                       physaddr);
-               rc = -ENODEV;
-               goto err_region;
-       }
-       drvdata->regs_phys = physaddr;
-       drvdata->regs = ioremap(physaddr, 8);
-       if (!drvdata->regs) {
-               dev_err(dev, "Couldn't lock memory region at 0x%08lX\n",
-                       physaddr);
-               rc = -ENODEV;
-               goto err_map;
+       if (drvdata->flags & PLB_ACCESS_FLAG) {
+               /*
+                * Map the control registers in if the controller
+                * is on direct PLB interface.
+                */
+               if (!request_mem_region(physaddr, 8, DRIVER_NAME)) {
+                       dev_err(dev, "Couldn't lock memory region at 0x%08lX\n",
+                               physaddr);
+                       rc = -ENODEV;
+                       goto err_region;
+               }
+
+               drvdata->regs_phys = physaddr;
+               drvdata->regs = ioremap(physaddr, 8);
+               if (!drvdata->regs) {
+                       dev_err(dev, "Couldn't lock memory region at 0x%08lX\n",
+                               physaddr);
+                       rc = -ENODEV;
+                       goto err_map;
+               }
        }
 
        /* Allocate the framebuffer memory */
@@ -247,7 +266,10 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr,
        if (!drvdata->fb_virt) {
                dev_err(dev, "Could not allocate frame buffer memory\n");
                rc = -ENOMEM;
-               goto err_fbmem;
+               if (drvdata->flags & PLB_ACCESS_FLAG)
+                       goto err_fbmem;
+               else
+                       goto err_region;
        }
 
        /* Clear (turn to black) the framebuffer */
@@ -260,7 +282,8 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr,
        drvdata->reg_ctrl_default = REG_CTRL_ENABLE;
        if (pdata->rotate_screen)
                drvdata->reg_ctrl_default |= REG_CTRL_ROTATE;
-       xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
+       xilinx_fb_out_be32(drvdata, REG_CTRL,
+                                       drvdata->reg_ctrl_default);
 
        /* Fill struct fb_info */
        drvdata->info.device = dev;
@@ -296,11 +319,14 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr,
                goto err_regfb;
        }
 
+       if (drvdata->flags & PLB_ACCESS_FLAG) {
+               /* Put a banner in the log (for DEBUG) */
+               dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr,
+                                       drvdata->regs);
+       }
        /* Put a banner in the log (for DEBUG) */
-       dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, drvdata->regs);
-       dev_dbg(dev, "fb: phys=%llx, virt=%p, size=%x\n",
-               (unsigned long long) drvdata->fb_phys, drvdata->fb_virt,
-               fbsize);
+       dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n",
+               (void *)drvdata->fb_phys, drvdata->fb_virt, fbsize);
 
        return 0;       /* success */
 
@@ -311,14 +337,19 @@ err_cmap:
        if (drvdata->fb_alloced)
                dma_free_coherent(dev, PAGE_ALIGN(fbsize), drvdata->fb_virt,
                        drvdata->fb_phys);
+       else
+               iounmap(drvdata->fb_virt);
+
        /* Turn off the display */
        xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
 
 err_fbmem:
-       iounmap(drvdata->regs);
+       if (drvdata->flags & PLB_ACCESS_FLAG)
+               iounmap(drvdata->regs);
 
 err_map:
-       release_mem_region(physaddr, 8);
+       if (drvdata->flags & PLB_ACCESS_FLAG)
+               release_mem_region(physaddr, 8);
 
 err_region:
        kfree(drvdata);
@@ -342,12 +373,18 @@ static int xilinxfb_release(struct device *dev)
        if (drvdata->fb_alloced)
                dma_free_coherent(dev, PAGE_ALIGN(drvdata->info.fix.smem_len),
                                  drvdata->fb_virt, drvdata->fb_phys);
+       else
+               iounmap(drvdata->fb_virt);
 
        /* Turn off the display */
        xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
-       iounmap(drvdata->regs);
 
-       release_mem_region(drvdata->regs_phys, 8);
+       /* Release the resources, as allocated based on interface */
+       if (drvdata->flags & PLB_ACCESS_FLAG) {
+               iounmap(drvdata->regs);
+               release_mem_region(drvdata->regs_phys, 8);
+       } else
+               dcr_unmap(drvdata->dcr_host, drvdata->dcr_len);
 
        kfree(drvdata);
        dev_set_drvdata(dev, NULL);
@@ -356,77 +393,57 @@ static int xilinxfb_release(struct device *dev)
 }
 
 /* ---------------------------------------------------------------------
- * Platform bus binding
- */
-
-static int
-xilinxfb_platform_probe(struct platform_device *pdev)
-{
-       struct xilinxfb_platform_data *pdata;
-       struct resource *res;
-
-       /* Find the registers address */
-       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "Couldn't get registers resource\n");
-               return -ENODEV;
-       }
-
-       /* If a pdata structure is provided, then extract the parameters */
-       pdata = &xilinx_fb_default_pdata;
-       if (pdev->dev.platform_data) {
-               pdata = pdev->dev.platform_data;
-               if (!pdata->xres)
-                       pdata->xres = xilinx_fb_default_pdata.xres;
-               if (!pdata->yres)
-                       pdata->yres = xilinx_fb_default_pdata.yres;
-               if (!pdata->xvirt)
-                       pdata->xvirt = xilinx_fb_default_pdata.xvirt;
-               if (!pdata->yvirt)
-                       pdata->yvirt = xilinx_fb_default_pdata.yvirt;
-       }
-
-       return xilinxfb_assign(&pdev->dev, res->start, pdata);
-}
-
-static int
-xilinxfb_platform_remove(struct platform_device *pdev)
-{
-       return xilinxfb_release(&pdev->dev);
-}
-
-
-static struct platform_driver xilinxfb_platform_driver = {
-       .probe          = xilinxfb_platform_probe,
-       .remove         = xilinxfb_platform_remove,
-       .driver = {
-               .owner = THIS_MODULE,
-               .name = DRIVER_NAME,
-       },
-};
-
-/* ---------------------------------------------------------------------
  * OF bus binding
  */
 
-#if defined(CONFIG_OF)
 static int __devinit
 xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match)
 {
-       struct resource res;
        const u32 *prop;
+       u32 *p;
+       u32 tft_access;
        struct xilinxfb_platform_data pdata;
+       struct resource res;
        int size, rc;
+       int start = 0, len = 0;
+       dcr_host_t dcr_host;
+       struct xilinxfb_drvdata *drvdata;
 
        /* Copy with the default pdata (not a ptr reference!) */
        pdata = xilinx_fb_default_pdata;
 
        dev_dbg(&op->dev, "xilinxfb_of_probe(%p, %p)\n", op, match);
 
-       rc = of_address_to_resource(op->node, 0, &res);
-       if (rc) {
-               dev_err(&op->dev, "invalid address\n");
-               return rc;
+       /*
+        * To check whether the core is connected directly to DCR or PLB
+        * interface and initialize the tft_access accordingly.
+        */
+       p = (u32 *)of_get_property(op->node, "xlnx,dcr-splb-slave-if", NULL);
+
+       if (p)
+               tft_access = *p;
+       else
+               tft_access = 0;         /* For backward compatibility */
+
+       /*
+        * Fill the resource structure if its direct PLB interface
+        * otherwise fill the dcr_host structure.
+        */
+       if (tft_access) {
+               rc = of_address_to_resource(op->node, 0, &res);
+               if (rc) {
+                       dev_err(&op->dev, "invalid address\n");
+                       return -ENODEV;
+               }
+
+       } else {
+               start = dcr_resource_start(op->node, 0);
+               len = dcr_resource_len(op->node, 0);
+               dcr_host = dcr_map(op->node, start, len);
+               if (!DCR_MAP_OK(dcr_host)) {
+                       dev_err(&op->dev, "invalid address\n");
+                       return -ENODEV;
+               }
        }
 
        prop = of_get_property(op->node, "phys-size", &size);
@@ -450,7 +467,26 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match)
        if (of_find_property(op->node, "rotate-display", NULL))
                pdata.rotate_screen = 1;
 
-       return xilinxfb_assign(&op->dev, res.start, &pdata);
+       /* Allocate the driver data region */
+       drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+       if (!drvdata) {
+               dev_err(&op->dev, "Couldn't allocate device private record\n");
+               return -ENOMEM;
+       }
+       dev_set_drvdata(&op->dev, drvdata);
+
+       if (tft_access)
+               drvdata->flags |= PLB_ACCESS_FLAG;
+
+       /* Arguments are passed based on the interface */
+       if (drvdata->flags & PLB_ACCESS_FLAG) {
+               return xilinxfb_assign(&op->dev, drvdata, res.start, &pdata);
+       } else {
+               drvdata->dcr_start = start;
+               drvdata->dcr_len = len;
+               drvdata->dcr_host = dcr_host;
+               return xilinxfb_assign(&op->dev, drvdata, 0, &pdata);
+       }
 }
 
 static int __devexit xilinxfb_of_remove(struct of_device *op)
@@ -460,7 +496,9 @@ static int __devexit xilinxfb_of_remove(struct of_device *op)
 
 /* Match table for of_platform binding */
 static struct of_device_id xilinxfb_of_match[] __devinitdata = {
+       { .compatible = "xlnx,xps-tft-1.00.a", },
        { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", },
+       { .compatible = "xlnx,plb-dvi-cntlr-ref-1.00.c", },
        {},
 };
 MODULE_DEVICE_TABLE(of, xilinxfb_of_match);
@@ -476,22 +514,6 @@ static struct of_platform_driver xilinxfb_of_driver = {
        },
 };
 
-/* Registration helpers to keep the number of #ifdefs to a minimum */
-static inline int __init xilinxfb_of_register(void)
-{
-       pr_debug("xilinxfb: calling of_register_platform_driver()\n");
-       return of_register_platform_driver(&xilinxfb_of_driver);
-}
-
-static inline void __exit xilinxfb_of_unregister(void)
-{
-       of_unregister_platform_driver(&xilinxfb_of_driver);
-}
-#else /* CONFIG_OF */
-/* CONFIG_OF not enabled; do nothing helpers */
-static inline int __init xilinxfb_of_register(void) { return 0; }
-static inline void __exit xilinxfb_of_unregister(void) { }
-#endif /* CONFIG_OF */
 
 /* ---------------------------------------------------------------------
  * Module setup and teardown
@@ -500,28 +522,18 @@ static inline void __exit xilinxfb_of_unregister(void) { }
 static int __init
 xilinxfb_init(void)
 {
-       int rc;
-       rc = xilinxfb_of_register();
-       if (rc)
-               return rc;
-
-       rc = platform_driver_register(&xilinxfb_platform_driver);
-       if (rc)
-               xilinxfb_of_unregister();
-
-       return rc;
+       return of_register_platform_driver(&xilinxfb_of_driver);
 }
 
 static void __exit
 xilinxfb_cleanup(void)
 {
-       platform_driver_unregister(&xilinxfb_platform_driver);
-       xilinxfb_of_unregister();
+       of_unregister_platform_driver(&xilinxfb_of_driver);
 }
 
 module_init(xilinxfb_init);
 module_exit(xilinxfb_cleanup);
 
 MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
-MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
+MODULE_DESCRIPTION("Xilinx TFT frame buffer driver");
 MODULE_LICENSE("GPL");
index 064279e..36df60b 100644 (file)
 #include "dat.h"
 #include "alloc.h"
 
+struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap)
+{
+       return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode));
+}
+
 int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level,
                               __u64 *ptrp)
 {
-       __u64 ptr;
+       sector_t blocknr;
        int ret;
 
        down_read(&bmap->b_sem);
        ret = bmap->b_ops->bop_lookup(bmap, key, level, ptrp);
        if (ret < 0)
                goto out;
-       if (bmap->b_pops->bpop_translate != NULL) {
-               ret = bmap->b_pops->bpop_translate(bmap, *ptrp, &ptr);
-               if (ret < 0)
-                       goto out;
-               *ptrp = ptr;
+       if (NILFS_BMAP_USE_VBN(bmap)) {
+               ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), *ptrp,
+                                         &blocknr);
+               if (!ret)
+                       *ptrp = blocknr;
        }
 
  out:
@@ -53,6 +58,16 @@ int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level,
        return ret;
 }
 
+int nilfs_bmap_lookup_contig(struct nilfs_bmap *bmap, __u64 key, __u64 *ptrp,
+                            unsigned maxblocks)
+{
+       int ret;
+
+       down_read(&bmap->b_sem);
+       ret = bmap->b_ops->bop_lookup_contig(bmap, key, ptrp, maxblocks);
+       up_read(&bmap->b_sem);
+       return ret;
+}
 
 /**
  * nilfs_bmap_lookup - find a record
@@ -101,8 +116,7 @@ static int nilfs_bmap_do_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
                        if (n < 0)
                                return n;
                        ret = nilfs_btree_convert_and_insert(
-                               bmap, key, ptr, keys, ptrs, n,
-                               NILFS_BMAP_LARGE_LOW, NILFS_BMAP_LARGE_HIGH);
+                               bmap, key, ptr, keys, ptrs, n);
                        if (ret == 0)
                                bmap->b_u.u_flags |= NILFS_BMAP_LARGE;
 
@@ -158,8 +172,7 @@ static int nilfs_bmap_do_delete(struct nilfs_bmap *bmap, __u64 key)
                        if (n < 0)
                                return n;
                        ret = nilfs_direct_delete_and_convert(
-                               bmap, key, keys, ptrs, n,
-                               NILFS_BMAP_SMALL_LOW, NILFS_BMAP_SMALL_HIGH);
+                               bmap, key, keys, ptrs, n);
                        if (ret == 0)
                                bmap->b_u.u_flags &= ~NILFS_BMAP_LARGE;
 
@@ -417,38 +430,6 @@ void nilfs_bmap_sub_blocks(const struct nilfs_bmap *bmap, int n)
                mark_inode_dirty(bmap->b_inode);
 }
 
-int nilfs_bmap_get_block(const struct nilfs_bmap *bmap, __u64 ptr,
-                        struct buffer_head **bhp)
-{
-       return nilfs_btnode_get(&NILFS_BMAP_I(bmap)->i_btnode_cache,
-                               ptr, 0, bhp, 0);
-}
-
-void nilfs_bmap_put_block(const struct nilfs_bmap *bmap,
-                         struct buffer_head *bh)
-{
-       brelse(bh);
-}
-
-int nilfs_bmap_get_new_block(const struct nilfs_bmap *bmap, __u64 ptr,
-                            struct buffer_head **bhp)
-{
-       int ret;
-
-       ret = nilfs_btnode_get(&NILFS_BMAP_I(bmap)->i_btnode_cache,
-                              ptr, 0, bhp, 1);
-       if (ret < 0)
-               return ret;
-       set_buffer_nilfs_volatile(*bhp);
-       return 0;
-}
-
-void nilfs_bmap_delete_block(const struct nilfs_bmap *bmap,
-                            struct buffer_head *bh)
-{
-       nilfs_btnode_delete(bh);
-}
-
 __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *bmap,
                              const struct buffer_head *bh)
 {
@@ -476,11 +457,6 @@ __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *bmap, __u64 key)
                return NILFS_BMAP_INVALID_PTR;
 }
 
-static struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap)
-{
-       return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode));
-}
-
 #define NILFS_BMAP_GROUP_DIV   8
 __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
 {
@@ -493,64 +469,51 @@ __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
                (entries_per_group / NILFS_BMAP_GROUP_DIV);
 }
 
-static int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *bmap,
-                                     union nilfs_bmap_ptr_req *req)
+int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *bmap,
+                                union nilfs_bmap_ptr_req *req)
 {
        return nilfs_dat_prepare_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
 }
 
-static void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *bmap,
-                                     union nilfs_bmap_ptr_req *req)
+void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *bmap,
+                                union nilfs_bmap_ptr_req *req)
 {
        nilfs_dat_commit_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
 }
 
-static void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *bmap,
-                                    union nilfs_bmap_ptr_req *req)
+void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *bmap,
+                             union nilfs_bmap_ptr_req *req)
 {
        nilfs_dat_abort_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
 }
 
-static int nilfs_bmap_prepare_start_v(struct nilfs_bmap *bmap,
-                                     union nilfs_bmap_ptr_req *req)
+int nilfs_bmap_start_v(struct nilfs_bmap *bmap, union nilfs_bmap_ptr_req *req,
+                      sector_t blocknr)
 {
-       return nilfs_dat_prepare_start(nilfs_bmap_get_dat(bmap), &req->bpr_req);
-}
-
-static void nilfs_bmap_commit_start_v(struct nilfs_bmap *bmap,
-                                     union nilfs_bmap_ptr_req *req,
-                                     sector_t blocknr)
-{
-       nilfs_dat_commit_start(nilfs_bmap_get_dat(bmap), &req->bpr_req,
-                              blocknr);
-}
+       struct inode *dat = nilfs_bmap_get_dat(bmap);
+       int ret;
 
-static void nilfs_bmap_abort_start_v(struct nilfs_bmap *bmap,
-                                    union nilfs_bmap_ptr_req *req)
-{
-       nilfs_dat_abort_start(nilfs_bmap_get_dat(bmap), &req->bpr_req);
+       ret = nilfs_dat_prepare_start(dat, &req->bpr_req);
+       if (likely(!ret))
+               nilfs_dat_commit_start(dat, &req->bpr_req, blocknr);
+       return ret;
 }
 
-static int nilfs_bmap_prepare_end_v(struct nilfs_bmap *bmap,
-                                   union nilfs_bmap_ptr_req *req)
+int nilfs_bmap_prepare_end_v(struct nilfs_bmap *bmap,
+                            union nilfs_bmap_ptr_req *req)
 {
        return nilfs_dat_prepare_end(nilfs_bmap_get_dat(bmap), &req->bpr_req);
 }
 
-static void nilfs_bmap_commit_end_v(struct nilfs_bmap *bmap,
-                                   union nilfs_bmap_ptr_req *req)
-{
-       nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req, 0);
-}
-
-static void nilfs_bmap_commit_end_vmdt(struct nilfs_bmap *bmap,
-                                      union nilfs_bmap_ptr_req *req)
+void nilfs_bmap_commit_end_v(struct nilfs_bmap *bmap,
+                            union nilfs_bmap_ptr_req *req)
 {
-       nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req, 1);
+       nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req,
+                            bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
 }
 
-static void nilfs_bmap_abort_end_v(struct nilfs_bmap *bmap,
-                                  union nilfs_bmap_ptr_req *req)
+void nilfs_bmap_abort_end_v(struct nilfs_bmap *bmap,
+                           union nilfs_bmap_ptr_req *req)
 {
        nilfs_dat_abort_end(nilfs_bmap_get_dat(bmap), &req->bpr_req);
 }
@@ -566,128 +529,44 @@ int nilfs_bmap_mark_dirty(const struct nilfs_bmap *bmap, __u64 vblocknr)
        return nilfs_dat_mark_dirty(nilfs_bmap_get_dat(bmap), vblocknr);
 }
 
-int nilfs_bmap_prepare_update(struct nilfs_bmap *bmap,
-                             union nilfs_bmap_ptr_req *oldreq,
-                             union nilfs_bmap_ptr_req *newreq)
+int nilfs_bmap_prepare_update_v(struct nilfs_bmap *bmap,
+                               union nilfs_bmap_ptr_req *oldreq,
+                               union nilfs_bmap_ptr_req *newreq)
 {
+       struct inode *dat = nilfs_bmap_get_dat(bmap);
        int ret;
 
-       ret = bmap->b_pops->bpop_prepare_end_ptr(bmap, oldreq);
+       ret = nilfs_dat_prepare_end(dat, &oldreq->bpr_req);
        if (ret < 0)
                return ret;
-       ret = bmap->b_pops->bpop_prepare_alloc_ptr(bmap, newreq);
+       ret = nilfs_dat_prepare_alloc(dat, &newreq->bpr_req);
        if (ret < 0)
-               bmap->b_pops->bpop_abort_end_ptr(bmap, oldreq);
+               nilfs_dat_abort_end(dat, &oldreq->bpr_req);
 
        return ret;
 }
 
-void nilfs_bmap_commit_update(struct nilfs_bmap *bmap,
-                             union nilfs_bmap_ptr_req *oldreq,
-                             union nilfs_bmap_ptr_req *newreq)
+void nilfs_bmap_commit_update_v(struct nilfs_bmap *bmap,
+                               union nilfs_bmap_ptr_req *oldreq,
+                               union nilfs_bmap_ptr_req *newreq)
 {
-       bmap->b_pops->bpop_commit_end_ptr(bmap, oldreq);
-       bmap->b_pops->bpop_commit_alloc_ptr(bmap, newreq);
-}
+       struct inode *dat = nilfs_bmap_get_dat(bmap);
 
-void nilfs_bmap_abort_update(struct nilfs_bmap *bmap,
-                            union nilfs_bmap_ptr_req *oldreq,
-                            union nilfs_bmap_ptr_req *newreq)
-{
-       bmap->b_pops->bpop_abort_end_ptr(bmap, oldreq);
-       bmap->b_pops->bpop_abort_alloc_ptr(bmap, newreq);
+       nilfs_dat_commit_end(dat, &oldreq->bpr_req,
+                            bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
+       nilfs_dat_commit_alloc(dat, &newreq->bpr_req);
 }
 
-static int nilfs_bmap_translate_v(const struct nilfs_bmap *bmap, __u64 ptr,
-                                 __u64 *ptrp)
+void nilfs_bmap_abort_update_v(struct nilfs_bmap *bmap,
+                              union nilfs_bmap_ptr_req *oldreq,
+                              union nilfs_bmap_ptr_req *newreq)
 {
-       sector_t blocknr;
-       int ret;
-
-       ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), ptr, &blocknr);
-       if (ret < 0)
-               return ret;
-       if (ptrp != NULL)
-               *ptrp = blocknr;
-       return 0;
-}
+       struct inode *dat = nilfs_bmap_get_dat(bmap);
 
-static int nilfs_bmap_prepare_alloc_p(struct nilfs_bmap *bmap,
-                                     union nilfs_bmap_ptr_req *req)
-{
-       /* ignore target ptr */
-       req->bpr_ptr = bmap->b_last_allocated_ptr++;
-       return 0;
+       nilfs_dat_abort_end(dat, &oldreq->bpr_req);
+       nilfs_dat_abort_alloc(dat, &newreq->bpr_req);
 }
 
-static void nilfs_bmap_commit_alloc_p(struct nilfs_bmap *bmap,
-                                     union nilfs_bmap_ptr_req *req)
-{
-       /* do nothing */
-}
-
-static void nilfs_bmap_abort_alloc_p(struct nilfs_bmap *bmap,
-                                    union nilfs_bmap_ptr_req *req)
-{
-       bmap->b_last_allocated_ptr--;
-}
-
-static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_v = {
-       .bpop_prepare_alloc_ptr =       nilfs_bmap_prepare_alloc_v,
-       .bpop_commit_alloc_ptr  =       nilfs_bmap_commit_alloc_v,
-       .bpop_abort_alloc_ptr   =       nilfs_bmap_abort_alloc_v,
-       .bpop_prepare_start_ptr =       nilfs_bmap_prepare_start_v,
-       .bpop_commit_start_ptr  =       nilfs_bmap_commit_start_v,
-       .bpop_abort_start_ptr   =       nilfs_bmap_abort_start_v,
-       .bpop_prepare_end_ptr   =       nilfs_bmap_prepare_end_v,
-       .bpop_commit_end_ptr    =       nilfs_bmap_commit_end_v,
-       .bpop_abort_end_ptr     =       nilfs_bmap_abort_end_v,
-
-       .bpop_translate         =       nilfs_bmap_translate_v,
-};
-
-static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_vmdt = {
-       .bpop_prepare_alloc_ptr =       nilfs_bmap_prepare_alloc_v,
-       .bpop_commit_alloc_ptr  =       nilfs_bmap_commit_alloc_v,
-       .bpop_abort_alloc_ptr   =       nilfs_bmap_abort_alloc_v,
-       .bpop_prepare_start_ptr =       nilfs_bmap_prepare_start_v,
-       .bpop_commit_start_ptr  =       nilfs_bmap_commit_start_v,
-       .bpop_abort_start_ptr   =       nilfs_bmap_abort_start_v,
-       .bpop_prepare_end_ptr   =       nilfs_bmap_prepare_end_v,
-       .bpop_commit_end_ptr    =       nilfs_bmap_commit_end_vmdt,
-       .bpop_abort_end_ptr     =       nilfs_bmap_abort_end_v,
-
-       .bpop_translate         =       nilfs_bmap_translate_v,
-};
-
-static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_p = {
-       .bpop_prepare_alloc_ptr =       nilfs_bmap_prepare_alloc_p,
-       .bpop_commit_alloc_ptr  =       nilfs_bmap_commit_alloc_p,
-       .bpop_abort_alloc_ptr   =       nilfs_bmap_abort_alloc_p,
-       .bpop_prepare_start_ptr =       NULL,
-       .bpop_commit_start_ptr  =       NULL,
-       .bpop_abort_start_ptr   =       NULL,
-       .bpop_prepare_end_ptr   =       NULL,
-       .bpop_commit_end_ptr    =       NULL,
-       .bpop_abort_end_ptr     =       NULL,
-
-       .bpop_translate         =       NULL,
-};
-
-static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_gc = {
-       .bpop_prepare_alloc_ptr =       NULL,
-       .bpop_commit_alloc_ptr  =       NULL,
-       .bpop_abort_alloc_ptr   =       NULL,
-       .bpop_prepare_start_ptr =       NULL,
-       .bpop_commit_start_ptr  =       NULL,
-       .bpop_abort_start_ptr   =       NULL,
-       .bpop_prepare_end_ptr   =       NULL,
-       .bpop_commit_end_ptr    =       NULL,
-       .bpop_abort_end_ptr     =       NULL,
-
-       .bpop_translate         =       NULL,
-};
-
 static struct lock_class_key nilfs_bmap_dat_lock_key;
 
 /**
@@ -714,31 +593,26 @@ int nilfs_bmap_read(struct nilfs_bmap *bmap, struct nilfs_inode *raw_inode)
        bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode;
        switch (bmap->b_inode->i_ino) {
        case NILFS_DAT_INO:
-               bmap->b_pops = &nilfs_bmap_ptr_ops_p;
-               bmap->b_last_allocated_key = 0; /* XXX: use macro */
+               bmap->b_ptr_type = NILFS_BMAP_PTR_P;
+               bmap->b_last_allocated_key = 0;
                bmap->b_last_allocated_ptr = NILFS_BMAP_NEW_PTR_INIT;
                lockdep_set_class(&bmap->b_sem, &nilfs_bmap_dat_lock_key);
                break;
        case NILFS_CPFILE_INO:
        case NILFS_SUFILE_INO:
-               bmap->b_pops = &nilfs_bmap_ptr_ops_vmdt;
-               bmap->b_last_allocated_key = 0; /* XXX: use macro */
+               bmap->b_ptr_type = NILFS_BMAP_PTR_VS;
+               bmap->b_last_allocated_key = 0;
                bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
                break;
        default:
-               bmap->b_pops = &nilfs_bmap_ptr_ops_v;
-               bmap->b_last_allocated_key = 0; /* XXX: use macro */
+               bmap->b_ptr_type = NILFS_BMAP_PTR_VM;
+               bmap->b_last_allocated_key = 0;
                bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
                break;
        }
 
        return (bmap->b_u.u_flags & NILFS_BMAP_LARGE) ?
-               nilfs_btree_init(bmap,
-                                NILFS_BMAP_LARGE_LOW,
-                                NILFS_BMAP_LARGE_HIGH) :
-               nilfs_direct_init(bmap,
-                                 NILFS_BMAP_SMALL_LOW,
-                                 NILFS_BMAP_SMALL_HIGH);
+               nilfs_btree_init(bmap) : nilfs_direct_init(bmap);
 }
 
 /**
@@ -764,7 +638,7 @@ void nilfs_bmap_init_gc(struct nilfs_bmap *bmap)
        memset(&bmap->b_u, 0, NILFS_BMAP_SIZE);
        init_rwsem(&bmap->b_sem);
        bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode;
-       bmap->b_pops = &nilfs_bmap_ptr_ops_gc;
+       bmap->b_ptr_type = NILFS_BMAP_PTR_U;
        bmap->b_last_allocated_key = 0;
        bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
        bmap->b_state = 0;
index 4f2708a..b2890cd 100644 (file)
@@ -64,6 +64,8 @@ struct nilfs_bmap_stats {
  */
 struct nilfs_bmap_operations {
        int (*bop_lookup)(const struct nilfs_bmap *, __u64, int, __u64 *);
+       int (*bop_lookup_contig)(const struct nilfs_bmap *, __u64, __u64 *,
+                                unsigned);
        int (*bop_insert)(struct nilfs_bmap *, __u64, __u64);
        int (*bop_delete)(struct nilfs_bmap *, __u64);
        void (*bop_clear)(struct nilfs_bmap *);
@@ -86,34 +88,6 @@ struct nilfs_bmap_operations {
 };
 
 
-/**
- * struct nilfs_bmap_ptr_operations - bmap ptr operation table
- */
-struct nilfs_bmap_ptr_operations {
-       int (*bpop_prepare_alloc_ptr)(struct nilfs_bmap *,
-                                     union nilfs_bmap_ptr_req *);
-       void (*bpop_commit_alloc_ptr)(struct nilfs_bmap *,
-                                     union nilfs_bmap_ptr_req *);
-       void (*bpop_abort_alloc_ptr)(struct nilfs_bmap *,
-                                    union nilfs_bmap_ptr_req *);
-       int (*bpop_prepare_start_ptr)(struct nilfs_bmap *,
-                                     union nilfs_bmap_ptr_req *);
-       void (*bpop_commit_start_ptr)(struct nilfs_bmap *,
-                                     union nilfs_bmap_ptr_req *,
-                                     sector_t);
-       void (*bpop_abort_start_ptr)(struct nilfs_bmap *,
-                                    union nilfs_bmap_ptr_req *);
-       int (*bpop_prepare_end_ptr)(struct nilfs_bmap *,
-                                   union nilfs_bmap_ptr_req *);
-       void (*bpop_commit_end_ptr)(struct nilfs_bmap *,
-                                   union nilfs_bmap_ptr_req *);
-       void (*bpop_abort_end_ptr)(struct nilfs_bmap *,
-                                  union nilfs_bmap_ptr_req *);
-
-       int (*bpop_translate)(const struct nilfs_bmap *, __u64, __u64 *);
-};
-
-
 #define NILFS_BMAP_SIZE                (NILFS_INODE_BMAP_SIZE * sizeof(__le64))
 #define NILFS_BMAP_KEY_BIT     (sizeof(unsigned long) * 8 /* CHAR_BIT */)
 #define NILFS_BMAP_NEW_PTR_INIT        \
@@ -131,11 +105,9 @@ static inline int nilfs_bmap_is_new_ptr(unsigned long ptr)
  * @b_sem: semaphore
  * @b_inode: owner of bmap
  * @b_ops: bmap operation table
- * @b_pops: bmap ptr operation table
- * @b_low: low watermark of conversion
- * @b_high: high watermark of conversion
  * @b_last_allocated_key: last allocated key for data block
  * @b_last_allocated_ptr: last allocated ptr for data block
+ * @b_ptr_type: pointer type
  * @b_state: state
  */
 struct nilfs_bmap {
@@ -146,14 +118,22 @@ struct nilfs_bmap {
        struct rw_semaphore b_sem;
        struct inode *b_inode;
        const struct nilfs_bmap_operations *b_ops;
-       const struct nilfs_bmap_ptr_operations *b_pops;
-       __u64 b_low;
-       __u64 b_high;
        __u64 b_last_allocated_key;
        __u64 b_last_allocated_ptr;
+       int b_ptr_type;
        int b_state;
 };
 
+/* pointer type */
+#define NILFS_BMAP_PTR_P       0       /* physical block number (i.e. LBN) */
+#define NILFS_BMAP_PTR_VS      1       /* virtual block number (single
+                                          version) */
+#define NILFS_BMAP_PTR_VM      2       /* virtual block number (has multiple
+                                          versions) */
+#define NILFS_BMAP_PTR_U       (-1)    /* never perform pointer operations */
+
+#define NILFS_BMAP_USE_VBN(bmap)       ((bmap)->b_ptr_type > 0)
+
 /* state */
 #define NILFS_BMAP_DIRTY       0x00000001
 
@@ -162,6 +142,7 @@ int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *);
 int nilfs_bmap_read(struct nilfs_bmap *, struct nilfs_inode *);
 void nilfs_bmap_write(struct nilfs_bmap *, struct nilfs_inode *);
 int nilfs_bmap_lookup(struct nilfs_bmap *, unsigned long, unsigned long *);
+int nilfs_bmap_lookup_contig(struct nilfs_bmap *, __u64, __u64 *, unsigned);
 int nilfs_bmap_insert(struct nilfs_bmap *, unsigned long, unsigned long);
 int nilfs_bmap_delete(struct nilfs_bmap *, unsigned long);
 int nilfs_bmap_last_key(struct nilfs_bmap *, unsigned long *);
@@ -182,7 +163,67 @@ void nilfs_bmap_commit_gcdat(struct nilfs_bmap *, struct nilfs_bmap *);
 /*
  * Internal use only
  */
+struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *);
+int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *,
+                              union nilfs_bmap_ptr_req *);
+void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *,
+                              union nilfs_bmap_ptr_req *);
+void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *,
+                             union nilfs_bmap_ptr_req *);
 
+static inline int nilfs_bmap_prepare_alloc_ptr(struct nilfs_bmap *bmap,
+                                              union nilfs_bmap_ptr_req *req)
+{
+       if (NILFS_BMAP_USE_VBN(bmap))
+               return nilfs_bmap_prepare_alloc_v(bmap, req);
+       /* ignore target ptr */
+       req->bpr_ptr = bmap->b_last_allocated_ptr++;
+       return 0;
+}
+
+static inline void nilfs_bmap_commit_alloc_ptr(struct nilfs_bmap *bmap,
+                                              union nilfs_bmap_ptr_req *req)
+{
+       if (NILFS_BMAP_USE_VBN(bmap))
+               nilfs_bmap_commit_alloc_v(bmap, req);
+}
+
+static inline void nilfs_bmap_abort_alloc_ptr(struct nilfs_bmap *bmap,
+                                             union nilfs_bmap_ptr_req *req)
+{
+       if (NILFS_BMAP_USE_VBN(bmap))
+               nilfs_bmap_abort_alloc_v(bmap, req);
+       else
+               bmap->b_last_allocated_ptr--;
+}
+
+int nilfs_bmap_prepare_end_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *);
+void nilfs_bmap_commit_end_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *);
+void nilfs_bmap_abort_end_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *);
+
+static inline int nilfs_bmap_prepare_end_ptr(struct nilfs_bmap *bmap,
+                                            union nilfs_bmap_ptr_req *req)
+{
+       return NILFS_BMAP_USE_VBN(bmap) ?
+               nilfs_bmap_prepare_end_v(bmap, req) : 0;
+}
+
+static inline void nilfs_bmap_commit_end_ptr(struct nilfs_bmap *bmap,
+                                            union nilfs_bmap_ptr_req *req)
+{
+       if (NILFS_BMAP_USE_VBN(bmap))
+               nilfs_bmap_commit_end_v(bmap, req);
+}
+
+static inline void nilfs_bmap_abort_end_ptr(struct nilfs_bmap *bmap,
+                                           union nilfs_bmap_ptr_req *req)
+{
+       if (NILFS_BMAP_USE_VBN(bmap))
+               nilfs_bmap_abort_end_v(bmap, req);
+}
+
+int nilfs_bmap_start_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *,
+                      sector_t);
 int nilfs_bmap_move_v(const struct nilfs_bmap *, __u64, sector_t);
 int nilfs_bmap_mark_dirty(const struct nilfs_bmap *, __u64);
 
@@ -193,28 +234,20 @@ __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *,
 __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *, __u64);
 __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *);
 
-int nilfs_bmap_prepare_update(struct nilfs_bmap *,
-                             union nilfs_bmap_ptr_req *,
-                             union nilfs_bmap_ptr_req *);
-void nilfs_bmap_commit_update(struct nilfs_bmap *,
-                             union nilfs_bmap_ptr_req *,
-                             union nilfs_bmap_ptr_req *);
-void nilfs_bmap_abort_update(struct nilfs_bmap *,
-                            union nilfs_bmap_ptr_req *,
-                            union nilfs_bmap_ptr_req *);
+int nilfs_bmap_prepare_update_v(struct nilfs_bmap *,
+                               union nilfs_bmap_ptr_req *,
+                               union nilfs_bmap_ptr_req *);
+void nilfs_bmap_commit_update_v(struct nilfs_bmap *,
+                               union nilfs_bmap_ptr_req *,
+                               union nilfs_bmap_ptr_req *);
+void nilfs_bmap_abort_update_v(struct nilfs_bmap *,
+                              union nilfs_bmap_ptr_req *,
+                              union nilfs_bmap_ptr_req *);
 
 void nilfs_bmap_add_blocks(const struct nilfs_bmap *, int);
 void nilfs_bmap_sub_blocks(const struct nilfs_bmap *, int);
 
 
-int nilfs_bmap_get_block(const struct nilfs_bmap *, __u64,
-                        struct buffer_head **);
-void nilfs_bmap_put_block(const struct nilfs_bmap *, struct buffer_head *);
-int nilfs_bmap_get_new_block(const struct nilfs_bmap *, __u64,
-                            struct buffer_head **);
-void nilfs_bmap_delete_block(const struct nilfs_bmap *, struct buffer_head *);
-
-
 /* Assume that bmap semaphore is locked. */
 static inline int nilfs_bmap_dirty(const struct nilfs_bmap *bmap)
 {
index 4cc07b2..7e0b61b 100644 (file)
@@ -46,15 +46,18 @@ void nilfs_btnode_cache_init_once(struct address_space *btnc)
        INIT_LIST_HEAD(&btnc->i_mmap_nonlinear);
 }
 
-static struct address_space_operations def_btnode_aops;
+static struct address_space_operations def_btnode_aops = {
+       .sync_page              = block_sync_page,
+};
 
-void nilfs_btnode_cache_init(struct address_space *btnc)
+void nilfs_btnode_cache_init(struct address_space *btnc,
+                            struct backing_dev_info *bdi)
 {
        btnc->host = NULL;  /* can safely set to host inode ? */
        btnc->flags = 0;
        mapping_set_gfp_mask(btnc, GFP_NOFS);
        btnc->assoc_mapping = NULL;
-       btnc->backing_dev_info = &default_backing_dev_info;
+       btnc->backing_dev_info = bdi;
        btnc->a_ops = &def_btnode_aops;
 }
 
index 35faa86..3e22751 100644 (file)
@@ -38,7 +38,7 @@ struct nilfs_btnode_chkey_ctxt {
 };
 
 void nilfs_btnode_cache_init_once(struct address_space *);
-void nilfs_btnode_cache_init(struct address_space *);
+void nilfs_btnode_cache_init(struct address_space *, struct backing_dev_info *);
 void nilfs_btnode_cache_clear(struct address_space *);
 int nilfs_btnode_submit_block(struct address_space *, __u64, sector_t,
                              struct buffer_head **, int);
index 6b37a27..aa41272 100644 (file)
@@ -29,6 +29,7 @@
 #include "btnode.h"
 #include "btree.h"
 #include "alloc.h"
+#include "dat.h"
 
 /**
  * struct nilfs_btree_path - A path on which B-tree operations are executed
@@ -109,8 +110,7 @@ static void nilfs_btree_clear_path(const struct nilfs_btree *btree,
             level < NILFS_BTREE_LEVEL_MAX;
             level++) {
                if (path[level].bp_bh != NULL) {
-                       nilfs_bmap_put_block(&btree->bt_bmap,
-                                            path[level].bp_bh);
+                       brelse(path[level].bp_bh);
                        path[level].bp_bh = NULL;
                }
                /* sib_bh is released or deleted by prepare or commit
@@ -123,10 +123,29 @@ static void nilfs_btree_clear_path(const struct nilfs_btree *btree,
        }
 }
 
-
 /*
  * B-tree node operations
  */
+static int nilfs_btree_get_block(const struct nilfs_btree *btree, __u64 ptr,
+                                struct buffer_head **bhp)
+{
+       struct address_space *btnc =
+               &NILFS_BMAP_I((struct nilfs_bmap *)btree)->i_btnode_cache;
+       return nilfs_btnode_get(btnc, ptr, 0, bhp, 0);
+}
+
+static int nilfs_btree_get_new_block(const struct nilfs_btree *btree,
+                                    __u64 ptr, struct buffer_head **bhp)
+{
+       struct address_space *btnc =
+               &NILFS_BMAP_I((struct nilfs_bmap *)btree)->i_btnode_cache;
+       int ret;
+
+       ret = nilfs_btnode_get(btnc, ptr, 0, bhp, 1);
+       if (!ret)
+               set_buffer_nilfs_volatile(*bhp);
+       return ret;
+}
 
 static inline int
 nilfs_btree_node_get_flags(const struct nilfs_btree *btree,
@@ -488,8 +507,7 @@ static int nilfs_btree_do_lookup(const struct nilfs_btree *btree,
        path[level].bp_index = index;
 
        for (level--; level >= minlevel; level--) {
-               ret = nilfs_bmap_get_block(&btree->bt_bmap, ptr,
-                                          &path[level].bp_bh);
+               ret = nilfs_btree_get_block(btree, ptr, &path[level].bp_bh);
                if (ret < 0)
                        return ret;
                node = nilfs_btree_get_nonroot_node(btree, path, level);
@@ -535,8 +553,7 @@ static int nilfs_btree_do_lookup_last(const struct nilfs_btree *btree,
        path[level].bp_index = index;
 
        for (level--; level > 0; level--) {
-               ret = nilfs_bmap_get_block(&btree->bt_bmap, ptr,
-                                          &path[level].bp_bh);
+               ret = nilfs_btree_get_block(btree, ptr, &path[level].bp_bh);
                if (ret < 0)
                        return ret;
                node = nilfs_btree_get_nonroot_node(btree, path, level);
@@ -579,6 +596,87 @@ static int nilfs_btree_lookup(const struct nilfs_bmap *bmap,
        return ret;
 }
 
+static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
+                                    __u64 key, __u64 *ptrp, unsigned maxblocks)
+{
+       struct nilfs_btree *btree = (struct nilfs_btree *)bmap;
+       struct nilfs_btree_path *path;
+       struct nilfs_btree_node *node;
+       struct inode *dat = NULL;
+       __u64 ptr, ptr2;
+       sector_t blocknr;
+       int level = NILFS_BTREE_LEVEL_NODE_MIN;
+       int ret, cnt, index, maxlevel;
+
+       path = nilfs_btree_alloc_path(btree);
+       if (path == NULL)
+               return -ENOMEM;
+       nilfs_btree_init_path(btree, path);
+       ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level);
+       if (ret < 0)
+               goto out;
+
+       if (NILFS_BMAP_USE_VBN(bmap)) {
+               dat = nilfs_bmap_get_dat(bmap);
+               ret = nilfs_dat_translate(dat, ptr, &blocknr);
+               if (ret < 0)
+                       goto out;
+               ptr = blocknr;
+       }
+       cnt = 1;
+       if (cnt == maxblocks)
+               goto end;
+
+       maxlevel = nilfs_btree_height(btree) - 1;
+       node = nilfs_btree_get_node(btree, path, level);
+       index = path[level].bp_index + 1;
+       for (;;) {
+               while (index < nilfs_btree_node_get_nchildren(btree, node)) {
+                       if (nilfs_btree_node_get_key(btree, node, index) !=
+                           key + cnt)
+                               goto end;
+                       ptr2 = nilfs_btree_node_get_ptr(btree, node, index);
+                       if (dat) {
+                               ret = nilfs_dat_translate(dat, ptr2, &blocknr);
+                               if (ret < 0)
+                                       goto out;
+                               ptr2 = blocknr;
+                       }
+                       if (ptr2 != ptr + cnt || ++cnt == maxblocks)
+                               goto end;
+                       index++;
+                       continue;
+               }
+               if (level == maxlevel)
+                       break;
+
+               /* look-up right sibling node */
+               node = nilfs_btree_get_node(btree, path, level + 1);
+               index = path[level + 1].bp_index + 1;
+               if (index >= nilfs_btree_node_get_nchildren(btree, node) ||
+                   nilfs_btree_node_get_key(btree, node, index) != key + cnt)
+                       break;
+               ptr2 = nilfs_btree_node_get_ptr(btree, node, index);
+               path[level + 1].bp_index = index;
+
+               brelse(path[level].bp_bh);
+               path[level].bp_bh = NULL;
+               ret = nilfs_btree_get_block(btree, ptr2, &path[level].bp_bh);
+               if (ret < 0)
+                       goto out;
+               node = nilfs_btree_get_nonroot_node(btree, path, level);
+               index = 0;
+               path[level].bp_index = index;
+       }
+ end:
+       *ptrp = ptr;
+       ret = cnt;
+ out:
+       nilfs_btree_clear_path(btree, path);
+       nilfs_btree_free_path(btree, path);
+       return ret;
+}
+
 static void nilfs_btree_promote_key(struct nilfs_btree *btree,
                                    struct nilfs_btree_path *path,
                                    int level, __u64 key)
@@ -669,13 +767,13 @@ static void nilfs_btree_carry_left(struct nilfs_btree *btree,
                                nilfs_btree_node_get_key(btree, node, 0));
 
        if (move) {
-               nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_bh);
+               brelse(path[level].bp_bh);
                path[level].bp_bh = path[level].bp_sib_bh;
                path[level].bp_sib_bh = NULL;
                path[level].bp_index += lnchildren;
                path[level + 1].bp_index--;
        } else {
-               nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
+               brelse(path[level].bp_sib_bh);
                path[level].bp_sib_bh = NULL;
                path[level].bp_index -= n;
        }
@@ -722,14 +820,14 @@ static void nilfs_btree_carry_right(struct nilfs_btree *btree,
        path[level + 1].bp_index--;
 
        if (move) {
-               nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_bh);
+               brelse(path[level].bp_bh);
                path[level].bp_bh = path[level].bp_sib_bh;
                path[level].bp_sib_bh = NULL;
                path[level].bp_index -=
                        nilfs_btree_node_get_nchildren(btree, node);
                path[level + 1].bp_index++;
        } else {
-               nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
+               brelse(path[level].bp_sib_bh);
                path[level].bp_sib_bh = NULL;
        }
 
@@ -781,7 +879,7 @@ static void nilfs_btree_split(struct nilfs_btree *btree,
                *keyp = nilfs_btree_node_get_key(btree, right, 0);
                *ptrp = path[level].bp_newreq.bpr_ptr;
 
-               nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_bh);
+               brelse(path[level].bp_bh);
                path[level].bp_bh = path[level].bp_sib_bh;
                path[level].bp_sib_bh = NULL;
        } else {
@@ -790,7 +888,7 @@ static void nilfs_btree_split(struct nilfs_btree *btree,
                *keyp = nilfs_btree_node_get_key(btree, right, 0);
                *ptrp = path[level].bp_newreq.bpr_ptr;
 
-               nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
+               brelse(path[level].bp_sib_bh);
                path[level].bp_sib_bh = NULL;
        }
 
@@ -897,12 +995,12 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
        level = NILFS_BTREE_LEVEL_DATA;
 
        /* allocate a new ptr for data block */
-       if (btree->bt_ops->btop_find_target != NULL)
+       if (NILFS_BMAP_USE_VBN(&btree->bt_bmap))
                path[level].bp_newreq.bpr_ptr =
-                       btree->bt_ops->btop_find_target(btree, path, key);
+                       nilfs_btree_find_target_v(btree, path, key);
 
-       ret = btree->bt_bmap.b_pops->bpop_prepare_alloc_ptr(
-               &btree->bt_bmap, &path[level].bp_newreq);
+       ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap,
+                                          &path[level].bp_newreq);
        if (ret < 0)
                goto err_out_data;
 
@@ -924,8 +1022,7 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
                if (pindex > 0) {
                        sibptr = nilfs_btree_node_get_ptr(btree, parent,
                                                          pindex - 1);
-                       ret = nilfs_bmap_get_block(&btree->bt_bmap, sibptr,
-                                                  &bh);
+                       ret = nilfs_btree_get_block(btree, sibptr, &bh);
                        if (ret < 0)
                                goto err_out_child_node;
                        sib = (struct nilfs_btree_node *)bh->b_data;
@@ -936,7 +1033,7 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
                                stats->bs_nblocks++;
                                goto out;
                        } else
-                               nilfs_bmap_put_block(&btree->bt_bmap, bh);
+                               brelse(bh);
                }
 
                /* right sibling */
@@ -944,8 +1041,7 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
                    nilfs_btree_node_get_nchildren(btree, parent) - 1) {
                        sibptr = nilfs_btree_node_get_ptr(btree, parent,
                                                          pindex + 1);
-                       ret = nilfs_bmap_get_block(&btree->bt_bmap, sibptr,
-                                                  &bh);
+                       ret = nilfs_btree_get_block(btree, sibptr, &bh);
                        if (ret < 0)
                                goto err_out_child_node;
                        sib = (struct nilfs_btree_node *)bh->b_data;
@@ -956,19 +1052,19 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
                                stats->bs_nblocks++;
                                goto out;
                        } else
-                               nilfs_bmap_put_block(&btree->bt_bmap, bh);
+                               brelse(bh);
                }
 
                /* split */
                path[level].bp_newreq.bpr_ptr =
                        path[level - 1].bp_newreq.bpr_ptr + 1;
-               ret = btree->bt_bmap.b_pops->bpop_prepare_alloc_ptr(
-                       &btree->bt_bmap, &path[level].bp_newreq);
+               ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap,
+                                                  &path[level].bp_newreq);
                if (ret < 0)
                        goto err_out_child_node;
-               ret = nilfs_bmap_get_new_block(&btree->bt_bmap,
-                                              path[level].bp_newreq.bpr_ptr,
-                                              &bh);
+               ret = nilfs_btree_get_new_block(btree,
+                                               path[level].bp_newreq.bpr_ptr,
+                                               &bh);
                if (ret < 0)
                        goto err_out_curr_node;
 
@@ -994,12 +1090,12 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
 
        /* grow */
        path[level].bp_newreq.bpr_ptr = path[level - 1].bp_newreq.bpr_ptr + 1;
-       ret = btree->bt_bmap.b_pops->bpop_prepare_alloc_ptr(
-               &btree->bt_bmap, &path[level].bp_newreq);
+       ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap,
+                                          &path[level].bp_newreq);
        if (ret < 0)
                goto err_out_child_node;
-       ret = nilfs_bmap_get_new_block(&btree->bt_bmap,
-                                      path[level].bp_newreq.bpr_ptr, &bh);
+       ret = nilfs_btree_get_new_block(btree, path[level].bp_newreq.bpr_ptr,
+                                       &bh);
        if (ret < 0)
                goto err_out_curr_node;
 
@@ -1023,18 +1119,16 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
 
        /* error */
  err_out_curr_node:
-       btree->bt_bmap.b_pops->bpop_abort_alloc_ptr(&btree->bt_bmap,
-                                                   &path[level].bp_newreq);
+       nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq);
  err_out_child_node:
        for (level--; level > NILFS_BTREE_LEVEL_DATA; level--) {
-               nilfs_bmap_delete_block(&btree->bt_bmap, path[level].bp_sib_bh);
-               btree->bt_bmap.b_pops->bpop_abort_alloc_ptr(
-                       &btree->bt_bmap, &path[level].bp_newreq);
+               nilfs_btnode_delete(path[level].bp_sib_bh);
+               nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap,
+                                          &path[level].bp_newreq);
 
        }
 
-       btree->bt_bmap.b_pops->bpop_abort_alloc_ptr(&btree->bt_bmap,
-                                                      &path[level].bp_newreq);
+       nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq);
  err_out_data:
        *levelp = level;
        stats->bs_nblocks = 0;
@@ -1049,14 +1143,12 @@ static void nilfs_btree_commit_insert(struct nilfs_btree *btree,
 
        set_buffer_nilfs_volatile((struct buffer_head *)((unsigned long)ptr));
        ptr = path[NILFS_BTREE_LEVEL_DATA].bp_newreq.bpr_ptr;
-       if (btree->bt_ops->btop_set_target != NULL)
-               btree->bt_ops->btop_set_target(btree, key, ptr);
+       if (NILFS_BMAP_USE_VBN(&btree->bt_bmap))
+               nilfs_btree_set_target_v(btree, key, ptr);
 
        for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) {
-               if (btree->bt_bmap.b_pops->bpop_commit_alloc_ptr != NULL) {
-                       btree->bt_bmap.b_pops->bpop_commit_alloc_ptr(
-                               &btree->bt_bmap, &path[level - 1].bp_newreq);
-               }
+               nilfs_bmap_commit_alloc_ptr(&btree->bt_bmap,
+                                           &path[level - 1].bp_newreq);
                path[level].bp_op(btree, path, level, &key, &ptr);
        }
 
@@ -1153,7 +1245,7 @@ static void nilfs_btree_borrow_left(struct nilfs_btree *btree,
        nilfs_btree_promote_key(btree, path, level + 1,
                                nilfs_btree_node_get_key(btree, node, 0));
 
-       nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
+       brelse(path[level].bp_sib_bh);
        path[level].bp_sib_bh = NULL;
        path[level].bp_index += n;
 }
@@ -1192,7 +1284,7 @@ static void nilfs_btree_borrow_right(struct nilfs_btree *btree,
                                nilfs_btree_node_get_key(btree, right, 0));
        path[level + 1].bp_index--;
 
-       nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
+       brelse(path[level].bp_sib_bh);
        path[level].bp_sib_bh = NULL;
 }
 
@@ -1221,7 +1313,7 @@ static void nilfs_btree_concat_left(struct nilfs_btree *btree,
        unlock_buffer(path[level].bp_bh);
        unlock_buffer(path[level].bp_sib_bh);
 
-       nilfs_bmap_delete_block(&btree->bt_bmap, path[level].bp_bh);
+       nilfs_btnode_delete(path[level].bp_bh);
        path[level].bp_bh = path[level].bp_sib_bh;
        path[level].bp_sib_bh = NULL;
        path[level].bp_index += nilfs_btree_node_get_nchildren(btree, left);
@@ -1252,7 +1344,7 @@ static void nilfs_btree_concat_right(struct nilfs_btree *btree,
        unlock_buffer(path[level].bp_bh);
        unlock_buffer(path[level].bp_sib_bh);
 
-       nilfs_bmap_delete_block(&btree->bt_bmap, path[level].bp_sib_bh);
+       nilfs_btnode_delete(path[level].bp_sib_bh);
        path[level].bp_sib_bh = NULL;
        path[level + 1].bp_index++;
 }
@@ -1276,7 +1368,7 @@ static void nilfs_btree_shrink(struct nilfs_btree *btree,
        nilfs_btree_node_move_left(btree, root, child, n);
        unlock_buffer(path[level].bp_bh);
 
-       nilfs_bmap_delete_block(&btree->bt_bmap, path[level].bp_bh);
+       nilfs_btnode_delete(path[level].bp_bh);
        path[level].bp_bh = NULL;
 }
 
@@ -1300,12 +1392,10 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
                path[level].bp_oldreq.bpr_ptr =
                        nilfs_btree_node_get_ptr(btree, node,
                                                 path[level].bp_index);
-               if (btree->bt_bmap.b_pops->bpop_prepare_end_ptr != NULL) {
-                       ret = btree->bt_bmap.b_pops->bpop_prepare_end_ptr(
-                               &btree->bt_bmap, &path[level].bp_oldreq);
-                       if (ret < 0)
-                               goto err_out_child_node;
-               }
+               ret = nilfs_bmap_prepare_end_ptr(&btree->bt_bmap,
+                                                &path[level].bp_oldreq);
+               if (ret < 0)
+                       goto err_out_child_node;
 
                if (nilfs_btree_node_get_nchildren(btree, node) >
                    nilfs_btree_node_nchildren_min(btree, node)) {
@@ -1321,8 +1411,7 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
                        /* left sibling */
                        sibptr = nilfs_btree_node_get_ptr(btree, parent,
                                                          pindex - 1);
-                       ret = nilfs_bmap_get_block(&btree->bt_bmap, sibptr,
-                                                  &bh);
+                       ret = nilfs_btree_get_block(btree, sibptr, &bh);
                        if (ret < 0)
                                goto err_out_curr_node;
                        sib = (struct nilfs_btree_node *)bh->b_data;
@@ -1343,8 +1432,7 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
                        /* right sibling */
                        sibptr = nilfs_btree_node_get_ptr(btree, parent,
                                                          pindex + 1);
-                       ret = nilfs_bmap_get_block(&btree->bt_bmap, sibptr,
-                                                  &bh);
+                       ret = nilfs_btree_get_block(btree, sibptr, &bh);
                        if (ret < 0)
                                goto err_out_curr_node;
                        sib = (struct nilfs_btree_node *)bh->b_data;
@@ -1381,12 +1469,12 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
        node = nilfs_btree_get_root(btree);
        path[level].bp_oldreq.bpr_ptr =
                nilfs_btree_node_get_ptr(btree, node, path[level].bp_index);
-       if (btree->bt_bmap.b_pops->bpop_prepare_end_ptr != NULL) {
-               ret = btree->bt_bmap.b_pops->bpop_prepare_end_ptr(
-                       &btree->bt_bmap, &path[level].bp_oldreq);
-               if (ret < 0)
-                       goto err_out_child_node;
-       }
+
+       ret = nilfs_bmap_prepare_end_ptr(&btree->bt_bmap,
+                                        &path[level].bp_oldreq);
+       if (ret < 0)
+               goto err_out_child_node;
+
        /* child of the root node is deleted */
        path[level].bp_op = nilfs_btree_do_delete;
        stats->bs_nblocks++;
@@ -1398,15 +1486,12 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
 
        /* error */
  err_out_curr_node:
-       if (btree->bt_bmap.b_pops->bpop_abort_end_ptr != NULL)
-               btree->bt_bmap.b_pops->bpop_abort_end_ptr(
-                       &btree->bt_bmap, &path[level].bp_oldreq);
+       nilfs_bmap_abort_end_ptr(&btree->bt_bmap, &path[level].bp_oldreq);
  err_out_child_node:
        for (level--; level >= NILFS_BTREE_LEVEL_NODE_MIN; level--) {
-               nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
-               if (btree->bt_bmap.b_pops->bpop_abort_end_ptr != NULL)
-                       btree->bt_bmap.b_pops->bpop_abort_end_ptr(
-                               &btree->bt_bmap, &path[level].bp_oldreq);
+               brelse(path[level].bp_sib_bh);
+               nilfs_bmap_abort_end_ptr(&btree->bt_bmap,
+                                        &path[level].bp_oldreq);
        }
        *levelp = level;
        stats->bs_nblocks = 0;
@@ -1420,9 +1505,8 @@ static void nilfs_btree_commit_delete(struct nilfs_btree *btree,
        int level;
 
        for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) {
-               if (btree->bt_bmap.b_pops->bpop_commit_end_ptr != NULL)
-                       btree->bt_bmap.b_pops->bpop_commit_end_ptr(
-                               &btree->bt_bmap, &path[level].bp_oldreq);
+               nilfs_bmap_commit_end_ptr(&btree->bt_bmap,
+                                         &path[level].bp_oldreq);
                path[level].bp_op(btree, path, level, NULL, NULL);
        }
 
@@ -1501,7 +1585,7 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *bmap, __u64 key)
                if (nchildren > 1)
                        return 0;
                ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1);
-               ret = nilfs_bmap_get_block(bmap, ptr, &bh);
+               ret = nilfs_btree_get_block(btree, ptr, &bh);
                if (ret < 0)
                        return ret;
                node = (struct nilfs_btree_node *)bh->b_data;
@@ -1515,9 +1599,9 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *bmap, __u64 key)
        nextmaxkey = (nchildren > 1) ?
                nilfs_btree_node_get_key(btree, node, nchildren - 2) : 0;
        if (bh != NULL)
-               nilfs_bmap_put_block(bmap, bh);
+               brelse(bh);
 
-       return (maxkey == key) && (nextmaxkey < bmap->b_low);
+       return (maxkey == key) && (nextmaxkey < NILFS_BMAP_LARGE_LOW);
 }
 
 static int nilfs_btree_gather_data(struct nilfs_bmap *bmap,
@@ -1542,7 +1626,7 @@ static int nilfs_btree_gather_data(struct nilfs_bmap *bmap,
                nchildren = nilfs_btree_node_get_nchildren(btree, root);
                WARN_ON(nchildren > 1);
                ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1);
-               ret = nilfs_bmap_get_block(bmap, ptr, &bh);
+               ret = nilfs_btree_get_block(btree, ptr, &bh);
                if (ret < 0)
                        return ret;
                node = (struct nilfs_btree_node *)bh->b_data;
@@ -1563,7 +1647,7 @@ static int nilfs_btree_gather_data(struct nilfs_bmap *bmap,
        }
 
        if (bh != NULL)
-               nilfs_bmap_put_block(bmap, bh);
+               brelse(bh);
 
        return nitems;
 }
@@ -1584,10 +1668,10 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
 
        /* for data */
        /* cannot find near ptr */
-       if (btree->bt_ops->btop_find_target != NULL)
-               dreq->bpr_ptr
-                       = btree->bt_ops->btop_find_target(btree, NULL, key);
-       ret = bmap->b_pops->bpop_prepare_alloc_ptr(bmap, dreq);
+       if (NILFS_BMAP_USE_VBN(bmap))
+               dreq->bpr_ptr = nilfs_btree_find_target_v(btree, NULL, key);
+
+       ret = nilfs_bmap_prepare_alloc_ptr(bmap, dreq);
        if (ret < 0)
                return ret;
 
@@ -1595,11 +1679,11 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
        stats->bs_nblocks++;
        if (nreq != NULL) {
                nreq->bpr_ptr = dreq->bpr_ptr + 1;
-               ret = bmap->b_pops->bpop_prepare_alloc_ptr(bmap, nreq);
+               ret = nilfs_bmap_prepare_alloc_ptr(bmap, nreq);
                if (ret < 0)
                        goto err_out_dreq;
 
-               ret = nilfs_bmap_get_new_block(bmap, nreq->bpr_ptr, &bh);
+               ret = nilfs_btree_get_new_block(btree, nreq->bpr_ptr, &bh);
                if (ret < 0)
                        goto err_out_nreq;
 
@@ -1612,9 +1696,9 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
 
        /* error */
  err_out_nreq:
-       bmap->b_pops->bpop_abort_alloc_ptr(bmap, nreq);
+       nilfs_bmap_abort_alloc_ptr(bmap, nreq);
  err_out_dreq:
-       bmap->b_pops->bpop_abort_alloc_ptr(bmap, dreq);
+       nilfs_bmap_abort_alloc_ptr(bmap, dreq);
        stats->bs_nblocks = 0;
        return ret;
 
@@ -1624,7 +1708,7 @@ static void
 nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
                                      __u64 key, __u64 ptr,
                                      const __u64 *keys, const __u64 *ptrs,
-                                     int n, __u64 low, __u64 high,
+                                     int n,
                                      union nilfs_bmap_ptr_req *dreq,
                                      union nilfs_bmap_ptr_req *nreq,
                                      struct buffer_head *bh)
@@ -1642,12 +1726,10 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
 
        /* convert and insert */
        btree = (struct nilfs_btree *)bmap;
-       nilfs_btree_init(bmap, low, high);
+       nilfs_btree_init(bmap);
        if (nreq != NULL) {
-               if (bmap->b_pops->bpop_commit_alloc_ptr != NULL) {
-                       bmap->b_pops->bpop_commit_alloc_ptr(bmap, dreq);
-                       bmap->b_pops->bpop_commit_alloc_ptr(bmap, nreq);
-               }
+               nilfs_bmap_commit_alloc_ptr(bmap, dreq);
+               nilfs_bmap_commit_alloc_ptr(bmap, nreq);
 
                /* create child node at level 1 */
                lock_buffer(bh);
@@ -1661,7 +1743,7 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
                        nilfs_bmap_set_dirty(bmap);
 
                unlock_buffer(bh);
-               nilfs_bmap_put_block(bmap, bh);
+               brelse(bh);
 
                /* create root node at level 2 */
                node = nilfs_btree_get_root(btree);
@@ -1669,8 +1751,7 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
                nilfs_btree_node_init(btree, node, NILFS_BTREE_NODE_ROOT,
                                      2, 1, &keys[0], &tmpptr);
        } else {
-               if (bmap->b_pops->bpop_commit_alloc_ptr != NULL)
-                       bmap->b_pops->bpop_commit_alloc_ptr(bmap, dreq);
+               nilfs_bmap_commit_alloc_ptr(bmap, dreq);
 
                /* create root node at level 1 */
                node = nilfs_btree_get_root(btree);
@@ -1682,8 +1763,8 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
                        nilfs_bmap_set_dirty(bmap);
        }
 
-       if (btree->bt_ops->btop_set_target != NULL)
-               btree->bt_ops->btop_set_target(btree, key, dreq->bpr_ptr);
+       if (NILFS_BMAP_USE_VBN(bmap))
+               nilfs_btree_set_target_v(btree, key, dreq->bpr_ptr);
 }
 
 /**
@@ -1694,13 +1775,10 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
  * @keys:
  * @ptrs:
  * @n:
- * @low:
- * @high:
  */
 int nilfs_btree_convert_and_insert(struct nilfs_bmap *bmap,
                                   __u64 key, __u64 ptr,
-                                  const __u64 *keys, const __u64 *ptrs,
-                                  int n, __u64 low, __u64 high)
+                                  const __u64 *keys, const __u64 *ptrs, int n)
 {
        struct buffer_head *bh;
        union nilfs_bmap_ptr_req dreq, nreq, *di, *ni;
@@ -1725,7 +1803,7 @@ int nilfs_btree_convert_and_insert(struct nilfs_bmap *bmap,
        if (ret < 0)
                return ret;
        nilfs_btree_commit_convert_and_insert(bmap, key, ptr, keys, ptrs, n,
-                                             low, high, di, ni, bh);
+                                             di, ni, bh);
        nilfs_bmap_add_blocks(bmap, stats.bs_nblocks);
        return 0;
 }
@@ -1754,9 +1832,9 @@ static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree,
                nilfs_btree_node_get_ptr(btree, parent,
                                         path[level + 1].bp_index);
        path[level].bp_newreq.bpr_ptr = path[level].bp_oldreq.bpr_ptr + 1;
-       ret = nilfs_bmap_prepare_update(&btree->bt_bmap,
-                                       &path[level].bp_oldreq,
-                                       &path[level].bp_newreq);
+       ret = nilfs_bmap_prepare_update_v(&btree->bt_bmap,
+                                         &path[level].bp_oldreq,
+                                         &path[level].bp_newreq);
        if (ret < 0)
                return ret;
 
@@ -1768,9 +1846,9 @@ static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree,
                        &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
                        &path[level].bp_ctxt);
                if (ret < 0) {
-                       nilfs_bmap_abort_update(&btree->bt_bmap,
-                                               &path[level].bp_oldreq,
-                                               &path[level].bp_newreq);
+                       nilfs_bmap_abort_update_v(&btree->bt_bmap,
+                                                 &path[level].bp_oldreq,
+                                                 &path[level].bp_newreq);
                        return ret;
                }
        }
@@ -1784,9 +1862,9 @@ static void nilfs_btree_commit_update_v(struct nilfs_btree *btree,
 {
        struct nilfs_btree_node *parent;
 
-       nilfs_bmap_commit_update(&btree->bt_bmap,
-                                &path[level].bp_oldreq,
-                                &path[level].bp_newreq);
+       nilfs_bmap_commit_update_v(&btree->bt_bmap,
+                                  &path[level].bp_oldreq,
+                                  &path[level].bp_newreq);
 
        if (buffer_nilfs_node(path[level].bp_bh)) {
                nilfs_btnode_commit_change_key(
@@ -1805,9 +1883,9 @@ static void nilfs_btree_abort_update_v(struct nilfs_btree *btree,
                                       struct nilfs_btree_path *path,
                                       int level)
 {
-       nilfs_bmap_abort_update(&btree->bt_bmap,
-                               &path[level].bp_oldreq,
-                               &path[level].bp_newreq);
+       nilfs_bmap_abort_update_v(&btree->bt_bmap,
+                                 &path[level].bp_oldreq,
+                                 &path[level].bp_newreq);
        if (buffer_nilfs_node(path[level].bp_bh))
                nilfs_btnode_abort_change_key(
                        &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
@@ -1930,7 +2008,9 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
                goto out;
        }
 
-       ret = btree->bt_ops->btop_propagate(btree, path, level, bh);
+       ret = NILFS_BMAP_USE_VBN(bmap) ?
+               nilfs_btree_propagate_v(btree, path, level, bh) :
+               nilfs_btree_propagate_p(btree, path, level, bh);
 
  out:
        nilfs_btree_clear_path(btree, path);
@@ -2066,12 +2146,9 @@ static int nilfs_btree_assign_v(struct nilfs_btree *btree,
        ptr = nilfs_btree_node_get_ptr(btree, parent,
                                       path[level + 1].bp_index);
        req.bpr_ptr = ptr;
-       ret = btree->bt_bmap.b_pops->bpop_prepare_start_ptr(&btree->bt_bmap,
-                                                              &req);
-       if (ret < 0)
+       ret = nilfs_bmap_start_v(&btree->bt_bmap, &req, blocknr);
+       if (unlikely(ret < 0))
                return ret;
-       btree->bt_bmap.b_pops->bpop_commit_start_ptr(&btree->bt_bmap,
-                                                       &req, blocknr);
 
        key = nilfs_btree_node_get_key(btree, parent,
                                       path[level + 1].bp_index);
@@ -2114,8 +2191,9 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap,
                goto out;
        }
 
-       ret = btree->bt_ops->btop_assign(btree, path, level, bh,
-                                           blocknr, binfo);
+       ret = NILFS_BMAP_USE_VBN(bmap) ?
+               nilfs_btree_assign_v(btree, path, level, bh, blocknr, binfo) :
+               nilfs_btree_assign_p(btree, path, level, bh, blocknr, binfo);
 
  out:
        nilfs_btree_clear_path(btree, path);
@@ -2171,7 +2249,7 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
                WARN_ON(ret == -ENOENT);
                goto out;
        }
-       ret = nilfs_bmap_get_block(&btree->bt_bmap, ptr, &bh);
+       ret = nilfs_btree_get_block(btree, ptr, &bh);
        if (ret < 0) {
                WARN_ON(ret == -ENOENT);
                goto out;
@@ -2179,7 +2257,7 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
 
        if (!buffer_dirty(bh))
                nilfs_btnode_mark_dirty(bh);
-       nilfs_bmap_put_block(&btree->bt_bmap, bh);
+       brelse(bh);
        if (!nilfs_bmap_dirty(&btree->bt_bmap))
                nilfs_bmap_set_dirty(&btree->bt_bmap);
 
@@ -2191,6 +2269,7 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
 
 static const struct nilfs_bmap_operations nilfs_btree_ops = {
        .bop_lookup             =       nilfs_btree_lookup,
+       .bop_lookup_contig      =       nilfs_btree_lookup_contig,
        .bop_insert             =       nilfs_btree_insert,
        .bop_delete             =       nilfs_btree_delete,
        .bop_clear              =       NULL,
@@ -2210,6 +2289,7 @@ static const struct nilfs_bmap_operations nilfs_btree_ops = {
 
 static const struct nilfs_bmap_operations nilfs_btree_ops_gc = {
        .bop_lookup             =       NULL,
+       .bop_lookup_contig      =       NULL,
        .bop_insert             =       NULL,
        .bop_delete             =       NULL,
        .bop_clear              =       NULL,
@@ -2227,43 +2307,13 @@ static const struct nilfs_bmap_operations nilfs_btree_ops_gc = {
        .bop_gather_data        =       NULL,
 };
 
-static const struct nilfs_btree_operations nilfs_btree_ops_v = {
-       .btop_find_target       =       nilfs_btree_find_target_v,
-       .btop_set_target        =       nilfs_btree_set_target_v,
-       .btop_propagate         =       nilfs_btree_propagate_v,
-       .btop_assign            =       nilfs_btree_assign_v,
-};
-
-static const struct nilfs_btree_operations nilfs_btree_ops_p = {
-       .btop_find_target       =       NULL,
-       .btop_set_target        =       NULL,
-       .btop_propagate         =       nilfs_btree_propagate_p,
-       .btop_assign            =       nilfs_btree_assign_p,
-};
-
-int nilfs_btree_init(struct nilfs_bmap *bmap, __u64 low, __u64 high)
+int nilfs_btree_init(struct nilfs_bmap *bmap)
 {
-       struct nilfs_btree *btree;
-
-       btree = (struct nilfs_btree *)bmap;
        bmap->b_ops = &nilfs_btree_ops;
-       bmap->b_low = low;
-       bmap->b_high = high;
-       switch (bmap->b_inode->i_ino) {
-       case NILFS_DAT_INO:
-               btree->bt_ops = &nilfs_btree_ops_p;
-               break;
-       default:
-               btree->bt_ops = &nilfs_btree_ops_v;
-               break;
-       }
-
        return 0;
 }
 
 void nilfs_btree_init_gc(struct nilfs_bmap *bmap)
 {
-       bmap->b_low = NILFS_BMAP_LARGE_LOW;
-       bmap->b_high = NILFS_BMAP_LARGE_HIGH;
        bmap->b_ops = &nilfs_btree_ops_gc;
 }
index 4766deb..0e72bbb 100644 (file)
@@ -34,28 +34,6 @@ struct nilfs_btree;
 struct nilfs_btree_path;
 
 /**
- * struct nilfs_btree_operations - B-tree operation table
- */
-struct nilfs_btree_operations {
-       __u64 (*btop_find_target)(const struct nilfs_btree *,
-                                 const struct nilfs_btree_path *, __u64);
-       void (*btop_set_target)(struct nilfs_btree *, __u64, __u64);
-
-       struct the_nilfs *(*btop_get_nilfs)(struct nilfs_btree *);
-
-       int (*btop_propagate)(struct nilfs_btree *,
-                             struct nilfs_btree_path *,
-                             int,
-                             struct buffer_head *);
-       int (*btop_assign)(struct nilfs_btree *,
-                          struct nilfs_btree_path *,
-                          int,
-                          struct buffer_head **,
-                          sector_t,
-                          union nilfs_binfo *);
-};
-
-/**
  * struct nilfs_btree_node - B-tree node
  * @bn_flags: flags
  * @bn_level: level
@@ -80,13 +58,9 @@ struct nilfs_btree_node {
 /**
  * struct nilfs_btree - B-tree structure
  * @bt_bmap: bmap base structure
- * @bt_ops: B-tree operation table
  */
 struct nilfs_btree {
        struct nilfs_bmap bt_bmap;
-
-       /* B-tree-specific members */
-       const struct nilfs_btree_operations *bt_ops;
 };
 
 
@@ -108,10 +82,9 @@ struct nilfs_btree {
 
 int nilfs_btree_path_cache_init(void);
 void nilfs_btree_path_cache_destroy(void);
-int nilfs_btree_init(struct nilfs_bmap *, __u64, __u64);
+int nilfs_btree_init(struct nilfs_bmap *);
 int nilfs_btree_convert_and_insert(struct nilfs_bmap *, __u64, __u64,
-                                  const __u64 *, const __u64 *,
-                                  int, __u64, __u64);
+                                  const __u64 *, const __u64 *, int);
 void nilfs_btree_init_gc(struct nilfs_bmap *);
 
 #endif /* _NILFS_BTREE_H */
index cadd36b..7d49813 100644 (file)
@@ -295,10 +295,6 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile,
                return -EINVAL;
        }
 
-       /* cannot delete the latest checkpoint */
-       if (start == nilfs_mdt_cno(cpfile) - 1)
-               return -EPERM;
-
        down_write(&NILFS_MDT(cpfile)->mi_sem);
 
        ret = nilfs_cpfile_get_header_block(cpfile, &header_bh);
@@ -384,9 +380,10 @@ static void nilfs_cpfile_checkpoint_to_cpinfo(struct inode *cpfile,
 }
 
 static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop,
-                                         struct nilfs_cpinfo *ci, size_t nci)
+                                         void *buf, unsigned cisz, size_t nci)
 {
        struct nilfs_checkpoint *cp;
+       struct nilfs_cpinfo *ci = buf;
        struct buffer_head *bh;
        size_t cpsz = NILFS_MDT(cpfile)->mi_entry_size;
        __u64 cur_cno = nilfs_mdt_cno(cpfile), cno = *cnop;
@@ -410,17 +407,22 @@ static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop,
                kaddr = kmap_atomic(bh->b_page, KM_USER0);
                cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr);
                for (i = 0; i < ncps && n < nci; i++, cp = (void *)cp + cpsz) {
-                       if (!nilfs_checkpoint_invalid(cp))
-                               nilfs_cpfile_checkpoint_to_cpinfo(
-                                       cpfile, cp, &ci[n++]);
+                       if (!nilfs_checkpoint_invalid(cp)) {
+                               nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp,
+                                                                 ci);
+                               ci = (void *)ci + cisz;
+                               n++;
+                       }
                }
                kunmap_atomic(kaddr, KM_USER0);
                brelse(bh);
        }
 
        ret = n;
-       if (n > 0)
-               *cnop = ci[n - 1].ci_cno + 1;
+       if (n > 0) {
+               ci = (void *)ci - cisz;
+               *cnop = ci->ci_cno + 1;
+       }
 
  out:
        up_read(&NILFS_MDT(cpfile)->mi_sem);
@@ -428,11 +430,12 @@ static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop,
 }
 
 static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop,
-                                         struct nilfs_cpinfo *ci, size_t nci)
+                                         void *buf, unsigned cisz, size_t nci)
 {
        struct buffer_head *bh;
        struct nilfs_cpfile_header *header;
        struct nilfs_checkpoint *cp;
+       struct nilfs_cpinfo *ci = buf;
        __u64 curr = *cnop, next;
        unsigned long curr_blkoff, next_blkoff;
        void *kaddr;
@@ -472,7 +475,9 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop,
                if (unlikely(nilfs_checkpoint_invalid(cp) ||
                             !nilfs_checkpoint_snapshot(cp)))
                        break;
-               nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, &ci[n++]);
+               nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, ci);
+               ci = (void *)ci + cisz;
+               n++;
                next = le64_to_cpu(cp->cp_snapshot_list.ssl_next);
                if (next == 0)
                        break; /* reach end of the snapshot list */
@@ -511,13 +516,13 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop,
  */
 
 ssize_t nilfs_cpfile_get_cpinfo(struct inode *cpfile, __u64 *cnop, int mode,
-                               struct nilfs_cpinfo *ci, size_t nci)
+                               void *buf, unsigned cisz, size_t nci)
 {
        switch (mode) {
        case NILFS_CHECKPOINT:
-               return nilfs_cpfile_do_get_cpinfo(cpfile, cnop, ci, nci);
+               return nilfs_cpfile_do_get_cpinfo(cpfile, cnop, buf, cisz, nci);
        case NILFS_SNAPSHOT:
-               return nilfs_cpfile_do_get_ssinfo(cpfile, cnop, ci, nci);
+               return nilfs_cpfile_do_get_ssinfo(cpfile, cnop, buf, cisz, nci);
        default:
                return -EINVAL;
        }
@@ -533,20 +538,14 @@ int nilfs_cpfile_delete_checkpoint(struct inode *cpfile, __u64 cno)
        struct nilfs_cpinfo ci;
        __u64 tcno = cno;
        ssize_t nci;
-       int ret;
 
-       nci = nilfs_cpfile_do_get_cpinfo(cpfile, &tcno, &ci, 1);
+       nci = nilfs_cpfile_do_get_cpinfo(cpfile, &tcno, &ci, sizeof(ci), 1);
        if (nci < 0)
                return nci;
        else if (nci == 0 || ci.ci_cno != cno)
                return -ENOENT;
-
-       /* cannot delete the latest checkpoint nor snapshots */
-       ret = nilfs_cpinfo_snapshot(&ci);
-       if (ret < 0)
-               return ret;
-       else if (ret > 0 || cno == nilfs_mdt_cno(cpfile) - 1)
-               return -EPERM;
+       else if (nilfs_cpinfo_snapshot(&ci))
+               return -EBUSY;
 
        return nilfs_cpfile_delete_checkpoints(cpfile, cno, cno + 1);
 }
index 1a8a100..788a459 100644 (file)
@@ -39,7 +39,7 @@ int nilfs_cpfile_delete_checkpoint(struct inode *, __u64);
 int nilfs_cpfile_change_cpmode(struct inode *, __u64, int);
 int nilfs_cpfile_is_snapshot(struct inode *, __u64);
 int nilfs_cpfile_get_stat(struct inode *, struct nilfs_cpstat *);
-ssize_t nilfs_cpfile_get_cpinfo(struct inode *, __u64 *, int,
-                               struct nilfs_cpinfo *, size_t);
+ssize_t nilfs_cpfile_get_cpinfo(struct inode *, __u64 *, int, void *, unsigned,
+                               size_t);
 
 #endif /* _NILFS_CPFILE_H */
index bb8a581..0b2710e 100644 (file)
@@ -92,21 +92,6 @@ void nilfs_dat_abort_alloc(struct inode *dat, struct nilfs_palloc_req *req)
        nilfs_palloc_abort_alloc_entry(dat, req);
 }
 
-int nilfs_dat_prepare_free(struct inode *dat, struct nilfs_palloc_req *req)
-{
-       int ret;
-
-       ret = nilfs_palloc_prepare_free_entry(dat, req);
-       if (ret < 0)
-               return ret;
-       ret = nilfs_dat_prepare_entry(dat, req, 0);
-       if (ret < 0) {
-               nilfs_palloc_abort_free_entry(dat, req);
-               return ret;
-       }
-       return 0;
-}
-
 void nilfs_dat_commit_free(struct inode *dat, struct nilfs_palloc_req *req)
 {
        struct nilfs_dat_entry *entry;
@@ -391,36 +376,37 @@ int nilfs_dat_translate(struct inode *dat, __u64 vblocknr, sector_t *blocknrp)
        return ret;
 }
 
-ssize_t nilfs_dat_get_vinfo(struct inode *dat, struct nilfs_vinfo *vinfo,
+ssize_t nilfs_dat_get_vinfo(struct inode *dat, void *buf, unsigned visz,
                            size_t nvi)
 {
        struct buffer_head *entry_bh;
        struct nilfs_dat_entry *entry;
+       struct nilfs_vinfo *vinfo = buf;
        __u64 first, last;
        void *kaddr;
        unsigned long entries_per_block = NILFS_MDT(dat)->mi_entries_per_block;
        int i, j, n, ret;
 
        for (i = 0; i < nvi; i += n) {
-               ret = nilfs_palloc_get_entry_block(dat, vinfo[i].vi_vblocknr,
+               ret = nilfs_palloc_get_entry_block(dat, vinfo->vi_vblocknr,
                                                   0, &entry_bh);
                if (ret < 0)
                        return ret;
                kaddr = kmap_atomic(entry_bh->b_page, KM_USER0);
                /* last virtual block number in this block */
-               first = vinfo[i].vi_vblocknr;
+               first = vinfo->vi_vblocknr;
                do_div(first, entries_per_block);
                first *= entries_per_block;
                last = first + entries_per_block - 1;
                for (j = i, n = 0;
-                    j < nvi && vinfo[j].vi_vblocknr >= first &&
-                            vinfo[j].vi_vblocknr <= last;
-                    j++, n++) {
+                    j < nvi && vinfo->vi_vblocknr >= first &&
+                            vinfo->vi_vblocknr <= last;
+                    j++, n++, vinfo = (void *)vinfo + visz) {
                        entry = nilfs_palloc_block_get_entry(
-                               dat, vinfo[j].vi_vblocknr, entry_bh, kaddr);
-                       vinfo[j].vi_start = le64_to_cpu(entry->de_start);
-                       vinfo[j].vi_end = le64_to_cpu(entry->de_end);
-                       vinfo[j].vi_blocknr = le64_to_cpu(entry->de_blocknr);
+                               dat, vinfo->vi_vblocknr, entry_bh, kaddr);
+                       vinfo->vi_start = le64_to_cpu(entry->de_start);
+                       vinfo->vi_end = le64_to_cpu(entry->de_end);
+                       vinfo->vi_blocknr = le64_to_cpu(entry->de_blocknr);
                }
                kunmap_atomic(kaddr, KM_USER0);
                brelse(entry_bh);
index d956065..d328b81 100644 (file)
@@ -47,6 +47,6 @@ void nilfs_dat_abort_end(struct inode *, struct nilfs_palloc_req *);
 int nilfs_dat_mark_dirty(struct inode *, __u64);
 int nilfs_dat_freev(struct inode *, __u64 *, size_t);
 int nilfs_dat_move(struct inode *, __u64, sector_t);
-ssize_t nilfs_dat_get_vinfo(struct inode *, struct nilfs_vinfo *, size_t);
+ssize_t nilfs_dat_get_vinfo(struct inode *, void *, unsigned, size_t);
 
 #endif /* _NILFS_DAT_H */
index c6379e4..342d976 100644 (file)
@@ -25,6 +25,7 @@
 #include "page.h"
 #include "direct.h"
 #include "alloc.h"
+#include "dat.h"
 
 static inline __le64 *nilfs_direct_dptrs(const struct nilfs_direct *direct)
 {
@@ -62,6 +63,47 @@ static int nilfs_direct_lookup(const struct nilfs_bmap *bmap,
        return 0;
 }
 
+static int nilfs_direct_lookup_contig(const struct nilfs_bmap *bmap,
+                                     __u64 key, __u64 *ptrp,
+                                     unsigned maxblocks)
+{
+       struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
+       struct inode *dat = NULL;
+       __u64 ptr, ptr2;
+       sector_t blocknr;
+       int ret, cnt;
+
+       if (key > NILFS_DIRECT_KEY_MAX ||
+           (ptr = nilfs_direct_get_ptr(direct, key)) ==
+           NILFS_BMAP_INVALID_PTR)
+               return -ENOENT;
+
+       if (NILFS_BMAP_USE_VBN(bmap)) {
+               dat = nilfs_bmap_get_dat(bmap);
+               ret = nilfs_dat_translate(dat, ptr, &blocknr);
+               if (ret < 0)
+                       return ret;
+               ptr = blocknr;
+       }
+
+       maxblocks = min_t(unsigned, maxblocks, NILFS_DIRECT_KEY_MAX - key + 1);
+       for (cnt = 1; cnt < maxblocks &&
+                    (ptr2 = nilfs_direct_get_ptr(direct, key + cnt)) !=
+                    NILFS_BMAP_INVALID_PTR;
+            cnt++) {
+               if (dat) {
+                       ret = nilfs_dat_translate(dat, ptr2, &blocknr);
+                       if (ret < 0)
+                               return ret;
+                       ptr2 = blocknr;
+               }
+               if (ptr2 != ptr + cnt)
+                       break;
+       }
+       *ptrp = ptr;
+       return cnt;
+}
+
 static __u64
 nilfs_direct_find_target_v(const struct nilfs_direct *direct, __u64 key)
 {
@@ -90,10 +132,9 @@ static int nilfs_direct_prepare_insert(struct nilfs_direct *direct,
 {
        int ret;
 
-       if (direct->d_ops->dop_find_target != NULL)
-               req->bpr_ptr = direct->d_ops->dop_find_target(direct, key);
-       ret = direct->d_bmap.b_pops->bpop_prepare_alloc_ptr(&direct->d_bmap,
-                                                              req);
+       if (NILFS_BMAP_USE_VBN(&direct->d_bmap))
+               req->bpr_ptr = nilfs_direct_find_target_v(direct, key);
+       ret = nilfs_bmap_prepare_alloc_ptr(&direct->d_bmap, req);
        if (ret < 0)
                return ret;
 
@@ -111,16 +152,14 @@ static void nilfs_direct_commit_insert(struct nilfs_direct *direct,
        bh = (struct buffer_head *)((unsigned long)ptr);
        set_buffer_nilfs_volatile(bh);
 
-       if (direct->d_bmap.b_pops->bpop_commit_alloc_ptr != NULL)
-               direct->d_bmap.b_pops->bpop_commit_alloc_ptr(
-                       &direct->d_bmap, req);
+       nilfs_bmap_commit_alloc_ptr(&direct->d_bmap, req);
        nilfs_direct_set_ptr(direct, key, req->bpr_ptr);
 
        if (!nilfs_bmap_dirty(&direct->d_bmap))
                nilfs_bmap_set_dirty(&direct->d_bmap);
 
-       if (direct->d_ops->dop_set_target != NULL)
-               direct->d_ops->dop_set_target(direct, key, req->bpr_ptr);
+       if (NILFS_BMAP_USE_VBN(&direct->d_bmap))
+               nilfs_direct_set_target_v(direct, key, req->bpr_ptr);
 }
 
 static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
@@ -152,25 +191,18 @@ static int nilfs_direct_prepare_delete(struct nilfs_direct *direct,
 {
        int ret;
 
-       if (direct->d_bmap.b_pops->bpop_prepare_end_ptr != NULL) {
-               req->bpr_ptr = nilfs_direct_get_ptr(direct, key);
-               ret = direct->d_bmap.b_pops->bpop_prepare_end_ptr(
-                       &direct->d_bmap, req);
-               if (ret < 0)
-                       return ret;
-       }
-
-       stats->bs_nblocks = 1;
-       return 0;
+       req->bpr_ptr = nilfs_direct_get_ptr(direct, key);
+       ret = nilfs_bmap_prepare_end_ptr(&direct->d_bmap, req);
+       if (!ret)
+               stats->bs_nblocks = 1;
+       return ret;
 }
 
 static void nilfs_direct_commit_delete(struct nilfs_direct *direct,
                                       union nilfs_bmap_ptr_req *req,
                                       __u64 key)
 {
-       if (direct->d_bmap.b_pops->bpop_commit_end_ptr != NULL)
-               direct->d_bmap.b_pops->bpop_commit_end_ptr(
-                       &direct->d_bmap, req);
+       nilfs_bmap_commit_end_ptr(&direct->d_bmap, req);
        nilfs_direct_set_ptr(direct, key, NILFS_BMAP_INVALID_PTR);
 }
 
@@ -244,8 +276,7 @@ static int nilfs_direct_gather_data(struct nilfs_bmap *bmap,
 }
 
 int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap,
-                                   __u64 key, __u64 *keys, __u64 *ptrs,
-                                   int n, __u64 low, __u64 high)
+                                   __u64 key, __u64 *keys, __u64 *ptrs, int n)
 {
        struct nilfs_direct *direct;
        __le64 *dptrs;
@@ -275,8 +306,7 @@ int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap,
                        dptrs[i] = NILFS_BMAP_INVALID_PTR;
        }
 
-       nilfs_direct_init(bmap, low, high);
-
+       nilfs_direct_init(bmap);
        return 0;
 }
 
@@ -293,11 +323,11 @@ static int nilfs_direct_propagate_v(struct nilfs_direct *direct,
        if (!buffer_nilfs_volatile(bh)) {
                oldreq.bpr_ptr = ptr;
                newreq.bpr_ptr = ptr;
-               ret = nilfs_bmap_prepare_update(&direct->d_bmap, &oldreq,
-                                               &newreq);
+               ret = nilfs_bmap_prepare_update_v(&direct->d_bmap, &oldreq,
+                                                 &newreq);
                if (ret < 0)
                        return ret;
-               nilfs_bmap_commit_update(&direct->d_bmap, &oldreq, &newreq);
+               nilfs_bmap_commit_update_v(&direct->d_bmap, &oldreq, &newreq);
                set_buffer_nilfs_volatile(bh);
                nilfs_direct_set_ptr(direct, key, newreq.bpr_ptr);
        } else
@@ -309,12 +339,10 @@ static int nilfs_direct_propagate_v(struct nilfs_direct *direct,
 static int nilfs_direct_propagate(const struct nilfs_bmap *bmap,
                                  struct buffer_head *bh)
 {
-       struct nilfs_direct *direct;
+       struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
 
-       direct = (struct nilfs_direct *)bmap;
-       return (direct->d_ops->dop_propagate != NULL) ?
-               direct->d_ops->dop_propagate(direct, bh) :
-               0;
+       return NILFS_BMAP_USE_VBN(bmap) ?
+               nilfs_direct_propagate_v(direct, bh) : 0;
 }
 
 static int nilfs_direct_assign_v(struct nilfs_direct *direct,
@@ -327,12 +355,9 @@ static int nilfs_direct_assign_v(struct nilfs_direct *direct,
        int ret;
 
        req.bpr_ptr = ptr;
-       ret = direct->d_bmap.b_pops->bpop_prepare_start_ptr(
-               &direct->d_bmap, &req);
-       if (ret < 0)
+       ret = nilfs_bmap_start_v(&direct->d_bmap, &req, blocknr);
+       if (unlikely(ret < 0))
                return ret;
-       direct->d_bmap.b_pops->bpop_commit_start_ptr(&direct->d_bmap,
-                                                    &req, blocknr);
 
        binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr);
        binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key);
@@ -377,12 +402,14 @@ static int nilfs_direct_assign(struct nilfs_bmap *bmap,
                return -EINVAL;
        }
 
-       return direct->d_ops->dop_assign(direct, key, ptr, bh,
-                                        blocknr, binfo);
+       return NILFS_BMAP_USE_VBN(bmap) ?
+               nilfs_direct_assign_v(direct, key, ptr, bh, blocknr, binfo) :
+               nilfs_direct_assign_p(direct, key, ptr, bh, blocknr, binfo);
 }
 
 static const struct nilfs_bmap_operations nilfs_direct_ops = {
        .bop_lookup             =       nilfs_direct_lookup,
+       .bop_lookup_contig      =       nilfs_direct_lookup_contig,
        .bop_insert             =       nilfs_direct_insert,
        .bop_delete             =       nilfs_direct_delete,
        .bop_clear              =       NULL,
@@ -401,36 +428,8 @@ static const struct nilfs_bmap_operations nilfs_direct_ops = {
 };
 
 
-static const struct nilfs_direct_operations nilfs_direct_ops_v = {
-       .dop_find_target        =       nilfs_direct_find_target_v,
-       .dop_set_target         =       nilfs_direct_set_target_v,
-       .dop_propagate          =       nilfs_direct_propagate_v,
-       .dop_assign             =       nilfs_direct_assign_v,
-};
-
-static const struct nilfs_direct_operations nilfs_direct_ops_p = {
-       .dop_find_target        =       NULL,
-       .dop_set_target         =       NULL,
-       .dop_propagate          =       NULL,
-       .dop_assign             =       nilfs_direct_assign_p,
-};
-
-int nilfs_direct_init(struct nilfs_bmap *bmap, __u64 low, __u64 high)
+int nilfs_direct_init(struct nilfs_bmap *bmap)
 {
-       struct nilfs_direct *direct;
-
-       direct = (struct nilfs_direct *)bmap;
        bmap->b_ops = &nilfs_direct_ops;
-       bmap->b_low = low;
-       bmap->b_high = high;
-       switch (bmap->b_inode->i_ino) {
-       case NILFS_DAT_INO:
-               direct->d_ops = &nilfs_direct_ops_p;
-               break;
-       default:
-               direct->d_ops = &nilfs_direct_ops_v;
-               break;
-       }
-
        return 0;
 }
index 45d2c5c..a5ffd66 100644 (file)
 struct nilfs_direct;
 
 /**
- * struct nilfs_direct_operations - direct mapping operation table
- */
-struct nilfs_direct_operations {
-       __u64 (*dop_find_target)(const struct nilfs_direct *, __u64);
-       void (*dop_set_target)(struct nilfs_direct *, __u64, __u64);
-       int (*dop_propagate)(struct nilfs_direct *, struct buffer_head *);
-       int (*dop_assign)(struct nilfs_direct *, __u64, __u64,
-                         struct buffer_head **, sector_t,
-                         union nilfs_binfo *);
-};
-
-/**
  * struct nilfs_direct_node - direct node
  * @dn_flags: flags
  * @dn_pad: padding
@@ -55,13 +43,9 @@ struct nilfs_direct_node {
 /**
  * struct nilfs_direct - direct mapping
  * @d_bmap: bmap structure
- * @d_ops: direct mapping operation table
  */
 struct nilfs_direct {
        struct nilfs_bmap d_bmap;
-
-       /* direct-mapping-specific members */
-       const struct nilfs_direct_operations *d_ops;
 };
 
 
@@ -70,9 +54,9 @@ struct nilfs_direct {
 #define NILFS_DIRECT_KEY_MAX   (NILFS_DIRECT_NBLOCKS - 1)
 
 
-int nilfs_direct_init(struct nilfs_bmap *, __u64, __u64);
+int nilfs_direct_init(struct nilfs_bmap *);
 int nilfs_direct_delete_and_convert(struct nilfs_bmap *, __u64, __u64 *,
-                                   __u64 *, int, __u64, __u64);
+                                   __u64 *, int);
 
 
 #endif /* _NILFS_DIRECT_H */
index 19d2102..1b3c2bb 100644 (file)
@@ -52,8 +52,9 @@
 #include "dat.h"
 #include "ifile.h"
 
-static struct address_space_operations def_gcinode_aops = {};
-/* XXX need def_gcinode_iops/fops? */
+static struct address_space_operations def_gcinode_aops = {
+       .sync_page              = block_sync_page,
+};
 
 /*
  * nilfs_gccache_submit_read_data() - add data buffer and submit read request
index 49ab4a4..2696d6b 100644 (file)
  *
  * This function does not issue actual read request of the specified data
  * block. It is done by VFS.
- * Bulk read for direct-io is not supported yet. (should be supported)
  */
 int nilfs_get_block(struct inode *inode, sector_t blkoff,
                    struct buffer_head *bh_result, int create)
 {
        struct nilfs_inode_info *ii = NILFS_I(inode);
-       unsigned long blknum = 0;
+       __u64 blknum = 0;
        int err = 0, ret;
        struct inode *dat = nilfs_dat_inode(NILFS_I_NILFS(inode));
+       unsigned maxblocks = bh_result->b_size >> inode->i_blkbits;
 
-       /* This exclusion control is a workaround; should be revised */
-       down_read(&NILFS_MDT(dat)->mi_sem);     /* XXX */
-       ret = nilfs_bmap_lookup(ii->i_bmap, (unsigned long)blkoff, &blknum);
-       up_read(&NILFS_MDT(dat)->mi_sem);       /* XXX */
-       if (ret == 0) { /* found */
+       down_read(&NILFS_MDT(dat)->mi_sem);
+       ret = nilfs_bmap_lookup_contig(ii->i_bmap, blkoff, &blknum, maxblocks);
+       up_read(&NILFS_MDT(dat)->mi_sem);
+       if (ret >= 0) { /* found */
                map_bh(bh_result, inode->i_sb, blknum);
+               if (ret > 0)
+                       bh_result->b_size = (ret << inode->i_blkbits);
                goto out;
        }
        /* data block was not found */
@@ -240,7 +241,7 @@ nilfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
 struct address_space_operations nilfs_aops = {
        .writepage              = nilfs_writepage,
        .readpage               = nilfs_readpage,
-       /* .sync_page           = nilfs_sync_page, */
+       .sync_page              = block_sync_page,
        .writepages             = nilfs_writepages,
        .set_page_dirty         = nilfs_set_page_dirty,
        .readpages              = nilfs_readpages,
@@ -249,6 +250,7 @@ struct address_space_operations nilfs_aops = {
        /* .releasepage         = nilfs_releasepage, */
        .invalidatepage         = block_invalidatepage,
        .direct_IO              = nilfs_direct_IO,
+       .is_partially_uptodate  = block_is_partially_uptodate,
 };
 
 struct inode *nilfs_new_inode(struct inode *dir, int mode)
index d6759b9..6ea5f87 100644 (file)
@@ -152,7 +152,7 @@ nilfs_ioctl_do_get_cpinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
 
        down_read(&nilfs->ns_segctor_sem);
        ret = nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf,
-                                     nmembs);
+                                     size, nmembs);
        up_read(&nilfs->ns_segctor_sem);
        return ret;
 }
@@ -182,7 +182,8 @@ nilfs_ioctl_do_get_suinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
        int ret;
 
        down_read(&nilfs->ns_segctor_sem);
-       ret = nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, nmembs);
+       ret = nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, size,
+                                     nmembs);
        up_read(&nilfs->ns_segctor_sem);
        return ret;
 }
@@ -212,7 +213,7 @@ nilfs_ioctl_do_get_vinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
        int ret;
 
        down_read(&nilfs->ns_segctor_sem);
-       ret = nilfs_dat_get_vinfo(nilfs_dat_inode(nilfs), buf, nmembs);
+       ret = nilfs_dat_get_vinfo(nilfs_dat_inode(nilfs), buf, size, nmembs);
        up_read(&nilfs->ns_segctor_sem);
        return ret;
 }
@@ -435,24 +436,6 @@ static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
        return nmembs;
 }
 
-static int nilfs_ioctl_free_segments(struct the_nilfs *nilfs,
-                                    struct nilfs_argv *argv, void *buf)
-{
-       size_t nmembs = argv->v_nmembs;
-       struct nilfs_sb_info *sbi = nilfs->ns_writer;
-       int ret;
-
-       if (unlikely(!sbi)) {
-               /* never happens because called for a writable mount */
-               WARN_ON(1);
-               return -EROFS;
-       }
-       ret = nilfs_segctor_add_segments_to_be_freed(
-               NILFS_SC(sbi), buf, nmembs);
-
-       return (ret < 0) ? ret : nmembs;
-}
-
 int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
                                       struct nilfs_argv *argv, void **kbufs)
 {
@@ -491,14 +474,6 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
                msg = "cannot mark copying blocks dirty";
                goto failed;
        }
-       ret = nilfs_ioctl_free_segments(nilfs, &argv[4], kbufs[4]);
-       if (ret < 0) {
-               /*
-                * can safely abort because this operation is atomic.
-                */
-               msg = "cannot set segments to be freed";
-               goto failed;
-       }
        return 0;
 
  failed:
@@ -615,7 +590,7 @@ static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
        if (copy_from_user(&argv, argp, sizeof(argv)))
                return -EFAULT;
 
-       if (argv.v_size != membsz)
+       if (argv.v_size < membsz)
                return -EINVAL;
 
        ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), dofunc);
index bb78745..3d3ddb3 100644 (file)
@@ -430,6 +430,7 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)
 
 static struct address_space_operations def_mdt_aops = {
        .writepage              = nilfs_mdt_write_page,
+       .sync_page              = block_sync_page,
 };
 
 static struct inode_operations def_mdt_iops;
@@ -449,7 +450,7 @@ struct inode *
 nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb,
                     ino_t ino, gfp_t gfp_mask)
 {
-       struct inode *inode = nilfs_alloc_inode(sb);
+       struct inode *inode = nilfs_alloc_inode_common(nilfs);
 
        if (!inode)
                return NULL;
index da6fc0b..edf6a59 100644 (file)
@@ -263,6 +263,7 @@ extern void nilfs_dirty_inode(struct inode *);
 extern struct dentry *nilfs_get_parent(struct dentry *);
 
 /* super.c */
+extern struct inode *nilfs_alloc_inode_common(struct the_nilfs *);
 extern struct inode *nilfs_alloc_inode(struct super_block *);
 extern void nilfs_destroy_inode(struct inode *);
 extern void nilfs_error(struct super_block *, const char *, const char *, ...)
index 57afa9d..d80cc71 100644 (file)
@@ -28,7 +28,6 @@
 #include "segment.h"
 #include "sufile.h"
 #include "page.h"
-#include "seglist.h"
 #include "segbuf.h"
 
 /*
@@ -395,6 +394,24 @@ static void dispose_recovery_list(struct list_head *head)
        }
 }
 
+struct nilfs_segment_entry {
+       struct list_head        list;
+       __u64                   segnum;
+};
+
+static int nilfs_segment_list_add(struct list_head *head, __u64 segnum)
+{
+       struct nilfs_segment_entry *ent = kmalloc(sizeof(*ent), GFP_NOFS);
+
+       if (unlikely(!ent))
+               return -ENOMEM;
+
+       ent->segnum = segnum;
+       INIT_LIST_HEAD(&ent->list);
+       list_add_tail(&ent->list, head);
+       return 0;
+}
+
 void nilfs_dispose_segment_list(struct list_head *head)
 {
        while (!list_empty(head)) {
@@ -402,7 +419,7 @@ void nilfs_dispose_segment_list(struct list_head *head)
                        = list_entry(head->next,
                                     struct nilfs_segment_entry, list);
                list_del(&ent->list);
-               nilfs_free_segment_entry(ent);
+               kfree(ent);
        }
 }
 
@@ -431,12 +448,10 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
        if (unlikely(err))
                goto failed;
 
-       err = -ENOMEM;
        for (i = 1; i < 4; i++) {
-               ent = nilfs_alloc_segment_entry(segnum[i]);
-               if (unlikely(!ent))
+               err = nilfs_segment_list_add(head, segnum[i]);
+               if (unlikely(err))
                        goto failed;
-               list_add_tail(&ent->list, head);
        }
 
        /*
@@ -450,7 +465,7 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
                                goto failed;
                }
                list_del(&ent->list);
-               nilfs_free_segment_entry(ent);
+               kfree(ent);
        }
 
        /* Allocate new segments for recovery */
@@ -791,7 +806,6 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
        u64 seg_seq;
        __u64 segnum, nextnum = 0;
        __u64 cno;
-       struct nilfs_segment_entry *ent;
        LIST_HEAD(segments);
        int empty_seg = 0, scan_newer = 0;
        int ret;
@@ -892,12 +906,9 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
                if (empty_seg++)
                        goto super_root_found; /* found a valid super root */
 
-               ent = nilfs_alloc_segment_entry(segnum);
-               if (unlikely(!ent)) {
-                       ret = -ENOMEM;
+               ret = nilfs_segment_list_add(&segments, segnum);
+               if (unlikely(ret))
                        goto failed;
-               }
-               list_add_tail(&ent->list, &segments);
 
                seg_seq++;
                segnum = nextnum;
index 1e68821..9e3fe17 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/crc32.h>
 #include "page.h"
 #include "segbuf.h"
-#include "seglist.h"
 
 
 static struct kmem_cache *nilfs_segbuf_cachep;
@@ -394,7 +393,7 @@ int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
                 * Last BIO is always sent through the following
                 * submission.
                 */
-               rw |= (1 << BIO_RW_SYNCIO);
+               rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG);
                res = nilfs_submit_seg_bio(wi, rw);
                if (unlikely(res))
                        goto failed_bio;
diff --git a/fs/nilfs2/seglist.h b/fs/nilfs2/seglist.h
deleted file mode 100644 (file)
index d39df91..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * seglist.h - expediential structure and routines to handle list of segments
- *             (would be removed in a future release)
- *
- * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Written by Ryusuke Konishi <ryusuke@osrg.net>
- *
- */
-#ifndef _NILFS_SEGLIST_H
-#define _NILFS_SEGLIST_H
-
-#include <linux/fs.h>
-#include <linux/buffer_head.h>
-#include <linux/nilfs2_fs.h>
-#include "sufile.h"
-
-struct nilfs_segment_entry {
-       __u64                   segnum;
-
-#define NILFS_SLH_FREED                0x0001  /* The segment was freed provisonally.
-                                          It must be cancelled if
-                                          construction aborted */
-
-       unsigned                flags;
-       struct list_head        list;
-       struct buffer_head     *bh_su;
-       struct nilfs_segment_usage *raw_su;
-};
-
-
-void nilfs_dispose_segment_list(struct list_head *);
-
-static inline struct nilfs_segment_entry *
-nilfs_alloc_segment_entry(__u64 segnum)
-{
-       struct nilfs_segment_entry *ent = kmalloc(sizeof(*ent), GFP_NOFS);
-
-       if (likely(ent)) {
-               ent->segnum = segnum;
-               ent->flags = 0;
-               ent->bh_su = NULL;
-               ent->raw_su = NULL;
-               INIT_LIST_HEAD(&ent->list);
-       }
-       return ent;
-}
-
-static inline int nilfs_open_segment_entry(struct nilfs_segment_entry *ent,
-                                          struct inode *sufile)
-{
-       return nilfs_sufile_get_segment_usage(sufile, ent->segnum,
-                                             &ent->raw_su, &ent->bh_su);
-}
-
-static inline void nilfs_close_segment_entry(struct nilfs_segment_entry *ent,
-                                            struct inode *sufile)
-{
-       if (!ent->bh_su)
-               return;
-       nilfs_sufile_put_segment_usage(sufile, ent->segnum, ent->bh_su);
-       ent->bh_su = NULL;
-       ent->raw_su = NULL;
-}
-
-static inline void nilfs_free_segment_entry(struct nilfs_segment_entry *ent)
-{
-       kfree(ent);
-}
-
-#endif /* _NILFS_SEGLIST_H */
index 22c7f65..aa97754 100644 (file)
@@ -39,7 +39,6 @@
 #include "sufile.h"
 #include "cpfile.h"
 #include "ifile.h"
-#include "seglist.h"
 #include "segbuf.h"
 
 
@@ -79,7 +78,8 @@ enum {
 /* State flags of collection */
 #define NILFS_CF_NODE          0x0001  /* Collecting node blocks */
 #define NILFS_CF_IFILE_STARTED 0x0002  /* IFILE stage has started */
-#define NILFS_CF_HISTORY_MASK  (NILFS_CF_IFILE_STARTED)
+#define NILFS_CF_SUFREED       0x0004  /* segment usages has been freed */
+#define NILFS_CF_HISTORY_MASK  (NILFS_CF_IFILE_STARTED | NILFS_CF_SUFREED)
 
 /* Operations depending on the construction mode and file type */
 struct nilfs_sc_operations {
@@ -810,7 +810,7 @@ static int nilfs_segctor_clean(struct nilfs_sc_info *sci)
 {
        return list_empty(&sci->sc_dirty_files) &&
                !test_bit(NILFS_SC_DIRTY, &sci->sc_flags) &&
-               list_empty(&sci->sc_cleaning_segments) &&
+               sci->sc_nfreesegs == 0 &&
                (!nilfs_doing_gc() || list_empty(&sci->sc_gc_inodes));
 }
 
@@ -1005,44 +1005,6 @@ static void nilfs_drop_collected_inodes(struct list_head *head)
        }
 }
 
-static void nilfs_segctor_cancel_free_segments(struct nilfs_sc_info *sci,
-                                              struct inode *sufile)
-
-{
-       struct list_head *head = &sci->sc_cleaning_segments;
-       struct nilfs_segment_entry *ent;
-       int err;
-
-       list_for_each_entry(ent, head, list) {
-               if (!(ent->flags & NILFS_SLH_FREED))
-                       break;
-               err = nilfs_sufile_cancel_free(sufile, ent->segnum);
-               WARN_ON(err); /* do not happen */
-               ent->flags &= ~NILFS_SLH_FREED;
-       }
-}
-
-static int nilfs_segctor_prepare_free_segments(struct nilfs_sc_info *sci,
-                                              struct inode *sufile)
-{
-       struct list_head *head = &sci->sc_cleaning_segments;
-       struct nilfs_segment_entry *ent;
-       int err;
-
-       list_for_each_entry(ent, head, list) {
-               err = nilfs_sufile_free(sufile, ent->segnum);
-               if (unlikely(err))
-                       return err;
-               ent->flags |= NILFS_SLH_FREED;
-       }
-       return 0;
-}
-
-static void nilfs_segctor_commit_free_segments(struct nilfs_sc_info *sci)
-{
-       nilfs_dispose_segment_list(&sci->sc_cleaning_segments);
-}
-
 static int nilfs_segctor_apply_buffers(struct nilfs_sc_info *sci,
                                       struct inode *inode,
                                       struct list_head *listp,
@@ -1161,6 +1123,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
        struct the_nilfs *nilfs = sbi->s_nilfs;
        struct list_head *head;
        struct nilfs_inode_info *ii;
+       size_t ndone;
        int err = 0;
 
        switch (sci->sc_stage.scnt) {
@@ -1250,10 +1213,16 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
                        break;
                sci->sc_stage.scnt++;  /* Fall through */
        case NILFS_ST_SUFILE:
-               err = nilfs_segctor_prepare_free_segments(sci,
-                                                         nilfs->ns_sufile);
-               if (unlikely(err))
+               err = nilfs_sufile_freev(nilfs->ns_sufile, sci->sc_freesegs,
+                                        sci->sc_nfreesegs, &ndone);
+               if (unlikely(err)) {
+                       nilfs_sufile_cancel_freev(nilfs->ns_sufile,
+                                                 sci->sc_freesegs, ndone,
+                                                 NULL);
                        break;
+               }
+               sci->sc_stage.flags |= NILFS_CF_SUFREED;
+
                err = nilfs_segctor_scan_file(sci, nilfs->ns_sufile,
                                              &nilfs_sc_file_ops);
                if (unlikely(err))
@@ -1486,7 +1455,15 @@ static void nilfs_segctor_end_construction(struct nilfs_sc_info *sci,
 {
        if (unlikely(err)) {
                nilfs_segctor_free_incomplete_segments(sci, nilfs);
-               nilfs_segctor_cancel_free_segments(sci, nilfs->ns_sufile);
+               if (sci->sc_stage.flags & NILFS_CF_SUFREED) {
+                       int ret;
+
+                       ret = nilfs_sufile_cancel_freev(nilfs->ns_sufile,
+                                                       sci->sc_freesegs,
+                                                       sci->sc_nfreesegs,
+                                                       NULL);
+                       WARN_ON(ret); /* do not happen */
+               }
        }
        nilfs_segctor_clear_segment_buffers(sci);
 }
@@ -1585,7 +1562,13 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
                if (mode != SC_LSEG_SR || sci->sc_stage.scnt < NILFS_ST_CPFILE)
                        break;
 
-               nilfs_segctor_cancel_free_segments(sci, nilfs->ns_sufile);
+               if (sci->sc_stage.flags & NILFS_CF_SUFREED) {
+                       err = nilfs_sufile_cancel_freev(nilfs->ns_sufile,
+                                                       sci->sc_freesegs,
+                                                       sci->sc_nfreesegs,
+                                                       NULL);
+                       WARN_ON(err); /* do not happen */
+               }
                nilfs_segctor_clear_segment_buffers(sci);
 
                err = nilfs_segctor_extend_segments(sci, nilfs, nadd);
@@ -2224,10 +2207,8 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
                nilfs_segctor_complete_write(sci);
 
                /* Commit segments */
-               if (has_sr) {
-                       nilfs_segctor_commit_free_segments(sci);
+               if (has_sr)
                        nilfs_segctor_clear_metadata_dirty(sci);
-               }
 
                nilfs_segctor_end_construction(sci, nilfs, 0);
 
@@ -2301,48 +2282,6 @@ void nilfs_flush_segment(struct super_block *sb, ino_t ino)
                                        /* assign bit 0 to data files */
 }
 
-int nilfs_segctor_add_segments_to_be_freed(struct nilfs_sc_info *sci,
-                                          __u64 *segnum, size_t nsegs)
-{
-       struct nilfs_segment_entry *ent;
-       struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs;
-       struct inode *sufile = nilfs->ns_sufile;
-       LIST_HEAD(list);
-       __u64 *pnum;
-       size_t i;
-       int err;
-
-       for (pnum = segnum, i = 0; i < nsegs; pnum++, i++) {
-               ent = nilfs_alloc_segment_entry(*pnum);
-               if (unlikely(!ent)) {
-                       err = -ENOMEM;
-                       goto failed;
-               }
-               list_add_tail(&ent->list, &list);
-
-               err = nilfs_open_segment_entry(ent, sufile);
-               if (unlikely(err))
-                       goto failed;
-
-               if (unlikely(!nilfs_segment_usage_dirty(ent->raw_su)))
-                       printk(KERN_WARNING "NILFS: unused segment is "
-                              "requested to be cleaned (segnum=%llu)\n",
-                              (unsigned long long)ent->segnum);
-               nilfs_close_segment_entry(ent, sufile);
-       }
-       list_splice(&list, sci->sc_cleaning_segments.prev);
-       return 0;
-
- failed:
-       nilfs_dispose_segment_list(&list);
-       return err;
-}
-
-void nilfs_segctor_clear_segments_to_be_freed(struct nilfs_sc_info *sci)
-{
-       nilfs_dispose_segment_list(&sci->sc_cleaning_segments);
-}
-
 struct nilfs_segctor_wait_request {
        wait_queue_t    wq;
        __u32           seq;
@@ -2607,10 +2546,13 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
        err = nilfs_init_gcdat_inode(nilfs);
        if (unlikely(err))
                goto out_unlock;
+
        err = nilfs_ioctl_prepare_clean_segments(nilfs, argv, kbufs);
        if (unlikely(err))
                goto out_unlock;
 
+       sci->sc_freesegs = kbufs[4];
+       sci->sc_nfreesegs = argv[4].v_nmembs;
        list_splice_init(&nilfs->ns_gc_inodes, sci->sc_gc_inodes.prev);
 
        for (;;) {
@@ -2629,6 +2571,8 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
        }
 
  out_unlock:
+       sci->sc_freesegs = NULL;
+       sci->sc_nfreesegs = 0;
        nilfs_clear_gcdat_inode(nilfs);
        nilfs_transaction_unlock(sbi);
        return err;
@@ -2835,7 +2779,6 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi)
        INIT_LIST_HEAD(&sci->sc_dirty_files);
        INIT_LIST_HEAD(&sci->sc_segbufs);
        INIT_LIST_HEAD(&sci->sc_gc_inodes);
-       INIT_LIST_HEAD(&sci->sc_cleaning_segments);
        INIT_LIST_HEAD(&sci->sc_copied_buffers);
 
        sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT;
@@ -2901,9 +2844,6 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
                nilfs_dispose_list(sbi, &sci->sc_dirty_files, 1);
        }
 
-       if (!list_empty(&sci->sc_cleaning_segments))
-               nilfs_dispose_segment_list(&sci->sc_cleaning_segments);
-
        WARN_ON(!list_empty(&sci->sc_segbufs));
 
        down_write(&sbi->s_nilfs->ns_segctor_sem);
index 476bdd5..0d2a475 100644 (file)
@@ -90,8 +90,9 @@ struct nilfs_segsum_pointer {
  * @sc_nblk_inc: Block count of current generation
  * @sc_dirty_files: List of files to be written
  * @sc_gc_inodes: List of GC inodes having blocks to be written
- * @sc_cleaning_segments: List of segments to be freed through construction
  * @sc_copied_buffers: List of copied buffers (buffer heads) to freeze data
+ * @sc_freesegs: array of segment numbers to be freed
+ * @sc_nfreesegs: number of segments on @sc_freesegs
  * @sc_dsync_inode: inode whose data pages are written for a sync operation
  * @sc_dsync_start: start byte offset of data pages
  * @sc_dsync_end: end byte offset of data pages (inclusive)
@@ -131,9 +132,11 @@ struct nilfs_sc_info {
 
        struct list_head        sc_dirty_files;
        struct list_head        sc_gc_inodes;
-       struct list_head        sc_cleaning_segments;
        struct list_head        sc_copied_buffers;
 
+       __u64                  *sc_freesegs;
+       size_t                  sc_nfreesegs;
+
        struct nilfs_inode_info *sc_dsync_inode;
        loff_t                  sc_dsync_start;
        loff_t                  sc_dsync_end;
@@ -225,10 +228,6 @@ extern void nilfs_flush_segment(struct super_block *, ino_t);
 extern int nilfs_clean_segments(struct super_block *, struct nilfs_argv *,
                                void **);
 
-extern int nilfs_segctor_add_segments_to_be_freed(struct nilfs_sc_info *,
-                                                 __u64 *, size_t);
-extern void nilfs_segctor_clear_segments_to_be_freed(struct nilfs_sc_info *);
-
 extern int nilfs_attach_segment_constructor(struct nilfs_sb_info *);
 extern void nilfs_detach_segment_constructor(struct nilfs_sb_info *);
 
@@ -240,5 +239,6 @@ extern int nilfs_search_super_root(struct the_nilfs *, struct nilfs_sb_info *,
 extern int nilfs_recover_logical_segments(struct the_nilfs *,
                                          struct nilfs_sb_info *,
                                          struct nilfs_recovery_info *);
+extern void nilfs_dispose_segment_list(struct list_head *);
 
 #endif /* _NILFS_SEGMENT_H */
index 98e6867..37994d4 100644 (file)
@@ -18,6 +18,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  * Written by Koji Sato <koji@osrg.net>.
+ * Rivised by Ryusuke Konishi <ryusuke@osrg.net>.
  */
 
 #include <linux/kernel.h>
@@ -108,6 +109,102 @@ static void nilfs_sufile_mod_counter(struct buffer_head *header_bh,
        nilfs_mdt_mark_buffer_dirty(header_bh);
 }
 
+/**
+ * nilfs_sufile_updatev - modify multiple segment usages at a time
+ * @sufile: inode of segment usage file
+ * @segnumv: array of segment numbers
+ * @nsegs: size of @segnumv array
+ * @create: creation flag
+ * @ndone: place to store number of modified segments on @segnumv
+ * @dofunc: primitive operation for the update
+ *
+ * Description: nilfs_sufile_updatev() repeatedly calls @dofunc
+ * against the given array of segments.  The @dofunc is called with
+ * buffers of a header block and the sufile block in which the target
+ * segment usage entry is contained.  If @ndone is given, the number
+ * of successfully modified segments from the head is stored in the
+ * place @ndone points to.
+ *
+ * Return Value: On success, zero is returned.  On error, one of the
+ * following negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-ENOENT - Given segment usage is in hole block (may be returned if
+ *            @create is zero)
+ *
+ * %-EINVAL - Invalid segment usage number
+ */
+int nilfs_sufile_updatev(struct inode *sufile, __u64 *segnumv, size_t nsegs,
+                        int create, size_t *ndone,
+                        void (*dofunc)(struct inode *, __u64,
+                                       struct buffer_head *,
+                                       struct buffer_head *))
+{
+       struct buffer_head *header_bh, *bh;
+       unsigned long blkoff, prev_blkoff;
+       __u64 *seg;
+       size_t nerr = 0, n = 0;
+       int ret = 0;
+
+       if (unlikely(nsegs == 0))
+               goto out;
+
+       down_write(&NILFS_MDT(sufile)->mi_sem);
+       for (seg = segnumv; seg < segnumv + nsegs; seg++) {
+               if (unlikely(*seg >= nilfs_sufile_get_nsegments(sufile))) {
+                       printk(KERN_WARNING
+                              "%s: invalid segment number: %llu\n", __func__,
+                              (unsigned long long)*seg);
+                       nerr++;
+               }
+       }
+       if (nerr > 0) {
+               ret = -EINVAL;
+               goto out_sem;
+       }
+
+       ret = nilfs_sufile_get_header_block(sufile, &header_bh);
+       if (ret < 0)
+               goto out_sem;
+
+       seg = segnumv;
+       blkoff = nilfs_sufile_get_blkoff(sufile, *seg);
+       ret = nilfs_mdt_get_block(sufile, blkoff, create, NULL, &bh);
+       if (ret < 0)
+               goto out_header;
+
+       for (;;) {
+               dofunc(sufile, *seg, header_bh, bh);
+
+               if (++seg >= segnumv + nsegs)
+                       break;
+               prev_blkoff = blkoff;
+               blkoff = nilfs_sufile_get_blkoff(sufile, *seg);
+               if (blkoff == prev_blkoff)
+                       continue;
+
+               /* get different block */
+               brelse(bh);
+               ret = nilfs_mdt_get_block(sufile, blkoff, create, NULL, &bh);
+               if (unlikely(ret < 0))
+                       goto out_header;
+       }
+       brelse(bh);
+
+ out_header:
+       n = seg - segnumv;
+       brelse(header_bh);
+ out_sem:
+       up_write(&NILFS_MDT(sufile)->mi_sem);
+ out:
+       if (ndone)
+               *ndone = n;
+       return ret;
+}
+
 int nilfs_sufile_update(struct inode *sufile, __u64 segnum, int create,
                        void (*dofunc)(struct inode *, __u64,
                                       struct buffer_head *,
@@ -490,7 +587,8 @@ void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum,
  * nilfs_sufile_get_suinfo -
  * @sufile: inode of segment usage file
  * @segnum: segment number to start looking
- * @si: array of suinfo
+ * @buf: array of suinfo
+ * @sisz: byte size of suinfo
  * @nsi: size of suinfo array
  *
  * Description:
@@ -502,11 +600,12 @@ void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum,
  *
  * %-ENOMEM - Insufficient amount of memory available.
  */
-ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum,
-                               struct nilfs_suinfo *si, size_t nsi)
+ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf,
+                               unsigned sisz, size_t nsi)
 {
        struct buffer_head *su_bh;
        struct nilfs_segment_usage *su;
+       struct nilfs_suinfo *si = buf;
        size_t susz = NILFS_MDT(sufile)->mi_entry_size;
        struct the_nilfs *nilfs = NILFS_MDT(sufile)->mi_nilfs;
        void *kaddr;
@@ -531,20 +630,22 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum,
                        if (ret != -ENOENT)
                                goto out;
                        /* hole */
-                       memset(&si[i], 0, sizeof(struct nilfs_suinfo) * n);
+                       memset(si, 0, sisz * n);
+                       si = (void *)si + sisz * n;
                        continue;
                }
 
                kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
                su = nilfs_sufile_block_get_segment_usage(
                        sufile, segnum, su_bh, kaddr);
-               for (j = 0; j < n; j++, su = (void *)su + susz) {
-                       si[i + j].sui_lastmod = le64_to_cpu(su->su_lastmod);
-                       si[i + j].sui_nblocks = le32_to_cpu(su->su_nblocks);
-                       si[i + j].sui_flags = le32_to_cpu(su->su_flags) &
+               for (j = 0; j < n;
+                    j++, su = (void *)su + susz, si = (void *)si + sisz) {
+                       si->sui_lastmod = le64_to_cpu(su->su_lastmod);
+                       si->sui_nblocks = le32_to_cpu(su->su_nblocks);
+                       si->sui_flags = le32_to_cpu(su->su_flags) &
                                ~(1UL << NILFS_SEGMENT_USAGE_ACTIVE);
                        if (nilfs_segment_is_active(nilfs, segnum + j))
-                               si[i + j].sui_flags |=
+                               si->sui_flags |=
                                        (1UL << NILFS_SEGMENT_USAGE_ACTIVE);
                }
                kunmap_atomic(kaddr, KM_USER0);
index a2e2efd..a2c4d76 100644 (file)
@@ -43,43 +43,27 @@ void nilfs_sufile_put_segment_usage(struct inode *, __u64,
                                    struct buffer_head *);
 int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *);
 int nilfs_sufile_get_ncleansegs(struct inode *, unsigned long *);
-ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, struct nilfs_suinfo *,
+ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned,
                                size_t);
 
+int nilfs_sufile_updatev(struct inode *, __u64 *, size_t, int, size_t *,
+                        void (*dofunc)(struct inode *, __u64,
+                                       struct buffer_head *,
+                                       struct buffer_head *));
 int nilfs_sufile_update(struct inode *, __u64, int,
                        void (*dofunc)(struct inode *, __u64,
                                       struct buffer_head *,
                                       struct buffer_head *));
-void nilfs_sufile_do_cancel_free(struct inode *, __u64, struct buffer_head *,
-                                struct buffer_head *);
 void nilfs_sufile_do_scrap(struct inode *, __u64, struct buffer_head *,
                           struct buffer_head *);
 void nilfs_sufile_do_free(struct inode *, __u64, struct buffer_head *,
                          struct buffer_head *);
+void nilfs_sufile_do_cancel_free(struct inode *, __u64, struct buffer_head *,
+                                struct buffer_head *);
 void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *,
                               struct buffer_head *);
 
 /**
- * nilfs_sufile_cancel_free -
- * @sufile: inode of segment usage file
- * @segnum: segment number
- *
- * Description:
- *
- * Return Value: On success, 0 is returned. On error, one of the following
- * negative error codes is returned.
- *
- * %-EIO - I/O error.
- *
- * %-ENOMEM - Insufficient amount of memory available.
- */
-static inline int nilfs_sufile_cancel_free(struct inode *sufile, __u64 segnum)
-{
-       return nilfs_sufile_update(sufile, segnum, 0,
-                                  nilfs_sufile_do_cancel_free);
-}
-
-/**
  * nilfs_sufile_scrap - make a segment garbage
  * @sufile: inode of segment usage file
  * @segnum: segment number to be freed
@@ -100,6 +84,38 @@ static inline int nilfs_sufile_free(struct inode *sufile, __u64 segnum)
 }
 
 /**
+ * nilfs_sufile_freev - free segments
+ * @sufile: inode of segment usage file
+ * @segnumv: array of segment numbers
+ * @nsegs: size of @segnumv array
+ * @ndone: place to store the number of freed segments
+ */
+static inline int nilfs_sufile_freev(struct inode *sufile, __u64 *segnumv,
+                                    size_t nsegs, size_t *ndone)
+{
+       return nilfs_sufile_updatev(sufile, segnumv, nsegs, 0, ndone,
+                                   nilfs_sufile_do_free);
+}
+
+/**
+ * nilfs_sufile_cancel_freev - reallocate freeing segments
+ * @sufile: inode of segment usage file
+ * @segnumv: array of segment numbers
+ * @nsegs: size of @segnumv array
+ * @ndone: place to store the number of cancelled segments
+ *
+ * Return Value: On success, 0 is returned. On error, a negative error codes
+ * is returned.
+ */
+static inline int nilfs_sufile_cancel_freev(struct inode *sufile,
+                                           __u64 *segnumv, size_t nsegs,
+                                           size_t *ndone)
+{
+       return nilfs_sufile_updatev(sufile, segnumv, nsegs, 0, ndone,
+                                   nilfs_sufile_do_cancel_free);
+}
+
+/**
  * nilfs_sufile_set_error - mark a segment as erroneous
  * @sufile: inode of segment usage file
  * @segnum: segment number
index 1777a34..ab785f8 100644 (file)
@@ -133,7 +133,7 @@ void nilfs_warning(struct super_block *sb, const char *function,
 
 static struct kmem_cache *nilfs_inode_cachep;
 
-struct inode *nilfs_alloc_inode(struct super_block *sb)
+struct inode *nilfs_alloc_inode_common(struct the_nilfs *nilfs)
 {
        struct nilfs_inode_info *ii;
 
@@ -143,10 +143,15 @@ struct inode *nilfs_alloc_inode(struct super_block *sb)
        ii->i_bh = NULL;
        ii->i_state = 0;
        ii->vfs_inode.i_version = 1;
-       nilfs_btnode_cache_init(&ii->i_btnode_cache);
+       nilfs_btnode_cache_init(&ii->i_btnode_cache, nilfs->ns_bdi);
        return &ii->vfs_inode;
 }
 
+struct inode *nilfs_alloc_inode(struct super_block *sb)
+{
+       return nilfs_alloc_inode_common(NILFS_SB(sb)->s_nilfs);
+}
+
 void nilfs_destroy_inode(struct inode *inode)
 {
        kmem_cache_free(nilfs_inode_cachep, NILFS_I(inode));
index e4e5c78..8b88898 100644 (file)
@@ -32,7 +32,6 @@
 #include "cpfile.h"
 #include "sufile.h"
 #include "dat.h"
-#include "seglist.h"
 #include "segbuf.h"
 
 
index 3a6b193..0ff7566 100644 (file)
@@ -202,9 +202,12 @@ static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts)
                                return -EINVAL;
                        opts->mode = option & S_IALLUGO;
                        break;
-               default:
-                       printk(KERN_ERR "ramfs: bad mount option: %s\n", p);
-                       return -EINVAL;
+               /*
+                * We might like to report bad mount options here;
+                * but traditionally ramfs has ignored all mount options,
+                * and as it is used as a !CONFIG_SHMEM simple substitute
+                * for tmpfs, better continue to ignore other mount options.
+                */
                }
        }
 
index 3435c1f..aa01d38 100644 (file)
 #define PCI_DEVICE_ID_MPC8547E         0x0018
 #define PCI_DEVICE_ID_MPC8545E         0x0019
 #define PCI_DEVICE_ID_MPC8545          0x001a
+#define PCI_DEVICE_ID_MPC8569E         0x0061
+#define PCI_DEVICE_ID_MPC8569          0x0060
 #define PCI_DEVICE_ID_MPC8568E         0x0020
 #define PCI_DEVICE_ID_MPC8568          0x0021
 #define PCI_DEVICE_ID_MPC8567E         0x0022
 #define PCI_DEVICE_ID_MPC8572          0x0041
 #define PCI_DEVICE_ID_MPC8536E         0x0050
 #define PCI_DEVICE_ID_MPC8536          0x0051
+#define PCI_DEVICE_ID_P2020E           0x0070
+#define PCI_DEVICE_ID_P2020            0x0071
 #define PCI_DEVICE_ID_MPC8641          0x7010
 #define PCI_DEVICE_ID_MPC8641D         0x7011
 #define PCI_DEVICE_ID_MPC8610          0x7018
diff --git a/include/linux/regulator/lp3971.h b/include/linux/regulator/lp3971.h
new file mode 100644 (file)
index 0000000..6140164
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * National Semiconductors LP3971 PMIC chip client interface
+ *
+ *  Copyright (C) 2009 Samsung Electronics
+ *  Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * Based on wm8400.h
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __LINUX_REGULATOR_LP3971_H
+#define __LINUX_REGULATOR_LP3971_H
+
+#include <linux/regulator/machine.h>
+
+#define LP3971_LDO1  0
+#define LP3971_LDO2  1
+#define LP3971_LDO3  2
+#define LP3971_LDO4  3
+#define LP3971_LDO5  4
+
+#define LP3971_DCDC1 5
+#define LP3971_DCDC2 6
+#define LP3971_DCDC3 7
+
+#define LP3971_NUM_REGULATORS 8
+
+struct lp3971_regulator_subdev {
+       int id;
+       struct regulator_init_data *initdata;
+};
+
+struct lp3971_platform_data {
+       int num_regulators;
+       struct lp3971_regulator_subdev *regulators;
+};
+
+#endif
diff --git a/include/linux/regulator/max1586.h b/include/linux/regulator/max1586.h
new file mode 100644 (file)
index 0000000..4456319
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * max1586.h  --  Voltage regulation for the Maxim 1586
+ *
+ * Copyright (C) 2008 Robert Jarzmik
+ *
+ * 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
+ */
+
+#ifndef REGULATOR_MAX1586
+#define REGULATOR_MAX1586
+
+#include <linux/regulator/machine.h>
+
+#define MAX1586_V3 0
+#define MAX1586_V6 1
+
+/* precalculated values for v3_gain */
+#define MAX1586_GAIN_NO_R24   1000000  /* 700000 .. 1475000 mV */
+#define MAX1586_GAIN_R24_3k32 1051098  /* 735768 .. 1550369 mV */
+#define MAX1586_GAIN_R24_5k11 1078648  /* 755053 .. 1591005 mV */
+#define MAX1586_GAIN_R24_7k5  1115432  /* 780802 .. 1645262 mV */
+
+/**
+ * max1586_subdev_data - regulator data
+ * @id: regulator Id (either MAX1586_V3 or MAX1586_V6)
+ * @name: regulator cute name (example for V3: "vcc_core")
+ * @platform_data: regulator init data (contraints, supplies, ...)
+ */
+struct max1586_subdev_data {
+       int                             id;
+       char                            *name;
+       struct regulator_init_data      *platform_data;
+};
+
+/**
+ * max1586_platform_data - platform data for max1586
+ * @num_subdevs: number of regultors used (may be 1 or 2)
+ * @subdevs: regulator used
+ *           At most, there will be a regulator for V3 and one for V6 voltages.
+ * @v3_gain: gain on the V3 voltage output multiplied by 1e6.
+ *           This can be calculated as ((1 + R24/R25 + R24/185.5kOhm) * 1e6)
+ *           for an external resistor configuration as described in the
+ *           data sheet (R25=100kOhm).
+ */
+struct max1586_platform_data {
+       int num_subdevs;
+       struct max1586_subdev_data *subdevs;
+       int v3_gain;
+};
+
+#endif
diff --git a/include/linux/regulator/userspace-consumer.h b/include/linux/regulator/userspace-consumer.h
new file mode 100644 (file)
index 0000000..b4554ce
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __REGULATOR_PLATFORM_CONSUMER_H_
+#define __REGULATOR_PLATFORM_CONSUMER_H_
+
+struct regulator_consumer_supply;
+
+/**
+ * struct regulator_userspace_consumer_data - line consumer
+ * initialisation data.
+ *
+ * @name: Name for the consumer line
+ * @num_supplies: Number of supplies feeding the line
+ * @supplies: Supplies configuration.
+ * @init_on: Set if the regulators supplying the line should be
+ *           enabled during initialisation
+ */
+struct regulator_userspace_consumer_data {
+       const char *name;
+
+       int num_supplies;
+       struct regulator_bulk_data *supplies;
+
+       bool init_on;
+};
+
+#endif /* __REGULATOR_PLATFORM_CONSUMER_H_ */