aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/powerpc/booting-without-of.txt32
-rw-r--r--arch/powerpc/Kconfig3
-rw-r--r--arch/powerpc/Kconfig.debug7
-rw-r--r--arch/powerpc/Makefile3
-rw-r--r--arch/powerpc/boot/4xx.c2
-rw-r--r--arch/powerpc/boot/Makefile95
-rw-r--r--arch/powerpc/boot/bamboo.c2
-rw-r--r--arch/powerpc/boot/cuboot-52xx.c2
-rw-r--r--arch/powerpc/boot/cuboot-83xx.c2
-rw-r--r--arch/powerpc/boot/cuboot-85xx.c2
-rw-r--r--arch/powerpc/boot/cuboot-8xx.c2
-rw-r--r--arch/powerpc/boot/cuboot-hpc2.c2
-rw-r--r--arch/powerpc/boot/cuboot-pq2.c2
-rw-r--r--arch/powerpc/boot/cuboot-sequoia.c2
-rw-r--r--arch/powerpc/boot/dtc-src/Makefile.dtc25
-rw-r--r--arch/powerpc/boot/dtc-src/checks.c750
-rw-r--r--arch/powerpc/boot/dtc-src/data.c321
-rw-r--r--arch/powerpc/boot/dtc-src/dtc-lexer.l328
-rw-r--r--arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped2174
-rw-r--r--arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped1983
-rw-r--r--arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped111
-rw-r--r--arch/powerpc/boot/dtc-src/dtc-parser.y336
-rw-r--r--arch/powerpc/boot/dtc-src/dtc.c231
-rw-r--r--arch/powerpc/boot/dtc-src/dtc.h269
-rw-r--r--arch/powerpc/boot/dtc-src/flattree.c968
-rw-r--r--arch/powerpc/boot/dtc-src/fstree.c94
-rw-r--r--arch/powerpc/boot/dtc-src/livetree.c305
-rw-r--r--arch/powerpc/boot/dtc-src/srcpos.c105
-rw-r--r--arch/powerpc/boot/dtc-src/srcpos.h75
-rw-r--r--arch/powerpc/boot/dtc-src/treesource.c275
-rw-r--r--arch/powerpc/boot/dtc-src/version_gen.h1
-rw-r--r--arch/powerpc/boot/dts/kuroboxHD.dts16
-rw-r--r--arch/powerpc/boot/dts/kuroboxHG.dts16
-rw-r--r--arch/powerpc/boot/dts/lite5200.dts6
-rw-r--r--arch/powerpc/boot/dts/lite5200b.dts6
-rw-r--r--arch/powerpc/boot/dts/mpc8313erdb.dts36
-rw-r--r--arch/powerpc/boot/dts/mpc832x_mds.dts45
-rw-r--r--arch/powerpc/boot/dts/mpc832x_rdb.dts47
-rw-r--r--arch/powerpc/boot/dts/mpc8349emitx.dts54
-rw-r--r--arch/powerpc/boot/dts/mpc8349emitxgp.dts32
-rw-r--r--arch/powerpc/boot/dts/mpc834x_mds.dts51
-rw-r--r--arch/powerpc/boot/dts/mpc836x_mds.dts47
-rw-r--r--arch/powerpc/boot/dts/mpc8540ads.dts59
-rw-r--r--arch/powerpc/boot/dts/mpc8541cds.dts41
-rw-r--r--arch/powerpc/boot/dts/mpc8544ds.dts59
-rw-r--r--arch/powerpc/boot/dts/mpc8548cds.dts68
-rw-r--r--arch/powerpc/boot/dts/mpc8555cds.dts41
-rw-r--r--arch/powerpc/boot/dts/mpc8560ads.dts59
-rw-r--r--arch/powerpc/boot/dts/mpc8568mds.dts80
-rw-r--r--arch/powerpc/boot/dts/mpc8572ds.dts59
-rw-r--r--arch/powerpc/boot/dts/mpc8610_hpcd.dts28
-rw-r--r--arch/powerpc/boot/dts/mpc8641_hpcn.dts80
-rw-r--r--arch/powerpc/boot/dts/mpc866ads.dts156
-rw-r--r--arch/powerpc/boot/ebony.c2
-rw-r--r--arch/powerpc/boot/ep88xc.c2
-rw-r--r--arch/powerpc/boot/flatdevtree.c1036
-rw-r--r--arch/powerpc/boot/flatdevtree.h113
-rw-r--r--arch/powerpc/boot/flatdevtree_misc.c79
-rw-r--r--arch/powerpc/boot/holly.c2
-rw-r--r--arch/powerpc/boot/libfdt-wrapper.c184
-rw-r--r--arch/powerpc/boot/libfdt/Makefile.libfdt14
-rw-r--r--arch/powerpc/boot/libfdt/fdt.c156
-rw-r--r--arch/powerpc/boot/libfdt/fdt.h60
-rw-r--r--arch/powerpc/boot/libfdt/fdt_ro.c583
-rw-r--r--arch/powerpc/boot/libfdt/fdt_rw.c447
-rw-r--r--arch/powerpc/boot/libfdt/fdt_strerror.c96
-rw-r--r--arch/powerpc/boot/libfdt/fdt_sw.c258
-rw-r--r--arch/powerpc/boot/libfdt/fdt_wip.c144
-rw-r--r--arch/powerpc/boot/libfdt/libfdt.h721
-rw-r--r--arch/powerpc/boot/libfdt/libfdt_internal.h89
-rw-r--r--arch/powerpc/boot/libfdt_env.h17
-rw-r--r--arch/powerpc/boot/main.c1
-rw-r--r--arch/powerpc/boot/ops.h2
-rw-r--r--arch/powerpc/boot/prpmc2800.c3
-rw-r--r--arch/powerpc/boot/ps3.c2
-rw-r--r--arch/powerpc/boot/treeboot-walnut.c2
-rwxr-xr-xarch/powerpc/boot/wrapper19
-rw-r--r--arch/powerpc/configs/celleb_defconfig38
-rw-r--r--arch/powerpc/configs/mpc837x_mds_defconfig878
-rw-r--r--arch/powerpc/configs/ppc64_defconfig8
-rw-r--r--arch/powerpc/kernel/Makefile2
-rw-r--r--arch/powerpc/kernel/cputable.c13
-rw-r--r--arch/powerpc/kernel/ibmebus.c2
-rw-r--r--arch/powerpc/kernel/iommu.c8
-rw-r--r--arch/powerpc/kernel/isa-bridge.c6
-rw-r--r--arch/powerpc/kernel/legacy_serial.c2
-rw-r--r--arch/powerpc/kernel/lparcfg.c12
-rw-r--r--arch/powerpc/kernel/misc.S8
-rw-r--r--arch/powerpc/kernel/misc_32.S7
-rw-r--r--arch/powerpc/kernel/misc_64.S7
-rw-r--r--arch/powerpc/kernel/module_32.c77
-rw-r--r--arch/powerpc/kernel/module_64.c81
-rw-r--r--arch/powerpc/kernel/of_platform.c28
-rw-r--r--arch/powerpc/kernel/pci-common.c779
-rw-r--r--arch/powerpc/kernel/pci_32.c891
-rw-r--r--arch/powerpc/kernel/pci_64.c439
-rw-r--r--arch/powerpc/kernel/pci_dn.c2
-rw-r--r--arch/powerpc/kernel/prom.c15
-rw-r--r--arch/powerpc/kernel/prom_parse.c22
-rw-r--r--arch/powerpc/kernel/rtas_pci.c8
-rw-r--r--arch/powerpc/kernel/setup-common.c78
-rw-r--r--arch/powerpc/kernel/signal_32.c3
-rw-r--r--arch/powerpc/kernel/time.c91
-rw-r--r--arch/powerpc/kernel/traps.c25
-rw-r--r--arch/powerpc/kernel/udbg.c4
-rw-r--r--arch/powerpc/kernel/udbg_16550.c10
-rw-r--r--arch/powerpc/mm/fault.c2
-rw-r--r--arch/powerpc/mm/hash_utils_64.c1
-rw-r--r--arch/powerpc/mm/numa.c59
-rw-r--r--arch/powerpc/mm/slb.c3
-rw-r--r--arch/powerpc/mm/slb_low.S5
-rw-r--r--arch/powerpc/oprofile/op_model_cell.c20
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pci.c2
-rw-r--r--arch/powerpc/platforms/82xx/pq2.c4
-rw-r--r--arch/powerpc/platforms/82xx/pq2fads.c2
-rw-r--r--arch/powerpc/platforms/83xx/Kconfig11
-rw-r--r--arch/powerpc/platforms/83xx/Makefile1
-rw-r--r--arch/powerpc/platforms/83xx/mpc8313_rdb.c4
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_mds.c4
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_rdb.c2
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_mds.c21
-rw-r--r--arch/powerpc/platforms/83xx/mpc836x_mds.c4
-rw-r--r--arch/powerpc/platforms/83xx/mpc837x_mds.c104
-rw-r--r--arch/powerpc/platforms/83xx/pci.c2
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ds.c2
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c4
-rw-r--r--arch/powerpc/platforms/86xx/mpc8610_hpcd.c2
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c2
-rw-r--r--arch/powerpc/platforms/8xx/Kconfig1
-rw-r--r--arch/powerpc/platforms/8xx/m8xx_setup.c2
-rw-r--r--arch/powerpc/platforms/8xx/mpc86xads.h44
-rw-r--r--arch/powerpc/platforms/8xx/mpc86xads_setup.c289
-rw-r--r--arch/powerpc/platforms/cell/Makefile2
-rw-r--r--arch/powerpc/platforms/cell/cbe_cpufreq.c3
-rw-r--r--arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c3
-rw-r--r--arch/powerpc/platforms/cell/cbe_regs.c5
-rw-r--r--arch/powerpc/platforms/cell/io-workarounds.c4
-rw-r--r--arch/powerpc/platforms/cell/iommu.c6
-rw-r--r--arch/powerpc/platforms/cell/pmu.c2
-rw-r--r--arch/powerpc/platforms/cell/setup.c2
-rw-r--r--arch/powerpc/platforms/cell/smp.c3
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c224
-rw-r--r--arch/powerpc/platforms/cell/spu_fault.c98
-rw-r--r--arch/powerpc/platforms/cell/spu_manage.c28
-rw-r--r--arch/powerpc/platforms/cell/spufs/Makefile2
-rw-r--r--arch/powerpc/platforms/cell/spufs/backing_ops.c31
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c53
-rw-r--r--arch/powerpc/platforms/cell/spufs/coredump.c8
-rw-r--r--arch/powerpc/platforms/cell/spufs/fault.c187
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c429
-rw-r--r--arch/powerpc/platforms/cell/spufs/hw_ops.c33
-rw-r--r--arch/powerpc/platforms/cell/spufs/lscsa_alloc.c4
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c190
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c361
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h64
-rw-r--r--arch/powerpc/platforms/cell/spufs/switch.c73
-rw-r--r--arch/powerpc/platforms/celleb/Kconfig2
-rw-r--r--arch/powerpc/platforms/celleb/io-workarounds.c6
-rw-r--r--arch/powerpc/platforms/celleb/iommu.c5
-rw-r--r--arch/powerpc/platforms/celleb/pci.c13
-rw-r--r--arch/powerpc/platforms/celleb/scc_epci.c2
-rw-r--r--arch/powerpc/platforms/celleb/scc_uhc.c3
-rw-r--r--arch/powerpc/platforms/celleb/setup.c150
-rw-r--r--arch/powerpc/platforms/chrp/pci.c2
-rw-r--r--arch/powerpc/platforms/chrp/setup.c13
-rw-r--r--arch/powerpc/platforms/embedded6xx/holly.c3
-rw-r--r--arch/powerpc/platforms/iseries/Makefile2
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c4
-rw-r--r--arch/powerpc/platforms/iseries/lpevents.c2
-rw-r--r--arch/powerpc/platforms/iseries/pci.c665
-rw-r--r--arch/powerpc/platforms/iseries/pci.h27
-rw-r--r--arch/powerpc/platforms/iseries/setup.c61
-rw-r--r--arch/powerpc/platforms/iseries/setup.h1
-rw-r--r--arch/powerpc/platforms/iseries/vpdinfo.c275
-rw-r--r--arch/powerpc/platforms/maple/Kconfig1
-rw-r--r--arch/powerpc/platforms/maple/pci.c2
-rw-r--r--arch/powerpc/platforms/pasemi/Kconfig3
-rw-r--r--arch/powerpc/platforms/pasemi/cpufreq.c19
-rw-r--r--arch/powerpc/platforms/pasemi/gpio_mdio.c96
-rw-r--r--arch/powerpc/platforms/pasemi/pasemi.h6
-rw-r--r--arch/powerpc/platforms/pasemi/powersave.S11
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c23
-rw-r--r--arch/powerpc/platforms/powermac/pci.c248
-rw-r--r--arch/powerpc/platforms/powermac/pmac.h2
-rw-r--r--arch/powerpc/platforms/powermac/setup.c9
-rw-r--r--arch/powerpc/platforms/powermac/time.c2
-rw-r--r--arch/powerpc/platforms/ps3/spu.c27
-rw-r--r--arch/powerpc/platforms/pseries/eeh.c3
-rw-r--r--arch/powerpc/platforms/pseries/eeh_driver.c19
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c28
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c14
-rw-r--r--arch/powerpc/platforms/pseries/plpar_wrappers.h5
-rw-r--r--arch/powerpc/platforms/pseries/smp.c3
-rw-r--r--arch/powerpc/platforms/pseries/xics.c59
-rw-r--r--arch/powerpc/platforms/pseries/xics.h3
-rw-r--r--arch/powerpc/sysdev/Makefile2
-rw-r--r--arch/powerpc/sysdev/axonram.c5
-rw-r--r--arch/powerpc/sysdev/bestcomm/bestcomm.h2
-rw-r--r--arch/powerpc/sysdev/commproc.c47
-rw-r--r--arch/powerpc/sysdev/cpm2_common.c25
-rw-r--r--arch/powerpc/sysdev/fsl_pci.c4
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c23
-rw-r--r--arch/powerpc/sysdev/grackle.c2
-rw-r--r--arch/powerpc/sysdev/ipic.c219
-rw-r--r--arch/powerpc/sysdev/ipic.h13
-rw-r--r--arch/powerpc/sysdev/mmio_nvram.c2
-rw-r--r--arch/powerpc/sysdev/mpic.c35
-rw-r--r--arch/powerpc/sysdev/mpic.h7
-rw-r--r--arch/powerpc/sysdev/mpic_pasemi_msi.c172
-rw-r--r--arch/powerpc/sysdev/pmi.c4
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe.c46
-rw-r--r--arch/powerpc/xmon/xmon.c69
-rw-r--r--arch/ppc/kernel/setup.c1
-rw-r--r--arch/ppc/platforms/85xx/stx_gp3.c1
-rw-r--r--arch/ppc/platforms/ev64260.c4
-rw-r--r--arch/ppc/platforms/prep_pci.c1
-rw-r--r--arch/ppc/syslib/gt64260_pic.c1
-rw-r--r--arch/ppc/syslib/mpc52xx_pic.c1
-rw-r--r--arch/ppc/syslib/mv64360_pic.c1
-rw-r--r--arch/ppc/syslib/ocp.c2
-rw-r--r--arch/ppc/syslib/ppc83xx_setup.c1
-rw-r--r--arch/ppc/syslib/ppc8xx_pic.c2
-rw-r--r--arch/ppc/syslib/ppc_sys.c2
-rw-r--r--arch/ppc/xmon/start.c1
-rw-r--r--drivers/char/hw_random/Kconfig2
-rw-r--r--drivers/char/hw_random/pasemi-rng.c7
-rw-r--r--drivers/edac/pasemi_edac.c4
-rw-r--r--drivers/macintosh/adb.c174
-rw-r--r--drivers/macintosh/mediabay.c14
-rw-r--r--drivers/macintosh/therm_pm72.c9
-rw-r--r--drivers/macintosh/therm_windtunnel.c34
-rw-r--r--drivers/macintosh/via-pmu-backlight.c48
-rw-r--r--drivers/macintosh/via-pmu.c664
-rw-r--r--drivers/net/fs_enet/mac-fcc.c10
-rw-r--r--drivers/net/fs_enet/mac-scc.c11
-rw-r--r--drivers/net/ucc_geth.c55
-rw-r--r--drivers/pci/hotplug/rpadlpar_core.c2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm1.c6
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c8
-rw-r--r--include/asm-powerpc/8xx_immap.h2
-rw-r--r--include/asm-powerpc/commproc.h2
-rw-r--r--include/asm-powerpc/cpm.h1
-rw-r--r--include/asm-powerpc/cputhreads.h71
-rw-r--r--include/asm-powerpc/dma-mapping.h3
-rw-r--r--include/asm-powerpc/firmware.h2
-rw-r--r--include/asm-powerpc/immap_86xx.h25
-rw-r--r--include/asm-powerpc/io.h5
-rw-r--r--include/asm-powerpc/iommu.h3
-rw-r--r--include/asm-powerpc/ipic.h12
-rw-r--r--include/asm-powerpc/iseries/hv_lp_event.h2
-rw-r--r--include/asm-powerpc/machdep.h58
-rw-r--r--include/asm-powerpc/mmu-hash64.h1
-rw-r--r--include/asm-powerpc/nvram.h11
-rw-r--r--include/asm-powerpc/of_platform.h12
-rw-r--r--include/asm-powerpc/pci-bridge.h191
-rw-r--r--include/asm-powerpc/pci.h29
-rw-r--r--include/asm-powerpc/ppc-pci.h4
-rw-r--r--include/asm-powerpc/prom.h4
-rw-r--r--include/asm-powerpc/qe.h95
-rw-r--r--include/asm-powerpc/reg.h6
-rw-r--r--include/asm-powerpc/reg_booke.h15
-rw-r--r--include/asm-powerpc/smu.h142
-rw-r--r--include/asm-powerpc/spu.h28
-rw-r--r--include/asm-powerpc/spu_csa.h13
-rw-r--r--include/asm-powerpc/spu_priv1.h15
-rw-r--r--include/asm-ppc/8xx_immap.h2
-rw-r--r--include/asm-ppc/commproc.h2
-rw-r--r--include/asm-ppc/reg_booke.h2
-rw-r--r--include/linux/of.h4
-rw-r--r--include/linux/pmu.h36
270 files changed, 17883 insertions, 6060 deletions
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index e9a3cb1d6b06..ee0209a7de3e 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -711,13 +711,14 @@ define a bus type with a more complex address format, including things
711like address space bits, you'll have to add a bus translator to the 711like address space bits, you'll have to add a bus translator to the
712prom_parse.c file of the recent kernels for your bus type. 712prom_parse.c file of the recent kernels for your bus type.
713 713
714The "reg" property only defines addresses and sizes (if #size-cells 714The "reg" property only defines addresses and sizes (if #size-cells is
715is non-0) within a given bus. In order to translate addresses upward 715non-0) within a given bus. In order to translate addresses upward
716(that is into parent bus addresses, and possibly into CPU physical 716(that is into parent bus addresses, and possibly into CPU physical
717addresses), all busses must contain a "ranges" property. If the 717addresses), all busses must contain a "ranges" property. If the
718"ranges" property is missing at a given level, it's assumed that 718"ranges" property is missing at a given level, it's assumed that
719translation isn't possible. The format of the "ranges" property for a 719translation isn't possible, i.e., the registers are not visible on the
720bus is a list of: 720parent bus. The format of the "ranges" property for a bus is a list
721of:
721 722
722 bus address, parent bus address, size 723 bus address, parent bus address, size
723 724
@@ -735,6 +736,10 @@ fit in a single 32-bit word. New 32-bit powerpc boards should use a
7351/1 format, unless the processor supports physical addresses greater 7361/1 format, unless the processor supports physical addresses greater
736than 32-bits, in which case a 2/1 format is recommended. 737than 32-bits, in which case a 2/1 format is recommended.
737 738
739Alternatively, the "ranges" property may be empty, indicating that the
740registers are visible on the parent bus using an identity mapping
741translation. In other words, the parent bus address space is the same
742as the child bus address space.
738 743
7392) Note about "compatible" properties 7442) Note about "compatible" properties
740------------------------------------- 745-------------------------------------
@@ -1218,16 +1223,14 @@ platforms are moved over to use the flattened-device-tree model.
1218 1223
1219 Required properties: 1224 Required properties:
1220 - reg : Offset and length of the register set for the device 1225 - reg : Offset and length of the register set for the device
1221 - device_type : Should be "mdio"
1222 - compatible : Should define the compatible device type for the 1226 - compatible : Should define the compatible device type for the
1223 mdio. Currently, this is most likely to be "gianfar" 1227 mdio. Currently, this is most likely to be "fsl,gianfar-mdio"
1224 1228
1225 Example: 1229 Example:
1226 1230
1227 mdio@24520 { 1231 mdio@24520 {
1228 reg = <24520 20>; 1232 reg = <24520 20>;
1229 device_type = "mdio"; 1233 compatible = "fsl,gianfar-mdio";
1230 compatible = "gianfar";
1231 1234
1232 ethernet-phy@0 { 1235 ethernet-phy@0 {
1233 ...... 1236 ......
@@ -1626,6 +1629,19 @@ platforms are moved over to use the flattened-device-tree model.
1626 - interrupt-parent : the phandle for the interrupt controller that 1629 - interrupt-parent : the phandle for the interrupt controller that
1627 services interrupts for this device. 1630 services interrupts for this device.
1628 - pio-handle : The phandle for the Parallel I/O port configuration. 1631 - pio-handle : The phandle for the Parallel I/O port configuration.
1632 - rx-clock-name: the UCC receive clock source
1633 "none": clock source is disabled
1634 "brg1" through "brg16": clock source is BRG1-BRG16, respectively
1635 "clk1" through "clk24": clock source is CLK1-CLK24, respectively
1636 - tx-clock-name: the UCC transmit clock source
1637 "none": clock source is disabled
1638 "brg1" through "brg16": clock source is BRG1-BRG16, respectively
1639 "clk1" through "clk24": clock source is CLK1-CLK24, respectively
1640 The following two properties are deprecated. rx-clock has been replaced
1641 with rx-clock-name, and tx-clock has been replaced with tx-clock-name.
1642 Drivers that currently use the deprecated properties should continue to
1643 do so, in order to support older device trees, but they should be updated
1644 to check for the new properties first.
1629 - rx-clock : represents the UCC receive clock source. 1645 - rx-clock : represents the UCC receive clock source.
1630 0x00 : clock source is disabled; 1646 0x00 : clock source is disabled;
1631 0x1~0x10 : clock source is BRG1~BRG16 respectively; 1647 0x1~0x10 : clock source is BRG1~BRG16 respectively;
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 232c298c933f..d40844f9b047 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -160,6 +160,7 @@ config PPC_DCR
160 160
161config PPC_OF_PLATFORM_PCI 161config PPC_OF_PLATFORM_PCI
162 bool 162 bool
163 depends on PCI
163 depends on PPC64 # not supported on 32 bits yet 164 depends on PPC64 # not supported on 32 bits yet
164 default n 165 default n
165 166
@@ -417,7 +418,7 @@ endmenu
417 418
418config ISA_DMA_API 419config ISA_DMA_API
419 bool 420 bool
420 default y 421 default !PPC_ISERIES || PCI
421 422
422menu "Bus options" 423menu "Bus options"
423 424
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 6a79fe43e229..d20ccf5f2ca9 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -151,6 +151,13 @@ config BOOTX_TEXT
151 151
152config PPC_EARLY_DEBUG 152config PPC_EARLY_DEBUG
153 bool "Early debugging (dangerous)" 153 bool "Early debugging (dangerous)"
154 help
155 Say Y to enable some early debugging facilities that may be available
156 for your processor/board combination. Those facilities are hacks
157 intended to debug problems early during boot, this should not be
158 enabled in a production kernel.
159 Note that enabling this will also cause the kernel default log level
160 to be pushed to max automatically very early during boot
154 161
155choice 162choice
156 prompt "Early debugging console" 163 prompt "Early debugging console"
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile
index bd87626c1f60..f70df9b64f8f 100644
--- a/arch/powerpc/Makefile
+++ b/arch/powerpc/Makefile
@@ -167,6 +167,9 @@ boot := arch/$(ARCH)/boot
167$(BOOT_TARGETS): vmlinux 167$(BOOT_TARGETS): vmlinux
168 $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@) 168 $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
169 169
170bootwrapper_install:
171 $(Q)$(MAKE) ARCH=ppc64 $(build)=$(boot) $(patsubst %,$(boot)/%,$@)
172
170define archhelp 173define archhelp
171 @echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)' 174 @echo '* zImage - Compressed kernel image (arch/$(ARCH)/boot/zImage.*)'
172 @echo ' install - Install kernel using' 175 @echo ' install - Install kernel using'
diff --git a/arch/powerpc/boot/4xx.c b/arch/powerpc/boot/4xx.c
index ebf9e217612d..3d0e4f921f1d 100644
--- a/arch/powerpc/boot/4xx.c
+++ b/arch/powerpc/boot/4xx.c
@@ -122,7 +122,7 @@ void ibm4xx_denali_fixup_memsize(void)
122 else 122 else
123 dpath = 4; /* 32 bits */ 123 dpath = 4; /* 32 bits */
124 124
125 /* get adress pins (rows) */ 125 /* get address pins (rows) */
126 val = mfdcr_sdram0(DDR0_42); 126 val = mfdcr_sdram0(DDR0_42);
127 127
128 row = DDR_GET_VAL(val, DDR_APIN, DDR_APIN_SHIFT); 128 row = DDR_GET_VAL(val, DDR_APIN, DDR_APIN_SHIFT);
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 18e32719d0ed..9149bb8ed03c 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -33,7 +33,7 @@ ifeq ($(call cc-option-yn, -fstack-protector),y)
33BOOTCFLAGS += -fno-stack-protector 33BOOTCFLAGS += -fno-stack-protector
34endif 34endif
35 35
36BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) 36BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) -I$(srctree)/$(src)/libfdt
37 37
38$(obj)/4xx.o: BOOTCFLAGS += -mcpu=440 38$(obj)/4xx.o: BOOTCFLAGS += -mcpu=440
39$(obj)/ebony.o: BOOTCFLAGS += -mcpu=440 39$(obj)/ebony.o: BOOTCFLAGS += -mcpu=440
@@ -46,7 +46,9 @@ zliblinuxheader := zlib.h zconf.h zutil.h
46$(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \ 46$(addprefix $(obj)/,$(zlib) gunzip_util.o main.o): \
47 $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader)) 47 $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
48 48
49src-wlib := string.S crt0.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \ 49src-libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
50src-wlib := string.S crt0.S stdio.c main.c \
51 $(addprefix libfdt/,$(src-libfdt)) libfdt-wrapper.c \
50 ns16550.c serial.c simple_alloc.c div64.S util.S \ 52 ns16550.c serial.c simple_alloc.c div64.S util.S \
51 gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \ 53 gunzip_util.c elf_util.c $(zlib) devtree.c oflib.c ofconsole.c \
52 4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \ 54 4xx.c ebony.c mv64x60.c mpsc.c mv64x60_i2c.c cuboot.c bamboo.c \
@@ -101,24 +103,61 @@ quiet_cmd_bootar = BOOTAR $@
101 cmd_bootar = $(CROSS32AR) -cr $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@ 103 cmd_bootar = $(CROSS32AR) -cr $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@
102 104
103$(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c FORCE 105$(patsubst %.c,%.o, $(filter %.c, $(src-boot))): %.o: %.c FORCE
106 $(Q)mkdir -p $(dir $@)
104 $(call if_changed_dep,bootcc) 107 $(call if_changed_dep,bootcc)
105$(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S FORCE 108$(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S FORCE
109 $(Q)mkdir -p $(dir $@)
106 $(call if_changed_dep,bootas) 110 $(call if_changed_dep,bootas)
107 111
108$(obj)/wrapper.a: $(obj-wlib) FORCE 112$(obj)/wrapper.a: $(obj-wlib) FORCE
109 $(call if_changed,bootar) 113 $(call if_changed,bootar)
110 114
111hostprogs-y := addnote addRamDisk hack-coff mktree 115hostprogs-y := addnote addRamDisk hack-coff mktree dtc
112 116
113targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a) 117targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a)
114extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ 118extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
115 $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds 119 $(obj)/zImage.lds $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds
116 120
117wrapper :=$(srctree)/$(src)/wrapper 121wrapper :=$(srctree)/$(src)/wrapper
118wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree) \ 122wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree dtc) \
119 $(wrapper) FORCE 123 $(wrapper) FORCE
120 124
121############# 125#############
126# Bits for building dtc
127# DTC_GENPARSER := 1 # Uncomment to rebuild flex/bison output
128
129dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o srcpos.o checks.o
130dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o
131dtc-objs := $(addprefix dtc-src/, $(dtc-objs))
132
133# prerequisites on generated files needs to be explicit
134$(obj)/dtc-src/dtc-parser.tab.o: $(obj)/dtc-src/dtc-parser.tab.c $(obj)/dtc-src/dtc-parser.tab.h
135$(obj)/dtc-src/dtc-lexer.lex.o: $(obj)/dtc-src/dtc-lexer.lex.c $(obj)/dtc-src/dtc-parser.tab.h
136
137HOSTCFLAGS += -I$(src)/dtc-src/ -I$(src)/libfdt/
138
139targets += dtc-src/dtc-parser.tab.c
140targets += dtc-src/dtc-lexer.lex.c
141
142ifdef DTC_GENPARSER
143BISON = bison
144FLEX = flex
145
146quiet_cmd_bison = BISON $@
147 cmd_bison = $(BISON) -o$@ -d $<; cp $@ $@_shipped
148quiet_cmd_flex = FLEX $@
149 cmd_flex = $(FLEX) -o$@ $<; cp $@ $@_shipped
150
151$(obj)/dtc-src/dtc-parser.tab.c: $(src)/dtc-src/dtc-parser.y FORCE
152 $(call if_changed,bison)
153
154$(obj)/dtc-src/dtc-parser.tab.h: $(obj)/dtc-src/dtc-parser.tab.c
155
156$(obj)/dtc-src/dtc-lexer.lex.c: $(src)/dtc-src/dtc-lexer.l FORCE
157 $(call if_changed,flex)
158endif
159
160#############
122# Bits for building various flavours of zImage 161# Bits for building various flavours of zImage
123 162
124ifneq ($(CROSS32_COMPILE),) 163ifneq ($(CROSS32_COMPILE),)
@@ -243,3 +282,51 @@ clean-kernel := vmlinux.strip vmlinux.bin
243clean-kernel += $(addsuffix .gz,$(clean-kernel)) 282clean-kernel += $(addsuffix .gz,$(clean-kernel))
244# If not absolute clean-files are relative to $(obj). 283# If not absolute clean-files are relative to $(obj).
245clean-files += $(addprefix $(objtree)/, $(clean-kernel)) 284clean-files += $(addprefix $(objtree)/, $(clean-kernel))
285
286WRAPPER_OBJDIR := /usr/lib/kernel-wrapper
287WRAPPER_DTSDIR := /usr/lib/kernel-wrapper/dts
288WRAPPER_BINDIR := /usr/sbin
289INSTALL := install
290
291extra-installed := $(patsubst $(obj)/%, $(DESTDIR)$(WRAPPER_OBJDIR)/%, $(extra-y))
292hostprogs-installed := $(patsubst %, $(DESTDIR)$(WRAPPER_BINDIR)/%, $(hostprogs-y))
293wrapper-installed := $(DESTDIR)$(WRAPPER_BINDIR)/wrapper
294dts-installed := $(patsubst $(obj)/dts/%, $(DESTDIR)$(WRAPPER_DTSDIR)/%, $(wildcard $(obj)/dts/*.dts))
295
296all-installed := $(extra-installed) $(hostprogs-installed) $(wrapper-installed) $(dts-installed)
297
298quiet_cmd_mkdir = MKDIR $(patsubst $(INSTALL_HDR_PATH)/%,%,$@)
299 cmd_mkdir = mkdir -p $@
300
301quiet_cmd_install = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_OBJDIR)/%,%,$@)
302 cmd_install = $(INSTALL) -m0644 $(patsubst $(DESTDIR)$(WRAPPER_OBJDIR)/%,$(obj)/%,$@) $@
303
304quiet_cmd_install_dts = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_DTSDIR)/%,dts/%,$@)
305 cmd_install_dts = $(INSTALL) -m0644 $(patsubst $(DESTDIR)$(WRAPPER_DTSDIR)/%,$(srctree)/$(obj)/dts/%,$@) $@
306
307quiet_cmd_install_exe = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,%,$@)
308 cmd_install_exe = $(INSTALL) -m0755 $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,$(obj)/%,$@) $@
309
310quiet_cmd_install_wrapper = INSTALL $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,%,$@)
311 cmd_install_wrapper = $(INSTALL) -m0755 $(patsubst $(DESTDIR)$(WRAPPER_BINDIR)/%,$(srctree)/$(obj)/%,$@) $@ ;\
312 sed -i $@ -e 's%^object=.*%object=$(WRAPPER_OBJDIR)%' \
313 -e 's%^objbin=.*%objbin=$(WRAPPER_BINDIR)%' \
314
315
316$(DESTDIR)$(WRAPPER_OBJDIR) $(DESTDIR)$(WRAPPER_DTSDIR) $(DESTDIR)$(WRAPPER_BINDIR):
317 $(call cmd,mkdir)
318
319$(extra-installed) : $(DESTDIR)$(WRAPPER_OBJDIR)/% : $(obj)/% | $(DESTDIR)$(WRAPPER_OBJDIR)
320 $(call cmd,install)
321
322$(hostprogs-installed) : $(DESTDIR)$(WRAPPER_BINDIR)/% : $(obj)/% | $(DESTDIR)$(WRAPPER_BINDIR)
323 $(call cmd,install_exe)
324
325$(dts-installed) : $(DESTDIR)$(WRAPPER_DTSDIR)/% : $(srctree)/$(obj)/dts/% | $(DESTDIR)$(WRAPPER_DTSDIR)
326 $(call cmd,install_dts)
327
328$(wrapper-installed): $(DESTDIR)$(WRAPPER_BINDIR) $(srctree)/$(obj)/wrapper | $(DESTDIR)$(WRAPPER_BINDIR)
329 $(call cmd,install_wrapper)
330
331$(obj)/bootwrapper_install: $(all-installed)
332
diff --git a/arch/powerpc/boot/bamboo.c b/arch/powerpc/boot/bamboo.c
index f61fcdab1c7c..e634359d98e9 100644
--- a/arch/powerpc/boot/bamboo.c
+++ b/arch/powerpc/boot/bamboo.c
@@ -42,6 +42,6 @@ void bamboo_init(void *mac0, void *mac1)
42 platform_ops.exit = ibm44x_dbcr_reset; 42 platform_ops.exit = ibm44x_dbcr_reset;
43 bamboo_mac0 = mac0; 43 bamboo_mac0 = mac0;
44 bamboo_mac1 = mac1; 44 bamboo_mac1 = mac1;
45 ft_init(_dtb_start, 0, 32); 45 fdt_init(_dtb_start);
46 serial_console_init(); 46 serial_console_init();
47} 47}
diff --git a/arch/powerpc/boot/cuboot-52xx.c b/arch/powerpc/boot/cuboot-52xx.c
index 9256a26d40e4..a8611546a656 100644
--- a/arch/powerpc/boot/cuboot-52xx.c
+++ b/arch/powerpc/boot/cuboot-52xx.c
@@ -53,7 +53,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
53 unsigned long r6, unsigned long r7) 53 unsigned long r6, unsigned long r7)
54{ 54{
55 CUBOOT_INIT(); 55 CUBOOT_INIT();
56 ft_init(_dtb_start, _dtb_end - _dtb_start, 32); 56 fdt_init(_dtb_start);
57 serial_console_init(); 57 serial_console_init();
58 platform_ops.fixups = platform_fixups; 58 platform_ops.fixups = platform_fixups;
59} 59}
diff --git a/arch/powerpc/boot/cuboot-83xx.c b/arch/powerpc/boot/cuboot-83xx.c
index a0505509abcc..acd860ed7393 100644
--- a/arch/powerpc/boot/cuboot-83xx.c
+++ b/arch/powerpc/boot/cuboot-83xx.c
@@ -52,7 +52,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
52 unsigned long r6, unsigned long r7) 52 unsigned long r6, unsigned long r7)
53{ 53{
54 CUBOOT_INIT(); 54 CUBOOT_INIT();
55 ft_init(_dtb_start, _dtb_end - _dtb_start, 32); 55 fdt_init(_dtb_start);
56 serial_console_init(); 56 serial_console_init();
57 platform_ops.fixups = platform_fixups; 57 platform_ops.fixups = platform_fixups;
58} 58}
diff --git a/arch/powerpc/boot/cuboot-85xx.c b/arch/powerpc/boot/cuboot-85xx.c
index 345dcbecef0f..943779ed19be 100644
--- a/arch/powerpc/boot/cuboot-85xx.c
+++ b/arch/powerpc/boot/cuboot-85xx.c
@@ -53,7 +53,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
53 unsigned long r6, unsigned long r7) 53 unsigned long r6, unsigned long r7)
54{ 54{
55 CUBOOT_INIT(); 55 CUBOOT_INIT();
56 ft_init(_dtb_start, _dtb_end - _dtb_start, 32); 56 fdt_init(_dtb_start);
57 serial_console_init(); 57 serial_console_init();
58 platform_ops.fixups = platform_fixups; 58 platform_ops.fixups = platform_fixups;
59} 59}
diff --git a/arch/powerpc/boot/cuboot-8xx.c b/arch/powerpc/boot/cuboot-8xx.c
index 0e82015a5f95..c202c8868bd6 100644
--- a/arch/powerpc/boot/cuboot-8xx.c
+++ b/arch/powerpc/boot/cuboot-8xx.c
@@ -41,7 +41,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
41 unsigned long r6, unsigned long r7) 41 unsigned long r6, unsigned long r7)
42{ 42{
43 CUBOOT_INIT(); 43 CUBOOT_INIT();
44 ft_init(_dtb_start, _dtb_end - _dtb_start, 32); 44 fdt_init(_dtb_start);
45 serial_console_init(); 45 serial_console_init();
46 platform_ops.fixups = platform_fixups; 46 platform_ops.fixups = platform_fixups;
47} 47}
diff --git a/arch/powerpc/boot/cuboot-hpc2.c b/arch/powerpc/boot/cuboot-hpc2.c
index d333898bca30..1b8953259d75 100644
--- a/arch/powerpc/boot/cuboot-hpc2.c
+++ b/arch/powerpc/boot/cuboot-hpc2.c
@@ -42,7 +42,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
42 unsigned long r6, unsigned long r7) 42 unsigned long r6, unsigned long r7)
43{ 43{
44 CUBOOT_INIT(); 44 CUBOOT_INIT();
45 ft_init(_dtb_start, _dtb_end - _dtb_start, 32); 45 fdt_init(_dtb_start);
46 serial_console_init(); 46 serial_console_init();
47 platform_ops.fixups = platform_fixups; 47 platform_ops.fixups = platform_fixups;
48} 48}
diff --git a/arch/powerpc/boot/cuboot-pq2.c b/arch/powerpc/boot/cuboot-pq2.c
index 61574f3272dd..f56ac6cae9f3 100644
--- a/arch/powerpc/boot/cuboot-pq2.c
+++ b/arch/powerpc/boot/cuboot-pq2.c
@@ -255,7 +255,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
255 unsigned long r6, unsigned long r7) 255 unsigned long r6, unsigned long r7)
256{ 256{
257 CUBOOT_INIT(); 257 CUBOOT_INIT();
258 ft_init(_dtb_start, _dtb_end - _dtb_start, 32); 258 fdt_init(_dtb_start);
259 serial_console_init(); 259 serial_console_init();
260 platform_ops.fixups = pq2_platform_fixups; 260 platform_ops.fixups = pq2_platform_fixups;
261} 261}
diff --git a/arch/powerpc/boot/cuboot-sequoia.c b/arch/powerpc/boot/cuboot-sequoia.c
index ec635e0bd4ec..cf78260fcf3f 100644
--- a/arch/powerpc/boot/cuboot-sequoia.c
+++ b/arch/powerpc/boot/cuboot-sequoia.c
@@ -51,6 +51,6 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
51 CUBOOT_INIT(); 51 CUBOOT_INIT();
52 platform_ops.fixups = sequoia_fixups; 52 platform_ops.fixups = sequoia_fixups;
53 platform_ops.exit = ibm44x_dbcr_reset; 53 platform_ops.exit = ibm44x_dbcr_reset;
54 ft_init(_dtb_start, 0, 32); 54 fdt_init(_dtb_start);
55 serial_console_init(); 55 serial_console_init();
56} 56}
diff --git a/arch/powerpc/boot/dtc-src/Makefile.dtc b/arch/powerpc/boot/dtc-src/Makefile.dtc
new file mode 100644
index 000000000000..d607fdb8df8d
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/Makefile.dtc
@@ -0,0 +1,25 @@
1# Makefile.dtc
2#
3# This is not a complete Makefile of itself. Instead, it is designed to
4# be easily embeddable into other systems of Makefiles.
5#
6DTC_SRCS = dtc.c flattree.c fstree.c data.c livetree.c treesource.c srcpos.c \
7 checks.c
8DTC_EXTRA = dtc.h srcpos.h
9DTC_LEXFILES = dtc-lexer.l
10DTC_BISONFILES = dtc-parser.y
11
12DTC_LEX_SRCS = $(DTC_LEXFILES:%.l=%.lex.c)
13DTC_BISON_SRCS = $(DTC_BISONFILES:%.y=%.tab.c)
14DTC_BISON_INCLUDES = $(DTC_BISONFILES:%.y=%.tab.h)
15
16DTC_GEN_SRCS = $(DTC_LEX_SRCS) $(DTC_BISON_SRCS)
17DTC_GEN_ALL = $(DTC_GEN_SRCS) $(DTC_BISON_INCLUDES)
18DTC_OBJS = $(DTC_SRCS:%.c=%.o) $(DTC_GEN_SRCS:%.c=%.o)
19
20DTC_CLEANFILES = $(DTC_GEN_ALL)
21
22# We assume the containing Makefile system can do auto-dependencies for most
23# things, but we supply the dependencies on generated header files explicitly
24
25$(addprefix $(DTC_objdir)/,$(DTC_GEN_SRCS:%.c=%.o)): $(addprefix $(DTC_objdir)/,$(DTC_BISON_INCLUDES))
diff --git a/arch/powerpc/boot/dtc-src/checks.c b/arch/powerpc/boot/dtc-src/checks.c
new file mode 100644
index 000000000000..2ce961cd414d
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/checks.c
@@ -0,0 +1,750 @@
1/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2007.
3 *
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 */
20
21#include "dtc.h"
22
23#ifdef TRACE_CHECKS
24#define TRACE(c, ...) \
25 do { \
26 fprintf(stderr, "=== %s: ", (c)->name); \
27 fprintf(stderr, __VA_ARGS__); \
28 fprintf(stderr, "\n"); \
29 } while (0)
30#else
31#define TRACE(c, fmt, ...) do { } while (0)
32#endif
33
34enum checklevel {
35 IGNORE = 0,
36 WARN = 1,
37 ERROR = 2,
38};
39
40enum checkstatus {
41 UNCHECKED = 0,
42 PREREQ,
43 PASSED,
44 FAILED,
45};
46
47struct check;
48
49typedef void (*tree_check_fn)(struct check *c, struct node *dt);
50typedef void (*node_check_fn)(struct check *c, struct node *dt, struct node *node);
51typedef void (*prop_check_fn)(struct check *c, struct node *dt,
52 struct node *node, struct property *prop);
53
54struct check {
55 const char *name;
56 tree_check_fn tree_fn;
57 node_check_fn node_fn;
58 prop_check_fn prop_fn;
59 void *data;
60 enum checklevel level;
61 enum checkstatus status;
62 int inprogress;
63 int num_prereqs;
64 struct check **prereq;
65};
66
67#define CHECK(nm, tfn, nfn, pfn, d, lvl, ...) \
68 static struct check *nm##_prereqs[] = { __VA_ARGS__ }; \
69 static struct check nm = { \
70 .name = #nm, \
71 .tree_fn = (tfn), \
72 .node_fn = (nfn), \
73 .prop_fn = (pfn), \
74 .data = (d), \
75 .level = (lvl), \
76 .status = UNCHECKED, \
77 .num_prereqs = ARRAY_SIZE(nm##_prereqs), \
78 .prereq = nm##_prereqs, \
79 };
80
81#define TREE_CHECK(nm, d, lvl, ...) \
82 CHECK(nm, check_##nm, NULL, NULL, d, lvl, __VA_ARGS__)
83#define NODE_CHECK(nm, d, lvl, ...) \
84 CHECK(nm, NULL, check_##nm, NULL, d, lvl, __VA_ARGS__)
85#define PROP_CHECK(nm, d, lvl, ...) \
86 CHECK(nm, NULL, NULL, check_##nm, d, lvl, __VA_ARGS__)
87#define BATCH_CHECK(nm, lvl, ...) \
88 CHECK(nm, NULL, NULL, NULL, NULL, lvl, __VA_ARGS__)
89
90#ifdef __GNUC__
91static inline void check_msg(struct check *c, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
92#endif
93static inline void check_msg(struct check *c, const char *fmt, ...)
94{
95 va_list ap;
96 va_start(ap, fmt);
97
98 if ((c->level < WARN) || (c->level <= quiet))
99 return; /* Suppress message */
100
101 fprintf(stderr, "%s (%s): ",
102 (c->level == ERROR) ? "ERROR" : "Warning", c->name);
103 vfprintf(stderr, fmt, ap);
104 fprintf(stderr, "\n");
105}
106
107#define FAIL(c, ...) \
108 do { \
109 TRACE((c), "\t\tFAILED at %s:%d", __FILE__, __LINE__); \
110 (c)->status = FAILED; \
111 check_msg((c), __VA_ARGS__); \
112 } while (0)
113
114static void check_nodes_props(struct check *c, struct node *dt, struct node *node)
115{
116 struct node *child;
117 struct property *prop;
118
119 TRACE(c, "%s", node->fullpath);
120 if (c->node_fn)
121 c->node_fn(c, dt, node);
122
123 if (c->prop_fn)
124 for_each_property(node, prop) {
125 TRACE(c, "%s\t'%s'", node->fullpath, prop->name);
126 c->prop_fn(c, dt, node, prop);
127 }
128
129 for_each_child(node, child)
130 check_nodes_props(c, dt, child);
131}
132
133static int run_check(struct check *c, struct node *dt)
134{
135 int error = 0;
136 int i;
137
138 assert(!c->inprogress);
139
140 if (c->status != UNCHECKED)
141 goto out;
142
143 c->inprogress = 1;
144
145 for (i = 0; i < c->num_prereqs; i++) {
146 struct check *prq = c->prereq[i];
147 error |= run_check(prq, dt);
148 if (prq->status != PASSED) {
149 c->status = PREREQ;
150 check_msg(c, "Failed prerequisite '%s'",
151 c->prereq[i]->name);
152 }
153 }
154
155 if (c->status != UNCHECKED)
156 goto out;
157
158 if (c->node_fn || c->prop_fn)
159 check_nodes_props(c, dt, dt);
160
161 if (c->tree_fn)
162 c->tree_fn(c, dt);
163 if (c->status == UNCHECKED)
164 c->status = PASSED;
165
166 TRACE(c, "\tCompleted, status %d", c->status);
167
168out:
169 c->inprogress = 0;
170 if ((c->status != PASSED) && (c->level == ERROR))
171 error = 1;
172 return error;
173}
174
175/*
176 * Utility check functions
177 */
178
179static void check_is_string(struct check *c, struct node *root,
180 struct node *node)
181{
182 struct property *prop;
183 char *propname = c->data;
184
185 prop = get_property(node, propname);
186 if (!prop)
187 return; /* Not present, assumed ok */
188
189 if (!data_is_one_string(prop->val))
190 FAIL(c, "\"%s\" property in %s is not a string",
191 propname, node->fullpath);
192}
193#define CHECK_IS_STRING(nm, propname, lvl) \
194 CHECK(nm, NULL, check_is_string, NULL, (propname), (lvl))
195
196static void check_is_cell(struct check *c, struct node *root,
197 struct node *node)
198{
199 struct property *prop;
200 char *propname = c->data;
201
202 prop = get_property(node, propname);
203 if (!prop)
204 return; /* Not present, assumed ok */
205
206 if (prop->val.len != sizeof(cell_t))
207 FAIL(c, "\"%s\" property in %s is not a single cell",
208 propname, node->fullpath);
209}
210#define CHECK_IS_CELL(nm, propname, lvl) \
211 CHECK(nm, NULL, check_is_cell, NULL, (propname), (lvl))
212
213/*
214 * Structural check functions
215 */
216
217static void check_duplicate_node_names(struct check *c, struct node *dt,
218 struct node *node)
219{
220 struct node *child, *child2;
221
222 for_each_child(node, child)
223 for (child2 = child->next_sibling;
224 child2;
225 child2 = child2->next_sibling)
226 if (streq(child->name, child2->name))
227 FAIL(c, "Duplicate node name %s",
228 child->fullpath);
229}
230NODE_CHECK(duplicate_node_names, NULL, ERROR);
231
232static void check_duplicate_property_names(struct check *c, struct node *dt,
233 struct node *node)
234{
235 struct property *prop, *prop2;
236
237 for_each_property(node, prop)
238 for (prop2 = prop->next; prop2; prop2 = prop2->next)
239 if (streq(prop->name, prop2->name))
240 FAIL(c, "Duplicate property name %s in %s",
241 prop->name, node->fullpath);
242}
243NODE_CHECK(duplicate_property_names, NULL, ERROR);
244
245static void check_explicit_phandles(struct check *c, struct node *root,
246 struct node *node)
247{
248 struct property *prop;
249 struct node *other;
250 cell_t phandle;
251
252 prop = get_property(node, "linux,phandle");
253 if (! prop)
254 return; /* No phandle, that's fine */
255
256 if (prop->val.len != sizeof(cell_t)) {
257 FAIL(c, "%s has bad length (%d) linux,phandle property",
258 node->fullpath, prop->val.len);
259 return;
260 }
261
262 phandle = propval_cell(prop);
263 if ((phandle == 0) || (phandle == -1)) {
264 FAIL(c, "%s has invalid linux,phandle value 0x%x",
265 node->fullpath, phandle);
266 return;
267 }
268
269 other = get_node_by_phandle(root, phandle);
270 if (other) {
271 FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)",
272 node->fullpath, phandle, other->fullpath);
273 return;
274 }
275
276 node->phandle = phandle;
277}
278NODE_CHECK(explicit_phandles, NULL, ERROR);
279
280static void check_name_properties(struct check *c, struct node *root,
281 struct node *node)
282{
283 struct property *prop;
284
285 prop = get_property(node, "name");
286 if (!prop)
287 return; /* No name property, that's fine */
288
289 if ((prop->val.len != node->basenamelen+1)
290 || (memcmp(prop->val.val, node->name, node->basenamelen) != 0))
291 FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead"
292 " of base node name)", node->fullpath, prop->val.val);
293}
294CHECK_IS_STRING(name_is_string, "name", ERROR);
295NODE_CHECK(name_properties, NULL, ERROR, &name_is_string);
296
297/*
298 * Reference fixup functions
299 */
300
301static void fixup_phandle_references(struct check *c, struct node *dt,
302 struct node *node, struct property *prop)
303{
304 struct marker *m = prop->val.markers;
305 struct node *refnode;
306 cell_t phandle;
307
308 for_each_marker_of_type(m, REF_PHANDLE) {
309 assert(m->offset + sizeof(cell_t) <= prop->val.len);
310
311 refnode = get_node_by_ref(dt, m->ref);
312 if (! refnode) {
313 FAIL(c, "Reference to non-existent node or label \"%s\"\n",
314 m->ref);
315 continue;
316 }
317
318 phandle = get_node_phandle(dt, refnode);
319 *((cell_t *)(prop->val.val + m->offset)) = cpu_to_be32(phandle);
320 }
321}
322CHECK(phandle_references, NULL, NULL, fixup_phandle_references, NULL, ERROR,
323 &duplicate_node_names, &explicit_phandles);
324
325static void fixup_path_references(struct check *c, struct node *dt,
326 struct node *node, struct property *prop)
327{
328 struct marker *m = prop->val.markers;
329 struct node *refnode;
330 char *path;
331
332 for_each_marker_of_type(m, REF_PATH) {
333 assert(m->offset <= prop->val.len);
334
335 refnode = get_node_by_ref(dt, m->ref);
336 if (!refnode) {
337 FAIL(c, "Reference to non-existent node or label \"%s\"\n",
338 m->ref);
339 continue;
340 }
341
342 path = refnode->fullpath;
343 prop->val = data_insert_at_marker(prop->val, m, path,
344 strlen(path) + 1);
345 }
346}
347CHECK(path_references, NULL, NULL, fixup_path_references, NULL, ERROR,
348 &duplicate_node_names);
349
350/*
351 * Semantic checks
352 */
353CHECK_IS_CELL(address_cells_is_cell, "#address-cells", WARN);
354CHECK_IS_CELL(size_cells_is_cell, "#size-cells", WARN);
355CHECK_IS_CELL(interrupt_cells_is_cell, "#interrupt-cells", WARN);
356
357CHECK_IS_STRING(device_type_is_string, "device_type", WARN);
358CHECK_IS_STRING(model_is_string, "model", WARN);
359CHECK_IS_STRING(status_is_string, "status", WARN);
360
361static void fixup_addr_size_cells(struct check *c, struct node *dt,
362 struct node *node)
363{
364 struct property *prop;
365
366 node->addr_cells = -1;
367 node->size_cells = -1;
368
369 prop = get_property(node, "#address-cells");
370 if (prop)
371 node->addr_cells = propval_cell(prop);
372
373 prop = get_property(node, "#size-cells");
374 if (prop)
375 node->size_cells = propval_cell(prop);
376}
377CHECK(addr_size_cells, NULL, fixup_addr_size_cells, NULL, NULL, WARN,
378 &address_cells_is_cell, &size_cells_is_cell);
379
380#define node_addr_cells(n) \
381 (((n)->addr_cells == -1) ? 2 : (n)->addr_cells)
382#define node_size_cells(n) \
383 (((n)->size_cells == -1) ? 1 : (n)->size_cells)
384
385static void check_reg_format(struct check *c, struct node *dt,
386 struct node *node)
387{
388 struct property *prop;
389 int addr_cells, size_cells, entrylen;
390
391 prop = get_property(node, "reg");
392 if (!prop)
393 return; /* No "reg", that's fine */
394
395 if (!node->parent) {
396 FAIL(c, "Root node has a \"reg\" property");
397 return;
398 }
399
400 if (prop->val.len == 0)
401 FAIL(c, "\"reg\" property in %s is empty", node->fullpath);
402
403 addr_cells = node_addr_cells(node->parent);
404 size_cells = node_size_cells(node->parent);
405 entrylen = (addr_cells + size_cells) * sizeof(cell_t);
406
407 if ((prop->val.len % entrylen) != 0)
408 FAIL(c, "\"reg\" property in %s has invalid length (%d bytes) "
409 "(#address-cells == %d, #size-cells == %d)",
410 node->fullpath, prop->val.len, addr_cells, size_cells);
411}
412NODE_CHECK(reg_format, NULL, WARN, &addr_size_cells);
413
414static void check_ranges_format(struct check *c, struct node *dt,
415 struct node *node)
416{
417 struct property *prop;
418 int c_addr_cells, p_addr_cells, c_size_cells, p_size_cells, entrylen;
419
420 prop = get_property(node, "ranges");
421 if (!prop)
422 return;
423
424 if (!node->parent) {
425 FAIL(c, "Root node has a \"ranges\" property");
426 return;
427 }
428
429 p_addr_cells = node_addr_cells(node->parent);
430 p_size_cells = node_size_cells(node->parent);
431 c_addr_cells = node_addr_cells(node);
432 c_size_cells = node_size_cells(node);
433 entrylen = (p_addr_cells + c_addr_cells + c_size_cells) * sizeof(cell_t);
434
435 if (prop->val.len == 0) {
436 if (p_addr_cells != c_addr_cells)
437 FAIL(c, "%s has empty \"ranges\" property but its "
438 "#address-cells (%d) differs from %s (%d)",
439 node->fullpath, c_addr_cells, node->parent->fullpath,
440 p_addr_cells);
441 if (p_size_cells != c_size_cells)
442 FAIL(c, "%s has empty \"ranges\" property but its "
443 "#size-cells (%d) differs from %s (%d)",
444 node->fullpath, c_size_cells, node->parent->fullpath,
445 p_size_cells);
446 } else if ((prop->val.len % entrylen) != 0) {
447 FAIL(c, "\"ranges\" property in %s has invalid length (%d bytes) "
448 "(parent #address-cells == %d, child #address-cells == %d, "
449 "#size-cells == %d)", node->fullpath, prop->val.len,
450 p_addr_cells, c_addr_cells, c_size_cells);
451 }
452}
453NODE_CHECK(ranges_format, NULL, WARN, &addr_size_cells);
454
455/*
456 * Style checks
457 */
458static void check_avoid_default_addr_size(struct check *c, struct node *dt,
459 struct node *node)
460{
461 struct property *reg, *ranges;
462
463 if (!node->parent)
464 return; /* Ignore root node */
465
466 reg = get_property(node, "reg");
467 ranges = get_property(node, "ranges");
468
469 if (!reg && !ranges)
470 return;
471
472 if ((node->parent->addr_cells == -1))
473 FAIL(c, "Relying on default #address-cells value for %s",
474 node->fullpath);
475
476 if ((node->parent->size_cells == -1))
477 FAIL(c, "Relying on default #size-cells value for %s",
478 node->fullpath);
479}
480NODE_CHECK(avoid_default_addr_size, NULL, WARN, &addr_size_cells);
481
482static void check_obsolete_chosen_interrupt_controller(struct check *c,
483 struct node *dt)
484{
485 struct node *chosen;
486 struct property *prop;
487
488 chosen = get_node_by_path(dt, "/chosen");
489 if (!chosen)
490 return;
491
492 prop = get_property(chosen, "interrupt-controller");
493 if (prop)
494 FAIL(c, "/chosen has obsolete \"interrupt-controller\" "
495 "property");
496}
497TREE_CHECK(obsolete_chosen_interrupt_controller, NULL, WARN);
498
499static struct check *check_table[] = {
500 &duplicate_node_names, &duplicate_property_names,
501 &name_is_string, &name_properties,
502 &explicit_phandles,
503 &phandle_references, &path_references,
504
505 &address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
506 &device_type_is_string, &model_is_string, &status_is_string,
507
508 &addr_size_cells, &reg_format, &ranges_format,
509
510 &avoid_default_addr_size,
511 &obsolete_chosen_interrupt_controller,
512};
513
514int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys);
515
516void process_checks(int force, struct boot_info *bi,
517 int checkflag, int outversion, int boot_cpuid_phys)
518{
519 struct node *dt = bi->dt;
520 int i;
521 int error = 0;
522
523 for (i = 0; i < ARRAY_SIZE(check_table); i++) {
524 struct check *c = check_table[i];
525
526 if (c->level != IGNORE)
527 error = error || run_check(c, dt);
528 }
529
530 if (error) {
531 if (!force) {
532 fprintf(stderr, "ERROR: Input tree has errors, aborting "
533 "(use -f to force output)\n");
534 exit(2);
535 } else if (quiet < 3) {
536 fprintf(stderr, "Warning: Input tree has errors, "
537 "output forced\n");
538 }
539 }
540
541 if (checkflag) {
542 if (error) {
543 fprintf(stderr, "Warning: Skipping semantic checks due to structural errors\n");
544 } else {
545 if (!check_semantics(bi->dt, outversion,
546 boot_cpuid_phys))
547 fprintf(stderr, "Warning: Input tree has semantic errors\n");
548 }
549 }
550}
551
552/*
553 * Semantic check functions
554 */
555
556#define ERRMSG(...) if (quiet < 2) fprintf(stderr, "ERROR: " __VA_ARGS__)
557#define WARNMSG(...) if (quiet < 1) fprintf(stderr, "Warning: " __VA_ARGS__)
558
559#define DO_ERR(...) do {ERRMSG(__VA_ARGS__); ok = 0; } while (0)
560
561#define CHECK_HAVE(node, propname) \
562 do { \
563 if (! (prop = get_property((node), (propname)))) \
564 DO_ERR("Missing \"%s\" property in %s\n", (propname), \
565 (node)->fullpath); \
566 } while (0);
567
568#define CHECK_HAVE_WARN(node, propname) \
569 do { \
570 if (! (prop = get_property((node), (propname)))) \
571 WARNMSG("%s has no \"%s\" property\n", \
572 (node)->fullpath, (propname)); \
573 } while (0)
574
575#define CHECK_HAVE_STRING(node, propname) \
576 do { \
577 CHECK_HAVE((node), (propname)); \
578 if (prop && !data_is_one_string(prop->val)) \
579 DO_ERR("\"%s\" property in %s is not a string\n", \
580 (propname), (node)->fullpath); \
581 } while (0)
582
583#define CHECK_HAVE_STREQ(node, propname, value) \
584 do { \
585 CHECK_HAVE_STRING((node), (propname)); \
586 if (prop && !streq(prop->val.val, (value))) \
587 DO_ERR("%s has wrong %s, %s (should be %s\n", \
588 (node)->fullpath, (propname), \
589 prop->val.val, (value)); \
590 } while (0)
591
592#define CHECK_HAVE_ONECELL(node, propname) \
593 do { \
594 CHECK_HAVE((node), (propname)); \
595 if (prop && (prop->val.len != sizeof(cell_t))) \
596 DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \
597 } while (0)
598
599#define CHECK_HAVE_WARN_ONECELL(node, propname) \
600 do { \
601 CHECK_HAVE_WARN((node), (propname)); \
602 if (prop && (prop->val.len != sizeof(cell_t))) \
603 DO_ERR("\"%s\" property in %s has wrong size %d (should be 1 cell)\n", (propname), (node)->fullpath, prop->val.len); \
604 } while (0)
605
606#define CHECK_HAVE_WARN_PHANDLE(xnode, propname, root) \
607 do { \
608 struct node *ref; \
609 CHECK_HAVE_WARN_ONECELL((xnode), (propname)); \
610 if (prop) {\
611 cell_t phandle = propval_cell(prop); \
612 if ((phandle == 0) || (phandle == -1)) { \
613 DO_ERR("\"%s\" property in %s contains an invalid phandle %x\n", (propname), (xnode)->fullpath, phandle); \
614 } else { \
615 ref = get_node_by_phandle((root), propval_cell(prop)); \
616 if (! ref) \
617 DO_ERR("\"%s\" property in %s refers to non-existant phandle %x\n", (propname), (xnode)->fullpath, propval_cell(prop)); \
618 } \
619 } \
620 } while (0)
621
622#define CHECK_HAVE_WARN_STRING(node, propname) \
623 do { \
624 CHECK_HAVE_WARN((node), (propname)); \
625 if (prop && !data_is_one_string(prop->val)) \
626 DO_ERR("\"%s\" property in %s is not a string\n", \
627 (propname), (node)->fullpath); \
628 } while (0)
629
630static int check_root(struct node *root)
631{
632 struct property *prop;
633 int ok = 1;
634
635 CHECK_HAVE_STRING(root, "model");
636 CHECK_HAVE_WARN(root, "compatible");
637
638 return ok;
639}
640
641static int check_cpus(struct node *root, int outversion, int boot_cpuid_phys)
642{
643 struct node *cpus, *cpu;
644 struct property *prop;
645 struct node *bootcpu = NULL;
646 int ok = 1;
647
648 cpus = get_subnode(root, "cpus");
649 if (! cpus) {
650 ERRMSG("Missing /cpus node\n");
651 return 0;
652 }
653
654 if (cpus->addr_cells != 1)
655 DO_ERR("%s has bad #address-cells value %d (should be 1)\n",
656 cpus->fullpath, cpus->addr_cells);
657 if (cpus->size_cells != 0)
658 DO_ERR("%s has bad #size-cells value %d (should be 0)\n",
659 cpus->fullpath, cpus->size_cells);
660
661 for_each_child(cpus, cpu) {
662 CHECK_HAVE_STREQ(cpu, "device_type", "cpu");
663
664 CHECK_HAVE_ONECELL(cpu, "reg");
665 if (prop) {
666 cell_t unitnum;
667 char *eptr;
668
669 unitnum = strtol(get_unitname(cpu), &eptr, 16);
670 if (*eptr) {
671 WARNMSG("%s has bad format unit name %s (should be CPU number\n",
672 cpu->fullpath, get_unitname(cpu));
673 } else if (unitnum != propval_cell(prop)) {
674 WARNMSG("%s unit name \"%s\" does not match \"reg\" property <%x>\n",
675 cpu->fullpath, get_unitname(cpu),
676 propval_cell(prop));
677 }
678 }
679
680/* CHECK_HAVE_ONECELL(cpu, "d-cache-line-size"); */
681/* CHECK_HAVE_ONECELL(cpu, "i-cache-line-size"); */
682 CHECK_HAVE_ONECELL(cpu, "d-cache-size");
683 CHECK_HAVE_ONECELL(cpu, "i-cache-size");
684
685 CHECK_HAVE_WARN_ONECELL(cpu, "clock-frequency");
686 CHECK_HAVE_WARN_ONECELL(cpu, "timebase-frequency");
687
688 prop = get_property(cpu, "linux,boot-cpu");
689 if (prop) {
690 if (prop->val.len)
691 WARNMSG("\"linux,boot-cpu\" property in %s is non-empty\n",
692 cpu->fullpath);
693 if (bootcpu)
694 DO_ERR("Multiple boot cpus (%s and %s)\n",
695 bootcpu->fullpath, cpu->fullpath);
696 else
697 bootcpu = cpu;
698 }
699 }
700
701 if (outversion < 2) {
702 if (! bootcpu)
703 WARNMSG("No cpu has \"linux,boot-cpu\" property\n");
704 } else {
705 if (bootcpu)
706 WARNMSG("\"linux,boot-cpu\" property is deprecated in blob version 2 or higher\n");
707 if (boot_cpuid_phys == 0xfeedbeef)
708 WARNMSG("physical boot CPU not set. Use -b option to set\n");
709 }
710
711 return ok;
712}
713
714static int check_memory(struct node *root)
715{
716 struct node *mem;
717 struct property *prop;
718 int nnodes = 0;
719 int ok = 1;
720
721 for_each_child(root, mem) {
722 if (! strneq(mem->name, "memory", mem->basenamelen))
723 continue;
724
725 nnodes++;
726
727 CHECK_HAVE_STREQ(mem, "device_type", "memory");
728 CHECK_HAVE(mem, "reg");
729 }
730
731 if (nnodes == 0) {
732 ERRMSG("No memory nodes\n");
733 return 0;
734 }
735
736 return ok;
737}
738
739int check_semantics(struct node *dt, int outversion, int boot_cpuid_phys)
740{
741 int ok = 1;
742
743 ok = ok && check_root(dt);
744 ok = ok && check_cpus(dt, outversion, boot_cpuid_phys);
745 ok = ok && check_memory(dt);
746 if (! ok)
747 return 0;
748
749 return 1;
750}
diff --git a/arch/powerpc/boot/dtc-src/data.c b/arch/powerpc/boot/dtc-src/data.c
new file mode 100644
index 000000000000..a94718c731a9
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/data.c
@@ -0,0 +1,321 @@
1/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3 *
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 */
20
21#include "dtc.h"
22
23void data_free(struct data d)
24{
25 struct marker *m, *nm;
26
27 m = d.markers;
28 while (m) {
29 nm = m->next;
30 free(m->ref);
31 free(m);
32 m = nm;
33 }
34
35 assert(!d.val || d.asize);
36
37 if (d.val)
38 free(d.val);
39}
40
41struct data data_grow_for(struct data d, int xlen)
42{
43 struct data nd;
44 int newsize;
45
46 /* we must start with an allocated datum */
47 assert(!d.val || d.asize);
48
49 if (xlen == 0)
50 return d;
51
52 nd = d;
53
54 newsize = xlen;
55
56 while ((d.len + xlen) > newsize)
57 newsize *= 2;
58
59 nd.asize = newsize;
60 nd.val = xrealloc(d.val, newsize);
61
62 assert(nd.asize >= (d.len + xlen));
63
64 return nd;
65}
66
67struct data data_copy_mem(const char *mem, int len)
68{
69 struct data d;
70
71 d = data_grow_for(empty_data, len);
72
73 d.len = len;
74 memcpy(d.val, mem, len);
75
76 return d;
77}
78
79static char get_oct_char(const char *s, int *i)
80{
81 char x[4];
82 char *endx;
83 long val;
84
85 x[3] = '\0';
86 x[0] = s[(*i)];
87 if (x[0]) {
88 x[1] = s[(*i)+1];
89 if (x[1])
90 x[2] = s[(*i)+2];
91 }
92
93 val = strtol(x, &endx, 8);
94 if ((endx - x) == 0)
95 fprintf(stderr, "Empty \\nnn escape\n");
96
97 (*i) += endx - x;
98 return val;
99}
100
101static char get_hex_char(const char *s, int *i)
102{
103 char x[3];
104 char *endx;
105 long val;
106
107 x[2] = '\0';
108 x[0] = s[(*i)];
109 if (x[0])
110 x[1] = s[(*i)+1];
111
112 val = strtol(x, &endx, 16);
113 if ((endx - x) == 0)
114 fprintf(stderr, "Empty \\x escape\n");
115
116 (*i) += endx - x;
117 return val;
118}
119
120struct data data_copy_escape_string(const char *s, int len)
121{
122 int i = 0;
123 struct data d;
124 char *q;
125
126 d = data_grow_for(empty_data, strlen(s)+1);
127
128 q = d.val;
129 while (i < len) {
130 char c = s[i++];
131
132 if (c != '\\') {
133 q[d.len++] = c;
134 continue;
135 }
136
137 c = s[i++];
138 assert(c);
139 switch (c) {
140 case 'a':
141 q[d.len++] = '\a';
142 break;
143 case 'b':
144 q[d.len++] = '\b';
145 break;
146 case 't':
147 q[d.len++] = '\t';
148 break;
149 case 'n':
150 q[d.len++] = '\n';
151 break;
152 case 'v':
153 q[d.len++] = '\v';
154 break;
155 case 'f':
156 q[d.len++] = '\f';
157 break;
158 case 'r':
159 q[d.len++] = '\r';
160 break;
161 case '0':
162 case '1':
163 case '2':
164 case '3':
165 case '4':
166 case '5':
167 case '6':
168 case '7':
169 i--; /* need to re-read the first digit as
170 * part of the octal value */
171 q[d.len++] = get_oct_char(s, &i);
172 break;
173 case 'x':
174 q[d.len++] = get_hex_char(s, &i);
175 break;
176 default:
177 q[d.len++] = c;
178 }
179 }
180
181 q[d.len++] = '\0';
182 return d;
183}
184
185struct data data_copy_file(FILE *f, size_t len)
186{
187 struct data d;
188
189 d = data_grow_for(empty_data, len);
190
191 d.len = len;
192 fread(d.val, len, 1, f);
193
194 return d;
195}
196
197struct data data_append_data(struct data d, const void *p, int len)
198{
199 d = data_grow_for(d, len);
200 memcpy(d.val + d.len, p, len);
201 d.len += len;
202 return d;
203}
204
205struct data data_insert_at_marker(struct data d, struct marker *m,
206 const void *p, int len)
207{
208 d = data_grow_for(d, len);
209 memmove(d.val + m->offset + len, d.val + m->offset, d.len - m->offset);
210 memcpy(d.val + m->offset, p, len);
211 d.len += len;
212
213 /* Adjust all markers after the one we're inserting at */
214 m = m->next;
215 for_each_marker(m)
216 m->offset += len;
217 return d;
218}
219
220struct data data_append_markers(struct data d, struct marker *m)
221{
222 struct marker **mp = &d.markers;
223
224 /* Find the end of the markerlist */
225 while (*mp)
226 mp = &((*mp)->next);
227 *mp = m;
228 return d;
229}
230
231struct data data_merge(struct data d1, struct data d2)
232{
233 struct data d;
234 struct marker *m2 = d2.markers;
235
236 d = data_append_markers(data_append_data(d1, d2.val, d2.len), m2);
237
238 /* Adjust for the length of d1 */
239 for_each_marker(m2)
240 m2->offset += d1.len;
241
242 d2.markers = NULL; /* So data_free() doesn't clobber them */
243 data_free(d2);
244
245 return d;
246}
247
248struct data data_append_cell(struct data d, cell_t word)
249{
250 cell_t beword = cpu_to_be32(word);
251
252 return data_append_data(d, &beword, sizeof(beword));
253}
254
255struct data data_append_re(struct data d, const struct fdt_reserve_entry *re)
256{
257 struct fdt_reserve_entry bere;
258
259 bere.address = cpu_to_be64(re->address);
260 bere.size = cpu_to_be64(re->size);
261
262 return data_append_data(d, &bere, sizeof(bere));
263}
264
265struct data data_append_addr(struct data d, u64 addr)
266{
267 u64 beaddr = cpu_to_be64(addr);
268
269 return data_append_data(d, &beaddr, sizeof(beaddr));
270}
271
272struct data data_append_byte(struct data d, uint8_t byte)
273{
274 return data_append_data(d, &byte, 1);
275}
276
277struct data data_append_zeroes(struct data d, int len)
278{
279 d = data_grow_for(d, len);
280
281 memset(d.val + d.len, 0, len);
282 d.len += len;
283 return d;
284}
285
286struct data data_append_align(struct data d, int align)
287{
288 int newlen = ALIGN(d.len, align);
289 return data_append_zeroes(d, newlen - d.len);
290}
291
292struct data data_add_marker(struct data d, enum markertype type, char *ref)
293{
294 struct marker *m;
295
296 m = xmalloc(sizeof(*m));
297 m->offset = d.len;
298 m->type = type;
299 m->ref = ref;
300 m->next = NULL;
301
302 return data_append_markers(d, m);
303}
304
305int data_is_one_string(struct data d)
306{
307 int i;
308 int len = d.len;
309
310 if (len == 0)
311 return 0;
312
313 for (i = 0; i < len-1; i++)
314 if (d.val[i] == '\0')
315 return 0;
316
317 if (d.val[len-1] != '\0')
318 return 0;
319
320 return 1;
321}
diff --git a/arch/powerpc/boot/dtc-src/dtc-lexer.l b/arch/powerpc/boot/dtc-src/dtc-lexer.l
new file mode 100644
index 000000000000..c811b221b31e
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/dtc-lexer.l
@@ -0,0 +1,328 @@
1/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3 *
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 */
20
21%option noyywrap nounput yylineno
22
23%x INCLUDE
24%x BYTESTRING
25%x PROPNODENAME
26%s V1
27
28PROPNODECHAR [a-zA-Z0-9,._+*#?@-]
29PATHCHAR ({PROPNODECHAR}|[/])
30LABEL [a-zA-Z_][a-zA-Z0-9_]*
31
32%{
33#include "dtc.h"
34#include "srcpos.h"
35#include "dtc-parser.tab.h"
36
37
38/*#define LEXDEBUG 1*/
39
40#ifdef LEXDEBUG
41#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
42#else
43#define DPRINT(fmt, ...) do { } while (0)
44#endif
45
46static int dts_version; /* = 0 */
47
48#define BEGIN_DEFAULT() if (dts_version == 0) { \
49 DPRINT("<INITIAL>\n"); \
50 BEGIN(INITIAL); \
51 } else { \
52 DPRINT("<V1>\n"); \
53 BEGIN(V1); \
54 }
55%}
56
57%%
58<*>"/include/" BEGIN(INCLUDE);
59
60<INCLUDE>\"[^"\n]*\" {
61 yytext[strlen(yytext) - 1] = 0;
62 if (!push_input_file(yytext + 1)) {
63 /* Some unrecoverable error.*/
64 exit(1);
65 }
66 BEGIN_DEFAULT();
67 }
68
69
70<*><<EOF>> {
71 if (!pop_input_file()) {
72 yyterminate();
73 }
74 }
75
76<*>\"([^\\"]|\\.)*\" {
77 yylloc.filenum = srcpos_filenum;
78 yylloc.first_line = yylineno;
79 DPRINT("String: %s\n", yytext);
80 yylval.data = data_copy_escape_string(yytext+1,
81 yyleng-2);
82 yylloc.first_line = yylineno;
83 return DT_STRING;
84 }
85
86<*>"/dts-v1/" {
87 yylloc.filenum = srcpos_filenum;
88 yylloc.first_line = yylineno;
89 DPRINT("Keyword: /dts-v1/\n");
90 dts_version = 1;
91 BEGIN_DEFAULT();
92 return DT_V1;
93 }
94
95<*>"/memreserve/" {
96 yylloc.filenum = srcpos_filenum;
97 yylloc.first_line = yylineno;
98 DPRINT("Keyword: /memreserve/\n");
99 BEGIN_DEFAULT();
100 return DT_MEMRESERVE;
101 }
102
103<*>{LABEL}: {
104 yylloc.filenum = srcpos_filenum;
105 yylloc.first_line = yylineno;
106 DPRINT("Label: %s\n", yytext);
107 yylval.labelref = strdup(yytext);
108 yylval.labelref[yyleng-1] = '\0';
109 return DT_LABEL;
110 }
111
112<INITIAL>[bodh]# {
113 yylloc.filenum = srcpos_filenum;
114 yylloc.first_line = yylineno;
115 if (*yytext == 'b')
116 yylval.cbase = 2;
117 else if (*yytext == 'o')
118 yylval.cbase = 8;
119 else if (*yytext == 'd')
120 yylval.cbase = 10;
121 else
122 yylval.cbase = 16;
123 DPRINT("Base: %d\n", yylval.cbase);
124 return DT_BASE;
125 }
126
127<INITIAL>[0-9a-fA-F]+ {
128 yylloc.filenum = srcpos_filenum;
129 yylloc.first_line = yylineno;
130 yylval.literal = strdup(yytext);
131 DPRINT("Literal: '%s'\n", yylval.literal);
132 return DT_LEGACYLITERAL;
133 }
134
135<V1>[0-9]+|0[xX][0-9a-fA-F]+ {
136 yylloc.filenum = srcpos_filenum;
137 yylloc.first_line = yylineno;
138 yylval.literal = strdup(yytext);
139 DPRINT("Literal: '%s'\n", yylval.literal);
140 return DT_LITERAL;
141 }
142
143\&{LABEL} { /* label reference */
144 yylloc.filenum = srcpos_filenum;
145 yylloc.first_line = yylineno;
146 DPRINT("Ref: %s\n", yytext+1);
147 yylval.labelref = strdup(yytext+1);
148 return DT_REF;
149 }
150
151"&{/"{PATHCHAR}+\} { /* new-style path reference */
152 yylloc.filenum = srcpos_filenum;
153 yylloc.first_line = yylineno;
154 yytext[yyleng-1] = '\0';
155 DPRINT("Ref: %s\n", yytext+2);
156 yylval.labelref = strdup(yytext+2);
157 return DT_REF;
158 }
159
160<INITIAL>"&/"{PATHCHAR}+ { /* old-style path reference */
161 yylloc.filenum = srcpos_filenum;
162 yylloc.first_line = yylineno;
163 DPRINT("Ref: %s\n", yytext+1);
164 yylval.labelref = strdup(yytext+1);
165 return DT_REF;
166 }
167
168<BYTESTRING>[0-9a-fA-F]{2} {
169 yylloc.filenum = srcpos_filenum;
170 yylloc.first_line = yylineno;
171 yylval.byte = strtol(yytext, NULL, 16);
172 DPRINT("Byte: %02x\n", (int)yylval.byte);
173 return DT_BYTE;
174 }
175
176<BYTESTRING>"]" {
177 yylloc.filenum = srcpos_filenum;
178 yylloc.first_line = yylineno;
179 DPRINT("/BYTESTRING\n");
180 BEGIN_DEFAULT();
181 return ']';
182 }
183
184<PROPNODENAME>{PROPNODECHAR}+ {
185 yylloc.filenum = srcpos_filenum;
186 yylloc.first_line = yylineno;
187 DPRINT("PropNodeName: %s\n", yytext);
188 yylval.propnodename = strdup(yytext);
189 BEGIN_DEFAULT();
190 return DT_PROPNODENAME;
191 }
192
193
194<*>[[:space:]]+ /* eat whitespace */
195
196<*>"/*"([^*]|\*+[^*/])*\*+"/" {
197 yylloc.filenum = srcpos_filenum;
198 yylloc.first_line = yylineno;
199 DPRINT("Comment: %s\n", yytext);
200 /* eat comments */
201 }
202
203<*>"//".*\n /* eat line comments */
204
205<*>. {
206 yylloc.filenum = srcpos_filenum;
207 yylloc.first_line = yylineno;
208 DPRINT("Char: %c (\\x%02x)\n", yytext[0],
209 (unsigned)yytext[0]);
210 if (yytext[0] == '[') {
211 DPRINT("<BYTESTRING>\n");
212 BEGIN(BYTESTRING);
213 }
214 if ((yytext[0] == '{')
215 || (yytext[0] == ';')) {
216 DPRINT("<PROPNODENAME>\n");
217 BEGIN(PROPNODENAME);
218 }
219 return yytext[0];
220 }
221
222%%
223
224
225/*
226 * Stack of nested include file contexts.
227 */
228
229struct incl_file {
230 int filenum;
231 FILE *file;
232 YY_BUFFER_STATE yy_prev_buf;
233 int yy_prev_lineno;
234 struct incl_file *prev;
235};
236
237struct incl_file *incl_file_stack;
238
239
240/*
241 * Detect infinite include recursion.
242 */
243#define MAX_INCLUDE_DEPTH (100)
244
245static int incl_depth = 0;
246
247
248int push_input_file(const char *filename)
249{
250 FILE *f;
251 struct incl_file *incl_file;
252
253 if (!filename) {
254 yyerror("No include file name given.");
255 return 0;
256 }
257
258 if (incl_depth++ >= MAX_INCLUDE_DEPTH) {
259 yyerror("Includes nested too deeply");
260 return 0;
261 }
262
263 f = dtc_open_file(filename);
264
265 incl_file = malloc(sizeof(struct incl_file));
266 if (!incl_file) {
267 yyerror("Can not allocate include file space.");
268 return 0;
269 }
270
271 /*
272 * Save current context.
273 */
274 incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
275 incl_file->yy_prev_lineno = yylineno;
276 incl_file->filenum = srcpos_filenum;
277 incl_file->file = yyin;
278 incl_file->prev = incl_file_stack;
279
280 incl_file_stack = incl_file;
281
282 /*
283 * Establish new context.
284 */
285 srcpos_filenum = lookup_file_name(filename, 0);
286 yylineno = 1;
287 yyin = f;
288 yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
289
290 return 1;
291}
292
293
294int pop_input_file(void)
295{
296 struct incl_file *incl_file;
297
298 if (incl_file_stack == 0)
299 return 0;
300
301 fclose(yyin);
302
303 /*
304 * Pop.
305 */
306 --incl_depth;
307 incl_file = incl_file_stack;
308 incl_file_stack = incl_file->prev;
309
310 /*
311 * Recover old context.
312 */
313 yy_delete_buffer(YY_CURRENT_BUFFER);
314 yy_switch_to_buffer(incl_file->yy_prev_buf);
315 yylineno = incl_file->yy_prev_lineno;
316 srcpos_filenum = incl_file->filenum;
317 yyin = incl_file->file;
318
319 /*
320 * Free old state.
321 */
322 free(incl_file);
323
324 if (YY_CURRENT_BUFFER == 0)
325 return 0;
326
327 return 1;
328}
diff --git a/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped b/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped
new file mode 100644
index 000000000000..d0f742460f92
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/dtc-lexer.lex.c_shipped
@@ -0,0 +1,2174 @@
1#line 2 "dtc-lexer.lex.c"
2
3#line 4 "dtc-lexer.lex.c"
4
5#define YY_INT_ALIGNED short int
6
7/* A lexical scanner generated by flex */
8
9#define FLEX_SCANNER
10#define YY_FLEX_MAJOR_VERSION 2
11#define YY_FLEX_MINOR_VERSION 5
12#define YY_FLEX_SUBMINOR_VERSION 33
13#if YY_FLEX_SUBMINOR_VERSION > 0
14#define FLEX_BETA
15#endif
16
17/* First, we deal with platform-specific or compiler-specific issues. */
18
19/* begin standard C headers. */
20#include <stdio.h>
21#include <string.h>
22#include <errno.h>
23#include <stdlib.h>
24
25/* end standard C headers. */
26
27/* flex integer type definitions */
28
29#ifndef FLEXINT_H
30#define FLEXINT_H
31
32/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
33
34#if __STDC_VERSION__ >= 199901L
35
36/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
37 * if you want the limit (max/min) macros for int types.
38 */
39#ifndef __STDC_LIMIT_MACROS
40#define __STDC_LIMIT_MACROS 1
41#endif
42
43#include <inttypes.h>
44typedef int8_t flex_int8_t;
45typedef uint8_t flex_uint8_t;
46typedef int16_t flex_int16_t;
47typedef uint16_t flex_uint16_t;
48typedef int32_t flex_int32_t;
49typedef uint32_t flex_uint32_t;
50#else
51typedef signed char flex_int8_t;
52typedef short int flex_int16_t;
53typedef int flex_int32_t;
54typedef unsigned char flex_uint8_t;
55typedef unsigned short int flex_uint16_t;
56typedef unsigned int flex_uint32_t;
57#endif /* ! C99 */
58
59/* Limits of integral types. */
60#ifndef INT8_MIN
61#define INT8_MIN (-128)
62#endif
63#ifndef INT16_MIN
64#define INT16_MIN (-32767-1)
65#endif
66#ifndef INT32_MIN
67#define INT32_MIN (-2147483647-1)
68#endif
69#ifndef INT8_MAX
70#define INT8_MAX (127)
71#endif
72#ifndef INT16_MAX
73#define INT16_MAX (32767)
74#endif
75#ifndef INT32_MAX
76#define INT32_MAX (2147483647)
77#endif
78#ifndef UINT8_MAX
79#define UINT8_MAX (255U)
80#endif
81#ifndef UINT16_MAX
82#define UINT16_MAX (65535U)
83#endif
84#ifndef UINT32_MAX
85#define UINT32_MAX (4294967295U)
86#endif
87
88#endif /* ! FLEXINT_H */
89
90#ifdef __cplusplus
91
92/* The "const" storage-class-modifier is valid. */
93#define YY_USE_CONST
94
95#else /* ! __cplusplus */
96
97#if __STDC__
98
99#define YY_USE_CONST
100
101#endif /* __STDC__ */
102#endif /* ! __cplusplus */
103
104#ifdef YY_USE_CONST
105#define yyconst const
106#else
107#define yyconst
108#endif
109
110/* Returned upon end-of-file. */
111#define YY_NULL 0
112
113/* Promotes a possibly negative, possibly signed char to an unsigned
114 * integer for use as an array index. If the signed char is negative,
115 * we want to instead treat it as an 8-bit unsigned char, hence the
116 * double cast.
117 */
118#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
119
120/* Enter a start condition. This macro really ought to take a parameter,
121 * but we do it the disgusting crufty way forced on us by the ()-less
122 * definition of BEGIN.
123 */
124#define BEGIN (yy_start) = 1 + 2 *
125
126/* Translate the current start state into a value that can be later handed
127 * to BEGIN to return to the state. The YYSTATE alias is for lex
128 * compatibility.
129 */
130#define YY_START (((yy_start) - 1) / 2)
131#define YYSTATE YY_START
132
133/* Action number for EOF rule of a given start state. */
134#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
135
136/* Special action meaning "start processing a new file". */
137#define YY_NEW_FILE yyrestart(yyin )
138
139#define YY_END_OF_BUFFER_CHAR 0
140
141/* Size of default input buffer. */
142#ifndef YY_BUF_SIZE
143#define YY_BUF_SIZE 16384
144#endif
145
146/* The state buf must be large enough to hold one state per character in the main buffer.
147 */
148#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
149
150#ifndef YY_TYPEDEF_YY_BUFFER_STATE
151#define YY_TYPEDEF_YY_BUFFER_STATE
152typedef struct yy_buffer_state *YY_BUFFER_STATE;
153#endif
154
155extern int yyleng;
156
157extern FILE *yyin, *yyout;
158
159#define EOB_ACT_CONTINUE_SCAN 0
160#define EOB_ACT_END_OF_FILE 1
161#define EOB_ACT_LAST_MATCH 2
162
163 /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
164 * access to the local variable yy_act. Since yyless() is a macro, it would break
165 * existing scanners that call yyless() from OUTSIDE yylex.
166 * One obvious solution it to make yy_act a global. I tried that, and saw
167 * a 5% performance hit in a non-yylineno scanner, because yy_act is
168 * normally declared as a register variable-- so it is not worth it.
169 */
170 #define YY_LESS_LINENO(n) \
171 do { \
172 int yyl;\
173 for ( yyl = n; yyl < yyleng; ++yyl )\
174 if ( yytext[yyl] == '\n' )\
175 --yylineno;\
176 }while(0)
177
178/* Return all but the first "n" matched characters back to the input stream. */
179#define yyless(n) \
180 do \
181 { \
182 /* Undo effects of setting up yytext. */ \
183 int yyless_macro_arg = (n); \
184 YY_LESS_LINENO(yyless_macro_arg);\
185 *yy_cp = (yy_hold_char); \
186 YY_RESTORE_YY_MORE_OFFSET \
187 (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
188 YY_DO_BEFORE_ACTION; /* set up yytext again */ \
189 } \
190 while ( 0 )
191
192#define unput(c) yyunput( c, (yytext_ptr) )
193
194/* The following is because we cannot portably get our hands on size_t
195 * (without autoconf's help, which isn't available because we want
196 * flex-generated scanners to compile on their own).
197 */
198
199#ifndef YY_TYPEDEF_YY_SIZE_T
200#define YY_TYPEDEF_YY_SIZE_T
201typedef unsigned int yy_size_t;
202#endif
203
204#ifndef YY_STRUCT_YY_BUFFER_STATE
205#define YY_STRUCT_YY_BUFFER_STATE
206struct yy_buffer_state
207 {
208 FILE *yy_input_file;
209
210 char *yy_ch_buf; /* input buffer */
211 char *yy_buf_pos; /* current position in input buffer */
212
213 /* Size of input buffer in bytes, not including room for EOB
214 * characters.
215 */
216 yy_size_t yy_buf_size;
217
218 /* Number of characters read into yy_ch_buf, not including EOB
219 * characters.
220 */
221 int yy_n_chars;
222
223 /* Whether we "own" the buffer - i.e., we know we created it,
224 * and can realloc() it to grow it, and should free() it to
225 * delete it.
226 */
227 int yy_is_our_buffer;
228
229 /* Whether this is an "interactive" input source; if so, and
230 * if we're using stdio for input, then we want to use getc()
231 * instead of fread(), to make sure we stop fetching input after
232 * each newline.
233 */
234 int yy_is_interactive;
235
236 /* Whether we're considered to be at the beginning of a line.
237 * If so, '^' rules will be active on the next match, otherwise
238 * not.
239 */
240 int yy_at_bol;
241
242 int yy_bs_lineno; /**< The line count. */
243 int yy_bs_column; /**< The column count. */
244
245 /* Whether to try to fill the input buffer when we reach the
246 * end of it.
247 */
248 int yy_fill_buffer;
249
250 int yy_buffer_status;
251
252#define YY_BUFFER_NEW 0
253#define YY_BUFFER_NORMAL 1
254 /* When an EOF's been seen but there's still some text to process
255 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
256 * shouldn't try reading from the input source any more. We might
257 * still have a bunch of tokens to match, though, because of
258 * possible backing-up.
259 *
260 * When we actually see the EOF, we change the status to "new"
261 * (via yyrestart()), so that the user can continue scanning by
262 * just pointing yyin at a new input file.
263 */
264#define YY_BUFFER_EOF_PENDING 2
265
266 };
267#endif /* !YY_STRUCT_YY_BUFFER_STATE */
268
269/* Stack of input buffers. */
270static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
271static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
272static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
273
274/* We provide macros for accessing buffer states in case in the
275 * future we want to put the buffer states in a more general
276 * "scanner state".
277 *
278 * Returns the top of the stack, or NULL.
279 */
280#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
281 ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
282 : NULL)
283
284/* Same as previous macro, but useful when we know that the buffer stack is not
285 * NULL or when we need an lvalue. For internal use only.
286 */
287#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
288
289/* yy_hold_char holds the character lost when yytext is formed. */
290static char yy_hold_char;
291static int yy_n_chars; /* number of characters read into yy_ch_buf */
292int yyleng;
293
294/* Points to current character in buffer. */
295static char *yy_c_buf_p = (char *) 0;
296static int yy_init = 0; /* whether we need to initialize */
297static int yy_start = 0; /* start state number */
298
299/* Flag which is used to allow yywrap()'s to do buffer switches
300 * instead of setting up a fresh yyin. A bit of a hack ...
301 */
302static int yy_did_buffer_switch_on_eof;
303
304void yyrestart (FILE *input_file );
305void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
306YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
307void yy_delete_buffer (YY_BUFFER_STATE b );
308void yy_flush_buffer (YY_BUFFER_STATE b );
309void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
310void yypop_buffer_state (void );
311
312static void yyensure_buffer_stack (void );
313static void yy_load_buffer_state (void );
314static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
315
316#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
317
318YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
319YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
320YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len );
321
322void *yyalloc (yy_size_t );
323void *yyrealloc (void *,yy_size_t );
324void yyfree (void * );
325
326#define yy_new_buffer yy_create_buffer
327
328#define yy_set_interactive(is_interactive) \
329 { \
330 if ( ! YY_CURRENT_BUFFER ){ \
331 yyensure_buffer_stack (); \
332 YY_CURRENT_BUFFER_LVALUE = \
333 yy_create_buffer(yyin,YY_BUF_SIZE ); \
334 } \
335 YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
336 }
337
338#define yy_set_bol(at_bol) \
339 { \
340 if ( ! YY_CURRENT_BUFFER ){\
341 yyensure_buffer_stack (); \
342 YY_CURRENT_BUFFER_LVALUE = \
343 yy_create_buffer(yyin,YY_BUF_SIZE ); \
344 } \
345 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
346 }
347
348#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
349
350/* Begin user sect3 */
351
352#define yywrap() 1
353#define YY_SKIP_YYWRAP
354
355typedef unsigned char YY_CHAR;
356
357FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
358
359typedef int yy_state_type;
360
361extern int yylineno;
362
363int yylineno = 1;
364
365extern char *yytext;
366#define yytext_ptr yytext
367
368static yy_state_type yy_get_previous_state (void );
369static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
370static int yy_get_next_buffer (void );
371static void yy_fatal_error (yyconst char msg[] );
372
373/* Done after the current pattern has been matched and before the
374 * corresponding action - sets up yytext.
375 */
376#define YY_DO_BEFORE_ACTION \
377 (yytext_ptr) = yy_bp; \
378 yyleng = (size_t) (yy_cp - yy_bp); \
379 (yy_hold_char) = *yy_cp; \
380 *yy_cp = '\0'; \
381 (yy_c_buf_p) = yy_cp;
382
383#define YY_NUM_RULES 20
384#define YY_END_OF_BUFFER 21
385/* This struct is not used in this scanner,
386 but its presence is necessary. */
387struct yy_trans_info
388 {
389 flex_int32_t yy_verify;
390 flex_int32_t yy_nxt;
391 };
392static yyconst flex_int16_t yy_accept[94] =
393 { 0,
394 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
395 21, 19, 16, 16, 19, 19, 19, 8, 8, 19,
396 8, 19, 19, 19, 19, 14, 15, 15, 19, 9,
397 9, 16, 0, 3, 0, 0, 10, 0, 0, 0,
398 0, 0, 0, 8, 8, 6, 0, 7, 0, 2,
399 0, 13, 13, 15, 15, 9, 0, 12, 10, 0,
400 0, 0, 0, 18, 0, 0, 0, 2, 9, 0,
401 17, 0, 0, 0, 11, 0, 0, 0, 0, 0,
402 0, 0, 0, 0, 4, 0, 0, 1, 0, 0,
403 0, 5, 0
404
405 } ;
406
407static yyconst flex_int32_t yy_ec[256] =
408 { 0,
409 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
410 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
411 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
412 1, 2, 1, 4, 5, 1, 1, 6, 1, 1,
413 1, 7, 8, 8, 9, 8, 10, 11, 12, 13,
414 13, 13, 13, 13, 13, 13, 13, 14, 1, 1,
415 1, 1, 8, 8, 15, 15, 15, 15, 15, 15,
416 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
417 16, 16, 16, 16, 16, 16, 16, 17, 16, 16,
418 1, 18, 19, 1, 16, 1, 15, 20, 21, 22,
419
420 23, 15, 16, 24, 25, 16, 16, 26, 27, 28,
421 24, 16, 16, 29, 30, 31, 32, 33, 16, 17,
422 16, 16, 34, 1, 35, 1, 1, 1, 1, 1,
423 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
424 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
425 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
426 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
427 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
428 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
429 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
430
431 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
432 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
433 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
434 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
435 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
436 1, 1, 1, 1, 1
437 } ;
438
439static yyconst flex_int32_t yy_meta[36] =
440 { 0,
441 1, 1, 1, 1, 2, 1, 2, 2, 2, 3,
442 4, 4, 4, 5, 6, 7, 7, 1, 1, 6,
443 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
444 7, 7, 7, 8, 1
445 } ;
446
447static yyconst flex_int16_t yy_base[107] =
448 { 0,
449 0, 0, 32, 0, 53, 0, 76, 0, 108, 111,
450 280, 288, 37, 39, 33, 36, 106, 0, 123, 146,
451 255, 251, 45, 0, 159, 288, 0, 53, 108, 172,
452 114, 127, 158, 288, 245, 0, 0, 234, 235, 236,
453 197, 195, 199, 0, 0, 288, 0, 288, 160, 288,
454 183, 288, 0, 0, 183, 182, 0, 0, 0, 0,
455 204, 189, 207, 288, 179, 187, 180, 194, 0, 171,
456 288, 196, 178, 174, 288, 169, 169, 177, 165, 153,
457 143, 155, 137, 118, 288, 122, 42, 288, 36, 36,
458 40, 288, 288, 212, 218, 223, 229, 234, 239, 245,
459
460 251, 255, 262, 270, 275, 280
461 } ;
462
463static yyconst flex_int16_t yy_def[107] =
464 { 0,
465 93, 1, 1, 3, 3, 5, 93, 7, 3, 3,
466 93, 93, 93, 93, 94, 95, 93, 96, 93, 19,
467 19, 20, 97, 98, 20, 93, 99, 100, 95, 93,
468 93, 93, 94, 93, 94, 101, 102, 93, 103, 104,
469 93, 93, 93, 96, 19, 93, 20, 93, 97, 93,
470 97, 93, 20, 99, 100, 93, 105, 101, 102, 106,
471 103, 103, 104, 93, 93, 93, 93, 94, 105, 106,
472 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
473 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
474 93, 93, 0, 93, 93, 93, 93, 93, 93, 93,
475
476 93, 93, 93, 93, 93, 93
477 } ;
478
479static yyconst flex_int16_t yy_nxt[324] =
480 { 0,
481 12, 13, 14, 15, 12, 16, 12, 12, 12, 17,
482 18, 18, 18, 12, 19, 20, 20, 12, 12, 21,
483 19, 21, 19, 22, 20, 20, 20, 20, 20, 20,
484 20, 20, 20, 12, 12, 23, 34, 12, 32, 32,
485 32, 32, 12, 12, 12, 36, 20, 33, 50, 92,
486 35, 20, 20, 20, 20, 20, 15, 54, 91, 54,
487 54, 54, 51, 24, 24, 24, 46, 25, 90, 38,
488 89, 26, 25, 25, 25, 25, 12, 13, 14, 15,
489 27, 12, 27, 27, 27, 17, 27, 27, 27, 12,
490 28, 28, 28, 12, 12, 28, 28, 28, 28, 28,
491
492 28, 28, 28, 28, 28, 28, 28, 28, 28, 12,
493 12, 15, 39, 29, 15, 40, 29, 93, 30, 31,
494 31, 30, 31, 31, 56, 56, 56, 41, 32, 32,
495 42, 88, 43, 45, 45, 45, 46, 45, 47, 47,
496 87, 38, 45, 45, 45, 45, 47, 47, 47, 47,
497 47, 47, 47, 47, 47, 47, 47, 47, 47, 86,
498 47, 34, 33, 50, 85, 47, 47, 47, 47, 53,
499 53, 53, 84, 53, 83, 35, 82, 51, 53, 53,
500 53, 53, 56, 56, 56, 93, 68, 54, 57, 54,
501 54, 54, 56, 56, 56, 62, 46, 34, 71, 81,
502
503 80, 79, 78, 77, 76, 75, 74, 73, 72, 64,
504 62, 35, 33, 33, 33, 33, 33, 33, 33, 33,
505 37, 67, 66, 37, 37, 37, 44, 65, 44, 49,
506 49, 49, 49, 49, 49, 49, 49, 52, 64, 52,
507 54, 62, 54, 60, 54, 54, 55, 93, 55, 55,
508 55, 55, 58, 58, 58, 48, 58, 58, 59, 48,
509 59, 59, 61, 61, 61, 61, 61, 61, 61, 61,
510 63, 63, 63, 63, 63, 63, 63, 63, 69, 93,
511 69, 70, 70, 70, 93, 70, 70, 11, 93, 93,
512 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
513
514 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
515 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
516 93, 93, 93
517 } ;
518
519static yyconst flex_int16_t yy_chk[324] =
520 { 0,
521 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
522 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
523 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
524 1, 1, 1, 1, 1, 3, 15, 3, 13, 13,
525 14, 14, 3, 3, 3, 16, 3, 23, 23, 91,
526 15, 3, 3, 3, 3, 3, 5, 28, 90, 28,
527 28, 28, 23, 5, 5, 5, 28, 5, 89, 16,
528 87, 5, 5, 5, 5, 5, 7, 7, 7, 7,
529 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
530 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
531
532 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
533 7, 9, 17, 9, 10, 17, 10, 29, 9, 9,
534 9, 10, 10, 10, 31, 31, 31, 17, 32, 32,
535 17, 86, 17, 19, 19, 19, 19, 19, 19, 19,
536 84, 29, 19, 19, 19, 19, 19, 19, 19, 19,
537 19, 19, 19, 19, 19, 19, 20, 20, 20, 83,
538 20, 33, 49, 49, 82, 20, 20, 20, 20, 25,
539 25, 25, 81, 25, 80, 33, 79, 49, 25, 25,
540 25, 25, 30, 30, 30, 51, 51, 55, 30, 55,
541 55, 55, 56, 56, 56, 62, 55, 68, 62, 78,
542
543 77, 76, 74, 73, 72, 70, 67, 66, 65, 63,
544 61, 68, 94, 94, 94, 94, 94, 94, 94, 94,
545 95, 43, 42, 95, 95, 95, 96, 41, 96, 97,
546 97, 97, 97, 97, 97, 97, 97, 98, 40, 98,
547 99, 39, 99, 38, 99, 99, 100, 35, 100, 100,
548 100, 100, 101, 101, 101, 22, 101, 101, 102, 21,
549 102, 102, 103, 103, 103, 103, 103, 103, 103, 103,
550 104, 104, 104, 104, 104, 104, 104, 104, 105, 11,
551 105, 106, 106, 106, 0, 106, 106, 93, 93, 93,
552 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
553
554 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
555 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
556 93, 93, 93
557 } ;
558
559/* Table of booleans, true if rule could match eol. */
560static yyconst flex_int32_t yy_rule_can_match_eol[21] =
561 { 0,
5620, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
563 0, };
564
565static yy_state_type yy_last_accepting_state;
566static char *yy_last_accepting_cpos;
567
568extern int yy_flex_debug;
569int yy_flex_debug = 0;
570
571/* The intent behind this definition is that it'll catch
572 * any uses of REJECT which flex missed.
573 */
574#define REJECT reject_used_but_not_detected
575#define yymore() yymore_used_but_not_detected
576#define YY_MORE_ADJ 0
577#define YY_RESTORE_YY_MORE_OFFSET
578char *yytext;
579#line 1 "dtc-lexer.l"
580/*
581 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
582 *
583 *
584 * This program is free software; you can redistribute it and/or
585 * modify it under the terms of the GNU General Public License as
586 * published by the Free Software Foundation; either version 2 of the
587 * License, or (at your option) any later version.
588 *
589 * This program is distributed in the hope that it will be useful,
590 * but WITHOUT ANY WARRANTY; without even the implied warranty of
591 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
592 * General Public License for more details.
593 *
594 * You should have received a copy of the GNU General Public License
595 * along with this program; if not, write to the Free Software
596 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
597 * USA
598 */
599
600
601
602
603#line 33 "dtc-lexer.l"
604#include "dtc.h"
605#include "srcpos.h"
606#include "dtc-parser.tab.h"
607
608
609/*#define LEXDEBUG 1*/
610
611#ifdef LEXDEBUG
612#define DPRINT(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
613#else
614#define DPRINT(fmt, ...) do { } while (0)
615#endif
616
617static int dts_version; /* = 0 */
618
619#define BEGIN_DEFAULT() if (dts_version == 0) { \
620 DPRINT("<INITIAL>\n"); \
621 BEGIN(INITIAL); \
622 } else { \
623 DPRINT("<V1>\n"); \
624 BEGIN(V1); \
625 }
626#line 627 "dtc-lexer.lex.c"
627
628#define INITIAL 0
629#define INCLUDE 1
630#define BYTESTRING 2
631#define PROPNODENAME 3
632#define V1 4
633
634#ifndef YY_NO_UNISTD_H
635/* Special case for "unistd.h", since it is non-ANSI. We include it way
636 * down here because we want the user's section 1 to have been scanned first.
637 * The user has a chance to override it with an option.
638 */
639#include <unistd.h>
640#endif
641
642#ifndef YY_EXTRA_TYPE
643#define YY_EXTRA_TYPE void *
644#endif
645
646static int yy_init_globals (void );
647
648/* Macros after this point can all be overridden by user definitions in
649 * section 1.
650 */
651
652#ifndef YY_SKIP_YYWRAP
653#ifdef __cplusplus
654extern "C" int yywrap (void );
655#else
656extern int yywrap (void );
657#endif
658#endif
659
660#ifndef yytext_ptr
661static void yy_flex_strncpy (char *,yyconst char *,int );
662#endif
663
664#ifdef YY_NEED_STRLEN
665static int yy_flex_strlen (yyconst char * );
666#endif
667
668#ifndef YY_NO_INPUT
669
670#ifdef __cplusplus
671static int yyinput (void );
672#else
673static int input (void );
674#endif
675
676#endif
677
678/* Amount of stuff to slurp up with each read. */
679#ifndef YY_READ_BUF_SIZE
680#define YY_READ_BUF_SIZE 8192
681#endif
682
683/* Copy whatever the last rule matched to the standard output. */
684#ifndef ECHO
685/* This used to be an fputs(), but since the string might contain NUL's,
686 * we now use fwrite().
687 */
688#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
689#endif
690
691/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
692 * is returned in "result".
693 */
694#ifndef YY_INPUT
695#define YY_INPUT(buf,result,max_size) \
696 if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
697 { \
698 int c = '*'; \
699 size_t n; \
700 for ( n = 0; n < max_size && \
701 (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
702 buf[n] = (char) c; \
703 if ( c == '\n' ) \
704 buf[n++] = (char) c; \
705 if ( c == EOF && ferror( yyin ) ) \
706 YY_FATAL_ERROR( "input in flex scanner failed" ); \
707 result = n; \
708 } \
709 else \
710 { \
711 errno=0; \
712 while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
713 { \
714 if( errno != EINTR) \
715 { \
716 YY_FATAL_ERROR( "input in flex scanner failed" ); \
717 break; \
718 } \
719 errno=0; \
720 clearerr(yyin); \
721 } \
722 }\
723\
724
725#endif
726
727/* No semi-colon after return; correct usage is to write "yyterminate();" -
728 * we don't want an extra ';' after the "return" because that will cause
729 * some compilers to complain about unreachable statements.
730 */
731#ifndef yyterminate
732#define yyterminate() return YY_NULL
733#endif
734
735/* Number of entries by which start-condition stack grows. */
736#ifndef YY_START_STACK_INCR
737#define YY_START_STACK_INCR 25
738#endif
739
740/* Report a fatal error. */
741#ifndef YY_FATAL_ERROR
742#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
743#endif
744
745/* end tables serialization structures and prototypes */
746
747/* Default declaration of generated scanner - a define so the user can
748 * easily add parameters.
749 */
750#ifndef YY_DECL
751#define YY_DECL_IS_OURS 1
752
753extern int yylex (void);
754
755#define YY_DECL int yylex (void)
756#endif /* !YY_DECL */
757
758/* Code executed at the beginning of each rule, after yytext and yyleng
759 * have been set up.
760 */
761#ifndef YY_USER_ACTION
762#define YY_USER_ACTION
763#endif
764
765/* Code executed at the end of each rule. */
766#ifndef YY_BREAK
767#define YY_BREAK break;
768#endif
769
770#define YY_RULE_SETUP \
771 YY_USER_ACTION
772
773/** The main scanner function which does all the work.
774 */
775YY_DECL
776{
777 register yy_state_type yy_current_state;
778 register char *yy_cp, *yy_bp;
779 register int yy_act;
780
781#line 57 "dtc-lexer.l"
782
783#line 784 "dtc-lexer.lex.c"
784
785 if ( !(yy_init) )
786 {
787 (yy_init) = 1;
788
789#ifdef YY_USER_INIT
790 YY_USER_INIT;
791#endif
792
793 if ( ! (yy_start) )
794 (yy_start) = 1; /* first start state */
795
796 if ( ! yyin )
797 yyin = stdin;
798
799 if ( ! yyout )
800 yyout = stdout;
801
802 if ( ! YY_CURRENT_BUFFER ) {
803 yyensure_buffer_stack ();
804 YY_CURRENT_BUFFER_LVALUE =
805 yy_create_buffer(yyin,YY_BUF_SIZE );
806 }
807
808 yy_load_buffer_state( );
809 }
810
811 while ( 1 ) /* loops until end-of-file is reached */
812 {
813 yy_cp = (yy_c_buf_p);
814
815 /* Support of yytext. */
816 *yy_cp = (yy_hold_char);
817
818 /* yy_bp points to the position in yy_ch_buf of the start of
819 * the current run.
820 */
821 yy_bp = yy_cp;
822
823 yy_current_state = (yy_start);
824yy_match:
825 do
826 {
827 register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
828 if ( yy_accept[yy_current_state] )
829 {
830 (yy_last_accepting_state) = yy_current_state;
831 (yy_last_accepting_cpos) = yy_cp;
832 }
833 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
834 {
835 yy_current_state = (int) yy_def[yy_current_state];
836 if ( yy_current_state >= 94 )
837 yy_c = yy_meta[(unsigned int) yy_c];
838 }
839 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
840 ++yy_cp;
841 }
842 while ( yy_base[yy_current_state] != 288 );
843
844yy_find_action:
845 yy_act = yy_accept[yy_current_state];
846 if ( yy_act == 0 )
847 { /* have to back up */
848 yy_cp = (yy_last_accepting_cpos);
849 yy_current_state = (yy_last_accepting_state);
850 yy_act = yy_accept[yy_current_state];
851 }
852
853 YY_DO_BEFORE_ACTION;
854
855 if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
856 {
857 int yyl;
858 for ( yyl = 0; yyl < yyleng; ++yyl )
859 if ( yytext[yyl] == '\n' )
860
861 yylineno++;
862;
863 }
864
865do_action: /* This label is used only to access EOF actions. */
866
867 switch ( yy_act )
868 { /* beginning of action switch */
869 case 0: /* must back up */
870 /* undo the effects of YY_DO_BEFORE_ACTION */
871 *yy_cp = (yy_hold_char);
872 yy_cp = (yy_last_accepting_cpos);
873 yy_current_state = (yy_last_accepting_state);
874 goto yy_find_action;
875
876case 1:
877YY_RULE_SETUP
878#line 58 "dtc-lexer.l"
879BEGIN(INCLUDE);
880 YY_BREAK
881case 2:
882YY_RULE_SETUP
883#line 60 "dtc-lexer.l"
884{
885 yytext[strlen(yytext) - 1] = 0;
886 if (!push_input_file(yytext + 1)) {
887 /* Some unrecoverable error.*/
888 exit(1);
889 }
890 BEGIN_DEFAULT();
891 }
892 YY_BREAK
893case YY_STATE_EOF(INITIAL):
894case YY_STATE_EOF(INCLUDE):
895case YY_STATE_EOF(BYTESTRING):
896case YY_STATE_EOF(PROPNODENAME):
897case YY_STATE_EOF(V1):
898#line 70 "dtc-lexer.l"
899{
900 if (!pop_input_file()) {
901 yyterminate();
902 }
903 }
904 YY_BREAK
905case 3:
906/* rule 3 can match eol */
907YY_RULE_SETUP
908#line 76 "dtc-lexer.l"
909{
910 yylloc.filenum = srcpos_filenum;
911 yylloc.first_line = yylineno;
912 DPRINT("String: %s\n", yytext);
913 yylval.data = data_copy_escape_string(yytext+1,
914 yyleng-2);
915 yylloc.first_line = yylineno;
916 return DT_STRING;
917 }
918 YY_BREAK
919case 4:
920YY_RULE_SETUP
921#line 86 "dtc-lexer.l"
922{
923 yylloc.filenum = srcpos_filenum;
924 yylloc.first_line = yylineno;
925 DPRINT("Keyword: /dts-v1/\n");
926 dts_version = 1;
927 BEGIN_DEFAULT();
928 return DT_V1;
929 }
930 YY_BREAK
931case 5:
932YY_RULE_SETUP
933#line 95 "dtc-lexer.l"
934{
935 yylloc.filenum = srcpos_filenum;
936 yylloc.first_line = yylineno;
937 DPRINT("Keyword: /memreserve/\n");
938 BEGIN_DEFAULT();
939 return DT_MEMRESERVE;
940 }
941 YY_BREAK
942case 6:
943YY_RULE_SETUP
944#line 103 "dtc-lexer.l"
945{
946 yylloc.filenum = srcpos_filenum;
947 yylloc.first_line = yylineno;
948 DPRINT("Label: %s\n", yytext);
949 yylval.labelref = strdup(yytext);
950 yylval.labelref[yyleng-1] = '\0';
951 return DT_LABEL;
952 }
953 YY_BREAK
954case 7:
955YY_RULE_SETUP
956#line 112 "dtc-lexer.l"
957{
958 yylloc.filenum = srcpos_filenum;
959 yylloc.first_line = yylineno;
960 if (*yytext == 'b')
961 yylval.cbase = 2;
962 else if (*yytext == 'o')
963 yylval.cbase = 8;
964 else if (*yytext == 'd')
965 yylval.cbase = 10;
966 else
967 yylval.cbase = 16;
968 DPRINT("Base: %d\n", yylval.cbase);
969 return DT_BASE;
970 }
971 YY_BREAK
972case 8:
973YY_RULE_SETUP
974#line 127 "dtc-lexer.l"
975{
976 yylloc.filenum = srcpos_filenum;
977 yylloc.first_line = yylineno;
978 yylval.literal = strdup(yytext);
979 DPRINT("Literal: '%s'\n", yylval.literal);
980 return DT_LEGACYLITERAL;
981 }
982 YY_BREAK
983case 9:
984YY_RULE_SETUP
985#line 135 "dtc-lexer.l"
986{
987 yylloc.filenum = srcpos_filenum;
988 yylloc.first_line = yylineno;
989 yylval.literal = strdup(yytext);
990 DPRINT("Literal: '%s'\n", yylval.literal);
991 return DT_LITERAL;
992 }
993 YY_BREAK
994case 10:
995YY_RULE_SETUP
996#line 143 "dtc-lexer.l"
997{ /* label reference */
998 yylloc.filenum = srcpos_filenum;
999 yylloc.first_line = yylineno;
1000 DPRINT("Ref: %s\n", yytext+1);
1001 yylval.labelref = strdup(yytext+1);
1002 return DT_REF;
1003 }
1004 YY_BREAK
1005case 11:
1006YY_RULE_SETUP
1007#line 151 "dtc-lexer.l"
1008{ /* new-style path reference */
1009 yylloc.filenum = srcpos_filenum;
1010 yylloc.first_line = yylineno;
1011 yytext[yyleng-1] = '\0';
1012 DPRINT("Ref: %s\n", yytext+2);
1013 yylval.labelref = strdup(yytext+2);
1014 return DT_REF;
1015 }
1016 YY_BREAK
1017case 12:
1018YY_RULE_SETUP
1019#line 160 "dtc-lexer.l"
1020{ /* old-style path reference */
1021 yylloc.filenum = srcpos_filenum;
1022 yylloc.first_line = yylineno;
1023 DPRINT("Ref: %s\n", yytext+1);
1024 yylval.labelref = strdup(yytext+1);
1025 return DT_REF;
1026 }
1027 YY_BREAK
1028case 13:
1029YY_RULE_SETUP
1030#line 168 "dtc-lexer.l"
1031{
1032 yylloc.filenum = srcpos_filenum;
1033 yylloc.first_line = yylineno;
1034 yylval.byte = strtol(yytext, NULL, 16);
1035 DPRINT("Byte: %02x\n", (int)yylval.byte);
1036 return DT_BYTE;
1037 }
1038 YY_BREAK
1039case 14:
1040YY_RULE_SETUP
1041#line 176 "dtc-lexer.l"
1042{
1043 yylloc.filenum = srcpos_filenum;
1044 yylloc.first_line = yylineno;
1045 DPRINT("/BYTESTRING\n");
1046 BEGIN_DEFAULT();
1047 return ']';
1048 }
1049 YY_BREAK
1050case 15:
1051YY_RULE_SETUP
1052#line 184 "dtc-lexer.l"
1053{
1054 yylloc.filenum = srcpos_filenum;
1055 yylloc.first_line = yylineno;
1056 DPRINT("PropNodeName: %s\n", yytext);
1057 yylval.propnodename = strdup(yytext);
1058 BEGIN_DEFAULT();
1059 return DT_PROPNODENAME;
1060 }
1061 YY_BREAK
1062case 16:
1063/* rule 16 can match eol */
1064YY_RULE_SETUP
1065#line 194 "dtc-lexer.l"
1066/* eat whitespace */
1067 YY_BREAK
1068case 17:
1069/* rule 17 can match eol */
1070YY_RULE_SETUP
1071#line 196 "dtc-lexer.l"
1072{
1073 yylloc.filenum = srcpos_filenum;
1074 yylloc.first_line = yylineno;
1075 DPRINT("Comment: %s\n", yytext);
1076 /* eat comments */
1077 }
1078 YY_BREAK
1079case 18:
1080/* rule 18 can match eol */
1081YY_RULE_SETUP
1082#line 203 "dtc-lexer.l"
1083/* eat line comments */
1084 YY_BREAK
1085case 19:
1086YY_RULE_SETUP
1087#line 205 "dtc-lexer.l"
1088{
1089 yylloc.filenum = srcpos_filenum;
1090 yylloc.first_line = yylineno;
1091 DPRINT("Char: %c (\\x%02x)\n", yytext[0],
1092 (unsigned)yytext[0]);
1093 if (yytext[0] == '[') {
1094 DPRINT("<BYTESTRING>\n");
1095 BEGIN(BYTESTRING);
1096 }
1097 if ((yytext[0] == '{')
1098 || (yytext[0] == ';')) {
1099 DPRINT("<PROPNODENAME>\n");
1100 BEGIN(PROPNODENAME);
1101 }
1102 return yytext[0];
1103 }
1104 YY_BREAK
1105case 20:
1106YY_RULE_SETUP
1107#line 222 "dtc-lexer.l"
1108ECHO;
1109 YY_BREAK
1110#line 1111 "dtc-lexer.lex.c"
1111
1112 case YY_END_OF_BUFFER:
1113 {
1114 /* Amount of text matched not including the EOB char. */
1115 int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
1116
1117 /* Undo the effects of YY_DO_BEFORE_ACTION. */
1118 *yy_cp = (yy_hold_char);
1119 YY_RESTORE_YY_MORE_OFFSET
1120
1121 if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
1122 {
1123 /* We're scanning a new file or input source. It's
1124 * possible that this happened because the user
1125 * just pointed yyin at a new source and called
1126 * yylex(). If so, then we have to assure
1127 * consistency between YY_CURRENT_BUFFER and our
1128 * globals. Here is the right place to do so, because
1129 * this is the first action (other than possibly a
1130 * back-up) that will match for the new input source.
1131 */
1132 (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
1133 YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
1134 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
1135 }
1136
1137 /* Note that here we test for yy_c_buf_p "<=" to the position
1138 * of the first EOB in the buffer, since yy_c_buf_p will
1139 * already have been incremented past the NUL character
1140 * (since all states make transitions on EOB to the
1141 * end-of-buffer state). Contrast this with the test
1142 * in input().
1143 */
1144 if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
1145 { /* This was really a NUL. */
1146 yy_state_type yy_next_state;
1147
1148 (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
1149
1150 yy_current_state = yy_get_previous_state( );
1151
1152 /* Okay, we're now positioned to make the NUL
1153 * transition. We couldn't have
1154 * yy_get_previous_state() go ahead and do it
1155 * for us because it doesn't know how to deal
1156 * with the possibility of jamming (and we don't
1157 * want to build jamming into it because then it
1158 * will run more slowly).
1159 */
1160
1161 yy_next_state = yy_try_NUL_trans( yy_current_state );
1162
1163 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
1164
1165 if ( yy_next_state )
1166 {
1167 /* Consume the NUL. */
1168 yy_cp = ++(yy_c_buf_p);
1169 yy_current_state = yy_next_state;
1170 goto yy_match;
1171 }
1172
1173 else
1174 {
1175 yy_cp = (yy_c_buf_p);
1176 goto yy_find_action;
1177 }
1178 }
1179
1180 else switch ( yy_get_next_buffer( ) )
1181 {
1182 case EOB_ACT_END_OF_FILE:
1183 {
1184 (yy_did_buffer_switch_on_eof) = 0;
1185
1186 if ( yywrap( ) )
1187 {
1188 /* Note: because we've taken care in
1189 * yy_get_next_buffer() to have set up
1190 * yytext, we can now set up
1191 * yy_c_buf_p so that if some total
1192 * hoser (like flex itself) wants to
1193 * call the scanner after we return the
1194 * YY_NULL, it'll still work - another
1195 * YY_NULL will get returned.
1196 */
1197 (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
1198
1199 yy_act = YY_STATE_EOF(YY_START);
1200 goto do_action;
1201 }
1202
1203 else
1204 {
1205 if ( ! (yy_did_buffer_switch_on_eof) )
1206 YY_NEW_FILE;
1207 }
1208 break;
1209 }
1210
1211 case EOB_ACT_CONTINUE_SCAN:
1212 (yy_c_buf_p) =
1213 (yytext_ptr) + yy_amount_of_matched_text;
1214
1215 yy_current_state = yy_get_previous_state( );
1216
1217 yy_cp = (yy_c_buf_p);
1218 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
1219 goto yy_match;
1220
1221 case EOB_ACT_LAST_MATCH:
1222 (yy_c_buf_p) =
1223 &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
1224
1225 yy_current_state = yy_get_previous_state( );
1226
1227 yy_cp = (yy_c_buf_p);
1228 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
1229 goto yy_find_action;
1230 }
1231 break;
1232 }
1233
1234 default:
1235 YY_FATAL_ERROR(
1236 "fatal flex scanner internal error--no action found" );
1237 } /* end of action switch */
1238 } /* end of scanning one token */
1239} /* end of yylex */
1240
1241/* yy_get_next_buffer - try to read in a new buffer
1242 *
1243 * Returns a code representing an action:
1244 * EOB_ACT_LAST_MATCH -
1245 * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
1246 * EOB_ACT_END_OF_FILE - end of file
1247 */
1248static int yy_get_next_buffer (void)
1249{
1250 register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
1251 register char *source = (yytext_ptr);
1252 register int number_to_move, i;
1253 int ret_val;
1254
1255 if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
1256 YY_FATAL_ERROR(
1257 "fatal flex scanner internal error--end of buffer missed" );
1258
1259 if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
1260 { /* Don't try to fill the buffer, so this is an EOF. */
1261 if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
1262 {
1263 /* We matched a single character, the EOB, so
1264 * treat this as a final EOF.
1265 */
1266 return EOB_ACT_END_OF_FILE;
1267 }
1268
1269 else
1270 {
1271 /* We matched some text prior to the EOB, first
1272 * process it.
1273 */
1274 return EOB_ACT_LAST_MATCH;
1275 }
1276 }
1277
1278 /* Try to read more data. */
1279
1280 /* First move last chars to start of buffer. */
1281 number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
1282
1283 for ( i = 0; i < number_to_move; ++i )
1284 *(dest++) = *(source++);
1285
1286 if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
1287 /* don't do the read, it's not guaranteed to return an EOF,
1288 * just force an EOF
1289 */
1290 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
1291
1292 else
1293 {
1294 int num_to_read =
1295 YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
1296
1297 while ( num_to_read <= 0 )
1298 { /* Not enough room in the buffer - grow it. */
1299
1300 /* just a shorter name for the current buffer */
1301 YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
1302
1303 int yy_c_buf_p_offset =
1304 (int) ((yy_c_buf_p) - b->yy_ch_buf);
1305
1306 if ( b->yy_is_our_buffer )
1307 {
1308 int new_size = b->yy_buf_size * 2;
1309
1310 if ( new_size <= 0 )
1311 b->yy_buf_size += b->yy_buf_size / 8;
1312 else
1313 b->yy_buf_size *= 2;
1314
1315 b->yy_ch_buf = (char *)
1316 /* Include room in for 2 EOB chars. */
1317 yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
1318 }
1319 else
1320 /* Can't grow it, we don't own it. */
1321 b->yy_ch_buf = 0;
1322
1323 if ( ! b->yy_ch_buf )
1324 YY_FATAL_ERROR(
1325 "fatal error - scanner input buffer overflow" );
1326
1327 (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
1328
1329 num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
1330 number_to_move - 1;
1331
1332 }
1333
1334 if ( num_to_read > YY_READ_BUF_SIZE )
1335 num_to_read = YY_READ_BUF_SIZE;
1336
1337 /* Read in more data. */
1338 YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
1339 (yy_n_chars), (size_t) num_to_read );
1340
1341 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1342 }
1343
1344 if ( (yy_n_chars) == 0 )
1345 {
1346 if ( number_to_move == YY_MORE_ADJ )
1347 {
1348 ret_val = EOB_ACT_END_OF_FILE;
1349 yyrestart(yyin );
1350 }
1351
1352 else
1353 {
1354 ret_val = EOB_ACT_LAST_MATCH;
1355 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
1356 YY_BUFFER_EOF_PENDING;
1357 }
1358 }
1359
1360 else
1361 ret_val = EOB_ACT_CONTINUE_SCAN;
1362
1363 (yy_n_chars) += number_to_move;
1364 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
1365 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
1366
1367 (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
1368
1369 return ret_val;
1370}
1371
1372/* yy_get_previous_state - get the state just before the EOB char was reached */
1373
1374 static yy_state_type yy_get_previous_state (void)
1375{
1376 register yy_state_type yy_current_state;
1377 register char *yy_cp;
1378
1379 yy_current_state = (yy_start);
1380
1381 for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
1382 {
1383 register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
1384 if ( yy_accept[yy_current_state] )
1385 {
1386 (yy_last_accepting_state) = yy_current_state;
1387 (yy_last_accepting_cpos) = yy_cp;
1388 }
1389 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1390 {
1391 yy_current_state = (int) yy_def[yy_current_state];
1392 if ( yy_current_state >= 94 )
1393 yy_c = yy_meta[(unsigned int) yy_c];
1394 }
1395 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
1396 }
1397
1398 return yy_current_state;
1399}
1400
1401/* yy_try_NUL_trans - try to make a transition on the NUL character
1402 *
1403 * synopsis
1404 * next_state = yy_try_NUL_trans( current_state );
1405 */
1406 static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
1407{
1408 register int yy_is_jam;
1409 register char *yy_cp = (yy_c_buf_p);
1410
1411 register YY_CHAR yy_c = 1;
1412 if ( yy_accept[yy_current_state] )
1413 {
1414 (yy_last_accepting_state) = yy_current_state;
1415 (yy_last_accepting_cpos) = yy_cp;
1416 }
1417 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1418 {
1419 yy_current_state = (int) yy_def[yy_current_state];
1420 if ( yy_current_state >= 94 )
1421 yy_c = yy_meta[(unsigned int) yy_c];
1422 }
1423 yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
1424 yy_is_jam = (yy_current_state == 93);
1425
1426 return yy_is_jam ? 0 : yy_current_state;
1427}
1428
1429#ifndef YY_NO_INPUT
1430#ifdef __cplusplus
1431 static int yyinput (void)
1432#else
1433 static int input (void)
1434#endif
1435
1436{
1437 int c;
1438
1439 *(yy_c_buf_p) = (yy_hold_char);
1440
1441 if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
1442 {
1443 /* yy_c_buf_p now points to the character we want to return.
1444 * If this occurs *before* the EOB characters, then it's a
1445 * valid NUL; if not, then we've hit the end of the buffer.
1446 */
1447 if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
1448 /* This was really a NUL. */
1449 *(yy_c_buf_p) = '\0';
1450
1451 else
1452 { /* need more input */
1453 int offset = (yy_c_buf_p) - (yytext_ptr);
1454 ++(yy_c_buf_p);
1455
1456 switch ( yy_get_next_buffer( ) )
1457 {
1458 case EOB_ACT_LAST_MATCH:
1459 /* This happens because yy_g_n_b()
1460 * sees that we've accumulated a
1461 * token and flags that we need to
1462 * try matching the token before
1463 * proceeding. But for input(),
1464 * there's no matching to consider.
1465 * So convert the EOB_ACT_LAST_MATCH
1466 * to EOB_ACT_END_OF_FILE.
1467 */
1468
1469 /* Reset buffer status. */
1470 yyrestart(yyin );
1471
1472 /*FALLTHROUGH*/
1473
1474 case EOB_ACT_END_OF_FILE:
1475 {
1476 if ( yywrap( ) )
1477 return EOF;
1478
1479 if ( ! (yy_did_buffer_switch_on_eof) )
1480 YY_NEW_FILE;
1481#ifdef __cplusplus
1482 return yyinput();
1483#else
1484 return input();
1485#endif
1486 }
1487
1488 case EOB_ACT_CONTINUE_SCAN:
1489 (yy_c_buf_p) = (yytext_ptr) + offset;
1490 break;
1491 }
1492 }
1493 }
1494
1495 c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
1496 *(yy_c_buf_p) = '\0'; /* preserve yytext */
1497 (yy_hold_char) = *++(yy_c_buf_p);
1498
1499 if ( c == '\n' )
1500
1501 yylineno++;
1502;
1503
1504 return c;
1505}
1506#endif /* ifndef YY_NO_INPUT */
1507
1508/** Immediately switch to a different input stream.
1509 * @param input_file A readable stream.
1510 *
1511 * @note This function does not reset the start condition to @c INITIAL .
1512 */
1513 void yyrestart (FILE * input_file )
1514{
1515
1516 if ( ! YY_CURRENT_BUFFER ){
1517 yyensure_buffer_stack ();
1518 YY_CURRENT_BUFFER_LVALUE =
1519 yy_create_buffer(yyin,YY_BUF_SIZE );
1520 }
1521
1522 yy_init_buffer(YY_CURRENT_BUFFER,input_file );
1523 yy_load_buffer_state( );
1524}
1525
1526/** Switch to a different input buffer.
1527 * @param new_buffer The new input buffer.
1528 *
1529 */
1530 void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
1531{
1532
1533 /* TODO. We should be able to replace this entire function body
1534 * with
1535 * yypop_buffer_state();
1536 * yypush_buffer_state(new_buffer);
1537 */
1538 yyensure_buffer_stack ();
1539 if ( YY_CURRENT_BUFFER == new_buffer )
1540 return;
1541
1542 if ( YY_CURRENT_BUFFER )
1543 {
1544 /* Flush out information for old buffer. */
1545 *(yy_c_buf_p) = (yy_hold_char);
1546 YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
1547 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1548 }
1549
1550 YY_CURRENT_BUFFER_LVALUE = new_buffer;
1551 yy_load_buffer_state( );
1552
1553 /* We don't actually know whether we did this switch during
1554 * EOF (yywrap()) processing, but the only time this flag
1555 * is looked at is after yywrap() is called, so it's safe
1556 * to go ahead and always set it.
1557 */
1558 (yy_did_buffer_switch_on_eof) = 1;
1559}
1560
1561static void yy_load_buffer_state (void)
1562{
1563 (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
1564 (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
1565 yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
1566 (yy_hold_char) = *(yy_c_buf_p);
1567}
1568
1569/** Allocate and initialize an input buffer state.
1570 * @param file A readable stream.
1571 * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
1572 *
1573 * @return the allocated buffer state.
1574 */
1575 YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
1576{
1577 YY_BUFFER_STATE b;
1578
1579 b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
1580 if ( ! b )
1581 YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
1582
1583 b->yy_buf_size = size;
1584
1585 /* yy_ch_buf has to be 2 characters longer than the size given because
1586 * we need to put in 2 end-of-buffer characters.
1587 */
1588 b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
1589 if ( ! b->yy_ch_buf )
1590 YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
1591
1592 b->yy_is_our_buffer = 1;
1593
1594 yy_init_buffer(b,file );
1595
1596 return b;
1597}
1598
1599/** Destroy the buffer.
1600 * @param b a buffer created with yy_create_buffer()
1601 *
1602 */
1603 void yy_delete_buffer (YY_BUFFER_STATE b )
1604{
1605
1606 if ( ! b )
1607 return;
1608
1609 if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
1610 YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
1611
1612 if ( b->yy_is_our_buffer )
1613 yyfree((void *) b->yy_ch_buf );
1614
1615 yyfree((void *) b );
1616}
1617
1618#ifndef __cplusplus
1619extern int isatty (int );
1620#endif /* __cplusplus */
1621
1622/* Initializes or reinitializes a buffer.
1623 * This function is sometimes called more than once on the same buffer,
1624 * such as during a yyrestart() or at EOF.
1625 */
1626 static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
1627
1628{
1629 int oerrno = errno;
1630
1631 yy_flush_buffer(b );
1632
1633 b->yy_input_file = file;
1634 b->yy_fill_buffer = 1;
1635
1636 /* If b is the current buffer, then yy_init_buffer was _probably_
1637 * called from yyrestart() or through yy_get_next_buffer.
1638 * In that case, we don't want to reset the lineno or column.
1639 */
1640 if (b != YY_CURRENT_BUFFER){
1641 b->yy_bs_lineno = 1;
1642 b->yy_bs_column = 0;
1643 }
1644
1645 b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
1646
1647 errno = oerrno;
1648}
1649
1650/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
1651 * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
1652 *
1653 */
1654 void yy_flush_buffer (YY_BUFFER_STATE b )
1655{
1656 if ( ! b )
1657 return;
1658
1659 b->yy_n_chars = 0;
1660
1661 /* We always need two end-of-buffer characters. The first causes
1662 * a transition to the end-of-buffer state. The second causes
1663 * a jam in that state.
1664 */
1665 b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
1666 b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
1667
1668 b->yy_buf_pos = &b->yy_ch_buf[0];
1669
1670 b->yy_at_bol = 1;
1671 b->yy_buffer_status = YY_BUFFER_NEW;
1672
1673 if ( b == YY_CURRENT_BUFFER )
1674 yy_load_buffer_state( );
1675}
1676
1677/** Pushes the new state onto the stack. The new state becomes
1678 * the current state. This function will allocate the stack
1679 * if necessary.
1680 * @param new_buffer The new state.
1681 *
1682 */
1683void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
1684{
1685 if (new_buffer == NULL)
1686 return;
1687
1688 yyensure_buffer_stack();
1689
1690 /* This block is copied from yy_switch_to_buffer. */
1691 if ( YY_CURRENT_BUFFER )
1692 {
1693 /* Flush out information for old buffer. */
1694 *(yy_c_buf_p) = (yy_hold_char);
1695 YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
1696 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1697 }
1698
1699 /* Only push if top exists. Otherwise, replace top. */
1700 if (YY_CURRENT_BUFFER)
1701 (yy_buffer_stack_top)++;
1702 YY_CURRENT_BUFFER_LVALUE = new_buffer;
1703
1704 /* copied from yy_switch_to_buffer. */
1705 yy_load_buffer_state( );
1706 (yy_did_buffer_switch_on_eof) = 1;
1707}
1708
1709/** Removes and deletes the top of the stack, if present.
1710 * The next element becomes the new top.
1711 *
1712 */
1713void yypop_buffer_state (void)
1714{
1715 if (!YY_CURRENT_BUFFER)
1716 return;
1717
1718 yy_delete_buffer(YY_CURRENT_BUFFER );
1719 YY_CURRENT_BUFFER_LVALUE = NULL;
1720 if ((yy_buffer_stack_top) > 0)
1721 --(yy_buffer_stack_top);
1722
1723 if (YY_CURRENT_BUFFER) {
1724 yy_load_buffer_state( );
1725 (yy_did_buffer_switch_on_eof) = 1;
1726 }
1727}
1728
1729/* Allocates the stack if it does not exist.
1730 * Guarantees space for at least one push.
1731 */
1732static void yyensure_buffer_stack (void)
1733{
1734 int num_to_alloc;
1735
1736 if (!(yy_buffer_stack)) {
1737
1738 /* First allocation is just for 2 elements, since we don't know if this
1739 * scanner will even need a stack. We use 2 instead of 1 to avoid an
1740 * immediate realloc on the next call.
1741 */
1742 num_to_alloc = 1;
1743 (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
1744 (num_to_alloc * sizeof(struct yy_buffer_state*)
1745 );
1746
1747 memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
1748
1749 (yy_buffer_stack_max) = num_to_alloc;
1750 (yy_buffer_stack_top) = 0;
1751 return;
1752 }
1753
1754 if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
1755
1756 /* Increase the buffer to prepare for a possible push. */
1757 int grow_size = 8 /* arbitrary grow size */;
1758
1759 num_to_alloc = (yy_buffer_stack_max) + grow_size;
1760 (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
1761 ((yy_buffer_stack),
1762 num_to_alloc * sizeof(struct yy_buffer_state*)
1763 );
1764
1765 /* zero only the new slots.*/
1766 memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
1767 (yy_buffer_stack_max) = num_to_alloc;
1768 }
1769}
1770
1771/** Setup the input buffer state to scan directly from a user-specified character buffer.
1772 * @param base the character buffer
1773 * @param size the size in bytes of the character buffer
1774 *
1775 * @return the newly allocated buffer state object.
1776 */
1777YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
1778{
1779 YY_BUFFER_STATE b;
1780
1781 if ( size < 2 ||
1782 base[size-2] != YY_END_OF_BUFFER_CHAR ||
1783 base[size-1] != YY_END_OF_BUFFER_CHAR )
1784 /* They forgot to leave room for the EOB's. */
1785 return 0;
1786
1787 b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
1788 if ( ! b )
1789 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
1790
1791 b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
1792 b->yy_buf_pos = b->yy_ch_buf = base;
1793 b->yy_is_our_buffer = 0;
1794 b->yy_input_file = 0;
1795 b->yy_n_chars = b->yy_buf_size;
1796 b->yy_is_interactive = 0;
1797 b->yy_at_bol = 1;
1798 b->yy_fill_buffer = 0;
1799 b->yy_buffer_status = YY_BUFFER_NEW;
1800
1801 yy_switch_to_buffer(b );
1802
1803 return b;
1804}
1805
1806/** Setup the input buffer state to scan a string. The next call to yylex() will
1807 * scan from a @e copy of @a str.
1808 * @param yystr a NUL-terminated string to scan
1809 *
1810 * @return the newly allocated buffer state object.
1811 * @note If you want to scan bytes that may contain NUL values, then use
1812 * yy_scan_bytes() instead.
1813 */
1814YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
1815{
1816
1817 return yy_scan_bytes(yystr,strlen(yystr) );
1818}
1819
1820/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
1821 * scan from a @e copy of @a bytes.
1822 * @param bytes the byte buffer to scan
1823 * @param len the number of bytes in the buffer pointed to by @a bytes.
1824 *
1825 * @return the newly allocated buffer state object.
1826 */
1827YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
1828{
1829 YY_BUFFER_STATE b;
1830 char *buf;
1831 yy_size_t n;
1832 int i;
1833
1834 /* Get memory for full buffer, including space for trailing EOB's. */
1835 n = _yybytes_len + 2;
1836 buf = (char *) yyalloc(n );
1837 if ( ! buf )
1838 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
1839
1840 for ( i = 0; i < _yybytes_len; ++i )
1841 buf[i] = yybytes[i];
1842
1843 buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
1844
1845 b = yy_scan_buffer(buf,n );
1846 if ( ! b )
1847 YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
1848
1849 /* It's okay to grow etc. this buffer, and we should throw it
1850 * away when we're done.
1851 */
1852 b->yy_is_our_buffer = 1;
1853
1854 return b;
1855}
1856
1857#ifndef YY_EXIT_FAILURE
1858#define YY_EXIT_FAILURE 2
1859#endif
1860
1861static void yy_fatal_error (yyconst char* msg )
1862{
1863 (void) fprintf( stderr, "%s\n", msg );
1864 exit( YY_EXIT_FAILURE );
1865}
1866
1867/* Redefine yyless() so it works in section 3 code. */
1868
1869#undef yyless
1870#define yyless(n) \
1871 do \
1872 { \
1873 /* Undo effects of setting up yytext. */ \
1874 int yyless_macro_arg = (n); \
1875 YY_LESS_LINENO(yyless_macro_arg);\
1876 yytext[yyleng] = (yy_hold_char); \
1877 (yy_c_buf_p) = yytext + yyless_macro_arg; \
1878 (yy_hold_char) = *(yy_c_buf_p); \
1879 *(yy_c_buf_p) = '\0'; \
1880 yyleng = yyless_macro_arg; \
1881 } \
1882 while ( 0 )
1883
1884/* Accessor methods (get/set functions) to struct members. */
1885
1886/** Get the current line number.
1887 *
1888 */
1889int yyget_lineno (void)
1890{
1891
1892 return yylineno;
1893}
1894
1895/** Get the input stream.
1896 *
1897 */
1898FILE *yyget_in (void)
1899{
1900 return yyin;
1901}
1902
1903/** Get the output stream.
1904 *
1905 */
1906FILE *yyget_out (void)
1907{
1908 return yyout;
1909}
1910
1911/** Get the length of the current token.
1912 *
1913 */
1914int yyget_leng (void)
1915{
1916 return yyleng;
1917}
1918
1919/** Get the current token.
1920 *
1921 */
1922
1923char *yyget_text (void)
1924{
1925 return yytext;
1926}
1927
1928/** Set the current line number.
1929 * @param line_number
1930 *
1931 */
1932void yyset_lineno (int line_number )
1933{
1934
1935 yylineno = line_number;
1936}
1937
1938/** Set the input stream. This does not discard the current
1939 * input buffer.
1940 * @param in_str A readable stream.
1941 *
1942 * @see yy_switch_to_buffer
1943 */
1944void yyset_in (FILE * in_str )
1945{
1946 yyin = in_str ;
1947}
1948
1949void yyset_out (FILE * out_str )
1950{
1951 yyout = out_str ;
1952}
1953
1954int yyget_debug (void)
1955{
1956 return yy_flex_debug;
1957}
1958
1959void yyset_debug (int bdebug )
1960{
1961 yy_flex_debug = bdebug ;
1962}
1963
1964static int yy_init_globals (void)
1965{
1966 /* Initialization is the same as for the non-reentrant scanner.
1967 * This function is called from yylex_destroy(), so don't allocate here.
1968 */
1969
1970 /* We do not touch yylineno unless the option is enabled. */
1971 yylineno = 1;
1972
1973 (yy_buffer_stack) = 0;
1974 (yy_buffer_stack_top) = 0;
1975 (yy_buffer_stack_max) = 0;
1976 (yy_c_buf_p) = (char *) 0;
1977 (yy_init) = 0;
1978 (yy_start) = 0;
1979
1980/* Defined in main.c */
1981#ifdef YY_STDINIT
1982 yyin = stdin;
1983 yyout = stdout;
1984#else
1985 yyin = (FILE *) 0;
1986 yyout = (FILE *) 0;
1987#endif
1988
1989 /* For future reference: Set errno on error, since we are called by
1990 * yylex_init()
1991 */
1992 return 0;
1993}
1994
1995/* yylex_destroy is for both reentrant and non-reentrant scanners. */
1996int yylex_destroy (void)
1997{
1998
1999 /* Pop the buffer stack, destroying each element. */
2000 while(YY_CURRENT_BUFFER){
2001 yy_delete_buffer(YY_CURRENT_BUFFER );
2002 YY_CURRENT_BUFFER_LVALUE = NULL;
2003 yypop_buffer_state();
2004 }
2005
2006 /* Destroy the stack itself. */
2007 yyfree((yy_buffer_stack) );
2008 (yy_buffer_stack) = NULL;
2009
2010 /* Reset the globals. This is important in a non-reentrant scanner so the next time
2011 * yylex() is called, initialization will occur. */
2012 yy_init_globals( );
2013
2014 return 0;
2015}
2016
2017/*
2018 * Internal utility routines.
2019 */
2020
2021#ifndef yytext_ptr
2022static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
2023{
2024 register int i;
2025 for ( i = 0; i < n; ++i )
2026 s1[i] = s2[i];
2027}
2028#endif
2029
2030#ifdef YY_NEED_STRLEN
2031static int yy_flex_strlen (yyconst char * s )
2032{
2033 register int n;
2034 for ( n = 0; s[n]; ++n )
2035 ;
2036
2037 return n;
2038}
2039#endif
2040
2041void *yyalloc (yy_size_t size )
2042{
2043 return (void *) malloc( size );
2044}
2045
2046void *yyrealloc (void * ptr, yy_size_t size )
2047{
2048 /* The cast to (char *) in the following accommodates both
2049 * implementations that use char* generic pointers, and those
2050 * that use void* generic pointers. It works with the latter
2051 * because both ANSI C and C++ allow castless assignment from
2052 * any pointer type to void*, and deal with argument conversions
2053 * as though doing an assignment.
2054 */
2055 return (void *) realloc( (char *) ptr, size );
2056}
2057
2058void yyfree (void * ptr )
2059{
2060 free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
2061}
2062
2063#define YYTABLES_NAME "yytables"
2064
2065#line 222 "dtc-lexer.l"
2066
2067
2068
2069
2070/*
2071 * Stack of nested include file contexts.
2072 */
2073
2074struct incl_file {
2075 int filenum;
2076 FILE *file;
2077 YY_BUFFER_STATE yy_prev_buf;
2078 int yy_prev_lineno;
2079 struct incl_file *prev;
2080};
2081
2082struct incl_file *incl_file_stack;
2083
2084
2085/*
2086 * Detect infinite include recursion.
2087 */
2088#define MAX_INCLUDE_DEPTH (100)
2089
2090static int incl_depth = 0;
2091
2092
2093int push_input_file(const char *filename)
2094{
2095 FILE *f;
2096 struct incl_file *incl_file;
2097
2098 if (!filename) {
2099 yyerror("No include file name given.");
2100 return 0;
2101 }
2102
2103 if (incl_depth++ >= MAX_INCLUDE_DEPTH) {
2104 yyerror("Includes nested too deeply");
2105 return 0;
2106 }
2107
2108 f = dtc_open_file(filename);
2109
2110 incl_file = malloc(sizeof(struct incl_file));
2111 if (!incl_file) {
2112 yyerror("Can not allocate include file space.");
2113 return 0;
2114 }
2115
2116 /*
2117 * Save current context.
2118 */
2119 incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
2120 incl_file->yy_prev_lineno = yylineno;
2121 incl_file->filenum = srcpos_filenum;
2122 incl_file->file = yyin;
2123 incl_file->prev = incl_file_stack;
2124
2125 incl_file_stack = incl_file;
2126
2127 /*
2128 * Establish new context.
2129 */
2130 srcpos_filenum = lookup_file_name(filename, 0);
2131 yylineno = 1;
2132 yyin = f;
2133 yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));
2134
2135 return 1;
2136}
2137
2138
2139int pop_input_file(void)
2140{
2141 struct incl_file *incl_file;
2142
2143 if (incl_file_stack == 0)
2144 return 0;
2145
2146 fclose(yyin);
2147
2148 /*
2149 * Pop.
2150 */
2151 --incl_depth;
2152 incl_file = incl_file_stack;
2153 incl_file_stack = incl_file->prev;
2154
2155 /*
2156 * Recover old context.
2157 */
2158 yy_delete_buffer(YY_CURRENT_BUFFER);
2159 yy_switch_to_buffer(incl_file->yy_prev_buf);
2160 yylineno = incl_file->yy_prev_lineno;
2161 srcpos_filenum = incl_file->filenum;
2162 yyin = incl_file->file;
2163
2164 /*
2165 * Free old state.
2166 */
2167 free(incl_file);
2168
2169 if (YY_CURRENT_BUFFER == 0)
2170 return 0;
2171
2172 return 1;
2173}
2174
diff --git a/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped b/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped
new file mode 100644
index 000000000000..28e6ec0296a1
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/dtc-parser.tab.c_shipped
@@ -0,0 +1,1983 @@
1/* A Bison parser, made by GNU Bison 2.3. */
2
3/* Skeleton implementation for Bison's Yacc-like parsers in C
4
5 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
6 Free Software Foundation, Inc.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
22
23/* As a special exception, you may create a larger work that contains
24 part or all of the Bison parser skeleton and distribute that work
25 under terms of your choice, so long as that work isn't itself a
26 parser generator using the skeleton or a modified version thereof
27 as a parser skeleton. Alternatively, if you modify or redistribute
28 the parser skeleton itself, you may (at your option) remove this
29 special exception, which will cause the skeleton and the resulting
30 Bison output files to be licensed under the GNU General Public
31 License without this special exception.
32
33 This special exception was added by the Free Software Foundation in
34 version 2.2 of Bison. */
35
36/* C LALR(1) parser skeleton written by Richard Stallman, by
37 simplifying the original so-called "semantic" parser. */
38
39/* All symbols defined below should begin with yy or YY, to avoid
40 infringing on user name space. This should be done even for local
41 variables, as they might otherwise be expanded by user macros.
42 There are some unavoidable exceptions within include files to
43 define necessary library symbols; they are noted "INFRINGES ON
44 USER NAME SPACE" below. */
45
46/* Identify Bison output. */
47#define YYBISON 1
48
49/* Bison version. */
50#define YYBISON_VERSION "2.3"
51
52/* Skeleton name. */
53#define YYSKELETON_NAME "yacc.c"
54
55/* Pure parsers. */
56#define YYPURE 0
57
58/* Using locations. */
59#define YYLSP_NEEDED 1
60
61
62
63/* Tokens. */
64#ifndef YYTOKENTYPE
65# define YYTOKENTYPE
66 /* Put the tokens into the symbol table, so that GDB and other debuggers
67 know about them. */
68 enum yytokentype {
69 DT_V1 = 258,
70 DT_MEMRESERVE = 259,
71 DT_PROPNODENAME = 260,
72 DT_LITERAL = 261,
73 DT_LEGACYLITERAL = 262,
74 DT_BASE = 263,
75 DT_BYTE = 264,
76 DT_STRING = 265,
77 DT_LABEL = 266,
78 DT_REF = 267
79 };
80#endif
81/* Tokens. */
82#define DT_V1 258
83#define DT_MEMRESERVE 259
84#define DT_PROPNODENAME 260
85#define DT_LITERAL 261
86#define DT_LEGACYLITERAL 262
87#define DT_BASE 263
88#define DT_BYTE 264
89#define DT_STRING 265
90#define DT_LABEL 266
91#define DT_REF 267
92
93
94
95
96/* Copy the first part of user declarations. */
97#line 23 "dtc-parser.y"
98
99#include "dtc.h"
100#include "srcpos.h"
101
102int yylex(void);
103unsigned long long eval_literal(const char *s, int base, int bits);
104
105extern struct boot_info *the_boot_info;
106
107
108
109/* Enabling traces. */
110#ifndef YYDEBUG
111# define YYDEBUG 0
112#endif
113
114/* Enabling verbose error messages. */
115#ifdef YYERROR_VERBOSE
116# undef YYERROR_VERBOSE
117# define YYERROR_VERBOSE 1
118#else
119# define YYERROR_VERBOSE 0
120#endif
121
122/* Enabling the token table. */
123#ifndef YYTOKEN_TABLE
124# define YYTOKEN_TABLE 0
125#endif
126
127#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
128typedef union YYSTYPE
129#line 34 "dtc-parser.y"
130{
131 char *propnodename;
132 char *literal;
133 char *labelref;
134 unsigned int cbase;
135 u8 byte;
136 struct data data;
137
138 u64 addr;
139 cell_t cell;
140 struct property *prop;
141 struct property *proplist;
142 struct node *node;
143 struct node *nodelist;
144 struct reserve_info *re;
145}
146/* Line 187 of yacc.c. */
147#line 148 "dtc-parser.tab.c"
148 YYSTYPE;
149# define yystype YYSTYPE /* obsolescent; will be withdrawn */
150# define YYSTYPE_IS_DECLARED 1
151# define YYSTYPE_IS_TRIVIAL 1
152#endif
153
154#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
155typedef struct YYLTYPE
156{
157 int first_line;
158 int first_column;
159 int last_line;
160 int last_column;
161} YYLTYPE;
162# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
163# define YYLTYPE_IS_DECLARED 1
164# define YYLTYPE_IS_TRIVIAL 1
165#endif
166
167
168/* Copy the second part of user declarations. */
169
170
171/* Line 216 of yacc.c. */
172#line 173 "dtc-parser.tab.c"
173
174#ifdef short
175# undef short
176#endif
177
178#ifdef YYTYPE_UINT8
179typedef YYTYPE_UINT8 yytype_uint8;
180#else
181typedef unsigned char yytype_uint8;
182#endif
183
184#ifdef YYTYPE_INT8
185typedef YYTYPE_INT8 yytype_int8;
186#elif (defined __STDC__ || defined __C99__FUNC__ \
187 || defined __cplusplus || defined _MSC_VER)
188typedef signed char yytype_int8;
189#else
190typedef short int yytype_int8;
191#endif
192
193#ifdef YYTYPE_UINT16
194typedef YYTYPE_UINT16 yytype_uint16;
195#else
196typedef unsigned short int yytype_uint16;
197#endif
198
199#ifdef YYTYPE_INT16
200typedef YYTYPE_INT16 yytype_int16;
201#else
202typedef short int yytype_int16;
203#endif
204
205#ifndef YYSIZE_T
206# ifdef __SIZE_TYPE__
207# define YYSIZE_T __SIZE_TYPE__
208# elif defined size_t
209# define YYSIZE_T size_t
210# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
211 || defined __cplusplus || defined _MSC_VER)
212# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
213# define YYSIZE_T size_t
214# else
215# define YYSIZE_T unsigned int
216# endif
217#endif
218
219#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
220
221#ifndef YY_
222# if YYENABLE_NLS
223# if ENABLE_NLS
224# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
225# define YY_(msgid) dgettext ("bison-runtime", msgid)
226# endif
227# endif
228# ifndef YY_
229# define YY_(msgid) msgid
230# endif
231#endif
232
233/* Suppress unused-variable warnings by "using" E. */
234#if ! defined lint || defined __GNUC__
235# define YYUSE(e) ((void) (e))
236#else
237# define YYUSE(e) /* empty */
238#endif
239
240/* Identity function, used to suppress warnings about constant conditions. */
241#ifndef lint
242# define YYID(n) (n)
243#else
244#if (defined __STDC__ || defined __C99__FUNC__ \
245 || defined __cplusplus || defined _MSC_VER)
246static int
247YYID (int i)
248#else
249static int
250YYID (i)
251 int i;
252#endif
253{
254 return i;
255}
256#endif
257
258#if ! defined yyoverflow || YYERROR_VERBOSE
259
260/* The parser invokes alloca or malloc; define the necessary symbols. */
261
262# ifdef YYSTACK_USE_ALLOCA
263# if YYSTACK_USE_ALLOCA
264# ifdef __GNUC__
265# define YYSTACK_ALLOC __builtin_alloca
266# elif defined __BUILTIN_VA_ARG_INCR
267# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
268# elif defined _AIX
269# define YYSTACK_ALLOC __alloca
270# elif defined _MSC_VER
271# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
272# define alloca _alloca
273# else
274# define YYSTACK_ALLOC alloca
275# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
276 || defined __cplusplus || defined _MSC_VER)
277# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
278# ifndef _STDLIB_H
279# define _STDLIB_H 1
280# endif
281# endif
282# endif
283# endif
284# endif
285
286# ifdef YYSTACK_ALLOC
287 /* Pacify GCC's `empty if-body' warning. */
288# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
289# ifndef YYSTACK_ALLOC_MAXIMUM
290 /* The OS might guarantee only one guard page at the bottom of the stack,
291 and a page size can be as small as 4096 bytes. So we cannot safely
292 invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
293 to allow for a few compiler-allocated temporary stack slots. */
294# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
295# endif
296# else
297# define YYSTACK_ALLOC YYMALLOC
298# define YYSTACK_FREE YYFREE
299# ifndef YYSTACK_ALLOC_MAXIMUM
300# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
301# endif
302# if (defined __cplusplus && ! defined _STDLIB_H \
303 && ! ((defined YYMALLOC || defined malloc) \
304 && (defined YYFREE || defined free)))
305# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
306# ifndef _STDLIB_H
307# define _STDLIB_H 1
308# endif
309# endif
310# ifndef YYMALLOC
311# define YYMALLOC malloc
312# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
313 || defined __cplusplus || defined _MSC_VER)
314void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
315# endif
316# endif
317# ifndef YYFREE
318# define YYFREE free
319# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
320 || defined __cplusplus || defined _MSC_VER)
321void free (void *); /* INFRINGES ON USER NAME SPACE */
322# endif
323# endif
324# endif
325#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
326
327
328#if (! defined yyoverflow \
329 && (! defined __cplusplus \
330 || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
331 && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
332
333/* A type that is properly aligned for any stack member. */
334union yyalloc
335{
336 yytype_int16 yyss;
337 YYSTYPE yyvs;
338 YYLTYPE yyls;
339};
340
341/* The size of the maximum gap between one aligned stack and the next. */
342# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
343
344/* The size of an array large to enough to hold all stacks, each with
345 N elements. */
346# define YYSTACK_BYTES(N) \
347 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
348 + 2 * YYSTACK_GAP_MAXIMUM)
349
350/* Copy COUNT objects from FROM to TO. The source and destination do
351 not overlap. */
352# ifndef YYCOPY
353# if defined __GNUC__ && 1 < __GNUC__
354# define YYCOPY(To, From, Count) \
355 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
356# else
357# define YYCOPY(To, From, Count) \
358 do \
359 { \
360 YYSIZE_T yyi; \
361 for (yyi = 0; yyi < (Count); yyi++) \
362 (To)[yyi] = (From)[yyi]; \
363 } \
364 while (YYID (0))
365# endif
366# endif
367
368/* Relocate STACK from its old location to the new one. The
369 local variables YYSIZE and YYSTACKSIZE give the old and new number of
370 elements in the stack, and YYPTR gives the new location of the
371 stack. Advance YYPTR to a properly aligned location for the next
372 stack. */
373# define YYSTACK_RELOCATE(Stack) \
374 do \
375 { \
376 YYSIZE_T yynewbytes; \
377 YYCOPY (&yyptr->Stack, Stack, yysize); \
378 Stack = &yyptr->Stack; \
379 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
380 yyptr += yynewbytes / sizeof (*yyptr); \
381 } \
382 while (YYID (0))
383
384#endif
385
386/* YYFINAL -- State number of the termination state. */
387#define YYFINAL 9
388/* YYLAST -- Last index in YYTABLE. */
389#define YYLAST 60
390
391/* YYNTOKENS -- Number of terminals. */
392#define YYNTOKENS 24
393/* YYNNTS -- Number of nonterminals. */
394#define YYNNTS 20
395/* YYNRULES -- Number of rules. */
396#define YYNRULES 43
397/* YYNRULES -- Number of states. */
398#define YYNSTATES 67
399
400/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
401#define YYUNDEFTOK 2
402#define YYMAXUTOK 267
403
404#define YYTRANSLATE(YYX) \
405 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
406
407/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
408static const yytype_uint8 yytranslate[] =
409{
410 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
411 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
412 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
413 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
414 2, 2, 2, 2, 23, 14, 2, 15, 2, 2,
415 2, 2, 2, 2, 2, 2, 2, 2, 2, 13,
416 19, 18, 20, 2, 2, 2, 2, 2, 2, 2,
417 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
418 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
419 2, 21, 2, 22, 2, 2, 2, 2, 2, 2,
420 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
421 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
422 2, 2, 2, 16, 2, 17, 2, 2, 2, 2,
423 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
424 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
425 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
426 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
427 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
428 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
429 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
430 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
431 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
432 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
433 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
434 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
435 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
436 5, 6, 7, 8, 9, 10, 11, 12
437};
438
439#if YYDEBUG
440/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
441 YYRHS. */
442static const yytype_uint8 yyprhs[] =
443{
444 0, 0, 3, 8, 11, 12, 15, 21, 22, 25,
445 27, 34, 36, 38, 41, 47, 48, 51, 57, 61,
446 64, 69, 74, 77, 80, 81, 84, 87, 88, 91,
447 94, 97, 98, 100, 102, 105, 106, 109, 112, 113,
448 116, 119, 123, 124
449};
450
451/* YYRHS -- A `-1'-separated list of the rules' RHS. */
452static const yytype_int8 yyrhs[] =
453{
454 25, 0, -1, 3, 13, 26, 31, -1, 28, 31,
455 -1, -1, 27, 26, -1, 43, 4, 30, 30, 13,
456 -1, -1, 29, 28, -1, 27, -1, 43, 4, 30,
457 14, 30, 13, -1, 6, -1, 7, -1, 15, 32,
458 -1, 16, 33, 41, 17, 13, -1, -1, 33, 34,
459 -1, 43, 5, 18, 35, 13, -1, 43, 5, 13,
460 -1, 36, 10, -1, 36, 19, 37, 20, -1, 36,
461 21, 40, 22, -1, 36, 12, -1, 35, 11, -1,
462 -1, 35, 23, -1, 36, 11, -1, -1, 37, 39,
463 -1, 37, 12, -1, 37, 11, -1, -1, 8, -1,
464 6, -1, 38, 7, -1, -1, 40, 9, -1, 40,
465 11, -1, -1, 42, 41, -1, 42, 34, -1, 43,
466 5, 32, -1, -1, 11, -1
467};
468
469/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
470static const yytype_uint16 yyrline[] =
471{
472 0, 85, 85, 89, 97, 100, 107, 115, 118, 125,
473 129, 136, 140, 147, 154, 162, 165, 172, 176, 183,
474 187, 191, 195, 199, 207, 210, 214, 222, 225, 229,
475 234, 242, 245, 249, 253, 261, 264, 268, 276, 279,
476 283, 291, 299, 302
477};
478#endif
479
480#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
481/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
482 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
483static const char *const yytname[] =
484{
485 "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE",
486 "DT_PROPNODENAME", "DT_LITERAL", "DT_LEGACYLITERAL", "DT_BASE",
487 "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", "';'", "'-'", "'/'", "'{'",
488 "'}'", "'='", "'<'", "'>'", "'['", "']'", "','", "$accept", "sourcefile",
489 "memreserves", "memreserve", "v0_memreserves", "v0_memreserve", "addr",
490 "devicetree", "nodedef", "proplist", "propdef", "propdata",
491 "propdataprefix", "celllist", "cellbase", "cellval", "bytestring",
492 "subnodes", "subnode", "label", 0
493};
494#endif
495
496# ifdef YYPRINT
497/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
498 token YYLEX-NUM. */
499static const yytype_uint16 yytoknum[] =
500{
501 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
502 265, 266, 267, 59, 45, 47, 123, 125, 61, 60,
503 62, 91, 93, 44
504};
505# endif
506
507/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
508static const yytype_uint8 yyr1[] =
509{
510 0, 24, 25, 25, 26, 26, 27, 28, 28, 29,
511 29, 30, 30, 31, 32, 33, 33, 34, 34, 35,
512 35, 35, 35, 35, 36, 36, 36, 37, 37, 37,
513 37, 38, 38, 39, 39, 40, 40, 40, 41, 41,
514 41, 42, 43, 43
515};
516
517/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
518static const yytype_uint8 yyr2[] =
519{
520 0, 2, 4, 2, 0, 2, 5, 0, 2, 1,
521 6, 1, 1, 2, 5, 0, 2, 5, 3, 2,
522 4, 4, 2, 2, 0, 2, 2, 0, 2, 2,
523 2, 0, 1, 1, 2, 0, 2, 2, 0, 2,
524 2, 3, 0, 1
525};
526
527/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
528 STATE-NUM when YYTABLE doesn't specify something else to do. Zero
529 means the default is an error. */
530static const yytype_uint8 yydefact[] =
531{
532 7, 0, 43, 0, 9, 0, 7, 0, 4, 1,
533 0, 3, 8, 0, 0, 4, 0, 15, 13, 11,
534 12, 0, 2, 5, 0, 38, 0, 0, 0, 16,
535 0, 38, 0, 0, 6, 0, 40, 39, 0, 10,
536 14, 18, 24, 41, 0, 0, 23, 17, 25, 19,
537 26, 22, 27, 35, 31, 0, 33, 32, 30, 29,
538 20, 0, 28, 36, 37, 21, 34
539};
540
541/* YYDEFGOTO[NTERM-NUM]. */
542static const yytype_int8 yydefgoto[] =
543{
544 -1, 3, 14, 4, 5, 6, 27, 11, 18, 25,
545 29, 44, 45, 54, 61, 62, 55, 30, 31, 7
546};
547
548/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
549 STATE-NUM. */
550#define YYPACT_NINF -13
551static const yytype_int8 yypact[] =
552{
553 23, 11, -13, 37, -13, -4, 18, 39, 18, -13,
554 28, -13, -13, 34, -4, 18, 41, -13, -13, -13,
555 -13, 25, -13, -13, 34, -3, 34, 33, 34, -13,
556 30, -3, 43, 36, -13, 38, -13, -13, 20, -13,
557 -13, -13, -13, -13, 2, 9, -13, -13, -13, -13,
558 -13, -13, -13, -13, -2, -6, -13, -13, -13, -13,
559 -13, 45, -13, -13, -13, -13, -13
560};
561
562/* YYPGOTO[NTERM-NUM]. */
563static const yytype_int8 yypgoto[] =
564{
565 -13, -13, 35, 27, 47, -13, -12, 40, 17, -13,
566 26, -13, -13, -13, -13, -13, -13, 29, -13, -8
567};
568
569/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
570 positive, shift that token. If negative, reduce the rule which
571 number is the opposite. If zero, do what YYDEFACT says.
572 If YYTABLE_NINF, syntax error. */
573#define YYTABLE_NINF -43
574static const yytype_int8 yytable[] =
575{
576 16, 21, -42, 63, 56, 64, 57, 16, 2, 58,
577 59, 10, 28, 46, 33, 47, 65, 32, 60, 49,
578 50, 51, -42, 32, 8, 48, 1, -42, 52, 2,
579 53, 19, 20, 41, 2, 15, 17, 9, 42, 26,
580 19, 20, 15, 13, 17, 24, 34, 35, 38, 39,
581 23, 40, 66, 12, 22, 43, 0, 36, 0, 0,
582 37
583};
584
585static const yytype_int8 yycheck[] =
586{
587 8, 13, 5, 9, 6, 11, 8, 15, 11, 11,
588 12, 15, 24, 11, 26, 13, 22, 25, 20, 10,
589 11, 12, 4, 31, 13, 23, 3, 4, 19, 11,
590 21, 6, 7, 13, 11, 8, 16, 0, 18, 14,
591 6, 7, 15, 4, 16, 4, 13, 17, 5, 13,
592 15, 13, 7, 6, 14, 38, -1, 31, -1, -1,
593 31
594};
595
596/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
597 symbol of state STATE-NUM. */
598static const yytype_uint8 yystos[] =
599{
600 0, 3, 11, 25, 27, 28, 29, 43, 13, 0,
601 15, 31, 28, 4, 26, 27, 43, 16, 32, 6,
602 7, 30, 31, 26, 4, 33, 14, 30, 30, 34,
603 41, 42, 43, 30, 13, 17, 34, 41, 5, 13,
604 13, 13, 18, 32, 35, 36, 11, 13, 23, 10,
605 11, 12, 19, 21, 37, 40, 6, 8, 11, 12,
606 20, 38, 39, 9, 11, 22, 7
607};
608
609#define yyerrok (yyerrstatus = 0)
610#define yyclearin (yychar = YYEMPTY)
611#define YYEMPTY (-2)
612#define YYEOF 0
613
614#define YYACCEPT goto yyacceptlab
615#define YYABORT goto yyabortlab
616#define YYERROR goto yyerrorlab
617
618
619/* Like YYERROR except do call yyerror. This remains here temporarily
620 to ease the transition to the new meaning of YYERROR, for GCC.
621 Once GCC version 2 has supplanted version 1, this can go. */
622
623#define YYFAIL goto yyerrlab
624
625#define YYRECOVERING() (!!yyerrstatus)
626
627#define YYBACKUP(Token, Value) \
628do \
629 if (yychar == YYEMPTY && yylen == 1) \
630 { \
631 yychar = (Token); \
632 yylval = (Value); \
633 yytoken = YYTRANSLATE (yychar); \
634 YYPOPSTACK (1); \
635 goto yybackup; \
636 } \
637 else \
638 { \
639 yyerror (YY_("syntax error: cannot back up")); \
640 YYERROR; \
641 } \
642while (YYID (0))
643
644
645#define YYTERROR 1
646#define YYERRCODE 256
647
648
649/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
650 If N is 0, then set CURRENT to the empty location which ends
651 the previous symbol: RHS[0] (always defined). */
652
653#define YYRHSLOC(Rhs, K) ((Rhs)[K])
654#ifndef YYLLOC_DEFAULT
655# define YYLLOC_DEFAULT(Current, Rhs, N) \
656 do \
657 if (YYID (N)) \
658 { \
659 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
660 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
661 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
662 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
663 } \
664 else \
665 { \
666 (Current).first_line = (Current).last_line = \
667 YYRHSLOC (Rhs, 0).last_line; \
668 (Current).first_column = (Current).last_column = \
669 YYRHSLOC (Rhs, 0).last_column; \
670 } \
671 while (YYID (0))
672#endif
673
674
675/* YY_LOCATION_PRINT -- Print the location on the stream.
676 This macro was not mandated originally: define only if we know
677 we won't break user code: when these are the locations we know. */
678
679#ifndef YY_LOCATION_PRINT
680# if YYLTYPE_IS_TRIVIAL
681# define YY_LOCATION_PRINT(File, Loc) \
682 fprintf (File, "%d.%d-%d.%d", \
683 (Loc).first_line, (Loc).first_column, \
684 (Loc).last_line, (Loc).last_column)
685# else
686# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
687# endif
688#endif
689
690
691/* YYLEX -- calling `yylex' with the right arguments. */
692
693#ifdef YYLEX_PARAM
694# define YYLEX yylex (YYLEX_PARAM)
695#else
696# define YYLEX yylex ()
697#endif
698
699/* Enable debugging if requested. */
700#if YYDEBUG
701
702# ifndef YYFPRINTF
703# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
704# define YYFPRINTF fprintf
705# endif
706
707# define YYDPRINTF(Args) \
708do { \
709 if (yydebug) \
710 YYFPRINTF Args; \
711} while (YYID (0))
712
713# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
714do { \
715 if (yydebug) \
716 { \
717 YYFPRINTF (stderr, "%s ", Title); \
718 yy_symbol_print (stderr, \
719 Type, Value, Location); \
720 YYFPRINTF (stderr, "\n"); \
721 } \
722} while (YYID (0))
723
724
725/*--------------------------------.
726| Print this symbol on YYOUTPUT. |
727`--------------------------------*/
728
729/*ARGSUSED*/
730#if (defined __STDC__ || defined __C99__FUNC__ \
731 || defined __cplusplus || defined _MSC_VER)
732static void
733yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
734#else
735static void
736yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp)
737 FILE *yyoutput;
738 int yytype;
739 YYSTYPE const * const yyvaluep;
740 YYLTYPE const * const yylocationp;
741#endif
742{
743 if (!yyvaluep)
744 return;
745 YYUSE (yylocationp);
746# ifdef YYPRINT
747 if (yytype < YYNTOKENS)
748 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
749# else
750 YYUSE (yyoutput);
751# endif
752 switch (yytype)
753 {
754 default:
755 break;
756 }
757}
758
759
760/*--------------------------------.
761| Print this symbol on YYOUTPUT. |
762`--------------------------------*/
763
764#if (defined __STDC__ || defined __C99__FUNC__ \
765 || defined __cplusplus || defined _MSC_VER)
766static void
767yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
768#else
769static void
770yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp)
771 FILE *yyoutput;
772 int yytype;
773 YYSTYPE const * const yyvaluep;
774 YYLTYPE const * const yylocationp;
775#endif
776{
777 if (yytype < YYNTOKENS)
778 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
779 else
780 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
781
782 YY_LOCATION_PRINT (yyoutput, *yylocationp);
783 YYFPRINTF (yyoutput, ": ");
784 yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
785 YYFPRINTF (yyoutput, ")");
786}
787
788/*------------------------------------------------------------------.
789| yy_stack_print -- Print the state stack from its BOTTOM up to its |
790| TOP (included). |
791`------------------------------------------------------------------*/
792
793#if (defined __STDC__ || defined __C99__FUNC__ \
794 || defined __cplusplus || defined _MSC_VER)
795static void
796yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
797#else
798static void
799yy_stack_print (bottom, top)
800 yytype_int16 *bottom;
801 yytype_int16 *top;
802#endif
803{
804 YYFPRINTF (stderr, "Stack now");
805 for (; bottom <= top; ++bottom)
806 YYFPRINTF (stderr, " %d", *bottom);
807 YYFPRINTF (stderr, "\n");
808}
809
810# define YY_STACK_PRINT(Bottom, Top) \
811do { \
812 if (yydebug) \
813 yy_stack_print ((Bottom), (Top)); \
814} while (YYID (0))
815
816
817/*------------------------------------------------.
818| Report that the YYRULE is going to be reduced. |
819`------------------------------------------------*/
820
821#if (defined __STDC__ || defined __C99__FUNC__ \
822 || defined __cplusplus || defined _MSC_VER)
823static void
824yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule)
825#else
826static void
827yy_reduce_print (yyvsp, yylsp, yyrule)
828 YYSTYPE *yyvsp;
829 YYLTYPE *yylsp;
830 int yyrule;
831#endif
832{
833 int yynrhs = yyr2[yyrule];
834 int yyi;
835 unsigned long int yylno = yyrline[yyrule];
836 YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
837 yyrule - 1, yylno);
838 /* The symbols being reduced. */
839 for (yyi = 0; yyi < yynrhs; yyi++)
840 {
841 fprintf (stderr, " $%d = ", yyi + 1);
842 yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
843 &(yyvsp[(yyi + 1) - (yynrhs)])
844 , &(yylsp[(yyi + 1) - (yynrhs)]) );
845 fprintf (stderr, "\n");
846 }
847}
848
849# define YY_REDUCE_PRINT(Rule) \
850do { \
851 if (yydebug) \
852 yy_reduce_print (yyvsp, yylsp, Rule); \
853} while (YYID (0))
854
855/* Nonzero means print parse trace. It is left uninitialized so that
856 multiple parsers can coexist. */
857int yydebug;
858#else /* !YYDEBUG */
859# define YYDPRINTF(Args)
860# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
861# define YY_STACK_PRINT(Bottom, Top)
862# define YY_REDUCE_PRINT(Rule)
863#endif /* !YYDEBUG */
864
865
866/* YYINITDEPTH -- initial size of the parser's stacks. */
867#ifndef YYINITDEPTH
868# define YYINITDEPTH 200
869#endif
870
871/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
872 if the built-in stack extension method is used).
873
874 Do not make this value too large; the results are undefined if
875 YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
876 evaluated with infinite-precision integer arithmetic. */
877
878#ifndef YYMAXDEPTH
879# define YYMAXDEPTH 10000
880#endif
881
882
883
884#if YYERROR_VERBOSE
885
886# ifndef yystrlen
887# if defined __GLIBC__ && defined _STRING_H
888# define yystrlen strlen
889# else
890/* Return the length of YYSTR. */
891#if (defined __STDC__ || defined __C99__FUNC__ \
892 || defined __cplusplus || defined _MSC_VER)
893static YYSIZE_T
894yystrlen (const char *yystr)
895#else
896static YYSIZE_T
897yystrlen (yystr)
898 const char *yystr;
899#endif
900{
901 YYSIZE_T yylen;
902 for (yylen = 0; yystr[yylen]; yylen++)
903 continue;
904 return yylen;
905}
906# endif
907# endif
908
909# ifndef yystpcpy
910# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
911# define yystpcpy stpcpy
912# else
913/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
914 YYDEST. */
915#if (defined __STDC__ || defined __C99__FUNC__ \
916 || defined __cplusplus || defined _MSC_VER)
917static char *
918yystpcpy (char *yydest, const char *yysrc)
919#else
920static char *
921yystpcpy (yydest, yysrc)
922 char *yydest;
923 const char *yysrc;
924#endif
925{
926 char *yyd = yydest;
927 const char *yys = yysrc;
928
929 while ((*yyd++ = *yys++) != '\0')
930 continue;
931
932 return yyd - 1;
933}
934# endif
935# endif
936
937# ifndef yytnamerr
938/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
939 quotes and backslashes, so that it's suitable for yyerror. The
940 heuristic is that double-quoting is unnecessary unless the string
941 contains an apostrophe, a comma, or backslash (other than
942 backslash-backslash). YYSTR is taken from yytname. If YYRES is
943 null, do not copy; instead, return the length of what the result
944 would have been. */
945static YYSIZE_T
946yytnamerr (char *yyres, const char *yystr)
947{
948 if (*yystr == '"')
949 {
950 YYSIZE_T yyn = 0;
951 char const *yyp = yystr;
952
953 for (;;)
954 switch (*++yyp)
955 {
956 case '\'':
957 case ',':
958 goto do_not_strip_quotes;
959
960 case '\\':
961 if (*++yyp != '\\')
962 goto do_not_strip_quotes;
963 /* Fall through. */
964 default:
965 if (yyres)
966 yyres[yyn] = *yyp;
967 yyn++;
968 break;
969
970 case '"':
971 if (yyres)
972 yyres[yyn] = '\0';
973 return yyn;
974 }
975 do_not_strip_quotes: ;
976 }
977
978 if (! yyres)
979 return yystrlen (yystr);
980
981 return yystpcpy (yyres, yystr) - yyres;
982}
983# endif
984
985/* Copy into YYRESULT an error message about the unexpected token
986 YYCHAR while in state YYSTATE. Return the number of bytes copied,
987 including the terminating null byte. If YYRESULT is null, do not
988 copy anything; just return the number of bytes that would be
989 copied. As a special case, return 0 if an ordinary "syntax error"
990 message will do. Return YYSIZE_MAXIMUM if overflow occurs during
991 size calculation. */
992static YYSIZE_T
993yysyntax_error (char *yyresult, int yystate, int yychar)
994{
995 int yyn = yypact[yystate];
996
997 if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
998 return 0;
999 else
1000 {
1001 int yytype = YYTRANSLATE (yychar);
1002 YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
1003 YYSIZE_T yysize = yysize0;
1004 YYSIZE_T yysize1;
1005 int yysize_overflow = 0;
1006 enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1007 char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1008 int yyx;
1009
1010# if 0
1011 /* This is so xgettext sees the translatable formats that are
1012 constructed on the fly. */
1013 YY_("syntax error, unexpected %s");
1014 YY_("syntax error, unexpected %s, expecting %s");
1015 YY_("syntax error, unexpected %s, expecting %s or %s");
1016 YY_("syntax error, unexpected %s, expecting %s or %s or %s");
1017 YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
1018# endif
1019 char *yyfmt;
1020 char const *yyf;
1021 static char const yyunexpected[] = "syntax error, unexpected %s";
1022 static char const yyexpecting[] = ", expecting %s";
1023 static char const yyor[] = " or %s";
1024 char yyformat[sizeof yyunexpected
1025 + sizeof yyexpecting - 1
1026 + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
1027 * (sizeof yyor - 1))];
1028 char const *yyprefix = yyexpecting;
1029
1030 /* Start YYX at -YYN if negative to avoid negative indexes in
1031 YYCHECK. */
1032 int yyxbegin = yyn < 0 ? -yyn : 0;
1033
1034 /* Stay within bounds of both yycheck and yytname. */
1035 int yychecklim = YYLAST - yyn + 1;
1036 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1037 int yycount = 1;
1038
1039 yyarg[0] = yytname[yytype];
1040 yyfmt = yystpcpy (yyformat, yyunexpected);
1041
1042 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1043 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
1044 {
1045 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1046 {
1047 yycount = 1;
1048 yysize = yysize0;
1049 yyformat[sizeof yyunexpected - 1] = '\0';
1050 break;
1051 }
1052 yyarg[yycount++] = yytname[yyx];
1053 yysize1 = yysize + yytnamerr (0, yytname[yyx]);
1054 yysize_overflow |= (yysize1 < yysize);
1055 yysize = yysize1;
1056 yyfmt = yystpcpy (yyfmt, yyprefix);
1057 yyprefix = yyor;
1058 }
1059
1060 yyf = YY_(yyformat);
1061 yysize1 = yysize + yystrlen (yyf);
1062 yysize_overflow |= (yysize1 < yysize);
1063 yysize = yysize1;
1064
1065 if (yysize_overflow)
1066 return YYSIZE_MAXIMUM;
1067
1068 if (yyresult)
1069 {
1070 /* Avoid sprintf, as that infringes on the user's name space.
1071 Don't have undefined behavior even if the translation
1072 produced a string with the wrong number of "%s"s. */
1073 char *yyp = yyresult;
1074 int yyi = 0;
1075 while ((*yyp = *yyf) != '\0')
1076 {
1077 if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
1078 {
1079 yyp += yytnamerr (yyp, yyarg[yyi++]);
1080 yyf += 2;
1081 }
1082 else
1083 {
1084 yyp++;
1085 yyf++;
1086 }
1087 }
1088 }
1089 return yysize;
1090 }
1091}
1092#endif /* YYERROR_VERBOSE */
1093
1094
1095/*-----------------------------------------------.
1096| Release the memory associated to this symbol. |
1097`-----------------------------------------------*/
1098
1099/*ARGSUSED*/
1100#if (defined __STDC__ || defined __C99__FUNC__ \
1101 || defined __cplusplus || defined _MSC_VER)
1102static void
1103yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
1104#else
1105static void
1106yydestruct (yymsg, yytype, yyvaluep, yylocationp)
1107 const char *yymsg;
1108 int yytype;
1109 YYSTYPE *yyvaluep;
1110 YYLTYPE *yylocationp;
1111#endif
1112{
1113 YYUSE (yyvaluep);
1114 YYUSE (yylocationp);
1115
1116 if (!yymsg)
1117 yymsg = "Deleting";
1118 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1119
1120 switch (yytype)
1121 {
1122
1123 default:
1124 break;
1125 }
1126}
1127
1128
1129/* Prevent warnings from -Wmissing-prototypes. */
1130
1131#ifdef YYPARSE_PARAM
1132#if defined __STDC__ || defined __cplusplus
1133int yyparse (void *YYPARSE_PARAM);
1134#else
1135int yyparse ();
1136#endif
1137#else /* ! YYPARSE_PARAM */
1138#if defined __STDC__ || defined __cplusplus
1139int yyparse (void);
1140#else
1141int yyparse ();
1142#endif
1143#endif /* ! YYPARSE_PARAM */
1144
1145
1146
1147/* The look-ahead symbol. */
1148int yychar;
1149
1150/* The semantic value of the look-ahead symbol. */
1151YYSTYPE yylval;
1152
1153/* Number of syntax errors so far. */
1154int yynerrs;
1155/* Location data for the look-ahead symbol. */
1156YYLTYPE yylloc;
1157
1158
1159
1160/*----------.
1161| yyparse. |
1162`----------*/
1163
1164#ifdef YYPARSE_PARAM
1165#if (defined __STDC__ || defined __C99__FUNC__ \
1166 || defined __cplusplus || defined _MSC_VER)
1167int
1168yyparse (void *YYPARSE_PARAM)
1169#else
1170int
1171yyparse (YYPARSE_PARAM)
1172 void *YYPARSE_PARAM;
1173#endif
1174#else /* ! YYPARSE_PARAM */
1175#if (defined __STDC__ || defined __C99__FUNC__ \
1176 || defined __cplusplus || defined _MSC_VER)
1177int
1178yyparse (void)
1179#else
1180int
1181yyparse ()
1182
1183#endif
1184#endif
1185{
1186
1187 int yystate;
1188 int yyn;
1189 int yyresult;
1190 /* Number of tokens to shift before error messages enabled. */
1191 int yyerrstatus;
1192 /* Look-ahead token as an internal (translated) token number. */
1193 int yytoken = 0;
1194#if YYERROR_VERBOSE
1195 /* Buffer for error messages, and its allocated size. */
1196 char yymsgbuf[128];
1197 char *yymsg = yymsgbuf;
1198 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1199#endif
1200
1201 /* Three stacks and their tools:
1202 `yyss': related to states,
1203 `yyvs': related to semantic values,
1204 `yyls': related to locations.
1205
1206 Refer to the stacks thru separate pointers, to allow yyoverflow
1207 to reallocate them elsewhere. */
1208
1209 /* The state stack. */
1210 yytype_int16 yyssa[YYINITDEPTH];
1211 yytype_int16 *yyss = yyssa;
1212 yytype_int16 *yyssp;
1213
1214 /* The semantic value stack. */
1215 YYSTYPE yyvsa[YYINITDEPTH];
1216 YYSTYPE *yyvs = yyvsa;
1217 YYSTYPE *yyvsp;
1218
1219 /* The location stack. */
1220 YYLTYPE yylsa[YYINITDEPTH];
1221 YYLTYPE *yyls = yylsa;
1222 YYLTYPE *yylsp;
1223 /* The locations where the error started and ended. */
1224 YYLTYPE yyerror_range[2];
1225
1226#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
1227
1228 YYSIZE_T yystacksize = YYINITDEPTH;
1229
1230 /* The variables used to return semantic value and location from the
1231 action routines. */
1232 YYSTYPE yyval;
1233 YYLTYPE yyloc;
1234
1235 /* The number of symbols on the RHS of the reduced rule.
1236 Keep to zero when no symbol should be popped. */
1237 int yylen = 0;
1238
1239 YYDPRINTF ((stderr, "Starting parse\n"));
1240
1241 yystate = 0;
1242 yyerrstatus = 0;
1243 yynerrs = 0;
1244 yychar = YYEMPTY; /* Cause a token to be read. */
1245
1246 /* Initialize stack pointers.
1247 Waste one element of value and location stack
1248 so that they stay on the same level as the state stack.
1249 The wasted elements are never initialized. */
1250
1251 yyssp = yyss;
1252 yyvsp = yyvs;
1253 yylsp = yyls;
1254#if YYLTYPE_IS_TRIVIAL
1255 /* Initialize the default location before parsing starts. */
1256 yylloc.first_line = yylloc.last_line = 1;
1257 yylloc.first_column = yylloc.last_column = 0;
1258#endif
1259
1260 goto yysetstate;
1261
1262/*------------------------------------------------------------.
1263| yynewstate -- Push a new state, which is found in yystate. |
1264`------------------------------------------------------------*/
1265 yynewstate:
1266 /* In all cases, when you get here, the value and location stacks
1267 have just been pushed. So pushing a state here evens the stacks. */
1268 yyssp++;
1269
1270 yysetstate:
1271 *yyssp = yystate;
1272
1273 if (yyss + yystacksize - 1 <= yyssp)
1274 {
1275 /* Get the current used size of the three stacks, in elements. */
1276 YYSIZE_T yysize = yyssp - yyss + 1;
1277
1278#ifdef yyoverflow
1279 {
1280 /* Give user a chance to reallocate the stack. Use copies of
1281 these so that the &'s don't force the real ones into
1282 memory. */
1283 YYSTYPE *yyvs1 = yyvs;
1284 yytype_int16 *yyss1 = yyss;
1285 YYLTYPE *yyls1 = yyls;
1286
1287 /* Each stack pointer address is followed by the size of the
1288 data in use in that stack, in bytes. This used to be a
1289 conditional around just the two extra args, but that might
1290 be undefined if yyoverflow is a macro. */
1291 yyoverflow (YY_("memory exhausted"),
1292 &yyss1, yysize * sizeof (*yyssp),
1293 &yyvs1, yysize * sizeof (*yyvsp),
1294 &yyls1, yysize * sizeof (*yylsp),
1295 &yystacksize);
1296 yyls = yyls1;
1297 yyss = yyss1;
1298 yyvs = yyvs1;
1299 }
1300#else /* no yyoverflow */
1301# ifndef YYSTACK_RELOCATE
1302 goto yyexhaustedlab;
1303# else
1304 /* Extend the stack our own way. */
1305 if (YYMAXDEPTH <= yystacksize)
1306 goto yyexhaustedlab;
1307 yystacksize *= 2;
1308 if (YYMAXDEPTH < yystacksize)
1309 yystacksize = YYMAXDEPTH;
1310
1311 {
1312 yytype_int16 *yyss1 = yyss;
1313 union yyalloc *yyptr =
1314 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1315 if (! yyptr)
1316 goto yyexhaustedlab;
1317 YYSTACK_RELOCATE (yyss);
1318 YYSTACK_RELOCATE (yyvs);
1319 YYSTACK_RELOCATE (yyls);
1320# undef YYSTACK_RELOCATE
1321 if (yyss1 != yyssa)
1322 YYSTACK_FREE (yyss1);
1323 }
1324# endif
1325#endif /* no yyoverflow */
1326
1327 yyssp = yyss + yysize - 1;
1328 yyvsp = yyvs + yysize - 1;
1329 yylsp = yyls + yysize - 1;
1330
1331 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1332 (unsigned long int) yystacksize));
1333
1334 if (yyss + yystacksize - 1 <= yyssp)
1335 YYABORT;
1336 }
1337
1338 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1339
1340 goto yybackup;
1341
1342/*-----------.
1343| yybackup. |
1344`-----------*/
1345yybackup:
1346
1347 /* Do appropriate processing given the current state. Read a
1348 look-ahead token if we need one and don't already have one. */
1349
1350 /* First try to decide what to do without reference to look-ahead token. */
1351 yyn = yypact[yystate];
1352 if (yyn == YYPACT_NINF)
1353 goto yydefault;
1354
1355 /* Not known => get a look-ahead token if don't already have one. */
1356
1357 /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
1358 if (yychar == YYEMPTY)
1359 {
1360 YYDPRINTF ((stderr, "Reading a token: "));
1361 yychar = YYLEX;
1362 }
1363
1364 if (yychar <= YYEOF)
1365 {
1366 yychar = yytoken = YYEOF;
1367 YYDPRINTF ((stderr, "Now at end of input.\n"));
1368 }
1369 else
1370 {
1371 yytoken = YYTRANSLATE (yychar);
1372 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1373 }
1374
1375 /* If the proper action on seeing token YYTOKEN is to reduce or to
1376 detect an error, take that action. */
1377 yyn += yytoken;
1378 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1379 goto yydefault;
1380 yyn = yytable[yyn];
1381 if (yyn <= 0)
1382 {
1383 if (yyn == 0 || yyn == YYTABLE_NINF)
1384 goto yyerrlab;
1385 yyn = -yyn;
1386 goto yyreduce;
1387 }
1388
1389 if (yyn == YYFINAL)
1390 YYACCEPT;
1391
1392 /* Count tokens shifted since error; after three, turn off error
1393 status. */
1394 if (yyerrstatus)
1395 yyerrstatus--;
1396
1397 /* Shift the look-ahead token. */
1398 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1399
1400 /* Discard the shifted token unless it is eof. */
1401 if (yychar != YYEOF)
1402 yychar = YYEMPTY;
1403
1404 yystate = yyn;
1405 *++yyvsp = yylval;
1406 *++yylsp = yylloc;
1407 goto yynewstate;
1408
1409
1410/*-----------------------------------------------------------.
1411| yydefault -- do the default action for the current state. |
1412`-----------------------------------------------------------*/
1413yydefault:
1414 yyn = yydefact[yystate];
1415 if (yyn == 0)
1416 goto yyerrlab;
1417 goto yyreduce;
1418
1419
1420/*-----------------------------.
1421| yyreduce -- Do a reduction. |
1422`-----------------------------*/
1423yyreduce:
1424 /* yyn is the number of a rule to reduce with. */
1425 yylen = yyr2[yyn];
1426
1427 /* If YYLEN is nonzero, implement the default value of the action:
1428 `$$ = $1'.
1429
1430 Otherwise, the following line sets YYVAL to garbage.
1431 This behavior is undocumented and Bison
1432 users should not rely upon it. Assigning to YYVAL
1433 unconditionally makes the parser a bit smaller, and it avoids a
1434 GCC warning that YYVAL may be used uninitialized. */
1435 yyval = yyvsp[1-yylen];
1436
1437 /* Default location. */
1438 YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
1439 YY_REDUCE_PRINT (yyn);
1440 switch (yyn)
1441 {
1442 case 2:
1443#line 86 "dtc-parser.y"
1444 {
1445 the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node));
1446 ;}
1447 break;
1448
1449 case 3:
1450#line 90 "dtc-parser.y"
1451 {
1452 the_boot_info = build_boot_info((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].node));
1453 ;}
1454 break;
1455
1456 case 4:
1457#line 97 "dtc-parser.y"
1458 {
1459 (yyval.re) = NULL;
1460 ;}
1461 break;
1462
1463 case 5:
1464#line 101 "dtc-parser.y"
1465 {
1466 (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
1467 ;}
1468 break;
1469
1470 case 6:
1471#line 108 "dtc-parser.y"
1472 {
1473 (yyval.re) = build_reserve_entry((yyvsp[(3) - (5)].addr), (yyvsp[(4) - (5)].addr), (yyvsp[(1) - (5)].labelref));
1474 ;}
1475 break;
1476
1477 case 7:
1478#line 115 "dtc-parser.y"
1479 {
1480 (yyval.re) = NULL;
1481 ;}
1482 break;
1483
1484 case 8:
1485#line 119 "dtc-parser.y"
1486 {
1487 (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
1488 ;}
1489 break;
1490
1491 case 9:
1492#line 126 "dtc-parser.y"
1493 {
1494 (yyval.re) = (yyvsp[(1) - (1)].re);
1495 ;}
1496 break;
1497
1498 case 10:
1499#line 130 "dtc-parser.y"
1500 {
1501 (yyval.re) = build_reserve_entry((yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].addr) - (yyvsp[(3) - (6)].addr) + 1, (yyvsp[(1) - (6)].labelref));
1502 ;}
1503 break;
1504
1505 case 11:
1506#line 137 "dtc-parser.y"
1507 {
1508 (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64);
1509 ;}
1510 break;
1511
1512 case 12:
1513#line 141 "dtc-parser.y"
1514 {
1515 (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 16, 64);
1516 ;}
1517 break;
1518
1519 case 13:
1520#line 148 "dtc-parser.y"
1521 {
1522 (yyval.node) = name_node((yyvsp[(2) - (2)].node), "", NULL);
1523 ;}
1524 break;
1525
1526 case 14:
1527#line 155 "dtc-parser.y"
1528 {
1529 (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist));
1530 ;}
1531 break;
1532
1533 case 15:
1534#line 162 "dtc-parser.y"
1535 {
1536 (yyval.proplist) = NULL;
1537 ;}
1538 break;
1539
1540 case 16:
1541#line 166 "dtc-parser.y"
1542 {
1543 (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist));
1544 ;}
1545 break;
1546
1547 case 17:
1548#line 173 "dtc-parser.y"
1549 {
1550 (yyval.prop) = build_property((yyvsp[(2) - (5)].propnodename), (yyvsp[(4) - (5)].data), (yyvsp[(1) - (5)].labelref));
1551 ;}
1552 break;
1553
1554 case 18:
1555#line 177 "dtc-parser.y"
1556 {
1557 (yyval.prop) = build_property((yyvsp[(2) - (3)].propnodename), empty_data, (yyvsp[(1) - (3)].labelref));
1558 ;}
1559 break;
1560
1561 case 19:
1562#line 184 "dtc-parser.y"
1563 {
1564 (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data));
1565 ;}
1566 break;
1567
1568 case 20:
1569#line 188 "dtc-parser.y"
1570 {
1571 (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
1572 ;}
1573 break;
1574
1575 case 21:
1576#line 192 "dtc-parser.y"
1577 {
1578 (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
1579 ;}
1580 break;
1581
1582 case 22:
1583#line 196 "dtc-parser.y"
1584 {
1585 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref));
1586 ;}
1587 break;
1588
1589 case 23:
1590#line 200 "dtc-parser.y"
1591 {
1592 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1593 ;}
1594 break;
1595
1596 case 24:
1597#line 207 "dtc-parser.y"
1598 {
1599 (yyval.data) = empty_data;
1600 ;}
1601 break;
1602
1603 case 25:
1604#line 211 "dtc-parser.y"
1605 {
1606 (yyval.data) = (yyvsp[(1) - (2)].data);
1607 ;}
1608 break;
1609
1610 case 26:
1611#line 215 "dtc-parser.y"
1612 {
1613 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1614 ;}
1615 break;
1616
1617 case 27:
1618#line 222 "dtc-parser.y"
1619 {
1620 (yyval.data) = empty_data;
1621 ;}
1622 break;
1623
1624 case 28:
1625#line 226 "dtc-parser.y"
1626 {
1627 (yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell));
1628 ;}
1629 break;
1630
1631 case 29:
1632#line 230 "dtc-parser.y"
1633 {
1634 (yyval.data) = data_append_cell(data_add_marker((yyvsp[(1) - (2)].data), REF_PHANDLE,
1635 (yyvsp[(2) - (2)].labelref)), -1);
1636 ;}
1637 break;
1638
1639 case 30:
1640#line 235 "dtc-parser.y"
1641 {
1642 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1643 ;}
1644 break;
1645
1646 case 31:
1647#line 242 "dtc-parser.y"
1648 {
1649 (yyval.cbase) = 16;
1650 ;}
1651 break;
1652
1653 case 33:
1654#line 250 "dtc-parser.y"
1655 {
1656 (yyval.cell) = eval_literal((yyvsp[(1) - (1)].literal), 0, 32);
1657 ;}
1658 break;
1659
1660 case 34:
1661#line 254 "dtc-parser.y"
1662 {
1663 (yyval.cell) = eval_literal((yyvsp[(2) - (2)].literal), (yyvsp[(1) - (2)].cbase), 32);
1664 ;}
1665 break;
1666
1667 case 35:
1668#line 261 "dtc-parser.y"
1669 {
1670 (yyval.data) = empty_data;
1671 ;}
1672 break;
1673
1674 case 36:
1675#line 265 "dtc-parser.y"
1676 {
1677 (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte));
1678 ;}
1679 break;
1680
1681 case 37:
1682#line 269 "dtc-parser.y"
1683 {
1684 (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
1685 ;}
1686 break;
1687
1688 case 38:
1689#line 276 "dtc-parser.y"
1690 {
1691 (yyval.nodelist) = NULL;
1692 ;}
1693 break;
1694
1695 case 39:
1696#line 280 "dtc-parser.y"
1697 {
1698 (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist));
1699 ;}
1700 break;
1701
1702 case 40:
1703#line 284 "dtc-parser.y"
1704 {
1705 yyerror("syntax error: properties must precede subnodes\n");
1706 YYERROR;
1707 ;}
1708 break;
1709
1710 case 41:
1711#line 292 "dtc-parser.y"
1712 {
1713 (yyval.node) = name_node((yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].propnodename), (yyvsp[(1) - (3)].labelref));
1714 ;}
1715 break;
1716
1717 case 42:
1718#line 299 "dtc-parser.y"
1719 {
1720 (yyval.labelref) = NULL;
1721 ;}
1722 break;
1723
1724 case 43:
1725#line 303 "dtc-parser.y"
1726 {
1727 (yyval.labelref) = (yyvsp[(1) - (1)].labelref);
1728 ;}
1729 break;
1730
1731
1732/* Line 1267 of yacc.c. */
1733#line 1734 "dtc-parser.tab.c"
1734 default: break;
1735 }
1736 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
1737
1738 YYPOPSTACK (yylen);
1739 yylen = 0;
1740 YY_STACK_PRINT (yyss, yyssp);
1741
1742 *++yyvsp = yyval;
1743 *++yylsp = yyloc;
1744
1745 /* Now `shift' the result of the reduction. Determine what state
1746 that goes to, based on the state we popped back to and the rule
1747 number reduced by. */
1748
1749 yyn = yyr1[yyn];
1750
1751 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
1752 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1753 yystate = yytable[yystate];
1754 else
1755 yystate = yydefgoto[yyn - YYNTOKENS];
1756
1757 goto yynewstate;
1758
1759
1760/*------------------------------------.
1761| yyerrlab -- here on detecting error |
1762`------------------------------------*/
1763yyerrlab:
1764 /* If not already recovering from an error, report this error. */
1765 if (!yyerrstatus)
1766 {
1767 ++yynerrs;
1768#if ! YYERROR_VERBOSE
1769 yyerror (YY_("syntax error"));
1770#else
1771 {
1772 YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
1773 if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
1774 {
1775 YYSIZE_T yyalloc = 2 * yysize;
1776 if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
1777 yyalloc = YYSTACK_ALLOC_MAXIMUM;
1778 if (yymsg != yymsgbuf)
1779 YYSTACK_FREE (yymsg);
1780 yymsg = (char *) YYSTACK_ALLOC (yyalloc);
1781 if (yymsg)
1782 yymsg_alloc = yyalloc;
1783 else
1784 {
1785 yymsg = yymsgbuf;
1786 yymsg_alloc = sizeof yymsgbuf;
1787 }
1788 }
1789
1790 if (0 < yysize && yysize <= yymsg_alloc)
1791 {
1792 (void) yysyntax_error (yymsg, yystate, yychar);
1793 yyerror (yymsg);
1794 }
1795 else
1796 {
1797 yyerror (YY_("syntax error"));
1798 if (yysize != 0)
1799 goto yyexhaustedlab;
1800 }
1801 }
1802#endif
1803 }
1804
1805 yyerror_range[0] = yylloc;
1806
1807 if (yyerrstatus == 3)
1808 {
1809 /* If just tried and failed to reuse look-ahead token after an
1810 error, discard it. */
1811
1812 if (yychar <= YYEOF)
1813 {
1814 /* Return failure if at end of input. */
1815 if (yychar == YYEOF)
1816 YYABORT;
1817 }
1818 else
1819 {
1820 yydestruct ("Error: discarding",
1821 yytoken, &yylval, &yylloc);
1822 yychar = YYEMPTY;
1823 }
1824 }
1825
1826 /* Else will try to reuse look-ahead token after shifting the error
1827 token. */
1828 goto yyerrlab1;
1829
1830
1831/*---------------------------------------------------.
1832| yyerrorlab -- error raised explicitly by YYERROR. |
1833`---------------------------------------------------*/
1834yyerrorlab:
1835
1836 /* Pacify compilers like GCC when the user code never invokes
1837 YYERROR and the label yyerrorlab therefore never appears in user
1838 code. */
1839 if (/*CONSTCOND*/ 0)
1840 goto yyerrorlab;
1841
1842 yyerror_range[0] = yylsp[1-yylen];
1843 /* Do not reclaim the symbols of the rule which action triggered
1844 this YYERROR. */
1845 YYPOPSTACK (yylen);
1846 yylen = 0;
1847 YY_STACK_PRINT (yyss, yyssp);
1848 yystate = *yyssp;
1849 goto yyerrlab1;
1850
1851
1852/*-------------------------------------------------------------.
1853| yyerrlab1 -- common code for both syntax error and YYERROR. |
1854`-------------------------------------------------------------*/
1855yyerrlab1:
1856 yyerrstatus = 3; /* Each real token shifted decrements this. */
1857
1858 for (;;)
1859 {
1860 yyn = yypact[yystate];
1861 if (yyn != YYPACT_NINF)
1862 {
1863 yyn += YYTERROR;
1864 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
1865 {
1866 yyn = yytable[yyn];
1867 if (0 < yyn)
1868 break;
1869 }
1870 }
1871
1872 /* Pop the current state because it cannot handle the error token. */
1873 if (yyssp == yyss)
1874 YYABORT;
1875
1876 yyerror_range[0] = *yylsp;
1877 yydestruct ("Error: popping",
1878 yystos[yystate], yyvsp, yylsp);
1879 YYPOPSTACK (1);
1880 yystate = *yyssp;
1881 YY_STACK_PRINT (yyss, yyssp);
1882 }
1883
1884 if (yyn == YYFINAL)
1885 YYACCEPT;
1886
1887 *++yyvsp = yylval;
1888
1889 yyerror_range[1] = yylloc;
1890 /* Using YYLLOC is tempting, but would change the location of
1891 the look-ahead. YYLOC is available though. */
1892 YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
1893 *++yylsp = yyloc;
1894
1895 /* Shift the error token. */
1896 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
1897
1898 yystate = yyn;
1899 goto yynewstate;
1900
1901
1902/*-------------------------------------.
1903| yyacceptlab -- YYACCEPT comes here. |
1904`-------------------------------------*/
1905yyacceptlab:
1906 yyresult = 0;
1907 goto yyreturn;
1908
1909/*-----------------------------------.
1910| yyabortlab -- YYABORT comes here. |
1911`-----------------------------------*/
1912yyabortlab:
1913 yyresult = 1;
1914 goto yyreturn;
1915
1916#ifndef yyoverflow
1917/*-------------------------------------------------.
1918| yyexhaustedlab -- memory exhaustion comes here. |
1919`-------------------------------------------------*/
1920yyexhaustedlab:
1921 yyerror (YY_("memory exhausted"));
1922 yyresult = 2;
1923 /* Fall through. */
1924#endif
1925
1926yyreturn:
1927 if (yychar != YYEOF && yychar != YYEMPTY)
1928 yydestruct ("Cleanup: discarding lookahead",
1929 yytoken, &yylval, &yylloc);
1930 /* Do not reclaim the symbols of the rule which action triggered
1931 this YYABORT or YYACCEPT. */
1932 YYPOPSTACK (yylen);
1933 YY_STACK_PRINT (yyss, yyssp);
1934 while (yyssp != yyss)
1935 {
1936 yydestruct ("Cleanup: popping",
1937 yystos[*yyssp], yyvsp, yylsp);
1938 YYPOPSTACK (1);
1939 }
1940#ifndef yyoverflow
1941 if (yyss != yyssa)
1942 YYSTACK_FREE (yyss);
1943#endif
1944#if YYERROR_VERBOSE
1945 if (yymsg != yymsgbuf)
1946 YYSTACK_FREE (yymsg);
1947#endif
1948 /* Make sure YYID is used. */
1949 return YYID (yyresult);
1950}
1951
1952
1953#line 308 "dtc-parser.y"
1954
1955
1956void yyerror (char const *s)
1957{
1958 const char *fname = srcpos_filename_for_num(yylloc.filenum);
1959
1960 if (strcmp(fname, "-") == 0)
1961 fname = "stdin";
1962
1963 fprintf(stderr, "%s:%d %s\n",
1964 fname, yylloc.first_line, s);
1965}
1966
1967unsigned long long eval_literal(const char *s, int base, int bits)
1968{
1969 unsigned long long val;
1970 char *e;
1971
1972 errno = 0;
1973 val = strtoull(s, &e, base);
1974 if (*e)
1975 yyerror("bad characters in literal");
1976 else if ((errno == ERANGE)
1977 || ((bits < 64) && (val >= (1ULL << bits))))
1978 yyerror("literal out of range");
1979 else if (errno != 0)
1980 yyerror("bad literal");
1981 return val;
1982}
1983
diff --git a/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped b/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped
new file mode 100644
index 000000000000..4707b029ed25
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/dtc-parser.tab.h_shipped
@@ -0,0 +1,111 @@
1/* A Bison parser, made by GNU Bison 2.3. */
2
3/* Skeleton interface for Bison's Yacc-like parsers in C
4
5 Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
6 Free Software Foundation, Inc.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
22
23/* As a special exception, you may create a larger work that contains
24 part or all of the Bison parser skeleton and distribute that work
25 under terms of your choice, so long as that work isn't itself a
26 parser generator using the skeleton or a modified version thereof
27 as a parser skeleton. Alternatively, if you modify or redistribute
28 the parser skeleton itself, you may (at your option) remove this
29 special exception, which will cause the skeleton and the resulting
30 Bison output files to be licensed under the GNU General Public
31 License without this special exception.
32
33 This special exception was added by the Free Software Foundation in
34 version 2.2 of Bison. */
35
36/* Tokens. */
37#ifndef YYTOKENTYPE
38# define YYTOKENTYPE
39 /* Put the tokens into the symbol table, so that GDB and other debuggers
40 know about them. */
41 enum yytokentype {
42 DT_V1 = 258,
43 DT_MEMRESERVE = 259,
44 DT_PROPNODENAME = 260,
45 DT_LITERAL = 261,
46 DT_LEGACYLITERAL = 262,
47 DT_BASE = 263,
48 DT_BYTE = 264,
49 DT_STRING = 265,
50 DT_LABEL = 266,
51 DT_REF = 267
52 };
53#endif
54/* Tokens. */
55#define DT_V1 258
56#define DT_MEMRESERVE 259
57#define DT_PROPNODENAME 260
58#define DT_LITERAL 261
59#define DT_LEGACYLITERAL 262
60#define DT_BASE 263
61#define DT_BYTE 264
62#define DT_STRING 265
63#define DT_LABEL 266
64#define DT_REF 267
65
66
67
68
69#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
70typedef union YYSTYPE
71#line 34 "dtc-parser.y"
72{
73 char *propnodename;
74 char *literal;
75 char *labelref;
76 unsigned int cbase;
77 u8 byte;
78 struct data data;
79
80 u64 addr;
81 cell_t cell;
82 struct property *prop;
83 struct property *proplist;
84 struct node *node;
85 struct node *nodelist;
86 struct reserve_info *re;
87}
88/* Line 1489 of yacc.c. */
89#line 90 "dtc-parser.tab.h"
90 YYSTYPE;
91# define yystype YYSTYPE /* obsolescent; will be withdrawn */
92# define YYSTYPE_IS_DECLARED 1
93# define YYSTYPE_IS_TRIVIAL 1
94#endif
95
96extern YYSTYPE yylval;
97
98#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
99typedef struct YYLTYPE
100{
101 int first_line;
102 int first_column;
103 int last_line;
104 int last_column;
105} YYLTYPE;
106# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
107# define YYLTYPE_IS_DECLARED 1
108# define YYLTYPE_IS_TRIVIAL 1
109#endif
110
111extern YYLTYPE yylloc;
diff --git a/arch/powerpc/boot/dtc-src/dtc-parser.y b/arch/powerpc/boot/dtc-src/dtc-parser.y
new file mode 100644
index 000000000000..002ea7fef184
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/dtc-parser.y
@@ -0,0 +1,336 @@
1/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3 *
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 */
20
21%locations
22
23%{
24#include "dtc.h"
25#include "srcpos.h"
26
27int yylex(void);
28unsigned long long eval_literal(const char *s, int base, int bits);
29
30extern struct boot_info *the_boot_info;
31
32%}
33
34%union {
35 char *propnodename;
36 char *literal;
37 char *labelref;
38 unsigned int cbase;
39 u8 byte;
40 struct data data;
41
42 u64 addr;
43 cell_t cell;
44 struct property *prop;
45 struct property *proplist;
46 struct node *node;
47 struct node *nodelist;
48 struct reserve_info *re;
49}
50
51%token DT_V1
52%token DT_MEMRESERVE
53%token <propnodename> DT_PROPNODENAME
54%token <literal> DT_LITERAL
55%token <literal> DT_LEGACYLITERAL
56%token <cbase> DT_BASE
57%token <byte> DT_BYTE
58%token <data> DT_STRING
59%token <labelref> DT_LABEL
60%token <labelref> DT_REF
61
62%type <data> propdata
63%type <data> propdataprefix
64%type <re> memreserve
65%type <re> memreserves
66%type <re> v0_memreserve
67%type <re> v0_memreserves
68%type <addr> addr
69%type <data> celllist
70%type <cbase> cellbase
71%type <cell> cellval
72%type <data> bytestring
73%type <prop> propdef
74%type <proplist> proplist
75
76%type <node> devicetree
77%type <node> nodedef
78%type <node> subnode
79%type <nodelist> subnodes
80%type <labelref> label
81
82%%
83
84sourcefile:
85 DT_V1 ';' memreserves devicetree
86 {
87 the_boot_info = build_boot_info($3, $4);
88 }
89 | v0_memreserves devicetree
90 {
91 the_boot_info = build_boot_info($1, $2);
92 }
93 ;
94
95memreserves:
96 /* empty */
97 {
98 $$ = NULL;
99 }
100 | memreserve memreserves
101 {
102 $$ = chain_reserve_entry($1, $2);
103 }
104 ;
105
106memreserve:
107 label DT_MEMRESERVE addr addr ';'
108 {
109 $$ = build_reserve_entry($3, $4, $1);
110 }
111 ;
112
113v0_memreserves:
114 /* empty */
115 {
116 $$ = NULL;
117 }
118 | v0_memreserve v0_memreserves
119 {
120 $$ = chain_reserve_entry($1, $2);
121 };
122 ;
123
124v0_memreserve:
125 memreserve
126 {
127 $$ = $1;
128 }
129 | label DT_MEMRESERVE addr '-' addr ';'
130 {
131 $$ = build_reserve_entry($3, $5 - $3 + 1, $1);
132 }
133 ;
134
135addr:
136 DT_LITERAL
137 {
138 $$ = eval_literal($1, 0, 64);
139 }
140 | DT_LEGACYLITERAL
141 {
142 $$ = eval_literal($1, 16, 64);
143 }
144 ;
145
146devicetree:
147 '/' nodedef
148 {
149 $$ = name_node($2, "", NULL);
150 }
151 ;
152
153nodedef:
154 '{' proplist subnodes '}' ';'
155 {
156 $$ = build_node($2, $3);
157 }
158 ;
159
160proplist:
161 /* empty */
162 {
163 $$ = NULL;
164 }
165 | proplist propdef
166 {
167 $$ = chain_property($2, $1);
168 }
169 ;
170
171propdef:
172 label DT_PROPNODENAME '=' propdata ';'
173 {
174 $$ = build_property($2, $4, $1);
175 }
176 | label DT_PROPNODENAME ';'
177 {
178 $$ = build_property($2, empty_data, $1);
179 }
180 ;
181
182propdata:
183 propdataprefix DT_STRING
184 {
185 $$ = data_merge($1, $2);
186 }
187 | propdataprefix '<' celllist '>'
188 {
189 $$ = data_merge($1, $3);
190 }
191 | propdataprefix '[' bytestring ']'
192 {
193 $$ = data_merge($1, $3);
194 }
195 | propdataprefix DT_REF
196 {
197 $$ = data_add_marker($1, REF_PATH, $2);
198 }
199 | propdata DT_LABEL
200 {
201 $$ = data_add_marker($1, LABEL, $2);
202 }
203 ;
204
205propdataprefix:
206 /* empty */
207 {
208 $$ = empty_data;
209 }
210 | propdata ','
211 {
212 $$ = $1;
213 }
214 | propdataprefix DT_LABEL
215 {
216 $$ = data_add_marker($1, LABEL, $2);
217 }
218 ;
219
220celllist:
221 /* empty */
222 {
223 $$ = empty_data;
224 }
225 | celllist cellval
226 {
227 $$ = data_append_cell($1, $2);
228 }
229 | celllist DT_REF
230 {
231 $$ = data_append_cell(data_add_marker($1, REF_PHANDLE,
232 $2), -1);
233 }
234 | celllist DT_LABEL
235 {
236 $$ = data_add_marker($1, LABEL, $2);
237 }
238 ;
239
240cellbase:
241 /* empty */
242 {
243 $$ = 16;
244 }
245 | DT_BASE
246 ;
247
248cellval:
249 DT_LITERAL
250 {
251 $$ = eval_literal($1, 0, 32);
252 }
253 | cellbase DT_LEGACYLITERAL
254 {
255 $$ = eval_literal($2, $1, 32);
256 }
257 ;
258
259bytestring:
260 /* empty */
261 {
262 $$ = empty_data;
263 }
264 | bytestring DT_BYTE
265 {
266 $$ = data_append_byte($1, $2);
267 }
268 | bytestring DT_LABEL
269 {
270 $$ = data_add_marker($1, LABEL, $2);
271 }
272 ;
273
274subnodes:
275 /* empty */
276 {
277 $$ = NULL;
278 }
279 | subnode subnodes
280 {
281 $$ = chain_node($1, $2);
282 }
283 | subnode propdef
284 {
285 yyerror("syntax error: properties must precede subnodes\n");
286 YYERROR;
287 }
288 ;
289
290subnode:
291 label DT_PROPNODENAME nodedef
292 {
293 $$ = name_node($3, $2, $1);
294 }
295 ;
296
297label:
298 /* empty */
299 {
300 $$ = NULL;
301 }
302 | DT_LABEL
303 {
304 $$ = $1;
305 }
306 ;
307
308%%
309
310void yyerror (char const *s)
311{
312 const char *fname = srcpos_filename_for_num(yylloc.filenum);
313
314 if (strcmp(fname, "-") == 0)
315 fname = "stdin";
316
317 fprintf(stderr, "%s:%d %s\n",
318 fname, yylloc.first_line, s);
319}
320
321unsigned long long eval_literal(const char *s, int base, int bits)
322{
323 unsigned long long val;
324 char *e;
325
326 errno = 0;
327 val = strtoull(s, &e, base);
328 if (*e)
329 yyerror("bad characters in literal");
330 else if ((errno == ERANGE)
331 || ((bits < 64) && (val >= (1ULL << bits))))
332 yyerror("literal out of range");
333 else if (errno != 0)
334 yyerror("bad literal");
335 return val;
336}
diff --git a/arch/powerpc/boot/dtc-src/dtc.c b/arch/powerpc/boot/dtc-src/dtc.c
new file mode 100644
index 000000000000..01131d7c2d5e
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/dtc.c
@@ -0,0 +1,231 @@
1/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3 *
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 */
20
21#include "dtc.h"
22#include "srcpos.h"
23
24#include "version_gen.h"
25
26/*
27 * Command line options
28 */
29int quiet; /* Level of quietness */
30int reservenum; /* Number of memory reservation slots */
31int minsize; /* Minimum blob size */
32int padsize; /* Additional padding to blob */
33
34char *join_path(const char *path, const char *name)
35{
36 int lenp = strlen(path);
37 int lenn = strlen(name);
38 int len;
39 int needslash = 1;
40 char *str;
41
42 len = lenp + lenn + 2;
43 if ((lenp > 0) && (path[lenp-1] == '/')) {
44 needslash = 0;
45 len--;
46 }
47
48 str = xmalloc(len);
49 memcpy(str, path, lenp);
50 if (needslash) {
51 str[lenp] = '/';
52 lenp++;
53 }
54 memcpy(str+lenp, name, lenn+1);
55 return str;
56}
57
58void fill_fullpaths(struct node *tree, const char *prefix)
59{
60 struct node *child;
61 const char *unit;
62
63 tree->fullpath = join_path(prefix, tree->name);
64
65 unit = strchr(tree->name, '@');
66 if (unit)
67 tree->basenamelen = unit - tree->name;
68 else
69 tree->basenamelen = strlen(tree->name);
70
71 for_each_child(tree, child)
72 fill_fullpaths(child, tree->fullpath);
73}
74
75static void __attribute__ ((noreturn)) usage(void)
76{
77 fprintf(stderr, "Usage:\n");
78 fprintf(stderr, "\tdtc [options] <input file>\n");
79 fprintf(stderr, "\nOptions:\n");
80 fprintf(stderr, "\t-h\n");
81 fprintf(stderr, "\t\tThis help text\n");
82 fprintf(stderr, "\t-q\n");
83 fprintf(stderr, "\t\tQuiet: -q suppress warnings, -qq errors, -qqq all\n");
84 fprintf(stderr, "\t-I <input format>\n");
85 fprintf(stderr, "\t\tInput formats are:\n");
86 fprintf(stderr, "\t\t\tdts - device tree source text\n");
87 fprintf(stderr, "\t\t\tdtb - device tree blob\n");
88 fprintf(stderr, "\t\t\tfs - /proc/device-tree style directory\n");
89 fprintf(stderr, "\t-o <output file>\n");
90 fprintf(stderr, "\t-O <output format>\n");
91 fprintf(stderr, "\t\tOutput formats are:\n");
92 fprintf(stderr, "\t\t\tdts - device tree source text\n");
93 fprintf(stderr, "\t\t\tdtb - device tree blob\n");
94 fprintf(stderr, "\t\t\tasm - assembler source\n");
95 fprintf(stderr, "\t-V <output version>\n");
96 fprintf(stderr, "\t\tBlob version to produce, defaults to %d (relevant for dtb\n\t\tand asm output only)\n", DEFAULT_FDT_VERSION);
97 fprintf(stderr, "\t-R <number>\n");
98 fprintf(stderr, "\t\tMake space for <number> reserve map entries (relevant for \n\t\tdtb and asm output only)\n");
99 fprintf(stderr, "\t-S <bytes>\n");
100 fprintf(stderr, "\t\tMake the blob at least <bytes> long (extra space)\n");
101 fprintf(stderr, "\t-p <bytes>\n");
102 fprintf(stderr, "\t\tAdd padding to the blob of <bytes> long (extra space)\n");
103 fprintf(stderr, "\t-b <number>\n");
104 fprintf(stderr, "\t\tSet the physical boot cpu\n");
105 fprintf(stderr, "\t-f\n");
106 fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n");
107 fprintf(stderr, "\t-v\n");
108 fprintf(stderr, "\t\tPrint DTC version and exit\n");
109 exit(2);
110}
111
112int main(int argc, char *argv[])
113{
114 struct boot_info *bi;
115 const char *inform = "dts";
116 const char *outform = "dts";
117 const char *outname = "-";
118 int force = 0, check = 0;
119 const char *arg;
120 int opt;
121 FILE *inf = NULL;
122 FILE *outf = NULL;
123 int outversion = DEFAULT_FDT_VERSION;
124 int boot_cpuid_phys = 0xfeedbeef;
125
126 quiet = 0;
127 reservenum = 0;
128 minsize = 0;
129 padsize = 0;
130
131 while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:v")) != EOF) {
132 switch (opt) {
133 case 'I':
134 inform = optarg;
135 break;
136 case 'O':
137 outform = optarg;
138 break;
139 case 'o':
140 outname = optarg;
141 break;
142 case 'V':
143 outversion = strtol(optarg, NULL, 0);
144 break;
145 case 'R':
146 reservenum = strtol(optarg, NULL, 0);
147 break;
148 case 'S':
149 minsize = strtol(optarg, NULL, 0);
150 break;
151 case 'p':
152 padsize = strtol(optarg, NULL, 0);
153 break;
154 case 'f':
155 force = 1;
156 break;
157 case 'c':
158 check = 1;
159 break;
160 case 'q':
161 quiet++;
162 break;
163 case 'b':
164 boot_cpuid_phys = strtol(optarg, NULL, 0);
165 break;
166 case 'v':
167 printf("Version: %s\n", DTC_VERSION);
168 exit(0);
169 case 'h':
170 default:
171 usage();
172 }
173 }
174
175 if (argc > (optind+1))
176 usage();
177 else if (argc < (optind+1))
178 arg = "-";
179 else
180 arg = argv[optind];
181
182 /* minsize and padsize are mutually exclusive */
183 if ((minsize) && (padsize)) {
184 die("Can't set both -p and -S\n");
185 }
186
187 fprintf(stderr, "DTC: %s->%s on file \"%s\"\n",
188 inform, outform, arg);
189
190 if (streq(inform, "dts")) {
191 bi = dt_from_source(arg);
192 } else if (streq(inform, "fs")) {
193 bi = dt_from_fs(arg);
194 } else if(streq(inform, "dtb")) {
195 inf = dtc_open_file(arg);
196 bi = dt_from_blob(inf);
197 } else {
198 die("Unknown input format \"%s\"\n", inform);
199 }
200
201 if (inf && (inf != stdin))
202 fclose(inf);
203
204 if (! bi || ! bi->dt)
205 die("Couldn't read input tree\n");
206
207 process_checks(force, bi, check, outversion, boot_cpuid_phys);
208
209 if (streq(outname, "-")) {
210 outf = stdout;
211 } else {
212 outf = fopen(outname, "w");
213 if (! outf)
214 die("Couldn't open output file %s: %s\n",
215 outname, strerror(errno));
216 }
217
218 if (streq(outform, "dts")) {
219 dt_to_source(outf, bi);
220 } else if (streq(outform, "dtb")) {
221 dt_to_blob(outf, bi, outversion, boot_cpuid_phys);
222 } else if (streq(outform, "asm")) {
223 dt_to_asm(outf, bi, outversion, boot_cpuid_phys);
224 } else if (streq(outform, "null")) {
225 /* do nothing */
226 } else {
227 die("Unknown output format \"%s\"\n", outform);
228 }
229
230 exit(0);
231}
diff --git a/arch/powerpc/boot/dtc-src/dtc.h b/arch/powerpc/boot/dtc-src/dtc.h
new file mode 100644
index 000000000000..65281777a167
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/dtc.h
@@ -0,0 +1,269 @@
1#ifndef _DTC_H
2#define _DTC_H
3
4/*
5 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
6 *
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 * USA
22 */
23
24#include <stdio.h>
25#include <string.h>
26#include <stdlib.h>
27#include <stdint.h>
28#include <stdarg.h>
29#include <assert.h>
30#include <ctype.h>
31#include <errno.h>
32#include <unistd.h>
33#include <netinet/in.h>
34#include <endian.h>
35#include <byteswap.h>
36
37#include <fdt.h>
38
39#define DEFAULT_FDT_VERSION 17
40/*
41 * Command line options
42 */
43extern int quiet; /* Level of quietness */
44extern int reservenum; /* Number of memory reservation slots */
45extern int minsize; /* Minimum blob size */
46extern int padsize; /* Additional padding to blob */
47
48static inline void __attribute__((noreturn)) die(char * str, ...)
49{
50 va_list ap;
51
52 va_start(ap, str);
53 fprintf(stderr, "FATAL ERROR: ");
54 vfprintf(stderr, str, ap);
55 exit(1);
56}
57
58static inline void *xmalloc(size_t len)
59{
60 void *new = malloc(len);
61
62 if (! new)
63 die("malloc() failed\n");
64
65 return new;
66}
67
68static inline void *xrealloc(void *p, size_t len)
69{
70 void *new = realloc(p, len);
71
72 if (! new)
73 die("realloc() failed (len=%d)\n", len);
74
75 return new;
76}
77
78typedef uint8_t u8;
79typedef uint16_t u16;
80typedef uint32_t u32;
81typedef uint64_t u64;
82typedef u32 cell_t;
83
84#define cpu_to_be16(x) htons(x)
85#define be16_to_cpu(x) ntohs(x)
86
87#define cpu_to_be32(x) htonl(x)
88#define be32_to_cpu(x) ntohl(x)
89
90#if __BYTE_ORDER == __BIG_ENDIAN
91#define cpu_to_be64(x) (x)
92#define be64_to_cpu(x) (x)
93#else
94#define cpu_to_be64(x) bswap_64(x)
95#define be64_to_cpu(x) bswap_64(x)
96#endif
97
98#define streq(a, b) (strcmp((a), (b)) == 0)
99#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
100
101#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
102#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
103
104/* Data blobs */
105enum markertype {
106 REF_PHANDLE,
107 REF_PATH,
108 LABEL,
109};
110
111struct marker {
112 enum markertype type;
113 int offset;
114 char *ref;
115 struct marker *next;
116};
117
118struct data {
119 int len;
120 char *val;
121 int asize;
122 struct marker *markers;
123};
124
125
126#define empty_data ((struct data){ /* all .members = 0 or NULL */ })
127
128#define for_each_marker(m) \
129 for (; (m); (m) = (m)->next)
130#define for_each_marker_of_type(m, t) \
131 for_each_marker(m) \
132 if ((m)->type == (t))
133
134void data_free(struct data d);
135
136struct data data_grow_for(struct data d, int xlen);
137
138struct data data_copy_mem(const char *mem, int len);
139struct data data_copy_escape_string(const char *s, int len);
140struct data data_copy_file(FILE *f, size_t len);
141
142struct data data_append_data(struct data d, const void *p, int len);
143struct data data_insert_at_marker(struct data d, struct marker *m,
144 const void *p, int len);
145struct data data_merge(struct data d1, struct data d2);
146struct data data_append_cell(struct data d, cell_t word);
147struct data data_append_re(struct data d, const struct fdt_reserve_entry *re);
148struct data data_append_addr(struct data d, u64 addr);
149struct data data_append_byte(struct data d, uint8_t byte);
150struct data data_append_zeroes(struct data d, int len);
151struct data data_append_align(struct data d, int align);
152
153struct data data_add_marker(struct data d, enum markertype type, char *ref);
154
155int data_is_one_string(struct data d);
156
157/* DT constraints */
158
159#define MAX_PROPNAME_LEN 31
160#define MAX_NODENAME_LEN 31
161
162/* Live trees */
163struct property {
164 char *name;
165 struct data val;
166
167 struct property *next;
168
169 char *label;
170};
171
172struct node {
173 char *name;
174 struct property *proplist;
175 struct node *children;
176
177 struct node *parent;
178 struct node *next_sibling;
179
180 char *fullpath;
181 int basenamelen;
182
183 cell_t phandle;
184 int addr_cells, size_cells;
185
186 char *label;
187};
188
189#define for_each_property(n, p) \
190 for ((p) = (n)->proplist; (p); (p) = (p)->next)
191
192#define for_each_child(n, c) \
193 for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
194
195struct property *build_property(char *name, struct data val, char *label);
196struct property *chain_property(struct property *first, struct property *list);
197struct property *reverse_properties(struct property *first);
198
199struct node *build_node(struct property *proplist, struct node *children);
200struct node *name_node(struct node *node, char *name, char *label);
201struct node *chain_node(struct node *first, struct node *list);
202
203void add_property(struct node *node, struct property *prop);
204void add_child(struct node *parent, struct node *child);
205
206const char *get_unitname(struct node *node);
207struct property *get_property(struct node *node, const char *propname);
208cell_t propval_cell(struct property *prop);
209struct node *get_subnode(struct node *node, const char *nodename);
210struct node *get_node_by_path(struct node *tree, const char *path);
211struct node *get_node_by_label(struct node *tree, const char *label);
212struct node *get_node_by_phandle(struct node *tree, cell_t phandle);
213struct node *get_node_by_ref(struct node *tree, const char *ref);
214cell_t get_node_phandle(struct node *root, struct node *node);
215
216/* Boot info (tree plus memreserve information */
217
218struct reserve_info {
219 struct fdt_reserve_entry re;
220
221 struct reserve_info *next;
222
223 char *label;
224};
225
226struct reserve_info *build_reserve_entry(u64 start, u64 len, char *label);
227struct reserve_info *chain_reserve_entry(struct reserve_info *first,
228 struct reserve_info *list);
229struct reserve_info *add_reserve_entry(struct reserve_info *list,
230 struct reserve_info *new);
231
232
233struct boot_info {
234 struct reserve_info *reservelist;
235 struct node *dt; /* the device tree */
236};
237
238struct boot_info *build_boot_info(struct reserve_info *reservelist,
239 struct node *tree);
240
241/* Checks */
242
243void process_checks(int force, struct boot_info *bi,
244 int checkflag, int outversion, int boot_cpuid_phys);
245
246/* Flattened trees */
247
248void dt_to_blob(FILE *f, struct boot_info *bi, int version,
249 int boot_cpuid_phys);
250void dt_to_asm(FILE *f, struct boot_info *bi, int version,
251 int boot_cpuid_phys);
252
253struct boot_info *dt_from_blob(FILE *f);
254
255/* Tree source */
256
257void dt_to_source(FILE *f, struct boot_info *bi);
258struct boot_info *dt_from_source(const char *f);
259
260/* FS trees */
261
262struct boot_info *dt_from_fs(const char *dirname);
263
264/* misc */
265
266char *join_path(const char *path, const char *name);
267void fill_fullpaths(struct node *tree, const char *prefix);
268
269#endif /* _DTC_H */
diff --git a/arch/powerpc/boot/dtc-src/flattree.c b/arch/powerpc/boot/dtc-src/flattree.c
new file mode 100644
index 000000000000..a7cfb843d334
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/flattree.c
@@ -0,0 +1,968 @@
1/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3 *
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 */
20
21#include "dtc.h"
22
23#define FTF_FULLPATH 0x1
24#define FTF_VARALIGN 0x2
25#define FTF_NAMEPROPS 0x4
26#define FTF_BOOTCPUID 0x8
27#define FTF_STRTABSIZE 0x10
28#define FTF_STRUCTSIZE 0x20
29#define FTF_NOPS 0x40
30
31static struct version_info {
32 int version;
33 int last_comp_version;
34 int hdr_size;
35 int flags;
36} version_table[] = {
37 {1, 1, FDT_V1_SIZE,
38 FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS},
39 {2, 1, FDT_V2_SIZE,
40 FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID},
41 {3, 1, FDT_V3_SIZE,
42 FTF_FULLPATH|FTF_VARALIGN|FTF_NAMEPROPS|FTF_BOOTCPUID|FTF_STRTABSIZE},
43 {16, 16, FDT_V3_SIZE,
44 FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_NOPS},
45 {17, 16, FDT_V17_SIZE,
46 FTF_BOOTCPUID|FTF_STRTABSIZE|FTF_STRUCTSIZE|FTF_NOPS},
47};
48
49struct emitter {
50 void (*cell)(void *, cell_t);
51 void (*string)(void *, char *, int);
52 void (*align)(void *, int);
53 void (*data)(void *, struct data);
54 void (*beginnode)(void *, const char *);
55 void (*endnode)(void *, const char *);
56 void (*property)(void *, const char *);
57};
58
59static void bin_emit_cell(void *e, cell_t val)
60{
61 struct data *dtbuf = e;
62
63 *dtbuf = data_append_cell(*dtbuf, val);
64}
65
66static void bin_emit_string(void *e, char *str, int len)
67{
68 struct data *dtbuf = e;
69
70 if (len == 0)
71 len = strlen(str);
72
73 *dtbuf = data_append_data(*dtbuf, str, len);
74 *dtbuf = data_append_byte(*dtbuf, '\0');
75}
76
77static void bin_emit_align(void *e, int a)
78{
79 struct data *dtbuf = e;
80
81 *dtbuf = data_append_align(*dtbuf, a);
82}
83
84static void bin_emit_data(void *e, struct data d)
85{
86 struct data *dtbuf = e;
87
88 *dtbuf = data_append_data(*dtbuf, d.val, d.len);
89}
90
91static void bin_emit_beginnode(void *e, const char *label)
92{
93 bin_emit_cell(e, FDT_BEGIN_NODE);
94}
95
96static void bin_emit_endnode(void *e, const char *label)
97{
98 bin_emit_cell(e, FDT_END_NODE);
99}
100
101static void bin_emit_property(void *e, const char *label)
102{
103 bin_emit_cell(e, FDT_PROP);
104}
105
106static struct emitter bin_emitter = {
107 .cell = bin_emit_cell,
108 .string = bin_emit_string,
109 .align = bin_emit_align,
110 .data = bin_emit_data,
111 .beginnode = bin_emit_beginnode,
112 .endnode = bin_emit_endnode,
113 .property = bin_emit_property,
114};
115
116static void emit_label(FILE *f, const char *prefix, const char *label)
117{
118 fprintf(f, "\t.globl\t%s_%s\n", prefix, label);
119 fprintf(f, "%s_%s:\n", prefix, label);
120 fprintf(f, "_%s_%s:\n", prefix, label);
121}
122
123static void emit_offset_label(FILE *f, const char *label, int offset)
124{
125 fprintf(f, "\t.globl\t%s\n", label);
126 fprintf(f, "%s\t= . + %d\n", label, offset);
127}
128
129static void asm_emit_cell(void *e, cell_t val)
130{
131 FILE *f = e;
132
133 fprintf(f, "\t.long\t0x%x\n", val);
134}
135
136static void asm_emit_string(void *e, char *str, int len)
137{
138 FILE *f = e;
139 char c = 0;
140
141 if (len != 0) {
142 /* XXX: ewww */
143 c = str[len];
144 str[len] = '\0';
145 }
146
147 fprintf(f, "\t.string\t\"%s\"\n", str);
148
149 if (len != 0) {
150 str[len] = c;
151 }
152}
153
154static void asm_emit_align(void *e, int a)
155{
156 FILE *f = e;
157
158 fprintf(f, "\t.balign\t%d\n", a);
159}
160
161static void asm_emit_data(void *e, struct data d)
162{
163 FILE *f = e;
164 int off = 0;
165 struct marker *m;
166
167 m = d.markers;
168 while (m) {
169 if (m->type == LABEL)
170 emit_offset_label(f, m->ref, m->offset);
171 m = m->next;
172 }
173
174 while ((d.len - off) >= sizeof(u32)) {
175 fprintf(f, "\t.long\t0x%x\n",
176 be32_to_cpu(*((u32 *)(d.val+off))));
177 off += sizeof(u32);
178 }
179
180 if ((d.len - off) >= sizeof(u16)) {
181 fprintf(f, "\t.short\t0x%hx\n",
182 be16_to_cpu(*((u16 *)(d.val+off))));
183 off += sizeof(u16);
184 }
185
186 if ((d.len - off) >= 1) {
187 fprintf(f, "\t.byte\t0x%hhx\n", d.val[off]);
188 off += 1;
189 }
190
191 assert(off == d.len);
192}
193
194static void asm_emit_beginnode(void *e, const char *label)
195{
196 FILE *f = e;
197
198 if (label) {
199 fprintf(f, "\t.globl\t%s\n", label);
200 fprintf(f, "%s:\n", label);
201 }
202 fprintf(f, "\t.long\tFDT_BEGIN_NODE\n");
203}
204
205static void asm_emit_endnode(void *e, const char *label)
206{
207 FILE *f = e;
208
209 fprintf(f, "\t.long\tFDT_END_NODE\n");
210 if (label) {
211 fprintf(f, "\t.globl\t%s_end\n", label);
212 fprintf(f, "%s_end:\n", label);
213 }
214}
215
216static void asm_emit_property(void *e, const char *label)
217{
218 FILE *f = e;
219
220 if (label) {
221 fprintf(f, "\t.globl\t%s\n", label);
222 fprintf(f, "%s:\n", label);
223 }
224 fprintf(f, "\t.long\tFDT_PROP\n");
225}
226
227static struct emitter asm_emitter = {
228 .cell = asm_emit_cell,
229 .string = asm_emit_string,
230 .align = asm_emit_align,
231 .data = asm_emit_data,
232 .beginnode = asm_emit_beginnode,
233 .endnode = asm_emit_endnode,
234 .property = asm_emit_property,
235};
236
237static int stringtable_insert(struct data *d, const char *str)
238{
239 int i;
240
241 /* FIXME: do this more efficiently? */
242
243 for (i = 0; i < d->len; i++) {
244 if (streq(str, d->val + i))
245 return i;
246 }
247
248 *d = data_append_data(*d, str, strlen(str)+1);
249 return i;
250}
251
252static void flatten_tree(struct node *tree, struct emitter *emit,
253 void *etarget, struct data *strbuf,
254 struct version_info *vi)
255{
256 struct property *prop;
257 struct node *child;
258 int seen_name_prop = 0;
259
260 emit->beginnode(etarget, tree->label);
261
262 if (vi->flags & FTF_FULLPATH)
263 emit->string(etarget, tree->fullpath, 0);
264 else
265 emit->string(etarget, tree->name, 0);
266
267 emit->align(etarget, sizeof(cell_t));
268
269 for_each_property(tree, prop) {
270 int nameoff;
271
272 if (streq(prop->name, "name"))
273 seen_name_prop = 1;
274
275 nameoff = stringtable_insert(strbuf, prop->name);
276
277 emit->property(etarget, prop->label);
278 emit->cell(etarget, prop->val.len);
279 emit->cell(etarget, nameoff);
280
281 if ((vi->flags & FTF_VARALIGN) && (prop->val.len >= 8))
282 emit->align(etarget, 8);
283
284 emit->data(etarget, prop->val);
285 emit->align(etarget, sizeof(cell_t));
286 }
287
288 if ((vi->flags & FTF_NAMEPROPS) && !seen_name_prop) {
289 emit->property(etarget, NULL);
290 emit->cell(etarget, tree->basenamelen+1);
291 emit->cell(etarget, stringtable_insert(strbuf, "name"));
292
293 if ((vi->flags & FTF_VARALIGN) && ((tree->basenamelen+1) >= 8))
294 emit->align(etarget, 8);
295
296 emit->string(etarget, tree->name, tree->basenamelen);
297 emit->align(etarget, sizeof(cell_t));
298 }
299
300 for_each_child(tree, child) {
301 flatten_tree(child, emit, etarget, strbuf, vi);
302 }
303
304 emit->endnode(etarget, tree->label);
305}
306
307static struct data flatten_reserve_list(struct reserve_info *reservelist,
308 struct version_info *vi)
309{
310 struct reserve_info *re;
311 struct data d = empty_data;
312 static struct fdt_reserve_entry null_re = {0,0};
313 int j;
314
315 for (re = reservelist; re; re = re->next) {
316 d = data_append_re(d, &re->re);
317 }
318 /*
319 * Add additional reserved slots if the user asked for them.
320 */
321 for (j = 0; j < reservenum; j++) {
322 d = data_append_re(d, &null_re);
323 }
324
325 return d;
326}
327
328static void make_fdt_header(struct fdt_header *fdt,
329 struct version_info *vi,
330 int reservesize, int dtsize, int strsize,
331 int boot_cpuid_phys)
332{
333 int reserve_off;
334
335 reservesize += sizeof(struct fdt_reserve_entry);
336
337 memset(fdt, 0xff, sizeof(*fdt));
338
339 fdt->magic = cpu_to_be32(FDT_MAGIC);
340 fdt->version = cpu_to_be32(vi->version);
341 fdt->last_comp_version = cpu_to_be32(vi->last_comp_version);
342
343 /* Reserve map should be doubleword aligned */
344 reserve_off = ALIGN(vi->hdr_size, 8);
345
346 fdt->off_mem_rsvmap = cpu_to_be32(reserve_off);
347 fdt->off_dt_struct = cpu_to_be32(reserve_off + reservesize);
348 fdt->off_dt_strings = cpu_to_be32(reserve_off + reservesize
349 + dtsize);
350 fdt->totalsize = cpu_to_be32(reserve_off + reservesize + dtsize + strsize);
351
352 if (vi->flags & FTF_BOOTCPUID)
353 fdt->boot_cpuid_phys = cpu_to_be32(boot_cpuid_phys);
354 if (vi->flags & FTF_STRTABSIZE)
355 fdt->size_dt_strings = cpu_to_be32(strsize);
356 if (vi->flags & FTF_STRUCTSIZE)
357 fdt->size_dt_struct = cpu_to_be32(dtsize);
358}
359
360void dt_to_blob(FILE *f, struct boot_info *bi, int version,
361 int boot_cpuid_phys)
362{
363 struct version_info *vi = NULL;
364 int i;
365 struct data blob = empty_data;
366 struct data reservebuf = empty_data;
367 struct data dtbuf = empty_data;
368 struct data strbuf = empty_data;
369 struct fdt_header fdt;
370 int padlen = 0;
371
372 for (i = 0; i < ARRAY_SIZE(version_table); i++) {
373 if (version_table[i].version == version)
374 vi = &version_table[i];
375 }
376 if (!vi)
377 die("Unknown device tree blob version %d\n", version);
378
379 flatten_tree(bi->dt, &bin_emitter, &dtbuf, &strbuf, vi);
380 bin_emit_cell(&dtbuf, FDT_END);
381
382 reservebuf = flatten_reserve_list(bi->reservelist, vi);
383
384 /* Make header */
385 make_fdt_header(&fdt, vi, reservebuf.len, dtbuf.len, strbuf.len,
386 boot_cpuid_phys);
387
388 /*
389 * If the user asked for more space than is used, adjust the totalsize.
390 */
391 if (minsize > 0) {
392 padlen = minsize - be32_to_cpu(fdt.totalsize);
393 if ((padlen < 0) && (quiet < 1))
394 fprintf(stderr,
395 "Warning: blob size %d >= minimum size %d\n",
396 be32_to_cpu(fdt.totalsize), minsize);
397 }
398
399 if (padsize > 0)
400 padlen = padsize;
401
402 if (padlen > 0) {
403 int tsize = be32_to_cpu(fdt.totalsize);
404 tsize += padlen;
405 fdt.totalsize = cpu_to_be32(tsize);
406 }
407
408 /*
409 * Assemble the blob: start with the header, add with alignment
410 * the reserve buffer, add the reserve map terminating zeroes,
411 * the device tree itself, and finally the strings.
412 */
413 blob = data_append_data(blob, &fdt, sizeof(fdt));
414 blob = data_append_align(blob, 8);
415 blob = data_merge(blob, reservebuf);
416 blob = data_append_zeroes(blob, sizeof(struct fdt_reserve_entry));
417 blob = data_merge(blob, dtbuf);
418 blob = data_merge(blob, strbuf);
419
420 /*
421 * If the user asked for more space than is used, pad out the blob.
422 */
423 if (padlen > 0)
424 blob = data_append_zeroes(blob, padlen);
425
426 fwrite(blob.val, blob.len, 1, f);
427
428 if (ferror(f))
429 die("Error writing device tree blob: %s\n", strerror(errno));
430
431 /*
432 * data_merge() frees the right-hand element so only the blob
433 * remains to be freed.
434 */
435 data_free(blob);
436}
437
438static void dump_stringtable_asm(FILE *f, struct data strbuf)
439{
440 const char *p;
441 int len;
442
443 p = strbuf.val;
444
445 while (p < (strbuf.val + strbuf.len)) {
446 len = strlen(p);
447 fprintf(f, "\t.string \"%s\"\n", p);
448 p += len+1;
449 }
450}
451
452void dt_to_asm(FILE *f, struct boot_info *bi, int version, int boot_cpuid_phys)
453{
454 struct version_info *vi = NULL;
455 int i;
456 struct data strbuf = empty_data;
457 struct reserve_info *re;
458 const char *symprefix = "dt";
459
460 for (i = 0; i < ARRAY_SIZE(version_table); i++) {
461 if (version_table[i].version == version)
462 vi = &version_table[i];
463 }
464 if (!vi)
465 die("Unknown device tree blob version %d\n", version);
466
467 fprintf(f, "/* autogenerated by dtc, do not edit */\n\n");
468 fprintf(f, "#define FDT_MAGIC 0x%x\n", FDT_MAGIC);
469 fprintf(f, "#define FDT_BEGIN_NODE 0x%x\n", FDT_BEGIN_NODE);
470 fprintf(f, "#define FDT_END_NODE 0x%x\n", FDT_END_NODE);
471 fprintf(f, "#define FDT_PROP 0x%x\n", FDT_PROP);
472 fprintf(f, "#define FDT_END 0x%x\n", FDT_END);
473 fprintf(f, "\n");
474
475 emit_label(f, symprefix, "blob_start");
476 emit_label(f, symprefix, "header");
477 fprintf(f, "\t.long\tFDT_MAGIC\t\t\t\t/* magic */\n");
478 fprintf(f, "\t.long\t_%s_blob_abs_end - _%s_blob_start\t/* totalsize */\n",
479 symprefix, symprefix);
480 fprintf(f, "\t.long\t_%s_struct_start - _%s_blob_start\t/* off_dt_struct */\n",
481 symprefix, symprefix);
482 fprintf(f, "\t.long\t_%s_strings_start - _%s_blob_start\t/* off_dt_strings */\n",
483 symprefix, symprefix);
484 fprintf(f, "\t.long\t_%s_reserve_map - _%s_blob_start\t/* off_dt_strings */\n",
485 symprefix, symprefix);
486 fprintf(f, "\t.long\t%d\t\t\t\t\t/* version */\n", vi->version);
487 fprintf(f, "\t.long\t%d\t\t\t\t\t/* last_comp_version */\n",
488 vi->last_comp_version);
489
490 if (vi->flags & FTF_BOOTCPUID)
491 fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n",
492 boot_cpuid_phys);
493
494 if (vi->flags & FTF_STRTABSIZE)
495 fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n",
496 symprefix, symprefix);
497
498 if (vi->flags & FTF_STRUCTSIZE)
499 fprintf(f, "\t.long\t_%s_struct_end - _%s_struct_start\t/* size_dt_struct */\n",
500 symprefix, symprefix);
501
502 /*
503 * Reserve map entries.
504 * Align the reserve map to a doubleword boundary.
505 * Each entry is an (address, size) pair of u64 values.
506 * Always supply a zero-sized temination entry.
507 */
508 asm_emit_align(f, 8);
509 emit_label(f, symprefix, "reserve_map");
510
511 fprintf(f, "/* Memory reserve map from source file */\n");
512
513 /*
514 * Use .long on high and low halfs of u64s to avoid .quad
515 * as it appears .quad isn't available in some assemblers.
516 */
517 for (re = bi->reservelist; re; re = re->next) {
518 if (re->label) {
519 fprintf(f, "\t.globl\t%s\n", re->label);
520 fprintf(f, "%s:\n", re->label);
521 }
522 fprintf(f, "\t.long\t0x%08x, 0x%08x\n",
523 (unsigned int)(re->re.address >> 32),
524 (unsigned int)(re->re.address & 0xffffffff));
525 fprintf(f, "\t.long\t0x%08x, 0x%08x\n",
526 (unsigned int)(re->re.size >> 32),
527 (unsigned int)(re->re.size & 0xffffffff));
528 }
529 for (i = 0; i < reservenum; i++) {
530 fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
531 }
532
533 fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
534
535 emit_label(f, symprefix, "struct_start");
536 flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi);
537 fprintf(f, "\t.long\tFDT_END\n");
538 emit_label(f, symprefix, "struct_end");
539
540 emit_label(f, symprefix, "strings_start");
541 dump_stringtable_asm(f, strbuf);
542 emit_label(f, symprefix, "strings_end");
543
544 emit_label(f, symprefix, "blob_end");
545
546 /*
547 * If the user asked for more space than is used, pad it out.
548 */
549 if (minsize > 0) {
550 fprintf(f, "\t.space\t%d - (_%s_blob_end - _%s_blob_start), 0\n",
551 minsize, symprefix, symprefix);
552 }
553 if (padsize > 0) {
554 fprintf(f, "\t.space\t%d, 0\n", padsize);
555 }
556 emit_label(f, symprefix, "blob_abs_end");
557
558 data_free(strbuf);
559}
560
561struct inbuf {
562 char *base, *limit, *ptr;
563};
564
565static void inbuf_init(struct inbuf *inb, void *base, void *limit)
566{
567 inb->base = base;
568 inb->limit = limit;
569 inb->ptr = inb->base;
570}
571
572static void flat_read_chunk(struct inbuf *inb, void *p, int len)
573{
574 if ((inb->ptr + len) > inb->limit)
575 die("Premature end of data parsing flat device tree\n");
576
577 memcpy(p, inb->ptr, len);
578
579 inb->ptr += len;
580}
581
582static u32 flat_read_word(struct inbuf *inb)
583{
584 u32 val;
585
586 assert(((inb->ptr - inb->base) % sizeof(val)) == 0);
587
588 flat_read_chunk(inb, &val, sizeof(val));
589
590 return be32_to_cpu(val);
591}
592
593static void flat_realign(struct inbuf *inb, int align)
594{
595 int off = inb->ptr - inb->base;
596
597 inb->ptr = inb->base + ALIGN(off, align);
598 if (inb->ptr > inb->limit)
599 die("Premature end of data parsing flat device tree\n");
600}
601
602static char *flat_read_string(struct inbuf *inb)
603{
604 int len = 0;
605 const char *p = inb->ptr;
606 char *str;
607
608 do {
609 if (p >= inb->limit)
610 die("Premature end of data parsing flat device tree\n");
611 len++;
612 } while ((*p++) != '\0');
613
614 str = strdup(inb->ptr);
615
616 inb->ptr += len;
617
618 flat_realign(inb, sizeof(u32));
619
620 return str;
621}
622
623static struct data flat_read_data(struct inbuf *inb, int len)
624{
625 struct data d = empty_data;
626
627 if (len == 0)
628 return empty_data;
629
630 d = data_grow_for(d, len);
631 d.len = len;
632
633 flat_read_chunk(inb, d.val, len);
634
635 flat_realign(inb, sizeof(u32));
636
637 return d;
638}
639
640static char *flat_read_stringtable(struct inbuf *inb, int offset)
641{
642 const char *p;
643
644 p = inb->base + offset;
645 while (1) {
646 if (p >= inb->limit || p < inb->base)
647 die("String offset %d overruns string table\n",
648 offset);
649
650 if (*p == '\0')
651 break;
652
653 p++;
654 }
655
656 return strdup(inb->base + offset);
657}
658
659static struct property *flat_read_property(struct inbuf *dtbuf,
660 struct inbuf *strbuf, int flags)
661{
662 u32 proplen, stroff;
663 char *name;
664 struct data val;
665
666 proplen = flat_read_word(dtbuf);
667 stroff = flat_read_word(dtbuf);
668
669 name = flat_read_stringtable(strbuf, stroff);
670
671 if ((flags & FTF_VARALIGN) && (proplen >= 8))
672 flat_realign(dtbuf, 8);
673
674 val = flat_read_data(dtbuf, proplen);
675
676 return build_property(name, val, NULL);
677}
678
679
680static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
681{
682 struct reserve_info *reservelist = NULL;
683 struct reserve_info *new;
684 const char *p;
685 struct fdt_reserve_entry re;
686
687 /*
688 * Each entry is a pair of u64 (addr, size) values for 4 cell_t's.
689 * List terminates at an entry with size equal to zero.
690 *
691 * First pass, count entries.
692 */
693 p = inb->ptr;
694 while (1) {
695 flat_read_chunk(inb, &re, sizeof(re));
696 re.address = be64_to_cpu(re.address);
697 re.size = be64_to_cpu(re.size);
698 if (re.size == 0)
699 break;
700
701 new = build_reserve_entry(re.address, re.size, NULL);
702 reservelist = add_reserve_entry(reservelist, new);
703 }
704
705 return reservelist;
706}
707
708
709static char *nodename_from_path(const char *ppath, const char *cpath)
710{
711 const char *lslash;
712 int plen;
713
714 lslash = strrchr(cpath, '/');
715 if (! lslash)
716 return NULL;
717
718 plen = lslash - cpath;
719
720 if (streq(cpath, "/") && streq(ppath, ""))
721 return "";
722
723 if ((plen == 0) && streq(ppath, "/"))
724 return strdup(lslash+1);
725
726 if (! strneq(ppath, cpath, plen))
727 return NULL;
728
729 return strdup(lslash+1);
730}
731
732static const char PROPCHAR[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,._+*#?-";
733static const char UNITCHAR[] = "0123456789abcdef,";
734
735static int check_node_name(const char *name)
736{
737 const char *atpos;
738 int basenamelen;
739
740 atpos = strrchr(name, '@');
741
742 if (atpos)
743 basenamelen = atpos - name;
744 else
745 basenamelen = strlen(name);
746
747 if (strspn(name, PROPCHAR) < basenamelen)
748 return -1;
749
750 if (atpos
751 && ((basenamelen + 1 + strspn(atpos+1, UNITCHAR)) < strlen(name)))
752 return -1;
753
754 return basenamelen;
755}
756
757static struct node *unflatten_tree(struct inbuf *dtbuf,
758 struct inbuf *strbuf,
759 const char *parent_path, int flags)
760{
761 struct node *node;
762 u32 val;
763
764 node = build_node(NULL, NULL);
765
766 if (flags & FTF_FULLPATH) {
767 node->fullpath = flat_read_string(dtbuf);
768 node->name = nodename_from_path(parent_path, node->fullpath);
769
770 if (! node->name)
771 die("Path \"%s\" is not valid as a child of \"%s\"\n",
772 node->fullpath, parent_path);
773 } else {
774 node->name = flat_read_string(dtbuf);
775 node->fullpath = join_path(parent_path, node->name);
776 }
777
778 node->basenamelen = check_node_name(node->name);
779 if (node->basenamelen < 0) {
780 fprintf(stderr, "Warning \"%s\" has incorrect format\n", node->name);
781 }
782
783 do {
784 struct property *prop;
785 struct node *child;
786
787 val = flat_read_word(dtbuf);
788 switch (val) {
789 case FDT_PROP:
790 if (node->children)
791 fprintf(stderr, "Warning: Flat tree input has "
792 "subnodes preceding a property.\n");
793 prop = flat_read_property(dtbuf, strbuf, flags);
794 add_property(node, prop);
795 break;
796
797 case FDT_BEGIN_NODE:
798 child = unflatten_tree(dtbuf,strbuf, node->fullpath,
799 flags);
800 add_child(node, child);
801 break;
802
803 case FDT_END_NODE:
804 break;
805
806 case FDT_END:
807 die("Premature FDT_END in device tree blob\n");
808 break;
809
810 case FDT_NOP:
811 if (!(flags & FTF_NOPS))
812 fprintf(stderr, "Warning: NOP tag found in flat tree"
813 " version <16\n");
814
815 /* Ignore */
816 break;
817
818 default:
819 die("Invalid opcode word %08x in device tree blob\n",
820 val);
821 }
822 } while (val != FDT_END_NODE);
823
824 return node;
825}
826
827
828struct boot_info *dt_from_blob(FILE *f)
829{
830 u32 magic, totalsize, version, size_str, size_dt;
831 u32 off_dt, off_str, off_mem_rsvmap;
832 int rc;
833 char *blob;
834 struct fdt_header *fdt;
835 char *p;
836 struct inbuf dtbuf, strbuf;
837 struct inbuf memresvbuf;
838 int sizeleft;
839 struct reserve_info *reservelist;
840 struct node *tree;
841 u32 val;
842 int flags = 0;
843
844 rc = fread(&magic, sizeof(magic), 1, f);
845 if (ferror(f))
846 die("Error reading DT blob magic number: %s\n",
847 strerror(errno));
848 if (rc < 1) {
849 if (feof(f))
850 die("EOF reading DT blob magic number\n");
851 else
852 die("Mysterious short read reading magic number\n");
853 }
854
855 magic = be32_to_cpu(magic);
856 if (magic != FDT_MAGIC)
857 die("Blob has incorrect magic number\n");
858
859 rc = fread(&totalsize, sizeof(totalsize), 1, f);
860 if (ferror(f))
861 die("Error reading DT blob size: %s\n", strerror(errno));
862 if (rc < 1) {
863 if (feof(f))
864 die("EOF reading DT blob size\n");
865 else
866 die("Mysterious short read reading blob size\n");
867 }
868
869 totalsize = be32_to_cpu(totalsize);
870 if (totalsize < FDT_V1_SIZE)
871 die("DT blob size (%d) is too small\n", totalsize);
872
873 blob = xmalloc(totalsize);
874
875 fdt = (struct fdt_header *)blob;
876 fdt->magic = cpu_to_be32(magic);
877 fdt->totalsize = cpu_to_be32(totalsize);
878
879 sizeleft = totalsize - sizeof(magic) - sizeof(totalsize);
880 p = blob + sizeof(magic) + sizeof(totalsize);
881
882 while (sizeleft) {
883 if (feof(f))
884 die("EOF before reading %d bytes of DT blob\n",
885 totalsize);
886
887 rc = fread(p, 1, sizeleft, f);
888 if (ferror(f))
889 die("Error reading DT blob: %s\n",
890 strerror(errno));
891
892 sizeleft -= rc;
893 p += rc;
894 }
895
896 off_dt = be32_to_cpu(fdt->off_dt_struct);
897 off_str = be32_to_cpu(fdt->off_dt_strings);
898 off_mem_rsvmap = be32_to_cpu(fdt->off_mem_rsvmap);
899 version = be32_to_cpu(fdt->version);
900
901 fprintf(stderr, "\tmagic:\t\t\t0x%x\n", magic);
902 fprintf(stderr, "\ttotalsize:\t\t%d\n", totalsize);
903 fprintf(stderr, "\toff_dt_struct:\t\t0x%x\n", off_dt);
904 fprintf(stderr, "\toff_dt_strings:\t\t0x%x\n", off_str);
905 fprintf(stderr, "\toff_mem_rsvmap:\t\t0x%x\n", off_mem_rsvmap);
906 fprintf(stderr, "\tversion:\t\t0x%x\n", version );
907 fprintf(stderr, "\tlast_comp_version:\t0x%x\n",
908 be32_to_cpu(fdt->last_comp_version));
909
910 if (off_mem_rsvmap >= totalsize)
911 die("Mem Reserve structure offset exceeds total size\n");
912
913 if (off_dt >= totalsize)
914 die("DT structure offset exceeds total size\n");
915
916 if (off_str > totalsize)
917 die("String table offset exceeds total size\n");
918
919 if (version >= 2)
920 fprintf(stderr, "\tboot_cpuid_phys:\t0x%x\n",
921 be32_to_cpu(fdt->boot_cpuid_phys));
922
923 size_str = -1;
924 if (version >= 3) {
925 size_str = be32_to_cpu(fdt->size_dt_strings);
926 fprintf(stderr, "\tsize_dt_strings:\t%d\n", size_str);
927 if (off_str+size_str > totalsize)
928 die("String table extends past total size\n");
929 }
930
931 if (version >= 17) {
932 size_dt = be32_to_cpu(fdt->size_dt_struct);
933 fprintf(stderr, "\tsize_dt_struct:\t\t%d\n", size_dt);
934 if (off_dt+size_dt > totalsize)
935 die("Structure block extends past total size\n");
936 }
937
938 if (version < 16) {
939 flags |= FTF_FULLPATH | FTF_NAMEPROPS | FTF_VARALIGN;
940 } else {
941 flags |= FTF_NOPS;
942 }
943
944 inbuf_init(&memresvbuf,
945 blob + off_mem_rsvmap, blob + totalsize);
946 inbuf_init(&dtbuf, blob + off_dt, blob + totalsize);
947 if (size_str >= 0)
948 inbuf_init(&strbuf, blob + off_str, blob + off_str + size_str);
949 else
950 inbuf_init(&strbuf, blob + off_str, blob + totalsize);
951
952 reservelist = flat_read_mem_reserve(&memresvbuf);
953
954 val = flat_read_word(&dtbuf);
955
956 if (val != FDT_BEGIN_NODE)
957 die("Device tree blob doesn't begin with FDT_BEGIN_NODE (begins with 0x%08x)\n", val);
958
959 tree = unflatten_tree(&dtbuf, &strbuf, "", flags);
960
961 val = flat_read_word(&dtbuf);
962 if (val != FDT_END)
963 die("Device tree blob doesn't end with FDT_END\n");
964
965 free(blob);
966
967 return build_boot_info(reservelist, tree);
968}
diff --git a/arch/powerpc/boot/dtc-src/fstree.c b/arch/powerpc/boot/dtc-src/fstree.c
new file mode 100644
index 000000000000..2a160a46998e
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/fstree.c
@@ -0,0 +1,94 @@
1/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3 *
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 */
20
21#include "dtc.h"
22
23#include <dirent.h>
24#include <sys/stat.h>
25
26static struct node *read_fstree(const char *dirname)
27{
28 DIR *d;
29 struct dirent *de;
30 struct stat st;
31 struct node *tree;
32
33 d = opendir(dirname);
34 if (! d)
35 die("opendir(): %s\n", strerror(errno));
36
37 tree = build_node(NULL, NULL);
38
39 while ((de = readdir(d)) != NULL) {
40 char *tmpnam;
41
42 if (streq(de->d_name, ".")
43 || streq(de->d_name, ".."))
44 continue;
45
46 tmpnam = join_path(dirname, de->d_name);
47
48 if (lstat(tmpnam, &st) < 0)
49 die("stat(%s): %s\n", tmpnam, strerror(errno));
50
51 if (S_ISREG(st.st_mode)) {
52 struct property *prop;
53 FILE *pfile;
54
55 pfile = fopen(tmpnam, "r");
56 if (! pfile) {
57 fprintf(stderr,
58 "WARNING: Cannot open %s: %s\n",
59 tmpnam, strerror(errno));
60 } else {
61 prop = build_property(strdup(de->d_name),
62 data_copy_file(pfile,
63 st.st_size),
64 NULL);
65 add_property(tree, prop);
66 fclose(pfile);
67 }
68 } else if (S_ISDIR(st.st_mode)) {
69 struct node *newchild;
70
71 newchild = read_fstree(tmpnam);
72 newchild = name_node(newchild, strdup(de->d_name),
73 NULL);
74 add_child(tree, newchild);
75 }
76
77 free(tmpnam);
78 }
79
80 return tree;
81}
82
83struct boot_info *dt_from_fs(const char *dirname)
84{
85 struct node *tree;
86
87 tree = read_fstree(dirname);
88 tree = name_node(tree, "", NULL);
89
90 fill_fullpaths(tree, "");
91
92 return build_boot_info(NULL, tree);
93}
94
diff --git a/arch/powerpc/boot/dtc-src/livetree.c b/arch/powerpc/boot/dtc-src/livetree.c
new file mode 100644
index 000000000000..6ba0846b4310
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/livetree.c
@@ -0,0 +1,305 @@
1/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3 *
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 */
20
21#include "dtc.h"
22
23/*
24 * Tree building functions
25 */
26
27struct property *build_property(char *name, struct data val, char *label)
28{
29 struct property *new = xmalloc(sizeof(*new));
30
31 new->name = name;
32 new->val = val;
33
34 new->next = NULL;
35
36 new->label = label;
37
38 return new;
39}
40
41struct property *chain_property(struct property *first, struct property *list)
42{
43 assert(first->next == NULL);
44
45 first->next = list;
46 return first;
47}
48
49struct property *reverse_properties(struct property *first)
50{
51 struct property *p = first;
52 struct property *head = NULL;
53 struct property *next;
54
55 while (p) {
56 next = p->next;
57 p->next = head;
58 head = p;
59 p = next;
60 }
61 return head;
62}
63
64struct node *build_node(struct property *proplist, struct node *children)
65{
66 struct node *new = xmalloc(sizeof(*new));
67 struct node *child;
68
69 memset(new, 0, sizeof(*new));
70
71 new->proplist = reverse_properties(proplist);
72 new->children = children;
73
74 for_each_child(new, child) {
75 child->parent = new;
76 }
77
78 return new;
79}
80
81struct node *name_node(struct node *node, char *name, char * label)
82{
83 assert(node->name == NULL);
84
85 node->name = name;
86
87 node->label = label;
88
89 return node;
90}
91
92struct node *chain_node(struct node *first, struct node *list)
93{
94 assert(first->next_sibling == NULL);
95
96 first->next_sibling = list;
97 return first;
98}
99
100void add_property(struct node *node, struct property *prop)
101{
102 struct property **p;
103
104 prop->next = NULL;
105
106 p = &node->proplist;
107 while (*p)
108 p = &((*p)->next);
109
110 *p = prop;
111}
112
113void add_child(struct node *parent, struct node *child)
114{
115 struct node **p;
116
117 child->next_sibling = NULL;
118
119 p = &parent->children;
120 while (*p)
121 p = &((*p)->next_sibling);
122
123 *p = child;
124}
125
126struct reserve_info *build_reserve_entry(u64 address, u64 size, char *label)
127{
128 struct reserve_info *new = xmalloc(sizeof(*new));
129
130 new->re.address = address;
131 new->re.size = size;
132
133 new->next = NULL;
134
135 new->label = label;
136
137 return new;
138}
139
140struct reserve_info *chain_reserve_entry(struct reserve_info *first,
141 struct reserve_info *list)
142{
143 assert(first->next == NULL);
144
145 first->next = list;
146 return first;
147}
148
149struct reserve_info *add_reserve_entry(struct reserve_info *list,
150 struct reserve_info *new)
151{
152 struct reserve_info *last;
153
154 new->next = NULL;
155
156 if (! list)
157 return new;
158
159 for (last = list; last->next; last = last->next)
160 ;
161
162 last->next = new;
163
164 return list;
165}
166
167struct boot_info *build_boot_info(struct reserve_info *reservelist,
168 struct node *tree)
169{
170 struct boot_info *bi;
171
172 bi = xmalloc(sizeof(*bi));
173 bi->reservelist = reservelist;
174 bi->dt = tree;
175
176 return bi;
177}
178
179/*
180 * Tree accessor functions
181 */
182
183const char *get_unitname(struct node *node)
184{
185 if (node->name[node->basenamelen] == '\0')
186 return "";
187 else
188 return node->name + node->basenamelen + 1;
189}
190
191struct property *get_property(struct node *node, const char *propname)
192{
193 struct property *prop;
194
195 for_each_property(node, prop)
196 if (streq(prop->name, propname))
197 return prop;
198
199 return NULL;
200}
201
202cell_t propval_cell(struct property *prop)
203{
204 assert(prop->val.len == sizeof(cell_t));
205 return be32_to_cpu(*((cell_t *)prop->val.val));
206}
207
208struct node *get_subnode(struct node *node, const char *nodename)
209{
210 struct node *child;
211
212 for_each_child(node, child)
213 if (streq(child->name, nodename))
214 return child;
215
216 return NULL;
217}
218
219struct node *get_node_by_path(struct node *tree, const char *path)
220{
221 const char *p;
222 struct node *child;
223
224 if (!path || ! (*path))
225 return tree;
226
227 while (path[0] == '/')
228 path++;
229
230 p = strchr(path, '/');
231
232 for_each_child(tree, child) {
233 if (p && strneq(path, child->name, p-path))
234 return get_node_by_path(child, p+1);
235 else if (!p && streq(path, child->name))
236 return child;
237 }
238
239 return NULL;
240}
241
242struct node *get_node_by_label(struct node *tree, const char *label)
243{
244 struct node *child, *node;
245
246 assert(label && (strlen(label) > 0));
247
248 if (tree->label && streq(tree->label, label))
249 return tree;
250
251 for_each_child(tree, child) {
252 node = get_node_by_label(child, label);
253 if (node)
254 return node;
255 }
256
257 return NULL;
258}
259
260struct node *get_node_by_phandle(struct node *tree, cell_t phandle)
261{
262 struct node *child, *node;
263
264 assert((phandle != 0) && (phandle != -1));
265
266 if (tree->phandle == phandle)
267 return tree;
268
269 for_each_child(tree, child) {
270 node = get_node_by_phandle(child, phandle);
271 if (node)
272 return node;
273 }
274
275 return NULL;
276}
277
278struct node *get_node_by_ref(struct node *tree, const char *ref)
279{
280 if (ref[0] == '/')
281 return get_node_by_path(tree, ref);
282 else
283 return get_node_by_label(tree, ref);
284}
285
286cell_t get_node_phandle(struct node *root, struct node *node)
287{
288 static cell_t phandle = 1; /* FIXME: ick, static local */
289
290 if ((node->phandle != 0) && (node->phandle != -1))
291 return node->phandle;
292
293 assert(! get_property(node, "linux,phandle"));
294
295 while (get_node_by_phandle(root, phandle))
296 phandle++;
297
298 node->phandle = phandle;
299 add_property(node,
300 build_property("linux,phandle",
301 data_append_cell(empty_data, phandle),
302 NULL));
303
304 return node->phandle;
305}
diff --git a/arch/powerpc/boot/dtc-src/srcpos.c b/arch/powerpc/boot/dtc-src/srcpos.c
new file mode 100644
index 000000000000..352b0fe06fde
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/srcpos.c
@@ -0,0 +1,105 @@
1/*
2 * Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17 * USA
18 */
19
20#include "dtc.h"
21#include "srcpos.h"
22
23
24/*
25 * Record the complete unique set of opened file names.
26 * Primarily used to cache source position file names.
27 */
28#define MAX_N_FILE_NAMES (100)
29
30const char *file_names[MAX_N_FILE_NAMES];
31static int n_file_names = 0;
32
33/*
34 * Like yylineno, this is the current open file pos.
35 */
36
37int srcpos_filenum = -1;
38
39
40
41FILE *dtc_open_file(const char *fname)
42{
43 FILE *f;
44
45 if (lookup_file_name(fname, 1) < 0)
46 die("Too many files opened\n");
47
48 if (streq(fname, "-"))
49 f = stdin;
50 else
51 f = fopen(fname, "r");
52
53 if (! f)
54 die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
55
56 return f;
57}
58
59
60
61/*
62 * Locate and optionally add filename fname in the file_names[] array.
63 *
64 * If the filename is currently not in the array and the boolean
65 * add_it is non-zero, an attempt to add the filename will be made.
66 *
67 * Returns;
68 * Index [0..MAX_N_FILE_NAMES) where the filename is kept
69 * -1 if the name can not be recorded
70 */
71
72int lookup_file_name(const char *fname, int add_it)
73{
74 int i;
75
76 for (i = 0; i < n_file_names; i++) {
77 if (strcmp(file_names[i], fname) == 0)
78 return i;
79 }
80
81 if (add_it) {
82 if (n_file_names < MAX_N_FILE_NAMES) {
83 file_names[n_file_names] = strdup(fname);
84 return n_file_names++;
85 }
86 }
87
88 return -1;
89}
90
91
92const char *srcpos_filename_for_num(int filenum)
93{
94 if (0 <= filenum && filenum < n_file_names) {
95 return file_names[filenum];
96 }
97
98 return 0;
99}
100
101
102const char *srcpos_get_filename(void)
103{
104 return srcpos_filename_for_num(srcpos_filenum);
105}
diff --git a/arch/powerpc/boot/dtc-src/srcpos.h b/arch/powerpc/boot/dtc-src/srcpos.h
new file mode 100644
index 000000000000..ce7ab5ba5b46
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/srcpos.h
@@ -0,0 +1,75 @@
1/*
2 * Copyright 2007 Jon Loeliger, Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17 * USA
18 */
19
20/*
21 * Augment the standard YYLTYPE with a filenum index into an
22 * array of all opened filenames.
23 */
24
25#if ! defined(YYLTYPE) && ! defined(YYLTYPE_IS_DECLARED)
26typedef struct YYLTYPE {
27 int first_line;
28 int first_column;
29 int last_line;
30 int last_column;
31 int filenum;
32} YYLTYPE;
33
34#define YYLTYPE_IS_DECLARED 1
35#define YYLTYPE_IS_TRIVIAL 1
36#endif
37
38/* Cater to old parser templates. */
39#ifndef YYID
40#define YYID(n) (n)
41#endif
42
43#define YYLLOC_DEFAULT(Current, Rhs, N) \
44 do \
45 if (YYID (N)) \
46 { \
47 (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
48 (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
49 (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
50 (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
51 (Current).filenum = YYRHSLOC (Rhs, N).filenum; \
52 } \
53 else \
54 { \
55 (Current).first_line = (Current).last_line = \
56 YYRHSLOC (Rhs, 0).last_line; \
57 (Current).first_column = (Current).last_column = \
58 YYRHSLOC (Rhs, 0).last_column; \
59 (Current).filenum = YYRHSLOC (Rhs, 0).filenum; \
60 } \
61 while (YYID (0))
62
63
64
65extern void yyerror(char const *);
66
67extern int srcpos_filenum;
68
69extern int push_input_file(const char *filename);
70extern int pop_input_file(void);
71
72extern FILE *dtc_open_file(const char *fname);
73extern int lookup_file_name(const char *fname, int add_it);
74extern const char *srcpos_filename_for_num(int filenum);
75const char *srcpos_get_filename(void);
diff --git a/arch/powerpc/boot/dtc-src/treesource.c b/arch/powerpc/boot/dtc-src/treesource.c
new file mode 100644
index 000000000000..a6a776797636
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/treesource.c
@@ -0,0 +1,275 @@
1/*
2 * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005.
3 *
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
18 * USA
19 */
20
21#include "dtc.h"
22#include "srcpos.h"
23
24extern FILE *yyin;
25extern int yyparse(void);
26extern void yyerror(char const *);
27
28struct boot_info *the_boot_info;
29
30struct boot_info *dt_from_source(const char *fname)
31{
32 the_boot_info = NULL;
33
34 push_input_file(fname);
35
36 if (yyparse() != 0)
37 return NULL;
38
39 fill_fullpaths(the_boot_info->dt, "");
40
41 return the_boot_info;
42}
43
44static void write_prefix(FILE *f, int level)
45{
46 int i;
47
48 for (i = 0; i < level; i++)
49 fputc('\t', f);
50}
51
52int isstring(char c)
53{
54 return (isprint(c)
55 || (c == '\0')
56 || strchr("\a\b\t\n\v\f\r", c));
57}
58
59static void write_propval_string(FILE *f, struct data val)
60{
61 const char *str = val.val;
62 int i;
63 int newchunk = 1;
64 struct marker *m = val.markers;
65
66 assert(str[val.len-1] == '\0');
67
68 for (i = 0; i < (val.len-1); i++) {
69 char c = str[i];
70
71 if (newchunk) {
72 while (m && (m->offset <= i)) {
73 if (m->type == LABEL) {
74 assert(m->offset == i);
75 fprintf(f, "%s: ", m->ref);
76 }
77 m = m->next;
78 }
79 fprintf(f, "\"");
80 newchunk = 0;
81 }
82
83 switch (c) {
84 case '\a':
85 fprintf(f, "\\a");
86 break;
87 case '\b':
88 fprintf(f, "\\b");
89 break;
90 case '\t':
91 fprintf(f, "\\t");
92 break;
93 case '\n':
94 fprintf(f, "\\n");
95 break;
96 case '\v':
97 fprintf(f, "\\v");
98 break;
99 case '\f':
100 fprintf(f, "\\f");
101 break;
102 case '\r':
103 fprintf(f, "\\r");
104 break;
105 case '\\':
106 fprintf(f, "\\\\");
107 break;
108 case '\"':
109 fprintf(f, "\\\"");
110 break;
111 case '\0':
112 fprintf(f, "\", ");
113 newchunk = 1;
114 break;
115 default:
116 if (isprint(c))
117 fprintf(f, "%c", c);
118 else
119 fprintf(f, "\\x%02hhx", c);
120 }
121 }
122 fprintf(f, "\"");
123
124 /* Wrap up any labels at the end of the value */
125 for_each_marker_of_type(m, LABEL) {
126 assert (m->offset == val.len);
127 fprintf(f, " %s:", m->ref);
128 }
129}
130
131static void write_propval_cells(FILE *f, struct data val)
132{
133 void *propend = val.val + val.len;
134 cell_t *cp = (cell_t *)val.val;
135 struct marker *m = val.markers;
136
137 fprintf(f, "<");
138 for (;;) {
139 while (m && (m->offset <= ((char *)cp - val.val))) {
140 if (m->type == LABEL) {
141 assert(m->offset == ((char *)cp - val.val));
142 fprintf(f, "%s: ", m->ref);
143 }
144 m = m->next;
145 }
146
147 fprintf(f, "0x%x", be32_to_cpu(*cp++));
148 if ((void *)cp >= propend)
149 break;
150 fprintf(f, " ");
151 }
152
153 /* Wrap up any labels at the end of the value */
154 for_each_marker_of_type(m, LABEL) {
155 assert (m->offset == val.len);
156 fprintf(f, " %s:", m->ref);
157 }
158 fprintf(f, ">");
159}
160
161static void write_propval_bytes(FILE *f, struct data val)
162{
163 void *propend = val.val + val.len;
164 const char *bp = val.val;
165 struct marker *m = val.markers;
166
167 fprintf(f, "[");
168 for (;;) {
169 while (m && (m->offset == (bp-val.val))) {
170 if (m->type == LABEL)
171 fprintf(f, "%s: ", m->ref);
172 m = m->next;
173 }
174
175 fprintf(f, "%02hhx", *bp++);
176 if ((void *)bp >= propend)
177 break;
178 fprintf(f, " ");
179 }
180
181 /* Wrap up any labels at the end of the value */
182 for_each_marker_of_type(m, LABEL) {
183 assert (m->offset == val.len);
184 fprintf(f, " %s:", m->ref);
185 }
186 fprintf(f, "]");
187}
188
189static void write_propval(FILE *f, struct property *prop)
190{
191 int len = prop->val.len;
192 const char *p = prop->val.val;
193 struct marker *m = prop->val.markers;
194 int nnotstring = 0, nnul = 0;
195 int nnotstringlbl = 0, nnotcelllbl = 0;
196 int i;
197
198 if (len == 0) {
199 fprintf(f, ";\n");
200 return;
201 }
202
203 for (i = 0; i < len; i++) {
204 if (! isstring(p[i]))
205 nnotstring++;
206 if (p[i] == '\0')
207 nnul++;
208 }
209
210 for_each_marker_of_type(m, LABEL) {
211 if ((m->offset > 0) && (prop->val.val[m->offset - 1] != '\0'))
212 nnotstringlbl++;
213 if ((m->offset % sizeof(cell_t)) != 0)
214 nnotcelllbl++;
215 }
216
217 fprintf(f, " = ");
218 if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul))
219 && (nnotstringlbl == 0)) {
220 write_propval_string(f, prop->val);
221 } else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) {
222 write_propval_cells(f, prop->val);
223 } else {
224 write_propval_bytes(f, prop->val);
225 }
226
227 fprintf(f, ";\n");
228}
229
230static void write_tree_source_node(FILE *f, struct node *tree, int level)
231{
232 struct property *prop;
233 struct node *child;
234
235 write_prefix(f, level);
236 if (tree->label)
237 fprintf(f, "%s: ", tree->label);
238 if (tree->name && (*tree->name))
239 fprintf(f, "%s {\n", tree->name);
240 else
241 fprintf(f, "/ {\n");
242
243 for_each_property(tree, prop) {
244 write_prefix(f, level+1);
245 if (prop->label)
246 fprintf(f, "%s: ", prop->label);
247 fprintf(f, "%s", prop->name);
248 write_propval(f, prop);
249 }
250 for_each_child(tree, child) {
251 fprintf(f, "\n");
252 write_tree_source_node(f, child, level+1);
253 }
254 write_prefix(f, level);
255 fprintf(f, "};\n");
256}
257
258
259void dt_to_source(FILE *f, struct boot_info *bi)
260{
261 struct reserve_info *re;
262
263 fprintf(f, "/dts-v1/;\n\n");
264
265 for (re = bi->reservelist; re; re = re->next) {
266 if (re->label)
267 fprintf(f, "%s: ", re->label);
268 fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n",
269 (unsigned long long)re->re.address,
270 (unsigned long long)re->re.size);
271 }
272
273 write_tree_source_node(f, bi->dt, 0);
274}
275
diff --git a/arch/powerpc/boot/dtc-src/version_gen.h b/arch/powerpc/boot/dtc-src/version_gen.h
new file mode 100644
index 000000000000..6c343031538e
--- /dev/null
+++ b/arch/powerpc/boot/dtc-src/version_gen.h
@@ -0,0 +1 @@
#define DTC_VERSION "DTC 1.0.0-gd6f9b62f"
diff --git a/arch/powerpc/boot/dts/kuroboxHD.dts b/arch/powerpc/boot/dts/kuroboxHD.dts
index ec71ab819fee..446958854519 100644
--- a/arch/powerpc/boot/dts/kuroboxHD.dts
+++ b/arch/powerpc/boot/dts/kuroboxHD.dts
@@ -23,6 +23,12 @@ XXXX add flash parts, rtc, ??
23 #address-cells = <1>; 23 #address-cells = <1>;
24 #size-cells = <1>; 24 #size-cells = <1>;
25 25
26 aliases {
27 serial0 = &serial0;
28 serial1 = &serial1;
29 pci0 = &pci0;
30 };
31
26 cpus { 32 cpus {
27 #address-cells = <1>; 33 #address-cells = <1>;
28 #size-cells = <0>; 34 #size-cells = <0>;
@@ -60,7 +66,7 @@ XXXX add flash parts, rtc, ??
60 i2c@80003000 { 66 i2c@80003000 {
61 #address-cells = <1>; 67 #address-cells = <1>;
62 #size-cells = <0>; 68 #size-cells = <0>;
63 device_type = "i2c"; 69 cell-index = <0>;
64 compatible = "fsl-i2c"; 70 compatible = "fsl-i2c";
65 reg = <80003000 1000>; 71 reg = <80003000 1000>;
66 interrupts = <5 2>; 72 interrupts = <5 2>;
@@ -73,7 +79,8 @@ XXXX add flash parts, rtc, ??
73 }; 79 };
74 }; 80 };
75 81
76 serial@80004500 { 82 serial0: serial@80004500 {
83 cell-index = <0>;
77 device_type = "serial"; 84 device_type = "serial";
78 compatible = "ns16550"; 85 compatible = "ns16550";
79 reg = <80004500 8>; 86 reg = <80004500 8>;
@@ -83,7 +90,8 @@ XXXX add flash parts, rtc, ??
83 interrupt-parent = <&mpic>; 90 interrupt-parent = <&mpic>;
84 }; 91 };
85 92
86 serial@80004600 { 93 serial1: serial@80004600 {
94 cell-index = <1>;
87 device_type = "serial"; 95 device_type = "serial";
88 compatible = "ns16550"; 96 compatible = "ns16550";
89 reg = <80004600 8>; 97 reg = <80004600 8>;
@@ -102,7 +110,7 @@ XXXX add flash parts, rtc, ??
102 reg = <80040000 40000>; 110 reg = <80040000 40000>;
103 }; 111 };
104 112
105 pci@fec00000 { 113 pci0: pci@fec00000 {
106 #address-cells = <3>; 114 #address-cells = <3>;
107 #size-cells = <2>; 115 #size-cells = <2>;
108 #interrupt-cells = <1>; 116 #interrupt-cells = <1>;
diff --git a/arch/powerpc/boot/dts/kuroboxHG.dts b/arch/powerpc/boot/dts/kuroboxHG.dts
index 32ecd2319928..8443c85b7b30 100644
--- a/arch/powerpc/boot/dts/kuroboxHG.dts
+++ b/arch/powerpc/boot/dts/kuroboxHG.dts
@@ -23,6 +23,12 @@ XXXX add flash parts, rtc, ??
23 #address-cells = <1>; 23 #address-cells = <1>;
24 #size-cells = <1>; 24 #size-cells = <1>;
25 25
26 aliases {
27 serial0 = &serial0;
28 serial1 = &serial1;
29 pci0 = &pci0;
30 };
31
26 cpus { 32 cpus {
27 #address-cells = <1>; 33 #address-cells = <1>;
28 #size-cells = <0>; 34 #size-cells = <0>;
@@ -60,7 +66,7 @@ XXXX add flash parts, rtc, ??
60 i2c@80003000 { 66 i2c@80003000 {
61 #address-cells = <1>; 67 #address-cells = <1>;
62 #size-cells = <0>; 68 #size-cells = <0>;
63 device_type = "i2c"; 69 cell-index = <0>;
64 compatible = "fsl-i2c"; 70 compatible = "fsl-i2c";
65 reg = <80003000 1000>; 71 reg = <80003000 1000>;
66 interrupts = <5 2>; 72 interrupts = <5 2>;
@@ -73,7 +79,8 @@ XXXX add flash parts, rtc, ??
73 }; 79 };
74 }; 80 };
75 81
76 serial@80004500 { 82 serial0: serial@80004500 {
83 cell-index = <0>;
77 device_type = "serial"; 84 device_type = "serial";
78 compatible = "ns16550"; 85 compatible = "ns16550";
79 reg = <80004500 8>; 86 reg = <80004500 8>;
@@ -83,7 +90,8 @@ XXXX add flash parts, rtc, ??
83 interrupt-parent = <&mpic>; 90 interrupt-parent = <&mpic>;
84 }; 91 };
85 92
86 serial@80004600 { 93 serial1: serial@80004600 {
94 cell-index = <1>;
87 device_type = "serial"; 95 device_type = "serial";
88 compatible = "ns16550"; 96 compatible = "ns16550";
89 reg = <80004600 8>; 97 reg = <80004600 8>;
@@ -102,7 +110,7 @@ XXXX add flash parts, rtc, ??
102 reg = <80040000 40000>; 110 reg = <80040000 40000>;
103 }; 111 };
104 112
105 pci@fec00000 { 113 pci0: pci@fec00000 {
106 #address-cells = <3>; 114 #address-cells = <3>;
107 #size-cells = <2>; 115 #size-cells = <2>;
108 #interrupt-cells = <1>; 116 #interrupt-cells = <1>;
diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts
index 6731763f0282..23eeeb1fc61e 100644
--- a/arch/powerpc/boot/dts/lite5200.dts
+++ b/arch/powerpc/boot/dts/lite5200.dts
@@ -284,7 +284,8 @@
284 }; 284 };
285 285
286 i2c@3d00 { 286 i2c@3d00 {
287 device_type = "i2c"; 287 #address-cells = <1>;
288 #size-cells = <0>;
288 compatible = "mpc5200-i2c","fsl-i2c"; 289 compatible = "mpc5200-i2c","fsl-i2c";
289 cell-index = <0>; 290 cell-index = <0>;
290 reg = <3d00 40>; 291 reg = <3d00 40>;
@@ -294,7 +295,8 @@
294 }; 295 };
295 296
296 i2c@3d40 { 297 i2c@3d40 {
297 device_type = "i2c"; 298 #address-cells = <1>;
299 #size-cells = <0>;
298 compatible = "mpc5200-i2c","fsl-i2c"; 300 compatible = "mpc5200-i2c","fsl-i2c";
299 cell-index = <1>; 301 cell-index = <1>;
300 reg = <3d40 40>; 302 reg = <3d40 40>;
diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts
index b540388c608c..f94e073de9a7 100644
--- a/arch/powerpc/boot/dts/lite5200b.dts
+++ b/arch/powerpc/boot/dts/lite5200b.dts
@@ -300,7 +300,8 @@
300 }; 300 };
301 301
302 i2c@3d00 { 302 i2c@3d00 {
303 device_type = "i2c"; 303 #address-cells = <1>;
304 #size-cells = <0>;
304 compatible = "mpc5200b-i2c","mpc5200-i2c","fsl-i2c"; 305 compatible = "mpc5200b-i2c","mpc5200-i2c","fsl-i2c";
305 cell-index = <0>; 306 cell-index = <0>;
306 reg = <3d00 40>; 307 reg = <3d00 40>;
@@ -310,7 +311,8 @@
310 }; 311 };
311 312
312 i2c@3d40 { 313 i2c@3d40 {
313 device_type = "i2c"; 314 #address-cells = <1>;
315 #size-cells = <0>;
314 compatible = "mpc5200b-i2c","mpc5200-i2c","fsl-i2c"; 316 compatible = "mpc5200b-i2c","mpc5200-i2c","fsl-i2c";
315 cell-index = <1>; 317 cell-index = <1>;
316 reg = <3d40 40>; 318 reg = <3d40 40>;
diff --git a/arch/powerpc/boot/dts/mpc8313erdb.dts b/arch/powerpc/boot/dts/mpc8313erdb.dts
index 9e7eba973262..c5b6665a8209 100644
--- a/arch/powerpc/boot/dts/mpc8313erdb.dts
+++ b/arch/powerpc/boot/dts/mpc8313erdb.dts
@@ -15,6 +15,14 @@
15 #address-cells = <1>; 15 #address-cells = <1>;
16 #size-cells = <1>; 16 #size-cells = <1>;
17 17
18 aliases {
19 ethernet0 = &enet0;
20 ethernet1 = &enet1;
21 serial0 = &serial0;
22 serial1 = &serial1;
23 pci0 = &pci0;
24 };
25
18 cpus { 26 cpus {
19 #address-cells = <1>; 27 #address-cells = <1>;
20 #size-cells = <0>; 28 #size-cells = <0>;
@@ -52,7 +60,9 @@
52 }; 60 };
53 61
54 i2c@3000 { 62 i2c@3000 {
55 device_type = "i2c"; 63 #address-cells = <1>;
64 #size-cells = <0>;
65 cell-index = <0>;
56 compatible = "fsl-i2c"; 66 compatible = "fsl-i2c";
57 reg = <3000 100>; 67 reg = <3000 100>;
58 interrupts = <e 8>; 68 interrupts = <e 8>;
@@ -61,7 +71,9 @@
61 }; 71 };
62 72
63 i2c@3100 { 73 i2c@3100 {
64 device_type = "i2c"; 74 #address-cells = <1>;
75 #size-cells = <0>;
76 cell-index = <1>;
65 compatible = "fsl-i2c"; 77 compatible = "fsl-i2c";
66 reg = <3100 100>; 78 reg = <3100 100>;
67 interrupts = <f 8>; 79 interrupts = <f 8>;
@@ -91,11 +103,10 @@
91 }; 103 };
92 104
93 mdio@24520 { 105 mdio@24520 {
94 device_type = "mdio";
95 compatible = "gianfar";
96 reg = <24520 20>;
97 #address-cells = <1>; 106 #address-cells = <1>;
98 #size-cells = <0>; 107 #size-cells = <0>;
108 compatible = "fsl,gianfar-mdio";
109 reg = <24520 20>;
99 phy1: ethernet-phy@1 { 110 phy1: ethernet-phy@1 {
100 interrupt-parent = < &ipic >; 111 interrupt-parent = < &ipic >;
101 interrupts = <13 8>; 112 interrupts = <13 8>;
@@ -110,7 +121,8 @@
110 }; 121 };
111 }; 122 };
112 123
113 ethernet@24000 { 124 enet0: ethernet@24000 {
125 cell-index = <0>;
114 device_type = "network"; 126 device_type = "network";
115 model = "eTSEC"; 127 model = "eTSEC";
116 compatible = "gianfar"; 128 compatible = "gianfar";
@@ -121,7 +133,8 @@
121 phy-handle = < &phy1 >; 133 phy-handle = < &phy1 >;
122 }; 134 };
123 135
124 ethernet@25000 { 136 enet1: ethernet@25000 {
137 cell-index = <1>;
125 device_type = "network"; 138 device_type = "network";
126 model = "eTSEC"; 139 model = "eTSEC";
127 compatible = "gianfar"; 140 compatible = "gianfar";
@@ -132,7 +145,8 @@
132 phy-handle = < &phy4 >; 145 phy-handle = < &phy4 >;
133 }; 146 };
134 147
135 serial@4500 { 148 serial0: serial@4500 {
149 cell-index = <0>;
136 device_type = "serial"; 150 device_type = "serial";
137 compatible = "ns16550"; 151 compatible = "ns16550";
138 reg = <4500 100>; 152 reg = <4500 100>;
@@ -141,7 +155,8 @@
141 interrupt-parent = < &ipic >; 155 interrupt-parent = < &ipic >;
142 }; 156 };
143 157
144 serial@4600 { 158 serial1: serial@4600 {
159 cell-index = <1>;
145 device_type = "serial"; 160 device_type = "serial";
146 compatible = "ns16550"; 161 compatible = "ns16550";
147 reg = <4600 100>; 162 reg = <4600 100>;
@@ -179,7 +194,8 @@
179 }; 194 };
180 }; 195 };
181 196
182 pci@e0008500 { 197 pci0: pci@e0008500 {
198 cell-index = <1>;
183 interrupt-map-mask = <f800 0 0 7>; 199 interrupt-map-mask = <f800 0 0 7>;
184 interrupt-map = < 200 interrupt-map = <
185 201
diff --git a/arch/powerpc/boot/dts/mpc832x_mds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
index c64f3037a13b..26ac467b10ea 100644
--- a/arch/powerpc/boot/dts/mpc832x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -15,6 +15,14 @@
15 #address-cells = <1>; 15 #address-cells = <1>;
16 #size-cells = <1>; 16 #size-cells = <1>;
17 17
18 aliases {
19 ethernet0 = &enet0;
20 ethernet1 = &enet1;
21 serial0 = &serial0;
22 serial1 = &serial1;
23 pci0 = &pci0;
24 };
25
18 cpus { 26 cpus {
19 #address-cells = <1>; 27 #address-cells = <1>;
20 #size-cells = <0>; 28 #size-cells = <0>;
@@ -59,7 +67,7 @@
59 i2c@3000 { 67 i2c@3000 {
60 #address-cells = <1>; 68 #address-cells = <1>;
61 #size-cells = <0>; 69 #size-cells = <0>;
62 device_type = "i2c"; 70 cell-index = <0>;
63 compatible = "fsl-i2c"; 71 compatible = "fsl-i2c";
64 reg = <3000 100>; 72 reg = <3000 100>;
65 interrupts = <e 8>; 73 interrupts = <e 8>;
@@ -72,7 +80,8 @@
72 }; 80 };
73 }; 81 };
74 82
75 serial@4500 { 83 serial0: serial@4500 {
84 cell-index = <0>;
76 device_type = "serial"; 85 device_type = "serial";
77 compatible = "ns16550"; 86 compatible = "ns16550";
78 reg = <4500 100>; 87 reg = <4500 100>;
@@ -81,7 +90,8 @@
81 interrupt-parent = < &ipic >; 90 interrupt-parent = < &ipic >;
82 }; 91 };
83 92
84 serial@4600 { 93 serial1: serial@4600 {
94 cell-index = <1>;
85 device_type = "serial"; 95 device_type = "serial";
86 compatible = "ns16550"; 96 compatible = "ns16550";
87 reg = <4600 100>; 97 reg = <4600 100>;
@@ -208,44 +218,34 @@
208 mode = "slave"; 218 mode = "slave";
209 }; 219 };
210 220
211 ucc@2200 { 221 enet0: ucc@2200 {
212 device_type = "network"; 222 device_type = "network";
213 compatible = "ucc_geth"; 223 compatible = "ucc_geth";
214 model = "UCC"; 224 model = "UCC";
225 cell-index = <3>;
215 device-id = <3>; 226 device-id = <3>;
216 reg = <2200 200>; 227 reg = <2200 200>;
217 interrupts = <22>; 228 interrupts = <22>;
218 interrupt-parent = < &qeic >; 229 interrupt-parent = < &qeic >;
219 /*
220 * mac-address is deprecated and will be removed
221 * in 2.6.25. Only recent versions of
222 * U-Boot support local-mac-address, however.
223 */
224 mac-address = [ 00 00 00 00 00 00 ];
225 local-mac-address = [ 00 00 00 00 00 00 ]; 230 local-mac-address = [ 00 00 00 00 00 00 ];
226 rx-clock = <19>; 231 rx-clock-name = "clk9";
227 tx-clock = <1a>; 232 tx-clock-name = "clk10";
228 phy-handle = < &phy3 >; 233 phy-handle = < &phy3 >;
229 pio-handle = < &pio3 >; 234 pio-handle = < &pio3 >;
230 }; 235 };
231 236
232 ucc@3200 { 237 enet1: ucc@3200 {
233 device_type = "network"; 238 device_type = "network";
234 compatible = "ucc_geth"; 239 compatible = "ucc_geth";
235 model = "UCC"; 240 model = "UCC";
241 cell-index = <4>;
236 device-id = <4>; 242 device-id = <4>;
237 reg = <3200 200>; 243 reg = <3200 200>;
238 interrupts = <23>; 244 interrupts = <23>;
239 interrupt-parent = < &qeic >; 245 interrupt-parent = < &qeic >;
240 /*
241 * mac-address is deprecated and will be removed
242 * in 2.6.25. Only recent versions of
243 * U-Boot support local-mac-address, however.
244 */
245 mac-address = [ 00 00 00 00 00 00 ];
246 local-mac-address = [ 00 00 00 00 00 00 ]; 246 local-mac-address = [ 00 00 00 00 00 00 ];
247 rx-clock = <17>; 247 rx-clock-name = "clk7";
248 tx-clock = <18>; 248 tx-clock-name = "clk8";
249 phy-handle = < &phy4 >; 249 phy-handle = < &phy4 >;
250 pio-handle = < &pio4 >; 250 pio-handle = < &pio4 >;
251 }; 251 };
@@ -283,7 +283,8 @@
283 }; 283 };
284 }; 284 };
285 285
286 pci@e0008500 { 286 pci0: pci@e0008500 {
287 cell-index = <1>;
287 interrupt-map-mask = <f800 0 0 7>; 288 interrupt-map-mask = <f800 0 0 7>;
288 interrupt-map = < 289 interrupt-map = <
289 /* IDSEL 0x11 AD17 */ 290 /* IDSEL 0x11 AD17 */
diff --git a/arch/powerpc/boot/dts/mpc832x_rdb.dts b/arch/powerpc/boot/dts/mpc832x_rdb.dts
index 388c8a7012e1..10ff7aadf9dc 100644
--- a/arch/powerpc/boot/dts/mpc832x_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc832x_rdb.dts
@@ -15,6 +15,14 @@
15 #address-cells = <1>; 15 #address-cells = <1>;
16 #size-cells = <1>; 16 #size-cells = <1>;
17 17
18 aliases {
19 ethernet0 = &enet0;
20 ethernet1 = &enet1;
21 serial0 = &serial0;
22 serial1 = &serial1;
23 pci0 = &pci0;
24 };
25
18 cpus { 26 cpus {
19 #address-cells = <1>; 27 #address-cells = <1>;
20 #size-cells = <0>; 28 #size-cells = <0>;
@@ -52,7 +60,9 @@
52 }; 60 };
53 61
54 i2c@3000 { 62 i2c@3000 {
55 device_type = "i2c"; 63 #address-cells = <1>;
64 #size-cells = <0>;
65 cell-index = <0>;
56 compatible = "fsl-i2c"; 66 compatible = "fsl-i2c";
57 reg = <3000 100>; 67 reg = <3000 100>;
58 interrupts = <e 8>; 68 interrupts = <e 8>;
@@ -60,7 +70,8 @@
60 dfsrr; 70 dfsrr;
61 }; 71 };
62 72
63 serial@4500 { 73 serial0: serial@4500 {
74 cell-index = <0>;
64 device_type = "serial"; 75 device_type = "serial";
65 compatible = "ns16550"; 76 compatible = "ns16550";
66 reg = <4500 100>; 77 reg = <4500 100>;
@@ -69,7 +80,8 @@
69 interrupt-parent = <&pic>; 80 interrupt-parent = <&pic>;
70 }; 81 };
71 82
72 serial@4600 { 83 serial1: serial@4600 {
84 cell-index = <1>;
73 device_type = "serial"; 85 device_type = "serial";
74 compatible = "ns16550"; 86 compatible = "ns16550";
75 reg = <4600 100>; 87 reg = <4600 100>;
@@ -187,44 +199,34 @@
187 mode = "cpu"; 199 mode = "cpu";
188 }; 200 };
189 201
190 ucc@3000 { 202 enet0: ucc@3000 {
191 device_type = "network"; 203 device_type = "network";
192 compatible = "ucc_geth"; 204 compatible = "ucc_geth";
193 model = "UCC"; 205 model = "UCC";
206 cell-index = <2>;
194 device-id = <2>; 207 device-id = <2>;
195 reg = <3000 200>; 208 reg = <3000 200>;
196 interrupts = <21>; 209 interrupts = <21>;
197 interrupt-parent = <&qeic>; 210 interrupt-parent = <&qeic>;
198 /*
199 * mac-address is deprecated and will be removed
200 * in 2.6.25. Only recent versions of
201 * U-Boot support local-mac-address, however.
202 */
203 mac-address = [ 00 00 00 00 00 00 ];
204 local-mac-address = [ 00 00 00 00 00 00 ]; 211 local-mac-address = [ 00 00 00 00 00 00 ];
205 rx-clock = <20>; 212 rx-clock-name = "clk16";
206 tx-clock = <13>; 213 tx-clock-name = "clk3";
207 phy-handle = <&phy00>; 214 phy-handle = <&phy00>;
208 pio-handle = <&ucc2pio>; 215 pio-handle = <&ucc2pio>;
209 }; 216 };
210 217
211 ucc@2200 { 218 enet1: ucc@2200 {
212 device_type = "network"; 219 device_type = "network";
213 compatible = "ucc_geth"; 220 compatible = "ucc_geth";
214 model = "UCC"; 221 model = "UCC";
222 cell-index = <3>;
215 device-id = <3>; 223 device-id = <3>;
216 reg = <2200 200>; 224 reg = <2200 200>;
217 interrupts = <22>; 225 interrupts = <22>;
218 interrupt-parent = <&qeic>; 226 interrupt-parent = <&qeic>;
219 /*
220 * mac-address is deprecated and will be removed
221 * in 2.6.25. Only recent versions of
222 * U-Boot support local-mac-address, however.
223 */
224 mac-address = [ 00 00 00 00 00 00 ];
225 local-mac-address = [ 00 00 00 00 00 00 ]; 227 local-mac-address = [ 00 00 00 00 00 00 ];
226 rx-clock = <19>; 228 rx-clock-name = "clk9";
227 tx-clock = <1a>; 229 tx-clock-name = "clk10";
228 phy-handle = <&phy04>; 230 phy-handle = <&phy04>;
229 pio-handle = <&ucc3pio>; 231 pio-handle = <&ucc3pio>;
230 }; 232 };
@@ -262,7 +264,8 @@
262 }; 264 };
263 }; 265 };
264 266
265 pci@e0008500 { 267 pci0: pci@e0008500 {
268 cell-index = <1>;
266 interrupt-map-mask = <f800 0 0 7>; 269 interrupt-map-mask = <f800 0 0 7>;
267 interrupt-map = < 270 interrupt-map = <
268 /* IDSEL 0x10 AD16 (USB) */ 271 /* IDSEL 0x10 AD16 (USB) */
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts
index 5072f6d0a46d..e354f2634246 100644
--- a/arch/powerpc/boot/dts/mpc8349emitx.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitx.dts
@@ -14,6 +14,15 @@
14 #address-cells = <1>; 14 #address-cells = <1>;
15 #size-cells = <1>; 15 #size-cells = <1>;
16 16
17 aliases {
18 ethernet0 = &enet0;
19 ethernet1 = &enet1;
20 serial0 = &serial0;
21 serial1 = &serial1;
22 pci0 = &pci0;
23 pci1 = &pci1;
24 };
25
17 cpus { 26 cpus {
18 #address-cells = <1>; 27 #address-cells = <1>;
19 #size-cells = <0>; 28 #size-cells = <0>;
@@ -51,7 +60,9 @@
51 }; 60 };
52 61
53 i2c@3000 { 62 i2c@3000 {
54 device_type = "i2c"; 63 #address-cells = <1>;
64 #size-cells = <0>;
65 cell-index = <0>;
55 compatible = "fsl-i2c"; 66 compatible = "fsl-i2c";
56 reg = <3000 100>; 67 reg = <3000 100>;
57 interrupts = <e 8>; 68 interrupts = <e 8>;
@@ -60,7 +71,9 @@
60 }; 71 };
61 72
62 i2c@3100 { 73 i2c@3100 {
63 device_type = "i2c"; 74 #address-cells = <1>;
75 #size-cells = <0>;
76 cell-index = <1>;
64 compatible = "fsl-i2c"; 77 compatible = "fsl-i2c";
65 reg = <3100 100>; 78 reg = <3100 100>;
66 interrupts = <f 8>; 79 interrupts = <f 8>;
@@ -102,11 +115,10 @@
102 }; 115 };
103 116
104 mdio@24520 { 117 mdio@24520 {
105 device_type = "mdio";
106 compatible = "gianfar";
107 reg = <24520 20>;
108 #address-cells = <1>; 118 #address-cells = <1>;
109 #size-cells = <0>; 119 #size-cells = <0>;
120 compatible = "fsl,gianfar-mdio";
121 reg = <24520 20>;
110 122
111 /* Vitesse 8201 */ 123 /* Vitesse 8201 */
112 phy1c: ethernet-phy@1c { 124 phy1c: ethernet-phy@1c {
@@ -125,17 +137,12 @@
125 }; 137 };
126 }; 138 };
127 139
128 ethernet@24000 { 140 enet0: ethernet@24000 {
141 cell-index = <0>;
129 device_type = "network"; 142 device_type = "network";
130 model = "TSEC"; 143 model = "TSEC";
131 compatible = "gianfar"; 144 compatible = "gianfar";
132 reg = <24000 1000>; 145 reg = <24000 1000>;
133 /*
134 * address is deprecated and will be removed
135 * in 2.6.25. Only recent versions of
136 * U-Boot support local-mac-address, however.
137 */
138 address = [ 00 00 00 00 00 00 ];
139 local-mac-address = [ 00 00 00 00 00 00 ]; 146 local-mac-address = [ 00 00 00 00 00 00 ];
140 interrupts = <20 8 21 8 22 8>; 147 interrupts = <20 8 21 8 22 8>;
141 interrupt-parent = < &ipic >; 148 interrupt-parent = < &ipic >;
@@ -143,19 +150,12 @@
143 linux,network-index = <0>; 150 linux,network-index = <0>;
144 }; 151 };
145 152
146 ethernet@25000 { 153 enet1: ethernet@25000 {
147 #address-cells = <1>; 154 cell-index = <1>;
148 #size-cells = <0>;
149 device_type = "network"; 155 device_type = "network";
150 model = "TSEC"; 156 model = "TSEC";
151 compatible = "gianfar"; 157 compatible = "gianfar";
152 reg = <25000 1000>; 158 reg = <25000 1000>;
153 /*
154 * address is deprecated and will be removed
155 * in 2.6.25. Only recent versions of
156 * U-Boot support local-mac-address, however.
157 */
158 address = [ 00 00 00 00 00 00 ];
159 local-mac-address = [ 00 00 00 00 00 00 ]; 159 local-mac-address = [ 00 00 00 00 00 00 ];
160 interrupts = <23 8 24 8 25 8>; 160 interrupts = <23 8 24 8 25 8>;
161 interrupt-parent = < &ipic >; 161 interrupt-parent = < &ipic >;
@@ -163,7 +163,8 @@
163 linux,network-index = <1>; 163 linux,network-index = <1>;
164 }; 164 };
165 165
166 serial@4500 { 166 serial0: serial@4500 {
167 cell-index = <0>;
167 device_type = "serial"; 168 device_type = "serial";
168 compatible = "ns16550"; 169 compatible = "ns16550";
169 reg = <4500 100>; 170 reg = <4500 100>;
@@ -172,7 +173,8 @@
172 interrupt-parent = < &ipic >; 173 interrupt-parent = < &ipic >;
173 }; 174 };
174 175
175 serial@4600 { 176 serial1: serial@4600 {
177 cell-index = <1>;
176 device_type = "serial"; 178 device_type = "serial";
177 compatible = "ns16550"; 179 compatible = "ns16550";
178 reg = <4600 100>; 180 reg = <4600 100>;
@@ -203,7 +205,8 @@
203 }; 205 };
204 }; 206 };
205 207
206 pci@e0008500 { 208 pci0: pci@e0008500 {
209 cell-index = <1>;
207 interrupt-map-mask = <f800 0 0 7>; 210 interrupt-map-mask = <f800 0 0 7>;
208 interrupt-map = < 211 interrupt-map = <
209 /* IDSEL 0x10 - SATA */ 212 /* IDSEL 0x10 - SATA */
@@ -224,7 +227,8 @@
224 device_type = "pci"; 227 device_type = "pci";
225 }; 228 };
226 229
227 pci@e0008600 { 230 pci1: pci@e0008600 {
231 cell-index = <2>;
228 interrupt-map-mask = <f800 0 0 7>; 232 interrupt-map-mask = <f800 0 0 7>;
229 interrupt-map = < 233 interrupt-map = <
230 /* IDSEL 0x0E - MiniPCI Slot */ 234 /* IDSEL 0x0E - MiniPCI Slot */
diff --git a/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/arch/powerpc/boot/dts/mpc8349emitxgp.dts
index 074f7a2ab7e4..ebdf0b750086 100644
--- a/arch/powerpc/boot/dts/mpc8349emitxgp.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitxgp.dts
@@ -14,6 +14,13 @@
14 #address-cells = <1>; 14 #address-cells = <1>;
15 #size-cells = <1>; 15 #size-cells = <1>;
16 16
17 aliases {
18 ethernet0 = &enet0;
19 serial0 = &serial0;
20 serial1 = &serial1;
21 pci0 = &pci0;
22 };
23
17 cpus { 24 cpus {
18 #address-cells = <1>; 25 #address-cells = <1>;
19 #size-cells = <0>; 26 #size-cells = <0>;
@@ -51,7 +58,9 @@
51 }; 58 };
52 59
53 i2c@3000 { 60 i2c@3000 {
54 device_type = "i2c"; 61 #address-cells = <1>;
62 #size-cells = <0>;
63 cell-index = <0>;
55 compatible = "fsl-i2c"; 64 compatible = "fsl-i2c";
56 reg = <3000 100>; 65 reg = <3000 100>;
57 interrupts = <e 8>; 66 interrupts = <e 8>;
@@ -60,7 +69,9 @@
60 }; 69 };
61 70
62 i2c@3100 { 71 i2c@3100 {
63 device_type = "i2c"; 72 #address-cells = <1>;
73 #size-cells = <0>;
74 cell-index = <1>;
64 compatible = "fsl-i2c"; 75 compatible = "fsl-i2c";
65 reg = <3100 100>; 76 reg = <3100 100>;
66 interrupts = <f 8>; 77 interrupts = <f 8>;
@@ -90,11 +101,10 @@
90 }; 101 };
91 102
92 mdio@24520 { 103 mdio@24520 {
93 device_type = "mdio";
94 compatible = "gianfar";
95 reg = <24520 20>;
96 #address-cells = <1>; 104 #address-cells = <1>;
97 #size-cells = <0>; 105 #size-cells = <0>;
106 compatible = "fsl,gianfar-mdio";
107 reg = <24520 20>;
98 108
99 /* Vitesse 8201 */ 109 /* Vitesse 8201 */
100 phy1c: ethernet-phy@1c { 110 phy1c: ethernet-phy@1c {
@@ -105,7 +115,8 @@
105 }; 115 };
106 }; 116 };
107 117
108 ethernet@24000 { 118 enet0: ethernet@24000 {
119 cell-index = <0>;
109 device_type = "network"; 120 device_type = "network";
110 model = "TSEC"; 121 model = "TSEC";
111 compatible = "gianfar"; 122 compatible = "gianfar";
@@ -117,7 +128,8 @@
117 linux,network-index = <0>; 128 linux,network-index = <0>;
118 }; 129 };
119 130
120 serial@4500 { 131 serial0: serial@4500 {
132 cell-index = <0>;
121 device_type = "serial"; 133 device_type = "serial";
122 compatible = "ns16550"; 134 compatible = "ns16550";
123 reg = <4500 100>; 135 reg = <4500 100>;
@@ -126,7 +138,8 @@
126 interrupt-parent = < &ipic >; 138 interrupt-parent = < &ipic >;
127 }; 139 };
128 140
129 serial@4600 { 141 serial1: serial@4600 {
142 cell-index = <1>;
130 device_type = "serial"; 143 device_type = "serial";
131 compatible = "ns16550"; 144 compatible = "ns16550";
132 reg = <4600 100>; 145 reg = <4600 100>;
@@ -157,7 +170,8 @@
157 }; 170 };
158 }; 171 };
159 172
160 pci@e0008600 { 173 pci0: pci@e0008600 {
174 cell-index = <2>;
161 interrupt-map-mask = <f800 0 0 7>; 175 interrupt-map-mask = <f800 0 0 7>;
162 interrupt-map = < 176 interrupt-map = <
163 /* IDSEL 0x0F - PCI Slot */ 177 /* IDSEL 0x0F - PCI Slot */
diff --git a/arch/powerpc/boot/dts/mpc834x_mds.dts b/arch/powerpc/boot/dts/mpc834x_mds.dts
index 49363f89cb71..0ba13ebcea68 100644
--- a/arch/powerpc/boot/dts/mpc834x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc834x_mds.dts
@@ -15,6 +15,15 @@
15 #address-cells = <1>; 15 #address-cells = <1>;
16 #size-cells = <1>; 16 #size-cells = <1>;
17 17
18 aliases {
19 ethernet0 = &enet0;
20 ethernet1 = &enet1;
21 serial0 = &serial0;
22 serial1 = &serial1;
23 pci0 = &pci0;
24 pci1 = &pci1;
25 };
26
18 cpus { 27 cpus {
19 #address-cells = <1>; 28 #address-cells = <1>;
20 #size-cells = <0>; 29 #size-cells = <0>;
@@ -59,7 +68,7 @@
59 i2c@3000 { 68 i2c@3000 {
60 #address-cells = <1>; 69 #address-cells = <1>;
61 #size-cells = <0>; 70 #size-cells = <0>;
62 device_type = "i2c"; 71 cell-index = <0>;
63 compatible = "fsl-i2c"; 72 compatible = "fsl-i2c";
64 reg = <3000 100>; 73 reg = <3000 100>;
65 interrupts = <e 8>; 74 interrupts = <e 8>;
@@ -75,7 +84,7 @@
75 i2c@3100 { 84 i2c@3100 {
76 #address-cells = <1>; 85 #address-cells = <1>;
77 #size-cells = <0>; 86 #size-cells = <0>;
78 device_type = "i2c"; 87 cell-index = <1>;
79 compatible = "fsl-i2c"; 88 compatible = "fsl-i2c";
80 reg = <3100 100>; 89 reg = <3100 100>;
81 interrupts = <f 8>; 90 interrupts = <f 8>;
@@ -119,11 +128,11 @@
119 }; 128 };
120 129
121 mdio@24520 { 130 mdio@24520 {
122 device_type = "mdio";
123 compatible = "gianfar";
124 reg = <24520 20>;
125 #address-cells = <1>; 131 #address-cells = <1>;
126 #size-cells = <0>; 132 #size-cells = <0>;
133 compatible = "fsl,gianfar-mdio";
134 reg = <24520 20>;
135
127 phy0: ethernet-phy@0 { 136 phy0: ethernet-phy@0 {
128 interrupt-parent = < &ipic >; 137 interrupt-parent = < &ipic >;
129 interrupts = <11 8>; 138 interrupts = <11 8>;
@@ -138,17 +147,12 @@
138 }; 147 };
139 }; 148 };
140 149
141 ethernet@24000 { 150 enet0: ethernet@24000 {
151 cell-index = <0>;
142 device_type = "network"; 152 device_type = "network";
143 model = "TSEC"; 153 model = "TSEC";
144 compatible = "gianfar"; 154 compatible = "gianfar";
145 reg = <24000 1000>; 155 reg = <24000 1000>;
146 /*
147 * address is deprecated and will be removed
148 * in 2.6.25. Only recent versions of
149 * U-Boot support local-mac-address, however.
150 */
151 address = [ 00 00 00 00 00 00 ];
152 local-mac-address = [ 00 00 00 00 00 00 ]; 156 local-mac-address = [ 00 00 00 00 00 00 ];
153 interrupts = <20 8 21 8 22 8>; 157 interrupts = <20 8 21 8 22 8>;
154 interrupt-parent = < &ipic >; 158 interrupt-parent = < &ipic >;
@@ -156,19 +160,12 @@
156 linux,network-index = <0>; 160 linux,network-index = <0>;
157 }; 161 };
158 162
159 ethernet@25000 { 163 enet1: ethernet@25000 {
160 #address-cells = <1>; 164 cell-index = <1>;
161 #size-cells = <0>;
162 device_type = "network"; 165 device_type = "network";
163 model = "TSEC"; 166 model = "TSEC";
164 compatible = "gianfar"; 167 compatible = "gianfar";
165 reg = <25000 1000>; 168 reg = <25000 1000>;
166 /*
167 * address is deprecated and will be removed
168 * in 2.6.25. Only recent versions of
169 * U-Boot support local-mac-address, however.
170 */
171 address = [ 00 00 00 00 00 00 ];
172 local-mac-address = [ 00 00 00 00 00 00 ]; 169 local-mac-address = [ 00 00 00 00 00 00 ];
173 interrupts = <23 8 24 8 25 8>; 170 interrupts = <23 8 24 8 25 8>;
174 interrupt-parent = < &ipic >; 171 interrupt-parent = < &ipic >;
@@ -176,7 +173,8 @@
176 linux,network-index = <1>; 173 linux,network-index = <1>;
177 }; 174 };
178 175
179 serial@4500 { 176 serial0: serial@4500 {
177 cell-index = <0>;
180 device_type = "serial"; 178 device_type = "serial";
181 compatible = "ns16550"; 179 compatible = "ns16550";
182 reg = <4500 100>; 180 reg = <4500 100>;
@@ -185,7 +183,8 @@
185 interrupt-parent = < &ipic >; 183 interrupt-parent = < &ipic >;
186 }; 184 };
187 185
188 serial@4600 { 186 serial1: serial@4600 {
187 cell-index = <1>;
189 device_type = "serial"; 188 device_type = "serial";
190 compatible = "ns16550"; 189 compatible = "ns16550";
191 reg = <4600 100>; 190 reg = <4600 100>;
@@ -225,7 +224,8 @@
225 }; 224 };
226 }; 225 };
227 226
228 pci@e0008500 { 227 pci0: pci@e0008500 {
228 cell-index = <1>;
229 interrupt-map-mask = <f800 0 0 7>; 229 interrupt-map-mask = <f800 0 0 7>;
230 interrupt-map = < 230 interrupt-map = <
231 231
@@ -285,7 +285,8 @@
285 device_type = "pci"; 285 device_type = "pci";
286 }; 286 };
287 287
288 pci@e0008600 { 288 pci1: pci@e0008600 {
289 cell-index = <2>;
289 interrupt-map-mask = <f800 0 0 7>; 290 interrupt-map-mask = <f800 0 0 7>;
290 interrupt-map = < 291 interrupt-map = <
291 292
diff --git a/arch/powerpc/boot/dts/mpc836x_mds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
index 0b2d2b588daa..fd841b2fddd0 100644
--- a/arch/powerpc/boot/dts/mpc836x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -20,6 +20,14 @@
20 #address-cells = <1>; 20 #address-cells = <1>;
21 #size-cells = <1>; 21 #size-cells = <1>;
22 22
23 aliases {
24 ethernet0 = &enet0;
25 ethernet1 = &enet1;
26 serial0 = &serial0;
27 serial1 = &serial1;
28 pci0 = &pci0;
29 };
30
23 cpus { 31 cpus {
24 #address-cells = <1>; 32 #address-cells = <1>;
25 #size-cells = <0>; 33 #size-cells = <0>;
@@ -64,7 +72,7 @@
64 i2c@3000 { 72 i2c@3000 {
65 #address-cells = <1>; 73 #address-cells = <1>;
66 #size-cells = <0>; 74 #size-cells = <0>;
67 device_type = "i2c"; 75 cell-index = <0>;
68 compatible = "fsl-i2c"; 76 compatible = "fsl-i2c";
69 reg = <3000 100>; 77 reg = <3000 100>;
70 interrupts = <e 8>; 78 interrupts = <e 8>;
@@ -80,7 +88,7 @@
80 i2c@3100 { 88 i2c@3100 {
81 #address-cells = <1>; 89 #address-cells = <1>;
82 #size-cells = <0>; 90 #size-cells = <0>;
83 device_type = "i2c"; 91 cell-index = <1>;
84 compatible = "fsl-i2c"; 92 compatible = "fsl-i2c";
85 reg = <3100 100>; 93 reg = <3100 100>;
86 interrupts = <f 8>; 94 interrupts = <f 8>;
@@ -88,7 +96,8 @@
88 dfsrr; 96 dfsrr;
89 }; 97 };
90 98
91 serial@4500 { 99 serial0: serial@4500 {
100 cell-index = <0>;
92 device_type = "serial"; 101 device_type = "serial";
93 compatible = "ns16550"; 102 compatible = "ns16550";
94 reg = <4500 100>; 103 reg = <4500 100>;
@@ -97,7 +106,8 @@
97 interrupt-parent = < &ipic >; 106 interrupt-parent = < &ipic >;
98 }; 107 };
99 108
100 serial@4600 { 109 serial1: serial@4600 {
110 cell-index = <1>;
101 device_type = "serial"; 111 device_type = "serial";
102 compatible = "ns16550"; 112 compatible = "ns16550";
103 reg = <4600 100>; 113 reg = <4600 100>;
@@ -239,45 +249,35 @@
239 mode = "slave"; 249 mode = "slave";
240 }; 250 };
241 251
242 ucc@2000 { 252 enet0: ucc@2000 {
243 device_type = "network"; 253 device_type = "network";
244 compatible = "ucc_geth"; 254 compatible = "ucc_geth";
245 model = "UCC"; 255 model = "UCC";
256 cell-index = <1>;
246 device-id = <1>; 257 device-id = <1>;
247 reg = <2000 200>; 258 reg = <2000 200>;
248 interrupts = <20>; 259 interrupts = <20>;
249 interrupt-parent = < &qeic >; 260 interrupt-parent = < &qeic >;
250 /*
251 * mac-address is deprecated and will be removed
252 * in 2.6.25. Only recent versions of
253 * U-Boot support local-mac-address, however.
254 */
255 mac-address = [ 00 00 00 00 00 00 ];
256 local-mac-address = [ 00 00 00 00 00 00 ]; 261 local-mac-address = [ 00 00 00 00 00 00 ];
257 rx-clock = <0>; 262 rx-clock-name = "none";
258 tx-clock = <19>; 263 tx-clock-name = "clk9";
259 phy-handle = < &phy0 >; 264 phy-handle = < &phy0 >;
260 phy-connection-type = "rgmii-id"; 265 phy-connection-type = "rgmii-id";
261 pio-handle = < &pio1 >; 266 pio-handle = < &pio1 >;
262 }; 267 };
263 268
264 ucc@3000 { 269 enet1: ucc@3000 {
265 device_type = "network"; 270 device_type = "network";
266 compatible = "ucc_geth"; 271 compatible = "ucc_geth";
267 model = "UCC"; 272 model = "UCC";
273 cell-index = <2>;
268 device-id = <2>; 274 device-id = <2>;
269 reg = <3000 200>; 275 reg = <3000 200>;
270 interrupts = <21>; 276 interrupts = <21>;
271 interrupt-parent = < &qeic >; 277 interrupt-parent = < &qeic >;
272 /*
273 * mac-address is deprecated and will be removed
274 * in 2.6.25. Only recent versions of
275 * U-Boot support local-mac-address, however.
276 */
277 mac-address = [ 00 00 00 00 00 00 ];
278 local-mac-address = [ 00 00 00 00 00 00 ]; 278 local-mac-address = [ 00 00 00 00 00 00 ];
279 rx-clock = <0>; 279 rx-clock-name = "none";
280 tx-clock = <14>; 280 tx-clock-name = "clk4";
281 phy-handle = < &phy1 >; 281 phy-handle = < &phy1 >;
282 phy-connection-type = "rgmii-id"; 282 phy-connection-type = "rgmii-id";
283 pio-handle = < &pio2 >; 283 pio-handle = < &pio2 >;
@@ -316,7 +316,8 @@
316 }; 316 };
317 }; 317 };
318 318
319 pci@e0008500 { 319 pci0: pci@e0008500 {
320 cell-index = <1>;
320 interrupt-map-mask = <f800 0 0 7>; 321 interrupt-map-mask = <f800 0 0 7>;
321 interrupt-map = < 322 interrupt-map = <
322 323
diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/boot/dts/mpc8540ads.dts
index 6442a717ec3b..975248491b7b 100644
--- a/arch/powerpc/boot/dts/mpc8540ads.dts
+++ b/arch/powerpc/boot/dts/mpc8540ads.dts
@@ -16,6 +16,15 @@
16 #address-cells = <1>; 16 #address-cells = <1>;
17 #size-cells = <1>; 17 #size-cells = <1>;
18 18
19 aliases {
20 ethernet0 = &enet0;
21 ethernet1 = &enet1;
22 ethernet2 = &enet2;
23 serial0 = &serial0;
24 serial1 = &serial1;
25 pci0 = &pci0;
26 };
27
19 cpus { 28 cpus {
20 #address-cells = <1>; 29 #address-cells = <1>;
21 #size-cells = <0>; 30 #size-cells = <0>;
@@ -63,7 +72,9 @@
63 }; 72 };
64 73
65 i2c@3000 { 74 i2c@3000 {
66 device_type = "i2c"; 75 #address-cells = <1>;
76 #size-cells = <0>;
77 cell-index = <0>;
67 compatible = "fsl-i2c"; 78 compatible = "fsl-i2c";
68 reg = <3000 100>; 79 reg = <3000 100>;
69 interrupts = <2b 2>; 80 interrupts = <2b 2>;
@@ -74,9 +85,9 @@
74 mdio@24520 { 85 mdio@24520 {
75 #address-cells = <1>; 86 #address-cells = <1>;
76 #size-cells = <0>; 87 #size-cells = <0>;
77 device_type = "mdio"; 88 compatible = "fsl,gianfar-mdio";
78 compatible = "gianfar";
79 reg = <24520 20>; 89 reg = <24520 20>;
90
80 phy0: ethernet-phy@0 { 91 phy0: ethernet-phy@0 {
81 interrupt-parent = <&mpic>; 92 interrupt-parent = <&mpic>;
82 interrupts = <5 1>; 93 interrupts = <5 1>;
@@ -97,64 +108,44 @@
97 }; 108 };
98 }; 109 };
99 110
100 ethernet@24000 { 111 enet0: ethernet@24000 {
101 #address-cells = <1>; 112 cell-index = <0>;
102 #size-cells = <0>;
103 device_type = "network"; 113 device_type = "network";
104 model = "TSEC"; 114 model = "TSEC";
105 compatible = "gianfar"; 115 compatible = "gianfar";
106 reg = <24000 1000>; 116 reg = <24000 1000>;
107 /*
108 * address is deprecated and will be removed
109 * in 2.6.25. Only recent versions of
110 * U-Boot support local-mac-address, however.
111 */
112 address = [ 00 00 00 00 00 00 ];
113 local-mac-address = [ 00 00 00 00 00 00 ]; 117 local-mac-address = [ 00 00 00 00 00 00 ];
114 interrupts = <1d 2 1e 2 22 2>; 118 interrupts = <1d 2 1e 2 22 2>;
115 interrupt-parent = <&mpic>; 119 interrupt-parent = <&mpic>;
116 phy-handle = <&phy0>; 120 phy-handle = <&phy0>;
117 }; 121 };
118 122
119 ethernet@25000 { 123 enet1: ethernet@25000 {
120 #address-cells = <1>; 124 cell-index = <1>;
121 #size-cells = <0>;
122 device_type = "network"; 125 device_type = "network";
123 model = "TSEC"; 126 model = "TSEC";
124 compatible = "gianfar"; 127 compatible = "gianfar";
125 reg = <25000 1000>; 128 reg = <25000 1000>;
126 /*
127 * address is deprecated and will be removed
128 * in 2.6.25. Only recent versions of
129 * U-Boot support local-mac-address, however.
130 */
131 address = [ 00 00 00 00 00 00 ];
132 local-mac-address = [ 00 00 00 00 00 00 ]; 129 local-mac-address = [ 00 00 00 00 00 00 ];
133 interrupts = <23 2 24 2 28 2>; 130 interrupts = <23 2 24 2 28 2>;
134 interrupt-parent = <&mpic>; 131 interrupt-parent = <&mpic>;
135 phy-handle = <&phy1>; 132 phy-handle = <&phy1>;
136 }; 133 };
137 134
138 ethernet@26000 { 135 enet2: ethernet@26000 {
139 #address-cells = <1>; 136 cell-index = <2>;
140 #size-cells = <0>;
141 device_type = "network"; 137 device_type = "network";
142 model = "FEC"; 138 model = "FEC";
143 compatible = "gianfar"; 139 compatible = "gianfar";
144 reg = <26000 1000>; 140 reg = <26000 1000>;
145 /*
146 * address is deprecated and will be removed
147 * in 2.6.25. Only recent versions of
148 * U-Boot support local-mac-address, however.
149 */
150 address = [ 00 00 00 00 00 00 ];
151 local-mac-address = [ 00 00 00 00 00 00 ]; 141 local-mac-address = [ 00 00 00 00 00 00 ];
152 interrupts = <29 2>; 142 interrupts = <29 2>;
153 interrupt-parent = <&mpic>; 143 interrupt-parent = <&mpic>;
154 phy-handle = <&phy3>; 144 phy-handle = <&phy3>;
155 }; 145 };
156 146
157 serial@4500 { 147 serial0: serial@4500 {
148 cell-index = <0>;
158 device_type = "serial"; 149 device_type = "serial";
159 compatible = "ns16550"; 150 compatible = "ns16550";
160 reg = <4500 100>; // reg base, size 151 reg = <4500 100>; // reg base, size
@@ -163,7 +154,8 @@
163 interrupt-parent = <&mpic>; 154 interrupt-parent = <&mpic>;
164 }; 155 };
165 156
166 serial@4600 { 157 serial1: serial@4600 {
158 cell-index = <1>;
167 device_type = "serial"; 159 device_type = "serial";
168 compatible = "ns16550"; 160 compatible = "ns16550";
169 reg = <4600 100>; // reg base, size 161 reg = <4600 100>; // reg base, size
@@ -183,7 +175,8 @@
183 }; 175 };
184 }; 176 };
185 177
186 pci@e0008000 { 178 pci0: pci@e0008000 {
179 cell-index = <0>;
187 interrupt-map-mask = <f800 0 0 7>; 180 interrupt-map-mask = <f800 0 0 7>;
188 interrupt-map = < 181 interrupt-map = <
189 182
diff --git a/arch/powerpc/boot/dts/mpc8541cds.dts b/arch/powerpc/boot/dts/mpc8541cds.dts
index f3f4d79deb63..fa8d9aaad157 100644
--- a/arch/powerpc/boot/dts/mpc8541cds.dts
+++ b/arch/powerpc/boot/dts/mpc8541cds.dts
@@ -16,6 +16,15 @@
16 #address-cells = <1>; 16 #address-cells = <1>;
17 #size-cells = <1>; 17 #size-cells = <1>;
18 18
19 aliases {
20 ethernet0 = &enet0;
21 ethernet1 = &enet1;
22 serial0 = &serial0;
23 serial1 = &serial1;
24 pci0 = &pci0;
25 pci1 = &pci1;
26 };
27
19 cpus { 28 cpus {
20 #address-cells = <1>; 29 #address-cells = <1>;
21 #size-cells = <0>; 30 #size-cells = <0>;
@@ -63,7 +72,9 @@
63 }; 72 };
64 73
65 i2c@3000 { 74 i2c@3000 {
66 device_type = "i2c"; 75 #address-cells = <1>;
76 #size-cells = <0>;
77 cell-index = <0>;
67 compatible = "fsl-i2c"; 78 compatible = "fsl-i2c";
68 reg = <3000 100>; 79 reg = <3000 100>;
69 interrupts = <2b 2>; 80 interrupts = <2b 2>;
@@ -74,9 +85,9 @@
74 mdio@24520 { 85 mdio@24520 {
75 #address-cells = <1>; 86 #address-cells = <1>;
76 #size-cells = <0>; 87 #size-cells = <0>;
77 device_type = "mdio"; 88 compatible = "fsl,gianfar-mdio";
78 compatible = "gianfar";
79 reg = <24520 20>; 89 reg = <24520 20>;
90
80 phy0: ethernet-phy@0 { 91 phy0: ethernet-phy@0 {
81 interrupt-parent = <&mpic>; 92 interrupt-parent = <&mpic>;
82 interrupts = <5 1>; 93 interrupts = <5 1>;
@@ -91,9 +102,8 @@
91 }; 102 };
92 }; 103 };
93 104
94 ethernet@24000 { 105 enet0: ethernet@24000 {
95 #address-cells = <1>; 106 cell-index = <0>;
96 #size-cells = <0>;
97 device_type = "network"; 107 device_type = "network";
98 model = "TSEC"; 108 model = "TSEC";
99 compatible = "gianfar"; 109 compatible = "gianfar";
@@ -104,9 +114,8 @@
104 phy-handle = <&phy0>; 114 phy-handle = <&phy0>;
105 }; 115 };
106 116
107 ethernet@25000 { 117 enet1: ethernet@25000 {
108 #address-cells = <1>; 118 cell-index = <1>;
109 #size-cells = <0>;
110 device_type = "network"; 119 device_type = "network";
111 model = "TSEC"; 120 model = "TSEC";
112 compatible = "gianfar"; 121 compatible = "gianfar";
@@ -117,7 +126,8 @@
117 phy-handle = <&phy1>; 126 phy-handle = <&phy1>;
118 }; 127 };
119 128
120 serial@4500 { 129 serial0: serial@4500 {
130 cell-index = <0>;
121 device_type = "serial"; 131 device_type = "serial";
122 compatible = "ns16550"; 132 compatible = "ns16550";
123 reg = <4500 100>; // reg base, size 133 reg = <4500 100>; // reg base, size
@@ -126,7 +136,8 @@
126 interrupt-parent = <&mpic>; 136 interrupt-parent = <&mpic>;
127 }; 137 };
128 138
129 serial@4600 { 139 serial1: serial@4600 {
140 cell-index = <1>;
130 device_type = "serial"; 141 device_type = "serial";
131 compatible = "ns16550"; 142 compatible = "ns16550";
132 reg = <4600 100>; // reg base, size 143 reg = <4600 100>; // reg base, size
@@ -183,7 +194,8 @@
183 }; 194 };
184 }; 195 };
185 196
186 pci1: pci@e0008000 { 197 pci0: pci@e0008000 {
198 cell-index = <0>;
187 interrupt-map-mask = <1f800 0 0 7>; 199 interrupt-map-mask = <1f800 0 0 7>;
188 interrupt-map = < 200 interrupt-map = <
189 201
@@ -250,11 +262,12 @@
250 #interrupt-cells = <2>; 262 #interrupt-cells = <2>;
251 compatible = "chrp,iic"; 263 compatible = "chrp,iic";
252 interrupts = <1>; 264 interrupts = <1>;
253 interrupt-parent = <&pci1>; 265 interrupt-parent = <&pci0>;
254 }; 266 };
255 }; 267 };
256 268
257 pci@e0009000 { 269 pci1: pci@e0009000 {
270 cell-index = <1>;
258 interrupt-map-mask = <f800 0 0 7>; 271 interrupt-map-mask = <f800 0 0 7>;
259 interrupt-map = < 272 interrupt-map = <
260 273
diff --git a/arch/powerpc/boot/dts/mpc8544ds.dts b/arch/powerpc/boot/dts/mpc8544ds.dts
index 6c608de1fc1b..54b3bdf7fc97 100644
--- a/arch/powerpc/boot/dts/mpc8544ds.dts
+++ b/arch/powerpc/boot/dts/mpc8544ds.dts
@@ -15,6 +15,17 @@
15 #address-cells = <1>; 15 #address-cells = <1>;
16 #size-cells = <1>; 16 #size-cells = <1>;
17 17
18 aliases {
19 ethernet0 = &enet0;
20 ethernet1 = &enet1;
21 serial0 = &serial0;
22 serial1 = &serial1;
23 pci0 = &pci0;
24 pci1 = &pci1;
25 pci2 = &pci2;
26 pci3 = &pci3;
27 };
28
18 cpus { 29 cpus {
19 #cpus = <1>; 30 #cpus = <1>;
20 #address-cells = <1>; 31 #address-cells = <1>;
@@ -64,7 +75,9 @@
64 }; 75 };
65 76
66 i2c@3000 { 77 i2c@3000 {
67 device_type = "i2c"; 78 #address-cells = <1>;
79 #size-cells = <0>;
80 cell-index = <0>;
68 compatible = "fsl-i2c"; 81 compatible = "fsl-i2c";
69 reg = <3000 100>; 82 reg = <3000 100>;
70 interrupts = <2b 2>; 83 interrupts = <2b 2>;
@@ -72,12 +85,23 @@
72 dfsrr; 85 dfsrr;
73 }; 86 };
74 87
88 i2c@3100 {
89 #address-cells = <1>;
90 #size-cells = <0>;
91 cell-index = <1>;
92 compatible = "fsl-i2c";
93 reg = <3100 100>;
94 interrupts = <2b 2>;
95 interrupt-parent = <&mpic>;
96 dfsrr;
97 };
98
75 mdio@24520 { 99 mdio@24520 {
76 #address-cells = <1>; 100 #address-cells = <1>;
77 #size-cells = <0>; 101 #size-cells = <0>;
78 device_type = "mdio"; 102 compatible = "fsl,gianfar-mdio";
79 compatible = "gianfar";
80 reg = <24520 20>; 103 reg = <24520 20>;
104
81 phy0: ethernet-phy@0 { 105 phy0: ethernet-phy@0 {
82 interrupt-parent = <&mpic>; 106 interrupt-parent = <&mpic>;
83 interrupts = <a 1>; 107 interrupts = <a 1>;
@@ -92,9 +116,8 @@
92 }; 116 };
93 }; 117 };
94 118
95 ethernet@24000 { 119 enet0: ethernet@24000 {
96 #address-cells = <1>; 120 cell-index = <0>;
97 #size-cells = <0>;
98 device_type = "network"; 121 device_type = "network";
99 model = "TSEC"; 122 model = "TSEC";
100 compatible = "gianfar"; 123 compatible = "gianfar";
@@ -106,9 +129,8 @@
106 phy-connection-type = "rgmii-id"; 129 phy-connection-type = "rgmii-id";
107 }; 130 };
108 131
109 ethernet@26000 { 132 enet1: ethernet@26000 {
110 #address-cells = <1>; 133 cell-index = <1>;
111 #size-cells = <0>;
112 device_type = "network"; 134 device_type = "network";
113 model = "TSEC"; 135 model = "TSEC";
114 compatible = "gianfar"; 136 compatible = "gianfar";
@@ -120,7 +142,8 @@
120 phy-connection-type = "rgmii-id"; 142 phy-connection-type = "rgmii-id";
121 }; 143 };
122 144
123 serial@4500 { 145 serial0: serial@4500 {
146 cell-index = <0>;
124 device_type = "serial"; 147 device_type = "serial";
125 compatible = "ns16550"; 148 compatible = "ns16550";
126 reg = <4500 100>; 149 reg = <4500 100>;
@@ -129,7 +152,8 @@
129 interrupt-parent = <&mpic>; 152 interrupt-parent = <&mpic>;
130 }; 153 };
131 154
132 serial@4600 { 155 serial1: serial@4600 {
156 cell-index = <1>;
133 device_type = "serial"; 157 device_type = "serial";
134 compatible = "ns16550"; 158 compatible = "ns16550";
135 reg = <4600 100>; 159 reg = <4600 100>;
@@ -156,7 +180,8 @@
156 }; 180 };
157 }; 181 };
158 182
159 pci@e0008000 { 183 pci0: pci@e0008000 {
184 cell-index = <0>;
160 compatible = "fsl,mpc8540-pci"; 185 compatible = "fsl,mpc8540-pci";
161 device_type = "pci"; 186 device_type = "pci";
162 interrupt-map-mask = <f800 0 0 7>; 187 interrupt-map-mask = <f800 0 0 7>;
@@ -187,7 +212,8 @@
187 reg = <e0008000 1000>; 212 reg = <e0008000 1000>;
188 }; 213 };
189 214
190 pcie@e0009000 { 215 pci1: pcie@e0009000 {
216 cell-index = <1>;
191 compatible = "fsl,mpc8548-pcie"; 217 compatible = "fsl,mpc8548-pcie";
192 device_type = "pci"; 218 device_type = "pci";
193 #interrupt-cells = <1>; 219 #interrupt-cells = <1>;
@@ -223,7 +249,8 @@
223 }; 249 };
224 }; 250 };
225 251
226 pcie@e000a000 { 252 pci2: pcie@e000a000 {
253 cell-index = <2>;
227 compatible = "fsl,mpc8548-pcie"; 254 compatible = "fsl,mpc8548-pcie";
228 device_type = "pci"; 255 device_type = "pci";
229 #interrupt-cells = <1>; 256 #interrupt-cells = <1>;
@@ -259,7 +286,8 @@
259 }; 286 };
260 }; 287 };
261 288
262 pcie@e000b000 { 289 pci3: pcie@e000b000 {
290 cell-index = <3>;
263 compatible = "fsl,mpc8548-pcie"; 291 compatible = "fsl,mpc8548-pcie";
264 device_type = "pci"; 292 device_type = "pci";
265 #interrupt-cells = <1>; 293 #interrupt-cells = <1>;
@@ -369,6 +397,5 @@
369 }; 397 };
370 }; 398 };
371 }; 399 };
372
373 }; 400 };
374}; 401};
diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts
index 69ca5025d972..1f470c6a1c63 100644
--- a/arch/powerpc/boot/dts/mpc8548cds.dts
+++ b/arch/powerpc/boot/dts/mpc8548cds.dts
@@ -16,6 +16,20 @@
16 #address-cells = <1>; 16 #address-cells = <1>;
17 #size-cells = <1>; 17 #size-cells = <1>;
18 18
19 aliases {
20 ethernet0 = &enet0;
21 ethernet1 = &enet1;
22/*
23 ethernet2 = &enet2;
24 ethernet3 = &enet3;
25*/
26 serial0 = &serial0;
27 serial1 = &serial1;
28 pci0 = &pci0;
29 pci1 = &pci1;
30 pci2 = &pci2;
31 };
32
19 cpus { 33 cpus {
20 #address-cells = <1>; 34 #address-cells = <1>;
21 #size-cells = <0>; 35 #size-cells = <0>;
@@ -63,7 +77,9 @@
63 }; 77 };
64 78
65 i2c@3000 { 79 i2c@3000 {
66 device_type = "i2c"; 80 #address-cells = <1>;
81 #size-cells = <0>;
82 cell-index = <0>;
67 compatible = "fsl-i2c"; 83 compatible = "fsl-i2c";
68 reg = <3000 100>; 84 reg = <3000 100>;
69 interrupts = <2b 2>; 85 interrupts = <2b 2>;
@@ -71,12 +87,23 @@
71 dfsrr; 87 dfsrr;
72 }; 88 };
73 89
90 i2c@3100 {
91 #address-cells = <1>;
92 #size-cells = <0>;
93 cell-index = <1>;
94 compatible = "fsl-i2c";
95 reg = <3100 100>;
96 interrupts = <2b 2>;
97 interrupt-parent = <&mpic>;
98 dfsrr;
99 };
100
74 mdio@24520 { 101 mdio@24520 {
75 #address-cells = <1>; 102 #address-cells = <1>;
76 #size-cells = <0>; 103 #size-cells = <0>;
77 device_type = "mdio"; 104 compatible = "fsl,gianfar-mdio";
78 compatible = "gianfar";
79 reg = <24520 20>; 105 reg = <24520 20>;
106
80 phy0: ethernet-phy@0 { 107 phy0: ethernet-phy@0 {
81 interrupt-parent = <&mpic>; 108 interrupt-parent = <&mpic>;
82 interrupts = <5 1>; 109 interrupts = <5 1>;
@@ -103,9 +130,8 @@
103 }; 130 };
104 }; 131 };
105 132
106 ethernet@24000 { 133 enet0: ethernet@24000 {
107 #address-cells = <1>; 134 cell-index = <0>;
108 #size-cells = <0>;
109 device_type = "network"; 135 device_type = "network";
110 model = "eTSEC"; 136 model = "eTSEC";
111 compatible = "gianfar"; 137 compatible = "gianfar";
@@ -116,9 +142,8 @@
116 phy-handle = <&phy0>; 142 phy-handle = <&phy0>;
117 }; 143 };
118 144
119 ethernet@25000 { 145 enet1: ethernet@25000 {
120 #address-cells = <1>; 146 cell-index = <1>;
121 #size-cells = <0>;
122 device_type = "network"; 147 device_type = "network";
123 model = "eTSEC"; 148 model = "eTSEC";
124 compatible = "gianfar"; 149 compatible = "gianfar";
@@ -130,9 +155,8 @@
130 }; 155 };
131 156
132/* eTSEC 3/4 are currently broken 157/* eTSEC 3/4 are currently broken
133 ethernet@26000 { 158 enet2: ethernet@26000 {
134 #address-cells = <1>; 159 cell-index = <2>;
135 #size-cells = <0>;
136 device_type = "network"; 160 device_type = "network";
137 model = "eTSEC"; 161 model = "eTSEC";
138 compatible = "gianfar"; 162 compatible = "gianfar";
@@ -143,9 +167,8 @@
143 phy-handle = <&phy2>; 167 phy-handle = <&phy2>;
144 }; 168 };
145 169
146 ethernet@27000 { 170 enet3: ethernet@27000 {
147 #address-cells = <1>; 171 cell-index = <3>;
148 #size-cells = <0>;
149 device_type = "network"; 172 device_type = "network";
150 model = "eTSEC"; 173 model = "eTSEC";
151 compatible = "gianfar"; 174 compatible = "gianfar";
@@ -157,7 +180,8 @@
157 }; 180 };
158 */ 181 */
159 182
160 serial@4500 { 183 serial0: serial@4500 {
184 cell-index = <0>;
161 device_type = "serial"; 185 device_type = "serial";
162 compatible = "ns16550"; 186 compatible = "ns16550";
163 reg = <4500 100>; // reg base, size 187 reg = <4500 100>; // reg base, size
@@ -166,7 +190,8 @@
166 interrupt-parent = <&mpic>; 190 interrupt-parent = <&mpic>;
167 }; 191 };
168 192
169 serial@4600 { 193 serial1: serial@4600 {
194 cell-index = <1>;
170 device_type = "serial"; 195 device_type = "serial";
171 compatible = "ns16550"; 196 compatible = "ns16550";
172 reg = <4600 100>; // reg base, size 197 reg = <4600 100>; // reg base, size
@@ -193,7 +218,8 @@
193 }; 218 };
194 }; 219 };
195 220
196 pci@e0008000 { 221 pci0: pci@e0008000 {
222 cell-index = <0>;
197 interrupt-map-mask = <f800 0 0 7>; 223 interrupt-map-mask = <f800 0 0 7>;
198 interrupt-map = < 224 interrupt-map = <
199 /* IDSEL 0x4 (PCIX Slot 2) */ 225 /* IDSEL 0x4 (PCIX Slot 2) */
@@ -342,7 +368,8 @@
342 }; 368 };
343 }; 369 };
344 370
345 pci@e0009000 { 371 pci1: pci@e0009000 {
372 cell-index = <1>;
346 interrupt-map-mask = <f800 0 0 7>; 373 interrupt-map-mask = <f800 0 0 7>;
347 interrupt-map = < 374 interrupt-map = <
348 375
@@ -366,7 +393,8 @@
366 device_type = "pci"; 393 device_type = "pci";
367 }; 394 };
368 395
369 pcie@e000a000 { 396 pci2: pcie@e000a000 {
397 cell-index = <2>;
370 interrupt-map-mask = <f800 0 0 7>; 398 interrupt-map-mask = <f800 0 0 7>;
371 interrupt-map = < 399 interrupt-map = <
372 400
diff --git a/arch/powerpc/boot/dts/mpc8555cds.dts b/arch/powerpc/boot/dts/mpc8555cds.dts
index 57029cca32b2..4538f3c38862 100644
--- a/arch/powerpc/boot/dts/mpc8555cds.dts
+++ b/arch/powerpc/boot/dts/mpc8555cds.dts
@@ -16,6 +16,15 @@
16 #address-cells = <1>; 16 #address-cells = <1>;
17 #size-cells = <1>; 17 #size-cells = <1>;
18 18
19 aliases {
20 ethernet0 = &enet0;
21 ethernet1 = &enet1;
22 serial0 = &serial0;
23 serial1 = &serial1;
24 pci0 = &pci0;
25 pci1 = &pci1;
26 };
27
19 cpus { 28 cpus {
20 #address-cells = <1>; 29 #address-cells = <1>;
21 #size-cells = <0>; 30 #size-cells = <0>;
@@ -63,7 +72,9 @@
63 }; 72 };
64 73
65 i2c@3000 { 74 i2c@3000 {
66 device_type = "i2c"; 75 #address-cells = <1>;
76 #size-cells = <0>;
77 cell-index = <0>;
67 compatible = "fsl-i2c"; 78 compatible = "fsl-i2c";
68 reg = <3000 100>; 79 reg = <3000 100>;
69 interrupts = <2b 2>; 80 interrupts = <2b 2>;
@@ -74,9 +85,9 @@
74 mdio@24520 { 85 mdio@24520 {
75 #address-cells = <1>; 86 #address-cells = <1>;
76 #size-cells = <0>; 87 #size-cells = <0>;
77 device_type = "mdio"; 88 compatible = "fsl,gianfar-mdio";
78 compatible = "gianfar";
79 reg = <24520 20>; 89 reg = <24520 20>;
90
80 phy0: ethernet-phy@0 { 91 phy0: ethernet-phy@0 {
81 interrupt-parent = <&mpic>; 92 interrupt-parent = <&mpic>;
82 interrupts = <5 1>; 93 interrupts = <5 1>;
@@ -91,9 +102,8 @@
91 }; 102 };
92 }; 103 };
93 104
94 ethernet@24000 { 105 enet0: ethernet@24000 {
95 #address-cells = <1>; 106 cell-index = <0>;
96 #size-cells = <0>;
97 device_type = "network"; 107 device_type = "network";
98 model = "TSEC"; 108 model = "TSEC";
99 compatible = "gianfar"; 109 compatible = "gianfar";
@@ -104,9 +114,8 @@
104 phy-handle = <&phy0>; 114 phy-handle = <&phy0>;
105 }; 115 };
106 116
107 ethernet@25000 { 117 enet1: ethernet@25000 {
108 #address-cells = <1>; 118 cell-index = <1>;
109 #size-cells = <0>;
110 device_type = "network"; 119 device_type = "network";
111 model = "TSEC"; 120 model = "TSEC";
112 compatible = "gianfar"; 121 compatible = "gianfar";
@@ -117,7 +126,8 @@
117 phy-handle = <&phy1>; 126 phy-handle = <&phy1>;
118 }; 127 };
119 128
120 serial@4500 { 129 serial0: serial@4500 {
130 cell-index = <0>;
121 device_type = "serial"; 131 device_type = "serial";
122 compatible = "ns16550"; 132 compatible = "ns16550";
123 reg = <4500 100>; // reg base, size 133 reg = <4500 100>; // reg base, size
@@ -126,7 +136,8 @@
126 interrupt-parent = <&mpic>; 136 interrupt-parent = <&mpic>;
127 }; 137 };
128 138
129 serial@4600 { 139 serial1: serial@4600 {
140 cell-index = <1>;
130 device_type = "serial"; 141 device_type = "serial";
131 compatible = "ns16550"; 142 compatible = "ns16550";
132 reg = <4600 100>; // reg base, size 143 reg = <4600 100>; // reg base, size
@@ -183,7 +194,8 @@
183 }; 194 };
184 }; 195 };
185 196
186 pci1: pci@e0008000 { 197 pci0: pci@e0008000 {
198 cell-index = <0>;
187 interrupt-map-mask = <1f800 0 0 7>; 199 interrupt-map-mask = <1f800 0 0 7>;
188 interrupt-map = < 200 interrupt-map = <
189 201
@@ -250,11 +262,12 @@
250 #interrupt-cells = <2>; 262 #interrupt-cells = <2>;
251 compatible = "chrp,iic"; 263 compatible = "chrp,iic";
252 interrupts = <1>; 264 interrupts = <1>;
253 interrupt-parent = <&pci1>; 265 interrupt-parent = <&pci0>;
254 }; 266 };
255 }; 267 };
256 268
257 pci@e0009000 { 269 pci1: pci@e0009000 {
270 cell-index = <1>;
258 interrupt-map-mask = <f800 0 0 7>; 271 interrupt-map-mask = <f800 0 0 7>;
259 interrupt-map = < 272 interrupt-map = <
260 273
diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/boot/dts/mpc8560ads.dts
index 6b362f8222c1..639ce8a709a6 100644
--- a/arch/powerpc/boot/dts/mpc8560ads.dts
+++ b/arch/powerpc/boot/dts/mpc8560ads.dts
@@ -16,6 +16,16 @@
16 #address-cells = <1>; 16 #address-cells = <1>;
17 #size-cells = <1>; 17 #size-cells = <1>;
18 18
19 aliases {
20 ethernet0 = &enet0;
21 ethernet1 = &enet1;
22 ethernet2 = &enet2;
23 ethernet3 = &enet3;
24 serial0 = &serial0;
25 serial1 = &serial1;
26 pci0 = &pci0;
27 };
28
19 cpus { 29 cpus {
20 #address-cells = <1>; 30 #address-cells = <1>;
21 #size-cells = <0>; 31 #size-cells = <0>;
@@ -63,11 +73,11 @@
63 }; 73 };
64 74
65 mdio@24520 { 75 mdio@24520 {
66 device_type = "mdio";
67 compatible = "gianfar";
68 reg = <24520 20>;
69 #address-cells = <1>; 76 #address-cells = <1>;
70 #size-cells = <0>; 77 #size-cells = <0>;
78 compatible = "fsl,gianfar-mdio";
79 reg = <24520 20>;
80
71 phy0: ethernet-phy@0 { 81 phy0: ethernet-phy@0 {
72 interrupt-parent = <&mpic>; 82 interrupt-parent = <&mpic>;
73 interrupts = <5 1>; 83 interrupts = <5 1>;
@@ -94,36 +104,24 @@
94 }; 104 };
95 }; 105 };
96 106
97 ethernet@24000 { 107 enet0: ethernet@24000 {
108 cell-index = <0>;
98 device_type = "network"; 109 device_type = "network";
99 model = "TSEC"; 110 model = "TSEC";
100 compatible = "gianfar"; 111 compatible = "gianfar";
101 reg = <24000 1000>; 112 reg = <24000 1000>;
102 /*
103 * address is deprecated and will be removed
104 * in 2.6.25. Only recent versions of
105 * U-Boot support local-mac-address, however.
106 */
107 address = [ 00 00 00 00 00 00 ];
108 local-mac-address = [ 00 00 00 00 00 00 ]; 113 local-mac-address = [ 00 00 00 00 00 00 ];
109 interrupts = <1d 2 1e 2 22 2>; 114 interrupts = <1d 2 1e 2 22 2>;
110 interrupt-parent = <&mpic>; 115 interrupt-parent = <&mpic>;
111 phy-handle = <&phy0>; 116 phy-handle = <&phy0>;
112 }; 117 };
113 118
114 ethernet@25000 { 119 enet1: ethernet@25000 {
115 #address-cells = <1>; 120 cell-index = <1>;
116 #size-cells = <0>;
117 device_type = "network"; 121 device_type = "network";
118 model = "TSEC"; 122 model = "TSEC";
119 compatible = "gianfar"; 123 compatible = "gianfar";
120 reg = <25000 1000>; 124 reg = <25000 1000>;
121 /*
122 * address is deprecated and will be removed
123 * in 2.6.25. Only recent versions of
124 * U-Boot support local-mac-address, however.
125 */
126 address = [ 00 00 00 00 00 00 ];
127 local-mac-address = [ 00 00 00 00 00 00 ]; 125 local-mac-address = [ 00 00 00 00 00 00 ];
128 interrupts = <23 2 24 2 28 2>; 126 interrupts = <23 2 24 2 28 2>;
129 interrupt-parent = <&mpic>; 127 interrupt-parent = <&mpic>;
@@ -174,7 +172,7 @@
174 compatible = "fsl,mpc8560-cpm-pic", "fsl,cpm2-pic"; 172 compatible = "fsl,mpc8560-cpm-pic", "fsl,cpm2-pic";
175 }; 173 };
176 174
177 serial@91a00 { 175 serial0: serial@91a00 {
178 device_type = "serial"; 176 device_type = "serial";
179 compatible = "fsl,mpc8560-scc-uart", 177 compatible = "fsl,mpc8560-scc-uart",
180 "fsl,cpm2-scc-uart"; 178 "fsl,cpm2-scc-uart";
@@ -186,7 +184,7 @@
186 interrupt-parent = <&cpmpic>; 184 interrupt-parent = <&cpmpic>;
187 }; 185 };
188 186
189 serial@91a20 { 187 serial1: serial@91a20 {
190 device_type = "serial"; 188 device_type = "serial";
191 compatible = "fsl,mpc8560-scc-uart", 189 compatible = "fsl,mpc8560-scc-uart",
192 "fsl,cpm2-scc-uart"; 190 "fsl,cpm2-scc-uart";
@@ -198,17 +196,11 @@
198 interrupt-parent = <&cpmpic>; 196 interrupt-parent = <&cpmpic>;
199 }; 197 };
200 198
201 ethernet@91320 { 199 enet2: ethernet@91320 {
202 device_type = "network"; 200 device_type = "network";
203 compatible = "fsl,mpc8560-fcc-enet", 201 compatible = "fsl,mpc8560-fcc-enet",
204 "fsl,cpm2-fcc-enet"; 202 "fsl,cpm2-fcc-enet";
205 reg = <91320 20 88500 100 913b0 1>; 203 reg = <91320 20 88500 100 913b0 1>;
206 /*
207 * mac-address is deprecated and will be removed
208 * in 2.6.25. Only recent versions of
209 * U-Boot support local-mac-address, however.
210 */
211 mac-address = [ 00 00 00 00 00 00 ];
212 local-mac-address = [ 00 00 00 00 00 00 ]; 204 local-mac-address = [ 00 00 00 00 00 00 ];
213 fsl,cpm-command = <16200300>; 205 fsl,cpm-command = <16200300>;
214 interrupts = <21 8>; 206 interrupts = <21 8>;
@@ -216,17 +208,11 @@
216 phy-handle = <&phy2>; 208 phy-handle = <&phy2>;
217 }; 209 };
218 210
219 ethernet@91340 { 211 enet3: ethernet@91340 {
220 device_type = "network"; 212 device_type = "network";
221 compatible = "fsl,mpc8560-fcc-enet", 213 compatible = "fsl,mpc8560-fcc-enet",
222 "fsl,cpm2-fcc-enet"; 214 "fsl,cpm2-fcc-enet";
223 reg = <91340 20 88600 100 913d0 1>; 215 reg = <91340 20 88600 100 913d0 1>;
224 /*
225 * mac-address is deprecated and will be removed
226 * in 2.6.25. Only recent versions of
227 * U-Boot support local-mac-address, however.
228 */
229 mac-address = [ 00 00 00 00 00 00 ];
230 local-mac-address = [ 00 00 00 00 00 00 ]; 216 local-mac-address = [ 00 00 00 00 00 00 ];
231 fsl,cpm-command = <1a400300>; 217 fsl,cpm-command = <1a400300>;
232 interrupts = <22 8>; 218 interrupts = <22 8>;
@@ -236,7 +222,8 @@
236 }; 222 };
237 }; 223 };
238 224
239 pci@e0008000 { 225 pci0: pci@e0008000 {
226 cell-index = <0>;
240 #interrupt-cells = <1>; 227 #interrupt-cells = <1>;
241 #size-cells = <2>; 228 #size-cells = <2>;
242 #address-cells = <3>; 229 #address-cells = <3>;
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index 54394372b12a..5818a7c861e7 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -20,6 +20,17 @@
20 #address-cells = <1>; 20 #address-cells = <1>;
21 #size-cells = <1>; 21 #size-cells = <1>;
22 22
23 aliases {
24 ethernet0 = &enet0;
25 ethernet1 = &enet1;
26 ethernet2 = &enet2;
27 ethernet3 = &enet3;
28 serial0 = &serial0;
29 serial1 = &serial1;
30 pci0 = &pci0;
31 pci1 = &pci1;
32 };
33
23 cpus { 34 cpus {
24 #address-cells = <1>; 35 #address-cells = <1>;
25 #size-cells = <0>; 36 #size-cells = <0>;
@@ -74,7 +85,7 @@
74 i2c@3000 { 85 i2c@3000 {
75 #address-cells = <1>; 86 #address-cells = <1>;
76 #size-cells = <0>; 87 #size-cells = <0>;
77 device_type = "i2c"; 88 cell-index = <0>;
78 compatible = "fsl-i2c"; 89 compatible = "fsl-i2c";
79 reg = <3000 100>; 90 reg = <3000 100>;
80 interrupts = <2b 2>; 91 interrupts = <2b 2>;
@@ -90,7 +101,7 @@
90 i2c@3100 { 101 i2c@3100 {
91 #address-cells = <1>; 102 #address-cells = <1>;
92 #size-cells = <0>; 103 #size-cells = <0>;
93 device_type = "i2c"; 104 cell-index = <1>;
94 compatible = "fsl-i2c"; 105 compatible = "fsl-i2c";
95 reg = <3100 100>; 106 reg = <3100 100>;
96 interrupts = <2b 2>; 107 interrupts = <2b 2>;
@@ -101,9 +112,9 @@
101 mdio@24520 { 112 mdio@24520 {
102 #address-cells = <1>; 113 #address-cells = <1>;
103 #size-cells = <0>; 114 #size-cells = <0>;
104 device_type = "mdio"; 115 compatible = "fsl,gianfar-mdio";
105 compatible = "gianfar";
106 reg = <24520 20>; 116 reg = <24520 20>;
117
107 phy0: ethernet-phy@7 { 118 phy0: ethernet-phy@7 {
108 interrupt-parent = <&mpic>; 119 interrupt-parent = <&mpic>;
109 interrupts = <1 1>; 120 interrupts = <1 1>;
@@ -130,45 +141,32 @@
130 }; 141 };
131 }; 142 };
132 143
133 ethernet@24000 { 144 enet0: ethernet@24000 {
134 #address-cells = <1>; 145 cell-index = <0>;
135 #size-cells = <0>;
136 device_type = "network"; 146 device_type = "network";
137 model = "eTSEC"; 147 model = "eTSEC";
138 compatible = "gianfar"; 148 compatible = "gianfar";
139 reg = <24000 1000>; 149 reg = <24000 1000>;
140 /*
141 * mac-address is deprecated and will be removed
142 * in 2.6.25. Only recent versions of
143 * U-Boot support local-mac-address, however.
144 */
145 mac-address = [ 00 00 00 00 00 00 ];
146 local-mac-address = [ 00 00 00 00 00 00 ]; 150 local-mac-address = [ 00 00 00 00 00 00 ];
147 interrupts = <1d 2 1e 2 22 2>; 151 interrupts = <1d 2 1e 2 22 2>;
148 interrupt-parent = <&mpic>; 152 interrupt-parent = <&mpic>;
149 phy-handle = <&phy2>; 153 phy-handle = <&phy2>;
150 }; 154 };
151 155
152 ethernet@25000 { 156 enet1: ethernet@25000 {
153 #address-cells = <1>; 157 cell-index = <1>;
154 #size-cells = <0>;
155 device_type = "network"; 158 device_type = "network";
156 model = "eTSEC"; 159 model = "eTSEC";
157 compatible = "gianfar"; 160 compatible = "gianfar";
158 reg = <25000 1000>; 161 reg = <25000 1000>;
159 /*
160 * mac-address is deprecated and will be removed
161 * in 2.6.25. Only recent versions of
162 * U-Boot support local-mac-address, however.
163 */
164 mac-address = [ 00 00 00 00 00 00 ];
165 local-mac-address = [ 00 00 00 00 00 00 ]; 162 local-mac-address = [ 00 00 00 00 00 00 ];
166 interrupts = <23 2 24 2 28 2>; 163 interrupts = <23 2 24 2 28 2>;
167 interrupt-parent = <&mpic>; 164 interrupt-parent = <&mpic>;
168 phy-handle = <&phy3>; 165 phy-handle = <&phy3>;
169 }; 166 };
170 167
171 serial@4500 { 168 serial0: serial@4500 {
169 cell-index = <0>;
172 device_type = "serial"; 170 device_type = "serial";
173 compatible = "ns16550"; 171 compatible = "ns16550";
174 reg = <4500 100>; 172 reg = <4500 100>;
@@ -183,7 +181,8 @@
183 fsl,has-rstcr; 181 fsl,has-rstcr;
184 }; 182 };
185 183
186 serial@4600 { 184 serial1: serial@4600 {
185 cell-index = <1>;
187 device_type = "serial"; 186 device_type = "serial";
188 compatible = "ns16550"; 187 compatible = "ns16550";
189 reg = <4600 100>; 188 reg = <4600 100>;
@@ -318,45 +317,35 @@
318 mode = "cpu"; 317 mode = "cpu";
319 }; 318 };
320 319
321 ucc@2000 { 320 enet2: ucc@2000 {
322 device_type = "network"; 321 device_type = "network";
323 compatible = "ucc_geth"; 322 compatible = "ucc_geth";
324 model = "UCC"; 323 model = "UCC";
324 cell-index = <1>;
325 device-id = <1>; 325 device-id = <1>;
326 reg = <2000 200>; 326 reg = <2000 200>;
327 interrupts = <20>; 327 interrupts = <20>;
328 interrupt-parent = <&qeic>; 328 interrupt-parent = <&qeic>;
329 /*
330 * mac-address is deprecated and will be removed
331 * in 2.6.25. Only recent versions of
332 * U-Boot support local-mac-address, however.
333 */
334 mac-address = [ 00 00 00 00 00 00 ];
335 local-mac-address = [ 00 00 00 00 00 00 ]; 329 local-mac-address = [ 00 00 00 00 00 00 ];
336 rx-clock = <0>; 330 rx-clock-name = "none";
337 tx-clock = <20>; 331 tx-clock-name = "clk16";
338 pio-handle = <&pio1>; 332 pio-handle = <&pio1>;
339 phy-handle = <&phy0>; 333 phy-handle = <&phy0>;
340 phy-connection-type = "rgmii-id"; 334 phy-connection-type = "rgmii-id";
341 }; 335 };
342 336
343 ucc@3000 { 337 enet3: ucc@3000 {
344 device_type = "network"; 338 device_type = "network";
345 compatible = "ucc_geth"; 339 compatible = "ucc_geth";
346 model = "UCC"; 340 model = "UCC";
341 cell-index = <2>;
347 device-id = <2>; 342 device-id = <2>;
348 reg = <3000 200>; 343 reg = <3000 200>;
349 interrupts = <21>; 344 interrupts = <21>;
350 interrupt-parent = <&qeic>; 345 interrupt-parent = <&qeic>;
351 /*
352 * mac-address is deprecated and will be removed
353 * in 2.6.25. Only recent versions of
354 * U-Boot support local-mac-address, however.
355 */
356 mac-address = [ 00 00 00 00 00 00 ];
357 local-mac-address = [ 00 00 00 00 00 00 ]; 346 local-mac-address = [ 00 00 00 00 00 00 ];
358 rx-clock = <0>; 347 rx-clock-name = "none";
359 tx-clock = <20>; 348 tx-clock-name = "clk16";
360 pio-handle = <&pio2>; 349 pio-handle = <&pio2>;
361 phy-handle = <&phy1>; 350 phy-handle = <&phy1>;
362 phy-connection-type = "rgmii-id"; 351 phy-connection-type = "rgmii-id";
@@ -366,7 +355,6 @@
366 #address-cells = <1>; 355 #address-cells = <1>;
367 #size-cells = <0>; 356 #size-cells = <0>;
368 reg = <2120 18>; 357 reg = <2120 18>;
369 device_type = "mdio";
370 compatible = "ucc_geth_phy"; 358 compatible = "ucc_geth_phy";
371 359
372 /* These are the same PHYs as on 360 /* These are the same PHYs as on
@@ -410,7 +398,8 @@
410 398
411 }; 399 };
412 400
413 pci@e0008000 { 401 pci0: pci@e0008000 {
402 cell-index = <0>;
414 interrupt-map-mask = <f800 0 0 7>; 403 interrupt-map-mask = <f800 0 0 7>;
415 interrupt-map = < 404 interrupt-map = <
416 /* IDSEL 0x12 AD18 */ 405 /* IDSEL 0x12 AD18 */
@@ -440,7 +429,8 @@
440 }; 429 };
441 430
442 /* PCI Express */ 431 /* PCI Express */
443 pcie@e000a000 { 432 pci1: pcie@e000a000 {
433 cell-index = <2>;
444 interrupt-map-mask = <f800 0 0 7>; 434 interrupt-map-mask = <f800 0 0 7>;
445 interrupt-map = < 435 interrupt-map = <
446 436
diff --git a/arch/powerpc/boot/dts/mpc8572ds.dts b/arch/powerpc/boot/dts/mpc8572ds.dts
index 0eb44fb9647d..233e0d5a8b9d 100644
--- a/arch/powerpc/boot/dts/mpc8572ds.dts
+++ b/arch/powerpc/boot/dts/mpc8572ds.dts
@@ -15,6 +15,18 @@
15 #address-cells = <1>; 15 #address-cells = <1>;
16 #size-cells = <1>; 16 #size-cells = <1>;
17 17
18 aliases {
19 ethernet0 = &enet0;
20 ethernet1 = &enet1;
21 ethernet2 = &enet2;
22 ethernet3 = &enet3;
23 serial0 = &serial0;
24 serial1 = &serial1;
25 pci0 = &pci0;
26 pci1 = &pci1;
27 pci2 = &pci2;
28 };
29
18 cpus { 30 cpus {
19 #address-cells = <1>; 31 #address-cells = <1>;
20 #size-cells = <0>; 32 #size-cells = <0>;
@@ -69,7 +81,9 @@
69 }; 81 };
70 82
71 i2c@3000 { 83 i2c@3000 {
72 device_type = "i2c"; 84 #address-cells = <1>;
85 #size-cells = <0>;
86 cell-index = <0>;
73 compatible = "fsl-i2c"; 87 compatible = "fsl-i2c";
74 reg = <3000 100>; 88 reg = <3000 100>;
75 interrupts = <2b 2>; 89 interrupts = <2b 2>;
@@ -78,7 +92,9 @@
78 }; 92 };
79 93
80 i2c@3100 { 94 i2c@3100 {
81 device_type = "i2c"; 95 #address-cells = <1>;
96 #size-cells = <0>;
97 cell-index = <1>;
82 compatible = "fsl-i2c"; 98 compatible = "fsl-i2c";
83 reg = <3100 100>; 99 reg = <3100 100>;
84 interrupts = <2b 2>; 100 interrupts = <2b 2>;
@@ -89,9 +105,9 @@
89 mdio@24520 { 105 mdio@24520 {
90 #address-cells = <1>; 106 #address-cells = <1>;
91 #size-cells = <0>; 107 #size-cells = <0>;
92 device_type = "mdio"; 108 compatible = "fsl,gianfar-mdio";
93 compatible = "gianfar";
94 reg = <24520 20>; 109 reg = <24520 20>;
110
95 phy0: ethernet-phy@0 { 111 phy0: ethernet-phy@0 {
96 interrupt-parent = <&mpic>; 112 interrupt-parent = <&mpic>;
97 interrupts = <a 1>; 113 interrupts = <a 1>;
@@ -114,9 +130,8 @@
114 }; 130 };
115 }; 131 };
116 132
117 ethernet@24000 { 133 enet0: ethernet@24000 {
118 #address-cells = <1>; 134 cell-index = <0>;
119 #size-cells = <0>;
120 device_type = "network"; 135 device_type = "network";
121 model = "eTSEC"; 136 model = "eTSEC";
122 compatible = "gianfar"; 137 compatible = "gianfar";
@@ -128,9 +143,8 @@
128 phy-connection-type = "rgmii-id"; 143 phy-connection-type = "rgmii-id";
129 }; 144 };
130 145
131 ethernet@25000 { 146 enet1: ethernet@25000 {
132 #address-cells = <1>; 147 cell-index = <1>;
133 #size-cells = <0>;
134 device_type = "network"; 148 device_type = "network";
135 model = "eTSEC"; 149 model = "eTSEC";
136 compatible = "gianfar"; 150 compatible = "gianfar";
@@ -142,9 +156,8 @@
142 phy-connection-type = "rgmii-id"; 156 phy-connection-type = "rgmii-id";
143 }; 157 };
144 158
145 ethernet@26000 { 159 enet2: ethernet@26000 {
146 #address-cells = <1>; 160 cell-index = <2>;
147 #size-cells = <0>;
148 device_type = "network"; 161 device_type = "network";
149 model = "eTSEC"; 162 model = "eTSEC";
150 compatible = "gianfar"; 163 compatible = "gianfar";
@@ -156,9 +169,8 @@
156 phy-connection-type = "rgmii-id"; 169 phy-connection-type = "rgmii-id";
157 }; 170 };
158 171
159 ethernet@27000 { 172 enet3: ethernet@27000 {
160 #address-cells = <1>; 173 cell-index = <3>;
161 #size-cells = <0>;
162 device_type = "network"; 174 device_type = "network";
163 model = "eTSEC"; 175 model = "eTSEC";
164 compatible = "gianfar"; 176 compatible = "gianfar";
@@ -170,7 +182,8 @@
170 phy-connection-type = "rgmii-id"; 182 phy-connection-type = "rgmii-id";
171 }; 183 };
172 184
173 serial@4500 { 185 serial0: serial@4500 {
186 cell-index = <0>;
174 device_type = "serial"; 187 device_type = "serial";
175 compatible = "ns16550"; 188 compatible = "ns16550";
176 reg = <4500 100>; 189 reg = <4500 100>;
@@ -179,7 +192,8 @@
179 interrupt-parent = <&mpic>; 192 interrupt-parent = <&mpic>;
180 }; 193 };
181 194
182 serial@4600 { 195 serial1: serial@4600 {
196 cell-index = <1>;
183 device_type = "serial"; 197 device_type = "serial";
184 compatible = "ns16550"; 198 compatible = "ns16550";
185 reg = <4600 100>; 199 reg = <4600 100>;
@@ -206,7 +220,8 @@
206 }; 220 };
207 }; 221 };
208 222
209 pcie@ffe08000 { 223 pci0: pcie@ffe08000 {
224 cell-index = <0>;
210 compatible = "fsl,mpc8548-pcie"; 225 compatible = "fsl,mpc8548-pcie";
211 device_type = "pci"; 226 device_type = "pci";
212 #interrupt-cells = <1>; 227 #interrupt-cells = <1>;
@@ -415,7 +430,8 @@
415 430
416 }; 431 };
417 432
418 pcie@ffe09000 { 433 pci1: pcie@ffe09000 {
434 cell-index = <1>;
419 compatible = "fsl,mpc8548-pcie"; 435 compatible = "fsl,mpc8548-pcie";
420 device_type = "pci"; 436 device_type = "pci";
421 #interrupt-cells = <1>; 437 #interrupt-cells = <1>;
@@ -451,7 +467,8 @@
451 }; 467 };
452 }; 468 };
453 469
454 pcie@ffe0a000 { 470 pci2: pcie@ffe0a000 {
471 cell-index = <2>;
455 compatible = "fsl,mpc8548-pcie"; 472 compatible = "fsl,mpc8548-pcie";
456 device_type = "pci"; 473 device_type = "pci";
457 #interrupt-cells = <1>; 474 #interrupt-cells = <1>;
diff --git a/arch/powerpc/boot/dts/mpc8610_hpcd.dts b/arch/powerpc/boot/dts/mpc8610_hpcd.dts
index 966edf1161a6..01040a752c82 100644
--- a/arch/powerpc/boot/dts/mpc8610_hpcd.dts
+++ b/arch/powerpc/boot/dts/mpc8610_hpcd.dts
@@ -15,6 +15,13 @@
15 #address-cells = <1>; 15 #address-cells = <1>;
16 #size-cells = <1>; 16 #size-cells = <1>;
17 17
18 aliases {
19 serial0 = &serial0;
20 serial1 = &serial1;
21 pci0 = &pci0;
22 pci1 = &pci1;
23 };
24
18 cpus { 25 cpus {
19 #address-cells = <1>; 26 #address-cells = <1>;
20 #size-cells = <0>; 27 #size-cells = <0>;
@@ -47,10 +54,10 @@
47 bus-frequency = <0>; 54 bus-frequency = <0>;
48 55
49 i2c@3000 { 56 i2c@3000 {
50 device_type = "i2c";
51 compatible = "fsl-i2c";
52 #address-cells = <1>; 57 #address-cells = <1>;
53 #size-cells = <0>; 58 #size-cells = <0>;
59 cell-index = <0>;
60 compatible = "fsl-i2c";
54 reg = <3000 100>; 61 reg = <3000 100>;
55 interrupts = <2b 2>; 62 interrupts = <2b 2>;
56 interrupt-parent = <&mpic>; 63 interrupt-parent = <&mpic>;
@@ -58,17 +65,18 @@
58 }; 65 };
59 66
60 i2c@3100 { 67 i2c@3100 {
61 device_type = "i2c";
62 compatible = "fsl-i2c";
63 #address-cells = <1>; 68 #address-cells = <1>;
64 #size-cells = <0>; 69 #size-cells = <0>;
70 cell-index = <1>;
71 compatible = "fsl-i2c";
65 reg = <3100 100>; 72 reg = <3100 100>;
66 interrupts = <2b 2>; 73 interrupts = <2b 2>;
67 interrupt-parent = <&mpic>; 74 interrupt-parent = <&mpic>;
68 dfsrr; 75 dfsrr;
69 }; 76 };
70 77
71 serial@4500 { 78 serial0: serial@4500 {
79 cell-index = <0>;
72 device_type = "serial"; 80 device_type = "serial";
73 compatible = "ns16550"; 81 compatible = "ns16550";
74 reg = <4500 100>; 82 reg = <4500 100>;
@@ -77,7 +85,8 @@
77 interrupt-parent = <&mpic>; 85 interrupt-parent = <&mpic>;
78 }; 86 };
79 87
80 serial@4600 { 88 serial1: serial@4600 {
89 cell-index = <1>;
81 device_type = "serial"; 90 device_type = "serial";
82 compatible = "ns16550"; 91 compatible = "ns16550";
83 reg = <4600 100>; 92 reg = <4600 100>;
@@ -86,7 +95,6 @@
86 interrupt-parent = <&mpic>; 95 interrupt-parent = <&mpic>;
87 }; 96 };
88 97
89
90 mpic: interrupt-controller@40000 { 98 mpic: interrupt-controller@40000 {
91 clock-frequency = <0>; 99 clock-frequency = <0>;
92 interrupt-controller; 100 interrupt-controller;
@@ -105,7 +113,8 @@
105 }; 113 };
106 }; 114 };
107 115
108 pci@e0008000 { 116 pci0: pci@e0008000 {
117 cell-index = <0>;
109 compatible = "fsl,mpc8610-pci"; 118 compatible = "fsl,mpc8610-pci";
110 device_type = "pci"; 119 device_type = "pci";
111 #interrupt-cells = <1>; 120 #interrupt-cells = <1>;
@@ -134,7 +143,8 @@
134 >; 143 >;
135 }; 144 };
136 145
137 pcie@e000a000 { 146 pci1: pcie@e000a000 {
147 cell-index = <1>;
138 compatible = "fsl,mpc8641-pcie"; 148 compatible = "fsl,mpc8641-pcie";
139 device_type = "pci"; 149 device_type = "pci";
140 #interrupt-cells = <1>; 150 #interrupt-cells = <1>;
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index abb26dc42558..86fc2280c16d 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -16,6 +16,17 @@
16 #address-cells = <1>; 16 #address-cells = <1>;
17 #size-cells = <1>; 17 #size-cells = <1>;
18 18
19 aliases {
20 ethernet0 = &enet0;
21 ethernet1 = &enet1;
22 ethernet2 = &enet2;
23 ethernet3 = &enet3;
24 serial0 = &serial0;
25 serial1 = &serial1;
26 pci0 = &pci0;
27 pci1 = &pci1;
28 };
29
19 cpus { 30 cpus {
20 #address-cells = <1>; 31 #address-cells = <1>;
21 #size-cells = <0>; 32 #size-cells = <0>;
@@ -58,7 +69,9 @@
58 bus-frequency = <0>; 69 bus-frequency = <0>;
59 70
60 i2c@3000 { 71 i2c@3000 {
61 device_type = "i2c"; 72 #address-cells = <1>;
73 #size-cells = <0>;
74 cell-index = <0>;
62 compatible = "fsl-i2c"; 75 compatible = "fsl-i2c";
63 reg = <3000 100>; 76 reg = <3000 100>;
64 interrupts = <2b 2>; 77 interrupts = <2b 2>;
@@ -67,7 +80,9 @@
67 }; 80 };
68 81
69 i2c@3100 { 82 i2c@3100 {
70 device_type = "i2c"; 83 #address-cells = <1>;
84 #size-cells = <0>;
85 cell-index = <1>;
71 compatible = "fsl-i2c"; 86 compatible = "fsl-i2c";
72 reg = <3100 100>; 87 reg = <3100 100>;
73 interrupts = <2b 2>; 88 interrupts = <2b 2>;
@@ -78,9 +93,9 @@
78 mdio@24520 { 93 mdio@24520 {
79 #address-cells = <1>; 94 #address-cells = <1>;
80 #size-cells = <0>; 95 #size-cells = <0>;
81 device_type = "mdio"; 96 compatible = "fsl,gianfar-mdio";
82 compatible = "gianfar";
83 reg = <24520 20>; 97 reg = <24520 20>;
98
84 phy0: ethernet-phy@0 { 99 phy0: ethernet-phy@0 {
85 interrupt-parent = <&mpic>; 100 interrupt-parent = <&mpic>;
86 interrupts = <a 1>; 101 interrupts = <a 1>;
@@ -107,19 +122,12 @@
107 }; 122 };
108 }; 123 };
109 124
110 ethernet@24000 { 125 enet0: ethernet@24000 {
111 #address-cells = <1>; 126 cell-index = <0>;
112 #size-cells = <0>;
113 device_type = "network"; 127 device_type = "network";
114 model = "TSEC"; 128 model = "TSEC";
115 compatible = "gianfar"; 129 compatible = "gianfar";
116 reg = <24000 1000>; 130 reg = <24000 1000>;
117 /*
118 * mac-address is deprecated and will be removed
119 * in 2.6.25. Only recent versions of
120 * U-Boot support local-mac-address, however.
121 */
122 mac-address = [ 00 00 00 00 00 00 ];
123 local-mac-address = [ 00 00 00 00 00 00 ]; 131 local-mac-address = [ 00 00 00 00 00 00 ];
124 interrupts = <1d 2 1e 2 22 2>; 132 interrupts = <1d 2 1e 2 22 2>;
125 interrupt-parent = <&mpic>; 133 interrupt-parent = <&mpic>;
@@ -127,19 +135,12 @@
127 phy-connection-type = "rgmii-id"; 135 phy-connection-type = "rgmii-id";
128 }; 136 };
129 137
130 ethernet@25000 { 138 enet1: ethernet@25000 {
131 #address-cells = <1>; 139 cell-index = <1>;
132 #size-cells = <0>;
133 device_type = "network"; 140 device_type = "network";
134 model = "TSEC"; 141 model = "TSEC";
135 compatible = "gianfar"; 142 compatible = "gianfar";
136 reg = <25000 1000>; 143 reg = <25000 1000>;
137 /*
138 * mac-address is deprecated and will be removed
139 * in 2.6.25. Only recent versions of
140 * U-Boot support local-mac-address, however.
141 */
142 mac-address = [ 00 00 00 00 00 00 ];
143 local-mac-address = [ 00 00 00 00 00 00 ]; 144 local-mac-address = [ 00 00 00 00 00 00 ];
144 interrupts = <23 2 24 2 28 2>; 145 interrupts = <23 2 24 2 28 2>;
145 interrupt-parent = <&mpic>; 146 interrupt-parent = <&mpic>;
@@ -147,19 +148,12 @@
147 phy-connection-type = "rgmii-id"; 148 phy-connection-type = "rgmii-id";
148 }; 149 };
149 150
150 ethernet@26000 { 151 enet2: ethernet@26000 {
151 #address-cells = <1>; 152 cell-index = <2>;
152 #size-cells = <0>;
153 device_type = "network"; 153 device_type = "network";
154 model = "TSEC"; 154 model = "TSEC";
155 compatible = "gianfar"; 155 compatible = "gianfar";
156 reg = <26000 1000>; 156 reg = <26000 1000>;
157 /*
158 * mac-address is deprecated and will be removed
159 * in 2.6.25. Only recent versions of
160 * U-Boot support local-mac-address, however.
161 */
162 mac-address = [ 00 00 00 00 00 00 ];
163 local-mac-address = [ 00 00 00 00 00 00 ]; 157 local-mac-address = [ 00 00 00 00 00 00 ];
164 interrupts = <1F 2 20 2 21 2>; 158 interrupts = <1F 2 20 2 21 2>;
165 interrupt-parent = <&mpic>; 159 interrupt-parent = <&mpic>;
@@ -167,26 +161,21 @@
167 phy-connection-type = "rgmii-id"; 161 phy-connection-type = "rgmii-id";
168 }; 162 };
169 163
170 ethernet@27000 { 164 enet3: ethernet@27000 {
171 #address-cells = <1>; 165 cell-index = <3>;
172 #size-cells = <0>;
173 device_type = "network"; 166 device_type = "network";
174 model = "TSEC"; 167 model = "TSEC";
175 compatible = "gianfar"; 168 compatible = "gianfar";
176 reg = <27000 1000>; 169 reg = <27000 1000>;
177 /*
178 * mac-address is deprecated and will be removed
179 * in 2.6.25. Only recent versions of
180 * U-Boot support local-mac-address, however.
181 */
182 mac-address = [ 00 00 00 00 00 00 ];
183 local-mac-address = [ 00 00 00 00 00 00 ]; 170 local-mac-address = [ 00 00 00 00 00 00 ];
184 interrupts = <25 2 26 2 27 2>; 171 interrupts = <25 2 26 2 27 2>;
185 interrupt-parent = <&mpic>; 172 interrupt-parent = <&mpic>;
186 phy-handle = <&phy3>; 173 phy-handle = <&phy3>;
187 phy-connection-type = "rgmii-id"; 174 phy-connection-type = "rgmii-id";
188 }; 175 };
189 serial@4500 { 176
177 serial0: serial@4500 {
178 cell-index = <0>;
190 device_type = "serial"; 179 device_type = "serial";
191 compatible = "ns16550"; 180 compatible = "ns16550";
192 reg = <4500 100>; 181 reg = <4500 100>;
@@ -195,7 +184,8 @@
195 interrupt-parent = <&mpic>; 184 interrupt-parent = <&mpic>;
196 }; 185 };
197 186
198 serial@4600 { 187 serial1: serial@4600 {
188 cell-index = <1>;
199 device_type = "serial"; 189 device_type = "serial";
200 compatible = "ns16550"; 190 compatible = "ns16550";
201 reg = <4600 100>; 191 reg = <4600 100>;
@@ -222,7 +212,8 @@
222 }; 212 };
223 }; 213 };
224 214
225 pcie@f8008000 { 215 pci0: pcie@f8008000 {
216 cell-index = <0>;
226 compatible = "fsl,mpc8641-pcie"; 217 compatible = "fsl,mpc8641-pcie";
227 device_type = "pci"; 218 device_type = "pci";
228 #interrupt-cells = <1>; 219 #interrupt-cells = <1>;
@@ -430,7 +421,8 @@
430 421
431 }; 422 };
432 423
433 pcie@f8009000 { 424 pci1: pcie@f8009000 {
425 cell-index = <1>;
434 compatible = "fsl,mpc8641-pcie"; 426 compatible = "fsl,mpc8641-pcie";
435 device_type = "pci"; 427 device_type = "pci";
436 #interrupt-cells = <1>; 428 #interrupt-cells = <1>;
diff --git a/arch/powerpc/boot/dts/mpc866ads.dts b/arch/powerpc/boot/dts/mpc866ads.dts
index 90f2293ed3cd..daf9433e906b 100644
--- a/arch/powerpc/boot/dts/mpc866ads.dts
+++ b/arch/powerpc/boot/dts/mpc866ads.dts
@@ -12,7 +12,7 @@
12 12
13/ { 13/ {
14 model = "MPC866ADS"; 14 model = "MPC866ADS";
15 compatible = "mpc8xx"; 15 compatible = "fsl,mpc866ads";
16 #address-cells = <1>; 16 #address-cells = <1>;
17 #size-cells = <1>; 17 #size-cells = <1>;
18 18
@@ -23,15 +23,15 @@
23 PowerPC,866@0 { 23 PowerPC,866@0 {
24 device_type = "cpu"; 24 device_type = "cpu";
25 reg = <0>; 25 reg = <0>;
26 d-cache-line-size = <20>; // 32 bytes 26 d-cache-line-size = <10>; // 16 bytes
27 i-cache-line-size = <20>; // 32 bytes 27 i-cache-line-size = <10>; // 16 bytes
28 d-cache-size = <2000>; // L1, 8K 28 d-cache-size = <2000>; // L1, 8K
29 i-cache-size = <4000>; // L1, 16K 29 i-cache-size = <4000>; // L1, 16K
30 timebase-frequency = <0>; 30 timebase-frequency = <0>;
31 bus-frequency = <0>; 31 bus-frequency = <0>;
32 clock-frequency = <0>; 32 clock-frequency = <0>;
33 interrupts = <f 2>; // decrementer interrupt 33 interrupts = <f 2>; // decrementer interrupt
34 interrupt-parent = <&Mpc8xx_pic>; 34 interrupt-parent = <&PIC>;
35 }; 35 };
36 }; 36 };
37 37
@@ -40,107 +40,139 @@
40 reg = <00000000 800000>; 40 reg = <00000000 800000>;
41 }; 41 };
42 42
43 soc866@ff000000 { 43 localbus@ff000100 {
44 compatible = "fsl,mpc866-localbus", "fsl,pq1-localbus";
45 #address-cells = <2>;
46 #size-cells = <1>;
47 reg = <ff000100 40>;
48
49 ranges = <
50 1 0 ff080000 00008000
51 5 0 ff0a0000 00008000
52 >;
53
54 board-control@1,0 {
55 reg = <1 0 20 5 300 4>;
56 compatible = "fsl,mpc866ads-bcsr";
57 };
58 };
59
60 soc@ff000000 {
44 #address-cells = <1>; 61 #address-cells = <1>;
45 #size-cells = <1>; 62 #size-cells = <1>;
46 device_type = "soc"; 63 device_type = "soc";
47 ranges = <0 ff000000 00100000>; 64 ranges = <0 ff000000 00100000>;
48 reg = <ff000000 00000200>; 65 reg = <ff000000 00000200>;
49 bus-frequency = <0>; 66 bus-frequency = <0>;
50 mdio@e80 { 67
51 device_type = "mdio"; 68 mdio@e00 {
52 compatible = "fs_enet"; 69 compatible = "fsl,mpc866-fec-mdio", "fsl,pq1-fec-mdio";
53 reg = <e80 8>; 70 reg = <e00 188>;
54 #address-cells = <1>; 71 #address-cells = <1>;
55 #size-cells = <0>; 72 #size-cells = <0>;
56 phy: ethernet-phy@f { 73 PHY: ethernet-phy@f {
57 reg = <f>; 74 reg = <f>;
58 device_type = "ethernet-phy"; 75 device_type = "ethernet-phy";
59 }; 76 };
60 }; 77 };
61 78
62 fec@e00 { 79 ethernet@e00 {
63 device_type = "network"; 80 device_type = "network";
64 compatible = "fs_enet"; 81 compatible = "fsl,mpc866-fec-enet",
65 model = "FEC"; 82 "fsl,pq1-fec-enet";
66 device-id = <1>;
67 reg = <e00 188>; 83 reg = <e00 188>;
68 mac-address = [ 00 00 0C 00 01 FD ]; 84 local-mac-address = [ 00 00 00 00 00 00 ];
69 interrupts = <3 1>; 85 interrupts = <3 1>;
70 interrupt-parent = <&Mpc8xx_pic>; 86 interrupt-parent = <&PIC>;
71 phy-handle = <&Phy>; 87 phy-handle = <&PHY>;
88 linux,network-index = <0>;
72 }; 89 };
73 90
74 mpc8xx_pic: pic@ff000000 { 91 PIC: pic@0 {
75 interrupt-controller; 92 interrupt-controller;
76 #address-cells = <0>;
77 #interrupt-cells = <2>; 93 #interrupt-cells = <2>;
78 reg = <0 24>; 94 reg = <0 24>;
79 device_type = "mpc8xx-pic"; 95 compatible = "fsl,mpc866-pic", "fsl,pq1-pic";
80 compatible = "CPM";
81 }; 96 };
82 97
83 cpm@ff000000 { 98 cpm@9c0 {
84 #address-cells = <1>; 99 #address-cells = <1>;
85 #size-cells = <1>; 100 #size-cells = <1>;
86 device_type = "cpm"; 101 compatible = "fsl,mpc866-cpm", "fsl,cpm1";
87 model = "CPM"; 102 ranges;
88 ranges = <0 0 4000>; 103 reg = <9c0 40>;
89 reg = <860 f0>;
90 command-proc = <9c0>;
91 brg-frequency = <0>; 104 brg-frequency = <0>;
92 interrupts = <0 2>; // cpm error interrupt 105 interrupts = <0 2>; // cpm error interrupt
93 interrupt-parent = <&Cpm_pic>; 106 interrupt-parent = <&CPM_PIC>;
94 107
95 cpm_pic: pic@930 { 108 muram@2000 {
109 #address-cells = <1>;
110 #size-cells = <1>;
111 ranges = <0 2000 2000>;
112
113 data@0 {
114 compatible = "fsl,cpm-muram-data";
115 reg = <0 1c00>;
116 };
117 };
118
119 brg@9f0 {
120 compatible = "fsl,mpc866-brg",
121 "fsl,cpm1-brg",
122 "fsl,cpm-brg";
123 reg = <9f0 10>;
124 clock-frequency = <0>;
125 };
126
127 CPM_PIC: pic@930 {
96 interrupt-controller; 128 interrupt-controller;
97 #address-cells = <0>; 129 #address-cells = <0>;
98 #interrupt-cells = <2>; 130 #interrupt-cells = <1>;
99 interrupts = <5 2 0 2>; 131 interrupts = <5 2 0 2>;
100 interrupt-parent = <&Mpc8xx_pic>; 132 interrupt-parent = <&PIC>;
101 reg = <930 20>; 133 reg = <930 20>;
102 device_type = "cpm-pic"; 134 compatible = "fsl,mpc866-cpm-pic",
103 compatible = "CPM"; 135 "fsl,cpm1-pic";
104 }; 136 };
105 137
106 smc@a80 { 138
139 serial@a80 {
107 device_type = "serial"; 140 device_type = "serial";
108 compatible = "cpm_uart"; 141 compatible = "fsl,mpc866-smc-uart",
109 model = "SMC"; 142 "fsl,cpm1-smc-uart";
110 device-id = <1>;
111 reg = <a80 10 3e80 40>; 143 reg = <a80 10 3e80 40>;
112 clock-setup = <00ffffff 0>; 144 interrupts = <4>;
113 rx-clock = <1>; 145 interrupt-parent = <&CPM_PIC>;
114 tx-clock = <1>; 146 fsl,cpm-brg = <1>;
115 current-speed = <0>; 147 fsl,cpm-command = <0090>;
116 interrupts = <4 3>;
117 interrupt-parent = <&Cpm_pic>;
118 }; 148 };
119 149
120 smc@a90 { 150 serial@a90 {
121 device_type = "serial"; 151 device_type = "serial";
122 compatible = "cpm_uart"; 152 compatible = "fsl,mpc866-smc-uart",
123 model = "SMC"; 153 "fsl,cpm1-smc-uart";
124 device-id = <2>; 154 reg = <a90 10 3f80 40>;
125 reg = <a90 20 3f80 40>; 155 interrupts = <3>;
126 clock-setup = <ff00ffff 90000>; 156 interrupt-parent = <&CPM_PIC>;
127 rx-clock = <2>; 157 fsl,cpm-brg = <2>;
128 tx-clock = <2>; 158 fsl,cpm-command = <00d0>;
129 current-speed = <0>;
130 interrupts = <3 3>;
131 interrupt-parent = <&Cpm_pic>;
132 }; 159 };
133 160
134 scc@a00 { 161 ethernet@a00 {
135 device_type = "network"; 162 device_type = "network";
136 compatible = "fs_enet"; 163 compatible = "fsl,mpc866-scc-enet",
137 model = "SCC"; 164 "fsl,cpm1-scc-enet";
138 device-id = <1>; 165 reg = <a00 18 3c00 100>;
139 reg = <a00 18 3c00 80>; 166 local-mac-address = [ 00 00 00 00 00 00 ];
140 mac-address = [ 00 00 0C 00 03 FD ]; 167 interrupts = <1e>;
141 interrupts = <1e 3>; 168 interrupt-parent = <&CPM_PIC>;
142 interrupt-parent = <&Cpm_pic>; 169 fsl,cpm-command = <0000>;
170 linux,network-index = <1>;
143 }; 171 };
144 }; 172 };
145 }; 173 };
174
175 chosen {
176 linux,stdout-path = "/soc/cpm/serial@a80";
177 };
146}; 178};
diff --git a/arch/powerpc/boot/ebony.c b/arch/powerpc/boot/ebony.c
index 86c0f5df0a86..ee31be5e633e 100644
--- a/arch/powerpc/boot/ebony.c
+++ b/arch/powerpc/boot/ebony.c
@@ -146,6 +146,6 @@ void ebony_init(void *mac0, void *mac1)
146 platform_ops.exit = ibm44x_dbcr_reset; 146 platform_ops.exit = ibm44x_dbcr_reset;
147 ebony_mac0 = mac0; 147 ebony_mac0 = mac0;
148 ebony_mac1 = mac1; 148 ebony_mac1 = mac1;
149 ft_init(_dtb_start, _dtb_end - _dtb_start, 32); 149 fdt_init(_dtb_start);
150 serial_console_init(); 150 serial_console_init();
151} 151}
diff --git a/arch/powerpc/boot/ep88xc.c b/arch/powerpc/boot/ep88xc.c
index 6b87cdce3fe7..a400f5407155 100644
--- a/arch/powerpc/boot/ep88xc.c
+++ b/arch/powerpc/boot/ep88xc.c
@@ -45,7 +45,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
45 mem_size *= 1024 * 1024; 45 mem_size *= 1024 * 1024;
46 simple_alloc_init(_end, mem_size - (unsigned long)_end, 32, 64); 46 simple_alloc_init(_end, mem_size - (unsigned long)_end, 32, 64);
47 47
48 ft_init(_dtb_start, _dtb_end - _dtb_start, 32); 48 fdt_init(_dtb_start);
49 49
50 planetcore_set_stdout_path(table); 50 planetcore_set_stdout_path(table);
51 51
diff --git a/arch/powerpc/boot/flatdevtree.c b/arch/powerpc/boot/flatdevtree.c
deleted file mode 100644
index cf30675c6116..000000000000
--- a/arch/powerpc/boot/flatdevtree.c
+++ /dev/null
@@ -1,1036 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * Copyright Pantelis Antoniou 2006
17 * Copyright (C) IBM Corporation 2006
18 *
19 * Authors: Pantelis Antoniou <pantelis@embeddedalley.com>
20 * Hollis Blanchard <hollisb@us.ibm.com>
21 * Mark A. Greer <mgreer@mvista.com>
22 * Paul Mackerras <paulus@samba.org>
23 */
24
25#include <string.h>
26#include <stddef.h>
27#include "flatdevtree.h"
28#include "flatdevtree_env.h"
29
30#define _ALIGN(x, al) (((x) + (al) - 1) & ~((al) - 1))
31
32static char *ft_root_node(struct ft_cxt *cxt)
33{
34 return cxt->rgn[FT_STRUCT].start;
35}
36
37/* Routines for keeping node ptrs returned by ft_find_device current */
38/* First entry not used b/c it would return 0 and be taken as NULL/error */
39static void *ft_get_phandle(struct ft_cxt *cxt, char *node)
40{
41 unsigned int i;
42
43 if (!node)
44 return NULL;
45
46 for (i = 1; i < cxt->nodes_used; i++) /* already there? */
47 if (cxt->node_tbl[i] == node)
48 return (void *)i;
49
50 if (cxt->nodes_used < cxt->node_max) {
51 cxt->node_tbl[cxt->nodes_used] = node;
52 return (void *)cxt->nodes_used++;
53 }
54
55 return NULL;
56}
57
58static char *ft_node_ph2node(struct ft_cxt *cxt, const void *phandle)
59{
60 unsigned int i = (unsigned int)phandle;
61
62 if (i < cxt->nodes_used)
63 return cxt->node_tbl[i];
64 return NULL;
65}
66
67static void ft_node_update_before(struct ft_cxt *cxt, char *addr, int shift)
68{
69 unsigned int i;
70
71 if (shift == 0)
72 return;
73
74 for (i = 1; i < cxt->nodes_used; i++)
75 if (cxt->node_tbl[i] < addr)
76 cxt->node_tbl[i] += shift;
77}
78
79static void ft_node_update_after(struct ft_cxt *cxt, char *addr, int shift)
80{
81 unsigned int i;
82
83 if (shift == 0)
84 return;
85
86 for (i = 1; i < cxt->nodes_used; i++)
87 if (cxt->node_tbl[i] >= addr)
88 cxt->node_tbl[i] += shift;
89}
90
91/* Struct used to return info from ft_next() */
92struct ft_atom {
93 u32 tag;
94 const char *name;
95 void *data;
96 u32 size;
97};
98
99/* Set ptrs to current one's info; return addr of next one */
100static char *ft_next(struct ft_cxt *cxt, char *p, struct ft_atom *ret)
101{
102 u32 sz;
103
104 if (p >= cxt->rgn[FT_STRUCT].start + cxt->rgn[FT_STRUCT].size)
105 return NULL;
106
107 ret->tag = be32_to_cpu(*(u32 *) p);
108 p += 4;
109
110 switch (ret->tag) { /* Tag */
111 case OF_DT_BEGIN_NODE:
112 ret->name = p;
113 ret->data = (void *)(p - 4); /* start of node */
114 p += _ALIGN(strlen(p) + 1, 4);
115 break;
116 case OF_DT_PROP:
117 ret->size = sz = be32_to_cpu(*(u32 *) p);
118 ret->name = cxt->str_anchor + be32_to_cpu(*(u32 *) (p + 4));
119 ret->data = (void *)(p + 8);
120 p += 8 + _ALIGN(sz, 4);
121 break;
122 case OF_DT_END_NODE:
123 case OF_DT_NOP:
124 break;
125 case OF_DT_END:
126 default:
127 p = NULL;
128 break;
129 }
130
131 return p;
132}
133
134#define HDR_SIZE _ALIGN(sizeof(struct boot_param_header), 8)
135#define EXPAND_INCR 1024 /* alloc this much extra when expanding */
136
137/* Copy the tree to a newly-allocated region and put things in order */
138static int ft_reorder(struct ft_cxt *cxt, int nextra)
139{
140 unsigned long tot;
141 enum ft_rgn_id r;
142 char *p, *pend;
143 int stroff;
144
145 tot = HDR_SIZE + EXPAND_INCR;
146 for (r = FT_RSVMAP; r <= FT_STRINGS; ++r)
147 tot += cxt->rgn[r].size;
148 if (nextra > 0)
149 tot += nextra;
150 tot = _ALIGN(tot, 8);
151
152 if (!cxt->realloc)
153 return 0;
154 p = cxt->realloc(NULL, tot);
155 if (!p)
156 return 0;
157
158 memcpy(p, cxt->bph, sizeof(struct boot_param_header));
159 /* offsets get fixed up later */
160
161 cxt->bph = (struct boot_param_header *)p;
162 cxt->max_size = tot;
163 pend = p + tot;
164 p += HDR_SIZE;
165
166 memcpy(p, cxt->rgn[FT_RSVMAP].start, cxt->rgn[FT_RSVMAP].size);
167 cxt->rgn[FT_RSVMAP].start = p;
168 p += cxt->rgn[FT_RSVMAP].size;
169
170 memcpy(p, cxt->rgn[FT_STRUCT].start, cxt->rgn[FT_STRUCT].size);
171 ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start,
172 p - cxt->rgn[FT_STRUCT].start);
173 cxt->p += p - cxt->rgn[FT_STRUCT].start;
174 cxt->rgn[FT_STRUCT].start = p;
175
176 p = pend - cxt->rgn[FT_STRINGS].size;
177 memcpy(p, cxt->rgn[FT_STRINGS].start, cxt->rgn[FT_STRINGS].size);
178 stroff = cxt->str_anchor - cxt->rgn[FT_STRINGS].start;
179 cxt->rgn[FT_STRINGS].start = p;
180 cxt->str_anchor = p + stroff;
181
182 cxt->isordered = 1;
183 return 1;
184}
185
186static inline char *prev_end(struct ft_cxt *cxt, enum ft_rgn_id r)
187{
188 if (r > FT_RSVMAP)
189 return cxt->rgn[r - 1].start + cxt->rgn[r - 1].size;
190 return (char *)cxt->bph + HDR_SIZE;
191}
192
193static inline char *next_start(struct ft_cxt *cxt, enum ft_rgn_id r)
194{
195 if (r < FT_STRINGS)
196 return cxt->rgn[r + 1].start;
197 return (char *)cxt->bph + cxt->max_size;
198}
199
200/*
201 * See if we can expand region rgn by nextra bytes by using up
202 * free space after or before the region.
203 */
204static int ft_shuffle(struct ft_cxt *cxt, char **pp, enum ft_rgn_id rgn,
205 int nextra)
206{
207 char *p = *pp;
208 char *rgn_start, *rgn_end;
209
210 rgn_start = cxt->rgn[rgn].start;
211 rgn_end = rgn_start + cxt->rgn[rgn].size;
212 if (nextra <= 0 || rgn_end + nextra <= next_start(cxt, rgn)) {
213 /* move following stuff */
214 if (p < rgn_end) {
215 if (nextra < 0)
216 memmove(p, p - nextra, rgn_end - p + nextra);
217 else
218 memmove(p + nextra, p, rgn_end - p);
219 if (rgn == FT_STRUCT)
220 ft_node_update_after(cxt, p, nextra);
221 }
222 cxt->rgn[rgn].size += nextra;
223 if (rgn == FT_STRINGS)
224 /* assumes strings only added at beginning */
225 cxt->str_anchor += nextra;
226 return 1;
227 }
228 if (prev_end(cxt, rgn) <= rgn_start - nextra) {
229 /* move preceding stuff */
230 if (p > rgn_start) {
231 memmove(rgn_start - nextra, rgn_start, p - rgn_start);
232 if (rgn == FT_STRUCT)
233 ft_node_update_before(cxt, p, -nextra);
234 }
235 *pp -= nextra;
236 cxt->rgn[rgn].start -= nextra;
237 cxt->rgn[rgn].size += nextra;
238 return 1;
239 }
240 return 0;
241}
242
243static int ft_make_space(struct ft_cxt *cxt, char **pp, enum ft_rgn_id rgn,
244 int nextra)
245{
246 unsigned long size, ssize, tot;
247 char *str, *next;
248 enum ft_rgn_id r;
249
250 if (!cxt->isordered) {
251 unsigned long rgn_off = *pp - cxt->rgn[rgn].start;
252
253 if (!ft_reorder(cxt, nextra))
254 return 0;
255
256 *pp = cxt->rgn[rgn].start + rgn_off;
257 }
258 if (ft_shuffle(cxt, pp, rgn, nextra))
259 return 1;
260
261 /* See if there is space after the strings section */
262 ssize = cxt->rgn[FT_STRINGS].size;
263 if (cxt->rgn[FT_STRINGS].start + ssize
264 < (char *)cxt->bph + cxt->max_size) {
265 /* move strings up as far as possible */
266 str = (char *)cxt->bph + cxt->max_size - ssize;
267 cxt->str_anchor += str - cxt->rgn[FT_STRINGS].start;
268 memmove(str, cxt->rgn[FT_STRINGS].start, ssize);
269 cxt->rgn[FT_STRINGS].start = str;
270 /* enough space now? */
271 if (rgn >= FT_STRUCT && ft_shuffle(cxt, pp, rgn, nextra))
272 return 1;
273 }
274
275 /* how much total free space is there following this region? */
276 tot = 0;
277 for (r = rgn; r < FT_STRINGS; ++r) {
278 char *r_end = cxt->rgn[r].start + cxt->rgn[r].size;
279 tot += next_start(cxt, rgn) - r_end;
280 }
281
282 /* cast is to shut gcc up; we know nextra >= 0 */
283 if (tot < (unsigned int)nextra) {
284 /* have to reallocate */
285 char *newp, *new_start;
286 int shift;
287
288 if (!cxt->realloc)
289 return 0;
290 size = _ALIGN(cxt->max_size + (nextra - tot) + EXPAND_INCR, 8);
291 newp = cxt->realloc(cxt->bph, size);
292 if (!newp)
293 return 0;
294 cxt->max_size = size;
295 shift = newp - (char *)cxt->bph;
296
297 if (shift) { /* realloc can return same addr */
298 cxt->bph = (struct boot_param_header *)newp;
299 ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start,
300 shift);
301 for (r = FT_RSVMAP; r <= FT_STRINGS; ++r) {
302 new_start = cxt->rgn[r].start + shift;
303 cxt->rgn[r].start = new_start;
304 }
305 *pp += shift;
306 cxt->str_anchor += shift;
307 }
308
309 /* move strings up to the end */
310 str = newp + size - ssize;
311 cxt->str_anchor += str - cxt->rgn[FT_STRINGS].start;
312 memmove(str, cxt->rgn[FT_STRINGS].start, ssize);
313 cxt->rgn[FT_STRINGS].start = str;
314
315 if (ft_shuffle(cxt, pp, rgn, nextra))
316 return 1;
317 }
318
319 /* must be FT_RSVMAP and we need to move FT_STRUCT up */
320 if (rgn == FT_RSVMAP) {
321 next = cxt->rgn[FT_RSVMAP].start + cxt->rgn[FT_RSVMAP].size
322 + nextra;
323 ssize = cxt->rgn[FT_STRUCT].size;
324 if (next + ssize >= cxt->rgn[FT_STRINGS].start)
325 return 0; /* "can't happen" */
326 memmove(next, cxt->rgn[FT_STRUCT].start, ssize);
327 ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start, nextra);
328 cxt->rgn[FT_STRUCT].start = next;
329
330 if (ft_shuffle(cxt, pp, rgn, nextra))
331 return 1;
332 }
333
334 return 0; /* "can't happen" */
335}
336
337static void ft_put_word(struct ft_cxt *cxt, u32 v)
338{
339 *(u32 *) cxt->p = cpu_to_be32(v);
340 cxt->p += 4;
341}
342
343static void ft_put_bin(struct ft_cxt *cxt, const void *data, unsigned int sz)
344{
345 unsigned long sza = _ALIGN(sz, 4);
346
347 /* zero out the alignment gap if necessary */
348 if (sz < sza)
349 *(u32 *) (cxt->p + sza - 4) = 0;
350
351 /* copy in the data */
352 memcpy(cxt->p, data, sz);
353
354 cxt->p += sza;
355}
356
357char *ft_begin_node(struct ft_cxt *cxt, const char *name)
358{
359 unsigned long nlen = strlen(name) + 1;
360 unsigned long len = 8 + _ALIGN(nlen, 4);
361 char *ret;
362
363 if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, len))
364 return NULL;
365
366 ret = cxt->p;
367
368 ft_put_word(cxt, OF_DT_BEGIN_NODE);
369 ft_put_bin(cxt, name, strlen(name) + 1);
370
371 return ret;
372}
373
374void ft_end_node(struct ft_cxt *cxt)
375{
376 ft_put_word(cxt, OF_DT_END_NODE);
377}
378
379void ft_nop(struct ft_cxt *cxt)
380{
381 if (ft_make_space(cxt, &cxt->p, FT_STRUCT, 4))
382 ft_put_word(cxt, OF_DT_NOP);
383}
384
385#define NO_STRING 0x7fffffff
386
387static int lookup_string(struct ft_cxt *cxt, const char *name)
388{
389 char *p, *end;
390
391 p = cxt->rgn[FT_STRINGS].start;
392 end = p + cxt->rgn[FT_STRINGS].size;
393 while (p < end) {
394 if (strcmp(p, (char *)name) == 0)
395 return p - cxt->str_anchor;
396 p += strlen(p) + 1;
397 }
398
399 return NO_STRING;
400}
401
402/* lookup string and insert if not found */
403static int map_string(struct ft_cxt *cxt, const char *name)
404{
405 int off;
406 char *p;
407
408 off = lookup_string(cxt, name);
409 if (off != NO_STRING)
410 return off;
411 p = cxt->rgn[FT_STRINGS].start;
412 if (!ft_make_space(cxt, &p, FT_STRINGS, strlen(name) + 1))
413 return NO_STRING;
414 strcpy(p, name);
415 return p - cxt->str_anchor;
416}
417
418int ft_prop(struct ft_cxt *cxt, const char *name, const void *data,
419 unsigned int sz)
420{
421 int off, len;
422
423 off = map_string(cxt, name);
424 if (off == NO_STRING)
425 return -1;
426
427 len = 12 + _ALIGN(sz, 4);
428 if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, len))
429 return -1;
430
431 ft_put_word(cxt, OF_DT_PROP);
432 ft_put_word(cxt, sz);
433 ft_put_word(cxt, off);
434 ft_put_bin(cxt, data, sz);
435 return 0;
436}
437
438int ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str)
439{
440 return ft_prop(cxt, name, str, strlen(str) + 1);
441}
442
443int ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val)
444{
445 u32 v = cpu_to_be32((u32) val);
446
447 return ft_prop(cxt, name, &v, 4);
448}
449
450/* Calculate the size of the reserved map */
451static unsigned long rsvmap_size(struct ft_cxt *cxt)
452{
453 struct ft_reserve *res;
454
455 res = (struct ft_reserve *)cxt->rgn[FT_RSVMAP].start;
456 while (res->start || res->len)
457 ++res;
458 return (char *)(res + 1) - cxt->rgn[FT_RSVMAP].start;
459}
460
461/* Calculate the size of the struct region by stepping through it */
462static unsigned long struct_size(struct ft_cxt *cxt)
463{
464 char *p = cxt->rgn[FT_STRUCT].start;
465 char *next;
466 struct ft_atom atom;
467
468 /* make check in ft_next happy */
469 if (cxt->rgn[FT_STRUCT].size == 0)
470 cxt->rgn[FT_STRUCT].size = 0xfffffffful - (unsigned long)p;
471
472 while ((next = ft_next(cxt, p, &atom)) != NULL)
473 p = next;
474 return p + 4 - cxt->rgn[FT_STRUCT].start;
475}
476
477/* add `adj' on to all string offset values in the struct area */
478static void adjust_string_offsets(struct ft_cxt *cxt, int adj)
479{
480 char *p = cxt->rgn[FT_STRUCT].start;
481 char *next;
482 struct ft_atom atom;
483 int off;
484
485 while ((next = ft_next(cxt, p, &atom)) != NULL) {
486 if (atom.tag == OF_DT_PROP) {
487 off = be32_to_cpu(*(u32 *) (p + 8));
488 *(u32 *) (p + 8) = cpu_to_be32(off + adj);
489 }
490 p = next;
491 }
492}
493
494/* start construction of the flat OF tree from scratch */
495void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size,
496 void *(*realloc_fn) (void *, unsigned long))
497{
498 struct boot_param_header *bph = blob;
499 char *p;
500 struct ft_reserve *pres;
501
502 /* clear the cxt */
503 memset(cxt, 0, sizeof(*cxt));
504
505 cxt->bph = bph;
506 cxt->max_size = max_size;
507 cxt->realloc = realloc_fn;
508 cxt->isordered = 1;
509
510 /* zero everything in the header area */
511 memset(bph, 0, sizeof(*bph));
512
513 bph->magic = cpu_to_be32(OF_DT_HEADER);
514 bph->version = cpu_to_be32(0x10);
515 bph->last_comp_version = cpu_to_be32(0x10);
516
517 /* start pointers */
518 cxt->rgn[FT_RSVMAP].start = p = blob + HDR_SIZE;
519 cxt->rgn[FT_RSVMAP].size = sizeof(struct ft_reserve);
520 pres = (struct ft_reserve *)p;
521 cxt->rgn[FT_STRUCT].start = p += sizeof(struct ft_reserve);
522 cxt->rgn[FT_STRUCT].size = 4;
523 cxt->rgn[FT_STRINGS].start = blob + max_size;
524 cxt->rgn[FT_STRINGS].size = 0;
525
526 /* init rsvmap and struct */
527 pres->start = 0;
528 pres->len = 0;
529 *(u32 *) p = cpu_to_be32(OF_DT_END);
530
531 cxt->str_anchor = blob;
532}
533
534/* open up an existing blob to be examined or modified */
535int ft_open(struct ft_cxt *cxt, void *blob, unsigned int max_size,
536 unsigned int max_find_device,
537 void *(*realloc_fn) (void *, unsigned long))
538{
539 struct boot_param_header *bph = blob;
540
541 /* can't cope with version < 16 */
542 if (be32_to_cpu(bph->version) < 16)
543 return -1;
544
545 /* clear the cxt */
546 memset(cxt, 0, sizeof(*cxt));
547
548 /* alloc node_tbl to track node ptrs returned by ft_find_device */
549 ++max_find_device;
550 cxt->node_tbl = realloc_fn(NULL, max_find_device * sizeof(char *));
551 if (!cxt->node_tbl)
552 return -1;
553 memset(cxt->node_tbl, 0, max_find_device * sizeof(char *));
554 cxt->node_max = max_find_device;
555 cxt->nodes_used = 1; /* don't use idx 0 b/c looks like NULL */
556
557 cxt->bph = bph;
558 cxt->max_size = max_size;
559 cxt->realloc = realloc_fn;
560
561 cxt->rgn[FT_RSVMAP].start = blob + be32_to_cpu(bph->off_mem_rsvmap);
562 cxt->rgn[FT_RSVMAP].size = rsvmap_size(cxt);
563 cxt->rgn[FT_STRUCT].start = blob + be32_to_cpu(bph->off_dt_struct);
564 cxt->rgn[FT_STRUCT].size = struct_size(cxt);
565 cxt->rgn[FT_STRINGS].start = blob + be32_to_cpu(bph->off_dt_strings);
566 cxt->rgn[FT_STRINGS].size = be32_to_cpu(bph->dt_strings_size);
567
568 cxt->p = cxt->rgn[FT_STRUCT].start;
569 cxt->str_anchor = cxt->rgn[FT_STRINGS].start;
570
571 return 0;
572}
573
574/* add a reserver physical area to the rsvmap */
575int ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size)
576{
577 char *p;
578 struct ft_reserve *pres;
579
580 p = cxt->rgn[FT_RSVMAP].start + cxt->rgn[FT_RSVMAP].size
581 - sizeof(struct ft_reserve);
582 if (!ft_make_space(cxt, &p, FT_RSVMAP, sizeof(struct ft_reserve)))
583 return -1;
584
585 pres = (struct ft_reserve *)p;
586 pres->start = cpu_to_be64(physaddr);
587 pres->len = cpu_to_be64(size);
588
589 return 0;
590}
591
592void ft_begin_tree(struct ft_cxt *cxt)
593{
594 cxt->p = ft_root_node(cxt);
595}
596
597void ft_end_tree(struct ft_cxt *cxt)
598{
599 struct boot_param_header *bph = cxt->bph;
600 char *p, *oldstr, *str, *endp;
601 unsigned long ssize;
602 int adj;
603
604 if (!cxt->isordered)
605 return; /* we haven't touched anything */
606
607 /* adjust string offsets */
608 oldstr = cxt->rgn[FT_STRINGS].start;
609 adj = cxt->str_anchor - oldstr;
610 if (adj)
611 adjust_string_offsets(cxt, adj);
612
613 /* make strings end on 8-byte boundary */
614 ssize = cxt->rgn[FT_STRINGS].size;
615 endp = (char *)_ALIGN((unsigned long)cxt->rgn[FT_STRUCT].start
616 + cxt->rgn[FT_STRUCT].size + ssize, 8);
617 str = endp - ssize;
618
619 /* move strings down to end of structs */
620 memmove(str, oldstr, ssize);
621 cxt->str_anchor = str;
622 cxt->rgn[FT_STRINGS].start = str;
623
624 /* fill in header fields */
625 p = (char *)bph;
626 bph->totalsize = cpu_to_be32(endp - p);
627 bph->off_mem_rsvmap = cpu_to_be32(cxt->rgn[FT_RSVMAP].start - p);
628 bph->off_dt_struct = cpu_to_be32(cxt->rgn[FT_STRUCT].start - p);
629 bph->off_dt_strings = cpu_to_be32(cxt->rgn[FT_STRINGS].start - p);
630 bph->dt_strings_size = cpu_to_be32(ssize);
631}
632
633void *ft_find_device(struct ft_cxt *cxt, const void *top, const char *srch_path)
634{
635 char *node;
636
637 if (top) {
638 node = ft_node_ph2node(cxt, top);
639 if (node == NULL)
640 return NULL;
641 } else {
642 node = ft_root_node(cxt);
643 }
644
645 node = ft_find_descendent(cxt, node, srch_path);
646 return ft_get_phandle(cxt, node);
647}
648
649void *ft_find_descendent(struct ft_cxt *cxt, void *top, const char *srch_path)
650{
651 struct ft_atom atom;
652 char *p;
653 const char *cp, *q;
654 int cl;
655 int depth = -1;
656 int dmatch = 0;
657 const char *path_comp[FT_MAX_DEPTH];
658
659 cp = srch_path;
660 cl = 0;
661 p = top;
662
663 while ((p = ft_next(cxt, p, &atom)) != NULL) {
664 switch (atom.tag) {
665 case OF_DT_BEGIN_NODE:
666 ++depth;
667 if (depth != dmatch)
668 break;
669 cxt->genealogy[depth] = atom.data;
670 cxt->genealogy[depth + 1] = NULL;
671 if (depth && !(strncmp(atom.name, cp, cl) == 0
672 && (atom.name[cl] == '/'
673 || atom.name[cl] == '\0'
674 || atom.name[cl] == '@')))
675 break;
676 path_comp[dmatch] = cp;
677 /* it matches so far, advance to next path component */
678 cp += cl;
679 /* skip slashes */
680 while (*cp == '/')
681 ++cp;
682 /* we're done if this is the end of the string */
683 if (*cp == 0)
684 return atom.data;
685 /* look for end of this component */
686 q = strchr(cp, '/');
687 if (q)
688 cl = q - cp;
689 else
690 cl = strlen(cp);
691 ++dmatch;
692 break;
693 case OF_DT_END_NODE:
694 if (depth == 0)
695 return NULL;
696 if (dmatch > depth) {
697 --dmatch;
698 cl = cp - path_comp[dmatch] - 1;
699 cp = path_comp[dmatch];
700 while (cl > 0 && cp[cl - 1] == '/')
701 --cl;
702 }
703 --depth;
704 break;
705 }
706 }
707 return NULL;
708}
709
710void *__ft_get_parent(struct ft_cxt *cxt, void *node)
711{
712 int d;
713 struct ft_atom atom;
714 char *p;
715
716 for (d = 0; cxt->genealogy[d] != NULL; ++d)
717 if (cxt->genealogy[d] == node)
718 return d > 0 ? cxt->genealogy[d - 1] : NULL;
719
720 /* have to do it the hard way... */
721 p = ft_root_node(cxt);
722 d = 0;
723 while ((p = ft_next(cxt, p, &atom)) != NULL) {
724 switch (atom.tag) {
725 case OF_DT_BEGIN_NODE:
726 cxt->genealogy[d] = atom.data;
727 if (node == atom.data) {
728 /* found it */
729 cxt->genealogy[d + 1] = NULL;
730 return d > 0 ? cxt->genealogy[d - 1] : NULL;
731 }
732 ++d;
733 break;
734 case OF_DT_END_NODE:
735 --d;
736 break;
737 }
738 }
739 return NULL;
740}
741
742void *ft_get_parent(struct ft_cxt *cxt, const void *phandle)
743{
744 void *node = ft_node_ph2node(cxt, phandle);
745 if (node == NULL)
746 return NULL;
747
748 node = __ft_get_parent(cxt, node);
749 return ft_get_phandle(cxt, node);
750}
751
752static const void *__ft_get_prop(struct ft_cxt *cxt, void *node,
753 const char *propname, unsigned int *len)
754{
755 struct ft_atom atom;
756 int depth = 0;
757
758 while ((node = ft_next(cxt, node, &atom)) != NULL) {
759 switch (atom.tag) {
760 case OF_DT_BEGIN_NODE:
761 ++depth;
762 break;
763
764 case OF_DT_PROP:
765 if (depth != 1 || strcmp(atom.name, propname))
766 break;
767
768 if (len)
769 *len = atom.size;
770
771 return atom.data;
772
773 case OF_DT_END_NODE:
774 if (--depth <= 0)
775 return NULL;
776 }
777 }
778
779 return NULL;
780}
781
782int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
783 void *buf, const unsigned int buflen)
784{
785 const void *data;
786 unsigned int size;
787
788 void *node = ft_node_ph2node(cxt, phandle);
789 if (!node)
790 return -1;
791
792 data = __ft_get_prop(cxt, node, propname, &size);
793 if (data) {
794 unsigned int clipped_size = min(size, buflen);
795 memcpy(buf, data, clipped_size);
796 return size;
797 }
798
799 return -1;
800}
801
802void *__ft_find_node_by_prop_value(struct ft_cxt *cxt, void *prev,
803 const char *propname, const char *propval,
804 unsigned int proplen)
805{
806 struct ft_atom atom;
807 char *p = ft_root_node(cxt);
808 char *next;
809 int past_prev = prev ? 0 : 1;
810 int depth = -1;
811
812 while ((next = ft_next(cxt, p, &atom)) != NULL) {
813 const void *data;
814 unsigned int size;
815
816 switch (atom.tag) {
817 case OF_DT_BEGIN_NODE:
818 depth++;
819
820 if (prev == p) {
821 past_prev = 1;
822 break;
823 }
824
825 if (!past_prev || depth < 1)
826 break;
827
828 data = __ft_get_prop(cxt, p, propname, &size);
829 if (!data || size != proplen)
830 break;
831 if (memcmp(data, propval, size))
832 break;
833
834 return p;
835
836 case OF_DT_END_NODE:
837 if (depth-- == 0)
838 return NULL;
839
840 break;
841 }
842
843 p = next;
844 }
845
846 return NULL;
847}
848
849void *ft_find_node_by_prop_value(struct ft_cxt *cxt, const void *prev,
850 const char *propname, const char *propval,
851 int proplen)
852{
853 void *node = NULL;
854
855 if (prev) {
856 node = ft_node_ph2node(cxt, prev);
857
858 if (!node)
859 return NULL;
860 }
861
862 node = __ft_find_node_by_prop_value(cxt, node, propname,
863 propval, proplen);
864 return ft_get_phandle(cxt, node);
865}
866
867int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
868 const void *buf, const unsigned int buflen)
869{
870 struct ft_atom atom;
871 void *node;
872 char *p, *next;
873 int nextra;
874
875 node = ft_node_ph2node(cxt, phandle);
876 if (node == NULL)
877 return -1;
878
879 next = ft_next(cxt, node, &atom);
880 if (atom.tag != OF_DT_BEGIN_NODE)
881 /* phandle didn't point to a node */
882 return -1;
883 p = next;
884
885 while ((next = ft_next(cxt, p, &atom)) != NULL) {
886 switch (atom.tag) {
887 case OF_DT_BEGIN_NODE: /* properties must go before subnodes */
888 case OF_DT_END_NODE:
889 /* haven't found the property, insert here */
890 cxt->p = p;
891 return ft_prop(cxt, propname, buf, buflen);
892 case OF_DT_PROP:
893 if (strcmp(atom.name, propname))
894 break;
895 /* found an existing property, overwrite it */
896 nextra = _ALIGN(buflen, 4) - _ALIGN(atom.size, 4);
897 cxt->p = atom.data;
898 if (nextra && !ft_make_space(cxt, &cxt->p, FT_STRUCT,
899 nextra))
900 return -1;
901 *(u32 *) (cxt->p - 8) = cpu_to_be32(buflen);
902 ft_put_bin(cxt, buf, buflen);
903 return 0;
904 }
905 p = next;
906 }
907 return -1;
908}
909
910int ft_del_prop(struct ft_cxt *cxt, const void *phandle, const char *propname)
911{
912 struct ft_atom atom;
913 void *node;
914 char *p, *next;
915 int size;
916
917 node = ft_node_ph2node(cxt, phandle);
918 if (node == NULL)
919 return -1;
920
921 p = node;
922 while ((next = ft_next(cxt, p, &atom)) != NULL) {
923 switch (atom.tag) {
924 case OF_DT_BEGIN_NODE:
925 case OF_DT_END_NODE:
926 return -1;
927 case OF_DT_PROP:
928 if (strcmp(atom.name, propname))
929 break;
930 /* found the property, remove it */
931 size = 12 + -_ALIGN(atom.size, 4);
932 cxt->p = p;
933 if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, -size))
934 return -1;
935 return 0;
936 }
937 p = next;
938 }
939 return -1;
940}
941
942void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name)
943{
944 struct ft_atom atom;
945 char *p, *next, *ret;
946 int depth = 0;
947
948 if (parent) {
949 p = ft_node_ph2node(cxt, parent);
950 if (!p)
951 return NULL;
952 } else {
953 p = ft_root_node(cxt);
954 }
955
956 while ((next = ft_next(cxt, p, &atom)) != NULL) {
957 switch (atom.tag) {
958 case OF_DT_BEGIN_NODE:
959 ++depth;
960 if (depth == 1 && strcmp(atom.name, name) == 0)
961 /* duplicate node name, return error */
962 return NULL;
963 break;
964 case OF_DT_END_NODE:
965 --depth;
966 if (depth > 0)
967 break;
968 /* end of node, insert here */
969 cxt->p = p;
970 ret = ft_begin_node(cxt, name);
971 ft_end_node(cxt);
972 return ft_get_phandle(cxt, ret);
973 }
974 p = next;
975 }
976 return NULL;
977}
978
979/* Returns the start of the path within the provided buffer, or NULL on
980 * error.
981 */
982char *ft_get_path(struct ft_cxt *cxt, const void *phandle,
983 char *buf, int len)
984{
985 const char *path_comp[FT_MAX_DEPTH];
986 struct ft_atom atom;
987 char *p, *next, *pos;
988 int depth = 0, i;
989 void *node;
990
991 node = ft_node_ph2node(cxt, phandle);
992 if (node == NULL)
993 return NULL;
994
995 p = ft_root_node(cxt);
996
997 while ((next = ft_next(cxt, p, &atom)) != NULL) {
998 switch (atom.tag) {
999 case OF_DT_BEGIN_NODE:
1000 path_comp[depth++] = atom.name;
1001 if (p == node)
1002 goto found;
1003
1004 break;
1005
1006 case OF_DT_END_NODE:
1007 if (--depth == 0)
1008 return NULL;
1009 }
1010
1011 p = next;
1012 }
1013
1014found:
1015 pos = buf;
1016 for (i = 1; i < depth; i++) {
1017 int this_len;
1018
1019 if (len <= 1)
1020 return NULL;
1021
1022 *pos++ = '/';
1023 len--;
1024
1025 strncpy(pos, path_comp[i], len);
1026
1027 if (pos[len - 1] != 0)
1028 return NULL;
1029
1030 this_len = strlen(pos);
1031 len -= this_len;
1032 pos += this_len;
1033 }
1034
1035 return buf;
1036}
diff --git a/arch/powerpc/boot/flatdevtree.h b/arch/powerpc/boot/flatdevtree.h
deleted file mode 100644
index b0957a2d967f..000000000000
--- a/arch/powerpc/boot/flatdevtree.h
+++ /dev/null
@@ -1,113 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 */
16
17#ifndef FLATDEVTREE_H
18#define FLATDEVTREE_H
19
20#include "flatdevtree_env.h"
21
22/* Definitions used by the flattened device tree */
23#define OF_DT_HEADER 0xd00dfeed /* marker */
24#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
25#define OF_DT_END_NODE 0x2 /* End node */
26#define OF_DT_PROP 0x3 /* Property: name off, size, content */
27#define OF_DT_NOP 0x4 /* nop */
28#define OF_DT_END 0x9
29
30#define OF_DT_VERSION 0x10
31
32struct boot_param_header {
33 u32 magic; /* magic word OF_DT_HEADER */
34 u32 totalsize; /* total size of DT block */
35 u32 off_dt_struct; /* offset to structure */
36 u32 off_dt_strings; /* offset to strings */
37 u32 off_mem_rsvmap; /* offset to memory reserve map */
38 u32 version; /* format version */
39 u32 last_comp_version; /* last compatible version */
40 /* version 2 fields below */
41 u32 boot_cpuid_phys; /* Physical CPU id we're booting on */
42 /* version 3 fields below */
43 u32 dt_strings_size; /* size of the DT strings block */
44};
45
46struct ft_reserve {
47 u64 start;
48 u64 len;
49};
50
51struct ft_region {
52 char *start;
53 unsigned long size;
54};
55
56enum ft_rgn_id {
57 FT_RSVMAP,
58 FT_STRUCT,
59 FT_STRINGS,
60 FT_N_REGION
61};
62
63#define FT_MAX_DEPTH 50
64
65struct ft_cxt {
66 struct boot_param_header *bph;
67 int max_size; /* maximum size of tree */
68 int isordered; /* everything in standard order */
69 void *(*realloc)(void *, unsigned long);
70 char *str_anchor;
71 char *p; /* current insertion point in structs */
72 struct ft_region rgn[FT_N_REGION];
73 void *genealogy[FT_MAX_DEPTH+1];
74 char **node_tbl;
75 unsigned int node_max;
76 unsigned int nodes_used;
77};
78
79char *ft_begin_node(struct ft_cxt *cxt, const char *name);
80void ft_end_node(struct ft_cxt *cxt);
81
82void ft_begin_tree(struct ft_cxt *cxt);
83void ft_end_tree(struct ft_cxt *cxt);
84
85void ft_nop(struct ft_cxt *cxt);
86int ft_prop(struct ft_cxt *cxt, const char *name,
87 const void *data, unsigned int sz);
88int ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str);
89int ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val);
90void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size,
91 void *(*realloc_fn)(void *, unsigned long));
92int ft_open(struct ft_cxt *cxt, void *blob, unsigned int max_size,
93 unsigned int max_find_device,
94 void *(*realloc_fn)(void *, unsigned long));
95int ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size);
96
97void ft_dump_blob(const void *bphp);
98void ft_merge_blob(struct ft_cxt *cxt, void *blob);
99void *ft_find_device(struct ft_cxt *cxt, const void *top,
100 const char *srch_path);
101void *ft_find_descendent(struct ft_cxt *cxt, void *top, const char *srch_path);
102int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
103 void *buf, const unsigned int buflen);
104int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
105 const void *buf, const unsigned int buflen);
106void *ft_get_parent(struct ft_cxt *cxt, const void *phandle);
107void *ft_find_node_by_prop_value(struct ft_cxt *cxt, const void *prev,
108 const char *propname, const char *propval,
109 int proplen);
110void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name);
111char *ft_get_path(struct ft_cxt *cxt, const void *phandle, char *buf, int len);
112
113#endif /* FLATDEVTREE_H */
diff --git a/arch/powerpc/boot/flatdevtree_misc.c b/arch/powerpc/boot/flatdevtree_misc.c
deleted file mode 100644
index b3670096fa71..000000000000
--- a/arch/powerpc/boot/flatdevtree_misc.c
+++ /dev/null
@@ -1,79 +0,0 @@
1/*
2 * This file does the necessary interface mapping between the bootwrapper
3 * device tree operations and the interface provided by shared source
4 * files flatdevicetree.[ch].
5 *
6 * Author: Mark A. Greer <mgreer@mvista.com>
7 *
8 * 2006 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13#include <stddef.h>
14#include "flatdevtree.h"
15#include "ops.h"
16
17static struct ft_cxt cxt;
18
19static void *fdtm_finddevice(const char *name)
20{
21 return ft_find_device(&cxt, NULL, name);
22}
23
24static int fdtm_getprop(const void *phandle, const char *propname,
25 void *buf, const int buflen)
26{
27 return ft_get_prop(&cxt, phandle, propname, buf, buflen);
28}
29
30static int fdtm_setprop(const void *phandle, const char *propname,
31 const void *buf, const int buflen)
32{
33 return ft_set_prop(&cxt, phandle, propname, buf, buflen);
34}
35
36static void *fdtm_get_parent(const void *phandle)
37{
38 return ft_get_parent(&cxt, phandle);
39}
40
41static void *fdtm_create_node(const void *phandle, const char *name)
42{
43 return ft_create_node(&cxt, phandle, name);
44}
45
46static void *fdtm_find_node_by_prop_value(const void *prev,
47 const char *propname,
48 const char *propval,
49 int proplen)
50{
51 return ft_find_node_by_prop_value(&cxt, prev, propname,
52 propval, proplen);
53}
54
55static unsigned long fdtm_finalize(void)
56{
57 ft_end_tree(&cxt);
58 return (unsigned long)cxt.bph;
59}
60
61static char *fdtm_get_path(const void *phandle, char *buf, int len)
62{
63 return ft_get_path(&cxt, phandle, buf, len);
64}
65
66int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device)
67{
68 dt_ops.finddevice = fdtm_finddevice;
69 dt_ops.getprop = fdtm_getprop;
70 dt_ops.setprop = fdtm_setprop;
71 dt_ops.get_parent = fdtm_get_parent;
72 dt_ops.create_node = fdtm_create_node;
73 dt_ops.find_node_by_prop_value = fdtm_find_node_by_prop_value;
74 dt_ops.finalize = fdtm_finalize;
75 dt_ops.get_path = fdtm_get_path;
76
77 return ft_open(&cxt, dt_blob, max_size, max_find_device,
78 platform_ops.realloc);
79}
diff --git a/arch/powerpc/boot/holly.c b/arch/powerpc/boot/holly.c
index 199e783aea4d..58013b923178 100644
--- a/arch/powerpc/boot/holly.c
+++ b/arch/powerpc/boot/holly.c
@@ -28,6 +28,6 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5)
28 u32 heapsize = 0x8000000 - (u32)_end; /* 128M */ 28 u32 heapsize = 0x8000000 - (u32)_end; /* 128M */
29 29
30 simple_alloc_init(_end, heapsize, 32, 64); 30 simple_alloc_init(_end, heapsize, 32, 64);
31 ft_init(_dtb_start, 0, 4); 31 fdt_init(_dtb_start);
32 serial_console_init(); 32 serial_console_init();
33} 33}
diff --git a/arch/powerpc/boot/libfdt-wrapper.c b/arch/powerpc/boot/libfdt-wrapper.c
new file mode 100644
index 000000000000..97af36c224bd
--- /dev/null
+++ b/arch/powerpc/boot/libfdt-wrapper.c
@@ -0,0 +1,184 @@
1/*
2 * This file does the necessary interface mapping between the bootwrapper
3 * device tree operations and the interface provided by shared source
4 * files flatdevicetree.[ch].
5 *
6 * Copyright 2007 David Gibson, IBM Corporation.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 */
23
24#include <stddef.h>
25#include <stdio.h>
26#include <page.h>
27#include <libfdt.h>
28#include "ops.h"
29
30#define DEBUG 0
31#define BAD_ERROR(err) (((err) < 0) \
32 && ((err) != -FDT_ERR_NOTFOUND) \
33 && ((err) != -FDT_ERR_EXISTS))
34
35#define check_err(err) \
36 ({ \
37 if (BAD_ERROR(err) || ((err < 0) && DEBUG)) \
38 printf("%s():%d %s\n\r", __FUNCTION__, __LINE__, \
39 fdt_strerror(err)); \
40 if (BAD_ERROR(err)) \
41 exit(); \
42 (err < 0) ? -1 : 0; \
43 })
44
45#define offset_devp(off) \
46 ({ \
47 int _offset = (off); \
48 check_err(_offset) ? NULL : (void *)(_offset+1); \
49 })
50
51#define devp_offset_find(devp) (((int)(devp))-1)
52#define devp_offset(devp) (devp ? ((int)(devp))-1 : 0)
53
54static void *fdt;
55static void *buf; /* = NULL */
56
57#define EXPAND_GRANULARITY 1024
58
59static void expand_buf(int minexpand)
60{
61 int size = fdt_totalsize(fdt);
62 int rc;
63
64 size = _ALIGN(size + minexpand, EXPAND_GRANULARITY);
65 buf = platform_ops.realloc(buf, size);
66 if (!buf)
67 fatal("Couldn't find %d bytes to expand device tree\n\r", size);
68 rc = fdt_open_into(fdt, buf, size);
69 if (rc != 0)
70 fatal("Couldn't expand fdt into new buffer: %s\n\r",
71 fdt_strerror(rc));
72
73 fdt = buf;
74}
75
76static void *fdt_wrapper_finddevice(const char *path)
77{
78 return offset_devp(fdt_path_offset(fdt, path));
79}
80
81static int fdt_wrapper_getprop(const void *devp, const char *name,
82 void *buf, const int buflen)
83{
84 const void *p;
85 int len;
86
87 p = fdt_getprop(fdt, devp_offset(devp), name, &len);
88 if (!p)
89 return check_err(len);
90 memcpy(buf, p, min(len, buflen));
91 return len;
92}
93
94static int fdt_wrapper_setprop(const void *devp, const char *name,
95 const void *buf, const int len)
96{
97 int rc;
98
99 rc = fdt_setprop(fdt, devp_offset(devp), name, buf, len);
100 if (rc == -FDT_ERR_NOSPACE) {
101 expand_buf(len + 16);
102 rc = fdt_setprop(fdt, devp_offset(devp), name, buf, len);
103 }
104
105 return check_err(rc);
106}
107
108static void *fdt_wrapper_get_parent(const void *devp)
109{
110 return offset_devp(fdt_parent_offset(fdt, devp_offset(devp)));
111}
112
113static void *fdt_wrapper_create_node(const void *devp, const char *name)
114{
115 int offset;
116
117 offset = fdt_add_subnode(fdt, devp_offset(devp), name);
118 if (offset == -FDT_ERR_NOSPACE) {
119 expand_buf(strlen(name) + 16);
120 offset = fdt_add_subnode(fdt, devp_offset(devp), name);
121 }
122
123 return offset_devp(offset);
124}
125
126static void *fdt_wrapper_find_node_by_prop_value(const void *prev,
127 const char *name,
128 const char *val,
129 int len)
130{
131 int offset = fdt_node_offset_by_prop_value(fdt, devp_offset_find(prev),
132 name, val, len);
133 return offset_devp(offset);
134}
135
136static char *fdt_wrapper_get_path(const void *devp, char *buf, int len)
137{
138 int rc;
139
140 rc = fdt_get_path(fdt, devp_offset(devp), buf, len);
141 if (check_err(rc))
142 return NULL;
143 return buf;
144}
145
146static unsigned long fdt_wrapper_finalize(void)
147{
148 int rc;
149
150 rc = fdt_pack(fdt);
151 if (rc != 0)
152 fatal("Couldn't pack flat tree: %s\n\r",
153 fdt_strerror(rc));
154 return (unsigned long)fdt;
155}
156
157void fdt_init(void *blob)
158{
159 int err;
160
161 dt_ops.finddevice = fdt_wrapper_finddevice;
162 dt_ops.getprop = fdt_wrapper_getprop;
163 dt_ops.setprop = fdt_wrapper_setprop;
164 dt_ops.get_parent = fdt_wrapper_get_parent;
165 dt_ops.create_node = fdt_wrapper_create_node;
166 dt_ops.find_node_by_prop_value = fdt_wrapper_find_node_by_prop_value;
167 dt_ops.get_path = fdt_wrapper_get_path;
168 dt_ops.finalize = fdt_wrapper_finalize;
169
170 /* Make sure the dt blob is the right version and so forth */
171 fdt = blob;
172 err = fdt_open_into(fdt, fdt, fdt_totalsize(blob));
173 if (err == -FDT_ERR_NOSPACE) {
174 int bufsize = fdt_totalsize(fdt) + 4;
175 buf = malloc(bufsize);
176 err = fdt_open_into(fdt, buf, bufsize);
177 }
178
179 if (err != 0)
180 fatal("fdt_init(): %s\n\r", fdt_strerror(err));
181
182 if (buf)
183 fdt = buf;
184}
diff --git a/arch/powerpc/boot/libfdt/Makefile.libfdt b/arch/powerpc/boot/libfdt/Makefile.libfdt
new file mode 100644
index 000000000000..82f9c6a8287b
--- /dev/null
+++ b/arch/powerpc/boot/libfdt/Makefile.libfdt
@@ -0,0 +1,14 @@
1# Makefile.libfdt
2#
3# This is not a complete Makefile of itself. Instead, it is designed to
4# be easily embeddable into other systems of Makefiles.
5#
6LIBFDT_SRCS = fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
7LIBFDT_INCLUDES = fdt.h libfdt.h
8LIBFDT_EXTRA = libfdt_internal.h
9LIBFDT_LIB = libfdt/libfdt.a
10
11LIBFDT_OBJS = $(LIBFDT_SRCS:%.c=%.o)
12
13$(LIBFDT_objdir)/$(LIBFDT_LIB): $(addprefix $(LIBFDT_objdir)/,$(LIBFDT_OBJS))
14
diff --git a/arch/powerpc/boot/libfdt/fdt.c b/arch/powerpc/boot/libfdt/fdt.c
new file mode 100644
index 000000000000..586a36136db2
--- /dev/null
+++ b/arch/powerpc/boot/libfdt/fdt.c
@@ -0,0 +1,156 @@
1/*
2 * libfdt - Flat Device Tree manipulation
3 * Copyright (C) 2006 David Gibson, IBM Corporation.
4 *
5 * libfdt is dual licensed: you can use it either under the terms of
6 * the GPL, or the BSD license, at your option.
7 *
8 * a) This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21 * MA 02110-1301 USA
22 *
23 * Alternatively,
24 *
25 * b) Redistribution and use in source and binary forms, with or
26 * without modification, are permitted provided that the following
27 * conditions are met:
28 *
29 * 1. Redistributions of source code must retain the above
30 * copyright notice, this list of conditions and the following
31 * disclaimer.
32 * 2. Redistributions in binary form must reproduce the above
33 * copyright notice, this list of conditions and the following
34 * disclaimer in the documentation and/or other materials
35 * provided with the distribution.
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
38 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
39 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
42 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 */
51#include "libfdt_env.h"
52
53#include <fdt.h>
54#include <libfdt.h>
55
56#include "libfdt_internal.h"
57
58int fdt_check_header(const void *fdt)
59{
60 if (fdt_magic(fdt) == FDT_MAGIC) {
61 /* Complete tree */
62 if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION)
63 return -FDT_ERR_BADVERSION;
64 if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION)
65 return -FDT_ERR_BADVERSION;
66 } else if (fdt_magic(fdt) == SW_MAGIC) {
67 /* Unfinished sequential-write blob */
68 if (fdt_size_dt_struct(fdt) == 0)
69 return -FDT_ERR_BADSTATE;
70 } else {
71 return -FDT_ERR_BADMAGIC;
72 }
73
74 return 0;
75}
76
77const void *fdt_offset_ptr(const void *fdt, int offset, int len)
78{
79 const void *p;
80
81 if (fdt_version(fdt) >= 0x11)
82 if (((offset + len) < offset)
83 || ((offset + len) > fdt_size_dt_struct(fdt)))
84 return NULL;
85
86 p = _fdt_offset_ptr(fdt, offset);
87
88 if (p + len < p)
89 return NULL;
90 return p;
91}
92
93uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset)
94{
95 const uint32_t *tagp, *lenp;
96 uint32_t tag;
97 const char *p;
98
99 if (offset % FDT_TAGSIZE)
100 return -1;
101
102 tagp = fdt_offset_ptr(fdt, offset, FDT_TAGSIZE);
103 if (! tagp)
104 return FDT_END; /* premature end */
105 tag = fdt32_to_cpu(*tagp);
106 offset += FDT_TAGSIZE;
107
108 switch (tag) {
109 case FDT_BEGIN_NODE:
110 /* skip name */
111 do {
112 p = fdt_offset_ptr(fdt, offset++, 1);
113 } while (p && (*p != '\0'));
114 if (! p)
115 return FDT_END;
116 break;
117 case FDT_PROP:
118 lenp = fdt_offset_ptr(fdt, offset, sizeof(*lenp));
119 if (! lenp)
120 return FDT_END;
121 /* skip name offset, length and value */
122 offset += 2*FDT_TAGSIZE + fdt32_to_cpu(*lenp);
123 break;
124 }
125
126 if (nextoffset)
127 *nextoffset = ALIGN(offset, FDT_TAGSIZE);
128
129 return tag;
130}
131
132const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
133{
134 int len = strlen(s) + 1;
135 const char *last = strtab + tabsize - len;
136 const char *p;
137
138 for (p = strtab; p <= last; p++)
139 if (memeq(p, s, len))
140 return p;
141 return NULL;
142}
143
144int fdt_move(const void *fdt, void *buf, int bufsize)
145{
146 int err = fdt_check_header(fdt);
147
148 if (err)
149 return err;
150
151 if (fdt_totalsize(fdt) > bufsize)
152 return -FDT_ERR_NOSPACE;
153
154 memmove(buf, fdt, fdt_totalsize(fdt));
155 return 0;
156}
diff --git a/arch/powerpc/boot/libfdt/fdt.h b/arch/powerpc/boot/libfdt/fdt.h
new file mode 100644
index 000000000000..48ccfd910000
--- /dev/null
+++ b/arch/powerpc/boot/libfdt/fdt.h
@@ -0,0 +1,60 @@
1#ifndef _FDT_H
2#define _FDT_H
3
4#ifndef __ASSEMBLY__
5
6struct fdt_header {
7 uint32_t magic; /* magic word FDT_MAGIC */
8 uint32_t totalsize; /* total size of DT block */
9 uint32_t off_dt_struct; /* offset to structure */
10 uint32_t off_dt_strings; /* offset to strings */
11 uint32_t off_mem_rsvmap; /* offset to memory reserve map */
12 uint32_t version; /* format version */
13 uint32_t last_comp_version; /* last compatible version */
14
15 /* version 2 fields below */
16 uint32_t boot_cpuid_phys; /* Which physical CPU id we're
17 booting on */
18 /* version 3 fields below */
19 uint32_t size_dt_strings; /* size of the strings block */
20
21 /* version 17 fields below */
22 uint32_t size_dt_struct; /* size of the structure block */
23};
24
25struct fdt_reserve_entry {
26 uint64_t address;
27 uint64_t size;
28};
29
30struct fdt_node_header {
31 uint32_t tag;
32 char name[0];
33};
34
35struct fdt_property {
36 uint32_t tag;
37 uint32_t len;
38 uint32_t nameoff;
39 char data[0];
40};
41
42#endif /* !__ASSEMBLY */
43
44#define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */
45#define FDT_TAGSIZE sizeof(uint32_t)
46
47#define FDT_BEGIN_NODE 0x1 /* Start node: full name */
48#define FDT_END_NODE 0x2 /* End node */
49#define FDT_PROP 0x3 /* Property: name off,
50 size, content */
51#define FDT_NOP 0x4 /* nop */
52#define FDT_END 0x9
53
54#define FDT_V1_SIZE (7*sizeof(uint32_t))
55#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(uint32_t))
56#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(uint32_t))
57#define FDT_V16_SIZE FDT_V3_SIZE
58#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(uint32_t))
59
60#endif /* _FDT_H */
diff --git a/arch/powerpc/boot/libfdt/fdt_ro.c b/arch/powerpc/boot/libfdt/fdt_ro.c
new file mode 100644
index 000000000000..12a37d59f96e
--- /dev/null
+++ b/arch/powerpc/boot/libfdt/fdt_ro.c
@@ -0,0 +1,583 @@
1/*
2 * libfdt - Flat Device Tree manipulation
3 * Copyright (C) 2006 David Gibson, IBM Corporation.
4 *
5 * libfdt is dual licensed: you can use it either under the terms of
6 * the GPL, or the BSD license, at your option.
7 *
8 * a) This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21 * MA 02110-1301 USA
22 *
23 * Alternatively,
24 *
25 * b) Redistribution and use in source and binary forms, with or
26 * without modification, are permitted provided that the following
27 * conditions are met:
28 *
29 * 1. Redistributions of source code must retain the above
30 * copyright notice, this list of conditions and the following
31 * disclaimer.
32 * 2. Redistributions in binary form must reproduce the above
33 * copyright notice, this list of conditions and the following
34 * disclaimer in the documentation and/or other materials
35 * provided with the distribution.
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
38 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
39 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
42 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 */
51#include "libfdt_env.h"
52
53#include <fdt.h>
54#include <libfdt.h>
55
56#include "libfdt_internal.h"
57
58#define CHECK_HEADER(fdt) \
59 { \
60 int err; \
61 if ((err = fdt_check_header(fdt)) != 0) \
62 return err; \
63 }
64
65static int nodename_eq(const void *fdt, int offset,
66 const char *s, int len)
67{
68 const char *p = fdt_offset_ptr(fdt, offset, len+1);
69
70 if (! p)
71 /* short match */
72 return 0;
73
74 if (memcmp(p, s, len) != 0)
75 return 0;
76
77 if (p[len] == '\0')
78 return 1;
79 else if (!memchr(s, '@', len) && (p[len] == '@'))
80 return 1;
81 else
82 return 0;
83}
84
85const char *fdt_string(const void *fdt, int stroffset)
86{
87 return (char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
88}
89
90int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
91{
92 CHECK_HEADER(fdt);
93 *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);
94 *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);
95 return 0;
96}
97
98int fdt_num_mem_rsv(const void *fdt)
99{
100 int i = 0;
101
102 while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)
103 i++;
104 return i;
105}
106
107int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
108 const char *name, int namelen)
109{
110 int level = 0;
111 uint32_t tag;
112 int offset, nextoffset;
113
114 CHECK_HEADER(fdt);
115
116 tag = fdt_next_tag(fdt, parentoffset, &nextoffset);
117 if (tag != FDT_BEGIN_NODE)
118 return -FDT_ERR_BADOFFSET;
119
120 do {
121 offset = nextoffset;
122 tag = fdt_next_tag(fdt, offset, &nextoffset);
123
124 switch (tag) {
125 case FDT_END:
126 return -FDT_ERR_TRUNCATED;
127
128 case FDT_BEGIN_NODE:
129 level++;
130 if (level != 1)
131 continue;
132 if (nodename_eq(fdt, offset+FDT_TAGSIZE, name, namelen))
133 /* Found it! */
134 return offset;
135 break;
136
137 case FDT_END_NODE:
138 level--;
139 break;
140
141 case FDT_PROP:
142 case FDT_NOP:
143 break;
144
145 default:
146 return -FDT_ERR_BADSTRUCTURE;
147 }
148 } while (level >= 0);
149
150 return -FDT_ERR_NOTFOUND;
151}
152
153int fdt_subnode_offset(const void *fdt, int parentoffset,
154 const char *name)
155{
156 return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));
157}
158
159int fdt_path_offset(const void *fdt, const char *path)
160{
161 const char *end = path + strlen(path);
162 const char *p = path;
163 int offset = 0;
164
165 CHECK_HEADER(fdt);
166
167 if (*path != '/')
168 return -FDT_ERR_BADPATH;
169
170 while (*p) {
171 const char *q;
172
173 while (*p == '/')
174 p++;
175 if (! *p)
176 return offset;
177 q = strchr(p, '/');
178 if (! q)
179 q = end;
180
181 offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);
182 if (offset < 0)
183 return offset;
184
185 p = q;
186 }
187
188 return offset;
189}
190
191const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
192{
193 const struct fdt_node_header *nh;
194 int err;
195
196 if ((err = fdt_check_header(fdt)) != 0)
197 goto fail;
198
199 err = -FDT_ERR_BADOFFSET;
200 nh = fdt_offset_ptr(fdt, nodeoffset, sizeof(*nh));
201 if (!nh || (fdt32_to_cpu(nh->tag) != FDT_BEGIN_NODE))
202 goto fail;
203
204 if (len)
205 *len = strlen(nh->name);
206
207 return nh->name;
208
209 fail:
210 if (len)
211 *len = err;
212 return NULL;
213}
214
215const struct fdt_property *fdt_get_property(const void *fdt,
216 int nodeoffset,
217 const char *name, int *lenp)
218{
219 uint32_t tag;
220 const struct fdt_property *prop;
221 int namestroff;
222 int offset, nextoffset;
223 int err;
224
225 if ((err = fdt_check_header(fdt)) != 0)
226 goto fail;
227
228 err = -FDT_ERR_BADOFFSET;
229 if (nodeoffset % FDT_TAGSIZE)
230 goto fail;
231
232 tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
233 if (tag != FDT_BEGIN_NODE)
234 goto fail;
235
236 do {
237 offset = nextoffset;
238
239 tag = fdt_next_tag(fdt, offset, &nextoffset);
240 switch (tag) {
241 case FDT_END:
242 err = -FDT_ERR_TRUNCATED;
243 goto fail;
244
245 case FDT_BEGIN_NODE:
246 case FDT_END_NODE:
247 case FDT_NOP:
248 break;
249
250 case FDT_PROP:
251 err = -FDT_ERR_BADSTRUCTURE;
252 prop = fdt_offset_ptr(fdt, offset, sizeof(*prop));
253 if (! prop)
254 goto fail;
255 namestroff = fdt32_to_cpu(prop->nameoff);
256 if (streq(fdt_string(fdt, namestroff), name)) {
257 /* Found it! */
258 int len = fdt32_to_cpu(prop->len);
259 prop = fdt_offset_ptr(fdt, offset,
260 sizeof(*prop)+len);
261 if (! prop)
262 goto fail;
263
264 if (lenp)
265 *lenp = len;
266
267 return prop;
268 }
269 break;
270
271 default:
272 err = -FDT_ERR_BADSTRUCTURE;
273 goto fail;
274 }
275 } while ((tag != FDT_BEGIN_NODE) && (tag != FDT_END_NODE));
276
277 err = -FDT_ERR_NOTFOUND;
278 fail:
279 if (lenp)
280 *lenp = err;
281 return NULL;
282}
283
284const void *fdt_getprop(const void *fdt, int nodeoffset,
285 const char *name, int *lenp)
286{
287 const struct fdt_property *prop;
288
289 prop = fdt_get_property(fdt, nodeoffset, name, lenp);
290 if (! prop)
291 return NULL;
292
293 return prop->data;
294}
295
296uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
297{
298 const uint32_t *php;
299 int len;
300
301 php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);
302 if (!php || (len != sizeof(*php)))
303 return 0;
304
305 return fdt32_to_cpu(*php);
306}
307
308int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
309{
310 uint32_t tag;
311 int p = 0, overflow = 0;
312 int offset, nextoffset, namelen;
313 const char *name;
314
315 CHECK_HEADER(fdt);
316
317 tag = fdt_next_tag(fdt, 0, &nextoffset);
318 if (tag != FDT_BEGIN_NODE)
319 return -FDT_ERR_BADSTRUCTURE;
320
321 if (buflen < 2)
322 return -FDT_ERR_NOSPACE;
323 buf[0] = '/';
324 p = 1;
325
326 while (nextoffset <= nodeoffset) {
327 offset = nextoffset;
328 tag = fdt_next_tag(fdt, offset, &nextoffset);
329 switch (tag) {
330 case FDT_END:
331 return -FDT_ERR_BADOFFSET;
332
333 case FDT_BEGIN_NODE:
334 name = fdt_get_name(fdt, offset, &namelen);
335 if (!name)
336 return namelen;
337 if (overflow || ((p + namelen + 1) > buflen)) {
338 overflow++;
339 break;
340 }
341 memcpy(buf + p, name, namelen);
342 p += namelen;
343 buf[p++] = '/';
344 break;
345
346 case FDT_END_NODE:
347 if (overflow) {
348 overflow--;
349 break;
350 }
351 do {
352 p--;
353 } while (buf[p-1] != '/');
354 break;
355
356 case FDT_PROP:
357 case FDT_NOP:
358 break;
359
360 default:
361 return -FDT_ERR_BADSTRUCTURE;
362 }
363 }
364
365 if (overflow)
366 return -FDT_ERR_NOSPACE;
367
368 if (p > 1) /* special case so that root path is "/", not "" */
369 p--;
370 buf[p] = '\0';
371 return p;
372}
373
374int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
375 int supernodedepth, int *nodedepth)
376{
377 int level = -1;
378 uint32_t tag;
379 int offset, nextoffset = 0;
380 int supernodeoffset = -FDT_ERR_INTERNAL;
381
382 CHECK_HEADER(fdt);
383
384 if (supernodedepth < 0)
385 return -FDT_ERR_NOTFOUND;
386
387 do {
388 offset = nextoffset;
389 tag = fdt_next_tag(fdt, offset, &nextoffset);
390 switch (tag) {
391 case FDT_END:
392 return -FDT_ERR_BADOFFSET;
393
394 case FDT_BEGIN_NODE:
395 level++;
396 if (level == supernodedepth)
397 supernodeoffset = offset;
398 break;
399
400 case FDT_END_NODE:
401 level--;
402 break;
403
404 case FDT_PROP:
405 case FDT_NOP:
406 break;
407
408 default:
409 return -FDT_ERR_BADSTRUCTURE;
410 }
411 } while (offset < nodeoffset);
412
413 if (nodedepth)
414 *nodedepth = level;
415
416 if (supernodedepth > level)
417 return -FDT_ERR_NOTFOUND;
418 return supernodeoffset;
419}
420
421int fdt_node_depth(const void *fdt, int nodeoffset)
422{
423 int nodedepth;
424 int err;
425
426 err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
427 if (err)
428 return (err < 0) ? err : -FDT_ERR_INTERNAL;
429 return nodedepth;
430}
431
432int fdt_parent_offset(const void *fdt, int nodeoffset)
433{
434 int nodedepth = fdt_node_depth(fdt, nodeoffset);
435
436 if (nodedepth < 0)
437 return nodedepth;
438 return fdt_supernode_atdepth_offset(fdt, nodeoffset,
439 nodedepth - 1, NULL);
440}
441
442int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
443 const char *propname,
444 const void *propval, int proplen)
445{
446 uint32_t tag;
447 int offset, nextoffset;
448 const void *val;
449 int len;
450
451 CHECK_HEADER(fdt);
452
453 if (startoffset >= 0) {
454 tag = fdt_next_tag(fdt, startoffset, &nextoffset);
455 if (tag != FDT_BEGIN_NODE)
456 return -FDT_ERR_BADOFFSET;
457 } else {
458 nextoffset = 0;
459 }
460
461 /* FIXME: The algorithm here is pretty horrible: we scan each
462 * property of a node in fdt_getprop(), then if that didn't
463 * find what we want, we scan over them again making our way
464 * to the next node. Still it's the easiest to implement
465 * approach; performance can come later. */
466 do {
467 offset = nextoffset;
468 tag = fdt_next_tag(fdt, offset, &nextoffset);
469
470 switch (tag) {
471 case FDT_BEGIN_NODE:
472 val = fdt_getprop(fdt, offset, propname, &len);
473 if (val
474 && (len == proplen)
475 && (memcmp(val, propval, len) == 0))
476 return offset;
477 break;
478
479 case FDT_PROP:
480 case FDT_END:
481 case FDT_END_NODE:
482 case FDT_NOP:
483 break;
484
485 default:
486 return -FDT_ERR_BADSTRUCTURE;
487 }
488 } while (tag != FDT_END);
489
490 return -FDT_ERR_NOTFOUND;
491}
492
493int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
494{
495 if ((phandle == 0) || (phandle == -1))
496 return -FDT_ERR_BADPHANDLE;
497 phandle = cpu_to_fdt32(phandle);
498 return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle",
499 &phandle, sizeof(phandle));
500}
501
502int _stringlist_contains(const void *strlist, int listlen, const char *str)
503{
504 int len = strlen(str);
505 const void *p;
506
507 while (listlen >= len) {
508 if (memcmp(str, strlist, len+1) == 0)
509 return 1;
510 p = memchr(strlist, '\0', listlen);
511 if (!p)
512 return 0; /* malformed strlist.. */
513 listlen -= (p-strlist) + 1;
514 strlist = p + 1;
515 }
516 return 0;
517}
518
519int fdt_node_check_compatible(const void *fdt, int nodeoffset,
520 const char *compatible)
521{
522 const void *prop;
523 int len;
524
525 prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);
526 if (!prop)
527 return len;
528 if (_stringlist_contains(prop, len, compatible))
529 return 0;
530 else
531 return 1;
532}
533
534int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
535 const char *compatible)
536{
537 uint32_t tag;
538 int offset, nextoffset;
539 int err;
540
541 CHECK_HEADER(fdt);
542
543 if (startoffset >= 0) {
544 tag = fdt_next_tag(fdt, startoffset, &nextoffset);
545 if (tag != FDT_BEGIN_NODE)
546 return -FDT_ERR_BADOFFSET;
547 } else {
548 nextoffset = 0;
549 }
550
551 /* FIXME: The algorithm here is pretty horrible: we scan each
552 * property of a node in fdt_node_check_compatible(), then if
553 * that didn't find what we want, we scan over them again
554 * making our way to the next node. Still it's the easiest to
555 * implement approach; performance can come later. */
556 do {
557 offset = nextoffset;
558 tag = fdt_next_tag(fdt, offset, &nextoffset);
559
560 switch (tag) {
561 case FDT_BEGIN_NODE:
562 err = fdt_node_check_compatible(fdt, offset,
563 compatible);
564 if ((err < 0)
565 && (err != -FDT_ERR_NOTFOUND))
566 return err;
567 else if (err == 0)
568 return offset;
569 break;
570
571 case FDT_PROP:
572 case FDT_END:
573 case FDT_END_NODE:
574 case FDT_NOP:
575 break;
576
577 default:
578 return -FDT_ERR_BADSTRUCTURE;
579 }
580 } while (tag != FDT_END);
581
582 return -FDT_ERR_NOTFOUND;
583}
diff --git a/arch/powerpc/boot/libfdt/fdt_rw.c b/arch/powerpc/boot/libfdt/fdt_rw.c
new file mode 100644
index 000000000000..6673f8ec962a
--- /dev/null
+++ b/arch/powerpc/boot/libfdt/fdt_rw.c
@@ -0,0 +1,447 @@
1/*
2 * libfdt - Flat Device Tree manipulation
3 * Copyright (C) 2006 David Gibson, IBM Corporation.
4 *
5 * libfdt is dual licensed: you can use it either under the terms of
6 * the GPL, or the BSD license, at your option.
7 *
8 * a) This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21 * MA 02110-1301 USA
22 *
23 * Alternatively,
24 *
25 * b) Redistribution and use in source and binary forms, with or
26 * without modification, are permitted provided that the following
27 * conditions are met:
28 *
29 * 1. Redistributions of source code must retain the above
30 * copyright notice, this list of conditions and the following
31 * disclaimer.
32 * 2. Redistributions in binary form must reproduce the above
33 * copyright notice, this list of conditions and the following
34 * disclaimer in the documentation and/or other materials
35 * provided with the distribution.
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
38 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
39 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
42 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 */
51#include "libfdt_env.h"
52
53#include <fdt.h>
54#include <libfdt.h>
55
56#include "libfdt_internal.h"
57
58static int _blocks_misordered(const void *fdt,
59 int mem_rsv_size, int struct_size)
60{
61 return (fdt_off_mem_rsvmap(fdt) < ALIGN(sizeof(struct fdt_header), 8))
62 || (fdt_off_dt_struct(fdt) <
63 (fdt_off_mem_rsvmap(fdt) + mem_rsv_size))
64 || (fdt_off_dt_strings(fdt) <
65 (fdt_off_dt_struct(fdt) + struct_size))
66 || (fdt_totalsize(fdt) <
67 (fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt)));
68}
69
70static int rw_check_header(void *fdt)
71{
72 int err;
73
74 if ((err = fdt_check_header(fdt)))
75 return err;
76 if (fdt_version(fdt) < 17)
77 return -FDT_ERR_BADVERSION;
78 if (_blocks_misordered(fdt, sizeof(struct fdt_reserve_entry),
79 fdt_size_dt_struct(fdt)))
80 return -FDT_ERR_BADLAYOUT;
81 if (fdt_version(fdt) > 17)
82 fdt_set_version(fdt, 17);
83
84 return 0;
85}
86
87#define RW_CHECK_HEADER(fdt) \
88 { \
89 int err; \
90 if ((err = rw_check_header(fdt)) != 0) \
91 return err; \
92 }
93
94static inline int _blob_data_size(void *fdt)
95{
96 return fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
97}
98
99static int _blob_splice(void *fdt, void *p, int oldlen, int newlen)
100{
101 void *end = fdt + _blob_data_size(fdt);
102
103 if (((p + oldlen) < p) || ((p + oldlen) > end))
104 return -FDT_ERR_BADOFFSET;
105 if ((end - oldlen + newlen) > (fdt + fdt_totalsize(fdt)))
106 return -FDT_ERR_NOSPACE;
107 memmove(p + newlen, p + oldlen, end - p - oldlen);
108 return 0;
109}
110
111static int _blob_splice_mem_rsv(void *fdt, struct fdt_reserve_entry *p,
112 int oldn, int newn)
113{
114 int delta = (newn - oldn) * sizeof(*p);
115 int err;
116 err = _blob_splice(fdt, p, oldn * sizeof(*p), newn * sizeof(*p));
117 if (err)
118 return err;
119 fdt_set_off_dt_struct(fdt, fdt_off_dt_struct(fdt) + delta);
120 fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
121 return 0;
122}
123
124static int _blob_splice_struct(void *fdt, void *p,
125 int oldlen, int newlen)
126{
127 int delta = newlen - oldlen;
128 int err;
129
130 if ((err = _blob_splice(fdt, p, oldlen, newlen)))
131 return err;
132
133 fdt_set_size_dt_struct(fdt, fdt_size_dt_struct(fdt) + delta);
134 fdt_set_off_dt_strings(fdt, fdt_off_dt_strings(fdt) + delta);
135 return 0;
136}
137
138static int _blob_splice_string(void *fdt, int newlen)
139{
140 void *p = fdt + fdt_off_dt_strings(fdt) + fdt_size_dt_strings(fdt);
141 int err;
142
143 if ((err = _blob_splice(fdt, p, 0, newlen)))
144 return err;
145
146 fdt_set_size_dt_strings(fdt, fdt_size_dt_strings(fdt) + newlen);
147 return 0;
148}
149
150static int _find_add_string(void *fdt, const char *s)
151{
152 char *strtab = (char *)fdt + fdt_off_dt_strings(fdt);
153 const char *p;
154 char *new;
155 int len = strlen(s) + 1;
156 int err;
157
158 p = _fdt_find_string(strtab, fdt_size_dt_strings(fdt), s);
159 if (p)
160 /* found it */
161 return (p - strtab);
162
163 new = strtab + fdt_size_dt_strings(fdt);
164 err = _blob_splice_string(fdt, len);
165 if (err)
166 return err;
167
168 memcpy(new, s, len);
169 return (new - strtab);
170}
171
172int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size)
173{
174 struct fdt_reserve_entry *re;
175 int err;
176
177 if ((err = rw_check_header(fdt)))
178 return err;
179
180 re = _fdt_mem_rsv_w(fdt, fdt_num_mem_rsv(fdt));
181 err = _blob_splice_mem_rsv(fdt, re, 0, 1);
182 if (err)
183 return err;
184
185 re->address = cpu_to_fdt64(address);
186 re->size = cpu_to_fdt64(size);
187 return 0;
188}
189
190int fdt_del_mem_rsv(void *fdt, int n)
191{
192 struct fdt_reserve_entry *re = _fdt_mem_rsv_w(fdt, n);
193 int err;
194
195 if ((err = rw_check_header(fdt)))
196 return err;
197 if (n >= fdt_num_mem_rsv(fdt))
198 return -FDT_ERR_NOTFOUND;
199
200 err = _blob_splice_mem_rsv(fdt, re, 1, 0);
201 if (err)
202 return err;
203 return 0;
204}
205
206static int _resize_property(void *fdt, int nodeoffset, const char *name, int len,
207 struct fdt_property **prop)
208{
209 int oldlen;
210 int err;
211
212 *prop = fdt_get_property_w(fdt, nodeoffset, name, &oldlen);
213 if (! (*prop))
214 return oldlen;
215
216 if ((err = _blob_splice_struct(fdt, (*prop)->data,
217 ALIGN(oldlen, FDT_TAGSIZE),
218 ALIGN(len, FDT_TAGSIZE))))
219 return err;
220
221 (*prop)->len = cpu_to_fdt32(len);
222 return 0;
223}
224
225static int _add_property(void *fdt, int nodeoffset, const char *name, int len,
226 struct fdt_property **prop)
227{
228 uint32_t tag;
229 int proplen;
230 int nextoffset;
231 int namestroff;
232 int err;
233
234 tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
235 if (tag != FDT_BEGIN_NODE)
236 return -FDT_ERR_BADOFFSET;
237
238 namestroff = _find_add_string(fdt, name);
239 if (namestroff < 0)
240 return namestroff;
241
242 *prop = _fdt_offset_ptr_w(fdt, nextoffset);
243 proplen = sizeof(**prop) + ALIGN(len, FDT_TAGSIZE);
244
245 err = _blob_splice_struct(fdt, *prop, 0, proplen);
246 if (err)
247 return err;
248
249 (*prop)->tag = cpu_to_fdt32(FDT_PROP);
250 (*prop)->nameoff = cpu_to_fdt32(namestroff);
251 (*prop)->len = cpu_to_fdt32(len);
252 return 0;
253}
254
255int fdt_setprop(void *fdt, int nodeoffset, const char *name,
256 const void *val, int len)
257{
258 struct fdt_property *prop;
259 int err;
260
261 if ((err = rw_check_header(fdt)))
262 return err;
263
264 err = _resize_property(fdt, nodeoffset, name, len, &prop);
265 if (err == -FDT_ERR_NOTFOUND)
266 err = _add_property(fdt, nodeoffset, name, len, &prop);
267 if (err)
268 return err;
269
270 memcpy(prop->data, val, len);
271 return 0;
272}
273
274int fdt_delprop(void *fdt, int nodeoffset, const char *name)
275{
276 struct fdt_property *prop;
277 int len, proplen;
278
279 RW_CHECK_HEADER(fdt);
280
281 prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
282 if (! prop)
283 return len;
284
285 proplen = sizeof(*prop) + ALIGN(len, FDT_TAGSIZE);
286 return _blob_splice_struct(fdt, prop, proplen, 0);
287}
288
289int fdt_add_subnode_namelen(void *fdt, int parentoffset,
290 const char *name, int namelen)
291{
292 struct fdt_node_header *nh;
293 int offset, nextoffset;
294 int nodelen;
295 int err;
296 uint32_t tag;
297 uint32_t *endtag;
298
299 RW_CHECK_HEADER(fdt);
300
301 offset = fdt_subnode_offset_namelen(fdt, parentoffset, name, namelen);
302 if (offset >= 0)
303 return -FDT_ERR_EXISTS;
304 else if (offset != -FDT_ERR_NOTFOUND)
305 return offset;
306
307 /* Try to place the new node after the parent's properties */
308 fdt_next_tag(fdt, parentoffset, &nextoffset); /* skip the BEGIN_NODE */
309 do {
310 offset = nextoffset;
311 tag = fdt_next_tag(fdt, offset, &nextoffset);
312 } while (tag == FDT_PROP);
313
314 nh = _fdt_offset_ptr_w(fdt, offset);
315 nodelen = sizeof(*nh) + ALIGN(namelen+1, FDT_TAGSIZE) + FDT_TAGSIZE;
316
317 err = _blob_splice_struct(fdt, nh, 0, nodelen);
318 if (err)
319 return err;
320
321 nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
322 memset(nh->name, 0, ALIGN(namelen+1, FDT_TAGSIZE));
323 memcpy(nh->name, name, namelen);
324 endtag = (uint32_t *)((void *)nh + nodelen - FDT_TAGSIZE);
325 *endtag = cpu_to_fdt32(FDT_END_NODE);
326
327 return offset;
328}
329
330int fdt_add_subnode(void *fdt, int parentoffset, const char *name)
331{
332 return fdt_add_subnode_namelen(fdt, parentoffset, name, strlen(name));
333}
334
335int fdt_del_node(void *fdt, int nodeoffset)
336{
337 int endoffset;
338
339 RW_CHECK_HEADER(fdt);
340
341 endoffset = _fdt_node_end_offset(fdt, nodeoffset);
342 if (endoffset < 0)
343 return endoffset;
344
345 return _blob_splice_struct(fdt, _fdt_offset_ptr_w(fdt, nodeoffset),
346 endoffset - nodeoffset, 0);
347}
348
349static void _packblocks(const void *fdt, void *buf,
350 int mem_rsv_size, int struct_size)
351{
352 int mem_rsv_off, struct_off, strings_off;
353
354 mem_rsv_off = ALIGN(sizeof(struct fdt_header), 8);
355 struct_off = mem_rsv_off + mem_rsv_size;
356 strings_off = struct_off + struct_size;
357
358 memmove(buf + mem_rsv_off, fdt + fdt_off_mem_rsvmap(fdt), mem_rsv_size);
359 fdt_set_off_mem_rsvmap(buf, mem_rsv_off);
360
361 memmove(buf + struct_off, fdt + fdt_off_dt_struct(fdt), struct_size);
362 fdt_set_off_dt_struct(buf, struct_off);
363 fdt_set_size_dt_struct(buf, struct_size);
364
365 memmove(buf + strings_off, fdt + fdt_off_dt_strings(fdt),
366 fdt_size_dt_strings(fdt));
367 fdt_set_off_dt_strings(buf, strings_off);
368 fdt_set_size_dt_strings(buf, fdt_size_dt_strings(fdt));
369}
370
371int fdt_open_into(const void *fdt, void *buf, int bufsize)
372{
373 int err;
374 int mem_rsv_size, struct_size;
375 int newsize;
376 void *tmp;
377
378 err = fdt_check_header(fdt);
379 if (err)
380 return err;
381
382 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
383 * sizeof(struct fdt_reserve_entry);
384
385 if (fdt_version(fdt) >= 17) {
386 struct_size = fdt_size_dt_struct(fdt);
387 } else {
388 struct_size = 0;
389 while (fdt_next_tag(fdt, struct_size, &struct_size) != FDT_END)
390 ;
391 }
392
393 if (!_blocks_misordered(fdt, mem_rsv_size, struct_size)) {
394 /* no further work necessary */
395 err = fdt_move(fdt, buf, bufsize);
396 if (err)
397 return err;
398 fdt_set_version(buf, 17);
399 fdt_set_size_dt_struct(buf, struct_size);
400 fdt_set_totalsize(buf, bufsize);
401 return 0;
402 }
403
404 /* Need to reorder */
405 newsize = ALIGN(sizeof(struct fdt_header), 8) + mem_rsv_size
406 + struct_size + fdt_size_dt_strings(fdt);
407
408 if (bufsize < newsize)
409 return -FDT_ERR_NOSPACE;
410
411 if (((buf + newsize) <= fdt)
412 || (buf >= (fdt + fdt_totalsize(fdt)))) {
413 tmp = buf;
414 } else {
415 tmp = (void *)fdt + fdt_totalsize(fdt);
416 if ((tmp + newsize) > (buf + bufsize))
417 return -FDT_ERR_NOSPACE;
418 }
419
420 _packblocks(fdt, tmp, mem_rsv_size, struct_size);
421 memmove(buf, tmp, newsize);
422
423 fdt_set_magic(buf, FDT_MAGIC);
424 fdt_set_totalsize(buf, bufsize);
425 fdt_set_version(buf, 17);
426 fdt_set_last_comp_version(buf, 16);
427 fdt_set_boot_cpuid_phys(buf, fdt_boot_cpuid_phys(fdt));
428
429 return 0;
430}
431
432int fdt_pack(void *fdt)
433{
434 int mem_rsv_size;
435 int err;
436
437 err = rw_check_header(fdt);
438 if (err)
439 return err;
440
441 mem_rsv_size = (fdt_num_mem_rsv(fdt)+1)
442 * sizeof(struct fdt_reserve_entry);
443 _packblocks(fdt, fdt, mem_rsv_size, fdt_size_dt_struct(fdt));
444 fdt_set_totalsize(fdt, _blob_data_size(fdt));
445
446 return 0;
447}
diff --git a/arch/powerpc/boot/libfdt/fdt_strerror.c b/arch/powerpc/boot/libfdt/fdt_strerror.c
new file mode 100644
index 000000000000..f9d32ef5360a
--- /dev/null
+++ b/arch/powerpc/boot/libfdt/fdt_strerror.c
@@ -0,0 +1,96 @@
1/*
2 * libfdt - Flat Device Tree manipulation
3 * Copyright (C) 2006 David Gibson, IBM Corporation.
4 *
5 * libfdt is dual licensed: you can use it either under the terms of
6 * the GPL, or the BSD license, at your option.
7 *
8 * a) This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21 * MA 02110-1301 USA
22 *
23 * Alternatively,
24 *
25 * b) Redistribution and use in source and binary forms, with or
26 * without modification, are permitted provided that the following
27 * conditions are met:
28 *
29 * 1. Redistributions of source code must retain the above
30 * copyright notice, this list of conditions and the following
31 * disclaimer.
32 * 2. Redistributions in binary form must reproduce the above
33 * copyright notice, this list of conditions and the following
34 * disclaimer in the documentation and/or other materials
35 * provided with the distribution.
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
38 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
39 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
42 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 */
51#include "libfdt_env.h"
52
53#include <fdt.h>
54#include <libfdt.h>
55
56#include "libfdt_internal.h"
57
58struct errtabent {
59 const char *str;
60};
61
62#define ERRTABENT(val) \
63 [(val)] = { .str = #val, }
64
65static struct errtabent errtable[] = {
66 ERRTABENT(FDT_ERR_NOTFOUND),
67 ERRTABENT(FDT_ERR_EXISTS),
68 ERRTABENT(FDT_ERR_NOSPACE),
69
70 ERRTABENT(FDT_ERR_BADOFFSET),
71 ERRTABENT(FDT_ERR_BADPATH),
72 ERRTABENT(FDT_ERR_BADSTATE),
73
74 ERRTABENT(FDT_ERR_TRUNCATED),
75 ERRTABENT(FDT_ERR_BADMAGIC),
76 ERRTABENT(FDT_ERR_BADVERSION),
77 ERRTABENT(FDT_ERR_BADSTRUCTURE),
78 ERRTABENT(FDT_ERR_BADLAYOUT),
79};
80#define ERRTABSIZE (sizeof(errtable) / sizeof(errtable[0]))
81
82const char *fdt_strerror(int errval)
83{
84 if (errval > 0)
85 return "<valid offset/length>";
86 else if (errval == 0)
87 return "<no error>";
88 else if (errval > -ERRTABSIZE) {
89 const char *s = errtable[-errval].str;
90
91 if (s)
92 return s;
93 }
94
95 return "<unknown error>";
96}
diff --git a/arch/powerpc/boot/libfdt/fdt_sw.c b/arch/powerpc/boot/libfdt/fdt_sw.c
new file mode 100644
index 000000000000..dda2de34b2e0
--- /dev/null
+++ b/arch/powerpc/boot/libfdt/fdt_sw.c
@@ -0,0 +1,258 @@
1/*
2 * libfdt - Flat Device Tree manipulation
3 * Copyright (C) 2006 David Gibson, IBM Corporation.
4 *
5 * libfdt is dual licensed: you can use it either under the terms of
6 * the GPL, or the BSD license, at your option.
7 *
8 * a) This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21 * MA 02110-1301 USA
22 *
23 * Alternatively,
24 *
25 * b) Redistribution and use in source and binary forms, with or
26 * without modification, are permitted provided that the following
27 * conditions are met:
28 *
29 * 1. Redistributions of source code must retain the above
30 * copyright notice, this list of conditions and the following
31 * disclaimer.
32 * 2. Redistributions in binary form must reproduce the above
33 * copyright notice, this list of conditions and the following
34 * disclaimer in the documentation and/or other materials
35 * provided with the distribution.
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
38 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
39 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
42 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 */
51#include "libfdt_env.h"
52
53#include <fdt.h>
54#include <libfdt.h>
55
56#include "libfdt_internal.h"
57
58static int check_header_sw(void *fdt)
59{
60 if (fdt_magic(fdt) != SW_MAGIC)
61 return -FDT_ERR_BADMAGIC;
62 return 0;
63}
64
65static void *grab_space(void *fdt, int len)
66{
67 int offset = fdt_size_dt_struct(fdt);
68 int spaceleft;
69
70 spaceleft = fdt_totalsize(fdt) - fdt_off_dt_struct(fdt)
71 - fdt_size_dt_strings(fdt);
72
73 if ((offset + len < offset) || (offset + len > spaceleft))
74 return NULL;
75
76 fdt_set_size_dt_struct(fdt, offset + len);
77 return fdt_offset_ptr_w(fdt, offset, len);
78}
79
80int fdt_create(void *buf, int bufsize)
81{
82 void *fdt = buf;
83
84 if (bufsize < sizeof(struct fdt_header))
85 return -FDT_ERR_NOSPACE;
86
87 memset(buf, 0, bufsize);
88
89 fdt_set_magic(fdt, SW_MAGIC);
90 fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
91 fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
92 fdt_set_totalsize(fdt, bufsize);
93
94 fdt_set_off_mem_rsvmap(fdt, ALIGN(sizeof(struct fdt_header),
95 sizeof(struct fdt_reserve_entry)));
96 fdt_set_off_dt_struct(fdt, fdt_off_mem_rsvmap(fdt));
97 fdt_set_off_dt_strings(fdt, bufsize);
98
99 return 0;
100}
101
102int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size)
103{
104 struct fdt_reserve_entry *re;
105 int err = check_header_sw(fdt);
106 int offset;
107
108 if (err)
109 return err;
110 if (fdt_size_dt_struct(fdt))
111 return -FDT_ERR_BADSTATE;
112
113 offset = fdt_off_dt_struct(fdt);
114 if ((offset + sizeof(*re)) > fdt_totalsize(fdt))
115 return -FDT_ERR_NOSPACE;
116
117 re = (struct fdt_reserve_entry *)(fdt + offset);
118 re->address = cpu_to_fdt64(addr);
119 re->size = cpu_to_fdt64(size);
120
121 fdt_set_off_dt_struct(fdt, offset + sizeof(*re));
122
123 return 0;
124}
125
126int fdt_finish_reservemap(void *fdt)
127{
128 return fdt_add_reservemap_entry(fdt, 0, 0);
129}
130
131int fdt_begin_node(void *fdt, const char *name)
132{
133 struct fdt_node_header *nh;
134 int err = check_header_sw(fdt);
135 int namelen = strlen(name) + 1;
136
137 if (err)
138 return err;
139
140 nh = grab_space(fdt, sizeof(*nh) + ALIGN(namelen, FDT_TAGSIZE));
141 if (! nh)
142 return -FDT_ERR_NOSPACE;
143
144 nh->tag = cpu_to_fdt32(FDT_BEGIN_NODE);
145 memcpy(nh->name, name, namelen);
146 return 0;
147}
148
149int fdt_end_node(void *fdt)
150{
151 uint32_t *en;
152 int err = check_header_sw(fdt);
153
154 if (err)
155 return err;
156
157 en = grab_space(fdt, FDT_TAGSIZE);
158 if (! en)
159 return -FDT_ERR_NOSPACE;
160
161 *en = cpu_to_fdt32(FDT_END_NODE);
162 return 0;
163}
164
165static int find_add_string(void *fdt, const char *s)
166{
167 char *strtab = (char *)fdt + fdt_totalsize(fdt);
168 const char *p;
169 int strtabsize = fdt_size_dt_strings(fdt);
170 int len = strlen(s) + 1;
171 int struct_top, offset;
172
173 p = _fdt_find_string(strtab - strtabsize, strtabsize, s);
174 if (p)
175 return p - strtab;
176
177 /* Add it */
178 offset = -strtabsize - len;
179 struct_top = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
180 if (fdt_totalsize(fdt) + offset < struct_top)
181 return 0; /* no more room :( */
182
183 memcpy(strtab + offset, s, len);
184 fdt_set_size_dt_strings(fdt, strtabsize + len);
185 return offset;
186}
187
188int fdt_property(void *fdt, const char *name, const void *val, int len)
189{
190 struct fdt_property *prop;
191 int err = check_header_sw(fdt);
192 int nameoff;
193
194 if (err)
195 return err;
196
197 nameoff = find_add_string(fdt, name);
198 if (nameoff == 0)
199 return -FDT_ERR_NOSPACE;
200
201 prop = grab_space(fdt, sizeof(*prop) + ALIGN(len, FDT_TAGSIZE));
202 if (! prop)
203 return -FDT_ERR_NOSPACE;
204
205 prop->tag = cpu_to_fdt32(FDT_PROP);
206 prop->nameoff = cpu_to_fdt32(nameoff);
207 prop->len = cpu_to_fdt32(len);
208 memcpy(prop->data, val, len);
209 return 0;
210}
211
212int fdt_finish(void *fdt)
213{
214 int err = check_header_sw(fdt);
215 char *p = (char *)fdt;
216 uint32_t *end;
217 int oldstroffset, newstroffset;
218 uint32_t tag;
219 int offset, nextoffset;
220
221 if (err)
222 return err;
223
224 /* Add terminator */
225 end = grab_space(fdt, sizeof(*end));
226 if (! end)
227 return -FDT_ERR_NOSPACE;
228 *end = cpu_to_fdt32(FDT_END);
229
230 /* Relocate the string table */
231 oldstroffset = fdt_totalsize(fdt) - fdt_size_dt_strings(fdt);
232 newstroffset = fdt_off_dt_struct(fdt) + fdt_size_dt_struct(fdt);
233 memmove(p + newstroffset, p + oldstroffset, fdt_size_dt_strings(fdt));
234 fdt_set_off_dt_strings(fdt, newstroffset);
235
236 /* Walk the structure, correcting string offsets */
237 offset = 0;
238 while ((tag = fdt_next_tag(fdt, offset, &nextoffset)) != FDT_END) {
239 if (tag == FDT_PROP) {
240 struct fdt_property *prop =
241 fdt_offset_ptr_w(fdt, offset, sizeof(*prop));
242 int nameoff;
243
244 if (! prop)
245 return -FDT_ERR_BADSTRUCTURE;
246
247 nameoff = fdt32_to_cpu(prop->nameoff);
248 nameoff += fdt_size_dt_strings(fdt);
249 prop->nameoff = cpu_to_fdt32(nameoff);
250 }
251 offset = nextoffset;
252 }
253
254 /* Finally, adjust the header */
255 fdt_set_totalsize(fdt, newstroffset + fdt_size_dt_strings(fdt));
256 fdt_set_magic(fdt, FDT_MAGIC);
257 return 0;
258}
diff --git a/arch/powerpc/boot/libfdt/fdt_wip.c b/arch/powerpc/boot/libfdt/fdt_wip.c
new file mode 100644
index 000000000000..88e24b8318f4
--- /dev/null
+++ b/arch/powerpc/boot/libfdt/fdt_wip.c
@@ -0,0 +1,144 @@
1/*
2 * libfdt - Flat Device Tree manipulation
3 * Copyright (C) 2006 David Gibson, IBM Corporation.
4 *
5 * libfdt is dual licensed: you can use it either under the terms of
6 * the GPL, or the BSD license, at your option.
7 *
8 * a) This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of the
11 * License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this library; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
21 * MA 02110-1301 USA
22 *
23 * Alternatively,
24 *
25 * b) Redistribution and use in source and binary forms, with or
26 * without modification, are permitted provided that the following
27 * conditions are met:
28 *
29 * 1. Redistributions of source code must retain the above
30 * copyright notice, this list of conditions and the following
31 * disclaimer.
32 * 2. Redistributions in binary form must reproduce the above
33 * copyright notice, this list of conditions and the following
34 * disclaimer in the documentation and/or other materials
35 * provided with the distribution.
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
38 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
39 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
40 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
41 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
42 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
47 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
48 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
49 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
50 */
51#include "libfdt_env.h"
52
53#include <fdt.h>
54#include <libfdt.h>
55
56#include "libfdt_internal.h"
57
58int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
59 const void *val, int len)
60{
61 void *propval;
62 int proplen;
63
64 propval = fdt_getprop_w(fdt, nodeoffset, name, &proplen);
65 if (! propval)
66 return proplen;
67
68 if (proplen != len)
69 return -FDT_ERR_NOSPACE;
70
71 memcpy(propval, val, len);
72 return 0;
73}
74
75static void nop_region(void *start, int len)
76{
77 uint32_t *p;
78
79 for (p = start; (void *)p < (start + len); p++)
80 *p = cpu_to_fdt32(FDT_NOP);
81}
82
83int fdt_nop_property(void *fdt, int nodeoffset, const char *name)
84{
85 struct fdt_property *prop;
86 int len;
87
88 prop = fdt_get_property_w(fdt, nodeoffset, name, &len);
89 if (! prop)
90 return len;
91
92 nop_region(prop, len + sizeof(*prop));
93
94 return 0;
95}
96
97int _fdt_node_end_offset(void *fdt, int nodeoffset)
98{
99 int level = 0;
100 uint32_t tag;
101 int offset, nextoffset;
102
103 tag = fdt_next_tag(fdt, nodeoffset, &nextoffset);
104 if (tag != FDT_BEGIN_NODE)
105 return -FDT_ERR_BADOFFSET;
106 do {
107 offset = nextoffset;
108 tag = fdt_next_tag(fdt, offset, &nextoffset);
109
110 switch (tag) {
111 case FDT_END:
112 return offset;
113
114 case FDT_BEGIN_NODE:
115 level++;
116 break;
117
118 case FDT_END_NODE:
119 level--;
120 break;
121
122 case FDT_PROP:
123 case FDT_NOP:
124 break;
125
126 default:
127 return -FDT_ERR_BADSTRUCTURE;
128 }
129 } while (level >= 0);
130
131 return nextoffset;
132}
133
134int fdt_nop_node(void *fdt, int nodeoffset)
135{
136 int endoffset;
137
138 endoffset = _fdt_node_end_offset(fdt, nodeoffset);
139 if (endoffset < 0)
140 return endoffset;
141
142 nop_region(fdt_offset_ptr_w(fdt, nodeoffset, 0), endoffset - nodeoffset);
143 return 0;
144}
diff --git a/arch/powerpc/boot/libfdt/libfdt.h b/arch/powerpc/boot/libfdt/libfdt.h
new file mode 100644
index 000000000000..6b2fb92ea357
--- /dev/null
+++ b/arch/powerpc/boot/libfdt/libfdt.h
@@ -0,0 +1,721 @@
1#ifndef _LIBFDT_H
2#define _LIBFDT_H
3/*
4 * libfdt - Flat Device Tree manipulation
5 * Copyright (C) 2006 David Gibson, IBM Corporation.
6 *
7 * libfdt is dual licensed: you can use it either under the terms of
8 * the GPL, or the BSD license, at your option.
9 *
10 * a) This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of the
13 * License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public
21 * License along with this library; if not, write to the Free
22 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
23 * MA 02110-1301 USA
24 *
25 * Alternatively,
26 *
27 * b) Redistribution and use in source and binary forms, with or
28 * without modification, are permitted provided that the following
29 * conditions are met:
30 *
31 * 1. Redistributions of source code must retain the above
32 * copyright notice, this list of conditions and the following
33 * disclaimer.
34 * 2. Redistributions in binary form must reproduce the above
35 * copyright notice, this list of conditions and the following
36 * disclaimer in the documentation and/or other materials
37 * provided with the distribution.
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
40 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
41 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
42 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
44 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
49 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
50 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
51 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 */
53
54#include <libfdt_env.h>
55#include <fdt.h>
56
57#define FDT_FIRST_SUPPORTED_VERSION 0x10
58#define FDT_LAST_SUPPORTED_VERSION 0x11
59
60/* Error codes: informative error codes */
61#define FDT_ERR_NOTFOUND 1
62 /* FDT_ERR_NOTFOUND: The requested node or property does not exist */
63#define FDT_ERR_EXISTS 2
64 /* FDT_ERR_EXISTS: Attemped to create a node or property which
65 * already exists */
66#define FDT_ERR_NOSPACE 3
67 /* FDT_ERR_NOSPACE: Operation needed to expand the device
68 * tree, but its buffer did not have sufficient space to
69 * contain the expanded tree. Use fdt_open_into() to move the
70 * device tree to a buffer with more space. */
71
72/* Error codes: codes for bad parameters */
73#define FDT_ERR_BADOFFSET 4
74 /* FDT_ERR_BADOFFSET: Function was passed a structure block
75 * offset which is out-of-bounds, or which points to an
76 * unsuitable part of the structure for the operation. */
77#define FDT_ERR_BADPATH 5
78 /* FDT_ERR_BADPATH: Function was passed a badly formatted path
79 * (e.g. missing a leading / for a function which requires an
80 * absolute path) */
81#define FDT_ERR_BADPHANDLE 6
82 /* FDT_ERR_BADPHANDLE: Function was passed an invalid phandle
83 * value. phandle values of 0 and -1 are not permitted. */
84#define FDT_ERR_BADSTATE 7
85 /* FDT_ERR_BADSTATE: Function was passed an incomplete device
86 * tree created by the sequential-write functions, which is
87 * not sufficiently complete for the requested operation. */
88
89/* Error codes: codes for bad device tree blobs */
90#define FDT_ERR_TRUNCATED 8
91 /* FDT_ERR_TRUNCATED: Structure block of the given device tree
92 * ends without an FDT_END tag. */
93#define FDT_ERR_BADMAGIC 9
94 /* FDT_ERR_BADMAGIC: Given "device tree" appears not to be a
95 * device tree at all - it is missing the flattened device
96 * tree magic number. */
97#define FDT_ERR_BADVERSION 10
98 /* FDT_ERR_BADVERSION: Given device tree has a version which
99 * can't be handled by the requested operation. For
100 * read-write functions, this may mean that fdt_open_into() is
101 * required to convert the tree to the expected version. */
102#define FDT_ERR_BADSTRUCTURE 11
103 /* FDT_ERR_BADSTRUCTURE: Given device tree has a corrupt
104 * structure block or other serious error (e.g. misnested
105 * nodes, or subnodes preceding properties). */
106#define FDT_ERR_BADLAYOUT 12
107 /* FDT_ERR_BADLAYOUT: For read-write functions, the given
108 * device tree has it's sub-blocks in an order that the
109 * function can't handle (memory reserve map, then structure,
110 * then strings). Use fdt_open_into() to reorganize the tree
111 * into a form suitable for the read-write operations. */
112
113/* "Can't happen" error indicating a bug in libfdt */
114#define FDT_ERR_INTERNAL 13
115 /* FDT_ERR_INTERNAL: libfdt has failed an internal assertion.
116 * Should never be returned, if it is, it indicates a bug in
117 * libfdt itself. */
118
119#define FDT_ERR_MAX 13
120
121/**********************************************************************/
122/* Low-level functions (you probably don't need these) */
123/**********************************************************************/
124
125const void *fdt_offset_ptr(const void *fdt, int offset, int checklen);
126static inline void *fdt_offset_ptr_w(void *fdt, int offset, int checklen)
127{
128 return (void *)fdt_offset_ptr(fdt, offset, checklen);
129}
130
131uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);
132
133/**********************************************************************/
134/* General functions */
135/**********************************************************************/
136
137#define fdt_get_header(fdt, field) \
138 (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
139#define fdt_magic(fdt) (fdt_get_header(fdt, magic))
140#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
141#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
142#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings))
143#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap))
144#define fdt_version(fdt) (fdt_get_header(fdt, version))
145#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version))
146#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys))
147#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))
148#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct))
149
150#define __fdt_set_hdr(name) \
151 static inline void fdt_set_##name(void *fdt, uint32_t val) \
152 { \
153 struct fdt_header *fdth = fdt; \
154 fdth->name = cpu_to_fdt32(val); \
155 }
156__fdt_set_hdr(magic);
157__fdt_set_hdr(totalsize);
158__fdt_set_hdr(off_dt_struct);
159__fdt_set_hdr(off_dt_strings);
160__fdt_set_hdr(off_mem_rsvmap);
161__fdt_set_hdr(version);
162__fdt_set_hdr(last_comp_version);
163__fdt_set_hdr(boot_cpuid_phys);
164__fdt_set_hdr(size_dt_strings);
165__fdt_set_hdr(size_dt_struct);
166#undef __fdt_set_hdr
167
168/**
169 * fdt_check_header - sanity check a device tree or possible device tree
170 * @fdt: pointer to data which might be a flattened device tree
171 *
172 * fdt_check_header() checks that the given buffer contains what
173 * appears to be a flattened device tree with sane information in its
174 * header.
175 *
176 * returns:
177 * 0, if the buffer appears to contain a valid device tree
178 * -FDT_ERR_BADMAGIC,
179 * -FDT_ERR_BADVERSION,
180 * -FDT_ERR_BADSTATE, standard meanings, as above
181 */
182int fdt_check_header(const void *fdt);
183
184/**
185 * fdt_move - move a device tree around in memory
186 * @fdt: pointer to the device tree to move
187 * @buf: pointer to memory where the device is to be moved
188 * @bufsize: size of the memory space at buf
189 *
190 * fdt_move() relocates, if possible, the device tree blob located at
191 * fdt to the buffer at buf of size bufsize. The buffer may overlap
192 * with the existing device tree blob at fdt. Therefore,
193 * fdt_move(fdt, fdt, fdt_totalsize(fdt))
194 * should always succeed.
195 *
196 * returns:
197 * 0, on success
198 * -FDT_ERR_NOSPACE, bufsize is insufficient to contain the device tree
199 * -FDT_ERR_BADMAGIC,
200 * -FDT_ERR_BADVERSION,
201 * -FDT_ERR_BADSTATE, standard meanings
202 */
203int fdt_move(const void *fdt, void *buf, int bufsize);
204
205/**********************************************************************/
206/* Read-only functions */
207/**********************************************************************/
208
209/**
210 * fdt_string - retreive a string from the strings block of a device tree
211 * @fdt: pointer to the device tree blob
212 * @stroffset: offset of the string within the strings block (native endian)
213 *
214 * fdt_string() retrieves a pointer to a single string from the
215 * strings block of the device tree blob at fdt.
216 *
217 * returns:
218 * a pointer to the string, on success
219 * NULL, if stroffset is out of bounds
220 */
221const char *fdt_string(const void *fdt, int stroffset);
222
223/**
224 * fdt_num_mem_rsv - retreive the number of memory reserve map entries
225 * @fdt: pointer to the device tree blob
226 *
227 * Returns the number of entries in the device tree blob's memory
228 * reservation map. This does not include the terminating 0,0 entry
229 * or any other (0,0) entries reserved for expansion.
230 *
231 * returns:
232 * the number of entries
233 */
234int fdt_num_mem_rsv(const void *fdt);
235
236/**
237 * fdt_get_mem_rsv - retreive one memory reserve map entry
238 * @fdt: pointer to the device tree blob
239 * @address, @size: pointers to 64-bit variables
240 *
241 * On success, *address and *size will contain the address and size of
242 * the n-th reserve map entry from the device tree blob, in
243 * native-endian format.
244 *
245 * returns:
246 * 0, on success
247 * -FDT_ERR_BADMAGIC,
248 * -FDT_ERR_BADVERSION,
249 * -FDT_ERR_BADSTATE, standard meanings
250 */
251int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size);
252
253/**
254 * fdt_subnode_offset_namelen - find a subnode based on substring
255 * @fdt: pointer to the device tree blob
256 * @parentoffset: structure block offset of a node
257 * @name: name of the subnode to locate
258 * @namelen: number of characters of name to consider
259 *
260 * Identical to fdt_subnode_offset(), but only examine the first
261 * namelen characters of name for matching the subnode name. This is
262 * useful for finding subnodes based on a portion of a larger string,
263 * such as a full path.
264 */
265int fdt_subnode_offset_namelen(const void *fdt, int parentoffset,
266 const char *name, int namelen);
267/**
268 * fdt_subnode_offset - find a subnode of a given node
269 * @fdt: pointer to the device tree blob
270 * @parentoffset: structure block offset of a node
271 * @name: name of the subnode to locate
272 *
273 * fdt_subnode_offset() finds a subnode of the node at structure block
274 * offset parentoffset with the given name. name may include a unit
275 * address, in which case fdt_subnode_offset() will find the subnode
276 * with that unit address, or the unit address may be omitted, in
277 * which case fdt_subnode_offset() will find an arbitrary subnode
278 * whose name excluding unit address matches the given name.
279 *
280 * returns:
281 * structure block offset of the requested subnode (>=0), on success
282 * -FDT_ERR_NOTFOUND, if the requested subnode does not exist
283 * -FDT_ERR_BADOFFSET, if parentoffset did not point to an FDT_BEGIN_NODE tag
284 * -FDT_ERR_BADMAGIC,
285 * -FDT_ERR_BADVERSION,
286 * -FDT_ERR_BADSTATE,
287 * -FDT_ERR_BADSTRUCTURE,
288 * -FDT_ERR_TRUNCATED, standard meanings.
289 */
290int fdt_subnode_offset(const void *fdt, int parentoffset, const char *name);
291
292/**
293 * fdt_path_offset - find a tree node by its full path
294 * @fdt: pointer to the device tree blob
295 * @path: full path of the node to locate
296 *
297 * fdt_path_offset() finds a node of a given path in the device tree.
298 * Each path component may omit the unit address portion, but the
299 * results of this are undefined if any such path component is
300 * ambiguous (that is if there are multiple nodes at the relevant
301 * level matching the given component, differentiated only by unit
302 * address).
303 *
304 * returns:
305 * structure block offset of the node with the requested path (>=0), on success
306 * -FDT_ERR_BADPATH, given path does not begin with '/' or is invalid
307 * -FDT_ERR_NOTFOUND, if the requested node does not exist
308 * -FDT_ERR_BADMAGIC,
309 * -FDT_ERR_BADVERSION,
310 * -FDT_ERR_BADSTATE,
311 * -FDT_ERR_BADSTRUCTURE,
312 * -FDT_ERR_TRUNCATED, standard meanings.
313 */
314int fdt_path_offset(const void *fdt, const char *path);
315
316/**
317 * fdt_get_name - retreive the name of a given node
318 * @fdt: pointer to the device tree blob
319 * @nodeoffset: structure block offset of the starting node
320 * @lenp: pointer to an integer variable (will be overwritten) or NULL
321 *
322 * fdt_get_name() retrieves the name (including unit address) of the
323 * device tree node at structure block offset nodeoffset. If lenp is
324 * non-NULL, the length of this name is also returned, in the integer
325 * pointed to by lenp.
326 *
327 * returns:
328 * pointer to the node's name, on success
329 * If lenp is non-NULL, *lenp contains the length of that name (>=0)
330 * NULL, on error
331 * if lenp is non-NULL *lenp contains an error code (<0):
332 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
333 * -FDT_ERR_BADMAGIC,
334 * -FDT_ERR_BADVERSION,
335 * -FDT_ERR_BADSTATE, standard meanings
336 */
337const char *fdt_get_name(const void *fdt, int nodeoffset, int *lenp);
338
339/**
340 * fdt_get_property - find a given property in a given node
341 * @fdt: pointer to the device tree blob
342 * @nodeoffset: offset of the node whose property to find
343 * @name: name of the property to find
344 * @lenp: pointer to an integer variable (will be overwritten) or NULL
345 *
346 * fdt_get_property() retrieves a pointer to the fdt_property
347 * structure within the device tree blob corresponding to the property
348 * named 'name' of the node at offset nodeoffset. If lenp is
349 * non-NULL, the length of the property value also returned, in the
350 * integer pointed to by lenp.
351 *
352 * returns:
353 * pointer to the structure representing the property
354 * if lenp is non-NULL, *lenp contains the length of the property
355 * value (>=0)
356 * NULL, on error
357 * if lenp is non-NULL, *lenp contains an error code (<0):
358 * -FDT_ERR_NOTFOUND, node does not have named property
359 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
360 * -FDT_ERR_BADMAGIC,
361 * -FDT_ERR_BADVERSION,
362 * -FDT_ERR_BADSTATE,
363 * -FDT_ERR_BADSTRUCTURE,
364 * -FDT_ERR_TRUNCATED, standard meanings
365 */
366const struct fdt_property *fdt_get_property(const void *fdt, int nodeoffset,
367 const char *name, int *lenp);
368static inline struct fdt_property *fdt_get_property_w(void *fdt, int nodeoffset,
369 const char *name,
370 int *lenp)
371{
372 return (struct fdt_property *)fdt_get_property(fdt, nodeoffset,
373 name, lenp);
374}
375
376/**
377 * fdt_getprop - retrieve the value of a given property
378 * @fdt: pointer to the device tree blob
379 * @nodeoffset: offset of the node whose property to find
380 * @name: name of the property to find
381 * @lenp: pointer to an integer variable (will be overwritten) or NULL
382 *
383 * fdt_getprop() retrieves a pointer to the value of the property
384 * named 'name' of the node at offset nodeoffset (this will be a
385 * pointer to within the device blob itself, not a copy of the value).
386 * If lenp is non-NULL, the length of the property value also
387 * returned, in the integer pointed to by lenp.
388 *
389 * returns:
390 * pointer to the property's value
391 * if lenp is non-NULL, *lenp contains the length of the property
392 * value (>=0)
393 * NULL, on error
394 * if lenp is non-NULL, *lenp contains an error code (<0):
395 * -FDT_ERR_NOTFOUND, node does not have named property
396 * -FDT_ERR_BADOFFSET, nodeoffset did not point to FDT_BEGIN_NODE tag
397 * -FDT_ERR_BADMAGIC,
398 * -FDT_ERR_BADVERSION,
399 * -FDT_ERR_BADSTATE,
400 * -FDT_ERR_BADSTRUCTURE,
401 * -FDT_ERR_TRUNCATED, standard meanings
402 */
403const void *fdt_getprop(const void *fdt, int nodeoffset,
404 const char *name, int *lenp);
405static inline void *fdt_getprop_w(void *fdt, int nodeoffset,
406 const char *name, int *lenp)
407{
408 return (void *)fdt_getprop(fdt, nodeoffset, name, lenp);
409}
410
411/**
412 * fdt_get_phandle - retreive the phandle of a given node
413 * @fdt: pointer to the device tree blob
414 * @nodeoffset: structure block offset of the node
415 *
416 * fdt_get_phandle() retrieves the phandle of the device tree node at
417 * structure block offset nodeoffset.
418 *
419 * returns:
420 * the phandle of the node at nodeoffset, on succes (!= 0, != -1)
421 * 0, if the node has no phandle, or another error occurs
422 */
423uint32_t fdt_get_phandle(const void *fdt, int nodeoffset);
424
425/**
426 * fdt_get_path - determine the full path of a node
427 * @fdt: pointer to the device tree blob
428 * @nodeoffset: offset of the node whose path to find
429 * @buf: character buffer to contain the returned path (will be overwritten)
430 * @buflen: size of the character buffer at buf
431 *
432 * fdt_get_path() computes the full path of the node at offset
433 * nodeoffset, and records that path in the buffer at buf.
434 *
435 * NOTE: This function is expensive, as it must scan the device tree
436 * structure from the start to nodeoffset.
437 *
438 * returns:
439 * 0, on success
440 * buf contains the absolute path of the node at
441 * nodeoffset, as a NUL-terminated string.
442 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
443 * -FDT_ERR_NOSPACE, the path of the given node is longer than (bufsize-1)
444 * characters and will not fit in the given buffer.
445 * -FDT_ERR_BADMAGIC,
446 * -FDT_ERR_BADVERSION,
447 * -FDT_ERR_BADSTATE,
448 * -FDT_ERR_BADSTRUCTURE, standard meanings
449 */
450int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen);
451
452/**
453 * fdt_supernode_atdepth_offset - find a specific ancestor of a node
454 * @fdt: pointer to the device tree blob
455 * @nodeoffset: offset of the node whose parent to find
456 * @supernodedepth: depth of the ancestor to find
457 * @nodedepth: pointer to an integer variable (will be overwritten) or NULL
458 *
459 * fdt_supernode_atdepth_offset() finds an ancestor of the given node
460 * at a specific depth from the root (where the root itself has depth
461 * 0, its immediate subnodes depth 1 and so forth). So
462 * fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, NULL);
463 * will always return 0, the offset of the root node. If the node at
464 * nodeoffset has depth D, then:
465 * fdt_supernode_atdepth_offset(fdt, nodeoffset, D, NULL);
466 * will return nodeoffset itself.
467 *
468 * NOTE: This function is expensive, as it must scan the device tree
469 * structure from the start to nodeoffset.
470 *
471 * returns:
472
473 * structure block offset of the node at node offset's ancestor
474 * of depth supernodedepth (>=0), on success
475 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
476* -FDT_ERR_NOTFOUND, supernodedepth was greater than the depth of nodeoffset
477 * -FDT_ERR_BADMAGIC,
478 * -FDT_ERR_BADVERSION,
479 * -FDT_ERR_BADSTATE,
480 * -FDT_ERR_BADSTRUCTURE, standard meanings
481 */
482int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
483 int supernodedepth, int *nodedepth);
484
485/**
486 * fdt_node_depth - find the depth of a given node
487 * @fdt: pointer to the device tree blob
488 * @nodeoffset: offset of the node whose parent to find
489 *
490 * fdt_node_depth() finds the depth of a given node. The root node
491 * has depth 0, its immediate subnodes depth 1 and so forth.
492 *
493 * NOTE: This function is expensive, as it must scan the device tree
494 * structure from the start to nodeoffset.
495 *
496 * returns:
497 * depth of the node at nodeoffset (>=0), on success
498 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
499 * -FDT_ERR_BADMAGIC,
500 * -FDT_ERR_BADVERSION,
501 * -FDT_ERR_BADSTATE,
502 * -FDT_ERR_BADSTRUCTURE, standard meanings
503 */
504int fdt_node_depth(const void *fdt, int nodeoffset);
505
506/**
507 * fdt_parent_offset - find the parent of a given node
508 * @fdt: pointer to the device tree blob
509 * @nodeoffset: offset of the node whose parent to find
510 *
511 * fdt_parent_offset() locates the parent node of a given node (that
512 * is, it finds the offset of the node which contains the node at
513 * nodeoffset as a subnode).
514 *
515 * NOTE: This function is expensive, as it must scan the device tree
516 * structure from the start to nodeoffset, *twice*.
517 *
518 * returns:
519 * stucture block offset of the parent of the node at nodeoffset
520 * (>=0), on success
521 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
522 * -FDT_ERR_BADMAGIC,
523 * -FDT_ERR_BADVERSION,
524 * -FDT_ERR_BADSTATE,
525 * -FDT_ERR_BADSTRUCTURE, standard meanings
526 */
527int fdt_parent_offset(const void *fdt, int nodeoffset);
528
529/**
530 * fdt_node_offset_by_prop_value - find nodes with a given property value
531 * @fdt: pointer to the device tree blob
532 * @startoffset: only find nodes after this offset
533 * @propname: property name to check
534 * @propval: property value to search for
535 * @proplen: length of the value in propval
536 *
537 * fdt_node_offset_by_prop_value() returns the offset of the first
538 * node after startoffset, which has a property named propname whose
539 * value is of length proplen and has value equal to propval; or if
540 * startoffset is -1, the very first such node in the tree.
541 *
542 * To iterate through all nodes matching the criterion, the following
543 * idiom can be used:
544 * offset = fdt_node_offset_by_prop_value(fdt, -1, propname,
545 * propval, proplen);
546 * while (offset != -FDT_ERR_NOTFOUND) {
547 * // other code here
548 * offset = fdt_node_offset_by_prop_value(fdt, offset, propname,
549 * propval, proplen);
550 * }
551 *
552 * Note the -1 in the first call to the function, if 0 is used here
553 * instead, the function will never locate the root node, even if it
554 * matches the criterion.
555 *
556 * returns:
557 * structure block offset of the located node (>= 0, >startoffset),
558 * on success
559 * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
560 * tree after startoffset
561 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
562 * -FDT_ERR_BADMAGIC,
563 * -FDT_ERR_BADVERSION,
564 * -FDT_ERR_BADSTATE,
565 * -FDT_ERR_BADSTRUCTURE, standard meanings
566 */
567int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,
568 const char *propname,
569 const void *propval, int proplen);
570
571/**
572 * fdt_node_offset_by_phandle - find the node with a given phandle
573 * @fdt: pointer to the device tree blob
574 * @phandle: phandle value
575 *
576 * fdt_node_offset_by_prop_value() returns the offset of the node
577 * which has the given phandle value. If there is more than one node
578 * in the tree with the given phandle (an invalid tree), results are
579 * undefined.
580 *
581 * returns:
582 * structure block offset of the located node (>= 0), on success
583 * -FDT_ERR_NOTFOUND, no node with that phandle exists
584 * -FDT_ERR_BADPHANDLE, given phandle value was invalid (0 or -1)
585 * -FDT_ERR_BADMAGIC,
586 * -FDT_ERR_BADVERSION,
587 * -FDT_ERR_BADSTATE,
588 * -FDT_ERR_BADSTRUCTURE, standard meanings
589 */
590int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle);
591
592/**
593 * fdt_node_check_compatible: check a node's compatible property
594 * @fdt: pointer to the device tree blob
595 * @nodeoffset: offset of a tree node
596 * @compatible: string to match against
597 *
598 *
599 * fdt_node_check_compatible() returns 0 if the given node contains a
600 * 'compatible' property with the given string as one of its elements,
601 * it returns non-zero otherwise, or on error.
602 *
603 * returns:
604 * 0, if the node has a 'compatible' property listing the given string
605 * 1, if the node has a 'compatible' property, but it does not list
606 * the given string
607 * -FDT_ERR_NOTFOUND, if the given node has no 'compatible' property
608 * -FDT_ERR_BADOFFSET, if nodeoffset does not refer to a BEGIN_NODE tag
609 * -FDT_ERR_BADMAGIC,
610 * -FDT_ERR_BADVERSION,
611 * -FDT_ERR_BADSTATE,
612 * -FDT_ERR_BADSTRUCTURE, standard meanings
613 */
614int fdt_node_check_compatible(const void *fdt, int nodeoffset,
615 const char *compatible);
616
617/**
618 * fdt_node_offset_by_compatible - find nodes with a given 'compatible' value
619 * @fdt: pointer to the device tree blob
620 * @startoffset: only find nodes after this offset
621 * @compatible: 'compatible' string to match against
622 *
623 * fdt_node_offset_by_compatible() returns the offset of the first
624 * node after startoffset, which has a 'compatible' property which
625 * lists the given compatible string; or if startoffset is -1, the
626 * very first such node in the tree.
627 *
628 * To iterate through all nodes matching the criterion, the following
629 * idiom can be used:
630 * offset = fdt_node_offset_by_compatible(fdt, -1, compatible);
631 * while (offset != -FDT_ERR_NOTFOUND) {
632 * // other code here
633 * offset = fdt_node_offset_by_compatible(fdt, offset, compatible);
634 * }
635 *
636 * Note the -1 in the first call to the function, if 0 is used here
637 * instead, the function will never locate the root node, even if it
638 * matches the criterion.
639 *
640 * returns:
641 * structure block offset of the located node (>= 0, >startoffset),
642 * on success
643 * -FDT_ERR_NOTFOUND, no node matching the criterion exists in the
644 * tree after startoffset
645 * -FDT_ERR_BADOFFSET, nodeoffset does not refer to a BEGIN_NODE tag
646 * -FDT_ERR_BADMAGIC,
647 * -FDT_ERR_BADVERSION,
648 * -FDT_ERR_BADSTATE,
649 * -FDT_ERR_BADSTRUCTURE, standard meanings
650 */
651int fdt_node_offset_by_compatible(const void *fdt, int startoffset,
652 const char *compatible);
653
654/**********************************************************************/
655/* Write-in-place functions */
656/**********************************************************************/
657
658int fdt_setprop_inplace(void *fdt, int nodeoffset, const char *name,
659 const void *val, int len);
660static inline int fdt_setprop_inplace_cell(void *fdt, int nodeoffset,
661 const char *name, uint32_t val)
662{
663 val = cpu_to_fdt32(val);
664 return fdt_setprop_inplace(fdt, nodeoffset, name, &val, sizeof(val));
665}
666
667int fdt_nop_property(void *fdt, int nodeoffset, const char *name);
668int fdt_nop_node(void *fdt, int nodeoffset);
669
670/**********************************************************************/
671/* Sequential write functions */
672/**********************************************************************/
673
674int fdt_create(void *buf, int bufsize);
675int fdt_add_reservemap_entry(void *fdt, uint64_t addr, uint64_t size);
676int fdt_finish_reservemap(void *fdt);
677int fdt_begin_node(void *fdt, const char *name);
678int fdt_property(void *fdt, const char *name, const void *val, int len);
679static inline int fdt_property_cell(void *fdt, const char *name, uint32_t val)
680{
681 val = cpu_to_fdt32(val);
682 return fdt_property(fdt, name, &val, sizeof(val));
683}
684#define fdt_property_string(fdt, name, str) \
685 fdt_property(fdt, name, str, strlen(str)+1)
686int fdt_end_node(void *fdt);
687int fdt_finish(void *fdt);
688
689/**********************************************************************/
690/* Read-write functions */
691/**********************************************************************/
692
693int fdt_open_into(const void *fdt, void *buf, int bufsize);
694int fdt_pack(void *fdt);
695
696int fdt_add_mem_rsv(void *fdt, uint64_t address, uint64_t size);
697int fdt_del_mem_rsv(void *fdt, int n);
698
699int fdt_setprop(void *fdt, int nodeoffset, const char *name,
700 const void *val, int len);
701static inline int fdt_setprop_cell(void *fdt, int nodeoffset, const char *name,
702 uint32_t val)
703{
704 val = cpu_to_fdt32(val);
705 return fdt_setprop(fdt, nodeoffset, name, &val, sizeof(val));
706}
707#define fdt_setprop_string(fdt, nodeoffset, name, str) \
708 fdt_setprop((fdt), (nodeoffset), (name), (str), strlen(str)+1)
709int fdt_delprop(void *fdt, int nodeoffset, const char *name);
710int fdt_add_subnode_namelen(void *fdt, int parentoffset,
711 const char *name, int namelen);
712int fdt_add_subnode(void *fdt, int parentoffset, const char *name);
713int fdt_del_node(void *fdt, int nodeoffset);
714
715/**********************************************************************/
716/* Debugging / informational functions */
717/**********************************************************************/
718
719const char *fdt_strerror(int errval);
720
721#endif /* _LIBFDT_H */
diff --git a/arch/powerpc/boot/libfdt/libfdt_internal.h b/arch/powerpc/boot/libfdt/libfdt_internal.h
new file mode 100644
index 000000000000..1e60936beb5b
--- /dev/null
+++ b/arch/powerpc/boot/libfdt/libfdt_internal.h
@@ -0,0 +1,89 @@
1#ifndef _LIBFDT_INTERNAL_H
2#define _LIBFDT_INTERNAL_H
3/*
4 * libfdt - Flat Device Tree manipulation
5 * Copyright (C) 2006 David Gibson, IBM Corporation.
6 *
7 * libfdt is dual licensed: you can use it either under the terms of
8 * the GPL, or the BSD license, at your option.
9 *
10 * a) This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of the
13 * License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public
21 * License along with this library; if not, write to the Free
22 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
23 * MA 02110-1301 USA
24 *
25 * Alternatively,
26 *
27 * b) Redistribution and use in source and binary forms, with or
28 * without modification, are permitted provided that the following
29 * conditions are met:
30 *
31 * 1. Redistributions of source code must retain the above
32 * copyright notice, this list of conditions and the following
33 * disclaimer.
34 * 2. Redistributions in binary form must reproduce the above
35 * copyright notice, this list of conditions and the following
36 * disclaimer in the documentation and/or other materials
37 * provided with the distribution.
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
40 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
41 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
42 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
44 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
49 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
50 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
51 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 */
53#include <fdt.h>
54
55#define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
56#define PALIGN(p, a) ((void *)ALIGN((unsigned long)(p), (a)))
57
58#define memeq(p, q, n) (memcmp((p), (q), (n)) == 0)
59#define streq(p, q) (strcmp((p), (q)) == 0)
60
61uint32_t _fdt_next_tag(const void *fdt, int startoffset, int *nextoffset);
62const char *_fdt_find_string(const char *strtab, int tabsize, const char *s);
63int _fdt_node_end_offset(void *fdt, int nodeoffset);
64
65static inline const void *_fdt_offset_ptr(const void *fdt, int offset)
66{
67 return fdt + fdt_off_dt_struct(fdt) + offset;
68}
69
70static inline void *_fdt_offset_ptr_w(void *fdt, int offset)
71{
72 return (void *)_fdt_offset_ptr(fdt, offset);
73}
74
75static inline const struct fdt_reserve_entry *_fdt_mem_rsv(const void *fdt, int n)
76{
77 const struct fdt_reserve_entry *rsv_table =
78 fdt + fdt_off_mem_rsvmap(fdt);
79
80 return rsv_table + n;
81}
82static inline struct fdt_reserve_entry *_fdt_mem_rsv_w(void *fdt, int n)
83{
84 return (void *)_fdt_mem_rsv(fdt, n);
85}
86
87#define SW_MAGIC (~FDT_MAGIC)
88
89#endif /* _LIBFDT_INTERNAL_H */
diff --git a/arch/powerpc/boot/libfdt_env.h b/arch/powerpc/boot/libfdt_env.h
new file mode 100644
index 000000000000..a4b0fc959ece
--- /dev/null
+++ b/arch/powerpc/boot/libfdt_env.h
@@ -0,0 +1,17 @@
1#ifndef _ARCH_POWERPC_BOOT_LIBFDT_ENV_H
2#define _ARCH_POWERPC_BOOT_LIBFDT_ENV_H
3
4#include <types.h>
5#include <string.h>
6
7typedef u32 uint32_t;
8typedef u64 uint64_t;
9
10#define fdt16_to_cpu(x) (x)
11#define cpu_to_fdt16(x) (x)
12#define fdt32_to_cpu(x) (x)
13#define cpu_to_fdt32(x) (x)
14#define fdt64_to_cpu(x) (x)
15#define cpu_to_fdt64(x) (x)
16
17#endif /* _ARCH_POWERPC_BOOT_LIBFDT_ENV_H */
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index 1b496b37eca0..9e7f3ddd9913 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -16,7 +16,6 @@
16#include "stdio.h" 16#include "stdio.h"
17#include "ops.h" 17#include "ops.h"
18#include "gunzip_util.h" 18#include "gunzip_util.h"
19#include "flatdevtree.h"
20#include "reg.h" 19#include "reg.h"
21 20
22static struct gunzip_state gzstate; 21static struct gunzip_state gzstate;
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
index a180b6505f47..6036a98e646a 100644
--- a/arch/powerpc/boot/ops.h
+++ b/arch/powerpc/boot/ops.h
@@ -79,7 +79,7 @@ struct loader_info {
79extern struct loader_info loader_info; 79extern struct loader_info loader_info;
80 80
81void start(void); 81void start(void);
82int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device); 82void fdt_init(void *blob);
83int serial_console_init(void); 83int serial_console_init(void);
84int ns16550_console_init(void *devp, struct serial_console_data *scdp); 84int ns16550_console_init(void *devp, struct serial_console_data *scdp);
85int mpsc_console_init(void *devp, struct serial_console_data *scdp); 85int mpsc_console_init(void *devp, struct serial_console_data *scdp);
diff --git a/arch/powerpc/boot/prpmc2800.c b/arch/powerpc/boot/prpmc2800.c
index 9614e1db9dae..05c3245b30d7 100644
--- a/arch/powerpc/boot/prpmc2800.c
+++ b/arch/powerpc/boot/prpmc2800.c
@@ -547,8 +547,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
547 if (!dtb) 547 if (!dtb)
548 exit(); 548 exit();
549 memmove(dtb, _dtb_start, dt_size); 549 memmove(dtb, _dtb_start, dt_size);
550 if (ft_init(dtb, dt_size, 16)) 550 fdt_init(dtb);
551 exit();
552 551
553 bridge_base = mv64x60_get_bridge_base(); 552 bridge_base = mv64x60_get_bridge_base();
554 553
diff --git a/arch/powerpc/boot/ps3.c b/arch/powerpc/boot/ps3.c
index d6661151b494..3b0ac4d006ec 100644
--- a/arch/powerpc/boot/ps3.c
+++ b/arch/powerpc/boot/ps3.c
@@ -131,7 +131,7 @@ void platform_init(void)
131 printf("\n-- PS3 bootwrapper --\n"); 131 printf("\n-- PS3 bootwrapper --\n");
132 132
133 simple_alloc_init(_end, heapsize, 32, 64); 133 simple_alloc_init(_end, heapsize, 32, 64);
134 ft_init(_dtb_start, 0, 4); 134 fdt_init(_dtb_start);
135 135
136 chosen = finddevice("/chosen"); 136 chosen = finddevice("/chosen");
137 137
diff --git a/arch/powerpc/boot/treeboot-walnut.c b/arch/powerpc/boot/treeboot-walnut.c
index bb2c309d70fc..70ffce343c0a 100644
--- a/arch/powerpc/boot/treeboot-walnut.c
+++ b/arch/powerpc/boot/treeboot-walnut.c
@@ -128,6 +128,6 @@ void platform_init(void)
128 simple_alloc_init(_end, avail_ram, 32, 32); 128 simple_alloc_init(_end, avail_ram, 32, 32);
129 platform_ops.fixups = walnut_fixups; 129 platform_ops.fixups = walnut_fixups;
130 platform_ops.exit = ibm40x_dbcr_reset; 130 platform_ops.exit = ibm40x_dbcr_reset;
131 ft_init(_dtb_start, _dtb_end - _dtb_start, 32); 131 fdt_init(_dtb_start);
132 serial_console_init(); 132 serial_console_init();
133} 133}
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index 31147a037728..f961cdeb97a2 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -45,6 +45,7 @@ CROSS=
45 45
46# directory for object and other files used by this script 46# directory for object and other files used by this script
47object=arch/powerpc/boot 47object=arch/powerpc/boot
48objbin=$object
48 49
49# directory for working files 50# directory for working files
50tmpdir=. 51tmpdir=.
@@ -95,6 +96,7 @@ while [ "$#" -gt 0 ]; do
95 shift 96 shift
96 [ "$#" -gt 0 ] || usage 97 [ "$#" -gt 0 ] || usage
97 object="$1" 98 object="$1"
99 objbin="$1"
98 ;; 100 ;;
99 -W) 101 -W)
100 shift 102 shift
@@ -116,10 +118,13 @@ while [ "$#" -gt 0 ]; do
116done 118done
117 119
118if [ -n "$dts" ]; then 120if [ -n "$dts" ]; then
121 if [ ! -r "$dts" -a -r "$object/dts/$dts" ]; then
122 dts="$object/dts/$dts"
123 fi
119 if [ -z "$dtb" ]; then 124 if [ -z "$dtb" ]; then
120 dtb="$platform.dtb" 125 dtb="$platform.dtb"
121 fi 126 fi
122 dtc -O dtb -o "$dtb" -b 0 -V 16 "$dts" 127 $object/dtc -O dtb -o "$dtb" -b 0 "$dts"
123fi 128fi
124 129
125if [ -z "$kernel" ]; then 130if [ -z "$kernel" ]; then
@@ -246,11 +251,11 @@ fi
246# post-processing needed for some platforms 251# post-processing needed for some platforms
247case "$platform" in 252case "$platform" in
248pseries|chrp) 253pseries|chrp)
249 $object/addnote "$ofile" 254 $objbin/addnote "$ofile"
250 ;; 255 ;;
251coff) 256coff)
252 ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile" 257 ${CROSS}objcopy -O aixcoff-rs6000 --set-start "$entry" "$ofile"
253 $object/hack-coff "$ofile" 258 $objbin/hack-coff "$ofile"
254 ;; 259 ;;
255cuboot*) 260cuboot*)
256 gzip -f -9 "$ofile" 261 gzip -f -9 "$ofile"
@@ -259,7 +264,7 @@ cuboot*)
259 ;; 264 ;;
260treeboot*) 265treeboot*)
261 mv "$ofile" "$ofile.elf" 266 mv "$ofile" "$ofile.elf"
262 $object/mktree "$ofile.elf" "$ofile" "$base" "$entry" 267 $objbin/mktree "$ofile.elf" "$ofile" "$base" "$entry"
263 if [ -z "$cacheit" ]; then 268 if [ -z "$cacheit" ]; then
264 rm -f "$ofile.elf" 269 rm -f "$ofile.elf"
265 fi 270 fi
@@ -287,8 +292,6 @@ ps3)
287 overlay_dest="256" 292 overlay_dest="256"
288 overlay_size="256" 293 overlay_size="256"
289 294
290 rm -f "$object/otheros.bld"
291
292 ${CROSS}objcopy -O binary "$ofile" "$ofile.bin" 295 ${CROSS}objcopy -O binary "$ofile" "$ofile.bin"
293 296
294 dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \ 297 dd if="$ofile.bin" of="$ofile.bin" conv=notrunc \
@@ -299,6 +302,8 @@ ps3)
299 skip=$system_reset_overlay seek=$overlay_dest \ 302 skip=$system_reset_overlay seek=$overlay_dest \
300 count=$overlay_size bs=1 303 count=$overlay_size bs=1
301 304
302 gzip --force -9 --stdout "$ofile.bin" > "$object/otheros.bld" 305 odir="$(dirname "$ofile.bin")"
306 rm -f "$odir/otheros.bld"
307 gzip --force -9 --stdout "$ofile.bin" > "$odir/otheros.bld"
303 ;; 308 ;;
304esac 309esac
diff --git a/arch/powerpc/configs/celleb_defconfig b/arch/powerpc/configs/celleb_defconfig
index 421e08ee857a..9ed2e098f96f 100644
--- a/arch/powerpc/configs/celleb_defconfig
+++ b/arch/powerpc/configs/celleb_defconfig
@@ -50,7 +50,8 @@ CONFIG_AUDIT_ARCH=y
50CONFIG_GENERIC_BUG=y 50CONFIG_GENERIC_BUG=y
51# CONFIG_DEFAULT_UIMAGE is not set 51# CONFIG_DEFAULT_UIMAGE is not set
52# CONFIG_PPC_DCR_NATIVE is not set 52# CONFIG_PPC_DCR_NATIVE is not set
53# CONFIG_PPC_DCR_MMIO is not set 53CONFIG_PPC_DCR_MMIO=y
54CONFIG_PPC_DCR=y
54CONFIG_PPC_OF_PLATFORM_PCI=y 55CONFIG_PPC_OF_PLATFORM_PCI=y
55CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" 56CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
56 57
@@ -148,7 +149,7 @@ CONFIG_PPC_MULTIPLATFORM=y
148CONFIG_PPC_CELLEB=y 149CONFIG_PPC_CELLEB=y
149# CONFIG_PPC_PS3 is not set 150# CONFIG_PPC_PS3 is not set
150CONFIG_PPC_CELL=y 151CONFIG_PPC_CELL=y
151# CONFIG_PPC_CELL_NATIVE is not set 152CONFIG_PPC_CELL_NATIVE=y
152# CONFIG_PPC_IBM_CELL_BLADE is not set 153# CONFIG_PPC_IBM_CELL_BLADE is not set
153 154
154# 155#
@@ -157,13 +158,19 @@ CONFIG_PPC_CELL=y
157CONFIG_SPU_FS=y 158CONFIG_SPU_FS=y
158CONFIG_SPU_FS_64K_LS=y 159CONFIG_SPU_FS_64K_LS=y
159CONFIG_SPU_BASE=y 160CONFIG_SPU_BASE=y
161CONFIG_CBE_RAS=y
162# CONFIG_CBE_THERM is not set
160# CONFIG_PQ2ADS is not set 163# CONFIG_PQ2ADS is not set
164CONFIG_PPC_NATIVE=y
165CONFIG_UDBG_RTAS_CONSOLE=y
161CONFIG_PPC_UDBG_BEAT=y 166CONFIG_PPC_UDBG_BEAT=y
162# CONFIG_MPIC is not set 167CONFIG_MPIC=y
163# CONFIG_MPIC_WEIRD is not set 168# CONFIG_MPIC_WEIRD is not set
164# CONFIG_PPC_I8259 is not set 169# CONFIG_PPC_I8259 is not set
165# CONFIG_U3_DART is not set 170# CONFIG_U3_DART is not set
166# CONFIG_PPC_RTAS is not set 171CONFIG_PPC_RTAS=y
172# CONFIG_RTAS_ERROR_LOGGING is not set
173# CONFIG_RTAS_PROC is not set
167# CONFIG_MMIO_NVRAM is not set 174# CONFIG_MMIO_NVRAM is not set
168# CONFIG_PPC_MPC106 is not set 175# CONFIG_PPC_MPC106 is not set
169# CONFIG_PPC_970_NAP is not set 176# CONFIG_PPC_970_NAP is not set
@@ -593,10 +600,11 @@ CONFIG_MII=y
593# CONFIG_NET_VENDOR_3COM is not set 600# CONFIG_NET_VENDOR_3COM is not set
594# CONFIG_NET_TULIP is not set 601# CONFIG_NET_TULIP is not set
595# CONFIG_HP100 is not set 602# CONFIG_HP100 is not set
596# CONFIG_IBM_NEW_EMAC_ZMII is not set 603# CONFIG_IBM_NEW_EMAC is not set
597# CONFIG_IBM_NEW_EMAC_RGMII is not set 604CONFIG_IBM_NEW_EMAC_ZMII=y
598# CONFIG_IBM_NEW_EMAC_TAH is not set 605CONFIG_IBM_NEW_EMAC_RGMII=y
599# CONFIG_IBM_NEW_EMAC_EMAC4 is not set 606CONFIG_IBM_NEW_EMAC_TAH=y
607CONFIG_IBM_NEW_EMAC_EMAC4=y
600# CONFIG_NET_PCI is not set 608# CONFIG_NET_PCI is not set
601# CONFIG_B44 is not set 609# CONFIG_B44 is not set
602CONFIG_NETDEV_1000=y 610CONFIG_NETDEV_1000=y
@@ -741,6 +749,7 @@ CONFIG_SERIAL_TXX9_CONSOLE=y
741CONFIG_UNIX98_PTYS=y 749CONFIG_UNIX98_PTYS=y
742# CONFIG_LEGACY_PTYS is not set 750# CONFIG_LEGACY_PTYS is not set
743CONFIG_HVC_DRIVER=y 751CONFIG_HVC_DRIVER=y
752CONFIG_HVC_RTAS=y
744CONFIG_HVC_BEAT=y 753CONFIG_HVC_BEAT=y
745# CONFIG_IPMI_HANDLER is not set 754# CONFIG_IPMI_HANDLER is not set
746# CONFIG_HW_RANDOM is not set 755# CONFIG_HW_RANDOM is not set
@@ -822,6 +831,7 @@ CONFIG_WATCHDOG=y
822# Watchdog Device Drivers 831# Watchdog Device Drivers
823# 832#
824# CONFIG_SOFT_WATCHDOG is not set 833# CONFIG_SOFT_WATCHDOG is not set
834# CONFIG_WATCHDOG_RTAS is not set
825 835
826# 836#
827# PCI-based Watchdog Cards 837# PCI-based Watchdog Cards
@@ -1245,17 +1255,7 @@ CONFIG_XMON_DISASSEMBLY=y
1245CONFIG_IRQSTACKS=y 1255CONFIG_IRQSTACKS=y
1246# CONFIG_VIRQ_DEBUG is not set 1256# CONFIG_VIRQ_DEBUG is not set
1247# CONFIG_BOOTX_TEXT is not set 1257# CONFIG_BOOTX_TEXT is not set
1248CONFIG_PPC_EARLY_DEBUG=y 1258# CONFIG_PPC_EARLY_DEBUG is not set
1249# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
1250# CONFIG_PPC_EARLY_DEBUG_G5 is not set
1251# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set
1252# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
1253# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
1254# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
1255# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
1256CONFIG_PPC_EARLY_DEBUG_BEAT=y
1257# CONFIG_PPC_EARLY_DEBUG_44x is not set
1258# CONFIG_PPC_EARLY_DEBUG_CPM is not set
1259 1259
1260# 1260#
1261# Security options 1261# Security options
diff --git a/arch/powerpc/configs/mpc837x_mds_defconfig b/arch/powerpc/configs/mpc837x_mds_defconfig
new file mode 100644
index 000000000000..4f49aee5da66
--- /dev/null
+++ b/arch/powerpc/configs/mpc837x_mds_defconfig
@@ -0,0 +1,878 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.23
4# Wed Oct 10 16:31:39 2007
5#
6# CONFIG_PPC64 is not set
7
8#
9# Processor support
10#
11CONFIG_6xx=y
12# CONFIG_PPC_85xx is not set
13# CONFIG_PPC_8xx is not set
14# CONFIG_40x is not set
15# CONFIG_44x is not set
16# CONFIG_E200 is not set
17CONFIG_83xx=y
18CONFIG_PPC_FPU=y
19CONFIG_PPC_STD_MMU=y
20CONFIG_PPC_STD_MMU_32=y
21# CONFIG_PPC_MM_SLICES is not set
22# CONFIG_SMP is not set
23CONFIG_PPC32=y
24CONFIG_PPC_MERGE=y
25CONFIG_MMU=y
26CONFIG_GENERIC_HARDIRQS=y
27CONFIG_IRQ_PER_CPU=y
28CONFIG_RWSEM_XCHGADD_ALGORITHM=y
29CONFIG_ARCH_HAS_ILOG2_U32=y
30CONFIG_GENERIC_HWEIGHT=y
31CONFIG_GENERIC_CALIBRATE_DELAY=y
32CONFIG_GENERIC_FIND_NEXT_BIT=y
33# CONFIG_ARCH_NO_VIRT_TO_BUS is not set
34CONFIG_PPC=y
35CONFIG_EARLY_PRINTK=y
36CONFIG_GENERIC_NVRAM=y
37CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
38CONFIG_ARCH_MAY_HAVE_PC_FDC=y
39CONFIG_PPC_OF=y
40CONFIG_OF=y
41CONFIG_PPC_UDBG_16550=y
42# CONFIG_GENERIC_TBSYNC is not set
43CONFIG_AUDIT_ARCH=y
44CONFIG_GENERIC_BUG=y
45CONFIG_DEFAULT_UIMAGE=y
46# CONFIG_PPC_DCR_NATIVE is not set
47# CONFIG_PPC_DCR_MMIO is not set
48CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
49
50#
51# General setup
52#
53CONFIG_EXPERIMENTAL=y
54CONFIG_BROKEN_ON_SMP=y
55CONFIG_INIT_ENV_ARG_LIMIT=32
56CONFIG_LOCALVERSION=""
57CONFIG_LOCALVERSION_AUTO=y
58CONFIG_SWAP=y
59CONFIG_SYSVIPC=y
60CONFIG_SYSVIPC_SYSCTL=y
61# CONFIG_POSIX_MQUEUE is not set
62# CONFIG_BSD_PROCESS_ACCT is not set
63# CONFIG_TASKSTATS is not set
64# CONFIG_USER_NS is not set
65# CONFIG_AUDIT is not set
66# CONFIG_IKCONFIG is not set
67CONFIG_LOG_BUF_SHIFT=14
68CONFIG_SYSFS_DEPRECATED=y
69# CONFIG_RELAY is not set
70CONFIG_BLK_DEV_INITRD=y
71CONFIG_INITRAMFS_SOURCE=""
72# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
73CONFIG_SYSCTL=y
74CONFIG_EMBEDDED=y
75CONFIG_SYSCTL_SYSCALL=y
76CONFIG_KALLSYMS=y
77# CONFIG_KALLSYMS_EXTRA_PASS is not set
78CONFIG_HOTPLUG=y
79CONFIG_PRINTK=y
80CONFIG_BUG=y
81CONFIG_ELF_CORE=y
82CONFIG_BASE_FULL=y
83CONFIG_FUTEX=y
84CONFIG_ANON_INODES=y
85# CONFIG_EPOLL is not set
86CONFIG_SIGNALFD=y
87CONFIG_EVENTFD=y
88CONFIG_SHMEM=y
89CONFIG_VM_EVENT_COUNTERS=y
90CONFIG_SLAB=y
91# CONFIG_SLUB is not set
92# CONFIG_SLOB is not set
93CONFIG_RT_MUTEXES=y
94# CONFIG_TINY_SHMEM is not set
95CONFIG_BASE_SMALL=0
96CONFIG_MODULES=y
97CONFIG_MODULE_UNLOAD=y
98# CONFIG_MODULE_FORCE_UNLOAD is not set
99# CONFIG_MODVERSIONS is not set
100# CONFIG_MODULE_SRCVERSION_ALL is not set
101# CONFIG_KMOD is not set
102CONFIG_BLOCK=y
103# CONFIG_LBD is not set
104# CONFIG_BLK_DEV_IO_TRACE is not set
105# CONFIG_LSF is not set
106# CONFIG_BLK_DEV_BSG is not set
107
108#
109# IO Schedulers
110#
111CONFIG_IOSCHED_NOOP=y
112CONFIG_IOSCHED_AS=y
113CONFIG_IOSCHED_DEADLINE=y
114CONFIG_IOSCHED_CFQ=y
115CONFIG_DEFAULT_AS=y
116# CONFIG_DEFAULT_DEADLINE is not set
117# CONFIG_DEFAULT_CFQ is not set
118# CONFIG_DEFAULT_NOOP is not set
119CONFIG_DEFAULT_IOSCHED="anticipatory"
120
121#
122# Platform support
123#
124# CONFIG_PPC_MULTIPLATFORM is not set
125# CONFIG_EMBEDDED6xx is not set
126# CONFIG_PPC_82xx is not set
127CONFIG_PPC_83xx=y
128# CONFIG_PPC_86xx is not set
129# CONFIG_PPC_MPC52xx is not set
130# CONFIG_PPC_MPC5200 is not set
131# CONFIG_PPC_CELL is not set
132# CONFIG_PPC_CELL_NATIVE is not set
133# CONFIG_PQ2ADS is not set
134# CONFIG_MPC8313_RDB is not set
135# CONFIG_MPC832x_MDS is not set
136# CONFIG_MPC832x_RDB is not set
137# CONFIG_MPC834x_MDS is not set
138# CONFIG_MPC834x_ITX is not set
139# CONFIG_MPC836x_MDS is not set
140CONFIG_MPC837x_MDS=y
141CONFIG_PPC_MPC837x=y
142# CONFIG_MPIC is not set
143# CONFIG_MPIC_WEIRD is not set
144# CONFIG_PPC_I8259 is not set
145# CONFIG_PPC_RTAS is not set
146# CONFIG_MMIO_NVRAM is not set
147# CONFIG_PPC_MPC106 is not set
148# CONFIG_PPC_970_NAP is not set
149# CONFIG_PPC_INDIRECT_IO is not set
150# CONFIG_GENERIC_IOMAP is not set
151# CONFIG_CPU_FREQ is not set
152# CONFIG_CPM2 is not set
153# CONFIG_FSL_ULI1575 is not set
154CONFIG_FSL_SERDES=y
155
156#
157# Kernel options
158#
159# CONFIG_HIGHMEM is not set
160# CONFIG_HZ_100 is not set
161CONFIG_HZ_250=y
162# CONFIG_HZ_300 is not set
163# CONFIG_HZ_1000 is not set
164CONFIG_HZ=250
165CONFIG_PREEMPT_NONE=y
166# CONFIG_PREEMPT_VOLUNTARY is not set
167# CONFIG_PREEMPT is not set
168CONFIG_BINFMT_ELF=y
169# CONFIG_BINFMT_MISC is not set
170CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
171CONFIG_ARCH_FLATMEM_ENABLE=y
172CONFIG_ARCH_POPULATES_NODE_MAP=y
173CONFIG_SELECT_MEMORY_MODEL=y
174CONFIG_FLATMEM_MANUAL=y
175# CONFIG_DISCONTIGMEM_MANUAL is not set
176# CONFIG_SPARSEMEM_MANUAL is not set
177CONFIG_FLATMEM=y
178CONFIG_FLAT_NODE_MEM_MAP=y
179# CONFIG_SPARSEMEM_STATIC is not set
180CONFIG_SPLIT_PTLOCK_CPUS=4
181# CONFIG_RESOURCES_64BIT is not set
182CONFIG_ZONE_DMA_FLAG=1
183CONFIG_BOUNCE=y
184CONFIG_VIRT_TO_BUS=y
185CONFIG_PROC_DEVICETREE=y
186# CONFIG_CMDLINE_BOOL is not set
187# CONFIG_PM is not set
188CONFIG_SUSPEND_UP_POSSIBLE=y
189CONFIG_HIBERNATION_UP_POSSIBLE=y
190CONFIG_SECCOMP=y
191CONFIG_WANT_DEVICE_TREE=y
192CONFIG_DEVICE_TREE=""
193CONFIG_ISA_DMA_API=y
194
195#
196# Bus options
197#
198CONFIG_ZONE_DMA=y
199CONFIG_GENERIC_ISA_DMA=y
200CONFIG_PPC_INDIRECT_PCI=y
201CONFIG_FSL_SOC=y
202# CONFIG_PCI is not set
203# CONFIG_PCI_DOMAINS is not set
204# CONFIG_PCI_SYSCALL is not set
205# CONFIG_ARCH_SUPPORTS_MSI is not set
206
207#
208# PCCARD (PCMCIA/CardBus) support
209#
210# CONFIG_PCCARD is not set
211
212#
213# Advanced setup
214#
215# CONFIG_ADVANCED_OPTIONS is not set
216
217#
218# Default settings for advanced configuration options are used
219#
220CONFIG_HIGHMEM_START=0xfe000000
221CONFIG_LOWMEM_SIZE=0x30000000
222CONFIG_KERNEL_START=0xc0000000
223CONFIG_TASK_SIZE=0x80000000
224CONFIG_BOOT_LOAD=0x00800000
225
226#
227# Networking
228#
229CONFIG_NET=y
230
231#
232# Networking options
233#
234CONFIG_PACKET=y
235# CONFIG_PACKET_MMAP is not set
236CONFIG_UNIX=y
237CONFIG_XFRM=y
238CONFIG_XFRM_USER=m
239# CONFIG_XFRM_SUB_POLICY is not set
240# CONFIG_XFRM_MIGRATE is not set
241# CONFIG_NET_KEY is not set
242CONFIG_INET=y
243CONFIG_IP_MULTICAST=y
244# CONFIG_IP_ADVANCED_ROUTER is not set
245CONFIG_IP_FIB_HASH=y
246CONFIG_IP_PNP=y
247CONFIG_IP_PNP_DHCP=y
248CONFIG_IP_PNP_BOOTP=y
249# CONFIG_IP_PNP_RARP is not set
250# CONFIG_NET_IPIP is not set
251# CONFIG_NET_IPGRE is not set
252# CONFIG_IP_MROUTE is not set
253# CONFIG_ARPD is not set
254CONFIG_SYN_COOKIES=y
255# CONFIG_INET_AH is not set
256# CONFIG_INET_ESP is not set
257# CONFIG_INET_IPCOMP is not set
258# CONFIG_INET_XFRM_TUNNEL is not set
259# CONFIG_INET_TUNNEL is not set
260CONFIG_INET_XFRM_MODE_TRANSPORT=y
261CONFIG_INET_XFRM_MODE_TUNNEL=y
262CONFIG_INET_XFRM_MODE_BEET=y
263CONFIG_INET_DIAG=y
264CONFIG_INET_TCP_DIAG=y
265# CONFIG_TCP_CONG_ADVANCED is not set
266CONFIG_TCP_CONG_CUBIC=y
267CONFIG_DEFAULT_TCP_CONG="cubic"
268# CONFIG_TCP_MD5SIG is not set
269# CONFIG_IPV6 is not set
270# CONFIG_INET6_XFRM_TUNNEL is not set
271# CONFIG_INET6_TUNNEL is not set
272# CONFIG_NETWORK_SECMARK is not set
273# CONFIG_NETFILTER is not set
274# CONFIG_IP_DCCP is not set
275# CONFIG_IP_SCTP is not set
276# CONFIG_TIPC is not set
277# CONFIG_ATM is not set
278# CONFIG_BRIDGE is not set
279# CONFIG_VLAN_8021Q is not set
280# CONFIG_DECNET is not set
281# CONFIG_LLC2 is not set
282# CONFIG_IPX is not set
283# CONFIG_ATALK is not set
284# CONFIG_X25 is not set
285# CONFIG_LAPB is not set
286# CONFIG_ECONET is not set
287# CONFIG_WAN_ROUTER is not set
288
289#
290# QoS and/or fair queueing
291#
292# CONFIG_NET_SCHED is not set
293
294#
295# Network testing
296#
297# CONFIG_NET_PKTGEN is not set
298# CONFIG_HAMRADIO is not set
299# CONFIG_IRDA is not set
300# CONFIG_BT is not set
301# CONFIG_AF_RXRPC is not set
302
303#
304# Wireless
305#
306# CONFIG_CFG80211 is not set
307# CONFIG_WIRELESS_EXT is not set
308# CONFIG_MAC80211 is not set
309# CONFIG_IEEE80211 is not set
310# CONFIG_RFKILL is not set
311# CONFIG_NET_9P is not set
312
313#
314# Device Drivers
315#
316
317#
318# Generic Driver Options
319#
320CONFIG_STANDALONE=y
321CONFIG_PREVENT_FIRMWARE_BUILD=y
322# CONFIG_FW_LOADER is not set
323# CONFIG_SYS_HYPERVISOR is not set
324# CONFIG_CONNECTOR is not set
325# CONFIG_MTD is not set
326CONFIG_OF_DEVICE=y
327# CONFIG_PARPORT is not set
328CONFIG_BLK_DEV=y
329# CONFIG_BLK_DEV_FD is not set
330# CONFIG_BLK_DEV_COW_COMMON is not set
331CONFIG_BLK_DEV_LOOP=y
332# CONFIG_BLK_DEV_CRYPTOLOOP is not set
333# CONFIG_BLK_DEV_NBD is not set
334CONFIG_BLK_DEV_RAM=y
335CONFIG_BLK_DEV_RAM_COUNT=16
336CONFIG_BLK_DEV_RAM_SIZE=32768
337CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
338# CONFIG_CDROM_PKTCDVD is not set
339# CONFIG_ATA_OVER_ETH is not set
340CONFIG_MISC_DEVICES=y
341# CONFIG_EEPROM_93CX6 is not set
342# CONFIG_IDE is not set
343
344#
345# SCSI device support
346#
347# CONFIG_RAID_ATTRS is not set
348CONFIG_SCSI=y
349CONFIG_SCSI_DMA=y
350# CONFIG_SCSI_TGT is not set
351# CONFIG_SCSI_NETLINK is not set
352CONFIG_SCSI_PROC_FS=y
353
354#
355# SCSI support type (disk, tape, CD-ROM)
356#
357CONFIG_BLK_DEV_SD=y
358# CONFIG_CHR_DEV_ST is not set
359# CONFIG_CHR_DEV_OSST is not set
360# CONFIG_BLK_DEV_SR is not set
361CONFIG_CHR_DEV_SG=y
362# CONFIG_CHR_DEV_SCH is not set
363
364#
365# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
366#
367# CONFIG_SCSI_MULTI_LUN is not set
368# CONFIG_SCSI_CONSTANTS is not set
369# CONFIG_SCSI_LOGGING is not set
370# CONFIG_SCSI_SCAN_ASYNC is not set
371CONFIG_SCSI_WAIT_SCAN=m
372
373#
374# SCSI Transports
375#
376# CONFIG_SCSI_SPI_ATTRS is not set
377# CONFIG_SCSI_FC_ATTRS is not set
378# CONFIG_SCSI_ISCSI_ATTRS is not set
379# CONFIG_SCSI_SAS_LIBSAS is not set
380CONFIG_SCSI_LOWLEVEL=y
381# CONFIG_ISCSI_TCP is not set
382# CONFIG_SCSI_DEBUG is not set
383CONFIG_ATA=y
384# CONFIG_ATA_NONSTANDARD is not set
385CONFIG_SATA_FSL=y
386# CONFIG_PATA_PLATFORM is not set
387# CONFIG_MD is not set
388# CONFIG_MACINTOSH_DRIVERS is not set
389CONFIG_NETDEVICES=y
390# CONFIG_NETDEVICES_MULTIQUEUE is not set
391# CONFIG_DUMMY is not set
392# CONFIG_BONDING is not set
393# CONFIG_MACVLAN is not set
394# CONFIG_EQUALIZER is not set
395# CONFIG_TUN is not set
396CONFIG_PHYLIB=y
397
398#
399# MII PHY device drivers
400#
401CONFIG_MARVELL_PHY=y
402# CONFIG_DAVICOM_PHY is not set
403# CONFIG_QSEMI_PHY is not set
404# CONFIG_LXT_PHY is not set
405# CONFIG_CICADA_PHY is not set
406# CONFIG_VITESSE_PHY is not set
407# CONFIG_SMSC_PHY is not set
408# CONFIG_BROADCOM_PHY is not set
409# CONFIG_ICPLUS_PHY is not set
410# CONFIG_FIXED_PHY is not set
411CONFIG_NET_ETHERNET=y
412CONFIG_MII=y
413CONFIG_NETDEV_1000=y
414CONFIG_GIANFAR=y
415# CONFIG_GFAR_NAPI is not set
416CONFIG_NETDEV_10000=y
417
418#
419# Wireless LAN
420#
421# CONFIG_WLAN_PRE80211 is not set
422# CONFIG_WLAN_80211 is not set
423# CONFIG_WAN is not set
424# CONFIG_PPP is not set
425# CONFIG_SLIP is not set
426# CONFIG_SHAPER is not set
427# CONFIG_NETCONSOLE is not set
428# CONFIG_NETPOLL is not set
429# CONFIG_NET_POLL_CONTROLLER is not set
430# CONFIG_ISDN is not set
431# CONFIG_PHONE is not set
432
433#
434# Input device support
435#
436CONFIG_INPUT=y
437# CONFIG_INPUT_FF_MEMLESS is not set
438# CONFIG_INPUT_POLLDEV is not set
439
440#
441# Userland interfaces
442#
443# CONFIG_INPUT_MOUSEDEV is not set
444# CONFIG_INPUT_JOYDEV is not set
445# CONFIG_INPUT_TSDEV is not set
446# CONFIG_INPUT_EVDEV is not set
447# CONFIG_INPUT_EVBUG is not set
448
449#
450# Input Device Drivers
451#
452# CONFIG_INPUT_KEYBOARD is not set
453# CONFIG_INPUT_MOUSE is not set
454# CONFIG_INPUT_JOYSTICK is not set
455# CONFIG_INPUT_TABLET is not set
456# CONFIG_INPUT_TOUCHSCREEN is not set
457# CONFIG_INPUT_MISC is not set
458
459#
460# Hardware I/O ports
461#
462# CONFIG_SERIO is not set
463# CONFIG_GAMEPORT is not set
464
465#
466# Character devices
467#
468# CONFIG_VT is not set
469# CONFIG_SERIAL_NONSTANDARD is not set
470
471#
472# Serial drivers
473#
474CONFIG_SERIAL_8250=y
475CONFIG_SERIAL_8250_CONSOLE=y
476CONFIG_SERIAL_8250_NR_UARTS=4
477CONFIG_SERIAL_8250_RUNTIME_UARTS=4
478# CONFIG_SERIAL_8250_EXTENDED is not set
479
480#
481# Non-8250 serial port support
482#
483# CONFIG_SERIAL_UARTLITE is not set
484CONFIG_SERIAL_CORE=y
485CONFIG_SERIAL_CORE_CONSOLE=y
486# CONFIG_SERIAL_OF_PLATFORM is not set
487CONFIG_UNIX98_PTYS=y
488CONFIG_LEGACY_PTYS=y
489CONFIG_LEGACY_PTY_COUNT=256
490# CONFIG_IPMI_HANDLER is not set
491CONFIG_WATCHDOG=y
492# CONFIG_WATCHDOG_NOWAYOUT is not set
493
494#
495# Watchdog Device Drivers
496#
497# CONFIG_SOFT_WATCHDOG is not set
498CONFIG_83xx_WDT=y
499# CONFIG_HW_RANDOM is not set
500# CONFIG_NVRAM is not set
501CONFIG_GEN_RTC=y
502# CONFIG_GEN_RTC_X is not set
503# CONFIG_R3964 is not set
504# CONFIG_RAW_DRIVER is not set
505# CONFIG_TCG_TPM is not set
506CONFIG_I2C=y
507CONFIG_I2C_BOARDINFO=y
508CONFIG_I2C_CHARDEV=y
509
510#
511# I2C Algorithms
512#
513# CONFIG_I2C_ALGOBIT is not set
514# CONFIG_I2C_ALGOPCF is not set
515# CONFIG_I2C_ALGOPCA is not set
516
517#
518# I2C Hardware Bus support
519#
520CONFIG_I2C_MPC=y
521# CONFIG_I2C_OCORES is not set
522# CONFIG_I2C_PARPORT_LIGHT is not set
523# CONFIG_I2C_SIMTEC is not set
524# CONFIG_I2C_TAOS_EVM is not set
525# CONFIG_I2C_STUB is not set
526
527#
528# Miscellaneous I2C Chip support
529#
530# CONFIG_SENSORS_DS1337 is not set
531# CONFIG_SENSORS_DS1374 is not set
532# CONFIG_DS1682 is not set
533# CONFIG_SENSORS_EEPROM is not set
534# CONFIG_SENSORS_PCF8574 is not set
535# CONFIG_SENSORS_PCA9539 is not set
536# CONFIG_SENSORS_PCF8591 is not set
537# CONFIG_SENSORS_M41T00 is not set
538# CONFIG_SENSORS_MAX6875 is not set
539# CONFIG_SENSORS_TSL2550 is not set
540# CONFIG_I2C_DEBUG_CORE is not set
541# CONFIG_I2C_DEBUG_ALGO is not set
542# CONFIG_I2C_DEBUG_BUS is not set
543# CONFIG_I2C_DEBUG_CHIP is not set
544
545#
546# SPI support
547#
548# CONFIG_SPI is not set
549# CONFIG_SPI_MASTER is not set
550# CONFIG_W1 is not set
551# CONFIG_POWER_SUPPLY is not set
552CONFIG_HWMON=y
553# CONFIG_HWMON_VID is not set
554# CONFIG_SENSORS_ABITUGURU is not set
555# CONFIG_SENSORS_ABITUGURU3 is not set
556# CONFIG_SENSORS_AD7418 is not set
557# CONFIG_SENSORS_ADM1021 is not set
558# CONFIG_SENSORS_ADM1025 is not set
559# CONFIG_SENSORS_ADM1026 is not set
560# CONFIG_SENSORS_ADM1029 is not set
561# CONFIG_SENSORS_ADM1031 is not set
562# CONFIG_SENSORS_ADM9240 is not set
563# CONFIG_SENSORS_ASB100 is not set
564# CONFIG_SENSORS_ATXP1 is not set
565# CONFIG_SENSORS_DS1621 is not set
566# CONFIG_SENSORS_F71805F is not set
567# CONFIG_SENSORS_FSCHER is not set
568# CONFIG_SENSORS_FSCPOS is not set
569# CONFIG_SENSORS_GL518SM is not set
570# CONFIG_SENSORS_GL520SM is not set
571# CONFIG_SENSORS_IT87 is not set
572# CONFIG_SENSORS_LM63 is not set
573# CONFIG_SENSORS_LM75 is not set
574# CONFIG_SENSORS_LM77 is not set
575# CONFIG_SENSORS_LM78 is not set
576# CONFIG_SENSORS_LM80 is not set
577# CONFIG_SENSORS_LM83 is not set
578# CONFIG_SENSORS_LM85 is not set
579# CONFIG_SENSORS_LM87 is not set
580# CONFIG_SENSORS_LM90 is not set
581# CONFIG_SENSORS_LM92 is not set
582# CONFIG_SENSORS_LM93 is not set
583# CONFIG_SENSORS_MAX1619 is not set
584# CONFIG_SENSORS_MAX6650 is not set
585# CONFIG_SENSORS_PC87360 is not set
586# CONFIG_SENSORS_PC87427 is not set
587# CONFIG_SENSORS_DME1737 is not set
588# CONFIG_SENSORS_SMSC47M1 is not set
589# CONFIG_SENSORS_SMSC47M192 is not set
590# CONFIG_SENSORS_SMSC47B397 is not set
591# CONFIG_SENSORS_THMC50 is not set
592# CONFIG_SENSORS_VT1211 is not set
593# CONFIG_SENSORS_W83781D is not set
594# CONFIG_SENSORS_W83791D is not set
595# CONFIG_SENSORS_W83792D is not set
596# CONFIG_SENSORS_W83793 is not set
597# CONFIG_SENSORS_W83L785TS is not set
598# CONFIG_SENSORS_W83627HF is not set
599# CONFIG_SENSORS_W83627EHF is not set
600# CONFIG_HWMON_DEBUG_CHIP is not set
601
602#
603# Multifunction device drivers
604#
605# CONFIG_MFD_SM501 is not set
606
607#
608# Multimedia devices
609#
610# CONFIG_VIDEO_DEV is not set
611# CONFIG_DVB_CORE is not set
612CONFIG_DAB=y
613
614#
615# Graphics support
616#
617# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
618
619#
620# Display device support
621#
622# CONFIG_DISPLAY_SUPPORT is not set
623# CONFIG_VGASTATE is not set
624CONFIG_VIDEO_OUTPUT_CONTROL=m
625# CONFIG_FB is not set
626# CONFIG_FB_IBM_GXT4500 is not set
627
628#
629# Sound
630#
631# CONFIG_SOUND is not set
632CONFIG_HID_SUPPORT=y
633CONFIG_HID=y
634# CONFIG_HID_DEBUG is not set
635CONFIG_USB_SUPPORT=y
636CONFIG_USB_ARCH_HAS_HCD=y
637# CONFIG_USB_ARCH_HAS_OHCI is not set
638CONFIG_USB_ARCH_HAS_EHCI=y
639# CONFIG_USB is not set
640
641#
642# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
643#
644
645#
646# USB Gadget Support
647#
648# CONFIG_USB_GADGET is not set
649# CONFIG_MMC is not set
650# CONFIG_NEW_LEDS is not set
651# CONFIG_EDAC is not set
652# CONFIG_RTC_CLASS is not set
653
654#
655# DMA Engine support
656#
657# CONFIG_DMA_ENGINE is not set
658
659#
660# DMA Clients
661#
662
663#
664# DMA Devices
665#
666
667#
668# Userspace I/O
669#
670# CONFIG_UIO is not set
671
672#
673# File systems
674#
675CONFIG_EXT2_FS=y
676# CONFIG_EXT2_FS_XATTR is not set
677# CONFIG_EXT2_FS_XIP is not set
678CONFIG_EXT3_FS=y
679CONFIG_EXT3_FS_XATTR=y
680# CONFIG_EXT3_FS_POSIX_ACL is not set
681# CONFIG_EXT3_FS_SECURITY is not set
682# CONFIG_EXT4DEV_FS is not set
683CONFIG_JBD=y
684# CONFIG_JBD_DEBUG is not set
685CONFIG_FS_MBCACHE=y
686# CONFIG_REISERFS_FS is not set
687# CONFIG_JFS_FS is not set
688# CONFIG_FS_POSIX_ACL is not set
689# CONFIG_XFS_FS is not set
690# CONFIG_GFS2_FS is not set
691# CONFIG_OCFS2_FS is not set
692# CONFIG_MINIX_FS is not set
693# CONFIG_ROMFS_FS is not set
694CONFIG_INOTIFY=y
695CONFIG_INOTIFY_USER=y
696# CONFIG_QUOTA is not set
697CONFIG_DNOTIFY=y
698# CONFIG_AUTOFS_FS is not set
699# CONFIG_AUTOFS4_FS is not set
700# CONFIG_FUSE_FS is not set
701
702#
703# CD-ROM/DVD Filesystems
704#
705# CONFIG_ISO9660_FS is not set
706# CONFIG_UDF_FS is not set
707
708#
709# DOS/FAT/NT Filesystems
710#
711# CONFIG_MSDOS_FS is not set
712# CONFIG_VFAT_FS is not set
713# CONFIG_NTFS_FS is not set
714
715#
716# Pseudo filesystems
717#
718CONFIG_PROC_FS=y
719CONFIG_PROC_KCORE=y
720CONFIG_PROC_SYSCTL=y
721CONFIG_SYSFS=y
722CONFIG_TMPFS=y
723# CONFIG_TMPFS_POSIX_ACL is not set
724# CONFIG_HUGETLB_PAGE is not set
725CONFIG_RAMFS=y
726# CONFIG_CONFIGFS_FS is not set
727
728#
729# Miscellaneous filesystems
730#
731# CONFIG_ADFS_FS is not set
732# CONFIG_AFFS_FS is not set
733# CONFIG_HFS_FS is not set
734# CONFIG_HFSPLUS_FS is not set
735# CONFIG_BEFS_FS is not set
736# CONFIG_BFS_FS is not set
737# CONFIG_EFS_FS is not set
738# CONFIG_CRAMFS is not set
739# CONFIG_VXFS_FS is not set
740# CONFIG_HPFS_FS is not set
741# CONFIG_QNX4FS_FS is not set
742# CONFIG_SYSV_FS is not set
743# CONFIG_UFS_FS is not set
744
745#
746# Network File Systems
747#
748CONFIG_NFS_FS=y
749CONFIG_NFS_V3=y
750# CONFIG_NFS_V3_ACL is not set
751CONFIG_NFS_V4=y
752# CONFIG_NFS_DIRECTIO is not set
753# CONFIG_NFSD is not set
754CONFIG_ROOT_NFS=y
755CONFIG_LOCKD=y
756CONFIG_LOCKD_V4=y
757CONFIG_NFS_COMMON=y
758CONFIG_SUNRPC=y
759CONFIG_SUNRPC_GSS=y
760# CONFIG_SUNRPC_BIND34 is not set
761CONFIG_RPCSEC_GSS_KRB5=y
762# CONFIG_RPCSEC_GSS_SPKM3 is not set
763# CONFIG_SMB_FS is not set
764# CONFIG_CIFS is not set
765# CONFIG_NCP_FS is not set
766# CONFIG_CODA_FS is not set
767# CONFIG_AFS_FS is not set
768
769#
770# Partition Types
771#
772CONFIG_PARTITION_ADVANCED=y
773# CONFIG_ACORN_PARTITION is not set
774# CONFIG_OSF_PARTITION is not set
775# CONFIG_AMIGA_PARTITION is not set
776# CONFIG_ATARI_PARTITION is not set
777# CONFIG_MAC_PARTITION is not set
778CONFIG_MSDOS_PARTITION=y
779# CONFIG_BSD_DISKLABEL is not set
780# CONFIG_MINIX_SUBPARTITION is not set
781# CONFIG_SOLARIS_X86_PARTITION is not set
782# CONFIG_UNIXWARE_DISKLABEL is not set
783# CONFIG_LDM_PARTITION is not set
784# CONFIG_SGI_PARTITION is not set
785# CONFIG_ULTRIX_PARTITION is not set
786# CONFIG_SUN_PARTITION is not set
787# CONFIG_KARMA_PARTITION is not set
788# CONFIG_EFI_PARTITION is not set
789# CONFIG_SYSV68_PARTITION is not set
790
791#
792# Native Language Support
793#
794# CONFIG_NLS is not set
795
796#
797# Distributed Lock Manager
798#
799# CONFIG_DLM is not set
800# CONFIG_UCC_SLOW is not set
801
802#
803# Library routines
804#
805CONFIG_BITREVERSE=y
806# CONFIG_CRC_CCITT is not set
807# CONFIG_CRC16 is not set
808# CONFIG_CRC_ITU_T is not set
809CONFIG_CRC32=y
810# CONFIG_CRC7 is not set
811# CONFIG_LIBCRC32C is not set
812CONFIG_PLIST=y
813CONFIG_HAS_IOMEM=y
814CONFIG_HAS_IOPORT=y
815CONFIG_HAS_DMA=y
816
817#
818# Instrumentation Support
819#
820# CONFIG_PROFILING is not set
821# CONFIG_KPROBES is not set
822
823#
824# Kernel hacking
825#
826# CONFIG_PRINTK_TIME is not set
827CONFIG_ENABLE_MUST_CHECK=y
828# CONFIG_MAGIC_SYSRQ is not set
829# CONFIG_UNUSED_SYMBOLS is not set
830# CONFIG_DEBUG_FS is not set
831# CONFIG_HEADERS_CHECK is not set
832# CONFIG_DEBUG_KERNEL is not set
833# CONFIG_DEBUG_BUGVERBOSE is not set
834# CONFIG_PPC_EARLY_DEBUG is not set
835
836#
837# Security options
838#
839# CONFIG_KEYS is not set
840# CONFIG_SECURITY is not set
841CONFIG_CRYPTO=y
842CONFIG_CRYPTO_ALGAPI=y
843CONFIG_CRYPTO_BLKCIPHER=y
844CONFIG_CRYPTO_MANAGER=y
845# CONFIG_CRYPTO_HMAC is not set
846# CONFIG_CRYPTO_XCBC is not set
847# CONFIG_CRYPTO_NULL is not set
848# CONFIG_CRYPTO_MD4 is not set
849CONFIG_CRYPTO_MD5=y
850# CONFIG_CRYPTO_SHA1 is not set
851# CONFIG_CRYPTO_SHA256 is not set
852# CONFIG_CRYPTO_SHA512 is not set
853# CONFIG_CRYPTO_WP512 is not set
854# CONFIG_CRYPTO_TGR192 is not set
855# CONFIG_CRYPTO_GF128MUL is not set
856CONFIG_CRYPTO_ECB=m
857CONFIG_CRYPTO_CBC=y
858CONFIG_CRYPTO_PCBC=m
859# CONFIG_CRYPTO_LRW is not set
860# CONFIG_CRYPTO_CRYPTD is not set
861CONFIG_CRYPTO_DES=y
862# CONFIG_CRYPTO_FCRYPT is not set
863# CONFIG_CRYPTO_BLOWFISH is not set
864# CONFIG_CRYPTO_TWOFISH is not set
865# CONFIG_CRYPTO_SERPENT is not set
866# CONFIG_CRYPTO_AES is not set
867# CONFIG_CRYPTO_CAST5 is not set
868# CONFIG_CRYPTO_CAST6 is not set
869# CONFIG_CRYPTO_TEA is not set
870# CONFIG_CRYPTO_ARC4 is not set
871# CONFIG_CRYPTO_KHAZAD is not set
872# CONFIG_CRYPTO_ANUBIS is not set
873# CONFIG_CRYPTO_DEFLATE is not set
874# CONFIG_CRYPTO_MICHAEL_MIC is not set
875# CONFIG_CRYPTO_CRC32C is not set
876# CONFIG_CRYPTO_CAMELLIA is not set
877# CONFIG_CRYPTO_TEST is not set
878CONFIG_CRYPTO_HW=y
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index 5760b9f033ea..7695a4c66e80 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.24-rc4 3# Linux kernel version: 2.6.24-rc4
4# Thu Dec 6 16:49:07 2007 4# Fri Dec 21 14:47:29 2007
5# 5#
6CONFIG_PPC64=y 6CONFIG_PPC64=y
7 7
@@ -211,7 +211,7 @@ CONFIG_MMIO_NVRAM=y
211CONFIG_MPIC_U3_HT_IRQS=y 211CONFIG_MPIC_U3_HT_IRQS=y
212CONFIG_MPIC_BROKEN_REGREAD=y 212CONFIG_MPIC_BROKEN_REGREAD=y
213CONFIG_IBMVIO=y 213CONFIG_IBMVIO=y
214# CONFIG_IBMEBUS is not set 214CONFIG_IBMEBUS=y
215# CONFIG_PPC_MPC106 is not set 215# CONFIG_PPC_MPC106 is not set
216CONFIG_PPC_970_NAP=y 216CONFIG_PPC_970_NAP=y
217CONFIG_PPC_INDIRECT_IO=y 217CONFIG_PPC_INDIRECT_IO=y
@@ -375,7 +375,7 @@ CONFIG_INET_TUNNEL=y
375CONFIG_INET_XFRM_MODE_TRANSPORT=y 375CONFIG_INET_XFRM_MODE_TRANSPORT=y
376CONFIG_INET_XFRM_MODE_TUNNEL=y 376CONFIG_INET_XFRM_MODE_TUNNEL=y
377CONFIG_INET_XFRM_MODE_BEET=y 377CONFIG_INET_XFRM_MODE_BEET=y
378# CONFIG_INET_LRO is not set 378CONFIG_INET_LRO=m
379CONFIG_INET_DIAG=y 379CONFIG_INET_DIAG=y
380CONFIG_INET_TCP_DIAG=y 380CONFIG_INET_TCP_DIAG=y
381# CONFIG_TCP_CONG_ADVANCED is not set 381# CONFIG_TCP_CONG_ADVANCED is not set
@@ -929,6 +929,7 @@ CONFIG_SPIDER_NET=m
929CONFIG_NETDEV_10000=y 929CONFIG_NETDEV_10000=y
930# CONFIG_CHELSIO_T1 is not set 930# CONFIG_CHELSIO_T1 is not set
931# CONFIG_CHELSIO_T3 is not set 931# CONFIG_CHELSIO_T3 is not set
932CONFIG_EHEA=m
932# CONFIG_IXGBE is not set 933# CONFIG_IXGBE is not set
933CONFIG_IXGB=m 934CONFIG_IXGB=m
934# CONFIG_IXGB_NAPI is not set 935# CONFIG_IXGB_NAPI is not set
@@ -1558,6 +1559,7 @@ CONFIG_INFINIBAND_ADDR_TRANS=y
1558CONFIG_INFINIBAND_MTHCA=m 1559CONFIG_INFINIBAND_MTHCA=m
1559CONFIG_INFINIBAND_MTHCA_DEBUG=y 1560CONFIG_INFINIBAND_MTHCA_DEBUG=y
1560# CONFIG_INFINIBAND_IPATH is not set 1561# CONFIG_INFINIBAND_IPATH is not set
1562CONFIG_INFINIBAND_EHCA=m
1561# CONFIG_INFINIBAND_AMSO1100 is not set 1563# CONFIG_INFINIBAND_AMSO1100 is not set
1562# CONFIG_MLX4_INFINIBAND is not set 1564# CONFIG_MLX4_INFINIBAND is not set
1563CONFIG_INFINIBAND_IPOIB=m 1565CONFIG_INFINIBAND_IPOIB=m
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index ca51f0cf27ab..9374bc9a2dd1 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5ifeq ($(CONFIG_PPC64),y) 5ifeq ($(CONFIG_PPC64),y)
6EXTRA_CFLAGS += -mno-minimal-toc 6CFLAGS_prom_init.o += -mno-minimal-toc
7endif 7endif
8ifeq ($(CONFIG_PPC32),y) 8ifeq ($(CONFIG_PPC32),y)
9CFLAGS_prom_init.o += -fPIC 9CFLAGS_prom_init.o += -fPIC
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 9ed351f3c966..7c21f52d982a 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -888,7 +888,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
888 .cpu_setup = __setup_cpu_603, 888 .cpu_setup = __setup_cpu_603,
889 .platform = "ppc603", 889 .platform = "ppc603",
890 }, 890 },
891 { /* e300c3 on 83xx */ 891 { /* e300c3 (e300c1, plus one IU, half cache size) on 83xx */
892 .pvr_mask = 0x7fff0000, 892 .pvr_mask = 0x7fff0000,
893 .pvr_value = 0x00850000, 893 .pvr_value = 0x00850000,
894 .cpu_name = "e300c3", 894 .cpu_name = "e300c3",
@@ -899,6 +899,17 @@ static struct cpu_spec __initdata cpu_specs[] = {
899 .cpu_setup = __setup_cpu_603, 899 .cpu_setup = __setup_cpu_603,
900 .platform = "ppc603", 900 .platform = "ppc603",
901 }, 901 },
902 { /* e300c4 (e300c1, plus one IU) */
903 .pvr_mask = 0x7fff0000,
904 .pvr_value = 0x00860000,
905 .cpu_name = "e300c4",
906 .cpu_features = CPU_FTRS_E300,
907 .cpu_user_features = COMMON_USER,
908 .icache_bsize = 32,
909 .dcache_bsize = 32,
910 .cpu_setup = __setup_cpu_603,
911 .platform = "ppc603",
912 },
902 { /* default match, we assume split I/D cache & TB (non-601)... */ 913 { /* default match, we assume split I/D cache & TB (non-601)... */
903 .pvr_mask = 0x00000000, 914 .pvr_mask = 0x00000000,
904 .pvr_value = 0x00000000, 915 .pvr_value = 0x00000000,
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 72fd87156b24..caae49ff0668 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -52,7 +52,7 @@ static struct device ibmebus_bus_device = { /* fake "parent" device */
52struct bus_type ibmebus_bus_type; 52struct bus_type ibmebus_bus_type;
53 53
54/* These devices will automatically be added to the bus during init */ 54/* These devices will automatically be added to the bus during init */
55static struct of_device_id builtin_matches[] = { 55static struct of_device_id __initdata builtin_matches[] = {
56 { .compatible = "IBM,lhca" }, 56 { .compatible = "IBM,lhca" },
57 { .compatible = "IBM,lhea" }, 57 { .compatible = "IBM,lhea" },
58 {}, 58 {},
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 2d0c9ef555e9..47c3fe55242f 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -526,16 +526,14 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
526 return tbl; 526 return tbl;
527} 527}
528 528
529void iommu_free_table(struct device_node *dn) 529void iommu_free_table(struct iommu_table *tbl, const char *node_name)
530{ 530{
531 struct pci_dn *pdn = dn->data;
532 struct iommu_table *tbl = pdn->iommu_table;
533 unsigned long bitmap_sz, i; 531 unsigned long bitmap_sz, i;
534 unsigned int order; 532 unsigned int order;
535 533
536 if (!tbl || !tbl->it_map) { 534 if (!tbl || !tbl->it_map) {
537 printk(KERN_ERR "%s: expected TCE map for %s\n", __FUNCTION__, 535 printk(KERN_ERR "%s: expected TCE map for %s\n", __FUNCTION__,
538 dn->full_name); 536 node_name);
539 return; 537 return;
540 } 538 }
541 539
@@ -544,7 +542,7 @@ void iommu_free_table(struct device_node *dn)
544 for (i = 0; i < (tbl->it_size/64); i++) { 542 for (i = 0; i < (tbl->it_size/64); i++) {
545 if (tbl->it_map[i] != 0) { 543 if (tbl->it_map[i] != 0) {
546 printk(KERN_WARNING "%s: Unexpected TCEs for %s\n", 544 printk(KERN_WARNING "%s: Unexpected TCEs for %s\n",
547 __FUNCTION__, dn->full_name); 545 __FUNCTION__, node_name);
548 break; 546 break;
549 } 547 }
550 } 548 }
diff --git a/arch/powerpc/kernel/isa-bridge.c b/arch/powerpc/kernel/isa-bridge.c
index f0f49d1be3d5..ee172aa42aa7 100644
--- a/arch/powerpc/kernel/isa-bridge.c
+++ b/arch/powerpc/kernel/isa-bridge.c
@@ -108,7 +108,7 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
108 if (size > 0x10000) 108 if (size > 0x10000)
109 size = 0x10000; 109 size = 0x10000;
110 110
111 printk(KERN_ERR "no ISA IO ranges or unexpected isa range," 111 printk(KERN_ERR "no ISA IO ranges or unexpected isa range, "
112 "mapping 64k\n"); 112 "mapping 64k\n");
113 113
114 __ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE, 114 __ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE,
@@ -116,7 +116,7 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
116 return; 116 return;
117 117
118inval_range: 118inval_range:
119 printk(KERN_ERR "no ISA IO ranges or unexpected isa range," 119 printk(KERN_ERR "no ISA IO ranges or unexpected isa range, "
120 "mapping 64k\n"); 120 "mapping 64k\n");
121 __ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE, 121 __ioremap_at(phb_io_base_phys, (void *)ISA_IO_BASE,
122 0x10000, _PAGE_NO_CACHE|_PAGE_GUARDED); 122 0x10000, _PAGE_NO_CACHE|_PAGE_GUARDED);
@@ -145,7 +145,7 @@ void __init isa_bridge_find_early(struct pci_controller *hose)
145 for_each_node_by_type(np, "isa") { 145 for_each_node_by_type(np, "isa") {
146 /* Look for our hose being a parent */ 146 /* Look for our hose being a parent */
147 for (parent = of_get_parent(np); parent;) { 147 for (parent = of_get_parent(np); parent;) {
148 if (parent == hose->arch_data) { 148 if (parent == hose->dn) {
149 of_node_put(parent); 149 of_node_put(parent);
150 break; 150 break;
151 } 151 }
diff --git a/arch/powerpc/kernel/legacy_serial.c b/arch/powerpc/kernel/legacy_serial.c
index 4ed58875ee17..b9cae6b1f8ca 100644
--- a/arch/powerpc/kernel/legacy_serial.c
+++ b/arch/powerpc/kernel/legacy_serial.c
@@ -474,7 +474,7 @@ static int __init serial_dev_init(void)
474 474
475 /* 475 /*
476 * Before we register the platfrom serial devices, we need 476 * Before we register the platfrom serial devices, we need
477 * to fixup their interrutps and their IO ports. 477 * to fixup their interrupts and their IO ports.
478 */ 478 */
479 DBG("Fixing serial ports interrupts and IO ports ...\n"); 479 DBG("Fixing serial ports interrupts and IO ports ...\n");
480 480
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index ff781b2eddec..dcb89a88df46 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -41,7 +41,6 @@
41/* #define LPARCFG_DEBUG */ 41/* #define LPARCFG_DEBUG */
42 42
43static struct proc_dir_entry *proc_ppc64_lparcfg; 43static struct proc_dir_entry *proc_ppc64_lparcfg;
44#define LPARCFG_BUFF_SIZE 4096
45 44
46/* 45/*
47 * Track sum of all purrs across all processors. This is used to further 46 * Track sum of all purrs across all processors. This is used to further
@@ -595,13 +594,6 @@ int __init lparcfg_init(void)
595 ent = create_proc_entry("ppc64/lparcfg", mode, NULL); 594 ent = create_proc_entry("ppc64/lparcfg", mode, NULL);
596 if (ent) { 595 if (ent) {
597 ent->proc_fops = &lparcfg_fops; 596 ent->proc_fops = &lparcfg_fops;
598 ent->data = kmalloc(LPARCFG_BUFF_SIZE, GFP_KERNEL);
599 if (!ent->data) {
600 printk(KERN_ERR
601 "Failed to allocate buffer for lparcfg\n");
602 remove_proc_entry("lparcfg", ent->parent);
603 return -ENOMEM;
604 }
605 } else { 597 } else {
606 printk(KERN_ERR "Failed to create ppc64/lparcfg\n"); 598 printk(KERN_ERR "Failed to create ppc64/lparcfg\n");
607 return -EIO; 599 return -EIO;
@@ -613,10 +605,8 @@ int __init lparcfg_init(void)
613 605
614void __exit lparcfg_cleanup(void) 606void __exit lparcfg_cleanup(void)
615{ 607{
616 if (proc_ppc64_lparcfg) { 608 if (proc_ppc64_lparcfg)
617 kfree(proc_ppc64_lparcfg->data);
618 remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent); 609 remove_proc_entry("lparcfg", proc_ppc64_lparcfg->parent);
619 }
620} 610}
621 611
622module_init(lparcfg_init); 612module_init(lparcfg_init);
diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S
index 330c9dc7db86..74ce0c7a7b1e 100644
--- a/arch/powerpc/kernel/misc.S
+++ b/arch/powerpc/kernel/misc.S
@@ -14,6 +14,7 @@
14 * 2 of the License, or (at your option) any later version. 14 * 2 of the License, or (at your option) any later version.
15 */ 15 */
16#include <asm/ppc_asm.h> 16#include <asm/ppc_asm.h>
17#include <asm/unistd.h>
17 18
18 .text 19 .text
19 20
@@ -43,3 +44,10 @@ _GLOBAL(add_reloc_offset)
43 add r3,r3,r5 44 add r3,r3,r5
44 mtlr r0 45 mtlr r0
45 blr 46 blr
47
48_GLOBAL(kernel_execve)
49 li r0,__NR_execve
50 sc
51 bnslr
52 neg r3,r3
53 blr
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S
index 8b642ab26d37..ea1137851a4a 100644
--- a/arch/powerpc/kernel/misc_32.S
+++ b/arch/powerpc/kernel/misc_32.S
@@ -793,13 +793,6 @@ _GLOBAL(kernel_thread)
793 addi r1,r1,16 793 addi r1,r1,16
794 blr 794 blr
795 795
796_GLOBAL(kernel_execve)
797 li r0,__NR_execve
798 sc
799 bnslr
800 neg r3,r3
801 blr
802
803/* 796/*
804 * This routine is just here to keep GCC happy - sigh... 797 * This routine is just here to keep GCC happy - sigh...
805 */ 798 */
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index bbb3ba54c51c..a3c491e88a72 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -518,13 +518,6 @@ _GLOBAL(giveup_altivec)
518 518
519#endif /* CONFIG_ALTIVEC */ 519#endif /* CONFIG_ALTIVEC */
520 520
521_GLOBAL(kernel_execve)
522 li r0,__NR_execve
523 sc
524 bnslr
525 neg r3,r3
526 blr
527
528/* kexec_wait(phys_cpu) 521/* kexec_wait(phys_cpu)
529 * 522 *
530 * wait for the flag to change, indicating this kernel is going away but 523 * wait for the flag to change, indicating this kernel is going away but
diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c
index 07a89a398639..eab313858315 100644
--- a/arch/powerpc/kernel/module_32.c
+++ b/arch/powerpc/kernel/module_32.c
@@ -24,6 +24,7 @@
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/cache.h> 25#include <linux/cache.h>
26#include <linux/bug.h> 26#include <linux/bug.h>
27#include <linux/sort.h>
27 28
28#include "setup.h" 29#include "setup.h"
29 30
@@ -54,22 +55,60 @@ void module_free(struct module *mod, void *module_region)
54 addend) */ 55 addend) */
55static unsigned int count_relocs(const Elf32_Rela *rela, unsigned int num) 56static unsigned int count_relocs(const Elf32_Rela *rela, unsigned int num)
56{ 57{
57 unsigned int i, j, ret = 0; 58 unsigned int i, r_info, r_addend, _count_relocs;
58 59
59 /* Sure, this is order(n^2), but it's usually short, and not 60 _count_relocs = 0;
60 time critical */ 61 r_info = 0;
61 for (i = 0; i < num; i++) { 62 r_addend = 0;
62 for (j = 0; j < i; j++) { 63 for (i = 0; i < num; i++)
63 /* If this addend appeared before, it's 64 /* Only count 24-bit relocs, others don't need stubs */
64 already been counted */ 65 if (ELF32_R_TYPE(rela[i].r_info) == R_PPC_REL24 &&
65 if (ELF32_R_SYM(rela[i].r_info) 66 (r_info != ELF32_R_SYM(rela[i].r_info) ||
66 == ELF32_R_SYM(rela[j].r_info) 67 r_addend != rela[i].r_addend)) {
67 && rela[i].r_addend == rela[j].r_addend) 68 _count_relocs++;
68 break; 69 r_info = ELF32_R_SYM(rela[i].r_info);
70 r_addend = rela[i].r_addend;
69 } 71 }
70 if (j == i) ret++; 72
73 return _count_relocs;
74}
75
76static int relacmp(const void *_x, const void *_y)
77{
78 const Elf32_Rela *x, *y;
79
80 y = (Elf32_Rela *)_x;
81 x = (Elf32_Rela *)_y;
82
83 /* Compare the entire r_info (as opposed to ELF32_R_SYM(r_info) only) to
84 * make the comparison cheaper/faster. It won't affect the sorting or
85 * the counting algorithms' performance
86 */
87 if (x->r_info < y->r_info)
88 return -1;
89 else if (x->r_info > y->r_info)
90 return 1;
91 else if (x->r_addend < y->r_addend)
92 return -1;
93 else if (x->r_addend > y->r_addend)
94 return 1;
95 else
96 return 0;
97}
98
99static void relaswap(void *_x, void *_y, int size)
100{
101 uint32_t *x, *y, tmp;
102 int i;
103
104 y = (uint32_t *)_x;
105 x = (uint32_t *)_y;
106
107 for (i = 0; i < sizeof(Elf32_Rela) / sizeof(uint32_t); i++) {
108 tmp = x[i];
109 x[i] = y[i];
110 y[i] = tmp;
71 } 111 }
72 return ret;
73} 112}
74 113
75/* Get the potential trampolines size required of the init and 114/* Get the potential trampolines size required of the init and
@@ -100,6 +139,16 @@ static unsigned long get_plt_size(const Elf32_Ehdr *hdr,
100 DEBUGP("Ptr: %p. Number: %u\n", 139 DEBUGP("Ptr: %p. Number: %u\n",
101 (void *)hdr + sechdrs[i].sh_offset, 140 (void *)hdr + sechdrs[i].sh_offset,
102 sechdrs[i].sh_size / sizeof(Elf32_Rela)); 141 sechdrs[i].sh_size / sizeof(Elf32_Rela));
142
143 /* Sort the relocation information based on a symbol and
144 * addend key. This is a stable O(n*log n) complexity
145 * alogrithm but it will reduce the complexity of
146 * count_relocs() to linear complexity O(n)
147 */
148 sort((void *)hdr + sechdrs[i].sh_offset,
149 sechdrs[i].sh_size / sizeof(Elf32_Rela),
150 sizeof(Elf32_Rela), relacmp, relaswap);
151
103 ret += count_relocs((void *)hdr 152 ret += count_relocs((void *)hdr
104 + sechdrs[i].sh_offset, 153 + sechdrs[i].sh_offset,
105 sechdrs[i].sh_size 154 sechdrs[i].sh_size
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 75c7c4f19280..3a82b02b784b 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -24,6 +24,7 @@
24#include <asm/module.h> 24#include <asm/module.h>
25#include <asm/uaccess.h> 25#include <asm/uaccess.h>
26#include <asm/firmware.h> 26#include <asm/firmware.h>
27#include <linux/sort.h>
27 28
28#include "setup.h" 29#include "setup.h"
29 30
@@ -81,25 +82,23 @@ static struct ppc64_stub_entry ppc64_stub =
81 different addend) */ 82 different addend) */
82static unsigned int count_relocs(const Elf64_Rela *rela, unsigned int num) 83static unsigned int count_relocs(const Elf64_Rela *rela, unsigned int num)
83{ 84{
84 unsigned int i, j, ret = 0; 85 unsigned int i, r_info, r_addend, _count_relocs;
85 86
86 /* FIXME: Only count external ones --RR */ 87 /* FIXME: Only count external ones --RR */
87 /* Sure, this is order(n^2), but it's usually short, and not 88 _count_relocs = 0;
88 time critical */ 89 r_info = 0;
89 for (i = 0; i < num; i++) { 90 r_addend = 0;
91 for (i = 0; i < num; i++)
90 /* Only count 24-bit relocs, others don't need stubs */ 92 /* Only count 24-bit relocs, others don't need stubs */
91 if (ELF64_R_TYPE(rela[i].r_info) != R_PPC_REL24) 93 if (ELF64_R_TYPE(rela[i].r_info) == R_PPC_REL24 &&
92 continue; 94 (r_info != ELF64_R_SYM(rela[i].r_info) ||
93 for (j = 0; j < i; j++) { 95 r_addend != rela[i].r_addend)) {
94 /* If this addend appeared before, it's 96 _count_relocs++;
95 already been counted */ 97 r_info = ELF64_R_SYM(rela[i].r_info);
96 if (rela[i].r_info == rela[j].r_info 98 r_addend = rela[i].r_addend;
97 && rela[i].r_addend == rela[j].r_addend)
98 break;
99 } 99 }
100 if (j == i) ret++; 100
101 } 101 return _count_relocs;
102 return ret;
103} 102}
104 103
105void *module_alloc(unsigned long size) 104void *module_alloc(unsigned long size)
@@ -118,6 +117,44 @@ void module_free(struct module *mod, void *module_region)
118 table entries. */ 117 table entries. */
119} 118}
120 119
120static int relacmp(const void *_x, const void *_y)
121{
122 const Elf64_Rela *x, *y;
123
124 y = (Elf64_Rela *)_x;
125 x = (Elf64_Rela *)_y;
126
127 /* Compare the entire r_info (as opposed to ELF64_R_SYM(r_info) only) to
128 * make the comparison cheaper/faster. It won't affect the sorting or
129 * the counting algorithms' performance
130 */
131 if (x->r_info < y->r_info)
132 return -1;
133 else if (x->r_info > y->r_info)
134 return 1;
135 else if (x->r_addend < y->r_addend)
136 return -1;
137 else if (x->r_addend > y->r_addend)
138 return 1;
139 else
140 return 0;
141}
142
143static void relaswap(void *_x, void *_y, int size)
144{
145 uint64_t *x, *y, tmp;
146 int i;
147
148 y = (uint64_t *)_x;
149 x = (uint64_t *)_y;
150
151 for (i = 0; i < sizeof(Elf64_Rela) / sizeof(uint64_t); i++) {
152 tmp = x[i];
153 x[i] = y[i];
154 y[i] = tmp;
155 }
156}
157
121/* Get size of potential trampolines required. */ 158/* Get size of potential trampolines required. */
122static unsigned long get_stubs_size(const Elf64_Ehdr *hdr, 159static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
123 const Elf64_Shdr *sechdrs) 160 const Elf64_Shdr *sechdrs)
@@ -133,6 +170,16 @@ static unsigned long get_stubs_size(const Elf64_Ehdr *hdr,
133 DEBUGP("Ptr: %p. Number: %lu\n", 170 DEBUGP("Ptr: %p. Number: %lu\n",
134 (void *)sechdrs[i].sh_addr, 171 (void *)sechdrs[i].sh_addr,
135 sechdrs[i].sh_size / sizeof(Elf64_Rela)); 172 sechdrs[i].sh_size / sizeof(Elf64_Rela));
173
174 /* Sort the relocation information based on a symbol and
175 * addend key. This is a stable O(n*log n) complexity
176 * alogrithm but it will reduce the complexity of
177 * count_relocs() to linear complexity O(n)
178 */
179 sort((void *)sechdrs[i].sh_addr,
180 sechdrs[i].sh_size / sizeof(Elf64_Rela),
181 sizeof(Elf64_Rela), relacmp, relaswap);
182
136 relocs += count_relocs((void *)sechdrs[i].sh_addr, 183 relocs += count_relocs((void *)sechdrs[i].sh_addr,
137 sechdrs[i].sh_size 184 sechdrs[i].sh_size
138 / sizeof(Elf64_Rela)); 185 / sizeof(Elf64_Rela));
@@ -343,7 +390,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
343 /* Simply set it */ 390 /* Simply set it */
344 *(u32 *)location = value; 391 *(u32 *)location = value;
345 break; 392 break;
346 393
347 case R_PPC64_ADDR64: 394 case R_PPC64_ADDR64:
348 /* Simply set it */ 395 /* Simply set it */
349 *(unsigned long *)location = value; 396 *(unsigned long *)location = value;
@@ -399,7 +446,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
399 } 446 }
400 447
401 /* Only replace bits 2 through 26 */ 448 /* Only replace bits 2 through 26 */
402 *(uint32_t *)location 449 *(uint32_t *)location
403 = (*(uint32_t *)location & ~0x03fffffc) 450 = (*(uint32_t *)location & ~0x03fffffc)
404 | (value & 0x03fffffc); 451 | (value & 0x03fffffc);
405 break; 452 break;
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index aeaa20268ce2..de36e235a60a 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -40,7 +40,7 @@
40 * a bus type in the list 40 * a bus type in the list
41 */ 41 */
42 42
43static struct of_device_id of_default_bus_ids[] = { 43static const struct of_device_id of_default_bus_ids[] = {
44 { .type = "soc", }, 44 { .type = "soc", },
45 { .compatible = "soc", }, 45 { .compatible = "soc", },
46 { .type = "spider", }, 46 { .type = "spider", },
@@ -64,26 +64,6 @@ static int __init of_bus_driver_init(void)
64 64
65postcore_initcall(of_bus_driver_init); 65postcore_initcall(of_bus_driver_init);
66 66
67int of_register_platform_driver(struct of_platform_driver *drv)
68{
69 /* initialize common driver fields */
70 if (!drv->driver.name)
71 drv->driver.name = drv->name;
72 if (!drv->driver.owner)
73 drv->driver.owner = drv->owner;
74 drv->driver.bus = &of_platform_bus_type;
75
76 /* register with core */
77 return driver_register(&drv->driver);
78}
79EXPORT_SYMBOL(of_register_platform_driver);
80
81void of_unregister_platform_driver(struct of_platform_driver *drv)
82{
83 driver_unregister(&drv->driver);
84}
85EXPORT_SYMBOL(of_unregister_platform_driver);
86
87struct of_device* of_platform_device_create(struct device_node *np, 67struct of_device* of_platform_device_create(struct device_node *np,
88 const char *bus_id, 68 const char *bus_id,
89 struct device *parent) 69 struct device *parent)
@@ -120,8 +100,8 @@ EXPORT_SYMBOL(of_platform_device_create);
120 * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to 100 * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
121 * disallow recursive creation of child busses 101 * disallow recursive creation of child busses
122 */ 102 */
123static int of_platform_bus_create(struct device_node *bus, 103static int of_platform_bus_create(const struct device_node *bus,
124 struct of_device_id *matches, 104 const struct of_device_id *matches,
125 struct device *parent) 105 struct device *parent)
126{ 106{
127 struct device_node *child; 107 struct device_node *child;
@@ -157,7 +137,7 @@ static int of_platform_bus_create(struct device_node *bus,
157 */ 137 */
158 138
159int of_platform_bus_probe(struct device_node *root, 139int of_platform_bus_probe(struct device_node *root,
160 struct of_device_id *matches, 140 const struct of_device_id *matches,
161 struct device *parent) 141 struct device *parent)
162{ 142{
163 struct device_node *child; 143 struct device_node *child;
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 2ae3b6f778a3..571854f2906c 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -48,32 +48,26 @@
48static DEFINE_SPINLOCK(hose_spinlock); 48static DEFINE_SPINLOCK(hose_spinlock);
49 49
50/* XXX kill that some day ... */ 50/* XXX kill that some day ... */
51int global_phb_number; /* Global phb counter */ 51static int global_phb_number; /* Global phb counter */
52 52
53extern struct list_head hose_list; 53/* ISA Memory physical address */
54resource_size_t isa_mem_base;
54 55
55/* 56/* Default PCI flags is 0 */
56 * pci_controller(phb) initialized common variables. 57unsigned int ppc_pci_flags;
57 */
58static void __devinit pci_setup_pci_controller(struct pci_controller *hose)
59{
60 memset(hose, 0, sizeof(struct pci_controller));
61
62 spin_lock(&hose_spinlock);
63 hose->global_number = global_phb_number++;
64 list_add_tail(&hose->list_node, &hose_list);
65 spin_unlock(&hose_spinlock);
66}
67 58
68struct pci_controller * pcibios_alloc_controller(struct device_node *dev) 59struct pci_controller *pcibios_alloc_controller(struct device_node *dev)
69{ 60{
70 struct pci_controller *phb; 61 struct pci_controller *phb;
71 62
72 phb = alloc_maybe_bootmem(sizeof(struct pci_controller), GFP_KERNEL); 63 phb = zalloc_maybe_bootmem(sizeof(struct pci_controller), GFP_KERNEL);
73 if (phb == NULL) 64 if (phb == NULL)
74 return NULL; 65 return NULL;
75 pci_setup_pci_controller(phb); 66 spin_lock(&hose_spinlock);
76 phb->arch_data = dev; 67 phb->global_number = global_phb_number++;
68 list_add_tail(&phb->list_node, &hose_list);
69 spin_unlock(&hose_spinlock);
70 phb->dn = dev;
77 phb->is_dynamic = mem_init_done; 71 phb->is_dynamic = mem_init_done;
78#ifdef CONFIG_PPC64 72#ifdef CONFIG_PPC64
79 if (dev) { 73 if (dev) {
@@ -126,15 +120,10 @@ int pcibios_vaddr_is_ioport(void __iomem *address)
126 */ 120 */
127int pci_domain_nr(struct pci_bus *bus) 121int pci_domain_nr(struct pci_bus *bus)
128{ 122{
129 if (firmware_has_feature(FW_FEATURE_ISERIES)) 123 struct pci_controller *hose = pci_bus_to_host(bus);
130 return 0;
131 else {
132 struct pci_controller *hose = pci_bus_to_host(bus);
133 124
134 return hose->global_number; 125 return hose->global_number;
135 }
136} 126}
137
138EXPORT_SYMBOL(pci_domain_nr); 127EXPORT_SYMBOL(pci_domain_nr);
139 128
140#ifdef CONFIG_PPC_OF 129#ifdef CONFIG_PPC_OF
@@ -153,7 +142,7 @@ struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
153 while(node) { 142 while(node) {
154 struct pci_controller *hose, *tmp; 143 struct pci_controller *hose, *tmp;
155 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) 144 list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
156 if (hose->arch_data == node) 145 if (hose->dn == node)
157 return hose; 146 return hose;
158 node = node->parent; 147 node = node->parent;
159 } 148 }
@@ -201,6 +190,20 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
201 struct of_irq oirq; 190 struct of_irq oirq;
202 unsigned int virq; 191 unsigned int virq;
203 192
193 /* The current device-tree that iSeries generates from the HV
194 * PCI informations doesn't contain proper interrupt routing,
195 * and all the fallback would do is print out crap, so we
196 * don't attempt to resolve the interrupts here at all, some
197 * iSeries specific fixup does it.
198 *
199 * In the long run, we will hopefully fix the generated device-tree
200 * instead.
201 */
202#ifdef CONFIG_PPC_ISERIES
203 if (firmware_has_feature(FW_FEATURE_ISERIES))
204 return -1;
205#endif
206
204 DBG("Try to map irq for %s...\n", pci_name(pci_dev)); 207 DBG("Try to map irq for %s...\n", pci_name(pci_dev));
205 208
206#ifdef DEBUG 209#ifdef DEBUG
@@ -222,10 +225,11 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
222 if (pin == 0) 225 if (pin == 0)
223 return -1; 226 return -1;
224 if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) || 227 if (pci_read_config_byte(pci_dev, PCI_INTERRUPT_LINE, &line) ||
225 line == 0xff) { 228 line == 0xff || line == 0) {
226 return -1; 229 return -1;
227 } 230 }
228 DBG(" -> no map ! Using irq line %d from PCI config\n", line); 231 DBG(" -> no map ! Using line %d (pin %d) from PCI config\n",
232 line, pin);
229 233
230 virq = irq_create_mapping(NULL, line); 234 virq = irq_create_mapping(NULL, line);
231 if (virq != NO_IRQ) 235 if (virq != NO_IRQ)
@@ -475,3 +479,722 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
475 *start = rsrc->start - offset; 479 *start = rsrc->start - offset;
476 *end = rsrc->end - offset; 480 *end = rsrc->end - offset;
477} 481}
482
483/**
484 * pci_process_bridge_OF_ranges - Parse PCI bridge resources from device tree
485 * @hose: newly allocated pci_controller to be setup
486 * @dev: device node of the host bridge
487 * @primary: set if primary bus (32 bits only, soon to be deprecated)
488 *
489 * This function will parse the "ranges" property of a PCI host bridge device
490 * node and setup the resource mapping of a pci controller based on its
491 * content.
492 *
493 * Life would be boring if it wasn't for a few issues that we have to deal
494 * with here:
495 *
496 * - We can only cope with one IO space range and up to 3 Memory space
497 * ranges. However, some machines (thanks Apple !) tend to split their
498 * space into lots of small contiguous ranges. So we have to coalesce.
499 *
500 * - We can only cope with all memory ranges having the same offset
501 * between CPU addresses and PCI addresses. Unfortunately, some bridges
502 * are setup for a large 1:1 mapping along with a small "window" which
503 * maps PCI address 0 to some arbitrary high address of the CPU space in
504 * order to give access to the ISA memory hole.
505 * The way out of here that I've chosen for now is to always set the
506 * offset based on the first resource found, then override it if we
507 * have a different offset and the previous was set by an ISA hole.
508 *
509 * - Some busses have IO space not starting at 0, which causes trouble with
510 * the way we do our IO resource renumbering. The code somewhat deals with
511 * it for 64 bits but I would expect problems on 32 bits.
512 *
513 * - Some 32 bits platforms such as 4xx can have physical space larger than
514 * 32 bits so we need to use 64 bits values for the parsing
515 */
516void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
517 struct device_node *dev,
518 int primary)
519{
520 const u32 *ranges;
521 int rlen;
522 int pna = of_n_addr_cells(dev);
523 int np = pna + 5;
524 int memno = 0, isa_hole = -1;
525 u32 pci_space;
526 unsigned long long pci_addr, cpu_addr, pci_next, cpu_next, size;
527 unsigned long long isa_mb = 0;
528 struct resource *res;
529
530 printk(KERN_INFO "PCI host bridge %s %s ranges:\n",
531 dev->full_name, primary ? "(primary)" : "");
532
533 /* Get ranges property */
534 ranges = of_get_property(dev, "ranges", &rlen);
535 if (ranges == NULL)
536 return;
537
538 /* Parse it */
539 while ((rlen -= np * 4) >= 0) {
540 /* Read next ranges element */
541 pci_space = ranges[0];
542 pci_addr = of_read_number(ranges + 1, 2);
543 cpu_addr = of_translate_address(dev, ranges + 3);
544 size = of_read_number(ranges + pna + 3, 2);
545 ranges += np;
546 if (cpu_addr == OF_BAD_ADDR || size == 0)
547 continue;
548
549 /* Now consume following elements while they are contiguous */
550 for (; rlen >= np * sizeof(u32);
551 ranges += np, rlen -= np * 4) {
552 if (ranges[0] != pci_space)
553 break;
554 pci_next = of_read_number(ranges + 1, 2);
555 cpu_next = of_translate_address(dev, ranges + 3);
556 if (pci_next != pci_addr + size ||
557 cpu_next != cpu_addr + size)
558 break;
559 size += of_read_number(ranges + pna + 3, 2);
560 }
561
562 /* Act based on address space type */
563 res = NULL;
564 switch ((pci_space >> 24) & 0x3) {
565 case 1: /* PCI IO space */
566 printk(KERN_INFO
567 " IO 0x%016llx..0x%016llx -> 0x%016llx\n",
568 cpu_addr, cpu_addr + size - 1, pci_addr);
569
570 /* We support only one IO range */
571 if (hose->pci_io_size) {
572 printk(KERN_INFO
573 " \\--> Skipped (too many) !\n");
574 continue;
575 }
576#ifdef CONFIG_PPC32
577 /* On 32 bits, limit I/O space to 16MB */
578 if (size > 0x01000000)
579 size = 0x01000000;
580
581 /* 32 bits needs to map IOs here */
582 hose->io_base_virt = ioremap(cpu_addr, size);
583
584 /* Expect trouble if pci_addr is not 0 */
585 if (primary)
586 isa_io_base =
587 (unsigned long)hose->io_base_virt;
588#endif /* CONFIG_PPC32 */
589 /* pci_io_size and io_base_phys always represent IO
590 * space starting at 0 so we factor in pci_addr
591 */
592 hose->pci_io_size = pci_addr + size;
593 hose->io_base_phys = cpu_addr - pci_addr;
594
595 /* Build resource */
596 res = &hose->io_resource;
597 res->flags = IORESOURCE_IO;
598 res->start = pci_addr;
599 break;
600 case 2: /* PCI Memory space */
601 printk(KERN_INFO
602 " MEM 0x%016llx..0x%016llx -> 0x%016llx %s\n",
603 cpu_addr, cpu_addr + size - 1, pci_addr,
604 (pci_space & 0x40000000) ? "Prefetch" : "");
605
606 /* We support only 3 memory ranges */
607 if (memno >= 3) {
608 printk(KERN_INFO
609 " \\--> Skipped (too many) !\n");
610 continue;
611 }
612 /* Handles ISA memory hole space here */
613 if (pci_addr == 0) {
614 isa_mb = cpu_addr;
615 isa_hole = memno;
616 if (primary || isa_mem_base == 0)
617 isa_mem_base = cpu_addr;
618 }
619
620 /* We get the PCI/Mem offset from the first range or
621 * the, current one if the offset came from an ISA
622 * hole. If they don't match, bugger.
623 */
624 if (memno == 0 ||
625 (isa_hole >= 0 && pci_addr != 0 &&
626 hose->pci_mem_offset == isa_mb))
627 hose->pci_mem_offset = cpu_addr - pci_addr;
628 else if (pci_addr != 0 &&
629 hose->pci_mem_offset != cpu_addr - pci_addr) {
630 printk(KERN_INFO
631 " \\--> Skipped (offset mismatch) !\n");
632 continue;
633 }
634
635 /* Build resource */
636 res = &hose->mem_resources[memno++];
637 res->flags = IORESOURCE_MEM;
638 if (pci_space & 0x40000000)
639 res->flags |= IORESOURCE_PREFETCH;
640 res->start = cpu_addr;
641 break;
642 }
643 if (res != NULL) {
644 res->name = dev->full_name;
645 res->end = res->start + size - 1;
646 res->parent = NULL;
647 res->sibling = NULL;
648 res->child = NULL;
649 }
650 }
651
652 /* Out of paranoia, let's put the ISA hole last if any */
653 if (isa_hole >= 0 && memno > 0 && isa_hole != (memno-1)) {
654 struct resource tmp = hose->mem_resources[isa_hole];
655 hose->mem_resources[isa_hole] = hose->mem_resources[memno-1];
656 hose->mem_resources[memno-1] = tmp;
657 }
658}
659
660/* Decide whether to display the domain number in /proc */
661int pci_proc_domain(struct pci_bus *bus)
662{
663 struct pci_controller *hose = pci_bus_to_host(bus);
664#ifdef CONFIG_PPC64
665 return hose->buid != 0;
666#else
667 if (!(ppc_pci_flags & PPC_PCI_ENABLE_PROC_DOMAINS))
668 return 0;
669 if (ppc_pci_flags & PPC_PCI_COMPAT_DOMAIN_0)
670 return hose->global_number != 0;
671 return 1;
672#endif
673}
674
675void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
676 struct resource *res)
677{
678 resource_size_t offset = 0, mask = (resource_size_t)-1;
679 struct pci_controller *hose = pci_bus_to_host(dev->bus);
680
681 if (!hose)
682 return;
683 if (res->flags & IORESOURCE_IO) {
684 offset = (unsigned long)hose->io_base_virt - _IO_BASE;
685 mask = 0xffffffffu;
686 } else if (res->flags & IORESOURCE_MEM)
687 offset = hose->pci_mem_offset;
688
689 region->start = (res->start - offset) & mask;
690 region->end = (res->end - offset) & mask;
691}
692EXPORT_SYMBOL(pcibios_resource_to_bus);
693
694void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
695 struct pci_bus_region *region)
696{
697 resource_size_t offset = 0, mask = (resource_size_t)-1;
698 struct pci_controller *hose = pci_bus_to_host(dev->bus);
699
700 if (!hose)
701 return;
702 if (res->flags & IORESOURCE_IO) {
703 offset = (unsigned long)hose->io_base_virt - _IO_BASE;
704 mask = 0xffffffffu;
705 } else if (res->flags & IORESOURCE_MEM)
706 offset = hose->pci_mem_offset;
707 res->start = (region->start + offset) & mask;
708 res->end = (region->end + offset) & mask;
709}
710EXPORT_SYMBOL(pcibios_bus_to_resource);
711
712/* Fixup a bus resource into a linux resource */
713static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
714{
715 struct pci_controller *hose = pci_bus_to_host(dev->bus);
716 resource_size_t offset = 0, mask = (resource_size_t)-1;
717
718 if (res->flags & IORESOURCE_IO) {
719 offset = (unsigned long)hose->io_base_virt - _IO_BASE;
720 mask = 0xffffffffu;
721 } else if (res->flags & IORESOURCE_MEM)
722 offset = hose->pci_mem_offset;
723
724 res->start = (res->start + offset) & mask;
725 res->end = (res->end + offset) & mask;
726
727 pr_debug("PCI:%s %016llx-%016llx\n",
728 pci_name(dev),
729 (unsigned long long)res->start,
730 (unsigned long long)res->end);
731}
732
733
734/* This header fixup will do the resource fixup for all devices as they are
735 * probed, but not for bridge ranges
736 */
737static void __devinit pcibios_fixup_resources(struct pci_dev *dev)
738{
739 struct pci_controller *hose = pci_bus_to_host(dev->bus);
740 int i;
741
742 if (!hose) {
743 printk(KERN_ERR "No host bridge for PCI dev %s !\n",
744 pci_name(dev));
745 return;
746 }
747 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
748 struct resource *res = dev->resource + i;
749 if (!res->flags)
750 continue;
751 if (res->end == 0xffffffff) {
752 pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] is unassigned\n",
753 pci_name(dev), i,
754 (unsigned long long)res->start,
755 (unsigned long long)res->end,
756 (unsigned int)res->flags);
757 res->end -= res->start;
758 res->start = 0;
759 res->flags |= IORESOURCE_UNSET;
760 continue;
761 }
762
763 pr_debug("PCI:%s Resource %d %016llx-%016llx [%x] fixup...\n",
764 pci_name(dev), i,
765 (unsigned long long)res->start,\
766 (unsigned long long)res->end,
767 (unsigned int)res->flags);
768
769 fixup_resource(res, dev);
770 }
771
772 /* Call machine specific resource fixup */
773 if (ppc_md.pcibios_fixup_resources)
774 ppc_md.pcibios_fixup_resources(dev);
775}
776DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);
777
778static void __devinit __pcibios_fixup_bus(struct pci_bus *bus)
779{
780 struct pci_controller *hose = pci_bus_to_host(bus);
781 struct pci_dev *dev = bus->self;
782
783 pr_debug("PCI: Fixup bus %d (%s)\n", bus->number, dev ? pci_name(dev) : "PHB");
784
785 /* Fixup PCI<->PCI bridges. Host bridges are handled separately, for
786 * now differently between 32 and 64 bits.
787 */
788 if (dev != NULL) {
789 struct resource *res;
790 int i;
791
792 for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
793 if ((res = bus->resource[i]) == NULL)
794 continue;
795 if (!res->flags || bus->self->transparent)
796 continue;
797
798 /* On PowerMac, Apple leaves bridge windows open over
799 * an inaccessible region of memory space (0...fffff)
800 * which is somewhat bogus, but that's what they think
801 * means disabled...
802 *
803 * We clear those to force them to be reallocated later
804 *
805 * We detect such regions by the fact that the base is
806 * equal to the pci_mem_offset of the host bridge and
807 * their size is smaller than 1M.
808 */
809 if (res->start == hose->pci_mem_offset &&
810 res->end < 0x100000) {
811 printk(KERN_INFO
812 "PCI: Closing bogus Apple Firmware"
813 " region %d on bus 0x%02x\n",
814 i, bus->number);
815 res->flags = 0;
816 continue;
817 }
818
819 pr_debug("PCI:%s Bus rsrc %d %016llx-%016llx [%x] fixup...\n",
820 pci_name(dev), i,
821 (unsigned long long)res->start,\
822 (unsigned long long)res->end,
823 (unsigned int)res->flags);
824
825 fixup_resource(res, dev);
826 }
827 }
828
829 /* Additional setup that is different between 32 and 64 bits for now */
830 pcibios_do_bus_setup(bus);
831
832 /* Platform specific bus fixups */
833 if (ppc_md.pcibios_fixup_bus)
834 ppc_md.pcibios_fixup_bus(bus);
835
836 /* Read default IRQs and fixup if necessary */
837 list_for_each_entry(dev, &bus->devices, bus_list) {
838 pci_read_irq_line(dev);
839 if (ppc_md.pci_irq_fixup)
840 ppc_md.pci_irq_fixup(dev);
841 }
842}
843
844void __devinit pcibios_fixup_bus(struct pci_bus *bus)
845{
846 /* When called from the generic PCI probe, read PCI<->PCI bridge
847 * bases before proceeding
848 */
849 if (bus->self != NULL)
850 pci_read_bridge_bases(bus);
851 __pcibios_fixup_bus(bus);
852}
853EXPORT_SYMBOL(pcibios_fixup_bus);
854
855/* When building a bus from the OF tree rather than probing, we need a
856 * slightly different version of the fixup which doesn't read the
857 * bridge bases using config space accesses
858 */
859void __devinit pcibios_fixup_of_probed_bus(struct pci_bus *bus)
860{
861 __pcibios_fixup_bus(bus);
862}
863
864static int skip_isa_ioresource_align(struct pci_dev *dev)
865{
866 if ((ppc_pci_flags & PPC_PCI_CAN_SKIP_ISA_ALIGN) &&
867 !(dev->bus->bridge_ctl & PCI_BRIDGE_CTL_ISA))
868 return 1;
869 return 0;
870}
871
872/*
873 * We need to avoid collisions with `mirrored' VGA ports
874 * and other strange ISA hardware, so we always want the
875 * addresses to be allocated in the 0x000-0x0ff region
876 * modulo 0x400.
877 *
878 * Why? Because some silly external IO cards only decode
879 * the low 10 bits of the IO address. The 0x00-0xff region
880 * is reserved for motherboard devices that decode all 16
881 * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
882 * but we want to try to avoid allocating at 0x2900-0x2bff
883 * which might have be mirrored at 0x0100-0x03ff..
884 */
885void pcibios_align_resource(void *data, struct resource *res,
886 resource_size_t size, resource_size_t align)
887{
888 struct pci_dev *dev = data;
889
890 if (res->flags & IORESOURCE_IO) {
891 resource_size_t start = res->start;
892
893 if (skip_isa_ioresource_align(dev))
894 return;
895 if (start & 0x300) {
896 start = (start + 0x3ff) & ~0x3ff;
897 res->start = start;
898 }
899 }
900}
901EXPORT_SYMBOL(pcibios_align_resource);
902
903/*
904 * Reparent resource children of pr that conflict with res
905 * under res, and make res replace those children.
906 */
907static int __init reparent_resources(struct resource *parent,
908 struct resource *res)
909{
910 struct resource *p, **pp;
911 struct resource **firstpp = NULL;
912
913 for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
914 if (p->end < res->start)
915 continue;
916 if (res->end < p->start)
917 break;
918 if (p->start < res->start || p->end > res->end)
919 return -1; /* not completely contained */
920 if (firstpp == NULL)
921 firstpp = pp;
922 }
923 if (firstpp == NULL)
924 return -1; /* didn't find any conflicting entries? */
925 res->parent = parent;
926 res->child = *firstpp;
927 res->sibling = *pp;
928 *firstpp = res;
929 *pp = NULL;
930 for (p = res->child; p != NULL; p = p->sibling) {
931 p->parent = res;
932 DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n",
933 p->name,
934 (unsigned long long)p->start,
935 (unsigned long long)p->end, res->name);
936 }
937 return 0;
938}
939
940/*
941 * Handle resources of PCI devices. If the world were perfect, we could
942 * just allocate all the resource regions and do nothing more. It isn't.
943 * On the other hand, we cannot just re-allocate all devices, as it would
944 * require us to know lots of host bridge internals. So we attempt to
945 * keep as much of the original configuration as possible, but tweak it
946 * when it's found to be wrong.
947 *
948 * Known BIOS problems we have to work around:
949 * - I/O or memory regions not configured
950 * - regions configured, but not enabled in the command register
951 * - bogus I/O addresses above 64K used
952 * - expansion ROMs left enabled (this may sound harmless, but given
953 * the fact the PCI specs explicitly allow address decoders to be
954 * shared between expansion ROMs and other resource regions, it's
955 * at least dangerous)
956 *
957 * Our solution:
958 * (1) Allocate resources for all buses behind PCI-to-PCI bridges.
959 * This gives us fixed barriers on where we can allocate.
960 * (2) Allocate resources for all enabled devices. If there is
961 * a collision, just mark the resource as unallocated. Also
962 * disable expansion ROMs during this step.
963 * (3) Try to allocate resources for disabled devices. If the
964 * resources were assigned correctly, everything goes well,
965 * if they weren't, they won't disturb allocation of other
966 * resources.
967 * (4) Assign new addresses to resources which were either
968 * not configured at all or misconfigured. If explicitly
969 * requested by the user, configure expansion ROM address
970 * as well.
971 */
972
973static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
974{
975 struct pci_bus *bus;
976 int i;
977 struct resource *res, *pr;
978
979 /* Depth-First Search on bus tree */
980 list_for_each_entry(bus, bus_list, node) {
981 for (i = 0; i < PCI_BUS_NUM_RESOURCES; ++i) {
982 if ((res = bus->resource[i]) == NULL || !res->flags
983 || res->start > res->end)
984 continue;
985 if (bus->parent == NULL)
986 pr = (res->flags & IORESOURCE_IO) ?
987 &ioport_resource : &iomem_resource;
988 else {
989 /* Don't bother with non-root busses when
990 * re-assigning all resources. We clear the
991 * resource flags as if they were colliding
992 * and as such ensure proper re-allocation
993 * later.
994 */
995 if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)
996 goto clear_resource;
997 pr = pci_find_parent_resource(bus->self, res);
998 if (pr == res) {
999 /* this happens when the generic PCI
1000 * code (wrongly) decides that this
1001 * bridge is transparent -- paulus
1002 */
1003 continue;
1004 }
1005 }
1006
1007 DBG("PCI: %s (bus %d) bridge rsrc %d: %016llx-%016llx "
1008 "[0x%x], parent %p (%s)\n",
1009 bus->self ? pci_name(bus->self) : "PHB",
1010 bus->number, i,
1011 (unsigned long long)res->start,
1012 (unsigned long long)res->end,
1013 (unsigned int)res->flags,
1014 pr, (pr && pr->name) ? pr->name : "nil");
1015
1016 if (pr && !(pr->flags & IORESOURCE_UNSET)) {
1017 if (request_resource(pr, res) == 0)
1018 continue;
1019 /*
1020 * Must be a conflict with an existing entry.
1021 * Move that entry (or entries) under the
1022 * bridge resource and try again.
1023 */
1024 if (reparent_resources(pr, res) == 0)
1025 continue;
1026 }
1027 printk(KERN_WARNING
1028 "PCI: Cannot allocate resource region "
1029 "%d of PCI bridge %d, will remap\n",
1030 i, bus->number);
1031clear_resource:
1032 res->flags = 0;
1033 }
1034 pcibios_allocate_bus_resources(&bus->children);
1035 }
1036}
1037
1038static inline int __devinit alloc_resource(struct pci_dev *dev, int idx)
1039{
1040 struct resource *pr, *r = &dev->resource[idx];
1041
1042 DBG("PCI: Allocating %s: Resource %d: %016llx..%016llx [%x]\n",
1043 pci_name(dev), idx,
1044 (unsigned long long)r->start,
1045 (unsigned long long)r->end,
1046 (unsigned int)r->flags);
1047
1048 pr = pci_find_parent_resource(dev, r);
1049 if (!pr || (pr->flags & IORESOURCE_UNSET) ||
1050 request_resource(pr, r) < 0) {
1051 printk(KERN_WARNING "PCI: Cannot allocate resource region %d"
1052 " of device %s, will remap\n", idx, pci_name(dev));
1053 if (pr)
1054 DBG("PCI: parent is %p: %016llx-%016llx [%x]\n", pr,
1055 (unsigned long long)pr->start,
1056 (unsigned long long)pr->end,
1057 (unsigned int)pr->flags);
1058 /* We'll assign a new address later */
1059 r->flags |= IORESOURCE_UNSET;
1060 r->end -= r->start;
1061 r->start = 0;
1062
1063 return -EBUSY;
1064 }
1065 return 0;
1066}
1067
1068static void __init pcibios_allocate_resources(int pass)
1069{
1070 struct pci_dev *dev = NULL;
1071 int idx, disabled;
1072 u16 command;
1073 struct resource *r;
1074
1075 for_each_pci_dev(dev) {
1076 pci_read_config_word(dev, PCI_COMMAND, &command);
1077 for (idx = 0; idx < 6; idx++) {
1078 r = &dev->resource[idx];
1079 if (r->parent) /* Already allocated */
1080 continue;
1081 if (!r->flags || (r->flags & IORESOURCE_UNSET))
1082 continue; /* Not assigned at all */
1083 if (r->flags & IORESOURCE_IO)
1084 disabled = !(command & PCI_COMMAND_IO);
1085 else
1086 disabled = !(command & PCI_COMMAND_MEMORY);
1087 if (pass == disabled && alloc_resource(dev, idx)) {
1088 command &= ~(r->flags & (IORESOURCE_IO |
1089 IORESOURCE_MEM));
1090 pci_write_config_word(dev,
1091 PCI_COMMAND, command);
1092 }
1093 }
1094 if (pass)
1095 continue;
1096 r = &dev->resource[PCI_ROM_RESOURCE];
1097 if (r->flags & IORESOURCE_ROM_ENABLE) {
1098 /* Turn the ROM off, leave the resource region,
1099 * but keep it unregistered.
1100 */
1101 u32 reg;
1102 DBG("PCI: Switching off ROM of %s\n", pci_name(dev));
1103 r->flags &= ~IORESOURCE_ROM_ENABLE;
1104 pci_read_config_dword(dev, dev->rom_base_reg, &reg);
1105 pci_write_config_dword(dev, dev->rom_base_reg,
1106 reg & ~PCI_ROM_ADDRESS_ENABLE);
1107 }
1108 }
1109}
1110
1111void __init pcibios_resource_survey(void)
1112{
1113 /* Allocate and assign resources. If we re-assign everything, then
1114 * we skip the allocate phase
1115 */
1116 pcibios_allocate_bus_resources(&pci_root_buses);
1117
1118 if (!(ppc_pci_flags & PPC_PCI_REASSIGN_ALL_RSRC)) {
1119 pcibios_allocate_resources(0);
1120 pcibios_allocate_resources(1);
1121 }
1122
1123 if (!(ppc_pci_flags & PPC_PCI_PROBE_ONLY)) {
1124 DBG("PCI: Assigning unassigned resouces...\n");
1125 pci_assign_unassigned_resources();
1126 }
1127
1128 /* Call machine dependent fixup */
1129 if (ppc_md.pcibios_fixup)
1130 ppc_md.pcibios_fixup();
1131}
1132
1133#ifdef CONFIG_HOTPLUG
1134/* This is used by the pSeries hotplug driver to allocate resource
1135 * of newly plugged busses. We can try to consolidate with the
1136 * rest of the code later, for now, keep it as-is
1137 */
1138void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
1139{
1140 struct pci_dev *dev;
1141 struct pci_bus *child_bus;
1142
1143 list_for_each_entry(dev, &bus->devices, bus_list) {
1144 int i;
1145
1146 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
1147 struct resource *r = &dev->resource[i];
1148
1149 if (r->parent || !r->start || !r->flags)
1150 continue;
1151 pci_claim_resource(dev, i);
1152 }
1153 }
1154
1155 list_for_each_entry(child_bus, &bus->children, node)
1156 pcibios_claim_one_bus(child_bus);
1157}
1158EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
1159#endif /* CONFIG_HOTPLUG */
1160
1161int pcibios_enable_device(struct pci_dev *dev, int mask)
1162{
1163 u16 cmd, old_cmd;
1164 int idx;
1165 struct resource *r;
1166
1167 if (ppc_md.pcibios_enable_device_hook)
1168 if (ppc_md.pcibios_enable_device_hook(dev))
1169 return -EINVAL;
1170
1171 pci_read_config_word(dev, PCI_COMMAND, &cmd);
1172 old_cmd = cmd;
1173 for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
1174 /* Only set up the requested stuff */
1175 if (!(mask & (1 << idx)))
1176 continue;
1177 r = &dev->resource[idx];
1178 if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
1179 continue;
1180 if ((idx == PCI_ROM_RESOURCE) &&
1181 (!(r->flags & IORESOURCE_ROM_ENABLE)))
1182 continue;
1183 if (r->parent == NULL) {
1184 printk(KERN_ERR "PCI: Device %s not available because"
1185 " of resource collisions\n", pci_name(dev));
1186 return -EINVAL;
1187 }
1188 if (r->flags & IORESOURCE_IO)
1189 cmd |= PCI_COMMAND_IO;
1190 if (r->flags & IORESOURCE_MEM)
1191 cmd |= PCI_COMMAND_MEMORY;
1192 }
1193 if (cmd != old_cmd) {
1194 printk("PCI: Enabling device %s (%04x -> %04x)\n",
1195 pci_name(dev), old_cmd, cmd);
1196 pci_write_config_word(dev, PCI_COMMAND, cmd);
1197 }
1198 return 0;
1199}
1200
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 0e2bee46304c..a9c6cb24aab0 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -32,19 +32,12 @@
32#endif 32#endif
33 33
34unsigned long isa_io_base = 0; 34unsigned long isa_io_base = 0;
35unsigned long isa_mem_base = 0;
36unsigned long pci_dram_offset = 0; 35unsigned long pci_dram_offset = 0;
37int pcibios_assign_bus_offset = 1; 36int pcibios_assign_bus_offset = 1;
38 37
39void pcibios_make_OF_bus_map(void); 38void pcibios_make_OF_bus_map(void);
40 39
41static int pci_relocate_bridge_resource(struct pci_bus *bus, int i);
42static int probe_resource(struct pci_bus *parent, struct resource *pr,
43 struct resource *res, struct resource **conflict);
44static void update_bridge_base(struct pci_bus *bus, int i);
45static void pcibios_fixup_resources(struct pci_dev* dev);
46static void fixup_broken_pcnet32(struct pci_dev* dev); 40static void fixup_broken_pcnet32(struct pci_dev* dev);
47static int reparent_resources(struct resource *parent, struct resource *res);
48static void fixup_cpc710_pci64(struct pci_dev* dev); 41static void fixup_cpc710_pci64(struct pci_dev* dev);
49#ifdef CONFIG_PPC_OF 42#ifdef CONFIG_PPC_OF
50static u8* pci_to_OF_bus_map; 43static u8* pci_to_OF_bus_map;
@@ -53,7 +46,7 @@ static u8* pci_to_OF_bus_map;
53/* By default, we don't re-assign bus numbers. We do this only on 46/* By default, we don't re-assign bus numbers. We do this only on
54 * some pmacs 47 * some pmacs
55 */ 48 */
56int pci_assign_all_buses; 49static int pci_assign_all_buses;
57 50
58LIST_HEAD(hose_list); 51LIST_HEAD(hose_list);
59 52
@@ -100,338 +93,6 @@ fixup_cpc710_pci64(struct pci_dev* dev)
100} 93}
101DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CPC710_PCI64, fixup_cpc710_pci64); 94DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CPC710_PCI64, fixup_cpc710_pci64);
102 95
103static void
104pcibios_fixup_resources(struct pci_dev *dev)
105{
106 struct pci_controller* hose = (struct pci_controller *)dev->sysdata;
107 int i;
108 unsigned long offset;
109
110 if (!hose) {
111 printk(KERN_ERR "No hose for PCI dev %s!\n", pci_name(dev));
112 return;
113 }
114 for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
115 struct resource *res = dev->resource + i;
116 if (!res->flags)
117 continue;
118 if (res->end == 0xffffffff) {
119 DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n",
120 pci_name(dev), i, (u64)res->start, (u64)res->end);
121 res->end -= res->start;
122 res->start = 0;
123 res->flags |= IORESOURCE_UNSET;
124 continue;
125 }
126 offset = 0;
127 if (res->flags & IORESOURCE_MEM) {
128 offset = hose->pci_mem_offset;
129 } else if (res->flags & IORESOURCE_IO) {
130 offset = (unsigned long) hose->io_base_virt
131 - isa_io_base;
132 }
133 if (offset != 0) {
134 res->start += offset;
135 res->end += offset;
136 DBG("Fixup res %d (%lx) of dev %s: %llx -> %llx\n",
137 i, res->flags, pci_name(dev),
138 (u64)res->start - offset, (u64)res->start);
139 }
140 }
141
142 /* Call machine specific resource fixup */
143 if (ppc_md.pcibios_fixup_resources)
144 ppc_md.pcibios_fixup_resources(dev);
145}
146DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources);
147
148void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
149 struct resource *res)
150{
151 unsigned long offset = 0;
152 struct pci_controller *hose = dev->sysdata;
153
154 if (hose && res->flags & IORESOURCE_IO)
155 offset = (unsigned long)hose->io_base_virt - isa_io_base;
156 else if (hose && res->flags & IORESOURCE_MEM)
157 offset = hose->pci_mem_offset;
158 region->start = res->start - offset;
159 region->end = res->end - offset;
160}
161EXPORT_SYMBOL(pcibios_resource_to_bus);
162
163void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
164 struct pci_bus_region *region)
165{
166 unsigned long offset = 0;
167 struct pci_controller *hose = dev->sysdata;
168
169 if (hose && res->flags & IORESOURCE_IO)
170 offset = (unsigned long)hose->io_base_virt - isa_io_base;
171 else if (hose && res->flags & IORESOURCE_MEM)
172 offset = hose->pci_mem_offset;
173 res->start = region->start + offset;
174 res->end = region->end + offset;
175}
176EXPORT_SYMBOL(pcibios_bus_to_resource);
177
178/*
179 * We need to avoid collisions with `mirrored' VGA ports
180 * and other strange ISA hardware, so we always want the
181 * addresses to be allocated in the 0x000-0x0ff region
182 * modulo 0x400.
183 *
184 * Why? Because some silly external IO cards only decode
185 * the low 10 bits of the IO address. The 0x00-0xff region
186 * is reserved for motherboard devices that decode all 16
187 * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
188 * but we want to try to avoid allocating at 0x2900-0x2bff
189 * which might have be mirrored at 0x0100-0x03ff..
190 */
191void pcibios_align_resource(void *data, struct resource *res,
192 resource_size_t size, resource_size_t align)
193{
194 struct pci_dev *dev = data;
195
196 if (res->flags & IORESOURCE_IO) {
197 resource_size_t start = res->start;
198
199 if (size > 0x100) {
200 printk(KERN_ERR "PCI: I/O Region %s/%d too large"
201 " (%lld bytes)\n", pci_name(dev),
202 dev->resource - res, (unsigned long long)size);
203 }
204
205 if (start & 0x300) {
206 start = (start + 0x3ff) & ~0x3ff;
207 res->start = start;
208 }
209 }
210}
211EXPORT_SYMBOL(pcibios_align_resource);
212
213/*
214 * Handle resources of PCI devices. If the world were perfect, we could
215 * just allocate all the resource regions and do nothing more. It isn't.
216 * On the other hand, we cannot just re-allocate all devices, as it would
217 * require us to know lots of host bridge internals. So we attempt to
218 * keep as much of the original configuration as possible, but tweak it
219 * when it's found to be wrong.
220 *
221 * Known BIOS problems we have to work around:
222 * - I/O or memory regions not configured
223 * - regions configured, but not enabled in the command register
224 * - bogus I/O addresses above 64K used
225 * - expansion ROMs left enabled (this may sound harmless, but given
226 * the fact the PCI specs explicitly allow address decoders to be
227 * shared between expansion ROMs and other resource regions, it's
228 * at least dangerous)
229 *
230 * Our solution:
231 * (1) Allocate resources for all buses behind PCI-to-PCI bridges.
232 * This gives us fixed barriers on where we can allocate.
233 * (2) Allocate resources for all enabled devices. If there is
234 * a collision, just mark the resource as unallocated. Also
235 * disable expansion ROMs during this step.
236 * (3) Try to allocate resources for disabled devices. If the
237 * resources were assigned correctly, everything goes well,
238 * if they weren't, they won't disturb allocation of other
239 * resources.
240 * (4) Assign new addresses to resources which were either
241 * not configured at all or misconfigured. If explicitly
242 * requested by the user, configure expansion ROM address
243 * as well.
244 */
245
246static void __init
247pcibios_allocate_bus_resources(struct list_head *bus_list)
248{
249 struct pci_bus *bus;
250 int i;
251 struct resource *res, *pr;
252
253 /* Depth-First Search on bus tree */
254 list_for_each_entry(bus, bus_list, node) {
255 for (i = 0; i < 4; ++i) {
256 if ((res = bus->resource[i]) == NULL || !res->flags
257 || res->start > res->end)
258 continue;
259 if (bus->parent == NULL)
260 pr = (res->flags & IORESOURCE_IO)?
261 &ioport_resource: &iomem_resource;
262 else {
263 pr = pci_find_parent_resource(bus->self, res);
264 if (pr == res) {
265 /* this happens when the generic PCI
266 * code (wrongly) decides that this
267 * bridge is transparent -- paulus
268 */
269 continue;
270 }
271 }
272
273 DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n",
274 (u64)res->start, (u64)res->end, res->flags, pr);
275 if (pr) {
276 if (request_resource(pr, res) == 0)
277 continue;
278 /*
279 * Must be a conflict with an existing entry.
280 * Move that entry (or entries) under the
281 * bridge resource and try again.
282 */
283 if (reparent_resources(pr, res) == 0)
284 continue;
285 }
286 printk(KERN_ERR "PCI: Cannot allocate resource region "
287 "%d of PCI bridge %d\n", i, bus->number);
288 if (pci_relocate_bridge_resource(bus, i))
289 bus->resource[i] = NULL;
290 }
291 pcibios_allocate_bus_resources(&bus->children);
292 }
293}
294
295/*
296 * Reparent resource children of pr that conflict with res
297 * under res, and make res replace those children.
298 */
299static int __init
300reparent_resources(struct resource *parent, struct resource *res)
301{
302 struct resource *p, **pp;
303 struct resource **firstpp = NULL;
304
305 for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
306 if (p->end < res->start)
307 continue;
308 if (res->end < p->start)
309 break;
310 if (p->start < res->start || p->end > res->end)
311 return -1; /* not completely contained */
312 if (firstpp == NULL)
313 firstpp = pp;
314 }
315 if (firstpp == NULL)
316 return -1; /* didn't find any conflicting entries? */
317 res->parent = parent;
318 res->child = *firstpp;
319 res->sibling = *pp;
320 *firstpp = res;
321 *pp = NULL;
322 for (p = res->child; p != NULL; p = p->sibling) {
323 p->parent = res;
324 DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n",
325 p->name, (u64)p->start, (u64)p->end, res->name);
326 }
327 return 0;
328}
329
330/*
331 * A bridge has been allocated a range which is outside the range
332 * of its parent bridge, so it needs to be moved.
333 */
334static int __init
335pci_relocate_bridge_resource(struct pci_bus *bus, int i)
336{
337 struct resource *res, *pr, *conflict;
338 unsigned long try, size;
339 int j;
340 struct pci_bus *parent = bus->parent;
341
342 if (parent == NULL) {
343 /* shouldn't ever happen */
344 printk(KERN_ERR "PCI: can't move host bridge resource\n");
345 return -1;
346 }
347 res = bus->resource[i];
348 if (res == NULL)
349 return -1;
350 pr = NULL;
351 for (j = 0; j < 4; j++) {
352 struct resource *r = parent->resource[j];
353 if (!r)
354 continue;
355 if ((res->flags ^ r->flags) & (IORESOURCE_IO | IORESOURCE_MEM))
356 continue;
357 if (!((res->flags ^ r->flags) & IORESOURCE_PREFETCH)) {
358 pr = r;
359 break;
360 }
361 if (res->flags & IORESOURCE_PREFETCH)
362 pr = r;
363 }
364 if (pr == NULL)
365 return -1;
366 size = res->end - res->start;
367 if (pr->start > pr->end || size > pr->end - pr->start)
368 return -1;
369 try = pr->end;
370 for (;;) {
371 res->start = try - size;
372 res->end = try;
373 if (probe_resource(bus->parent, pr, res, &conflict) == 0)
374 break;
375 if (conflict->start <= pr->start + size)
376 return -1;
377 try = conflict->start - 1;
378 }
379 if (request_resource(pr, res)) {
380 DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n",
381 (u64)res->start, (u64)res->end);
382 return -1; /* "can't happen" */
383 }
384 update_bridge_base(bus, i);
385 printk(KERN_INFO "PCI: bridge %d resource %d moved to %llx..%llx\n",
386 bus->number, i, (unsigned long long)res->start,
387 (unsigned long long)res->end);
388 return 0;
389}
390
391static int __init
392probe_resource(struct pci_bus *parent, struct resource *pr,
393 struct resource *res, struct resource **conflict)
394{
395 struct pci_bus *bus;
396 struct pci_dev *dev;
397 struct resource *r;
398 int i;
399
400 for (r = pr->child; r != NULL; r = r->sibling) {
401 if (r->end >= res->start && res->end >= r->start) {
402 *conflict = r;
403 return 1;
404 }
405 }
406 list_for_each_entry(bus, &parent->children, node) {
407 for (i = 0; i < 4; ++i) {
408 if ((r = bus->resource[i]) == NULL)
409 continue;
410 if (!r->flags || r->start > r->end || r == res)
411 continue;
412 if (pci_find_parent_resource(bus->self, r) != pr)
413 continue;
414 if (r->end >= res->start && res->end >= r->start) {
415 *conflict = r;
416 return 1;
417 }
418 }
419 }
420 list_for_each_entry(dev, &parent->devices, bus_list) {
421 for (i = 0; i < 6; ++i) {
422 r = &dev->resource[i];
423 if (!r->flags || (r->flags & IORESOURCE_UNSET))
424 continue;
425 if (pci_find_parent_resource(dev, r) != pr)
426 continue;
427 if (r->end >= res->start && res->end >= r->start) {
428 *conflict = r;
429 return 1;
430 }
431 }
432 }
433 return 0;
434}
435 96
436void __init 97void __init
437update_bridge_resource(struct pci_dev *dev, struct resource *res) 98update_bridge_resource(struct pci_dev *dev, struct resource *res)
@@ -439,7 +100,7 @@ update_bridge_resource(struct pci_dev *dev, struct resource *res)
439 u8 io_base_lo, io_limit_lo; 100 u8 io_base_lo, io_limit_lo;
440 u16 mem_base, mem_limit; 101 u16 mem_base, mem_limit;
441 u16 cmd; 102 u16 cmd;
442 unsigned long start, end, off; 103 resource_size_t start, end, off;
443 struct pci_controller *hose = dev->sysdata; 104 struct pci_controller *hose = dev->sysdata;
444 105
445 if (!hose) { 106 if (!hose) {
@@ -489,115 +150,6 @@ update_bridge_resource(struct pci_dev *dev, struct resource *res)
489 pci_write_config_word(dev, PCI_COMMAND, cmd); 150 pci_write_config_word(dev, PCI_COMMAND, cmd);
490} 151}
491 152
492static void __init
493update_bridge_base(struct pci_bus *bus, int i)
494{
495 struct resource *res = bus->resource[i];
496 struct pci_dev *dev = bus->self;
497 update_bridge_resource(dev, res);
498}
499
500static inline void alloc_resource(struct pci_dev *dev, int idx)
501{
502 struct resource *pr, *r = &dev->resource[idx];
503
504 DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n",
505 pci_name(dev), idx, (u64)r->start, (u64)r->end, r->flags);
506 pr = pci_find_parent_resource(dev, r);
507 if (!pr || request_resource(pr, r) < 0) {
508 printk(KERN_ERR "PCI: Cannot allocate resource region %d"
509 " of device %s\n", idx, pci_name(dev));
510 if (pr)
511 DBG("PCI: parent is %p: %016llx-%016llx (f=%lx)\n",
512 pr, (u64)pr->start, (u64)pr->end, pr->flags);
513 /* We'll assign a new address later */
514 r->flags |= IORESOURCE_UNSET;
515 r->end -= r->start;
516 r->start = 0;
517 }
518}
519
520static void __init
521pcibios_allocate_resources(int pass)
522{
523 struct pci_dev *dev = NULL;
524 int idx, disabled;
525 u16 command;
526 struct resource *r;
527
528 for_each_pci_dev(dev) {
529 pci_read_config_word(dev, PCI_COMMAND, &command);
530 for (idx = 0; idx < 6; idx++) {
531 r = &dev->resource[idx];
532 if (r->parent) /* Already allocated */
533 continue;
534 if (!r->flags || (r->flags & IORESOURCE_UNSET))
535 continue; /* Not assigned at all */
536 if (r->flags & IORESOURCE_IO)
537 disabled = !(command & PCI_COMMAND_IO);
538 else
539 disabled = !(command & PCI_COMMAND_MEMORY);
540 if (pass == disabled)
541 alloc_resource(dev, idx);
542 }
543 if (pass)
544 continue;
545 r = &dev->resource[PCI_ROM_RESOURCE];
546 if (r->flags & IORESOURCE_ROM_ENABLE) {
547 /* Turn the ROM off, leave the resource region, but keep it unregistered. */
548 u32 reg;
549 DBG("PCI: Switching off ROM of %s\n", pci_name(dev));
550 r->flags &= ~IORESOURCE_ROM_ENABLE;
551 pci_read_config_dword(dev, dev->rom_base_reg, &reg);
552 pci_write_config_dword(dev, dev->rom_base_reg,
553 reg & ~PCI_ROM_ADDRESS_ENABLE);
554 }
555 }
556}
557
558static void __init
559pcibios_assign_resources(void)
560{
561 struct pci_dev *dev = NULL;
562 int idx;
563 struct resource *r;
564
565 for_each_pci_dev(dev) {
566 int class = dev->class >> 8;
567
568 /* Don't touch classless devices and host bridges */
569 if (!class || class == PCI_CLASS_BRIDGE_HOST)
570 continue;
571
572 for (idx = 0; idx < 6; idx++) {
573 r = &dev->resource[idx];
574
575 /*
576 * We shall assign a new address to this resource,
577 * either because the BIOS (sic) forgot to do so
578 * or because we have decided the old address was
579 * unusable for some reason.
580 */
581 if ((r->flags & IORESOURCE_UNSET) && r->end &&
582 (!ppc_md.pcibios_enable_device_hook ||
583 !ppc_md.pcibios_enable_device_hook(dev, 1))) {
584 int rc;
585
586 r->flags &= ~IORESOURCE_UNSET;
587 rc = pci_assign_resource(dev, idx);
588 BUG_ON(rc);
589 }
590 }
591
592#if 0 /* don't assign ROMs */
593 r = &dev->resource[PCI_ROM_RESOURCE];
594 r->end -= r->start;
595 r->start = 0;
596 if (r->end)
597 pci_assign_resource(dev, PCI_ROM_RESOURCE);
598#endif
599 }
600}
601 153
602#ifdef CONFIG_PPC_OF 154#ifdef CONFIG_PPC_OF
603/* 155/*
@@ -662,8 +214,8 @@ pcibios_make_OF_bus_map(void)
662 214
663 /* For each hose, we begin searching bridges */ 215 /* For each hose, we begin searching bridges */
664 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { 216 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
665 struct device_node* node; 217 struct device_node* node = hose->dn;
666 node = (struct device_node *)hose->arch_data; 218
667 if (!node) 219 if (!node)
668 continue; 220 continue;
669 make_one_node_map(node, hose->first_busno); 221 make_one_node_map(node, hose->first_busno);
@@ -742,7 +294,7 @@ static struct device_node *scan_OF_for_pci_bus(struct pci_bus *bus)
742 struct pci_controller *hose = pci_bus_to_host(bus); 294 struct pci_controller *hose = pci_bus_to_host(bus);
743 if (hose == NULL) 295 if (hose == NULL)
744 return NULL; 296 return NULL;
745 return of_node_get(hose->arch_data); 297 return of_node_get(hose->dn);
746 } 298 }
747 299
748 /* not a root bus, we need to get our parent */ 300 /* not a root bus, we need to get our parent */
@@ -812,9 +364,9 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
812 return -ENODEV; 364 return -ENODEV;
813 /* Make sure it's really a PCI device */ 365 /* Make sure it's really a PCI device */
814 hose = pci_find_hose_for_OF_device(node); 366 hose = pci_find_hose_for_OF_device(node);
815 if (!hose || !hose->arch_data) 367 if (!hose || !hose->dn)
816 return -ENODEV; 368 return -ENODEV;
817 if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child, 369 if (!scan_OF_pci_childs(hose->dn->child,
818 find_OF_pci_device_filter, (void *)node)) 370 find_OF_pci_device_filter, (void *)node))
819 return -ENODEV; 371 return -ENODEV;
820 reg = of_get_property(node, "reg", NULL); 372 reg = of_get_property(node, "reg", NULL);
@@ -843,120 +395,6 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
843} 395}
844EXPORT_SYMBOL(pci_device_from_OF_node); 396EXPORT_SYMBOL(pci_device_from_OF_node);
845 397
846void __init
847pci_process_bridge_OF_ranges(struct pci_controller *hose,
848 struct device_node *dev, int primary)
849{
850 static unsigned int static_lc_ranges[256] __initdata;
851 const unsigned int *dt_ranges;
852 unsigned int *lc_ranges, *ranges, *prev, size;
853 int rlen = 0, orig_rlen;
854 int memno = 0;
855 struct resource *res;
856 int np, na = of_n_addr_cells(dev);
857 np = na + 5;
858
859 /* First we try to merge ranges to fix a problem with some pmacs
860 * that can have more than 3 ranges, fortunately using contiguous
861 * addresses -- BenH
862 */
863 dt_ranges = of_get_property(dev, "ranges", &rlen);
864 if (!dt_ranges)
865 return;
866 /* Sanity check, though hopefully that never happens */
867 if (rlen > sizeof(static_lc_ranges)) {
868 printk(KERN_WARNING "OF ranges property too large !\n");
869 rlen = sizeof(static_lc_ranges);
870 }
871 lc_ranges = static_lc_ranges;
872 memcpy(lc_ranges, dt_ranges, rlen);
873 orig_rlen = rlen;
874
875 /* Let's work on a copy of the "ranges" property instead of damaging
876 * the device-tree image in memory
877 */
878 ranges = lc_ranges;
879 prev = NULL;
880 while ((rlen -= np * sizeof(unsigned int)) >= 0) {
881 if (prev) {
882 if (prev[0] == ranges[0] && prev[1] == ranges[1] &&
883 (prev[2] + prev[na+4]) == ranges[2] &&
884 (prev[na+2] + prev[na+4]) == ranges[na+2]) {
885 prev[na+4] += ranges[na+4];
886 ranges[0] = 0;
887 ranges += np;
888 continue;
889 }
890 }
891 prev = ranges;
892 ranges += np;
893 }
894
895 /*
896 * The ranges property is laid out as an array of elements,
897 * each of which comprises:
898 * cells 0 - 2: a PCI address
899 * cells 3 or 3+4: a CPU physical address
900 * (size depending on dev->n_addr_cells)
901 * cells 4+5 or 5+6: the size of the range
902 */
903 ranges = lc_ranges;
904 rlen = orig_rlen;
905 while (ranges && (rlen -= np * sizeof(unsigned int)) >= 0) {
906 res = NULL;
907 size = ranges[na+4];
908 switch ((ranges[0] >> 24) & 0x3) {
909 case 1: /* I/O space */
910 if (ranges[2] != 0)
911 break;
912 hose->io_base_phys = ranges[na+2];
913 /* limit I/O space to 16MB */
914 if (size > 0x01000000)
915 size = 0x01000000;
916 hose->io_base_virt = ioremap(ranges[na+2], size);
917 if (primary)
918 isa_io_base = (unsigned long) hose->io_base_virt;
919 res = &hose->io_resource;
920 res->flags = IORESOURCE_IO;
921 res->start = ranges[2];
922 DBG("PCI: IO 0x%llx -> 0x%llx\n",
923 (u64)res->start, (u64)res->start + size - 1);
924 break;
925 case 2: /* memory space */
926 memno = 0;
927 if (ranges[1] == 0 && ranges[2] == 0
928 && ranges[na+4] <= (16 << 20)) {
929 /* 1st 16MB, i.e. ISA memory area */
930 if (primary)
931 isa_mem_base = ranges[na+2];
932 memno = 1;
933 }
934 while (memno < 3 && hose->mem_resources[memno].flags)
935 ++memno;
936 if (memno == 0)
937 hose->pci_mem_offset = ranges[na+2] - ranges[2];
938 if (memno < 3) {
939 res = &hose->mem_resources[memno];
940 res->flags = IORESOURCE_MEM;
941 if(ranges[0] & 0x40000000)
942 res->flags |= IORESOURCE_PREFETCH;
943 res->start = ranges[na+2];
944 DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno,
945 (u64)res->start, (u64)res->start + size - 1);
946 }
947 break;
948 }
949 if (res != NULL) {
950 res->name = dev->full_name;
951 res->end = res->start + size - 1;
952 res->parent = NULL;
953 res->sibling = NULL;
954 res->child = NULL;
955 }
956 ranges += np;
957 }
958}
959
960/* We create the "pci-OF-bus-map" property now so it appears in the 398/* We create the "pci-OF-bus-map" property now so it appears in the
961 * /proc device tree 399 * /proc device tree
962 */ 400 */
@@ -986,219 +424,7 @@ void pcibios_make_OF_bus_map(void)
986} 424}
987#endif /* CONFIG_PPC_OF */ 425#endif /* CONFIG_PPC_OF */
988 426
989#ifdef CONFIG_PPC_PMAC 427static int __init pcibios_init(void)
990/*
991 * This set of routines checks for PCI<->PCI bridges that have closed
992 * IO resources and have child devices. It tries to re-open an IO
993 * window on them.
994 *
995 * This is a _temporary_ fix to workaround a problem with Apple's OF
996 * closing IO windows on P2P bridges when the OF drivers of cards
997 * below this bridge don't claim any IO range (typically ATI or
998 * Adaptec).
999 *
1000 * A more complete fix would be to use drivers/pci/setup-bus.c, which
1001 * involves a working pcibios_fixup_pbus_ranges(), some more care about
1002 * ordering when creating the host bus resources, and maybe a few more
1003 * minor tweaks
1004 */
1005
1006/* Initialize bridges with base/limit values we have collected */
1007static void __init
1008do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga)
1009{
1010 struct pci_dev *bridge = bus->self;
1011 struct pci_controller* hose = (struct pci_controller *)bridge->sysdata;
1012 u32 l;
1013 u16 w;
1014 struct resource res;
1015
1016 if (bus->resource[0] == NULL)
1017 return;
1018 res = *(bus->resource[0]);
1019
1020 DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge));
1021 res.start -= ((unsigned long) hose->io_base_virt - isa_io_base);
1022 res.end -= ((unsigned long) hose->io_base_virt - isa_io_base);
1023 DBG(" IO window: %016llx-%016llx\n", res.start, res.end);
1024
1025 /* Set up the top and bottom of the PCI I/O segment for this bus. */
1026 pci_read_config_dword(bridge, PCI_IO_BASE, &l);
1027 l &= 0xffff000f;
1028 l |= (res.start >> 8) & 0x00f0;
1029 l |= res.end & 0xf000;
1030 pci_write_config_dword(bridge, PCI_IO_BASE, l);
1031
1032 if ((l & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
1033 l = (res.start >> 16) | (res.end & 0xffff0000);
1034 pci_write_config_dword(bridge, PCI_IO_BASE_UPPER16, l);
1035 }
1036
1037 pci_read_config_word(bridge, PCI_COMMAND, &w);
1038 w |= PCI_COMMAND_IO;
1039 pci_write_config_word(bridge, PCI_COMMAND, w);
1040
1041#if 0 /* Enabling this causes XFree 4.2.0 to hang during PCI probe */
1042 if (enable_vga) {
1043 pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &w);
1044 w |= PCI_BRIDGE_CTL_VGA;
1045 pci_write_config_word(bridge, PCI_BRIDGE_CONTROL, w);
1046 }
1047#endif
1048}
1049
1050/* This function is pretty basic and actually quite broken for the
1051 * general case, it's enough for us right now though. It's supposed
1052 * to tell us if we need to open an IO range at all or not and what
1053 * size.
1054 */
1055static int __init
1056check_for_io_childs(struct pci_bus *bus, struct resource* res, int *found_vga)
1057{
1058 struct pci_dev *dev;
1059 int i;
1060 int rc = 0;
1061
1062#define push_end(res, mask) do { \
1063 BUG_ON((mask+1) & mask); \
1064 res->end = (res->end + mask) | mask; \
1065} while (0)
1066
1067 list_for_each_entry(dev, &bus->devices, bus_list) {
1068 u16 class = dev->class >> 8;
1069
1070 if (class == PCI_CLASS_DISPLAY_VGA ||
1071 class == PCI_CLASS_NOT_DEFINED_VGA)
1072 *found_vga = 1;
1073 if (class >> 8 == PCI_BASE_CLASS_BRIDGE && dev->subordinate)
1074 rc |= check_for_io_childs(dev->subordinate, res, found_vga);
1075 if (class == PCI_CLASS_BRIDGE_CARDBUS)
1076 push_end(res, 0xfff);
1077
1078 for (i=0; i<PCI_NUM_RESOURCES; i++) {
1079 struct resource *r;
1080 unsigned long r_size;
1081
1082 if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI
1083 && i >= PCI_BRIDGE_RESOURCES)
1084 continue;
1085 r = &dev->resource[i];
1086 r_size = r->end - r->start;
1087 if (r_size < 0xfff)
1088 r_size = 0xfff;
1089 if (r->flags & IORESOURCE_IO && (r_size) != 0) {
1090 rc = 1;
1091 push_end(res, r_size);
1092 }
1093 }
1094 }
1095
1096 return rc;
1097}
1098
1099/* Here we scan all P2P bridges of a given level that have a closed
1100 * IO window. Note that the test for the presence of a VGA card should
1101 * be improved to take into account already configured P2P bridges,
1102 * currently, we don't see them and might end up configuring 2 bridges
1103 * with VGA pass through enabled
1104 */
1105static void __init
1106do_fixup_p2p_level(struct pci_bus *bus)
1107{
1108 struct pci_bus *b;
1109 int i, parent_io;
1110 int has_vga = 0;
1111
1112 for (parent_io=0; parent_io<4; parent_io++)
1113 if (bus->resource[parent_io]
1114 && bus->resource[parent_io]->flags & IORESOURCE_IO)
1115 break;
1116 if (parent_io >= 4)
1117 return;
1118
1119 list_for_each_entry(b, &bus->children, node) {
1120 struct pci_dev *d = b->self;
1121 struct pci_controller* hose = (struct pci_controller *)d->sysdata;
1122 struct resource *res = b->resource[0];
1123 struct resource tmp_res;
1124 unsigned long max;
1125 int found_vga = 0;
1126
1127 memset(&tmp_res, 0, sizeof(tmp_res));
1128 tmp_res.start = bus->resource[parent_io]->start;
1129
1130 /* We don't let low addresses go through that closed P2P bridge, well,
1131 * that may not be necessary but I feel safer that way
1132 */
1133 if (tmp_res.start == 0)
1134 tmp_res.start = 0x1000;
1135
1136 if (!list_empty(&b->devices) && res && res->flags == 0 &&
1137 res != bus->resource[parent_io] &&
1138 (d->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
1139 check_for_io_childs(b, &tmp_res, &found_vga)) {
1140 u8 io_base_lo;
1141
1142 printk(KERN_INFO "Fixing up IO bus %s\n", b->name);
1143
1144 if (found_vga) {
1145 if (has_vga) {
1146 printk(KERN_WARNING "Skipping VGA, already active"
1147 " on bus segment\n");
1148 found_vga = 0;
1149 } else
1150 has_vga = 1;
1151 }
1152 pci_read_config_byte(d, PCI_IO_BASE, &io_base_lo);
1153
1154 if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32)
1155 max = ((unsigned long) hose->io_base_virt
1156 - isa_io_base) + 0xffffffff;
1157 else
1158 max = ((unsigned long) hose->io_base_virt
1159 - isa_io_base) + 0xffff;
1160
1161 *res = tmp_res;
1162 res->flags = IORESOURCE_IO;
1163 res->name = b->name;
1164
1165 /* Find a resource in the parent where we can allocate */
1166 for (i = 0 ; i < 4; i++) {
1167 struct resource *r = bus->resource[i];
1168 if (!r)
1169 continue;
1170 if ((r->flags & IORESOURCE_IO) == 0)
1171 continue;
1172 DBG("Trying to allocate from %016llx, size %016llx from parent"
1173 " res %d: %016llx -> %016llx\n",
1174 res->start, res->end, i, r->start, r->end);
1175
1176 if (allocate_resource(r, res, res->end + 1, res->start, max,
1177 res->end + 1, NULL, NULL) < 0) {
1178 DBG("Failed !\n");
1179 continue;
1180 }
1181 do_update_p2p_io_resource(b, found_vga);
1182 break;
1183 }
1184 }
1185 do_fixup_p2p_level(b);
1186 }
1187}
1188
1189static void
1190pcibios_fixup_p2p_bridges(void)
1191{
1192 struct pci_bus *b;
1193
1194 list_for_each_entry(b, &pci_root_buses, node)
1195 do_fixup_p2p_level(b);
1196}
1197
1198#endif /* CONFIG_PPC_PMAC */
1199
1200static int __init
1201pcibios_init(void)
1202{ 428{
1203 struct pci_controller *hose, *tmp; 429 struct pci_controller *hose, *tmp;
1204 struct pci_bus *bus; 430 struct pci_bus *bus;
@@ -1206,6 +432,9 @@ pcibios_init(void)
1206 432
1207 printk(KERN_INFO "PCI: Probing PCI hardware\n"); 433 printk(KERN_INFO "PCI: Probing PCI hardware\n");
1208 434
435 if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS)
436 pci_assign_all_buses = 1;
437
1209 /* Scan all of the recorded PCI controllers. */ 438 /* Scan all of the recorded PCI controllers. */
1210 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { 439 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
1211 if (pci_assign_all_buses) 440 if (pci_assign_all_buses)
@@ -1213,9 +442,10 @@ pcibios_init(void)
1213 hose->last_busno = 0xff; 442 hose->last_busno = 0xff;
1214 bus = pci_scan_bus_parented(hose->parent, hose->first_busno, 443 bus = pci_scan_bus_parented(hose->parent, hose->first_busno,
1215 hose->ops, hose); 444 hose->ops, hose);
1216 if (bus) 445 if (bus) {
1217 pci_bus_add_devices(bus); 446 pci_bus_add_devices(bus);
1218 hose->last_busno = bus->subordinate; 447 hose->last_busno = bus->subordinate;
448 }
1219 if (pci_assign_all_buses || next_busno <= hose->last_busno) 449 if (pci_assign_all_buses || next_busno <= hose->last_busno)
1220 next_busno = hose->last_busno + pcibios_assign_bus_offset; 450 next_busno = hose->last_busno + pcibios_assign_bus_offset;
1221 } 451 }
@@ -1228,18 +458,8 @@ pcibios_init(void)
1228 if (pci_assign_all_buses && have_of) 458 if (pci_assign_all_buses && have_of)
1229 pcibios_make_OF_bus_map(); 459 pcibios_make_OF_bus_map();
1230 460
1231 /* Call machine dependent fixup */ 461 /* Call common code to handle resource allocation */
1232 if (ppc_md.pcibios_fixup) 462 pcibios_resource_survey();
1233 ppc_md.pcibios_fixup();
1234
1235 /* Allocate and assign resources */
1236 pcibios_allocate_bus_resources(&pci_root_buses);
1237 pcibios_allocate_resources(0);
1238 pcibios_allocate_resources(1);
1239#ifdef CONFIG_PPC_PMAC
1240 pcibios_fixup_p2p_bridges();
1241#endif /* CONFIG_PPC_PMAC */
1242 pcibios_assign_resources();
1243 463
1244 /* Call machine dependent post-init code */ 464 /* Call machine dependent post-init code */
1245 if (ppc_md.pcibios_after_init) 465 if (ppc_md.pcibios_after_init)
@@ -1250,14 +470,14 @@ pcibios_init(void)
1250 470
1251subsys_initcall(pcibios_init); 471subsys_initcall(pcibios_init);
1252 472
1253void pcibios_fixup_bus(struct pci_bus *bus) 473void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
1254{ 474{
1255 struct pci_controller *hose = (struct pci_controller *) bus->sysdata; 475 struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
1256 unsigned long io_offset; 476 unsigned long io_offset;
1257 struct resource *res; 477 struct resource *res;
1258 struct pci_dev *dev;
1259 int i; 478 int i;
1260 479
480 /* Hookup PHB resources */
1261 io_offset = (unsigned long)hose->io_base_virt - isa_io_base; 481 io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
1262 if (bus->parent == NULL) { 482 if (bus->parent == NULL) {
1263 /* This is a host bridge - fill in its resources */ 483 /* This is a host bridge - fill in its resources */
@@ -1272,8 +492,8 @@ void pcibios_fixup_bus(struct pci_bus *bus)
1272 res->end = IO_SPACE_LIMIT; 492 res->end = IO_SPACE_LIMIT;
1273 res->flags = IORESOURCE_IO; 493 res->flags = IORESOURCE_IO;
1274 } 494 }
1275 res->start += io_offset; 495 res->start = (res->start + io_offset) & 0xffffffffu;
1276 res->end += io_offset; 496 res->end = (res->end + io_offset) & 0xffffffffu;
1277 497
1278 for (i = 0; i < 3; ++i) { 498 for (i = 0; i < 3; ++i) {
1279 res = &hose->mem_resources[i]; 499 res = &hose->mem_resources[i];
@@ -1288,35 +508,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)
1288 } 508 }
1289 bus->resource[i+1] = res; 509 bus->resource[i+1] = res;
1290 } 510 }
1291 } else {
1292 /* This is a subordinate bridge */
1293 pci_read_bridge_bases(bus);
1294
1295 for (i = 0; i < 4; ++i) {
1296 if ((res = bus->resource[i]) == NULL)
1297 continue;
1298 if (!res->flags || bus->self->transparent)
1299 continue;
1300 if (io_offset && (res->flags & IORESOURCE_IO)) {
1301 res->start += io_offset;
1302 res->end += io_offset;
1303 } else if (hose->pci_mem_offset
1304 && (res->flags & IORESOURCE_MEM)) {
1305 res->start += hose->pci_mem_offset;
1306 res->end += hose->pci_mem_offset;
1307 }
1308 }
1309 }
1310
1311 /* Platform specific bus fixups */
1312 if (ppc_md.pcibios_fixup_bus)
1313 ppc_md.pcibios_fixup_bus(bus);
1314
1315 /* Read default IRQs and fixup if necessary */
1316 list_for_each_entry(dev, &bus->devices, bus_list) {
1317 pci_read_irq_line(dev);
1318 if (ppc_md.pci_irq_fixup)
1319 ppc_md.pci_irq_fixup(dev);
1320 } 511 }
1321} 512}
1322 513
@@ -1328,37 +519,6 @@ pcibios_update_irq(struct pci_dev *dev, int irq)
1328 /* XXX FIXME - update OF device tree node interrupt property */ 519 /* XXX FIXME - update OF device tree node interrupt property */
1329} 520}
1330 521
1331int pcibios_enable_device(struct pci_dev *dev, int mask)
1332{
1333 u16 cmd, old_cmd;
1334 int idx;
1335 struct resource *r;
1336
1337 if (ppc_md.pcibios_enable_device_hook)
1338 if (ppc_md.pcibios_enable_device_hook(dev, 0))
1339 return -EINVAL;
1340
1341 pci_read_config_word(dev, PCI_COMMAND, &cmd);
1342 old_cmd = cmd;
1343 for (idx=0; idx<6; idx++) {
1344 r = &dev->resource[idx];
1345 if (r->flags & IORESOURCE_UNSET) {
1346 printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));
1347 return -EINVAL;
1348 }
1349 if (r->flags & IORESOURCE_IO)
1350 cmd |= PCI_COMMAND_IO;
1351 if (r->flags & IORESOURCE_MEM)
1352 cmd |= PCI_COMMAND_MEMORY;
1353 }
1354 if (cmd != old_cmd) {
1355 printk("PCI: Enabling device %s (%04x -> %04x)\n",
1356 pci_name(dev), old_cmd, cmd);
1357 pci_write_config_word(dev, PCI_COMMAND, cmd);
1358 }
1359 return 0;
1360}
1361
1362static struct pci_controller* 522static struct pci_controller*
1363pci_bus_to_hose(int bus) 523pci_bus_to_hose(int bus)
1364{ 524{
@@ -1381,17 +541,6 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
1381 struct pci_controller* hose; 541 struct pci_controller* hose;
1382 long result = -EOPNOTSUPP; 542 long result = -EOPNOTSUPP;
1383 543
1384 /* Argh ! Please forgive me for that hack, but that's the
1385 * simplest way to get existing XFree to not lockup on some
1386 * G5 machines... So when something asks for bus 0 io base
1387 * (bus 0 is HT root), we return the AGP one instead.
1388 */
1389#ifdef CONFIG_PPC_PMAC
1390 if (machine_is(powermac) && machine_is_compatible("MacRISC4"))
1391 if (bus == 0)
1392 bus = 0xf0;
1393#endif /* CONFIG_PPC_PMAC */
1394
1395 hose = pci_bus_to_hose(bus); 544 hose = pci_bus_to_hose(bus);
1396 if (!hose) 545 if (!hose)
1397 return -ENODEV; 546 return -ENODEV;
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 9f63bdcb0bdf..5949bbabd7fb 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -31,7 +31,6 @@
31#include <asm/byteorder.h> 31#include <asm/byteorder.h>
32#include <asm/machdep.h> 32#include <asm/machdep.h>
33#include <asm/ppc-pci.h> 33#include <asm/ppc-pci.h>
34#include <asm/firmware.h>
35 34
36#ifdef DEBUG 35#ifdef DEBUG
37#include <asm/udbg.h> 36#include <asm/udbg.h>
@@ -41,10 +40,6 @@
41#endif 40#endif
42 41
43unsigned long pci_probe_only = 1; 42unsigned long pci_probe_only = 1;
44int pci_assign_all_buses = 0;
45
46static void fixup_resource(struct resource *res, struct pci_dev *dev);
47static void do_bus_setup(struct pci_bus *bus);
48 43
49/* pci_io_base -- the base address from which io bars are offsets. 44/* pci_io_base -- the base address from which io bars are offsets.
50 * This is the lowest I/O base address (so bar values are always positive), 45 * This is the lowest I/O base address (so bar values are always positive),
@@ -70,139 +65,31 @@ struct dma_mapping_ops *get_pci_dma_ops(void)
70} 65}
71EXPORT_SYMBOL(get_pci_dma_ops); 66EXPORT_SYMBOL(get_pci_dma_ops);
72 67
73static void fixup_broken_pcnet32(struct pci_dev* dev)
74{
75 if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
76 dev->vendor = PCI_VENDOR_ID_AMD;
77 pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
78 }
79}
80DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32);
81 68
82void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, 69int pci_set_dma_mask(struct pci_dev *dev, u64 mask)
83 struct resource *res)
84{ 70{
85 unsigned long offset = 0; 71 return dma_set_mask(&dev->dev, mask);
86 struct pci_controller *hose = pci_bus_to_host(dev->bus);
87
88 if (!hose)
89 return;
90
91 if (res->flags & IORESOURCE_IO)
92 offset = (unsigned long)hose->io_base_virt - _IO_BASE;
93
94 if (res->flags & IORESOURCE_MEM)
95 offset = hose->pci_mem_offset;
96
97 region->start = res->start - offset;
98 region->end = res->end - offset;
99} 72}
100 73
101void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, 74int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
102 struct pci_bus_region *region)
103{ 75{
104 unsigned long offset = 0; 76 int rc;
105 struct pci_controller *hose = pci_bus_to_host(dev->bus);
106
107 if (!hose)
108 return;
109
110 if (res->flags & IORESOURCE_IO)
111 offset = (unsigned long)hose->io_base_virt - _IO_BASE;
112 77
113 if (res->flags & IORESOURCE_MEM) 78 rc = dma_set_mask(&dev->dev, mask);
114 offset = hose->pci_mem_offset; 79 dev->dev.coherent_dma_mask = dev->dma_mask;
115 80
116 res->start = region->start + offset; 81 return rc;
117 res->end = region->end + offset;
118} 82}
119 83
120#ifdef CONFIG_HOTPLUG 84static void fixup_broken_pcnet32(struct pci_dev* dev)
121EXPORT_SYMBOL(pcibios_resource_to_bus);
122EXPORT_SYMBOL(pcibios_bus_to_resource);
123#endif
124
125/*
126 * We need to avoid collisions with `mirrored' VGA ports
127 * and other strange ISA hardware, so we always want the
128 * addresses to be allocated in the 0x000-0x0ff region
129 * modulo 0x400.
130 *
131 * Why? Because some silly external IO cards only decode
132 * the low 10 bits of the IO address. The 0x00-0xff region
133 * is reserved for motherboard devices that decode all 16
134 * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
135 * but we want to try to avoid allocating at 0x2900-0x2bff
136 * which might have be mirrored at 0x0100-0x03ff..
137 */
138void pcibios_align_resource(void *data, struct resource *res,
139 resource_size_t size, resource_size_t align)
140{
141 struct pci_dev *dev = data;
142 struct pci_controller *hose = pci_bus_to_host(dev->bus);
143 resource_size_t start = res->start;
144 unsigned long alignto;
145
146 if (res->flags & IORESOURCE_IO) {
147 unsigned long offset = (unsigned long)hose->io_base_virt -
148 _IO_BASE;
149 /* Make sure we start at our min on all hoses */
150 if (start - offset < PCIBIOS_MIN_IO)
151 start = PCIBIOS_MIN_IO + offset;
152
153 /*
154 * Put everything into 0x00-0xff region modulo 0x400
155 */
156 if (start & 0x300)
157 start = (start + 0x3ff) & ~0x3ff;
158
159 } else if (res->flags & IORESOURCE_MEM) {
160 /* Make sure we start at our min on all hoses */
161 if (start - hose->pci_mem_offset < PCIBIOS_MIN_MEM)
162 start = PCIBIOS_MIN_MEM + hose->pci_mem_offset;
163
164 /* Align to multiple of size of minimum base. */
165 alignto = max(0x1000UL, align);
166 start = ALIGN(start, alignto);
167 }
168
169 res->start = start;
170}
171
172void __devinit pcibios_claim_one_bus(struct pci_bus *b)
173{ 85{
174 struct pci_dev *dev; 86 if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
175 struct pci_bus *child_bus; 87 dev->vendor = PCI_VENDOR_ID_AMD;
176 88 pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
177 list_for_each_entry(dev, &b->devices, bus_list) {
178 int i;
179
180 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
181 struct resource *r = &dev->resource[i];
182
183 if (r->parent || !r->start || !r->flags)
184 continue;
185 pci_claim_resource(dev, i);
186 }
187 } 89 }
188
189 list_for_each_entry(child_bus, &b->children, node)
190 pcibios_claim_one_bus(child_bus);
191} 90}
192#ifdef CONFIG_HOTPLUG 91DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32);
193EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
194#endif
195
196static void __init pcibios_claim_of_setup(void)
197{
198 struct pci_bus *b;
199
200 if (firmware_has_feature(FW_FEATURE_ISERIES))
201 return;
202 92
203 list_for_each_entry(b, &pci_root_buses, node)
204 pcibios_claim_one_bus(b);
205}
206 93
207static u32 get_int_prop(struct device_node *np, const char *name, u32 def) 94static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
208{ 95{
@@ -270,7 +157,6 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
270 res->end = base + size - 1; 157 res->end = base + size - 1;
271 res->flags = flags; 158 res->flags = flags;
272 res->name = pci_name(dev); 159 res->name = pci_name(dev);
273 fixup_resource(res, dev);
274 } 160 }
275} 161}
276 162
@@ -339,7 +225,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
339EXPORT_SYMBOL(of_create_pci_dev); 225EXPORT_SYMBOL(of_create_pci_dev);
340 226
341void __devinit of_scan_bus(struct device_node *node, 227void __devinit of_scan_bus(struct device_node *node,
342 struct pci_bus *bus) 228 struct pci_bus *bus)
343{ 229{
344 struct device_node *child = NULL; 230 struct device_node *child = NULL;
345 const u32 *reg; 231 const u32 *reg;
@@ -348,6 +234,7 @@ void __devinit of_scan_bus(struct device_node *node,
348 234
349 DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number); 235 DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number);
350 236
237 /* Scan direct children */
351 while ((child = of_get_next_child(node, child)) != NULL) { 238 while ((child = of_get_next_child(node, child)) != NULL) {
352 DBG(" * %s\n", child->full_name); 239 DBG(" * %s\n", child->full_name);
353 reg = of_get_property(child, "reg", &reglen); 240 reg = of_get_property(child, "reg", &reglen);
@@ -359,19 +246,26 @@ void __devinit of_scan_bus(struct device_node *node,
359 dev = of_create_pci_dev(child, bus, devfn); 246 dev = of_create_pci_dev(child, bus, devfn);
360 if (!dev) 247 if (!dev)
361 continue; 248 continue;
362 DBG("dev header type: %x\n", dev->hdr_type); 249 DBG(" dev header type: %x\n", dev->hdr_type);
250 }
251
252 /* Ally all fixups */
253 pcibios_fixup_of_probed_bus(bus);
363 254
255 /* Now scan child busses */
256 list_for_each_entry(dev, &bus->devices, bus_list) {
364 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || 257 if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
365 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) 258 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
366 of_scan_pci_bridge(child, dev); 259 struct device_node *child = pci_device_to_OF_node(dev);
260 if (dev)
261 of_scan_pci_bridge(child, dev);
262 }
367 } 263 }
368
369 do_bus_setup(bus);
370} 264}
371EXPORT_SYMBOL(of_scan_bus); 265EXPORT_SYMBOL(of_scan_bus);
372 266
373void __devinit of_scan_pci_bridge(struct device_node *node, 267void __devinit of_scan_pci_bridge(struct device_node *node,
374 struct pci_dev *dev) 268 struct pci_dev *dev)
375{ 269{
376 struct pci_bus *bus; 270 struct pci_bus *bus;
377 const u32 *busrange, *ranges; 271 const u32 *busrange, *ranges;
@@ -441,7 +335,6 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
441 res->start = of_read_number(&ranges[1], 2); 335 res->start = of_read_number(&ranges[1], 2);
442 res->end = res->start + size - 1; 336 res->end = res->start + size - 1;
443 res->flags = flags; 337 res->flags = flags;
444 fixup_resource(res, dev);
445 } 338 }
446 sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus), 339 sprintf(bus->name, "PCI Bus %04x:%02x", pci_domain_nr(bus),
447 bus->number); 340 bus->number);
@@ -462,12 +355,13 @@ EXPORT_SYMBOL(of_scan_pci_bridge);
462void __devinit scan_phb(struct pci_controller *hose) 355void __devinit scan_phb(struct pci_controller *hose)
463{ 356{
464 struct pci_bus *bus; 357 struct pci_bus *bus;
465 struct device_node *node = hose->arch_data; 358 struct device_node *node = hose->dn;
466 int i, mode; 359 int i, mode;
467 struct resource *res; 360 struct resource *res;
468 361
469 DBG("Scanning PHB %s\n", node ? node->full_name : "<NO NAME>"); 362 DBG("PCI: Scanning PHB %s\n", node ? node->full_name : "<NO NAME>");
470 363
364 /* Create an empty bus for the toplevel */
471 bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node); 365 bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node);
472 if (bus == NULL) { 366 if (bus == NULL) {
473 printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", 367 printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
@@ -477,27 +371,29 @@ void __devinit scan_phb(struct pci_controller *hose)
477 bus->secondary = hose->first_busno; 371 bus->secondary = hose->first_busno;
478 hose->bus = bus; 372 hose->bus = bus;
479 373
480 if (!firmware_has_feature(FW_FEATURE_ISERIES)) 374 /* Get some IO space for the new PHB */
481 pcibios_map_io_space(bus); 375 pcibios_map_io_space(bus);
482 376
483 bus->resource[0] = res = &hose->io_resource; 377 /* Wire up PHB bus resources */
484 if (res->flags && request_resource(&ioport_resource, res)) { 378 if (hose->io_resource.flags) {
485 printk(KERN_ERR "Failed to request PCI IO region " 379 DBG("PCI: PHB IO resource = %016lx-%016lx [%lx]\n",
486 "on PCI domain %04x\n", hose->global_number); 380 hose->io_resource.start, hose->io_resource.end,
487 DBG("res->start = 0x%016lx, res->end = 0x%016lx\n", 381 hose->io_resource.flags);
488 res->start, res->end); 382 bus->resource[0] = res = &hose->io_resource;
489 } 383 }
490
491 for (i = 0; i < 3; ++i) { 384 for (i = 0; i < 3; ++i) {
492 res = &hose->mem_resources[i]; 385 DBG("PCI: PHB MEM resource %d = %016lx-%016lx [%lx]\n", i,
493 bus->resource[i+1] = res; 386 hose->mem_resources[i].start,
494 if (res->flags && request_resource(&iomem_resource, res)) 387 hose->mem_resources[i].end,
495 printk(KERN_ERR "Failed to request PCI memory region " 388 hose->mem_resources[i].flags);
496 "on PCI domain %04x\n", hose->global_number); 389 bus->resource[i+1] = &hose->mem_resources[i];
497 } 390 }
391 DBG("PCI: PHB MEM offset = %016lx\n", hose->pci_mem_offset);
392 DBG("PCI: PHB IO offset = %08lx\n",
393 (unsigned long)hose->io_base_virt - _IO_BASE);
498 394
395 /* Get probe mode and perform scan */
499 mode = PCI_PROBE_NORMAL; 396 mode = PCI_PROBE_NORMAL;
500
501 if (node && ppc_md.pci_probe_mode) 397 if (node && ppc_md.pci_probe_mode)
502 mode = ppc_md.pci_probe_mode(bus); 398 mode = ppc_md.pci_probe_mode(bus);
503 DBG(" probe mode: %d\n", mode); 399 DBG(" probe mode: %d\n", mode);
@@ -514,15 +410,15 @@ static int __init pcibios_init(void)
514{ 410{
515 struct pci_controller *hose, *tmp; 411 struct pci_controller *hose, *tmp;
516 412
413 printk(KERN_INFO "PCI: Probing PCI hardware\n");
414
517 /* For now, override phys_mem_access_prot. If we need it, 415 /* For now, override phys_mem_access_prot. If we need it,
518 * later, we may move that initialization to each ppc_md 416 * later, we may move that initialization to each ppc_md
519 */ 417 */
520 ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; 418 ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
521 419
522 if (firmware_has_feature(FW_FEATURE_ISERIES)) 420 if (pci_probe_only)
523 iSeries_pcibios_init(); 421 ppc_pci_flags |= PPC_PCI_PROBE_ONLY;
524
525 printk(KERN_DEBUG "PCI: Probing PCI hardware\n");
526 422
527 /* Scan all of the recorded PCI controllers. */ 423 /* Scan all of the recorded PCI controllers. */
528 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { 424 list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
@@ -530,19 +426,8 @@ static int __init pcibios_init(void)
530 pci_bus_add_devices(hose->bus); 426 pci_bus_add_devices(hose->bus);
531 } 427 }
532 428
533 if (!firmware_has_feature(FW_FEATURE_ISERIES)) { 429 /* Call common code to handle resource allocation */
534 if (pci_probe_only) 430 pcibios_resource_survey();
535 pcibios_claim_of_setup();
536 else
537 /* FIXME: `else' will be removed when
538 pci_assign_unassigned_resources() is able to work
539 correctly with [partially] allocated PCI tree. */
540 pci_assign_unassigned_resources();
541 }
542
543 /* Call machine dependent final fixup */
544 if (ppc_md.pcibios_fixup)
545 ppc_md.pcibios_fixup();
546 431
547 printk(KERN_DEBUG "PCI: Probing PCI hardware done\n"); 432 printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
548 433
@@ -551,141 +436,6 @@ static int __init pcibios_init(void)
551 436
552subsys_initcall(pcibios_init); 437subsys_initcall(pcibios_init);
553 438
554int pcibios_enable_device(struct pci_dev *dev, int mask)
555{
556 u16 cmd, oldcmd;
557 int i;
558
559 pci_read_config_word(dev, PCI_COMMAND, &cmd);
560 oldcmd = cmd;
561
562 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
563 struct resource *res = &dev->resource[i];
564
565 /* Only set up the requested stuff */
566 if (!(mask & (1<<i)))
567 continue;
568
569 if (res->flags & IORESOURCE_IO)
570 cmd |= PCI_COMMAND_IO;
571 if (res->flags & IORESOURCE_MEM)
572 cmd |= PCI_COMMAND_MEMORY;
573 }
574
575 if (cmd != oldcmd) {
576 printk(KERN_DEBUG "PCI: Enabling device: (%s), cmd %x\n",
577 pci_name(dev), cmd);
578 /* Enable the appropriate bits in the PCI command register. */
579 pci_write_config_word(dev, PCI_COMMAND, cmd);
580 }
581 return 0;
582}
583
584/* Decide whether to display the domain number in /proc */
585int pci_proc_domain(struct pci_bus *bus)
586{
587 if (firmware_has_feature(FW_FEATURE_ISERIES))
588 return 0;
589 else {
590 struct pci_controller *hose = pci_bus_to_host(bus);
591 return hose->buid != 0;
592 }
593}
594
595void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
596 struct device_node *dev, int prim)
597{
598 const unsigned int *ranges;
599 unsigned int pci_space;
600 unsigned long size;
601 int rlen = 0;
602 int memno = 0;
603 struct resource *res;
604 int np, na = of_n_addr_cells(dev);
605 unsigned long pci_addr, cpu_phys_addr;
606
607 np = na + 5;
608
609 /* From "PCI Binding to 1275"
610 * The ranges property is laid out as an array of elements,
611 * each of which comprises:
612 * cells 0 - 2: a PCI address
613 * cells 3 or 3+4: a CPU physical address
614 * (size depending on dev->n_addr_cells)
615 * cells 4+5 or 5+6: the size of the range
616 */
617 ranges = of_get_property(dev, "ranges", &rlen);
618 if (ranges == NULL)
619 return;
620 hose->io_base_phys = 0;
621 while ((rlen -= np * sizeof(unsigned int)) >= 0) {
622 res = NULL;
623 pci_space = ranges[0];
624 pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2];
625 cpu_phys_addr = of_translate_address(dev, &ranges[3]);
626 size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4];
627 ranges += np;
628 if (size == 0)
629 continue;
630
631 /* Now consume following elements while they are contiguous */
632 while (rlen >= np * sizeof(unsigned int)) {
633 unsigned long addr, phys;
634
635 if (ranges[0] != pci_space)
636 break;
637 addr = ((unsigned long)ranges[1] << 32) | ranges[2];
638 phys = ranges[3];
639 if (na >= 2)
640 phys = (phys << 32) | ranges[4];
641 if (addr != pci_addr + size ||
642 phys != cpu_phys_addr + size)
643 break;
644
645 size += ((unsigned long)ranges[na+3] << 32)
646 | ranges[na+4];
647 ranges += np;
648 rlen -= np * sizeof(unsigned int);
649 }
650
651 switch ((pci_space >> 24) & 0x3) {
652 case 1: /* I/O space */
653 hose->io_base_phys = cpu_phys_addr - pci_addr;
654 /* handle from 0 to top of I/O window */
655 hose->pci_io_size = pci_addr + size;
656
657 res = &hose->io_resource;
658 res->flags = IORESOURCE_IO;
659 res->start = pci_addr;
660 DBG("phb%d: IO 0x%lx -> 0x%lx\n", hose->global_number,
661 res->start, res->start + size - 1);
662 break;
663 case 2: /* memory space */
664 memno = 0;
665 while (memno < 3 && hose->mem_resources[memno].flags)
666 ++memno;
667
668 if (memno == 0)
669 hose->pci_mem_offset = cpu_phys_addr - pci_addr;
670 if (memno < 3) {
671 res = &hose->mem_resources[memno];
672 res->flags = IORESOURCE_MEM;
673 res->start = cpu_phys_addr;
674 DBG("phb%d: MEM 0x%lx -> 0x%lx\n", hose->global_number,
675 res->start, res->start + size - 1);
676 }
677 break;
678 }
679 if (res != NULL) {
680 res->name = dev->full_name;
681 res->end = res->start + size - 1;
682 res->parent = NULL;
683 res->sibling = NULL;
684 res->child = NULL;
685 }
686 }
687}
688
689#ifdef CONFIG_HOTPLUG 439#ifdef CONFIG_HOTPLUG
690 440
691int pcibios_unmap_io_space(struct pci_bus *bus) 441int pcibios_unmap_io_space(struct pci_bus *bus)
@@ -719,8 +469,7 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
719 if (hose->io_base_alloc == 0) 469 if (hose->io_base_alloc == 0)
720 return 0; 470 return 0;
721 471
722 DBG("IO unmapping for PHB %s\n", 472 DBG("IO unmapping for PHB %s\n", hose->dn->full_name);
723 ((struct device_node *)hose->arch_data)->full_name);
724 DBG(" alloc=0x%p\n", hose->io_base_alloc); 473 DBG(" alloc=0x%p\n", hose->io_base_alloc);
725 474
726 /* This is a PHB, we fully unmap the IO area */ 475 /* This is a PHB, we fully unmap the IO area */
@@ -779,8 +528,7 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
779 hose->io_base_virt = (void __iomem *)(area->addr + 528 hose->io_base_virt = (void __iomem *)(area->addr +
780 hose->io_base_phys - phys_page); 529 hose->io_base_phys - phys_page);
781 530
782 DBG("IO mapping for PHB %s\n", 531 DBG("IO mapping for PHB %s\n", hose->dn->full_name);
783 ((struct device_node *)hose->arch_data)->full_name);
784 DBG(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n", 532 DBG(" phys=0x%016lx, virt=0x%p (alloc=0x%p)\n",
785 hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc); 533 hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc);
786 DBG(" size=0x%016lx (alloc=0x%016lx)\n", 534 DBG(" size=0x%016lx (alloc=0x%016lx)\n",
@@ -803,51 +551,13 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
803} 551}
804EXPORT_SYMBOL_GPL(pcibios_map_io_space); 552EXPORT_SYMBOL_GPL(pcibios_map_io_space);
805 553
806static void __devinit fixup_resource(struct resource *res, struct pci_dev *dev)
807{
808 struct pci_controller *hose = pci_bus_to_host(dev->bus);
809 unsigned long offset;
810
811 if (res->flags & IORESOURCE_IO) {
812 offset = (unsigned long)hose->io_base_virt - _IO_BASE;
813 res->start += offset;
814 res->end += offset;
815 } else if (res->flags & IORESOURCE_MEM) {
816 res->start += hose->pci_mem_offset;
817 res->end += hose->pci_mem_offset;
818 }
819}
820
821void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
822 struct pci_bus *bus)
823{
824 /* Update device resources. */
825 int i;
826
827 DBG("%s: Fixup resources:\n", pci_name(dev));
828 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
829 struct resource *res = &dev->resource[i];
830 if (!res->flags)
831 continue;
832
833 DBG(" 0x%02x < %08lx:0x%016lx...0x%016lx\n",
834 i, res->flags, res->start, res->end);
835
836 fixup_resource(res, dev);
837
838 DBG(" > %08lx:0x%016lx...0x%016lx\n",
839 res->flags, res->start, res->end);
840 }
841}
842EXPORT_SYMBOL(pcibios_fixup_device_resources);
843
844void __devinit pcibios_setup_new_device(struct pci_dev *dev) 554void __devinit pcibios_setup_new_device(struct pci_dev *dev)
845{ 555{
846 struct dev_archdata *sd = &dev->dev.archdata; 556 struct dev_archdata *sd = &dev->dev.archdata;
847 557
848 sd->of_node = pci_device_to_OF_node(dev); 558 sd->of_node = pci_device_to_OF_node(dev);
849 559
850 DBG("PCI device %s OF node: %s\n", pci_name(dev), 560 DBG("PCI: device %s OF node: %s\n", pci_name(dev),
851 sd->of_node ? sd->of_node->full_name : "<none>"); 561 sd->of_node ? sd->of_node->full_name : "<none>");
852 562
853 sd->dma_ops = pci_dma_ops; 563 sd->dma_ops = pci_dma_ops;
@@ -861,7 +571,7 @@ void __devinit pcibios_setup_new_device(struct pci_dev *dev)
861} 571}
862EXPORT_SYMBOL(pcibios_setup_new_device); 572EXPORT_SYMBOL(pcibios_setup_new_device);
863 573
864static void __devinit do_bus_setup(struct pci_bus *bus) 574void __devinit pcibios_do_bus_setup(struct pci_bus *bus)
865{ 575{
866 struct pci_dev *dev; 576 struct pci_dev *dev;
867 577
@@ -870,42 +580,7 @@ static void __devinit do_bus_setup(struct pci_bus *bus)
870 580
871 list_for_each_entry(dev, &bus->devices, bus_list) 581 list_for_each_entry(dev, &bus->devices, bus_list)
872 pcibios_setup_new_device(dev); 582 pcibios_setup_new_device(dev);
873
874 /* Read default IRQs and fixup if necessary */
875 list_for_each_entry(dev, &bus->devices, bus_list) {
876 pci_read_irq_line(dev);
877 if (ppc_md.pci_irq_fixup)
878 ppc_md.pci_irq_fixup(dev);
879 }
880}
881
882void __devinit pcibios_fixup_bus(struct pci_bus *bus)
883{
884 struct pci_dev *dev = bus->self;
885 struct device_node *np;
886
887 np = pci_bus_to_OF_node(bus);
888
889 DBG("pcibios_fixup_bus(%s)\n", np ? np->full_name : "<???>");
890
891 if (dev && pci_probe_only &&
892 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
893 /* This is a subordinate bridge */
894
895 pci_read_bridge_bases(bus);
896 pcibios_fixup_device_resources(dev, bus);
897 }
898
899 do_bus_setup(bus);
900
901 if (!pci_probe_only)
902 return;
903
904 list_for_each_entry(dev, &bus->devices, bus_list)
905 if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
906 pcibios_fixup_device_resources(dev, bus);
907} 583}
908EXPORT_SYMBOL(pcibios_fixup_bus);
909 584
910unsigned long pci_address_to_pio(phys_addr_t address) 585unsigned long pci_address_to_pio(phys_addr_t address)
911{ 586{
diff --git a/arch/powerpc/kernel/pci_dn.c b/arch/powerpc/kernel/pci_dn.c
index b4839038613d..85d4d8924b5c 100644
--- a/arch/powerpc/kernel/pci_dn.c
+++ b/arch/powerpc/kernel/pci_dn.c
@@ -133,7 +133,7 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
133 */ 133 */
134void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb) 134void __devinit pci_devs_phb_init_dynamic(struct pci_controller *phb)
135{ 135{
136 struct device_node * dn = (struct device_node *) phb->arch_data; 136 struct device_node *dn = phb->dn;
137 struct pci_dn *pdn; 137 struct pci_dn *pdn;
138 138
139 /* PHB nodes themselves must not match */ 139 /* PHB nodes themselves must not match */
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index acc0d247d3c3..6c2d8836f77d 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -583,6 +583,20 @@ static void __init check_cpu_pa_features(unsigned long node)
583 ibm_pa_features, ARRAY_SIZE(ibm_pa_features)); 583 ibm_pa_features, ARRAY_SIZE(ibm_pa_features));
584} 584}
585 585
586#ifdef CONFIG_PPC64
587static void __init check_cpu_slb_size(unsigned long node)
588{
589 u32 *slb_size_ptr;
590
591 slb_size_ptr = of_get_flat_dt_prop(node, "ibm,slb-size", NULL);
592 if (slb_size_ptr != NULL) {
593 mmu_slb_size = *slb_size_ptr;
594 }
595}
596#else
597#define check_cpu_slb_size(node) do { } while(0)
598#endif
599
586static struct feature_property { 600static struct feature_property {
587 const char *name; 601 const char *name;
588 u32 min_value; 602 u32 min_value;
@@ -713,6 +727,7 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
713 727
714 check_cpu_feature_properties(node); 728 check_cpu_feature_properties(node);
715 check_cpu_pa_features(node); 729 check_cpu_pa_features(node);
730 check_cpu_slb_size(node);
716 731
717#ifdef CONFIG_PPC_PSERIES 732#ifdef CONFIG_PPC_PSERIES
718 if (nthreads > 1) 733 if (nthreads > 1)
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index b5c96af955c6..90eb3a3e383e 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -273,7 +273,7 @@ int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
273#else 273#else
274 struct pci_controller *host; 274 struct pci_controller *host;
275 host = pci_bus_to_host(pdev->bus); 275 host = pci_bus_to_host(pdev->bus);
276 ppnode = host ? host->arch_data : NULL; 276 ppnode = host ? host->dn : NULL;
277#endif 277#endif
278 /* No node for host bridge ? give up */ 278 /* No node for host bridge ? give up */
279 if (ppnode == NULL) 279 if (ppnode == NULL)
@@ -419,7 +419,7 @@ static struct of_bus *of_match_bus(struct device_node *np)
419 419
420static int of_translate_one(struct device_node *parent, struct of_bus *bus, 420static int of_translate_one(struct device_node *parent, struct of_bus *bus,
421 struct of_bus *pbus, u32 *addr, 421 struct of_bus *pbus, u32 *addr,
422 int na, int ns, int pna) 422 int na, int ns, int pna, const char *rprop)
423{ 423{
424 const u32 *ranges; 424 const u32 *ranges;
425 unsigned int rlen; 425 unsigned int rlen;
@@ -438,7 +438,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
438 * to translate addresses that aren't supposed to be translated in 438 * to translate addresses that aren't supposed to be translated in
439 * the first place. --BenH. 439 * the first place. --BenH.
440 */ 440 */
441 ranges = of_get_property(parent, "ranges", &rlen); 441 ranges = of_get_property(parent, rprop, &rlen);
442 if (ranges == NULL || rlen == 0) { 442 if (ranges == NULL || rlen == 0) {
443 offset = of_read_number(addr, na); 443 offset = of_read_number(addr, na);
444 memset(addr, 0, pna * 4); 444 memset(addr, 0, pna * 4);
@@ -481,7 +481,8 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
481 * that can be mapped to a cpu physical address). This is not really specified 481 * that can be mapped to a cpu physical address). This is not really specified
482 * that way, but this is traditionally the way IBM at least do things 482 * that way, but this is traditionally the way IBM at least do things
483 */ 483 */
484u64 of_translate_address(struct device_node *dev, const u32 *in_addr) 484u64 __of_translate_address(struct device_node *dev, const u32 *in_addr,
485 const char *rprop)
485{ 486{
486 struct device_node *parent = NULL; 487 struct device_node *parent = NULL;
487 struct of_bus *bus, *pbus; 488 struct of_bus *bus, *pbus;
@@ -540,7 +541,7 @@ u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
540 pbus->name, pna, pns, parent->full_name); 541 pbus->name, pna, pns, parent->full_name);
541 542
542 /* Apply bus translation */ 543 /* Apply bus translation */
543 if (of_translate_one(dev, bus, pbus, addr, na, ns, pna)) 544 if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
544 break; 545 break;
545 546
546 /* Complete the move up one level */ 547 /* Complete the move up one level */
@@ -556,8 +557,19 @@ u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
556 557
557 return result; 558 return result;
558} 559}
560
561u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
562{
563 return __of_translate_address(dev, in_addr, "ranges");
564}
559EXPORT_SYMBOL(of_translate_address); 565EXPORT_SYMBOL(of_translate_address);
560 566
567u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr)
568{
569 return __of_translate_address(dev, in_addr, "dma-ranges");
570}
571EXPORT_SYMBOL(of_translate_dma_address);
572
561const u32 *of_get_address(struct device_node *dev, int index, u64 *size, 573const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
562 unsigned int *flags) 574 unsigned int *flags)
563{ 575{
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 21f14e57d1f3..99aaae3409c0 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -260,7 +260,7 @@ static int phb_set_bus_ranges(struct device_node *dev,
260 260
261int __devinit rtas_setup_phb(struct pci_controller *phb) 261int __devinit rtas_setup_phb(struct pci_controller *phb)
262{ 262{
263 struct device_node *dev = phb->arch_data; 263 struct device_node *dev = phb->dn;
264 264
265 if (is_python(dev)) 265 if (is_python(dev))
266 python_countermeasures(dev); 266 python_countermeasures(dev);
@@ -311,10 +311,12 @@ void __init find_and_init_phbs(void)
311 if (prop) 311 if (prop)
312 pci_probe_only = *prop; 312 pci_probe_only = *prop;
313 313
314#ifdef CONFIG_PPC32 /* Will be made generic soon */
314 prop = of_get_property(of_chosen, 315 prop = of_get_property(of_chosen,
315 "linux,pci-assign-all-buses", NULL); 316 "linux,pci-assign-all-buses", NULL);
316 if (prop) 317 if (prop && *prop)
317 pci_assign_all_buses = *prop; 318 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
319#endif /* CONFIG_PPC32 */
318 } 320 }
319} 321}
320 322
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 2de00f870edc..6adb5a1e98bb 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -33,6 +33,7 @@
33#include <linux/serial.h> 33#include <linux/serial.h>
34#include <linux/serial_8250.h> 34#include <linux/serial_8250.h>
35#include <linux/debugfs.h> 35#include <linux/debugfs.h>
36#include <linux/percpu.h>
36#include <asm/io.h> 37#include <asm/io.h>
37#include <asm/prom.h> 38#include <asm/prom.h>
38#include <asm/processor.h> 39#include <asm/processor.h>
@@ -57,6 +58,7 @@
57#include <asm/mmu.h> 58#include <asm/mmu.h>
58#include <asm/lmb.h> 59#include <asm/lmb.h>
59#include <asm/xmon.h> 60#include <asm/xmon.h>
61#include <asm/cputhreads.h>
60 62
61#include "setup.h" 63#include "setup.h"
62 64
@@ -327,6 +329,31 @@ void __init check_for_initrd(void)
327 329
328#ifdef CONFIG_SMP 330#ifdef CONFIG_SMP
329 331
332int threads_per_core, threads_shift;
333cpumask_t threads_core_mask;
334
335static void __init cpu_init_thread_core_maps(int tpc)
336{
337 int i;
338
339 threads_per_core = tpc;
340 threads_core_mask = CPU_MASK_NONE;
341
342 /* This implementation only supports power of 2 number of threads
343 * for simplicity and performance
344 */
345 threads_shift = ilog2(tpc);
346 BUG_ON(tpc != (1 << threads_shift));
347
348 for (i = 0; i < tpc; i++)
349 cpu_set(i, threads_core_mask);
350
351 printk(KERN_INFO "CPU maps initialized for %d thread%s per core\n",
352 tpc, tpc > 1 ? "s" : "");
353 printk(KERN_DEBUG " (thread shift is %d)\n", threads_shift);
354}
355
356
330/** 357/**
331 * setup_cpu_maps - initialize the following cpu maps: 358 * setup_cpu_maps - initialize the following cpu maps:
332 * cpu_possible_map 359 * cpu_possible_map
@@ -350,22 +377,32 @@ void __init smp_setup_cpu_maps(void)
350{ 377{
351 struct device_node *dn = NULL; 378 struct device_node *dn = NULL;
352 int cpu = 0; 379 int cpu = 0;
380 int nthreads = 1;
381
382 DBG("smp_setup_cpu_maps()\n");
353 383
354 while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) { 384 while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
355 const int *intserv; 385 const int *intserv;
356 int j, len = sizeof(u32), nthreads = 1; 386 int j, len;
387
388 DBG(" * %s...\n", dn->full_name);
357 389
358 intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s", 390 intserv = of_get_property(dn, "ibm,ppc-interrupt-server#s",
359 &len); 391 &len);
360 if (intserv) 392 if (intserv) {
361 nthreads = len / sizeof(int); 393 nthreads = len / sizeof(int);
362 else { 394 DBG(" ibm,ppc-interrupt-server#s -> %d threads\n",
395 nthreads);
396 } else {
397 DBG(" no ibm,ppc-interrupt-server#s -> 1 thread\n");
363 intserv = of_get_property(dn, "reg", NULL); 398 intserv = of_get_property(dn, "reg", NULL);
364 if (!intserv) 399 if (!intserv)
365 intserv = &cpu; /* assume logical == phys */ 400 intserv = &cpu; /* assume logical == phys */
366 } 401 }
367 402
368 for (j = 0; j < nthreads && cpu < NR_CPUS; j++) { 403 for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
404 DBG(" thread %d -> cpu %d (hard id %d)\n",
405 j, cpu, intserv[j]);
369 cpu_set(cpu, cpu_present_map); 406 cpu_set(cpu, cpu_present_map);
370 set_hard_smp_processor_id(cpu, intserv[j]); 407 set_hard_smp_processor_id(cpu, intserv[j]);
371 cpu_set(cpu, cpu_possible_map); 408 cpu_set(cpu, cpu_possible_map);
@@ -373,6 +410,12 @@ void __init smp_setup_cpu_maps(void)
373 } 410 }
374 } 411 }
375 412
413 /* If no SMT supported, nthreads is forced to 1 */
414 if (!cpu_has_feature(CPU_FTR_SMT)) {
415 DBG(" SMT disabled ! nthreads forced to 1\n");
416 nthreads = 1;
417 }
418
376#ifdef CONFIG_PPC64 419#ifdef CONFIG_PPC64
377 /* 420 /*
378 * On pSeries LPAR, we need to know how many cpus 421 * On pSeries LPAR, we need to know how many cpus
@@ -395,7 +438,7 @@ void __init smp_setup_cpu_maps(void)
395 438
396 /* Double maxcpus for processors which have SMT capability */ 439 /* Double maxcpus for processors which have SMT capability */
397 if (cpu_has_feature(CPU_FTR_SMT)) 440 if (cpu_has_feature(CPU_FTR_SMT))
398 maxcpus *= 2; 441 maxcpus *= nthreads;
399 442
400 if (maxcpus > NR_CPUS) { 443 if (maxcpus > NR_CPUS) {
401 printk(KERN_WARNING 444 printk(KERN_WARNING
@@ -412,9 +455,16 @@ void __init smp_setup_cpu_maps(void)
412 out: 455 out:
413 of_node_put(dn); 456 of_node_put(dn);
414 } 457 }
415
416 vdso_data->processorCount = num_present_cpus(); 458 vdso_data->processorCount = num_present_cpus();
417#endif /* CONFIG_PPC64 */ 459#endif /* CONFIG_PPC64 */
460
461 /* Initialize CPU <=> thread mapping/
462 *
463 * WARNING: We assume that the number of threads is the same for
464 * every CPU in the system. If that is not the case, then some code
465 * here will have to be reworked
466 */
467 cpu_init_thread_core_maps(nthreads);
418} 468}
419 469
420/* 470/*
@@ -424,17 +474,19 @@ void __init smp_setup_cpu_maps(void)
424 */ 474 */
425void __init smp_setup_cpu_sibling_map(void) 475void __init smp_setup_cpu_sibling_map(void)
426{ 476{
427#if defined(CONFIG_PPC64) 477#ifdef CONFIG_PPC64
428 int cpu; 478 int i, cpu, base;
429 479
430 /*
431 * Do the sibling map; assume only two threads per processor.
432 */
433 for_each_possible_cpu(cpu) { 480 for_each_possible_cpu(cpu) {
434 cpu_set(cpu, per_cpu(cpu_sibling_map, cpu)); 481 DBG("Sibling map for CPU %d:", cpu);
435 if (cpu_has_feature(CPU_FTR_SMT)) 482 base = cpu_first_thread_in_core(cpu);
436 cpu_set(cpu ^ 0x1, per_cpu(cpu_sibling_map, cpu)); 483 for (i = 0; i < threads_per_core; i++) {
484 cpu_set(base + i, per_cpu(cpu_sibling_map, cpu));
485 DBG(" %d", base + i);
486 }
487 DBG("\n");
437 } 488 }
489
438#endif /* CONFIG_PPC64 */ 490#endif /* CONFIG_PPC64 */
439} 491}
440#endif /* CONFIG_SMP */ 492#endif /* CONFIG_SMP */
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 6126bca8b70a..d840bc772fd3 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -24,13 +24,12 @@
24#include <linux/signal.h> 24#include <linux/signal.h>
25#include <linux/errno.h> 25#include <linux/errno.h>
26#include <linux/elf.h> 26#include <linux/elf.h>
27#include <linux/ptrace.h>
27#ifdef CONFIG_PPC64 28#ifdef CONFIG_PPC64
28#include <linux/syscalls.h> 29#include <linux/syscalls.h>
29#include <linux/compat.h> 30#include <linux/compat.h>
30#include <linux/ptrace.h>
31#else 31#else
32#include <linux/wait.h> 32#include <linux/wait.h>
33#include <linux/ptrace.h>
34#include <linux/unistd.h> 33#include <linux/unistd.h>
35#include <linux/stddef.h> 34#include <linux/stddef.h>
36#include <linux/tty.h> 35#include <linux/tty.h>
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index a925a8eae121..5cd3db5cae41 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -116,9 +116,12 @@ static struct clock_event_device decrementer_clockevent = {
116 .features = CLOCK_EVT_FEAT_ONESHOT, 116 .features = CLOCK_EVT_FEAT_ONESHOT,
117}; 117};
118 118
119static DEFINE_PER_CPU(struct clock_event_device, decrementers); 119struct decrementer_clock {
120void init_decrementer_clockevent(void); 120 struct clock_event_device event;
121static DEFINE_PER_CPU(u64, decrementer_next_tb); 121 u64 next_tb;
122};
123
124static DEFINE_PER_CPU(struct decrementer_clock, decrementers);
122 125
123#ifdef CONFIG_PPC_ISERIES 126#ifdef CONFIG_PPC_ISERIES
124static unsigned long __initdata iSeries_recal_titan; 127static unsigned long __initdata iSeries_recal_titan;
@@ -216,7 +219,11 @@ static u64 read_purr(void)
216 */ 219 */
217static u64 read_spurr(u64 purr) 220static u64 read_spurr(u64 purr)
218{ 221{
219 if (cpu_has_feature(CPU_FTR_SPURR)) 222 /*
223 * cpus without PURR won't have a SPURR
224 * We already know the former when we use this, so tell gcc
225 */
226 if (cpu_has_feature(CPU_FTR_PURR) && cpu_has_feature(CPU_FTR_SPURR))
220 return mfspr(SPRN_SPURR); 227 return mfspr(SPRN_SPURR);
221 return purr; 228 return purr;
222} 229}
@@ -227,29 +234,30 @@ static u64 read_spurr(u64 purr)
227 */ 234 */
228void account_system_vtime(struct task_struct *tsk) 235void account_system_vtime(struct task_struct *tsk)
229{ 236{
230 u64 now, nowscaled, delta, deltascaled; 237 u64 now, nowscaled, delta, deltascaled, sys_time;
231 unsigned long flags; 238 unsigned long flags;
232 239
233 local_irq_save(flags); 240 local_irq_save(flags);
234 now = read_purr(); 241 now = read_purr();
235 delta = now - get_paca()->startpurr;
236 get_paca()->startpurr = now;
237 nowscaled = read_spurr(now); 242 nowscaled = read_spurr(now);
243 delta = now - get_paca()->startpurr;
238 deltascaled = nowscaled - get_paca()->startspurr; 244 deltascaled = nowscaled - get_paca()->startspurr;
245 get_paca()->startpurr = now;
239 get_paca()->startspurr = nowscaled; 246 get_paca()->startspurr = nowscaled;
240 if (!in_interrupt()) { 247 if (!in_interrupt()) {
241 /* deltascaled includes both user and system time. 248 /* deltascaled includes both user and system time.
242 * Hence scale it based on the purr ratio to estimate 249 * Hence scale it based on the purr ratio to estimate
243 * the system time */ 250 * the system time */
251 sys_time = get_paca()->system_time;
244 if (get_paca()->user_time) 252 if (get_paca()->user_time)
245 deltascaled = deltascaled * get_paca()->system_time / 253 deltascaled = deltascaled * sys_time /
246 (get_paca()->system_time + get_paca()->user_time); 254 (sys_time + get_paca()->user_time);
247 delta += get_paca()->system_time; 255 delta += sys_time;
248 get_paca()->system_time = 0; 256 get_paca()->system_time = 0;
249 } 257 }
250 account_system_time(tsk, 0, delta); 258 account_system_time(tsk, 0, delta);
251 get_paca()->purrdelta = delta;
252 account_system_time_scaled(tsk, deltascaled); 259 account_system_time_scaled(tsk, deltascaled);
260 get_paca()->purrdelta = delta;
253 get_paca()->spurrdelta = deltascaled; 261 get_paca()->spurrdelta = deltascaled;
254 local_irq_restore(flags); 262 local_irq_restore(flags);
255} 263}
@@ -326,11 +334,9 @@ void calculate_steal_time(void)
326 s64 stolen; 334 s64 stolen;
327 struct cpu_purr_data *pme; 335 struct cpu_purr_data *pme;
328 336
329 if (!cpu_has_feature(CPU_FTR_PURR)) 337 pme = &__get_cpu_var(cpu_purr_data);
330 return;
331 pme = &per_cpu(cpu_purr_data, smp_processor_id());
332 if (!pme->initialized) 338 if (!pme->initialized)
333 return; /* this can happen in early boot */ 339 return; /* !CPU_FTR_PURR or early in early boot */
334 tb = mftb(); 340 tb = mftb();
335 purr = mfspr(SPRN_PURR); 341 purr = mfspr(SPRN_PURR);
336 stolen = (tb - pme->tb) - (purr - pme->purr); 342 stolen = (tb - pme->tb) - (purr - pme->purr);
@@ -353,7 +359,7 @@ static void snapshot_purr(void)
353 if (!cpu_has_feature(CPU_FTR_PURR)) 359 if (!cpu_has_feature(CPU_FTR_PURR))
354 return; 360 return;
355 local_irq_save(flags); 361 local_irq_save(flags);
356 pme = &per_cpu(cpu_purr_data, smp_processor_id()); 362 pme = &__get_cpu_var(cpu_purr_data);
357 pme->tb = mftb(); 363 pme->tb = mftb();
358 pme->purr = mfspr(SPRN_PURR); 364 pme->purr = mfspr(SPRN_PURR);
359 pme->initialized = 1; 365 pme->initialized = 1;
@@ -556,8 +562,8 @@ void __init iSeries_time_init_early(void)
556void timer_interrupt(struct pt_regs * regs) 562void timer_interrupt(struct pt_regs * regs)
557{ 563{
558 struct pt_regs *old_regs; 564 struct pt_regs *old_regs;
559 int cpu = smp_processor_id(); 565 struct decrementer_clock *decrementer = &__get_cpu_var(decrementers);
560 struct clock_event_device *evt = &per_cpu(decrementers, cpu); 566 struct clock_event_device *evt = &decrementer->event;
561 u64 now; 567 u64 now;
562 568
563 /* Ensure a positive value is written to the decrementer, or else 569 /* Ensure a positive value is written to the decrementer, or else
@@ -570,9 +576,9 @@ void timer_interrupt(struct pt_regs * regs)
570#endif 576#endif
571 577
572 now = get_tb_or_rtc(); 578 now = get_tb_or_rtc();
573 if (now < per_cpu(decrementer_next_tb, cpu)) { 579 if (now < decrementer->next_tb) {
574 /* not time for this event yet */ 580 /* not time for this event yet */
575 now = per_cpu(decrementer_next_tb, cpu) - now; 581 now = decrementer->next_tb - now;
576 if (now <= DECREMENTER_MAX) 582 if (now <= DECREMENTER_MAX)
577 set_dec((int)now); 583 set_dec((int)now);
578 return; 584 return;
@@ -623,6 +629,45 @@ void wakeup_decrementer(void)
623 set_dec(ticks); 629 set_dec(ticks);
624} 630}
625 631
632#ifdef CONFIG_SUSPEND
633void generic_suspend_disable_irqs(void)
634{
635 preempt_disable();
636
637 /* Disable the decrementer, so that it doesn't interfere
638 * with suspending.
639 */
640
641 set_dec(0x7fffffff);
642 local_irq_disable();
643 set_dec(0x7fffffff);
644}
645
646void generic_suspend_enable_irqs(void)
647{
648 wakeup_decrementer();
649
650 local_irq_enable();
651 preempt_enable();
652}
653
654/* Overrides the weak version in kernel/power/main.c */
655void arch_suspend_disable_irqs(void)
656{
657 if (ppc_md.suspend_disable_irqs)
658 ppc_md.suspend_disable_irqs();
659 generic_suspend_disable_irqs();
660}
661
662/* Overrides the weak version in kernel/power/main.c */
663void arch_suspend_enable_irqs(void)
664{
665 generic_suspend_enable_irqs();
666 if (ppc_md.suspend_enable_irqs)
667 ppc_md.suspend_enable_irqs();
668}
669#endif
670
626#ifdef CONFIG_SMP 671#ifdef CONFIG_SMP
627void __init smp_space_timers(unsigned int max_cpus) 672void __init smp_space_timers(unsigned int max_cpus)
628{ 673{
@@ -811,7 +856,7 @@ void __init clocksource_init(void)
811static int decrementer_set_next_event(unsigned long evt, 856static int decrementer_set_next_event(unsigned long evt,
812 struct clock_event_device *dev) 857 struct clock_event_device *dev)
813{ 858{
814 __get_cpu_var(decrementer_next_tb) = get_tb_or_rtc() + evt; 859 __get_cpu_var(decrementers).next_tb = get_tb_or_rtc() + evt;
815 set_dec(evt); 860 set_dec(evt);
816 return 0; 861 return 0;
817} 862}
@@ -825,7 +870,7 @@ static void decrementer_set_mode(enum clock_event_mode mode,
825 870
826static void register_decrementer_clockevent(int cpu) 871static void register_decrementer_clockevent(int cpu)
827{ 872{
828 struct clock_event_device *dec = &per_cpu(decrementers, cpu); 873 struct clock_event_device *dec = &per_cpu(decrementers, cpu).event;
829 874
830 *dec = decrementer_clockevent; 875 *dec = decrementer_clockevent;
831 dec->cpumask = cpumask_of_cpu(cpu); 876 dec->cpumask = cpumask_of_cpu(cpu);
@@ -836,7 +881,7 @@ static void register_decrementer_clockevent(int cpu)
836 clockevents_register_device(dec); 881 clockevents_register_device(dec);
837} 882}
838 883
839void init_decrementer_clockevent(void) 884static void __init init_decrementer_clockevent(void)
840{ 885{
841 int cpu = smp_processor_id(); 886 int cpu = smp_processor_id();
842 887
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 59c464e26f38..cad64840fce4 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -622,6 +622,9 @@ static void parse_fpe(struct pt_regs *regs)
622#define INST_POPCNTB 0x7c0000f4 622#define INST_POPCNTB 0x7c0000f4
623#define INST_POPCNTB_MASK 0xfc0007fe 623#define INST_POPCNTB_MASK 0xfc0007fe
624 624
625#define INST_ISEL 0x7c00001e
626#define INST_ISEL_MASK 0xfc00003e
627
625static int emulate_string_inst(struct pt_regs *regs, u32 instword) 628static int emulate_string_inst(struct pt_regs *regs, u32 instword)
626{ 629{
627 u8 rT = (instword >> 21) & 0x1f; 630 u8 rT = (instword >> 21) & 0x1f;
@@ -707,6 +710,23 @@ static int emulate_popcntb_inst(struct pt_regs *regs, u32 instword)
707 return 0; 710 return 0;
708} 711}
709 712
713static int emulate_isel(struct pt_regs *regs, u32 instword)
714{
715 u8 rT = (instword >> 21) & 0x1f;
716 u8 rA = (instword >> 16) & 0x1f;
717 u8 rB = (instword >> 11) & 0x1f;
718 u8 BC = (instword >> 6) & 0x1f;
719 u8 bit;
720 unsigned long tmp;
721
722 tmp = (rA == 0) ? 0 : regs->gpr[rA];
723 bit = (regs->ccr >> (31 - BC)) & 0x1;
724
725 regs->gpr[rT] = bit ? tmp : regs->gpr[rB];
726
727 return 0;
728}
729
710static int emulate_instruction(struct pt_regs *regs) 730static int emulate_instruction(struct pt_regs *regs)
711{ 731{
712 u32 instword; 732 u32 instword;
@@ -749,6 +769,11 @@ static int emulate_instruction(struct pt_regs *regs)
749 return emulate_popcntb_inst(regs, instword); 769 return emulate_popcntb_inst(regs, instword);
750 } 770 }
751 771
772 /* Emulate isel (Integer Select) instruction */
773 if ((instword & INST_ISEL_MASK) == INST_ISEL) {
774 return emulate_isel(regs, instword);
775 }
776
752 return -EINVAL; 777 return -EINVAL;
753} 778}
754 779
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index d723070c9a33..eba148f2a31c 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -57,6 +57,10 @@ void __init udbg_early_init(void)
57#elif defined(CONFIG_PPC_EARLY_DEBUG_CPM) 57#elif defined(CONFIG_PPC_EARLY_DEBUG_CPM)
58 udbg_init_cpm(); 58 udbg_init_cpm();
59#endif 59#endif
60
61#ifdef CONFIG_PPC_EARLY_DEBUG
62 console_loglevel = 10;
63#endif
60} 64}
61 65
62/* udbg library, used by xmon et al */ 66/* udbg library, used by xmon et al */
diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c
index 833a3d0bcfa7..df740eae77b8 100644
--- a/arch/powerpc/kernel/udbg_16550.c
+++ b/arch/powerpc/kernel/udbg_16550.c
@@ -46,7 +46,7 @@ struct NS16550 {
46 46
47#define LCR_DLAB 0x80 47#define LCR_DLAB 0x80
48 48
49static volatile struct NS16550 __iomem *udbg_comport; 49static struct NS16550 __iomem *udbg_comport;
50 50
51static void udbg_550_putc(char c) 51static void udbg_550_putc(char c)
52{ 52{
@@ -117,7 +117,7 @@ unsigned int udbg_probe_uart_speed(void __iomem *comport, unsigned int clock)
117{ 117{
118 unsigned int dll, dlm, divisor, prescaler, speed; 118 unsigned int dll, dlm, divisor, prescaler, speed;
119 u8 old_lcr; 119 u8 old_lcr;
120 volatile struct NS16550 __iomem *port = comport; 120 struct NS16550 __iomem *port = comport;
121 121
122 old_lcr = in_8(&port->lcr); 122 old_lcr = in_8(&port->lcr);
123 123
@@ -162,7 +162,7 @@ void udbg_maple_real_putc(char c)
162 162
163void __init udbg_init_maple_realmode(void) 163void __init udbg_init_maple_realmode(void)
164{ 164{
165 udbg_comport = (volatile struct NS16550 __iomem *)0xf40003f8; 165 udbg_comport = (struct NS16550 __iomem *)0xf40003f8;
166 166
167 udbg_putc = udbg_maple_real_putc; 167 udbg_putc = udbg_maple_real_putc;
168 udbg_getc = NULL; 168 udbg_getc = NULL;
@@ -184,7 +184,7 @@ void udbg_pas_real_putc(char c)
184 184
185void udbg_init_pas_realmode(void) 185void udbg_init_pas_realmode(void)
186{ 186{
187 udbg_comport = (volatile struct NS16550 __iomem *)0xfcff03f8UL; 187 udbg_comport = (struct NS16550 __iomem *)0xfcff03f8UL;
188 188
189 udbg_putc = udbg_pas_real_putc; 189 udbg_putc = udbg_pas_real_putc;
190 udbg_getc = NULL; 190 udbg_getc = NULL;
@@ -219,7 +219,7 @@ static int udbg_44x_as1_getc(void)
219void __init udbg_init_44x_as1(void) 219void __init udbg_init_44x_as1(void)
220{ 220{
221 udbg_comport = 221 udbg_comport =
222 (volatile struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR; 222 (struct NS16550 __iomem *)PPC44x_EARLY_DEBUG_VIRTADDR;
223 223
224 udbg_putc = udbg_44x_as1_putc; 224 udbg_putc = udbg_44x_as1_putc;
225 udbg_getc = udbg_44x_as1_getc; 225 udbg_getc = udbg_44x_as1_getc;
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index 8135da06e0a4..10dda224a361 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -189,7 +189,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address,
189 return SIGSEGV; 189 return SIGSEGV;
190 /* in_atomic() in user mode is really bad, 190 /* in_atomic() in user mode is really bad,
191 as is current->mm == NULL. */ 191 as is current->mm == NULL. */
192 printk(KERN_EMERG "Page fault in user mode with" 192 printk(KERN_EMERG "Page fault in user mode with "
193 "in_atomic() = %d mm = %p\n", in_atomic(), mm); 193 "in_atomic() = %d mm = %p\n", in_atomic(), mm);
194 printk(KERN_EMERG "NIP = %lx MSR = %lx\n", 194 printk(KERN_EMERG "NIP = %lx MSR = %lx\n",
195 regs->nip, regs->msr); 195 regs->nip, regs->msr);
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index f09730bf3a33..cbbd8b0bc8f4 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -96,6 +96,7 @@ int mmu_vmalloc_psize = MMU_PAGE_4K;
96int mmu_io_psize = MMU_PAGE_4K; 96int mmu_io_psize = MMU_PAGE_4K;
97int mmu_kernel_ssize = MMU_SEGSIZE_256M; 97int mmu_kernel_ssize = MMU_SEGSIZE_256M;
98int mmu_highuser_ssize = MMU_SEGSIZE_256M; 98int mmu_highuser_ssize = MMU_SEGSIZE_256M;
99u16 mmu_slb_size = 64;
99#ifdef CONFIG_HUGETLB_PAGE 100#ifdef CONFIG_HUGETLB_PAGE
100int mmu_huge_psize = MMU_PAGE_16M; 101int mmu_huge_psize = MMU_PAGE_16M;
101unsigned int HPAGE_SHIFT; 102unsigned int HPAGE_SHIFT;
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index c12adc3ddffd..1666e7d54cca 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -24,6 +24,8 @@
24 24
25static int numa_enabled = 1; 25static int numa_enabled = 1;
26 26
27static char *cmdline __initdata;
28
27static int numa_debug; 29static int numa_debug;
28#define dbg(args...) if (numa_debug) { printk(KERN_INFO args); } 30#define dbg(args...) if (numa_debug) { printk(KERN_INFO args); }
29 31
@@ -39,6 +41,43 @@ static bootmem_data_t __initdata plat_node_bdata[MAX_NUMNODES];
39static int min_common_depth; 41static int min_common_depth;
40static int n_mem_addr_cells, n_mem_size_cells; 42static int n_mem_addr_cells, n_mem_size_cells;
41 43
44static int __cpuinit fake_numa_create_new_node(unsigned long end_pfn,
45 unsigned int *nid)
46{
47 unsigned long long mem;
48 char *p = cmdline;
49 static unsigned int fake_nid = 0;
50 static unsigned long long curr_boundary = 0;
51
52 *nid = fake_nid;
53 if (!p)
54 return 0;
55
56 mem = memparse(p, &p);
57 if (!mem)
58 return 0;
59
60 if (mem < curr_boundary)
61 return 0;
62
63 curr_boundary = mem;
64
65 if ((end_pfn << PAGE_SHIFT) > mem) {
66 /*
67 * Skip commas and spaces
68 */
69 while (*p == ',' || *p == ' ' || *p == '\t')
70 p++;
71
72 cmdline = p;
73 fake_nid++;
74 *nid = fake_nid;
75 dbg("created new fake_node with id %d\n", fake_nid);
76 return 1;
77 }
78 return 0;
79}
80
42static void __cpuinit map_cpu_to_node(int cpu, int node) 81static void __cpuinit map_cpu_to_node(int cpu, int node)
43{ 82{
44 numa_cpu_lookup_table[cpu] = node; 83 numa_cpu_lookup_table[cpu] = node;
@@ -344,12 +383,14 @@ static void __init parse_drconf_memory(struct device_node *memory)
344 if (nid == 0xffff || nid >= MAX_NUMNODES) 383 if (nid == 0xffff || nid >= MAX_NUMNODES)
345 nid = default_nid; 384 nid = default_nid;
346 } 385 }
347 node_set_online(nid);
348 386
349 size = numa_enforce_memory_limit(start, lmb_size); 387 size = numa_enforce_memory_limit(start, lmb_size);
350 if (!size) 388 if (!size)
351 continue; 389 continue;
352 390
391 fake_numa_create_new_node(((start + size) >> PAGE_SHIFT), &nid);
392 node_set_online(nid);
393
353 add_active_range(nid, start >> PAGE_SHIFT, 394 add_active_range(nid, start >> PAGE_SHIFT,
354 (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT)); 395 (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT));
355 } 396 }
@@ -429,7 +470,6 @@ new_range:
429 nid = of_node_to_nid_single(memory); 470 nid = of_node_to_nid_single(memory);
430 if (nid < 0) 471 if (nid < 0)
431 nid = default_nid; 472 nid = default_nid;
432 node_set_online(nid);
433 473
434 if (!(size = numa_enforce_memory_limit(start, size))) { 474 if (!(size = numa_enforce_memory_limit(start, size))) {
435 if (--ranges) 475 if (--ranges)
@@ -438,6 +478,9 @@ new_range:
438 continue; 478 continue;
439 } 479 }
440 480
481 fake_numa_create_new_node(((start + size) >> PAGE_SHIFT), &nid);
482 node_set_online(nid);
483
441 add_active_range(nid, start >> PAGE_SHIFT, 484 add_active_range(nid, start >> PAGE_SHIFT,
442 (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT)); 485 (start >> PAGE_SHIFT) + (size >> PAGE_SHIFT));
443 486
@@ -461,7 +504,7 @@ static void __init setup_nonnuma(void)
461 unsigned long top_of_ram = lmb_end_of_DRAM(); 504 unsigned long top_of_ram = lmb_end_of_DRAM();
462 unsigned long total_ram = lmb_phys_mem_size(); 505 unsigned long total_ram = lmb_phys_mem_size();
463 unsigned long start_pfn, end_pfn; 506 unsigned long start_pfn, end_pfn;
464 unsigned int i; 507 unsigned int i, nid = 0;
465 508
466 printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n", 509 printk(KERN_DEBUG "Top of RAM: 0x%lx, Total RAM: 0x%lx\n",
467 top_of_ram, total_ram); 510 top_of_ram, total_ram);
@@ -471,9 +514,11 @@ static void __init setup_nonnuma(void)
471 for (i = 0; i < lmb.memory.cnt; ++i) { 514 for (i = 0; i < lmb.memory.cnt; ++i) {
472 start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT; 515 start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
473 end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i); 516 end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
474 add_active_range(0, start_pfn, end_pfn); 517
518 fake_numa_create_new_node(end_pfn, &nid);
519 add_active_range(nid, start_pfn, end_pfn);
520 node_set_online(nid);
475 } 521 }
476 node_set_online(0);
477} 522}
478 523
479void __init dump_numa_cpu_topology(void) 524void __init dump_numa_cpu_topology(void)
@@ -702,6 +747,10 @@ static int __init early_numa(char *p)
702 if (strstr(p, "debug")) 747 if (strstr(p, "debug"))
703 numa_debug = 1; 748 numa_debug = 1;
704 749
750 p = strstr(p, "fake=");
751 if (p)
752 cmdline = p + strlen("fake=");
753
705 return 0; 754 return 0;
706} 755}
707early_param("numa", early_numa); 756early_param("numa", early_numa);
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index 27922dff8b94..3cf0802cd2b6 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -256,6 +256,7 @@ void slb_initialize(void)
256 static int slb_encoding_inited; 256 static int slb_encoding_inited;
257 extern unsigned int *slb_miss_kernel_load_linear; 257 extern unsigned int *slb_miss_kernel_load_linear;
258 extern unsigned int *slb_miss_kernel_load_io; 258 extern unsigned int *slb_miss_kernel_load_io;
259 extern unsigned int *slb_compare_rr_to_size;
259 260
260 /* Prepare our SLB miss handler based on our page size */ 261 /* Prepare our SLB miss handler based on our page size */
261 linear_llp = mmu_psize_defs[mmu_linear_psize].sllp; 262 linear_llp = mmu_psize_defs[mmu_linear_psize].sllp;
@@ -269,6 +270,8 @@ void slb_initialize(void)
269 SLB_VSID_KERNEL | linear_llp); 270 SLB_VSID_KERNEL | linear_llp);
270 patch_slb_encoding(slb_miss_kernel_load_io, 271 patch_slb_encoding(slb_miss_kernel_load_io,
271 SLB_VSID_KERNEL | io_llp); 272 SLB_VSID_KERNEL | io_llp);
273 patch_slb_encoding(slb_compare_rr_to_size,
274 mmu_slb_size);
272 275
273 DBG("SLB: linear LLP = %04x\n", linear_llp); 276 DBG("SLB: linear LLP = %04x\n", linear_llp);
274 DBG("SLB: io LLP = %04x\n", io_llp); 277 DBG("SLB: io LLP = %04x\n", io_llp);
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index 1328a81a84aa..657f6b37e9df 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -227,8 +227,9 @@ END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
227 227
2287: ld r10,PACASTABRR(r13) 2287: ld r10,PACASTABRR(r13)
229 addi r10,r10,1 229 addi r10,r10,1
230 /* use a cpu feature mask if we ever change our slb size */ 230 /* This gets soft patched on boot. */
231 cmpldi r10,SLB_NUM_ENTRIES 231_GLOBAL(slb_compare_rr_to_size)
232 cmpldi r10,0
232 233
233 blt+ 4f 234 blt+ 4f
234 li r10,SLB_NUM_BOLTED 235 li r10,SLB_NUM_BOLTED
diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c
index bb6bff51ce48..13929771bee7 100644
--- a/arch/powerpc/oprofile/op_model_cell.c
+++ b/arch/powerpc/oprofile/op_model_cell.c
@@ -61,7 +61,7 @@ static unsigned int spu_cycle_reset;
61#define NUM_THREADS 2 /* number of physical threads in 61#define NUM_THREADS 2 /* number of physical threads in
62 * physical processor 62 * physical processor
63 */ 63 */
64#define NUM_TRACE_BUS_WORDS 4 64#define NUM_DEBUG_BUS_WORDS 4
65#define NUM_INPUT_BUS_WORDS 2 65#define NUM_INPUT_BUS_WORDS 2
66 66
67#define MAX_SPU_COUNT 0xFFFFFF /* maximum 24 bit LFSR value */ 67#define MAX_SPU_COUNT 0xFFFFFF /* maximum 24 bit LFSR value */
@@ -169,7 +169,6 @@ static DEFINE_SPINLOCK(virt_cntr_lock);
169 169
170static u32 ctr_enabled; 170static u32 ctr_enabled;
171 171
172static unsigned char trace_bus[NUM_TRACE_BUS_WORDS];
173static unsigned char input_bus[NUM_INPUT_BUS_WORDS]; 172static unsigned char input_bus[NUM_INPUT_BUS_WORDS];
174 173
175/* 174/*
@@ -298,7 +297,7 @@ static void set_pm_event(u32 ctr, int event, u32 unit_mask)
298 297
299 p->signal_group = event / 100; 298 p->signal_group = event / 100;
300 p->bus_word = bus_word; 299 p->bus_word = bus_word;
301 p->sub_unit = (unit_mask & 0x0000f000) >> 12; 300 p->sub_unit = GET_SUB_UNIT(unit_mask);
302 301
303 pm_regs.pm07_cntrl[ctr] = 0; 302 pm_regs.pm07_cntrl[ctr] = 0;
304 pm_regs.pm07_cntrl[ctr] |= PM07_CTR_COUNT_CYCLES(count_cycles); 303 pm_regs.pm07_cntrl[ctr] |= PM07_CTR_COUNT_CYCLES(count_cycles);
@@ -334,16 +333,16 @@ static void set_pm_event(u32 ctr, int event, u32 unit_mask)
334 p->bit = signal_bit; 333 p->bit = signal_bit;
335 } 334 }
336 335
337 for (i = 0; i < NUM_TRACE_BUS_WORDS; i++) { 336 for (i = 0; i < NUM_DEBUG_BUS_WORDS; i++) {
338 if (bus_word & (1 << i)) { 337 if (bus_word & (1 << i)) {
339 pm_regs.debug_bus_control |= 338 pm_regs.debug_bus_control |=
340 (bus_type << (31 - (2 * i) + 1)); 339 (bus_type << (30 - (2 * i)));
341 340
342 for (j = 0; j < NUM_INPUT_BUS_WORDS; j++) { 341 for (j = 0; j < NUM_INPUT_BUS_WORDS; j++) {
343 if (input_bus[j] == 0xff) { 342 if (input_bus[j] == 0xff) {
344 input_bus[j] = i; 343 input_bus[j] = i;
345 pm_regs.group_control |= 344 pm_regs.group_control |=
346 (i << (31 - i)); 345 (i << (30 - (2 * j)));
347 346
348 break; 347 break;
349 } 348 }
@@ -450,6 +449,12 @@ static void cell_virtual_cntr(unsigned long data)
450 hdw_thread = 1 ^ hdw_thread; 449 hdw_thread = 1 ^ hdw_thread;
451 next_hdw_thread = hdw_thread; 450 next_hdw_thread = hdw_thread;
452 451
452 pm_regs.group_control = 0;
453 pm_regs.debug_bus_control = 0;
454
455 for (i = 0; i < NUM_INPUT_BUS_WORDS; i++)
456 input_bus[i] = 0xff;
457
453 /* 458 /*
454 * There are some per thread events. Must do the 459 * There are some per thread events. Must do the
455 * set event, for the thread that is being started 460 * set event, for the thread that is being started
@@ -619,9 +624,6 @@ static int cell_reg_setup(struct op_counter_config *ctr,
619 pmc_cntrl[1][i].vcntr = i; 624 pmc_cntrl[1][i].vcntr = i;
620 } 625 }
621 626
622 for (i = 0; i < NUM_TRACE_BUS_WORDS; i++)
623 trace_bus[i] = 0xff;
624
625 for (i = 0; i < NUM_INPUT_BUS_WORDS; i++) 627 for (i = 0; i < NUM_INPUT_BUS_WORDS; i++)
626 input_bus[i] = 0xff; 628 input_bus[i] = 0xff;
627 629
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pci.c b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
index 4c6c82a684b1..262eda8659d0 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pci.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pci.c
@@ -363,7 +363,7 @@ mpc52xx_add_bridge(struct device_node *node)
363 363
364 pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name); 364 pr_debug("Adding MPC52xx PCI host bridge %s\n", node->full_name);
365 365
366 pci_assign_all_buses = 1; 366 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
367 367
368 if (of_address_to_resource(node, 0, &rsrc) != 0) { 368 if (of_address_to_resource(node, 0, &rsrc) != 0) {
369 printk(KERN_ERR "Can't get %s resources\n", node->full_name); 369 printk(KERN_ERR "Can't get %s resources\n", node->full_name);
diff --git a/arch/powerpc/platforms/82xx/pq2.c b/arch/powerpc/platforms/82xx/pq2.c
index a497cbaa1ac5..1b75902fad64 100644
--- a/arch/powerpc/platforms/82xx/pq2.c
+++ b/arch/powerpc/platforms/82xx/pq2.c
@@ -53,13 +53,13 @@ static void __init pq2_pci_add_bridge(struct device_node *np)
53 if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b) 53 if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b)
54 goto err; 54 goto err;
55 55
56 pci_assign_all_buses = 1; 56 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
57 57
58 hose = pcibios_alloc_controller(np); 58 hose = pcibios_alloc_controller(np);
59 if (!hose) 59 if (!hose)
60 return; 60 return;
61 61
62 hose->arch_data = np; 62 hose->dn = np;
63 63
64 setup_indirect_pci(hose, r.start + 0x100, r.start + 0x104, 0); 64 setup_indirect_pci(hose, r.start + 0x100, r.start + 0x104, 0);
65 pci_process_bridge_OF_ranges(hose, np, 1); 65 pci_process_bridge_OF_ranges(hose, np, 1);
diff --git a/arch/powerpc/platforms/82xx/pq2fads.c b/arch/powerpc/platforms/82xx/pq2fads.c
index 4f457a9c79ae..1be500501806 100644
--- a/arch/powerpc/platforms/82xx/pq2fads.c
+++ b/arch/powerpc/platforms/82xx/pq2fads.c
@@ -15,12 +15,12 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/interrupt.h> 16#include <linux/interrupt.h>
17#include <linux/fsl_devices.h> 17#include <linux/fsl_devices.h>
18#include <linux/of_platform.h>
18 19
19#include <asm/io.h> 20#include <asm/io.h>
20#include <asm/cpm2.h> 21#include <asm/cpm2.h>
21#include <asm/udbg.h> 22#include <asm/udbg.h>
22#include <asm/machdep.h> 23#include <asm/machdep.h>
23#include <asm/of_platform.h>
24#include <asm/time.h> 24#include <asm/time.h>
25 25
26#include <sysdev/fsl_soc.h> 26#include <sysdev/fsl_soc.h>
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index ec305f18abd8..2430ac840493 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -50,6 +50,11 @@ config MPC836x_MDS
50 help 50 help
51 This option enables support for the MPC836x MDS Processor Board. 51 This option enables support for the MPC836x MDS Processor Board.
52 52
53config MPC837x_MDS
54 bool "Freescale MPC837x MDS"
55 select DEFAULT_UIMAGE
56 help
57 This option enables support for the MPC837x MDS Processor Board.
53endchoice 58endchoice
54 59
55config PPC_MPC831x 60config PPC_MPC831x
@@ -75,3 +80,9 @@ config PPC_MPC836x
75 select PPC_UDBG_16550 80 select PPC_UDBG_16550
76 select PPC_INDIRECT_PCI 81 select PPC_INDIRECT_PCI
77 default y if MPC836x_MDS 82 default y if MPC836x_MDS
83
84config PPC_MPC837x
85 bool
86 select PPC_UDBG_16550
87 select PPC_INDIRECT_PCI
88 default y if MPC837x_MDS
diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile
index 5a98f885779f..df4662999a95 100644
--- a/arch/powerpc/platforms/83xx/Makefile
+++ b/arch/powerpc/platforms/83xx/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o
9obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o 9obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o
10obj-$(CONFIG_MPC836x_MDS) += mpc836x_mds.o 10obj-$(CONFIG_MPC836x_MDS) += mpc836x_mds.o
11obj-$(CONFIG_MPC832x_MDS) += mpc832x_mds.o 11obj-$(CONFIG_MPC832x_MDS) += mpc832x_mds.o
12obj-$(CONFIG_MPC837x_MDS) += mpc837x_mds.o
diff --git a/arch/powerpc/platforms/83xx/mpc8313_rdb.c b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
index 33766b8f2594..6fb82993967c 100644
--- a/arch/powerpc/platforms/83xx/mpc8313_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
@@ -70,9 +70,9 @@ void __init mpc8313_rdb_init_IRQ(void)
70 */ 70 */
71static int __init mpc8313_rdb_probe(void) 71static int __init mpc8313_rdb_probe(void)
72{ 72{
73 unsigned long root = of_get_flat_dt_root(); 73 unsigned long root = of_get_flat_dt_root();
74 74
75 return of_flat_dt_is_compatible(root, "MPC8313ERDB"); 75 return of_flat_dt_is_compatible(root, "MPC8313ERDB");
76} 76}
77 77
78define_machine(mpc8313_rdb) { 78define_machine(mpc8313_rdb) {
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index 39ee7a13b25a..1e570bb947fc 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -23,9 +23,9 @@
23#include <linux/seq_file.h> 23#include <linux/seq_file.h>
24#include <linux/root_dev.h> 24#include <linux/root_dev.h>
25#include <linux/initrd.h> 25#include <linux/initrd.h>
26#include <linux/of_platform.h>
27#include <linux/of_device.h>
26 28
27#include <asm/of_device.h>
28#include <asm/of_platform.h>
29#include <asm/system.h> 29#include <asm/system.h>
30#include <asm/atomic.h> 30#include <asm/atomic.h>
31#include <asm/time.h> 31#include <asm/time.h>
diff --git a/arch/powerpc/platforms/83xx/mpc832x_rdb.c b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
index d4bd04001b99..ffb2e9361ce3 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_rdb.c
@@ -19,8 +19,8 @@
19#include <linux/spi/spi.h> 19#include <linux/spi/spi.h>
20#include <linux/spi/mmc_spi.h> 20#include <linux/spi/mmc_spi.h>
21#include <linux/mmc/host.h> 21#include <linux/mmc/host.h>
22#include <linux/of_platform.h>
22 23
23#include <asm/of_platform.h>
24#include <asm/time.h> 24#include <asm/time.h>
25#include <asm/ipic.h> 25#include <asm/ipic.h>
26#include <asm/udbg.h> 26#include <asm/udbg.h>
diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c
index a81bb3ce6b94..459fb7227e76 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c
@@ -23,6 +23,7 @@
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/seq_file.h> 24#include <linux/seq_file.h>
25#include <linux/root_dev.h> 25#include <linux/root_dev.h>
26#include <linux/of_platform.h>
26 27
27#include <asm/system.h> 28#include <asm/system.h>
28#include <asm/atomic.h> 29#include <asm/atomic.h>
@@ -106,14 +107,30 @@ static void __init mpc834x_mds_init_IRQ(void)
106 ipic_set_default_priority(); 107 ipic_set_default_priority();
107} 108}
108 109
110static struct of_device_id mpc834x_ids[] = {
111 { .type = "soc", },
112 { .compatible = "soc", },
113 {},
114};
115
116static int __init mpc834x_declare_of_platform_devices(void)
117{
118 if (!machine_is(mpc834x_mds))
119 return 0;
120
121 of_platform_bus_probe(NULL, mpc834x_ids, NULL);
122 return 0;
123}
124device_initcall(mpc834x_declare_of_platform_devices);
125
109/* 126/*
110 * Called very early, MMU is off, device-tree isn't unflattened 127 * Called very early, MMU is off, device-tree isn't unflattened
111 */ 128 */
112static int __init mpc834x_mds_probe(void) 129static int __init mpc834x_mds_probe(void)
113{ 130{
114 unsigned long root = of_get_flat_dt_root(); 131 unsigned long root = of_get_flat_dt_root();
115 132
116 return of_flat_dt_is_compatible(root, "MPC834xMDS"); 133 return of_flat_dt_is_compatible(root, "MPC834xMDS");
117} 134}
118 135
119define_machine(mpc834x_mds) { 136define_machine(mpc834x_mds) {
diff --git a/arch/powerpc/platforms/83xx/mpc836x_mds.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index e40012f8f488..2ac9890b763c 100644
--- a/arch/powerpc/platforms/83xx/mpc836x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -29,9 +29,9 @@
29#include <linux/seq_file.h> 29#include <linux/seq_file.h>
30#include <linux/root_dev.h> 30#include <linux/root_dev.h>
31#include <linux/initrd.h> 31#include <linux/initrd.h>
32#include <linux/of_platform.h>
33#include <linux/of_device.h>
32 34
33#include <asm/of_device.h>
34#include <asm/of_platform.h>
35#include <asm/system.h> 35#include <asm/system.h>
36#include <asm/atomic.h> 36#include <asm/atomic.h>
37#include <asm/time.h> 37#include <asm/time.h>
diff --git a/arch/powerpc/platforms/83xx/mpc837x_mds.c b/arch/powerpc/platforms/83xx/mpc837x_mds.c
new file mode 100644
index 000000000000..166c1116b1ac
--- /dev/null
+++ b/arch/powerpc/platforms/83xx/mpc837x_mds.c
@@ -0,0 +1,104 @@
1/*
2 * arch/powerpc/platforms/83xx/mpc837x_mds.c
3 *
4 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
5 *
6 * MPC837x MDS board specific routines
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#include <linux/pci.h>
15#include <linux/of.h>
16#include <linux/of_platform.h>
17
18#include <asm/time.h>
19#include <asm/ipic.h>
20#include <asm/udbg.h>
21#include <asm/prom.h>
22
23#include "mpc83xx.h"
24
25#ifndef CONFIG_PCI
26unsigned long isa_io_base = 0;
27unsigned long isa_mem_base = 0;
28#endif
29
30/* ************************************************************************
31 *
32 * Setup the architecture
33 *
34 */
35static void __init mpc837x_mds_setup_arch(void)
36{
37#ifdef CONFIG_PCI
38 struct device_node *np;
39#endif
40
41 if (ppc_md.progress)
42 ppc_md.progress("mpc837x_mds_setup_arch()", 0);
43
44#ifdef CONFIG_PCI
45 for_each_compatible_node(np, "pci", "fsl,mpc8349-pci")
46 mpc83xx_add_bridge(np);
47#endif
48}
49
50static struct of_device_id mpc837x_ids[] = {
51 { .type = "soc", },
52 { .compatible = "soc", },
53 {},
54};
55
56static int __init mpc837x_declare_of_platform_devices(void)
57{
58 if (!machine_is(mpc837x_mds))
59 return 0;
60
61 /* Publish of_device */
62 of_platform_bus_probe(NULL, mpc837x_ids, NULL);
63
64 return 0;
65}
66device_initcall(mpc837x_declare_of_platform_devices);
67
68static void __init mpc837x_mds_init_IRQ(void)
69{
70 struct device_node *np;
71
72 np = of_find_compatible_node(NULL, NULL, "fsl,ipic");
73 if (!np)
74 return;
75
76 ipic_init(np, 0);
77
78 /* Initialize the default interrupt mapping priorities,
79 * in case the boot rom changed something on us.
80 */
81 ipic_set_default_priority();
82}
83
84/*
85 * Called very early, MMU is off, device-tree isn't unflattened
86 */
87static int __init mpc837x_mds_probe(void)
88{
89 unsigned long root = of_get_flat_dt_root();
90
91 return of_flat_dt_is_compatible(root, "fsl,mpc837xmds");
92}
93
94define_machine(mpc837x_mds) {
95 .name = "MPC837x MDS",
96 .probe = mpc837x_mds_probe,
97 .setup_arch = mpc837x_mds_setup_arch,
98 .init_IRQ = mpc837x_mds_init_IRQ,
99 .get_irq = ipic_get_irq,
100 .restart = mpc83xx_restart,
101 .time_init = mpc83xx_time_init,
102 .calibrate_decr = generic_calibrate_decr,
103 .progress = udbg_progress,
104};
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c
index 80425d7b14f8..14f1080c6c9d 100644
--- a/arch/powerpc/platforms/83xx/pci.c
+++ b/arch/powerpc/platforms/83xx/pci.c
@@ -54,7 +54,7 @@ int __init mpc83xx_add_bridge(struct device_node *dev)
54 " bus 0\n", dev->full_name); 54 " bus 0\n", dev->full_name);
55 } 55 }
56 56
57 pci_assign_all_buses = 1; 57 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
58 hose = pcibios_alloc_controller(dev); 58 hose = pcibios_alloc_controller(dev);
59 if (!hose) 59 if (!hose)
60 return -ENOMEM; 60 return -ENOMEM;
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index 59c121a97ac7..bdb3d0b38cd2 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -123,7 +123,7 @@ static int mpc85xx_exclude_device(struct pci_controller *hose,
123 struct device_node* node; 123 struct device_node* node;
124 struct resource rsrc; 124 struct resource rsrc;
125 125
126 node = (struct device_node *)hose->arch_data; 126 node = hose->dn;
127 of_address_to_resource(node, 0, &rsrc); 127 of_address_to_resource(node, 0, &rsrc);
128 128
129 if ((rsrc.start & 0xfffff) == primary_phb_addr) { 129 if ((rsrc.start & 0xfffff) == primary_phb_addr) {
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 61b3eedf41b9..e6c63a5b1efb 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -30,9 +30,9 @@
30#include <linux/initrd.h> 30#include <linux/initrd.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <linux/fsl_devices.h> 32#include <linux/fsl_devices.h>
33#include <linux/of_platform.h>
34#include <linux/of_device.h>
33 35
34#include <asm/of_device.h>
35#include <asm/of_platform.h>
36#include <asm/system.h> 36#include <asm/system.h>
37#include <asm/atomic.h> 37#include <asm/atomic.h>
38#include <asm/time.h> 38#include <asm/time.h>
diff --git a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
index 6390895e5e92..c6d2f48f8f3d 100644
--- a/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
+++ b/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
@@ -124,7 +124,7 @@ static void __devinit quirk_uli5229(struct pci_dev *dev)
124static void __devinit final_uli5288(struct pci_dev *dev) 124static void __devinit final_uli5288(struct pci_dev *dev)
125{ 125{
126 struct pci_controller *hose = pci_bus_to_host(dev->bus); 126 struct pci_controller *hose = pci_bus_to_host(dev->bus);
127 struct device_node *hosenode = hose ? hose->arch_data : NULL; 127 struct device_node *hosenode = hose ? hose->dn : NULL;
128 struct of_irq oirq; 128 struct of_irq oirq;
129 int virq, pin = 2; 129 int virq, pin = 2;
130 u32 laddr[3]; 130 u32 laddr[3];
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 32a531aebcb7..14f4e527e7ac 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -116,7 +116,7 @@ static int mpc86xx_exclude_device(struct pci_controller *hose,
116 struct device_node* node; 116 struct device_node* node;
117 struct resource rsrc; 117 struct resource rsrc;
118 118
119 node = (struct device_node *)hose->arch_data; 119 node = hose->dn;
120 of_address_to_resource(node, 0, &rsrc); 120 of_address_to_resource(node, 0, &rsrc);
121 121
122 if ((rsrc.start & 0xfffff) == 0x8000) { 122 if ((rsrc.start & 0xfffff) == 0x8000) {
diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig
index bd28655043a0..91fbe4241918 100644
--- a/arch/powerpc/platforms/8xx/Kconfig
+++ b/arch/powerpc/platforms/8xx/Kconfig
@@ -18,6 +18,7 @@ config MPC8XXFADS
18config MPC86XADS 18config MPC86XADS
19 bool "MPC86XADS" 19 bool "MPC86XADS"
20 select CPM1 20 select CPM1
21 select PPC_CPM_NEW_BINDING
21 help 22 help
22 MPC86x Application Development System by Freescale Semiconductor. 23 MPC86x Application Development System by Freescale Semiconductor.
23 The MPC86xADS is meant to serve as a platform for s/w and h/w 24 The MPC86xADS is meant to serve as a platform for s/w and h/w
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index d35eda80e9e6..ba645c2b63f6 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -120,7 +120,7 @@ void __init mpc8xx_calibrate_decr(void)
120 ppc_tb_freq /= 16; 120 ppc_tb_freq /= 16;
121 ppc_proc_freq = 50000000; 121 ppc_proc_freq = 50000000;
122 if (!get_freq("clock-frequency", &ppc_proc_freq)) 122 if (!get_freq("clock-frequency", &ppc_proc_freq))
123 printk(KERN_ERR "WARNING: Estimating processor frequency" 123 printk(KERN_ERR "WARNING: Estimating processor frequency "
124 "(not found)\n"); 124 "(not found)\n");
125 125
126 printk("Decrementer Frequency = 0x%lx\n", ppc_tb_freq); 126 printk("Decrementer Frequency = 0x%lx\n", ppc_tb_freq);
diff --git a/arch/powerpc/platforms/8xx/mpc86xads.h b/arch/powerpc/platforms/8xx/mpc86xads.h
index cffa194ccf1f..17b1fe75e0b2 100644
--- a/arch/powerpc/platforms/8xx/mpc86xads.h
+++ b/arch/powerpc/platforms/8xx/mpc86xads.h
@@ -15,27 +15,6 @@
15#ifndef __ASM_MPC86XADS_H__ 15#ifndef __ASM_MPC86XADS_H__
16#define __ASM_MPC86XADS_H__ 16#define __ASM_MPC86XADS_H__
17 17
18#include <sysdev/fsl_soc.h>
19
20/* U-Boot maps BCSR to 0xff080000 */
21#define BCSR_ADDR ((uint)0xff080000)
22#define BCSR_SIZE ((uint)32)
23#define BCSR0 ((uint)(BCSR_ADDR + 0x00))
24#define BCSR1 ((uint)(BCSR_ADDR + 0x04))
25#define BCSR2 ((uint)(BCSR_ADDR + 0x08))
26#define BCSR3 ((uint)(BCSR_ADDR + 0x0c))
27#define BCSR4 ((uint)(BCSR_ADDR + 0x10))
28
29#define CFG_PHYDEV_ADDR ((uint)0xff0a0000)
30#define BCSR5 ((uint)(CFG_PHYDEV_ADDR + 0x300))
31
32#define MPC8xx_CPM_OFFSET (0x9c0)
33#define CPM_MAP_ADDR (get_immrbase() + MPC8xx_CPM_OFFSET)
34#define CPM_IRQ_OFFSET 16 // for compability with cpm_uart driver
35
36#define PCMCIA_MEM_ADDR ((uint)0xff020000)
37#define PCMCIA_MEM_SIZE ((uint)(64 * 1024))
38
39/* Bits of interest in the BCSRs. 18/* Bits of interest in the BCSRs.
40 */ 19 */
41#define BCSR1_ETHEN ((uint)0x20000000) 20#define BCSR1_ETHEN ((uint)0x20000000)
@@ -64,28 +43,5 @@
64#define BCSR5_MII1_EN 0x02 43#define BCSR5_MII1_EN 0x02
65#define BCSR5_MII1_RST 0x01 44#define BCSR5_MII1_RST 0x01
66 45
67/* Interrupt level assignments */
68#define PHY_INTERRUPT SIU_IRQ7 /* PHY link change interrupt */
69#define SIU_INT_FEC1 SIU_LEVEL1 /* FEC1 interrupt */
70#define FEC_INTERRUPT SIU_INT_FEC1 /* FEC interrupt */
71
72/* We don't use the 8259 */
73#define NR_8259_INTS 0
74
75/* CPM Ethernet through SCC1 */
76#define PA_ENET_RXD ((ushort)0x0001)
77#define PA_ENET_TXD ((ushort)0x0002)
78#define PA_ENET_TCLK ((ushort)0x0100)
79#define PA_ENET_RCLK ((ushort)0x0200)
80#define PB_ENET_TENA ((uint)0x00001000)
81#define PC_ENET_CLSN ((ushort)0x0010)
82#define PC_ENET_RENA ((ushort)0x0020)
83
84/* Control bits in the SICR to route TCLK (CLK1) and RCLK (CLK2) to
85 * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero.
86 */
87#define SICR_ENET_MASK ((uint)0x000000ff)
88#define SICR_ENET_CLKRT ((uint)0x0000002c)
89
90#endif /* __ASM_MPC86XADS_H__ */ 46#endif /* __ASM_MPC86XADS_H__ */
91#endif /* __KERNEL__ */ 47#endif /* __KERNEL__ */
diff --git a/arch/powerpc/platforms/8xx/mpc86xads_setup.c b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
index 49012835f453..d2927a434aef 100644
--- a/arch/powerpc/platforms/8xx/mpc86xads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc86xads_setup.c
@@ -6,264 +6,134 @@
6 * 6 *
7 * Copyright 2005 MontaVista Software Inc. 7 * Copyright 2005 MontaVista Software Inc.
8 * 8 *
9 * Heavily modified by Scott Wood <scottwood@freescale.com>
10 * Copyright 2007 Freescale Semiconductor, Inc.
11 *
9 * This file is licensed under the terms of the GNU General Public License 12 * This file is licensed under the terms of the GNU General Public License
10 * version 2. This program is licensed "as is" without any warranty of any 13 * version 2. This program is licensed "as is" without any warranty of any
11 * kind, whether express or implied. 14 * kind, whether express or implied.
12 */ 15 */
13 16
14#include <linux/init.h> 17#include <linux/init.h>
15#include <linux/module.h> 18#include <linux/of_platform.h>
16#include <linux/param.h>
17#include <linux/string.h>
18#include <linux/ioport.h>
19#include <linux/device.h>
20#include <linux/delay.h>
21#include <linux/root_dev.h>
22
23#include <linux/fs_enet_pd.h>
24#include <linux/fs_uart_pd.h>
25#include <linux/mii.h>
26 19
27#include <asm/delay.h>
28#include <asm/io.h> 20#include <asm/io.h>
29#include <asm/machdep.h> 21#include <asm/machdep.h>
30#include <asm/page.h>
31#include <asm/processor.h>
32#include <asm/system.h> 22#include <asm/system.h>
33#include <asm/time.h> 23#include <asm/time.h>
34#include <asm/mpc8xx.h> 24#include <asm/mpc8xx.h>
35#include <asm/8xx_immap.h> 25#include <asm/8xx_immap.h>
36#include <asm/commproc.h> 26#include <asm/commproc.h>
37#include <asm/fs_pd.h> 27#include <asm/fs_pd.h>
38#include <asm/prom.h> 28#include <asm/udbg.h>
39 29
40#include <sysdev/commproc.h> 30#include <sysdev/commproc.h>
41 31
42static void init_smc1_uart_ioports(struct fs_uart_platform_info* fpi); 32#include "mpc86xads.h"
43static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi);
44static void init_scc1_ioports(struct fs_platform_info* ptr);
45
46void __init mpc86xads_board_setup(void)
47{
48 cpm8xx_t *cp;
49 unsigned int *bcsr_io;
50 u8 tmpval8;
51
52 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
53 cp = (cpm8xx_t *)immr_map(im_cpm);
54
55 if (bcsr_io == NULL) {
56 printk(KERN_CRIT "Could not remap BCSR\n");
57 return;
58 }
59#ifdef CONFIG_SERIAL_CPM_SMC1
60 clrbits32(bcsr_io, BCSR1_RS232EN_1);
61 clrbits32(&cp->cp_simode, 0xe0000000 >> 17); /* brg1 */
62 tmpval8 = in_8(&(cp->cp_smc[0].smc_smcm)) | (SMCM_RX | SMCM_TX);
63 out_8(&(cp->cp_smc[0].smc_smcm), tmpval8);
64 clrbits16(&cp->cp_smc[0].smc_smcmr, SMCMR_REN | SMCMR_TEN);
65#else
66 setbits32(bcsr_io,BCSR1_RS232EN_1);
67 out_be16(&cp->cp_smc[0].smc_smcmr, 0);
68 out_8(&cp->cp_smc[0].smc_smce, 0);
69#endif
70
71#ifdef CONFIG_SERIAL_CPM_SMC2
72 clrbits32(bcsr_io,BCSR1_RS232EN_2);
73 clrbits32(&cp->cp_simode, 0xe0000000 >> 1);
74 setbits32(&cp->cp_simode, 0x20000000 >> 1); /* brg2 */
75 tmpval8 = in_8(&(cp->cp_smc[1].smc_smcm)) | (SMCM_RX | SMCM_TX);
76 out_8(&(cp->cp_smc[1].smc_smcm), tmpval8);
77 clrbits16(&cp->cp_smc[1].smc_smcmr, SMCMR_REN | SMCMR_TEN);
78 33
79 init_smc2_uart_ioports(0); 34struct cpm_pin {
80#else 35 int port, pin, flags;
81 setbits32(bcsr_io,BCSR1_RS232EN_2); 36};
82 out_be16(&cp->cp_smc[1].smc_smcmr, 0);
83 out_8(&cp->cp_smc[1].smc_smce, 0);
84#endif
85 immr_unmap(cp);
86 iounmap(bcsr_io);
87}
88 37
38static struct cpm_pin mpc866ads_pins[] = {
39 /* SMC1 */
40 {CPM_PORTB, 24, CPM_PIN_INPUT}, /* RX */
41 {CPM_PORTB, 25, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */
42
43 /* SMC2 */
44 {CPM_PORTB, 21, CPM_PIN_INPUT}, /* RX */
45 {CPM_PORTB, 20, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TX */
46
47 /* SCC1 */
48 {CPM_PORTA, 6, CPM_PIN_INPUT}, /* CLK1 */
49 {CPM_PORTA, 7, CPM_PIN_INPUT}, /* CLK2 */
50 {CPM_PORTA, 14, CPM_PIN_INPUT}, /* TX */
51 {CPM_PORTA, 15, CPM_PIN_INPUT}, /* RX */
52 {CPM_PORTB, 19, CPM_PIN_INPUT | CPM_PIN_SECONDARY}, /* TENA */
53 {CPM_PORTC, 10, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, /* RENA */
54 {CPM_PORTC, 11, CPM_PIN_INPUT | CPM_PIN_SECONDARY | CPM_PIN_GPIO}, /* CLSN */
55
56 /* MII */
57 {CPM_PORTD, 3, CPM_PIN_OUTPUT},
58 {CPM_PORTD, 4, CPM_PIN_OUTPUT},
59 {CPM_PORTD, 5, CPM_PIN_OUTPUT},
60 {CPM_PORTD, 6, CPM_PIN_OUTPUT},
61 {CPM_PORTD, 7, CPM_PIN_OUTPUT},
62 {CPM_PORTD, 8, CPM_PIN_OUTPUT},
63 {CPM_PORTD, 9, CPM_PIN_OUTPUT},
64 {CPM_PORTD, 10, CPM_PIN_OUTPUT},
65 {CPM_PORTD, 11, CPM_PIN_OUTPUT},
66 {CPM_PORTD, 12, CPM_PIN_OUTPUT},
67 {CPM_PORTD, 13, CPM_PIN_OUTPUT},
68 {CPM_PORTD, 14, CPM_PIN_OUTPUT},
69 {CPM_PORTD, 15, CPM_PIN_OUTPUT},
70};
89 71
90static void init_fec1_ioports(struct fs_platform_info* ptr) 72static void __init init_ioports(void)
91{ 73{
92 iop8xx_t *io_port = (iop8xx_t *)immr_map(im_ioport); 74 int i;
93 75
94 /* configure FEC1 pins */ 76 for (i = 0; i < ARRAY_SIZE(mpc866ads_pins); i++) {
77 struct cpm_pin *pin = &mpc866ads_pins[i];
78 cpm1_set_pin(pin->port, pin->pin, pin->flags);
79 }
95 80
96 setbits16(&io_port->iop_pdpar, 0x1fff); 81 cpm1_clk_setup(CPM_CLK_SMC1, CPM_BRG1, CPM_CLK_RTX);
97 setbits16(&io_port->iop_pddir, 0x1fff); 82 cpm1_clk_setup(CPM_CLK_SMC2, CPM_BRG2, CPM_CLK_RTX);
83 cpm1_clk_setup(CPM_CLK_SCC1, CPM_CLK1, CPM_CLK_TX);
84 cpm1_clk_setup(CPM_CLK_SCC1, CPM_CLK2, CPM_CLK_RX);
98 85
99 immr_unmap(io_port); 86 /* Set FEC1 and FEC2 to MII mode */
87 clrbits32(&mpc8xx_immr->im_cpm.cp_cptr, 0x00000180);
100} 88}
101 89
102void init_fec_ioports(struct fs_platform_info *fpi) 90static void __init mpc86xads_setup_arch(void)
103{ 91{
104 int fec_no = fs_get_fec_index(fpi->fs_no); 92 struct device_node *np;
93 u32 __iomem *bcsr_io;
94
95 cpm_reset();
96 init_ioports();
105 97
106 switch (fec_no) { 98 np = of_find_compatible_node(NULL, NULL, "fsl,mpc866ads-bcsr");
107 case 0: 99 if (!np) {
108 init_fec1_ioports(fpi); 100 printk(KERN_CRIT "Could not find fsl,mpc866ads-bcsr node\n");
109 break;
110 default:
111 printk(KERN_ERR "init_fec_ioports: invalid FEC number\n");
112 return; 101 return;
113 } 102 }
114}
115 103
116static void init_scc1_ioports(struct fs_platform_info* fpi) 104 bcsr_io = of_iomap(np, 0);
117{ 105 of_node_put(np);
118 unsigned *bcsr_io;
119 iop8xx_t *io_port;
120 cpm8xx_t *cp;
121
122 bcsr_io = ioremap(BCSR_ADDR, BCSR_SIZE);
123 io_port = (iop8xx_t *)immr_map(im_ioport);
124 cp = (cpm8xx_t *)immr_map(im_cpm);
125 106
126 if (bcsr_io == NULL) { 107 if (bcsr_io == NULL) {
127 printk(KERN_CRIT "Could not remap BCSR\n"); 108 printk(KERN_CRIT "Could not remap BCSR\n");
128 return; 109 return;
129 } 110 }
130 111
131 /* Configure port A pins for Txd and Rxd. 112 clrbits32(bcsr_io, BCSR1_RS232EN_1 | BCSR1_RS232EN_2 | BCSR1_ETHEN);
132 */
133 setbits16(&io_port->iop_papar, PA_ENET_RXD | PA_ENET_TXD);
134 clrbits16(&io_port->iop_padir, PA_ENET_RXD | PA_ENET_TXD);
135 clrbits16(&io_port->iop_paodr, PA_ENET_TXD);
136
137 /* Configure port C pins to enable CLSN and RENA.
138 */
139 clrbits16(&io_port->iop_pcpar, PC_ENET_CLSN | PC_ENET_RENA);
140 clrbits16(&io_port->iop_pcdir, PC_ENET_CLSN | PC_ENET_RENA);
141 setbits16(&io_port->iop_pcso, PC_ENET_CLSN | PC_ENET_RENA);
142
143 /* Configure port A for TCLK and RCLK.
144 */
145 setbits16(&io_port->iop_papar, PA_ENET_TCLK | PA_ENET_RCLK);
146 clrbits16(&io_port->iop_padir, PA_ENET_TCLK | PA_ENET_RCLK);
147 clrbits32(&cp->cp_pbpar, PB_ENET_TENA);
148 clrbits32(&cp->cp_pbdir, PB_ENET_TENA);
149
150 /* Configure Serial Interface clock routing.
151 * First, clear all SCC bits to zero, then set the ones we want.
152 */
153 clrbits32(&cp->cp_sicr, SICR_ENET_MASK);
154 setbits32(&cp->cp_sicr, SICR_ENET_CLKRT);
155
156 /* In the original SCC enet driver the following code is placed at
157 the end of the initialization */
158 setbits32(&cp->cp_pbpar, PB_ENET_TENA);
159 setbits32(&cp->cp_pbdir, PB_ENET_TENA);
160
161 clrbits32(bcsr_io+1, BCSR1_ETHEN);
162 iounmap(bcsr_io); 113 iounmap(bcsr_io);
163 immr_unmap(cp);
164 immr_unmap(io_port);
165}
166
167void init_scc_ioports(struct fs_platform_info *fpi)
168{
169 int scc_no = fs_get_scc_index(fpi->fs_no);
170
171 switch (scc_no) {
172 case 0:
173 init_scc1_ioports(fpi);
174 break;
175 default:
176 printk(KERN_ERR "init_scc_ioports: invalid SCC number\n");
177 return;
178 }
179} 114}
180 115
181 116static int __init mpc86xads_probe(void)
182
183static void init_smc1_uart_ioports(struct fs_uart_platform_info* ptr)
184{ 117{
185 unsigned *bcsr_io; 118 unsigned long root = of_get_flat_dt_root();
186 cpm8xx_t *cp = (cpm8xx_t *)immr_map(im_cpm); 119 return of_flat_dt_is_compatible(root, "fsl,mpc866ads");
187
188 setbits32(&cp->cp_pbpar, 0x000000c0);
189 clrbits32(&cp->cp_pbdir, 0x000000c0);
190 clrbits16(&cp->cp_pbodr, 0x00c0);
191 immr_unmap(cp);
192
193 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
194
195 if (bcsr_io == NULL) {
196 printk(KERN_CRIT "Could not remap BCSR1\n");
197 return;
198 }
199 clrbits32(bcsr_io,BCSR1_RS232EN_1);
200 iounmap(bcsr_io);
201} 120}
202 121
203static void init_smc2_uart_ioports(struct fs_uart_platform_info* fpi) 122static struct of_device_id __initdata of_bus_ids[] = {
204{ 123 { .name = "soc", },
205 unsigned *bcsr_io; 124 { .name = "cpm", },
206 cpm8xx_t *cp = (cpm8xx_t *)immr_map(im_cpm); 125 { .name = "localbus", },
207 126 {},
208 setbits32(&cp->cp_pbpar, 0x00000c00); 127};
209 clrbits32(&cp->cp_pbdir, 0x00000c00);
210 clrbits16(&cp->cp_pbodr, 0x0c00);
211 immr_unmap(cp);
212
213 bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
214
215 if (bcsr_io == NULL) {
216 printk(KERN_CRIT "Could not remap BCSR1\n");
217 return;
218 }
219 clrbits32(bcsr_io,BCSR1_RS232EN_2);
220 iounmap(bcsr_io);
221}
222 128
223void init_smc_ioports(struct fs_uart_platform_info *data) 129static int __init declare_of_platform_devices(void)
224{ 130{
225 int smc_no = fs_uart_id_fsid2smc(data->fs_no); 131 if (machine_is(mpc86x_ads))
132 of_platform_bus_probe(NULL, of_bus_ids, NULL);
226 133
227 switch (smc_no) {
228 case 0:
229 init_smc1_uart_ioports(data);
230 data->brg = data->clk_rx;
231 break;
232 case 1:
233 init_smc2_uart_ioports(data);
234 data->brg = data->clk_rx;
235 break;
236 default:
237 printk(KERN_ERR "init_scc_ioports: invalid SCC number\n");
238 return;
239 }
240}
241
242int platform_device_skip(const char *model, int id)
243{
244 return 0; 134 return 0;
245} 135}
246 136device_initcall(declare_of_platform_devices);
247static void __init mpc86xads_setup_arch(void)
248{
249 cpm_reset();
250
251 mpc86xads_board_setup();
252
253 ROOT_DEV = Root_NFS;
254}
255
256static int __init mpc86xads_probe(void)
257{
258 char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
259 "model", NULL);
260 if (model == NULL)
261 return 0;
262 if (strcmp(model, "MPC866ADS"))
263 return 0;
264
265 return 1;
266}
267 137
268define_machine(mpc86x_ads) { 138define_machine(mpc86x_ads) {
269 .name = "MPC86x ADS", 139 .name = "MPC86x ADS",
@@ -275,4 +145,5 @@ define_machine(mpc86x_ads) {
275 .calibrate_decr = mpc8xx_calibrate_decr, 145 .calibrate_decr = mpc8xx_calibrate_decr,
276 .set_rtc_time = mpc8xx_set_rtc_time, 146 .set_rtc_time = mpc8xx_set_rtc_time,
277 .get_rtc_time = mpc8xx_get_rtc_time, 147 .get_rtc_time = mpc8xx_get_rtc_time,
148 .progress = udbg_progress,
278}; 149};
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
index 61d12f183036..3cd565a04d0a 100644
--- a/arch/powerpc/platforms/cell/Makefile
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -19,7 +19,7 @@ spu-manage-$(CONFIG_PPC_CELLEB) += spu_manage.o
19spu-manage-$(CONFIG_PPC_CELL_NATIVE) += spu_manage.o 19spu-manage-$(CONFIG_PPC_CELL_NATIVE) += spu_manage.o
20 20
21obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \ 21obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \
22 spu_syscalls.o \ 22 spu_syscalls.o spu_fault.o \
23 $(spu-priv1-y) \ 23 $(spu-priv1-y) \
24 $(spu-manage-y) \ 24 $(spu-manage-y) \
25 spufs/ 25 spufs/
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c
index 13d5a87f13b1..ec7c8f45a215 100644
--- a/arch/powerpc/platforms/cell/cbe_cpufreq.c
+++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c
@@ -21,8 +21,9 @@
21 */ 21 */
22 22
23#include <linux/cpufreq.h> 23#include <linux/cpufreq.h>
24#include <linux/of_platform.h>
25
24#include <asm/machdep.h> 26#include <asm/machdep.h>
25#include <asm/of_platform.h>
26#include <asm/prom.h> 27#include <asm/prom.h>
27#include <asm/cell-regs.h> 28#include <asm/cell-regs.h>
28#include "cbe_cpufreq.h" 29#include "cbe_cpufreq.h"
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c b/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c
index 6a2c1b0a9a94..69288f653144 100644
--- a/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c
+++ b/arch/powerpc/platforms/cell/cbe_cpufreq_pmi.c
@@ -23,7 +23,8 @@
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/types.h> 24#include <linux/types.h>
25#include <linux/timer.h> 25#include <linux/timer.h>
26#include <asm/of_platform.h> 26#include <linux/of_platform.h>
27
27#include <asm/processor.h> 28#include <asm/processor.h>
28#include <asm/prom.h> 29#include <asm/prom.h>
29#include <asm/pmi.h> 30#include <asm/pmi.h>
diff --git a/arch/powerpc/platforms/cell/cbe_regs.c b/arch/powerpc/platforms/cell/cbe_regs.c
index 16a9b07e7b0c..dbc338f187a2 100644
--- a/arch/powerpc/platforms/cell/cbe_regs.c
+++ b/arch/powerpc/platforms/cell/cbe_regs.c
@@ -9,13 +9,13 @@
9#include <linux/percpu.h> 9#include <linux/percpu.h>
10#include <linux/types.h> 10#include <linux/types.h>
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/of_device.h>
13#include <linux/of_platform.h>
12 14
13#include <asm/io.h> 15#include <asm/io.h>
14#include <asm/pgtable.h> 16#include <asm/pgtable.h>
15#include <asm/prom.h> 17#include <asm/prom.h>
16#include <asm/ptrace.h> 18#include <asm/ptrace.h>
17#include <asm/of_device.h>
18#include <asm/of_platform.h>
19#include <asm/cell-regs.h> 19#include <asm/cell-regs.h>
20 20
21/* 21/*
@@ -256,6 +256,7 @@ void __init cbe_regs_init(void)
256 printk(KERN_ERR "cbe_regs: More BE chips than supported" 256 printk(KERN_ERR "cbe_regs: More BE chips than supported"
257 "!\n"); 257 "!\n");
258 cbe_regs_map_count--; 258 cbe_regs_map_count--;
259 of_node_put(cpu);
259 return; 260 return;
260 } 261 }
261 map->cpu_node = cpu; 262 map->cpu_node = cpu;
diff --git a/arch/powerpc/platforms/cell/io-workarounds.c b/arch/powerpc/platforms/cell/io-workarounds.c
index 9d7c2ef940a8..b86076e3c09e 100644
--- a/arch/powerpc/platforms/cell/io-workarounds.c
+++ b/arch/powerpc/platforms/cell/io-workarounds.c
@@ -238,7 +238,7 @@ static void __init spider_pci_setup_chip(struct spider_pci_bus *bus)
238static void __init spider_pci_add_one(struct pci_controller *phb) 238static void __init spider_pci_add_one(struct pci_controller *phb)
239{ 239{
240 struct spider_pci_bus *bus = &spider_pci_busses[spider_pci_count]; 240 struct spider_pci_bus *bus = &spider_pci_busses[spider_pci_count];
241 struct device_node *np = phb->arch_data; 241 struct device_node *np = phb->dn;
242 struct resource rsrc; 242 struct resource rsrc;
243 void __iomem *regs; 243 void __iomem *regs;
244 244
@@ -317,7 +317,7 @@ static int __init spider_pci_workaround_init(void)
317 * update this code to cope with dynamically added busses 317 * update this code to cope with dynamically added busses
318 */ 318 */
319 list_for_each_entry(phb, &hose_list, list_node) { 319 list_for_each_entry(phb, &hose_list, list_node) {
320 struct device_node *np = phb->arch_data; 320 struct device_node *np = phb->dn;
321 const char *model = of_get_property(np, "model", NULL); 321 const char *model = of_get_property(np, "model", NULL);
322 322
323 /* If no model property or name isn't exactly "pci", skip */ 323 /* If no model property or name isn't exactly "pci", skip */
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index faabc3fdc130..1221c6d8650f 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -26,14 +26,15 @@
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/interrupt.h> 27#include <linux/interrupt.h>
28#include <linux/notifier.h> 28#include <linux/notifier.h>
29#include <linux/of_platform.h>
29 30
30#include <asm/prom.h> 31#include <asm/prom.h>
31#include <asm/iommu.h> 32#include <asm/iommu.h>
32#include <asm/machdep.h> 33#include <asm/machdep.h>
33#include <asm/pci-bridge.h> 34#include <asm/pci-bridge.h>
34#include <asm/udbg.h> 35#include <asm/udbg.h>
35#include <asm/of_platform.h>
36#include <asm/lmb.h> 36#include <asm/lmb.h>
37#include <asm/firmware.h>
37#include <asm/cell-regs.h> 38#include <asm/cell-regs.h>
38 39
39#include "interrupt.h" 40#include "interrupt.h"
@@ -699,7 +700,8 @@ static int __init cell_iommu_init(void)
699{ 700{
700 struct device_node *np; 701 struct device_node *np;
701 702
702 if (!machine_is(cell)) 703 if (!machine_is(cell) &&
704 !machine_is(celleb_native))
703 return -ENODEV; 705 return -ENODEV;
704 706
705 /* If IOMMU is disabled or we have little enough RAM to not need 707 /* If IOMMU is disabled or we have little enough RAM to not need
diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c
index 1ed303678887..99d688e88cbe 100644
--- a/arch/powerpc/platforms/cell/pmu.c
+++ b/arch/powerpc/platforms/cell/pmu.c
@@ -213,7 +213,7 @@ u32 cbe_read_pm(u32 cpu, enum pm_reg_name reg)
213 break; 213 break;
214 214
215 case pm_interval: 215 case pm_interval:
216 READ_SHADOW_REG(val, pm_interval); 216 READ_MMIO_UPPER32(val, pm_interval);
217 break; 217 break;
218 218
219 case pm_start_stop: 219 case pm_start_stop:
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 98e7ef8e6fc6..4f6347c9fe68 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -30,6 +30,7 @@
30#include <linux/console.h> 30#include <linux/console.h>
31#include <linux/mutex.h> 31#include <linux/mutex.h>
32#include <linux/memory_hotplug.h> 32#include <linux/memory_hotplug.h>
33#include <linux/of_platform.h>
33 34
34#include <asm/mmu.h> 35#include <asm/mmu.h>
35#include <asm/processor.h> 36#include <asm/processor.h>
@@ -51,7 +52,6 @@
51#include <asm/spu_priv1.h> 52#include <asm/spu_priv1.h>
52#include <asm/udbg.h> 53#include <asm/udbg.h>
53#include <asm/mpic.h> 54#include <asm/mpic.h>
54#include <asm/of_platform.h>
55#include <asm/cell-regs.h> 55#include <asm/cell-regs.h>
56 56
57#include "interrupt.h" 57#include "interrupt.h"
diff --git a/arch/powerpc/platforms/cell/smp.c b/arch/powerpc/platforms/cell/smp.c
index e4438456c867..efb3964457b1 100644
--- a/arch/powerpc/platforms/cell/smp.c
+++ b/arch/powerpc/platforms/cell/smp.c
@@ -42,6 +42,7 @@
42#include <asm/firmware.h> 42#include <asm/firmware.h>
43#include <asm/system.h> 43#include <asm/system.h>
44#include <asm/rtas.h> 44#include <asm/rtas.h>
45#include <asm/cputhreads.h>
45 46
46#include "interrupt.h" 47#include "interrupt.h"
47#include <asm/udbg.h> 48#include <asm/udbg.h>
@@ -182,7 +183,7 @@ static int smp_cell_cpu_bootable(unsigned int nr)
182 */ 183 */
183 if (system_state < SYSTEM_RUNNING && 184 if (system_state < SYSTEM_RUNNING &&
184 cpu_has_feature(CPU_FTR_SMT) && 185 cpu_has_feature(CPU_FTR_SMT) &&
185 !smt_enabled_at_boot && nr % 2 != 0) 186 !smt_enabled_at_boot && cpu_thread_in_core(nr) != 0)
186 return 0; 187 return 0;
187 188
188 return 1; 189 return 1;
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index c83c3e3f5178..fb266ae32095 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -34,6 +34,7 @@
34#include <linux/linux_logo.h> 34#include <linux/linux_logo.h>
35#include <asm/spu.h> 35#include <asm/spu.h>
36#include <asm/spu_priv1.h> 36#include <asm/spu_priv1.h>
37#include <asm/spu_csa.h>
37#include <asm/xmon.h> 38#include <asm/xmon.h>
38#include <asm/prom.h> 39#include <asm/prom.h>
39 40
@@ -47,6 +48,13 @@ struct cbe_spu_info cbe_spu_info[MAX_NUMNODES];
47EXPORT_SYMBOL_GPL(cbe_spu_info); 48EXPORT_SYMBOL_GPL(cbe_spu_info);
48 49
49/* 50/*
51 * The spufs fault-handling code needs to call force_sig_info to raise signals
52 * on DMA errors. Export it here to avoid general kernel-wide access to this
53 * function
54 */
55EXPORT_SYMBOL_GPL(force_sig_info);
56
57/*
50 * Protects cbe_spu_info and spu->number. 58 * Protects cbe_spu_info and spu->number.
51 */ 59 */
52static DEFINE_SPINLOCK(spu_lock); 60static DEFINE_SPINLOCK(spu_lock);
@@ -66,6 +74,10 @@ static LIST_HEAD(spu_full_list);
66static DEFINE_SPINLOCK(spu_full_list_lock); 74static DEFINE_SPINLOCK(spu_full_list_lock);
67static DEFINE_MUTEX(spu_full_list_mutex); 75static DEFINE_MUTEX(spu_full_list_mutex);
68 76
77struct spu_slb {
78 u64 esid, vsid;
79};
80
69void spu_invalidate_slbs(struct spu *spu) 81void spu_invalidate_slbs(struct spu *spu)
70{ 82{
71 struct spu_priv2 __iomem *priv2 = spu->priv2; 83 struct spu_priv2 __iomem *priv2 = spu->priv2;
@@ -114,40 +126,36 @@ void spu_associate_mm(struct spu *spu, struct mm_struct *mm)
114} 126}
115EXPORT_SYMBOL_GPL(spu_associate_mm); 127EXPORT_SYMBOL_GPL(spu_associate_mm);
116 128
117static int __spu_trap_invalid_dma(struct spu *spu) 129int spu_64k_pages_available(void)
118{ 130{
119 pr_debug("%s\n", __FUNCTION__); 131 return mmu_psize_defs[MMU_PAGE_64K].shift != 0;
120 spu->dma_callback(spu, SPE_EVENT_INVALID_DMA);
121 return 0;
122} 132}
133EXPORT_SYMBOL_GPL(spu_64k_pages_available);
123 134
124static int __spu_trap_dma_align(struct spu *spu) 135static void spu_restart_dma(struct spu *spu)
125{ 136{
126 pr_debug("%s\n", __FUNCTION__); 137 struct spu_priv2 __iomem *priv2 = spu->priv2;
127 spu->dma_callback(spu, SPE_EVENT_DMA_ALIGNMENT);
128 return 0;
129}
130 138
131static int __spu_trap_error(struct spu *spu) 139 if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags))
132{ 140 out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND);
133 pr_debug("%s\n", __FUNCTION__);
134 spu->dma_callback(spu, SPE_EVENT_SPE_ERROR);
135 return 0;
136} 141}
137 142
138static void spu_restart_dma(struct spu *spu) 143static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb)
139{ 144{
140 struct spu_priv2 __iomem *priv2 = spu->priv2; 145 struct spu_priv2 __iomem *priv2 = spu->priv2;
141 146
142 if (!test_bit(SPU_CONTEXT_SWITCH_PENDING, &spu->flags)) 147 pr_debug("%s: adding SLB[%d] 0x%016lx 0x%016lx\n",
143 out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESTART_DMA_COMMAND); 148 __func__, slbe, slb->vsid, slb->esid);
149
150 out_be64(&priv2->slb_index_W, slbe);
151 out_be64(&priv2->slb_vsid_RW, slb->vsid);
152 out_be64(&priv2->slb_esid_RW, slb->esid);
144} 153}
145 154
146static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) 155static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
147{ 156{
148 struct spu_priv2 __iomem *priv2 = spu->priv2;
149 struct mm_struct *mm = spu->mm; 157 struct mm_struct *mm = spu->mm;
150 u64 esid, vsid, llp; 158 struct spu_slb slb;
151 int psize; 159 int psize;
152 160
153 pr_debug("%s\n", __FUNCTION__); 161 pr_debug("%s\n", __FUNCTION__);
@@ -159,7 +167,7 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
159 printk("%s: invalid access during switch!\n", __func__); 167 printk("%s: invalid access during switch!\n", __func__);
160 return 1; 168 return 1;
161 } 169 }
162 esid = (ea & ESID_MASK) | SLB_ESID_V; 170 slb.esid = (ea & ESID_MASK) | SLB_ESID_V;
163 171
164 switch(REGION_ID(ea)) { 172 switch(REGION_ID(ea)) {
165 case USER_REGION_ID: 173 case USER_REGION_ID:
@@ -168,21 +176,21 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
168#else 176#else
169 psize = mm->context.user_psize; 177 psize = mm->context.user_psize;
170#endif 178#endif
171 vsid = (get_vsid(mm->context.id, ea, MMU_SEGSIZE_256M) << SLB_VSID_SHIFT) | 179 slb.vsid = (get_vsid(mm->context.id, ea, MMU_SEGSIZE_256M)
172 SLB_VSID_USER; 180 << SLB_VSID_SHIFT) | SLB_VSID_USER;
173 break; 181 break;
174 case VMALLOC_REGION_ID: 182 case VMALLOC_REGION_ID:
175 if (ea < VMALLOC_END) 183 if (ea < VMALLOC_END)
176 psize = mmu_vmalloc_psize; 184 psize = mmu_vmalloc_psize;
177 else 185 else
178 psize = mmu_io_psize; 186 psize = mmu_io_psize;
179 vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M) << SLB_VSID_SHIFT) | 187 slb.vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M)
180 SLB_VSID_KERNEL; 188 << SLB_VSID_SHIFT) | SLB_VSID_KERNEL;
181 break; 189 break;
182 case KERNEL_REGION_ID: 190 case KERNEL_REGION_ID:
183 psize = mmu_linear_psize; 191 psize = mmu_linear_psize;
184 vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M) << SLB_VSID_SHIFT) | 192 slb.vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M)
185 SLB_VSID_KERNEL; 193 << SLB_VSID_SHIFT) | SLB_VSID_KERNEL;
186 break; 194 break;
187 default: 195 default:
188 /* Future: support kernel segments so that drivers 196 /* Future: support kernel segments so that drivers
@@ -191,11 +199,9 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
191 pr_debug("invalid region access at %016lx\n", ea); 199 pr_debug("invalid region access at %016lx\n", ea);
192 return 1; 200 return 1;
193 } 201 }
194 llp = mmu_psize_defs[psize].sllp; 202 slb.vsid |= mmu_psize_defs[psize].sllp;
195 203
196 out_be64(&priv2->slb_index_W, spu->slb_replace); 204 spu_load_slb(spu, spu->slb_replace, &slb);
197 out_be64(&priv2->slb_vsid_RW, vsid | llp);
198 out_be64(&priv2->slb_esid_RW, esid);
199 205
200 spu->slb_replace++; 206 spu->slb_replace++;
201 if (spu->slb_replace >= 8) 207 if (spu->slb_replace >= 8)
@@ -225,13 +231,83 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr)
225 return 1; 231 return 1;
226 } 232 }
227 233
234 spu->class_0_pending = 0;
228 spu->dar = ea; 235 spu->dar = ea;
229 spu->dsisr = dsisr; 236 spu->dsisr = dsisr;
230 mb(); 237
231 spu->stop_callback(spu); 238 spu->stop_callback(spu);
239
240 return 0;
241}
242
243static void __spu_kernel_slb(void *addr, struct spu_slb *slb)
244{
245 unsigned long ea = (unsigned long)addr;
246 u64 llp;
247
248 if (REGION_ID(ea) == KERNEL_REGION_ID)
249 llp = mmu_psize_defs[mmu_linear_psize].sllp;
250 else
251 llp = mmu_psize_defs[mmu_virtual_psize].sllp;
252
253 slb->vsid = (get_kernel_vsid(ea, MMU_SEGSIZE_256M) << SLB_VSID_SHIFT) |
254 SLB_VSID_KERNEL | llp;
255 slb->esid = (ea & ESID_MASK) | SLB_ESID_V;
256}
257
258/**
259 * Given an array of @nr_slbs SLB entries, @slbs, return non-zero if the
260 * address @new_addr is present.
261 */
262static inline int __slb_present(struct spu_slb *slbs, int nr_slbs,
263 void *new_addr)
264{
265 unsigned long ea = (unsigned long)new_addr;
266 int i;
267
268 for (i = 0; i < nr_slbs; i++)
269 if (!((slbs[i].esid ^ ea) & ESID_MASK))
270 return 1;
271
232 return 0; 272 return 0;
233} 273}
234 274
275/**
276 * Setup the SPU kernel SLBs, in preparation for a context save/restore. We
277 * need to map both the context save area, and the save/restore code.
278 *
279 * Because the lscsa and code may cross segment boundaires, we check to see
280 * if mappings are required for the start and end of each range. We currently
281 * assume that the mappings are smaller that one segment - if not, something
282 * is seriously wrong.
283 */
284void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa,
285 void *code, int code_size)
286{
287 struct spu_slb slbs[4];
288 int i, nr_slbs = 0;
289 /* start and end addresses of both mappings */
290 void *addrs[] = {
291 lscsa, (void *)lscsa + sizeof(*lscsa) - 1,
292 code, code + code_size - 1
293 };
294
295 /* check the set of addresses, and create a new entry in the slbs array
296 * if there isn't already a SLB for that address */
297 for (i = 0; i < ARRAY_SIZE(addrs); i++) {
298 if (__slb_present(slbs, nr_slbs, addrs[i]))
299 continue;
300
301 __spu_kernel_slb(addrs[i], &slbs[nr_slbs]);
302 nr_slbs++;
303 }
304
305 /* Add the set of SLBs */
306 for (i = 0; i < nr_slbs; i++)
307 spu_load_slb(spu, i, &slbs[i]);
308}
309EXPORT_SYMBOL_GPL(spu_setup_kernel_slbs);
310
235static irqreturn_t 311static irqreturn_t
236spu_irq_class_0(int irq, void *data) 312spu_irq_class_0(int irq, void *data)
237{ 313{
@@ -240,12 +316,13 @@ spu_irq_class_0(int irq, void *data)
240 316
241 spu = data; 317 spu = data;
242 318
319 spin_lock(&spu->register_lock);
243 mask = spu_int_mask_get(spu, 0); 320 mask = spu_int_mask_get(spu, 0);
244 stat = spu_int_stat_get(spu, 0); 321 stat = spu_int_stat_get(spu, 0) & mask;
245 stat &= mask;
246 322
247 spin_lock(&spu->register_lock);
248 spu->class_0_pending |= stat; 323 spu->class_0_pending |= stat;
324 spu->dsisr = spu_mfc_dsisr_get(spu);
325 spu->dar = spu_mfc_dar_get(spu);
249 spin_unlock(&spu->register_lock); 326 spin_unlock(&spu->register_lock);
250 327
251 spu->stop_callback(spu); 328 spu->stop_callback(spu);
@@ -255,31 +332,6 @@ spu_irq_class_0(int irq, void *data)
255 return IRQ_HANDLED; 332 return IRQ_HANDLED;
256} 333}
257 334
258int
259spu_irq_class_0_bottom(struct spu *spu)
260{
261 unsigned long flags;
262 unsigned long stat;
263
264 spin_lock_irqsave(&spu->register_lock, flags);
265 stat = spu->class_0_pending;
266 spu->class_0_pending = 0;
267
268 if (stat & 1) /* invalid DMA alignment */
269 __spu_trap_dma_align(spu);
270
271 if (stat & 2) /* invalid MFC DMA */
272 __spu_trap_invalid_dma(spu);
273
274 if (stat & 4) /* error on SPU */
275 __spu_trap_error(spu);
276
277 spin_unlock_irqrestore(&spu->register_lock, flags);
278
279 return (stat & 0x7) ? -EIO : 0;
280}
281EXPORT_SYMBOL_GPL(spu_irq_class_0_bottom);
282
283static irqreturn_t 335static irqreturn_t
284spu_irq_class_1(int irq, void *data) 336spu_irq_class_1(int irq, void *data)
285{ 337{
@@ -294,24 +346,23 @@ spu_irq_class_1(int irq, void *data)
294 stat = spu_int_stat_get(spu, 1) & mask; 346 stat = spu_int_stat_get(spu, 1) & mask;
295 dar = spu_mfc_dar_get(spu); 347 dar = spu_mfc_dar_get(spu);
296 dsisr = spu_mfc_dsisr_get(spu); 348 dsisr = spu_mfc_dsisr_get(spu);
297 if (stat & 2) /* mapping fault */ 349 if (stat & CLASS1_STORAGE_FAULT_INTR)
298 spu_mfc_dsisr_set(spu, 0ul); 350 spu_mfc_dsisr_set(spu, 0ul);
299 spu_int_stat_clear(spu, 1, stat); 351 spu_int_stat_clear(spu, 1, stat);
300 spin_unlock(&spu->register_lock); 352 spin_unlock(&spu->register_lock);
301 pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat, 353 pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat,
302 dar, dsisr); 354 dar, dsisr);
303 355
304 if (stat & 1) /* segment fault */ 356 if (stat & CLASS1_SEGMENT_FAULT_INTR)
305 __spu_trap_data_seg(spu, dar); 357 __spu_trap_data_seg(spu, dar);
306 358
307 if (stat & 2) { /* mapping fault */ 359 if (stat & CLASS1_STORAGE_FAULT_INTR)
308 __spu_trap_data_map(spu, dar, dsisr); 360 __spu_trap_data_map(spu, dar, dsisr);
309 }
310 361
311 if (stat & 4) /* ls compare & suspend on get */ 362 if (stat & CLASS1_LS_COMPARE_SUSPEND_ON_GET_INTR)
312 ; 363 ;
313 364
314 if (stat & 8) /* ls compare & suspend on put */ 365 if (stat & CLASS1_LS_COMPARE_SUSPEND_ON_PUT_INTR)
315 ; 366 ;
316 367
317 return stat ? IRQ_HANDLED : IRQ_NONE; 368 return stat ? IRQ_HANDLED : IRQ_NONE;
@@ -323,6 +374,8 @@ spu_irq_class_2(int irq, void *data)
323 struct spu *spu; 374 struct spu *spu;
324 unsigned long stat; 375 unsigned long stat;
325 unsigned long mask; 376 unsigned long mask;
377 const int mailbox_intrs =
378 CLASS2_MAILBOX_THRESHOLD_INTR | CLASS2_MAILBOX_INTR;
326 379
327 spu = data; 380 spu = data;
328 spin_lock(&spu->register_lock); 381 spin_lock(&spu->register_lock);
@@ -330,31 +383,30 @@ spu_irq_class_2(int irq, void *data)
330 mask = spu_int_mask_get(spu, 2); 383 mask = spu_int_mask_get(spu, 2);
331 /* ignore interrupts we're not waiting for */ 384 /* ignore interrupts we're not waiting for */
332 stat &= mask; 385 stat &= mask;
333 /* 386
334 * mailbox interrupts (0x1 and 0x10) are level triggered. 387 /* mailbox interrupts are level triggered. mask them now before
335 * mask them now before acknowledging. 388 * acknowledging */
336 */ 389 if (stat & mailbox_intrs)
337 if (stat & 0x11) 390 spu_int_mask_and(spu, 2, ~(stat & mailbox_intrs));
338 spu_int_mask_and(spu, 2, ~(stat & 0x11));
339 /* acknowledge all interrupts before the callbacks */ 391 /* acknowledge all interrupts before the callbacks */
340 spu_int_stat_clear(spu, 2, stat); 392 spu_int_stat_clear(spu, 2, stat);
341 spin_unlock(&spu->register_lock); 393 spin_unlock(&spu->register_lock);
342 394
343 pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, mask); 395 pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, mask);
344 396
345 if (stat & 1) /* PPC core mailbox */ 397 if (stat & CLASS2_MAILBOX_INTR)
346 spu->ibox_callback(spu); 398 spu->ibox_callback(spu);
347 399
348 if (stat & 2) /* SPU stop-and-signal */ 400 if (stat & CLASS2_SPU_STOP_INTR)
349 spu->stop_callback(spu); 401 spu->stop_callback(spu);
350 402
351 if (stat & 4) /* SPU halted */ 403 if (stat & CLASS2_SPU_HALT_INTR)
352 spu->stop_callback(spu); 404 spu->stop_callback(spu);
353 405
354 if (stat & 8) /* DMA tag group complete */ 406 if (stat & CLASS2_SPU_DMA_TAG_GROUP_COMPLETE_INTR)
355 spu->mfc_callback(spu); 407 spu->mfc_callback(spu);
356 408
357 if (stat & 0x10) /* SPU mailbox threshold */ 409 if (stat & CLASS2_MAILBOX_THRESHOLD_INTR)
358 spu->wbox_callback(spu); 410 spu->wbox_callback(spu);
359 411
360 spu->stats.class2_intr++; 412 spu->stats.class2_intr++;
@@ -479,13 +531,27 @@ EXPORT_SYMBOL_GPL(spu_add_sysdev_attr);
479int spu_add_sysdev_attr_group(struct attribute_group *attrs) 531int spu_add_sysdev_attr_group(struct attribute_group *attrs)
480{ 532{
481 struct spu *spu; 533 struct spu *spu;
534 int rc = 0;
482 535
483 mutex_lock(&spu_full_list_mutex); 536 mutex_lock(&spu_full_list_mutex);
484 list_for_each_entry(spu, &spu_full_list, full_list) 537 list_for_each_entry(spu, &spu_full_list, full_list) {
485 sysfs_create_group(&spu->sysdev.kobj, attrs); 538 rc = sysfs_create_group(&spu->sysdev.kobj, attrs);
539
540 /* we're in trouble here, but try unwinding anyway */
541 if (rc) {
542 printk(KERN_ERR "%s: can't create sysfs group '%s'\n",
543 __func__, attrs->name);
544
545 list_for_each_entry_continue_reverse(spu,
546 &spu_full_list, full_list)
547 sysfs_remove_group(&spu->sysdev.kobj, attrs);
548 break;
549 }
550 }
551
486 mutex_unlock(&spu_full_list_mutex); 552 mutex_unlock(&spu_full_list_mutex);
487 553
488 return 0; 554 return rc;
489} 555}
490EXPORT_SYMBOL_GPL(spu_add_sysdev_attr_group); 556EXPORT_SYMBOL_GPL(spu_add_sysdev_attr_group);
491 557
diff --git a/arch/powerpc/platforms/cell/spu_fault.c b/arch/powerpc/platforms/cell/spu_fault.c
new file mode 100644
index 000000000000..c8b1cd42905d
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spu_fault.c
@@ -0,0 +1,98 @@
1/*
2 * SPU mm fault handler
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2007
5 *
6 * Author: Arnd Bergmann <arndb@de.ibm.com>
7 * Author: Jeremy Kerr <jk@ozlabs.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23#include <linux/sched.h>
24#include <linux/mm.h>
25#include <linux/module.h>
26
27#include <asm/spu.h>
28#include <asm/spu_csa.h>
29
30/*
31 * This ought to be kept in sync with the powerpc specific do_page_fault
32 * function. Currently, there are a few corner cases that we haven't had
33 * to handle fortunately.
34 */
35int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
36 unsigned long dsisr, unsigned *flt)
37{
38 struct vm_area_struct *vma;
39 unsigned long is_write;
40 int ret;
41
42#if 0
43 if (!IS_VALID_EA(ea)) {
44 return -EFAULT;
45 }
46#endif /* XXX */
47 if (mm == NULL) {
48 return -EFAULT;
49 }
50 if (mm->pgd == NULL) {
51 return -EFAULT;
52 }
53
54 down_read(&mm->mmap_sem);
55 vma = find_vma(mm, ea);
56 if (!vma)
57 goto bad_area;
58 if (vma->vm_start <= ea)
59 goto good_area;
60 if (!(vma->vm_flags & VM_GROWSDOWN))
61 goto bad_area;
62 if (expand_stack(vma, ea))
63 goto bad_area;
64good_area:
65 is_write = dsisr & MFC_DSISR_ACCESS_PUT;
66 if (is_write) {
67 if (!(vma->vm_flags & VM_WRITE))
68 goto bad_area;
69 } else {
70 if (dsisr & MFC_DSISR_ACCESS_DENIED)
71 goto bad_area;
72 if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
73 goto bad_area;
74 }
75 ret = 0;
76 *flt = handle_mm_fault(mm, vma, ea, is_write);
77 if (unlikely(*flt & VM_FAULT_ERROR)) {
78 if (*flt & VM_FAULT_OOM) {
79 ret = -ENOMEM;
80 goto bad_area;
81 } else if (*flt & VM_FAULT_SIGBUS) {
82 ret = -EFAULT;
83 goto bad_area;
84 }
85 BUG();
86 }
87 if (*flt & VM_FAULT_MAJOR)
88 current->maj_flt++;
89 else
90 current->min_flt++;
91 up_read(&mm->mmap_sem);
92 return ret;
93
94bad_area:
95 up_read(&mm->mmap_sem);
96 return -EFAULT;
97}
98EXPORT_SYMBOL_GPL(spu_handle_mm_fault);
diff --git a/arch/powerpc/platforms/cell/spu_manage.c b/arch/powerpc/platforms/cell/spu_manage.c
index 1b010707488d..d351bdebf5f1 100644
--- a/arch/powerpc/platforms/cell/spu_manage.c
+++ b/arch/powerpc/platforms/cell/spu_manage.c
@@ -35,6 +35,7 @@
35#include <asm/firmware.h> 35#include <asm/firmware.h>
36#include <asm/prom.h> 36#include <asm/prom.h>
37 37
38#include "spufs/spufs.h"
38#include "interrupt.h" 39#include "interrupt.h"
39 40
40struct device_node *spu_devnode(struct spu *spu) 41struct device_node *spu_devnode(struct spu *spu)
@@ -345,7 +346,7 @@ static int __init of_create_spu(struct spu *spu, void *data)
345 } 346 }
346 ret = spu_map_interrupts_old(spu, spe); 347 ret = spu_map_interrupts_old(spu, spe);
347 if (ret) { 348 if (ret) {
348 printk(KERN_ERR "%s: could not map interrupts", 349 printk(KERN_ERR "%s: could not map interrupts\n",
349 spu->name); 350 spu->name);
350 goto out_unmap; 351 goto out_unmap;
351 } 352 }
@@ -369,6 +370,16 @@ static int of_destroy_spu(struct spu *spu)
369 return 0; 370 return 0;
370} 371}
371 372
373static void enable_spu_by_master_run(struct spu_context *ctx)
374{
375 ctx->ops->master_start(ctx);
376}
377
378static void disable_spu_by_master_run(struct spu_context *ctx)
379{
380 ctx->ops->master_stop(ctx);
381}
382
372/* Hardcoded affinity idxs for qs20 */ 383/* Hardcoded affinity idxs for qs20 */
373#define QS20_SPES_PER_BE 8 384#define QS20_SPES_PER_BE 8
374static int qs20_reg_idxs[QS20_SPES_PER_BE] = { 0, 2, 4, 6, 7, 5, 3, 1 }; 385static int qs20_reg_idxs[QS20_SPES_PER_BE] = { 0, 2, 4, 6, 7, 5, 3, 1 };
@@ -411,10 +422,15 @@ static void init_affinity_qs20_harcoded(void)
411 422
412static int of_has_vicinity(void) 423static int of_has_vicinity(void)
413{ 424{
414 struct spu* spu; 425 struct device_node *dn;
415 426
416 spu = list_first_entry(&cbe_spu_info[0].spus, struct spu, cbe_list); 427 for_each_node_by_type(dn, "spe") {
417 return of_find_property(spu_devnode(spu), "vicinity", NULL) != NULL; 428 if (of_find_property(dn, "vicinity", NULL)) {
429 of_node_put(dn);
430 return 1;
431 }
432 }
433 return 0;
418} 434}
419 435
420static struct spu *devnode_spu(int cbe, struct device_node *dn) 436static struct spu *devnode_spu(int cbe, struct device_node *dn)
@@ -525,7 +541,7 @@ static int __init init_affinity(void)
525 if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) 541 if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
526 init_affinity_qs20_harcoded(); 542 init_affinity_qs20_harcoded();
527 else 543 else
528 printk("No affinity configuration found"); 544 printk("No affinity configuration found\n");
529 } 545 }
530 546
531 return 0; 547 return 0;
@@ -535,5 +551,7 @@ const struct spu_management_ops spu_management_of_ops = {
535 .enumerate_spus = of_enumerate_spus, 551 .enumerate_spus = of_enumerate_spus,
536 .create_spu = of_create_spu, 552 .create_spu = of_create_spu,
537 .destroy_spu = of_destroy_spu, 553 .destroy_spu = of_destroy_spu,
554 .enable_spu = enable_spu_by_master_run,
555 .disable_spu = disable_spu_by_master_run,
538 .init_affinity = init_affinity, 556 .init_affinity = init_affinity,
539}; 557};
diff --git a/arch/powerpc/platforms/cell/spufs/Makefile b/arch/powerpc/platforms/cell/spufs/Makefile
index 328afcf89503..d3a349fb42e5 100644
--- a/arch/powerpc/platforms/cell/spufs/Makefile
+++ b/arch/powerpc/platforms/cell/spufs/Makefile
@@ -1,8 +1,8 @@
1obj-y += switch.o fault.o lscsa_alloc.o
2 1
3obj-$(CONFIG_SPU_FS) += spufs.o 2obj-$(CONFIG_SPU_FS) += spufs.o
4spufs-y += inode.o file.o context.o syscalls.o coredump.o 3spufs-y += inode.o file.o context.o syscalls.o coredump.o
5spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o 4spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o
5spufs-y += switch.o fault.o lscsa_alloc.o
6 6
7# Rules to build switch.o with the help of SPU tool chain 7# Rules to build switch.o with the help of SPU tool chain
8SPU_CROSS := spu- 8SPU_CROSS := spu-
diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c
index ec01214e51ee..50d98a154aaf 100644
--- a/arch/powerpc/platforms/cell/spufs/backing_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c
@@ -106,16 +106,20 @@ static unsigned int spu_backing_mbox_stat_poll(struct spu_context *ctx,
106 if (stat & 0xff0000) 106 if (stat & 0xff0000)
107 ret |= POLLIN | POLLRDNORM; 107 ret |= POLLIN | POLLRDNORM;
108 else { 108 else {
109 ctx->csa.priv1.int_stat_class0_RW &= ~0x1; 109 ctx->csa.priv1.int_stat_class2_RW &=
110 ctx->csa.priv1.int_mask_class2_RW |= 0x1; 110 ~CLASS2_MAILBOX_INTR;
111 ctx->csa.priv1.int_mask_class2_RW |=
112 CLASS2_ENABLE_MAILBOX_INTR;
111 } 113 }
112 } 114 }
113 if (events & (POLLOUT | POLLWRNORM)) { 115 if (events & (POLLOUT | POLLWRNORM)) {
114 if (stat & 0x00ff00) 116 if (stat & 0x00ff00)
115 ret = POLLOUT | POLLWRNORM; 117 ret = POLLOUT | POLLWRNORM;
116 else { 118 else {
117 ctx->csa.priv1.int_stat_class0_RW &= ~0x10; 119 ctx->csa.priv1.int_stat_class2_RW &=
118 ctx->csa.priv1.int_mask_class2_RW |= 0x10; 120 ~CLASS2_MAILBOX_THRESHOLD_INTR;
121 ctx->csa.priv1.int_mask_class2_RW |=
122 CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR;
119 } 123 }
120 } 124 }
121 spin_unlock_irq(&ctx->csa.register_lock); 125 spin_unlock_irq(&ctx->csa.register_lock);
@@ -139,7 +143,7 @@ static int spu_backing_ibox_read(struct spu_context *ctx, u32 * data)
139 ret = 4; 143 ret = 4;
140 } else { 144 } else {
141 /* make sure we get woken up by the interrupt */ 145 /* make sure we get woken up by the interrupt */
142 ctx->csa.priv1.int_mask_class2_RW |= 0x1UL; 146 ctx->csa.priv1.int_mask_class2_RW |= CLASS2_ENABLE_MAILBOX_INTR;
143 ret = 0; 147 ret = 0;
144 } 148 }
145 spin_unlock(&ctx->csa.register_lock); 149 spin_unlock(&ctx->csa.register_lock);
@@ -169,7 +173,8 @@ static int spu_backing_wbox_write(struct spu_context *ctx, u32 data)
169 } else { 173 } else {
170 /* make sure we get woken up by the interrupt when space 174 /* make sure we get woken up by the interrupt when space
171 becomes available */ 175 becomes available */
172 ctx->csa.priv1.int_mask_class2_RW |= 0x10; 176 ctx->csa.priv1.int_mask_class2_RW |=
177 CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR;
173 ret = 0; 178 ret = 0;
174 } 179 }
175 spin_unlock(&ctx->csa.register_lock); 180 spin_unlock(&ctx->csa.register_lock);
@@ -268,6 +273,11 @@ static char *spu_backing_get_ls(struct spu_context *ctx)
268 return ctx->csa.lscsa->ls; 273 return ctx->csa.lscsa->ls;
269} 274}
270 275
276static void spu_backing_privcntl_write(struct spu_context *ctx, u64 val)
277{
278 ctx->csa.priv2.spu_privcntl_RW = val;
279}
280
271static u32 spu_backing_runcntl_read(struct spu_context *ctx) 281static u32 spu_backing_runcntl_read(struct spu_context *ctx)
272{ 282{
273 return ctx->csa.prob.spu_runcntl_RW; 283 return ctx->csa.prob.spu_runcntl_RW;
@@ -285,6 +295,11 @@ static void spu_backing_runcntl_write(struct spu_context *ctx, u32 val)
285 spin_unlock(&ctx->csa.register_lock); 295 spin_unlock(&ctx->csa.register_lock);
286} 296}
287 297
298static void spu_backing_runcntl_stop(struct spu_context *ctx)
299{
300 spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP);
301}
302
288static void spu_backing_master_start(struct spu_context *ctx) 303static void spu_backing_master_start(struct spu_context *ctx)
289{ 304{
290 struct spu_state *csa = &ctx->csa; 305 struct spu_state *csa = &ctx->csa;
@@ -358,7 +373,7 @@ static int spu_backing_send_mfc_command(struct spu_context *ctx,
358 373
359static void spu_backing_restart_dma(struct spu_context *ctx) 374static void spu_backing_restart_dma(struct spu_context *ctx)
360{ 375{
361 /* nothing to do here */ 376 ctx->csa.priv2.mfc_control_RW |= MFC_CNTL_RESTART_DMA_COMMAND;
362} 377}
363 378
364struct spu_context_ops spu_backing_ops = { 379struct spu_context_ops spu_backing_ops = {
@@ -379,8 +394,10 @@ struct spu_context_ops spu_backing_ops = {
379 .npc_write = spu_backing_npc_write, 394 .npc_write = spu_backing_npc_write,
380 .status_read = spu_backing_status_read, 395 .status_read = spu_backing_status_read,
381 .get_ls = spu_backing_get_ls, 396 .get_ls = spu_backing_get_ls,
397 .privcntl_write = spu_backing_privcntl_write,
382 .runcntl_read = spu_backing_runcntl_read, 398 .runcntl_read = spu_backing_runcntl_read,
383 .runcntl_write = spu_backing_runcntl_write, 399 .runcntl_write = spu_backing_runcntl_write,
400 .runcntl_stop = spu_backing_runcntl_stop,
384 .master_start = spu_backing_master_start, 401 .master_start = spu_backing_master_start,
385 .master_stop = spu_backing_master_stop, 402 .master_stop = spu_backing_master_stop,
386 .set_mfc_query = spu_backing_set_mfc_query, 403 .set_mfc_query = spu_backing_set_mfc_query,
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 9cb081c26e71..237e152d31dc 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -52,6 +52,7 @@ struct spu_context *alloc_spu_context(struct spu_gang *gang)
52 init_waitqueue_head(&ctx->wbox_wq); 52 init_waitqueue_head(&ctx->wbox_wq);
53 init_waitqueue_head(&ctx->stop_wq); 53 init_waitqueue_head(&ctx->stop_wq);
54 init_waitqueue_head(&ctx->mfc_wq); 54 init_waitqueue_head(&ctx->mfc_wq);
55 init_waitqueue_head(&ctx->run_wq);
55 ctx->state = SPU_STATE_SAVED; 56 ctx->state = SPU_STATE_SAVED;
56 ctx->ops = &spu_backing_ops; 57 ctx->ops = &spu_backing_ops;
57 ctx->owner = get_task_mm(current); 58 ctx->owner = get_task_mm(current);
@@ -105,7 +106,17 @@ int put_spu_context(struct spu_context *ctx)
105void spu_forget(struct spu_context *ctx) 106void spu_forget(struct spu_context *ctx)
106{ 107{
107 struct mm_struct *mm; 108 struct mm_struct *mm;
108 spu_acquire_saved(ctx); 109
110 /*
111 * This is basically an open-coded spu_acquire_saved, except that
112 * we don't acquire the state mutex interruptible.
113 */
114 mutex_lock(&ctx->state_mutex);
115 if (ctx->state != SPU_STATE_SAVED) {
116 set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags);
117 spu_deactivate(ctx);
118 }
119
109 mm = ctx->owner; 120 mm = ctx->owner;
110 ctx->owner = NULL; 121 ctx->owner = NULL;
111 mmput(mm); 122 mmput(mm);
@@ -133,47 +144,23 @@ void spu_unmap_mappings(struct spu_context *ctx)
133} 144}
134 145
135/** 146/**
136 * spu_acquire_runnable - lock spu contex and make sure it is in runnable state 147 * spu_acquire_saved - lock spu contex and make sure it is in saved state
137 * @ctx: spu contex to lock 148 * @ctx: spu contex to lock
138 *
139 * Note:
140 * Returns 0 and with the context locked on success
141 * Returns negative error and with the context _unlocked_ on failure.
142 */ 149 */
143int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags) 150int spu_acquire_saved(struct spu_context *ctx)
144{ 151{
145 int ret = -EINVAL; 152 int ret;
146
147 spu_acquire(ctx);
148 if (ctx->state == SPU_STATE_SAVED) {
149 /*
150 * Context is about to be freed, so we can't acquire it anymore.
151 */
152 if (!ctx->owner)
153 goto out_unlock;
154 ret = spu_activate(ctx, flags);
155 if (ret)
156 goto out_unlock;
157 }
158 153
159 return 0; 154 ret = spu_acquire(ctx);
160 155 if (ret)
161 out_unlock: 156 return ret;
162 spu_release(ctx);
163 return ret;
164}
165 157
166/**
167 * spu_acquire_saved - lock spu contex and make sure it is in saved state
168 * @ctx: spu contex to lock
169 */
170void spu_acquire_saved(struct spu_context *ctx)
171{
172 spu_acquire(ctx);
173 if (ctx->state != SPU_STATE_SAVED) { 158 if (ctx->state != SPU_STATE_SAVED) {
174 set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags); 159 set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags);
175 spu_deactivate(ctx); 160 spu_deactivate(ctx);
176 } 161 }
162
163 return 0;
177} 164}
178 165
179/** 166/**
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index 80f62363e1ce..0c6a96b82b2d 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -148,7 +148,9 @@ int spufs_coredump_extra_notes_size(void)
148 148
149 fd = 0; 149 fd = 0;
150 while ((ctx = coredump_next_context(&fd)) != NULL) { 150 while ((ctx = coredump_next_context(&fd)) != NULL) {
151 spu_acquire_saved(ctx); 151 rc = spu_acquire_saved(ctx);
152 if (rc)
153 break;
152 rc = spufs_ctx_note_size(ctx, fd); 154 rc = spufs_ctx_note_size(ctx, fd);
153 spu_release_saved(ctx); 155 spu_release_saved(ctx);
154 if (rc < 0) 156 if (rc < 0)
@@ -224,7 +226,9 @@ int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset)
224 226
225 fd = 0; 227 fd = 0;
226 while ((ctx = coredump_next_context(&fd)) != NULL) { 228 while ((ctx = coredump_next_context(&fd)) != NULL) {
227 spu_acquire_saved(ctx); 229 rc = spu_acquire_saved(ctx);
230 if (rc)
231 return rc;
228 232
229 for (j = 0; spufs_coredump_read[j].name != NULL; j++) { 233 for (j = 0; spufs_coredump_read[j].name != NULL; j++) {
230 rc = spufs_arch_write_note(ctx, j, file, fd, foffset); 234 rc = spufs_arch_write_note(ctx, j, file, fd, foffset);
diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c
index 917eab4be486..eff4d291ba85 100644
--- a/arch/powerpc/platforms/cell/spufs/fault.c
+++ b/arch/powerpc/platforms/cell/spufs/fault.c
@@ -28,117 +28,71 @@
28 28
29#include "spufs.h" 29#include "spufs.h"
30 30
31/* 31/**
32 * This ought to be kept in sync with the powerpc specific do_page_fault 32 * Handle an SPE event, depending on context SPU_CREATE_EVENTS_ENABLED flag.
33 * function. Currently, there are a few corner cases that we haven't had 33 *
34 * to handle fortunately. 34 * If the context was created with events, we just set the return event.
35 * Otherwise, send an appropriate signal to the process.
35 */ 36 */
36static int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea, 37static void spufs_handle_event(struct spu_context *ctx,
37 unsigned long dsisr, unsigned *flt) 38 unsigned long ea, int type)
38{ 39{
39 struct vm_area_struct *vma; 40 siginfo_t info;
40 unsigned long is_write;
41 int ret;
42 41
43#if 0 42 if (ctx->flags & SPU_CREATE_EVENTS_ENABLED) {
44 if (!IS_VALID_EA(ea)) { 43 ctx->event_return |= type;
45 return -EFAULT; 44 wake_up_all(&ctx->stop_wq);
46 } 45 return;
47#endif /* XXX */
48 if (mm == NULL) {
49 return -EFAULT;
50 }
51 if (mm->pgd == NULL) {
52 return -EFAULT;
53 } 46 }
54 47
55 down_read(&mm->mmap_sem); 48 memset(&info, 0, sizeof(info));
56 vma = find_vma(mm, ea); 49
57 if (!vma) 50 switch (type) {
58 goto bad_area; 51 case SPE_EVENT_INVALID_DMA:
59 if (vma->vm_start <= ea) 52 info.si_signo = SIGBUS;
60 goto good_area; 53 info.si_code = BUS_OBJERR;
61 if (!(vma->vm_flags & VM_GROWSDOWN)) 54 break;
62 goto bad_area; 55 case SPE_EVENT_SPE_DATA_STORAGE:
63 if (expand_stack(vma, ea)) 56 info.si_signo = SIGSEGV;
64 goto bad_area; 57 info.si_addr = (void __user *)ea;
65good_area: 58 info.si_code = SEGV_ACCERR;
66 is_write = dsisr & MFC_DSISR_ACCESS_PUT; 59 ctx->ops->restart_dma(ctx);
67 if (is_write) { 60 break;
68 if (!(vma->vm_flags & VM_WRITE)) 61 case SPE_EVENT_DMA_ALIGNMENT:
69 goto bad_area; 62 info.si_signo = SIGBUS;
70 } else { 63 /* DAR isn't set for an alignment fault :( */
71 if (dsisr & MFC_DSISR_ACCESS_DENIED) 64 info.si_code = BUS_ADRALN;
72 goto bad_area; 65 break;
73 if (!(vma->vm_flags & (VM_READ | VM_EXEC))) 66 case SPE_EVENT_SPE_ERROR:
74 goto bad_area; 67 info.si_signo = SIGILL;
68 info.si_addr = (void __user *)(unsigned long)
69 ctx->ops->npc_read(ctx) - 4;
70 info.si_code = ILL_ILLOPC;
71 break;
75 } 72 }
76 ret = 0;
77 *flt = handle_mm_fault(mm, vma, ea, is_write);
78 if (unlikely(*flt & VM_FAULT_ERROR)) {
79 if (*flt & VM_FAULT_OOM) {
80 ret = -ENOMEM;
81 goto bad_area;
82 } else if (*flt & VM_FAULT_SIGBUS) {
83 ret = -EFAULT;
84 goto bad_area;
85 }
86 BUG();
87 }
88 if (*flt & VM_FAULT_MAJOR)
89 current->maj_flt++;
90 else
91 current->min_flt++;
92 up_read(&mm->mmap_sem);
93 return ret;
94 73
95bad_area: 74 if (info.si_signo)
96 up_read(&mm->mmap_sem); 75 force_sig_info(info.si_signo, &info, current);
97 return -EFAULT;
98} 76}
99 77
100static void spufs_handle_dma_error(struct spu_context *ctx, 78int spufs_handle_class0(struct spu_context *ctx)
101 unsigned long ea, int type)
102{ 79{
103 if (ctx->flags & SPU_CREATE_EVENTS_ENABLED) { 80 unsigned long stat = ctx->csa.class_0_pending & CLASS0_INTR_MASK;
104 ctx->event_return |= type;
105 wake_up_all(&ctx->stop_wq);
106 } else {
107 siginfo_t info;
108 memset(&info, 0, sizeof(info));
109
110 switch (type) {
111 case SPE_EVENT_INVALID_DMA:
112 info.si_signo = SIGBUS;
113 info.si_code = BUS_OBJERR;
114 break;
115 case SPE_EVENT_SPE_DATA_STORAGE:
116 info.si_signo = SIGBUS;
117 info.si_addr = (void __user *)ea;
118 info.si_code = BUS_ADRERR;
119 break;
120 case SPE_EVENT_DMA_ALIGNMENT:
121 info.si_signo = SIGBUS;
122 /* DAR isn't set for an alignment fault :( */
123 info.si_code = BUS_ADRALN;
124 break;
125 case SPE_EVENT_SPE_ERROR:
126 info.si_signo = SIGILL;
127 info.si_addr = (void __user *)(unsigned long)
128 ctx->ops->npc_read(ctx) - 4;
129 info.si_code = ILL_ILLOPC;
130 break;
131 }
132 if (info.si_signo)
133 force_sig_info(info.si_signo, &info, current);
134 }
135}
136 81
137void spufs_dma_callback(struct spu *spu, int type) 82 if (likely(!stat))
138{ 83 return 0;
139 spufs_handle_dma_error(spu->ctx, spu->dar, type); 84
85 if (stat & CLASS0_DMA_ALIGNMENT_INTR)
86 spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_DMA_ALIGNMENT);
87
88 if (stat & CLASS0_INVALID_DMA_COMMAND_INTR)
89 spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_INVALID_DMA);
90
91 if (stat & CLASS0_SPU_ERROR_INTR)
92 spufs_handle_event(ctx, ctx->csa.dar, SPE_EVENT_SPE_ERROR);
93
94 return -EIO;
140} 95}
141EXPORT_SYMBOL_GPL(spufs_dma_callback);
142 96
143/* 97/*
144 * bottom half handler for page faults, we can't do this from 98 * bottom half handler for page faults, we can't do this from
@@ -154,7 +108,7 @@ int spufs_handle_class1(struct spu_context *ctx)
154 u64 ea, dsisr, access; 108 u64 ea, dsisr, access;
155 unsigned long flags; 109 unsigned long flags;
156 unsigned flt = 0; 110 unsigned flt = 0;
157 int ret; 111 int ret, ret2;
158 112
159 /* 113 /*
160 * dar and dsisr get passed from the registers 114 * dar and dsisr get passed from the registers
@@ -165,16 +119,8 @@ int spufs_handle_class1(struct spu_context *ctx)
165 * in time, we can still expect to get the same fault 119 * in time, we can still expect to get the same fault
166 * the immediately after the context restore. 120 * the immediately after the context restore.
167 */ 121 */
168 if (ctx->state == SPU_STATE_RUNNABLE) { 122 ea = ctx->csa.dar;
169 ea = ctx->spu->dar; 123 dsisr = ctx->csa.dsisr;
170 dsisr = ctx->spu->dsisr;
171 ctx->spu->dar= ctx->spu->dsisr = 0;
172 } else {
173 ea = ctx->csa.priv1.mfc_dar_RW;
174 dsisr = ctx->csa.priv1.mfc_dsisr_RW;
175 ctx->csa.priv1.mfc_dar_RW = 0;
176 ctx->csa.priv1.mfc_dsisr_RW = 0;
177 }
178 124
179 if (!(dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))) 125 if (!(dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)))
180 return 0; 126 return 0;
@@ -201,7 +147,22 @@ int spufs_handle_class1(struct spu_context *ctx)
201 if (ret) 147 if (ret)
202 ret = spu_handle_mm_fault(current->mm, ea, dsisr, &flt); 148 ret = spu_handle_mm_fault(current->mm, ea, dsisr, &flt);
203 149
204 spu_acquire(ctx); 150 /*
151 * If spu_acquire fails due to a pending signal we just want to return
152 * EINTR to userspace even if that means missing the dma restart or
153 * updating the page fault statistics.
154 */
155 ret2 = spu_acquire(ctx);
156 if (ret2)
157 goto out;
158
159 /*
160 * Clear dsisr under ctxt lock after handling the fault, so that
161 * time slicing will not preempt the context while the page fault
162 * handler is running. Context switch code removes mappings.
163 */
164 ctx->csa.dar = ctx->csa.dsisr = 0;
165
205 /* 166 /*
206 * If we handled the fault successfully and are in runnable 167 * If we handled the fault successfully and are in runnable
207 * state, restart the DMA. 168 * state, restart the DMA.
@@ -222,9 +183,9 @@ int spufs_handle_class1(struct spu_context *ctx)
222 if (ctx->spu) 183 if (ctx->spu)
223 ctx->ops->restart_dma(ctx); 184 ctx->ops->restart_dma(ctx);
224 } else 185 } else
225 spufs_handle_dma_error(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE); 186 spufs_handle_event(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE);
226 187
188 out:
227 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); 189 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
228 return ret; 190 return ret;
229} 191}
230EXPORT_SYMBOL_GPL(spufs_handle_class1);
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index d9e56a503795..3fcd06418b01 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -40,6 +40,120 @@
40 40
41#define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000) 41#define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000)
42 42
43/* Simple attribute files */
44struct spufs_attr {
45 int (*get)(void *, u64 *);
46 int (*set)(void *, u64);
47 char get_buf[24]; /* enough to store a u64 and "\n\0" */
48 char set_buf[24];
49 void *data;
50 const char *fmt; /* format for read operation */
51 struct mutex mutex; /* protects access to these buffers */
52};
53
54static int spufs_attr_open(struct inode *inode, struct file *file,
55 int (*get)(void *, u64 *), int (*set)(void *, u64),
56 const char *fmt)
57{
58 struct spufs_attr *attr;
59
60 attr = kmalloc(sizeof(*attr), GFP_KERNEL);
61 if (!attr)
62 return -ENOMEM;
63
64 attr->get = get;
65 attr->set = set;
66 attr->data = inode->i_private;
67 attr->fmt = fmt;
68 mutex_init(&attr->mutex);
69 file->private_data = attr;
70
71 return nonseekable_open(inode, file);
72}
73
74static int spufs_attr_release(struct inode *inode, struct file *file)
75{
76 kfree(file->private_data);
77 return 0;
78}
79
80static ssize_t spufs_attr_read(struct file *file, char __user *buf,
81 size_t len, loff_t *ppos)
82{
83 struct spufs_attr *attr;
84 size_t size;
85 ssize_t ret;
86
87 attr = file->private_data;
88 if (!attr->get)
89 return -EACCES;
90
91 ret = mutex_lock_interruptible(&attr->mutex);
92 if (ret)
93 return ret;
94
95 if (*ppos) { /* continued read */
96 size = strlen(attr->get_buf);
97 } else { /* first read */
98 u64 val;
99 ret = attr->get(attr->data, &val);
100 if (ret)
101 goto out;
102
103 size = scnprintf(attr->get_buf, sizeof(attr->get_buf),
104 attr->fmt, (unsigned long long)val);
105 }
106
107 ret = simple_read_from_buffer(buf, len, ppos, attr->get_buf, size);
108out:
109 mutex_unlock(&attr->mutex);
110 return ret;
111}
112
113static ssize_t spufs_attr_write(struct file *file, const char __user *buf,
114 size_t len, loff_t *ppos)
115{
116 struct spufs_attr *attr;
117 u64 val;
118 size_t size;
119 ssize_t ret;
120
121 attr = file->private_data;
122 if (!attr->set)
123 return -EACCES;
124
125 ret = mutex_lock_interruptible(&attr->mutex);
126 if (ret)
127 return ret;
128
129 ret = -EFAULT;
130 size = min(sizeof(attr->set_buf) - 1, len);
131 if (copy_from_user(attr->set_buf, buf, size))
132 goto out;
133
134 ret = len; /* claim we got the whole input */
135 attr->set_buf[size] = '\0';
136 val = simple_strtol(attr->set_buf, NULL, 0);
137 attr->set(attr->data, val);
138out:
139 mutex_unlock(&attr->mutex);
140 return ret;
141}
142
143#define DEFINE_SPUFS_SIMPLE_ATTRIBUTE(__fops, __get, __set, __fmt) \
144static int __fops ## _open(struct inode *inode, struct file *file) \
145{ \
146 __simple_attr_check_format(__fmt, 0ull); \
147 return spufs_attr_open(inode, file, __get, __set, __fmt); \
148} \
149static struct file_operations __fops = { \
150 .owner = THIS_MODULE, \
151 .open = __fops ## _open, \
152 .release = spufs_attr_release, \
153 .read = spufs_attr_read, \
154 .write = spufs_attr_write, \
155};
156
43 157
44static int 158static int
45spufs_mem_open(struct inode *inode, struct file *file) 159spufs_mem_open(struct inode *inode, struct file *file)
@@ -84,9 +198,12 @@ spufs_mem_read(struct file *file, char __user *buffer,
84 struct spu_context *ctx = file->private_data; 198 struct spu_context *ctx = file->private_data;
85 ssize_t ret; 199 ssize_t ret;
86 200
87 spu_acquire(ctx); 201 ret = spu_acquire(ctx);
202 if (ret)
203 return ret;
88 ret = __spufs_mem_read(ctx, buffer, size, pos); 204 ret = __spufs_mem_read(ctx, buffer, size, pos);
89 spu_release(ctx); 205 spu_release(ctx);
206
90 return ret; 207 return ret;
91} 208}
92 209
@@ -106,7 +223,10 @@ spufs_mem_write(struct file *file, const char __user *buffer,
106 if (size > LS_SIZE - pos) 223 if (size > LS_SIZE - pos)
107 size = LS_SIZE - pos; 224 size = LS_SIZE - pos;
108 225
109 spu_acquire(ctx); 226 ret = spu_acquire(ctx);
227 if (ret)
228 return ret;
229
110 local_store = ctx->ops->get_ls(ctx); 230 local_store = ctx->ops->get_ls(ctx);
111 ret = copy_from_user(local_store + pos, buffer, size); 231 ret = copy_from_user(local_store + pos, buffer, size);
112 spu_release(ctx); 232 spu_release(ctx);
@@ -146,7 +266,8 @@ static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma,
146 pr_debug("spufs_mem_mmap_nopfn address=0x%lx -> 0x%lx, offset=0x%lx\n", 266 pr_debug("spufs_mem_mmap_nopfn address=0x%lx -> 0x%lx, offset=0x%lx\n",
147 addr0, address, offset); 267 addr0, address, offset);
148 268
149 spu_acquire(ctx); 269 if (spu_acquire(ctx))
270 return NOPFN_REFAULT;
150 271
151 if (ctx->state == SPU_STATE_SAVED) { 272 if (ctx->state == SPU_STATE_SAVED) {
152 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 273 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
@@ -236,23 +357,32 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
236{ 357{
237 struct spu_context *ctx = vma->vm_file->private_data; 358 struct spu_context *ctx = vma->vm_file->private_data;
238 unsigned long area, offset = address - vma->vm_start; 359 unsigned long area, offset = address - vma->vm_start;
239 int ret;
240 360
241 offset += vma->vm_pgoff << PAGE_SHIFT; 361 offset += vma->vm_pgoff << PAGE_SHIFT;
242 if (offset >= ps_size) 362 if (offset >= ps_size)
243 return NOPFN_SIGBUS; 363 return NOPFN_SIGBUS;
244 364
245 /* error here usually means a signal.. we might want to test 365 /*
246 * the error code more precisely though 366 * We have to wait for context to be loaded before we have
367 * pages to hand out to the user, but we don't want to wait
368 * with the mmap_sem held.
369 * It is possible to drop the mmap_sem here, but then we need
370 * to return NOPFN_REFAULT because the mappings may have
371 * hanged.
247 */ 372 */
248 ret = spu_acquire_runnable(ctx, 0); 373 if (spu_acquire(ctx))
249 if (ret)
250 return NOPFN_REFAULT; 374 return NOPFN_REFAULT;
251 375
252 area = ctx->spu->problem_phys + ps_offs; 376 if (ctx->state == SPU_STATE_SAVED) {
253 vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT); 377 up_read(&current->mm->mmap_sem);
254 spu_release(ctx); 378 spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
379 down_read(&current->mm->mmap_sem);
380 } else {
381 area = ctx->spu->problem_phys + ps_offs;
382 vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT);
383 }
255 384
385 spu_release(ctx);
256 return NOPFN_REFAULT; 386 return NOPFN_REFAULT;
257} 387}
258 388
@@ -286,25 +416,32 @@ static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma)
286#define spufs_cntl_mmap NULL 416#define spufs_cntl_mmap NULL
287#endif /* !SPUFS_MMAP_4K */ 417#endif /* !SPUFS_MMAP_4K */
288 418
289static u64 spufs_cntl_get(void *data) 419static int spufs_cntl_get(void *data, u64 *val)
290{ 420{
291 struct spu_context *ctx = data; 421 struct spu_context *ctx = data;
292 u64 val; 422 int ret;
293 423
294 spu_acquire(ctx); 424 ret = spu_acquire(ctx);
295 val = ctx->ops->status_read(ctx); 425 if (ret)
426 return ret;
427 *val = ctx->ops->status_read(ctx);
296 spu_release(ctx); 428 spu_release(ctx);
297 429
298 return val; 430 return 0;
299} 431}
300 432
301static void spufs_cntl_set(void *data, u64 val) 433static int spufs_cntl_set(void *data, u64 val)
302{ 434{
303 struct spu_context *ctx = data; 435 struct spu_context *ctx = data;
436 int ret;
304 437
305 spu_acquire(ctx); 438 ret = spu_acquire(ctx);
439 if (ret)
440 return ret;
306 ctx->ops->runcntl_write(ctx, val); 441 ctx->ops->runcntl_write(ctx, val);
307 spu_release(ctx); 442 spu_release(ctx);
443
444 return 0;
308} 445}
309 446
310static int spufs_cntl_open(struct inode *inode, struct file *file) 447static int spufs_cntl_open(struct inode *inode, struct file *file)
@@ -317,7 +454,7 @@ static int spufs_cntl_open(struct inode *inode, struct file *file)
317 if (!i->i_openers++) 454 if (!i->i_openers++)
318 ctx->cntl = inode->i_mapping; 455 ctx->cntl = inode->i_mapping;
319 mutex_unlock(&ctx->mapping_lock); 456 mutex_unlock(&ctx->mapping_lock);
320 return simple_attr_open(inode, file, spufs_cntl_get, 457 return spufs_attr_open(inode, file, spufs_cntl_get,
321 spufs_cntl_set, "0x%08lx"); 458 spufs_cntl_set, "0x%08lx");
322} 459}
323 460
@@ -327,7 +464,7 @@ spufs_cntl_release(struct inode *inode, struct file *file)
327 struct spufs_inode_info *i = SPUFS_I(inode); 464 struct spufs_inode_info *i = SPUFS_I(inode);
328 struct spu_context *ctx = i->i_ctx; 465 struct spu_context *ctx = i->i_ctx;
329 466
330 simple_attr_close(inode, file); 467 spufs_attr_release(inode, file);
331 468
332 mutex_lock(&ctx->mapping_lock); 469 mutex_lock(&ctx->mapping_lock);
333 if (!--i->i_openers) 470 if (!--i->i_openers)
@@ -339,8 +476,8 @@ spufs_cntl_release(struct inode *inode, struct file *file)
339static const struct file_operations spufs_cntl_fops = { 476static const struct file_operations spufs_cntl_fops = {
340 .open = spufs_cntl_open, 477 .open = spufs_cntl_open,
341 .release = spufs_cntl_release, 478 .release = spufs_cntl_release,
342 .read = simple_attr_read, 479 .read = spufs_attr_read,
343 .write = simple_attr_write, 480 .write = spufs_attr_write,
344 .mmap = spufs_cntl_mmap, 481 .mmap = spufs_cntl_mmap,
345}; 482};
346 483
@@ -368,7 +505,9 @@ spufs_regs_read(struct file *file, char __user *buffer,
368 int ret; 505 int ret;
369 struct spu_context *ctx = file->private_data; 506 struct spu_context *ctx = file->private_data;
370 507
371 spu_acquire_saved(ctx); 508 ret = spu_acquire_saved(ctx);
509 if (ret)
510 return ret;
372 ret = __spufs_regs_read(ctx, buffer, size, pos); 511 ret = __spufs_regs_read(ctx, buffer, size, pos);
373 spu_release_saved(ctx); 512 spu_release_saved(ctx);
374 return ret; 513 return ret;
@@ -387,7 +526,9 @@ spufs_regs_write(struct file *file, const char __user *buffer,
387 return -EFBIG; 526 return -EFBIG;
388 *pos += size; 527 *pos += size;
389 528
390 spu_acquire_saved(ctx); 529 ret = spu_acquire_saved(ctx);
530 if (ret)
531 return ret;
391 532
392 ret = copy_from_user(lscsa->gprs + *pos - size, 533 ret = copy_from_user(lscsa->gprs + *pos - size,
393 buffer, size) ? -EFAULT : size; 534 buffer, size) ? -EFAULT : size;
@@ -419,7 +560,9 @@ spufs_fpcr_read(struct file *file, char __user * buffer,
419 int ret; 560 int ret;
420 struct spu_context *ctx = file->private_data; 561 struct spu_context *ctx = file->private_data;
421 562
422 spu_acquire_saved(ctx); 563 ret = spu_acquire_saved(ctx);
564 if (ret)
565 return ret;
423 ret = __spufs_fpcr_read(ctx, buffer, size, pos); 566 ret = __spufs_fpcr_read(ctx, buffer, size, pos);
424 spu_release_saved(ctx); 567 spu_release_saved(ctx);
425 return ret; 568 return ret;
@@ -436,10 +579,12 @@ spufs_fpcr_write(struct file *file, const char __user * buffer,
436 size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size); 579 size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size);
437 if (size <= 0) 580 if (size <= 0)
438 return -EFBIG; 581 return -EFBIG;
439 *pos += size;
440 582
441 spu_acquire_saved(ctx); 583 ret = spu_acquire_saved(ctx);
584 if (ret)
585 return ret;
442 586
587 *pos += size;
443 ret = copy_from_user((char *)&lscsa->fpcr + *pos - size, 588 ret = copy_from_user((char *)&lscsa->fpcr + *pos - size,
444 buffer, size) ? -EFAULT : size; 589 buffer, size) ? -EFAULT : size;
445 590
@@ -486,7 +631,10 @@ static ssize_t spufs_mbox_read(struct file *file, char __user *buf,
486 631
487 udata = (void __user *)buf; 632 udata = (void __user *)buf;
488 633
489 spu_acquire(ctx); 634 count = spu_acquire(ctx);
635 if (count)
636 return count;
637
490 for (count = 0; (count + 4) <= len; count += 4, udata++) { 638 for (count = 0; (count + 4) <= len; count += 4, udata++) {
491 int ret; 639 int ret;
492 ret = ctx->ops->mbox_read(ctx, &mbox_data); 640 ret = ctx->ops->mbox_read(ctx, &mbox_data);
@@ -522,12 +670,15 @@ static ssize_t spufs_mbox_stat_read(struct file *file, char __user *buf,
522 size_t len, loff_t *pos) 670 size_t len, loff_t *pos)
523{ 671{
524 struct spu_context *ctx = file->private_data; 672 struct spu_context *ctx = file->private_data;
673 ssize_t ret;
525 u32 mbox_stat; 674 u32 mbox_stat;
526 675
527 if (len < 4) 676 if (len < 4)
528 return -EINVAL; 677 return -EINVAL;
529 678
530 spu_acquire(ctx); 679 ret = spu_acquire(ctx);
680 if (ret)
681 return ret;
531 682
532 mbox_stat = ctx->ops->mbox_stat_read(ctx) & 0xff; 683 mbox_stat = ctx->ops->mbox_stat_read(ctx) & 0xff;
533 684
@@ -562,6 +713,9 @@ void spufs_ibox_callback(struct spu *spu)
562{ 713{
563 struct spu_context *ctx = spu->ctx; 714 struct spu_context *ctx = spu->ctx;
564 715
716 if (!ctx)
717 return;
718
565 wake_up_all(&ctx->ibox_wq); 719 wake_up_all(&ctx->ibox_wq);
566 kill_fasync(&ctx->ibox_fasync, SIGIO, POLLIN); 720 kill_fasync(&ctx->ibox_fasync, SIGIO, POLLIN);
567} 721}
@@ -593,7 +747,9 @@ static ssize_t spufs_ibox_read(struct file *file, char __user *buf,
593 747
594 udata = (void __user *)buf; 748 udata = (void __user *)buf;
595 749
596 spu_acquire(ctx); 750 count = spu_acquire(ctx);
751 if (count)
752 return count;
597 753
598 /* wait only for the first element */ 754 /* wait only for the first element */
599 count = 0; 755 count = 0;
@@ -639,7 +795,11 @@ static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait)
639 795
640 poll_wait(file, &ctx->ibox_wq, wait); 796 poll_wait(file, &ctx->ibox_wq, wait);
641 797
642 spu_acquire(ctx); 798 /*
799 * For now keep this uninterruptible and also ignore the rule
800 * that poll should not sleep. Will be fixed later.
801 */
802 mutex_lock(&ctx->state_mutex);
643 mask = ctx->ops->mbox_stat_poll(ctx, POLLIN | POLLRDNORM); 803 mask = ctx->ops->mbox_stat_poll(ctx, POLLIN | POLLRDNORM);
644 spu_release(ctx); 804 spu_release(ctx);
645 805
@@ -657,12 +817,15 @@ static ssize_t spufs_ibox_stat_read(struct file *file, char __user *buf,
657 size_t len, loff_t *pos) 817 size_t len, loff_t *pos)
658{ 818{
659 struct spu_context *ctx = file->private_data; 819 struct spu_context *ctx = file->private_data;
820 ssize_t ret;
660 u32 ibox_stat; 821 u32 ibox_stat;
661 822
662 if (len < 4) 823 if (len < 4)
663 return -EINVAL; 824 return -EINVAL;
664 825
665 spu_acquire(ctx); 826 ret = spu_acquire(ctx);
827 if (ret)
828 return ret;
666 ibox_stat = (ctx->ops->mbox_stat_read(ctx) >> 16) & 0xff; 829 ibox_stat = (ctx->ops->mbox_stat_read(ctx) >> 16) & 0xff;
667 spu_release(ctx); 830 spu_release(ctx);
668 831
@@ -698,6 +861,9 @@ void spufs_wbox_callback(struct spu *spu)
698{ 861{
699 struct spu_context *ctx = spu->ctx; 862 struct spu_context *ctx = spu->ctx;
700 863
864 if (!ctx)
865 return;
866
701 wake_up_all(&ctx->wbox_wq); 867 wake_up_all(&ctx->wbox_wq);
702 kill_fasync(&ctx->wbox_fasync, SIGIO, POLLOUT); 868 kill_fasync(&ctx->wbox_fasync, SIGIO, POLLOUT);
703} 869}
@@ -731,7 +897,9 @@ static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
731 if (__get_user(wbox_data, udata)) 897 if (__get_user(wbox_data, udata))
732 return -EFAULT; 898 return -EFAULT;
733 899
734 spu_acquire(ctx); 900 count = spu_acquire(ctx);
901 if (count)
902 return count;
735 903
736 /* 904 /*
737 * make sure we can at least write one element, by waiting 905 * make sure we can at least write one element, by waiting
@@ -772,7 +940,11 @@ static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait)
772 940
773 poll_wait(file, &ctx->wbox_wq, wait); 941 poll_wait(file, &ctx->wbox_wq, wait);
774 942
775 spu_acquire(ctx); 943 /*
944 * For now keep this uninterruptible and also ignore the rule
945 * that poll should not sleep. Will be fixed later.
946 */
947 mutex_lock(&ctx->state_mutex);
776 mask = ctx->ops->mbox_stat_poll(ctx, POLLOUT | POLLWRNORM); 948 mask = ctx->ops->mbox_stat_poll(ctx, POLLOUT | POLLWRNORM);
777 spu_release(ctx); 949 spu_release(ctx);
778 950
@@ -790,12 +962,15 @@ static ssize_t spufs_wbox_stat_read(struct file *file, char __user *buf,
790 size_t len, loff_t *pos) 962 size_t len, loff_t *pos)
791{ 963{
792 struct spu_context *ctx = file->private_data; 964 struct spu_context *ctx = file->private_data;
965 ssize_t ret;
793 u32 wbox_stat; 966 u32 wbox_stat;
794 967
795 if (len < 4) 968 if (len < 4)
796 return -EINVAL; 969 return -EINVAL;
797 970
798 spu_acquire(ctx); 971 ret = spu_acquire(ctx);
972 if (ret)
973 return ret;
799 wbox_stat = (ctx->ops->mbox_stat_read(ctx) >> 8) & 0xff; 974 wbox_stat = (ctx->ops->mbox_stat_read(ctx) >> 8) & 0xff;
800 spu_release(ctx); 975 spu_release(ctx);
801 976
@@ -866,7 +1041,9 @@ static ssize_t spufs_signal1_read(struct file *file, char __user *buf,
866 int ret; 1041 int ret;
867 struct spu_context *ctx = file->private_data; 1042 struct spu_context *ctx = file->private_data;
868 1043
869 spu_acquire_saved(ctx); 1044 ret = spu_acquire_saved(ctx);
1045 if (ret)
1046 return ret;
870 ret = __spufs_signal1_read(ctx, buf, len, pos); 1047 ret = __spufs_signal1_read(ctx, buf, len, pos);
871 spu_release_saved(ctx); 1048 spu_release_saved(ctx);
872 1049
@@ -877,6 +1054,7 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
877 size_t len, loff_t *pos) 1054 size_t len, loff_t *pos)
878{ 1055{
879 struct spu_context *ctx; 1056 struct spu_context *ctx;
1057 ssize_t ret;
880 u32 data; 1058 u32 data;
881 1059
882 ctx = file->private_data; 1060 ctx = file->private_data;
@@ -887,7 +1065,9 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
887 if (copy_from_user(&data, buf, 4)) 1065 if (copy_from_user(&data, buf, 4))
888 return -EFAULT; 1066 return -EFAULT;
889 1067
890 spu_acquire(ctx); 1068 ret = spu_acquire(ctx);
1069 if (ret)
1070 return ret;
891 ctx->ops->signal1_write(ctx, data); 1071 ctx->ops->signal1_write(ctx, data);
892 spu_release(ctx); 1072 spu_release(ctx);
893 1073
@@ -997,7 +1177,9 @@ static ssize_t spufs_signal2_read(struct file *file, char __user *buf,
997 struct spu_context *ctx = file->private_data; 1177 struct spu_context *ctx = file->private_data;
998 int ret; 1178 int ret;
999 1179
1000 spu_acquire_saved(ctx); 1180 ret = spu_acquire_saved(ctx);
1181 if (ret)
1182 return ret;
1001 ret = __spufs_signal2_read(ctx, buf, len, pos); 1183 ret = __spufs_signal2_read(ctx, buf, len, pos);
1002 spu_release_saved(ctx); 1184 spu_release_saved(ctx);
1003 1185
@@ -1008,6 +1190,7 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf,
1008 size_t len, loff_t *pos) 1190 size_t len, loff_t *pos)
1009{ 1191{
1010 struct spu_context *ctx; 1192 struct spu_context *ctx;
1193 ssize_t ret;
1011 u32 data; 1194 u32 data;
1012 1195
1013 ctx = file->private_data; 1196 ctx = file->private_data;
@@ -1018,7 +1201,9 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf,
1018 if (copy_from_user(&data, buf, 4)) 1201 if (copy_from_user(&data, buf, 4))
1019 return -EFAULT; 1202 return -EFAULT;
1020 1203
1021 spu_acquire(ctx); 1204 ret = spu_acquire(ctx);
1205 if (ret)
1206 return ret;
1022 ctx->ops->signal2_write(ctx, data); 1207 ctx->ops->signal2_write(ctx, data);
1023 spu_release(ctx); 1208 spu_release(ctx);
1024 1209
@@ -1086,33 +1271,42 @@ static const struct file_operations spufs_signal2_nosched_fops = {
1086#define SPU_ATTR_ACQUIRE_SAVED 2 1271#define SPU_ATTR_ACQUIRE_SAVED 2
1087 1272
1088#define DEFINE_SPUFS_ATTRIBUTE(__name, __get, __set, __fmt, __acquire) \ 1273#define DEFINE_SPUFS_ATTRIBUTE(__name, __get, __set, __fmt, __acquire) \
1089static u64 __##__get(void *data) \ 1274static int __##__get(void *data, u64 *val) \
1090{ \ 1275{ \
1091 struct spu_context *ctx = data; \ 1276 struct spu_context *ctx = data; \
1092 u64 ret; \ 1277 int ret = 0; \
1093 \ 1278 \
1094 if (__acquire == SPU_ATTR_ACQUIRE) { \ 1279 if (__acquire == SPU_ATTR_ACQUIRE) { \
1095 spu_acquire(ctx); \ 1280 ret = spu_acquire(ctx); \
1096 ret = __get(ctx); \ 1281 if (ret) \
1282 return ret; \
1283 *val = __get(ctx); \
1097 spu_release(ctx); \ 1284 spu_release(ctx); \
1098 } else if (__acquire == SPU_ATTR_ACQUIRE_SAVED) { \ 1285 } else if (__acquire == SPU_ATTR_ACQUIRE_SAVED) { \
1099 spu_acquire_saved(ctx); \ 1286 ret = spu_acquire_saved(ctx); \
1100 ret = __get(ctx); \ 1287 if (ret) \
1288 return ret; \
1289 *val = __get(ctx); \
1101 spu_release_saved(ctx); \ 1290 spu_release_saved(ctx); \
1102 } else \ 1291 } else \
1103 ret = __get(ctx); \ 1292 *val = __get(ctx); \
1104 \ 1293 \
1105 return ret; \ 1294 return 0; \
1106} \ 1295} \
1107DEFINE_SIMPLE_ATTRIBUTE(__name, __##__get, __set, __fmt); 1296DEFINE_SPUFS_SIMPLE_ATTRIBUTE(__name, __##__get, __set, __fmt);
1108 1297
1109static void spufs_signal1_type_set(void *data, u64 val) 1298static int spufs_signal1_type_set(void *data, u64 val)
1110{ 1299{
1111 struct spu_context *ctx = data; 1300 struct spu_context *ctx = data;
1301 int ret;
1112 1302
1113 spu_acquire(ctx); 1303 ret = spu_acquire(ctx);
1304 if (ret)
1305 return ret;
1114 ctx->ops->signal1_type_set(ctx, val); 1306 ctx->ops->signal1_type_set(ctx, val);
1115 spu_release(ctx); 1307 spu_release(ctx);
1308
1309 return 0;
1116} 1310}
1117 1311
1118static u64 spufs_signal1_type_get(struct spu_context *ctx) 1312static u64 spufs_signal1_type_get(struct spu_context *ctx)
@@ -1123,13 +1317,18 @@ DEFINE_SPUFS_ATTRIBUTE(spufs_signal1_type, spufs_signal1_type_get,
1123 spufs_signal1_type_set, "%llu", SPU_ATTR_ACQUIRE); 1317 spufs_signal1_type_set, "%llu", SPU_ATTR_ACQUIRE);
1124 1318
1125 1319
1126static void spufs_signal2_type_set(void *data, u64 val) 1320static int spufs_signal2_type_set(void *data, u64 val)
1127{ 1321{
1128 struct spu_context *ctx = data; 1322 struct spu_context *ctx = data;
1323 int ret;
1129 1324
1130 spu_acquire(ctx); 1325 ret = spu_acquire(ctx);
1326 if (ret)
1327 return ret;
1131 ctx->ops->signal2_type_set(ctx, val); 1328 ctx->ops->signal2_type_set(ctx, val);
1132 spu_release(ctx); 1329 spu_release(ctx);
1330
1331 return 0;
1133} 1332}
1134 1333
1135static u64 spufs_signal2_type_get(struct spu_context *ctx) 1334static u64 spufs_signal2_type_get(struct spu_context *ctx)
@@ -1329,6 +1528,9 @@ void spufs_mfc_callback(struct spu *spu)
1329{ 1528{
1330 struct spu_context *ctx = spu->ctx; 1529 struct spu_context *ctx = spu->ctx;
1331 1530
1531 if (!ctx)
1532 return;
1533
1332 wake_up_all(&ctx->mfc_wq); 1534 wake_up_all(&ctx->mfc_wq);
1333 1535
1334 pr_debug("%s %s\n", __FUNCTION__, spu->name); 1536 pr_debug("%s %s\n", __FUNCTION__, spu->name);
@@ -1375,12 +1577,17 @@ static ssize_t spufs_mfc_read(struct file *file, char __user *buffer,
1375 if (size != 4) 1577 if (size != 4)
1376 goto out; 1578 goto out;
1377 1579
1378 spu_acquire(ctx); 1580 ret = spu_acquire(ctx);
1581 if (ret)
1582 return ret;
1583
1584 ret = -EINVAL;
1379 if (file->f_flags & O_NONBLOCK) { 1585 if (file->f_flags & O_NONBLOCK) {
1380 status = ctx->ops->read_mfc_tagstatus(ctx); 1586 status = ctx->ops->read_mfc_tagstatus(ctx);
1381 if (!(status & ctx->tagwait)) 1587 if (!(status & ctx->tagwait))
1382 ret = -EAGAIN; 1588 ret = -EAGAIN;
1383 else 1589 else
1590 /* XXX(hch): shouldn't we clear ret here? */
1384 ctx->tagwait &= ~status; 1591 ctx->tagwait &= ~status;
1385 } else { 1592 } else {
1386 ret = spufs_wait(ctx->mfc_wq, 1593 ret = spufs_wait(ctx->mfc_wq,
@@ -1505,7 +1712,11 @@ static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer,
1505 if (ret) 1712 if (ret)
1506 goto out; 1713 goto out;
1507 1714
1508 ret = spu_acquire_runnable(ctx, 0); 1715 ret = spu_acquire(ctx);
1716 if (ret)
1717 goto out;
1718
1719 ret = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
1509 if (ret) 1720 if (ret)
1510 goto out; 1721 goto out;
1511 1722
@@ -1539,7 +1750,11 @@ static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait)
1539 1750
1540 poll_wait(file, &ctx->mfc_wq, wait); 1751 poll_wait(file, &ctx->mfc_wq, wait);
1541 1752
1542 spu_acquire(ctx); 1753 /*
1754 * For now keep this uninterruptible and also ignore the rule
1755 * that poll should not sleep. Will be fixed later.
1756 */
1757 mutex_lock(&ctx->state_mutex);
1543 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2); 1758 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2);
1544 free_elements = ctx->ops->get_mfc_free_elements(ctx); 1759 free_elements = ctx->ops->get_mfc_free_elements(ctx);
1545 tagstatus = ctx->ops->read_mfc_tagstatus(ctx); 1760 tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
@@ -1562,7 +1777,9 @@ static int spufs_mfc_flush(struct file *file, fl_owner_t id)
1562 struct spu_context *ctx = file->private_data; 1777 struct spu_context *ctx = file->private_data;
1563 int ret; 1778 int ret;
1564 1779
1565 spu_acquire(ctx); 1780 ret = spu_acquire(ctx);
1781 if (ret)
1782 return ret;
1566#if 0 1783#if 0
1567/* this currently hangs */ 1784/* this currently hangs */
1568 ret = spufs_wait(ctx->mfc_wq, 1785 ret = spufs_wait(ctx->mfc_wq,
@@ -1605,12 +1822,18 @@ static const struct file_operations spufs_mfc_fops = {
1605 .mmap = spufs_mfc_mmap, 1822 .mmap = spufs_mfc_mmap,
1606}; 1823};
1607 1824
1608static void spufs_npc_set(void *data, u64 val) 1825static int spufs_npc_set(void *data, u64 val)
1609{ 1826{
1610 struct spu_context *ctx = data; 1827 struct spu_context *ctx = data;
1611 spu_acquire(ctx); 1828 int ret;
1829
1830 ret = spu_acquire(ctx);
1831 if (ret)
1832 return ret;
1612 ctx->ops->npc_write(ctx, val); 1833 ctx->ops->npc_write(ctx, val);
1613 spu_release(ctx); 1834 spu_release(ctx);
1835
1836 return 0;
1614} 1837}
1615 1838
1616static u64 spufs_npc_get(struct spu_context *ctx) 1839static u64 spufs_npc_get(struct spu_context *ctx)
@@ -1620,13 +1843,19 @@ static u64 spufs_npc_get(struct spu_context *ctx)
1620DEFINE_SPUFS_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set, 1843DEFINE_SPUFS_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set,
1621 "0x%llx\n", SPU_ATTR_ACQUIRE); 1844 "0x%llx\n", SPU_ATTR_ACQUIRE);
1622 1845
1623static void spufs_decr_set(void *data, u64 val) 1846static int spufs_decr_set(void *data, u64 val)
1624{ 1847{
1625 struct spu_context *ctx = data; 1848 struct spu_context *ctx = data;
1626 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1849 struct spu_lscsa *lscsa = ctx->csa.lscsa;
1627 spu_acquire_saved(ctx); 1850 int ret;
1851
1852 ret = spu_acquire_saved(ctx);
1853 if (ret)
1854 return ret;
1628 lscsa->decr.slot[0] = (u32) val; 1855 lscsa->decr.slot[0] = (u32) val;
1629 spu_release_saved(ctx); 1856 spu_release_saved(ctx);
1857
1858 return 0;
1630} 1859}
1631 1860
1632static u64 spufs_decr_get(struct spu_context *ctx) 1861static u64 spufs_decr_get(struct spu_context *ctx)
@@ -1637,15 +1866,21 @@ static u64 spufs_decr_get(struct spu_context *ctx)
1637DEFINE_SPUFS_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set, 1866DEFINE_SPUFS_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set,
1638 "0x%llx\n", SPU_ATTR_ACQUIRE_SAVED); 1867 "0x%llx\n", SPU_ATTR_ACQUIRE_SAVED);
1639 1868
1640static void spufs_decr_status_set(void *data, u64 val) 1869static int spufs_decr_status_set(void *data, u64 val)
1641{ 1870{
1642 struct spu_context *ctx = data; 1871 struct spu_context *ctx = data;
1643 spu_acquire_saved(ctx); 1872 int ret;
1873
1874 ret = spu_acquire_saved(ctx);
1875 if (ret)
1876 return ret;
1644 if (val) 1877 if (val)
1645 ctx->csa.priv2.mfc_control_RW |= MFC_CNTL_DECREMENTER_RUNNING; 1878 ctx->csa.priv2.mfc_control_RW |= MFC_CNTL_DECREMENTER_RUNNING;
1646 else 1879 else
1647 ctx->csa.priv2.mfc_control_RW &= ~MFC_CNTL_DECREMENTER_RUNNING; 1880 ctx->csa.priv2.mfc_control_RW &= ~MFC_CNTL_DECREMENTER_RUNNING;
1648 spu_release_saved(ctx); 1881 spu_release_saved(ctx);
1882
1883 return 0;
1649} 1884}
1650 1885
1651static u64 spufs_decr_status_get(struct spu_context *ctx) 1886static u64 spufs_decr_status_get(struct spu_context *ctx)
@@ -1659,13 +1894,19 @@ DEFINE_SPUFS_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get,
1659 spufs_decr_status_set, "0x%llx\n", 1894 spufs_decr_status_set, "0x%llx\n",
1660 SPU_ATTR_ACQUIRE_SAVED); 1895 SPU_ATTR_ACQUIRE_SAVED);
1661 1896
1662static void spufs_event_mask_set(void *data, u64 val) 1897static int spufs_event_mask_set(void *data, u64 val)
1663{ 1898{
1664 struct spu_context *ctx = data; 1899 struct spu_context *ctx = data;
1665 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1900 struct spu_lscsa *lscsa = ctx->csa.lscsa;
1666 spu_acquire_saved(ctx); 1901 int ret;
1902
1903 ret = spu_acquire_saved(ctx);
1904 if (ret)
1905 return ret;
1667 lscsa->event_mask.slot[0] = (u32) val; 1906 lscsa->event_mask.slot[0] = (u32) val;
1668 spu_release_saved(ctx); 1907 spu_release_saved(ctx);
1908
1909 return 0;
1669} 1910}
1670 1911
1671static u64 spufs_event_mask_get(struct spu_context *ctx) 1912static u64 spufs_event_mask_get(struct spu_context *ctx)
@@ -1690,13 +1931,19 @@ static u64 spufs_event_status_get(struct spu_context *ctx)
1690DEFINE_SPUFS_ATTRIBUTE(spufs_event_status_ops, spufs_event_status_get, 1931DEFINE_SPUFS_ATTRIBUTE(spufs_event_status_ops, spufs_event_status_get,
1691 NULL, "0x%llx\n", SPU_ATTR_ACQUIRE_SAVED) 1932 NULL, "0x%llx\n", SPU_ATTR_ACQUIRE_SAVED)
1692 1933
1693static void spufs_srr0_set(void *data, u64 val) 1934static int spufs_srr0_set(void *data, u64 val)
1694{ 1935{
1695 struct spu_context *ctx = data; 1936 struct spu_context *ctx = data;
1696 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1937 struct spu_lscsa *lscsa = ctx->csa.lscsa;
1697 spu_acquire_saved(ctx); 1938 int ret;
1939
1940 ret = spu_acquire_saved(ctx);
1941 if (ret)
1942 return ret;
1698 lscsa->srr0.slot[0] = (u32) val; 1943 lscsa->srr0.slot[0] = (u32) val;
1699 spu_release_saved(ctx); 1944 spu_release_saved(ctx);
1945
1946 return 0;
1700} 1947}
1701 1948
1702static u64 spufs_srr0_get(struct spu_context *ctx) 1949static u64 spufs_srr0_get(struct spu_context *ctx)
@@ -1727,10 +1974,12 @@ static u64 spufs_object_id_get(struct spu_context *ctx)
1727 return ctx->object_id; 1974 return ctx->object_id;
1728} 1975}
1729 1976
1730static void spufs_object_id_set(void *data, u64 id) 1977static int spufs_object_id_set(void *data, u64 id)
1731{ 1978{
1732 struct spu_context *ctx = data; 1979 struct spu_context *ctx = data;
1733 ctx->object_id = id; 1980 ctx->object_id = id;
1981
1982 return 0;
1734} 1983}
1735 1984
1736DEFINE_SPUFS_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get, 1985DEFINE_SPUFS_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get,
@@ -1777,13 +2026,13 @@ static const struct file_operations spufs_caps_fops = {
1777static ssize_t __spufs_mbox_info_read(struct spu_context *ctx, 2026static ssize_t __spufs_mbox_info_read(struct spu_context *ctx,
1778 char __user *buf, size_t len, loff_t *pos) 2027 char __user *buf, size_t len, loff_t *pos)
1779{ 2028{
1780 u32 mbox_stat;
1781 u32 data; 2029 u32 data;
1782 2030
1783 mbox_stat = ctx->csa.prob.mb_stat_R; 2031 /* EOF if there's no entry in the mbox */
1784 if (mbox_stat & 0x0000ff) { 2032 if (!(ctx->csa.prob.mb_stat_R & 0x0000ff))
1785 data = ctx->csa.prob.pu_mb_R; 2033 return 0;
1786 } 2034
2035 data = ctx->csa.prob.pu_mb_R;
1787 2036
1788 return simple_read_from_buffer(buf, len, pos, &data, sizeof data); 2037 return simple_read_from_buffer(buf, len, pos, &data, sizeof data);
1789} 2038}
@@ -1797,7 +2046,9 @@ static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf,
1797 if (!access_ok(VERIFY_WRITE, buf, len)) 2046 if (!access_ok(VERIFY_WRITE, buf, len))
1798 return -EFAULT; 2047 return -EFAULT;
1799 2048
1800 spu_acquire_saved(ctx); 2049 ret = spu_acquire_saved(ctx);
2050 if (ret)
2051 return ret;
1801 spin_lock(&ctx->csa.register_lock); 2052 spin_lock(&ctx->csa.register_lock);
1802 ret = __spufs_mbox_info_read(ctx, buf, len, pos); 2053 ret = __spufs_mbox_info_read(ctx, buf, len, pos);
1803 spin_unlock(&ctx->csa.register_lock); 2054 spin_unlock(&ctx->csa.register_lock);
@@ -1815,13 +2066,13 @@ static const struct file_operations spufs_mbox_info_fops = {
1815static ssize_t __spufs_ibox_info_read(struct spu_context *ctx, 2066static ssize_t __spufs_ibox_info_read(struct spu_context *ctx,
1816 char __user *buf, size_t len, loff_t *pos) 2067 char __user *buf, size_t len, loff_t *pos)
1817{ 2068{
1818 u32 ibox_stat;
1819 u32 data; 2069 u32 data;
1820 2070
1821 ibox_stat = ctx->csa.prob.mb_stat_R; 2071 /* EOF if there's no entry in the ibox */
1822 if (ibox_stat & 0xff0000) { 2072 if (!(ctx->csa.prob.mb_stat_R & 0xff0000))
1823 data = ctx->csa.priv2.puint_mb_R; 2073 return 0;
1824 } 2074
2075 data = ctx->csa.priv2.puint_mb_R;
1825 2076
1826 return simple_read_from_buffer(buf, len, pos, &data, sizeof data); 2077 return simple_read_from_buffer(buf, len, pos, &data, sizeof data);
1827} 2078}
@@ -1835,7 +2086,9 @@ static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf,
1835 if (!access_ok(VERIFY_WRITE, buf, len)) 2086 if (!access_ok(VERIFY_WRITE, buf, len))
1836 return -EFAULT; 2087 return -EFAULT;
1837 2088
1838 spu_acquire_saved(ctx); 2089 ret = spu_acquire_saved(ctx);
2090 if (ret)
2091 return ret;
1839 spin_lock(&ctx->csa.register_lock); 2092 spin_lock(&ctx->csa.register_lock);
1840 ret = __spufs_ibox_info_read(ctx, buf, len, pos); 2093 ret = __spufs_ibox_info_read(ctx, buf, len, pos);
1841 spin_unlock(&ctx->csa.register_lock); 2094 spin_unlock(&ctx->csa.register_lock);
@@ -1876,7 +2129,9 @@ static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf,
1876 if (!access_ok(VERIFY_WRITE, buf, len)) 2129 if (!access_ok(VERIFY_WRITE, buf, len))
1877 return -EFAULT; 2130 return -EFAULT;
1878 2131
1879 spu_acquire_saved(ctx); 2132 ret = spu_acquire_saved(ctx);
2133 if (ret)
2134 return ret;
1880 spin_lock(&ctx->csa.register_lock); 2135 spin_lock(&ctx->csa.register_lock);
1881 ret = __spufs_wbox_info_read(ctx, buf, len, pos); 2136 ret = __spufs_wbox_info_read(ctx, buf, len, pos);
1882 spin_unlock(&ctx->csa.register_lock); 2137 spin_unlock(&ctx->csa.register_lock);
@@ -1926,7 +2181,9 @@ static ssize_t spufs_dma_info_read(struct file *file, char __user *buf,
1926 if (!access_ok(VERIFY_WRITE, buf, len)) 2181 if (!access_ok(VERIFY_WRITE, buf, len))
1927 return -EFAULT; 2182 return -EFAULT;
1928 2183
1929 spu_acquire_saved(ctx); 2184 ret = spu_acquire_saved(ctx);
2185 if (ret)
2186 return ret;
1930 spin_lock(&ctx->csa.register_lock); 2187 spin_lock(&ctx->csa.register_lock);
1931 ret = __spufs_dma_info_read(ctx, buf, len, pos); 2188 ret = __spufs_dma_info_read(ctx, buf, len, pos);
1932 spin_unlock(&ctx->csa.register_lock); 2189 spin_unlock(&ctx->csa.register_lock);
@@ -1977,7 +2234,9 @@ static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf,
1977 struct spu_context *ctx = file->private_data; 2234 struct spu_context *ctx = file->private_data;
1978 int ret; 2235 int ret;
1979 2236
1980 spu_acquire_saved(ctx); 2237 ret = spu_acquire_saved(ctx);
2238 if (ret)
2239 return ret;
1981 spin_lock(&ctx->csa.register_lock); 2240 spin_lock(&ctx->csa.register_lock);
1982 ret = __spufs_proxydma_info_read(ctx, buf, len, pos); 2241 ret = __spufs_proxydma_info_read(ctx, buf, len, pos);
1983 spin_unlock(&ctx->csa.register_lock); 2242 spin_unlock(&ctx->csa.register_lock);
@@ -2066,8 +2325,12 @@ static unsigned long long spufs_class2_intrs(struct spu_context *ctx)
2066static int spufs_show_stat(struct seq_file *s, void *private) 2325static int spufs_show_stat(struct seq_file *s, void *private)
2067{ 2326{
2068 struct spu_context *ctx = s->private; 2327 struct spu_context *ctx = s->private;
2328 int ret;
2329
2330 ret = spu_acquire(ctx);
2331 if (ret)
2332 return ret;
2069 2333
2070 spu_acquire(ctx);
2071 seq_printf(s, "%s %llu %llu %llu %llu " 2334 seq_printf(s, "%s %llu %llu %llu %llu "
2072 "%llu %llu %llu %llu %llu %llu %llu %llu\n", 2335 "%llu %llu %llu %llu %llu %llu %llu %llu\n",
2073 ctx_state_names[ctx->stats.util_state], 2336 ctx_state_names[ctx->stats.util_state],
diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c
index fc4ed1ffbd4f..64f8540b832c 100644
--- a/arch/powerpc/platforms/cell/spufs/hw_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c
@@ -76,16 +76,18 @@ static unsigned int spu_hw_mbox_stat_poll(struct spu_context *ctx,
76 if (stat & 0xff0000) 76 if (stat & 0xff0000)
77 ret |= POLLIN | POLLRDNORM; 77 ret |= POLLIN | POLLRDNORM;
78 else { 78 else {
79 spu_int_stat_clear(spu, 2, 0x1); 79 spu_int_stat_clear(spu, 2, CLASS2_MAILBOX_INTR);
80 spu_int_mask_or(spu, 2, 0x1); 80 spu_int_mask_or(spu, 2, CLASS2_ENABLE_MAILBOX_INTR);
81 } 81 }
82 } 82 }
83 if (events & (POLLOUT | POLLWRNORM)) { 83 if (events & (POLLOUT | POLLWRNORM)) {
84 if (stat & 0x00ff00) 84 if (stat & 0x00ff00)
85 ret = POLLOUT | POLLWRNORM; 85 ret = POLLOUT | POLLWRNORM;
86 else { 86 else {
87 spu_int_stat_clear(spu, 2, 0x10); 87 spu_int_stat_clear(spu, 2,
88 spu_int_mask_or(spu, 2, 0x10); 88 CLASS2_MAILBOX_THRESHOLD_INTR);
89 spu_int_mask_or(spu, 2,
90 CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR);
89 } 91 }
90 } 92 }
91 spin_unlock_irq(&spu->register_lock); 93 spin_unlock_irq(&spu->register_lock);
@@ -106,7 +108,7 @@ static int spu_hw_ibox_read(struct spu_context *ctx, u32 * data)
106 ret = 4; 108 ret = 4;
107 } else { 109 } else {
108 /* make sure we get woken up by the interrupt */ 110 /* make sure we get woken up by the interrupt */
109 spu_int_mask_or(spu, 2, 0x1); 111 spu_int_mask_or(spu, 2, CLASS2_ENABLE_MAILBOX_INTR);
110 ret = 0; 112 ret = 0;
111 } 113 }
112 spin_unlock_irq(&spu->register_lock); 114 spin_unlock_irq(&spu->register_lock);
@@ -127,7 +129,7 @@ static int spu_hw_wbox_write(struct spu_context *ctx, u32 data)
127 } else { 129 } else {
128 /* make sure we get woken up by the interrupt when space 130 /* make sure we get woken up by the interrupt when space
129 becomes available */ 131 becomes available */
130 spu_int_mask_or(spu, 2, 0x10); 132 spu_int_mask_or(spu, 2, CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR);
131 ret = 0; 133 ret = 0;
132 } 134 }
133 spin_unlock_irq(&spu->register_lock); 135 spin_unlock_irq(&spu->register_lock);
@@ -206,6 +208,11 @@ static char *spu_hw_get_ls(struct spu_context *ctx)
206 return ctx->spu->local_store; 208 return ctx->spu->local_store;
207} 209}
208 210
211static void spu_hw_privcntl_write(struct spu_context *ctx, u64 val)
212{
213 out_be64(&ctx->spu->priv2->spu_privcntl_RW, val);
214}
215
209static u32 spu_hw_runcntl_read(struct spu_context *ctx) 216static u32 spu_hw_runcntl_read(struct spu_context *ctx)
210{ 217{
211 return in_be32(&ctx->spu->problem->spu_runcntl_RW); 218 return in_be32(&ctx->spu->problem->spu_runcntl_RW);
@@ -215,11 +222,21 @@ static void spu_hw_runcntl_write(struct spu_context *ctx, u32 val)
215{ 222{
216 spin_lock_irq(&ctx->spu->register_lock); 223 spin_lock_irq(&ctx->spu->register_lock);
217 if (val & SPU_RUNCNTL_ISOLATE) 224 if (val & SPU_RUNCNTL_ISOLATE)
218 out_be64(&ctx->spu->priv2->spu_privcntl_RW, 4LL); 225 spu_hw_privcntl_write(ctx,
226 SPU_PRIVCNT_LOAD_REQUEST_ENABLE_MASK);
219 out_be32(&ctx->spu->problem->spu_runcntl_RW, val); 227 out_be32(&ctx->spu->problem->spu_runcntl_RW, val);
220 spin_unlock_irq(&ctx->spu->register_lock); 228 spin_unlock_irq(&ctx->spu->register_lock);
221} 229}
222 230
231static void spu_hw_runcntl_stop(struct spu_context *ctx)
232{
233 spin_lock_irq(&ctx->spu->register_lock);
234 out_be32(&ctx->spu->problem->spu_runcntl_RW, SPU_RUNCNTL_STOP);
235 while (in_be32(&ctx->spu->problem->spu_status_R) & SPU_STATUS_RUNNING)
236 cpu_relax();
237 spin_unlock_irq(&ctx->spu->register_lock);
238}
239
223static void spu_hw_master_start(struct spu_context *ctx) 240static void spu_hw_master_start(struct spu_context *ctx)
224{ 241{
225 struct spu *spu = ctx->spu; 242 struct spu *spu = ctx->spu;
@@ -319,8 +336,10 @@ struct spu_context_ops spu_hw_ops = {
319 .npc_write = spu_hw_npc_write, 336 .npc_write = spu_hw_npc_write,
320 .status_read = spu_hw_status_read, 337 .status_read = spu_hw_status_read,
321 .get_ls = spu_hw_get_ls, 338 .get_ls = spu_hw_get_ls,
339 .privcntl_write = spu_hw_privcntl_write,
322 .runcntl_read = spu_hw_runcntl_read, 340 .runcntl_read = spu_hw_runcntl_read,
323 .runcntl_write = spu_hw_runcntl_write, 341 .runcntl_write = spu_hw_runcntl_write,
342 .runcntl_stop = spu_hw_runcntl_stop,
324 .master_start = spu_hw_master_start, 343 .master_start = spu_hw_master_start,
325 .master_stop = spu_hw_master_stop, 344 .master_stop = spu_hw_master_stop,
326 .set_mfc_query = spu_hw_set_mfc_query, 345 .set_mfc_query = spu_hw_set_mfc_query,
diff --git a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c
index f4b3c052dabf..0e9f325c9ff7 100644
--- a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c
+++ b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c
@@ -28,6 +28,8 @@
28#include <asm/spu_csa.h> 28#include <asm/spu_csa.h>
29#include <asm/mmu.h> 29#include <asm/mmu.h>
30 30
31#include "spufs.h"
32
31static int spu_alloc_lscsa_std(struct spu_state *csa) 33static int spu_alloc_lscsa_std(struct spu_state *csa)
32{ 34{
33 struct spu_lscsa *lscsa; 35 struct spu_lscsa *lscsa;
@@ -73,7 +75,7 @@ int spu_alloc_lscsa(struct spu_state *csa)
73 int i, j, n_4k; 75 int i, j, n_4k;
74 76
75 /* Check availability of 64K pages */ 77 /* Check availability of 64K pages */
76 if (mmu_psize_defs[MMU_PAGE_64K].shift == 0) 78 if (!spu_64k_pages_available())
77 goto fail; 79 goto fail;
78 80
79 csa->use_big_pages = 1; 81 csa->use_big_pages = 1;
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index 1ce5e22ea5f4..c01a09da1e56 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -15,24 +15,55 @@ void spufs_stop_callback(struct spu *spu)
15{ 15{
16 struct spu_context *ctx = spu->ctx; 16 struct spu_context *ctx = spu->ctx;
17 17
18 wake_up_all(&ctx->stop_wq); 18 /*
19 * It should be impossible to preempt a context while an exception
20 * is being processed, since the context switch code is specially
21 * coded to deal with interrupts ... But, just in case, sanity check
22 * the context pointer. It is OK to return doing nothing since
23 * the exception will be regenerated when the context is resumed.
24 */
25 if (ctx) {
26 /* Copy exception arguments into module specific structure */
27 ctx->csa.class_0_pending = spu->class_0_pending;
28 ctx->csa.dsisr = spu->dsisr;
29 ctx->csa.dar = spu->dar;
30
31 /* ensure that the exception status has hit memory before a
32 * thread waiting on the context's stop queue is woken */
33 smp_wmb();
34
35 wake_up_all(&ctx->stop_wq);
36 }
37
38 /* Clear callback arguments from spu structure */
39 spu->class_0_pending = 0;
40 spu->dsisr = 0;
41 spu->dar = 0;
19} 42}
20 43
21static inline int spu_stopped(struct spu_context *ctx, u32 *stat) 44int spu_stopped(struct spu_context *ctx, u32 *stat)
22{ 45{
23 struct spu *spu; 46 u64 dsisr;
24 u64 pte_fault; 47 u32 stopped;
25 48
26 *stat = ctx->ops->status_read(ctx); 49 *stat = ctx->ops->status_read(ctx);
27 50
28 spu = ctx->spu; 51 if (test_bit(SPU_SCHED_NOTIFY_ACTIVE, &ctx->sched_flags))
29 if (ctx->state != SPU_STATE_RUNNABLE ||
30 test_bit(SPU_SCHED_NOTIFY_ACTIVE, &ctx->sched_flags))
31 return 1; 52 return 1;
32 pte_fault = spu->dsisr & 53
33 (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED); 54 stopped = SPU_STATUS_INVALID_INSTR | SPU_STATUS_SINGLE_STEP |
34 return (!(*stat & SPU_STATUS_RUNNING) || pte_fault || spu->class_0_pending) ? 55 SPU_STATUS_STOPPED_BY_HALT | SPU_STATUS_STOPPED_BY_STOP;
35 1 : 0; 56 if (*stat & stopped)
57 return 1;
58
59 dsisr = ctx->csa.dsisr;
60 if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED))
61 return 1;
62
63 if (ctx->csa.class_0_pending)
64 return 1;
65
66 return 0;
36} 67}
37 68
38static int spu_setup_isolated(struct spu_context *ctx) 69static int spu_setup_isolated(struct spu_context *ctx)
@@ -128,34 +159,66 @@ out:
128 159
129static int spu_run_init(struct spu_context *ctx, u32 *npc) 160static int spu_run_init(struct spu_context *ctx, u32 *npc)
130{ 161{
162 unsigned long runcntl = SPU_RUNCNTL_RUNNABLE;
163 int ret;
164
131 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); 165 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
132 166
133 if (ctx->flags & SPU_CREATE_ISOLATE) { 167 /*
134 unsigned long runcntl; 168 * NOSCHED is synchronous scheduling with respect to the caller.
169 * The caller waits for the context to be loaded.
170 */
171 if (ctx->flags & SPU_CREATE_NOSCHED) {
172 if (ctx->state == SPU_STATE_SAVED) {
173 ret = spu_activate(ctx, 0);
174 if (ret)
175 return ret;
176 }
177 }
135 178
179 /*
180 * Apply special setup as required.
181 */
182 if (ctx->flags & SPU_CREATE_ISOLATE) {
136 if (!(ctx->ops->status_read(ctx) & SPU_STATUS_ISOLATED_STATE)) { 183 if (!(ctx->ops->status_read(ctx) & SPU_STATUS_ISOLATED_STATE)) {
137 int ret = spu_setup_isolated(ctx); 184 ret = spu_setup_isolated(ctx);
138 if (ret) 185 if (ret)
139 return ret; 186 return ret;
140 } 187 }
141 188
142 /* if userspace has set the runcntrl register (eg, to issue an 189 /*
143 * isolated exit), we need to re-set it here */ 190 * If userspace has set the runcntrl register (eg, to
191 * issue an isolated exit), we need to re-set it here
192 */
144 runcntl = ctx->ops->runcntl_read(ctx) & 193 runcntl = ctx->ops->runcntl_read(ctx) &
145 (SPU_RUNCNTL_RUNNABLE | SPU_RUNCNTL_ISOLATE); 194 (SPU_RUNCNTL_RUNNABLE | SPU_RUNCNTL_ISOLATE);
146 if (runcntl == 0) 195 if (runcntl == 0)
147 runcntl = SPU_RUNCNTL_RUNNABLE; 196 runcntl = SPU_RUNCNTL_RUNNABLE;
197 }
198
199 if (ctx->flags & SPU_CREATE_NOSCHED) {
200 spuctx_switch_state(ctx, SPU_UTIL_USER);
148 ctx->ops->runcntl_write(ctx, runcntl); 201 ctx->ops->runcntl_write(ctx, runcntl);
149 } else { 202 } else {
150 unsigned long mode = SPU_PRIVCNTL_MODE_NORMAL; 203 unsigned long privcntl;
151 ctx->ops->npc_write(ctx, *npc); 204
152 if (test_thread_flag(TIF_SINGLESTEP)) 205 if (test_thread_flag(TIF_SINGLESTEP))
153 mode = SPU_PRIVCNTL_MODE_SINGLE_STEP; 206 privcntl = SPU_PRIVCNTL_MODE_SINGLE_STEP;
154 out_be64(&ctx->spu->priv2->spu_privcntl_RW, mode); 207 else
155 ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE); 208 privcntl = SPU_PRIVCNTL_MODE_NORMAL;
156 }
157 209
158 spuctx_switch_state(ctx, SPU_UTIL_USER); 210 ctx->ops->npc_write(ctx, *npc);
211 ctx->ops->privcntl_write(ctx, privcntl);
212 ctx->ops->runcntl_write(ctx, runcntl);
213
214 if (ctx->state == SPU_STATE_SAVED) {
215 ret = spu_activate(ctx, 0);
216 if (ret)
217 return ret;
218 } else {
219 spuctx_switch_state(ctx, SPU_UTIL_USER);
220 }
221 }
159 222
160 return 0; 223 return 0;
161} 224}
@@ -165,6 +228,8 @@ static int spu_run_fini(struct spu_context *ctx, u32 *npc,
165{ 228{
166 int ret = 0; 229 int ret = 0;
167 230
231 spu_del_from_rq(ctx);
232
168 *status = ctx->ops->status_read(ctx); 233 *status = ctx->ops->status_read(ctx);
169 *npc = ctx->ops->npc_read(ctx); 234 *npc = ctx->ops->npc_read(ctx);
170 235
@@ -177,26 +242,6 @@ static int spu_run_fini(struct spu_context *ctx, u32 *npc,
177 return ret; 242 return ret;
178} 243}
179 244
180static int spu_reacquire_runnable(struct spu_context *ctx, u32 *npc,
181 u32 *status)
182{
183 int ret;
184
185 ret = spu_run_fini(ctx, npc, status);
186 if (ret)
187 return ret;
188
189 if (*status & (SPU_STATUS_STOPPED_BY_STOP | SPU_STATUS_STOPPED_BY_HALT))
190 return *status;
191
192 ret = spu_acquire_runnable(ctx, 0);
193 if (ret)
194 return ret;
195
196 spuctx_switch_state(ctx, SPU_UTIL_USER);
197 return 0;
198}
199
200/* 245/*
201 * SPU syscall restarting is tricky because we violate the basic 246 * SPU syscall restarting is tricky because we violate the basic
202 * assumption that the signal handler is running on the interrupted 247 * assumption that the signal handler is running on the interrupted
@@ -247,7 +292,7 @@ static int spu_process_callback(struct spu_context *ctx)
247 u32 ls_pointer, npc; 292 u32 ls_pointer, npc;
248 void __iomem *ls; 293 void __iomem *ls;
249 long spu_ret; 294 long spu_ret;
250 int ret; 295 int ret, ret2;
251 296
252 /* get syscall block from local store */ 297 /* get syscall block from local store */
253 npc = ctx->ops->npc_read(ctx) & ~3; 298 npc = ctx->ops->npc_read(ctx) & ~3;
@@ -269,9 +314,11 @@ static int spu_process_callback(struct spu_context *ctx)
269 if (spu_ret <= -ERESTARTSYS) { 314 if (spu_ret <= -ERESTARTSYS) {
270 ret = spu_handle_restartsys(ctx, &spu_ret, &npc); 315 ret = spu_handle_restartsys(ctx, &spu_ret, &npc);
271 } 316 }
272 spu_acquire(ctx); 317 ret2 = spu_acquire(ctx);
273 if (ret == -ERESTARTSYS) 318 if (ret == -ERESTARTSYS)
274 return ret; 319 return ret;
320 if (ret2)
321 return -EINTR;
275 } 322 }
276 323
277 /* write result, jump over indirect pointer */ 324 /* write result, jump over indirect pointer */
@@ -281,18 +328,6 @@ static int spu_process_callback(struct spu_context *ctx)
281 return ret; 328 return ret;
282} 329}
283 330
284static inline int spu_process_events(struct spu_context *ctx)
285{
286 struct spu *spu = ctx->spu;
287 int ret = 0;
288
289 if (spu->class_0_pending)
290 ret = spu_irq_class_0_bottom(spu);
291 if (!ret && signal_pending(current))
292 ret = -ERESTARTSYS;
293 return ret;
294}
295
296long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event) 331long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event)
297{ 332{
298 int ret; 333 int ret;
@@ -302,29 +337,14 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event)
302 if (mutex_lock_interruptible(&ctx->run_mutex)) 337 if (mutex_lock_interruptible(&ctx->run_mutex))
303 return -ERESTARTSYS; 338 return -ERESTARTSYS;
304 339
305 ctx->ops->master_start(ctx); 340 spu_enable_spu(ctx);
306 ctx->event_return = 0; 341 ctx->event_return = 0;
307 342
308 spu_acquire(ctx); 343 ret = spu_acquire(ctx);
309 if (ctx->state == SPU_STATE_SAVED) { 344 if (ret)
310 __spu_update_sched_info(ctx); 345 goto out_unlock;
311 spu_set_timeslice(ctx);
312 346
313 ret = spu_activate(ctx, 0); 347 spu_update_sched_info(ctx);
314 if (ret) {
315 spu_release(ctx);
316 goto out;
317 }
318 } else {
319 /*
320 * We have to update the scheduling priority under active_mutex
321 * to protect against find_victim().
322 *
323 * No need to update the timeslice ASAP, it will get updated
324 * once the current one has expired.
325 */
326 spu_update_sched_info(ctx);
327 }
328 348
329 ret = spu_run_init(ctx, npc); 349 ret = spu_run_init(ctx, npc);
330 if (ret) { 350 if (ret) {
@@ -358,14 +378,12 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event)
358 if (ret) 378 if (ret)
359 break; 379 break;
360 380
361 if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) { 381 ret = spufs_handle_class0(ctx);
362 ret = spu_reacquire_runnable(ctx, npc, &status); 382 if (ret)
363 if (ret) 383 break;
364 goto out2;
365 continue;
366 }
367 ret = spu_process_events(ctx);
368 384
385 if (signal_pending(current))
386 ret = -ERESTARTSYS;
369 } while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP | 387 } while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP |
370 SPU_STATUS_STOPPED_BY_HALT | 388 SPU_STATUS_STOPPED_BY_HALT |
371 SPU_STATUS_SINGLE_STEP))); 389 SPU_STATUS_SINGLE_STEP)));
@@ -376,11 +394,10 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event)
376 ctx->stats.libassist++; 394 ctx->stats.libassist++;
377 395
378 396
379 ctx->ops->master_stop(ctx); 397 spu_disable_spu(ctx);
380 ret = spu_run_fini(ctx, npc, &status); 398 ret = spu_run_fini(ctx, npc, &status);
381 spu_yield(ctx); 399 spu_yield(ctx);
382 400
383out2:
384 if ((ret == 0) || 401 if ((ret == 0) ||
385 ((ret == -ERESTARTSYS) && 402 ((ret == -ERESTARTSYS) &&
386 ((status & SPU_STATUS_STOPPED_BY_HALT) || 403 ((status & SPU_STATUS_STOPPED_BY_HALT) ||
@@ -401,6 +418,7 @@ out2:
401 418
402out: 419out:
403 *event = ctx->event_return; 420 *event = ctx->event_return;
421out_unlock:
404 mutex_unlock(&ctx->run_mutex); 422 mutex_unlock(&ctx->run_mutex);
405 return ret; 423 return ret;
406} 424}
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 4d257b3f9336..8c8af11b35b4 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -58,6 +58,7 @@ static unsigned long spu_avenrun[3];
58static struct spu_prio_array *spu_prio; 58static struct spu_prio_array *spu_prio;
59static struct task_struct *spusched_task; 59static struct task_struct *spusched_task;
60static struct timer_list spusched_timer; 60static struct timer_list spusched_timer;
61static struct timer_list spuloadavg_timer;
61 62
62/* 63/*
63 * Priority of a normal, non-rt, non-niced'd process (aka nice level 0). 64 * Priority of a normal, non-rt, non-niced'd process (aka nice level 0).
@@ -105,15 +106,21 @@ void spu_set_timeslice(struct spu_context *ctx)
105void __spu_update_sched_info(struct spu_context *ctx) 106void __spu_update_sched_info(struct spu_context *ctx)
106{ 107{
107 /* 108 /*
108 * 32-Bit assignment are atomic on powerpc, and we don't care about 109 * assert that the context is not on the runqueue, so it is safe
109 * memory ordering here because retriving the controlling thread is 110 * to change its scheduling parameters.
110 * per defintion racy. 111 */
112 BUG_ON(!list_empty(&ctx->rq));
113
114 /*
115 * 32-Bit assignments are atomic on powerpc, and we don't care about
116 * memory ordering here because retrieving the controlling thread is
117 * per definition racy.
111 */ 118 */
112 ctx->tid = current->pid; 119 ctx->tid = current->pid;
113 120
114 /* 121 /*
115 * We do our own priority calculations, so we normally want 122 * We do our own priority calculations, so we normally want
116 * ->static_prio to start with. Unfortunately thies field 123 * ->static_prio to start with. Unfortunately this field
117 * contains junk for threads with a realtime scheduling 124 * contains junk for threads with a realtime scheduling
118 * policy so we have to look at ->prio in this case. 125 * policy so we have to look at ->prio in this case.
119 */ 126 */
@@ -124,23 +131,32 @@ void __spu_update_sched_info(struct spu_context *ctx)
124 ctx->policy = current->policy; 131 ctx->policy = current->policy;
125 132
126 /* 133 /*
127 * A lot of places that don't hold list_mutex poke into 134 * TO DO: the context may be loaded, so we may need to activate
128 * cpus_allowed, including grab_runnable_context which 135 * it again on a different node. But it shouldn't hurt anything
129 * already holds the runq_lock. So abuse runq_lock 136 * to update its parameters, because we know that the scheduler
130 * to protect this field aswell. 137 * is not actively looking at this field, since it is not on the
138 * runqueue. The context will be rescheduled on the proper node
139 * if it is timesliced or preempted.
131 */ 140 */
132 spin_lock(&spu_prio->runq_lock);
133 ctx->cpus_allowed = current->cpus_allowed; 141 ctx->cpus_allowed = current->cpus_allowed;
134 spin_unlock(&spu_prio->runq_lock);
135} 142}
136 143
137void spu_update_sched_info(struct spu_context *ctx) 144void spu_update_sched_info(struct spu_context *ctx)
138{ 145{
139 int node = ctx->spu->node; 146 int node;
140 147
141 mutex_lock(&cbe_spu_info[node].list_mutex); 148 if (ctx->state == SPU_STATE_RUNNABLE) {
142 __spu_update_sched_info(ctx); 149 node = ctx->spu->node;
143 mutex_unlock(&cbe_spu_info[node].list_mutex); 150
151 /*
152 * Take list_mutex to sync with find_victim().
153 */
154 mutex_lock(&cbe_spu_info[node].list_mutex);
155 __spu_update_sched_info(ctx);
156 mutex_unlock(&cbe_spu_info[node].list_mutex);
157 } else {
158 __spu_update_sched_info(ctx);
159 }
144} 160}
145 161
146static int __node_allowed(struct spu_context *ctx, int node) 162static int __node_allowed(struct spu_context *ctx, int node)
@@ -182,7 +198,7 @@ static void notify_spus_active(void)
182 * Wake up the active spu_contexts. 198 * Wake up the active spu_contexts.
183 * 199 *
184 * When the awakened processes see their "notify_active" flag is set, 200 * When the awakened processes see their "notify_active" flag is set,
185 * they will call spu_switch_notify(); 201 * they will call spu_switch_notify().
186 */ 202 */
187 for_each_online_node(node) { 203 for_each_online_node(node) {
188 struct spu *spu; 204 struct spu *spu;
@@ -245,7 +261,6 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
245 spu->wbox_callback = spufs_wbox_callback; 261 spu->wbox_callback = spufs_wbox_callback;
246 spu->stop_callback = spufs_stop_callback; 262 spu->stop_callback = spufs_stop_callback;
247 spu->mfc_callback = spufs_mfc_callback; 263 spu->mfc_callback = spufs_mfc_callback;
248 spu->dma_callback = spufs_dma_callback;
249 mb(); 264 mb();
250 spu_unmap_mappings(ctx); 265 spu_unmap_mappings(ctx);
251 spu_restore(&ctx->csa, spu); 266 spu_restore(&ctx->csa, spu);
@@ -433,7 +448,6 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx)
433 spu->wbox_callback = NULL; 448 spu->wbox_callback = NULL;
434 spu->stop_callback = NULL; 449 spu->stop_callback = NULL;
435 spu->mfc_callback = NULL; 450 spu->mfc_callback = NULL;
436 spu->dma_callback = NULL;
437 spu_associate_mm(spu, NULL); 451 spu_associate_mm(spu, NULL);
438 spu->pid = 0; 452 spu->pid = 0;
439 spu->tgid = 0; 453 spu->tgid = 0;
@@ -478,6 +492,13 @@ static void __spu_add_to_rq(struct spu_context *ctx)
478 } 492 }
479} 493}
480 494
495static void spu_add_to_rq(struct spu_context *ctx)
496{
497 spin_lock(&spu_prio->runq_lock);
498 __spu_add_to_rq(ctx);
499 spin_unlock(&spu_prio->runq_lock);
500}
501
481static void __spu_del_from_rq(struct spu_context *ctx) 502static void __spu_del_from_rq(struct spu_context *ctx)
482{ 503{
483 int prio = ctx->prio; 504 int prio = ctx->prio;
@@ -492,10 +513,24 @@ static void __spu_del_from_rq(struct spu_context *ctx)
492 } 513 }
493} 514}
494 515
516void spu_del_from_rq(struct spu_context *ctx)
517{
518 spin_lock(&spu_prio->runq_lock);
519 __spu_del_from_rq(ctx);
520 spin_unlock(&spu_prio->runq_lock);
521}
522
495static void spu_prio_wait(struct spu_context *ctx) 523static void spu_prio_wait(struct spu_context *ctx)
496{ 524{
497 DEFINE_WAIT(wait); 525 DEFINE_WAIT(wait);
498 526
527 /*
528 * The caller must explicitly wait for a context to be loaded
529 * if the nosched flag is set. If NOSCHED is not set, the caller
530 * queues the context and waits for an spu event or error.
531 */
532 BUG_ON(!(ctx->flags & SPU_CREATE_NOSCHED));
533
499 spin_lock(&spu_prio->runq_lock); 534 spin_lock(&spu_prio->runq_lock);
500 prepare_to_wait_exclusive(&ctx->stop_wq, &wait, TASK_INTERRUPTIBLE); 535 prepare_to_wait_exclusive(&ctx->stop_wq, &wait, TASK_INTERRUPTIBLE);
501 if (!signal_pending(current)) { 536 if (!signal_pending(current)) {
@@ -579,7 +614,7 @@ static struct spu *find_victim(struct spu_context *ctx)
579 /* 614 /*
580 * Look for a possible preemption candidate on the local node first. 615 * Look for a possible preemption candidate on the local node first.
581 * If there is no candidate look at the other nodes. This isn't 616 * If there is no candidate look at the other nodes. This isn't
582 * exactly fair, but so far the whole spu schedule tries to keep 617 * exactly fair, but so far the whole spu scheduler tries to keep
583 * a strong node affinity. We might want to fine-tune this in 618 * a strong node affinity. We might want to fine-tune this in
584 * the future. 619 * the future.
585 */ 620 */
@@ -595,6 +630,7 @@ static struct spu *find_victim(struct spu_context *ctx)
595 struct spu_context *tmp = spu->ctx; 630 struct spu_context *tmp = spu->ctx;
596 631
597 if (tmp && tmp->prio > ctx->prio && 632 if (tmp && tmp->prio > ctx->prio &&
633 !(tmp->flags & SPU_CREATE_NOSCHED) &&
598 (!victim || tmp->prio > victim->prio)) 634 (!victim || tmp->prio > victim->prio))
599 victim = spu->ctx; 635 victim = spu->ctx;
600 } 636 }
@@ -606,6 +642,10 @@ static struct spu *find_victim(struct spu_context *ctx)
606 * higher priority contexts before lower priority 642 * higher priority contexts before lower priority
607 * ones, so this is safe until we introduce 643 * ones, so this is safe until we introduce
608 * priority inheritance schemes. 644 * priority inheritance schemes.
645 *
646 * XXX if the highest priority context is locked,
647 * this can loop a long time. Might be better to
648 * look at another context or give up after X retries.
609 */ 649 */
610 if (!mutex_trylock(&victim->state_mutex)) { 650 if (!mutex_trylock(&victim->state_mutex)) {
611 victim = NULL; 651 victim = NULL;
@@ -613,10 +653,10 @@ static struct spu *find_victim(struct spu_context *ctx)
613 } 653 }
614 654
615 spu = victim->spu; 655 spu = victim->spu;
616 if (!spu) { 656 if (!spu || victim->prio <= ctx->prio) {
617 /* 657 /*
618 * This race can happen because we've dropped 658 * This race can happen because we've dropped
619 * the active list mutex. No a problem, just 659 * the active list mutex. Not a problem, just
620 * restart the search. 660 * restart the search.
621 */ 661 */
622 mutex_unlock(&victim->state_mutex); 662 mutex_unlock(&victim->state_mutex);
@@ -631,13 +671,10 @@ static struct spu *find_victim(struct spu_context *ctx)
631 671
632 victim->stats.invol_ctx_switch++; 672 victim->stats.invol_ctx_switch++;
633 spu->stats.invol_ctx_switch++; 673 spu->stats.invol_ctx_switch++;
674 spu_add_to_rq(victim);
675
634 mutex_unlock(&victim->state_mutex); 676 mutex_unlock(&victim->state_mutex);
635 /* 677
636 * We need to break out of the wait loop in spu_run
637 * manually to ensure this context gets put on the
638 * runqueue again ASAP.
639 */
640 wake_up(&victim->stop_wq);
641 return spu; 678 return spu;
642 } 679 }
643 } 680 }
@@ -645,6 +682,50 @@ static struct spu *find_victim(struct spu_context *ctx)
645 return NULL; 682 return NULL;
646} 683}
647 684
685static void __spu_schedule(struct spu *spu, struct spu_context *ctx)
686{
687 int node = spu->node;
688 int success = 0;
689
690 spu_set_timeslice(ctx);
691
692 mutex_lock(&cbe_spu_info[node].list_mutex);
693 if (spu->ctx == NULL) {
694 spu_bind_context(spu, ctx);
695 cbe_spu_info[node].nr_active++;
696 spu->alloc_state = SPU_USED;
697 success = 1;
698 }
699 mutex_unlock(&cbe_spu_info[node].list_mutex);
700
701 if (success)
702 wake_up_all(&ctx->run_wq);
703 else
704 spu_add_to_rq(ctx);
705}
706
707static void spu_schedule(struct spu *spu, struct spu_context *ctx)
708{
709 /* not a candidate for interruptible because it's called either
710 from the scheduler thread or from spu_deactivate */
711 mutex_lock(&ctx->state_mutex);
712 __spu_schedule(spu, ctx);
713 spu_release(ctx);
714}
715
716static void spu_unschedule(struct spu *spu, struct spu_context *ctx)
717{
718 int node = spu->node;
719
720 mutex_lock(&cbe_spu_info[node].list_mutex);
721 cbe_spu_info[node].nr_active--;
722 spu->alloc_state = SPU_FREE;
723 spu_unbind_context(spu, ctx);
724 ctx->stats.invol_ctx_switch++;
725 spu->stats.invol_ctx_switch++;
726 mutex_unlock(&cbe_spu_info[node].list_mutex);
727}
728
648/** 729/**
649 * spu_activate - find a free spu for a context and execute it 730 * spu_activate - find a free spu for a context and execute it
650 * @ctx: spu context to schedule 731 * @ctx: spu context to schedule
@@ -656,39 +737,47 @@ static struct spu *find_victim(struct spu_context *ctx)
656 */ 737 */
657int spu_activate(struct spu_context *ctx, unsigned long flags) 738int spu_activate(struct spu_context *ctx, unsigned long flags)
658{ 739{
659 do { 740 struct spu *spu;
660 struct spu *spu;
661 741
662 /* 742 /*
663 * If there are multiple threads waiting for a single context 743 * If there are multiple threads waiting for a single context
664 * only one actually binds the context while the others will 744 * only one actually binds the context while the others will
665 * only be able to acquire the state_mutex once the context 745 * only be able to acquire the state_mutex once the context
666 * already is in runnable state. 746 * already is in runnable state.
667 */ 747 */
668 if (ctx->spu) 748 if (ctx->spu)
669 return 0; 749 return 0;
670 750
671 spu = spu_get_idle(ctx); 751spu_activate_top:
672 /* 752 if (signal_pending(current))
673 * If this is a realtime thread we try to get it running by 753 return -ERESTARTSYS;
674 * preempting a lower priority thread.
675 */
676 if (!spu && rt_prio(ctx->prio))
677 spu = find_victim(ctx);
678 if (spu) {
679 int node = spu->node;
680 754
681 mutex_lock(&cbe_spu_info[node].list_mutex); 755 spu = spu_get_idle(ctx);
682 spu_bind_context(spu, ctx); 756 /*
683 cbe_spu_info[node].nr_active++; 757 * If this is a realtime thread we try to get it running by
684 mutex_unlock(&cbe_spu_info[node].list_mutex); 758 * preempting a lower priority thread.
685 return 0; 759 */
686 } 760 if (!spu && rt_prio(ctx->prio))
761 spu = find_victim(ctx);
762 if (spu) {
763 unsigned long runcntl;
764
765 runcntl = ctx->ops->runcntl_read(ctx);
766 __spu_schedule(spu, ctx);
767 if (runcntl & SPU_RUNCNTL_RUNNABLE)
768 spuctx_switch_state(ctx, SPU_UTIL_USER);
687 769
770 return 0;
771 }
772
773 if (ctx->flags & SPU_CREATE_NOSCHED) {
688 spu_prio_wait(ctx); 774 spu_prio_wait(ctx);
689 } while (!signal_pending(current)); 775 goto spu_activate_top;
776 }
690 777
691 return -ERESTARTSYS; 778 spu_add_to_rq(ctx);
779
780 return 0;
692} 781}
693 782
694/** 783/**
@@ -730,21 +819,19 @@ static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio)
730 if (spu) { 819 if (spu) {
731 new = grab_runnable_context(max_prio, spu->node); 820 new = grab_runnable_context(max_prio, spu->node);
732 if (new || force) { 821 if (new || force) {
733 int node = spu->node; 822 spu_unschedule(spu, ctx);
734 823 if (new) {
735 mutex_lock(&cbe_spu_info[node].list_mutex); 824 if (new->flags & SPU_CREATE_NOSCHED)
736 spu_unbind_context(spu, ctx); 825 wake_up(&new->stop_wq);
737 spu->alloc_state = SPU_FREE; 826 else {
738 cbe_spu_info[node].nr_active--; 827 spu_release(ctx);
739 mutex_unlock(&cbe_spu_info[node].list_mutex); 828 spu_schedule(spu, new);
740 829 /* this one can't easily be made
741 ctx->stats.vol_ctx_switch++; 830 interruptible */
742 spu->stats.vol_ctx_switch++; 831 mutex_lock(&ctx->state_mutex);
743 832 }
744 if (new) 833 }
745 wake_up(&new->stop_wq);
746 } 834 }
747
748 } 835 }
749 836
750 return new != NULL; 837 return new != NULL;
@@ -781,43 +868,38 @@ void spu_yield(struct spu_context *ctx)
781 868
782static noinline void spusched_tick(struct spu_context *ctx) 869static noinline void spusched_tick(struct spu_context *ctx)
783{ 870{
871 struct spu_context *new = NULL;
872 struct spu *spu = NULL;
873 u32 status;
874
875 if (spu_acquire(ctx))
876 BUG(); /* a kernel thread never has signals pending */
877
878 if (ctx->state != SPU_STATE_RUNNABLE)
879 goto out;
880 if (spu_stopped(ctx, &status))
881 goto out;
784 if (ctx->flags & SPU_CREATE_NOSCHED) 882 if (ctx->flags & SPU_CREATE_NOSCHED)
785 return; 883 goto out;
786 if (ctx->policy == SCHED_FIFO) 884 if (ctx->policy == SCHED_FIFO)
787 return; 885 goto out;
788 886
789 if (--ctx->time_slice) 887 if (--ctx->time_slice)
790 return; 888 goto out;
791 889
792 /* 890 spu = ctx->spu;
793 * Unfortunately list_mutex ranks outside of state_mutex, so 891 new = grab_runnable_context(ctx->prio + 1, spu->node);
794 * we have to trylock here. If we fail give the context another 892 if (new) {
795 * tick and try again. 893 spu_unschedule(spu, ctx);
796 */ 894 spu_add_to_rq(ctx);
797 if (mutex_trylock(&ctx->state_mutex)) {
798 struct spu *spu = ctx->spu;
799 struct spu_context *new;
800
801 new = grab_runnable_context(ctx->prio + 1, spu->node);
802 if (new) {
803 spu_unbind_context(spu, ctx);
804 ctx->stats.invol_ctx_switch++;
805 spu->stats.invol_ctx_switch++;
806 spu->alloc_state = SPU_FREE;
807 cbe_spu_info[spu->node].nr_active--;
808 wake_up(&new->stop_wq);
809 /*
810 * We need to break out of the wait loop in
811 * spu_run manually to ensure this context
812 * gets put on the runqueue again ASAP.
813 */
814 wake_up(&ctx->stop_wq);
815 }
816 spu_set_timeslice(ctx);
817 mutex_unlock(&ctx->state_mutex);
818 } else { 895 } else {
819 ctx->time_slice++; 896 ctx->time_slice++;
820 } 897 }
898out:
899 spu_release(ctx);
900
901 if (new)
902 spu_schedule(spu, new);
821} 903}
822 904
823/** 905/**
@@ -841,35 +923,31 @@ static unsigned long count_active_contexts(void)
841} 923}
842 924
843/** 925/**
844 * spu_calc_load - given tick count, update the avenrun load estimates. 926 * spu_calc_load - update the avenrun load estimates.
845 * @tick: tick count
846 * 927 *
847 * No locking against reading these values from userspace, as for 928 * No locking against reading these values from userspace, as for
848 * the CPU loadavg code. 929 * the CPU loadavg code.
849 */ 930 */
850static void spu_calc_load(unsigned long ticks) 931static void spu_calc_load(void)
851{ 932{
852 unsigned long active_tasks; /* fixed-point */ 933 unsigned long active_tasks; /* fixed-point */
853 static int count = LOAD_FREQ; 934
854 935 active_tasks = count_active_contexts() * FIXED_1;
855 count -= ticks; 936 CALC_LOAD(spu_avenrun[0], EXP_1, active_tasks);
856 937 CALC_LOAD(spu_avenrun[1], EXP_5, active_tasks);
857 if (unlikely(count < 0)) { 938 CALC_LOAD(spu_avenrun[2], EXP_15, active_tasks);
858 active_tasks = count_active_contexts() * FIXED_1;
859 do {
860 CALC_LOAD(spu_avenrun[0], EXP_1, active_tasks);
861 CALC_LOAD(spu_avenrun[1], EXP_5, active_tasks);
862 CALC_LOAD(spu_avenrun[2], EXP_15, active_tasks);
863 count += LOAD_FREQ;
864 } while (count < 0);
865 }
866} 939}
867 940
868static void spusched_wake(unsigned long data) 941static void spusched_wake(unsigned long data)
869{ 942{
870 mod_timer(&spusched_timer, jiffies + SPUSCHED_TICK); 943 mod_timer(&spusched_timer, jiffies + SPUSCHED_TICK);
871 wake_up_process(spusched_task); 944 wake_up_process(spusched_task);
872 spu_calc_load(SPUSCHED_TICK); 945}
946
947static void spuloadavg_wake(unsigned long data)
948{
949 mod_timer(&spuloadavg_timer, jiffies + LOAD_FREQ);
950 spu_calc_load();
873} 951}
874 952
875static int spusched_thread(void *unused) 953static int spusched_thread(void *unused)
@@ -881,17 +959,58 @@ static int spusched_thread(void *unused)
881 set_current_state(TASK_INTERRUPTIBLE); 959 set_current_state(TASK_INTERRUPTIBLE);
882 schedule(); 960 schedule();
883 for (node = 0; node < MAX_NUMNODES; node++) { 961 for (node = 0; node < MAX_NUMNODES; node++) {
884 mutex_lock(&cbe_spu_info[node].list_mutex); 962 struct mutex *mtx = &cbe_spu_info[node].list_mutex;
885 list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) 963
886 if (spu->ctx) 964 mutex_lock(mtx);
887 spusched_tick(spu->ctx); 965 list_for_each_entry(spu, &cbe_spu_info[node].spus,
888 mutex_unlock(&cbe_spu_info[node].list_mutex); 966 cbe_list) {
967 struct spu_context *ctx = spu->ctx;
968
969 if (ctx) {
970 mutex_unlock(mtx);
971 spusched_tick(ctx);
972 mutex_lock(mtx);
973 }
974 }
975 mutex_unlock(mtx);
889 } 976 }
890 } 977 }
891 978
892 return 0; 979 return 0;
893} 980}
894 981
982void spuctx_switch_state(struct spu_context *ctx,
983 enum spu_utilization_state new_state)
984{
985 unsigned long long curtime;
986 signed long long delta;
987 struct timespec ts;
988 struct spu *spu;
989 enum spu_utilization_state old_state;
990
991 ktime_get_ts(&ts);
992 curtime = timespec_to_ns(&ts);
993 delta = curtime - ctx->stats.tstamp;
994
995 WARN_ON(!mutex_is_locked(&ctx->state_mutex));
996 WARN_ON(delta < 0);
997
998 spu = ctx->spu;
999 old_state = ctx->stats.util_state;
1000 ctx->stats.util_state = new_state;
1001 ctx->stats.tstamp = curtime;
1002
1003 /*
1004 * Update the physical SPU utilization statistics.
1005 */
1006 if (spu) {
1007 ctx->stats.times[old_state] += delta;
1008 spu->stats.times[old_state] += delta;
1009 spu->stats.util_state = new_state;
1010 spu->stats.tstamp = curtime;
1011 }
1012}
1013
895#define LOAD_INT(x) ((x) >> FSHIFT) 1014#define LOAD_INT(x) ((x) >> FSHIFT)
896#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) 1015#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
897 1016
@@ -905,7 +1024,7 @@ static int show_spu_loadavg(struct seq_file *s, void *private)
905 1024
906 /* 1025 /*
907 * Note that last_pid doesn't really make much sense for the 1026 * Note that last_pid doesn't really make much sense for the
908 * SPU loadavg (it even seems very odd on the CPU side..), 1027 * SPU loadavg (it even seems very odd on the CPU side...),
909 * but we include it here to have a 100% compatible interface. 1028 * but we include it here to have a 100% compatible interface.
910 */ 1029 */
911 seq_printf(s, "%d.%02d %d.%02d %d.%02d %ld/%d %d\n", 1030 seq_printf(s, "%d.%02d %d.%02d %d.%02d %ld/%d %d\n",
@@ -946,6 +1065,7 @@ int __init spu_sched_init(void)
946 spin_lock_init(&spu_prio->runq_lock); 1065 spin_lock_init(&spu_prio->runq_lock);
947 1066
948 setup_timer(&spusched_timer, spusched_wake, 0); 1067 setup_timer(&spusched_timer, spusched_wake, 0);
1068 setup_timer(&spuloadavg_timer, spuloadavg_wake, 0);
949 1069
950 spusched_task = kthread_run(spusched_thread, NULL, "spusched"); 1070 spusched_task = kthread_run(spusched_thread, NULL, "spusched");
951 if (IS_ERR(spusched_task)) { 1071 if (IS_ERR(spusched_task)) {
@@ -953,6 +1073,8 @@ int __init spu_sched_init(void)
953 goto out_free_spu_prio; 1073 goto out_free_spu_prio;
954 } 1074 }
955 1075
1076 mod_timer(&spuloadavg_timer, 0);
1077
956 entry = create_proc_entry("spu_loadavg", 0, NULL); 1078 entry = create_proc_entry("spu_loadavg", 0, NULL);
957 if (!entry) 1079 if (!entry)
958 goto out_stop_kthread; 1080 goto out_stop_kthread;
@@ -978,6 +1100,7 @@ void spu_sched_exit(void)
978 remove_proc_entry("spu_loadavg", NULL); 1100 remove_proc_entry("spu_loadavg", NULL);
979 1101
980 del_timer_sync(&spusched_timer); 1102 del_timer_sync(&spusched_timer);
1103 del_timer_sync(&spuloadavg_timer);
981 kthread_stop(spusched_task); 1104 kthread_stop(spusched_task);
982 1105
983 for (node = 0; node < MAX_NUMNODES; node++) { 1106 for (node = 0; node < MAX_NUMNODES; node++) {
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index ca47b991bda5..0e114038ea6f 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -71,6 +71,7 @@ struct spu_context {
71 wait_queue_head_t wbox_wq; 71 wait_queue_head_t wbox_wq;
72 wait_queue_head_t stop_wq; 72 wait_queue_head_t stop_wq;
73 wait_queue_head_t mfc_wq; 73 wait_queue_head_t mfc_wq;
74 wait_queue_head_t run_wq;
74 struct fasync_struct *ibox_fasync; 75 struct fasync_struct *ibox_fasync;
75 struct fasync_struct *wbox_fasync; 76 struct fasync_struct *wbox_fasync;
76 struct fasync_struct *mfc_fasync; 77 struct fasync_struct *mfc_fasync;
@@ -168,8 +169,10 @@ struct spu_context_ops {
168 void (*npc_write) (struct spu_context * ctx, u32 data); 169 void (*npc_write) (struct spu_context * ctx, u32 data);
169 u32(*status_read) (struct spu_context * ctx); 170 u32(*status_read) (struct spu_context * ctx);
170 char*(*get_ls) (struct spu_context * ctx); 171 char*(*get_ls) (struct spu_context * ctx);
172 void (*privcntl_write) (struct spu_context *ctx, u64 data);
171 u32 (*runcntl_read) (struct spu_context * ctx); 173 u32 (*runcntl_read) (struct spu_context * ctx);
172 void (*runcntl_write) (struct spu_context * ctx, u32 data); 174 void (*runcntl_write) (struct spu_context * ctx, u32 data);
175 void (*runcntl_stop) (struct spu_context * ctx);
173 void (*master_start) (struct spu_context * ctx); 176 void (*master_start) (struct spu_context * ctx);
174 void (*master_stop) (struct spu_context * ctx); 177 void (*master_stop) (struct spu_context * ctx);
175 int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode); 178 int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode);
@@ -219,15 +222,16 @@ void spu_gang_add_ctx(struct spu_gang *gang, struct spu_context *ctx);
219 222
220/* fault handling */ 223/* fault handling */
221int spufs_handle_class1(struct spu_context *ctx); 224int spufs_handle_class1(struct spu_context *ctx);
225int spufs_handle_class0(struct spu_context *ctx);
222 226
223/* affinity */ 227/* affinity */
224struct spu *affinity_check(struct spu_context *ctx); 228struct spu *affinity_check(struct spu_context *ctx);
225 229
226/* context management */ 230/* context management */
227extern atomic_t nr_spu_contexts; 231extern atomic_t nr_spu_contexts;
228static inline void spu_acquire(struct spu_context *ctx) 232static inline int __must_check spu_acquire(struct spu_context *ctx)
229{ 233{
230 mutex_lock(&ctx->state_mutex); 234 return mutex_lock_interruptible(&ctx->state_mutex);
231} 235}
232 236
233static inline void spu_release(struct spu_context *ctx) 237static inline void spu_release(struct spu_context *ctx)
@@ -242,10 +246,11 @@ int put_spu_context(struct spu_context *ctx);
242void spu_unmap_mappings(struct spu_context *ctx); 246void spu_unmap_mappings(struct spu_context *ctx);
243 247
244void spu_forget(struct spu_context *ctx); 248void spu_forget(struct spu_context *ctx);
245int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags); 249int __must_check spu_acquire_saved(struct spu_context *ctx);
246void spu_acquire_saved(struct spu_context *ctx);
247void spu_release_saved(struct spu_context *ctx); 250void spu_release_saved(struct spu_context *ctx);
248 251
252int spu_stopped(struct spu_context *ctx, u32 * stat);
253void spu_del_from_rq(struct spu_context *ctx);
249int spu_activate(struct spu_context *ctx, unsigned long flags); 254int spu_activate(struct spu_context *ctx, unsigned long flags);
250void spu_deactivate(struct spu_context *ctx); 255void spu_deactivate(struct spu_context *ctx);
251void spu_yield(struct spu_context *ctx); 256void spu_yield(struct spu_context *ctx);
@@ -279,7 +284,9 @@ extern char *isolated_loader;
279 } \ 284 } \
280 spu_release(ctx); \ 285 spu_release(ctx); \
281 schedule(); \ 286 schedule(); \
282 spu_acquire(ctx); \ 287 __ret = spu_acquire(ctx); \
288 if (__ret) \
289 break; \
283 } \ 290 } \
284 finish_wait(&(wq), &__wait); \ 291 finish_wait(&(wq), &__wait); \
285 __ret; \ 292 __ret; \
@@ -306,41 +313,16 @@ struct spufs_coredump_reader {
306extern struct spufs_coredump_reader spufs_coredump_read[]; 313extern struct spufs_coredump_reader spufs_coredump_read[];
307extern int spufs_coredump_num_notes; 314extern int spufs_coredump_num_notes;
308 315
309/* 316extern int spu_init_csa(struct spu_state *csa);
310 * This function is a little bit too large for an inline, but 317extern void spu_fini_csa(struct spu_state *csa);
311 * as fault.c is built into the kernel we can't move it out of 318extern int spu_save(struct spu_state *prev, struct spu *spu);
312 * line. 319extern int spu_restore(struct spu_state *new, struct spu *spu);
313 */ 320extern int spu_switch(struct spu_state *prev, struct spu_state *new,
314static inline void spuctx_switch_state(struct spu_context *ctx, 321 struct spu *spu);
315 enum spu_utilization_state new_state) 322extern int spu_alloc_lscsa(struct spu_state *csa);
316{ 323extern void spu_free_lscsa(struct spu_state *csa);
317 unsigned long long curtime; 324
318 signed long long delta; 325extern void spuctx_switch_state(struct spu_context *ctx,
319 struct timespec ts; 326 enum spu_utilization_state new_state);
320 struct spu *spu;
321 enum spu_utilization_state old_state;
322
323 ktime_get_ts(&ts);
324 curtime = timespec_to_ns(&ts);
325 delta = curtime - ctx->stats.tstamp;
326
327 WARN_ON(!mutex_is_locked(&ctx->state_mutex));
328 WARN_ON(delta < 0);
329
330 spu = ctx->spu;
331 old_state = ctx->stats.util_state;
332 ctx->stats.util_state = new_state;
333 ctx->stats.tstamp = curtime;
334
335 /*
336 * Update the physical SPU utilization statistics.
337 */
338 if (spu) {
339 ctx->stats.times[old_state] += delta;
340 spu->stats.times[old_state] += delta;
341 spu->stats.util_state = new_state;
342 spu->stats.tstamp = curtime;
343 }
344}
345 327
346#endif 328#endif
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index 3d64c81cc6e2..6063c88c26d2 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -48,6 +48,8 @@
48#include <asm/spu_csa.h> 48#include <asm/spu_csa.h>
49#include <asm/mmu_context.h> 49#include <asm/mmu_context.h>
50 50
51#include "spufs.h"
52
51#include "spu_save_dump.h" 53#include "spu_save_dump.h"
52#include "spu_restore_dump.h" 54#include "spu_restore_dump.h"
53 55
@@ -691,35 +693,9 @@ static inline void resume_mfc_queue(struct spu_state *csa, struct spu *spu)
691 out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESUME_DMA_QUEUE); 693 out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESUME_DMA_QUEUE);
692} 694}
693 695
694static inline void get_kernel_slb(u64 ea, u64 slb[2]) 696static inline void setup_mfc_slbs(struct spu_state *csa, struct spu *spu,
697 unsigned int *code, int code_size)
695{ 698{
696 u64 llp;
697
698 if (REGION_ID(ea) == KERNEL_REGION_ID)
699 llp = mmu_psize_defs[mmu_linear_psize].sllp;
700 else
701 llp = mmu_psize_defs[mmu_virtual_psize].sllp;
702 slb[0] = (get_kernel_vsid(ea, MMU_SEGSIZE_256M) << SLB_VSID_SHIFT) |
703 SLB_VSID_KERNEL | llp;
704 slb[1] = (ea & ESID_MASK) | SLB_ESID_V;
705}
706
707static inline void load_mfc_slb(struct spu *spu, u64 slb[2], int slbe)
708{
709 struct spu_priv2 __iomem *priv2 = spu->priv2;
710
711 out_be64(&priv2->slb_index_W, slbe);
712 eieio();
713 out_be64(&priv2->slb_vsid_RW, slb[0]);
714 out_be64(&priv2->slb_esid_RW, slb[1]);
715 eieio();
716}
717
718static inline void setup_mfc_slbs(struct spu_state *csa, struct spu *spu)
719{
720 u64 code_slb[2];
721 u64 lscsa_slb[2];
722
723 /* Save, Step 47: 699 /* Save, Step 47:
724 * Restore, Step 30. 700 * Restore, Step 30.
725 * If MFC_SR1[R]=1, write 0 to SLB_Invalidate_All 701 * If MFC_SR1[R]=1, write 0 to SLB_Invalidate_All
@@ -735,11 +711,7 @@ static inline void setup_mfc_slbs(struct spu_state *csa, struct spu *spu)
735 * translation is desired by OS environment). 711 * translation is desired by OS environment).
736 */ 712 */
737 spu_invalidate_slbs(spu); 713 spu_invalidate_slbs(spu);
738 get_kernel_slb((unsigned long)&spu_save_code[0], code_slb); 714 spu_setup_kernel_slbs(spu, csa->lscsa, code, code_size);
739 get_kernel_slb((unsigned long)csa->lscsa, lscsa_slb);
740 load_mfc_slb(spu, code_slb, 0);
741 if ((lscsa_slb[0] != code_slb[0]) || (lscsa_slb[1] != code_slb[1]))
742 load_mfc_slb(spu, lscsa_slb, 1);
743} 715}
744 716
745static inline void set_switch_active(struct spu_state *csa, struct spu *spu) 717static inline void set_switch_active(struct spu_state *csa, struct spu *spu)
@@ -768,9 +740,9 @@ static inline void enable_interrupts(struct spu_state *csa, struct spu *spu)
768 * (translation) interrupts. 740 * (translation) interrupts.
769 */ 741 */
770 spin_lock_irq(&spu->register_lock); 742 spin_lock_irq(&spu->register_lock);
771 spu_int_stat_clear(spu, 0, ~0ul); 743 spu_int_stat_clear(spu, 0, CLASS0_INTR_MASK);
772 spu_int_stat_clear(spu, 1, ~0ul); 744 spu_int_stat_clear(spu, 1, CLASS1_INTR_MASK);
773 spu_int_stat_clear(spu, 2, ~0ul); 745 spu_int_stat_clear(spu, 2, CLASS2_INTR_MASK);
774 spu_int_mask_set(spu, 0, 0ul); 746 spu_int_mask_set(spu, 0, 0ul);
775 spu_int_mask_set(spu, 1, class1_mask); 747 spu_int_mask_set(spu, 1, class1_mask);
776 spu_int_mask_set(spu, 2, 0ul); 748 spu_int_mask_set(spu, 2, 0ul);
@@ -927,8 +899,8 @@ static inline void wait_tag_complete(struct spu_state *csa, struct spu *spu)
927 POLL_WHILE_FALSE(in_be32(&prob->dma_tagstatus_R) & mask); 899 POLL_WHILE_FALSE(in_be32(&prob->dma_tagstatus_R) & mask);
928 900
929 local_irq_save(flags); 901 local_irq_save(flags);
930 spu_int_stat_clear(spu, 0, ~(0ul)); 902 spu_int_stat_clear(spu, 0, CLASS0_INTR_MASK);
931 spu_int_stat_clear(spu, 2, ~(0ul)); 903 spu_int_stat_clear(spu, 2, CLASS2_INTR_MASK);
932 local_irq_restore(flags); 904 local_irq_restore(flags);
933} 905}
934 906
@@ -946,8 +918,8 @@ static inline void wait_spu_stopped(struct spu_state *csa, struct spu *spu)
946 POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING); 918 POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING);
947 919
948 local_irq_save(flags); 920 local_irq_save(flags);
949 spu_int_stat_clear(spu, 0, ~(0ul)); 921 spu_int_stat_clear(spu, 0, CLASS0_INTR_MASK);
950 spu_int_stat_clear(spu, 2, ~(0ul)); 922 spu_int_stat_clear(spu, 2, CLASS2_INTR_MASK);
951 local_irq_restore(flags); 923 local_irq_restore(flags);
952} 924}
953 925
@@ -1423,9 +1395,9 @@ static inline void clear_interrupts(struct spu_state *csa, struct spu *spu)
1423 spu_int_mask_set(spu, 0, 0ul); 1395 spu_int_mask_set(spu, 0, 0ul);
1424 spu_int_mask_set(spu, 1, 0ul); 1396 spu_int_mask_set(spu, 1, 0ul);
1425 spu_int_mask_set(spu, 2, 0ul); 1397 spu_int_mask_set(spu, 2, 0ul);
1426 spu_int_stat_clear(spu, 0, ~0ul); 1398 spu_int_stat_clear(spu, 0, CLASS0_INTR_MASK);
1427 spu_int_stat_clear(spu, 1, ~0ul); 1399 spu_int_stat_clear(spu, 1, CLASS1_INTR_MASK);
1428 spu_int_stat_clear(spu, 2, ~0ul); 1400 spu_int_stat_clear(spu, 2, CLASS2_INTR_MASK);
1429 spin_unlock_irq(&spu->register_lock); 1401 spin_unlock_irq(&spu->register_lock);
1430} 1402}
1431 1403
@@ -1866,7 +1838,8 @@ static void save_lscsa(struct spu_state *prev, struct spu *spu)
1866 */ 1838 */
1867 1839
1868 resume_mfc_queue(prev, spu); /* Step 46. */ 1840 resume_mfc_queue(prev, spu); /* Step 46. */
1869 setup_mfc_slbs(prev, spu); /* Step 47. */ 1841 /* Step 47. */
1842 setup_mfc_slbs(prev, spu, spu_save_code, sizeof(spu_save_code));
1870 set_switch_active(prev, spu); /* Step 48. */ 1843 set_switch_active(prev, spu); /* Step 48. */
1871 enable_interrupts(prev, spu); /* Step 49. */ 1844 enable_interrupts(prev, spu); /* Step 49. */
1872 save_ls_16kb(prev, spu); /* Step 50. */ 1845 save_ls_16kb(prev, spu); /* Step 50. */
@@ -1971,7 +1944,8 @@ static void restore_lscsa(struct spu_state *next, struct spu *spu)
1971 setup_spu_status_part1(next, spu); /* Step 27. */ 1944 setup_spu_status_part1(next, spu); /* Step 27. */
1972 setup_spu_status_part2(next, spu); /* Step 28. */ 1945 setup_spu_status_part2(next, spu); /* Step 28. */
1973 restore_mfc_rag(next, spu); /* Step 29. */ 1946 restore_mfc_rag(next, spu); /* Step 29. */
1974 setup_mfc_slbs(next, spu); /* Step 30. */ 1947 /* Step 30. */
1948 setup_mfc_slbs(next, spu, spu_restore_code, sizeof(spu_restore_code));
1975 set_spu_npc(next, spu); /* Step 31. */ 1949 set_spu_npc(next, spu); /* Step 31. */
1976 set_signot1(next, spu); /* Step 32. */ 1950 set_signot1(next, spu); /* Step 32. */
1977 set_signot2(next, spu); /* Step 33. */ 1951 set_signot2(next, spu); /* Step 33. */
@@ -2103,10 +2077,6 @@ int spu_save(struct spu_state *prev, struct spu *spu)
2103 int rc; 2077 int rc;
2104 2078
2105 acquire_spu_lock(spu); /* Step 1. */ 2079 acquire_spu_lock(spu); /* Step 1. */
2106 prev->dar = spu->dar;
2107 prev->dsisr = spu->dsisr;
2108 spu->dar = 0;
2109 spu->dsisr = 0;
2110 rc = __do_spu_save(prev, spu); /* Steps 2-53. */ 2080 rc = __do_spu_save(prev, spu); /* Steps 2-53. */
2111 release_spu_lock(spu); 2081 release_spu_lock(spu);
2112 if (rc != 0 && rc != 2 && rc != 6) { 2082 if (rc != 0 && rc != 2 && rc != 6) {
@@ -2133,9 +2103,6 @@ int spu_restore(struct spu_state *new, struct spu *spu)
2133 acquire_spu_lock(spu); 2103 acquire_spu_lock(spu);
2134 harvest(NULL, spu); 2104 harvest(NULL, spu);
2135 spu->slb_replace = 0; 2105 spu->slb_replace = 0;
2136 new->dar = 0;
2137 new->dsisr = 0;
2138 spu->class_0_pending = 0;
2139 rc = __do_spu_restore(new, spu); 2106 rc = __do_spu_restore(new, spu);
2140 release_spu_lock(spu); 2107 release_spu_lock(spu);
2141 if (rc) { 2108 if (rc) {
@@ -2215,10 +2182,8 @@ int spu_init_csa(struct spu_state *csa)
2215 2182
2216 return 0; 2183 return 0;
2217} 2184}
2218EXPORT_SYMBOL_GPL(spu_init_csa);
2219 2185
2220void spu_fini_csa(struct spu_state *csa) 2186void spu_fini_csa(struct spu_state *csa)
2221{ 2187{
2222 spu_free_lscsa(csa); 2188 spu_free_lscsa(csa);
2223} 2189}
2224EXPORT_SYMBOL_GPL(spu_fini_csa);
diff --git a/arch/powerpc/platforms/celleb/Kconfig b/arch/powerpc/platforms/celleb/Kconfig
index 04748d410fc9..372891edcdd2 100644
--- a/arch/powerpc/platforms/celleb/Kconfig
+++ b/arch/powerpc/platforms/celleb/Kconfig
@@ -2,6 +2,8 @@ config PPC_CELLEB
2 bool "Toshiba's Cell Reference Set 'Celleb' Architecture" 2 bool "Toshiba's Cell Reference Set 'Celleb' Architecture"
3 depends on PPC_MULTIPLATFORM && PPC64 3 depends on PPC_MULTIPLATFORM && PPC64
4 select PPC_CELL 4 select PPC_CELL
5 select PPC_CELL_NATIVE
6 select PPC_RTAS
5 select PPC_INDIRECT_IO 7 select PPC_INDIRECT_IO
6 select PPC_OF_PLATFORM_PCI 8 select PPC_OF_PLATFORM_PCI
7 select HAS_TXX9_SERIAL 9 select HAS_TXX9_SERIAL
diff --git a/arch/powerpc/platforms/celleb/io-workarounds.c b/arch/powerpc/platforms/celleb/io-workarounds.c
index 2b912140bcbb..b939c0e98af8 100644
--- a/arch/powerpc/platforms/celleb/io-workarounds.c
+++ b/arch/powerpc/platforms/celleb/io-workarounds.c
@@ -222,7 +222,7 @@ void __init celleb_pci_add_one(struct pci_controller *phb,
222 void (*dummy_read)(struct pci_controller *)) 222 void (*dummy_read)(struct pci_controller *))
223{ 223{
224 struct celleb_pci_bus *bus = &celleb_pci_busses[celleb_pci_count]; 224 struct celleb_pci_bus *bus = &celleb_pci_busses[celleb_pci_count];
225 struct device_node *np = phb->arch_data; 225 struct device_node *np = phb->dn;
226 226
227 if (celleb_pci_count >= MAX_CELLEB_PCI_BUS) { 227 if (celleb_pci_count >= MAX_CELLEB_PCI_BUS) {
228 printk(KERN_ERR "Too many pci bridges, workarounds" 228 printk(KERN_ERR "Too many pci bridges, workarounds"
@@ -256,13 +256,13 @@ int __init celleb_pci_workaround_init(void)
256 256
257 celleb_dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL); 257 celleb_dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL);
258 if (!celleb_dummy_page_va) { 258 if (!celleb_dummy_page_va) {
259 printk(KERN_ERR "Celleb: dummy read disabled." 259 printk(KERN_ERR "Celleb: dummy read disabled. "
260 "Alloc celleb_dummy_page_va failed\n"); 260 "Alloc celleb_dummy_page_va failed\n");
261 return 1; 261 return 1;
262 } 262 }
263 263
264 list_for_each_entry(phb, &hose_list, list_node) { 264 list_for_each_entry(phb, &hose_list, list_node) {
265 node = phb->arch_data; 265 node = phb->dn;
266 match = of_match_node(celleb_pci_workaround_match, node); 266 match = of_match_node(celleb_pci_workaround_match, node);
267 267
268 if (match) { 268 if (match) {
diff --git a/arch/powerpc/platforms/celleb/iommu.c b/arch/powerpc/platforms/celleb/iommu.c
index 755d869d8553..fbe718d517a6 100644
--- a/arch/powerpc/platforms/celleb/iommu.c
+++ b/arch/powerpc/platforms/celleb/iommu.c
@@ -22,8 +22,9 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/dma-mapping.h> 23#include <linux/dma-mapping.h>
24#include <linux/pci.h> 24#include <linux/pci.h>
25#include <linux/of_platform.h>
25 26
26#include <asm/of_platform.h> 27#include <asm/machdep.h>
27 28
28#include "beat_wrapper.h" 29#include "beat_wrapper.h"
29 30
@@ -91,7 +92,7 @@ static struct notifier_block celleb_of_bus_notifier = {
91 92
92static int __init celleb_init_iommu(void) 93static int __init celleb_init_iommu(void)
93{ 94{
94 if (!machine_is(celleb)) 95 if (!machine_is(celleb_beat))
95 return -ENODEV; 96 return -ENODEV;
96 97
97 celleb_init_direct_mapping(); 98 celleb_init_direct_mapping();
diff --git a/arch/powerpc/platforms/celleb/pci.c b/arch/powerpc/platforms/celleb/pci.c
index 6bc32fda7a6b..5d399e038c23 100644
--- a/arch/powerpc/platforms/celleb/pci.c
+++ b/arch/powerpc/platforms/celleb/pci.c
@@ -138,8 +138,6 @@ static void celleb_config_read_fake(unsigned char *config, int where,
138 *val = celleb_fake_config_readl(p); 138 *val = celleb_fake_config_readl(p);
139 break; 139 break;
140 } 140 }
141
142 return;
143} 141}
144 142
145static void celleb_config_write_fake(unsigned char *config, int where, 143static void celleb_config_write_fake(unsigned char *config, int where,
@@ -158,7 +156,6 @@ static void celleb_config_write_fake(unsigned char *config, int where,
158 celleb_fake_config_writel(val, p); 156 celleb_fake_config_writel(val, p);
159 break; 157 break;
160 } 158 }
161 return;
162} 159}
163 160
164static int celleb_fake_pci_read_config(struct pci_bus *bus, 161static int celleb_fake_pci_read_config(struct pci_bus *bus,
@@ -351,6 +348,10 @@ static int __init celleb_setup_fake_pci_device(struct device_node *node,
351 wi1 = of_get_property(node, "vendor-id", NULL); 348 wi1 = of_get_property(node, "vendor-id", NULL);
352 wi2 = of_get_property(node, "class-code", NULL); 349 wi2 = of_get_property(node, "class-code", NULL);
353 wi3 = of_get_property(node, "revision-id", NULL); 350 wi3 = of_get_property(node, "revision-id", NULL);
351 if (!wi0 || !wi1 || !wi2 || !wi3) {
352 printk(KERN_ERR "PCI: Missing device tree properties.\n");
353 goto error;
354 }
354 355
355 celleb_config_write_fake(*config, PCI_DEVICE_ID, 2, wi0[0] & 0xffff); 356 celleb_config_write_fake(*config, PCI_DEVICE_ID, 2, wi0[0] & 0xffff);
356 celleb_config_write_fake(*config, PCI_VENDOR_ID, 2, wi1[0] & 0xffff); 357 celleb_config_write_fake(*config, PCI_VENDOR_ID, 2, wi1[0] & 0xffff);
@@ -372,6 +373,10 @@ static int __init celleb_setup_fake_pci_device(struct device_node *node,
372 celleb_setup_pci_base_addrs(hose, devno, fn, num_base_addr); 373 celleb_setup_pci_base_addrs(hose, devno, fn, num_base_addr);
373 374
374 li = of_get_property(node, "interrupts", &rlen); 375 li = of_get_property(node, "interrupts", &rlen);
376 if (!li) {
377 printk(KERN_ERR "PCI: interrupts not found.\n");
378 goto error;
379 }
375 val = li[0]; 380 val = li[0];
376 celleb_config_write_fake(*config, PCI_INTERRUPT_PIN, 1, 1); 381 celleb_config_write_fake(*config, PCI_INTERRUPT_PIN, 1, 1);
377 celleb_config_write_fake(*config, PCI_INTERRUPT_LINE, 1, val); 382 celleb_config_write_fake(*config, PCI_INTERRUPT_LINE, 1, val);
@@ -475,7 +480,7 @@ static struct of_device_id celleb_phb_match[] __initdata = {
475 480
476int __init celleb_setup_phb(struct pci_controller *phb) 481int __init celleb_setup_phb(struct pci_controller *phb)
477{ 482{
478 struct device_node *dev = phb->arch_data; 483 struct device_node *dev = phb->dn;
479 const struct of_device_id *match; 484 const struct of_device_id *match;
480 int (*setup_func)(struct device_node *, struct pci_controller *); 485 int (*setup_func)(struct device_node *, struct pci_controller *);
481 486
diff --git a/arch/powerpc/platforms/celleb/scc_epci.c b/arch/powerpc/platforms/celleb/scc_epci.c
index 9d076426676c..a3c7cfbcb323 100644
--- a/arch/powerpc/platforms/celleb/scc_epci.c
+++ b/arch/powerpc/platforms/celleb/scc_epci.c
@@ -95,7 +95,7 @@ void __init epci_workaround_init(struct pci_controller *hose)
95 private->dummy_page_da = dma_map_single(hose->parent, 95 private->dummy_page_da = dma_map_single(hose->parent,
96 celleb_dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE); 96 celleb_dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE);
97 if (private->dummy_page_da == DMA_ERROR_CODE) { 97 if (private->dummy_page_da == DMA_ERROR_CODE) {
98 printk(KERN_ERR "EPCI: dummy read disabled." 98 printk(KERN_ERR "EPCI: dummy read disabled. "
99 "Map dummy page failed.\n"); 99 "Map dummy page failed.\n");
100 return; 100 return;
101 } 101 }
diff --git a/arch/powerpc/platforms/celleb/scc_uhc.c b/arch/powerpc/platforms/celleb/scc_uhc.c
index b59c38a06e3e..cb4307994087 100644
--- a/arch/powerpc/platforms/celleb/scc_uhc.c
+++ b/arch/powerpc/platforms/celleb/scc_uhc.c
@@ -47,7 +47,8 @@ static void enable_scc_uhc(struct pci_dev *dev)
47 u32 val = 0; 47 u32 val = 0;
48 int i; 48 int i;
49 49
50 if (!machine_is(celleb)) 50 if (!machine_is(celleb_beat) &&
51 !machine_is(celleb_native))
51 return; 52 return;
52 53
53 uhc_base = ioremap(pci_resource_start(dev, 0), 54 uhc_base = ioremap(pci_resource_start(dev, 0),
diff --git a/arch/powerpc/platforms/celleb/setup.c b/arch/powerpc/platforms/celleb/setup.c
index ddfb35ae741f..0f0c4680bf01 100644
--- a/arch/powerpc/platforms/celleb/setup.c
+++ b/arch/powerpc/platforms/celleb/setup.c
@@ -40,6 +40,7 @@
40#include <linux/seq_file.h> 40#include <linux/seq_file.h>
41#include <linux/root_dev.h> 41#include <linux/root_dev.h>
42#include <linux/console.h> 42#include <linux/console.h>
43#include <linux/of_platform.h>
43 44
44#include <asm/mmu.h> 45#include <asm/mmu.h>
45#include <asm/processor.h> 46#include <asm/processor.h>
@@ -52,12 +53,16 @@
52#include <asm/time.h> 53#include <asm/time.h>
53#include <asm/spu_priv1.h> 54#include <asm/spu_priv1.h>
54#include <asm/firmware.h> 55#include <asm/firmware.h>
55#include <asm/of_platform.h> 56#include <asm/rtas.h>
57#include <asm/cell-regs.h>
56 58
57#include "interrupt.h" 59#include "interrupt.h"
58#include "beat_wrapper.h" 60#include "beat_wrapper.h"
59#include "beat.h" 61#include "beat.h"
60#include "pci.h" 62#include "pci.h"
63#include "../cell/interrupt.h"
64#include "../cell/pervasive.h"
65#include "../cell/ras.h"
61 66
62static char celleb_machine_type[128] = "Celleb"; 67static char celleb_machine_type[128] = "Celleb";
63 68
@@ -88,17 +93,8 @@ static void celleb_progress(char *s, unsigned short hex)
88 printk("*** %04x : %s\n", hex, s ? s : ""); 93 printk("*** %04x : %s\n", hex, s ? s : "");
89} 94}
90 95
91static void __init celleb_setup_arch(void) 96static void __init celleb_setup_arch_common(void)
92{ 97{
93#ifdef CONFIG_SPU_BASE
94 spu_priv1_ops = &spu_priv1_beat_ops;
95 spu_management_ops = &spu_management_of_ops;
96#endif
97
98#ifdef CONFIG_SMP
99 smp_init_celleb();
100#endif
101
102 /* init to some ~sane value until calibrate_delay() runs */ 98 /* init to some ~sane value until calibrate_delay() runs */
103 loops_per_jiffy = 50000000; 99 loops_per_jiffy = 50000000;
104 100
@@ -107,18 +103,6 @@ static void __init celleb_setup_arch(void)
107#endif 103#endif
108} 104}
109 105
110static int __init celleb_probe(void)
111{
112 unsigned long root = of_get_flat_dt_root();
113
114 if (!of_flat_dt_is_compatible(root, "Beat"))
115 return 0;
116
117 powerpc_firmware_features |= FW_FEATURE_CELLEB_POSSIBLE;
118 hpte_init_beat_v3();
119 return 1;
120}
121
122static struct of_device_id celleb_bus_ids[] __initdata = { 106static struct of_device_id celleb_bus_ids[] __initdata = {
123 { .type = "scc", }, 107 { .type = "scc", },
124 { .type = "ioif", }, /* old style */ 108 { .type = "ioif", }, /* old style */
@@ -127,8 +111,9 @@ static struct of_device_id celleb_bus_ids[] __initdata = {
127 111
128static int __init celleb_publish_devices(void) 112static int __init celleb_publish_devices(void)
129{ 113{
130 if (!machine_is(celleb)) 114 if (!machine_is(celleb_beat) &&
131 return 0; 115 !machine_is(celleb_native))
116 return -ENODEV;
132 117
133 /* Publish OF platform devices for southbridge IOs */ 118 /* Publish OF platform devices for southbridge IOs */
134 of_platform_bus_probe(NULL, celleb_bus_ids, NULL); 119 of_platform_bus_probe(NULL, celleb_bus_ids, NULL);
@@ -139,10 +124,94 @@ static int __init celleb_publish_devices(void)
139} 124}
140device_initcall(celleb_publish_devices); 125device_initcall(celleb_publish_devices);
141 126
142define_machine(celleb) { 127
143 .name = "Cell Reference Set", 128/*
144 .probe = celleb_probe, 129 * functions for Celleb-Beat
145 .setup_arch = celleb_setup_arch, 130 */
131static void __init celleb_setup_arch_beat(void)
132{
133#ifdef CONFIG_SPU_BASE
134 spu_priv1_ops = &spu_priv1_beat_ops;
135 spu_management_ops = &spu_management_of_ops;
136#endif
137
138#ifdef CONFIG_SMP
139 smp_init_celleb();
140#endif
141
142 celleb_setup_arch_common();
143}
144
145static int __init celleb_probe_beat(void)
146{
147 unsigned long root = of_get_flat_dt_root();
148
149 if (!of_flat_dt_is_compatible(root, "Beat"))
150 return 0;
151
152 powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS
153 | FW_FEATURE_BEAT | FW_FEATURE_LPAR;
154 hpte_init_beat_v3();
155
156 return 1;
157}
158
159
160/*
161 * functions for Celleb-native
162 */
163static void __init celleb_init_IRQ_native(void)
164{
165 iic_init_IRQ();
166 spider_init_IRQ();
167}
168
169static void __init celleb_setup_arch_native(void)
170{
171#ifdef CONFIG_SPU_BASE
172 spu_priv1_ops = &spu_priv1_mmio_ops;
173 spu_management_ops = &spu_management_of_ops;
174#endif
175
176 cbe_regs_init();
177
178#ifdef CONFIG_CBE_RAS
179 cbe_ras_init();
180#endif
181
182#ifdef CONFIG_SMP
183 smp_init_cell();
184#endif
185
186 cbe_pervasive_init();
187
188 /* XXX: nvram initialization should be added */
189
190 celleb_setup_arch_common();
191}
192
193static int __init celleb_probe_native(void)
194{
195 unsigned long root = of_get_flat_dt_root();
196
197 if (of_flat_dt_is_compatible(root, "Beat") ||
198 !of_flat_dt_is_compatible(root, "TOSHIBA,Celleb"))
199 return 0;
200
201 powerpc_firmware_features |= FW_FEATURE_CELLEB_ALWAYS;
202 hpte_init_native();
203
204 return 1;
205}
206
207
208/*
209 * machine definitions
210 */
211define_machine(celleb_beat) {
212 .name = "Cell Reference Set (Beat)",
213 .probe = celleb_probe_beat,
214 .setup_arch = celleb_setup_arch_beat,
146 .show_cpuinfo = celleb_show_cpuinfo, 215 .show_cpuinfo = celleb_show_cpuinfo,
147 .restart = beat_restart, 216 .restart = beat_restart,
148 .power_off = beat_power_off, 217 .power_off = beat_power_off,
@@ -167,3 +236,26 @@ define_machine(celleb) {
167 .machine_crash_shutdown = default_machine_crash_shutdown, 236 .machine_crash_shutdown = default_machine_crash_shutdown,
168#endif 237#endif
169}; 238};
239
240define_machine(celleb_native) {
241 .name = "Cell Reference Set (native)",
242 .probe = celleb_probe_native,
243 .setup_arch = celleb_setup_arch_native,
244 .show_cpuinfo = celleb_show_cpuinfo,
245 .restart = rtas_restart,
246 .power_off = rtas_power_off,
247 .halt = rtas_halt,
248 .get_boot_time = rtas_get_boot_time,
249 .get_rtc_time = rtas_get_rtc_time,
250 .set_rtc_time = rtas_set_rtc_time,
251 .calibrate_decr = generic_calibrate_decr,
252 .progress = celleb_progress,
253 .pci_probe_mode = celleb_pci_probe_mode,
254 .pci_setup_phb = celleb_setup_phb,
255 .init_IRQ = celleb_init_IRQ_native,
256#ifdef CONFIG_KEXEC
257 .machine_kexec = default_machine_kexec,
258 .machine_kexec_prepare = default_machine_kexec_prepare,
259 .machine_crash_shutdown = default_machine_crash_shutdown,
260#endif
261};
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index 0340a342f772..d51f83aeef7f 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -198,7 +198,7 @@ static void __init setup_peg2(struct pci_controller *hose, struct device_node *d
198 printk ("RTAS supporting Pegasos OF not found, please upgrade" 198 printk ("RTAS supporting Pegasos OF not found, please upgrade"
199 " your firmware\n"); 199 " your firmware\n");
200 } 200 }
201 pci_assign_all_buses = 1; 201 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
202 /* keep the reference to the root node */ 202 /* keep the reference to the root node */
203} 203}
204 204
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 59306261f5b2..42a21bab76c8 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -115,7 +115,7 @@ void chrp_show_cpuinfo(struct seq_file *m)
115 seq_printf(m, "machine\t\t: CHRP %s\n", model); 115 seq_printf(m, "machine\t\t: CHRP %s\n", model);
116 116
117 /* longtrail (goldengate) stuff */ 117 /* longtrail (goldengate) stuff */
118 if (!strncmp(model, "IBM,LongTrail", 13)) { 118 if (model && !strncmp(model, "IBM,LongTrail", 13)) {
119 /* VLSI VAS96011/12 `Golden Gate 2' */ 119 /* VLSI VAS96011/12 `Golden Gate 2' */
120 /* Memory banks */ 120 /* Memory banks */
121 sdramen = (in_le32(gg2_pci_config_base + GG2_PCI_DRAM_CTRL) 121 sdramen = (in_le32(gg2_pci_config_base + GG2_PCI_DRAM_CTRL)
@@ -203,15 +203,20 @@ static void __init sio_fixup_irq(const char *name, u8 device, u8 level,
203static void __init sio_init(void) 203static void __init sio_init(void)
204{ 204{
205 struct device_node *root; 205 struct device_node *root;
206 const char *model;
206 207
207 if ((root = of_find_node_by_path("/")) && 208 root = of_find_node_by_path("/");
208 !strncmp(of_get_property(root, "model", NULL), 209 if (!root)
209 "IBM,LongTrail", 13)) { 210 return;
211
212 model = of_get_property(root, "model", NULL);
213 if (model && !strncmp(model, "IBM,LongTrail", 13)) {
210 /* logical device 0 (KBC/Keyboard) */ 214 /* logical device 0 (KBC/Keyboard) */
211 sio_fixup_irq("keyboard", 0, 1, 2); 215 sio_fixup_irq("keyboard", 0, 1, 2);
212 /* select logical device 1 (KBC/Mouse) */ 216 /* select logical device 1 (KBC/Mouse) */
213 sio_fixup_irq("mouse", 1, 12, 2); 217 sio_fixup_irq("mouse", 1, 12, 2);
214 } 218 }
219
215 of_node_put(root); 220 of_node_put(root);
216} 221}
217 222
diff --git a/arch/powerpc/platforms/embedded6xx/holly.c b/arch/powerpc/platforms/embedded6xx/holly.c
index b6de2b5223dd..b21fde589ca7 100644
--- a/arch/powerpc/platforms/embedded6xx/holly.c
+++ b/arch/powerpc/platforms/embedded6xx/holly.c
@@ -20,12 +20,12 @@
20#include <linux/console.h> 20#include <linux/console.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/irq.h> 22#include <linux/irq.h>
23#include <linux/ide.h>
24#include <linux/seq_file.h> 23#include <linux/seq_file.h>
25#include <linux/root_dev.h> 24#include <linux/root_dev.h>
26#include <linux/serial.h> 25#include <linux/serial.h>
27#include <linux/tty.h> 26#include <linux/tty.h>
28#include <linux/serial_core.h> 27#include <linux/serial_core.h>
28#include <linux/of_platform.h>
29 29
30#include <asm/system.h> 30#include <asm/system.h>
31#include <asm/time.h> 31#include <asm/time.h>
@@ -39,7 +39,6 @@
39#include <asm/tsi108_irq.h> 39#include <asm/tsi108_irq.h>
40#include <asm/tsi108_pci.h> 40#include <asm/tsi108_pci.h>
41#include <asm/mpic.h> 41#include <asm/mpic.h>
42#include <asm/of_platform.h>
43 42
44#undef DEBUG 43#undef DEBUG
45 44
diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile
index a65f1b44abf8..cc7161ff1666 100644
--- a/arch/powerpc/platforms/iseries/Makefile
+++ b/arch/powerpc/platforms/iseries/Makefile
@@ -5,7 +5,7 @@ extra-y += dt.o
5obj-y += exception.o 5obj-y += exception.o
6obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \ 6obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \
7 hvcall.o proc.o htab.o iommu.o misc.o irq.o 7 hvcall.o proc.o htab.o iommu.o misc.o irq.o
8obj-$(CONFIG_PCI) += pci.o vpdinfo.o 8obj-$(CONFIG_PCI) += pci.o
9obj-$(CONFIG_SMP) += smp.o 9obj-$(CONFIG_SMP) += smp.o
10obj-$(CONFIG_VIOPATH) += viopath.o vio.o 10obj-$(CONFIG_VIOPATH) += viopath.o vio.o
11obj-$(CONFIG_MODULES) += ksyms.o 11obj-$(CONFIG_MODULES) += ksyms.o
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 49e9c664ea89..6a0c6f6675cd 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -163,8 +163,10 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
163 (it->it_type == TCE_PCI) && 163 (it->it_type == TCE_PCI) &&
164 (it->it_offset == tbl->it_offset) && 164 (it->it_offset == tbl->it_offset) &&
165 (it->it_index == tbl->it_index) && 165 (it->it_index == tbl->it_index) &&
166 (it->it_size == tbl->it_size)) 166 (it->it_size == tbl->it_size)) {
167 of_node_put(node);
167 return it; 168 return it;
169 }
168 } 170 }
169 return NULL; 171 return NULL;
170} 172}
diff --git a/arch/powerpc/platforms/iseries/lpevents.c b/arch/powerpc/platforms/iseries/lpevents.c
index 275f49449839..e5b40e3e0082 100644
--- a/arch/powerpc/platforms/iseries/lpevents.c
+++ b/arch/powerpc/platforms/iseries/lpevents.c
@@ -239,7 +239,7 @@ int HvLpEvent_unregisterHandler(HvLpEvent_Type eventType)
239 * other CPUs, and that the deleted handler isn't 239 * other CPUs, and that the deleted handler isn't
240 * still running on another CPU when we return. 240 * still running on another CPU when we return.
241 */ 241 */
242 synchronize_rcu(); 242 synchronize_sched();
243 return 0; 243 return 0;
244 } 244 }
245 } 245 }
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index da87162000f0..30e3d992dc0d 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (C) 2001 Allan Trautman, IBM Corporation 2 * Copyright (C) 2001 Allan Trautman, IBM Corporation
3 * Copyright (C) 2005,2007 Stephen Rothwell, IBM Corp
3 * 4 *
4 * iSeries specific routines for PCI. 5 * iSeries specific routines for PCI.
5 * 6 *
@@ -19,6 +20,9 @@
19 * along with this program; if not, write to the Free Software 20 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 22 */
23
24#undef DEBUG
25
22#include <linux/kernel.h> 26#include <linux/kernel.h>
23#include <linux/list.h> 27#include <linux/list.h>
24#include <linux/string.h> 28#include <linux/string.h>
@@ -26,6 +30,7 @@
26#include <linux/module.h> 30#include <linux/module.h>
27#include <linux/pci.h> 31#include <linux/pci.h>
28 32
33#include <asm/types.h>
29#include <asm/io.h> 34#include <asm/io.h>
30#include <asm/irq.h> 35#include <asm/irq.h>
31#include <asm/prom.h> 36#include <asm/prom.h>
@@ -35,6 +40,7 @@
35#include <asm/abs_addr.h> 40#include <asm/abs_addr.h>
36#include <asm/firmware.h> 41#include <asm/firmware.h>
37 42
43#include <asm/iseries/hv_types.h>
38#include <asm/iseries/hv_call_xm.h> 44#include <asm/iseries/hv_call_xm.h>
39#include <asm/iseries/mf.h> 45#include <asm/iseries/mf.h>
40#include <asm/iseries/iommu.h> 46#include <asm/iseries/iommu.h>
@@ -45,15 +51,8 @@
45#include "pci.h" 51#include "pci.h"
46#include "call_pci.h" 52#include "call_pci.h"
47 53
48/* 54#define PCI_RETRY_MAX 3
49 * Forward declares of prototypes. 55static int limit_pci_retries = 1; /* Set Retry Error on. */
50 */
51static struct device_node *find_Device_Node(int bus, int devfn);
52
53static int Pci_Retry_Max = 3; /* Only retry 3 times */
54static int Pci_Error_Flag = 1; /* Set Retry Error on. */
55
56static struct pci_ops iSeries_pci_ops;
57 56
58/* 57/*
59 * Table defines 58 * Table defines
@@ -62,6 +61,7 @@ static struct pci_ops iSeries_pci_ops;
62#define IOMM_TABLE_MAX_ENTRIES 1024 61#define IOMM_TABLE_MAX_ENTRIES 1024
63#define IOMM_TABLE_ENTRY_SIZE 0x0000000000400000UL 62#define IOMM_TABLE_ENTRY_SIZE 0x0000000000400000UL
64#define BASE_IO_MEMORY 0xE000000000000000UL 63#define BASE_IO_MEMORY 0xE000000000000000UL
64#define END_IO_MEMORY 0xEFFFFFFFFFFFFFFFUL
65 65
66static unsigned long max_io_memory = BASE_IO_MEMORY; 66static unsigned long max_io_memory = BASE_IO_MEMORY;
67static long current_iomm_table_entry; 67static long current_iomm_table_entry;
@@ -72,10 +72,234 @@ static long current_iomm_table_entry;
72static struct device_node *iomm_table[IOMM_TABLE_MAX_ENTRIES]; 72static struct device_node *iomm_table[IOMM_TABLE_MAX_ENTRIES];
73static u8 iobar_table[IOMM_TABLE_MAX_ENTRIES]; 73static u8 iobar_table[IOMM_TABLE_MAX_ENTRIES];
74 74
75static const char pci_io_text[] = "iSeries PCI I/O";
76static DEFINE_SPINLOCK(iomm_table_lock); 75static DEFINE_SPINLOCK(iomm_table_lock);
77 76
78/* 77/*
78 * Generate a Direct Select Address for the Hypervisor
79 */
80static inline u64 iseries_ds_addr(struct device_node *node)
81{
82 struct pci_dn *pdn = PCI_DN(node);
83
84 return ((u64)pdn->busno << 48) + ((u64)pdn->bussubno << 40)
85 + ((u64)0x10 << 32);
86}
87
88/*
89 * Size of Bus VPD data
90 */
91#define BUS_VPDSIZE 1024
92
93/*
94 * Bus Vpd Tags
95 */
96#define VPD_END_OF_AREA 0x79
97#define VPD_ID_STRING 0x82
98#define VPD_VENDOR_AREA 0x84
99
100/*
101 * Mfg Area Tags
102 */
103#define VPD_FRU_FRAME_ID 0x4649 /* "FI" */
104#define VPD_SLOT_MAP_FORMAT 0x4D46 /* "MF" */
105#define VPD_SLOT_MAP 0x534D /* "SM" */
106
107/*
108 * Structures of the areas
109 */
110struct mfg_vpd_area {
111 u16 tag;
112 u8 length;
113 u8 data1;
114 u8 data2;
115};
116#define MFG_ENTRY_SIZE 3
117
118struct slot_map {
119 u8 agent;
120 u8 secondary_agent;
121 u8 phb;
122 char card_location[3];
123 char parms[8];
124 char reserved[2];
125};
126#define SLOT_ENTRY_SIZE 16
127
128/*
129 * Parse the Slot Area
130 */
131static void __init iseries_parse_slot_area(struct slot_map *map, int len,
132 HvAgentId agent, u8 *phb, char card[4])
133{
134 /*
135 * Parse Slot label until we find the one requested
136 */
137 while (len > 0) {
138 if (map->agent == agent) {
139 /*
140 * If Phb wasn't found, grab the entry first one found.
141 */
142 if (*phb == 0xff)
143 *phb = map->phb;
144 /* Found it, extract the data. */
145 if (map->phb == *phb) {
146 memcpy(card, &map->card_location, 3);
147 card[3] = 0;
148 break;
149 }
150 }
151 /* Point to the next Slot */
152 map = (struct slot_map *)((char *)map + SLOT_ENTRY_SIZE);
153 len -= SLOT_ENTRY_SIZE;
154 }
155}
156
157/*
158 * Parse the Mfg Area
159 */
160static void __init iseries_parse_mfg_area(struct mfg_vpd_area *area, int len,
161 HvAgentId agent, u8 *phb, u8 *frame, char card[4])
162{
163 u16 slot_map_fmt = 0;
164
165 /* Parse Mfg Data */
166 while (len > 0) {
167 int mfg_tag_len = area->length;
168 /* Frame ID (FI 4649020310 ) */
169 if (area->tag == VPD_FRU_FRAME_ID)
170 *frame = area->data1;
171 /* Slot Map Format (MF 4D46020004 ) */
172 else if (area->tag == VPD_SLOT_MAP_FORMAT)
173 slot_map_fmt = (area->data1 * 256)
174 + area->data2;
175 /* Slot Map (SM 534D90 */
176 else if (area->tag == VPD_SLOT_MAP) {
177 struct slot_map *slot_map;
178
179 if (slot_map_fmt == 0x1004)
180 slot_map = (struct slot_map *)((char *)area
181 + MFG_ENTRY_SIZE + 1);
182 else
183 slot_map = (struct slot_map *)((char *)area
184 + MFG_ENTRY_SIZE);
185 iseries_parse_slot_area(slot_map, mfg_tag_len,
186 agent, phb, card);
187 }
188 /*
189 * Point to the next Mfg Area
190 * Use defined size, sizeof give wrong answer
191 */
192 area = (struct mfg_vpd_area *)((char *)area + mfg_tag_len
193 + MFG_ENTRY_SIZE);
194 len -= (mfg_tag_len + MFG_ENTRY_SIZE);
195 }
196}
197
198/*
199 * Look for "BUS".. Data is not Null terminated.
200 * PHBID of 0xFF indicates PHB was not found in VPD Data.
201 */
202static u8 __init iseries_parse_phbid(u8 *area, int len)
203{
204 while (len > 0) {
205 if ((*area == 'B') && (*(area + 1) == 'U')
206 && (*(area + 2) == 'S')) {
207 area += 3;
208 while (*area == ' ')
209 area++;
210 return *area & 0x0F;
211 }
212 area++;
213 len--;
214 }
215 return 0xff;
216}
217
218/*
219 * Parse out the VPD Areas
220 */
221static void __init iseries_parse_vpd(u8 *data, int data_len,
222 HvAgentId agent, u8 *frame, char card[4])
223{
224 u8 phb = 0xff;
225
226 while (data_len > 0) {
227 int len;
228 u8 tag = *data;
229
230 if (tag == VPD_END_OF_AREA)
231 break;
232 len = *(data + 1) + (*(data + 2) * 256);
233 data += 3;
234 data_len -= 3;
235 if (tag == VPD_ID_STRING)
236 phb = iseries_parse_phbid(data, len);
237 else if (tag == VPD_VENDOR_AREA)
238 iseries_parse_mfg_area((struct mfg_vpd_area *)data, len,
239 agent, &phb, frame, card);
240 /* Point to next Area. */
241 data += len;
242 data_len -= len;
243 }
244}
245
246static int __init iseries_get_location_code(u16 bus, HvAgentId agent,
247 u8 *frame, char card[4])
248{
249 int status = 0;
250 int bus_vpd_len = 0;
251 u8 *bus_vpd = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
252
253 if (bus_vpd == NULL) {
254 printk("PCI: Bus VPD Buffer allocation failure.\n");
255 return 0;
256 }
257 bus_vpd_len = HvCallPci_getBusVpd(bus, iseries_hv_addr(bus_vpd),
258 BUS_VPDSIZE);
259 if (bus_vpd_len == 0) {
260 printk("PCI: Bus VPD Buffer zero length.\n");
261 goto out_free;
262 }
263 /* printk("PCI: bus_vpd: %p, %d\n",bus_vpd, bus_vpd_len); */
264 /* Make sure this is what I think it is */
265 if (*bus_vpd != VPD_ID_STRING) {
266 printk("PCI: Bus VPD Buffer missing starting tag.\n");
267 goto out_free;
268 }
269 iseries_parse_vpd(bus_vpd, bus_vpd_len, agent, frame, card);
270 status = 1;
271out_free:
272 kfree(bus_vpd);
273 return status;
274}
275
276/*
277 * Prints the device information.
278 * - Pass in pci_dev* pointer to the device.
279 * - Pass in the device count
280 *
281 * Format:
282 * PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet
283 * controller
284 */
285static void __init iseries_device_information(struct pci_dev *pdev,
286 u16 bus, HvSubBusNumber subbus)
287{
288 u8 frame = 0;
289 char card[4];
290 HvAgentId agent;
291
292 agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
293 ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
294
295 if (iseries_get_location_code(bus, agent, &frame, card)) {
296 printk(KERN_INFO "PCI: %s, Vendor %04X Frame%3d, "
297 "Card %4s 0x%04X\n", pci_name(pdev), pdev->vendor,
298 frame, card, (int)(pdev->class >> 8));
299 }
300}
301
302/*
79 * iomm_table_allocate_entry 303 * iomm_table_allocate_entry
80 * 304 *
81 * Adds pci_dev entry in address translation table 305 * Adds pci_dev entry in address translation table
@@ -87,7 +311,7 @@ static DEFINE_SPINLOCK(iomm_table_lock);
87 * - CurrentIndex is incremented to keep track of the last entry. 311 * - CurrentIndex is incremented to keep track of the last entry.
88 * - Builds the resource entry for allocated BARs. 312 * - Builds the resource entry for allocated BARs.
89 */ 313 */
90static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num) 314static void __init iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
91{ 315{
92 struct resource *bar_res = &dev->resource[bar_num]; 316 struct resource *bar_res = &dev->resource[bar_num];
93 long bar_size = pci_resource_len(dev, bar_num); 317 long bar_size = pci_resource_len(dev, bar_num);
@@ -101,7 +325,6 @@ static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
101 * Set Resource values. 325 * Set Resource values.
102 */ 326 */
103 spin_lock(&iomm_table_lock); 327 spin_lock(&iomm_table_lock);
104 bar_res->name = pci_io_text;
105 bar_res->start = BASE_IO_MEMORY + 328 bar_res->start = BASE_IO_MEMORY +
106 IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry; 329 IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry;
107 bar_res->end = bar_res->start + bar_size - 1; 330 bar_res->end = bar_res->start + bar_size - 1;
@@ -130,7 +353,7 @@ static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
130 * - Loops through The Bar resources(0 - 5) including the ROM 353 * - Loops through The Bar resources(0 - 5) including the ROM
131 * is resource(6). 354 * is resource(6).
132 */ 355 */
133static void allocate_device_bars(struct pci_dev *dev) 356static void __init allocate_device_bars(struct pci_dev *dev)
134{ 357{
135 int bar_num; 358 int bar_num;
136 359
@@ -145,79 +368,19 @@ static void allocate_device_bars(struct pci_dev *dev)
145 * PCI: Read Vendor Failed 0x18.58.10 Rc: 0x00xx 368 * PCI: Read Vendor Failed 0x18.58.10 Rc: 0x00xx
146 * PCI: Connect Bus Unit Failed 0x18.58.10 Rc: 0x00xx 369 * PCI: Connect Bus Unit Failed 0x18.58.10 Rc: 0x00xx
147 */ 370 */
148static void pci_Log_Error(char *Error_Text, int Bus, int SubBus, 371static void pci_log_error(char *error, int bus, int subbus,
149 int AgentId, int HvRc) 372 int agent, int hv_res)
150{ 373{
151 if (HvRc == 0x0302) 374 if (hv_res == 0x0302)
152 return; 375 return;
153 printk(KERN_ERR "PCI: %s Failed: 0x%02X.%02X.%02X Rc: 0x%04X", 376 printk(KERN_ERR "PCI: %s Failed: 0x%02X.%02X.%02X Rc: 0x%04X",
154 Error_Text, Bus, SubBus, AgentId, HvRc); 377 error, bus, subbus, agent, hv_res);
155}
156
157/*
158 * iSeries_pci_final_fixup(void)
159 */
160void __init iSeries_pci_final_fixup(void)
161{
162 struct pci_dev *pdev = NULL;
163 struct device_node *node;
164 int DeviceCount = 0;
165
166 /* Fix up at the device node and pci_dev relationship */
167 mf_display_src(0xC9000100);
168
169 printk("pcibios_final_fixup\n");
170 for_each_pci_dev(pdev) {
171 node = find_Device_Node(pdev->bus->number, pdev->devfn);
172 printk("pci dev %p (%x.%x), node %p\n", pdev,
173 pdev->bus->number, pdev->devfn, node);
174
175 if (node != NULL) {
176 struct pci_dn *pdn = PCI_DN(node);
177 const u32 *agent;
178
179 agent = of_get_property(node, "linux,agent-id", NULL);
180 if ((pdn != NULL) && (agent != NULL)) {
181 u8 irq = iSeries_allocate_IRQ(pdn->busno, 0,
182 pdn->bussubno);
183 int err;
184
185 err = HvCallXm_connectBusUnit(pdn->busno, pdn->bussubno,
186 *agent, irq);
187 if (err)
188 pci_Log_Error("Connect Bus Unit",
189 pdn->busno, pdn->bussubno, *agent, err);
190 else {
191 err = HvCallPci_configStore8(pdn->busno, pdn->bussubno,
192 *agent,
193 PCI_INTERRUPT_LINE,
194 irq);
195 if (err)
196 pci_Log_Error("PciCfgStore Irq Failed!",
197 pdn->busno, pdn->bussubno, *agent, err);
198 }
199 if (!err)
200 pdev->irq = irq;
201 }
202
203 ++DeviceCount;
204 pdev->sysdata = (void *)node;
205 PCI_DN(node)->pcidev = pdev;
206 allocate_device_bars(pdev);
207 iSeries_Device_Information(pdev, DeviceCount);
208 iommu_devnode_init_iSeries(pdev, node);
209 } else
210 printk("PCI: Device Tree not found for 0x%016lX\n",
211 (unsigned long)pdev);
212 }
213 iSeries_activate_IRQs();
214 mf_display_src(0xC9000200);
215} 378}
216 379
217/* 380/*
218 * Look down the chain to find the matching Device Device 381 * Look down the chain to find the matching Device Device
219 */ 382 */
220static struct device_node *find_Device_Node(int bus, int devfn) 383static struct device_node *find_device_node(int bus, int devfn)
221{ 384{
222 struct device_node *node; 385 struct device_node *node;
223 386
@@ -230,22 +393,67 @@ static struct device_node *find_Device_Node(int bus, int devfn)
230 return NULL; 393 return NULL;
231} 394}
232 395
233#if 0
234/* 396/*
235 * Returns the device node for the passed pci_dev 397 * iSeries_pcibios_fixup_resources
236 * Sanity Check Node PciDev to passed pci_dev 398 *
237 * If none is found, returns a NULL which the client must handle. 399 * Fixes up all resources for devices
238 */ 400 */
239static struct device_node *get_Device_Node(struct pci_dev *pdev) 401void __init iSeries_pcibios_fixup_resources(struct pci_dev *pdev)
240{ 402{
403 const u32 *agent;
404 const u32 *sub_bus;
405 unsigned char bus = pdev->bus->number;
241 struct device_node *node; 406 struct device_node *node;
407 int i;
408
409 node = find_device_node(bus, pdev->devfn);
410 pr_debug("PCI: iSeries %s, pdev %p, node %p\n",
411 pci_name(pdev), pdev, node);
412 if (!node) {
413 printk("PCI: %s disabled, device tree entry not found !\n",
414 pci_name(pdev));
415 for (i = 0; i <= PCI_ROM_RESOURCE; i++)
416 pdev->resource[i].flags = 0;
417 return;
418 }
419 sub_bus = of_get_property(node, "linux,subbus", NULL);
420 agent = of_get_property(node, "linux,agent-id", NULL);
421 if (agent && sub_bus) {
422 u8 irq = iSeries_allocate_IRQ(bus, 0, *sub_bus);
423 int err;
424
425 err = HvCallXm_connectBusUnit(bus, *sub_bus, *agent, irq);
426 if (err)
427 pci_log_error("Connect Bus Unit",
428 bus, *sub_bus, *agent, err);
429 else {
430 err = HvCallPci_configStore8(bus, *sub_bus,
431 *agent, PCI_INTERRUPT_LINE, irq);
432 if (err)
433 pci_log_error("PciCfgStore Irq Failed!",
434 bus, *sub_bus, *agent, err);
435 else
436 pdev->irq = irq;
437 }
438 }
242 439
243 node = pdev->sysdata; 440 pdev->sysdata = node;
244 if (node == NULL || PCI_DN(node)->pcidev != pdev) 441 PCI_DN(node)->pcidev = pdev;
245 node = find_Device_Node(pdev->bus->number, pdev->devfn); 442 allocate_device_bars(pdev);
246 return node; 443 iseries_device_information(pdev, bus, *sub_bus);
444 iommu_devnode_init_iSeries(pdev, node);
445}
446
447/*
448 * iSeries_pci_final_fixup(void)
449 */
450void __init iSeries_pci_final_fixup(void)
451{
452 /* Fix up at the device node and pci_dev relationship */
453 mf_display_src(0xC9000100);
454 iSeries_activate_IRQs();
455 mf_display_src(0xC9000200);
247} 456}
248#endif
249 457
250/* 458/*
251 * Config space read and write functions. 459 * Config space read and write functions.
@@ -269,7 +477,7 @@ static u64 hv_cfg_write_func[4] = {
269static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn, 477static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
270 int offset, int size, u32 *val) 478 int offset, int size, u32 *val)
271{ 479{
272 struct device_node *node = find_Device_Node(bus->number, devfn); 480 struct device_node *node = find_device_node(bus->number, devfn);
273 u64 fn; 481 u64 fn;
274 struct HvCallPci_LoadReturn ret; 482 struct HvCallPci_LoadReturn ret;
275 483
@@ -299,7 +507,7 @@ static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
299static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn, 507static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
300 int offset, int size, u32 val) 508 int offset, int size, u32 val)
301{ 509{
302 struct device_node *node = find_Device_Node(bus->number, devfn); 510 struct device_node *node = find_device_node(bus->number, devfn);
303 u64 fn; 511 u64 fn;
304 u64 ret; 512 u64 ret;
305 513
@@ -331,22 +539,22 @@ static struct pci_ops iSeries_pci_ops = {
331 * PCI: Device 23.90 ReadL Retry( 1) 539 * PCI: Device 23.90 ReadL Retry( 1)
332 * PCI: Device 23.90 ReadL Retry Successful(1) 540 * PCI: Device 23.90 ReadL Retry Successful(1)
333 */ 541 */
334static int CheckReturnCode(char *TextHdr, struct device_node *DevNode, 542static int check_return_code(char *type, struct device_node *dn,
335 int *retry, u64 ret) 543 int *retry, u64 ret)
336{ 544{
337 if (ret != 0) { 545 if (ret != 0) {
338 struct pci_dn *pdn = PCI_DN(DevNode); 546 struct pci_dn *pdn = PCI_DN(dn);
339 547
340 (*retry)++; 548 (*retry)++;
341 printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n", 549 printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n",
342 TextHdr, pdn->busno, pdn->devfn, 550 type, pdn->busno, pdn->devfn,
343 *retry, (int)ret); 551 *retry, (int)ret);
344 /* 552 /*
345 * Bump the retry and check for retry count exceeded. 553 * Bump the retry and check for retry count exceeded.
346 * If, Exceeded, panic the system. 554 * If, Exceeded, panic the system.
347 */ 555 */
348 if (((*retry) > Pci_Retry_Max) && 556 if (((*retry) > PCI_RETRY_MAX) &&
349 (Pci_Error_Flag > 0)) { 557 (limit_pci_retries > 0)) {
350 mf_display_src(0xB6000103); 558 mf_display_src(0xB6000103);
351 panic_timeout = 0; 559 panic_timeout = 0;
352 panic("PCI: Hardware I/O Error, SRC B6000103, " 560 panic("PCI: Hardware I/O Error, SRC B6000103, "
@@ -363,28 +571,40 @@ static int CheckReturnCode(char *TextHdr, struct device_node *DevNode,
363 * the exposure of being device global. 571 * the exposure of being device global.
364 */ 572 */
365static inline struct device_node *xlate_iomm_address( 573static inline struct device_node *xlate_iomm_address(
366 const volatile void __iomem *IoAddress, 574 const volatile void __iomem *addr,
367 u64 *dsaptr, u64 *BarOffsetPtr) 575 u64 *dsaptr, u64 *bar_offset, const char *func)
368{ 576{
369 unsigned long OrigIoAddr; 577 unsigned long orig_addr;
370 unsigned long BaseIoAddr; 578 unsigned long base_addr;
371 unsigned long TableIndex; 579 unsigned long ind;
372 struct device_node *DevNode; 580 struct device_node *dn;
373 581
374 OrigIoAddr = (unsigned long __force)IoAddress; 582 orig_addr = (unsigned long __force)addr;
375 if ((OrigIoAddr < BASE_IO_MEMORY) || (OrigIoAddr >= max_io_memory)) 583 if ((orig_addr < BASE_IO_MEMORY) || (orig_addr >= max_io_memory)) {
584 static unsigned long last_jiffies;
585 static int num_printed;
586
587 if ((jiffies - last_jiffies) > 60 * HZ) {
588 last_jiffies = jiffies;
589 num_printed = 0;
590 }
591 if (num_printed++ < 10)
592 printk(KERN_ERR
593 "iSeries_%s: invalid access at IO address %p\n",
594 func, addr);
376 return NULL; 595 return NULL;
377 BaseIoAddr = OrigIoAddr - BASE_IO_MEMORY; 596 }
378 TableIndex = BaseIoAddr / IOMM_TABLE_ENTRY_SIZE; 597 base_addr = orig_addr - BASE_IO_MEMORY;
379 DevNode = iomm_table[TableIndex]; 598 ind = base_addr / IOMM_TABLE_ENTRY_SIZE;
380 599 dn = iomm_table[ind];
381 if (DevNode != NULL) { 600
382 int barnum = iobar_table[TableIndex]; 601 if (dn != NULL) {
383 *dsaptr = iseries_ds_addr(DevNode) | (barnum << 24); 602 int barnum = iobar_table[ind];
384 *BarOffsetPtr = BaseIoAddr % IOMM_TABLE_ENTRY_SIZE; 603 *dsaptr = iseries_ds_addr(dn) | (barnum << 24);
604 *bar_offset = base_addr % IOMM_TABLE_ENTRY_SIZE;
385 } else 605 } else
386 panic("PCI: Invalid PCI IoAddress detected!\n"); 606 panic("PCI: Invalid PCI IO address detected!\n");
387 return DevNode; 607 return dn;
388} 608}
389 609
390/* 610/*
@@ -392,91 +612,58 @@ static inline struct device_node *xlate_iomm_address(
392 * On MM I/O error, all ones are returned and iSeries_pci_IoError is cal 612 * On MM I/O error, all ones are returned and iSeries_pci_IoError is cal
393 * else, data is returned in Big Endian format. 613 * else, data is returned in Big Endian format.
394 */ 614 */
395static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) 615static u8 iseries_readb(const volatile void __iomem *addr)
396{ 616{
397 u64 BarOffset; 617 u64 bar_offset;
398 u64 dsa; 618 u64 dsa;
399 int retry = 0; 619 int retry = 0;
400 struct HvCallPci_LoadReturn ret; 620 struct HvCallPci_LoadReturn ret;
401 struct device_node *DevNode = 621 struct device_node *dn =
402 xlate_iomm_address(IoAddress, &dsa, &BarOffset); 622 xlate_iomm_address(addr, &dsa, &bar_offset, "read_byte");
403
404 if (DevNode == NULL) {
405 static unsigned long last_jiffies;
406 static int num_printed;
407 623
408 if ((jiffies - last_jiffies) > 60 * HZ) { 624 if (dn == NULL)
409 last_jiffies = jiffies;
410 num_printed = 0;
411 }
412 if (num_printed++ < 10)
413 printk(KERN_ERR "iSeries_Read_Byte: invalid access at IO address %p\n",
414 IoAddress);
415 return 0xff; 625 return 0xff;
416 }
417 do { 626 do {
418 HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0); 627 HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, bar_offset, 0);
419 } while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0); 628 } while (check_return_code("RDB", dn, &retry, ret.rc) != 0);
420 629
421 return ret.value; 630 return ret.value;
422} 631}
423 632
424static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) 633static u16 iseries_readw_be(const volatile void __iomem *addr)
425{ 634{
426 u64 BarOffset; 635 u64 bar_offset;
427 u64 dsa; 636 u64 dsa;
428 int retry = 0; 637 int retry = 0;
429 struct HvCallPci_LoadReturn ret; 638 struct HvCallPci_LoadReturn ret;
430 struct device_node *DevNode = 639 struct device_node *dn =
431 xlate_iomm_address(IoAddress, &dsa, &BarOffset); 640 xlate_iomm_address(addr, &dsa, &bar_offset, "read_word");
432 641
433 if (DevNode == NULL) { 642 if (dn == NULL)
434 static unsigned long last_jiffies;
435 static int num_printed;
436
437 if ((jiffies - last_jiffies) > 60 * HZ) {
438 last_jiffies = jiffies;
439 num_printed = 0;
440 }
441 if (num_printed++ < 10)
442 printk(KERN_ERR "iSeries_Read_Word: invalid access at IO address %p\n",
443 IoAddress);
444 return 0xffff; 643 return 0xffff;
445 }
446 do { 644 do {
447 HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa, 645 HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa,
448 BarOffset, 0); 646 bar_offset, 0);
449 } while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0); 647 } while (check_return_code("RDW", dn, &retry, ret.rc) != 0);
450 648
451 return ret.value; 649 return ret.value;
452} 650}
453 651
454static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) 652static u32 iseries_readl_be(const volatile void __iomem *addr)
455{ 653{
456 u64 BarOffset; 654 u64 bar_offset;
457 u64 dsa; 655 u64 dsa;
458 int retry = 0; 656 int retry = 0;
459 struct HvCallPci_LoadReturn ret; 657 struct HvCallPci_LoadReturn ret;
460 struct device_node *DevNode = 658 struct device_node *dn =
461 xlate_iomm_address(IoAddress, &dsa, &BarOffset); 659 xlate_iomm_address(addr, &dsa, &bar_offset, "read_long");
462
463 if (DevNode == NULL) {
464 static unsigned long last_jiffies;
465 static int num_printed;
466 660
467 if ((jiffies - last_jiffies) > 60 * HZ) { 661 if (dn == NULL)
468 last_jiffies = jiffies;
469 num_printed = 0;
470 }
471 if (num_printed++ < 10)
472 printk(KERN_ERR "iSeries_Read_Long: invalid access at IO address %p\n",
473 IoAddress);
474 return 0xffffffff; 662 return 0xffffffff;
475 }
476 do { 663 do {
477 HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa, 664 HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa,
478 BarOffset, 0); 665 bar_offset, 0);
479 } while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0); 666 } while (check_return_code("RDL", dn, &retry, ret.rc) != 0);
480 667
481 return ret.value; 668 return ret.value;
482} 669}
@@ -485,134 +672,72 @@ static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
485 * Write MM I/O Instructions for the iSeries 672 * Write MM I/O Instructions for the iSeries
486 * 673 *
487 */ 674 */
488static void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) 675static void iseries_writeb(u8 data, volatile void __iomem *addr)
489{ 676{
490 u64 BarOffset; 677 u64 bar_offset;
491 u64 dsa; 678 u64 dsa;
492 int retry = 0; 679 int retry = 0;
493 u64 rc; 680 u64 rc;
494 struct device_node *DevNode = 681 struct device_node *dn =
495 xlate_iomm_address(IoAddress, &dsa, &BarOffset); 682 xlate_iomm_address(addr, &dsa, &bar_offset, "write_byte");
496
497 if (DevNode == NULL) {
498 static unsigned long last_jiffies;
499 static int num_printed;
500 683
501 if ((jiffies - last_jiffies) > 60 * HZ) { 684 if (dn == NULL)
502 last_jiffies = jiffies;
503 num_printed = 0;
504 }
505 if (num_printed++ < 10)
506 printk(KERN_ERR "iSeries_Write_Byte: invalid access at IO address %p\n", IoAddress);
507 return; 685 return;
508 }
509 do { 686 do {
510 rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0); 687 rc = HvCall4(HvCallPciBarStore8, dsa, bar_offset, data, 0);
511 } while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0); 688 } while (check_return_code("WWB", dn, &retry, rc) != 0);
512} 689}
513 690
514static void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) 691static void iseries_writew_be(u16 data, volatile void __iomem *addr)
515{ 692{
516 u64 BarOffset; 693 u64 bar_offset;
517 u64 dsa; 694 u64 dsa;
518 int retry = 0; 695 int retry = 0;
519 u64 rc; 696 u64 rc;
520 struct device_node *DevNode = 697 struct device_node *dn =
521 xlate_iomm_address(IoAddress, &dsa, &BarOffset); 698 xlate_iomm_address(addr, &dsa, &bar_offset, "write_word");
522 699
523 if (DevNode == NULL) { 700 if (dn == NULL)
524 static unsigned long last_jiffies;
525 static int num_printed;
526
527 if ((jiffies - last_jiffies) > 60 * HZ) {
528 last_jiffies = jiffies;
529 num_printed = 0;
530 }
531 if (num_printed++ < 10)
532 printk(KERN_ERR "iSeries_Write_Word: invalid access at IO address %p\n",
533 IoAddress);
534 return; 701 return;
535 }
536 do { 702 do {
537 rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, data, 0); 703 rc = HvCall4(HvCallPciBarStore16, dsa, bar_offset, data, 0);
538 } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0); 704 } while (check_return_code("WWW", dn, &retry, rc) != 0);
539} 705}
540 706
541static void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) 707static void iseries_writel_be(u32 data, volatile void __iomem *addr)
542{ 708{
543 u64 BarOffset; 709 u64 bar_offset;
544 u64 dsa; 710 u64 dsa;
545 int retry = 0; 711 int retry = 0;
546 u64 rc; 712 u64 rc;
547 struct device_node *DevNode = 713 struct device_node *dn =
548 xlate_iomm_address(IoAddress, &dsa, &BarOffset); 714 xlate_iomm_address(addr, &dsa, &bar_offset, "write_long");
549
550 if (DevNode == NULL) {
551 static unsigned long last_jiffies;
552 static int num_printed;
553 715
554 if ((jiffies - last_jiffies) > 60 * HZ) { 716 if (dn == NULL)
555 last_jiffies = jiffies;
556 num_printed = 0;
557 }
558 if (num_printed++ < 10)
559 printk(KERN_ERR "iSeries_Write_Long: invalid access at IO address %p\n",
560 IoAddress);
561 return; 717 return;
562 }
563 do { 718 do {
564 rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, data, 0); 719 rc = HvCall4(HvCallPciBarStore32, dsa, bar_offset, data, 0);
565 } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0); 720 } while (check_return_code("WWL", dn, &retry, rc) != 0);
566}
567
568static u8 iseries_readb(const volatile void __iomem *addr)
569{
570 return iSeries_Read_Byte(addr);
571} 721}
572 722
573static u16 iseries_readw(const volatile void __iomem *addr) 723static u16 iseries_readw(const volatile void __iomem *addr)
574{ 724{
575 return le16_to_cpu(iSeries_Read_Word(addr)); 725 return le16_to_cpu(iseries_readw_be(addr));
576} 726}
577 727
578static u32 iseries_readl(const volatile void __iomem *addr) 728static u32 iseries_readl(const volatile void __iomem *addr)
579{ 729{
580 return le32_to_cpu(iSeries_Read_Long(addr)); 730 return le32_to_cpu(iseries_readl_be(addr));
581}
582
583static u16 iseries_readw_be(const volatile void __iomem *addr)
584{
585 return iSeries_Read_Word(addr);
586}
587
588static u32 iseries_readl_be(const volatile void __iomem *addr)
589{
590 return iSeries_Read_Long(addr);
591}
592
593static void iseries_writeb(u8 data, volatile void __iomem *addr)
594{
595 iSeries_Write_Byte(data, addr);
596} 731}
597 732
598static void iseries_writew(u16 data, volatile void __iomem *addr) 733static void iseries_writew(u16 data, volatile void __iomem *addr)
599{ 734{
600 iSeries_Write_Word(cpu_to_le16(data), addr); 735 iseries_writew_be(cpu_to_le16(data), addr);
601} 736}
602 737
603static void iseries_writel(u32 data, volatile void __iomem *addr) 738static void iseries_writel(u32 data, volatile void __iomem *addr)
604{ 739{
605 iSeries_Write_Long(cpu_to_le32(data), addr); 740 iseries_writel(cpu_to_le32(data), addr);
606}
607
608static void iseries_writew_be(u16 data, volatile void __iomem *addr)
609{
610 iSeries_Write_Word(data, addr);
611}
612
613static void iseries_writel_be(u32 data, volatile void __iomem *addr)
614{
615 iSeries_Write_Long(data, addr);
616} 741}
617 742
618static void iseries_readsb(const volatile void __iomem *addr, void *buf, 743static void iseries_readsb(const volatile void __iomem *addr, void *buf,
@@ -620,7 +745,7 @@ static void iseries_readsb(const volatile void __iomem *addr, void *buf,
620{ 745{
621 u8 *dst = buf; 746 u8 *dst = buf;
622 while(count-- > 0) 747 while(count-- > 0)
623 *(dst++) = iSeries_Read_Byte(addr); 748 *(dst++) = iseries_readb(addr);
624} 749}
625 750
626static void iseries_readsw(const volatile void __iomem *addr, void *buf, 751static void iseries_readsw(const volatile void __iomem *addr, void *buf,
@@ -628,7 +753,7 @@ static void iseries_readsw(const volatile void __iomem *addr, void *buf,
628{ 753{
629 u16 *dst = buf; 754 u16 *dst = buf;
630 while(count-- > 0) 755 while(count-- > 0)
631 *(dst++) = iSeries_Read_Word(addr); 756 *(dst++) = iseries_readw_be(addr);
632} 757}
633 758
634static void iseries_readsl(const volatile void __iomem *addr, void *buf, 759static void iseries_readsl(const volatile void __iomem *addr, void *buf,
@@ -636,7 +761,7 @@ static void iseries_readsl(const volatile void __iomem *addr, void *buf,
636{ 761{
637 u32 *dst = buf; 762 u32 *dst = buf;
638 while(count-- > 0) 763 while(count-- > 0)
639 *(dst++) = iSeries_Read_Long(addr); 764 *(dst++) = iseries_readl_be(addr);
640} 765}
641 766
642static void iseries_writesb(volatile void __iomem *addr, const void *buf, 767static void iseries_writesb(volatile void __iomem *addr, const void *buf,
@@ -644,7 +769,7 @@ static void iseries_writesb(volatile void __iomem *addr, const void *buf,
644{ 769{
645 const u8 *src = buf; 770 const u8 *src = buf;
646 while(count-- > 0) 771 while(count-- > 0)
647 iSeries_Write_Byte(*(src++), addr); 772 iseries_writeb(*(src++), addr);
648} 773}
649 774
650static void iseries_writesw(volatile void __iomem *addr, const void *buf, 775static void iseries_writesw(volatile void __iomem *addr, const void *buf,
@@ -652,7 +777,7 @@ static void iseries_writesw(volatile void __iomem *addr, const void *buf,
652{ 777{
653 const u16 *src = buf; 778 const u16 *src = buf;
654 while(count-- > 0) 779 while(count-- > 0)
655 iSeries_Write_Word(*(src++), addr); 780 iseries_writew_be(*(src++), addr);
656} 781}
657 782
658static void iseries_writesl(volatile void __iomem *addr, const void *buf, 783static void iseries_writesl(volatile void __iomem *addr, const void *buf,
@@ -660,7 +785,7 @@ static void iseries_writesl(volatile void __iomem *addr, const void *buf,
660{ 785{
661 const u32 *src = buf; 786 const u32 *src = buf;
662 while(count-- > 0) 787 while(count-- > 0)
663 iSeries_Write_Long(*(src++), addr); 788 iseries_writel_be(*(src++), addr);
664} 789}
665 790
666static void iseries_memset_io(volatile void __iomem *addr, int c, 791static void iseries_memset_io(volatile void __iomem *addr, int c,
@@ -669,7 +794,7 @@ static void iseries_memset_io(volatile void __iomem *addr, int c,
669 volatile char __iomem *d = addr; 794 volatile char __iomem *d = addr;
670 795
671 while (n-- > 0) 796 while (n-- > 0)
672 iSeries_Write_Byte(c, d++); 797 iseries_writeb(c, d++);
673} 798}
674 799
675static void iseries_memcpy_fromio(void *dest, const volatile void __iomem *src, 800static void iseries_memcpy_fromio(void *dest, const volatile void __iomem *src,
@@ -679,7 +804,7 @@ static void iseries_memcpy_fromio(void *dest, const volatile void __iomem *src,
679 const volatile char __iomem *s = src; 804 const volatile char __iomem *s = src;
680 805
681 while (n-- > 0) 806 while (n-- > 0)
682 *d++ = iSeries_Read_Byte(s++); 807 *d++ = iseries_readb(s++);
683} 808}
684 809
685static void iseries_memcpy_toio(volatile void __iomem *dest, const void *src, 810static void iseries_memcpy_toio(volatile void __iomem *dest, const void *src,
@@ -689,7 +814,7 @@ static void iseries_memcpy_toio(volatile void __iomem *dest, const void *src,
689 volatile char __iomem *d = dest; 814 volatile char __iomem *d = dest;
690 815
691 while (n-- > 0) 816 while (n-- > 0)
692 iSeries_Write_Byte(*s++, d++); 817 iseries_writeb(*s++, d++);
693} 818}
694 819
695/* We only set MMIO ops. The default PIO ops will be default 820/* We only set MMIO ops. The default PIO ops will be default
@@ -742,6 +867,8 @@ void __init iSeries_pcibios_init(void)
742 /* Install IO hooks */ 867 /* Install IO hooks */
743 ppc_pci_io = iseries_pci_io; 868 ppc_pci_io = iseries_pci_io;
744 869
870 pci_probe_only = 1;
871
745 /* iSeries has no IO space in the common sense, it needs to set 872 /* iSeries has no IO space in the common sense, it needs to set
746 * the IO base to 0 873 * the IO base to 0
747 */ 874 */
@@ -767,11 +894,21 @@ void __init iSeries_pcibios_init(void)
767 phb = pcibios_alloc_controller(node); 894 phb = pcibios_alloc_controller(node);
768 if (phb == NULL) 895 if (phb == NULL)
769 continue; 896 continue;
897 /* All legacy iSeries PHBs are in domain zero */
898 phb->global_number = 0;
770 899
771 phb->pci_mem_offset = bus;
772 phb->first_busno = bus; 900 phb->first_busno = bus;
773 phb->last_busno = bus; 901 phb->last_busno = bus;
774 phb->ops = &iSeries_pci_ops; 902 phb->ops = &iSeries_pci_ops;
903 phb->io_base_virt = (void __iomem *)_IO_BASE;
904 phb->io_resource.flags = IORESOURCE_IO;
905 phb->io_resource.start = BASE_IO_MEMORY;
906 phb->io_resource.end = END_IO_MEMORY;
907 phb->io_resource.name = "iSeries PCI IO";
908 phb->mem_resources[0].flags = IORESOURCE_MEM;
909 phb->mem_resources[0].start = BASE_IO_MEMORY;
910 phb->mem_resources[0].end = END_IO_MEMORY;
911 phb->mem_resources[0].name = "Series PCI MEM";
775 } 912 }
776 913
777 of_node_put(root); 914 of_node_put(root);
diff --git a/arch/powerpc/platforms/iseries/pci.h b/arch/powerpc/platforms/iseries/pci.h
index 33a8489fde54..d9cf974c2718 100644
--- a/arch/powerpc/platforms/iseries/pci.h
+++ b/arch/powerpc/platforms/iseries/pci.h
@@ -30,10 +30,6 @@
30 * End Change Activity 30 * End Change Activity
31 */ 31 */
32 32
33#include <asm/pci-bridge.h>
34
35struct pci_dev; /* For Forward Reference */
36
37/* 33/*
38 * Decodes Linux DevFn to iSeries DevFn, bridge device, or function. 34 * Decodes Linux DevFn to iSeries DevFn, bridge device, or function.
39 * For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h 35 * For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h
@@ -47,17 +43,16 @@ struct pci_dev; /* For Forward Reference */
47#define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus) ((subbus >> 5) & 0x7) 43#define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus) ((subbus >> 5) & 0x7)
48#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7) 44#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7)
49 45
50/* 46struct pci_dev;
51 * Generate a Direct Select Address for the Hypervisor 47
52 */ 48#ifdef CONFIG_PCI
53static inline u64 iseries_ds_addr(struct device_node *node) 49extern void iSeries_pcibios_init(void);
54{ 50extern void iSeries_pci_final_fixup(void);
55 struct pci_dn *pdn = PCI_DN(node); 51extern void iSeries_pcibios_fixup_resources(struct pci_dev *dev);
56 52#else
57 return ((u64)pdn->busno << 48) + ((u64)pdn->bussubno << 40) 53static inline void iSeries_pcibios_init(void) { }
58 + ((u64)0x10 << 32); 54static inline void iSeries_pci_final_fixup(void) { }
59} 55static inline void iSeries_pcibios_fixup_resources(struct pci_dev *dev) {}
60 56#endif
61extern void iSeries_Device_Information(struct pci_dev*, int);
62 57
63#endif /* _PLATFORMS_ISERIES_PCI_H */ 58#endif /* _PLATFORMS_ISERIES_PCI_H */
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 0877a8834110..b72120751bbe 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -63,6 +63,7 @@
63#include "main_store.h" 63#include "main_store.h"
64#include "call_sm.h" 64#include "call_sm.h"
65#include "call_hpt.h" 65#include "call_hpt.h"
66#include "pci.h"
66 67
67#ifdef DEBUG 68#ifdef DEBUG
68#define DBG(fmt...) udbg_printf(fmt) 69#define DBG(fmt...) udbg_printf(fmt)
@@ -74,11 +75,6 @@
74static unsigned long build_iSeries_Memory_Map(void); 75static unsigned long build_iSeries_Memory_Map(void);
75static void iseries_shared_idle(void); 76static void iseries_shared_idle(void);
76static void iseries_dedicated_idle(void); 77static void iseries_dedicated_idle(void);
77#ifdef CONFIG_PCI
78extern void iSeries_pci_final_fixup(void);
79#else
80static void iSeries_pci_final_fixup(void) { }
81#endif
82 78
83 79
84struct MemoryBlock { 80struct MemoryBlock {
@@ -112,13 +108,13 @@ static unsigned long iSeries_process_Condor_mainstore_vpd(
112 * correctly. 108 * correctly.
113 */ 109 */
114 mb_array[0].logicalStart = 0; 110 mb_array[0].logicalStart = 0;
115 mb_array[0].logicalEnd = 0x100000000; 111 mb_array[0].logicalEnd = 0x100000000UL;
116 mb_array[0].absStart = 0; 112 mb_array[0].absStart = 0;
117 mb_array[0].absEnd = 0x100000000; 113 mb_array[0].absEnd = 0x100000000UL;
118 114
119 if (holeSize) { 115 if (holeSize) {
120 numMemoryBlocks = 2; 116 numMemoryBlocks = 2;
121 holeStart = holeStart & 0x000fffffffffffff; 117 holeStart = holeStart & 0x000fffffffffffffUL;
122 holeStart = addr_to_chunk(holeStart); 118 holeStart = addr_to_chunk(holeStart);
123 holeFirstChunk = holeStart; 119 holeFirstChunk = holeStart;
124 holeSize = addr_to_chunk(holeSize); 120 holeSize = addr_to_chunk(holeSize);
@@ -128,9 +124,9 @@ static unsigned long iSeries_process_Condor_mainstore_vpd(
128 mb_array[0].logicalEnd = holeFirstChunk; 124 mb_array[0].logicalEnd = holeFirstChunk;
129 mb_array[0].absEnd = holeFirstChunk; 125 mb_array[0].absEnd = holeFirstChunk;
130 mb_array[1].logicalStart = holeFirstChunk; 126 mb_array[1].logicalStart = holeFirstChunk;
131 mb_array[1].logicalEnd = 0x100000000 - holeSizeChunks; 127 mb_array[1].logicalEnd = 0x100000000UL - holeSizeChunks;
132 mb_array[1].absStart = holeFirstChunk + holeSizeChunks; 128 mb_array[1].absStart = holeFirstChunk + holeSizeChunks;
133 mb_array[1].absEnd = 0x100000000; 129 mb_array[1].absEnd = 0x100000000UL;
134 } 130 }
135 return numMemoryBlocks; 131 return numMemoryBlocks;
136} 132}
@@ -234,9 +230,9 @@ static unsigned long iSeries_process_Regatta_mainstore_vpd(
234 mb_array[i].logicalEnd, 230 mb_array[i].logicalEnd,
235 mb_array[i].absStart, mb_array[i].absEnd); 231 mb_array[i].absStart, mb_array[i].absEnd);
236 mb_array[i].absStart = addr_to_chunk(mb_array[i].absStart & 232 mb_array[i].absStart = addr_to_chunk(mb_array[i].absStart &
237 0x000fffffffffffff); 233 0x000fffffffffffffUL);
238 mb_array[i].absEnd = addr_to_chunk(mb_array[i].absEnd & 234 mb_array[i].absEnd = addr_to_chunk(mb_array[i].absEnd &
239 0x000fffffffffffff); 235 0x000fffffffffffffUL);
240 mb_array[i].logicalStart = 236 mb_array[i].logicalStart =
241 addr_to_chunk(mb_array[i].logicalStart); 237 addr_to_chunk(mb_array[i].logicalStart);
242 mb_array[i].logicalEnd = addr_to_chunk(mb_array[i].logicalEnd); 238 mb_array[i].logicalEnd = addr_to_chunk(mb_array[i].logicalEnd);
@@ -320,7 +316,7 @@ struct mschunks_map mschunks_map = {
320}; 316};
321EXPORT_SYMBOL(mschunks_map); 317EXPORT_SYMBOL(mschunks_map);
322 318
323void mschunks_alloc(unsigned long num_chunks) 319static void mschunks_alloc(unsigned long num_chunks)
324{ 320{
325 klimit = _ALIGN(klimit, sizeof(u32)); 321 klimit = _ALIGN(klimit, sizeof(u32));
326 mschunks_map.mapping = (u32 *)klimit; 322 mschunks_map.mapping = (u32 *)klimit;
@@ -499,6 +495,8 @@ static void __init iSeries_setup_arch(void)
499 itVpdAreas.xSlicMaxLogicalProcs); 495 itVpdAreas.xSlicMaxLogicalProcs);
500 printk("Max physical processors = %d\n", 496 printk("Max physical processors = %d\n",
501 itVpdAreas.xSlicMaxPhysicalProcs); 497 itVpdAreas.xSlicMaxPhysicalProcs);
498
499 iSeries_pcibios_init();
502} 500}
503 501
504static void iSeries_show_cpuinfo(struct seq_file *m) 502static void iSeries_show_cpuinfo(struct seq_file *m)
@@ -641,24 +639,25 @@ static int __init iseries_probe(void)
641} 639}
642 640
643define_machine(iseries) { 641define_machine(iseries) {
644 .name = "iSeries", 642 .name = "iSeries",
645 .setup_arch = iSeries_setup_arch, 643 .setup_arch = iSeries_setup_arch,
646 .show_cpuinfo = iSeries_show_cpuinfo, 644 .show_cpuinfo = iSeries_show_cpuinfo,
647 .init_IRQ = iSeries_init_IRQ, 645 .init_IRQ = iSeries_init_IRQ,
648 .get_irq = iSeries_get_irq, 646 .get_irq = iSeries_get_irq,
649 .init_early = iSeries_init_early, 647 .init_early = iSeries_init_early,
650 .pcibios_fixup = iSeries_pci_final_fixup, 648 .pcibios_fixup = iSeries_pci_final_fixup,
651 .restart = mf_reboot, 649 .pcibios_fixup_resources= iSeries_pcibios_fixup_resources,
652 .power_off = mf_power_off, 650 .restart = mf_reboot,
653 .halt = mf_power_off, 651 .power_off = mf_power_off,
654 .get_boot_time = iSeries_get_boot_time, 652 .halt = mf_power_off,
655 .set_rtc_time = iSeries_set_rtc_time, 653 .get_boot_time = iSeries_get_boot_time,
656 .get_rtc_time = iSeries_get_rtc_time, 654 .set_rtc_time = iSeries_set_rtc_time,
657 .calibrate_decr = generic_calibrate_decr, 655 .get_rtc_time = iSeries_get_rtc_time,
658 .progress = iSeries_progress, 656 .calibrate_decr = generic_calibrate_decr,
659 .probe = iseries_probe, 657 .progress = iSeries_progress,
660 .ioremap = iseries_ioremap, 658 .probe = iseries_probe,
661 .iounmap = iseries_iounmap, 659 .ioremap = iseries_ioremap,
660 .iounmap = iseries_iounmap,
662 /* XXX Implement enable_pmcs for iSeries */ 661 /* XXX Implement enable_pmcs for iSeries */
663}; 662};
664 663
diff --git a/arch/powerpc/platforms/iseries/setup.h b/arch/powerpc/platforms/iseries/setup.h
index 0a47ac53c959..729754bbb018 100644
--- a/arch/powerpc/platforms/iseries/setup.h
+++ b/arch/powerpc/platforms/iseries/setup.h
@@ -17,6 +17,7 @@
17#ifndef __ISERIES_SETUP_H__ 17#ifndef __ISERIES_SETUP_H__
18#define __ISERIES_SETUP_H__ 18#define __ISERIES_SETUP_H__
19 19
20extern void *iSeries_early_setup(void);
20extern unsigned long iSeries_get_boot_time(void); 21extern unsigned long iSeries_get_boot_time(void);
21extern int iSeries_set_rtc_time(struct rtc_time *tm); 22extern int iSeries_set_rtc_time(struct rtc_time *tm);
22extern void iSeries_get_rtc_time(struct rtc_time *tm); 23extern void iSeries_get_rtc_time(struct rtc_time *tm);
diff --git a/arch/powerpc/platforms/iseries/vpdinfo.c b/arch/powerpc/platforms/iseries/vpdinfo.c
deleted file mode 100644
index 9f83878a0c2e..000000000000
--- a/arch/powerpc/platforms/iseries/vpdinfo.c
+++ /dev/null
@@ -1,275 +0,0 @@
1/*
2 * This code gets the card location of the hardware
3 * Copyright (C) 2001 <Allan H Trautman> <IBM Corp>
4 * Copyright (C) 2005 Stephen Rothwel, IBM Corp
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the:
18 * Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330,
20 * Boston, MA 02111-1307 USA
21 *
22 * Change Activity:
23 * Created, Feb 2, 2001
24 * Ported to ppc64, August 20, 2001
25 * End Change Activity
26 */
27#include <linux/init.h>
28#include <linux/module.h>
29#include <linux/pci.h>
30
31#include <asm/types.h>
32#include <asm/resource.h>
33#include <asm/abs_addr.h>
34#include <asm/pci-bridge.h>
35#include <asm/iseries/hv_types.h>
36
37#include "pci.h"
38#include "call_pci.h"
39
40/*
41 * Size of Bus VPD data
42 */
43#define BUS_VPDSIZE 1024
44
45/*
46 * Bus Vpd Tags
47 */
48#define VpdEndOfAreaTag 0x79
49#define VpdIdStringTag 0x82
50#define VpdVendorAreaTag 0x84
51
52/*
53 * Mfg Area Tags
54 */
55#define VpdFruFrameId 0x4649 // "FI"
56#define VpdSlotMapFormat 0x4D46 // "MF"
57#define VpdSlotMap 0x534D // "SM"
58
59/*
60 * Structures of the areas
61 */
62struct MfgVpdAreaStruct {
63 u16 Tag;
64 u8 TagLength;
65 u8 AreaData1;
66 u8 AreaData2;
67};
68typedef struct MfgVpdAreaStruct MfgArea;
69#define MFG_ENTRY_SIZE 3
70
71struct SlotMapStruct {
72 u8 AgentId;
73 u8 SecondaryAgentId;
74 u8 PhbId;
75 char CardLocation[3];
76 char Parms[8];
77 char Reserved[2];
78};
79typedef struct SlotMapStruct SlotMap;
80#define SLOT_ENTRY_SIZE 16
81
82/*
83 * Parse the Slot Area
84 */
85static void __init iSeries_Parse_SlotArea(SlotMap *MapPtr, int MapLen,
86 HvAgentId agent, u8 *PhbId, char card[4])
87{
88 int SlotMapLen = MapLen;
89 SlotMap *SlotMapPtr = MapPtr;
90
91 /*
92 * Parse Slot label until we find the one requested
93 */
94 while (SlotMapLen > 0) {
95 if (SlotMapPtr->AgentId == agent) {
96 /*
97 * If Phb wasn't found, grab the entry first one found.
98 */
99 if (*PhbId == 0xff)
100 *PhbId = SlotMapPtr->PhbId;
101 /* Found it, extract the data. */
102 if (SlotMapPtr->PhbId == *PhbId) {
103 memcpy(card, &SlotMapPtr->CardLocation, 3);
104 card[3] = 0;
105 break;
106 }
107 }
108 /* Point to the next Slot */
109 SlotMapPtr = (SlotMap *)((char *)SlotMapPtr + SLOT_ENTRY_SIZE);
110 SlotMapLen -= SLOT_ENTRY_SIZE;
111 }
112}
113
114/*
115 * Parse the Mfg Area
116 */
117static void __init iSeries_Parse_MfgArea(u8 *AreaData, int AreaLen,
118 HvAgentId agent, u8 *PhbId,
119 u8 *frame, char card[4])
120{
121 MfgArea *MfgAreaPtr = (MfgArea *)AreaData;
122 int MfgAreaLen = AreaLen;
123 u16 SlotMapFmt = 0;
124
125 /* Parse Mfg Data */
126 while (MfgAreaLen > 0) {
127 int MfgTagLen = MfgAreaPtr->TagLength;
128 /* Frame ID (FI 4649020310 ) */
129 if (MfgAreaPtr->Tag == VpdFruFrameId) /* FI */
130 *frame = MfgAreaPtr->AreaData1;
131 /* Slot Map Format (MF 4D46020004 ) */
132 else if (MfgAreaPtr->Tag == VpdSlotMapFormat) /* MF */
133 SlotMapFmt = (MfgAreaPtr->AreaData1 * 256)
134 + MfgAreaPtr->AreaData2;
135 /* Slot Map (SM 534D90 */
136 else if (MfgAreaPtr->Tag == VpdSlotMap) { /* SM */
137 SlotMap *SlotMapPtr;
138
139 if (SlotMapFmt == 0x1004)
140 SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr
141 + MFG_ENTRY_SIZE + 1);
142 else
143 SlotMapPtr = (SlotMap *)((char *)MfgAreaPtr
144 + MFG_ENTRY_SIZE);
145 iSeries_Parse_SlotArea(SlotMapPtr, MfgTagLen,
146 agent, PhbId, card);
147 }
148 /*
149 * Point to the next Mfg Area
150 * Use defined size, sizeof give wrong answer
151 */
152 MfgAreaPtr = (MfgArea *)((char *)MfgAreaPtr + MfgTagLen
153 + MFG_ENTRY_SIZE);
154 MfgAreaLen -= (MfgTagLen + MFG_ENTRY_SIZE);
155 }
156}
157
158/*
159 * Look for "BUS".. Data is not Null terminated.
160 * PHBID of 0xFF indicates PHB was not found in VPD Data.
161 */
162static int __init iSeries_Parse_PhbId(u8 *AreaPtr, int AreaLength)
163{
164 u8 *PhbPtr = AreaPtr;
165 int DataLen = AreaLength;
166 char PhbId = 0xFF;
167
168 while (DataLen > 0) {
169 if ((*PhbPtr == 'B') && (*(PhbPtr + 1) == 'U')
170 && (*(PhbPtr + 2) == 'S')) {
171 PhbPtr += 3;
172 while (*PhbPtr == ' ')
173 ++PhbPtr;
174 PhbId = (*PhbPtr & 0x0F);
175 break;
176 }
177 ++PhbPtr;
178 --DataLen;
179 }
180 return PhbId;
181}
182
183/*
184 * Parse out the VPD Areas
185 */
186static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen,
187 HvAgentId agent, u8 *frame, char card[4])
188{
189 u8 *TagPtr = VpdData;
190 int DataLen = VpdDataLen - 3;
191 u8 PhbId = 0xff;
192
193 while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) {
194 int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256);
195 u8 *AreaData = TagPtr + 3;
196
197 if (*TagPtr == VpdIdStringTag)
198 PhbId = iSeries_Parse_PhbId(AreaData, AreaLen);
199 else if (*TagPtr == VpdVendorAreaTag)
200 iSeries_Parse_MfgArea(AreaData, AreaLen,
201 agent, &PhbId, frame, card);
202 /* Point to next Area. */
203 TagPtr = AreaData + AreaLen;
204 DataLen -= AreaLen;
205 }
206}
207
208static int __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
209 u8 *frame, char card[4])
210{
211 int status = 0;
212 int BusVpdLen = 0;
213 u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
214
215 if (BusVpdPtr == NULL) {
216 printk("PCI: Bus VPD Buffer allocation failure.\n");
217 return 0;
218 }
219 BusVpdLen = HvCallPci_getBusVpd(bus, iseries_hv_addr(BusVpdPtr),
220 BUS_VPDSIZE);
221 if (BusVpdLen == 0) {
222 printk("PCI: Bus VPD Buffer zero length.\n");
223 goto out_free;
224 }
225 /* printk("PCI: BusVpdPtr: %p, %d\n",BusVpdPtr, BusVpdLen); */
226 /* Make sure this is what I think it is */
227 if (*BusVpdPtr != VpdIdStringTag) { /* 0x82 */
228 printk("PCI: Bus VPD Buffer missing starting tag.\n");
229 goto out_free;
230 }
231 iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card);
232 status = 1;
233out_free:
234 kfree(BusVpdPtr);
235 return status;
236}
237
238/*
239 * Prints the device information.
240 * - Pass in pci_dev* pointer to the device.
241 * - Pass in the device count
242 *
243 * Format:
244 * PCI: Bus 0, Device 26, Vendor 0x12AE Frame 1, Card C10 Ethernet
245 * controller
246 */
247void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
248{
249 struct device_node *DevNode = PciDev->sysdata;
250 struct pci_dn *pdn;
251 u16 bus;
252 u8 frame = 0;
253 char card[4];
254 HvSubBusNumber subbus;
255 HvAgentId agent;
256
257 if (DevNode == NULL) {
258 printk("%d. PCI: iSeries_Device_Information DevNode is NULL\n",
259 count);
260 return;
261 }
262
263 pdn = PCI_DN(DevNode);
264 bus = pdn->busno;
265 subbus = pdn->bussubno;
266 agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
267 ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
268
269 if (iSeries_Get_Location_Code(bus, agent, &frame, card)) {
270 printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, "
271 "Card %4s 0x%04X\n", count, bus,
272 PCI_SLOT(PciDev->devfn), PciDev->vendor, frame,
273 card, (int)(PciDev->class >> 8));
274 }
275}
diff --git a/arch/powerpc/platforms/maple/Kconfig b/arch/powerpc/platforms/maple/Kconfig
index f7c95eb5d8ba..a6467a5591fa 100644
--- a/arch/powerpc/platforms/maple/Kconfig
+++ b/arch/powerpc/platforms/maple/Kconfig
@@ -1,6 +1,7 @@
1config PPC_MAPLE 1config PPC_MAPLE
2 depends on PPC_MULTIPLATFORM && PPC64 2 depends on PPC_MULTIPLATFORM && PPC64
3 bool "Maple 970FX Evaluation Board" 3 bool "Maple 970FX Evaluation Board"
4 select PCI
4 select MPIC 5 select MPIC
5 select U3_DART 6 select U3_DART
6 select MPIC_U3_HT_IRQS 7 select MPIC_U3_HT_IRQS
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index 771ed0cf29a5..3ffa0ac170ee 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -558,7 +558,7 @@ void __init maple_pci_init(void)
558 * safe assumptions hopefully. 558 * safe assumptions hopefully.
559 */ 559 */
560 if (u3_agp) { 560 if (u3_agp) {
561 struct device_node *np = u3_agp->arch_data; 561 struct device_node *np = u3_agp->dn;
562 PCI_DN(np)->busno = 0xf0; 562 PCI_DN(np)->busno = 0xf0;
563 for (np = np->child; np; np = np->sibling) 563 for (np = np->child; np; np = np->sibling)
564 PCI_DN(np)->busno = 0xf0; 564 PCI_DN(np)->busno = 0xf0;
diff --git a/arch/powerpc/platforms/pasemi/Kconfig b/arch/powerpc/platforms/pasemi/Kconfig
index 735e1536cbfc..b3458a181a15 100644
--- a/arch/powerpc/platforms/pasemi/Kconfig
+++ b/arch/powerpc/platforms/pasemi/Kconfig
@@ -3,6 +3,7 @@ config PPC_PASEMI
3 bool "PA Semi SoC-based platforms" 3 bool "PA Semi SoC-based platforms"
4 default n 4 default n
5 select MPIC 5 select MPIC
6 select PCI
6 select PPC_UDBG_16550 7 select PPC_UDBG_16550
7 select PPC_NATIVE 8 select PPC_NATIVE
8 select MPIC_BROKEN_REGREAD 9 select MPIC_BROKEN_REGREAD
@@ -17,7 +18,7 @@ config PPC_PASEMI_IOMMU
17 bool "PA Semi IOMMU support" 18 bool "PA Semi IOMMU support"
18 depends on PPC_PASEMI 19 depends on PPC_PASEMI
19 help 20 help
20 IOMMU support for PA6T-1682M 21 IOMMU support for PA Semi PWRficient
21 22
22config PPC_PASEMI_IOMMU_DMA_FORCE 23config PPC_PASEMI_IOMMU_DMA_FORCE
23 bool "Force DMA engine to use IOMMU" 24 bool "Force DMA engine to use IOMMU"
diff --git a/arch/powerpc/platforms/pasemi/cpufreq.c b/arch/powerpc/platforms/pasemi/cpufreq.c
index 1cfb8b0c8fec..58556b028a4c 100644
--- a/arch/powerpc/platforms/pasemi/cpufreq.c
+++ b/arch/powerpc/platforms/pasemi/cpufreq.c
@@ -32,6 +32,7 @@
32#include <asm/io.h> 32#include <asm/io.h>
33#include <asm/prom.h> 33#include <asm/prom.h>
34#include <asm/time.h> 34#include <asm/time.h>
35#include <asm/smp.h>
35 36
36#define SDCASR_REG 0x0100 37#define SDCASR_REG 0x0100
37#define SDCASR_REG_STRIDE 0x1000 38#define SDCASR_REG_STRIDE 0x1000
@@ -124,6 +125,11 @@ static void set_astate(int cpu, unsigned int astate)
124 local_irq_restore(flags); 125 local_irq_restore(flags);
125} 126}
126 127
128int check_astate(void)
129{
130 return get_cur_astate(hard_smp_processor_id());
131}
132
127void restore_astate(int cpu) 133void restore_astate(int cpu)
128{ 134{
129 set_astate(cpu, current_astate); 135 set_astate(cpu, current_astate);
@@ -147,7 +153,10 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
147 if (!cpu) 153 if (!cpu)
148 goto out; 154 goto out;
149 155
150 dn = of_find_compatible_node(NULL, "sdc", "1682m-sdc"); 156 dn = of_find_compatible_node(NULL, NULL, "1682m-sdc");
157 if (!dn)
158 dn = of_find_compatible_node(NULL, NULL,
159 "pasemi,pwrficient-sdc");
151 if (!dn) 160 if (!dn)
152 goto out; 161 goto out;
153 err = of_address_to_resource(dn, 0, &res); 162 err = of_address_to_resource(dn, 0, &res);
@@ -160,7 +169,10 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
160 goto out; 169 goto out;
161 } 170 }
162 171
163 dn = of_find_compatible_node(NULL, "gizmo", "1682m-gizmo"); 172 dn = of_find_compatible_node(NULL, NULL, "1682m-gizmo");
173 if (!dn)
174 dn = of_find_compatible_node(NULL, NULL,
175 "pasemi,pwrficient-gizmo");
164 if (!dn) { 176 if (!dn) {
165 err = -ENODEV; 177 err = -ENODEV;
166 goto out_unmap_sdcasr; 178 goto out_unmap_sdcasr;
@@ -292,7 +304,8 @@ static struct cpufreq_driver pas_cpufreq_driver = {
292 304
293static int __init pas_cpufreq_init(void) 305static int __init pas_cpufreq_init(void)
294{ 306{
295 if (!machine_is_compatible("PA6T-1682M")) 307 if (!machine_is_compatible("PA6T-1682M") &&
308 !machine_is_compatible("pasemi,pwrficient"))
296 return -ENODEV; 309 return -ENODEV;
297 310
298 return cpufreq_register_driver(&pas_cpufreq_driver); 311 return cpufreq_register_driver(&pas_cpufreq_driver);
diff --git a/arch/powerpc/platforms/pasemi/gpio_mdio.c b/arch/powerpc/platforms/pasemi/gpio_mdio.c
index dae9f658122e..b46542990cf8 100644
--- a/arch/powerpc/platforms/pasemi/gpio_mdio.c
+++ b/arch/powerpc/platforms/pasemi/gpio_mdio.c
@@ -30,7 +30,7 @@
30#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/phy.h> 31#include <linux/phy.h>
32#include <linux/platform_device.h> 32#include <linux/platform_device.h>
33#include <asm/of_platform.h> 33#include <linux/of_platform.h>
34 34
35#define DELAY 1 35#define DELAY 1
36 36
@@ -218,45 +218,27 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
218 const struct of_device_id *match) 218 const struct of_device_id *match)
219{ 219{
220 struct device *dev = &ofdev->dev; 220 struct device *dev = &ofdev->dev;
221 struct device_node *np = ofdev->node; 221 struct device_node *phy_dn, *np = ofdev->node;
222 struct device_node *gpio_np;
223 struct mii_bus *new_bus; 222 struct mii_bus *new_bus;
224 struct resource res;
225 struct gpio_priv *priv; 223 struct gpio_priv *priv;
226 const unsigned int *prop; 224 const unsigned int *prop;
227 int err = 0; 225 int err;
228 int i; 226 int i;
229 227
230 gpio_np = of_find_compatible_node(NULL, "gpio", "1682m-gpio"); 228 err = -ENOMEM;
231
232 if (!gpio_np)
233 return -ENODEV;
234
235 err = of_address_to_resource(gpio_np, 0, &res);
236 of_node_put(gpio_np);
237
238 if (err)
239 return -EINVAL;
240
241 if (!gpio_regs)
242 gpio_regs = ioremap(res.start, 0x100);
243
244 if (!gpio_regs)
245 return -EPERM;
246
247 priv = kzalloc(sizeof(struct gpio_priv), GFP_KERNEL); 229 priv = kzalloc(sizeof(struct gpio_priv), GFP_KERNEL);
248 if (priv == NULL) 230 if (!priv)
249 return -ENOMEM; 231 goto out;
250 232
251 new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL); 233 new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
252 234
253 if (new_bus == NULL) 235 if (!new_bus)
254 return -ENOMEM; 236 goto out_free_priv;
255 237
256 new_bus->name = "pasemi gpio mdio bus", 238 new_bus->name = "pasemi gpio mdio bus";
257 new_bus->read = &gpio_mdio_read, 239 new_bus->read = &gpio_mdio_read;
258 new_bus->write = &gpio_mdio_write, 240 new_bus->write = &gpio_mdio_write;
259 new_bus->reset = &gpio_mdio_reset, 241 new_bus->reset = &gpio_mdio_reset;
260 242
261 prop = of_get_property(np, "reg", NULL); 243 prop = of_get_property(np, "reg", NULL);
262 new_bus->id = *prop; 244 new_bus->id = *prop;
@@ -265,9 +247,24 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
265 new_bus->phy_mask = 0; 247 new_bus->phy_mask = 0;
266 248
267 new_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL); 249 new_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
268 for(i = 0; i < PHY_MAX_ADDR; ++i)
269 new_bus->irq[i] = irq_create_mapping(NULL, 10);
270 250
251 if (!new_bus->irq)
252 goto out_free_bus;
253
254 for (i = 0; i < PHY_MAX_ADDR; i++)
255 new_bus->irq[i] = NO_IRQ;
256
257 for (phy_dn = of_get_next_child(np, NULL);
258 phy_dn != NULL;
259 phy_dn = of_get_next_child(np, phy_dn)) {
260 const unsigned int *ip, *regp;
261
262 ip = of_get_property(phy_dn, "interrupts", NULL);
263 regp = of_get_property(phy_dn, "reg", NULL);
264 if (!ip || !regp || *regp >= PHY_MAX_ADDR)
265 continue;
266 new_bus->irq[*regp] = irq_create_mapping(NULL, *ip);
267 }
271 268
272 prop = of_get_property(np, "mdc-pin", NULL); 269 prop = of_get_property(np, "mdc-pin", NULL);
273 priv->mdc_pin = *prop; 270 priv->mdc_pin = *prop;
@@ -280,17 +277,21 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
280 277
281 err = mdiobus_register(new_bus); 278 err = mdiobus_register(new_bus);
282 279
283 if (0 != err) { 280 if (err != 0) {
284 printk(KERN_ERR "%s: Cannot register as MDIO bus, err %d\n", 281 printk(KERN_ERR "%s: Cannot register as MDIO bus, err %d\n",
285 new_bus->name, err); 282 new_bus->name, err);
286 goto bus_register_fail; 283 goto out_free_irq;
287 } 284 }
288 285
289 return 0; 286 return 0;
290 287
291bus_register_fail: 288out_free_irq:
289 kfree(new_bus->irq);
290out_free_bus:
292 kfree(new_bus); 291 kfree(new_bus);
293 292out_free_priv:
293 kfree(priv);
294out:
294 return err; 295 return err;
295} 296}
296 297
@@ -317,6 +318,7 @@ static struct of_device_id gpio_mdio_match[] =
317 }, 318 },
318 {}, 319 {},
319}; 320};
321MODULE_DEVICE_TABLE(of, gpio_mdio_match);
320 322
321static struct of_platform_driver gpio_mdio_driver = 323static struct of_platform_driver gpio_mdio_driver =
322{ 324{
@@ -330,12 +332,32 @@ static struct of_platform_driver gpio_mdio_driver =
330 332
331int gpio_mdio_init(void) 333int gpio_mdio_init(void)
332{ 334{
335 struct device_node *np;
336
337 np = of_find_compatible_node(NULL, NULL, "1682m-gpio");
338 if (!np)
339 np = of_find_compatible_node(NULL, NULL,
340 "pasemi,pwrficient-gpio");
341 if (!np)
342 return -ENODEV;
343 gpio_regs = of_iomap(np, 0);
344 of_node_put(np);
345
346 if (!gpio_regs)
347 return -ENODEV;
348
333 return of_register_platform_driver(&gpio_mdio_driver); 349 return of_register_platform_driver(&gpio_mdio_driver);
334} 350}
351module_init(gpio_mdio_init);
335 352
336void gpio_mdio_exit(void) 353void gpio_mdio_exit(void)
337{ 354{
338 of_unregister_platform_driver(&gpio_mdio_driver); 355 of_unregister_platform_driver(&gpio_mdio_driver);
356 if (gpio_regs)
357 iounmap(gpio_regs);
339} 358}
340device_initcall(gpio_mdio_init); 359module_exit(gpio_mdio_exit);
341 360
361MODULE_LICENSE("GPL");
362MODULE_AUTHOR("Olof Johansson <olof@lixom.net>");
363MODULE_DESCRIPTION("Driver for MDIO over GPIO on PA Semi PWRficient-based boards");
diff --git a/arch/powerpc/platforms/pasemi/pasemi.h b/arch/powerpc/platforms/pasemi/pasemi.h
index 516acabb4e96..c96127b029b6 100644
--- a/arch/powerpc/platforms/pasemi/pasemi.h
+++ b/arch/powerpc/platforms/pasemi/pasemi.h
@@ -16,8 +16,14 @@ extern void idle_doze(void);
16 16
17/* Restore astate to last set */ 17/* Restore astate to last set */
18#ifdef CONFIG_PPC_PASEMI_CPUFREQ 18#ifdef CONFIG_PPC_PASEMI_CPUFREQ
19extern int check_astate(void);
19extern void restore_astate(int cpu); 20extern void restore_astate(int cpu);
20#else 21#else
22static inline int check_astate(void)
23{
24 /* Always return >0 so we never power save */
25 return 1;
26}
21static inline void restore_astate(int cpu) 27static inline void restore_astate(int cpu)
22{ 28{
23} 29}
diff --git a/arch/powerpc/platforms/pasemi/powersave.S b/arch/powerpc/platforms/pasemi/powersave.S
index 6d0fba6aab17..56f45adcd089 100644
--- a/arch/powerpc/platforms/pasemi/powersave.S
+++ b/arch/powerpc/platforms/pasemi/powersave.S
@@ -62,7 +62,16 @@ sleep_common:
62 mflr r0 62 mflr r0
63 std r0, 16(r1) 63 std r0, 16(r1)
64 stdu r1,-64(r1) 64 stdu r1,-64(r1)
65#ifdef CONFIG_PPC_PASEMI_CPUFREQ
66 std r3, 48(r1)
65 67
68 /* Only do power savings when in astate 0 */
69 bl .check_astate
70 cmpwi r3,0
71 bne 1f
72
73 ld r3, 48(r1)
74#endif
66 LOAD_REG_IMMEDIATE(r6,MSR_DR|MSR_IR|MSR_ME|MSR_EE) 75 LOAD_REG_IMMEDIATE(r6,MSR_DR|MSR_IR|MSR_ME|MSR_EE)
67 mfmsr r4 76 mfmsr r4
68 andc r5,r4,r6 77 andc r5,r4,r6
@@ -73,7 +82,7 @@ sleep_common:
73 82
74 mtmsrd r4,0 83 mtmsrd r4,0
75 84
76 addi r1,r1,64 851: addi r1,r1,64
77 ld r0,16(r1) 86 ld r0,16(r1)
78 mtlr r0 87 mtlr r0
79 blr 88 blr
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index 3d62060498b4..b5dfd4252110 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -27,6 +27,7 @@
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/console.h> 28#include <linux/console.h>
29#include <linux/pci.h> 29#include <linux/pci.h>
30#include <linux/of_platform.h>
30 31
31#include <asm/prom.h> 32#include <asm/prom.h>
32#include <asm/system.h> 33#include <asm/system.h>
@@ -35,7 +36,7 @@
35#include <asm/mpic.h> 36#include <asm/mpic.h>
36#include <asm/smp.h> 37#include <asm/smp.h>
37#include <asm/time.h> 38#include <asm/time.h>
38#include <asm/of_platform.h> 39#include <asm/mmu.h>
39 40
40#include <pcmcia/ss.h> 41#include <pcmcia/ss.h>
41#include <pcmcia/cistpl.h> 42#include <pcmcia/cistpl.h>
@@ -43,6 +44,10 @@
43 44
44#include "pasemi.h" 45#include "pasemi.h"
45 46
47#if !defined(CONFIG_SMP)
48static void smp_send_stop(void) {}
49#endif
50
46/* SDC reset register, must be pre-mapped at reset time */ 51/* SDC reset register, must be pre-mapped at reset time */
47static void __iomem *reset_reg; 52static void __iomem *reset_reg;
48 53
@@ -60,6 +65,9 @@ static int num_mce_regs;
60 65
61static void pas_restart(char *cmd) 66static void pas_restart(char *cmd)
62{ 67{
68 /* Need to put others cpu in hold loop so they're not sleeping */
69 smp_send_stop();
70 udelay(10000);
63 printk("Restarting...\n"); 71 printk("Restarting...\n");
64 while (1) 72 while (1)
65 out_le32(reset_reg, 0x6000000); 73 out_le32(reset_reg, 0x6000000);
@@ -215,7 +223,7 @@ static __init void pas_init_IRQ(void)
215 223
216 mpic = mpic_alloc(mpic_node, openpic_addr, 224 mpic = mpic_alloc(mpic_node, openpic_addr,
217 MPIC_PRIMARY|MPIC_LARGE_VECTORS, 225 MPIC_PRIMARY|MPIC_LARGE_VECTORS,
218 0, 0, " PAS-OPIC "); 226 0, 0, "PASEMI-OPIC");
219 BUG_ON(!mpic); 227 BUG_ON(!mpic);
220 228
221 mpic_assign_isu(mpic, 0, openpic_addr + 0x10000); 229 mpic_assign_isu(mpic, 0, openpic_addr + 0x10000);
@@ -295,7 +303,7 @@ static int pas_machine_check_handler(struct pt_regs *regs)
295 int i; 303 int i;
296 304
297 printk(KERN_ERR "slb contents:\n"); 305 printk(KERN_ERR "slb contents:\n");
298 for (i = 0; i < SLB_NUM_ENTRIES; i++) { 306 for (i = 0; i < mmu_slb_size; i++) {
299 asm volatile("slbmfee %0,%1" : "=r" (e) : "r" (i)); 307 asm volatile("slbmfee %0,%1" : "=r" (e) : "r" (i));
300 asm volatile("slbmfev %0,%1" : "=r" (v) : "r" (i)); 308 asm volatile("slbmfev %0,%1" : "=r" (v) : "r" (i));
301 printk(KERN_ERR "%02d %016lx %016lx\n", i, e, v); 309 printk(KERN_ERR "%02d %016lx %016lx\n", i, e, v);
@@ -362,8 +370,12 @@ static inline void pasemi_pcmcia_init(void)
362 370
363 371
364static struct of_device_id pasemi_bus_ids[] = { 372static struct of_device_id pasemi_bus_ids[] = {
373 /* Unfortunately needed for legacy firmwares */
365 { .type = "localbus", }, 374 { .type = "localbus", },
366 { .type = "sdc", }, 375 { .type = "sdc", },
376 /* These are the proper entries, which newer firmware uses */
377 { .compatible = "pasemi,localbus", },
378 { .compatible = "pasemi,sdc", },
367 {}, 379 {},
368}; 380};
369 381
@@ -389,7 +401,8 @@ static int __init pas_probe(void)
389{ 401{
390 unsigned long root = of_get_flat_dt_root(); 402 unsigned long root = of_get_flat_dt_root();
391 403
392 if (!of_flat_dt_is_compatible(root, "PA6T-1682M")) 404 if (!of_flat_dt_is_compatible(root, "PA6T-1682M") &&
405 !of_flat_dt_is_compatible(root, "pasemi,pwrficient"))
393 return 0; 406 return 0;
394 407
395 hpte_init_native(); 408 hpte_init_native();
@@ -400,7 +413,7 @@ static int __init pas_probe(void)
400} 413}
401 414
402define_machine(pasemi) { 415define_machine(pasemi) {
403 .name = "PA Semi PA6T-1682M", 416 .name = "PA Semi PWRficient",
404 .probe = pas_probe, 417 .probe = pas_probe,
405 .setup_arch = pas_setup_arch, 418 .setup_arch = pas_setup_arch,
406 .init_early = pas_init_early, 419 .init_early = pas_init_early,
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index f852ae3e0ee4..1c58db9d42cb 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -40,8 +40,6 @@
40static int has_uninorth; 40static int has_uninorth;
41#ifdef CONFIG_PPC64 41#ifdef CONFIG_PPC64
42static struct pci_controller *u3_agp; 42static struct pci_controller *u3_agp;
43static struct pci_controller *u4_pcie;
44static struct pci_controller *u3_ht;
45#else 43#else
46static int has_second_ohare; 44static int has_second_ohare;
47#endif /* CONFIG_PPC64 */ 45#endif /* CONFIG_PPC64 */
@@ -314,12 +312,15 @@ static int u3_ht_skip_device(struct pci_controller *hose,
314 312
315 /* We only allow config cycles to devices that are in OF device-tree 313 /* We only allow config cycles to devices that are in OF device-tree
316 * as we are apparently having some weird things going on with some 314 * as we are apparently having some weird things going on with some
317 * revs of K2 on recent G5s 315 * revs of K2 on recent G5s, except for the host bridge itself, which
316 * is missing from the tree but we know we can probe.
318 */ 317 */
319 if (bus->self) 318 if (bus->self)
320 busdn = pci_device_to_OF_node(bus->self); 319 busdn = pci_device_to_OF_node(bus->self);
320 else if (devfn == 0)
321 return 0;
321 else 322 else
322 busdn = hose->arch_data; 323 busdn = hose->dn;
323 for (dn = busdn->child; dn; dn = dn->sibling) 324 for (dn = busdn->child; dn; dn = dn->sibling)
324 if (PCI_DN(dn) && PCI_DN(dn)->devfn == devfn) 325 if (PCI_DN(dn) && PCI_DN(dn)->devfn == devfn)
325 break; 326 break;
@@ -344,14 +345,15 @@ static int u3_ht_skip_device(struct pci_controller *hose,
344 + (((unsigned int)bus) << 16) \ 345 + (((unsigned int)bus) << 16) \
345 + 0x01000000UL) 346 + 0x01000000UL)
346 347
347static volatile void __iomem *u3_ht_cfg_access(struct pci_controller* hose, 348static void __iomem *u3_ht_cfg_access(struct pci_controller *hose, u8 bus,
348 u8 bus, u8 devfn, u8 offset) 349 u8 devfn, u8 offset, int *swap)
349{ 350{
351 *swap = 1;
350 if (bus == hose->first_busno) { 352 if (bus == hose->first_busno) {
351 /* For now, we don't self probe U3 HT bridge */ 353 if (devfn != 0)
352 if (PCI_SLOT(devfn) == 0) 354 return hose->cfg_data + U3_HT_CFA0(devfn, offset);
353 return NULL; 355 *swap = 0;
354 return hose->cfg_data + U3_HT_CFA0(devfn, offset); 356 return ((void __iomem *)hose->cfg_addr) + (offset << 2);
355 } else 357 } else
356 return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset); 358 return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset);
357} 359}
@@ -360,14 +362,15 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
360 int offset, int len, u32 *val) 362 int offset, int len, u32 *val)
361{ 363{
362 struct pci_controller *hose; 364 struct pci_controller *hose;
363 volatile void __iomem *addr; 365 void __iomem *addr;
366 int swap;
364 367
365 hose = pci_bus_to_host(bus); 368 hose = pci_bus_to_host(bus);
366 if (hose == NULL) 369 if (hose == NULL)
367 return PCIBIOS_DEVICE_NOT_FOUND; 370 return PCIBIOS_DEVICE_NOT_FOUND;
368 if (offset >= 0x100) 371 if (offset >= 0x100)
369 return PCIBIOS_BAD_REGISTER_NUMBER; 372 return PCIBIOS_BAD_REGISTER_NUMBER;
370 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); 373 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset, &swap);
371 if (!addr) 374 if (!addr)
372 return PCIBIOS_DEVICE_NOT_FOUND; 375 return PCIBIOS_DEVICE_NOT_FOUND;
373 376
@@ -397,10 +400,10 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
397 *val = in_8(addr); 400 *val = in_8(addr);
398 break; 401 break;
399 case 2: 402 case 2:
400 *val = in_le16(addr); 403 *val = swap ? in_le16(addr) : in_be16(addr);
401 break; 404 break;
402 default: 405 default:
403 *val = in_le32(addr); 406 *val = swap ? in_le32(addr) : in_be32(addr);
404 break; 407 break;
405 } 408 }
406 return PCIBIOS_SUCCESSFUL; 409 return PCIBIOS_SUCCESSFUL;
@@ -410,14 +413,15 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
410 int offset, int len, u32 val) 413 int offset, int len, u32 val)
411{ 414{
412 struct pci_controller *hose; 415 struct pci_controller *hose;
413 volatile void __iomem *addr; 416 void __iomem *addr;
417 int swap;
414 418
415 hose = pci_bus_to_host(bus); 419 hose = pci_bus_to_host(bus);
416 if (hose == NULL) 420 if (hose == NULL)
417 return PCIBIOS_DEVICE_NOT_FOUND; 421 return PCIBIOS_DEVICE_NOT_FOUND;
418 if (offset >= 0x100) 422 if (offset >= 0x100)
419 return PCIBIOS_BAD_REGISTER_NUMBER; 423 return PCIBIOS_BAD_REGISTER_NUMBER;
420 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset); 424 addr = u3_ht_cfg_access(hose, bus->number, devfn, offset, &swap);
421 if (!addr) 425 if (!addr)
422 return PCIBIOS_DEVICE_NOT_FOUND; 426 return PCIBIOS_DEVICE_NOT_FOUND;
423 427
@@ -439,10 +443,10 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
439 out_8(addr, val); 443 out_8(addr, val);
440 break; 444 break;
441 case 2: 445 case 2:
442 out_le16(addr, val); 446 swap ? out_le16(addr, val) : out_be16(addr, val);
443 break; 447 break;
444 default: 448 default:
445 out_le32((u32 __iomem *)addr, val); 449 swap ? out_le32(addr, val) : out_be32(addr, val);
446 break; 450 break;
447 } 451 }
448 return PCIBIOS_SUCCESSFUL; 452 return PCIBIOS_SUCCESSFUL;
@@ -725,7 +729,7 @@ static void __init setup_bandit(struct pci_controller *hose,
725static int __init setup_uninorth(struct pci_controller *hose, 729static int __init setup_uninorth(struct pci_controller *hose,
726 struct resource *addr) 730 struct resource *addr)
727{ 731{
728 pci_assign_all_buses = 1; 732 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
729 has_uninorth = 1; 733 has_uninorth = 1;
730 hose->ops = &macrisc_pci_ops; 734 hose->ops = &macrisc_pci_ops;
731 hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000); 735 hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
@@ -773,31 +777,72 @@ static void __init setup_u4_pcie(struct pci_controller* hose)
773 */ 777 */
774 hose->first_busno = 0x00; 778 hose->first_busno = 0x00;
775 hose->last_busno = 0xff; 779 hose->last_busno = 0xff;
776 u4_pcie = hose;
777} 780}
778 781
779static void __init setup_u3_ht(struct pci_controller* hose) 782static void __init parse_region_decode(struct pci_controller *hose,
783 u32 decode)
780{ 784{
781 struct device_node *np = (struct device_node *)hose->arch_data; 785 unsigned long base, end, next = -1;
782 struct pci_controller *other = NULL; 786 int i, cur = -1;
783 int i, cur;
784 787
788 /* Iterate through all bits. We ignore the last bit as this region is
789 * reserved for the ROM among other niceties
790 */
791 for (i = 0; i < 31; i++) {
792 if ((decode & (0x80000000 >> i)) == 0)
793 continue;
794 if (i < 16) {
795 base = 0xf0000000 | (((u32)i) << 24);
796 end = base + 0x00ffffff;
797 } else {
798 base = ((u32)i-16) << 28;
799 end = base + 0x0fffffff;
800 }
801 if (base != next) {
802 if (++cur >= 3) {
803 printk(KERN_WARNING "PCI: Too many ranges !\n");
804 break;
805 }
806 hose->mem_resources[cur].flags = IORESOURCE_MEM;
807 hose->mem_resources[cur].name = hose->dn->full_name;
808 hose->mem_resources[cur].start = base;
809 hose->mem_resources[cur].end = end;
810 DBG(" %d: 0x%08lx-0x%08lx\n", cur, base, end);
811 } else {
812 DBG(" : -0x%08lx\n", end);
813 hose->mem_resources[cur].end = end;
814 }
815 next = end + 1;
816 }
817}
818
819static void __init setup_u3_ht(struct pci_controller* hose)
820{
821 struct device_node *np = hose->dn;
822 struct resource cfg_res, self_res;
823 u32 decode;
785 824
786 hose->ops = &u3_ht_pci_ops; 825 hose->ops = &u3_ht_pci_ops;
787 826
788 /* We hard code the address because of the different size of 827 /* Get base addresses from OF tree
789 * the reg address cell, we shall fix that by killing struct
790 * reg_property and using some accessor functions instead
791 */ 828 */
792 hose->cfg_data = ioremap(0xf2000000, 0x02000000); 829 if (of_address_to_resource(np, 0, &cfg_res) ||
830 of_address_to_resource(np, 1, &self_res)) {
831 printk(KERN_ERR "PCI: Failed to get U3/U4 HT resources !\n");
832 return;
833 }
834
835 /* Map external cfg space access into cfg_data and self registers
836 * into cfg_addr
837 */
838 hose->cfg_data = ioremap(cfg_res.start, 0x02000000);
839 hose->cfg_addr = ioremap(self_res.start,
840 self_res.end - self_res.start + 1);
793 841
794 /* 842 /*
795 * /ht node doesn't expose a "ranges" property, so we "remove" 843 * /ht node doesn't expose a "ranges" property, we read the register
796 * regions that have been allocated to AGP. So far, this version of 844 * that controls the decoding logic and use that for memory regions.
797 * the code doesn't assign any of the 0xfxxxxxxx "fine" memory regions 845 * The IO region is hard coded since it is fixed in HW as well.
798 * to /ht. We need to fix that sooner or later by either parsing all
799 * child "ranges" properties or figuring out the U3 address space
800 * decoding logic and then read its configuration register (if any).
801 */ 846 */
802 hose->io_base_phys = 0xf4000000; 847 hose->io_base_phys = 0xf4000000;
803 hose->pci_io_size = 0x00400000; 848 hose->pci_io_size = 0x00400000;
@@ -808,76 +853,33 @@ static void __init setup_u3_ht(struct pci_controller* hose)
808 hose->pci_mem_offset = 0; 853 hose->pci_mem_offset = 0;
809 hose->first_busno = 0; 854 hose->first_busno = 0;
810 hose->last_busno = 0xef; 855 hose->last_busno = 0xef;
811 hose->mem_resources[0].name = np->full_name;
812 hose->mem_resources[0].start = 0x80000000;
813 hose->mem_resources[0].end = 0xefffffff;
814 hose->mem_resources[0].flags = IORESOURCE_MEM;
815
816 u3_ht = hose;
817 856
818 if (u3_agp != NULL) 857 /* Note: fix offset when cfg_addr becomes a void * */
819 other = u3_agp; 858 decode = in_be32(hose->cfg_addr + 0x80);
820 else if (u4_pcie != NULL)
821 other = u4_pcie;
822
823 if (other == NULL) {
824 DBG("U3/4 has no AGP/PCIE, using full resource range\n");
825 return;
826 }
827 859
828 /* Fixup bus range vs. PCIE */ 860 DBG("PCI: Apple HT bridge decode register: 0x%08x\n", decode);
829 if (u4_pcie)
830 hose->last_busno = u4_pcie->first_busno - 1;
831 861
832 /* We "remove" the AGP resources from the resources allocated to HT, 862 /* NOTE: The decode register setup is a bit weird... region
833 * that is we create "holes". However, that code does assumptions 863 * 0xf8000000 for example is marked as enabled in there while it's
834 * that so far happen to be true (cross fingers...), typically that 864 & actually the memory controller registers.
835 * resources in the AGP node are properly ordered 865 * That means that we are incorrectly attributing it to HT.
866 *
867 * In a similar vein, region 0xf4000000 is actually the HT IO space but
868 * also marked as enabled in here and 0xf9000000 is used by some other
869 * internal bits of the northbridge.
870 *
871 * Unfortunately, we can't just mask out those bit as we would end
872 * up with more regions than we can cope (linux can only cope with
873 * 3 memory regions for a PHB at this stage).
874 *
875 * So for now, we just do a little hack. We happen to -know- that
876 * Apple firmware doesn't assign things below 0xfa000000 for that
877 * bridge anyway so we mask out all bits we don't want.
836 */ 878 */
837 cur = 0; 879 decode &= 0x003fffff;
838 for (i=0; i<3; i++) { 880
839 struct resource *res = &other->mem_resources[i]; 881 /* Now parse the resulting bits and build resources */
840 if (res->flags != IORESOURCE_MEM) 882 parse_region_decode(hose, decode);
841 continue;
842 /* We don't care about "fine" resources */
843 if (res->start >= 0xf0000000)
844 continue;
845 /* Check if it's just a matter of "shrinking" us in one
846 * direction
847 */
848 if (hose->mem_resources[cur].start == res->start) {
849 DBG("U3/HT: shrink start of %d, %08lx -> %08lx\n",
850 cur, hose->mem_resources[cur].start,
851 res->end + 1);
852 hose->mem_resources[cur].start = res->end + 1;
853 continue;
854 }
855 if (hose->mem_resources[cur].end == res->end) {
856 DBG("U3/HT: shrink end of %d, %08lx -> %08lx\n",
857 cur, hose->mem_resources[cur].end,
858 res->start - 1);
859 hose->mem_resources[cur].end = res->start - 1;
860 continue;
861 }
862 /* No, it's not the case, we need a hole */
863 if (cur == 2) {
864 /* not enough resources for a hole, we drop part
865 * of the range
866 */
867 printk(KERN_WARNING "Running out of resources"
868 " for /ht host !\n");
869 hose->mem_resources[cur].end = res->start - 1;
870 continue;
871 }
872 cur++;
873 DBG("U3/HT: hole, %d end at %08lx, %d start at %08lx\n",
874 cur-1, res->start - 1, cur, res->end + 1);
875 hose->mem_resources[cur].name = np->full_name;
876 hose->mem_resources[cur].flags = IORESOURCE_MEM;
877 hose->mem_resources[cur].start = res->end + 1;
878 hose->mem_resources[cur].end = hose->mem_resources[cur-1].end;
879 hose->mem_resources[cur-1].end = res->start - 1;
880 }
881} 883}
882#endif /* CONFIG_PPC64 */ 884#endif /* CONFIG_PPC64 */
883 885
@@ -994,6 +996,8 @@ void __init pmac_pci_init(void)
994 struct device_node *np, *root; 996 struct device_node *np, *root;
995 struct device_node *ht = NULL; 997 struct device_node *ht = NULL;
996 998
999 ppc_pci_flags = PPC_PCI_CAN_SKIP_ISA_ALIGN;
1000
997 root = of_find_node_by_path("/"); 1001 root = of_find_node_by_path("/");
998 if (root == NULL) { 1002 if (root == NULL) {
999 printk(KERN_CRIT "pmac_pci_init: can't find root " 1003 printk(KERN_CRIT "pmac_pci_init: can't find root "
@@ -1032,15 +1036,15 @@ void __init pmac_pci_init(void)
1032 * future though 1036 * future though
1033 */ 1037 */
1034 if (u3_agp) { 1038 if (u3_agp) {
1035 struct device_node *np = u3_agp->arch_data; 1039 struct device_node *np = u3_agp->dn;
1036 PCI_DN(np)->busno = 0xf0; 1040 PCI_DN(np)->busno = 0xf0;
1037 for (np = np->child; np; np = np->sibling) 1041 for (np = np->child; np; np = np->sibling)
1038 PCI_DN(np)->busno = 0xf0; 1042 PCI_DN(np)->busno = 0xf0;
1039 } 1043 }
1040 /* pmac_check_ht_link(); */ 1044 /* pmac_check_ht_link(); */
1041 1045
1042 /* Tell pci.c to not use the common resource allocation mechanism */ 1046 /* We can allocate missing resources if any */
1043 pci_probe_only = 1; 1047 pci_probe_only = 0;
1044 1048
1045#else /* CONFIG_PPC64 */ 1049#else /* CONFIG_PPC64 */
1046 init_p2pbridge(); 1050 init_p2pbridge();
@@ -1051,13 +1055,13 @@ void __init pmac_pci_init(void)
1051 * some offset between bus number and domains for now when we 1055 * some offset between bus number and domains for now when we
1052 * assign all busses should help for now 1056 * assign all busses should help for now
1053 */ 1057 */
1054 if (pci_assign_all_buses) 1058 if (ppc_pci_flags & PPC_PCI_REASSIGN_ALL_BUS)
1055 pcibios_assign_bus_offset = 0x10; 1059 pcibios_assign_bus_offset = 0x10;
1056#endif 1060#endif
1057} 1061}
1058 1062
1059int 1063#ifdef CONFIG_PPC32
1060pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) 1064int pmac_pci_enable_device_hook(struct pci_dev *dev)
1061{ 1065{
1062 struct device_node* node; 1066 struct device_node* node;
1063 int updatecfg = 0; 1067 int updatecfg = 0;
@@ -1099,24 +1103,21 @@ pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
1099 updatecfg = 1; 1103 updatecfg = 1;
1100 } 1104 }
1101 1105
1106 /*
1107 * Fixup various header fields on 32 bits. We don't do that on
1108 * 64 bits as some of these have strange values behind the HT
1109 * bridge and we must not, for example, enable MWI or set the
1110 * cache line size on them.
1111 */
1102 if (updatecfg) { 1112 if (updatecfg) {
1103 u16 cmd; 1113 u16 cmd;
1104 1114
1105 /*
1106 * Make sure PCI is correctly configured
1107 *
1108 * We use old pci_bios versions of the function since, by
1109 * default, gmac is not powered up, and so will be absent
1110 * from the kernel initial PCI lookup.
1111 *
1112 * Should be replaced by 2.4 new PCI mechanisms and really
1113 * register the device.
1114 */
1115 pci_read_config_word(dev, PCI_COMMAND, &cmd); 1115 pci_read_config_word(dev, PCI_COMMAND, &cmd);
1116 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER 1116 cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
1117 | PCI_COMMAND_INVALIDATE; 1117 | PCI_COMMAND_INVALIDATE;
1118 pci_write_config_word(dev, PCI_COMMAND, cmd); 1118 pci_write_config_word(dev, PCI_COMMAND, cmd);
1119 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16); 1119 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16);
1120
1120 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 1121 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
1121 L1_CACHE_BYTES >> 2); 1122 L1_CACHE_BYTES >> 2);
1122 } 1123 }
@@ -1124,6 +1125,18 @@ pmac_pci_enable_device_hook(struct pci_dev *dev, int initial)
1124 return 0; 1125 return 0;
1125} 1126}
1126 1127
1128void __devinit pmac_pci_fixup_ohci(struct pci_dev *dev)
1129{
1130 struct device_node *node = pci_device_to_OF_node(dev);
1131
1132 /* We don't want to assign resources to USB controllers
1133 * absent from the OF tree (iBook second controller)
1134 */
1135 if (dev->class == PCI_CLASS_SERIAL_USB_OHCI && !node)
1136 dev->resource[0].flags = 0;
1137}
1138DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_APPLE, PCI_ANY_ID, pmac_pci_fixup_ohci);
1139
1127/* We power down some devices after they have been probed. They'll 1140/* We power down some devices after they have been probed. They'll
1128 * be powered back on later on 1141 * be powered back on later on
1129 */ 1142 */
@@ -1171,7 +1184,6 @@ void __init pmac_pcibios_after_init(void)
1171 of_node_put(nd); 1184 of_node_put(nd);
1172} 1185}
1173 1186
1174#ifdef CONFIG_PPC32
1175void pmac_pci_fixup_cardbus(struct pci_dev* dev) 1187void pmac_pci_fixup_cardbus(struct pci_dev* dev)
1176{ 1188{
1177 if (!machine_is(powermac)) 1189 if (!machine_is(powermac))
@@ -1259,7 +1271,7 @@ void pmac_pci_fixup_pciata(struct pci_dev* dev)
1259 } 1271 }
1260} 1272}
1261DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata); 1273DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata);
1262#endif 1274#endif /* CONFIG_PPC32 */
1263 1275
1264/* 1276/*
1265 * Disable second function on K2-SATA, it's broken 1277 * Disable second function on K2-SATA, it's broken
diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h
index fcde070f7054..b3abaaf61eb4 100644
--- a/arch/powerpc/platforms/powermac/pmac.h
+++ b/arch/powerpc/platforms/powermac/pmac.h
@@ -26,7 +26,7 @@ extern void pmac_pci_init(void);
26extern void pmac_nvram_update(void); 26extern void pmac_nvram_update(void);
27extern unsigned char pmac_nvram_read_byte(int addr); 27extern unsigned char pmac_nvram_read_byte(int addr);
28extern void pmac_nvram_write_byte(int addr, unsigned char val); 28extern void pmac_nvram_write_byte(int addr, unsigned char val);
29extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial); 29extern int pmac_pci_enable_device_hook(struct pci_dev *dev);
30extern void pmac_pcibios_after_init(void); 30extern void pmac_pcibios_after_init(void);
31extern int of_show_percpuinfo(struct seq_file *m, int i); 31extern int of_show_percpuinfo(struct seq_file *m, int i);
32 32
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 02c533096627..adad4e976381 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -51,6 +51,8 @@
51#include <linux/root_dev.h> 51#include <linux/root_dev.h>
52#include <linux/bitops.h> 52#include <linux/bitops.h>
53#include <linux/suspend.h> 53#include <linux/suspend.h>
54#include <linux/of_device.h>
55#include <linux/of_platform.h>
54 56
55#include <asm/reg.h> 57#include <asm/reg.h>
56#include <asm/sections.h> 58#include <asm/sections.h>
@@ -68,8 +70,6 @@
68#include <asm/btext.h> 70#include <asm/btext.h>
69#include <asm/pmac_feature.h> 71#include <asm/pmac_feature.h>
70#include <asm/time.h> 72#include <asm/time.h>
71#include <asm/of_device.h>
72#include <asm/of_platform.h>
73#include <asm/mmu_context.h> 73#include <asm/mmu_context.h>
74#include <asm/iommu.h> 74#include <asm/iommu.h>
75#include <asm/smu.h> 75#include <asm/smu.h>
@@ -94,7 +94,6 @@ extern struct machdep_calls pmac_md;
94#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */ 94#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */
95 95
96#ifdef CONFIG_PPC64 96#ifdef CONFIG_PPC64
97#include <asm/udbg.h>
98int sccdbg; 97int sccdbg;
99#endif 98#endif
100 99
@@ -613,9 +612,11 @@ static int pmac_pci_probe_mode(struct pci_bus *bus)
613 612
614 /* We need to use normal PCI probing for the AGP bus, 613 /* We need to use normal PCI probing for the AGP bus,
615 * since the device for the AGP bridge isn't in the tree. 614 * since the device for the AGP bridge isn't in the tree.
615 * Same for the PCIe host on U4 and the HT host bridge.
616 */ 616 */
617 if (bus->self == NULL && (of_device_is_compatible(node, "u3-agp") || 617 if (bus->self == NULL && (of_device_is_compatible(node, "u3-agp") ||
618 of_device_is_compatible(node, "u4-pcie"))) 618 of_device_is_compatible(node, "u4-pcie") ||
619 of_device_is_compatible(node, "u3-ht")))
619 return PCI_PROBE_NORMAL; 620 return PCI_PROBE_NORMAL;
620 return PCI_PROBE_DEVTREE; 621 return PCI_PROBE_DEVTREE;
621} 622}
diff --git a/arch/powerpc/platforms/powermac/time.c b/arch/powerpc/platforms/powermac/time.c
index bf9da56942e8..bbbefd64ab59 100644
--- a/arch/powerpc/platforms/powermac/time.c
+++ b/arch/powerpc/platforms/powermac/time.c
@@ -84,12 +84,14 @@ long __init pmac_time_init(void)
84 return delta; 84 return delta;
85} 85}
86 86
87#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
87static void to_rtc_time(unsigned long now, struct rtc_time *tm) 88static void to_rtc_time(unsigned long now, struct rtc_time *tm)
88{ 89{
89 to_tm(now, tm); 90 to_tm(now, tm);
90 tm->tm_year -= 1900; 91 tm->tm_year -= 1900;
91 tm->tm_mon -= 1; 92 tm->tm_mon -= 1;
92} 93}
94#endif
93 95
94static unsigned long from_rtc_time(struct rtc_time *tm) 96static unsigned long from_rtc_time(struct rtc_time *tm)
95{ 97{
diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c
index d1630a074acf..5ad41189b494 100644
--- a/arch/powerpc/platforms/ps3/spu.c
+++ b/arch/powerpc/platforms/ps3/spu.c
@@ -28,6 +28,7 @@
28#include <asm/spu_priv1.h> 28#include <asm/spu_priv1.h>
29#include <asm/lv1call.h> 29#include <asm/lv1call.h>
30 30
31#include "../cell/spufs/spufs.h"
31#include "platform.h" 32#include "platform.h"
32 33
33/* spu_management_ops */ 34/* spu_management_ops */
@@ -419,10 +420,34 @@ static int ps3_init_affinity(void)
419 return 0; 420 return 0;
420} 421}
421 422
423/**
424 * ps3_enable_spu - Enable SPU run control.
425 *
426 * An outstanding enhancement for the PS3 would be to add a guard to check
427 * for incorrect access to the spu problem state when the spu context is
428 * disabled. This check could be implemented with a flag added to the spu
429 * context that would inhibit mapping problem state pages, and a routine
430 * to unmap spu problem state pages. When the spu is enabled with
431 * ps3_enable_spu() the flag would be set allowing pages to be mapped,
432 * and when the spu is disabled with ps3_disable_spu() the flag would be
433 * cleared and the mapped problem state pages would be unmapped.
434 */
435
436static void ps3_enable_spu(struct spu_context *ctx)
437{
438}
439
440static void ps3_disable_spu(struct spu_context *ctx)
441{
442 ctx->ops->runcntl_stop(ctx);
443}
444
422const struct spu_management_ops spu_management_ps3_ops = { 445const struct spu_management_ops spu_management_ps3_ops = {
423 .enumerate_spus = ps3_enumerate_spus, 446 .enumerate_spus = ps3_enumerate_spus,
424 .create_spu = ps3_create_spu, 447 .create_spu = ps3_create_spu,
425 .destroy_spu = ps3_destroy_spu, 448 .destroy_spu = ps3_destroy_spu,
449 .enable_spu = ps3_enable_spu,
450 .disable_spu = ps3_disable_spu,
426 .init_affinity = ps3_init_affinity, 451 .init_affinity = ps3_init_affinity,
427}; 452};
428 453
@@ -505,8 +530,6 @@ static void mfc_sr1_set(struct spu *spu, u64 sr1)
505 static const u64 allowed = ~(MFC_STATE1_LOCAL_STORAGE_DECODE_MASK 530 static const u64 allowed = ~(MFC_STATE1_LOCAL_STORAGE_DECODE_MASK
506 | MFC_STATE1_PROBLEM_STATE_MASK); 531 | MFC_STATE1_PROBLEM_STATE_MASK);
507 532
508 sr1 |= MFC_STATE1_MASTER_RUN_CONTROL_MASK;
509
510 BUG_ON((sr1 & allowed) != (spu_pdata(spu)->cache.sr1 & allowed)); 533 BUG_ON((sr1 & allowed) != (spu_pdata(spu)->cache.sr1 & allowed));
511 534
512 spu_pdata(spu)->cache.sr1 = sr1; 535 spu_pdata(spu)->cache.sr1 = sr1;
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index fb3d636e088b..aa14a8559edb 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -480,6 +480,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
480 no_dn++; 480 no_dn++;
481 return 0; 481 return 0;
482 } 482 }
483 dn = find_device_pe(dn);
483 pdn = PCI_DN(dn); 484 pdn = PCI_DN(dn);
484 485
485 /* Access to IO BARs might get this far and still not want checking. */ 486 /* Access to IO BARs might get this far and still not want checking. */
@@ -545,7 +546,7 @@ int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev)
545 546
546 /* Note that config-io to empty slots may fail; 547 /* Note that config-io to empty slots may fail;
547 * they are empty when they don't have children. */ 548 * they are empty when they don't have children. */
548 if ((rets[0] == 5) && (dn->child == NULL)) { 549 if ((rets[0] == 5) && (rets[2] == 0) && (dn->child == NULL)) {
549 false_positives++; 550 false_positives++;
550 pdn->eeh_false_positives ++; 551 pdn->eeh_false_positives ++;
551 rc = 0; 552 rc = 0;
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index 57e025e84ab4..68ea5eee39a8 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -310,8 +310,6 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
310 const char *location, *pci_str, *drv_str; 310 const char *location, *pci_str, *drv_str;
311 311
312 frozen_dn = find_device_pe(event->dn); 312 frozen_dn = find_device_pe(event->dn);
313 frozen_bus = pcibios_find_pci_bus(frozen_dn);
314
315 if (!frozen_dn) { 313 if (!frozen_dn) {
316 314
317 location = of_get_property(event->dn, "ibm,loc-code", NULL); 315 location = of_get_property(event->dn, "ibm,loc-code", NULL);
@@ -321,6 +319,8 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
321 location, pci_name(event->dev)); 319 location, pci_name(event->dev));
322 return NULL; 320 return NULL;
323 } 321 }
322
323 frozen_bus = pcibios_find_pci_bus(frozen_dn);
324 location = of_get_property(frozen_dn, "ibm,loc-code", NULL); 324 location = of_get_property(frozen_dn, "ibm,loc-code", NULL);
325 location = location ? location : "unknown"; 325 location = location ? location : "unknown";
326 326
@@ -354,13 +354,6 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
354 if (frozen_pdn->eeh_freeze_count > EEH_MAX_ALLOWED_FREEZES) 354 if (frozen_pdn->eeh_freeze_count > EEH_MAX_ALLOWED_FREEZES)
355 goto excess_failures; 355 goto excess_failures;
356 356
357 /* Get the current PCI slot state. */
358 rc = eeh_wait_for_slot_status (frozen_pdn, MAX_WAIT_FOR_RECOVERY*1000);
359 if (rc < 0) {
360 printk(KERN_WARNING "EEH: Permanent failure\n");
361 goto hard_fail;
362 }
363
364 printk(KERN_WARNING 357 printk(KERN_WARNING
365 "EEH: This PCI device has failed %d times in the last hour:\n", 358 "EEH: This PCI device has failed %d times in the last hour:\n",
366 frozen_pdn->eeh_freeze_count); 359 frozen_pdn->eeh_freeze_count);
@@ -376,6 +369,14 @@ struct pci_dn * handle_eeh_events (struct eeh_event *event)
376 */ 369 */
377 pci_walk_bus(frozen_bus, eeh_report_error, &result); 370 pci_walk_bus(frozen_bus, eeh_report_error, &result);
378 371
372 /* Get the current PCI slot state. This can take a long time,
373 * sometimes over 3 seconds for certain systems. */
374 rc = eeh_wait_for_slot_status (frozen_pdn, MAX_WAIT_FOR_RECOVERY*1000);
375 if (rc < 0) {
376 printk(KERN_WARNING "EEH: Permanent failure\n");
377 goto hard_fail;
378 }
379
379 /* Since rtas may enable MMIO when posting the error log, 380 /* Since rtas may enable MMIO when posting the error log,
380 * don't post the error log until after all dev drivers 381 * don't post the error log until after all dev drivers
381 * have been informed. 382 * have been informed.
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index be17d2395072..a65c76308201 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -251,7 +251,7 @@ static void iommu_table_setparms(struct pci_controller *phb,
251 const unsigned long *basep; 251 const unsigned long *basep;
252 const u32 *sizep; 252 const u32 *sizep;
253 253
254 node = (struct device_node *)phb->arch_data; 254 node = phb->dn;
255 255
256 basep = of_get_property(node, "linux,tce-base", NULL); 256 basep = of_get_property(node, "linux,tce-base", NULL);
257 sizep = of_get_property(node, "linux,tce-size", NULL); 257 sizep = of_get_property(node, "linux,tce-size", NULL);
@@ -296,11 +296,12 @@ static void iommu_table_setparms(struct pci_controller *phb,
296static void iommu_table_setparms_lpar(struct pci_controller *phb, 296static void iommu_table_setparms_lpar(struct pci_controller *phb,
297 struct device_node *dn, 297 struct device_node *dn,
298 struct iommu_table *tbl, 298 struct iommu_table *tbl,
299 const void *dma_window) 299 const void *dma_window,
300 int bussubno)
300{ 301{
301 unsigned long offset, size; 302 unsigned long offset, size;
302 303
303 tbl->it_busno = PCI_DN(dn)->bussubno; 304 tbl->it_busno = bussubno;
304 of_parse_dma_window(dn, dma_window, &tbl->it_index, &offset, &size); 305 of_parse_dma_window(dn, dma_window, &tbl->it_index, &offset, &size);
305 306
306 tbl->it_base = 0; 307 tbl->it_base = 0;
@@ -420,17 +421,10 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
420 pdn->full_name, ppci->iommu_table); 421 pdn->full_name, ppci->iommu_table);
421 422
422 if (!ppci->iommu_table) { 423 if (!ppci->iommu_table) {
423 /* Bussubno hasn't been copied yet.
424 * Do it now because iommu_table_setparms_lpar needs it.
425 */
426
427 ppci->bussubno = bus->number;
428
429 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, 424 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
430 ppci->phb->node); 425 ppci->phb->node);
431 426 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window,
432 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); 427 bus->number);
433
434 ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node); 428 ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node);
435 DBG(" created table: %p\n", ppci->iommu_table); 429 DBG(" created table: %p\n", ppci->iommu_table);
436 } 430 }
@@ -523,14 +517,10 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
523 517
524 pci = PCI_DN(pdn); 518 pci = PCI_DN(pdn);
525 if (!pci->iommu_table) { 519 if (!pci->iommu_table) {
526 /* iommu_table_setparms_lpar needs bussubno. */
527 pci->bussubno = pci->phb->bus->number;
528
529 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, 520 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
530 pci->phb->node); 521 pci->phb->node);
531 522 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window,
532 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); 523 pci->phb->bus->number);
533
534 pci->iommu_table = iommu_init_table(tbl, pci->phb->node); 524 pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
535 DBG(" created table: %p\n", pci->iommu_table); 525 DBG(" created table: %p\n", pci->iommu_table);
536 } else { 526 } else {
@@ -556,7 +546,7 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti
556 case PSERIES_RECONFIG_REMOVE: 546 case PSERIES_RECONFIG_REMOVE:
557 if (pci && pci->iommu_table && 547 if (pci && pci->iommu_table &&
558 of_get_property(np, "ibm,dma-window", NULL)) 548 of_get_property(np, "ibm,dma-window", NULL))
559 iommu_free_table(np); 549 iommu_free_table(pci->iommu_table, np->full_name);
560 break; 550 break;
561 default: 551 default:
562 err = NOTIFY_DONE; 552 err = NOTIFY_DONE;
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 47f0e0857f0e..5a5a19e40bb4 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -83,7 +83,7 @@ EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
83 83
84/* Must be called before pci_bus_add_devices */ 84/* Must be called before pci_bus_add_devices */
85void 85void
86pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus) 86pcibios_fixup_new_pci_devices(struct pci_bus *bus)
87{ 87{
88 struct pci_dev *dev; 88 struct pci_dev *dev;
89 89
@@ -98,8 +98,6 @@ pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
98 /* Fill device archdata and setup iommu table */ 98 /* Fill device archdata and setup iommu table */
99 pcibios_setup_new_device(dev); 99 pcibios_setup_new_device(dev);
100 100
101 if(fix_bus)
102 pcibios_fixup_device_resources(dev, bus);
103 pci_read_irq_line(dev); 101 pci_read_irq_line(dev);
104 for (i = 0; i < PCI_NUM_RESOURCES; i++) { 102 for (i = 0; i < PCI_NUM_RESOURCES; i++) {
105 struct resource *r = &dev->resource[i]; 103 struct resource *r = &dev->resource[i];
@@ -132,8 +130,8 @@ pcibios_pci_config_bridge(struct pci_dev *dev)
132 130
133 pci_scan_child_bus(child_bus); 131 pci_scan_child_bus(child_bus);
134 132
135 /* Fixup new pci devices without touching bus struct */ 133 /* Fixup new pci devices */
136 pcibios_fixup_new_pci_devices(child_bus, 0); 134 pcibios_fixup_new_pci_devices(child_bus);
137 135
138 /* Make the discovered devices available */ 136 /* Make the discovered devices available */
139 pci_bus_add_devices(child_bus); 137 pci_bus_add_devices(child_bus);
@@ -169,7 +167,7 @@ pcibios_add_pci_devices(struct pci_bus * bus)
169 /* use ofdt-based probe */ 167 /* use ofdt-based probe */
170 of_scan_bus(dn, bus); 168 of_scan_bus(dn, bus);
171 if (!list_empty(&bus->devices)) { 169 if (!list_empty(&bus->devices)) {
172 pcibios_fixup_new_pci_devices(bus, 0); 170 pcibios_fixup_new_pci_devices(bus);
173 pci_bus_add_devices(bus); 171 pci_bus_add_devices(bus);
174 eeh_add_device_tree_late(bus); 172 eeh_add_device_tree_late(bus);
175 } 173 }
@@ -178,7 +176,7 @@ pcibios_add_pci_devices(struct pci_bus * bus)
178 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn); 176 slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
179 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0)); 177 num = pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
180 if (num) { 178 if (num) {
181 pcibios_fixup_new_pci_devices(bus, 1); 179 pcibios_fixup_new_pci_devices(bus);
182 pci_bus_add_devices(bus); 180 pci_bus_add_devices(bus);
183 eeh_add_device_tree_late(bus); 181 eeh_add_device_tree_late(bus);
184 } 182 }
@@ -208,7 +206,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
208 eeh_add_device_tree_early(dn); 206 eeh_add_device_tree_early(dn);
209 207
210 scan_phb(phb); 208 scan_phb(phb);
211 pcibios_fixup_new_pci_devices(phb->bus, 0); 209 pcibios_fixup_new_pci_devices(phb->bus);
212 pci_bus_add_devices(phb->bus); 210 pci_bus_add_devices(phb->bus);
213 eeh_add_device_tree_late(phb->bus); 211 eeh_add_device_tree_late(phb->bus);
214 212
diff --git a/arch/powerpc/platforms/pseries/plpar_wrappers.h b/arch/powerpc/platforms/pseries/plpar_wrappers.h
index d003c80fa31d..d8680b589dc9 100644
--- a/arch/powerpc/platforms/pseries/plpar_wrappers.h
+++ b/arch/powerpc/platforms/pseries/plpar_wrappers.h
@@ -8,11 +8,6 @@ static inline long poll_pending(void)
8 return plpar_hcall_norets(H_POLL_PENDING); 8 return plpar_hcall_norets(H_POLL_PENDING);
9} 9}
10 10
11static inline long prod_processor(void)
12{
13 return plpar_hcall_norets(H_PROD);
14}
15
16static inline long cede_processor(void) 11static inline long cede_processor(void)
17{ 12{
18 return plpar_hcall_norets(H_CEDE); 13 return plpar_hcall_norets(H_CEDE);
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 116305b22a2b..ea4c65917a64 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -46,6 +46,7 @@
46#include <asm/pSeries_reconfig.h> 46#include <asm/pSeries_reconfig.h>
47#include <asm/mpic.h> 47#include <asm/mpic.h>
48#include <asm/vdso_datapage.h> 48#include <asm/vdso_datapage.h>
49#include <asm/cputhreads.h>
49 50
50#include "plpar_wrappers.h" 51#include "plpar_wrappers.h"
51#include "pseries.h" 52#include "pseries.h"
@@ -202,7 +203,7 @@ static int smp_pSeries_cpu_bootable(unsigned int nr)
202 */ 203 */
203 if (system_state < SYSTEM_RUNNING && 204 if (system_state < SYSTEM_RUNNING &&
204 cpu_has_feature(CPU_FTR_SMT) && 205 cpu_has_feature(CPU_FTR_SMT) &&
205 !smt_enabled_at_boot && nr % 2 != 0) 206 !smt_enabled_at_boot && cpu_thread_in_core(nr) != 0)
206 return 0; 207 return 0;
207 208
208 return 1; 209 return 1;
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 66e7d68ffeb1..8f8dd9c3ca6b 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -87,19 +87,25 @@ static int ibm_int_off;
87/* Direct HW low level accessors */ 87/* Direct HW low level accessors */
88 88
89 89
90static inline unsigned int direct_xirr_info_get(int n_cpu) 90static inline unsigned int direct_xirr_info_get(void)
91{ 91{
92 return in_be32(&xics_per_cpu[n_cpu]->xirr.word); 92 int cpu = smp_processor_id();
93
94 return in_be32(&xics_per_cpu[cpu]->xirr.word);
93} 95}
94 96
95static inline void direct_xirr_info_set(int n_cpu, int value) 97static inline void direct_xirr_info_set(int value)
96{ 98{
97 out_be32(&xics_per_cpu[n_cpu]->xirr.word, value); 99 int cpu = smp_processor_id();
100
101 out_be32(&xics_per_cpu[cpu]->xirr.word, value);
98} 102}
99 103
100static inline void direct_cppr_info(int n_cpu, u8 value) 104static inline void direct_cppr_info(u8 value)
101{ 105{
102 out_8(&xics_per_cpu[n_cpu]->xirr.bytes[0], value); 106 int cpu = smp_processor_id();
107
108 out_8(&xics_per_cpu[cpu]->xirr.bytes[0], value);
103} 109}
104 110
105static inline void direct_qirr_info(int n_cpu, u8 value) 111static inline void direct_qirr_info(int n_cpu, u8 value)
@@ -111,7 +117,7 @@ static inline void direct_qirr_info(int n_cpu, u8 value)
111/* LPAR low level accessors */ 117/* LPAR low level accessors */
112 118
113 119
114static inline unsigned int lpar_xirr_info_get(int n_cpu) 120static inline unsigned int lpar_xirr_info_get(void)
115{ 121{
116 unsigned long lpar_rc; 122 unsigned long lpar_rc;
117 unsigned long return_value; 123 unsigned long return_value;
@@ -122,7 +128,7 @@ static inline unsigned int lpar_xirr_info_get(int n_cpu)
122 return (unsigned int)return_value; 128 return (unsigned int)return_value;
123} 129}
124 130
125static inline void lpar_xirr_info_set(int n_cpu, int value) 131static inline void lpar_xirr_info_set(int value)
126{ 132{
127 unsigned long lpar_rc; 133 unsigned long lpar_rc;
128 unsigned long val64 = value & 0xffffffff; 134 unsigned long val64 = value & 0xffffffff;
@@ -133,7 +139,7 @@ static inline void lpar_xirr_info_set(int n_cpu, int value)
133 val64); 139 val64);
134} 140}
135 141
136static inline void lpar_cppr_info(int n_cpu, u8 value) 142static inline void lpar_cppr_info(u8 value)
137{ 143{
138 unsigned long lpar_rc; 144 unsigned long lpar_rc;
139 145
@@ -275,21 +281,19 @@ static unsigned int xics_startup(unsigned int virq)
275 281
276static void xics_eoi_direct(unsigned int virq) 282static void xics_eoi_direct(unsigned int virq)
277{ 283{
278 int cpu = smp_processor_id();
279 unsigned int irq = (unsigned int)irq_map[virq].hwirq; 284 unsigned int irq = (unsigned int)irq_map[virq].hwirq;
280 285
281 iosync(); 286 iosync();
282 direct_xirr_info_set(cpu, (0xff << 24) | irq); 287 direct_xirr_info_set((0xff << 24) | irq);
283} 288}
284 289
285 290
286static void xics_eoi_lpar(unsigned int virq) 291static void xics_eoi_lpar(unsigned int virq)
287{ 292{
288 int cpu = smp_processor_id();
289 unsigned int irq = (unsigned int)irq_map[virq].hwirq; 293 unsigned int irq = (unsigned int)irq_map[virq].hwirq;
290 294
291 iosync(); 295 iosync();
292 lpar_xirr_info_set(cpu, (0xff << 24) | irq); 296 lpar_xirr_info_set((0xff << 24) | irq);
293} 297}
294 298
295static inline unsigned int xics_remap_irq(unsigned int vec) 299static inline unsigned int xics_remap_irq(unsigned int vec)
@@ -312,16 +316,12 @@ static inline unsigned int xics_remap_irq(unsigned int vec)
312 316
313static unsigned int xics_get_irq_direct(void) 317static unsigned int xics_get_irq_direct(void)
314{ 318{
315 unsigned int cpu = smp_processor_id(); 319 return xics_remap_irq(direct_xirr_info_get());
316
317 return xics_remap_irq(direct_xirr_info_get(cpu));
318} 320}
319 321
320static unsigned int xics_get_irq_lpar(void) 322static unsigned int xics_get_irq_lpar(void)
321{ 323{
322 unsigned int cpu = smp_processor_id(); 324 return xics_remap_irq(lpar_xirr_info_get());
323
324 return xics_remap_irq(lpar_xirr_info_get(cpu));
325} 325}
326 326
327#ifdef CONFIG_SMP 327#ifdef CONFIG_SMP
@@ -387,12 +387,12 @@ void xics_cause_IPI(int cpu)
387 387
388#endif /* CONFIG_SMP */ 388#endif /* CONFIG_SMP */
389 389
390static void xics_set_cpu_priority(int cpu, unsigned char cppr) 390static void xics_set_cpu_priority(unsigned char cppr)
391{ 391{
392 if (firmware_has_feature(FW_FEATURE_LPAR)) 392 if (firmware_has_feature(FW_FEATURE_LPAR))
393 lpar_cppr_info(cpu, cppr); 393 lpar_cppr_info(cppr);
394 else 394 else
395 direct_cppr_info(cpu, cppr); 395 direct_cppr_info(cppr);
396 iosync(); 396 iosync();
397} 397}
398 398
@@ -440,9 +440,7 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
440 440
441void xics_setup_cpu(void) 441void xics_setup_cpu(void)
442{ 442{
443 int cpu = smp_processor_id(); 443 xics_set_cpu_priority(0xff);
444
445 xics_set_cpu_priority(cpu, 0xff);
446 444
447 /* 445 /*
448 * Put the calling processor into the GIQ. This is really only 446 * Put the calling processor into the GIQ. This is really only
@@ -783,7 +781,7 @@ void xics_teardown_cpu(int secondary)
783 unsigned int ipi; 781 unsigned int ipi;
784 struct irq_desc *desc; 782 struct irq_desc *desc;
785 783
786 xics_set_cpu_priority(cpu, 0); 784 xics_set_cpu_priority(0);
787 785
788 /* 786 /*
789 * Clear IPI 787 * Clear IPI
@@ -824,10 +822,11 @@ void xics_teardown_cpu(int secondary)
824void xics_migrate_irqs_away(void) 822void xics_migrate_irqs_away(void)
825{ 823{
826 int status; 824 int status;
827 unsigned int irq, virq, cpu = smp_processor_id(); 825 int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();
826 unsigned int irq, virq;
828 827
829 /* Reject any interrupt that was queued to us... */ 828 /* Reject any interrupt that was queued to us... */
830 xics_set_cpu_priority(cpu, 0); 829 xics_set_cpu_priority(0);
831 830
832 /* remove ourselves from the global interrupt queue */ 831 /* remove ourselves from the global interrupt queue */
833 status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, 832 status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE,
@@ -835,7 +834,7 @@ void xics_migrate_irqs_away(void)
835 WARN_ON(status < 0); 834 WARN_ON(status < 0);
836 835
837 /* Allow IPIs again... */ 836 /* Allow IPIs again... */
838 xics_set_cpu_priority(cpu, DEFAULT_PRIORITY); 837 xics_set_cpu_priority(DEFAULT_PRIORITY);
839 838
840 for_each_irq(virq) { 839 for_each_irq(virq) {
841 struct irq_desc *desc; 840 struct irq_desc *desc;
@@ -874,7 +873,7 @@ void xics_migrate_irqs_away(void)
874 * The irq has to be migrated only in the single cpu 873 * The irq has to be migrated only in the single cpu
875 * case. 874 * case.
876 */ 875 */
877 if (xics_status[0] != get_hard_smp_processor_id(cpu)) 876 if (xics_status[0] != hw_cpu)
878 goto unlock; 877 goto unlock;
879 878
880 printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n", 879 printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n",
diff --git a/arch/powerpc/platforms/pseries/xics.h b/arch/powerpc/platforms/pseries/xics.h
index db0ec3ba3ae2..9ffd809d29e2 100644
--- a/arch/powerpc/platforms/pseries/xics.h
+++ b/arch/powerpc/platforms/pseries/xics.h
@@ -21,9 +21,6 @@ extern void xics_cause_IPI(int cpu);
21extern void xics_request_IPIs(void); 21extern void xics_request_IPIs(void);
22extern void xics_migrate_irqs_away(void); 22extern void xics_migrate_irqs_away(void);
23 23
24/* first argument is ignored for now*/
25void pSeriesLP_cppr_info(int n_cpu, u8 value);
26
27struct xics_ipi_struct { 24struct xics_ipi_struct {
28 volatile unsigned long value; 25 volatile unsigned long value;
29} ____cacheline_aligned; 26} ____cacheline_aligned;
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 99a77d743d48..85cf8c60f0be 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -2,7 +2,7 @@ ifeq ($(CONFIG_PPC64),y)
2EXTRA_CFLAGS += -mno-minimal-toc 2EXTRA_CFLAGS += -mno-minimal-toc
3endif 3endif
4 4
5mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o 5mpic-msi-obj-$(CONFIG_PCI_MSI) += mpic_msi.o mpic_u3msi.o mpic_pasemi_msi.o
6obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y) 6obj-$(CONFIG_MPIC) += mpic.o $(mpic-msi-obj-y)
7 7
8obj-$(CONFIG_PPC_MPC106) += grackle.o 8obj-$(CONFIG_PPC_MPC106) += grackle.o
diff --git a/arch/powerpc/sysdev/axonram.c b/arch/powerpc/sysdev/axonram.c
index 5eaf3e3f4b8b..d359d6e92975 100644
--- a/arch/powerpc/sysdev/axonram.c
+++ b/arch/powerpc/sysdev/axonram.c
@@ -42,8 +42,9 @@
42#include <linux/slab.h> 42#include <linux/slab.h>
43#include <linux/string.h> 43#include <linux/string.h>
44#include <linux/types.h> 44#include <linux/types.h>
45#include <asm/of_device.h> 45#include <linux/of_device.h>
46#include <asm/of_platform.h> 46#include <linux/of_platform.h>
47
47#include <asm/page.h> 48#include <asm/page.h>
48#include <asm/prom.h> 49#include <asm/prom.h>
49 50
diff --git a/arch/powerpc/sysdev/bestcomm/bestcomm.h b/arch/powerpc/sysdev/bestcomm/bestcomm.h
index e802cb4eb69a..c960a8b49655 100644
--- a/arch/powerpc/sysdev/bestcomm/bestcomm.h
+++ b/arch/powerpc/sysdev/bestcomm/bestcomm.h
@@ -20,7 +20,7 @@ struct bcom_bd; /* defined later on ... */
20 20
21 21
22/* ======================================================================== */ 22/* ======================================================================== */
23/* Generic task managment */ 23/* Generic task management */
24/* ======================================================================== */ 24/* ======================================================================== */
25 25
26/** 26/**
diff --git a/arch/powerpc/sysdev/commproc.c b/arch/powerpc/sysdev/commproc.c
index f6a63780bbde..621bc6c1d408 100644
--- a/arch/powerpc/sysdev/commproc.c
+++ b/arch/powerpc/sysdev/commproc.c
@@ -240,6 +240,34 @@ void __init cpm_reset(void)
240#endif 240#endif
241} 241}
242 242
243static DEFINE_SPINLOCK(cmd_lock);
244
245#define MAX_CR_CMD_LOOPS 10000
246
247int cpm_command(u32 command, u8 opcode)
248{
249 int i, ret;
250 unsigned long flags;
251
252 if (command & 0xffffff0f)
253 return -EINVAL;
254
255 spin_lock_irqsave(&cmd_lock, flags);
256
257 ret = 0;
258 out_be16(&cpmp->cp_cpcr, command | CPM_CR_FLG | (opcode << 8));
259 for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
260 if ((in_be16(&cpmp->cp_cpcr) & CPM_CR_FLG) == 0)
261 goto out;
262
263 printk(KERN_ERR "%s(): Not able to issue CPM command\n", __FUNCTION__);
264 ret = -EIO;
265out:
266 spin_unlock_irqrestore(&cmd_lock, flags);
267 return ret;
268}
269EXPORT_SYMBOL(cpm_command);
270
243/* We used to do this earlier, but have to postpone as long as possible 271/* We used to do this earlier, but have to postpone as long as possible
244 * to ensure the kernel VM is now running. 272 * to ensure the kernel VM is now running.
245 */ 273 */
@@ -408,7 +436,7 @@ EXPORT_SYMBOL(cpm_dpram_phys);
408#endif /* !CONFIG_PPC_CPM_NEW_BINDING */ 436#endif /* !CONFIG_PPC_CPM_NEW_BINDING */
409 437
410struct cpm_ioport16 { 438struct cpm_ioport16 {
411 __be16 dir, par, sor, dat, intr; 439 __be16 dir, par, odr_sor, dat, intr;
412 __be16 res[3]; 440 __be16 res[3];
413}; 441};
414 442
@@ -438,6 +466,13 @@ static void cpm1_set_pin32(int port, int pin, int flags)
438 else 466 else
439 clrbits32(&iop->par, pin); 467 clrbits32(&iop->par, pin);
440 468
469 if (port == CPM_PORTB) {
470 if (flags & CPM_PIN_OPENDRAIN)
471 setbits16(&mpc8xx_immr->im_cpm.cp_pbodr, pin);
472 else
473 clrbits16(&mpc8xx_immr->im_cpm.cp_pbodr, pin);
474 }
475
441 if (port == CPM_PORTE) { 476 if (port == CPM_PORTE) {
442 if (flags & CPM_PIN_SECONDARY) 477 if (flags & CPM_PIN_SECONDARY)
443 setbits32(&iop->sor, pin); 478 setbits32(&iop->sor, pin);
@@ -471,11 +506,17 @@ static void cpm1_set_pin16(int port, int pin, int flags)
471 else 506 else
472 clrbits16(&iop->par, pin); 507 clrbits16(&iop->par, pin);
473 508
509 if (port == CPM_PORTA) {
510 if (flags & CPM_PIN_OPENDRAIN)
511 setbits16(&iop->odr_sor, pin);
512 else
513 clrbits16(&iop->odr_sor, pin);
514 }
474 if (port == CPM_PORTC) { 515 if (port == CPM_PORTC) {
475 if (flags & CPM_PIN_SECONDARY) 516 if (flags & CPM_PIN_SECONDARY)
476 setbits16(&iop->sor, pin); 517 setbits16(&iop->odr_sor, pin);
477 else 518 else
478 clrbits16(&iop->sor, pin); 519 clrbits16(&iop->odr_sor, pin);
479 } 520 }
480} 521}
481 522
diff --git a/arch/powerpc/sysdev/cpm2_common.c b/arch/powerpc/sysdev/cpm2_common.c
index c1d824032020..f7188e2ba669 100644
--- a/arch/powerpc/sysdev/cpm2_common.c
+++ b/arch/powerpc/sysdev/cpm2_common.c
@@ -82,6 +82,31 @@ void __init cpm2_reset(void)
82 cpmp = &cpm2_immr->im_cpm; 82 cpmp = &cpm2_immr->im_cpm;
83} 83}
84 84
85static DEFINE_SPINLOCK(cmd_lock);
86
87#define MAX_CR_CMD_LOOPS 10000
88
89int cpm_command(u32 command, u8 opcode)
90{
91 int i, ret;
92 unsigned long flags;
93
94 spin_lock_irqsave(&cmd_lock, flags);
95
96 ret = 0;
97 out_be32(&cpmp->cp_cpcr, command | opcode | CPM_CR_FLG);
98 for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
99 if ((in_be32(&cpmp->cp_cpcr) & CPM_CR_FLG) == 0)
100 goto out;
101
102 printk(KERN_ERR "%s(): Not able to issue CPM command\n", __FUNCTION__);
103 ret = -EIO;
104out:
105 spin_unlock_irqrestore(&cmd_lock, flags);
106 return ret;
107}
108EXPORT_SYMBOL(cpm_command);
109
85/* Set a baud rate generator. This needs lots of work. There are 110/* Set a baud rate generator. This needs lots of work. There are
86 * eight BRGs, which can be connected to the CPM channels or output 111 * eight BRGs, which can be connected to the CPM channels or output
87 * as clocks. The BRGs are in two different block of internal 112 * as clocks. The BRGs are in two different block of internal
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 33df4c347ca7..4b1d5120c122 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -202,7 +202,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
202 printk(KERN_WARNING "Can't get bus-range for %s, assume" 202 printk(KERN_WARNING "Can't get bus-range for %s, assume"
203 " bus 0\n", dev->full_name); 203 " bus 0\n", dev->full_name);
204 204
205 pci_assign_all_buses = 1; 205 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
206 hose = pcibios_alloc_controller(dev); 206 hose = pcibios_alloc_controller(dev);
207 if (!hose) 207 if (!hose)
208 return -ENOMEM; 208 return -ENOMEM;
@@ -222,7 +222,7 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
222 hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK; 222 hose->indirect_type |= PPC_INDIRECT_TYPE_NO_PCIE_LINK;
223 } 223 }
224 224
225 printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx." 225 printk(KERN_INFO "Found FSL PCI host bridge at 0x%016llx. "
226 "Firmware bus number: %d->%d\n", 226 "Firmware bus number: %d->%d\n",
227 (unsigned long long)rsrc.start, hose->first_busno, 227 (unsigned long long)rsrc.start, hose->first_busno,
228 hose->last_busno); 228 hose->last_busno);
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 3ace7474809e..4baad80ab731 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -132,15 +132,18 @@ EXPORT_SYMBOL(get_baudrate);
132 132
133static int __init gfar_mdio_of_init(void) 133static int __init gfar_mdio_of_init(void)
134{ 134{
135 struct device_node *np; 135 struct device_node *np = NULL;
136 unsigned int i;
137 struct platform_device *mdio_dev; 136 struct platform_device *mdio_dev;
138 struct resource res; 137 struct resource res;
139 int ret; 138 int ret;
140 139
141 for (np = NULL, i = 0; 140 np = of_find_compatible_node(np, NULL, "fsl,gianfar-mdio");
142 (np = of_find_compatible_node(np, "mdio", "gianfar")) != NULL; 141
143 i++) { 142 /* try the deprecated version */
143 if (!np)
144 np = of_find_compatible_node(np, "mdio", "gianfar");
145
146 if (np) {
144 int k; 147 int k;
145 struct device_node *child = NULL; 148 struct device_node *child = NULL;
146 struct gianfar_mdio_data mdio_data; 149 struct gianfar_mdio_data mdio_data;
@@ -179,11 +182,13 @@ static int __init gfar_mdio_of_init(void)
179 goto unreg; 182 goto unreg;
180 } 183 }
181 184
185 of_node_put(np);
182 return 0; 186 return 0;
183 187
184unreg: 188unreg:
185 platform_device_unregister(mdio_dev); 189 platform_device_unregister(mdio_dev);
186err: 190err:
191 of_node_put(np);
187 return ret; 192 return ret;
188} 193}
189 194
@@ -390,13 +395,11 @@ static void __init of_register_i2c_devices(struct device_node *adap_node,
390static int __init fsl_i2c_of_init(void) 395static int __init fsl_i2c_of_init(void)
391{ 396{
392 struct device_node *np; 397 struct device_node *np;
393 unsigned int i; 398 unsigned int i = 0;
394 struct platform_device *i2c_dev; 399 struct platform_device *i2c_dev;
395 int ret; 400 int ret;
396 401
397 for (np = NULL, i = 0; 402 for_each_compatible_node(np, NULL, "fsl-i2c") {
398 (np = of_find_compatible_node(np, "i2c", "fsl-i2c")) != NULL;
399 i++) {
400 struct resource r[2]; 403 struct resource r[2];
401 struct fsl_i2c_platform_data i2c_data; 404 struct fsl_i2c_platform_data i2c_data;
402 const unsigned char *flags = NULL; 405 const unsigned char *flags = NULL;
@@ -432,7 +435,7 @@ static int __init fsl_i2c_of_init(void)
432 if (ret) 435 if (ret)
433 goto unreg; 436 goto unreg;
434 437
435 of_register_i2c_devices(np, i); 438 of_register_i2c_devices(np, i++);
436 } 439 }
437 440
438 return 0; 441 return 0;
diff --git a/arch/powerpc/sysdev/grackle.c b/arch/powerpc/sysdev/grackle.c
index 11ad5622eb76..d502927644c6 100644
--- a/arch/powerpc/sysdev/grackle.c
+++ b/arch/powerpc/sysdev/grackle.c
@@ -57,7 +57,7 @@ void __init setup_grackle(struct pci_controller *hose)
57{ 57{
58 setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0); 58 setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0);
59 if (machine_is_compatible("PowerMac1,1")) 59 if (machine_is_compatible("PowerMac1,1"))
60 pci_assign_all_buses = 1; 60 ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS;
61 if (machine_is_compatible("AAPL,PowerBook1998")) 61 if (machine_is_compatible("AAPL,PowerBook1998"))
62 grackle_set_loop_snoop(hose, 1); 62 grackle_set_loop_snoop(hose, 1);
63#if 0 /* Disabled for now, HW problems ??? */ 63#if 0 /* Disabled for now, HW problems ??? */
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 05a56e55804c..7274750fd9c6 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -30,11 +30,32 @@
30#include "ipic.h" 30#include "ipic.h"
31 31
32static struct ipic * primary_ipic; 32static struct ipic * primary_ipic;
33static struct irq_chip ipic_level_irq_chip, ipic_edge_irq_chip;
33static DEFINE_SPINLOCK(ipic_lock); 34static DEFINE_SPINLOCK(ipic_lock);
34 35
35static struct ipic_info ipic_info[] = { 36static struct ipic_info ipic_info[] = {
37 [1] = {
38 .mask = IPIC_SIMSR_H,
39 .prio = IPIC_SIPRR_C,
40 .force = IPIC_SIFCR_H,
41 .bit = 16,
42 .prio_mask = 0,
43 },
44 [2] = {
45 .mask = IPIC_SIMSR_H,
46 .prio = IPIC_SIPRR_C,
47 .force = IPIC_SIFCR_H,
48 .bit = 17,
49 .prio_mask = 1,
50 },
51 [4] = {
52 .mask = IPIC_SIMSR_H,
53 .prio = IPIC_SIPRR_C,
54 .force = IPIC_SIFCR_H,
55 .bit = 19,
56 .prio_mask = 3,
57 },
36 [9] = { 58 [9] = {
37 .pend = IPIC_SIPNR_H,
38 .mask = IPIC_SIMSR_H, 59 .mask = IPIC_SIMSR_H,
39 .prio = IPIC_SIPRR_D, 60 .prio = IPIC_SIPRR_D,
40 .force = IPIC_SIFCR_H, 61 .force = IPIC_SIFCR_H,
@@ -42,7 +63,6 @@ static struct ipic_info ipic_info[] = {
42 .prio_mask = 0, 63 .prio_mask = 0,
43 }, 64 },
44 [10] = { 65 [10] = {
45 .pend = IPIC_SIPNR_H,
46 .mask = IPIC_SIMSR_H, 66 .mask = IPIC_SIMSR_H,
47 .prio = IPIC_SIPRR_D, 67 .prio = IPIC_SIPRR_D,
48 .force = IPIC_SIFCR_H, 68 .force = IPIC_SIFCR_H,
@@ -50,15 +70,27 @@ static struct ipic_info ipic_info[] = {
50 .prio_mask = 1, 70 .prio_mask = 1,
51 }, 71 },
52 [11] = { 72 [11] = {
53 .pend = IPIC_SIPNR_H,
54 .mask = IPIC_SIMSR_H, 73 .mask = IPIC_SIMSR_H,
55 .prio = IPIC_SIPRR_D, 74 .prio = IPIC_SIPRR_D,
56 .force = IPIC_SIFCR_H, 75 .force = IPIC_SIFCR_H,
57 .bit = 26, 76 .bit = 26,
58 .prio_mask = 2, 77 .prio_mask = 2,
59 }, 78 },
79 [12] = {
80 .mask = IPIC_SIMSR_H,
81 .prio = IPIC_SIPRR_D,
82 .force = IPIC_SIFCR_H,
83 .bit = 27,
84 .prio_mask = 3,
85 },
86 [13] = {
87 .mask = IPIC_SIMSR_H,
88 .prio = IPIC_SIPRR_D,
89 .force = IPIC_SIFCR_H,
90 .bit = 28,
91 .prio_mask = 4,
92 },
60 [14] = { 93 [14] = {
61 .pend = IPIC_SIPNR_H,
62 .mask = IPIC_SIMSR_H, 94 .mask = IPIC_SIMSR_H,
63 .prio = IPIC_SIPRR_D, 95 .prio = IPIC_SIPRR_D,
64 .force = IPIC_SIFCR_H, 96 .force = IPIC_SIFCR_H,
@@ -66,7 +98,6 @@ static struct ipic_info ipic_info[] = {
66 .prio_mask = 5, 98 .prio_mask = 5,
67 }, 99 },
68 [15] = { 100 [15] = {
69 .pend = IPIC_SIPNR_H,
70 .mask = IPIC_SIMSR_H, 101 .mask = IPIC_SIMSR_H,
71 .prio = IPIC_SIPRR_D, 102 .prio = IPIC_SIPRR_D,
72 .force = IPIC_SIFCR_H, 103 .force = IPIC_SIFCR_H,
@@ -74,7 +105,6 @@ static struct ipic_info ipic_info[] = {
74 .prio_mask = 6, 105 .prio_mask = 6,
75 }, 106 },
76 [16] = { 107 [16] = {
77 .pend = IPIC_SIPNR_H,
78 .mask = IPIC_SIMSR_H, 108 .mask = IPIC_SIMSR_H,
79 .prio = IPIC_SIPRR_D, 109 .prio = IPIC_SIPRR_D,
80 .force = IPIC_SIFCR_H, 110 .force = IPIC_SIFCR_H,
@@ -82,7 +112,7 @@ static struct ipic_info ipic_info[] = {
82 .prio_mask = 7, 112 .prio_mask = 7,
83 }, 113 },
84 [17] = { 114 [17] = {
85 .pend = IPIC_SEPNR, 115 .ack = IPIC_SEPNR,
86 .mask = IPIC_SEMSR, 116 .mask = IPIC_SEMSR,
87 .prio = IPIC_SMPRR_A, 117 .prio = IPIC_SMPRR_A,
88 .force = IPIC_SEFCR, 118 .force = IPIC_SEFCR,
@@ -90,7 +120,7 @@ static struct ipic_info ipic_info[] = {
90 .prio_mask = 5, 120 .prio_mask = 5,
91 }, 121 },
92 [18] = { 122 [18] = {
93 .pend = IPIC_SEPNR, 123 .ack = IPIC_SEPNR,
94 .mask = IPIC_SEMSR, 124 .mask = IPIC_SEMSR,
95 .prio = IPIC_SMPRR_A, 125 .prio = IPIC_SMPRR_A,
96 .force = IPIC_SEFCR, 126 .force = IPIC_SEFCR,
@@ -98,7 +128,7 @@ static struct ipic_info ipic_info[] = {
98 .prio_mask = 6, 128 .prio_mask = 6,
99 }, 129 },
100 [19] = { 130 [19] = {
101 .pend = IPIC_SEPNR, 131 .ack = IPIC_SEPNR,
102 .mask = IPIC_SEMSR, 132 .mask = IPIC_SEMSR,
103 .prio = IPIC_SMPRR_A, 133 .prio = IPIC_SMPRR_A,
104 .force = IPIC_SEFCR, 134 .force = IPIC_SEFCR,
@@ -106,7 +136,7 @@ static struct ipic_info ipic_info[] = {
106 .prio_mask = 7, 136 .prio_mask = 7,
107 }, 137 },
108 [20] = { 138 [20] = {
109 .pend = IPIC_SEPNR, 139 .ack = IPIC_SEPNR,
110 .mask = IPIC_SEMSR, 140 .mask = IPIC_SEMSR,
111 .prio = IPIC_SMPRR_B, 141 .prio = IPIC_SMPRR_B,
112 .force = IPIC_SEFCR, 142 .force = IPIC_SEFCR,
@@ -114,7 +144,7 @@ static struct ipic_info ipic_info[] = {
114 .prio_mask = 4, 144 .prio_mask = 4,
115 }, 145 },
116 [21] = { 146 [21] = {
117 .pend = IPIC_SEPNR, 147 .ack = IPIC_SEPNR,
118 .mask = IPIC_SEMSR, 148 .mask = IPIC_SEMSR,
119 .prio = IPIC_SMPRR_B, 149 .prio = IPIC_SMPRR_B,
120 .force = IPIC_SEFCR, 150 .force = IPIC_SEFCR,
@@ -122,7 +152,7 @@ static struct ipic_info ipic_info[] = {
122 .prio_mask = 5, 152 .prio_mask = 5,
123 }, 153 },
124 [22] = { 154 [22] = {
125 .pend = IPIC_SEPNR, 155 .ack = IPIC_SEPNR,
126 .mask = IPIC_SEMSR, 156 .mask = IPIC_SEMSR,
127 .prio = IPIC_SMPRR_B, 157 .prio = IPIC_SMPRR_B,
128 .force = IPIC_SEFCR, 158 .force = IPIC_SEFCR,
@@ -130,7 +160,7 @@ static struct ipic_info ipic_info[] = {
130 .prio_mask = 6, 160 .prio_mask = 6,
131 }, 161 },
132 [23] = { 162 [23] = {
133 .pend = IPIC_SEPNR, 163 .ack = IPIC_SEPNR,
134 .mask = IPIC_SEMSR, 164 .mask = IPIC_SEMSR,
135 .prio = IPIC_SMPRR_B, 165 .prio = IPIC_SMPRR_B,
136 .force = IPIC_SEFCR, 166 .force = IPIC_SEFCR,
@@ -138,7 +168,6 @@ static struct ipic_info ipic_info[] = {
138 .prio_mask = 7, 168 .prio_mask = 7,
139 }, 169 },
140 [32] = { 170 [32] = {
141 .pend = IPIC_SIPNR_H,
142 .mask = IPIC_SIMSR_H, 171 .mask = IPIC_SIMSR_H,
143 .prio = IPIC_SIPRR_A, 172 .prio = IPIC_SIPRR_A,
144 .force = IPIC_SIFCR_H, 173 .force = IPIC_SIFCR_H,
@@ -146,7 +175,6 @@ static struct ipic_info ipic_info[] = {
146 .prio_mask = 0, 175 .prio_mask = 0,
147 }, 176 },
148 [33] = { 177 [33] = {
149 .pend = IPIC_SIPNR_H,
150 .mask = IPIC_SIMSR_H, 178 .mask = IPIC_SIMSR_H,
151 .prio = IPIC_SIPRR_A, 179 .prio = IPIC_SIPRR_A,
152 .force = IPIC_SIFCR_H, 180 .force = IPIC_SIFCR_H,
@@ -154,7 +182,6 @@ static struct ipic_info ipic_info[] = {
154 .prio_mask = 1, 182 .prio_mask = 1,
155 }, 183 },
156 [34] = { 184 [34] = {
157 .pend = IPIC_SIPNR_H,
158 .mask = IPIC_SIMSR_H, 185 .mask = IPIC_SIMSR_H,
159 .prio = IPIC_SIPRR_A, 186 .prio = IPIC_SIPRR_A,
160 .force = IPIC_SIFCR_H, 187 .force = IPIC_SIFCR_H,
@@ -162,7 +189,6 @@ static struct ipic_info ipic_info[] = {
162 .prio_mask = 2, 189 .prio_mask = 2,
163 }, 190 },
164 [35] = { 191 [35] = {
165 .pend = IPIC_SIPNR_H,
166 .mask = IPIC_SIMSR_H, 192 .mask = IPIC_SIMSR_H,
167 .prio = IPIC_SIPRR_A, 193 .prio = IPIC_SIPRR_A,
168 .force = IPIC_SIFCR_H, 194 .force = IPIC_SIFCR_H,
@@ -170,7 +196,6 @@ static struct ipic_info ipic_info[] = {
170 .prio_mask = 3, 196 .prio_mask = 3,
171 }, 197 },
172 [36] = { 198 [36] = {
173 .pend = IPIC_SIPNR_H,
174 .mask = IPIC_SIMSR_H, 199 .mask = IPIC_SIMSR_H,
175 .prio = IPIC_SIPRR_A, 200 .prio = IPIC_SIPRR_A,
176 .force = IPIC_SIFCR_H, 201 .force = IPIC_SIFCR_H,
@@ -178,7 +203,6 @@ static struct ipic_info ipic_info[] = {
178 .prio_mask = 4, 203 .prio_mask = 4,
179 }, 204 },
180 [37] = { 205 [37] = {
181 .pend = IPIC_SIPNR_H,
182 .mask = IPIC_SIMSR_H, 206 .mask = IPIC_SIMSR_H,
183 .prio = IPIC_SIPRR_A, 207 .prio = IPIC_SIPRR_A,
184 .force = IPIC_SIFCR_H, 208 .force = IPIC_SIFCR_H,
@@ -186,7 +210,6 @@ static struct ipic_info ipic_info[] = {
186 .prio_mask = 5, 210 .prio_mask = 5,
187 }, 211 },
188 [38] = { 212 [38] = {
189 .pend = IPIC_SIPNR_H,
190 .mask = IPIC_SIMSR_H, 213 .mask = IPIC_SIMSR_H,
191 .prio = IPIC_SIPRR_A, 214 .prio = IPIC_SIPRR_A,
192 .force = IPIC_SIFCR_H, 215 .force = IPIC_SIFCR_H,
@@ -194,15 +217,48 @@ static struct ipic_info ipic_info[] = {
194 .prio_mask = 6, 217 .prio_mask = 6,
195 }, 218 },
196 [39] = { 219 [39] = {
197 .pend = IPIC_SIPNR_H,
198 .mask = IPIC_SIMSR_H, 220 .mask = IPIC_SIMSR_H,
199 .prio = IPIC_SIPRR_A, 221 .prio = IPIC_SIPRR_A,
200 .force = IPIC_SIFCR_H, 222 .force = IPIC_SIFCR_H,
201 .bit = 7, 223 .bit = 7,
202 .prio_mask = 7, 224 .prio_mask = 7,
203 }, 225 },
226 [42] = {
227 .mask = IPIC_SIMSR_H,
228 .prio = IPIC_SIPRR_B,
229 .force = IPIC_SIFCR_H,
230 .bit = 10,
231 .prio_mask = 2,
232 },
233 [44] = {
234 .mask = IPIC_SIMSR_H,
235 .prio = IPIC_SIPRR_B,
236 .force = IPIC_SIFCR_H,
237 .bit = 12,
238 .prio_mask = 4,
239 },
240 [45] = {
241 .mask = IPIC_SIMSR_H,
242 .prio = IPIC_SIPRR_B,
243 .force = IPIC_SIFCR_H,
244 .bit = 13,
245 .prio_mask = 5,
246 },
247 [46] = {
248 .mask = IPIC_SIMSR_H,
249 .prio = IPIC_SIPRR_B,
250 .force = IPIC_SIFCR_H,
251 .bit = 14,
252 .prio_mask = 6,
253 },
254 [47] = {
255 .mask = IPIC_SIMSR_H,
256 .prio = IPIC_SIPRR_B,
257 .force = IPIC_SIFCR_H,
258 .bit = 15,
259 .prio_mask = 7,
260 },
204 [48] = { 261 [48] = {
205 .pend = IPIC_SEPNR,
206 .mask = IPIC_SEMSR, 262 .mask = IPIC_SEMSR,
207 .prio = IPIC_SMPRR_A, 263 .prio = IPIC_SMPRR_A,
208 .force = IPIC_SEFCR, 264 .force = IPIC_SEFCR,
@@ -210,7 +266,6 @@ static struct ipic_info ipic_info[] = {
210 .prio_mask = 4, 266 .prio_mask = 4,
211 }, 267 },
212 [64] = { 268 [64] = {
213 .pend = IPIC_SIPNR_L,
214 .mask = IPIC_SIMSR_L, 269 .mask = IPIC_SIMSR_L,
215 .prio = IPIC_SMPRR_A, 270 .prio = IPIC_SMPRR_A,
216 .force = IPIC_SIFCR_L, 271 .force = IPIC_SIFCR_L,
@@ -218,7 +273,6 @@ static struct ipic_info ipic_info[] = {
218 .prio_mask = 0, 273 .prio_mask = 0,
219 }, 274 },
220 [65] = { 275 [65] = {
221 .pend = IPIC_SIPNR_L,
222 .mask = IPIC_SIMSR_L, 276 .mask = IPIC_SIMSR_L,
223 .prio = IPIC_SMPRR_A, 277 .prio = IPIC_SMPRR_A,
224 .force = IPIC_SIFCR_L, 278 .force = IPIC_SIFCR_L,
@@ -226,7 +280,6 @@ static struct ipic_info ipic_info[] = {
226 .prio_mask = 1, 280 .prio_mask = 1,
227 }, 281 },
228 [66] = { 282 [66] = {
229 .pend = IPIC_SIPNR_L,
230 .mask = IPIC_SIMSR_L, 283 .mask = IPIC_SIMSR_L,
231 .prio = IPIC_SMPRR_A, 284 .prio = IPIC_SMPRR_A,
232 .force = IPIC_SIFCR_L, 285 .force = IPIC_SIFCR_L,
@@ -234,7 +287,6 @@ static struct ipic_info ipic_info[] = {
234 .prio_mask = 2, 287 .prio_mask = 2,
235 }, 288 },
236 [67] = { 289 [67] = {
237 .pend = IPIC_SIPNR_L,
238 .mask = IPIC_SIMSR_L, 290 .mask = IPIC_SIMSR_L,
239 .prio = IPIC_SMPRR_A, 291 .prio = IPIC_SMPRR_A,
240 .force = IPIC_SIFCR_L, 292 .force = IPIC_SIFCR_L,
@@ -242,7 +294,6 @@ static struct ipic_info ipic_info[] = {
242 .prio_mask = 3, 294 .prio_mask = 3,
243 }, 295 },
244 [68] = { 296 [68] = {
245 .pend = IPIC_SIPNR_L,
246 .mask = IPIC_SIMSR_L, 297 .mask = IPIC_SIMSR_L,
247 .prio = IPIC_SMPRR_B, 298 .prio = IPIC_SMPRR_B,
248 .force = IPIC_SIFCR_L, 299 .force = IPIC_SIFCR_L,
@@ -250,7 +301,6 @@ static struct ipic_info ipic_info[] = {
250 .prio_mask = 0, 301 .prio_mask = 0,
251 }, 302 },
252 [69] = { 303 [69] = {
253 .pend = IPIC_SIPNR_L,
254 .mask = IPIC_SIMSR_L, 304 .mask = IPIC_SIMSR_L,
255 .prio = IPIC_SMPRR_B, 305 .prio = IPIC_SMPRR_B,
256 .force = IPIC_SIFCR_L, 306 .force = IPIC_SIFCR_L,
@@ -258,7 +308,6 @@ static struct ipic_info ipic_info[] = {
258 .prio_mask = 1, 308 .prio_mask = 1,
259 }, 309 },
260 [70] = { 310 [70] = {
261 .pend = IPIC_SIPNR_L,
262 .mask = IPIC_SIMSR_L, 311 .mask = IPIC_SIMSR_L,
263 .prio = IPIC_SMPRR_B, 312 .prio = IPIC_SMPRR_B,
264 .force = IPIC_SIFCR_L, 313 .force = IPIC_SIFCR_L,
@@ -266,7 +315,6 @@ static struct ipic_info ipic_info[] = {
266 .prio_mask = 2, 315 .prio_mask = 2,
267 }, 316 },
268 [71] = { 317 [71] = {
269 .pend = IPIC_SIPNR_L,
270 .mask = IPIC_SIMSR_L, 318 .mask = IPIC_SIMSR_L,
271 .prio = IPIC_SMPRR_B, 319 .prio = IPIC_SMPRR_B,
272 .force = IPIC_SIFCR_L, 320 .force = IPIC_SIFCR_L,
@@ -274,91 +322,114 @@ static struct ipic_info ipic_info[] = {
274 .prio_mask = 3, 322 .prio_mask = 3,
275 }, 323 },
276 [72] = { 324 [72] = {
277 .pend = IPIC_SIPNR_L,
278 .mask = IPIC_SIMSR_L, 325 .mask = IPIC_SIMSR_L,
279 .prio = 0, 326 .prio = 0,
280 .force = IPIC_SIFCR_L, 327 .force = IPIC_SIFCR_L,
281 .bit = 8, 328 .bit = 8,
282 }, 329 },
283 [73] = { 330 [73] = {
284 .pend = IPIC_SIPNR_L,
285 .mask = IPIC_SIMSR_L, 331 .mask = IPIC_SIMSR_L,
286 .prio = 0, 332 .prio = 0,
287 .force = IPIC_SIFCR_L, 333 .force = IPIC_SIFCR_L,
288 .bit = 9, 334 .bit = 9,
289 }, 335 },
290 [74] = { 336 [74] = {
291 .pend = IPIC_SIPNR_L,
292 .mask = IPIC_SIMSR_L, 337 .mask = IPIC_SIMSR_L,
293 .prio = 0, 338 .prio = 0,
294 .force = IPIC_SIFCR_L, 339 .force = IPIC_SIFCR_L,
295 .bit = 10, 340 .bit = 10,
296 }, 341 },
297 [75] = { 342 [75] = {
298 .pend = IPIC_SIPNR_L,
299 .mask = IPIC_SIMSR_L, 343 .mask = IPIC_SIMSR_L,
300 .prio = 0, 344 .prio = 0,
301 .force = IPIC_SIFCR_L, 345 .force = IPIC_SIFCR_L,
302 .bit = 11, 346 .bit = 11,
303 }, 347 },
304 [76] = { 348 [76] = {
305 .pend = IPIC_SIPNR_L,
306 .mask = IPIC_SIMSR_L, 349 .mask = IPIC_SIMSR_L,
307 .prio = 0, 350 .prio = 0,
308 .force = IPIC_SIFCR_L, 351 .force = IPIC_SIFCR_L,
309 .bit = 12, 352 .bit = 12,
310 }, 353 },
311 [77] = { 354 [77] = {
312 .pend = IPIC_SIPNR_L,
313 .mask = IPIC_SIMSR_L, 355 .mask = IPIC_SIMSR_L,
314 .prio = 0, 356 .prio = 0,
315 .force = IPIC_SIFCR_L, 357 .force = IPIC_SIFCR_L,
316 .bit = 13, 358 .bit = 13,
317 }, 359 },
318 [78] = { 360 [78] = {
319 .pend = IPIC_SIPNR_L,
320 .mask = IPIC_SIMSR_L, 361 .mask = IPIC_SIMSR_L,
321 .prio = 0, 362 .prio = 0,
322 .force = IPIC_SIFCR_L, 363 .force = IPIC_SIFCR_L,
323 .bit = 14, 364 .bit = 14,
324 }, 365 },
325 [79] = { 366 [79] = {
326 .pend = IPIC_SIPNR_L,
327 .mask = IPIC_SIMSR_L, 367 .mask = IPIC_SIMSR_L,
328 .prio = 0, 368 .prio = 0,
329 .force = IPIC_SIFCR_L, 369 .force = IPIC_SIFCR_L,
330 .bit = 15, 370 .bit = 15,
331 }, 371 },
332 [80] = { 372 [80] = {
333 .pend = IPIC_SIPNR_L,
334 .mask = IPIC_SIMSR_L, 373 .mask = IPIC_SIMSR_L,
335 .prio = 0, 374 .prio = 0,
336 .force = IPIC_SIFCR_L, 375 .force = IPIC_SIFCR_L,
337 .bit = 16, 376 .bit = 16,
338 }, 377 },
378 [81] = {
379 .mask = IPIC_SIMSR_L,
380 .prio = 0,
381 .force = IPIC_SIFCR_L,
382 .bit = 17,
383 },
384 [82] = {
385 .mask = IPIC_SIMSR_L,
386 .prio = 0,
387 .force = IPIC_SIFCR_L,
388 .bit = 18,
389 },
339 [84] = { 390 [84] = {
340 .pend = IPIC_SIPNR_L,
341 .mask = IPIC_SIMSR_L, 391 .mask = IPIC_SIMSR_L,
342 .prio = 0, 392 .prio = 0,
343 .force = IPIC_SIFCR_L, 393 .force = IPIC_SIFCR_L,
344 .bit = 20, 394 .bit = 20,
345 }, 395 },
346 [85] = { 396 [85] = {
347 .pend = IPIC_SIPNR_L,
348 .mask = IPIC_SIMSR_L, 397 .mask = IPIC_SIMSR_L,
349 .prio = 0, 398 .prio = 0,
350 .force = IPIC_SIFCR_L, 399 .force = IPIC_SIFCR_L,
351 .bit = 21, 400 .bit = 21,
352 }, 401 },
402 [86] = {
403 .mask = IPIC_SIMSR_L,
404 .prio = 0,
405 .force = IPIC_SIFCR_L,
406 .bit = 22,
407 },
408 [87] = {
409 .mask = IPIC_SIMSR_L,
410 .prio = 0,
411 .force = IPIC_SIFCR_L,
412 .bit = 23,
413 },
414 [88] = {
415 .mask = IPIC_SIMSR_L,
416 .prio = 0,
417 .force = IPIC_SIFCR_L,
418 .bit = 24,
419 },
420 [89] = {
421 .mask = IPIC_SIMSR_L,
422 .prio = 0,
423 .force = IPIC_SIFCR_L,
424 .bit = 25,
425 },
353 [90] = { 426 [90] = {
354 .pend = IPIC_SIPNR_L,
355 .mask = IPIC_SIMSR_L, 427 .mask = IPIC_SIMSR_L,
356 .prio = 0, 428 .prio = 0,
357 .force = IPIC_SIFCR_L, 429 .force = IPIC_SIFCR_L,
358 .bit = 26, 430 .bit = 26,
359 }, 431 },
360 [91] = { 432 [91] = {
361 .pend = IPIC_SIPNR_L,
362 .mask = IPIC_SIMSR_L, 433 .mask = IPIC_SIMSR_L,
363 .prio = 0, 434 .prio = 0,
364 .force = IPIC_SIFCR_L, 435 .force = IPIC_SIFCR_L,
@@ -412,6 +483,10 @@ static void ipic_mask_irq(unsigned int virq)
412 temp &= ~(1 << (31 - ipic_info[src].bit)); 483 temp &= ~(1 << (31 - ipic_info[src].bit));
413 ipic_write(ipic->regs, ipic_info[src].mask, temp); 484 ipic_write(ipic->regs, ipic_info[src].mask, temp);
414 485
486 /* mb() can't guarantee that masking is finished. But it does finish
487 * for nearly all cases. */
488 mb();
489
415 spin_unlock_irqrestore(&ipic_lock, flags); 490 spin_unlock_irqrestore(&ipic_lock, flags);
416} 491}
417 492
@@ -424,9 +499,13 @@ static void ipic_ack_irq(unsigned int virq)
424 499
425 spin_lock_irqsave(&ipic_lock, flags); 500 spin_lock_irqsave(&ipic_lock, flags);
426 501
427 temp = ipic_read(ipic->regs, ipic_info[src].pend); 502 temp = ipic_read(ipic->regs, ipic_info[src].ack);
428 temp |= (1 << (31 - ipic_info[src].bit)); 503 temp |= (1 << (31 - ipic_info[src].bit));
429 ipic_write(ipic->regs, ipic_info[src].pend, temp); 504 ipic_write(ipic->regs, ipic_info[src].ack, temp);
505
506 /* mb() can't guarantee that ack is finished. But it does finish
507 * for nearly all cases. */
508 mb();
430 509
431 spin_unlock_irqrestore(&ipic_lock, flags); 510 spin_unlock_irqrestore(&ipic_lock, flags);
432} 511}
@@ -444,9 +523,13 @@ static void ipic_mask_irq_and_ack(unsigned int virq)
444 temp &= ~(1 << (31 - ipic_info[src].bit)); 523 temp &= ~(1 << (31 - ipic_info[src].bit));
445 ipic_write(ipic->regs, ipic_info[src].mask, temp); 524 ipic_write(ipic->regs, ipic_info[src].mask, temp);
446 525
447 temp = ipic_read(ipic->regs, ipic_info[src].pend); 526 temp = ipic_read(ipic->regs, ipic_info[src].ack);
448 temp |= (1 << (31 - ipic_info[src].bit)); 527 temp |= (1 << (31 - ipic_info[src].bit));
449 ipic_write(ipic->regs, ipic_info[src].pend, temp); 528 ipic_write(ipic->regs, ipic_info[src].ack, temp);
529
530 /* mb() can't guarantee that ack is finished. But it does finish
531 * for nearly all cases. */
532 mb();
450 533
451 spin_unlock_irqrestore(&ipic_lock, flags); 534 spin_unlock_irqrestore(&ipic_lock, flags);
452} 535}
@@ -468,14 +551,22 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
468 flow_type); 551 flow_type);
469 return -EINVAL; 552 return -EINVAL;
470 } 553 }
554 /* ipic supports only edge mode on external interrupts */
555 if ((flow_type & IRQ_TYPE_EDGE_FALLING) && !ipic_info[src].ack) {
556 printk(KERN_ERR "ipic: edge sense not supported on internal "
557 "interrupts\n");
558 return -EINVAL;
559 }
471 560
472 desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL); 561 desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
473 desc->status |= flow_type & IRQ_TYPE_SENSE_MASK; 562 desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
474 if (flow_type & IRQ_TYPE_LEVEL_LOW) { 563 if (flow_type & IRQ_TYPE_LEVEL_LOW) {
475 desc->status |= IRQ_LEVEL; 564 desc->status |= IRQ_LEVEL;
476 desc->handle_irq = handle_level_irq; 565 desc->handle_irq = handle_level_irq;
566 desc->chip = &ipic_level_irq_chip;
477 } else { 567 } else {
478 desc->handle_irq = handle_edge_irq; 568 desc->handle_irq = handle_edge_irq;
569 desc->chip = &ipic_edge_irq_chip;
479 } 570 }
480 571
481 /* only EXT IRQ senses are programmable on ipic 572 /* only EXT IRQ senses are programmable on ipic
@@ -500,7 +591,16 @@ static int ipic_set_irq_type(unsigned int virq, unsigned int flow_type)
500 return 0; 591 return 0;
501} 592}
502 593
503static struct irq_chip ipic_irq_chip = { 594/* level interrupts and edge interrupts have different ack operations */
595static struct irq_chip ipic_level_irq_chip = {
596 .typename = " IPIC ",
597 .unmask = ipic_unmask_irq,
598 .mask = ipic_mask_irq,
599 .mask_ack = ipic_mask_irq,
600 .set_type = ipic_set_irq_type,
601};
602
603static struct irq_chip ipic_edge_irq_chip = {
504 .typename = " IPIC ", 604 .typename = " IPIC ",
505 .unmask = ipic_unmask_irq, 605 .unmask = ipic_unmask_irq,
506 .mask = ipic_mask_irq, 606 .mask = ipic_mask_irq,
@@ -519,13 +619,9 @@ static int ipic_host_map(struct irq_host *h, unsigned int virq,
519 irq_hw_number_t hw) 619 irq_hw_number_t hw)
520{ 620{
521 struct ipic *ipic = h->host_data; 621 struct ipic *ipic = h->host_data;
522 struct irq_chip *chip;
523
524 /* Default chip */
525 chip = &ipic->hc_irq;
526 622
527 set_irq_chip_data(virq, ipic); 623 set_irq_chip_data(virq, ipic);
528 set_irq_chip_and_handler(virq, chip, handle_level_irq); 624 set_irq_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq);
529 625
530 /* Set default irq type */ 626 /* Set default irq type */
531 set_irq_type(virq, IRQ_TYPE_NONE); 627 set_irq_type(virq, IRQ_TYPE_NONE);
@@ -584,7 +680,6 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
584 ipic->regs = ioremap(res.start, res.end - res.start + 1); 680 ipic->regs = ioremap(res.start, res.end - res.start + 1);
585 681
586 ipic->irqhost->host_data = ipic; 682 ipic->irqhost->host_data = ipic;
587 ipic->hc_irq = ipic_irq_chip;
588 683
589 /* init hw */ 684 /* init hw */
590 ipic_write(ipic->regs, IPIC_SICNR, 0x0); 685 ipic_write(ipic->regs, IPIC_SICNR, 0x0);
@@ -593,6 +688,10 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
593 * configure SICFR accordingly */ 688 * configure SICFR accordingly */
594 if (flags & IPIC_SPREADMODE_GRP_A) 689 if (flags & IPIC_SPREADMODE_GRP_A)
595 temp |= SICFR_IPSA; 690 temp |= SICFR_IPSA;
691 if (flags & IPIC_SPREADMODE_GRP_B)
692 temp |= SICFR_IPSB;
693 if (flags & IPIC_SPREADMODE_GRP_C)
694 temp |= SICFR_IPSC;
596 if (flags & IPIC_SPREADMODE_GRP_D) 695 if (flags & IPIC_SPREADMODE_GRP_D)
597 temp |= SICFR_IPSD; 696 temp |= SICFR_IPSD;
598 if (flags & IPIC_SPREADMODE_MIX_A) 697 if (flags & IPIC_SPREADMODE_MIX_A)
@@ -600,7 +699,7 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
600 if (flags & IPIC_SPREADMODE_MIX_B) 699 if (flags & IPIC_SPREADMODE_MIX_B)
601 temp |= SICFR_MPSB; 700 temp |= SICFR_MPSB;
602 701
603 ipic_write(ipic->regs, IPIC_SICNR, temp); 702 ipic_write(ipic->regs, IPIC_SICFR, temp);
604 703
605 /* handle MCP route */ 704 /* handle MCP route */
606 temp = 0; 705 temp = 0;
@@ -672,10 +771,12 @@ void ipic_set_highest_priority(unsigned int virq)
672 771
673void ipic_set_default_priority(void) 772void ipic_set_default_priority(void)
674{ 773{
675 ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_SIPRR_A_DEFAULT); 774 ipic_write(primary_ipic->regs, IPIC_SIPRR_A, IPIC_PRIORITY_DEFAULT);
676 ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_SIPRR_D_DEFAULT); 775 ipic_write(primary_ipic->regs, IPIC_SIPRR_B, IPIC_PRIORITY_DEFAULT);
677 ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_SMPRR_A_DEFAULT); 776 ipic_write(primary_ipic->regs, IPIC_SIPRR_C, IPIC_PRIORITY_DEFAULT);
678 ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_SMPRR_B_DEFAULT); 777 ipic_write(primary_ipic->regs, IPIC_SIPRR_D, IPIC_PRIORITY_DEFAULT);
778 ipic_write(primary_ipic->regs, IPIC_SMPRR_A, IPIC_PRIORITY_DEFAULT);
779 ipic_write(primary_ipic->regs, IPIC_SMPRR_B, IPIC_PRIORITY_DEFAULT);
679} 780}
680 781
681void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq) 782void ipic_enable_mcp(enum ipic_mcp_irq mcp_irq)
diff --git a/arch/powerpc/sysdev/ipic.h b/arch/powerpc/sysdev/ipic.h
index bb309a501b2d..9391c57b0c51 100644
--- a/arch/powerpc/sysdev/ipic.h
+++ b/arch/powerpc/sysdev/ipic.h
@@ -23,13 +23,12 @@
23#define IPIC_IRQ_EXT7 23 23#define IPIC_IRQ_EXT7 23
24 24
25/* Default Priority Registers */ 25/* Default Priority Registers */
26#define IPIC_SIPRR_A_DEFAULT 0x05309770 26#define IPIC_PRIORITY_DEFAULT 0x05309770
27#define IPIC_SIPRR_D_DEFAULT 0x05309770
28#define IPIC_SMPRR_A_DEFAULT 0x05309770
29#define IPIC_SMPRR_B_DEFAULT 0x05309770
30 27
31/* System Global Interrupt Configuration Register */ 28/* System Global Interrupt Configuration Register */
32#define SICFR_IPSA 0x00010000 29#define SICFR_IPSA 0x00010000
30#define SICFR_IPSB 0x00020000
31#define SICFR_IPSC 0x00040000
33#define SICFR_IPSD 0x00080000 32#define SICFR_IPSD 0x00080000
34#define SICFR_MPSA 0x00200000 33#define SICFR_MPSA 0x00200000
35#define SICFR_MPSB 0x00400000 34#define SICFR_MPSB 0x00400000
@@ -45,13 +44,11 @@ struct ipic {
45 44
46 /* The remapper for this IPIC */ 45 /* The remapper for this IPIC */
47 struct irq_host *irqhost; 46 struct irq_host *irqhost;
48
49 /* The "linux" controller struct */
50 struct irq_chip hc_irq;
51}; 47};
52 48
53struct ipic_info { 49struct ipic_info {
54 u8 pend; /* pending register offset from base */ 50 u8 ack; /* pending register offset from base if the irq
51 supports ack operation */
55 u8 mask; /* mask register offset from base */ 52 u8 mask; /* mask register offset from base */
56 u8 prio; /* priority register offset from base */ 53 u8 prio; /* priority register offset from base */
57 u8 force; /* force register offset from base */ 54 u8 force; /* force register offset from base */
diff --git a/arch/powerpc/sysdev/mmio_nvram.c b/arch/powerpc/sysdev/mmio_nvram.c
index e073e246293d..7b49633a4bd0 100644
--- a/arch/powerpc/sysdev/mmio_nvram.c
+++ b/arch/powerpc/sysdev/mmio_nvram.c
@@ -99,7 +99,7 @@ int __init mmio_nvram_init(void)
99 nvram_addr = r.start; 99 nvram_addr = r.start;
100 mmio_nvram_len = r.end - r.start + 1; 100 mmio_nvram_len = r.end - r.start + 1;
101 if ( (!mmio_nvram_len) || (!nvram_addr) ) { 101 if ( (!mmio_nvram_len) || (!nvram_addr) ) {
102 printk(KERN_WARNING "nvram: address or lenght is 0\n"); 102 printk(KERN_WARNING "nvram: address or length is 0\n");
103 ret = -EIO; 103 ret = -EIO;
104 goto out; 104 goto out;
105 } 105 }
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index e47938899a92..f74fe26b787e 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -612,12 +612,11 @@ static inline void mpic_eoi(struct mpic *mpic)
612} 612}
613 613
614#ifdef CONFIG_SMP 614#ifdef CONFIG_SMP
615static irqreturn_t mpic_ipi_action(int irq, void *dev_id) 615static irqreturn_t mpic_ipi_action(int irq, void *data)
616{ 616{
617 struct mpic *mpic; 617 long ipi = (long)data;
618 618
619 mpic = mpic_find(irq, NULL); 619 smp_message_recv(ipi);
620 smp_message_recv(mpic_irq_to_hw(irq) - mpic->ipi_vecs[0]);
621 620
622 return IRQ_HANDLED; 621 return IRQ_HANDLED;
623} 622}
@@ -842,6 +841,24 @@ int mpic_set_irq_type(unsigned int virq, unsigned int flow_type)
842 return 0; 841 return 0;
843} 842}
844 843
844void mpic_set_vector(unsigned int virq, unsigned int vector)
845{
846 struct mpic *mpic = mpic_from_irq(virq);
847 unsigned int src = mpic_irq_to_hw(virq);
848 unsigned int vecpri;
849
850 DBG("mpic: set_vector(mpic:@%p,virq:%d,src:%d,vector:0x%x)\n",
851 mpic, virq, src, vector);
852
853 if (src >= mpic->irq_count)
854 return;
855
856 vecpri = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI));
857 vecpri = vecpri & ~MPIC_INFO(VECPRI_VECTOR_MASK);
858 vecpri |= vector;
859 mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vecpri);
860}
861
845static struct irq_chip mpic_irq_chip = { 862static struct irq_chip mpic_irq_chip = {
846 .mask = mpic_mask_irq, 863 .mask = mpic_mask_irq,
847 .unmask = mpic_unmask_irq, 864 .unmask = mpic_unmask_irq,
@@ -1230,6 +1247,8 @@ void __init mpic_init(struct mpic *mpic)
1230 mpic_u3msi_init(mpic); 1247 mpic_u3msi_init(mpic);
1231 } 1248 }
1232 1249
1250 mpic_pasemi_msi_init(mpic);
1251
1233 for (i = 0; i < mpic->num_sources; i++) { 1252 for (i = 0; i < mpic->num_sources; i++) {
1234 /* start with vector = source number, and masked */ 1253 /* start with vector = source number, and masked */
1235 u32 vecpri = MPIC_VECPRI_MASK | i | 1254 u32 vecpri = MPIC_VECPRI_MASK | i |
@@ -1457,7 +1476,7 @@ unsigned int mpic_get_irq(void)
1457void mpic_request_ipis(void) 1476void mpic_request_ipis(void)
1458{ 1477{
1459 struct mpic *mpic = mpic_primary; 1478 struct mpic *mpic = mpic_primary;
1460 int i, err; 1479 long i, err;
1461 static char *ipi_names[] = { 1480 static char *ipi_names[] = {
1462 "IPI0 (call function)", 1481 "IPI0 (call function)",
1463 "IPI1 (reschedule)", 1482 "IPI1 (reschedule)",
@@ -1472,14 +1491,14 @@ void mpic_request_ipis(void)
1472 unsigned int vipi = irq_create_mapping(mpic->irqhost, 1491 unsigned int vipi = irq_create_mapping(mpic->irqhost,
1473 mpic->ipi_vecs[0] + i); 1492 mpic->ipi_vecs[0] + i);
1474 if (vipi == NO_IRQ) { 1493 if (vipi == NO_IRQ) {
1475 printk(KERN_ERR "Failed to map IPI %d\n", i); 1494 printk(KERN_ERR "Failed to map IPI %ld\n", i);
1476 break; 1495 break;
1477 } 1496 }
1478 err = request_irq(vipi, mpic_ipi_action, 1497 err = request_irq(vipi, mpic_ipi_action,
1479 IRQF_DISABLED|IRQF_PERCPU, 1498 IRQF_DISABLED|IRQF_PERCPU,
1480 ipi_names[i], mpic); 1499 ipi_names[i], (void *)i);
1481 if (err) { 1500 if (err) {
1482 printk(KERN_ERR "Request of irq %d for IPI %d failed\n", 1501 printk(KERN_ERR "Request of irq %d for IPI %ld failed\n",
1483 vipi, i); 1502 vipi, i);
1484 break; 1503 break;
1485 } 1504 }
diff --git a/arch/powerpc/sysdev/mpic.h b/arch/powerpc/sysdev/mpic.h
index 1cb6bd841027..4783c6e9f30d 100644
--- a/arch/powerpc/sysdev/mpic.h
+++ b/arch/powerpc/sysdev/mpic.h
@@ -17,6 +17,7 @@ extern int mpic_msi_init_allocator(struct mpic *mpic);
17extern irq_hw_number_t mpic_msi_alloc_hwirqs(struct mpic *mpic, int num); 17extern irq_hw_number_t mpic_msi_alloc_hwirqs(struct mpic *mpic, int num);
18extern void mpic_msi_free_hwirqs(struct mpic *mpic, int offset, int num); 18extern void mpic_msi_free_hwirqs(struct mpic *mpic, int offset, int num);
19extern int mpic_u3msi_init(struct mpic *mpic); 19extern int mpic_u3msi_init(struct mpic *mpic);
20extern int mpic_pasemi_msi_init(struct mpic *mpic);
20#else 21#else
21static inline void mpic_msi_reserve_hwirq(struct mpic *mpic, 22static inline void mpic_msi_reserve_hwirq(struct mpic *mpic,
22 irq_hw_number_t hwirq) 23 irq_hw_number_t hwirq)
@@ -28,9 +29,15 @@ static inline int mpic_u3msi_init(struct mpic *mpic)
28{ 29{
29 return -1; 30 return -1;
30} 31}
32
33static inline int mpic_pasemi_msi_init(struct mpic *mpic)
34{
35 return -1;
36}
31#endif 37#endif
32 38
33extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type); 39extern int mpic_set_irq_type(unsigned int virq, unsigned int flow_type);
40extern void mpic_set_vector(unsigned int virq, unsigned int vector);
34extern void mpic_end_irq(unsigned int irq); 41extern void mpic_end_irq(unsigned int irq);
35extern void mpic_mask_irq(unsigned int irq); 42extern void mpic_mask_irq(unsigned int irq);
36extern void mpic_unmask_irq(unsigned int irq); 43extern void mpic_unmask_irq(unsigned int irq);
diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c
new file mode 100644
index 000000000000..d6bfda30ac87
--- /dev/null
+++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c
@@ -0,0 +1,172 @@
1/*
2 * Copyright 2007, Olof Johansson, PA Semi
3 *
4 * Based on arch/powerpc/sysdev/mpic_u3msi.c:
5 *
6 * Copyright 2006, Segher Boessenkool, IBM Corporation.
7 * Copyright 2006-2007, Michael Ellerman, IBM Corporation.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; version 2 of the
12 * License.
13 *
14 */
15
16#undef DEBUG
17
18#include <linux/irq.h>
19#include <linux/bootmem.h>
20#include <linux/msi.h>
21#include <asm/mpic.h>
22#include <asm/prom.h>
23#include <asm/hw_irq.h>
24#include <asm/ppc-pci.h>
25
26#include "mpic.h"
27
28/* Allocate 16 interrupts per device, to give an alignment of 16,
29 * since that's the size of the grouping w.r.t. affinity. If someone
30 * needs more than 32 MSI's down the road we'll have to rethink this,
31 * but it should be OK for now.
32 */
33#define ALLOC_CHUNK 16
34
35#define PASEMI_MSI_ADDR 0xfc080000
36
37/* A bit ugly, can we get this from the pci_dev somehow? */
38static struct mpic *msi_mpic;
39
40
41static void mpic_pasemi_msi_mask_irq(unsigned int irq)
42{
43 pr_debug("mpic_pasemi_msi_mask_irq %d\n", irq);
44 mask_msi_irq(irq);
45 mpic_mask_irq(irq);
46}
47
48static void mpic_pasemi_msi_unmask_irq(unsigned int irq)
49{
50 pr_debug("mpic_pasemi_msi_unmask_irq %d\n", irq);
51 mpic_unmask_irq(irq);
52 unmask_msi_irq(irq);
53}
54
55static struct irq_chip mpic_pasemi_msi_chip = {
56 .shutdown = mpic_pasemi_msi_mask_irq,
57 .mask = mpic_pasemi_msi_mask_irq,
58 .unmask = mpic_pasemi_msi_unmask_irq,
59 .eoi = mpic_end_irq,
60 .set_type = mpic_set_irq_type,
61 .set_affinity = mpic_set_affinity,
62 .typename = "PASEMI-MSI ",
63};
64
65static int pasemi_msi_check_device(struct pci_dev *pdev, int nvec, int type)
66{
67 if (type == PCI_CAP_ID_MSIX)
68 pr_debug("pasemi_msi: MSI-X untested, trying anyway\n");
69
70 return 0;
71}
72
73static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev)
74{
75 struct msi_desc *entry;
76
77 pr_debug("pasemi_msi_teardown_msi_irqs, pdev %p\n", pdev);
78
79 list_for_each_entry(entry, &pdev->msi_list, list) {
80 if (entry->irq == NO_IRQ)
81 continue;
82
83 set_irq_msi(entry->irq, NULL);
84 mpic_msi_free_hwirqs(msi_mpic, virq_to_hw(entry->irq),
85 ALLOC_CHUNK);
86 irq_dispose_mapping(entry->irq);
87 }
88
89 return;
90}
91
92static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
93{
94 irq_hw_number_t hwirq;
95 unsigned int virq;
96 struct msi_desc *entry;
97 struct msi_msg msg;
98 u64 addr;
99
100 pr_debug("pasemi_msi_setup_msi_irqs, pdev %p nvec %d type %d\n",
101 pdev, nvec, type);
102
103 msg.address_hi = 0;
104 msg.address_lo = PASEMI_MSI_ADDR;
105
106 list_for_each_entry(entry, &pdev->msi_list, list) {
107 /* Allocate 16 interrupts for now, since that's the grouping for
108 * affinity. This can be changed later if it turns out 32 is too
109 * few MSIs for someone, but restrictions will apply to how the
110 * sources can be changed independently.
111 */
112 hwirq = mpic_msi_alloc_hwirqs(msi_mpic, ALLOC_CHUNK);
113 if (hwirq < 0) {
114 pr_debug("pasemi_msi: failed allocating hwirq\n");
115 return hwirq;
116 }
117
118 virq = irq_create_mapping(msi_mpic->irqhost, hwirq);
119 if (virq == NO_IRQ) {
120 pr_debug("pasemi_msi: failed mapping hwirq 0x%lx\n", hwirq);
121 mpic_msi_free_hwirqs(msi_mpic, hwirq, ALLOC_CHUNK);
122 return -ENOSPC;
123 }
124
125 /* Vector on MSI is really an offset, the hardware adds
126 * it to the value written at the magic address. So set
127 * it to 0 to remain sane.
128 */
129 mpic_set_vector(virq, 0);
130
131 set_irq_msi(virq, entry);
132 set_irq_chip(virq, &mpic_pasemi_msi_chip);
133 set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
134
135 pr_debug("pasemi_msi: allocated virq 0x%x (hw 0x%lx) addr 0x%lx\n",
136 virq, hwirq, addr);
137
138 /* Likewise, the device writes [0...511] into the target
139 * register to generate MSI [512...1023]
140 */
141 msg.data = hwirq-0x200;
142 write_msi_msg(virq, &msg);
143 }
144
145 return 0;
146}
147
148int mpic_pasemi_msi_init(struct mpic *mpic)
149{
150 int rc;
151
152 if (!mpic->irqhost->of_node ||
153 !of_device_is_compatible(mpic->irqhost->of_node,
154 "pasemi,pwrficient-openpic"))
155 return -ENODEV;
156
157 rc = mpic_msi_init_allocator(mpic);
158 if (rc) {
159 pr_debug("pasemi_msi: Error allocating bitmap!\n");
160 return rc;
161 }
162
163 pr_debug("pasemi_msi: Registering PA Semi MPIC MSI callbacks\n");
164
165 msi_mpic = mpic;
166 WARN_ON(ppc_md.setup_msi_irqs);
167 ppc_md.setup_msi_irqs = pasemi_msi_setup_msi_irqs;
168 ppc_md.teardown_msi_irqs = pasemi_msi_teardown_msi_irqs;
169 ppc_md.msi_check_device = pasemi_msi_check_device;
170
171 return 0;
172}
diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c
index 20edd1e94eff..c858749263e0 100644
--- a/arch/powerpc/sysdev/pmi.c
+++ b/arch/powerpc/sysdev/pmi.c
@@ -28,9 +28,9 @@
28#include <linux/completion.h> 28#include <linux/completion.h>
29#include <linux/spinlock.h> 29#include <linux/spinlock.h>
30#include <linux/workqueue.h> 30#include <linux/workqueue.h>
31#include <linux/of_device.h>
32#include <linux/of_platform.h>
31 33
32#include <asm/of_device.h>
33#include <asm/of_platform.h>
34#include <asm/io.h> 34#include <asm/io.h>
35#include <asm/pmi.h> 35#include <asm/pmi.h>
36#include <asm/prom.h> 36#include <asm/prom.h>
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 3d57d3835b04..21e01061aca9 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -167,19 +167,20 @@ unsigned int get_brg_clk(void)
167 167
168/* Program the BRG to the given sampling rate and multiplier 168/* Program the BRG to the given sampling rate and multiplier
169 * 169 *
170 * @brg: the BRG, 1-16 170 * @brg: the BRG, QE_BRG1 - QE_BRG16
171 * @rate: the desired sampling rate 171 * @rate: the desired sampling rate
172 * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or 172 * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or
173 * GUMR_L[TDCR]. E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01, 173 * GUMR_L[TDCR]. E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01,
174 * then 'multiplier' should be 8. 174 * then 'multiplier' should be 8.
175 *
176 * Also note that the value programmed into the BRGC register must be even.
177 */ 175 */
178void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier) 176int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
179{ 177{
180 u32 divisor, tempval; 178 u32 divisor, tempval;
181 u32 div16 = 0; 179 u32 div16 = 0;
182 180
181 if ((brg < QE_BRG1) || (brg > QE_BRG16))
182 return -EINVAL;
183
183 divisor = get_brg_clk() / (rate * multiplier); 184 divisor = get_brg_clk() / (rate * multiplier);
184 185
185 if (divisor > QE_BRGC_DIVISOR_MAX + 1) { 186 if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
@@ -196,8 +197,43 @@ void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier)
196 tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | 197 tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
197 QE_BRGC_ENABLE | div16; 198 QE_BRGC_ENABLE | div16;
198 199
199 out_be32(&qe_immr->brg.brgc[brg - 1], tempval); 200 out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval);
201
202 return 0;
203}
204EXPORT_SYMBOL(qe_setbrg);
205
206/* Convert a string to a QE clock source enum
207 *
208 * This function takes a string, typically from a property in the device
209 * tree, and returns the corresponding "enum qe_clock" value.
210*/
211enum qe_clock qe_clock_source(const char *source)
212{
213 unsigned int i;
214
215 if (strcasecmp(source, "none") == 0)
216 return QE_CLK_NONE;
217
218 if (strncasecmp(source, "brg", 3) == 0) {
219 i = simple_strtoul(source + 3, NULL, 10);
220 if ((i >= 1) && (i <= 16))
221 return (QE_BRG1 - 1) + i;
222 else
223 return QE_CLK_DUMMY;
224 }
225
226 if (strncasecmp(source, "clk", 3) == 0) {
227 i = simple_strtoul(source + 3, NULL, 10);
228 if ((i >= 1) && (i <= 24))
229 return (QE_CLK1 - 1) + i;
230 else
231 return QE_CLK_DUMMY;
232 }
233
234 return QE_CLK_DUMMY;
200} 235}
236EXPORT_SYMBOL(qe_clock_source);
201 237
202/* Initialize SNUMs (thread serial numbers) according to 238/* Initialize SNUMs (thread serial numbers) according to
203 * QE Module Control chapter, SNUM table 239 * QE Module Control chapter, SNUM table
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index 121b04d165d1..865e36751f21 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -153,6 +153,10 @@ static const char *getvecname(unsigned long vec);
153 153
154static int do_spu_cmd(void); 154static int do_spu_cmd(void);
155 155
156#ifdef CONFIG_44x
157static void dump_tlb_44x(void);
158#endif
159
156int xmon_no_auto_backtrace; 160int xmon_no_auto_backtrace;
157 161
158extern void xmon_enter(void); 162extern void xmon_enter(void);
@@ -231,6 +235,9 @@ Commands:\n\
231#ifdef CONFIG_PPC_STD_MMU_32 235#ifdef CONFIG_PPC_STD_MMU_32
232" u dump segment registers\n" 236" u dump segment registers\n"
233#endif 237#endif
238#ifdef CONFIG_44x
239" u dump TLB\n"
240#endif
234" ? help\n" 241" ? help\n"
235" zr reboot\n\ 242" zr reboot\n\
236 zh halt\n" 243 zh halt\n"
@@ -856,6 +863,11 @@ cmds(struct pt_regs *excp)
856 dump_segments(); 863 dump_segments();
857 break; 864 break;
858#endif 865#endif
866#ifdef CONFIG_4xx
867 case 'u':
868 dump_tlb_44x();
869 break;
870#endif
859 default: 871 default:
860 printf("Unrecognized command: "); 872 printf("Unrecognized command: ");
861 do { 873 do {
@@ -2527,16 +2539,33 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
2527static void dump_slb(void) 2539static void dump_slb(void)
2528{ 2540{
2529 int i; 2541 int i;
2530 unsigned long tmp; 2542 unsigned long esid,vsid,valid;
2543 unsigned long llp;
2531 2544
2532 printf("SLB contents of cpu %x\n", smp_processor_id()); 2545 printf("SLB contents of cpu %x\n", smp_processor_id());
2533 2546
2534 for (i = 0; i < SLB_NUM_ENTRIES; i++) { 2547 for (i = 0; i < mmu_slb_size; i++) {
2535 asm volatile("slbmfee %0,%1" : "=r" (tmp) : "r" (i)); 2548 asm volatile("slbmfee %0,%1" : "=r" (esid) : "r" (i));
2536 printf("%02d %016lx ", i, tmp); 2549 asm volatile("slbmfev %0,%1" : "=r" (vsid) : "r" (i));
2537 2550 valid = (esid & SLB_ESID_V);
2538 asm volatile("slbmfev %0,%1" : "=r" (tmp) : "r" (i)); 2551 if (valid | esid | vsid) {
2539 printf("%016lx\n", tmp); 2552 printf("%02d %016lx %016lx", i, esid, vsid);
2553 if (valid) {
2554 llp = vsid & SLB_VSID_LLP;
2555 if (vsid & SLB_VSID_B_1T) {
2556 printf(" 1T ESID=%9lx VSID=%13lx LLP:%3lx \n",
2557 GET_ESID_1T(esid),
2558 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT_1T,
2559 llp);
2560 } else {
2561 printf(" 256M ESID=%9lx VSID=%13lx LLP:%3lx \n",
2562 GET_ESID(esid),
2563 (vsid & ~SLB_VSID_B) >> SLB_VSID_SHIFT,
2564 llp);
2565 }
2566 } else
2567 printf("\n");
2568 }
2540 } 2569 }
2541} 2570}
2542 2571
@@ -2581,6 +2610,32 @@ void dump_segments(void)
2581} 2610}
2582#endif 2611#endif
2583 2612
2613#ifdef CONFIG_44x
2614static void dump_tlb_44x(void)
2615{
2616 int i;
2617
2618 for (i = 0; i < PPC44x_TLB_SIZE; i++) {
2619 unsigned long w0,w1,w2;
2620 asm volatile("tlbre %0,%1,0" : "=r" (w0) : "r" (i));
2621 asm volatile("tlbre %0,%1,1" : "=r" (w1) : "r" (i));
2622 asm volatile("tlbre %0,%1,2" : "=r" (w2) : "r" (i));
2623 printf("[%02x] %08x %08x %08x ", i, w0, w1, w2);
2624 if (w0 & PPC44x_TLB_VALID) {
2625 printf("V %08x -> %01x%08x %c%c%c%c%c",
2626 w0 & PPC44x_TLB_EPN_MASK,
2627 w1 & PPC44x_TLB_ERPN_MASK,
2628 w1 & PPC44x_TLB_RPN_MASK,
2629 (w2 & PPC44x_TLB_W) ? 'W' : 'w',
2630 (w2 & PPC44x_TLB_I) ? 'I' : 'i',
2631 (w2 & PPC44x_TLB_M) ? 'M' : 'm',
2632 (w2 & PPC44x_TLB_G) ? 'G' : 'g',
2633 (w2 & PPC44x_TLB_E) ? 'E' : 'e');
2634 }
2635 printf("\n");
2636 }
2637}
2638#endif /* CONFIG_44x */
2584void xmon_init(int enable) 2639void xmon_init(int enable)
2585{ 2640{
2586#ifdef CONFIG_PPC_ISERIES 2641#ifdef CONFIG_PPC_ISERIES
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 5255bd80aa6b..3c453029f1c5 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -37,7 +37,6 @@
37#include <asm/nvram.h> 37#include <asm/nvram.h>
38#include <asm/xmon.h> 38#include <asm/xmon.h>
39#include <asm/ocp.h> 39#include <asm/ocp.h>
40#include <asm/prom.h>
41 40
42#define USES_PPC_SYS (defined(CONFIG_85xx) || defined(CONFIG_83xx) || \ 41#define USES_PPC_SYS (defined(CONFIG_85xx) || defined(CONFIG_83xx) || \
43 defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \ 42 defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \
diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c
index b1f5b737c70d..731b40eacfdb 100644
--- a/arch/ppc/platforms/85xx/stx_gp3.c
+++ b/arch/ppc/platforms/85xx/stx_gp3.c
@@ -50,7 +50,6 @@
50#include <asm/irq.h> 50#include <asm/irq.h>
51#include <asm/immap_85xx.h> 51#include <asm/immap_85xx.h>
52#include <asm/cpm2.h> 52#include <asm/cpm2.h>
53#include <asm/mpc85xx.h>
54#include <asm/ppc_sys.h> 53#include <asm/ppc_sys.h>
55 54
56#include <syslib/cpm2_pic.h> 55#include <syslib/cpm2_pic.h>
diff --git a/arch/ppc/platforms/ev64260.c b/arch/ppc/platforms/ev64260.c
index 976270d537c1..c1f77e1d368e 100644
--- a/arch/ppc/platforms/ev64260.c
+++ b/arch/ppc/platforms/ev64260.c
@@ -336,7 +336,7 @@ ev64260_early_serial_map(void)
336#endif 336#endif
337 337
338 if (early_serial_setup(&port) != 0) 338 if (early_serial_setup(&port) != 0)
339 printk(KERN_WARNING "Early serial init of port 0" 339 printk(KERN_WARNING "Early serial init of port 0 "
340 "failed\n"); 340 "failed\n");
341 341
342 first_time = 0; 342 first_time = 0;
@@ -388,7 +388,7 @@ ev64260_setup_arch(void)
388 ev64260_early_serial_map(); 388 ev64260_early_serial_map();
389#endif 389#endif
390 390
391 printk(KERN_INFO "%s %s port (C) 2001 MontaVista Software, Inc." 391 printk(KERN_INFO "%s %s port (C) 2001 MontaVista Software, Inc. "
392 "(source@mvista.com)\n", BOARD_VENDOR, BOARD_MACHINE); 392 "(source@mvista.com)\n", BOARD_VENDOR, BOARD_MACHINE);
393 393
394 if (ppc_md.progress) 394 if (ppc_md.progress)
diff --git a/arch/ppc/platforms/prep_pci.c b/arch/ppc/platforms/prep_pci.c
index 1df3150f016e..8ed433e2a5c7 100644
--- a/arch/ppc/platforms/prep_pci.c
+++ b/arch/ppc/platforms/prep_pci.c
@@ -1099,7 +1099,6 @@ prep_pib_init(void)
1099 pci_write_config_byte(dev, 0x43, reg); 1099 pci_write_config_byte(dev, 0x43, reg);
1100 } 1100 }
1101 } 1101 }
1102 pci_dev_put(dev);
1103 } 1102 }
1104 1103
1105 if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND, 1104 if ((dev = pci_get_device(PCI_VENDOR_ID_WINBOND,
diff --git a/arch/ppc/syslib/gt64260_pic.c b/arch/ppc/syslib/gt64260_pic.c
index e84d432c0657..3b4fcca5d1e1 100644
--- a/arch/ppc/syslib/gt64260_pic.c
+++ b/arch/ppc/syslib/gt64260_pic.c
@@ -35,7 +35,6 @@
35#include <linux/interrupt.h> 35#include <linux/interrupt.h>
36#include <linux/sched.h> 36#include <linux/sched.h>
37#include <linux/signal.h> 37#include <linux/signal.h>
38#include <linux/stddef.h>
39#include <linux/delay.h> 38#include <linux/delay.h>
40#include <linux/irq.h> 39#include <linux/irq.h>
41 40
diff --git a/arch/ppc/syslib/mpc52xx_pic.c b/arch/ppc/syslib/mpc52xx_pic.c
index af35a316544a..f58149c03b0f 100644
--- a/arch/ppc/syslib/mpc52xx_pic.c
+++ b/arch/ppc/syslib/mpc52xx_pic.c
@@ -20,7 +20,6 @@
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/sched.h> 21#include <linux/sched.h>
22#include <linux/signal.h> 22#include <linux/signal.h>
23#include <linux/stddef.h>
24#include <linux/delay.h> 23#include <linux/delay.h>
25#include <linux/irq.h> 24#include <linux/irq.h>
26 25
diff --git a/arch/ppc/syslib/mv64360_pic.c b/arch/ppc/syslib/mv64360_pic.c
index 4b7a3338e122..2dd2dc5cd404 100644
--- a/arch/ppc/syslib/mv64360_pic.c
+++ b/arch/ppc/syslib/mv64360_pic.c
@@ -36,7 +36,6 @@
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/sched.h> 37#include <linux/sched.h>
38#include <linux/signal.h> 38#include <linux/signal.h>
39#include <linux/stddef.h>
40#include <linux/delay.h> 39#include <linux/delay.h>
41#include <linux/irq.h> 40#include <linux/irq.h>
42#include <linux/interrupt.h> 41#include <linux/interrupt.h>
diff --git a/arch/ppc/syslib/ocp.c b/arch/ppc/syslib/ocp.c
index 3f5be2c5ce99..d42d4085dc81 100644
--- a/arch/ppc/syslib/ocp.c
+++ b/arch/ppc/syslib/ocp.c
@@ -376,7 +376,7 @@ ocp_remove_one_device(unsigned int vendor, unsigned int function, int index)
376 376
377 down_write(&ocp_devices_sem); 377 down_write(&ocp_devices_sem);
378 dev = __ocp_find_device(vendor, function, index); 378 dev = __ocp_find_device(vendor, function, index);
379 list_del((struct list_head *)dev); 379 list_del(&dev->link);
380 up_write(&ocp_devices_sem); 380 up_write(&ocp_devices_sem);
381 381
382 DBG(("ocp: ocp_remove_one_device(vendor: %x, function: %x, index: %d)... done.\n", vendor, function, index)); 382 DBG(("ocp: ocp_remove_one_device(vendor: %x, function: %x, index: %d)... done.\n", vendor, function, index));
diff --git a/arch/ppc/syslib/ppc83xx_setup.c b/arch/ppc/syslib/ppc83xx_setup.c
index ec466db52114..ea372914dd6e 100644
--- a/arch/ppc/syslib/ppc83xx_setup.c
+++ b/arch/ppc/syslib/ppc83xx_setup.c
@@ -41,7 +41,6 @@
41 41
42#include <syslib/ppc83xx_setup.h> 42#include <syslib/ppc83xx_setup.h>
43#if defined(CONFIG_PCI) 43#if defined(CONFIG_PCI)
44#include <asm/delay.h>
45#include <syslib/ppc83xx_pci.h> 44#include <syslib/ppc83xx_pci.h>
46#endif 45#endif
47 46
diff --git a/arch/ppc/syslib/ppc8xx_pic.c b/arch/ppc/syslib/ppc8xx_pic.c
index e8619c750732..bce9a75c80e3 100644
--- a/arch/ppc/syslib/ppc8xx_pic.c
+++ b/arch/ppc/syslib/ppc8xx_pic.c
@@ -16,7 +16,7 @@ extern int cpm_get_irq(void);
16 * the only interrupt controller. Some boards, like the MBX and 16 * the only interrupt controller. Some boards, like the MBX and
17 * Sandpoint have the 8259 as a secondary controller. Depending 17 * Sandpoint have the 8259 as a secondary controller. Depending
18 * upon the processor type, the internal controller can have as 18 * upon the processor type, the internal controller can have as
19 * few as 16 interrups or as many as 64. We could use the 19 * few as 16 interrupts or as many as 64. We could use the
20 * "clear_bit()" and "set_bit()" functions like other platforms, 20 * "clear_bit()" and "set_bit()" functions like other platforms,
21 * but they are overkill for us. 21 * but they are overkill for us.
22 */ 22 */
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
index 2d48018b71d9..837183c24dfc 100644
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -185,7 +185,7 @@ void platform_notify_map(const struct platform_notify_dev_map *map,
185 */ 185 */
186 186
187/* 187/*
188 Here we'll replace .name pointers with fixed-lenght strings 188 Here we'll replace .name pointers with fixed-length strings
189 Hereby, this should be called *before* any func stuff triggeded. 189 Hereby, this should be called *before* any func stuff triggeded.
190 */ 190 */
191void ppc_sys_device_initfunc(void) 191void ppc_sys_device_initfunc(void)
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
index 8f0b953179fa..9056fe58aaa1 100644
--- a/arch/ppc/xmon/start.c
+++ b/arch/ppc/xmon/start.c
@@ -10,7 +10,6 @@
10#include <linux/sysrq.h> 10#include <linux/sysrq.h>
11#include <linux/bitops.h> 11#include <linux/bitops.h>
12#include <asm/xmon.h> 12#include <asm/xmon.h>
13#include <asm/machdep.h>
14#include <asm/errno.h> 13#include <asm/errno.h>
15#include <asm/processor.h> 14#include <asm/processor.h>
16#include <asm/delay.h> 15#include <asm/delay.h>
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 2d7cd486e025..6bbd4fa50f3b 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -98,7 +98,7 @@ config HW_RANDOM_PASEMI
98 default HW_RANDOM 98 default HW_RANDOM
99 ---help--- 99 ---help---
100 This driver provides kernel-side support for the Random Number 100 This driver provides kernel-side support for the Random Number
101 Generator hardware found on PA6T-1682M processor. 101 Generator hardware found on PA Semi PWRficient SoCs.
102 102
103 To compile this driver as a module, choose M here: the 103 To compile this driver as a module, choose M here: the
104 module will be called pasemi-rng. 104 module will be called pasemi-rng.
diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c
index fa6040b6c8f2..24ae3073991f 100644
--- a/drivers/char/hw_random/pasemi-rng.c
+++ b/drivers/char/hw_random/pasemi-rng.c
@@ -126,10 +126,9 @@ static int __devexit rng_remove(struct of_device *dev)
126} 126}
127 127
128static struct of_device_id rng_match[] = { 128static struct of_device_id rng_match[] = {
129 { 129 { .compatible = "1682m-rng", },
130 .compatible = "1682m-rng", 130 { .compatible = "pasemi,pwrficient-rng", },
131 }, 131 { },
132 {},
133}; 132};
134 133
135static struct of_platform_driver rng_driver = { 134static struct of_platform_driver rng_driver = {
diff --git a/drivers/edac/pasemi_edac.c b/drivers/edac/pasemi_edac.c
index 9007d0677220..90320917be28 100644
--- a/drivers/edac/pasemi_edac.c
+++ b/drivers/edac/pasemi_edac.c
@@ -225,7 +225,7 @@ static int __devinit pasemi_edac_probe(struct pci_dev *pdev,
225 EDAC_FLAG_NONE; 225 EDAC_FLAG_NONE;
226 mci->mod_name = MODULE_NAME; 226 mci->mod_name = MODULE_NAME;
227 mci->dev_name = pci_name(pdev); 227 mci->dev_name = pci_name(pdev);
228 mci->ctl_name = "pasemi,1682m-mc"; 228 mci->ctl_name = "pasemi,pwrficient-mc";
229 mci->edac_check = pasemi_edac_check; 229 mci->edac_check = pasemi_edac_check;
230 mci->ctl_page_to_phys = NULL; 230 mci->ctl_page_to_phys = NULL;
231 pci_read_config_dword(pdev, MCCFG_SCRUB, &scrub); 231 pci_read_config_dword(pdev, MCCFG_SCRUB, &scrub);
@@ -297,4 +297,4 @@ module_exit(pasemi_edac_exit);
297 297
298MODULE_LICENSE("GPL"); 298MODULE_LICENSE("GPL");
299MODULE_AUTHOR("Egor Martovetsky <egor@pasemi.com>"); 299MODULE_AUTHOR("Egor Martovetsky <egor@pasemi.com>");
300MODULE_DESCRIPTION("MC support for PA Semi PA6T-1682M memory controller"); 300MODULE_DESCRIPTION("MC support for PA Semi PWRficient memory controller");
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index 5c742a526082..5ae28f076d25 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -35,6 +35,7 @@
35#include <linux/spinlock.h> 35#include <linux/spinlock.h>
36#include <linux/completion.h> 36#include <linux/completion.h>
37#include <linux/device.h> 37#include <linux/device.h>
38#include <linux/kthread.h>
38 39
39#include <asm/uaccess.h> 40#include <asm/uaccess.h>
40#include <asm/semaphore.h> 41#include <asm/semaphore.h>
@@ -82,21 +83,11 @@ struct adb_driver *adb_controller;
82BLOCKING_NOTIFIER_HEAD(adb_client_list); 83BLOCKING_NOTIFIER_HEAD(adb_client_list);
83static int adb_got_sleep; 84static int adb_got_sleep;
84static int adb_inited; 85static int adb_inited;
85static pid_t adb_probe_task_pid;
86static DECLARE_MUTEX(adb_probe_mutex); 86static DECLARE_MUTEX(adb_probe_mutex);
87static struct completion adb_probe_task_comp;
88static int sleepy_trackpad; 87static int sleepy_trackpad;
89static int autopoll_devs; 88static int autopoll_devs;
90int __adb_probe_sync; 89int __adb_probe_sync;
91 90
92#ifdef CONFIG_PM_SLEEP
93static void adb_notify_sleep(struct pmu_sleep_notifier *self, int when);
94static struct pmu_sleep_notifier adb_sleep_notifier = {
95 adb_notify_sleep,
96 SLEEP_LEVEL_ADB,
97};
98#endif
99
100static int adb_scan_bus(void); 91static int adb_scan_bus(void);
101static int do_adb_reset_bus(void); 92static int do_adb_reset_bus(void);
102static void adbdev_init(void); 93static void adbdev_init(void);
@@ -134,16 +125,6 @@ static void printADBreply(struct adb_request *req)
134} 125}
135#endif 126#endif
136 127
137
138static __inline__ void adb_wait_ms(unsigned int ms)
139{
140 if (current->pid && adb_probe_task_pid &&
141 adb_probe_task_pid == current->pid)
142 msleep(ms);
143 else
144 mdelay(ms);
145}
146
147static int adb_scan_bus(void) 128static int adb_scan_bus(void)
148{ 129{
149 int i, highFree=0, noMovement; 130 int i, highFree=0, noMovement;
@@ -248,13 +229,10 @@ static int adb_scan_bus(void)
248static int 229static int
249adb_probe_task(void *x) 230adb_probe_task(void *x)
250{ 231{
251 strcpy(current->comm, "kadbprobe");
252
253 printk(KERN_INFO "adb: starting probe task...\n"); 232 printk(KERN_INFO "adb: starting probe task...\n");
254 do_adb_reset_bus(); 233 do_adb_reset_bus();
255 printk(KERN_INFO "adb: finished probe task...\n"); 234 printk(KERN_INFO "adb: finished probe task...\n");
256 235
257 adb_probe_task_pid = 0;
258 up(&adb_probe_mutex); 236 up(&adb_probe_mutex);
259 237
260 return 0; 238 return 0;
@@ -263,7 +241,7 @@ adb_probe_task(void *x)
263static void 241static void
264__adb_probe_task(struct work_struct *bullshit) 242__adb_probe_task(struct work_struct *bullshit)
265{ 243{
266 adb_probe_task_pid = kernel_thread(adb_probe_task, NULL, SIGCHLD | CLONE_KERNEL); 244 kthread_run(adb_probe_task, NULL, "kadbprobe");
267} 245}
268 246
269static DECLARE_WORK(adb_reset_work, __adb_probe_task); 247static DECLARE_WORK(adb_reset_work, __adb_probe_task);
@@ -281,6 +259,36 @@ adb_reset_bus(void)
281 return 0; 259 return 0;
282} 260}
283 261
262#ifdef CONFIG_PM
263/*
264 * notify clients before sleep
265 */
266static int adb_suspend(struct platform_device *dev, pm_message_t state)
267{
268 adb_got_sleep = 1;
269 /* We need to get a lock on the probe thread */
270 down(&adb_probe_mutex);
271 /* Stop autopoll */
272 if (adb_controller->autopoll)
273 adb_controller->autopoll(0);
274 blocking_notifier_call_chain(&adb_client_list, ADB_MSG_POWERDOWN, NULL);
275
276 return 0;
277}
278
279/*
280 * reset bus after sleep
281 */
282static int adb_resume(struct platform_device *dev)
283{
284 adb_got_sleep = 0;
285 up(&adb_probe_mutex);
286 adb_reset_bus();
287
288 return 0;
289}
290#endif /* CONFIG_PM */
291
284int __init adb_init(void) 292int __init adb_init(void)
285{ 293{
286 struct adb_driver *driver; 294 struct adb_driver *driver;
@@ -313,15 +321,12 @@ int __init adb_init(void)
313 printk(KERN_WARNING "Warning: no ADB interface detected\n"); 321 printk(KERN_WARNING "Warning: no ADB interface detected\n");
314 adb_controller = NULL; 322 adb_controller = NULL;
315 } else { 323 } else {
316#ifdef CONFIG_PM_SLEEP
317 pmu_register_sleep_notifier(&adb_sleep_notifier);
318#endif /* CONFIG_PM */
319#ifdef CONFIG_PPC 324#ifdef CONFIG_PPC
320 if (machine_is_compatible("AAPL,PowerBook1998") || 325 if (machine_is_compatible("AAPL,PowerBook1998") ||
321 machine_is_compatible("PowerBook1,1")) 326 machine_is_compatible("PowerBook1,1"))
322 sleepy_trackpad = 1; 327 sleepy_trackpad = 1;
323#endif /* CONFIG_PPC */ 328#endif /* CONFIG_PPC */
324 init_completion(&adb_probe_task_comp); 329
325 adbdev_init(); 330 adbdev_init();
326 adb_reset_bus(); 331 adb_reset_bus();
327 } 332 }
@@ -330,33 +335,6 @@ int __init adb_init(void)
330 335
331__initcall(adb_init); 336__initcall(adb_init);
332 337
333#ifdef CONFIG_PM
334/*
335 * notify clients before sleep and reset bus afterwards
336 */
337void
338adb_notify_sleep(struct pmu_sleep_notifier *self, int when)
339{
340 switch (when) {
341 case PBOOK_SLEEP_REQUEST:
342 adb_got_sleep = 1;
343 /* We need to get a lock on the probe thread */
344 down(&adb_probe_mutex);
345 /* Stop autopoll */
346 if (adb_controller->autopoll)
347 adb_controller->autopoll(0);
348 blocking_notifier_call_chain(&adb_client_list,
349 ADB_MSG_POWERDOWN, NULL);
350 break;
351 case PBOOK_WAKE:
352 adb_got_sleep = 0;
353 up(&adb_probe_mutex);
354 adb_reset_bus();
355 break;
356 }
357}
358#endif /* CONFIG_PM */
359
360static int 338static int
361do_adb_reset_bus(void) 339do_adb_reset_bus(void)
362{ 340{
@@ -373,7 +351,7 @@ do_adb_reset_bus(void)
373 351
374 if (sleepy_trackpad) { 352 if (sleepy_trackpad) {
375 /* Let the trackpad settle down */ 353 /* Let the trackpad settle down */
376 adb_wait_ms(500); 354 msleep(500);
377 } 355 }
378 356
379 down(&adb_handler_sem); 357 down(&adb_handler_sem);
@@ -389,7 +367,7 @@ do_adb_reset_bus(void)
389 367
390 if (sleepy_trackpad) { 368 if (sleepy_trackpad) {
391 /* Let the trackpad settle down */ 369 /* Let the trackpad settle down */
392 adb_wait_ms(1500); 370 msleep(1500);
393 } 371 }
394 372
395 if (!ret) { 373 if (!ret) {
@@ -413,41 +391,27 @@ adb_poll(void)
413 adb_controller->poll(); 391 adb_controller->poll();
414} 392}
415 393
416static void 394static void adb_sync_req_done(struct adb_request *req)
417adb_probe_wakeup(struct adb_request *req)
418{ 395{
419 complete(&adb_probe_task_comp); 396 struct completion *comp = req->arg;
420}
421 397
422/* Static request used during probe */ 398 complete(comp);
423static struct adb_request adb_sreq; 399}
424static unsigned long adb_sreq_lock; // Use semaphore ! */
425 400
426int 401int
427adb_request(struct adb_request *req, void (*done)(struct adb_request *), 402adb_request(struct adb_request *req, void (*done)(struct adb_request *),
428 int flags, int nbytes, ...) 403 int flags, int nbytes, ...)
429{ 404{
430 va_list list; 405 va_list list;
431 int i, use_sreq; 406 int i;
432 int rc; 407 int rc;
408 struct completion comp;
433 409
434 if ((adb_controller == NULL) || (adb_controller->send_request == NULL)) 410 if ((adb_controller == NULL) || (adb_controller->send_request == NULL))
435 return -ENXIO; 411 return -ENXIO;
436 if (nbytes < 1) 412 if (nbytes < 1)
437 return -EINVAL; 413 return -EINVAL;
438 if (req == NULL && (flags & ADBREQ_NOSEND)) 414
439 return -EINVAL;
440
441 if (req == NULL) {
442 if (test_and_set_bit(0,&adb_sreq_lock)) {
443 printk("adb.c: Warning: contention on static request !\n");
444 return -EPERM;
445 }
446 req = &adb_sreq;
447 flags |= ADBREQ_SYNC;
448 use_sreq = 1;
449 } else
450 use_sreq = 0;
451 req->nbytes = nbytes+1; 415 req->nbytes = nbytes+1;
452 req->done = done; 416 req->done = done;
453 req->reply_expected = flags & ADBREQ_REPLY; 417 req->reply_expected = flags & ADBREQ_REPLY;
@@ -460,25 +424,18 @@ adb_request(struct adb_request *req, void (*done)(struct adb_request *),
460 if (flags & ADBREQ_NOSEND) 424 if (flags & ADBREQ_NOSEND)
461 return 0; 425 return 0;
462 426
463 /* Synchronous requests send from the probe thread cause it to 427 /* Synchronous requests block using an on-stack completion */
464 * block. Beware that the "done" callback will be overriden ! 428 if (flags & ADBREQ_SYNC) {
465 */ 429 WARN_ON(done);
466 if ((flags & ADBREQ_SYNC) && 430 req->done = adb_sync_req_done;
467 (current->pid && adb_probe_task_pid && 431 req->arg = &comp;
468 adb_probe_task_pid == current->pid)) { 432 init_completion(&comp);
469 req->done = adb_probe_wakeup;
470 rc = adb_controller->send_request(req, 0);
471 if (rc || req->complete)
472 goto bail;
473 wait_for_completion(&adb_probe_task_comp);
474 rc = 0;
475 goto bail;
476 } 433 }
477 434
478 rc = adb_controller->send_request(req, flags & ADBREQ_SYNC); 435 rc = adb_controller->send_request(req, 0);
479bail: 436
480 if (use_sreq) 437 if ((flags & ADBREQ_SYNC) && !rc && !req->complete)
481 clear_bit(0, &adb_sreq_lock); 438 wait_for_completion(&comp);
482 439
483 return rc; 440 return rc;
484} 441}
@@ -864,7 +821,29 @@ static const struct file_operations adb_fops = {
864 .release = adb_release, 821 .release = adb_release,
865}; 822};
866 823
867static void 824static struct platform_driver adb_pfdrv = {
825 .driver = {
826 .name = "adb",
827 },
828#ifdef CONFIG_PM
829 .suspend = adb_suspend,
830 .resume = adb_resume,
831#endif
832};
833
834static struct platform_device adb_pfdev = {
835 .name = "adb",
836};
837
838static int __init
839adb_dummy_probe(struct platform_device *dev)
840{
841 if (dev == &adb_pfdev)
842 return 0;
843 return -ENODEV;
844}
845
846static void __init
868adbdev_init(void) 847adbdev_init(void)
869{ 848{
870 if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) { 849 if (register_chrdev(ADB_MAJOR, "adb", &adb_fops)) {
@@ -876,4 +855,7 @@ adbdev_init(void)
876 if (IS_ERR(adb_dev_class)) 855 if (IS_ERR(adb_dev_class))
877 return; 856 return;
878 class_device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb"); 857 class_device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb");
858
859 platform_device_register(&adb_pfdev);
860 platform_driver_probe(&adb_pfdrv, adb_dummy_probe);
879} 861}
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c
index 48d647abea46..192bef5c20b3 100644
--- a/drivers/macintosh/mediabay.c
+++ b/drivers/macintosh/mediabay.c
@@ -20,6 +20,7 @@
20#include <linux/stddef.h> 20#include <linux/stddef.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/ide.h> 22#include <linux/ide.h>
23#include <linux/kthread.h>
23#include <asm/prom.h> 24#include <asm/prom.h>
24#include <asm/pgtable.h> 25#include <asm/pgtable.h>
25#include <asm/io.h> 26#include <asm/io.h>
@@ -35,7 +36,6 @@
35 36
36 37
37#define MB_DEBUG 38#define MB_DEBUG
38#define MB_IGNORE_SIGNALS
39 39
40#ifdef MB_DEBUG 40#ifdef MB_DEBUG
41#define MBDBG(fmt, arg...) printk(KERN_INFO fmt , ## arg) 41#define MBDBG(fmt, arg...) printk(KERN_INFO fmt , ## arg)
@@ -622,12 +622,7 @@ static int media_bay_task(void *x)
622{ 622{
623 int i; 623 int i;
624 624
625 strcpy(current->comm, "media-bay"); 625 while (!kthread_should_stop()) {
626#ifdef MB_IGNORE_SIGNALS
627 sigfillset(&current->blocked);
628#endif
629
630 for (;;) {
631 for (i = 0; i < media_bay_count; ++i) { 626 for (i = 0; i < media_bay_count; ++i) {
632 down(&media_bays[i].lock); 627 down(&media_bays[i].lock);
633 if (!media_bays[i].sleeping) 628 if (!media_bays[i].sleeping)
@@ -636,9 +631,8 @@ static int media_bay_task(void *x)
636 } 631 }
637 632
638 msleep_interruptible(MB_POLL_DELAY); 633 msleep_interruptible(MB_POLL_DELAY);
639 if (signal_pending(current))
640 return 0;
641 } 634 }
635 return 0;
642} 636}
643 637
644static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_device_id *match) 638static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_device_id *match)
@@ -699,7 +693,7 @@ static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_de
699 693
700 /* Startup kernel thread */ 694 /* Startup kernel thread */
701 if (i == 0) 695 if (i == 0)
702 kernel_thread(media_bay_task, NULL, CLONE_KERNEL); 696 kthread_run(media_bay_task, NULL, "media-bay");
703 697
704 return 0; 698 return 0;
705 699
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index e43554e754a4..6fadc9ac66b0 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -121,6 +121,7 @@
121#include <linux/reboot.h> 121#include <linux/reboot.h>
122#include <linux/kmod.h> 122#include <linux/kmod.h>
123#include <linux/i2c.h> 123#include <linux/i2c.h>
124#include <linux/kthread.h>
124#include <asm/prom.h> 125#include <asm/prom.h>
125#include <asm/machdep.h> 126#include <asm/machdep.h>
126#include <asm/io.h> 127#include <asm/io.h>
@@ -161,7 +162,7 @@ static struct slots_pid_state slots_state;
161static int state; 162static int state;
162static int cpu_count; 163static int cpu_count;
163static int cpu_pid_type; 164static int cpu_pid_type;
164static pid_t ctrl_task; 165static struct task_struct *ctrl_task;
165static struct completion ctrl_complete; 166static struct completion ctrl_complete;
166static int critical_state; 167static int critical_state;
167static int rackmac; 168static int rackmac;
@@ -1779,8 +1780,6 @@ static int call_critical_overtemp(void)
1779 */ 1780 */
1780static int main_control_loop(void *x) 1781static int main_control_loop(void *x)
1781{ 1782{
1782 daemonize("kfand");
1783
1784 DBG("main_control_loop started\n"); 1783 DBG("main_control_loop started\n");
1785 1784
1786 down(&driver_lock); 1785 down(&driver_lock);
@@ -1956,7 +1955,7 @@ static void start_control_loops(void)
1956{ 1955{
1957 init_completion(&ctrl_complete); 1956 init_completion(&ctrl_complete);
1958 1957
1959 ctrl_task = kernel_thread(main_control_loop, NULL, SIGCHLD | CLONE_KERNEL); 1958 ctrl_task = kthread_run(main_control_loop, NULL, "kfand");
1960} 1959}
1961 1960
1962/* 1961/*
@@ -1964,7 +1963,7 @@ static void start_control_loops(void)
1964 */ 1963 */
1965static void stop_control_loops(void) 1964static void stop_control_loops(void)
1966{ 1965{
1967 if (ctrl_task != 0) 1966 if (ctrl_task)
1968 wait_for_completion(&ctrl_complete); 1967 wait_for_completion(&ctrl_complete);
1969} 1968}
1970 1969
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 5452da1bb1a5..37224025f00e 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -36,6 +36,7 @@
36#include <linux/i2c.h> 36#include <linux/i2c.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/init.h> 38#include <linux/init.h>
39#include <linux/kthread.h>
39 40
40#include <asm/prom.h> 41#include <asm/prom.h>
41#include <asm/machdep.h> 42#include <asm/machdep.h>
@@ -61,8 +62,7 @@ I2C_CLIENT_INSMOD;
61 62
62static struct { 63static struct {
63 volatile int running; 64 volatile int running;
64 struct completion completion; 65 struct task_struct *poll_task;
65 pid_t poll_task;
66 66
67 struct semaphore lock; 67 struct semaphore lock;
68 struct of_device *of_dev; 68 struct of_device *of_dev;
@@ -282,27 +282,27 @@ restore_regs( void )
282 write_reg( x.fan, 0x00, x.r0, 1 ); 282 write_reg( x.fan, 0x00, x.r0, 1 );
283} 283}
284 284
285static int 285static int control_loop(void *dummy)
286control_loop( void *dummy )
287{ 286{
288 daemonize("g4fand"); 287 down(&x.lock);
289
290 down( &x.lock );
291 setup_hardware(); 288 setup_hardware();
289 up(&x.lock);
292 290
293 while( x.running ) { 291 for (;;) {
294 up( &x.lock );
295
296 msleep_interruptible(8000); 292 msleep_interruptible(8000);
297 293 if (kthread_should_stop())
298 down( &x.lock ); 294 break;
295
296 down(&x.lock);
299 poll_temp(); 297 poll_temp();
298 up(&x.lock);
300 } 299 }
301 300
301 down(&x.lock);
302 restore_regs(); 302 restore_regs();
303 up( &x.lock ); 303 up(&x.lock);
304 304
305 complete_and_exit( &x.completion, 0 ); 305 return 0;
306} 306}
307 307
308 308
@@ -322,8 +322,7 @@ do_attach( struct i2c_adapter *adapter )
322 ret = i2c_probe( adapter, &addr_data, &do_probe ); 322 ret = i2c_probe( adapter, &addr_data, &do_probe );
323 if( x.thermostat && x.fan ) { 323 if( x.thermostat && x.fan ) {
324 x.running = 1; 324 x.running = 1;
325 init_completion( &x.completion ); 325 x.poll_task = kthread_run(control_loop, NULL, "g4fand");
326 x.poll_task = kernel_thread( control_loop, NULL, SIGCHLD | CLONE_KERNEL );
327 } 326 }
328 } 327 }
329 return ret; 328 return ret;
@@ -339,7 +338,8 @@ do_detach( struct i2c_client *client )
339 else { 338 else {
340 if( x.running ) { 339 if( x.running ) {
341 x.running = 0; 340 x.running = 0;
342 wait_for_completion( &x.completion ); 341 kthread_stop(x.poll_task);
342 x.poll_task = NULL;
343 } 343 }
344 if( client == x.thermostat ) 344 if( client == x.thermostat )
345 x.thermostat = NULL; 345 x.thermostat = NULL;
diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c
index 7e27071746e4..741a2e3f4fc6 100644
--- a/drivers/macintosh/via-pmu-backlight.c
+++ b/drivers/macintosh/via-pmu-backlight.c
@@ -22,7 +22,7 @@ static u8 bl_curve[FB_BACKLIGHT_LEVELS];
22 22
23static void pmu_backlight_init_curve(u8 off, u8 min, u8 max) 23static void pmu_backlight_init_curve(u8 off, u8 min, u8 max)
24{ 24{
25 unsigned int i, flat, count, range = (max - min); 25 int i, flat, count, range = (max - min);
26 26
27 bl_curve[0] = off; 27 bl_curve[0] = off;
28 28
@@ -68,17 +68,11 @@ static int pmu_backlight_get_level_brightness(int level)
68 return pmulevel; 68 return pmulevel;
69} 69}
70 70
71static int pmu_backlight_update_status(struct backlight_device *bd) 71static int __pmu_backlight_update_status(struct backlight_device *bd)
72{ 72{
73 struct adb_request req; 73 struct adb_request req;
74 unsigned long flags;
75 int level = bd->props.brightness; 74 int level = bd->props.brightness;
76 75
77 spin_lock_irqsave(&pmu_backlight_lock, flags);
78
79 /* Don't update brightness when sleeping */
80 if (sleeping)
81 goto out;
82 76
83 if (bd->props.power != FB_BLANK_UNBLANK || 77 if (bd->props.power != FB_BLANK_UNBLANK ||
84 bd->props.fb_blank != FB_BLANK_UNBLANK) 78 bd->props.fb_blank != FB_BLANK_UNBLANK)
@@ -99,12 +93,23 @@ static int pmu_backlight_update_status(struct backlight_device *bd)
99 pmu_wait_complete(&req); 93 pmu_wait_complete(&req);
100 } 94 }
101 95
102out:
103 spin_unlock_irqrestore(&pmu_backlight_lock, flags);
104
105 return 0; 96 return 0;
106} 97}
107 98
99static int pmu_backlight_update_status(struct backlight_device *bd)
100{
101 unsigned long flags;
102 int rc = 0;
103
104 spin_lock_irqsave(&pmu_backlight_lock, flags);
105 /* Don't update brightness when sleeping */
106 if (!sleeping)
107 rc = __pmu_backlight_update_status(bd);
108 spin_unlock_irqrestore(&pmu_backlight_lock, flags);
109 return rc;
110}
111
112
108static int pmu_backlight_get_brightness(struct backlight_device *bd) 113static int pmu_backlight_get_brightness(struct backlight_device *bd)
109{ 114{
110 return bd->props.brightness; 115 return bd->props.brightness;
@@ -123,6 +128,16 @@ void pmu_backlight_set_sleep(int sleep)
123 128
124 spin_lock_irqsave(&pmu_backlight_lock, flags); 129 spin_lock_irqsave(&pmu_backlight_lock, flags);
125 sleeping = sleep; 130 sleeping = sleep;
131 if (pmac_backlight) {
132 if (sleep) {
133 struct adb_request req;
134
135 pmu_request(&req, NULL, 2, PMU_POWER_CTRL,
136 PMU_POW_BACKLIGHT | PMU_POW_OFF);
137 pmu_wait_complete(&req);
138 } else
139 __pmu_backlight_update_status(pmac_backlight);
140 }
126 spin_unlock_irqrestore(&pmu_backlight_lock, flags); 141 spin_unlock_irqrestore(&pmu_backlight_lock, flags);
127} 142}
128#endif /* CONFIG_PM */ 143#endif /* CONFIG_PM */
@@ -148,8 +163,8 @@ void __init pmu_backlight_init()
148 163
149 bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data); 164 bd = backlight_device_register(name, NULL, NULL, &pmu_backlight_data);
150 if (IS_ERR(bd)) { 165 if (IS_ERR(bd)) {
151 printk("pmubl: Backlight registration failed\n"); 166 printk(KERN_ERR "PMU Backlight registration failed\n");
152 goto error; 167 return;
153 } 168 }
154 bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; 169 bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1;
155 pmu_backlight_init_curve(0x7F, 0x46, 0x0E); 170 pmu_backlight_init_curve(0x7F, 0x46, 0x0E);
@@ -171,10 +186,5 @@ void __init pmu_backlight_init()
171 bd->props.power = FB_BLANK_UNBLANK; 186 bd->props.power = FB_BLANK_UNBLANK;
172 backlight_update_status(bd); 187 backlight_update_status(bd);
173 188
174 printk("pmubl: Backlight initialized (%s)\n", name); 189 printk(KERN_INFO "PMU Backlight initialized (%s)\n", name);
175
176 return;
177
178error:
179 return;
180} 190}
diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c
index 6123c70153d3..82ec12e0edd2 100644
--- a/drivers/macintosh/via-pmu.c
+++ b/drivers/macintosh/via-pmu.c
@@ -10,13 +10,11 @@
10 * 10 *
11 * Copyright (C) 1998 Paul Mackerras and Fabio Riccardi. 11 * Copyright (C) 1998 Paul Mackerras and Fabio Riccardi.
12 * Copyright (C) 2001-2002 Benjamin Herrenschmidt 12 * Copyright (C) 2001-2002 Benjamin Herrenschmidt
13 * Copyright (C) 2006-2007 Johannes Berg
13 * 14 *
14 * THIS DRIVER IS BECOMING A TOTAL MESS ! 15 * THIS DRIVER IS BECOMING A TOTAL MESS !
15 * - Cleanup atomically disabling reply to PMU events after 16 * - Cleanup atomically disabling reply to PMU events after
16 * a sleep or a freq. switch 17 * a sleep or a freq. switch
17 * - Move sleep code out of here to pmac_pm, merge into new
18 * common PM infrastructure
19 * - Save/Restore PCI space properly
20 * 18 *
21 */ 19 */
22#include <stdarg.h> 20#include <stdarg.h>
@@ -33,7 +31,6 @@
33#include <linux/adb.h> 31#include <linux/adb.h>
34#include <linux/pmu.h> 32#include <linux/pmu.h>
35#include <linux/cuda.h> 33#include <linux/cuda.h>
36#include <linux/smp_lock.h>
37#include <linux/module.h> 34#include <linux/module.h>
38#include <linux/spinlock.h> 35#include <linux/spinlock.h>
39#include <linux/pm.h> 36#include <linux/pm.h>
@@ -65,9 +62,7 @@
65#include "via-pmu-event.h" 62#include "via-pmu-event.h"
66 63
67/* Some compile options */ 64/* Some compile options */
68#undef SUSPEND_USES_PMU 65#undef DEBUG_SLEEP
69#define DEBUG_SLEEP
70#undef HACKED_PCI_SAVE
71 66
72/* Misc minor number allocated for /dev/pmu */ 67/* Misc minor number allocated for /dev/pmu */
73#define PMU_MINOR 154 68#define PMU_MINOR 154
@@ -152,12 +147,9 @@ static spinlock_t pmu_lock;
152static u8 pmu_intr_mask; 147static u8 pmu_intr_mask;
153static int pmu_version; 148static int pmu_version;
154static int drop_interrupts; 149static int drop_interrupts;
155#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) 150#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
156static int option_lid_wakeup = 1; 151static int option_lid_wakeup = 1;
157#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ 152#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
158#if (defined(CONFIG_PM_SLEEP)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT_LEGACY)
159static int sleep_in_progress;
160#endif
161static unsigned long async_req_locks; 153static unsigned long async_req_locks;
162static unsigned int pmu_irq_stats[11]; 154static unsigned int pmu_irq_stats[11];
163 155
@@ -177,7 +169,6 @@ static struct proc_dir_entry *proc_pmu_batt[PMU_MAX_BATTERIES];
177 169
178int __fake_sleep; 170int __fake_sleep;
179int asleep; 171int asleep;
180BLOCKING_NOTIFIER_HEAD(sleep_notifier_list);
181 172
182#ifdef CONFIG_ADB 173#ifdef CONFIG_ADB
183static int adb_dev_map; 174static int adb_dev_map;
@@ -224,7 +215,7 @@ extern void enable_kernel_fp(void);
224 215
225#ifdef DEBUG_SLEEP 216#ifdef DEBUG_SLEEP
226int pmu_polled_request(struct adb_request *req); 217int pmu_polled_request(struct adb_request *req);
227int pmu_wink(struct adb_request *req); 218void pmu_blink(int n);
228#endif 219#endif
229 220
230/* 221/*
@@ -875,7 +866,7 @@ proc_read_options(char *page, char **start, off_t off,
875{ 866{
876 char *p = page; 867 char *p = page;
877 868
878#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) 869#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
879 if (pmu_kind == PMU_KEYLARGO_BASED && 870 if (pmu_kind == PMU_KEYLARGO_BASED &&
880 pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) 871 pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
881 p += sprintf(p, "lid_wakeup=%d\n", option_lid_wakeup); 872 p += sprintf(p, "lid_wakeup=%d\n", option_lid_wakeup);
@@ -916,7 +907,7 @@ proc_write_options(struct file *file, const char __user *buffer,
916 *(val++) = 0; 907 *(val++) = 0;
917 while(*val == ' ') 908 while(*val == ' ')
918 val++; 909 val++;
919#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) 910#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
920 if (pmu_kind == PMU_KEYLARGO_BASED && 911 if (pmu_kind == PMU_KEYLARGO_BASED &&
921 pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) 912 pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
922 if (!strcmp(label, "lid_wakeup")) 913 if (!strcmp(label, "lid_wakeup"))
@@ -1256,9 +1247,7 @@ void
1256pmu_suspend(void) 1247pmu_suspend(void)
1257{ 1248{
1258 unsigned long flags; 1249 unsigned long flags;
1259#ifdef SUSPEND_USES_PMU 1250
1260 struct adb_request *req;
1261#endif
1262 if (!via) 1251 if (!via)
1263 return; 1252 return;
1264 1253
@@ -1276,17 +1265,10 @@ pmu_suspend(void)
1276 via_pmu_interrupt(0, NULL); 1265 via_pmu_interrupt(0, NULL);
1277 spin_lock_irqsave(&pmu_lock, flags); 1266 spin_lock_irqsave(&pmu_lock, flags);
1278 if (!adb_int_pending && pmu_state == idle && !req_awaiting_reply) { 1267 if (!adb_int_pending && pmu_state == idle && !req_awaiting_reply) {
1279#ifdef SUSPEND_USES_PMU
1280 pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0);
1281 spin_unlock_irqrestore(&pmu_lock, flags);
1282 while(!req.complete)
1283 pmu_poll();
1284#else /* SUSPEND_USES_PMU */
1285 if (gpio_irq >= 0) 1268 if (gpio_irq >= 0)
1286 disable_irq_nosync(gpio_irq); 1269 disable_irq_nosync(gpio_irq);
1287 out_8(&via[IER], CB1_INT | IER_CLR); 1270 out_8(&via[IER], CB1_INT | IER_CLR);
1288 spin_unlock_irqrestore(&pmu_lock, flags); 1271 spin_unlock_irqrestore(&pmu_lock, flags);
1289#endif /* SUSPEND_USES_PMU */
1290 break; 1272 break;
1291 } 1273 }
1292 } while (1); 1274 } while (1);
@@ -1307,18 +1289,11 @@ pmu_resume(void)
1307 return; 1289 return;
1308 } 1290 }
1309 adb_int_pending = 1; 1291 adb_int_pending = 1;
1310#ifdef SUSPEND_USES_PMU
1311 pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, pmu_intr_mask);
1312 spin_unlock_irqrestore(&pmu_lock, flags);
1313 while(!req.complete)
1314 pmu_poll();
1315#else /* SUSPEND_USES_PMU */
1316 if (gpio_irq >= 0) 1292 if (gpio_irq >= 0)
1317 enable_irq(gpio_irq); 1293 enable_irq(gpio_irq);
1318 out_8(&via[IER], CB1_INT | IER_SET); 1294 out_8(&via[IER], CB1_INT | IER_SET);
1319 spin_unlock_irqrestore(&pmu_lock, flags); 1295 spin_unlock_irqrestore(&pmu_lock, flags);
1320 pmu_poll(); 1296 pmu_poll();
1321#endif /* SUSPEND_USES_PMU */
1322} 1297}
1323 1298
1324/* Interrupt data could be the result data from an ADB cmd */ 1299/* Interrupt data could be the result data from an ADB cmd */
@@ -1738,228 +1713,7 @@ pmu_present(void)
1738 return via != 0; 1713 return via != 0;
1739} 1714}
1740 1715
1741#ifdef CONFIG_PM_SLEEP 1716#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
1742
1743static LIST_HEAD(sleep_notifiers);
1744
1745int
1746pmu_register_sleep_notifier(struct pmu_sleep_notifier *n)
1747{
1748 struct list_head *list;
1749 struct pmu_sleep_notifier *notifier;
1750
1751 for (list = sleep_notifiers.next; list != &sleep_notifiers;
1752 list = list->next) {
1753 notifier = list_entry(list, struct pmu_sleep_notifier, list);
1754 if (n->priority > notifier->priority)
1755 break;
1756 }
1757 __list_add(&n->list, list->prev, list);
1758 return 0;
1759}
1760EXPORT_SYMBOL(pmu_register_sleep_notifier);
1761
1762int
1763pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* n)
1764{
1765 if (n->list.next == 0)
1766 return -ENOENT;
1767 list_del(&n->list);
1768 n->list.next = NULL;
1769 return 0;
1770}
1771EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
1772#endif /* CONFIG_PM_SLEEP */
1773
1774#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32)
1775
1776/* Sleep is broadcast last-to-first */
1777static void broadcast_sleep(int when)
1778{
1779 struct list_head *list;
1780 struct pmu_sleep_notifier *notifier;
1781
1782 for (list = sleep_notifiers.prev; list != &sleep_notifiers;
1783 list = list->prev) {
1784 notifier = list_entry(list, struct pmu_sleep_notifier, list);
1785 notifier->notifier_call(notifier, when);
1786 }
1787}
1788
1789/* Wake is broadcast first-to-last */
1790static void broadcast_wake(void)
1791{
1792 struct list_head *list;
1793 struct pmu_sleep_notifier *notifier;
1794
1795 for (list = sleep_notifiers.next; list != &sleep_notifiers;
1796 list = list->next) {
1797 notifier = list_entry(list, struct pmu_sleep_notifier, list);
1798 notifier->notifier_call(notifier, PBOOK_WAKE);
1799 }
1800}
1801
1802/*
1803 * This struct is used to store config register values for
1804 * PCI devices which may get powered off when we sleep.
1805 */
1806static struct pci_save {
1807#ifndef HACKED_PCI_SAVE
1808 u16 command;
1809 u16 cache_lat;
1810 u16 intr;
1811 u32 rom_address;
1812#else
1813 u32 config[16];
1814#endif
1815} *pbook_pci_saves;
1816static int pbook_npci_saves;
1817
1818static void
1819pbook_alloc_pci_save(void)
1820{
1821 int npci;
1822 struct pci_dev *pd = NULL;
1823
1824 npci = 0;
1825 while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
1826 ++npci;
1827 }
1828 if (npci == 0)
1829 return;
1830 pbook_pci_saves = (struct pci_save *)
1831 kmalloc(npci * sizeof(struct pci_save), GFP_KERNEL);
1832 pbook_npci_saves = npci;
1833}
1834
1835static void
1836pbook_free_pci_save(void)
1837{
1838 if (pbook_pci_saves == NULL)
1839 return;
1840 kfree(pbook_pci_saves);
1841 pbook_pci_saves = NULL;
1842 pbook_npci_saves = 0;
1843}
1844
1845static void
1846pbook_pci_save(void)
1847{
1848 struct pci_save *ps = pbook_pci_saves;
1849 struct pci_dev *pd = NULL;
1850 int npci = pbook_npci_saves;
1851
1852 if (ps == NULL)
1853 return;
1854
1855 while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
1856 if (npci-- == 0) {
1857 pci_dev_put(pd);
1858 return;
1859 }
1860#ifndef HACKED_PCI_SAVE
1861 pci_read_config_word(pd, PCI_COMMAND, &ps->command);
1862 pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat);
1863 pci_read_config_word(pd, PCI_INTERRUPT_LINE, &ps->intr);
1864 pci_read_config_dword(pd, PCI_ROM_ADDRESS, &ps->rom_address);
1865#else
1866 int i;
1867 for (i=1;i<16;i++)
1868 pci_read_config_dword(pd, i<<4, &ps->config[i]);
1869#endif
1870 ++ps;
1871 }
1872}
1873
1874/* For this to work, we must take care of a few things: If gmac was enabled
1875 * during boot, it will be in the pci dev list. If it's disabled at this point
1876 * (and it will probably be), then you can't access it's config space.
1877 */
1878static void
1879pbook_pci_restore(void)
1880{
1881 u16 cmd;
1882 struct pci_save *ps = pbook_pci_saves - 1;
1883 struct pci_dev *pd = NULL;
1884 int npci = pbook_npci_saves;
1885 int j;
1886
1887 while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) {
1888#ifdef HACKED_PCI_SAVE
1889 int i;
1890 if (npci-- == 0) {
1891 pci_dev_put(pd);
1892 return;
1893 }
1894 ps++;
1895 for (i=2;i<16;i++)
1896 pci_write_config_dword(pd, i<<4, ps->config[i]);
1897 pci_write_config_dword(pd, 4, ps->config[1]);
1898#else
1899 if (npci-- == 0)
1900 return;
1901 ps++;
1902 if (ps->command == 0)
1903 continue;
1904 pci_read_config_word(pd, PCI_COMMAND, &cmd);
1905 if ((ps->command & ~cmd) == 0)
1906 continue;
1907 switch (pd->hdr_type) {
1908 case PCI_HEADER_TYPE_NORMAL:
1909 for (j = 0; j < 6; ++j)
1910 pci_write_config_dword(pd,
1911 PCI_BASE_ADDRESS_0 + j*4,
1912 pd->resource[j].start);
1913 pci_write_config_dword(pd, PCI_ROM_ADDRESS,
1914 ps->rom_address);
1915 pci_write_config_word(pd, PCI_CACHE_LINE_SIZE,
1916 ps->cache_lat);
1917 pci_write_config_word(pd, PCI_INTERRUPT_LINE,
1918 ps->intr);
1919 pci_write_config_word(pd, PCI_COMMAND, ps->command);
1920 break;
1921 }
1922#endif
1923 }
1924}
1925
1926#ifdef DEBUG_SLEEP
1927/* N.B. This doesn't work on the 3400 */
1928void
1929pmu_blink(int n)
1930{
1931 struct adb_request req;
1932
1933 memset(&req, 0, sizeof(req));
1934
1935 for (; n > 0; --n) {
1936 req.nbytes = 4;
1937 req.done = NULL;
1938 req.data[0] = 0xee;
1939 req.data[1] = 4;
1940 req.data[2] = 0;
1941 req.data[3] = 1;
1942 req.reply[0] = ADB_RET_OK;
1943 req.reply_len = 1;
1944 req.reply_expected = 0;
1945 pmu_polled_request(&req);
1946 mdelay(50);
1947 req.nbytes = 4;
1948 req.done = NULL;
1949 req.data[0] = 0xee;
1950 req.data[1] = 4;
1951 req.data[2] = 0;
1952 req.data[3] = 0;
1953 req.reply[0] = ADB_RET_OK;
1954 req.reply_len = 1;
1955 req.reply_expected = 0;
1956 pmu_polled_request(&req);
1957 mdelay(50);
1958 }
1959 mdelay(50);
1960}
1961#endif
1962
1963/* 1717/*
1964 * Put the powerbook to sleep. 1718 * Put the powerbook to sleep.
1965 */ 1719 */
@@ -1994,134 +1748,6 @@ restore_via_state(void)
1994 out_8(&via[IER], IER_SET | SR_INT | CB1_INT); 1748 out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
1995} 1749}
1996 1750
1997extern void pmu_backlight_set_sleep(int sleep);
1998
1999static int
2000pmac_suspend_devices(void)
2001{
2002 int ret;
2003
2004 pm_prepare_console();
2005
2006 /* Notify old-style device drivers */
2007 broadcast_sleep(PBOOK_SLEEP_REQUEST);
2008
2009 /* Sync the disks. */
2010 /* XXX It would be nice to have some way to ensure that
2011 * nobody is dirtying any new buffers while we wait. That
2012 * could be achieved using the refrigerator for processes
2013 * that swsusp uses
2014 */
2015 sys_sync();
2016
2017 broadcast_sleep(PBOOK_SLEEP_NOW);
2018
2019 /* Send suspend call to devices, hold the device core's dpm_sem */
2020 ret = device_suspend(PMSG_SUSPEND);
2021 if (ret) {
2022 broadcast_wake();
2023 printk(KERN_ERR "Driver sleep failed\n");
2024 return -EBUSY;
2025 }
2026
2027#ifdef CONFIG_PMAC_BACKLIGHT
2028 /* Tell backlight code not to muck around with the chip anymore */
2029 pmu_backlight_set_sleep(1);
2030#endif
2031
2032 /* Call platform functions marked "on sleep" */
2033 pmac_pfunc_i2c_suspend();
2034 pmac_pfunc_base_suspend();
2035
2036 /* Stop preemption */
2037 preempt_disable();
2038
2039 /* Make sure the decrementer won't interrupt us */
2040 asm volatile("mtdec %0" : : "r" (0x7fffffff));
2041 /* Make sure any pending DEC interrupt occurring while we did
2042 * the above didn't re-enable the DEC */
2043 mb();
2044 asm volatile("mtdec %0" : : "r" (0x7fffffff));
2045
2046 /* We can now disable MSR_EE. This code of course works properly only
2047 * on UP machines... For SMP, if we ever implement sleep, we'll have to
2048 * stop the "other" CPUs way before we do all that stuff.
2049 */
2050 local_irq_disable();
2051
2052 /* Broadcast power down irq
2053 * This isn't that useful in most cases (only directly wired devices can
2054 * use this but still... This will take care of sysdev's as well, so
2055 * we exit from here with local irqs disabled and PIC off.
2056 */
2057 ret = device_power_down(PMSG_SUSPEND);
2058 if (ret) {
2059 wakeup_decrementer();
2060 local_irq_enable();
2061 preempt_enable();
2062 device_resume();
2063 broadcast_wake();
2064 printk(KERN_ERR "Driver powerdown failed\n");
2065 return -EBUSY;
2066 }
2067
2068 /* Wait for completion of async requests */
2069 while (!batt_req.complete)
2070 pmu_poll();
2071
2072 /* Giveup the lazy FPU & vec so we don't have to back them
2073 * up from the low level code
2074 */
2075 enable_kernel_fp();
2076
2077#ifdef CONFIG_ALTIVEC
2078 if (cpu_has_feature(CPU_FTR_ALTIVEC))
2079 enable_kernel_altivec();
2080#endif /* CONFIG_ALTIVEC */
2081
2082 return 0;
2083}
2084
2085static int
2086pmac_wakeup_devices(void)
2087{
2088 mdelay(100);
2089
2090#ifdef CONFIG_PMAC_BACKLIGHT
2091 /* Tell backlight code it can use the chip again */
2092 pmu_backlight_set_sleep(0);
2093#endif
2094
2095 /* Power back up system devices (including the PIC) */
2096 device_power_up();
2097
2098 /* Force a poll of ADB interrupts */
2099 adb_int_pending = 1;
2100 via_pmu_interrupt(0, NULL);
2101
2102 /* Restart jiffies & scheduling */
2103 wakeup_decrementer();
2104
2105 /* Re-enable local CPU interrupts */
2106 local_irq_enable();
2107 mdelay(10);
2108 preempt_enable();
2109
2110 /* Call platform functions marked "on wake" */
2111 pmac_pfunc_base_resume();
2112 pmac_pfunc_i2c_resume();
2113
2114 /* Resume devices */
2115 device_resume();
2116
2117 /* Notify old style drivers */
2118 broadcast_wake();
2119
2120 pm_restore_console();
2121
2122 return 0;
2123}
2124
2125#define GRACKLE_PM (1<<7) 1751#define GRACKLE_PM (1<<7)
2126#define GRACKLE_DOZE (1<<5) 1752#define GRACKLE_DOZE (1<<5)
2127#define GRACKLE_NAP (1<<4) 1753#define GRACKLE_NAP (1<<4)
@@ -2132,19 +1758,12 @@ static int powerbook_sleep_grackle(void)
2132 unsigned long save_l2cr; 1758 unsigned long save_l2cr;
2133 unsigned short pmcr1; 1759 unsigned short pmcr1;
2134 struct adb_request req; 1760 struct adb_request req;
2135 int ret;
2136 struct pci_dev *grackle; 1761 struct pci_dev *grackle;
2137 1762
2138 grackle = pci_get_bus_and_slot(0, 0); 1763 grackle = pci_get_bus_and_slot(0, 0);
2139 if (!grackle) 1764 if (!grackle)
2140 return -ENODEV; 1765 return -ENODEV;
2141 1766
2142 ret = pmac_suspend_devices();
2143 if (ret) {
2144 printk(KERN_ERR "Sleep rejected by devices\n");
2145 return ret;
2146 }
2147
2148 /* Turn off various things. Darwin does some retry tests here... */ 1767 /* Turn off various things. Darwin does some retry tests here... */
2149 pmu_request(&req, NULL, 2, PMU_POWER_CTRL0, PMU_POW0_OFF|PMU_POW0_HARD_DRIVE); 1768 pmu_request(&req, NULL, 2, PMU_POWER_CTRL0, PMU_POW0_OFF|PMU_POW0_HARD_DRIVE);
2150 pmu_wait_complete(&req); 1769 pmu_wait_complete(&req);
@@ -2207,8 +1826,6 @@ static int powerbook_sleep_grackle(void)
2207 PMU_POW_ON|PMU_POW_BACKLIGHT|PMU_POW_CHARGER|PMU_POW_IRLED|PMU_POW_MEDIABAY); 1826 PMU_POW_ON|PMU_POW_BACKLIGHT|PMU_POW_CHARGER|PMU_POW_IRLED|PMU_POW_MEDIABAY);
2208 pmu_wait_complete(&req); 1827 pmu_wait_complete(&req);
2209 1828
2210 pmac_wakeup_devices();
2211
2212 return 0; 1829 return 0;
2213} 1830}
2214 1831
@@ -2218,7 +1835,6 @@ powerbook_sleep_Core99(void)
2218 unsigned long save_l2cr; 1835 unsigned long save_l2cr;
2219 unsigned long save_l3cr; 1836 unsigned long save_l3cr;
2220 struct adb_request req; 1837 struct adb_request req;
2221 int ret;
2222 1838
2223 if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0) { 1839 if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0) {
2224 printk(KERN_ERR "Sleep mode not supported on this machine\n"); 1840 printk(KERN_ERR "Sleep mode not supported on this machine\n");
@@ -2228,12 +1844,6 @@ powerbook_sleep_Core99(void)
2228 if (num_online_cpus() > 1 || cpu_is_offline(0)) 1844 if (num_online_cpus() > 1 || cpu_is_offline(0))
2229 return -EAGAIN; 1845 return -EAGAIN;
2230 1846
2231 ret = pmac_suspend_devices();
2232 if (ret) {
2233 printk(KERN_ERR "Sleep rejected by devices\n");
2234 return ret;
2235 }
2236
2237 /* Stop environment and ADB interrupts */ 1847 /* Stop environment and ADB interrupts */
2238 pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0); 1848 pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, 0);
2239 pmu_wait_complete(&req); 1849 pmu_wait_complete(&req);
@@ -2304,45 +1914,33 @@ powerbook_sleep_Core99(void)
2304 /* Restore LPJ, cpufreq will adjust the cpu frequency */ 1914 /* Restore LPJ, cpufreq will adjust the cpu frequency */
2305 loops_per_jiffy /= 2; 1915 loops_per_jiffy /= 2;
2306 1916
2307 pmac_wakeup_devices();
2308
2309 return 0; 1917 return 0;
2310} 1918}
2311 1919
2312#define PB3400_MEM_CTRL 0xf8000000 1920#define PB3400_MEM_CTRL 0xf8000000
2313#define PB3400_MEM_CTRL_SLEEP 0x70 1921#define PB3400_MEM_CTRL_SLEEP 0x70
2314 1922
2315static int 1923static void __iomem *pb3400_mem_ctrl;
2316powerbook_sleep_3400(void) 1924
1925static void powerbook_sleep_init_3400(void)
1926{
1927 /* map in the memory controller registers */
1928 pb3400_mem_ctrl = ioremap(PB3400_MEM_CTRL, 0x100);
1929 if (pb3400_mem_ctrl == NULL)
1930 printk(KERN_WARNING "ioremap failed: sleep won't be possible");
1931}
1932
1933static int powerbook_sleep_3400(void)
2317{ 1934{
2318 int ret, i, x; 1935 int i, x;
2319 unsigned int hid0; 1936 unsigned int hid0;
2320 unsigned long p; 1937 unsigned long msr;
2321 struct adb_request sleep_req; 1938 struct adb_request sleep_req;
2322 void __iomem *mem_ctrl;
2323 unsigned int __iomem *mem_ctrl_sleep; 1939 unsigned int __iomem *mem_ctrl_sleep;
2324 1940
2325 /* first map in the memory controller registers */ 1941 if (pb3400_mem_ctrl == NULL)
2326 mem_ctrl = ioremap(PB3400_MEM_CTRL, 0x100);
2327 if (mem_ctrl == NULL) {
2328 printk("powerbook_sleep_3400: ioremap failed\n");
2329 return -ENOMEM; 1942 return -ENOMEM;
2330 } 1943 mem_ctrl_sleep = pb3400_mem_ctrl + PB3400_MEM_CTRL_SLEEP;
2331 mem_ctrl_sleep = mem_ctrl + PB3400_MEM_CTRL_SLEEP;
2332
2333 /* Allocate room for PCI save */
2334 pbook_alloc_pci_save();
2335
2336 ret = pmac_suspend_devices();
2337 if (ret) {
2338 pbook_free_pci_save();
2339 iounmap(mem_ctrl);
2340 printk(KERN_ERR "Sleep rejected by devices\n");
2341 return ret;
2342 }
2343
2344 /* Save the state of PCI config space for some slots */
2345 pbook_pci_save();
2346 1944
2347 /* Set the memory controller to keep the memory refreshed 1945 /* Set the memory controller to keep the memory refreshed
2348 while we're asleep */ 1946 while we're asleep */
@@ -2357,41 +1955,34 @@ powerbook_sleep_3400(void)
2357 1955
2358 /* Ask the PMU to put us to sleep */ 1956 /* Ask the PMU to put us to sleep */
2359 pmu_request(&sleep_req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T'); 1957 pmu_request(&sleep_req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T');
2360 while (!sleep_req.complete) 1958 pmu_wait_complete(&sleep_req);
2361 mb(); 1959 pmu_unlock();
2362 1960
2363 pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,1); 1961 pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, 1);
2364 1962
2365 /* displacement-flush the L2 cache - necessary? */
2366 for (p = KERNELBASE; p < KERNELBASE + 0x100000; p += 0x1000)
2367 i = *(volatile int *)p;
2368 asleep = 1; 1963 asleep = 1;
2369 1964
2370 /* Put the CPU into sleep mode */ 1965 /* Put the CPU into sleep mode */
2371 hid0 = mfspr(SPRN_HID0); 1966 hid0 = mfspr(SPRN_HID0);
2372 hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP; 1967 hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP;
2373 mtspr(SPRN_HID0, hid0); 1968 mtspr(SPRN_HID0, hid0);
2374 mtmsr(mfmsr() | MSR_POW | MSR_EE); 1969 local_irq_enable();
2375 udelay(10); 1970 msr = mfmsr() | MSR_POW;
1971 while (asleep) {
1972 mb();
1973 mtmsr(msr);
1974 isync();
1975 }
1976 local_irq_disable();
2376 1977
2377 /* OK, we're awake again, start restoring things */ 1978 /* OK, we're awake again, start restoring things */
2378 out_be32(mem_ctrl_sleep, 0x3f); 1979 out_be32(mem_ctrl_sleep, 0x3f);
2379 pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,0); 1980 pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, 0);
2380 pbook_pci_restore();
2381 pmu_unlock();
2382
2383 /* wait for the PMU interrupt sequence to complete */
2384 while (asleep)
2385 mb();
2386
2387 pmac_wakeup_devices();
2388 pbook_free_pci_save();
2389 iounmap(mem_ctrl);
2390 1981
2391 return 0; 1982 return 0;
2392} 1983}
2393 1984
2394#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ 1985#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
2395 1986
2396/* 1987/*
2397 * Support for /dev/pmu device 1988 * Support for /dev/pmu device
@@ -2548,7 +2139,6 @@ pmu_release(struct inode *inode, struct file *file)
2548 struct pmu_private *pp = file->private_data; 2139 struct pmu_private *pp = file->private_data;
2549 unsigned long flags; 2140 unsigned long flags;
2550 2141
2551 lock_kernel();
2552 if (pp != 0) { 2142 if (pp != 0) {
2553 file->private_data = NULL; 2143 file->private_data = NULL;
2554 spin_lock_irqsave(&all_pvt_lock, flags); 2144 spin_lock_irqsave(&all_pvt_lock, flags);
@@ -2562,10 +2152,96 @@ pmu_release(struct inode *inode, struct file *file)
2562 2152
2563 kfree(pp); 2153 kfree(pp);
2564 } 2154 }
2565 unlock_kernel();
2566 return 0; 2155 return 0;
2567} 2156}
2568 2157
2158#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
2159static void pmac_suspend_disable_irqs(void)
2160{
2161 /* Call platform functions marked "on sleep" */
2162 pmac_pfunc_i2c_suspend();
2163 pmac_pfunc_base_suspend();
2164}
2165
2166static int powerbook_sleep(suspend_state_t state)
2167{
2168 int error = 0;
2169
2170 /* Wait for completion of async requests */
2171 while (!batt_req.complete)
2172 pmu_poll();
2173
2174 /* Giveup the lazy FPU & vec so we don't have to back them
2175 * up from the low level code
2176 */
2177 enable_kernel_fp();
2178
2179#ifdef CONFIG_ALTIVEC
2180 if (cpu_has_feature(CPU_FTR_ALTIVEC))
2181 enable_kernel_altivec();
2182#endif /* CONFIG_ALTIVEC */
2183
2184 switch (pmu_kind) {
2185 case PMU_OHARE_BASED:
2186 error = powerbook_sleep_3400();
2187 break;
2188 case PMU_HEATHROW_BASED:
2189 case PMU_PADDINGTON_BASED:
2190 error = powerbook_sleep_grackle();
2191 break;
2192 case PMU_KEYLARGO_BASED:
2193 error = powerbook_sleep_Core99();
2194 break;
2195 default:
2196 return -ENOSYS;
2197 }
2198
2199 if (error)
2200 return error;
2201
2202 mdelay(100);
2203
2204 return 0;
2205}
2206
2207static void pmac_suspend_enable_irqs(void)
2208{
2209 /* Force a poll of ADB interrupts */
2210 adb_int_pending = 1;
2211 via_pmu_interrupt(0, NULL);
2212
2213 mdelay(10);
2214
2215 /* Call platform functions marked "on wake" */
2216 pmac_pfunc_base_resume();
2217 pmac_pfunc_i2c_resume();
2218}
2219
2220static int pmu_sleep_valid(suspend_state_t state)
2221{
2222 return state == PM_SUSPEND_MEM
2223 && (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) >= 0);
2224}
2225
2226static struct platform_suspend_ops pmu_pm_ops = {
2227 .enter = powerbook_sleep,
2228 .valid = pmu_sleep_valid,
2229};
2230
2231static int register_pmu_pm_ops(void)
2232{
2233 if (pmu_kind == PMU_OHARE_BASED)
2234 powerbook_sleep_init_3400();
2235 ppc_md.suspend_disable_irqs = pmac_suspend_disable_irqs;
2236 ppc_md.suspend_enable_irqs = pmac_suspend_enable_irqs;
2237 suspend_set_ops(&pmu_pm_ops);
2238
2239 return 0;
2240}
2241
2242device_initcall(register_pmu_pm_ops);
2243#endif
2244
2569static int 2245static int
2570pmu_ioctl(struct inode * inode, struct file *filp, 2246pmu_ioctl(struct inode * inode, struct file *filp,
2571 u_int cmd, u_long arg) 2247 u_int cmd, u_long arg)
@@ -2574,35 +2250,15 @@ pmu_ioctl(struct inode * inode, struct file *filp,
2574 int error = -EINVAL; 2250 int error = -EINVAL;
2575 2251
2576 switch (cmd) { 2252 switch (cmd) {
2577#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32)
2578 case PMU_IOC_SLEEP: 2253 case PMU_IOC_SLEEP:
2579 if (!capable(CAP_SYS_ADMIN)) 2254 if (!capable(CAP_SYS_ADMIN))
2580 return -EACCES; 2255 return -EACCES;
2581 if (sleep_in_progress) 2256 return pm_suspend(PM_SUSPEND_MEM);
2582 return -EBUSY;
2583 sleep_in_progress = 1;
2584 switch (pmu_kind) {
2585 case PMU_OHARE_BASED:
2586 error = powerbook_sleep_3400();
2587 break;
2588 case PMU_HEATHROW_BASED:
2589 case PMU_PADDINGTON_BASED:
2590 error = powerbook_sleep_grackle();
2591 break;
2592 case PMU_KEYLARGO_BASED:
2593 error = powerbook_sleep_Core99();
2594 break;
2595 default:
2596 error = -ENOSYS;
2597 }
2598 sleep_in_progress = 0;
2599 break;
2600 case PMU_IOC_CAN_SLEEP: 2257 case PMU_IOC_CAN_SLEEP:
2601 if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) < 0) 2258 if (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) < 0)
2602 return put_user(0, argp); 2259 return put_user(0, argp);
2603 else 2260 else
2604 return put_user(1, argp); 2261 return put_user(1, argp);
2605#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */
2606 2262
2607#ifdef CONFIG_PMAC_BACKLIGHT_LEGACY 2263#ifdef CONFIG_PMAC_BACKLIGHT_LEGACY
2608 /* Compatibility ioctl's for backlight */ 2264 /* Compatibility ioctl's for backlight */
@@ -2610,9 +2266,6 @@ pmu_ioctl(struct inode * inode, struct file *filp,
2610 { 2266 {
2611 int brightness; 2267 int brightness;
2612 2268
2613 if (sleep_in_progress)
2614 return -EBUSY;
2615
2616 brightness = pmac_backlight_get_legacy_brightness(); 2269 brightness = pmac_backlight_get_legacy_brightness();
2617 if (brightness < 0) 2270 if (brightness < 0)
2618 return brightness; 2271 return brightness;
@@ -2624,9 +2277,6 @@ pmu_ioctl(struct inode * inode, struct file *filp,
2624 { 2277 {
2625 int brightness; 2278 int brightness;
2626 2279
2627 if (sleep_in_progress)
2628 return -EBUSY;
2629
2630 error = get_user(brightness, argp); 2280 error = get_user(brightness, argp);
2631 if (error) 2281 if (error)
2632 return error; 2282 return error;
@@ -2751,15 +2401,43 @@ pmu_polled_request(struct adb_request *req)
2751 local_irq_restore(flags); 2401 local_irq_restore(flags);
2752 return 0; 2402 return 0;
2753} 2403}
2754#endif /* DEBUG_SLEEP */
2755 2404
2405/* N.B. This doesn't work on the 3400 */
2406void pmu_blink(int n)
2407{
2408 struct adb_request req;
2756 2409
2757/* FIXME: This is a temporary set of callbacks to enable us 2410 memset(&req, 0, sizeof(req));
2758 * to do suspend-to-disk.
2759 */
2760 2411
2761#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) 2412 for (; n > 0; --n) {
2413 req.nbytes = 4;
2414 req.done = NULL;
2415 req.data[0] = 0xee;
2416 req.data[1] = 4;
2417 req.data[2] = 0;
2418 req.data[3] = 1;
2419 req.reply[0] = ADB_RET_OK;
2420 req.reply_len = 1;
2421 req.reply_expected = 0;
2422 pmu_polled_request(&req);
2423 mdelay(50);
2424 req.nbytes = 4;
2425 req.done = NULL;
2426 req.data[0] = 0xee;
2427 req.data[1] = 4;
2428 req.data[2] = 0;
2429 req.data[3] = 0;
2430 req.reply[0] = ADB_RET_OK;
2431 req.reply_len = 1;
2432 req.reply_expected = 0;
2433 pmu_polled_request(&req);
2434 mdelay(50);
2435 }
2436 mdelay(50);
2437}
2438#endif /* DEBUG_SLEEP */
2762 2439
2440#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
2763int pmu_sys_suspended; 2441int pmu_sys_suspended;
2764 2442
2765static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state) 2443static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state)
@@ -2767,10 +2445,15 @@ static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state)
2767 if (state.event != PM_EVENT_SUSPEND || pmu_sys_suspended) 2445 if (state.event != PM_EVENT_SUSPEND || pmu_sys_suspended)
2768 return 0; 2446 return 0;
2769 2447
2770 /* Suspend PMU event interrupts */ 2448 /* Suspend PMU event interrupts */\
2771 pmu_suspend(); 2449 pmu_suspend();
2772
2773 pmu_sys_suspended = 1; 2450 pmu_sys_suspended = 1;
2451
2452#ifdef CONFIG_PMAC_BACKLIGHT
2453 /* Tell backlight code not to muck around with the chip anymore */
2454 pmu_backlight_set_sleep(1);
2455#endif
2456
2774 return 0; 2457 return 0;
2775} 2458}
2776 2459
@@ -2785,15 +2468,18 @@ static int pmu_sys_resume(struct sys_device *sysdev)
2785 pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2); 2468 pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2);
2786 pmu_wait_complete(&req); 2469 pmu_wait_complete(&req);
2787 2470
2471#ifdef CONFIG_PMAC_BACKLIGHT
2472 /* Tell backlight code it can use the chip again */
2473 pmu_backlight_set_sleep(0);
2474#endif
2788 /* Resume PMU event interrupts */ 2475 /* Resume PMU event interrupts */
2789 pmu_resume(); 2476 pmu_resume();
2790
2791 pmu_sys_suspended = 0; 2477 pmu_sys_suspended = 0;
2792 2478
2793 return 0; 2479 return 0;
2794} 2480}
2795 2481
2796#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ 2482#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
2797 2483
2798static struct sysdev_class pmu_sysclass = { 2484static struct sysdev_class pmu_sysclass = {
2799 set_kset_name("pmu"), 2485 set_kset_name("pmu"),
@@ -2804,10 +2490,10 @@ static struct sys_device device_pmu = {
2804}; 2490};
2805 2491
2806static struct sysdev_driver driver_pmu = { 2492static struct sysdev_driver driver_pmu = {
2807#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) 2493#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
2808 .suspend = &pmu_sys_suspend, 2494 .suspend = &pmu_sys_suspend,
2809 .resume = &pmu_sys_resume, 2495 .resume = &pmu_sys_resume,
2810#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ 2496#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
2811}; 2497};
2812 2498
2813static int __init init_pmu_sysfs(void) 2499static int __init init_pmu_sysfs(void)
@@ -2842,10 +2528,10 @@ EXPORT_SYMBOL(pmu_wait_complete);
2842EXPORT_SYMBOL(pmu_suspend); 2528EXPORT_SYMBOL(pmu_suspend);
2843EXPORT_SYMBOL(pmu_resume); 2529EXPORT_SYMBOL(pmu_resume);
2844EXPORT_SYMBOL(pmu_unlock); 2530EXPORT_SYMBOL(pmu_unlock);
2845#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) 2531#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
2846EXPORT_SYMBOL(pmu_enable_irled); 2532EXPORT_SYMBOL(pmu_enable_irled);
2847EXPORT_SYMBOL(pmu_battery_count); 2533EXPORT_SYMBOL(pmu_battery_count);
2848EXPORT_SYMBOL(pmu_batteries); 2534EXPORT_SYMBOL(pmu_batteries);
2849EXPORT_SYMBOL(pmu_power_flags); 2535EXPORT_SYMBOL(pmu_power_flags);
2850#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ 2536#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
2851 2537
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index da4efbca646e..e36321152d50 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -81,16 +81,8 @@
81static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 op) 81static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 op)
82{ 82{
83 const struct fs_platform_info *fpi = fep->fpi; 83 const struct fs_platform_info *fpi = fep->fpi;
84 int i;
85
86 W32(cpmp, cp_cpcr, fpi->cp_command | op | CPM_CR_FLG);
87 for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
88 if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
89 return 0;
90 84
91 printk(KERN_ERR "%s(): Not able to issue CPM command\n", 85 return cpm_command(fpi->cp_command, op);
92 __FUNCTION__);
93 return 1;
94} 86}
95 87
96static int do_pd_setup(struct fs_enet_private *fep) 88static int do_pd_setup(struct fs_enet_private *fep)
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c
index 48f2f3005935..fe3d8a621c33 100644
--- a/drivers/net/fs_enet/mac-scc.c
+++ b/drivers/net/fs_enet/mac-scc.c
@@ -89,21 +89,12 @@
89 * Delay to wait for SCC reset command to complete (in us) 89 * Delay to wait for SCC reset command to complete (in us)
90 */ 90 */
91#define SCC_RESET_DELAY 50 91#define SCC_RESET_DELAY 50
92#define MAX_CR_CMD_LOOPS 10000
93 92
94static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op) 93static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op)
95{ 94{
96 const struct fs_platform_info *fpi = fep->fpi; 95 const struct fs_platform_info *fpi = fep->fpi;
97 int i;
98
99 W16(cpmp, cp_cpcr, fpi->cp_command | CPM_CR_FLG | (op << 8));
100 for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
101 if ((R16(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
102 return 0;
103 96
104 printk(KERN_ERR "%s(): Not able to issue CPM command\n", 97 return cpm_command(fpi->cp_command, op);
105 __FUNCTION__);
106 return 1;
107} 98}
108 99
109static int do_pd_setup(struct fs_enet_private *fep) 100static int do_pd_setup(struct fs_enet_private *fep)
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index abac7db3819e..8d456e379a86 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -3822,6 +3822,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
3822 int err, ucc_num, max_speed = 0; 3822 int err, ucc_num, max_speed = 0;
3823 const phandle *ph; 3823 const phandle *ph;
3824 const unsigned int *prop; 3824 const unsigned int *prop;
3825 const char *sprop;
3825 const void *mac_addr; 3826 const void *mac_addr;
3826 phy_interface_t phy_interface; 3827 phy_interface_t phy_interface;
3827 static const int enet_to_speed[] = { 3828 static const int enet_to_speed[] = {
@@ -3854,10 +3855,56 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
3854 3855
3855 ug_info->uf_info.ucc_num = ucc_num; 3856 ug_info->uf_info.ucc_num = ucc_num;
3856 3857
3857 prop = of_get_property(np, "rx-clock", NULL); 3858 sprop = of_get_property(np, "rx-clock-name", NULL);
3858 ug_info->uf_info.rx_clock = *prop; 3859 if (sprop) {
3859 prop = of_get_property(np, "tx-clock", NULL); 3860 ug_info->uf_info.rx_clock = qe_clock_source(sprop);
3860 ug_info->uf_info.tx_clock = *prop; 3861 if ((ug_info->uf_info.rx_clock < QE_CLK_NONE) ||
3862 (ug_info->uf_info.rx_clock > QE_CLK24)) {
3863 printk(KERN_ERR
3864 "ucc_geth: invalid rx-clock-name property\n");
3865 return -EINVAL;
3866 }
3867 } else {
3868 prop = of_get_property(np, "rx-clock", NULL);
3869 if (!prop) {
3870 /* If both rx-clock-name and rx-clock are missing,
3871 we want to tell people to use rx-clock-name. */
3872 printk(KERN_ERR
3873 "ucc_geth: missing rx-clock-name property\n");
3874 return -EINVAL;
3875 }
3876 if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) {
3877 printk(KERN_ERR
3878 "ucc_geth: invalid rx-clock propperty\n");
3879 return -EINVAL;
3880 }
3881 ug_info->uf_info.rx_clock = *prop;
3882 }
3883
3884 sprop = of_get_property(np, "tx-clock-name", NULL);
3885 if (sprop) {
3886 ug_info->uf_info.tx_clock = qe_clock_source(sprop);
3887 if ((ug_info->uf_info.tx_clock < QE_CLK_NONE) ||
3888 (ug_info->uf_info.tx_clock > QE_CLK24)) {
3889 printk(KERN_ERR
3890 "ucc_geth: invalid tx-clock-name property\n");
3891 return -EINVAL;
3892 }
3893 } else {
3894 prop = of_get_property(np, "rx-clock", NULL);
3895 if (!prop) {
3896 printk(KERN_ERR
3897 "ucc_geth: mising tx-clock-name property\n");
3898 return -EINVAL;
3899 }
3900 if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) {
3901 printk(KERN_ERR
3902 "ucc_geth: invalid tx-clock property\n");
3903 return -EINVAL;
3904 }
3905 ug_info->uf_info.tx_clock = *prop;
3906 }
3907
3861 err = of_address_to_resource(np, 0, &res); 3908 err = of_address_to_resource(np, 0, &res);
3862 if (err) 3909 if (err)
3863 return -EINVAL; 3910 return -EINVAL;
diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
index b169b0e2647f..191954bc8e5b 100644
--- a/drivers/pci/hotplug/rpadlpar_core.c
+++ b/drivers/pci/hotplug/rpadlpar_core.c
@@ -155,7 +155,7 @@ static void dlpar_pci_add_bus(struct device_node *dn)
155 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) 155 dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
156 of_scan_pci_bridge(dn, dev); 156 of_scan_pci_bridge(dn, dev);
157 157
158 pcibios_fixup_new_pci_devices(dev->subordinate,0); 158 pcibios_fixup_new_pci_devices(dev->subordinate);
159 159
160 /* Claim new bus resources */ 160 /* Claim new bus resources */
161 pcibios_claim_one_bus(dev->bus); 161 pcibios_claim_one_bus(dev->bus);
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index 52fb044bb79a..6ea0366e26ae 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -52,11 +52,7 @@
52#ifdef CONFIG_PPC_CPM_NEW_BINDING 52#ifdef CONFIG_PPC_CPM_NEW_BINDING
53void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) 53void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
54{ 54{
55 u16 __iomem *cpcr = &cpmp->cp_cpcr; 55 cpm_command(port->command, cmd);
56
57 out_be16(cpcr, port->command | (cmd << 8) | CPM_CR_FLG);
58 while (in_be16(cpcr) & CPM_CR_FLG)
59 ;
60} 56}
61#else 57#else
62void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) 58void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index 882dbc17d590..def01582de5c 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -52,13 +52,7 @@
52#ifdef CONFIG_PPC_CPM_NEW_BINDING 52#ifdef CONFIG_PPC_CPM_NEW_BINDING
53void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) 53void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
54{ 54{
55 cpm_cpm2_t __iomem *cp = cpm2_map(im_cpm); 55 cpm_command(port->command, cmd);
56
57 out_be32(&cp->cp_cpcr, port->command | cmd | CPM_CR_FLG);
58 while (in_be32(&cp->cp_cpcr) & CPM_CR_FLG)
59 ;
60
61 cpm2_unmap(cp);
62} 56}
63#else 57#else
64void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd) 58void cpm_line_cr_cmd(struct uart_cpm_port *port, int cmd)
diff --git a/include/asm-powerpc/8xx_immap.h b/include/asm-powerpc/8xx_immap.h
index 1311cefdfd30..4b0e15206006 100644
--- a/include/asm-powerpc/8xx_immap.h
+++ b/include/asm-powerpc/8xx_immap.h
@@ -123,7 +123,7 @@ typedef struct mem_ctlr {
123#define OR_G5LA 0x00000400 /* Output #GPL5 on #GPL_A5 */ 123#define OR_G5LA 0x00000400 /* Output #GPL5 on #GPL_A5 */
124#define OR_G5LS 0x00000200 /* Drive #GPL high on falling edge of...*/ 124#define OR_G5LS 0x00000200 /* Drive #GPL high on falling edge of...*/
125#define OR_BI 0x00000100 /* Burst inhibit */ 125#define OR_BI 0x00000100 /* Burst inhibit */
126#define OR_SCY_MSK 0x000000f0 /* Cycle Lenght in Clocks */ 126#define OR_SCY_MSK 0x000000f0 /* Cycle Length in Clocks */
127#define OR_SCY_0_CLK 0x00000000 /* 0 clock cycles wait states */ 127#define OR_SCY_0_CLK 0x00000000 /* 0 clock cycles wait states */
128#define OR_SCY_1_CLK 0x00000010 /* 1 clock cycles wait states */ 128#define OR_SCY_1_CLK 0x00000010 /* 1 clock cycles wait states */
129#define OR_SCY_2_CLK 0x00000020 /* 2 clock cycles wait states */ 129#define OR_SCY_2_CLK 0x00000020 /* 2 clock cycles wait states */
diff --git a/include/asm-powerpc/commproc.h b/include/asm-powerpc/commproc.h
index 2ee59d7b335c..9e3b8648648c 100644
--- a/include/asm-powerpc/commproc.h
+++ b/include/asm-powerpc/commproc.h
@@ -693,7 +693,7 @@ typedef struct risc_timer_pram {
693#define CICR_SCC_SCC3 ((uint)0x00200000) /* SCC3 @ SCCc */ 693#define CICR_SCC_SCC3 ((uint)0x00200000) /* SCC3 @ SCCc */
694#define CICR_SCB_SCC2 ((uint)0x00040000) /* SCC2 @ SCCb */ 694#define CICR_SCB_SCC2 ((uint)0x00040000) /* SCC2 @ SCCb */
695#define CICR_SCA_SCC1 ((uint)0x00000000) /* SCC1 @ SCCa */ 695#define CICR_SCA_SCC1 ((uint)0x00000000) /* SCC1 @ SCCa */
696#define CICR_IRL_MASK ((uint)0x0000e000) /* Core interrrupt */ 696#define CICR_IRL_MASK ((uint)0x0000e000) /* Core interrupt */
697#define CICR_HP_MASK ((uint)0x00001f00) /* Hi-pri int. */ 697#define CICR_HP_MASK ((uint)0x00001f00) /* Hi-pri int. */
698#define CICR_IEN ((uint)0x00000080) /* Int. enable */ 698#define CICR_IEN ((uint)0x00000080) /* Int. enable */
699#define CICR_SPS ((uint)0x00000001) /* SCC Spread */ 699#define CICR_SPS ((uint)0x00000001) /* SCC Spread */
diff --git a/include/asm-powerpc/cpm.h b/include/asm-powerpc/cpm.h
index 48df9f330e76..fae83b137337 100644
--- a/include/asm-powerpc/cpm.h
+++ b/include/asm-powerpc/cpm.h
@@ -10,5 +10,6 @@ int cpm_muram_free(unsigned long offset);
10unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size); 10unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size);
11void __iomem *cpm_muram_addr(unsigned long offset); 11void __iomem *cpm_muram_addr(unsigned long offset);
12dma_addr_t cpm_muram_dma(void __iomem *addr); 12dma_addr_t cpm_muram_dma(void __iomem *addr);
13int cpm_command(u32 command, u8 opcode);
13 14
14#endif 15#endif
diff --git a/include/asm-powerpc/cputhreads.h b/include/asm-powerpc/cputhreads.h
new file mode 100644
index 000000000000..8485c28b5f47
--- /dev/null
+++ b/include/asm-powerpc/cputhreads.h
@@ -0,0 +1,71 @@
1#ifndef _ASM_POWERPC_CPUTHREADS_H
2#define _ASM_POWERPC_CPUTHREADS_H
3
4#include <linux/cpumask.h>
5
6/*
7 * Mapping of threads to cores
8 */
9
10#ifdef CONFIG_SMP
11extern int threads_per_core;
12extern int threads_shift;
13extern cpumask_t threads_core_mask;
14#else
15#define threads_per_core 1
16#define threads_shift 0
17#define threads_core_mask (CPU_MASK_CPU0)
18#endif
19
20/* cpu_thread_mask_to_cores - Return a cpumask of one per cores
21 * hit by the argument
22 *
23 * @threads: a cpumask of threads
24 *
25 * This function returns a cpumask which will have one "cpu" (or thread)
26 * bit set for each core that has at least one thread set in the argument.
27 *
28 * This can typically be used for things like IPI for tlb invalidations
29 * since those need to be done only once per core/TLB
30 */
31static inline cpumask_t cpu_thread_mask_to_cores(cpumask_t threads)
32{
33 cpumask_t tmp, res;
34 int i;
35
36 res = CPU_MASK_NONE;
37 for (i = 0; i < NR_CPUS; i += threads_per_core) {
38 cpus_shift_right(tmp, threads_core_mask, i);
39 if (cpus_intersects(threads, tmp))
40 cpu_set(i, res);
41 }
42 return res;
43}
44
45static inline int cpu_nr_cores(void)
46{
47 return NR_CPUS >> threads_shift;
48}
49
50static inline cpumask_t cpu_online_cores_map(void)
51{
52 return cpu_thread_mask_to_cores(cpu_online_map);
53}
54
55static inline int cpu_thread_to_core(int cpu)
56{
57 return cpu >> threads_shift;
58}
59
60static inline int cpu_thread_in_core(int cpu)
61{
62 return cpu & (threads_per_core - 1);
63}
64
65static inline int cpu_first_thread_in_core(int cpu)
66{
67 return cpu & ~(threads_per_core - 1);
68}
69
70#endif /* _ASM_POWERPC_CPUTHREADS_H */
71
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index ff52013c0e2d..e974876e18d2 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -87,6 +87,9 @@ static inline int dma_supported(struct device *dev, u64 mask)
87 return dma_ops->dma_supported(dev, mask); 87 return dma_ops->dma_supported(dev, mask);
88} 88}
89 89
90/* We have our own implementation of pci_set_dma_mask() */
91#define HAVE_ARCH_PCI_SET_DMA_MASK
92
90static inline int dma_set_mask(struct device *dev, u64 dma_mask) 93static inline int dma_set_mask(struct device *dev, u64 dma_mask)
91{ 94{
92 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 95 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
diff --git a/include/asm-powerpc/firmware.h b/include/asm-powerpc/firmware.h
index 3671c128f271..1e41bd1c8502 100644
--- a/include/asm-powerpc/firmware.h
+++ b/include/asm-powerpc/firmware.h
@@ -64,7 +64,7 @@ enum {
64 FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, 64 FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
65 FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1, 65 FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
66 FW_FEATURE_CELLEB_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_BEAT, 66 FW_FEATURE_CELLEB_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_BEAT,
67 FW_FEATURE_CELLEB_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_BEAT, 67 FW_FEATURE_CELLEB_ALWAYS = 0,
68 FW_FEATURE_NATIVE_POSSIBLE = 0, 68 FW_FEATURE_NATIVE_POSSIBLE = 0,
69 FW_FEATURE_NATIVE_ALWAYS = 0, 69 FW_FEATURE_NATIVE_ALWAYS = 0,
70 FW_FEATURE_POSSIBLE = 70 FW_FEATURE_POSSIBLE =
diff --git a/include/asm-powerpc/immap_86xx.h b/include/asm-powerpc/immap_86xx.h
index 0ad4e653d464..0f165e59c326 100644
--- a/include/asm-powerpc/immap_86xx.h
+++ b/include/asm-powerpc/immap_86xx.h
@@ -89,14 +89,14 @@ struct ccsr_guts {
89 * them. 89 * them.
90 * 90 *
91 * guts: Pointer to GUTS structure 91 * guts: Pointer to GUTS structure
92 * co: The DMA controller (1 or 2) 92 * co: The DMA controller (0 or 1)
93 * ch: The channel on the DMA controller (0, 1, 2, or 3) 93 * ch: The channel on the DMA controller (0, 1, 2, or 3)
94 * device: The device to set as the source (CCSR_GUTS_DMACR_DEV_xx) 94 * device: The device to set as the source (CCSR_GUTS_DMACR_DEV_xx)
95 */ 95 */
96static inline void guts_set_dmacr(struct ccsr_guts __iomem *guts, 96static inline void guts_set_dmacr(struct ccsr_guts __iomem *guts,
97 unsigned int co, unsigned int ch, unsigned int device) 97 unsigned int co, unsigned int ch, unsigned int device)
98{ 98{
99 unsigned int shift = 16 + (8 * (2 - co) + 2 * (3 - ch)); 99 unsigned int shift = 16 + (8 * (1 - co) + 2 * (3 - ch));
100 100
101 clrsetbits_be32(&guts->dmacr, 3 << shift, device << shift); 101 clrsetbits_be32(&guts->dmacr, 3 << shift, device << shift);
102} 102}
@@ -118,6 +118,27 @@ static inline void guts_set_dmacr(struct ccsr_guts __iomem *guts,
118#define CCSR_GUTS_PMUXCR_DMA1_0 0x00000002 118#define CCSR_GUTS_PMUXCR_DMA1_0 0x00000002
119#define CCSR_GUTS_PMUXCR_DMA1_3 0x00000001 119#define CCSR_GUTS_PMUXCR_DMA1_3 0x00000001
120 120
121/*
122 * Set the DMA external control bits in the GUTS
123 *
124 * The DMA external control bits in the PMUXCR are only meaningful for
125 * channels 0 and 3. Any other channels are ignored.
126 *
127 * guts: Pointer to GUTS structure
128 * co: The DMA controller (0 or 1)
129 * ch: The channel on the DMA controller (0, 1, 2, or 3)
130 * value: the new value for the bit (0 or 1)
131 */
132static inline void guts_set_pmuxcr_dma(struct ccsr_guts __iomem *guts,
133 unsigned int co, unsigned int ch, unsigned int value)
134{
135 if ((ch == 0) || (ch == 3)) {
136 unsigned int shift = 2 * (co + 1) - (ch & 1) - 1;
137
138 clrsetbits_be32(&guts->pmuxcr, 1 << shift, value << shift);
139 }
140}
141
121#define CCSR_GUTS_CLKDVDR_PXCKEN 0x80000000 142#define CCSR_GUTS_CLKDVDR_PXCKEN 0x80000000
122#define CCSR_GUTS_CLKDVDR_SSICKEN 0x20000000 143#define CCSR_GUTS_CLKDVDR_SSICKEN 0x20000000
123#define CCSR_GUTS_CLKDVDR_PXCKINV 0x10000000 144#define CCSR_GUTS_CLKDVDR_PXCKINV 0x10000000
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index e44cdfc8493a..7be26f615755 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -50,15 +50,16 @@ extern int check_legacy_ioport(unsigned long base_port);
50#define PCI_DRAM_OFFSET pci_dram_offset 50#define PCI_DRAM_OFFSET pci_dram_offset
51#else 51#else
52#define _IO_BASE pci_io_base 52#define _IO_BASE pci_io_base
53#define _ISA_MEM_BASE 0 53#define _ISA_MEM_BASE isa_mem_base
54#define PCI_DRAM_OFFSET 0 54#define PCI_DRAM_OFFSET 0
55#endif 55#endif
56 56
57extern unsigned long isa_io_base; 57extern unsigned long isa_io_base;
58extern unsigned long isa_mem_base;
59extern unsigned long pci_io_base; 58extern unsigned long pci_io_base;
60extern unsigned long pci_dram_offset; 59extern unsigned long pci_dram_offset;
61 60
61extern resource_size_t isa_mem_base;
62
62#if defined(CONFIG_PPC32) && defined(CONFIG_PPC_INDIRECT_IO) 63#if defined(CONFIG_PPC32) && defined(CONFIG_PPC_INDIRECT_IO)
63#error CONFIG_PPC_INDIRECT_IO is not yet supported on 32 bits 64#error CONFIG_PPC_INDIRECT_IO is not yet supported on 32 bits
64#endif 65#endif
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
index 4a82fdccee92..7a3cef785abd 100644
--- a/include/asm-powerpc/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -69,10 +69,9 @@ struct iommu_table {
69}; 69};
70 70
71struct scatterlist; 71struct scatterlist;
72struct device_node;
73 72
74/* Frees table for an individual device node */ 73/* Frees table for an individual device node */
75extern void iommu_free_table(struct device_node *dn); 74extern void iommu_free_table(struct iommu_table *tbl, const char *node_name);
76 75
77/* Initializes an iommu_table based in values set in the passed-in 76/* Initializes an iommu_table based in values set in the passed-in
78 * structure 77 * structure
diff --git a/include/asm-powerpc/ipic.h b/include/asm-powerpc/ipic.h
index edec79dcb7c1..8ff08be00146 100644
--- a/include/asm-powerpc/ipic.h
+++ b/include/asm-powerpc/ipic.h
@@ -20,11 +20,13 @@
20 20
21/* Flags when we init the IPIC */ 21/* Flags when we init the IPIC */
22#define IPIC_SPREADMODE_GRP_A 0x00000001 22#define IPIC_SPREADMODE_GRP_A 0x00000001
23#define IPIC_SPREADMODE_GRP_D 0x00000002 23#define IPIC_SPREADMODE_GRP_B 0x00000002
24#define IPIC_SPREADMODE_MIX_A 0x00000004 24#define IPIC_SPREADMODE_GRP_C 0x00000004
25#define IPIC_SPREADMODE_MIX_B 0x00000008 25#define IPIC_SPREADMODE_GRP_D 0x00000008
26#define IPIC_DISABLE_MCP_OUT 0x00000010 26#define IPIC_SPREADMODE_MIX_A 0x00000010
27#define IPIC_IRQ0_MCP 0x00000020 27#define IPIC_SPREADMODE_MIX_B 0x00000020
28#define IPIC_DISABLE_MCP_OUT 0x00000040
29#define IPIC_IRQ0_MCP 0x00000080
28 30
29/* IPIC registers offsets */ 31/* IPIC registers offsets */
30#define IPIC_SICFR 0x00 /* System Global Interrupt Configuration Register */ 32#define IPIC_SICFR 0x00 /* System Global Interrupt Configuration Register */
diff --git a/include/asm-powerpc/iseries/hv_lp_event.h b/include/asm-powerpc/iseries/hv_lp_event.h
index 6ce2ce1e2690..8f5da7d77202 100644
--- a/include/asm-powerpc/iseries/hv_lp_event.h
+++ b/include/asm-powerpc/iseries/hv_lp_event.h
@@ -78,7 +78,7 @@ extern int HvLpEvent_openPath(HvLpEvent_Type eventType, HvLpIndex lpIndex);
78 78
79/* 79/*
80 * Close an Lp Event Path for a type and partition 80 * Close an Lp Event Path for a type and partition
81 * returns 0 on sucess 81 * returns 0 on success
82 */ 82 */
83extern int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex); 83extern int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex);
84 84
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index 6968f4300dca..0872ec228c1e 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -204,6 +204,13 @@ struct machdep_calls {
204 /* 204 /*
205 * optional PCI "hooks" 205 * optional PCI "hooks"
206 */ 206 */
207 /* Called in indirect_* to avoid touching devices */
208 int (*pci_exclude_device)(struct pci_controller *, unsigned char, unsigned char);
209
210 /* Called at then very end of pcibios_init() */
211 void (*pcibios_after_init)(void);
212
213#endif /* CONFIG_PPC32 */
207 214
208 /* Called after PPC generic resource fixup to perform 215 /* Called after PPC generic resource fixup to perform
209 machine specific fixups */ 216 machine specific fixups */
@@ -212,18 +219,9 @@ struct machdep_calls {
212 /* Called for each PCI bus in the system when it's probed */ 219 /* Called for each PCI bus in the system when it's probed */
213 void (*pcibios_fixup_bus)(struct pci_bus *); 220 void (*pcibios_fixup_bus)(struct pci_bus *);
214 221
215 /* Called when pci_enable_device() is called (initial=0) or 222 /* Called when pci_enable_device() is called. Returns 0 to
216 * when a device with no assigned resource is found (initial=1). 223 * allow assignment/enabling of the device. */
217 * Returns 0 to allow assignment/enabling of the device. */ 224 int (*pcibios_enable_device_hook)(struct pci_dev *);
218 int (*pcibios_enable_device_hook)(struct pci_dev *, int initial);
219
220 /* Called in indirect_* to avoid touching devices */
221 int (*pci_exclude_device)(struct pci_controller *, unsigned char, unsigned char);
222
223 /* Called at then very end of pcibios_init() */
224 void (*pcibios_after_init)(void);
225
226#endif /* CONFIG_PPC32 */
227 225
228 /* Called to shutdown machine specific hardware not already controlled 226 /* Called to shutdown machine specific hardware not already controlled
229 * by other drivers. 227 * by other drivers.
@@ -253,6 +251,16 @@ struct machdep_calls {
253 */ 251 */
254 void (*machine_kexec)(struct kimage *image); 252 void (*machine_kexec)(struct kimage *image);
255#endif /* CONFIG_KEXEC */ 253#endif /* CONFIG_KEXEC */
254
255#ifdef CONFIG_SUSPEND
256 /* These are called to disable and enable, respectively, IRQs when
257 * entering a suspend state. If NULL, then the generic versions
258 * will be called. The generic versions disable/enable the
259 * decrementer along with interrupts.
260 */
261 void (*suspend_disable_irqs)(void);
262 void (*suspend_enable_irqs)(void);
263#endif
256}; 264};
257 265
258extern void power4_idle(void); 266extern void power4_idle(void);
@@ -326,5 +334,31 @@ static inline void log_error(char *buf, unsigned int err_type, int fatal)
326 ppc_md.log_error(buf, err_type, fatal); 334 ppc_md.log_error(buf, err_type, fatal);
327} 335}
328 336
337#define __define_machine_initcall(mach,level,fn,id) \
338 static int __init __machine_initcall_##mach##_##fn(void) { \
339 if (machine_is(mach)) return fn(); \
340 return 0; \
341 } \
342 __define_initcall(level,__machine_initcall_##mach##_##fn,id);
343
344#define machine_core_initcall(mach,fn) __define_machine_initcall(mach,"1",fn,1)
345#define machine_core_initcall_sync(mach,fn) __define_machine_initcall(mach,"1s",fn,1s)
346#define machine_postcore_initcall(mach,fn) __define_machine_initcall(mach,"2",fn,2)
347#define machine_postcore_initcall_sync(mach,fn) __define_machine_initcall(mach,"2s",fn,2s)
348#define machine_arch_initcall(mach,fn) __define_machine_initcall(mach,"3",fn,3)
349#define machine_arch_initcall_sync(mach,fn) __define_machine_initcall(mach,"3s",fn,3s)
350#define machine_subsys_initcall(mach,fn) __define_machine_initcall(mach,"4",fn,4)
351#define machine_subsys_initcall_sync(mach,fn) __define_machine_initcall(mach,"4s",fn,4s)
352#define machine_fs_initcall(mach,fn) __define_machine_initcall(mach,"5",fn,5)
353#define machine_fs_initcall_sync(mach,fn) __define_machine_initcall(mach,"5s",fn,5s)
354#define machine_rootfs_initcall(mach,fn) __define_machine_initcall(mach,"rootfs",fn,rootfs)
355#define machine_device_initcall(mach,fn) __define_machine_initcall(mach,"6",fn,6)
356#define machine_device_initcall_sync(mach,fn) __define_machine_initcall(mach,"6s",fn,6s)
357#define machine_late_initcall(mach,fn) __define_machine_initcall(mach,"7",fn,7)
358#define machine_late_initcall_sync(mach,fn) __define_machine_initcall(mach,"7s",fn,7s)
359
360void generic_suspend_disable_irqs(void);
361void generic_suspend_enable_irqs(void);
362
329#endif /* __KERNEL__ */ 363#endif /* __KERNEL__ */
330#endif /* _ASM_POWERPC_MACHDEP_H */ 364#endif /* _ASM_POWERPC_MACHDEP_H */
diff --git a/include/asm-powerpc/mmu-hash64.h b/include/asm-powerpc/mmu-hash64.h
index 82328dec2b52..12e5e773c67e 100644
--- a/include/asm-powerpc/mmu-hash64.h
+++ b/include/asm-powerpc/mmu-hash64.h
@@ -180,6 +180,7 @@ extern int mmu_vmalloc_psize;
180extern int mmu_io_psize; 180extern int mmu_io_psize;
181extern int mmu_kernel_ssize; 181extern int mmu_kernel_ssize;
182extern int mmu_highuser_ssize; 182extern int mmu_highuser_ssize;
183extern u16 mmu_slb_size;
183 184
184/* 185/*
185 * If the processor supports 64k normal pages but not 64k cache 186 * If the processor supports 64k normal pages but not 64k cache
diff --git a/include/asm-powerpc/nvram.h b/include/asm-powerpc/nvram.h
index 9877982508bf..4e7059cc6113 100644
--- a/include/asm-powerpc/nvram.h
+++ b/include/asm-powerpc/nvram.h
@@ -10,6 +10,8 @@
10#ifndef _ASM_POWERPC_NVRAM_H 10#ifndef _ASM_POWERPC_NVRAM_H
11#define _ASM_POWERPC_NVRAM_H 11#define _ASM_POWERPC_NVRAM_H
12 12
13#include <linux/errno.h>
14
13#define NVRW_CNT 0x20 15#define NVRW_CNT 0x20
14#define NVRAM_HEADER_LEN 16 /* sizeof(struct nvram_header) */ 16#define NVRAM_HEADER_LEN 16 /* sizeof(struct nvram_header) */
15#define NVRAM_BLOCK_LEN 16 17#define NVRAM_BLOCK_LEN 16
@@ -71,7 +73,16 @@ extern int nvram_clear_error_log(void);
71extern struct nvram_partition *nvram_find_partition(int sig, const char *name); 73extern struct nvram_partition *nvram_find_partition(int sig, const char *name);
72 74
73extern int pSeries_nvram_init(void); 75extern int pSeries_nvram_init(void);
76
77#ifdef CONFIG_MMIO_NVRAM
74extern int mmio_nvram_init(void); 78extern int mmio_nvram_init(void);
79#else
80static inline int mmio_nvram_init(void)
81{
82 return -ENODEV;
83}
84#endif
85
75#endif /* __KERNEL__ */ 86#endif /* __KERNEL__ */
76 87
77/* PowerMac specific nvram stuffs */ 88/* PowerMac specific nvram stuffs */
diff --git a/include/asm-powerpc/of_platform.h b/include/asm-powerpc/of_platform.h
index 80e6fad28b4f..1bce5efe1de0 100644
--- a/include/asm-powerpc/of_platform.h
+++ b/include/asm-powerpc/of_platform.h
@@ -15,8 +15,14 @@
15#include <linux/of_platform.h> 15#include <linux/of_platform.h>
16 16
17/* Platform drivers register/unregister */ 17/* Platform drivers register/unregister */
18extern int of_register_platform_driver(struct of_platform_driver *drv); 18static inline int of_register_platform_driver(struct of_platform_driver *drv)
19extern void of_unregister_platform_driver(struct of_platform_driver *drv); 19{
20 return of_register_driver(drv, &of_platform_bus_type);
21}
22static inline void of_unregister_platform_driver(struct of_platform_driver *drv)
23{
24 of_unregister_driver(drv);
25}
20 26
21/* Platform devices and busses creation */ 27/* Platform devices and busses creation */
22extern struct of_device *of_platform_device_create(struct device_node *np, 28extern struct of_device *of_platform_device_create(struct device_node *np,
@@ -26,7 +32,7 @@ extern struct of_device *of_platform_device_create(struct device_node *np,
26#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1) 32#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
27 33
28extern int of_platform_bus_probe(struct device_node *root, 34extern int of_platform_bus_probe(struct device_node *root,
29 struct of_device_id *matches, 35 const struct of_device_id *matches,
30 struct device *parent); 36 struct device *parent);
31 37
32extern struct of_device *of_find_device_by_phandle(phandle ph); 38extern struct of_device *of_find_device_by_phandle(phandle ph);
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index d8bdc79db12e..9b16d3b17169 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -1,15 +1,42 @@
1#ifndef _ASM_POWERPC_PCI_BRIDGE_H 1#ifndef _ASM_POWERPC_PCI_BRIDGE_H
2#define _ASM_POWERPC_PCI_BRIDGE_H 2#define _ASM_POWERPC_PCI_BRIDGE_H
3#ifdef __KERNEL__ 3#ifdef __KERNEL__
4 4/*
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 */
5#include <linux/pci.h> 10#include <linux/pci.h>
6#include <linux/list.h> 11#include <linux/list.h>
7#include <linux/ioport.h> 12#include <linux/ioport.h>
8 13
9#ifndef CONFIG_PPC64
10
11struct device_node; 14struct device_node;
12struct pci_controller; 15
16extern unsigned int ppc_pci_flags;
17enum {
18 /* Force re-assigning all resources (ignore firmware
19 * setup completely)
20 */
21 PPC_PCI_REASSIGN_ALL_RSRC = 0x00000001,
22
23 /* Re-assign all bus numbers */
24 PPC_PCI_REASSIGN_ALL_BUS = 0x00000002,
25
26 /* Do not try to assign, just use existing setup */
27 PPC_PCI_PROBE_ONLY = 0x00000004,
28
29 /* Don't bother with ISA alignment unless the bridge has
30 * ISA forwarding enabled
31 */
32 PPC_PCI_CAN_SKIP_ISA_ALIGN = 0x00000008,
33
34 /* Enable domain numbers in /proc */
35 PPC_PCI_ENABLE_PROC_DOMAINS = 0x00000010,
36 /* ... except for domain 0 */
37 PPC_PCI_COMPAT_DOMAIN_0 = 0x00000020,
38};
39
13 40
14/* 41/*
15 * Structure of a PCI controller (host bridge) 42 * Structure of a PCI controller (host bridge)
@@ -17,26 +44,41 @@ struct pci_controller;
17struct pci_controller { 44struct pci_controller {
18 struct pci_bus *bus; 45 struct pci_bus *bus;
19 char is_dynamic; 46 char is_dynamic;
20 void *arch_data; 47#ifdef CONFIG_PPC64
48 int node;
49#endif
50 struct device_node *dn;
21 struct list_head list_node; 51 struct list_head list_node;
22 struct device *parent; 52 struct device *parent;
23 53
24 int first_busno; 54 int first_busno;
25 int last_busno; 55 int last_busno;
56#ifndef CONFIG_PPC64
26 int self_busno; 57 int self_busno;
58#endif
27 59
28 void __iomem *io_base_virt; 60 void __iomem *io_base_virt;
61#ifdef CONFIG_PPC64
62 void *io_base_alloc;
63#endif
29 resource_size_t io_base_phys; 64 resource_size_t io_base_phys;
65#ifndef CONFIG_PPC64
66 resource_size_t pci_io_size;
67#endif
30 68
31 /* Some machines (PReP) have a non 1:1 mapping of 69 /* Some machines (PReP) have a non 1:1 mapping of
32 * the PCI memory space in the CPU bus space 70 * the PCI memory space in the CPU bus space
33 */ 71 */
34 resource_size_t pci_mem_offset; 72 resource_size_t pci_mem_offset;
73#ifdef CONFIG_PPC64
74 unsigned long pci_io_size;
75#endif
35 76
36 struct pci_ops *ops; 77 struct pci_ops *ops;
37 volatile unsigned int __iomem *cfg_addr; 78 unsigned int __iomem *cfg_addr;
38 volatile void __iomem *cfg_data; 79 void __iomem *cfg_data;
39 80
81#ifndef CONFIG_PPC64
40 /* 82 /*
41 * Used for variants of PCI indirect handling and possible quirks: 83 * Used for variants of PCI indirect handling and possible quirks:
42 * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1 84 * SET_CFG_TYPE - used on 4xx or any PHB that does explicit type0/1
@@ -51,21 +93,30 @@ struct pci_controller {
51 * set. 93 * set.
52 * BIG_ENDIAN - cfg_addr is a big endian register 94 * BIG_ENDIAN - cfg_addr is a big endian register
53 */ 95 */
54#define PPC_INDIRECT_TYPE_SET_CFG_TYPE (0x00000001) 96#define PPC_INDIRECT_TYPE_SET_CFG_TYPE 0x00000001
55#define PPC_INDIRECT_TYPE_EXT_REG (0x00000002) 97#define PPC_INDIRECT_TYPE_EXT_REG 0x00000002
56#define PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS (0x00000004) 98#define PPC_INDIRECT_TYPE_SURPRESS_PRIMARY_BUS 0x00000004
57#define PPC_INDIRECT_TYPE_NO_PCIE_LINK (0x00000008) 99#define PPC_INDIRECT_TYPE_NO_PCIE_LINK 0x00000008
58#define PPC_INDIRECT_TYPE_BIG_ENDIAN (0x00000010) 100#define PPC_INDIRECT_TYPE_BIG_ENDIAN 0x00000010
59 u32 indirect_type; 101 u32 indirect_type;
60 102#endif /* !CONFIG_PPC64 */
61 /* Currently, we limit ourselves to 1 IO range and 3 mem 103 /* Currently, we limit ourselves to 1 IO range and 3 mem
62 * ranges since the common pci_bus structure can't handle more 104 * ranges since the common pci_bus structure can't handle more
63 */ 105 */
64 struct resource io_resource; 106 struct resource io_resource;
65 struct resource mem_resources[3]; 107 struct resource mem_resources[3];
66 int global_number; /* PCI domain number */ 108 int global_number; /* PCI domain number */
109#ifdef CONFIG_PPC64
110 unsigned long buid;
111 unsigned long dma_window_base_cur;
112 unsigned long dma_window_size;
113
114 void *private_data;
115#endif /* CONFIG_PPC64 */
67}; 116};
68 117
118#ifndef CONFIG_PPC64
119
69static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus) 120static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
70{ 121{
71 return bus->sysdata; 122 return bus->sysdata;
@@ -81,18 +132,18 @@ static inline int isa_vaddr_is_ioport(void __iomem *address)
81 132
82/* These are used for config access before all the PCI probing 133/* These are used for config access before all the PCI probing
83 has been done. */ 134 has been done. */
84int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn, 135extern int early_read_config_byte(struct pci_controller *hose, int bus,
85 int where, u8 *val); 136 int dev_fn, int where, u8 *val);
86int early_read_config_word(struct pci_controller *hose, int bus, int dev_fn, 137extern int early_read_config_word(struct pci_controller *hose, int bus,
87 int where, u16 *val); 138 int dev_fn, int where, u16 *val);
88int early_read_config_dword(struct pci_controller *hose, int bus, int dev_fn, 139extern int early_read_config_dword(struct pci_controller *hose, int bus,
89 int where, u32 *val); 140 int dev_fn, int where, u32 *val);
90int early_write_config_byte(struct pci_controller *hose, int bus, int dev_fn, 141extern int early_write_config_byte(struct pci_controller *hose, int bus,
91 int where, u8 val); 142 int dev_fn, int where, u8 val);
92int early_write_config_word(struct pci_controller *hose, int bus, int dev_fn, 143extern int early_write_config_word(struct pci_controller *hose, int bus,
93 int where, u16 val); 144 int dev_fn, int where, u16 val);
94int early_write_config_dword(struct pci_controller *hose, int bus, int dev_fn, 145extern int early_write_config_dword(struct pci_controller *hose, int bus,
95 int where, u32 val); 146 int dev_fn, int where, u32 val);
96 147
97extern int early_find_capability(struct pci_controller *hose, int bus, 148extern int early_find_capability(struct pci_controller *hose, int bus,
98 int dev_fn, int cap); 149 int dev_fn, int cap);
@@ -104,62 +155,12 @@ extern void setup_grackle(struct pci_controller *hose);
104extern void __init update_bridge_resource(struct pci_dev *dev, 155extern void __init update_bridge_resource(struct pci_dev *dev,
105 struct resource *res); 156 struct resource *res);
106 157
107#else 158#else /* CONFIG_PPC64 */
108
109
110/*
111 * This program is free software; you can redistribute it and/or
112 * modify it under the terms of the GNU General Public License
113 * as published by the Free Software Foundation; either version
114 * 2 of the License, or (at your option) any later version.
115 */
116
117/*
118 * Structure of a PCI controller (host bridge)
119 */
120struct pci_controller {
121 struct pci_bus *bus;
122 char is_dynamic;
123 int node;
124 void *arch_data;
125 struct list_head list_node;
126 struct device *parent;
127
128 int first_busno;
129 int last_busno;
130
131 void __iomem *io_base_virt;
132 void *io_base_alloc;
133 resource_size_t io_base_phys;
134
135 /* Some machines have a non 1:1 mapping of
136 * the PCI memory space in the CPU bus space
137 */
138 resource_size_t pci_mem_offset;
139 unsigned long pci_io_size;
140
141 struct pci_ops *ops;
142 volatile unsigned int __iomem *cfg_addr;
143 volatile void __iomem *cfg_data;
144
145 /* Currently, we limit ourselves to 1 IO range and 3 mem
146 * ranges since the common pci_bus structure can't handle more
147 */
148 struct resource io_resource;
149 struct resource mem_resources[3];
150 int global_number;
151 unsigned long buid;
152 unsigned long dma_window_base_cur;
153 unsigned long dma_window_size;
154
155 void *private_data;
156};
157 159
158/* 160/*
159 * PCI stuff, for nodes representing PCI devices, pointed to 161 * PCI stuff, for nodes representing PCI devices, pointed to
160 * by device_node->data. 162 * by device_node->data.
161 */ 163 */
162struct pci_controller;
163struct iommu_table; 164struct iommu_table;
164 165
165struct pci_dn { 166struct pci_dn {
@@ -179,9 +180,9 @@ struct pci_dn {
179 int eeh_mode; /* See eeh.h for possible EEH_MODEs */ 180 int eeh_mode; /* See eeh.h for possible EEH_MODEs */
180 int eeh_config_addr; 181 int eeh_config_addr;
181 int eeh_pe_config_addr; /* new-style partition endpoint address */ 182 int eeh_pe_config_addr; /* new-style partition endpoint address */
182 int eeh_check_count; /* # times driver ignored error */ 183 int eeh_check_count; /* # times driver ignored error */
183 int eeh_freeze_count; /* # times this device froze up. */ 184 int eeh_freeze_count; /* # times this device froze up. */
184 int eeh_false_positives; /* # times this device reported #ff's */ 185 int eeh_false_positives; /* # times this device reported #ff's */
185 u32 config_space[16]; /* saved PCI config space */ 186 u32 config_space[16]; /* saved PCI config space */
186#endif 187#endif
187}; 188};
@@ -189,7 +190,7 @@ struct pci_dn {
189/* Get the pointer to a device_node's pci_dn */ 190/* Get the pointer to a device_node's pci_dn */
190#define PCI_DN(dn) ((struct pci_dn *) (dn)->data) 191#define PCI_DN(dn) ((struct pci_dn *) (dn)->data)
191 192
192struct device_node *fetch_dev_dn(struct pci_dev *dev); 193extern struct device_node *fetch_dev_dn(struct pci_dev *dev);
193 194
194/* Get a device_node from a pci_dev. This code must be fast except 195/* Get a device_node from a pci_dev. This code must be fast except
195 * in the case where the sysdata is incorrect and needs to be fixed 196 * in the case where the sysdata is incorrect and needs to be fixed
@@ -227,14 +228,14 @@ static inline struct device_node *pci_bus_to_OF_node(struct pci_bus *bus)
227} 228}
228 229
229/** Find the bus corresponding to the indicated device node */ 230/** Find the bus corresponding to the indicated device node */
230struct pci_bus * pcibios_find_pci_bus(struct device_node *dn); 231extern struct pci_bus *pcibios_find_pci_bus(struct device_node *dn);
231 232
232/** Remove all of the PCI devices under this bus */ 233/** Remove all of the PCI devices under this bus */
233void pcibios_remove_pci_devices(struct pci_bus *bus); 234extern void pcibios_remove_pci_devices(struct pci_bus *bus);
234 235
235/** Discover new pci devices under this bus, and add them */ 236/** Discover new pci devices under this bus, and add them */
236void pcibios_add_pci_devices(struct pci_bus * bus); 237extern void pcibios_add_pci_devices(struct pci_bus *bus);
237void pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus); 238extern void pcibios_fixup_new_pci_devices(struct pci_bus *bus);
238 239
239extern int pcibios_remove_root_bus(struct pci_controller *phb); 240extern int pcibios_remove_root_bus(struct pci_controller *phb);
240 241
@@ -270,20 +271,18 @@ extern int pcibios_map_io_space(struct pci_bus *bus);
270#define PHB_SET_NODE(PHB, NODE) ((PHB)->node = -1) 271#define PHB_SET_NODE(PHB, NODE) ((PHB)->node = -1)
271#endif 272#endif
272 273
273#endif /* CONFIG_PPC64 */ 274#endif /* CONFIG_PPC64 */
274 275
275/* Get the PCI host controller for an OF device */ 276/* Get the PCI host controller for an OF device */
276extern struct pci_controller* 277extern struct pci_controller *pci_find_hose_for_OF_device(
277pci_find_hose_for_OF_device(struct device_node* node); 278 struct device_node* node);
278 279
279/* Fill up host controller resources from the OF node */ 280/* Fill up host controller resources from the OF node */
280extern void 281extern void pci_process_bridge_OF_ranges(struct pci_controller *hose,
281pci_process_bridge_OF_ranges(struct pci_controller *hose, 282 struct device_node *dev, int primary);
282 struct device_node *dev, int primary);
283 283
284/* Allocate & free a PCI host bridge structure */ 284/* Allocate & free a PCI host bridge structure */
285extern struct pci_controller * 285extern struct pci_controller *pcibios_alloc_controller(struct device_node *dev);
286pcibios_alloc_controller(struct device_node *dev);
287extern void pcibios_free_controller(struct pci_controller *phb); 286extern void pcibios_free_controller(struct pci_controller *phb);
288 287
289#ifdef CONFIG_PCI 288#ifdef CONFIG_PCI
@@ -298,9 +297,7 @@ static inline int pcibios_vaddr_is_ioport(void __iomem *address)
298{ 297{
299 return 0; 298 return 0;
300} 299}
301#endif 300#endif /* CONFIG_PCI */
302
303 301
304 302#endif /* __KERNEL__ */
305#endif /* __KERNEL__ */ 303#endif /* _ASM_POWERPC_PCI_BRIDGE_H */
306#endif
diff --git a/include/asm-powerpc/pci.h b/include/asm-powerpc/pci.h
index 7b11765c6865..a05a942b1c25 100644
--- a/include/asm-powerpc/pci.h
+++ b/include/asm-powerpc/pci.h
@@ -36,11 +36,10 @@ struct pci_dev;
36 36
37/* 37/*
38 * Set this to 1 if you want the kernel to re-assign all PCI 38 * Set this to 1 if you want the kernel to re-assign all PCI
39 * bus numbers 39 * bus numbers (don't do that on ppc64 yet !)
40 */ 40 */
41extern int pci_assign_all_buses; 41#define pcibios_assign_all_busses() (ppc_pci_flags & \
42#define pcibios_assign_all_busses() (pci_assign_all_buses) 42 PPC_PCI_REASSIGN_ALL_BUS)
43
44#define pcibios_scan_all_fns(a, b) 0 43#define pcibios_scan_all_fns(a, b) 0
45 44
46static inline void pcibios_set_master(struct pci_dev *dev) 45static inline void pcibios_set_master(struct pci_dev *dev)
@@ -95,9 +94,6 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
95#define get_pci_dma_ops() NULL 94#define get_pci_dma_ops() NULL
96#endif 95#endif
97 96
98/* Decide whether to display the domain number in /proc */
99extern int pci_proc_domain(struct pci_bus *bus);
100
101#else /* 32-bit */ 97#else /* 32-bit */
102 98
103#ifdef CONFIG_PCI 99#ifdef CONFIG_PCI
@@ -109,17 +105,14 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev,
109 *strategy_parameter = ~0UL; 105 *strategy_parameter = ~0UL;
110} 106}
111#endif 107#endif
112
113/* Set the name of the bus as it appears in /proc/bus/pci */
114static inline int pci_proc_domain(struct pci_bus *bus)
115{
116 return 0;
117}
118
119#endif /* CONFIG_PPC64 */ 108#endif /* CONFIG_PPC64 */
120 109
121extern int pci_domain_nr(struct pci_bus *bus); 110extern int pci_domain_nr(struct pci_bus *bus);
122 111
112/* Decide whether to display the domain number in /proc */
113extern int pci_proc_domain(struct pci_bus *bus);
114
115
123struct vm_area_struct; 116struct vm_area_struct;
124/* Map a range of PCI memory or I/O space for a device into user space */ 117/* Map a range of PCI memory or I/O space for a device into user space */
125int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, 118int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
@@ -199,13 +192,12 @@ static inline struct resource *pcibios_select_root(struct pci_dev *pdev,
199 return root; 192 return root;
200} 193}
201 194
202extern void pcibios_fixup_device_resources(struct pci_dev *dev,
203 struct pci_bus *bus);
204
205extern void pcibios_setup_new_device(struct pci_dev *dev); 195extern void pcibios_setup_new_device(struct pci_dev *dev);
206 196
207extern void pcibios_claim_one_bus(struct pci_bus *b); 197extern void pcibios_claim_one_bus(struct pci_bus *b);
208 198
199extern void pcibios_resource_survey(void);
200
209extern struct pci_controller *init_phb_dynamic(struct device_node *dn); 201extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
210 202
211extern struct pci_dev *of_create_pci_dev(struct device_node *node, 203extern struct pci_dev *of_create_pci_dev(struct device_node *node,
@@ -229,5 +221,8 @@ extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
229 const struct resource *rsrc, 221 const struct resource *rsrc,
230 resource_size_t *start, resource_size_t *end); 222 resource_size_t *start, resource_size_t *end);
231 223
224extern void pcibios_do_bus_setup(struct pci_bus *bus);
225extern void pcibios_fixup_of_probed_bus(struct pci_bus *bus);
226
232#endif /* __KERNEL__ */ 227#endif /* __KERNEL__ */
233#endif /* __ASM_POWERPC_PCI_H */ 228#endif /* __ASM_POWERPC_PCI_H */
diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h
index b847aa10074b..854ab713f56c 100644
--- a/include/asm-powerpc/ppc-pci.h
+++ b/include/asm-powerpc/ppc-pci.h
@@ -22,7 +22,6 @@ extern void pci_setup_phb_io_dynamic(struct pci_controller *hose, int primary);
22 22
23 23
24extern struct list_head hose_list; 24extern struct list_head hose_list;
25extern int global_phb_number;
26 25
27extern void find_and_init_phbs(void); 26extern void find_and_init_phbs(void);
28 27
@@ -47,9 +46,6 @@ extern void init_pci_config_tokens (void);
47extern unsigned long get_phb_buid (struct device_node *); 46extern unsigned long get_phb_buid (struct device_node *);
48extern int rtas_setup_phb(struct pci_controller *phb); 47extern int rtas_setup_phb(struct pci_controller *phb);
49 48
50/* From iSeries PCI */
51extern void iSeries_pcibios_init(void);
52
53extern unsigned long pci_probe_only; 49extern unsigned long pci_probe_only;
54 50
55/* ---- EEH internal-use-only related routines ---- */ 51/* ---- EEH internal-use-only related routines ---- */
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index 925e2d384bb3..78b7b0d494c0 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -202,6 +202,10 @@ static inline unsigned long of_read_ulong(const u32 *cell, int size)
202 */ 202 */
203extern u64 of_translate_address(struct device_node *np, const u32 *addr); 203extern u64 of_translate_address(struct device_node *np, const u32 *addr);
204 204
205/* Translate a DMA address from device space to CPU space */
206extern u64 of_translate_dma_address(struct device_node *dev,
207 const u32 *in_addr);
208
205/* Extract an address from a device, returns the region size and 209/* Extract an address from a device, returns the region size and
206 * the address space flags too. The PCI version uses a BAR number 210 * the address space flags too. The PCI version uses a BAR number
207 * instead of an absolute index 211 * instead of an absolute index
diff --git a/include/asm-powerpc/qe.h b/include/asm-powerpc/qe.h
index 0dabe46a29d2..a24b7b14958f 100644
--- a/include/asm-powerpc/qe.h
+++ b/include/asm-powerpc/qe.h
@@ -28,6 +28,52 @@
28#define MEM_PART_SECONDARY 1 28#define MEM_PART_SECONDARY 1
29#define MEM_PART_MURAM 2 29#define MEM_PART_MURAM 2
30 30
31/* Clocks and BRGs */
32enum qe_clock {
33 QE_CLK_NONE = 0,
34 QE_BRG1, /* Baud Rate Generator 1 */
35 QE_BRG2, /* Baud Rate Generator 2 */
36 QE_BRG3, /* Baud Rate Generator 3 */
37 QE_BRG4, /* Baud Rate Generator 4 */
38 QE_BRG5, /* Baud Rate Generator 5 */
39 QE_BRG6, /* Baud Rate Generator 6 */
40 QE_BRG7, /* Baud Rate Generator 7 */
41 QE_BRG8, /* Baud Rate Generator 8 */
42 QE_BRG9, /* Baud Rate Generator 9 */
43 QE_BRG10, /* Baud Rate Generator 10 */
44 QE_BRG11, /* Baud Rate Generator 11 */
45 QE_BRG12, /* Baud Rate Generator 12 */
46 QE_BRG13, /* Baud Rate Generator 13 */
47 QE_BRG14, /* Baud Rate Generator 14 */
48 QE_BRG15, /* Baud Rate Generator 15 */
49 QE_BRG16, /* Baud Rate Generator 16 */
50 QE_CLK1, /* Clock 1 */
51 QE_CLK2, /* Clock 2 */
52 QE_CLK3, /* Clock 3 */
53 QE_CLK4, /* Clock 4 */
54 QE_CLK5, /* Clock 5 */
55 QE_CLK6, /* Clock 6 */
56 QE_CLK7, /* Clock 7 */
57 QE_CLK8, /* Clock 8 */
58 QE_CLK9, /* Clock 9 */
59 QE_CLK10, /* Clock 10 */
60 QE_CLK11, /* Clock 11 */
61 QE_CLK12, /* Clock 12 */
62 QE_CLK13, /* Clock 13 */
63 QE_CLK14, /* Clock 14 */
64 QE_CLK15, /* Clock 15 */
65 QE_CLK16, /* Clock 16 */
66 QE_CLK17, /* Clock 17 */
67 QE_CLK18, /* Clock 18 */
68 QE_CLK19, /* Clock 19 */
69 QE_CLK20, /* Clock 20 */
70 QE_CLK21, /* Clock 21 */
71 QE_CLK22, /* Clock 22 */
72 QE_CLK23, /* Clock 23 */
73 QE_CLK24, /* Clock 24 */
74 QE_CLK_DUMMY
75};
76
31/* Export QE common operations */ 77/* Export QE common operations */
32extern void qe_reset(void); 78extern void qe_reset(void);
33extern int par_io_init(struct device_node *np); 79extern int par_io_init(struct device_node *np);
@@ -38,7 +84,8 @@ extern int par_io_data_set(u8 port, u8 pin, u8 val);
38 84
39/* QE internal API */ 85/* QE internal API */
40int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input); 86int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input);
41void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier); 87enum qe_clock qe_clock_source(const char *source);
88int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier);
42int qe_get_snum(void); 89int qe_get_snum(void);
43void qe_put_snum(u8 snum); 90void qe_put_snum(u8 snum);
44unsigned long qe_muram_alloc(int size, int align); 91unsigned long qe_muram_alloc(int size, int align);
@@ -129,52 +176,6 @@ enum comm_dir {
129 COMM_DIR_RX_AND_TX = 3 176 COMM_DIR_RX_AND_TX = 3
130}; 177};
131 178
132/* Clocks and BRGs */
133enum qe_clock {
134 QE_CLK_NONE = 0,
135 QE_BRG1, /* Baud Rate Generator 1 */
136 QE_BRG2, /* Baud Rate Generator 2 */
137 QE_BRG3, /* Baud Rate Generator 3 */
138 QE_BRG4, /* Baud Rate Generator 4 */
139 QE_BRG5, /* Baud Rate Generator 5 */
140 QE_BRG6, /* Baud Rate Generator 6 */
141 QE_BRG7, /* Baud Rate Generator 7 */
142 QE_BRG8, /* Baud Rate Generator 8 */
143 QE_BRG9, /* Baud Rate Generator 9 */
144 QE_BRG10, /* Baud Rate Generator 10 */
145 QE_BRG11, /* Baud Rate Generator 11 */
146 QE_BRG12, /* Baud Rate Generator 12 */
147 QE_BRG13, /* Baud Rate Generator 13 */
148 QE_BRG14, /* Baud Rate Generator 14 */
149 QE_BRG15, /* Baud Rate Generator 15 */
150 QE_BRG16, /* Baud Rate Generator 16 */
151 QE_CLK1, /* Clock 1 */
152 QE_CLK2, /* Clock 2 */
153 QE_CLK3, /* Clock 3 */
154 QE_CLK4, /* Clock 4 */
155 QE_CLK5, /* Clock 5 */
156 QE_CLK6, /* Clock 6 */
157 QE_CLK7, /* Clock 7 */
158 QE_CLK8, /* Clock 8 */
159 QE_CLK9, /* Clock 9 */
160 QE_CLK10, /* Clock 10 */
161 QE_CLK11, /* Clock 11 */
162 QE_CLK12, /* Clock 12 */
163 QE_CLK13, /* Clock 13 */
164 QE_CLK14, /* Clock 14 */
165 QE_CLK15, /* Clock 15 */
166 QE_CLK16, /* Clock 16 */
167 QE_CLK17, /* Clock 17 */
168 QE_CLK18, /* Clock 18 */
169 QE_CLK19, /* Clock 19 */
170 QE_CLK20, /* Clock 20 */
171 QE_CLK21, /* Clock 21 */
172 QE_CLK22, /* Clock 22 */
173 QE_CLK23, /* Clock 23 */
174 QE_CLK24, /* Clock 24 */
175 QE_CLK_DUMMY,
176};
177
178/* QE CMXUCR Registers. 179/* QE CMXUCR Registers.
179 * There are two UCCs represented in each of the four CMXUCR registers. 180 * There are two UCCs represented in each of the four CMXUCR registers.
180 * These values are for the UCC in the LSBs 181 * These values are for the UCC in the LSBs
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index e775ff1ca413..1f685047c6ff 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -691,12 +691,6 @@
691#define PV_BE 0x0070 691#define PV_BE 0x0070
692#define PV_PA6T 0x0090 692#define PV_PA6T 0x0090
693 693
694/*
695 * Number of entries in the SLB. If this ever changes we should handle
696 * it with a use a cpu feature fixup.
697 */
698#define SLB_NUM_ENTRIES 64
699
700/* Macros for setting and retrieving special purpose registers */ 694/* Macros for setting and retrieving special purpose registers */
701#ifndef __ASSEMBLY__ 695#ifndef __ASSEMBLY__
702#define mfmsr() ({unsigned long rval; \ 696#define mfmsr() ({unsigned long rval; \
diff --git a/include/asm-powerpc/reg_booke.h b/include/asm-powerpc/reg_booke.h
index 8fdc2b47afb9..d3e8dd0fc738 100644
--- a/include/asm-powerpc/reg_booke.h
+++ b/include/asm-powerpc/reg_booke.h
@@ -123,16 +123,23 @@
123#define SPRN_SPEFSCR 0x200 /* SPE & Embedded FP Status & Control */ 123#define SPRN_SPEFSCR 0x200 /* SPE & Embedded FP Status & Control */
124#define SPRN_BBEAR 0x201 /* Branch Buffer Entry Address Register */ 124#define SPRN_BBEAR 0x201 /* Branch Buffer Entry Address Register */
125#define SPRN_BBTAR 0x202 /* Branch Buffer Target Address Register */ 125#define SPRN_BBTAR 0x202 /* Branch Buffer Target Address Register */
126#define SPRN_ATB 0x20E /* Alternate Time Base */
127#define SPRN_ATBL 0x20E /* Alternate Time Base Lower */
128#define SPRN_ATBU 0x20F /* Alternate Time Base Upper */
126#define SPRN_IVOR32 0x210 /* Interrupt Vector Offset Register 32 */ 129#define SPRN_IVOR32 0x210 /* Interrupt Vector Offset Register 32 */
127#define SPRN_IVOR33 0x211 /* Interrupt Vector Offset Register 33 */ 130#define SPRN_IVOR33 0x211 /* Interrupt Vector Offset Register 33 */
128#define SPRN_IVOR34 0x212 /* Interrupt Vector Offset Register 34 */ 131#define SPRN_IVOR34 0x212 /* Interrupt Vector Offset Register 34 */
129#define SPRN_IVOR35 0x213 /* Interrupt Vector Offset Register 35 */ 132#define SPRN_IVOR35 0x213 /* Interrupt Vector Offset Register 35 */
133#define SPRN_IVOR36 0x214 /* Interrupt Vector Offset Register 36 */
134#define SPRN_IVOR37 0x215 /* Interrupt Vector Offset Register 37 */
130#define SPRN_MCSRR0 0x23A /* Machine Check Save and Restore Register 0 */ 135#define SPRN_MCSRR0 0x23A /* Machine Check Save and Restore Register 0 */
131#define SPRN_MCSRR1 0x23B /* Machine Check Save and Restore Register 1 */ 136#define SPRN_MCSRR1 0x23B /* Machine Check Save and Restore Register 1 */
132#define SPRN_MCSR 0x23C /* Machine Check Status Register */ 137#define SPRN_MCSR 0x23C /* Machine Check Status Register */
133#define SPRN_MCAR 0x23D /* Machine Check Address Register */ 138#define SPRN_MCAR 0x23D /* Machine Check Address Register */
134#define SPRN_DSRR0 0x23E /* Debug Save and Restore Register 0 */ 139#define SPRN_DSRR0 0x23E /* Debug Save and Restore Register 0 */
135#define SPRN_DSRR1 0x23F /* Debug Save and Restore Register 1 */ 140#define SPRN_DSRR1 0x23F /* Debug Save and Restore Register 1 */
141#define SPRN_SPRG8 0x25C /* Special Purpose Register General 8 */
142#define SPRN_SPRG9 0x25D /* Special Purpose Register General 9 */
136#define SPRN_MAS0 0x270 /* MMU Assist Register 0 */ 143#define SPRN_MAS0 0x270 /* MMU Assist Register 0 */
137#define SPRN_MAS1 0x271 /* MMU Assist Register 1 */ 144#define SPRN_MAS1 0x271 /* MMU Assist Register 1 */
138#define SPRN_MAS2 0x272 /* MMU Assist Register 2 */ 145#define SPRN_MAS2 0x272 /* MMU Assist Register 2 */
@@ -140,15 +147,18 @@
140#define SPRN_MAS4 0x274 /* MMU Assist Register 4 */ 147#define SPRN_MAS4 0x274 /* MMU Assist Register 4 */
141#define SPRN_MAS5 0x275 /* MMU Assist Register 5 */ 148#define SPRN_MAS5 0x275 /* MMU Assist Register 5 */
142#define SPRN_MAS6 0x276 /* MMU Assist Register 6 */ 149#define SPRN_MAS6 0x276 /* MMU Assist Register 6 */
143#define SPRN_MAS7 0x3b0 /* MMU Assist Register 7 */
144#define SPRN_PID1 0x279 /* Process ID Register 1 */ 150#define SPRN_PID1 0x279 /* Process ID Register 1 */
145#define SPRN_PID2 0x27A /* Process ID Register 2 */ 151#define SPRN_PID2 0x27A /* Process ID Register 2 */
146#define SPRN_TLB0CFG 0x2B0 /* TLB 0 Config Register */ 152#define SPRN_TLB0CFG 0x2B0 /* TLB 0 Config Register */
147#define SPRN_TLB1CFG 0x2B1 /* TLB 1 Config Register */ 153#define SPRN_TLB1CFG 0x2B1 /* TLB 1 Config Register */
154#define SPRN_EPR 0x2BE /* External Proxy Register */
148#define SPRN_CCR1 0x378 /* Core Configuration Register 1 */ 155#define SPRN_CCR1 0x378 /* Core Configuration Register 1 */
149#define SPRN_ZPR 0x3B0 /* Zone Protection Register (40x) */ 156#define SPRN_ZPR 0x3B0 /* Zone Protection Register (40x) */
157#define SPRN_MAS7 0x3B0 /* MMU Assist Register 7 */
150#define SPRN_MMUCR 0x3B2 /* MMU Control Register */ 158#define SPRN_MMUCR 0x3B2 /* MMU Control Register */
151#define SPRN_CCR0 0x3B3 /* Core Configuration Register 0 */ 159#define SPRN_CCR0 0x3B3 /* Core Configuration Register 0 */
160#define SPRN_EPLC 0x3B3 /* External Process ID Load Context */
161#define SPRN_EPSC 0x3B4 /* External Process ID Store Context */
152#define SPRN_SGR 0x3B9 /* Storage Guarded Register */ 162#define SPRN_SGR 0x3B9 /* Storage Guarded Register */
153#define SPRN_DCWR 0x3BA /* Data Cache Write-thru Register */ 163#define SPRN_DCWR 0x3BA /* Data Cache Write-thru Register */
154#define SPRN_SLER 0x3BB /* Little-endian real mode */ 164#define SPRN_SLER 0x3BB /* Little-endian real mode */
@@ -159,6 +169,7 @@
159#define SPRN_L1CSR0 0x3F2 /* L1 Cache Control and Status Register 0 */ 169#define SPRN_L1CSR0 0x3F2 /* L1 Cache Control and Status Register 0 */
160#define SPRN_L1CSR1 0x3F3 /* L1 Cache Control and Status Register 1 */ 170#define SPRN_L1CSR1 0x3F3 /* L1 Cache Control and Status Register 1 */
161#define SPRN_PIT 0x3DB /* Programmable Interval Timer */ 171#define SPRN_PIT 0x3DB /* Programmable Interval Timer */
172#define SPRN_BUCSR 0x3F5 /* Branch Unit Control and Status */
162#define SPRN_DCCR 0x3FA /* Data Cache Cacheability Register */ 173#define SPRN_DCCR 0x3FA /* Data Cache Cacheability Register */
163#define SPRN_ICCR 0x3FB /* Instruction Cache Cacheability Register */ 174#define SPRN_ICCR 0x3FB /* Instruction Cache Cacheability Register */
164#define SPRN_SVR 0x3FF /* System Version Register */ 175#define SPRN_SVR 0x3FF /* System Version Register */
@@ -293,7 +304,7 @@
293#define ESR_IMCB 0x20000000 /* Instr. Machine Check - Bus error */ 304#define ESR_IMCB 0x20000000 /* Instr. Machine Check - Bus error */
294#define ESR_IMCT 0x10000000 /* Instr. Machine Check - Timeout */ 305#define ESR_IMCT 0x10000000 /* Instr. Machine Check - Timeout */
295#define ESR_PIL 0x08000000 /* Program Exception - Illegal */ 306#define ESR_PIL 0x08000000 /* Program Exception - Illegal */
296#define ESR_PPR 0x04000000 /* Program Exception - Priveleged */ 307#define ESR_PPR 0x04000000 /* Program Exception - Privileged */
297#define ESR_PTR 0x02000000 /* Program Exception - Trap */ 308#define ESR_PTR 0x02000000 /* Program Exception - Trap */
298#define ESR_FP 0x01000000 /* Floating Point Operation */ 309#define ESR_FP 0x01000000 /* Floating Point Operation */
299#define ESR_DST 0x00800000 /* Storage Exception - Data miss */ 310#define ESR_DST 0x00800000 /* Storage Exception - Data miss */
diff --git a/include/asm-powerpc/smu.h b/include/asm-powerpc/smu.h
index e49f644ca63a..7ae2753da565 100644
--- a/include/asm-powerpc/smu.h
+++ b/include/asm-powerpc/smu.h
@@ -22,7 +22,7 @@
22 * Partition info commands 22 * Partition info commands
23 * 23 *
24 * These commands are used to retrieve the sdb-partition-XX datas from 24 * These commands are used to retrieve the sdb-partition-XX datas from
25 * the SMU. The lenght is always 2. First byte is the subcommand code 25 * the SMU. The length is always 2. First byte is the subcommand code
26 * and second byte is the partition ID. 26 * and second byte is the partition ID.
27 * 27 *
28 * The reply is 6 bytes: 28 * The reply is 6 bytes:
@@ -173,12 +173,12 @@
173 * Power supply control 173 * Power supply control
174 * 174 *
175 * The "sub" command is an ASCII string in the data, the 175 * The "sub" command is an ASCII string in the data, the
176 * data lenght is that of the string. 176 * data length is that of the string.
177 * 177 *
178 * The VSLEW command can be used to get or set the voltage slewing. 178 * The VSLEW command can be used to get or set the voltage slewing.
179 * - lenght 5 (only "VSLEW") : it returns "DONE" and 3 bytes of 179 * - length 5 (only "VSLEW") : it returns "DONE" and 3 bytes of
180 * reply at data offset 6, 7 and 8. 180 * reply at data offset 6, 7 and 8.
181 * - lenght 8 ("VSLEWxyz") has 3 additional bytes appended, and is 181 * - length 8 ("VSLEWxyz") has 3 additional bytes appended, and is
182 * used to set the voltage slewing point. The SMU replies with "DONE" 182 * used to set the voltage slewing point. The SMU replies with "DONE"
183 * I yet have to figure out their exact meaning of those 3 bytes in 183 * I yet have to figure out their exact meaning of those 3 bytes in
184 * both cases. They seem to be: 184 * both cases. They seem to be:
@@ -201,20 +201,90 @@
201 */ 201 */
202#define SMU_CMD_READ_ADC 0xd8 202#define SMU_CMD_READ_ADC 0xd8
203 203
204
204/* Misc commands 205/* Misc commands
205 * 206 *
206 * This command seem to be a grab bag of various things 207 * This command seem to be a grab bag of various things
208 *
209 * Parameters:
210 * 1: subcommand
207 */ 211 */
208#define SMU_CMD_MISC_df_COMMAND 0xdf 212#define SMU_CMD_MISC_df_COMMAND 0xdf
209#define SMU_CMD_MISC_df_SET_DISPLAY_LIT 0x02 /* i: 1 byte */ 213
214/*
215 * Sets "system ready" status
216 *
217 * I did not yet understand how it exactly works or what it does.
218 *
219 * Guessing from OF code, 0x02 activates the display backlight. Apple uses/used
220 * the same codebase for all OF versions. On PowerBooks, this command would
221 * enable the backlight. For the G5s, it only activates the front LED. However,
222 * don't take this for granted.
223 *
224 * Parameters:
225 * 2: status [0x00, 0x01 or 0x02]
226 */
227#define SMU_CMD_MISC_df_SET_DISPLAY_LIT 0x02
228
229/*
230 * Sets mode of power switch.
231 *
232 * What this actually does is not yet known. Maybe it enables some interrupt.
233 *
234 * Parameters:
235 * 2: enable power switch? [0x00 or 0x01]
236 * 3 (optional): enable nmi? [0x00 or 0x01]
237 *
238 * Returns:
239 * If parameter 2 is 0x00 and parameter 3 is not specified, returns wether
240 * NMI is enabled. Otherwise unknown.
241 */
210#define SMU_CMD_MISC_df_NMI_OPTION 0x04 242#define SMU_CMD_MISC_df_NMI_OPTION 0x04
211 243
244/* Sets LED dimm offset.
245 *
246 * The front LED dimms itself during sleep. Its brightness (or, well, the PWM
247 * frequency) depends on current time. Therefore, the SMU needs to know the
248 * timezone.
249 *
250 * Parameters:
251 * 2-8: unknown (BCD coding)
252 */
253#define SMU_CMD_MISC_df_DIMM_OFFSET 0x99
254
255
212/* 256/*
213 * Version info commands 257 * Version info commands
214 * 258 *
215 * I haven't quite tried to figure out how these work 259 * Parameters:
260 * 1 (optional): Specifies version part to retrieve
261 *
262 * Returns:
263 * Version value
216 */ 264 */
217#define SMU_CMD_VERSION_COMMAND 0xea 265#define SMU_CMD_VERSION_COMMAND 0xea
266#define SMU_VERSION_RUNNING 0x00
267#define SMU_VERSION_BASE 0x01
268#define SMU_VERSION_UPDATE 0x02
269
270
271/*
272 * Switches
273 *
274 * These are switches whose status seems to be known to the SMU.
275 *
276 * Parameters:
277 * none
278 *
279 * Result:
280 * Switch bits (ORed, see below)
281 */
282#define SMU_CMD_SWITCHES 0xdc
283
284/* Switches bits */
285#define SMU_SWITCH_CASE_CLOSED 0x01
286#define SMU_SWITCH_AC_POWER 0x04
287#define SMU_SWITCH_POWER_SWITCH 0x08
218 288
219 289
220/* 290/*
@@ -243,10 +313,64 @@
243 */ 313 */
244#define SMU_CMD_MISC_ee_COMMAND 0xee 314#define SMU_CMD_MISC_ee_COMMAND 0xee
245#define SMU_CMD_MISC_ee_GET_DATABLOCK_REC 0x02 315#define SMU_CMD_MISC_ee_GET_DATABLOCK_REC 0x02
246#define SMU_CMD_MISC_ee_LEDS_CTRL 0x04 /* i: 00 (00,01) [00] */ 316
317/* Retrieves currently used watts.
318 *
319 * Parameters:
320 * 1: 0x03 (Meaning unknown)
321 */
322#define SMU_CMD_MISC_ee_GET_WATTS 0x03
323
324#define SMU_CMD_MISC_ee_LEDS_CTRL 0x04 /* i: 00 (00,01) [00] */
247#define SMU_CMD_MISC_ee_GET_DATA 0x05 /* i: 00 , o: ?? */ 325#define SMU_CMD_MISC_ee_GET_DATA 0x05 /* i: 00 , o: ?? */
248 326
249 327
328/*
329 * Power related commands
330 *
331 * Parameters:
332 * 1: subcommand
333 */
334#define SMU_CMD_POWER_EVENTS_COMMAND 0x8f
335
336/* SMU_POWER_EVENTS subcommands */
337enum {
338 SMU_PWR_GET_POWERUP_EVENTS = 0x00,
339 SMU_PWR_SET_POWERUP_EVENTS = 0x01,
340 SMU_PWR_CLR_POWERUP_EVENTS = 0x02,
341 SMU_PWR_GET_WAKEUP_EVENTS = 0x03,
342 SMU_PWR_SET_WAKEUP_EVENTS = 0x04,
343 SMU_PWR_CLR_WAKEUP_EVENTS = 0x05,
344
345 /*
346 * Get last shutdown cause
347 *
348 * Returns:
349 * 1 byte (signed char): Last shutdown cause. Exact meaning unknown.
350 */
351 SMU_PWR_LAST_SHUTDOWN_CAUSE = 0x07,
352
353 /*
354 * Sets or gets server ID. Meaning or use is unknown.
355 *
356 * Parameters:
357 * 2 (optional): Set server ID (1 byte)
358 *
359 * Returns:
360 * 1 byte (server ID?)
361 */
362 SMU_PWR_SERVER_ID = 0x08,
363};
364
365/* Power events wakeup bits */
366enum {
367 SMU_PWR_WAKEUP_KEY = 0x01, /* Wake on key press */
368 SMU_PWR_WAKEUP_AC_INSERT = 0x02, /* Wake on AC adapter plug */
369 SMU_PWR_WAKEUP_AC_CHANGE = 0x04,
370 SMU_PWR_WAKEUP_LID_OPEN = 0x08,
371 SMU_PWR_WAKEUP_RING = 0x10,
372};
373
250 374
251/* 375/*
252 * - Kernel side interface - 376 * - Kernel side interface -
@@ -564,13 +688,13 @@ struct smu_user_cmd_hdr
564 688
565 __u8 cmd; /* SMU command byte */ 689 __u8 cmd; /* SMU command byte */
566 __u8 pad[3]; /* padding */ 690 __u8 pad[3]; /* padding */
567 __u32 data_len; /* Lenght of data following */ 691 __u32 data_len; /* Length of data following */
568}; 692};
569 693
570struct smu_user_reply_hdr 694struct smu_user_reply_hdr
571{ 695{
572 __u32 status; /* Command status */ 696 __u32 status; /* Command status */
573 __u32 reply_len; /* Lenght of data follwing */ 697 __u32 reply_len; /* Length of data follwing */
574}; 698};
575 699
576#endif /* _SMU_H */ 700#endif /* _SMU_H */
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index b1accce77bb5..5ca30e2e2639 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -104,6 +104,7 @@
104 104
105struct spu_context; 105struct spu_context;
106struct spu_runqueue; 106struct spu_runqueue;
107struct spu_lscsa;
107struct device_node; 108struct device_node;
108 109
109enum spu_utilization_state { 110enum spu_utilization_state {
@@ -145,7 +146,6 @@ struct spu {
145 void (* ibox_callback)(struct spu *spu); 146 void (* ibox_callback)(struct spu *spu);
146 void (* stop_callback)(struct spu *spu); 147 void (* stop_callback)(struct spu *spu);
147 void (* mfc_callback)(struct spu *spu); 148 void (* mfc_callback)(struct spu *spu);
148 void (* dma_callback)(struct spu *spu, int type);
149 149
150 char irq_c0[8]; 150 char irq_c0[8];
151 char irq_c1[8]; 151 char irq_c1[8];
@@ -196,10 +196,11 @@ struct cbe_spu_info {
196extern struct cbe_spu_info cbe_spu_info[]; 196extern struct cbe_spu_info cbe_spu_info[];
197 197
198void spu_init_channels(struct spu *spu); 198void spu_init_channels(struct spu *spu);
199int spu_irq_class_0_bottom(struct spu *spu);
200int spu_irq_class_1_bottom(struct spu *spu);
201void spu_irq_setaffinity(struct spu *spu, int cpu); 199void spu_irq_setaffinity(struct spu *spu, int cpu);
202 200
201void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa,
202 void *code, int code_size);
203
203#ifdef CONFIG_KEXEC 204#ifdef CONFIG_KEXEC
204void crash_register_spus(struct list_head *list); 205void crash_register_spus(struct list_head *list);
205#else 206#else
@@ -210,6 +211,7 @@ static inline void crash_register_spus(struct list_head *list)
210 211
211extern void spu_invalidate_slbs(struct spu *spu); 212extern void spu_invalidate_slbs(struct spu *spu);
212extern void spu_associate_mm(struct spu *spu, struct mm_struct *mm); 213extern void spu_associate_mm(struct spu *spu, struct mm_struct *mm);
214int spu_64k_pages_available(void);
213 215
214/* Calls from the memory management to the SPU */ 216/* Calls from the memory management to the SPU */
215struct mm_struct; 217struct mm_struct;
@@ -278,6 +280,8 @@ void spu_remove_sysdev_attr(struct sysdev_attribute *attr);
278int spu_add_sysdev_attr_group(struct attribute_group *attrs); 280int spu_add_sysdev_attr_group(struct attribute_group *attrs);
279void spu_remove_sysdev_attr_group(struct attribute_group *attrs); 281void spu_remove_sysdev_attr_group(struct attribute_group *attrs);
280 282
283int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
284 unsigned long dsisr, unsigned *flt);
281 285
282/* 286/*
283 * Notifier blocks: 287 * Notifier blocks:
@@ -299,7 +303,7 @@ int spu_switch_event_register(struct notifier_block * n);
299int spu_switch_event_unregister(struct notifier_block * n); 303int spu_switch_event_unregister(struct notifier_block * n);
300 304
301/* 305/*
302 * This defines the Local Store, Problem Area and Privlege Area of an SPU. 306 * This defines the Local Store, Problem Area and Privilege Area of an SPU.
303 */ 307 */
304 308
305union mfc_tag_size_class_cmd { 309union mfc_tag_size_class_cmd {
@@ -520,8 +524,24 @@ struct spu_priv1 {
520#define CLASS2_ENABLE_SPU_STOP_INTR 0x2L 524#define CLASS2_ENABLE_SPU_STOP_INTR 0x2L
521#define CLASS2_ENABLE_SPU_HALT_INTR 0x4L 525#define CLASS2_ENABLE_SPU_HALT_INTR 0x4L
522#define CLASS2_ENABLE_SPU_DMA_TAG_GROUP_COMPLETE_INTR 0x8L 526#define CLASS2_ENABLE_SPU_DMA_TAG_GROUP_COMPLETE_INTR 0x8L
527#define CLASS2_ENABLE_MAILBOX_THRESHOLD_INTR 0x10L
523 u8 pad_0x118_0x140[0x28]; /* 0x118 */ 528 u8 pad_0x118_0x140[0x28]; /* 0x118 */
524 u64 int_stat_RW[3]; /* 0x140 */ 529 u64 int_stat_RW[3]; /* 0x140 */
530#define CLASS0_DMA_ALIGNMENT_INTR 0x1L
531#define CLASS0_INVALID_DMA_COMMAND_INTR 0x2L
532#define CLASS0_SPU_ERROR_INTR 0x4L
533#define CLASS0_INTR_MASK 0x7L
534#define CLASS1_SEGMENT_FAULT_INTR 0x1L
535#define CLASS1_STORAGE_FAULT_INTR 0x2L
536#define CLASS1_LS_COMPARE_SUSPEND_ON_GET_INTR 0x4L
537#define CLASS1_LS_COMPARE_SUSPEND_ON_PUT_INTR 0x8L
538#define CLASS1_INTR_MASK 0xfL
539#define CLASS2_MAILBOX_INTR 0x1L
540#define CLASS2_SPU_STOP_INTR 0x2L
541#define CLASS2_SPU_HALT_INTR 0x4L
542#define CLASS2_SPU_DMA_TAG_GROUP_COMPLETE_INTR 0x8L
543#define CLASS2_MAILBOX_THRESHOLD_INTR 0x10L
544#define CLASS2_INTR_MASK 0x1fL
525 u8 pad_0x158_0x180[0x28]; /* 0x158 */ 545 u8 pad_0x158_0x180[0x28]; /* 0x158 */
526 u64 int_route_RW; /* 0x180 */ 546 u64 int_route_RW; /* 0x180 */
527 547
diff --git a/include/asm-powerpc/spu_csa.h b/include/asm-powerpc/spu_csa.h
index e87794d5d4ea..0ab6bff86078 100644
--- a/include/asm-powerpc/spu_csa.h
+++ b/include/asm-powerpc/spu_csa.h
@@ -194,7 +194,7 @@ struct spu_priv1_collapsed {
194}; 194};
195 195
196/* 196/*
197 * struct spu_priv2_collapsed - condensed priviliged 2 area, w/o pads. 197 * struct spu_priv2_collapsed - condensed privileged 2 area, w/o pads.
198 */ 198 */
199struct spu_priv2_collapsed { 199struct spu_priv2_collapsed {
200 u64 slb_index_W; 200 u64 slb_index_W;
@@ -254,20 +254,11 @@ struct spu_state {
254 u64 spu_chnldata_RW[32]; 254 u64 spu_chnldata_RW[32];
255 u32 spu_mailbox_data[4]; 255 u32 spu_mailbox_data[4];
256 u32 pu_mailbox_data[1]; 256 u32 pu_mailbox_data[1];
257 u64 dar, dsisr; 257 u64 dar, dsisr, class_0_pending;
258 unsigned long suspend_time; 258 unsigned long suspend_time;
259 spinlock_t register_lock; 259 spinlock_t register_lock;
260}; 260};
261 261
262extern int spu_init_csa(struct spu_state *csa);
263extern void spu_fini_csa(struct spu_state *csa);
264extern int spu_save(struct spu_state *prev, struct spu *spu);
265extern int spu_restore(struct spu_state *new, struct spu *spu);
266extern int spu_switch(struct spu_state *prev, struct spu_state *new,
267 struct spu *spu);
268extern int spu_alloc_lscsa(struct spu_state *csa);
269extern void spu_free_lscsa(struct spu_state *csa);
270
271#endif /* !__SPU__ */ 262#endif /* !__SPU__ */
272#endif /* __KERNEL__ */ 263#endif /* __KERNEL__ */
273#endif /* !__ASSEMBLY__ */ 264#endif /* !__ASSEMBLY__ */
diff --git a/include/asm-powerpc/spu_priv1.h b/include/asm-powerpc/spu_priv1.h
index 0f37c7c90820..25020a34ce7f 100644
--- a/include/asm-powerpc/spu_priv1.h
+++ b/include/asm-powerpc/spu_priv1.h
@@ -24,6 +24,7 @@
24#include <linux/types.h> 24#include <linux/types.h>
25 25
26struct spu; 26struct spu;
27struct spu_context;
27 28
28/* access to priv1 registers */ 29/* access to priv1 registers */
29 30
@@ -178,6 +179,8 @@ struct spu_management_ops {
178 int (*enumerate_spus)(int (*fn)(void *data)); 179 int (*enumerate_spus)(int (*fn)(void *data));
179 int (*create_spu)(struct spu *spu, void *data); 180 int (*create_spu)(struct spu *spu, void *data);
180 int (*destroy_spu)(struct spu *spu); 181 int (*destroy_spu)(struct spu *spu);
182 void (*enable_spu)(struct spu_context *ctx);
183 void (*disable_spu)(struct spu_context *ctx);
181 int (*init_affinity)(void); 184 int (*init_affinity)(void);
182}; 185};
183 186
@@ -207,6 +210,18 @@ spu_init_affinity (void)
207 return spu_management_ops->init_affinity(); 210 return spu_management_ops->init_affinity();
208} 211}
209 212
213static inline void
214spu_enable_spu (struct spu_context *ctx)
215{
216 spu_management_ops->enable_spu(ctx);
217}
218
219static inline void
220spu_disable_spu (struct spu_context *ctx)
221{
222 spu_management_ops->disable_spu(ctx);
223}
224
210/* 225/*
211 * The declarations folowing are put here for convenience 226 * The declarations folowing are put here for convenience
212 * and only intended to be used by the platform setup code. 227 * and only intended to be used by the platform setup code.
diff --git a/include/asm-ppc/8xx_immap.h b/include/asm-ppc/8xx_immap.h
index 1311cefdfd30..4b0e15206006 100644
--- a/include/asm-ppc/8xx_immap.h
+++ b/include/asm-ppc/8xx_immap.h
@@ -123,7 +123,7 @@ typedef struct mem_ctlr {
123#define OR_G5LA 0x00000400 /* Output #GPL5 on #GPL_A5 */ 123#define OR_G5LA 0x00000400 /* Output #GPL5 on #GPL_A5 */
124#define OR_G5LS 0x00000200 /* Drive #GPL high on falling edge of...*/ 124#define OR_G5LS 0x00000200 /* Drive #GPL high on falling edge of...*/
125#define OR_BI 0x00000100 /* Burst inhibit */ 125#define OR_BI 0x00000100 /* Burst inhibit */
126#define OR_SCY_MSK 0x000000f0 /* Cycle Lenght in Clocks */ 126#define OR_SCY_MSK 0x000000f0 /* Cycle Length in Clocks */
127#define OR_SCY_0_CLK 0x00000000 /* 0 clock cycles wait states */ 127#define OR_SCY_0_CLK 0x00000000 /* 0 clock cycles wait states */
128#define OR_SCY_1_CLK 0x00000010 /* 1 clock cycles wait states */ 128#define OR_SCY_1_CLK 0x00000010 /* 1 clock cycles wait states */
129#define OR_SCY_2_CLK 0x00000020 /* 2 clock cycles wait states */ 129#define OR_SCY_2_CLK 0x00000020 /* 2 clock cycles wait states */
diff --git a/include/asm-ppc/commproc.h b/include/asm-ppc/commproc.h
index 397248705e0e..462abb185f07 100644
--- a/include/asm-ppc/commproc.h
+++ b/include/asm-ppc/commproc.h
@@ -681,7 +681,7 @@ typedef struct risc_timer_pram {
681#define CICR_SCC_SCC3 ((uint)0x00200000) /* SCC3 @ SCCc */ 681#define CICR_SCC_SCC3 ((uint)0x00200000) /* SCC3 @ SCCc */
682#define CICR_SCB_SCC2 ((uint)0x00040000) /* SCC2 @ SCCb */ 682#define CICR_SCB_SCC2 ((uint)0x00040000) /* SCC2 @ SCCb */
683#define CICR_SCA_SCC1 ((uint)0x00000000) /* SCC1 @ SCCa */ 683#define CICR_SCA_SCC1 ((uint)0x00000000) /* SCC1 @ SCCa */
684#define CICR_IRL_MASK ((uint)0x0000e000) /* Core interrrupt */ 684#define CICR_IRL_MASK ((uint)0x0000e000) /* Core interrupt */
685#define CICR_HP_MASK ((uint)0x00001f00) /* Hi-pri int. */ 685#define CICR_HP_MASK ((uint)0x00001f00) /* Hi-pri int. */
686#define CICR_IEN ((uint)0x00000080) /* Int. enable */ 686#define CICR_IEN ((uint)0x00000080) /* Int. enable */
687#define CICR_SPS ((uint)0x00000001) /* SCC Spread */ 687#define CICR_SPS ((uint)0x00000001) /* SCC Spread */
diff --git a/include/asm-ppc/reg_booke.h b/include/asm-ppc/reg_booke.h
index 82948ed2744a..4cad45a055dd 100644
--- a/include/asm-ppc/reg_booke.h
+++ b/include/asm-ppc/reg_booke.h
@@ -283,7 +283,7 @@
283#define ESR_IMCB 0x20000000 /* Instr. Machine Check - Bus error */ 283#define ESR_IMCB 0x20000000 /* Instr. Machine Check - Bus error */
284#define ESR_IMCT 0x10000000 /* Instr. Machine Check - Timeout */ 284#define ESR_IMCT 0x10000000 /* Instr. Machine Check - Timeout */
285#define ESR_PIL 0x08000000 /* Program Exception - Illegal */ 285#define ESR_PIL 0x08000000 /* Program Exception - Illegal */
286#define ESR_PPR 0x04000000 /* Program Exception - Priveleged */ 286#define ESR_PPR 0x04000000 /* Program Exception - Privileged */
287#define ESR_PTR 0x02000000 /* Program Exception - Trap */ 287#define ESR_PTR 0x02000000 /* Program Exception - Trap */
288#define ESR_FP 0x01000000 /* Floating Point Operation */ 288#define ESR_FP 0x01000000 /* Floating Point Operation */
289#define ESR_DST 0x00800000 /* Storage Exception - Data miss */ 289#define ESR_DST 0x00800000 /* Storage Exception - Data miss */
diff --git a/include/linux/of.h b/include/linux/of.h
index 5c39b9270ff7..c65af7bd1e9c 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -46,6 +46,10 @@ extern struct device_node *of_find_node_by_phandle(phandle handle);
46extern struct device_node *of_get_parent(const struct device_node *node); 46extern struct device_node *of_get_parent(const struct device_node *node);
47extern struct device_node *of_get_next_child(const struct device_node *node, 47extern struct device_node *of_get_next_child(const struct device_node *node,
48 struct device_node *prev); 48 struct device_node *prev);
49#define for_each_child_of_node(parent, child) \
50 for (child = of_get_next_child(parent, NULL); child != NULL; \
51 child = of_get_next_child(parent, child))
52
49extern struct property *of_find_property(const struct device_node *np, 53extern struct property *of_find_property(const struct device_node *np,
50 const char *name, 54 const char *name,
51 int *lenp); 55 int *lenp);
diff --git a/include/linux/pmu.h b/include/linux/pmu.h
index b7824c215354..4c5f65392d36 100644
--- a/include/linux/pmu.h
+++ b/include/linux/pmu.h
@@ -159,41 +159,7 @@ extern void pmu_unlock(void);
159extern int pmu_present(void); 159extern int pmu_present(void);
160extern int pmu_get_model(void); 160extern int pmu_get_model(void);
161 161
162#ifdef CONFIG_PM 162extern void pmu_backlight_set_sleep(int sleep);
163/*
164 * Stuff for putting the powerbook to sleep and waking it again.
165 *
166 */
167#include <linux/list.h>
168
169struct pmu_sleep_notifier
170{
171 void (*notifier_call)(struct pmu_sleep_notifier *self, int when);
172 int priority;
173 struct list_head list;
174};
175
176/* Code values for calling sleep/wakeup handlers
177 */
178#define PBOOK_SLEEP_REQUEST 1
179#define PBOOK_SLEEP_NOW 2
180#define PBOOK_WAKE 3
181
182/* priority levels in notifiers */
183#define SLEEP_LEVEL_VIDEO 100 /* Video driver (first wake) */
184#define SLEEP_LEVEL_MEDIABAY 90 /* Media bay driver */
185#define SLEEP_LEVEL_BLOCK 80 /* IDE, SCSI */
186#define SLEEP_LEVEL_NET 70 /* bmac, gmac */
187#define SLEEP_LEVEL_MISC 60 /* Anything else */
188#define SLEEP_LEVEL_USERLAND 55 /* Reserved for apm_emu */
189#define SLEEP_LEVEL_ADB 50 /* ADB (async) */
190#define SLEEP_LEVEL_SOUND 40 /* Sound driver (blocking) */
191
192/* special register notifier functions */
193int pmu_register_sleep_notifier(struct pmu_sleep_notifier* notifier);
194int pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* notifier);
195
196#endif /* CONFIG_PM */
197 163
198#define PMU_MAX_BATTERIES 2 164#define PMU_MAX_BATTERIES 2
199 165