From a8b4e827a4e9c2bd7c7985c6f5a4612c90f87259 Mon Sep 17 00:00:00 2001 From: Richard Weinberger Date: Mon, 26 Mar 2012 09:01:29 +0000 Subject: [PATCH] --- yaml --- r: 330366 b: refs/heads/master c: fca826460e55d4e8f2deceb09f22f9340a0db24c h: refs/heads/master v: v3 --- [refs] | 2 +- .../devicetree/bindings/powerpc/fsl/ifc.txt | 9 +- trunk/arch/arm/mach-tegra/pcie.c | 12 +- trunk/arch/mips/pci/pci-octeon.c | 15 +- trunk/arch/powerpc/Kconfig | 17 +- trunk/arch/powerpc/boot/Makefile | 1 - .../boot/dts/fsl/e500mc_power_isa.dtsi | 58 -- .../boot/dts/fsl/e500v2_power_isa.dtsi | 52 -- .../powerpc/boot/dts/fsl/e5500_power_isa.dtsi | 59 -- .../powerpc/boot/dts/fsl/mpc8536si-pre.dtsi | 3 - .../powerpc/boot/dts/fsl/mpc8544si-pre.dtsi | 3 - .../powerpc/boot/dts/fsl/mpc8548si-pre.dtsi | 3 - .../powerpc/boot/dts/fsl/mpc8568si-pre.dtsi | 3 - .../powerpc/boot/dts/fsl/mpc8569si-pre.dtsi | 3 - .../powerpc/boot/dts/fsl/mpc8572si-pre.dtsi | 3 - .../powerpc/boot/dts/fsl/p1010si-pre.dtsi | 3 - .../powerpc/boot/dts/fsl/p1020si-pre.dtsi | 3 - .../powerpc/boot/dts/fsl/p1021si-pre.dtsi | 3 - .../powerpc/boot/dts/fsl/p1022si-pre.dtsi | 3 - .../powerpc/boot/dts/fsl/p1023si-pre.dtsi | 3 - .../powerpc/boot/dts/fsl/p2020si-pre.dtsi | 3 - .../powerpc/boot/dts/fsl/p2041si-pre.dtsi | 3 - .../powerpc/boot/dts/fsl/p3041si-pre.dtsi | 3 - .../powerpc/boot/dts/fsl/p4080si-pre.dtsi | 3 - .../powerpc/boot/dts/fsl/p5020si-pre.dtsi | 3 - .../powerpc/boot/dts/fsl/p5040si-post.dtsi | 320 -------- .../powerpc/boot/dts/fsl/p5040si-pre.dtsi | 114 --- .../powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi | 118 --- trunk/arch/powerpc/boot/dts/mpc8536ds.dtsi | 4 - trunk/arch/powerpc/boot/dts/mpc8540ads.dts | 2 - trunk/arch/powerpc/boot/dts/mpc8541cds.dts | 2 - trunk/arch/powerpc/boot/dts/mpc8544ds.dts | 4 +- trunk/arch/powerpc/boot/dts/mpc8544ds.dtsi | 39 - trunk/arch/powerpc/boot/dts/mpc8555cds.dts | 2 - trunk/arch/powerpc/boot/dts/mpc8560ads.dts | 2 - .../powerpc/boot/dts/p1020rdb_camp_core0.dts | 63 ++ .../powerpc/boot/dts/p1020rdb_camp_core1.dts | 141 ++++ trunk/arch/powerpc/boot/dts/p1022ds.dtsi | 4 - trunk/arch/powerpc/boot/dts/p1022rdk.dts | 188 ----- .../powerpc/boot/dts/p2020rdb_camp_core0.dts | 67 ++ .../powerpc/boot/dts/p2020rdb_camp_core1.dts | 125 +++ trunk/arch/powerpc/boot/dts/p2041rdb.dts | 4 - trunk/arch/powerpc/boot/dts/p3041ds.dts | 4 - trunk/arch/powerpc/boot/dts/p4080ds.dts | 4 - trunk/arch/powerpc/boot/dts/p5020ds.dts | 4 - trunk/arch/powerpc/boot/dts/p5040ds.dts | 207 ----- .../powerpc/configs/corenet32_smp_defconfig | 1 - .../powerpc/configs/corenet64_smp_defconfig | 1 - trunk/arch/powerpc/configs/mpc85xx_defconfig | 1 - .../powerpc/configs/mpc85xx_smp_defconfig | 1 - trunk/arch/powerpc/configs/ppc64_defconfig | 1 - trunk/arch/powerpc/configs/pseries_defconfig | 1 - trunk/arch/powerpc/include/asm/abs_addr.h | 56 ++ trunk/arch/powerpc/include/asm/cacheflush.h | 2 - trunk/arch/powerpc/include/asm/debug.h | 2 +- trunk/arch/powerpc/include/asm/eeh.h | 141 +--- trunk/arch/powerpc/include/asm/eeh_event.h | 6 +- .../arch/powerpc/include/asm/exception-64e.h | 6 +- trunk/arch/powerpc/include/asm/fsl_guts.h | 2 - trunk/arch/powerpc/include/asm/fsl_ifc.h | 14 +- trunk/arch/powerpc/include/asm/hvcall.h | 5 + .../arch/powerpc/include/asm/hw_breakpoint.h | 9 +- trunk/arch/powerpc/include/asm/kprobes.h | 15 +- trunk/arch/powerpc/include/asm/kvm_book3s.h | 2 +- .../arch/powerpc/include/asm/kvm_book3s_asm.h | 1 + trunk/arch/powerpc/include/asm/machdep.h | 12 +- trunk/arch/powerpc/include/asm/mmu-hash64.h | 169 ++-- trunk/arch/powerpc/include/asm/mmu.h | 9 - trunk/arch/powerpc/include/asm/mpic.h | 19 - trunk/arch/powerpc/include/asm/paca.h | 3 +- trunk/arch/powerpc/include/asm/page_64.h | 10 +- trunk/arch/powerpc/include/asm/pci-bridge.h | 11 - .../powerpc/include/asm/pgtable-ppc64-4k.h | 4 +- .../powerpc/include/asm/pgtable-ppc64-64k.h | 2 +- .../arch/powerpc/include/asm/pgtable-ppc64.h | 19 +- trunk/arch/powerpc/include/asm/pgtable.h | 10 +- trunk/arch/powerpc/include/asm/ppc-opcode.h | 3 - trunk/arch/powerpc/include/asm/ppc-pci.h | 20 +- trunk/arch/powerpc/include/asm/probes.h | 42 - trunk/arch/powerpc/include/asm/processor.h | 6 +- .../arch/powerpc/include/asm/pte-hash64-64k.h | 18 +- trunk/arch/powerpc/include/asm/reg.h | 50 +- trunk/arch/powerpc/include/asm/setup.h | 2 +- trunk/arch/powerpc/include/asm/smp.h | 2 - trunk/arch/powerpc/include/asm/sparsemem.h | 4 +- trunk/arch/powerpc/include/asm/swiotlb.h | 6 - trunk/arch/powerpc/include/asm/thread_info.h | 7 +- trunk/arch/powerpc/include/asm/tlbflush.h | 7 +- trunk/arch/powerpc/include/asm/uaccess.h | 11 + trunk/arch/powerpc/include/asm/uprobes.h | 54 -- trunk/arch/powerpc/kernel/Makefile | 1 - trunk/arch/powerpc/kernel/asm-offsets.c | 2 +- .../arch/powerpc/kernel/cpu_setup_fsl_booke.S | 74 +- trunk/arch/powerpc/kernel/cputable.c | 4 - trunk/arch/powerpc/kernel/dma-swiotlb.c | 22 +- trunk/arch/powerpc/kernel/dma.c | 3 +- trunk/arch/powerpc/kernel/entry_32.S | 47 +- trunk/arch/powerpc/kernel/entry_64.S | 35 - trunk/arch/powerpc/kernel/exceptions-64e.S | 212 ++--- trunk/arch/powerpc/kernel/exceptions-64s.S | 127 +-- trunk/arch/powerpc/kernel/fadump.c | 3 +- trunk/arch/powerpc/kernel/head_fsl_booke.S | 46 +- trunk/arch/powerpc/kernel/hw_breakpoint.c | 25 +- trunk/arch/powerpc/kernel/ibmebus.c | 1 + trunk/arch/powerpc/kernel/irq.c | 8 +- trunk/arch/powerpc/kernel/machine_kexec.c | 14 +- trunk/arch/powerpc/kernel/paca.c | 1 - trunk/arch/powerpc/kernel/pci-common.c | 36 +- trunk/arch/powerpc/kernel/process.c | 16 +- trunk/arch/powerpc/kernel/prom.c | 4 +- trunk/arch/powerpc/kernel/prom_init.c | 2 +- trunk/arch/powerpc/kernel/ptrace.c | 3 - trunk/arch/powerpc/kernel/rtas_flash.c | 7 +- trunk/arch/powerpc/kernel/rtas_pci.c | 5 +- trunk/arch/powerpc/kernel/signal.c | 8 +- trunk/arch/powerpc/kernel/smp.c | 12 +- trunk/arch/powerpc/kernel/time.c | 8 +- trunk/arch/powerpc/kernel/traps.c | 1 - trunk/arch/powerpc/kernel/uprobes.c | 184 ----- trunk/arch/powerpc/kernel/vdso.c | 4 +- trunk/arch/powerpc/kernel/vio.c | 1 + trunk/arch/powerpc/kvm/book3s_32_mmu_host.c | 8 +- trunk/arch/powerpc/kvm/book3s_64_mmu_host.c | 17 +- trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S | 2 +- trunk/arch/powerpc/kvm/trace.h | 14 +- trunk/arch/powerpc/lib/sstep.c | 36 +- trunk/arch/powerpc/mm/fault.c | 1 - trunk/arch/powerpc/mm/hash_low_64.S | 97 +-- trunk/arch/powerpc/mm/hash_native_64.c | 166 ++-- trunk/arch/powerpc/mm/hash_utils_64.c | 48 +- trunk/arch/powerpc/mm/hugetlbpage-hash64.c | 15 +- trunk/arch/powerpc/mm/init_64.c | 1 + trunk/arch/powerpc/mm/mem.c | 5 +- trunk/arch/powerpc/mm/mmu_context_hash64.c | 10 +- trunk/arch/powerpc/mm/pgtable_64.c | 13 +- trunk/arch/powerpc/mm/slb_low.S | 62 +- trunk/arch/powerpc/mm/slice.c | 112 +-- trunk/arch/powerpc/mm/stab.c | 3 +- trunk/arch/powerpc/mm/subpage-prot.c | 6 +- trunk/arch/powerpc/mm/tlb_hash64.c | 11 +- trunk/arch/powerpc/mm/tlb_low_64e.S | 18 +- trunk/arch/powerpc/oprofile/op_model_power4.c | 116 +-- trunk/arch/powerpc/perf/core-book3s.c | 2 +- trunk/arch/powerpc/platforms/44x/currituck.c | 10 +- trunk/arch/powerpc/platforms/512x/clock.c | 6 +- trunk/arch/powerpc/platforms/85xx/Kconfig | 21 - trunk/arch/powerpc/platforms/85xx/Makefile | 2 - trunk/arch/powerpc/platforms/85xx/common.c | 10 - .../arch/powerpc/platforms/85xx/corenet_ds.c | 38 +- trunk/arch/powerpc/platforms/85xx/ge_imp3a.c | 62 +- .../arch/powerpc/platforms/85xx/mpc8536_ds.c | 36 +- .../arch/powerpc/platforms/85xx/mpc85xx_ads.c | 11 +- .../arch/powerpc/platforms/85xx/mpc85xx_cds.c | 44 +- .../arch/powerpc/platforms/85xx/mpc85xx_ds.c | 15 +- .../arch/powerpc/platforms/85xx/mpc85xx_mds.c | 40 +- .../arch/powerpc/platforms/85xx/mpc85xx_rdb.c | 30 +- trunk/arch/powerpc/platforms/85xx/p1010rdb.c | 14 +- trunk/arch/powerpc/platforms/85xx/p1022_ds.c | 36 +- trunk/arch/powerpc/platforms/85xx/p1022_rdk.c | 167 ---- trunk/arch/powerpc/platforms/85xx/p1023_rds.c | 9 +- trunk/arch/powerpc/platforms/85xx/p2041_rdb.c | 2 +- trunk/arch/powerpc/platforms/85xx/p3041_ds.c | 2 +- trunk/arch/powerpc/platforms/85xx/p4080_ds.c | 2 +- trunk/arch/powerpc/platforms/85xx/p5020_ds.c | 2 +- trunk/arch/powerpc/platforms/85xx/p5040_ds.c | 89 --- trunk/arch/powerpc/platforms/85xx/qemu_e500.c | 5 +- trunk/arch/powerpc/platforms/85xx/sbc8548.c | 21 +- trunk/arch/powerpc/platforms/85xx/smp.c | 220 +----- trunk/arch/powerpc/platforms/85xx/socrates.c | 11 +- trunk/arch/powerpc/platforms/85xx/stx_gp3.c | 13 +- trunk/arch/powerpc/platforms/85xx/tqm85xx.c | 21 +- .../arch/powerpc/platforms/85xx/xes_mpc85xx.c | 56 +- trunk/arch/powerpc/platforms/86xx/gef_ppc9a.c | 12 +- .../arch/powerpc/platforms/86xx/gef_sbc310.c | 13 +- .../arch/powerpc/platforms/86xx/gef_sbc610.c | 12 +- .../powerpc/platforms/86xx/mpc8610_hpcd.c | 21 +- .../powerpc/platforms/86xx/mpc86xx_hpcn.c | 42 +- trunk/arch/powerpc/platforms/86xx/sbc8641d.c | 14 +- trunk/arch/powerpc/platforms/cell/beat.c | 4 +- trunk/arch/powerpc/platforms/cell/beat.h | 2 +- trunk/arch/powerpc/platforms/cell/beat_htab.c | 45 +- trunk/arch/powerpc/platforms/pasemi/iommu.c | 6 +- .../arch/powerpc/platforms/powernv/pci-ioda.c | 734 ++++++++++++------ .../powerpc/platforms/powernv/pci-p5ioc2.c | 1 + trunk/arch/powerpc/platforms/powernv/pci.c | 7 +- trunk/arch/powerpc/platforms/powernv/pci.h | 21 +- trunk/arch/powerpc/platforms/ps3/htab.c | 22 +- trunk/arch/powerpc/platforms/ps3/setup.c | 10 +- trunk/arch/powerpc/platforms/pseries/Makefile | 5 +- trunk/arch/powerpc/platforms/pseries/eeh.c | 543 ++++++++++--- .../powerpc/platforms/pseries/eeh_cache.c | 59 +- .../arch/powerpc/platforms/pseries/eeh_dev.c | 14 +- .../powerpc/platforms/pseries/eeh_driver.c | 310 ++++---- .../powerpc/platforms/pseries/eeh_event.c | 54 +- trunk/arch/powerpc/platforms/pseries/eeh_pe.c | 655 ---------------- .../powerpc/platforms/pseries/eeh_pseries.c | 247 ++---- .../powerpc/platforms/pseries/eeh_sysfs.c | 9 + trunk/arch/powerpc/platforms/pseries/iommu.c | 12 +- trunk/arch/powerpc/platforms/pseries/lpar.c | 77 +- trunk/arch/powerpc/platforms/pseries/msi.c | 26 +- trunk/arch/powerpc/platforms/pseries/pci.c | 2 +- .../powerpc/platforms/pseries/pci_dlpar.c | 32 +- trunk/arch/powerpc/platforms/pseries/setup.c | 22 +- trunk/arch/powerpc/sysdev/Makefile | 2 +- trunk/arch/powerpc/sysdev/dart_iommu.c | 7 +- trunk/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c | 10 - trunk/arch/powerpc/sysdev/fsl_mpic_err.c | 149 ---- trunk/arch/powerpc/sysdev/fsl_pci.c | 118 ++- trunk/arch/powerpc/sysdev/fsl_pci.h | 20 +- trunk/arch/powerpc/sysdev/mpic.c | 102 +-- trunk/arch/powerpc/sysdev/mpic.h | 22 - trunk/arch/powerpc/xmon/xmon.c | 111 +-- trunk/arch/tile/kernel/pci.c | 26 +- trunk/drivers/crypto/nx/nx.c | 17 +- trunk/drivers/edac/mpc85xx_edac.c | 43 +- trunk/drivers/gpu/drm/radeon/evergreen.c | 10 +- trunk/drivers/infiniband/hw/ehca/ehca_cq.c | 2 +- trunk/drivers/infiniband/hw/ehca/ehca_eq.c | 2 +- trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c | 45 +- trunk/drivers/infiniband/hw/ehca/ehca_qp.c | 6 +- trunk/drivers/infiniband/hw/ehca/ehca_reqs.c | 2 +- trunk/drivers/infiniband/hw/ehca/ehca_tools.h | 1 + trunk/drivers/infiniband/hw/ehca/hcp_if.c | 12 +- trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.c | 2 +- .../drivers/infiniband/hw/mthca/mthca_reset.c | 8 +- trunk/drivers/infiniband/hw/qib/qib_pcie.c | 38 +- trunk/drivers/iommu/intel-iommu.c | 6 +- trunk/drivers/macintosh/smu.c | 3 +- .../net/ethernet/atheros/atl1c/atl1c_main.c | 2 +- .../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 18 +- trunk/drivers/net/ethernet/broadcom/tg3.c | 50 +- .../net/ethernet/chelsio/cxgb3/t3_hw.c | 22 +- .../net/ethernet/chelsio/cxgb4/cxgb4_main.c | 10 +- .../net/ethernet/chelsio/cxgb4/t4_hw.c | 6 +- trunk/drivers/net/ethernet/ibm/ehea/ehea.h | 1 + .../drivers/net/ethernet/ibm/ehea/ehea_phyp.c | 12 +- .../drivers/net/ethernet/ibm/ehea/ehea_qmr.c | 14 +- .../net/ethernet/intel/e1000e/netdev.c | 27 +- .../drivers/net/ethernet/intel/igb/igb_main.c | 12 +- .../net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +- .../net/ethernet/mellanox/mlx4/reset.c | 8 +- .../net/ethernet/myricom/myri10ge/myri10ge.c | 31 +- .../net/ethernet/neterion/vxge/vxge-config.c | 4 +- .../ethernet/qlogic/netxen/netxen_nic_main.c | 2 +- trunk/drivers/net/ethernet/realtek/r8169.c | 44 +- trunk/drivers/net/ethernet/sun/niu.c | 19 +- trunk/drivers/net/wireless/ath/ath9k/pci.c | 21 +- trunk/drivers/net/wireless/iwlegacy/common.h | 4 +- .../drivers/net/wireless/iwlwifi/pcie/trans.c | 7 +- trunk/drivers/net/wireless/rtlwifi/pci.c | 8 +- trunk/drivers/pci/access.c | 202 ----- trunk/drivers/pci/hotplug/pciehp_acpi.c | 6 +- trunk/drivers/pci/hotplug/pciehp_hpc.c | 12 +- trunk/drivers/pci/hotplug/pcihp_slot.c | 20 +- trunk/drivers/pci/hotplug/rpadlpar_core.c | 2 +- trunk/drivers/pci/iov.c | 6 +- trunk/drivers/pci/pci.c | 316 ++++++-- trunk/drivers/pci/pcie/aer/aer_inject.c | 2 +- trunk/drivers/pci/pcie/aer/aerdrv.c | 24 +- trunk/drivers/pci/pcie/aer/aerdrv_acpi.c | 2 +- trunk/drivers/pci/pcie/aer/aerdrv_core.c | 53 +- trunk/drivers/pci/pcie/aspm.c | 119 +-- trunk/drivers/pci/pcie/pme.c | 29 +- trunk/drivers/pci/pcie/portdrv_bus.c | 2 +- trunk/drivers/pci/pcie/portdrv_core.c | 19 +- trunk/drivers/pci/pcie/portdrv_pci.c | 17 +- trunk/drivers/pci/probe.c | 28 +- trunk/drivers/pci/quirks.c | 31 +- trunk/drivers/pci/search.c | 2 +- trunk/drivers/pci/setup-bus.c | 81 +- trunk/drivers/rapidio/devices/tsi721.c | 18 +- trunk/drivers/scsi/ipr.c | 18 +- trunk/drivers/scsi/qla2xxx/qla_nx.c | 8 +- trunk/drivers/scsi/qla4xxx/ql4_nx.c | 4 +- trunk/drivers/staging/et131x/et131x.c | 19 +- .../staging/rtl8192e/rtl8192e/rtl_pci.c | 8 +- trunk/drivers/tty/hvc/hvc_console.c | 33 +- trunk/drivers/tty/hvc/hvc_vio.c | 123 ++- trunk/drivers/video/ps3fb.c | 3 +- trunk/include/linux/pci.h | 46 +- trunk/include/linux/pci_regs.h | 1 - 281 files changed, 4012 insertions(+), 6495 deletions(-) delete mode 100644 trunk/arch/powerpc/boot/dts/fsl/e500mc_power_isa.dtsi delete mode 100644 trunk/arch/powerpc/boot/dts/fsl/e500v2_power_isa.dtsi delete mode 100644 trunk/arch/powerpc/boot/dts/fsl/e5500_power_isa.dtsi delete mode 100644 trunk/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi delete mode 100644 trunk/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi delete mode 100644 trunk/arch/powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi create mode 100644 trunk/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts create mode 100644 trunk/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts delete mode 100644 trunk/arch/powerpc/boot/dts/p1022rdk.dts create mode 100644 trunk/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts create mode 100644 trunk/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts delete mode 100644 trunk/arch/powerpc/boot/dts/p5040ds.dts create mode 100644 trunk/arch/powerpc/include/asm/abs_addr.h delete mode 100644 trunk/arch/powerpc/include/asm/probes.h delete mode 100644 trunk/arch/powerpc/include/asm/uprobes.h delete mode 100644 trunk/arch/powerpc/kernel/uprobes.c delete mode 100644 trunk/arch/powerpc/platforms/85xx/p1022_rdk.c delete mode 100644 trunk/arch/powerpc/platforms/85xx/p5040_ds.c delete mode 100644 trunk/arch/powerpc/platforms/pseries/eeh_pe.c delete mode 100644 trunk/arch/powerpc/sysdev/fsl_mpic_err.c diff --git a/[refs] b/[refs] index a29e3d1d7002..ac945d23acf6 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: caa1d631fc99940f866480c2bb88a6f5a235e7a2 +refs/heads/master: fca826460e55d4e8f2deceb09f22f9340a0db24c diff --git a/trunk/Documentation/devicetree/bindings/powerpc/fsl/ifc.txt b/trunk/Documentation/devicetree/bindings/powerpc/fsl/ifc.txt index d5e370450ac0..939a26d541f6 100644 --- a/trunk/Documentation/devicetree/bindings/powerpc/fsl/ifc.txt +++ b/trunk/Documentation/devicetree/bindings/powerpc/fsl/ifc.txt @@ -12,12 +12,9 @@ Properties: - #size-cells : Either one or two, depending on how large each chipselect can be. - reg : Offset and length of the register set for the device -- interrupts: IFC may have one or two interrupts. If two interrupt - specifiers are present, the first is the "common" - interrupt (CM_EVTER_STAT), and the second is the NAND - interrupt (NAND_EVTER_STAT). If there is only one, - that interrupt reports both types of event. - +- interrupts : IFC has two interrupts. The first one is the "common" + interrupt(CM_EVTER_STAT), and second is the NAND interrupt + (NAND_EVTER_STAT). - ranges : Each range corresponds to a single chipselect, and covers the entire access window as configured. diff --git a/trunk/arch/arm/mach-tegra/pcie.c b/trunk/arch/arm/mach-tegra/pcie.c index c25a2a4f2e3d..d3ad5150d660 100644 --- a/trunk/arch/arm/mach-tegra/pcie.c +++ b/trunk/arch/arm/mach-tegra/pcie.c @@ -367,7 +367,17 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_fixup_class); /* Tegra PCIE requires relaxed ordering */ static void __devinit tegra_pcie_relax_enable(struct pci_dev *dev) { - pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN); + u16 val16; + int pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + + if (pos <= 0) { + dev_err(&dev->dev, "skipping relaxed ordering fixup\n"); + return; + } + + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &val16); + val16 |= PCI_EXP_DEVCTL_RELAX_EN; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, val16); } DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable); diff --git a/trunk/arch/mips/pci/pci-octeon.c b/trunk/arch/mips/pci/pci-octeon.c index c5dfb2c87d44..52a1ba70b3b6 100644 --- a/trunk/arch/mips/pci/pci-octeon.c +++ b/trunk/arch/mips/pci/pci-octeon.c @@ -117,11 +117,16 @@ int pcibios_plat_dev_init(struct pci_dev *dev) } /* Enable the PCIe normal error reporting */ - config = PCI_EXP_DEVCTL_CERE; /* Correctable Error Reporting */ - config |= PCI_EXP_DEVCTL_NFERE; /* Non-Fatal Error Reporting */ - config |= PCI_EXP_DEVCTL_FERE; /* Fatal Error Reporting */ - config |= PCI_EXP_DEVCTL_URRE; /* Unsupported Request */ - pcie_capability_set_word(dev, PCI_EXP_DEVCTL, config); + pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (pos) { + /* Update Device Control */ + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config); + config |= PCI_EXP_DEVCTL_CERE; /* Correctable Error Reporting */ + config |= PCI_EXP_DEVCTL_NFERE; /* Non-Fatal Error Reporting */ + config |= PCI_EXP_DEVCTL_FERE; /* Fatal Error Reporting */ + config |= PCI_EXP_DEVCTL_URRE; /* Unsupported Request */ + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config); + } /* Find the Advanced Error Reporting capability */ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 4ce0be32d153..352f416269ce 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -215,8 +215,7 @@ config ARCH_HIBERNATION_POSSIBLE config ARCH_SUSPEND_POSSIBLE def_bool y depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ - (PPC_85xx && !PPC_E500MC) || PPC_86xx || PPC_PSERIES \ - || 44x || 40x + (PPC_85xx && !SMP) || PPC_86xx || PPC_PSERIES || 44x || 40x config PPC_DCR_NATIVE bool @@ -240,9 +239,6 @@ config PPC_OF_PLATFORM_PCI config ARCH_SUPPORTS_DEBUG_PAGEALLOC def_bool y -config ARCH_SUPPORTS_UPROBES - def_bool y - config PPC_ADV_DEBUG_REGS bool depends on 40x || BOOKE @@ -329,8 +325,7 @@ config SWIOTLB config HOTPLUG_CPU bool "Support for enabling/disabling CPUs" - depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || \ - PPC_PMAC || PPC_POWERNV || (PPC_85xx && !PPC_E500MC)) + depends on SMP && HOTPLUG && EXPERIMENTAL && (PPC_PSERIES || PPC_PMAC || PPC_POWERNV) ---help--- Say Y here to be able to disable and re-enable individual CPUs at runtime on SMP machines. @@ -562,14 +557,6 @@ config SCHED_SMT when dealing with POWER5 cpus at a cost of slightly increased overhead in some places. If unsure say N here. -config PPC_DENORMALISATION - bool "PowerPC denormalisation exception handling" - depends on PPC_BOOK3S_64 - default "n" - ---help--- - Add support for handling denormalisation of single precision - values. Useful for bare metal only. If unsure say Y here. - config CMDLINE_BOOL bool "Default bootloader kernel arguments" diff --git a/trunk/arch/powerpc/boot/Makefile b/trunk/arch/powerpc/boot/Makefile index 6a15c968d214..b7d833382be4 100644 --- a/trunk/arch/powerpc/boot/Makefile +++ b/trunk/arch/powerpc/boot/Makefile @@ -107,7 +107,6 @@ src-boot := $(addprefix $(obj)/, $(src-boot)) obj-boot := $(addsuffix .o, $(basename $(src-boot))) obj-wlib := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-wlib)))) obj-plat := $(addsuffix .o, $(basename $(addprefix $(obj)/, $(src-plat)))) -obj-plat: $(libfdt) quiet_cmd_copy_zlib = COPY $@ cmd_copy_zlib = sed "s@__used@@;s@]*\).*@\"\1\"@" $< > $@ diff --git a/trunk/arch/powerpc/boot/dts/fsl/e500mc_power_isa.dtsi b/trunk/arch/powerpc/boot/dts/fsl/e500mc_power_isa.dtsi deleted file mode 100644 index 870c6535a053..000000000000 --- a/trunk/arch/powerpc/boot/dts/fsl/e500mc_power_isa.dtsi +++ /dev/null @@ -1,58 +0,0 @@ -/* - * e500mc Power ISA Device Tree Source (include) - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/ { - cpus { - power-isa-version = "2.06"; - power-isa-b; // Base - power-isa-e; // Embedded - power-isa-atb; // Alternate Time Base - power-isa-cs; // Cache Specification - power-isa-ds; // Decorated Storage - power-isa-e.ed; // Embedded.Enhanced Debug - power-isa-e.pd; // Embedded.External PID - power-isa-e.hv; // Embedded.Hypervisor - power-isa-e.le; // Embedded.Little-Endian - power-isa-e.pm; // Embedded.Performance Monitor - power-isa-e.pc; // Embedded.Processor Control - power-isa-ecl; // Embedded Cache Locking - power-isa-exp; // External Proxy - power-isa-fp; // Floating Point - power-isa-fp.r; // Floating Point.Record - power-isa-mmc; // Memory Coherence - power-isa-scpm; // Store Conditional Page Mobility - power-isa-wt; // Wait - mmu-type = "power-embedded"; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/fsl/e500v2_power_isa.dtsi b/trunk/arch/powerpc/boot/dts/fsl/e500v2_power_isa.dtsi deleted file mode 100644 index f4928144d2c8..000000000000 --- a/trunk/arch/powerpc/boot/dts/fsl/e500v2_power_isa.dtsi +++ /dev/null @@ -1,52 +0,0 @@ -/* - * e500v2 Power ISA Device Tree Source (include) - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/ { - cpus { - power-isa-version = "2.03"; - power-isa-b; // Base - power-isa-e; // Embedded - power-isa-atb; // Alternate Time Base - power-isa-cs; // Cache Specification - power-isa-e.le; // Embedded.Little-Endian - power-isa-e.pm; // Embedded.Performance Monitor - power-isa-ecl; // Embedded Cache Locking - power-isa-mmc; // Memory Coherence - power-isa-sp; // Signal Processing Engine - power-isa-sp.fd; // SPE.Embedded Float Scalar Double - power-isa-sp.fs; // SPE.Embedded Float Scalar Single - power-isa-sp.fv; // SPE.Embedded Float Vector - mmu-type = "power-embedded"; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/fsl/e5500_power_isa.dtsi b/trunk/arch/powerpc/boot/dts/fsl/e5500_power_isa.dtsi deleted file mode 100644 index 3230212f7ad5..000000000000 --- a/trunk/arch/powerpc/boot/dts/fsl/e5500_power_isa.dtsi +++ /dev/null @@ -1,59 +0,0 @@ -/* - * e5500 Power ISA Device Tree Source (include) - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/ { - cpus { - power-isa-version = "2.06"; - power-isa-b; // Base - power-isa-e; // Embedded - power-isa-atb; // Alternate Time Base - power-isa-cs; // Cache Specification - power-isa-ds; // Decorated Storage - power-isa-e.ed; // Embedded.Enhanced Debug - power-isa-e.pd; // Embedded.External PID - power-isa-e.hv; // Embedded.Hypervisor - power-isa-e.le; // Embedded.Little-Endian - power-isa-e.pm; // Embedded.Performance Monitor - power-isa-e.pc; // Embedded.Processor Control - power-isa-ecl; // Embedded Cache Locking - power-isa-exp; // External Proxy - power-isa-fp; // Floating Point - power-isa-fp.r; // Floating Point.Record - power-isa-mmc; // Memory Coherence - power-isa-scpm; // Store Conditional Page Mobility - power-isa-wt; // Wait - power-isa-64; // 64-bit - mmu-type = "power-embedded"; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/fsl/mpc8536si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/mpc8536si-pre.dtsi index 152906f98a0f..7de45a784df6 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/mpc8536si-pre.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/mpc8536si-pre.dtsi @@ -33,9 +33,6 @@ */ /dts-v1/; - -/include/ "e500v2_power_isa.dtsi" - / { compatible = "fsl,MPC8536"; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/fsl/mpc8544si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/mpc8544si-pre.dtsi index 5a69bafb652a..8777f9239d9e 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/mpc8544si-pre.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/mpc8544si-pre.dtsi @@ -33,9 +33,6 @@ */ /dts-v1/; - -/include/ "e500v2_power_isa.dtsi" - / { compatible = "fsl,MPC8544"; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/fsl/mpc8548si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/mpc8548si-pre.dtsi index fc1ce977422b..720422d83529 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/mpc8548si-pre.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/mpc8548si-pre.dtsi @@ -33,9 +33,6 @@ */ /dts-v1/; - -/include/ "e500v2_power_isa.dtsi" - / { compatible = "fsl,MPC8548"; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/fsl/mpc8568si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/mpc8568si-pre.dtsi index 122ca3bd0b03..eacd62c5fe6c 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/mpc8568si-pre.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/mpc8568si-pre.dtsi @@ -33,9 +33,6 @@ */ /dts-v1/; - -/include/ "e500v2_power_isa.dtsi" - / { compatible = "fsl,MPC8568"; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/fsl/mpc8569si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/mpc8569si-pre.dtsi index 2cd15a2a0422..b07064d11930 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/mpc8569si-pre.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/mpc8569si-pre.dtsi @@ -33,9 +33,6 @@ */ /dts-v1/; - -/include/ "e500v2_power_isa.dtsi" - / { compatible = "fsl,MPC8569"; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/fsl/mpc8572si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/mpc8572si-pre.dtsi index 28c2a862be96..ca188326c2ca 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/mpc8572si-pre.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/mpc8572si-pre.dtsi @@ -33,9 +33,6 @@ */ /dts-v1/; - -/include/ "e500v2_power_isa.dtsi" - / { compatible = "fsl,MPC8572"; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/fsl/p1010si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p1010si-pre.dtsi index 6e76f9b282a1..7354a8f90ea5 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/p1010si-pre.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/p1010si-pre.dtsi @@ -33,9 +33,6 @@ */ /dts-v1/; - -/include/ "e500v2_power_isa.dtsi" - / { compatible = "fsl,P1010"; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/fsl/p1020si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p1020si-pre.dtsi index fed9c4c8d962..6f0376e554eb 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/p1020si-pre.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/p1020si-pre.dtsi @@ -33,9 +33,6 @@ */ /dts-v1/; - -/include/ "e500v2_power_isa.dtsi" - / { compatible = "fsl,P1020"; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/fsl/p1021si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p1021si-pre.dtsi index 36161b500176..4abd54bc3308 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/p1021si-pre.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/p1021si-pre.dtsi @@ -33,9 +33,6 @@ */ /dts-v1/; - -/include/ "e500v2_power_isa.dtsi" - / { compatible = "fsl,P1021"; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/fsl/p1022si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p1022si-pre.dtsi index 1956dea040cc..e930f4f7ca89 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/p1022si-pre.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/p1022si-pre.dtsi @@ -33,9 +33,6 @@ */ /dts-v1/; - -/include/ "e500v2_power_isa.dtsi" - / { compatible = "fsl,P1022"; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/fsl/p1023si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p1023si-pre.dtsi index 132a1521921a..ac45f6d93385 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/p1023si-pre.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/p1023si-pre.dtsi @@ -33,9 +33,6 @@ */ /dts-v1/; - -/include/ "e500v2_power_isa.dtsi" - / { compatible = "fsl,P1023"; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/fsl/p2020si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p2020si-pre.dtsi index 42bf3c6d25ca..3213288641d1 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/p2020si-pre.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/p2020si-pre.dtsi @@ -33,9 +33,6 @@ */ /dts-v1/; - -/include/ "e500v2_power_isa.dtsi" - / { compatible = "fsl,P2020"; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi index 7a2697d04549..2d0a40d6b10f 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/p2041si-pre.dtsi @@ -33,9 +33,6 @@ */ /dts-v1/; - -/include/ "e500mc_power_isa.dtsi" - / { compatible = "fsl,P2041"; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi index c9ca2c305cfe..136def3536b6 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/p3041si-pre.dtsi @@ -33,9 +33,6 @@ */ /dts-v1/; - -/include/ "e500mc_power_isa.dtsi" - / { compatible = "fsl,P3041"; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi index 493d9a056b5c..b9556ee3a639 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/p4080si-pre.dtsi @@ -33,9 +33,6 @@ */ /dts-v1/; - -/include/ "e500mc_power_isa.dtsi" - / { compatible = "fsl,P4080"; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi index 0a198b0a77e5..ae823a47584e 100644 --- a/trunk/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi +++ b/trunk/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi @@ -33,9 +33,6 @@ */ /dts-v1/; - -/include/ "e5500_power_isa.dtsi" - / { compatible = "fsl,P5020"; #address-cells = <2>; diff --git a/trunk/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi deleted file mode 100644 index db2c9a7b3a0e..000000000000 --- a/trunk/arch/powerpc/boot/dts/fsl/p5040si-post.dtsi +++ /dev/null @@ -1,320 +0,0 @@ -/* - * P5040 Silicon/SoC Device Tree Source (post include) - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * This software is provided by Freescale Semiconductor "as is" and any - * express or implied warranties, including, but not limited to, the implied - * warranties of merchantability and fitness for a particular purpose are - * disclaimed. In no event shall Freescale Semiconductor be liable for any - * direct, indirect, incidental, special, exemplary, or consequential damages - * (including, but not limited to, procurement of substitute goods or services; - * loss of use, data, or profits; or business interruption) however caused and - * on any theory of liability, whether in contract, strict liability, or tort - * (including negligence or otherwise) arising in any way out of the use of this - * software, even if advised of the possibility of such damage. - */ - -&lbc { - compatible = "fsl,p5040-elbc", "fsl,elbc", "simple-bus"; - interrupts = <25 2 0 0>; - #address-cells = <2>; - #size-cells = <1>; -}; - -/* controller at 0x200000 */ -&pci0 { - compatible = "fsl,p5040-pcie", "fsl,qoriq-pcie-v2.4"; - device_type = "pci"; - #size-cells = <2>; - #address-cells = <3>; - bus-range = <0x0 0xff>; - clock-frequency = <33333333>; - interrupts = <16 2 1 15>; - pcie@0 { - reg = <0 0 0 0 0>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - interrupts = <16 2 1 15>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = < - /* IDSEL 0x0 */ - 0000 0 0 1 &mpic 40 1 0 0 - 0000 0 0 2 &mpic 1 1 0 0 - 0000 0 0 3 &mpic 2 1 0 0 - 0000 0 0 4 &mpic 3 1 0 0 - >; - }; -}; - -/* controller at 0x201000 */ -&pci1 { - compatible = "fsl,p5040-pcie", "fsl,qoriq-pcie-v2.4"; - device_type = "pci"; - #size-cells = <2>; - #address-cells = <3>; - bus-range = <0 0xff>; - clock-frequency = <33333333>; - interrupts = <16 2 1 14>; - pcie@0 { - reg = <0 0 0 0 0>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - interrupts = <16 2 1 14>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = < - /* IDSEL 0x0 */ - 0000 0 0 1 &mpic 41 1 0 0 - 0000 0 0 2 &mpic 5 1 0 0 - 0000 0 0 3 &mpic 6 1 0 0 - 0000 0 0 4 &mpic 7 1 0 0 - >; - }; -}; - -/* controller at 0x202000 */ -&pci2 { - compatible = "fsl,p5040-pcie", "fsl,qoriq-pcie-v2.4"; - device_type = "pci"; - #size-cells = <2>; - #address-cells = <3>; - bus-range = <0x0 0xff>; - clock-frequency = <33333333>; - interrupts = <16 2 1 13>; - pcie@0 { - reg = <0 0 0 0 0>; - #interrupt-cells = <1>; - #size-cells = <2>; - #address-cells = <3>; - device_type = "pci"; - interrupts = <16 2 1 13>; - interrupt-map-mask = <0xf800 0 0 7>; - interrupt-map = < - /* IDSEL 0x0 */ - 0000 0 0 1 &mpic 42 1 0 0 - 0000 0 0 2 &mpic 9 1 0 0 - 0000 0 0 3 &mpic 10 1 0 0 - 0000 0 0 4 &mpic 11 1 0 0 - >; - }; -}; - -&dcsr { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,dcsr", "simple-bus"; - - dcsr-epu@0 { - compatible = "fsl,dcsr-epu"; - interrupts = <52 2 0 0 - 84 2 0 0 - 85 2 0 0>; - reg = <0x0 0x1000>; - }; - dcsr-npc { - compatible = "fsl,dcsr-npc"; - reg = <0x1000 0x1000 0x1000000 0x8000>; - }; - dcsr-nxc@2000 { - compatible = "fsl,dcsr-nxc"; - reg = <0x2000 0x1000>; - }; - dcsr-corenet { - compatible = "fsl,dcsr-corenet"; - reg = <0x8000 0x1000 0xB0000 0x1000>; - }; - dcsr-dpaa@9000 { - compatible = "fsl,p5040-dcsr-dpaa", "fsl,dcsr-dpaa"; - reg = <0x9000 0x1000>; - }; - dcsr-ocn@11000 { - compatible = "fsl,p5040-dcsr-ocn", "fsl,dcsr-ocn"; - reg = <0x11000 0x1000>; - }; - dcsr-ddr@12000 { - compatible = "fsl,dcsr-ddr"; - dev-handle = <&ddr1>; - reg = <0x12000 0x1000>; - }; - dcsr-ddr@13000 { - compatible = "fsl,dcsr-ddr"; - dev-handle = <&ddr2>; - reg = <0x13000 0x1000>; - }; - dcsr-nal@18000 { - compatible = "fsl,p5040-dcsr-nal", "fsl,dcsr-nal"; - reg = <0x18000 0x1000>; - }; - dcsr-rcpm@22000 { - compatible = "fsl,p5040-dcsr-rcpm", "fsl,dcsr-rcpm"; - reg = <0x22000 0x1000>; - }; - dcsr-cpu-sb-proxy@40000 { - compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; - cpu-handle = <&cpu0>; - reg = <0x40000 0x1000>; - }; - dcsr-cpu-sb-proxy@41000 { - compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; - cpu-handle = <&cpu1>; - reg = <0x41000 0x1000>; - }; - dcsr-cpu-sb-proxy@42000 { - compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; - cpu-handle = <&cpu2>; - reg = <0x42000 0x1000>; - }; - dcsr-cpu-sb-proxy@43000 { - compatible = "fsl,dcsr-e5500-sb-proxy", "fsl,dcsr-cpu-sb-proxy"; - cpu-handle = <&cpu3>; - reg = <0x43000 0x1000>; - }; -}; - -&soc { - #address-cells = <1>; - #size-cells = <1>; - device_type = "soc"; - compatible = "simple-bus"; - - soc-sram-error { - compatible = "fsl,soc-sram-error"; - interrupts = <16 2 1 29>; - }; - - corenet-law@0 { - compatible = "fsl,corenet-law"; - reg = <0x0 0x1000>; - fsl,num-laws = <32>; - }; - - ddr1: memory-controller@8000 { - compatible = "fsl,qoriq-memory-controller-v4.5", "fsl,qoriq-memory-controller"; - reg = <0x8000 0x1000>; - interrupts = <16 2 1 23>; - }; - - ddr2: memory-controller@9000 { - compatible = "fsl,qoriq-memory-controller-v4.5","fsl,qoriq-memory-controller"; - reg = <0x9000 0x1000>; - interrupts = <16 2 1 22>; - }; - - cpc: l3-cache-controller@10000 { - compatible = "fsl,p5040-l3-cache-controller", "fsl,p4080-l3-cache-controller", "cache"; - reg = <0x10000 0x1000 - 0x11000 0x1000>; - interrupts = <16 2 1 27 - 16 2 1 26>; - }; - - corenet-cf@18000 { - compatible = "fsl,corenet-cf"; - reg = <0x18000 0x1000>; - interrupts = <16 2 1 31>; - fsl,ccf-num-csdids = <32>; - fsl,ccf-num-snoopids = <32>; - }; - - iommu@20000 { - compatible = "fsl,pamu-v1.0", "fsl,pamu"; - reg = <0x20000 0x5000>; - interrupts = < - 24 2 0 0 - 16 2 1 30>; - }; - -/include/ "qoriq-mpic.dtsi" - - guts: global-utilities@e0000 { - compatible = "fsl,p5040-device-config", "fsl,qoriq-device-config-1.0"; - reg = <0xe0000 0xe00>; - fsl,has-rstcr; - #sleep-cells = <1>; - fsl,liodn-bits = <12>; - }; - - pins: global-utilities@e0e00 { - compatible = "fsl,p5040-pin-control", "fsl,qoriq-pin-control-1.0"; - reg = <0xe0e00 0x200>; - #sleep-cells = <2>; - }; - - clockgen: global-utilities@e1000 { - compatible = "fsl,p5040-clockgen", "fsl,qoriq-clockgen-1.0"; - reg = <0xe1000 0x1000>; - clock-frequency = <0>; - }; - - rcpm: global-utilities@e2000 { - compatible = "fsl,p5040-rcpm", "fsl,qoriq-rcpm-1.0"; - reg = <0xe2000 0x1000>; - #sleep-cells = <1>; - }; - - sfp: sfp@e8000 { - compatible = "fsl,p5040-sfp", "fsl,qoriq-sfp-1.0"; - reg = <0xe8000 0x1000>; - }; - - serdes: serdes@ea000 { - compatible = "fsl,p5040-serdes"; - reg = <0xea000 0x1000>; - }; - -/include/ "qoriq-dma-0.dtsi" -/include/ "qoriq-dma-1.dtsi" -/include/ "qoriq-espi-0.dtsi" - spi@110000 { - fsl,espi-num-chipselects = <4>; - }; - -/include/ "qoriq-esdhc-0.dtsi" - sdhc@114000 { - sdhci,auto-cmd12; - }; - -/include/ "qoriq-i2c-0.dtsi" -/include/ "qoriq-i2c-1.dtsi" -/include/ "qoriq-duart-0.dtsi" -/include/ "qoriq-duart-1.dtsi" -/include/ "qoriq-gpio-0.dtsi" -/include/ "qoriq-usb2-mph-0.dtsi" - usb0: usb@210000 { - compatible = "fsl-usb2-mph-v1.6", "fsl,mpc85xx-usb2-mph", "fsl-usb2-mph"; - phy_type = "utmi"; - port0; - }; - -/include/ "qoriq-usb2-dr-0.dtsi" - usb1: usb@211000 { - compatible = "fsl-usb2-dr-v1.6", "fsl,mpc85xx-usb2-dr", "fsl-usb2-dr"; - dr_mode = "host"; - phy_type = "utmi"; - }; - -/include/ "qoriq-sata2-0.dtsi" -/include/ "qoriq-sata2-1.dtsi" -/include/ "qoriq-sec5.2-0.dtsi" -}; diff --git a/trunk/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi b/trunk/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi deleted file mode 100644 index 40ca943f5d1c..000000000000 --- a/trunk/arch/powerpc/boot/dts/fsl/p5040si-pre.dtsi +++ /dev/null @@ -1,114 +0,0 @@ -/* - * P5040 Silicon/SoC Device Tree Source (pre include) - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * This software is provided by Freescale Semiconductor "as is" and any - * express or implied warranties, including, but not limited to, the implied - * warranties of merchantability and fitness for a particular purpose are - * disclaimed. In no event shall Freescale Semiconductor be liable for any - * direct, indirect, incidental, special, exemplary, or consequential damages - * (including, but not limited to, procurement of substitute goods or services; - * loss of use, data, or profits; or business interruption) however caused and - * on any theory of liability, whether in contract, strict liability, or tort - * (including negligence or otherwise) arising in any way out of the use of this - * software, even if advised of the possibility of such damage. - */ - -/dts-v1/; - -/include/ "e5500_power_isa.dtsi" - -/ { - compatible = "fsl,P5040"; - #address-cells = <2>; - #size-cells = <2>; - interrupt-parent = <&mpic>; - - aliases { - ccsr = &soc; - dcsr = &dcsr; - - serial0 = &serial0; - serial1 = &serial1; - serial2 = &serial2; - serial3 = &serial3; - pci0 = &pci0; - pci1 = &pci1; - pci2 = &pci2; - usb0 = &usb0; - usb1 = &usb1; - dma0 = &dma0; - dma1 = &dma1; - sdhc = &sdhc; - msi0 = &msi0; - msi1 = &msi1; - msi2 = &msi2; - - crypto = &crypto; - sec_jr0 = &sec_jr0; - sec_jr1 = &sec_jr1; - sec_jr2 = &sec_jr2; - sec_jr3 = &sec_jr3; - rtic_a = &rtic_a; - rtic_b = &rtic_b; - rtic_c = &rtic_c; - rtic_d = &rtic_d; - sec_mon = &sec_mon; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu0: PowerPC,e5500@0 { - device_type = "cpu"; - reg = <0>; - next-level-cache = <&L2_0>; - L2_0: l2-cache { - next-level-cache = <&cpc>; - }; - }; - cpu1: PowerPC,e5500@1 { - device_type = "cpu"; - reg = <1>; - next-level-cache = <&L2_1>; - L2_1: l2-cache { - next-level-cache = <&cpc>; - }; - }; - cpu2: PowerPC,e5500@2 { - device_type = "cpu"; - reg = <2>; - next-level-cache = <&L2_2>; - L2_2: l2-cache { - next-level-cache = <&cpc>; - }; - }; - cpu3: PowerPC,e5500@3 { - device_type = "cpu"; - reg = <3>; - next-level-cache = <&L2_3>; - L2_3: l2-cache { - next-level-cache = <&cpc>; - }; - }; - }; -}; diff --git a/trunk/arch/powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi b/trunk/arch/powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi deleted file mode 100644 index 7b2ab8a8c1f4..000000000000 --- a/trunk/arch/powerpc/boot/dts/fsl/qoriq-sec5.2-0.dtsi +++ /dev/null @@ -1,118 +0,0 @@ -/* - * QorIQ Sec/Crypto 5.2 device tree stub [ controller @ offset 0x300000 ] - * - * Copyright 2011-2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -crypto: crypto@300000 { - compatible = "fsl,sec-v5.2", "fsl,sec-v5.0", "fsl,sec-v4.0"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0x300000 0x10000>; - ranges = <0 0x300000 0x10000>; - interrupts = <92 2 0 0>; - - sec_jr0: jr@1000 { - compatible = "fsl,sec-v5.2-job-ring", - "fsl,sec-v5.0-job-ring", - "fsl,sec-v4.0-job-ring"; - reg = <0x1000 0x1000>; - interrupts = <88 2 0 0>; - }; - - sec_jr1: jr@2000 { - compatible = "fsl,sec-v5.2-job-ring", - "fsl,sec-v5.0-job-ring", - "fsl,sec-v4.0-job-ring"; - reg = <0x2000 0x1000>; - interrupts = <89 2 0 0>; - }; - - sec_jr2: jr@3000 { - compatible = "fsl,sec-v5.2-job-ring", - "fsl,sec-v5.0-job-ring", - "fsl,sec-v4.0-job-ring"; - reg = <0x3000 0x1000>; - interrupts = <90 2 0 0>; - }; - - sec_jr3: jr@4000 { - compatible = "fsl,sec-v5.2-job-ring", - "fsl,sec-v5.0-job-ring", - "fsl,sec-v4.0-job-ring"; - reg = <0x4000 0x1000>; - interrupts = <91 2 0 0>; - }; - - rtic@6000 { - compatible = "fsl,sec-v5.2-rtic", - "fsl,sec-v5.0-rtic", - "fsl,sec-v4.0-rtic"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0x6000 0x100>; - ranges = <0x0 0x6100 0xe00>; - - rtic_a: rtic-a@0 { - compatible = "fsl,sec-v5.2-rtic-memory", - "fsl,sec-v5.0-rtic-memory", - "fsl,sec-v4.0-rtic-memory"; - reg = <0x00 0x20 0x100 0x80>; - }; - - rtic_b: rtic-b@20 { - compatible = "fsl,sec-v5.2-rtic-memory", - "fsl,sec-v5.0-rtic-memory", - "fsl,sec-v4.0-rtic-memory"; - reg = <0x20 0x20 0x200 0x80>; - }; - - rtic_c: rtic-c@40 { - compatible = "fsl,sec-v5.2-rtic-memory", - "fsl,sec-v5.0-rtic-memory", - "fsl,sec-v4.0-rtic-memory"; - reg = <0x40 0x20 0x300 0x80>; - }; - - rtic_d: rtic-d@60 { - compatible = "fsl,sec-v5.2-rtic-memory", - "fsl,sec-v5.0-rtic-memory", - "fsl,sec-v4.0-rtic-memory"; - reg = <0x60 0x20 0x500 0x80>; - }; - }; -}; - -sec_mon: sec_mon@314000 { - compatible = "fsl,sec-v5.2-mon", "fsl,sec-v5.0-mon", "fsl,sec-v4.0-mon"; - reg = <0x314000 0x1000>; - interrupts = <93 2 0 0>; -}; diff --git a/trunk/arch/powerpc/boot/dts/mpc8536ds.dtsi b/trunk/arch/powerpc/boot/dts/mpc8536ds.dtsi index 7c3dde84d193..d304a2d68c62 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8536ds.dtsi +++ b/trunk/arch/powerpc/boot/dts/mpc8536ds.dtsi @@ -132,10 +132,6 @@ reg = <0x68>; interrupts = <0 0x1 0 0>; }; - adt7461@4c { - compatible = "adi,adt7461"; - reg = <0x4c>; - }; }; spi@7000 { diff --git a/trunk/arch/powerpc/boot/dts/mpc8540ads.dts b/trunk/arch/powerpc/boot/dts/mpc8540ads.dts index 2d31863accf5..f99fb110c97f 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8540ads.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8540ads.dts @@ -11,8 +11,6 @@ /dts-v1/; -/include/ "fsl/e500v2_power_isa.dtsi" - / { model = "MPC8540ADS"; compatible = "MPC8540ADS", "MPC85xxADS"; diff --git a/trunk/arch/powerpc/boot/dts/mpc8541cds.dts b/trunk/arch/powerpc/boot/dts/mpc8541cds.dts index 1c03c2667373..0f5e93912799 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8541cds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8541cds.dts @@ -11,8 +11,6 @@ /dts-v1/; -/include/ "fsl/e500v2_power_isa.dtsi" - / { model = "MPC8541CDS"; compatible = "MPC8541CDS", "MPC85xxCDS"; diff --git a/trunk/arch/powerpc/boot/dts/mpc8544ds.dts b/trunk/arch/powerpc/boot/dts/mpc8544ds.dts index ed38874c3a36..e934987e882b 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8544ds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8544ds.dts @@ -20,10 +20,8 @@ reg = <0 0 0 0>; // Filled by U-Boot }; - board_lbc: lbc: localbus@e0005000 { + lbc: localbus@e0005000 { reg = <0 0xe0005000 0 0x1000>; - - ranges = <0x0 0x0 0x0 0xff800000 0x800000>; }; board_soc: soc: soc8544@e0000000 { diff --git a/trunk/arch/powerpc/boot/dts/mpc8544ds.dtsi b/trunk/arch/powerpc/boot/dts/mpc8544ds.dtsi index b219d035d794..77ebc9f1d37c 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8544ds.dtsi +++ b/trunk/arch/powerpc/boot/dts/mpc8544ds.dtsi @@ -32,45 +32,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -&board_lbc { - nor@0,0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "cfi-flash"; - reg = <0x0 0x0 0x800000>; - bank-width = <2>; - device-width = <1>; - - partition@0 { - reg = <0x0 0x10000>; - label = "dtb-nor"; - }; - - partition@20000 { - reg = <0x20000 0x30000>; - label = "diagnostic-nor"; - read-only; - }; - - partition@200000 { - reg = <0x200000 0x200000>; - label = "dink-nor"; - read-only; - }; - - partition@400000 { - reg = <0x400000 0x380000>; - label = "kernel-nor"; - }; - - partition@780000 { - reg = <0x780000 0x80000>; - label = "u-boot-nor"; - read-only; - }; - }; -}; - &board_soc { enet0: ethernet@24000 { phy-handle = <&phy0>; diff --git a/trunk/arch/powerpc/boot/dts/mpc8555cds.dts b/trunk/arch/powerpc/boot/dts/mpc8555cds.dts index 36a7ea138c2f..fe10438613d6 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8555cds.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8555cds.dts @@ -11,8 +11,6 @@ /dts-v1/; -/include/ "fsl/e500v2_power_isa.dtsi" - / { model = "MPC8555CDS"; compatible = "MPC8555CDS", "MPC85xxCDS"; diff --git a/trunk/arch/powerpc/boot/dts/mpc8560ads.dts b/trunk/arch/powerpc/boot/dts/mpc8560ads.dts index 1a43f5a968f5..6e85e1ba0851 100644 --- a/trunk/arch/powerpc/boot/dts/mpc8560ads.dts +++ b/trunk/arch/powerpc/boot/dts/mpc8560ads.dts @@ -11,8 +11,6 @@ /dts-v1/; -/include/ "fsl/e500v2_power_isa.dtsi" - / { model = "MPC8560ADS"; compatible = "MPC8560ADS", "MPC85xxADS"; diff --git a/trunk/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts b/trunk/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts new file mode 100644 index 000000000000..41b4585c5da8 --- /dev/null +++ b/trunk/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts @@ -0,0 +1,63 @@ +/* + * P1020 RDB Core0 Device Tree Source in CAMP mode. + * + * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache + * can be shared, all the other devices must be assigned to one core only. + * This dts file allows core0 to have memory, l2, i2c, spi, gpio, tdm, dma, usb, + * eth1, eth2, sdhc, crypto, global-util, message, pci0, pci1, msi. + * + * Please note to add "-b 0" for core0's dts compiling. + * + * Copyright 2011 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/include/ "p1020rdb.dts" + +/ { + model = "fsl,P1020RDB"; + compatible = "fsl,P1020RDB", "fsl,MPC85XXRDB-CAMP"; + + aliases { + ethernet1 = &enet1; + ethernet2 = &enet2; + serial0 = &serial0; + pci0 = &pci0; + pci1 = &pci1; + }; + + cpus { + PowerPC,P1020@1 { + status = "disabled"; + }; + }; + + memory { + device_type = "memory"; + }; + + localbus@ffe05000 { + status = "disabled"; + }; + + soc@ffe00000 { + serial1: serial@4600 { + status = "disabled"; + }; + + enet0: ethernet@b0000 { + status = "disabled"; + }; + + mpic: pic@40000 { + protected-sources = < + 42 29 30 34 /* serial1, enet0-queue-group0 */ + 17 18 24 45 /* enet0-queue-group1, crypto */ + >; + }; + }; +}; diff --git a/trunk/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts b/trunk/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts new file mode 100644 index 000000000000..517453821884 --- /dev/null +++ b/trunk/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts @@ -0,0 +1,141 @@ +/* + * P1020 RDB Core1 Device Tree Source in CAMP mode. + * + * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache + * can be shared, all the other devices must be assigned to one core only. + * This dts allows core1 to have l2, eth0, crypto. + * + * Please note to add "-b 1" for core1's dts compiling. + * + * Copyright 2011 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/include/ "p1020rdb.dts" + +/ { + model = "fsl,P1020RDB"; + compatible = "fsl,P1020RDB", "fsl,MPC85XXRDB-CAMP"; + + aliases { + ethernet0 = &enet0; + serial0 = &serial1; + }; + + cpus { + PowerPC,P1020@0 { + status = "disabled"; + }; + }; + + memory { + device_type = "memory"; + }; + + localbus@ffe05000 { + status = "disabled"; + }; + + soc@ffe00000 { + ecm-law@0 { + status = "disabled"; + }; + + ecm@1000 { + status = "disabled"; + }; + + memory-controller@2000 { + status = "disabled"; + }; + + i2c@3000 { + status = "disabled"; + }; + + i2c@3100 { + status = "disabled"; + }; + + serial0: serial@4500 { + status = "disabled"; + }; + + spi@7000 { + status = "disabled"; + }; + + gpio: gpio-controller@f000 { + status = "disabled"; + }; + + dma@21300 { + status = "disabled"; + }; + + mdio@24000 { + status = "disabled"; + }; + + mdio@25000 { + status = "disabled"; + }; + + enet1: ethernet@b1000 { + status = "disabled"; + }; + + enet2: ethernet@b2000 { + status = "disabled"; + }; + + usb@22000 { + status = "disabled"; + }; + + sdhci@2e000 { + status = "disabled"; + }; + + mpic: pic@40000 { + protected-sources = < + 16 /* ecm, mem, L2, pci0, pci1 */ + 43 42 59 /* i2c, serial0, spi */ + 47 63 62 /* gpio, tdm */ + 20 21 22 23 /* dma */ + 03 02 /* mdio */ + 35 36 40 /* enet1-queue-group0 */ + 51 52 67 /* enet1-queue-group1 */ + 31 32 33 /* enet2-queue-group0 */ + 25 26 27 /* enet2-queue-group1 */ + 28 72 58 /* usb, sdhci, crypto */ + 0xb0 0xb1 0xb2 /* message */ + 0xb3 0xb4 0xb5 + 0xb6 0xb7 + 0xe0 0xe1 0xe2 /* msi */ + 0xe3 0xe4 0xe5 + 0xe6 0xe7 /* sdhci, crypto , pci */ + >; + }; + + msi@41600 { + status = "disabled"; + }; + + global-utilities@e0000 { //global utilities block + status = "disabled"; + }; + }; + + pci0: pcie@ffe09000 { + status = "disabled"; + }; + + pci1: pcie@ffe0a000 { + status = "disabled"; + }; +}; diff --git a/trunk/arch/powerpc/boot/dts/p1022ds.dtsi b/trunk/arch/powerpc/boot/dts/p1022ds.dtsi index 873da350d01b..c3344b04d8ff 100644 --- a/trunk/arch/powerpc/boot/dts/p1022ds.dtsi +++ b/trunk/arch/powerpc/boot/dts/p1022ds.dtsi @@ -149,10 +149,6 @@ compatible = "dallas,ds1339"; reg = <0x68>; }; - adt7461@4c { - compatible = "adi,adt7461"; - reg = <0x4c>; - }; }; spi@7000 { diff --git a/trunk/arch/powerpc/boot/dts/p1022rdk.dts b/trunk/arch/powerpc/boot/dts/p1022rdk.dts deleted file mode 100644 index 51d82de223f3..000000000000 --- a/trunk/arch/powerpc/boot/dts/p1022rdk.dts +++ /dev/null @@ -1,188 +0,0 @@ -/* - * P1022 RDK 32-bit Physical Address Map Device Tree Source - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/include/ "fsl/p1022si-pre.dtsi" -/ { - model = "fsl,P1022RDK"; - compatible = "fsl,P1022RDK"; - - memory { - device_type = "memory"; - }; - - board_lbc: lbc: localbus@ffe05000 { - /* The P1022 RDK does not have any localbus devices */ - status = "disabled"; - }; - - board_soc: soc: soc@ffe00000 { - ranges = <0x0 0x0 0xffe00000 0x100000>; - - i2c@3100 { - wm8960:codec@1a { - compatible = "wlf,wm8960"; - reg = <0x1a>; - /* MCLK source is a stand-alone oscillator */ - clock-frequency = <12288000>; - }; - rtc@68 { - compatible = "stm,m41t62"; - reg = <0x68>; - }; - adt7461@4c{ - compatible = "adi,adt7461"; - reg = <0x4c>; - }; - zl6100@21{ - compatible = "isil,zl6100"; - reg = <0x21>; - }; - zl6100@24{ - compatible = "isil,zl6100"; - reg = <0x24>; - }; - zl6100@26{ - compatible = "isil,zl6100"; - reg = <0x26>; - }; - zl6100@29{ - compatible = "isil,zl6100"; - reg = <0x29>; - }; - }; - - spi@7000 { - flash@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "spansion,m25p80"; - reg = <0>; - spi-max-frequency = <1000000>; - partition@0 { - label = "full-spi-flash"; - reg = <0x00000000 0x00100000>; - }; - }; - }; - - ssi@15000 { - fsl,mode = "i2s-slave"; - codec-handle = <&wm8960>; - }; - - usb@22000 { - phy_type = "ulpi"; - }; - - usb@23000 { - phy_type = "ulpi"; - }; - - mdio@24000 { - phy0: ethernet-phy@0 { - interrupts = <3 1 0 0>; - reg = <0x1>; - }; - phy1: ethernet-phy@1 { - interrupts = <9 1 0 0>; - reg = <0x2>; - }; - }; - - mdio@25000 { - tbi0: tbi-phy@11 { - reg = <0x11>; - device_type = "tbi-phy"; - }; - }; - - ethernet@b0000 { - phy-handle = <&phy0>; - phy-connection-type = "rgmii-id"; - }; - - ethernet@b1000 { - phy-handle = <&phy1>; - tbi-handle = <&tbi0>; - phy-connection-type = "sgmii"; - }; - }; - - pci0: pcie@ffe09000 { - ranges = <0x2000000 0x0 0xe0000000 0 0xa0000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>; - reg = <0x0 0xffe09000 0 0x1000>; - pcie@0 { - ranges = <0x2000000 0x0 0xe0000000 - 0x2000000 0x0 0xe0000000 - 0x0 0x20000000 - - 0x1000000 0x0 0x0 - 0x1000000 0x0 0x0 - 0x0 0x100000>; - }; - }; - - pci1: pcie@ffe0a000 { - ranges = <0x2000000 0x0 0xe0000000 0 0xc0000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>; - reg = <0 0xffe0a000 0 0x1000>; - pcie@0 { - ranges = <0x2000000 0x0 0xe0000000 - 0x2000000 0x0 0xe0000000 - 0x0 0x20000000 - - 0x1000000 0x0 0x0 - 0x1000000 0x0 0x0 - 0x0 0x100000>; - }; - }; - - pci2: pcie@ffe0b000 { - ranges = <0x2000000 0x0 0xe0000000 0 0x80000000 0x0 0x20000000 - 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>; - reg = <0 0xffe0b000 0 0x1000>; - pcie@0 { - ranges = <0x2000000 0x0 0xe0000000 - 0x2000000 0x0 0xe0000000 - 0x0 0x20000000 - - 0x1000000 0x0 0x0 - 0x1000000 0x0 0x0 - 0x0 0x100000>; - }; - }; -}; - -/include/ "fsl/p1022si-post.dtsi" diff --git a/trunk/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts b/trunk/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts new file mode 100644 index 000000000000..66aac864c4cc --- /dev/null +++ b/trunk/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts @@ -0,0 +1,67 @@ +/* + * P2020 RDB Core0 Device Tree Source in CAMP mode. + * + * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache + * can be shared, all the other devices must be assigned to one core only. + * This dts file allows core0 to have memory, l2, i2c, spi, gpio, dma1, usb, + * eth1, eth2, sdhc, crypto, global-util, pci0. + * + * Copyright 2009-2011 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/include/ "p2020rdb.dts" + +/ { + model = "fsl,P2020RDB"; + compatible = "fsl,P2020RDB", "fsl,MPC85XXRDB-CAMP"; + + cpus { + PowerPC,P2020@1 { + status = "disabled"; + }; + }; + + localbus@ffe05000 { + status = "disabled"; + }; + + soc@ffe00000 { + serial1: serial@4600 { + status = "disabled"; + }; + + dma@c300 { + status = "disabled"; + }; + + enet0: ethernet@24000 { + status = "disabled"; + }; + + mpic: pic@40000 { + protected-sources = < + 42 76 77 78 79 /* serial1 , dma2 */ + 29 30 34 26 /* enet0, pci1 */ + 0xe0 0xe1 0xe2 0xe3 /* msi */ + 0xe4 0xe5 0xe6 0xe7 + >; + }; + + msi@41600 { + status = "disabled"; + }; + }; + + pci0: pcie@ffe08000 { + status = "disabled"; + }; + + pci2: pcie@ffe0a000 { + status = "disabled"; + }; +}; diff --git a/trunk/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts b/trunk/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts new file mode 100644 index 000000000000..9bd8ef493dd2 --- /dev/null +++ b/trunk/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts @@ -0,0 +1,125 @@ +/* + * P2020 RDB Core1 Device Tree Source in CAMP mode. + * + * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache + * can be shared, all the other devices must be assigned to one core only. + * This dts allows core1 to have l2, dma2, eth0, pci1, msi. + * + * Please note to add "-b 1" for core1's dts compiling. + * + * Copyright 2009-2011 Freescale Semiconductor Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/include/ "p2020rdb.dts" + +/ { + model = "fsl,P2020RDB"; + compatible = "fsl,P2020RDB", "fsl,MPC85XXRDB-CAMP"; + + cpus { + PowerPC,P2020@0 { + status = "disabled"; + }; + }; + + localbus@ffe05000 { + status = "disabled"; + }; + + soc@ffe00000 { + ecm-law@0 { + status = "disabled"; + }; + + ecm@1000 { + status = "disabled"; + }; + + memory-controller@2000 { + status = "disabled"; + }; + + i2c@3000 { + status = "disabled"; + }; + + i2c@3100 { + status = "disabled"; + }; + + serial0: serial@4500 { + status = "disabled"; + }; + + spi@7000 { + status = "disabled"; + }; + + gpio: gpio-controller@f000 { + status = "disabled"; + }; + + dma@21300 { + status = "disabled"; + }; + + usb@22000 { + status = "disabled"; + }; + + mdio@24520 { + status = "disabled"; + }; + + mdio@25520 { + status = "disabled"; + }; + + mdio@26520 { + status = "disabled"; + }; + + enet1: ethernet@25000 { + status = "disabled"; + }; + + enet2: ethernet@26000 { + status = "disabled"; + }; + + sdhci@2e000 { + status = "disabled"; + }; + + crypto@30000 { + status = "disabled"; + }; + + mpic: pic@40000 { + protected-sources = < + 17 18 43 42 59 47 /*ecm, mem, i2c, serial0, spi,gpio */ + 16 20 21 22 23 28 /* L2, dma1, USB */ + 03 35 36 40 31 32 33 /* mdio, enet1, enet2 */ + 72 45 58 25 /* sdhci, crypto , pci */ + >; + }; + + global-utilities@e0000 { //global utilities block + status = "disabled"; + }; + + }; + + pci0: pcie@ffe08000 { + status = "disabled"; + }; + + pci1: pcie@ffe09000 { + status = "disabled"; + }; +}; diff --git a/trunk/arch/powerpc/boot/dts/p2041rdb.dts b/trunk/arch/powerpc/boot/dts/p2041rdb.dts index d97ad74c7279..baab0347dab0 100644 --- a/trunk/arch/powerpc/boot/dts/p2041rdb.dts +++ b/trunk/arch/powerpc/boot/dts/p2041rdb.dts @@ -94,10 +94,6 @@ compatible = "pericom,pt7c4338"; reg = <0x68>; }; - adt7461@4c { - compatible = "adi,adt7461"; - reg = <0x4c>; - }; }; i2c@118100 { diff --git a/trunk/arch/powerpc/boot/dts/p3041ds.dts b/trunk/arch/powerpc/boot/dts/p3041ds.dts index 2fed3bc0b990..6cdcadc80c30 100644 --- a/trunk/arch/powerpc/boot/dts/p3041ds.dts +++ b/trunk/arch/powerpc/boot/dts/p3041ds.dts @@ -98,10 +98,6 @@ reg = <0x68>; interrupts = <0x1 0x1 0 0>; }; - adt7461@4c { - compatible = "adi,adt7461"; - reg = <0x4c>; - }; }; }; diff --git a/trunk/arch/powerpc/boot/dts/p4080ds.dts b/trunk/arch/powerpc/boot/dts/p4080ds.dts index 1cf6148b8b05..3e204609d02e 100644 --- a/trunk/arch/powerpc/boot/dts/p4080ds.dts +++ b/trunk/arch/powerpc/boot/dts/p4080ds.dts @@ -96,10 +96,6 @@ reg = <0x68>; interrupts = <0x1 0x1 0 0>; }; - adt7461@4c { - compatible = "adi,adt7461"; - reg = <0x4c>; - }; }; usb0: usb@210000 { diff --git a/trunk/arch/powerpc/boot/dts/p5020ds.dts b/trunk/arch/powerpc/boot/dts/p5020ds.dts index 2869fea717dd..27c07ed6adc1 100644 --- a/trunk/arch/powerpc/boot/dts/p5020ds.dts +++ b/trunk/arch/powerpc/boot/dts/p5020ds.dts @@ -98,10 +98,6 @@ reg = <0x68>; interrupts = <0x1 0x1 0 0>; }; - adt7461@4c { - compatible = "adi,adt7461"; - reg = <0x4c>; - }; }; }; diff --git a/trunk/arch/powerpc/boot/dts/p5040ds.dts b/trunk/arch/powerpc/boot/dts/p5040ds.dts deleted file mode 100644 index 860b5ccf76c0..000000000000 --- a/trunk/arch/powerpc/boot/dts/p5040ds.dts +++ /dev/null @@ -1,207 +0,0 @@ -/* - * P5040DS Device Tree Source - * - * Copyright 2012 Freescale Semiconductor Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Freescale Semiconductor nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * - * ALTERNATIVELY, this software may be distributed under the terms of the - * GNU General Public License ("GPL") as published by the Free Software - * Foundation, either version 2 of that License or (at your option) any - * later version. - * - * This software is provided by Freescale Semiconductor "as is" and any - * express or implied warranties, including, but not limited to, the implied - * warranties of merchantability and fitness for a particular purpose are - * disclaimed. In no event shall Freescale Semiconductor be liable for any - * direct, indirect, incidental, special, exemplary, or consequential damages - * (including, but not limited to, procurement of substitute goods or services; - * loss of use, data, or profits; or business interruption) however caused and - * on any theory of liability, whether in contract, strict liability, or tort - * (including negligence or otherwise) arising in any way out of the use of this - * software, even if advised of the possibility of such damage. - */ - -/include/ "fsl/p5040si-pre.dtsi" - -/ { - model = "fsl,P5040DS"; - compatible = "fsl,P5040DS"; - #address-cells = <2>; - #size-cells = <2>; - interrupt-parent = <&mpic>; - - memory { - device_type = "memory"; - }; - - dcsr: dcsr@f00000000 { - ranges = <0x00000000 0xf 0x00000000 0x01008000>; - }; - - soc: soc@ffe000000 { - ranges = <0x00000000 0xf 0xfe000000 0x1000000>; - reg = <0xf 0xfe000000 0 0x00001000>; - spi@110000 { - flash@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "spansion,s25sl12801"; - reg = <0>; - spi-max-frequency = <40000000>; /* input clock */ - partition@u-boot { - label = "u-boot"; - reg = <0x00000000 0x00100000>; - }; - partition@kernel { - label = "kernel"; - reg = <0x00100000 0x00500000>; - }; - partition@dtb { - label = "dtb"; - reg = <0x00600000 0x00100000>; - }; - partition@fs { - label = "file system"; - reg = <0x00700000 0x00900000>; - }; - }; - }; - - i2c@118100 { - eeprom@51 { - compatible = "at24,24c256"; - reg = <0x51>; - }; - eeprom@52 { - compatible = "at24,24c256"; - reg = <0x52>; - }; - }; - - i2c@119100 { - rtc@68 { - compatible = "dallas,ds3232"; - reg = <0x68>; - interrupts = <0x1 0x1 0 0>; - }; - adt7461@4c { - compatible = "adi,adt7461"; - reg = <0x4c>; - }; - }; - }; - - lbc: localbus@ffe124000 { - reg = <0xf 0xfe124000 0 0x1000>; - ranges = <0 0 0xf 0xe8000000 0x08000000 - 2 0 0xf 0xffa00000 0x00040000 - 3 0 0xf 0xffdf0000 0x00008000>; - - flash@0,0 { - compatible = "cfi-flash"; - reg = <0 0 0x08000000>; - bank-width = <2>; - device-width = <2>; - }; - - nand@2,0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "fsl,elbc-fcm-nand"; - reg = <0x2 0x0 0x40000>; - - partition@0 { - label = "NAND U-Boot Image"; - reg = <0x0 0x02000000>; - }; - - partition@2000000 { - label = "NAND Root File System"; - reg = <0x02000000 0x10000000>; - }; - - partition@12000000 { - label = "NAND Compressed RFS Image"; - reg = <0x12000000 0x08000000>; - }; - - partition@1a000000 { - label = "NAND Linux Kernel Image"; - reg = <0x1a000000 0x04000000>; - }; - - partition@1e000000 { - label = "NAND DTB Image"; - reg = <0x1e000000 0x01000000>; - }; - - partition@1f000000 { - label = "NAND Writable User area"; - reg = <0x1f000000 0x01000000>; - }; - }; - - board-control@3,0 { - compatible = "fsl,p5040ds-fpga", "fsl,fpga-ngpixis"; - reg = <3 0 0x40>; - }; - }; - - pci0: pcie@ffe200000 { - reg = <0xf 0xfe200000 0 0x1000>; - ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000 - 0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>; - pcie@0 { - ranges = <0x02000000 0 0xe0000000 - 0x02000000 0 0xe0000000 - 0 0x20000000 - - 0x01000000 0 0x00000000 - 0x01000000 0 0x00000000 - 0 0x00010000>; - }; - }; - - pci1: pcie@ffe201000 { - reg = <0xf 0xfe201000 0 0x1000>; - ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000 - 0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>; - pcie@0 { - ranges = <0x02000000 0 0xe0000000 - 0x02000000 0 0xe0000000 - 0 0x20000000 - - 0x01000000 0 0x00000000 - 0x01000000 0 0x00000000 - 0 0x00010000>; - }; - }; - - pci2: pcie@ffe202000 { - reg = <0xf 0xfe202000 0 0x1000>; - ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x20000000 - 0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>; - pcie@0 { - ranges = <0x02000000 0 0xe0000000 - 0x02000000 0 0xe0000000 - 0 0x20000000 - - 0x01000000 0 0x00000000 - 0x01000000 0 0x00000000 - 0 0x00010000>; - }; - }; -}; - -/include/ "fsl/p5040si-post.dtsi" diff --git a/trunk/arch/powerpc/configs/corenet32_smp_defconfig b/trunk/arch/powerpc/configs/corenet32_smp_defconfig index 1c0f2432ecdb..8b3d57c1ebe8 100644 --- a/trunk/arch/powerpc/configs/corenet32_smp_defconfig +++ b/trunk/arch/powerpc/configs/corenet32_smp_defconfig @@ -27,7 +27,6 @@ CONFIG_P2041_RDB=y CONFIG_P3041_DS=y CONFIG_P4080_DS=y CONFIG_P5020_DS=y -CONFIG_P5040_DS=y CONFIG_HIGHMEM=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_BINFMT_MISC=m diff --git a/trunk/arch/powerpc/configs/corenet64_smp_defconfig b/trunk/arch/powerpc/configs/corenet64_smp_defconfig index 88fa5c46f66f..0516e22ca3de 100644 --- a/trunk/arch/powerpc/configs/corenet64_smp_defconfig +++ b/trunk/arch/powerpc/configs/corenet64_smp_defconfig @@ -23,7 +23,6 @@ CONFIG_MODVERSIONS=y CONFIG_PARTITION_ADVANCED=y CONFIG_MAC_PARTITION=y CONFIG_P5020_DS=y -CONFIG_P5040_DS=y # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set CONFIG_BINFMT_MISC=m CONFIG_IRQ_ALL_CPUS=y diff --git a/trunk/arch/powerpc/configs/mpc85xx_defconfig b/trunk/arch/powerpc/configs/mpc85xx_defconfig index cf815e847cdc..8b5bda27d248 100644 --- a/trunk/arch/powerpc/configs/mpc85xx_defconfig +++ b/trunk/arch/powerpc/configs/mpc85xx_defconfig @@ -30,7 +30,6 @@ CONFIG_MPC85xx_DS=y CONFIG_MPC85xx_RDB=y CONFIG_P1010_RDB=y CONFIG_P1022_DS=y -CONFIG_P1022_RDK=y CONFIG_P1023_RDS=y CONFIG_SOCRATES=y CONFIG_KSI8560=y diff --git a/trunk/arch/powerpc/configs/mpc85xx_smp_defconfig b/trunk/arch/powerpc/configs/mpc85xx_smp_defconfig index 502cd9e027e4..b0974e7e98ae 100644 --- a/trunk/arch/powerpc/configs/mpc85xx_smp_defconfig +++ b/trunk/arch/powerpc/configs/mpc85xx_smp_defconfig @@ -32,7 +32,6 @@ CONFIG_MPC85xx_DS=y CONFIG_MPC85xx_RDB=y CONFIG_P1010_RDB=y CONFIG_P1022_DS=y -CONFIG_P1022_RDK=y CONFIG_P1023_RDS=y CONFIG_SOCRATES=y CONFIG_KSI8560=y diff --git a/trunk/arch/powerpc/configs/ppc64_defconfig b/trunk/arch/powerpc/configs/ppc64_defconfig index e263e6a5aca1..db27c82e0542 100644 --- a/trunk/arch/powerpc/configs/ppc64_defconfig +++ b/trunk/arch/powerpc/configs/ppc64_defconfig @@ -51,7 +51,6 @@ CONFIG_KEXEC=y CONFIG_IRQ_ALL_CPUS=y CONFIG_MEMORY_HOTREMOVE=y CONFIG_SCHED_SMT=y -CONFIG_PPC_DENORMALISATION=y CONFIG_PCCARD=y CONFIG_ELECTRA_CF=y CONFIG_HOTPLUG_PCI=m diff --git a/trunk/arch/powerpc/configs/pseries_defconfig b/trunk/arch/powerpc/configs/pseries_defconfig index c169dfb3e42d..1f65b3c9b59a 100644 --- a/trunk/arch/powerpc/configs/pseries_defconfig +++ b/trunk/arch/powerpc/configs/pseries_defconfig @@ -48,7 +48,6 @@ CONFIG_MEMORY_HOTREMOVE=y CONFIG_PPC_64K_PAGES=y CONFIG_PPC_SUBPAGE_PROT=y CONFIG_SCHED_SMT=y -CONFIG_PPC_DENORMALISATION=y CONFIG_HOTPLUG_PCI=m CONFIG_HOTPLUG_PCI_RPA=m CONFIG_HOTPLUG_PCI_RPA_DLPAR=m diff --git a/trunk/arch/powerpc/include/asm/abs_addr.h b/trunk/arch/powerpc/include/asm/abs_addr.h new file mode 100644 index 000000000000..9d92ba04b033 --- /dev/null +++ b/trunk/arch/powerpc/include/asm/abs_addr.h @@ -0,0 +1,56 @@ +#ifndef _ASM_POWERPC_ABS_ADDR_H +#define _ASM_POWERPC_ABS_ADDR_H +#ifdef __KERNEL__ + + +/* + * c 2001 PPC 64 Team, IBM Corp + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include + +#include +#include +#include + +struct mschunks_map { + unsigned long num_chunks; + unsigned long chunk_size; + unsigned long chunk_shift; + unsigned long chunk_mask; + u32 *mapping; +}; + +extern struct mschunks_map mschunks_map; + +/* Chunks are 256 KB */ +#define MSCHUNKS_CHUNK_SHIFT (18) +#define MSCHUNKS_CHUNK_SIZE (1UL << MSCHUNKS_CHUNK_SHIFT) +#define MSCHUNKS_OFFSET_MASK (MSCHUNKS_CHUNK_SIZE - 1) + +static inline unsigned long chunk_to_addr(unsigned long chunk) +{ + return chunk << MSCHUNKS_CHUNK_SHIFT; +} + +static inline unsigned long addr_to_chunk(unsigned long addr) +{ + return addr >> MSCHUNKS_CHUNK_SHIFT; +} + +static inline unsigned long phys_to_abs(unsigned long pa) +{ + return pa; +} + +/* Convenience macros */ +#define virt_to_abs(va) phys_to_abs(__pa(va)) +#define abs_to_virt(aa) __va(aa) + +#endif /* __KERNEL__ */ +#endif /* _ASM_POWERPC_ABS_ADDR_H */ diff --git a/trunk/arch/powerpc/include/asm/cacheflush.h b/trunk/arch/powerpc/include/asm/cacheflush.h index b843e35122e8..ab9e402518e8 100644 --- a/trunk/arch/powerpc/include/asm/cacheflush.h +++ b/trunk/arch/powerpc/include/asm/cacheflush.h @@ -30,8 +30,6 @@ extern void flush_dcache_page(struct page *page); #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) -extern void __flush_disable_L1(void); - extern void __flush_icache_range(unsigned long, unsigned long); static inline void flush_icache_range(unsigned long start, unsigned long stop) { diff --git a/trunk/arch/powerpc/include/asm/debug.h b/trunk/arch/powerpc/include/asm/debug.h index 32de2577bb6d..716d2f089eb6 100644 --- a/trunk/arch/powerpc/include/asm/debug.h +++ b/trunk/arch/powerpc/include/asm/debug.h @@ -44,7 +44,7 @@ static inline int debugger_dabr_match(struct pt_regs *regs) { return 0; } static inline int debugger_fault_handler(struct pt_regs *regs) { return 0; } #endif -extern int set_dabr(unsigned long dabr, unsigned long dabrx); +extern int set_dabr(unsigned long dabr); #ifdef CONFIG_PPC_ADV_DEBUG_REGS extern void do_send_trap(struct pt_regs *regs, unsigned long address, unsigned long error_code, int signal_code, int brkpt); diff --git a/trunk/arch/powerpc/include/asm/eeh.h b/trunk/arch/powerpc/include/asm/eeh.h index b0ef73882b38..d60f99814ffb 100644 --- a/trunk/arch/powerpc/include/asm/eeh.h +++ b/trunk/arch/powerpc/include/asm/eeh.h @@ -31,46 +31,6 @@ struct device_node; #ifdef CONFIG_EEH -/* - * The struct is used to trace PE related EEH functionality. - * In theory, there will have one instance of the struct to - * be created against particular PE. In nature, PEs corelate - * to each other. the struct has to reflect that hierarchy in - * order to easily pick up those affected PEs when one particular - * PE has EEH errors. - * - * Also, one particular PE might be composed of PCI device, PCI - * bus and its subordinate components. The struct also need ship - * the information. Further more, one particular PE is only meaingful - * in the corresponding PHB. Therefore, the root PEs should be created - * against existing PHBs in on-to-one fashion. - */ -#define EEH_PE_INVALID (1 << 0) /* Invalid */ -#define EEH_PE_PHB (1 << 1) /* PHB PE */ -#define EEH_PE_DEVICE (1 << 2) /* Device PE */ -#define EEH_PE_BUS (1 << 3) /* Bus PE */ - -#define EEH_PE_ISOLATED (1 << 0) /* Isolated PE */ -#define EEH_PE_RECOVERING (1 << 1) /* Recovering PE */ - -struct eeh_pe { - int type; /* PE type: PHB/Bus/Device */ - int state; /* PE EEH dependent mode */ - int config_addr; /* Traditional PCI address */ - int addr; /* PE configuration address */ - struct pci_controller *phb; /* Associated PHB */ - int check_count; /* Times of ignored error */ - int freeze_count; /* Times of froze up */ - int false_positives; /* Times of reported #ff's */ - struct eeh_pe *parent; /* Parent PE */ - struct list_head child_list; /* Link PE to the child list */ - struct list_head edevs; /* Link list of EEH devices */ - struct list_head child; /* Child PEs */ -}; - -#define eeh_pe_for_each_dev(pe, edev) \ - list_for_each_entry(edev, &pe->edevs, list) - /* * The struct is used to trace EEH state for the associated * PCI device node or PCI device. In future, it might @@ -78,16 +38,21 @@ struct eeh_pe { * another tree except the currently existing tree of PCI * buses and PCI devices */ -#define EEH_DEV_IRQ_DISABLED (1<<0) /* Interrupt disabled */ +#define EEH_MODE_SUPPORTED (1<<0) /* EEH supported on the device */ +#define EEH_MODE_NOCHECK (1<<1) /* EEH check should be skipped */ +#define EEH_MODE_ISOLATED (1<<2) /* The device has been isolated */ +#define EEH_MODE_RECOVERING (1<<3) /* Recovering the device */ +#define EEH_MODE_IRQ_DISABLED (1<<4) /* Interrupt disabled */ struct eeh_dev { int mode; /* EEH mode */ int class_code; /* Class code of the device */ int config_addr; /* Config address */ int pe_config_addr; /* PE config address */ + int check_count; /* Times of ignored error */ + int freeze_count; /* Times of froze up */ + int false_positives; /* Times of reported #ff's */ u32 config_space[16]; /* Saved PCI config space */ - struct eeh_pe *pe; /* Associated PE */ - struct list_head list; /* Form link list in the PE */ struct pci_controller *phb; /* Associated PHB */ struct device_node *dn; /* Associated device node */ struct pci_dev *pdev; /* Associated PCI device */ @@ -130,51 +95,19 @@ static inline struct pci_dev *eeh_dev_to_pci_dev(struct eeh_dev *edev) struct eeh_ops { char *name; int (*init)(void); - void* (*of_probe)(struct device_node *dn, void *flag); - void* (*dev_probe)(struct pci_dev *dev, void *flag); - int (*set_option)(struct eeh_pe *pe, int option); - int (*get_pe_addr)(struct eeh_pe *pe); - int (*get_state)(struct eeh_pe *pe, int *state); - int (*reset)(struct eeh_pe *pe, int option); - int (*wait_state)(struct eeh_pe *pe, int max_wait); - int (*get_log)(struct eeh_pe *pe, int severity, char *drv_log, unsigned long len); - int (*configure_bridge)(struct eeh_pe *pe); + int (*set_option)(struct device_node *dn, int option); + int (*get_pe_addr)(struct device_node *dn); + int (*get_state)(struct device_node *dn, int *state); + int (*reset)(struct device_node *dn, int option); + int (*wait_state)(struct device_node *dn, int max_wait); + int (*get_log)(struct device_node *dn, int severity, char *drv_log, unsigned long len); + int (*configure_bridge)(struct device_node *dn); int (*read_config)(struct device_node *dn, int where, int size, u32 *val); int (*write_config)(struct device_node *dn, int where, int size, u32 val); }; extern struct eeh_ops *eeh_ops; extern int eeh_subsystem_enabled; -extern struct mutex eeh_mutex; -extern int eeh_probe_mode; - -#define EEH_PROBE_MODE_DEV (1<<0) /* From PCI device */ -#define EEH_PROBE_MODE_DEVTREE (1<<1) /* From device tree */ - -static inline void eeh_probe_mode_set(int flag) -{ - eeh_probe_mode = flag; -} - -static inline int eeh_probe_mode_devtree(void) -{ - return (eeh_probe_mode == EEH_PROBE_MODE_DEVTREE); -} - -static inline int eeh_probe_mode_dev(void) -{ - return (eeh_probe_mode == EEH_PROBE_MODE_DEV); -} - -static inline void eeh_lock(void) -{ - mutex_lock(&eeh_mutex); -} - -static inline void eeh_unlock(void) -{ - mutex_unlock(&eeh_mutex); -} /* * Max number of EEH freezes allowed before we consider the device @@ -182,26 +115,22 @@ static inline void eeh_unlock(void) */ #define EEH_MAX_ALLOWED_FREEZES 5 -typedef void *(*eeh_traverse_func)(void *data, void *flag); -int __devinit eeh_phb_pe_create(struct pci_controller *phb); -int eeh_add_to_parent_pe(struct eeh_dev *edev); -int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe); -void *eeh_pe_dev_traverse(struct eeh_pe *root, - eeh_traverse_func fn, void *flag); -void eeh_pe_restore_bars(struct eeh_pe *pe); -struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe); - void * __devinit eeh_dev_init(struct device_node *dn, void *data); void __devinit eeh_dev_phb_init_dynamic(struct pci_controller *phb); +void __init eeh_dev_phb_init(void); +void __init eeh_init(void); +#ifdef CONFIG_PPC_PSERIES +int __init eeh_pseries_init(void); +#endif int __init eeh_ops_register(struct eeh_ops *ops); int __exit eeh_ops_unregister(const char *name); unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val); -int eeh_dev_check_failure(struct eeh_dev *edev); -void __init eeh_addr_cache_build(void); +int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev); +void __init pci_addr_cache_build(void); void eeh_add_device_tree_early(struct device_node *); void eeh_add_device_tree_late(struct pci_bus *); -void eeh_remove_bus_device(struct pci_dev *, int); +void eeh_remove_bus_device(struct pci_dev *); /** * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure. @@ -227,24 +156,34 @@ static inline void *eeh_dev_init(struct device_node *dn, void *data) static inline void eeh_dev_phb_init_dynamic(struct pci_controller *phb) { } +static inline void eeh_dev_phb_init(void) { } + +static inline void eeh_init(void) { } + +#ifdef CONFIG_PPC_PSERIES +static inline int eeh_pseries_init(void) +{ + return 0; +} +#endif /* CONFIG_PPC_PSERIES */ + static inline unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val) { return val; } -#define eeh_dev_check_failure(x) (0) +static inline int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) +{ + return 0; +} -static inline void eeh_addr_cache_build(void) { } +static inline void pci_addr_cache_build(void) { } static inline void eeh_add_device_tree_early(struct device_node *dn) { } static inline void eeh_add_device_tree_late(struct pci_bus *bus) { } -static inline void eeh_remove_bus_device(struct pci_dev *dev, int purge_pe) { } - -static inline void eeh_lock(void) { } -static inline void eeh_unlock(void) { } - +static inline void eeh_remove_bus_device(struct pci_dev *dev) { } #define EEH_POSSIBLE_ERROR(val, type) (0) #define EEH_IO_ERROR_VALUE(size) (-1UL) #endif /* CONFIG_EEH */ diff --git a/trunk/arch/powerpc/include/asm/eeh_event.h b/trunk/arch/powerpc/include/asm/eeh_event.h index de67d830151b..c68b012b7797 100644 --- a/trunk/arch/powerpc/include/asm/eeh_event.h +++ b/trunk/arch/powerpc/include/asm/eeh_event.h @@ -28,11 +28,11 @@ */ struct eeh_event { struct list_head list; /* to form event queue */ - struct eeh_pe *pe; /* EEH PE */ + struct eeh_dev *edev; /* EEH device */ }; -int eeh_send_failure_event(struct eeh_pe *pe); -void eeh_handle_event(struct eeh_pe *pe); +int eeh_send_failure_event(struct eeh_dev *edev); +struct eeh_dev *handle_eeh_events(struct eeh_event *); #endif /* __KERNEL__ */ #endif /* ASM_POWERPC_EEH_EVENT_H */ diff --git a/trunk/arch/powerpc/include/asm/exception-64e.h b/trunk/arch/powerpc/include/asm/exception-64e.h index 51fa43e536b9..ac13addb8495 100644 --- a/trunk/arch/powerpc/include/asm/exception-64e.h +++ b/trunk/arch/powerpc/include/asm/exception-64e.h @@ -37,7 +37,6 @@ * critical data */ -#define PACA_EXGDBELL PACA_EXGEN /* We are out of SPRGs so we save some things in the PACA. The normal * exception frame is smaller than the CRIT or MC one though @@ -46,9 +45,8 @@ #define EX_CR (1 * 8) #define EX_R10 (2 * 8) #define EX_R11 (3 * 8) -#define EX_R13 (4 * 8) -#define EX_R14 (5 * 8) -#define EX_R15 (6 * 8) +#define EX_R14 (4 * 8) +#define EX_R15 (5 * 8) /* * The TLB miss exception uses different slots. diff --git a/trunk/arch/powerpc/include/asm/fsl_guts.h b/trunk/arch/powerpc/include/asm/fsl_guts.h index dd5ba2c22771..aa4c488589ce 100644 --- a/trunk/arch/powerpc/include/asm/fsl_guts.h +++ b/trunk/arch/powerpc/include/asm/fsl_guts.h @@ -48,8 +48,6 @@ struct ccsr_guts { __be32 dmuxcr; /* 0x.0068 - DMA Mux Control Register */ u8 res06c[0x70 - 0x6c]; __be32 devdisr; /* 0x.0070 - Device Disable Control */ -#define CCSR_GUTS_DEVDISR_TB1 0x00001000 -#define CCSR_GUTS_DEVDISR_TB0 0x00004000 __be32 devdisr2; /* 0x.0074 - Device Disable Control 2 */ u8 res078[0x7c - 0x78]; __be32 pmjcr; /* 0x.007c - 4 Power Management Jog Control Register */ diff --git a/trunk/arch/powerpc/include/asm/fsl_ifc.h b/trunk/arch/powerpc/include/asm/fsl_ifc.h index b8a4b9bc50b3..b955012939a2 100644 --- a/trunk/arch/powerpc/include/asm/fsl_ifc.h +++ b/trunk/arch/powerpc/include/asm/fsl_ifc.h @@ -768,24 +768,22 @@ struct fsl_ifc_gpcm { */ struct fsl_ifc_regs { __be32 ifc_rev; - u32 res1[0x2]; + u32 res1[0x3]; struct { - __be32 cspr_ext; __be32 cspr; - u32 res2; + u32 res2[0x2]; } cspr_cs[FSL_IFC_BANK_COUNT]; - u32 res3[0x19]; + u32 res3[0x18]; struct { __be32 amask; u32 res4[0x2]; } amask_cs[FSL_IFC_BANK_COUNT]; - u32 res5[0x17]; + u32 res5[0x18]; struct { - __be32 csor_ext; __be32 csor; - u32 res6; + u32 res6[0x2]; } csor_cs[FSL_IFC_BANK_COUNT]; - u32 res7[0x19]; + u32 res7[0x18]; struct { __be32 ftim[4]; u32 res8[0x8]; diff --git a/trunk/arch/powerpc/include/asm/hvcall.h b/trunk/arch/powerpc/include/asm/hvcall.h index 7a867065db79..423cf9eaf4a4 100644 --- a/trunk/arch/powerpc/include/asm/hvcall.h +++ b/trunk/arch/powerpc/include/asm/hvcall.h @@ -152,6 +152,11 @@ #define H_VASI_RESUMED 5 #define H_VASI_COMPLETED 6 +/* DABRX flags */ +#define H_DABRX_HYPERVISOR (1UL<<(63-61)) +#define H_DABRX_KERNEL (1UL<<(63-62)) +#define H_DABRX_USER (1UL<<(63-63)) + /* Each control block has to be on a 4K boundary */ #define H_CB_ALIGNMENT 4096 diff --git a/trunk/arch/powerpc/include/asm/hw_breakpoint.h b/trunk/arch/powerpc/include/asm/hw_breakpoint.h index 423424599dad..be04330af751 100644 --- a/trunk/arch/powerpc/include/asm/hw_breakpoint.h +++ b/trunk/arch/powerpc/include/asm/hw_breakpoint.h @@ -27,11 +27,10 @@ #ifdef CONFIG_HAVE_HW_BREAKPOINT struct arch_hw_breakpoint { - unsigned long address; - unsigned long dabrx; - int type; - u8 len; /* length of the target data symbol */ bool extraneous_interrupt; + u8 len; /* length of the target data symbol */ + int type; + unsigned long address; }; #include @@ -62,7 +61,7 @@ extern void ptrace_triggered(struct perf_event *bp, struct perf_sample_data *data, struct pt_regs *regs); static inline void hw_breakpoint_disable(void) { - set_dabr(0, 0); + set_dabr(0); } extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs); diff --git a/trunk/arch/powerpc/include/asm/kprobes.h b/trunk/arch/powerpc/include/asm/kprobes.h index 7b6feab6fd26..be0171afdc0f 100644 --- a/trunk/arch/powerpc/include/asm/kprobes.h +++ b/trunk/arch/powerpc/include/asm/kprobes.h @@ -29,16 +29,21 @@ #include #include #include -#include #define __ARCH_WANT_KPROBES_INSN_SLOT struct pt_regs; struct kprobe; -typedef ppc_opcode_t kprobe_opcode_t; +typedef unsigned int kprobe_opcode_t; +#define BREAKPOINT_INSTRUCTION 0x7fe00008 /* trap */ #define MAX_INSN_SIZE 1 +#define IS_TW(instr) (((instr) & 0xfc0007fe) == 0x7c000008) +#define IS_TD(instr) (((instr) & 0xfc0007fe) == 0x7c000088) +#define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000) +#define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000) + #ifdef CONFIG_PPC64 /* * 64bit powerpc uses function descriptors. @@ -67,6 +72,12 @@ typedef ppc_opcode_t kprobe_opcode_t; addr = (kprobe_opcode_t *)kallsyms_lookup_name(dot_name); \ } \ } + +#define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \ + IS_TWI(instr) || IS_TDI(instr)) +#else +/* Use stock kprobe_lookup_name since ppc32 doesn't use function descriptors */ +#define is_trap(instr) (IS_TW(instr) || IS_TWI(instr)) #endif #define flush_insn_slot(p) do { } while (0) diff --git a/trunk/arch/powerpc/include/asm/kvm_book3s.h b/trunk/arch/powerpc/include/asm/kvm_book3s.h index 7aefdb3e1ce4..f0e0c6a66d97 100644 --- a/trunk/arch/powerpc/include/asm/kvm_book3s.h +++ b/trunk/arch/powerpc/include/asm/kvm_book3s.h @@ -59,7 +59,7 @@ struct hpte_cache { struct hlist_node list_vpte; struct hlist_node list_vpte_long; struct rcu_head rcu_head; - u64 host_vpn; + u64 host_va; u64 pfn; ulong slot; struct kvmppc_pte pte; diff --git a/trunk/arch/powerpc/include/asm/kvm_book3s_asm.h b/trunk/arch/powerpc/include/asm/kvm_book3s_asm.h index 88609b23b775..bfcd00c1485d 100644 --- a/trunk/arch/powerpc/include/asm/kvm_book3s_asm.h +++ b/trunk/arch/powerpc/include/asm/kvm_book3s_asm.h @@ -74,6 +74,7 @@ struct kvmppc_host_state { ulong vmhandler; ulong scratch0; ulong scratch1; + ulong sprg3; u8 in_guest; u8 restore_hid5; u8 napping; diff --git a/trunk/arch/powerpc/include/asm/machdep.h b/trunk/arch/powerpc/include/asm/machdep.h index c4231973edd3..42ce570812c1 100644 --- a/trunk/arch/powerpc/include/asm/machdep.h +++ b/trunk/arch/powerpc/include/asm/machdep.h @@ -34,19 +34,19 @@ struct machdep_calls { char *name; #ifdef CONFIG_PPC64 void (*hpte_invalidate)(unsigned long slot, - unsigned long vpn, + unsigned long va, int psize, int ssize, int local); long (*hpte_updatepp)(unsigned long slot, unsigned long newpp, - unsigned long vpn, + unsigned long va, int psize, int ssize, int local); void (*hpte_updateboltedpp)(unsigned long newpp, unsigned long ea, int psize, int ssize); long (*hpte_insert)(unsigned long hpte_group, - unsigned long vpn, + unsigned long va, unsigned long prpn, unsigned long rflags, unsigned long vflags, @@ -180,8 +180,7 @@ struct machdep_calls { void (*enable_pmcs)(void); /* Set DABR for this platform, leave empty for default implemenation */ - int (*set_dabr)(unsigned long dabr, - unsigned long dabrx); + int (*set_dabr)(unsigned long dabr); #ifdef CONFIG_PPC32 /* XXX for now */ /* A general init function, called by ppc_init in init/main.c. @@ -215,9 +214,6 @@ struct machdep_calls { /* Called after scan and before resource survey */ void (*pcibios_fixup_phb)(struct pci_controller *hose); - /* Called during PCI resource reassignment */ - resource_size_t (*pcibios_window_alignment)(struct pci_bus *, unsigned long type); - /* Called to shutdown machine specific hardware not already controlled * by other drivers. */ diff --git a/trunk/arch/powerpc/include/asm/mmu-hash64.h b/trunk/arch/powerpc/include/asm/mmu-hash64.h index 9673f73eb8db..1c65a59881ea 100644 --- a/trunk/arch/powerpc/include/asm/mmu-hash64.h +++ b/trunk/arch/powerpc/include/asm/mmu-hash64.h @@ -15,13 +15,6 @@ #include #include -/* - * This is necessary to get the definition of PGTABLE_RANGE which we - * need for various slices related matters. Note that this isn't the - * complete pgtable.h but only a portion of it. - */ -#include - /* * Segment table */ @@ -161,25 +154,9 @@ struct mmu_psize_def #define MMU_SEGSIZE_256M 0 #define MMU_SEGSIZE_1T 1 -/* - * encode page number shift. - * in order to fit the 78 bit va in a 64 bit variable we shift the va by - * 12 bits. This enable us to address upto 76 bit va. - * For hpt hash from a va we can ignore the page size bits of va and for - * hpte encoding we ignore up to 23 bits of va. So ignoring lower 12 bits ensure - * we work in all cases including 4k page size. - */ -#define VPN_SHIFT 12 #ifndef __ASSEMBLY__ -static inline int segment_shift(int ssize) -{ - if (ssize == MMU_SEGSIZE_256M) - return SID_SHIFT; - return SID_SHIFT_1T; -} - /* * The current system page and segment sizes */ @@ -202,40 +179,19 @@ extern unsigned long tce_alloc_start, tce_alloc_end; */ extern int mmu_ci_restrictions; -/* - * This computes the AVPN and B fields of the first dword of a HPTE, - * for use when we want to match an existing PTE. The bottom 7 bits - * of the returned value are zero. - */ -static inline unsigned long hpte_encode_avpn(unsigned long vpn, int psize, - int ssize) -{ - unsigned long v; - /* - * The AVA field omits the low-order 23 bits of the 78 bits VA. - * These bits are not needed in the PTE, because the - * low-order b of these bits are part of the byte offset - * into the virtual page and, if b < 23, the high-order - * 23-b of these bits are always used in selecting the - * PTEGs to be searched - */ - v = (vpn >> (23 - VPN_SHIFT)) & ~(mmu_psize_defs[psize].avpnm); - v <<= HPTE_V_AVPN_SHIFT; - v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT; - return v; -} - /* * This function sets the AVPN and L fields of the HPTE appropriately * for the page size */ -static inline unsigned long hpte_encode_v(unsigned long vpn, - int psize, int ssize) +static inline unsigned long hpte_encode_v(unsigned long va, int psize, + int ssize) { unsigned long v; - v = hpte_encode_avpn(vpn, psize, ssize); + v = (va >> 23) & ~(mmu_psize_defs[psize].avpnm); + v <<= HPTE_V_AVPN_SHIFT; if (psize != MMU_PAGE_4K) v |= HPTE_V_LARGE; + v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT; return v; } @@ -260,37 +216,30 @@ static inline unsigned long hpte_encode_r(unsigned long pa, int psize) } /* - * Build a VPN_SHIFT bit shifted va given VSID, EA and segment size. + * Build a VA given VSID, EA and segment size */ -static inline unsigned long hpt_vpn(unsigned long ea, - unsigned long vsid, int ssize) +static inline unsigned long hpt_va(unsigned long ea, unsigned long vsid, + int ssize) { - unsigned long mask; - int s_shift = segment_shift(ssize); - - mask = (1ul << (s_shift - VPN_SHIFT)) - 1; - return (vsid << (s_shift - VPN_SHIFT)) | ((ea >> VPN_SHIFT) & mask); + if (ssize == MMU_SEGSIZE_256M) + return (vsid << 28) | (ea & 0xfffffffUL); + return (vsid << 40) | (ea & 0xffffffffffUL); } /* * This hashes a virtual address */ -static inline unsigned long hpt_hash(unsigned long vpn, - unsigned int shift, int ssize) + +static inline unsigned long hpt_hash(unsigned long va, unsigned int shift, + int ssize) { - int mask; unsigned long hash, vsid; - /* VPN_SHIFT can be atmost 12 */ if (ssize == MMU_SEGSIZE_256M) { - mask = (1ul << (SID_SHIFT - VPN_SHIFT)) - 1; - hash = (vpn >> (SID_SHIFT - VPN_SHIFT)) ^ - ((vpn & mask) >> (shift - VPN_SHIFT)); + hash = (va >> 28) ^ ((va & 0x0fffffffUL) >> shift); } else { - mask = (1ul << (SID_SHIFT_1T - VPN_SHIFT)) - 1; - vsid = vpn >> (SID_SHIFT_1T - VPN_SHIFT); - hash = vsid ^ (vsid << 25) ^ - ((vpn & mask) >> (shift - VPN_SHIFT)) ; + vsid = va >> 40; + hash = vsid ^ (vsid << 25) ^ ((va & 0xffffffffffUL) >> shift); } return hash & 0x7fffffffffUL; } @@ -331,61 +280,63 @@ extern void slb_set_size(u16 size); #endif /* __ASSEMBLY__ */ /* - * VSID allocation (256MB segment) - * - * We first generate a 38-bit "proto-VSID". For kernel addresses this - * is equal to the ESID | 1 << 37, for user addresses it is: - * (context << USER_ESID_BITS) | (esid & ((1U << USER_ESID_BITS) - 1) + * VSID allocation * - * This splits the proto-VSID into the below range - * 0 - (2^(CONTEXT_BITS + USER_ESID_BITS) - 1) : User proto-VSID range - * 2^(CONTEXT_BITS + USER_ESID_BITS) - 2^(VSID_BITS) : Kernel proto-VSID range + * We first generate a 36-bit "proto-VSID". For kernel addresses this + * is equal to the ESID, for user addresses it is: + * (context << 15) | (esid & 0x7fff) * - * We also have CONTEXT_BITS + USER_ESID_BITS = VSID_BITS - 1 - * That is, we assign half of the space to user processes and half - * to the kernel. + * The two forms are distinguishable because the top bit is 0 for user + * addresses, whereas the top two bits are 1 for kernel addresses. + * Proto-VSIDs with the top two bits equal to 0b10 are reserved for + * now. * * The proto-VSIDs are then scrambled into real VSIDs with the * multiplicative hash: * * VSID = (proto-VSID * VSID_MULTIPLIER) % VSID_MODULUS + * where VSID_MULTIPLIER = 268435399 = 0xFFFFFC7 + * VSID_MODULUS = 2^36-1 = 0xFFFFFFFFF * - * VSID_MULTIPLIER is prime, so in particular it is + * This scramble is only well defined for proto-VSIDs below + * 0xFFFFFFFFF, so both proto-VSID and actual VSID 0xFFFFFFFFF are + * reserved. VSID_MULTIPLIER is prime, so in particular it is * co-prime to VSID_MODULUS, making this a 1:1 scrambling function. * Because the modulus is 2^n-1 we can compute it efficiently without * a divide or extra multiply (see below). * * This scheme has several advantages over older methods: * - * - We have VSIDs allocated for every kernel address + * - We have VSIDs allocated for every kernel address * (i.e. everything above 0xC000000000000000), except the very top * segment, which simplifies several things. * - * - We allow for USER_ESID_BITS significant bits of ESID and - * CONTEXT_BITS bits of context for user addresses. - * i.e. 64T (46 bits) of address space for up to half a million contexts. + * - We allow for 16 significant bits of ESID and 19 bits of + * context for user addresses. i.e. 16T (44 bits) of address space for + * up to half a million contexts. * - * - The scramble function gives robust scattering in the hash + * - The scramble function gives robust scattering in the hash * table (at least based on some initial results). The previous * method was more susceptible to pathological cases giving excessive * hash collisions. */ - /* - * This should be computed such that protovosid * vsid_mulitplier - * doesn't overflow 64 bits. It should also be co-prime to vsid_modulus + * WARNING - If you change these you must make sure the asm + * implementations in slb_allocate (slb_low.S), do_stab_bolted + * (head.S) and ASM_VSID_SCRAMBLE (below) are changed accordingly. */ -#define VSID_MULTIPLIER_256M ASM_CONST(12538073) /* 24-bit prime */ -#define VSID_BITS_256M 38 + +#define VSID_MULTIPLIER_256M ASM_CONST(200730139) /* 28-bit prime */ +#define VSID_BITS_256M 36 #define VSID_MODULUS_256M ((1UL<> 41) #ifndef __ASSEMBLY__ @@ -467,7 +416,7 @@ typedef struct { #ifdef CONFIG_PPC_MM_SLICES u64 low_slices_psize; /* SLB page size encodings */ - unsigned char high_slices_psize[SLICE_ARRAY_SIZE]; + u64 high_slices_psize; /* 4 bits per slice for now */ #else u16 sllp; /* SLB page size encoding */ #endif @@ -503,32 +452,12 @@ typedef struct { }) #endif /* 1 */ -/* - * This is only valid for addresses >= PAGE_OFFSET - * The proto-VSID space is divided into two class - * User: 0 to 2^(CONTEXT_BITS + USER_ESID_BITS) -1 - * kernel: 2^(CONTEXT_BITS + USER_ESID_BITS) to 2^(VSID_BITS) - 1 - * - * With KERNEL_START at 0xc000000000000000, the proto vsid for - * the kernel ends up with 0xc00000000 (36 bits). With 64TB - * support we need to have kernel proto-VSID in the - * [2^37 to 2^38 - 1] range due to the increased USER_ESID_BITS. - */ +/* This is only valid for addresses >= PAGE_OFFSET */ static inline unsigned long get_kernel_vsid(unsigned long ea, int ssize) { - unsigned long proto_vsid; - /* - * We need to make sure proto_vsid for the kernel is - * >= 2^(CONTEXT_BITS + USER_ESID_BITS[_1T]) - */ - if (ssize == MMU_SEGSIZE_256M) { - proto_vsid = ea >> SID_SHIFT; - proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS)); - return vsid_scramble(proto_vsid, 256M); - } - proto_vsid = ea >> SID_SHIFT_1T; - proto_vsid |= (1UL << (CONTEXT_BITS + USER_ESID_BITS_1T)); - return vsid_scramble(proto_vsid, 1T); + if (ssize == MMU_SEGSIZE_256M) + return vsid_scramble(ea >> SID_SHIFT, 256M); + return vsid_scramble(ea >> SID_SHIFT_1T, 1T); } /* Returns the segment size indicator for a user address */ diff --git a/trunk/arch/powerpc/include/asm/mmu.h b/trunk/arch/powerpc/include/asm/mmu.h index 5e38eedea218..e8a26db2e8f3 100644 --- a/trunk/arch/powerpc/include/asm/mmu.h +++ b/trunk/arch/powerpc/include/asm/mmu.h @@ -146,15 +146,6 @@ extern void setup_initial_memory_limit(phys_addr_t first_memblock_base, extern u64 ppc64_rma_size; #endif /* CONFIG_PPC64 */ -struct mm_struct; -#ifdef CONFIG_DEBUG_VM -extern void assert_pte_locked(struct mm_struct *mm, unsigned long addr); -#else /* CONFIG_DEBUG_VM */ -static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr) -{ -} -#endif /* !CONFIG_DEBUG_VM */ - #endif /* !__ASSEMBLY__ */ /* The kernel use the constants below to index in the page sizes array. diff --git a/trunk/arch/powerpc/include/asm/mpic.h b/trunk/arch/powerpc/include/asm/mpic.h index c0f9ef90f0b8..c9f698a994be 100644 --- a/trunk/arch/powerpc/include/asm/mpic.h +++ b/trunk/arch/powerpc/include/asm/mpic.h @@ -63,7 +63,6 @@ */ #define MPIC_TIMER_BASE 0x01100 #define MPIC_TIMER_STRIDE 0x40 -#define MPIC_TIMER_GROUP_STRIDE 0x1000 #define MPIC_TIMER_CURRENT_CNT 0x00000 #define MPIC_TIMER_BASE_CNT 0x00010 @@ -111,16 +110,10 @@ #define MPIC_VECPRI_SENSE_MASK 0x00400000 #define MPIC_IRQ_DESTINATION 0x00010 -#define MPIC_FSL_BRR1 0x00000 -#define MPIC_FSL_BRR1_VER 0x0000ffff - #define MPIC_MAX_IRQ_SOURCES 2048 #define MPIC_MAX_CPUS 32 #define MPIC_MAX_ISU 32 -#define MPIC_MAX_ERR 32 -#define MPIC_FSL_ERR_INT 16 - /* * Tsi108 implementation of MPIC has many differences from the original one */ @@ -273,7 +266,6 @@ struct mpic struct irq_chip hc_ipi; #endif struct irq_chip hc_tm; - struct irq_chip hc_err; const char *name; /* Flags */ unsigned int flags; @@ -287,8 +279,6 @@ struct mpic /* vector numbers used for internal sources (ipi/timers) */ unsigned int ipi_vecs[4]; unsigned int timer_vecs[8]; - /* vector numbers used for FSL MPIC error interrupts */ - unsigned int err_int_vecs[MPIC_MAX_ERR]; /* Spurious vector to program into unused sources */ unsigned int spurious_vec; @@ -306,15 +296,11 @@ struct mpic phys_addr_t paddr; /* The various ioremap'ed bases */ - struct mpic_reg_bank thiscpuregs; struct mpic_reg_bank gregs; struct mpic_reg_bank tmregs; struct mpic_reg_bank cpuregs[MPIC_MAX_CPUS]; struct mpic_reg_bank isus[MPIC_MAX_ISU]; - /* ioremap'ed base for error interrupt registers */ - u32 __iomem *err_regs; - /* Protected sources */ unsigned long *protected; @@ -379,11 +365,6 @@ struct mpic #define MPIC_NO_RESET 0x00004000 /* Freescale MPIC (compatible includes "fsl,mpic") */ #define MPIC_FSL 0x00008000 -/* Freescale MPIC supports EIMR (error interrupt mask register). - * This flag is set for MPIC version >= 4.1 (version determined - * from the BRR1 register). -*/ -#define MPIC_FSL_HAS_EIMR 0x00010000 /* MPIC HW modification ID */ #define MPIC_REGSET_MASK 0xf0000000 diff --git a/trunk/arch/powerpc/include/asm/paca.h b/trunk/arch/powerpc/include/asm/paca.h index e9e7a6999bb8..daf813fea91f 100644 --- a/trunk/arch/powerpc/include/asm/paca.h +++ b/trunk/arch/powerpc/include/asm/paca.h @@ -100,7 +100,7 @@ struct paca_struct { /* SLB related definitions */ u16 vmalloc_sllp; u16 slb_cache_ptr; - u32 slb_cache[SLB_CACHE_ENTRIES]; + u16 slb_cache[SLB_CACHE_ENTRIES]; #endif /* CONFIG_PPC_STD_MMU_64 */ #ifdef CONFIG_PPC_BOOK3E @@ -136,7 +136,6 @@ struct paca_struct { u8 io_sync; /* writel() needs spin_unlock sync */ u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */ u8 nap_state_lost; /* NV GPR values lost in power7_idle */ - u64 sprg3; /* Saved user-visible sprg */ #ifdef CONFIG_PPC_POWERNV /* Pointer to OPAL machine check event structure set by the diff --git a/trunk/arch/powerpc/include/asm/page_64.h b/trunk/arch/powerpc/include/asm/page_64.h index cd915d6b093d..fed85e6290e1 100644 --- a/trunk/arch/powerpc/include/asm/page_64.h +++ b/trunk/arch/powerpc/include/asm/page_64.h @@ -78,19 +78,11 @@ extern u64 ppc64_pft_size; #define GET_LOW_SLICE_INDEX(addr) ((addr) >> SLICE_LOW_SHIFT) #define GET_HIGH_SLICE_INDEX(addr) ((addr) >> SLICE_HIGH_SHIFT) -/* - * 1 bit per slice and we have one slice per 1TB - * Right now we support only 64TB. - * IF we change this we will have to change the type - * of high_slices - */ -#define SLICE_MASK_SIZE 8 - #ifndef __ASSEMBLY__ struct slice_mask { u16 low_slices; - u64 high_slices; + u16 high_slices; }; struct mm_struct; diff --git a/trunk/arch/powerpc/include/asm/pci-bridge.h b/trunk/arch/powerpc/include/asm/pci-bridge.h index 025a130729bc..8cccbee61519 100644 --- a/trunk/arch/powerpc/include/asm/pci-bridge.h +++ b/trunk/arch/powerpc/include/asm/pci-bridge.h @@ -182,25 +182,14 @@ static inline int pci_device_from_OF_node(struct device_node *np, #if defined(CONFIG_EEH) static inline struct eeh_dev *of_node_to_eeh_dev(struct device_node *dn) { - /* - * For those OF nodes whose parent isn't PCI bridge, they - * don't have PCI_DN actually. So we have to skip them for - * any EEH operations. - */ - if (!dn || !PCI_DN(dn)) - return NULL; - return PCI_DN(dn)->edev; } -#else -#define of_node_to_eeh_dev(x) (NULL) #endif /** Find the bus corresponding to the indicated device node */ extern struct pci_bus *pcibios_find_pci_bus(struct device_node *dn); /** Remove all of the PCI devices under this bus */ -extern void __pcibios_remove_pci_devices(struct pci_bus *bus, int purge_pe); extern void pcibios_remove_pci_devices(struct pci_bus *bus); /** Discover new pci devices under this bus, and add them */ diff --git a/trunk/arch/powerpc/include/asm/pgtable-ppc64-4k.h b/trunk/arch/powerpc/include/asm/pgtable-ppc64-4k.h index 12798c9d4b4b..6eefdcffa359 100644 --- a/trunk/arch/powerpc/include/asm/pgtable-ppc64-4k.h +++ b/trunk/arch/powerpc/include/asm/pgtable-ppc64-4k.h @@ -7,7 +7,7 @@ */ #define PTE_INDEX_SIZE 9 #define PMD_INDEX_SIZE 7 -#define PUD_INDEX_SIZE 9 +#define PUD_INDEX_SIZE 7 #define PGD_INDEX_SIZE 9 #ifndef __ASSEMBLY__ @@ -19,7 +19,7 @@ #define PTRS_PER_PTE (1 << PTE_INDEX_SIZE) #define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) -#define PTRS_PER_PUD (1 << PUD_INDEX_SIZE) +#define PTRS_PER_PUD (1 << PMD_INDEX_SIZE) #define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) /* PMD_SHIFT determines what a second-level page table entry can map */ diff --git a/trunk/arch/powerpc/include/asm/pgtable-ppc64-64k.h b/trunk/arch/powerpc/include/asm/pgtable-ppc64-64k.h index be4e2878fbc0..90533ddcd703 100644 --- a/trunk/arch/powerpc/include/asm/pgtable-ppc64-64k.h +++ b/trunk/arch/powerpc/include/asm/pgtable-ppc64-64k.h @@ -7,7 +7,7 @@ #define PTE_INDEX_SIZE 12 #define PMD_INDEX_SIZE 12 #define PUD_INDEX_SIZE 0 -#define PGD_INDEX_SIZE 6 +#define PGD_INDEX_SIZE 4 #ifndef __ASSEMBLY__ #define PTE_TABLE_SIZE (sizeof(real_pte_t) << PTE_INDEX_SIZE) diff --git a/trunk/arch/powerpc/include/asm/pgtable-ppc64.h b/trunk/arch/powerpc/include/asm/pgtable-ppc64.h index 0182c203e411..c4205616dfb5 100644 --- a/trunk/arch/powerpc/include/asm/pgtable-ppc64.h +++ b/trunk/arch/powerpc/include/asm/pgtable-ppc64.h @@ -21,6 +21,17 @@ #define PGTABLE_RANGE (ASM_CONST(1) << PGTABLE_EADDR_SIZE) +/* Some sanity checking */ +#if TASK_SIZE_USER64 > PGTABLE_RANGE +#error TASK_SIZE_USER64 exceeds pagetable range +#endif + +#ifdef CONFIG_PPC_STD_MMU_64 +#if TASK_SIZE_USER64 > (1UL << (USER_ESID_BITS + SID_SHIFT)) +#error TASK_SIZE_USER64 exceeds user VSID range +#endif +#endif + /* * Define the address range of the kernel non-linear virtual area */ @@ -30,7 +41,7 @@ #else #define KERN_VIRT_START ASM_CONST(0xD000000000000000) #endif -#define KERN_VIRT_SIZE ASM_CONST(0x0000100000000000) +#define KERN_VIRT_SIZE PGTABLE_RANGE /* * The vmalloc space starts at the beginning of that region, and @@ -106,6 +117,9 @@ #ifndef __ASSEMBLY__ +#include +#include + /* * This is the default implementation of various PTE accessors, it's * used in all cases except Book3S with 64K pages where we have a @@ -184,8 +198,7 @@ /* to find an entry in a kernel page-table-directory */ /* This now only contains the vmalloc pages */ #define pgd_offset_k(address) pgd_offset(&init_mm, address) -extern void hpte_need_flush(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, unsigned long pte, int huge); + /* Atomic PTE updates */ static inline unsigned long pte_update(struct mm_struct *mm, diff --git a/trunk/arch/powerpc/include/asm/pgtable.h b/trunk/arch/powerpc/include/asm/pgtable.h index a9cbd3ba5c33..2e0e4110f7ae 100644 --- a/trunk/arch/powerpc/include/asm/pgtable.h +++ b/trunk/arch/powerpc/include/asm/pgtable.h @@ -9,6 +9,14 @@ struct mm_struct; +#ifdef CONFIG_DEBUG_VM +extern void assert_pte_locked(struct mm_struct *mm, unsigned long addr); +#else /* CONFIG_DEBUG_VM */ +static inline void assert_pte_locked(struct mm_struct *mm, unsigned long addr) +{ +} +#endif /* !CONFIG_DEBUG_VM */ + #endif /* !__ASSEMBLY__ */ #if defined(CONFIG_PPC64) @@ -19,8 +27,6 @@ struct mm_struct; #ifndef __ASSEMBLY__ -#include - /* Generic accessors to PTE bits */ static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } diff --git a/trunk/arch/powerpc/include/asm/ppc-opcode.h b/trunk/arch/powerpc/include/asm/ppc-opcode.h index 5f73ce63fcae..4c25319f2fbc 100644 --- a/trunk/arch/powerpc/include/asm/ppc-opcode.h +++ b/trunk/arch/powerpc/include/asm/ppc-opcode.h @@ -126,7 +126,6 @@ #define PPC_INST_TLBIVAX 0x7c000624 #define PPC_INST_TLBSRX_DOT 0x7c0006a5 #define PPC_INST_XXLOR 0xf0000510 -#define PPC_INST_XVCPSGNDP 0xf0000780 #define PPC_INST_NAP 0x4c000364 #define PPC_INST_SLEEP 0x4c0003a4 @@ -278,8 +277,6 @@ VSX_XX1((s), a, b)) #define XXLOR(t, a, b) stringify_in_c(.long PPC_INST_XXLOR | \ VSX_XX3((t), a, b)) -#define XVCPSGNDP(t, a, b) stringify_in_c(.long (PPC_INST_XVCPSGNDP | \ - VSX_XX3((t), (a), (b)))) #define PPC_NAP stringify_in_c(.long PPC_INST_NAP) #define PPC_SLEEP stringify_in_c(.long PPC_INST_SLEEP) diff --git a/trunk/arch/powerpc/include/asm/ppc-pci.h b/trunk/arch/powerpc/include/asm/ppc-pci.h index ed57fa7920c8..80fa704d410f 100644 --- a/trunk/arch/powerpc/include/asm/ppc-pci.h +++ b/trunk/arch/powerpc/include/asm/ppc-pci.h @@ -47,17 +47,19 @@ extern int rtas_setup_phb(struct pci_controller *phb); #ifdef CONFIG_EEH -void eeh_addr_cache_insert_dev(struct pci_dev *dev); -void eeh_addr_cache_rmv_dev(struct pci_dev *dev); -struct eeh_dev *eeh_addr_cache_get_dev(unsigned long addr); -void eeh_slot_error_detail(struct eeh_pe *pe, int severity); -int eeh_pci_enable(struct eeh_pe *pe, int function); -int eeh_reset_pe(struct eeh_pe *); -void eeh_save_bars(struct eeh_dev *edev); +void pci_addr_cache_build(void); +void pci_addr_cache_insert_device(struct pci_dev *dev); +void pci_addr_cache_remove_device(struct pci_dev *dev); +struct pci_dev *pci_addr_cache_get_device(unsigned long addr); +void eeh_slot_error_detail(struct eeh_dev *edev, int severity); +int eeh_pci_enable(struct eeh_dev *edev, int function); +int eeh_reset_pe(struct eeh_dev *); +void eeh_restore_bars(struct eeh_dev *); int rtas_write_config(struct pci_dn *, int where, int size, u32 val); int rtas_read_config(struct pci_dn *, int where, int size, u32 *val); -void eeh_pe_state_mark(struct eeh_pe *pe, int state); -void eeh_pe_state_clear(struct eeh_pe *pe, int state); +void eeh_mark_slot(struct device_node *dn, int mode_flag); +void eeh_clear_slot(struct device_node *dn, int mode_flag); +struct device_node *eeh_find_device_pe(struct device_node *dn); void eeh_sysfs_add_device(struct pci_dev *pdev); void eeh_sysfs_remove_device(struct pci_dev *pdev); diff --git a/trunk/arch/powerpc/include/asm/probes.h b/trunk/arch/powerpc/include/asm/probes.h deleted file mode 100644 index 5f1e15b68704..000000000000 --- a/trunk/arch/powerpc/include/asm/probes.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _ASM_POWERPC_PROBES_H -#define _ASM_POWERPC_PROBES_H -#ifdef __KERNEL__ -/* - * Definitions common to probes files - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright IBM Corporation, 2012 - */ -#include - -typedef u32 ppc_opcode_t; -#define BREAKPOINT_INSTRUCTION 0x7fe00008 /* trap */ - -/* Trap definitions per ISA */ -#define IS_TW(instr) (((instr) & 0xfc0007fe) == 0x7c000008) -#define IS_TD(instr) (((instr) & 0xfc0007fe) == 0x7c000088) -#define IS_TDI(instr) (((instr) & 0xfc000000) == 0x08000000) -#define IS_TWI(instr) (((instr) & 0xfc000000) == 0x0c000000) - -#ifdef CONFIG_PPC64 -#define is_trap(instr) (IS_TW(instr) || IS_TD(instr) || \ - IS_TWI(instr) || IS_TDI(instr)) -#else -#define is_trap(instr) (IS_TW(instr) || IS_TWI(instr)) -#endif /* CONFIG_PPC64 */ - -#endif /* __KERNEL__ */ -#endif /* _ASM_POWERPC_PROBES_H */ diff --git a/trunk/arch/powerpc/include/asm/processor.h b/trunk/arch/powerpc/include/asm/processor.h index 9dc5cd1fde1a..54b73a28c205 100644 --- a/trunk/arch/powerpc/include/asm/processor.h +++ b/trunk/arch/powerpc/include/asm/processor.h @@ -97,8 +97,8 @@ extern struct task_struct *last_task_used_spe; #endif #ifdef CONFIG_PPC64 -/* 64-bit user address space is 46-bits (64TB user VM) */ -#define TASK_SIZE_USER64 (0x0000400000000000UL) +/* 64-bit user address space is 44-bits (16TB user VM) */ +#define TASK_SIZE_USER64 (0x0000100000000000UL) /* * 32-bit user address space is 4GB - 1 page @@ -219,8 +219,6 @@ struct thread_struct { #endif /* CONFIG_HAVE_HW_BREAKPOINT */ #endif unsigned long dabr; /* Data address breakpoint register */ - unsigned long dabrx; /* ... extension */ - unsigned long trap_nr; /* last trap # on this thread */ #ifdef CONFIG_ALTIVEC /* Complete AltiVec register set */ vector128 vr[32] __attribute__((aligned(16))); diff --git a/trunk/arch/powerpc/include/asm/pte-hash64-64k.h b/trunk/arch/powerpc/include/asm/pte-hash64-64k.h index eedf427c9124..59247e816ac5 100644 --- a/trunk/arch/powerpc/include/asm/pte-hash64-64k.h +++ b/trunk/arch/powerpc/include/asm/pte-hash64-64k.h @@ -58,16 +58,14 @@ /* Trick: we set __end to va + 64k, which happens works for * a 16M page as well as we want only one iteration */ -#define pte_iterate_hashed_subpages(rpte, psize, vpn, index, shift) \ - do { \ - unsigned long __end = vpn + (1UL << (PAGE_SHIFT - VPN_SHIFT)); \ - unsigned __split = (psize == MMU_PAGE_4K || \ - psize == MMU_PAGE_64K_AP); \ - shift = mmu_psize_defs[psize].shift; \ - for (index = 0; vpn < __end; index++, \ - vpn += (1L << (shift - VPN_SHIFT))) { \ - if (!__split || __rpte_sub_valid(rpte, index)) \ - do { +#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ + do { \ + unsigned long __end = va + PAGE_SIZE; \ + unsigned __split = (psize == MMU_PAGE_4K || \ + psize == MMU_PAGE_64K_AP); \ + shift = mmu_psize_defs[psize].shift; \ + for (index = 0; va < __end; index++, va += (1L << shift)) { \ + if (!__split || __rpte_sub_valid(rpte, index)) do { \ #define pte_iterate_hashed_end() } while(0); } } while(0) diff --git a/trunk/arch/powerpc/include/asm/reg.h b/trunk/arch/powerpc/include/asm/reg.h index a1096fb62816..638608677e2a 100644 --- a/trunk/arch/powerpc/include/asm/reg.h +++ b/trunk/arch/powerpc/include/asm/reg.h @@ -208,9 +208,6 @@ #define SPRN_DABRX 0x3F7 /* Data Address Breakpoint Register Extension */ #define DABRX_USER (1UL << 0) #define DABRX_KERNEL (1UL << 1) -#define DABRX_HYP (1UL << 2) -#define DABRX_BTI (1UL << 3) -#define DABRX_ALL (DABRX_BTI | DABRX_HYP | DABRX_KERNEL | DABRX_USER) #define SPRN_DAR 0x013 /* Data Address Register */ #define SPRN_DBCR 0x136 /* e300 Data Breakpoint Control Reg */ #define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ @@ -524,7 +521,6 @@ #define SPRN_HSRR0 0x13A /* Save/Restore Register 0 */ #define SPRN_HSRR1 0x13B /* Save/Restore Register 1 */ -#define HSRR1_DENORM 0x00100000 /* Denorm exception */ #define SPRN_TBCTL 0x35f /* PA6T Timebase control register */ #define TBCTL_FREEZE 0x0000000000000000ull /* Freeze all tbs */ @@ -765,8 +761,7 @@ * 64-bit embedded * - SPRG0 generic exception scratch * - SPRG2 TLB exception stack - * - SPRG3 critical exception scratch and - * CPU and NUMA node for VDSO getcpu (user visible) + * - SPRG3 CPU and NUMA node for VDSO getcpu (user visible) * - SPRG4 unused (user visible) * - SPRG6 TLB miss scratch (user visible, sorry !) * - SPRG7 critical exception scratch @@ -863,12 +858,11 @@ #ifdef CONFIG_PPC_BOOK3E_64 #define SPRN_SPRG_MC_SCRATCH SPRN_SPRG8 -#define SPRN_SPRG_CRIT_SCRATCH SPRN_SPRG3 +#define SPRN_SPRG_CRIT_SCRATCH SPRN_SPRG7 #define SPRN_SPRG_DBG_SCRATCH SPRN_SPRG9 #define SPRN_SPRG_TLB_EXFRAME SPRN_SPRG2 #define SPRN_SPRG_TLB_SCRATCH SPRN_SPRG6 #define SPRN_SPRG_GEN_SCRATCH SPRN_SPRG0 -#define SPRN_SPRG_GDBELL_SCRATCH SPRN_SPRG_GEN_SCRATCH #define SET_PACA(rX) mtspr SPRN_SPRG_PACA,rX #define GET_PACA(rX) mfspr rX,SPRN_SPRG_PACA @@ -943,7 +937,7 @@ #define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */ #define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */ -#define pvr_version_is(pvr) (PVR_VER(mfspr(SPRN_PVR)) == (pvr)) +#define __is_processor(pv) (PVR_VER(mfspr(SPRN_PVR)) == (pv)) /* * IBM has further subdivided the standard PowerPC 16-bit version and @@ -1008,25 +1002,25 @@ #define PVR_476_ISS 0x00052000 /* 64-bit processors */ -#define PVR_NORTHSTAR 0x0033 -#define PVR_PULSAR 0x0034 -#define PVR_POWER4 0x0035 -#define PVR_ICESTAR 0x0036 -#define PVR_SSTAR 0x0037 -#define PVR_POWER4p 0x0038 -#define PVR_970 0x0039 -#define PVR_POWER5 0x003A -#define PVR_POWER5p 0x003B -#define PVR_970FX 0x003C -#define PVR_POWER6 0x003E -#define PVR_POWER7 0x003F -#define PVR_630 0x0040 -#define PVR_630p 0x0041 -#define PVR_970MP 0x0044 -#define PVR_970GX 0x0045 -#define PVR_POWER7p 0x004A -#define PVR_BE 0x0070 -#define PVR_PA6T 0x0090 +/* XXX the prefix should be PVR_, we'll do a global sweep to fix it one day */ +#define PV_NORTHSTAR 0x0033 +#define PV_PULSAR 0x0034 +#define PV_POWER4 0x0035 +#define PV_ICESTAR 0x0036 +#define PV_SSTAR 0x0037 +#define PV_POWER4p 0x0038 +#define PV_970 0x0039 +#define PV_POWER5 0x003A +#define PV_POWER5p 0x003B +#define PV_970FX 0x003C +#define PV_POWER6 0x003E +#define PV_POWER7 0x003F +#define PV_630 0x0040 +#define PV_630p 0x0041 +#define PV_970MP 0x0044 +#define PV_970GX 0x0045 +#define PV_BE 0x0070 +#define PV_PA6T 0x0090 /* Macros for setting and retrieving special purpose registers */ #ifndef __ASSEMBLY__ diff --git a/trunk/arch/powerpc/include/asm/setup.h b/trunk/arch/powerpc/include/asm/setup.h index 8b9a306260b2..d084ce195fc3 100644 --- a/trunk/arch/powerpc/include/asm/setup.h +++ b/trunk/arch/powerpc/include/asm/setup.h @@ -9,7 +9,7 @@ extern void ppc_printk_progress(char *s, unsigned short hex); extern unsigned int rtas_data; extern int mem_init_done; /* set on boot once kmalloc can be called */ extern int init_bootmem_done; /* set once bootmem is available */ -extern unsigned long long memory_limit; +extern phys_addr_t memory_limit; extern unsigned long klimit; extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask); diff --git a/trunk/arch/powerpc/include/asm/smp.h b/trunk/arch/powerpc/include/asm/smp.h index e807e9d8e3f7..ebc24dc5b1a1 100644 --- a/trunk/arch/powerpc/include/asm/smp.h +++ b/trunk/arch/powerpc/include/asm/smp.h @@ -65,7 +65,6 @@ int generic_cpu_disable(void); void generic_cpu_die(unsigned int cpu); void generic_mach_cpu_die(void); void generic_set_cpu_dead(unsigned int cpu); -void generic_set_cpu_up(unsigned int cpu); int generic_check_cpu_restart(unsigned int cpu); #endif @@ -191,7 +190,6 @@ extern unsigned long __secondary_hold_spinloop; extern unsigned long __secondary_hold_acknowledge; extern char __secondary_hold; -extern void __early_start(void); #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/trunk/arch/powerpc/include/asm/sparsemem.h b/trunk/arch/powerpc/include/asm/sparsemem.h index f6fc0ee813d7..0c5fa3145615 100644 --- a/trunk/arch/powerpc/include/asm/sparsemem.h +++ b/trunk/arch/powerpc/include/asm/sparsemem.h @@ -10,8 +10,8 @@ */ #define SECTION_SIZE_BITS 24 -#define MAX_PHYSADDR_BITS 46 -#define MAX_PHYSMEM_BITS 46 +#define MAX_PHYSADDR_BITS 44 +#define MAX_PHYSMEM_BITS 44 #endif /* CONFIG_SPARSEMEM */ diff --git a/trunk/arch/powerpc/include/asm/swiotlb.h b/trunk/arch/powerpc/include/asm/swiotlb.h index de99d6e29430..8979d4cd3d70 100644 --- a/trunk/arch/powerpc/include/asm/swiotlb.h +++ b/trunk/arch/powerpc/include/asm/swiotlb.h @@ -22,10 +22,4 @@ int __init swiotlb_setup_bus_notifier(void); extern void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev); -#ifdef CONFIG_SWIOTLB -void swiotlb_detect_4g(void); -#else -static inline void swiotlb_detect_4g(void) {} -#endif - #endif /* __ASM_SWIOTLB_H */ diff --git a/trunk/arch/powerpc/include/asm/thread_info.h b/trunk/arch/powerpc/include/asm/thread_info.h index 8ceea14d6fe4..faf93529cbf0 100644 --- a/trunk/arch/powerpc/include/asm/thread_info.h +++ b/trunk/arch/powerpc/include/asm/thread_info.h @@ -102,10 +102,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_RESTOREALL 11 /* Restore all regs (implies NOERROR) */ #define TIF_NOERROR 12 /* Force successful syscall return */ #define TIF_NOTIFY_RESUME 13 /* callback before returning to user */ -#define TIF_UPROBE 14 /* breakpointed or single-stepping */ #define TIF_SYSCALL_TRACEPOINT 15 /* syscall tracepoint instrumentation */ -#define TIF_EMULATE_STACK_STORE 16 /* Is an instruction emulation - for stack store? */ /* as above, but as bit values */ #define _TIF_SYSCALL_TRACE (1< - */ - -#include -#include - -typedef ppc_opcode_t uprobe_opcode_t; - -#define MAX_UINSN_BYTES 4 -#define UPROBE_XOL_SLOT_BYTES (MAX_UINSN_BYTES) - -/* The following alias is needed for reference from arch-agnostic code */ -#define UPROBE_SWBP_INSN BREAKPOINT_INSTRUCTION -#define UPROBE_SWBP_INSN_SIZE 4 /* swbp insn size in bytes */ - -struct arch_uprobe { - union { - u8 insn[MAX_UINSN_BYTES]; - u32 ainsn; - }; -}; - -struct arch_uprobe_task { - unsigned long saved_trap_nr; -}; - -extern int arch_uprobe_analyze_insn(struct arch_uprobe *aup, struct mm_struct *mm, unsigned long addr); -extern int arch_uprobe_pre_xol(struct arch_uprobe *aup, struct pt_regs *regs); -extern int arch_uprobe_post_xol(struct arch_uprobe *aup, struct pt_regs *regs); -extern bool arch_uprobe_xol_was_trapped(struct task_struct *tsk); -extern int arch_uprobe_exception_notify(struct notifier_block *self, unsigned long val, void *data); -extern void arch_uprobe_abort_xol(struct arch_uprobe *aup, struct pt_regs *regs); -#endif /* _ASM_UPROBES_H */ diff --git a/trunk/arch/powerpc/kernel/Makefile b/trunk/arch/powerpc/kernel/Makefile index cde12f8a4ebc..bb282dd81612 100644 --- a/trunk/arch/powerpc/kernel/Makefile +++ b/trunk/arch/powerpc/kernel/Makefile @@ -96,7 +96,6 @@ obj-$(CONFIG_MODULES) += ppc_ksyms.o obj-$(CONFIG_BOOTX_TEXT) += btext.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_KPROBES) += kprobes.o -obj-$(CONFIG_UPROBES) += uprobes.o obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_SWIOTLB) += dma-swiotlb.o diff --git a/trunk/arch/powerpc/kernel/asm-offsets.c b/trunk/arch/powerpc/kernel/asm-offsets.c index 7523539cfe9f..e8995727b1c1 100644 --- a/trunk/arch/powerpc/kernel/asm-offsets.c +++ b/trunk/arch/powerpc/kernel/asm-offsets.c @@ -206,7 +206,6 @@ int main(void) DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time)); DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save)); DEFINE(PACA_NAPSTATELOST, offsetof(struct paca_struct, nap_state_lost)); - DEFINE(PACA_SPRG3, offsetof(struct paca_struct, sprg3)); #endif /* CONFIG_PPC64 */ /* RTAS */ @@ -535,6 +534,7 @@ int main(void) HSTATE_FIELD(HSTATE_VMHANDLER, vmhandler); HSTATE_FIELD(HSTATE_SCRATCH0, scratch0); HSTATE_FIELD(HSTATE_SCRATCH1, scratch1); + HSTATE_FIELD(HSTATE_SPRG3, sprg3); HSTATE_FIELD(HSTATE_IN_GUEST, in_guest); HSTATE_FIELD(HSTATE_RESTORE_HID5, restore_hid5); HSTATE_FIELD(HSTATE_NAPPING, napping); diff --git a/trunk/arch/powerpc/kernel/cpu_setup_fsl_booke.S b/trunk/arch/powerpc/kernel/cpu_setup_fsl_booke.S index dcd881937f7a..69fdd2322a66 100644 --- a/trunk/arch/powerpc/kernel/cpu_setup_fsl_booke.S +++ b/trunk/arch/powerpc/kernel/cpu_setup_fsl_booke.S @@ -16,8 +16,6 @@ #include #include #include -#include -#include _GLOBAL(__e500_icache_setup) mfspr r0, SPRN_L1CSR1 @@ -75,81 +73,27 @@ _GLOBAL(__setup_cpu_e500v2) mtlr r4 blr _GLOBAL(__setup_cpu_e500mc) -_GLOBAL(__setup_cpu_e5500) - mflr r5 + mr r5, r4 + mflr r4 bl __e500_icache_setup bl __e500_dcache_setup bl __setup_e500mc_ivors - /* - * We only want to touch IVOR38-41 if we're running on hardware - * that supports category E.HV. The architectural way to determine - * this is MMUCFG[LPIDSIZE]. - */ - mfspr r3, SPRN_MMUCFG - rlwinm. r3, r3, 0, MMUCFG_LPIDSIZE - beq 1f - bl __setup_ehv_ivors - b 2f -1: - lwz r3, CPU_SPEC_FEATURES(r4) - /* We need this check as cpu_setup is also called for - * the secondary cores. So, if we have already cleared - * the feature on the primary core, avoid doing it on the - * secondary core. - */ - andis. r6, r3, CPU_FTR_EMB_HV@h - beq 2f - rlwinm r3, r3, 0, ~CPU_FTR_EMB_HV - stw r3, CPU_SPEC_FEATURES(r4) -2: - mtlr r5 + mtlr r4 blr #endif - -#ifdef CONFIG_PPC_BOOK3E_64 +/* Right now, restore and setup are the same thing */ _GLOBAL(__restore_cpu_e5500) +_GLOBAL(__setup_cpu_e5500) mflr r4 bl __e500_icache_setup bl __e500_dcache_setup +#ifdef CONFIG_PPC_BOOK3E_64 bl .__setup_base_ivors bl .setup_perfmon_ivor bl .setup_doorbell_ivors - /* - * We only want to touch IVOR38-41 if we're running on hardware - * that supports category E.HV. The architectural way to determine - * this is MMUCFG[LPIDSIZE]. - */ - mfspr r10,SPRN_MMUCFG - rlwinm. r10,r10,0,MMUCFG_LPIDSIZE - beq 1f bl .setup_ehv_ivors -1: +#else + bl __setup_e500mc_ivors +#endif mtlr r4 blr - -_GLOBAL(__setup_cpu_e5500) - mflr r5 - bl __e500_icache_setup - bl __e500_dcache_setup - bl .__setup_base_ivors - bl .setup_perfmon_ivor - bl .setup_doorbell_ivors - /* - * We only want to touch IVOR38-41 if we're running on hardware - * that supports category E.HV. The architectural way to determine - * this is MMUCFG[LPIDSIZE]. - */ - mfspr r10,SPRN_MMUCFG - rlwinm. r10,r10,0,MMUCFG_LPIDSIZE - beq 1f - bl .setup_ehv_ivors - b 2f -1: - ld r10,CPU_SPEC_FEATURES(r4) - LOAD_REG_IMMEDIATE(r9,CPU_FTR_EMB_HV) - andc r10,r10,r9 - std r10,CPU_SPEC_FEATURES(r4) -2: - mtlr r5 - blr -#endif diff --git a/trunk/arch/powerpc/kernel/cputable.c b/trunk/arch/powerpc/kernel/cputable.c index 0514c21f138b..455faa389876 100644 --- a/trunk/arch/powerpc/kernel/cputable.c +++ b/trunk/arch/powerpc/kernel/cputable.c @@ -2016,9 +2016,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .oprofile_cpu_type = "ppc/e500mc", .oprofile_type = PPC_OPROFILE_FSL_EMB, .cpu_setup = __setup_cpu_e5500, -#ifndef CONFIG_PPC32 .cpu_restore = __restore_cpu_e5500, -#endif .machine_check = machine_check_e500mc, .platform = "ppce5500", }, @@ -2036,9 +2034,7 @@ static struct cpu_spec __initdata cpu_specs[] = { .oprofile_cpu_type = "ppc/e6500", .oprofile_type = PPC_OPROFILE_FSL_EMB, .cpu_setup = __setup_cpu_e5500, -#ifndef CONFIG_PPC32 .cpu_restore = __restore_cpu_e5500, -#endif .machine_check = machine_check_e500mc, .platform = "ppce6500", }, diff --git a/trunk/arch/powerpc/kernel/dma-swiotlb.c b/trunk/arch/powerpc/kernel/dma-swiotlb.c index bd1a2aba599f..46943651da23 100644 --- a/trunk/arch/powerpc/kernel/dma-swiotlb.c +++ b/trunk/arch/powerpc/kernel/dma-swiotlb.c @@ -12,7 +12,6 @@ */ #include -#include #include #include #include @@ -21,6 +20,7 @@ #include #include #include +#include unsigned int ppc_swiotlb_enable; @@ -105,23 +105,3 @@ int __init swiotlb_setup_bus_notifier(void) &ppc_swiotlb_plat_bus_notifier); return 0; } - -void swiotlb_detect_4g(void) -{ - if ((memblock_end_of_DRAM() - 1) > 0xffffffff) - ppc_swiotlb_enable = 1; -} - -static int __init swiotlb_late_init(void) -{ - if (ppc_swiotlb_enable) { - swiotlb_print_info(); - set_pci_dma_ops(&swiotlb_dma_ops); - ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; - } else { - swiotlb_free(); - } - - return 0; -} -subsys_initcall(swiotlb_late_init); diff --git a/trunk/arch/powerpc/kernel/dma.c b/trunk/arch/powerpc/kernel/dma.c index 8032b97ccdcb..355b9d84b0f8 100644 --- a/trunk/arch/powerpc/kernel/dma.c +++ b/trunk/arch/powerpc/kernel/dma.c @@ -14,6 +14,7 @@ #include #include #include +#include #include /* @@ -49,7 +50,7 @@ void *dma_direct_alloc_coherent(struct device *dev, size_t size, return NULL; ret = page_address(page); memset(ret, 0, size); - *dma_handle = __pa(ret) + get_dma_offset(dev); + *dma_handle = virt_to_abs(ret) + get_dma_offset(dev); return ret; #endif diff --git a/trunk/arch/powerpc/kernel/entry_32.S b/trunk/arch/powerpc/kernel/entry_32.S index af37528da49f..ead5016b02d0 100644 --- a/trunk/arch/powerpc/kernel/entry_32.S +++ b/trunk/arch/powerpc/kernel/entry_32.S @@ -831,56 +831,19 @@ restore_user: bnel- load_dbcr0 #endif +#ifdef CONFIG_PREEMPT b restore /* N.B. the only way to get here is from the beq following ret_from_except. */ resume_kernel: - /* check current_thread_info, _TIF_EMULATE_STACK_STORE */ - CURRENT_THREAD_INFO(r9, r1) - lwz r8,TI_FLAGS(r9) - andis. r8,r8,_TIF_EMULATE_STACK_STORE@h - beq+ 1f - - addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */ - - lwz r3,GPR1(r1) - subi r3,r3,INT_FRAME_SIZE /* dst: Allocate a trampoline exception frame */ - mr r4,r1 /* src: current exception frame */ - mr r1,r3 /* Reroute the trampoline frame to r1 */ - - /* Copy from the original to the trampoline. */ - li r5,INT_FRAME_SIZE/4 /* size: INT_FRAME_SIZE */ - li r6,0 /* start offset: 0 */ - mtctr r5 -2: lwzx r0,r6,r4 - stwx r0,r6,r3 - addi r6,r6,4 - bdnz 2b - - /* Do real store operation to complete stwu */ - lwz r5,GPR1(r1) - stw r8,0(r5) - - /* Clear _TIF_EMULATE_STACK_STORE flag */ - lis r11,_TIF_EMULATE_STACK_STORE@h - addi r5,r9,TI_FLAGS -0: lwarx r8,0,r5 - andc r8,r8,r11 -#ifdef CONFIG_IBM405_ERR77 - dcbt 0,r5 -#endif - stwcx. r8,0,r5 - bne- 0b -1: - -#ifdef CONFIG_PREEMPT /* check current_thread_info->preempt_count */ + CURRENT_THREAD_INFO(r9, r1) lwz r0,TI_PREEMPT(r9) cmpwi 0,r0,0 /* if non-zero, just restore regs and return */ bne restore - andi. r8,r8,_TIF_NEED_RESCHED + lwz r0,TI_FLAGS(r9) + andi. r0,r0,_TIF_NEED_RESCHED beq+ restore - lwz r3,_MSR(r1) andi. r0,r3,MSR_EE /* interrupts off? */ beq restore /* don't schedule if so */ #ifdef CONFIG_TRACE_IRQFLAGS @@ -901,6 +864,8 @@ resume_kernel: */ bl trace_hardirqs_on #endif +#else +resume_kernel: #endif /* CONFIG_PREEMPT */ /* interrupts are hard-disabled at this point */ diff --git a/trunk/arch/powerpc/kernel/entry_64.S b/trunk/arch/powerpc/kernel/entry_64.S index 0e931aaffca2..b40e0b4815b3 100644 --- a/trunk/arch/powerpc/kernel/entry_64.S +++ b/trunk/arch/powerpc/kernel/entry_64.S @@ -593,41 +593,6 @@ _GLOBAL(ret_from_except_lite) b .ret_from_except resume_kernel: - /* check current_thread_info, _TIF_EMULATE_STACK_STORE */ - CURRENT_THREAD_INFO(r9, r1) - ld r8,TI_FLAGS(r9) - andis. r8,r8,_TIF_EMULATE_STACK_STORE@h - beq+ 1f - - addi r8,r1,INT_FRAME_SIZE /* Get the kprobed function entry */ - - lwz r3,GPR1(r1) - subi r3,r3,INT_FRAME_SIZE /* dst: Allocate a trampoline exception frame */ - mr r4,r1 /* src: current exception frame */ - mr r1,r3 /* Reroute the trampoline frame to r1 */ - - /* Copy from the original to the trampoline. */ - li r5,INT_FRAME_SIZE/8 /* size: INT_FRAME_SIZE */ - li r6,0 /* start offset: 0 */ - mtctr r5 -2: ldx r0,r6,r4 - stdx r0,r6,r3 - addi r6,r6,8 - bdnz 2b - - /* Do real store operation to complete stwu */ - lwz r5,GPR1(r1) - std r8,0(r5) - - /* Clear _TIF_EMULATE_STACK_STORE flag */ - lis r11,_TIF_EMULATE_STACK_STORE@h - addi r5,r9,TI_FLAGS - ldarx r4,0,r5 - andc r4,r4,r11 - stdcx. r4,0,r5 - bne- 0b -1: - #ifdef CONFIG_PREEMPT /* Check if we need to preempt */ andi. r0,r4,_TIF_NEED_RESCHED diff --git a/trunk/arch/powerpc/kernel/exceptions-64e.S b/trunk/arch/powerpc/kernel/exceptions-64e.S index 4684e33a26c3..98be7f0cd227 100644 --- a/trunk/arch/powerpc/kernel/exceptions-64e.S +++ b/trunk/arch/powerpc/kernel/exceptions-64e.S @@ -25,8 +25,6 @@ #include #include #include -#include -#include /* XXX This will ultimately add space for a special exception save * structure used to save things like SRR0/SRR1, SPRGs, MAS, etc... @@ -37,18 +35,16 @@ #define SPECIAL_EXC_FRAME_SIZE INT_FRAME_SIZE /* Exception prolog code for all exceptions */ -#define EXCEPTION_PROLOG(n, intnum, type, addition) \ +#define EXCEPTION_PROLOG(n, type, addition) \ mtspr SPRN_SPRG_##type##_SCRATCH,r13; /* get spare registers */ \ mfspr r13,SPRN_SPRG_PACA; /* get PACA */ \ std r10,PACA_EX##type+EX_R10(r13); \ std r11,PACA_EX##type+EX_R11(r13); \ - PROLOG_STORE_RESTORE_SCRATCH_##type; \ mfcr r10; /* save CR */ \ - mfspr r11,SPRN_##type##_SRR1;/* what are we coming from */ \ - DO_KVM intnum,SPRN_##type##_SRR1; /* KVM hook */ \ - stw r10,PACA_EX##type+EX_CR(r13); /* save old CR in the PACA */ \ addition; /* additional code for that exc. */ \ std r1,PACA_EX##type+EX_R1(r13); /* save old r1 in the PACA */ \ + stw r10,PACA_EX##type+EX_CR(r13); /* save old CR in the PACA */ \ + mfspr r11,SPRN_##type##_SRR1;/* what are we coming from */ \ type##_SET_KSTACK; /* get special stack if necessary */\ andi. r10,r11,MSR_PR; /* save stack pointer */ \ beq 1f; /* branch around if supervisor */ \ @@ -63,10 +59,6 @@ #define SPRN_GEN_SRR0 SPRN_SRR0 #define SPRN_GEN_SRR1 SPRN_SRR1 -#define GDBELL_SET_KSTACK GEN_SET_KSTACK -#define SPRN_GDBELL_SRR0 SPRN_GSRR0 -#define SPRN_GDBELL_SRR1 SPRN_GSRR1 - #define CRIT_SET_KSTACK \ ld r1,PACA_CRIT_STACK(r13); \ subi r1,r1,SPECIAL_EXC_FRAME_SIZE; @@ -85,46 +77,29 @@ #define SPRN_MC_SRR0 SPRN_MCSRR0 #define SPRN_MC_SRR1 SPRN_MCSRR1 -#define NORMAL_EXCEPTION_PROLOG(n, intnum, addition) \ - EXCEPTION_PROLOG(n, intnum, GEN, addition##_GEN(n)) - -#define CRIT_EXCEPTION_PROLOG(n, intnum, addition) \ - EXCEPTION_PROLOG(n, intnum, CRIT, addition##_CRIT(n)) +#define NORMAL_EXCEPTION_PROLOG(n, addition) \ + EXCEPTION_PROLOG(n, GEN, addition##_GEN(n)) -#define DBG_EXCEPTION_PROLOG(n, intnum, addition) \ - EXCEPTION_PROLOG(n, intnum, DBG, addition##_DBG(n)) +#define CRIT_EXCEPTION_PROLOG(n, addition) \ + EXCEPTION_PROLOG(n, CRIT, addition##_CRIT(n)) -#define MC_EXCEPTION_PROLOG(n, intnum, addition) \ - EXCEPTION_PROLOG(n, intnum, MC, addition##_MC(n)) +#define DBG_EXCEPTION_PROLOG(n, addition) \ + EXCEPTION_PROLOG(n, DBG, addition##_DBG(n)) -#define GDBELL_EXCEPTION_PROLOG(n, intnum, addition) \ - EXCEPTION_PROLOG(n, intnum, GDBELL, addition##_GDBELL(n)) +#define MC_EXCEPTION_PROLOG(n, addition) \ + EXCEPTION_PROLOG(n, MC, addition##_MC(n)) -/* - * Store user-visible scratch in PACA exception slots and restore proper value - */ -#define PROLOG_STORE_RESTORE_SCRATCH_GEN -#define PROLOG_STORE_RESTORE_SCRATCH_GDBELL -#define PROLOG_STORE_RESTORE_SCRATCH_DBG -#define PROLOG_STORE_RESTORE_SCRATCH_MC - -#define PROLOG_STORE_RESTORE_SCRATCH_CRIT \ - mfspr r10,SPRN_SPRG_CRIT_SCRATCH; /* get r13 */ \ - std r10,PACA_EXCRIT+EX_R13(r13); \ - ld r11,PACA_SPRG3(r13); \ - mtspr SPRN_SPRG_CRIT_SCRATCH,r11; /* Variants of the "addition" argument for the prolog */ #define PROLOG_ADDITION_NONE_GEN(n) -#define PROLOG_ADDITION_NONE_GDBELL(n) #define PROLOG_ADDITION_NONE_CRIT(n) #define PROLOG_ADDITION_NONE_DBG(n) #define PROLOG_ADDITION_NONE_MC(n) #define PROLOG_ADDITION_MASKABLE_GEN(n) \ - lbz r10,PACASOFTIRQEN(r13); /* are irqs soft-disabled ? */ \ - cmpwi cr0,r10,0; /* yes -> go out of line */ \ + lbz r11,PACASOFTIRQEN(r13); /* are irqs soft-disabled ? */ \ + cmpwi cr0,r11,0; /* yes -> go out of line */ \ beq masked_interrupt_book3e_##n #define PROLOG_ADDITION_2REGS_GEN(n) \ @@ -258,9 +233,9 @@ exc_##n##_bad_stack: \ 1: -#define MASKABLE_EXCEPTION(trapnum, intnum, label, hdlr, ack) \ +#define MASKABLE_EXCEPTION(trapnum, label, hdlr, ack) \ START_EXCEPTION(label); \ - NORMAL_EXCEPTION_PROLOG(trapnum, intnum, PROLOG_ADDITION_MASKABLE)\ + NORMAL_EXCEPTION_PROLOG(trapnum, PROLOG_ADDITION_MASKABLE) \ EXCEPTION_COMMON(trapnum, PACA_EXGEN, INTS_DISABLE) \ ack(r8); \ CHECK_NAPPING(); \ @@ -311,8 +286,7 @@ interrupt_end_book3e: /* Critical Input Interrupt */ START_EXCEPTION(critical_input); - CRIT_EXCEPTION_PROLOG(0x100, BOOKE_INTERRUPT_CRITICAL, - PROLOG_ADDITION_NONE) + CRIT_EXCEPTION_PROLOG(0x100, PROLOG_ADDITION_NONE) // EXCEPTION_COMMON(0x100, PACA_EXCRIT, INTS_DISABLE) // bl special_reg_save_crit // CHECK_NAPPING(); @@ -323,8 +297,7 @@ interrupt_end_book3e: /* Machine Check Interrupt */ START_EXCEPTION(machine_check); - MC_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_MACHINE_CHECK, - PROLOG_ADDITION_NONE) + CRIT_EXCEPTION_PROLOG(0x200, PROLOG_ADDITION_NONE) // EXCEPTION_COMMON(0x200, PACA_EXMC, INTS_DISABLE) // bl special_reg_save_mc // addi r3,r1,STACK_FRAME_OVERHEAD @@ -335,8 +308,7 @@ interrupt_end_book3e: /* Data Storage Interrupt */ START_EXCEPTION(data_storage) - NORMAL_EXCEPTION_PROLOG(0x300, BOOKE_INTERRUPT_DATA_STORAGE, - PROLOG_ADDITION_2REGS) + NORMAL_EXCEPTION_PROLOG(0x300, PROLOG_ADDITION_2REGS) mfspr r14,SPRN_DEAR mfspr r15,SPRN_ESR EXCEPTION_COMMON(0x300, PACA_EXGEN, INTS_DISABLE) @@ -344,21 +316,18 @@ interrupt_end_book3e: /* Instruction Storage Interrupt */ START_EXCEPTION(instruction_storage); - NORMAL_EXCEPTION_PROLOG(0x400, BOOKE_INTERRUPT_INST_STORAGE, - PROLOG_ADDITION_2REGS) + NORMAL_EXCEPTION_PROLOG(0x400, PROLOG_ADDITION_2REGS) li r15,0 mr r14,r10 EXCEPTION_COMMON(0x400, PACA_EXGEN, INTS_DISABLE) b storage_fault_common /* External Input Interrupt */ - MASKABLE_EXCEPTION(0x500, BOOKE_INTERRUPT_EXTERNAL, - external_input, .do_IRQ, ACK_NONE) + MASKABLE_EXCEPTION(0x500, external_input, .do_IRQ, ACK_NONE) /* Alignment */ START_EXCEPTION(alignment); - NORMAL_EXCEPTION_PROLOG(0x600, BOOKE_INTERRUPT_ALIGNMENT, - PROLOG_ADDITION_2REGS) + NORMAL_EXCEPTION_PROLOG(0x600, PROLOG_ADDITION_2REGS) mfspr r14,SPRN_DEAR mfspr r15,SPRN_ESR EXCEPTION_COMMON(0x600, PACA_EXGEN, INTS_KEEP) @@ -366,8 +335,7 @@ interrupt_end_book3e: /* Program Interrupt */ START_EXCEPTION(program); - NORMAL_EXCEPTION_PROLOG(0x700, BOOKE_INTERRUPT_PROGRAM, - PROLOG_ADDITION_1REG) + NORMAL_EXCEPTION_PROLOG(0x700, PROLOG_ADDITION_1REG) mfspr r14,SPRN_ESR EXCEPTION_COMMON(0x700, PACA_EXGEN, INTS_DISABLE) std r14,_DSISR(r1) @@ -379,8 +347,7 @@ interrupt_end_book3e: /* Floating Point Unavailable Interrupt */ START_EXCEPTION(fp_unavailable); - NORMAL_EXCEPTION_PROLOG(0x800, BOOKE_INTERRUPT_FP_UNAVAIL, - PROLOG_ADDITION_NONE) + NORMAL_EXCEPTION_PROLOG(0x800, PROLOG_ADDITION_NONE) /* we can probably do a shorter exception entry for that one... */ EXCEPTION_COMMON(0x800, PACA_EXGEN, INTS_KEEP) ld r12,_MSR(r1) @@ -395,17 +362,14 @@ interrupt_end_book3e: b .ret_from_except /* Decrementer Interrupt */ - MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER, - decrementer, .timer_interrupt, ACK_DEC) + MASKABLE_EXCEPTION(0x900, decrementer, .timer_interrupt, ACK_DEC) /* Fixed Interval Timer Interrupt */ - MASKABLE_EXCEPTION(0x980, BOOKE_INTERRUPT_FIT, - fixed_interval, .unknown_exception, ACK_FIT) + MASKABLE_EXCEPTION(0x980, fixed_interval, .unknown_exception, ACK_FIT) /* Watchdog Timer Interrupt */ START_EXCEPTION(watchdog); - CRIT_EXCEPTION_PROLOG(0x9f0, BOOKE_INTERRUPT_WATCHDOG, - PROLOG_ADDITION_NONE) + CRIT_EXCEPTION_PROLOG(0x9f0, PROLOG_ADDITION_NONE) // EXCEPTION_COMMON(0x9f0, PACA_EXCRIT, INTS_DISABLE) // bl special_reg_save_crit // CHECK_NAPPING(); @@ -424,8 +388,7 @@ interrupt_end_book3e: /* Auxiliary Processor Unavailable Interrupt */ START_EXCEPTION(ap_unavailable); - NORMAL_EXCEPTION_PROLOG(0xf20, BOOKE_INTERRUPT_AP_UNAVAIL, - PROLOG_ADDITION_NONE) + NORMAL_EXCEPTION_PROLOG(0xf20, PROLOG_ADDITION_NONE) EXCEPTION_COMMON(0xf20, PACA_EXGEN, INTS_DISABLE) bl .save_nvgprs addi r3,r1,STACK_FRAME_OVERHEAD @@ -434,8 +397,7 @@ interrupt_end_book3e: /* Debug exception as a critical interrupt*/ START_EXCEPTION(debug_crit); - CRIT_EXCEPTION_PROLOG(0xd00, BOOKE_INTERRUPT_DEBUG, - PROLOG_ADDITION_2REGS) + CRIT_EXCEPTION_PROLOG(0xd00, PROLOG_ADDITION_2REGS) /* * If there is a single step or branch-taken exception in an @@ -469,7 +431,7 @@ interrupt_end_book3e: mtcr r10 ld r10,PACA_EXCRIT+EX_R10(r13) /* restore registers */ ld r11,PACA_EXCRIT+EX_R11(r13) - ld r13,PACA_EXCRIT+EX_R13(r13) + mfspr r13,SPRN_SPRG_CRIT_SCRATCH rfci /* Normal debug exception */ @@ -482,7 +444,7 @@ interrupt_end_book3e: /* Now we mash up things to make it look like we are coming on a * normal exception */ - ld r15,PACA_EXCRIT+EX_R13(r13) + mfspr r15,SPRN_SPRG_CRIT_SCRATCH mtspr SPRN_SPRG_GEN_SCRATCH,r15 mfspr r14,SPRN_DBSR EXCEPTION_COMMON(0xd00, PACA_EXCRIT, INTS_DISABLE) @@ -500,8 +462,7 @@ kernel_dbg_exc: /* Debug exception as a debug interrupt*/ START_EXCEPTION(debug_debug); - DBG_EXCEPTION_PROLOG(0xd00, BOOKE_INTERRUPT_DEBUG, - PROLOG_ADDITION_2REGS) + DBG_EXCEPTION_PROLOG(0xd08, PROLOG_ADDITION_2REGS) /* * If there is a single step or branch-taken exception in an @@ -562,21 +523,18 @@ kernel_dbg_exc: b .ret_from_except START_EXCEPTION(perfmon); - NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR, - PROLOG_ADDITION_NONE) + NORMAL_EXCEPTION_PROLOG(0x260, PROLOG_ADDITION_NONE) EXCEPTION_COMMON(0x260, PACA_EXGEN, INTS_DISABLE) addi r3,r1,STACK_FRAME_OVERHEAD bl .performance_monitor_exception b .ret_from_except_lite /* Doorbell interrupt */ - MASKABLE_EXCEPTION(0x280, BOOKE_INTERRUPT_DOORBELL, - doorbell, .doorbell_exception, ACK_NONE) + MASKABLE_EXCEPTION(0x280, doorbell, .doorbell_exception, ACK_NONE) /* Doorbell critical Interrupt */ START_EXCEPTION(doorbell_crit); - CRIT_EXCEPTION_PROLOG(0x2a0, BOOKE_INTERRUPT_DOORBELL_CRITICAL, - PROLOG_ADDITION_NONE) + CRIT_EXCEPTION_PROLOG(0x2a0, PROLOG_ADDITION_NONE) // EXCEPTION_COMMON(0x2a0, PACA_EXCRIT, INTS_DISABLE) // bl special_reg_save_crit // CHECK_NAPPING(); @@ -585,24 +543,12 @@ kernel_dbg_exc: // b ret_from_crit_except b . -/* - * Guest doorbell interrupt - * This general exception use GSRRx save/restore registers - */ - START_EXCEPTION(guest_doorbell); - GDBELL_EXCEPTION_PROLOG(0x2c0, BOOKE_INTERRUPT_GUEST_DBELL, - PROLOG_ADDITION_NONE) - EXCEPTION_COMMON(0x2c0, PACA_EXGEN, INTS_KEEP) - addi r3,r1,STACK_FRAME_OVERHEAD - bl .save_nvgprs - INTS_RESTORE_HARD - bl .unknown_exception - b .ret_from_except +/* Guest Doorbell */ + MASKABLE_EXCEPTION(0x2c0, guest_doorbell, .unknown_exception, ACK_NONE) /* Guest Doorbell critical Interrupt */ START_EXCEPTION(guest_doorbell_crit); - CRIT_EXCEPTION_PROLOG(0x2e0, BOOKE_INTERRUPT_GUEST_DBELL_CRIT, - PROLOG_ADDITION_NONE) + CRIT_EXCEPTION_PROLOG(0x2e0, PROLOG_ADDITION_NONE) // EXCEPTION_COMMON(0x2e0, PACA_EXCRIT, INTS_DISABLE) // bl special_reg_save_crit // CHECK_NAPPING(); @@ -613,8 +559,7 @@ kernel_dbg_exc: /* Hypervisor call */ START_EXCEPTION(hypercall); - NORMAL_EXCEPTION_PROLOG(0x310, BOOKE_INTERRUPT_HV_SYSCALL, - PROLOG_ADDITION_NONE) + NORMAL_EXCEPTION_PROLOG(0x310, PROLOG_ADDITION_NONE) EXCEPTION_COMMON(0x310, PACA_EXGEN, INTS_KEEP) addi r3,r1,STACK_FRAME_OVERHEAD bl .save_nvgprs @@ -624,8 +569,7 @@ kernel_dbg_exc: /* Embedded Hypervisor priviledged */ START_EXCEPTION(ehpriv); - NORMAL_EXCEPTION_PROLOG(0x320, BOOKE_INTERRUPT_HV_PRIV, - PROLOG_ADDITION_NONE) + NORMAL_EXCEPTION_PROLOG(0x320, PROLOG_ADDITION_NONE) EXCEPTION_COMMON(0x320, PACA_EXGEN, INTS_KEEP) addi r3,r1,STACK_FRAME_OVERHEAD bl .save_nvgprs @@ -638,42 +582,44 @@ kernel_dbg_exc: * accordingly and if the interrupt is level sensitive, we hard disable */ -.macro masked_interrupt_book3e paca_irq full_mask - lbz r10,PACAIRQHAPPENED(r13) - ori r10,r10,\paca_irq - stb r10,PACAIRQHAPPENED(r13) - - .if \full_mask == 1 - rldicl r10,r11,48,1 /* clear MSR_EE */ - rotldi r11,r10,16 - mtspr SPRN_SRR1,r11 - .endif - - lwz r11,PACA_EXGEN+EX_CR(r13) - mtcr r11 - ld r10,PACA_EXGEN+EX_R10(r13) - ld r11,PACA_EXGEN+EX_R11(r13) - mfspr r13,SPRN_SPRG_GEN_SCRATCH - rfi - b . -.endm - masked_interrupt_book3e_0x500: - // XXX When adding support for EPR, use PACA_IRQ_EE_EDGE - masked_interrupt_book3e PACA_IRQ_EE 1 + /* XXX When adding support for EPR, use PACA_IRQ_EE_EDGE */ + li r11,PACA_IRQ_EE + b masked_interrupt_book3e_full_mask masked_interrupt_book3e_0x900: - ACK_DEC(r10); - masked_interrupt_book3e PACA_IRQ_DEC 0 - + ACK_DEC(r11); + li r11,PACA_IRQ_DEC + b masked_interrupt_book3e_no_mask masked_interrupt_book3e_0x980: - ACK_FIT(r10); - masked_interrupt_book3e PACA_IRQ_DEC 0 - + ACK_FIT(r11); + li r11,PACA_IRQ_DEC + b masked_interrupt_book3e_no_mask masked_interrupt_book3e_0x280: masked_interrupt_book3e_0x2c0: - masked_interrupt_book3e PACA_IRQ_DBELL 0 + li r11,PACA_IRQ_DBELL + b masked_interrupt_book3e_no_mask +masked_interrupt_book3e_no_mask: + mtcr r10 + lbz r10,PACAIRQHAPPENED(r13) + or r10,r10,r11 + stb r10,PACAIRQHAPPENED(r13) + b 1f +masked_interrupt_book3e_full_mask: + mtcr r10 + lbz r10,PACAIRQHAPPENED(r13) + or r10,r10,r11 + stb r10,PACAIRQHAPPENED(r13) + mfspr r10,SPRN_SRR1 + rldicl r11,r10,48,1 /* clear MSR_EE */ + rotldi r10,r11,16 + mtspr SPRN_SRR1,r10 +1: ld r10,PACA_EXGEN+EX_R10(r13); + ld r11,PACA_EXGEN+EX_R11(r13); + mfspr r13,SPRN_SPRG_GEN_SCRATCH; + rfi + b . /* * Called from arch_local_irq_enable when an interrupt needs * to be resent. r3 contains either 0x500,0x900,0x260 or 0x280 @@ -1356,11 +1302,25 @@ _GLOBAL(setup_perfmon_ivor) _GLOBAL(setup_doorbell_ivors) SET_IVOR(36, 0x280) /* Processor Doorbell */ SET_IVOR(37, 0x2a0) /* Processor Doorbell Crit */ + + /* Check MMUCFG[LPIDSIZE] to determine if we have category E.HV */ + mfspr r10,SPRN_MMUCFG + rlwinm. r10,r10,0,MMUCFG_LPIDSIZE + beqlr + + SET_IVOR(38, 0x2c0) /* Guest Processor Doorbell */ + SET_IVOR(39, 0x2e0) /* Guest Processor Doorbell Crit/MC */ blr _GLOBAL(setup_ehv_ivors) + /* + * We may be running as a guest and lack E.HV even on a chip + * that normally has it. + */ + mfspr r10,SPRN_MMUCFG + rlwinm. r10,r10,0,MMUCFG_LPIDSIZE + beqlr + SET_IVOR(40, 0x300) /* Embedded Hypervisor System Call */ SET_IVOR(41, 0x320) /* Embedded Hypervisor Privilege */ - SET_IVOR(38, 0x2c0) /* Guest Processor Doorbell */ - SET_IVOR(39, 0x2e0) /* Guest Processor Doorbell Crit/MC */ blr diff --git a/trunk/arch/powerpc/kernel/exceptions-64s.S b/trunk/arch/powerpc/kernel/exceptions-64s.S index 10b658ad65e1..39aa97d3ff88 100644 --- a/trunk/arch/powerpc/kernel/exceptions-64s.S +++ b/trunk/arch/powerpc/kernel/exceptions-64s.S @@ -275,31 +275,6 @@ vsx_unavailable_pSeries_1: STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint) KVM_HANDLER_PR_SKIP(PACA_EXGEN, EXC_STD, 0x1300) - . = 0x1500 - .global denorm_Hypervisor -denorm_exception_hv: - HMT_MEDIUM - mtspr SPRN_SPRG_HSCRATCH0,r13 - mfspr r13,SPRN_SPRG_HPACA - std r9,PACA_EXGEN+EX_R9(r13) - std r10,PACA_EXGEN+EX_R10(r13) - std r11,PACA_EXGEN+EX_R11(r13) - std r12,PACA_EXGEN+EX_R12(r13) - mfspr r9,SPRN_SPRG_HSCRATCH0 - std r9,PACA_EXGEN+EX_R13(r13) - mfcr r9 - -#ifdef CONFIG_PPC_DENORMALISATION - mfspr r10,SPRN_HSRR1 - mfspr r11,SPRN_HSRR0 /* save HSRR0 */ - andis. r10,r10,(HSRR1_DENORM)@h /* denorm? */ - addi r11,r11,-4 /* HSRR0 is next instruction */ - bne+ denorm_assist -#endif - - EXCEPTION_PROLOG_PSERIES_1(denorm_common, EXC_HV) - KVM_HANDLER_SKIP(PACA_EXGEN, EXC_STD, 0x1500) - #ifdef CONFIG_CBE_RAS STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance) KVM_HANDLER_SKIP(PACA_EXGEN, EXC_HV, 0x1602) @@ -361,103 +336,6 @@ do_stab_bolted_pSeries: KVM_HANDLER_PR(PACA_EXGEN, EXC_STD, 0x900) KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x982) -#ifdef CONFIG_PPC_DENORMALISATION -denorm_assist: -BEGIN_FTR_SECTION -/* - * To denormalise we need to move a copy of the register to itself. - * For POWER6 do that here for all FP regs. - */ - mfmsr r10 - ori r10,r10,(MSR_FP|MSR_FE0|MSR_FE1) - xori r10,r10,(MSR_FE0|MSR_FE1) - mtmsrd r10 - sync - fmr 0,0 - fmr 1,1 - fmr 2,2 - fmr 3,3 - fmr 4,4 - fmr 5,5 - fmr 6,6 - fmr 7,7 - fmr 8,8 - fmr 9,9 - fmr 10,10 - fmr 11,11 - fmr 12,12 - fmr 13,13 - fmr 14,14 - fmr 15,15 - fmr 16,16 - fmr 17,17 - fmr 18,18 - fmr 19,19 - fmr 20,20 - fmr 21,21 - fmr 22,22 - fmr 23,23 - fmr 24,24 - fmr 25,25 - fmr 26,26 - fmr 27,27 - fmr 28,28 - fmr 29,29 - fmr 30,30 - fmr 31,31 -FTR_SECTION_ELSE -/* - * To denormalise we need to move a copy of the register to itself. - * For POWER7 do that here for the first 32 VSX registers only. - */ - mfmsr r10 - oris r10,r10,MSR_VSX@h - mtmsrd r10 - sync - XVCPSGNDP(0,0,0) - XVCPSGNDP(1,1,1) - XVCPSGNDP(2,2,2) - XVCPSGNDP(3,3,3) - XVCPSGNDP(4,4,4) - XVCPSGNDP(5,5,5) - XVCPSGNDP(6,6,6) - XVCPSGNDP(7,7,7) - XVCPSGNDP(8,8,8) - XVCPSGNDP(9,9,9) - XVCPSGNDP(10,10,10) - XVCPSGNDP(11,11,11) - XVCPSGNDP(12,12,12) - XVCPSGNDP(13,13,13) - XVCPSGNDP(14,14,14) - XVCPSGNDP(15,15,15) - XVCPSGNDP(16,16,16) - XVCPSGNDP(17,17,17) - XVCPSGNDP(18,18,18) - XVCPSGNDP(19,19,19) - XVCPSGNDP(20,20,20) - XVCPSGNDP(21,21,21) - XVCPSGNDP(22,22,22) - XVCPSGNDP(23,23,23) - XVCPSGNDP(24,24,24) - XVCPSGNDP(25,25,25) - XVCPSGNDP(26,26,26) - XVCPSGNDP(27,27,27) - XVCPSGNDP(28,28,28) - XVCPSGNDP(29,29,29) - XVCPSGNDP(30,30,30) - XVCPSGNDP(31,31,31) -ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206) - mtspr SPRN_HSRR0,r11 - mtcrf 0x80,r9 - ld r9,PACA_EXGEN+EX_R9(r13) - ld r10,PACA_EXGEN+EX_R10(r13) - ld r11,PACA_EXGEN+EX_R11(r13) - ld r12,PACA_EXGEN+EX_R12(r13) - ld r13,PACA_EXGEN+EX_R13(r13) - HRFID - b . -#endif - .align 7 /* moved from 0xe00 */ STD_EXCEPTION_HV(., 0xe02, h_data_storage) @@ -617,7 +495,6 @@ machine_check_common: STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception) STD_EXCEPTION_COMMON_ASYNC(0xf00, performance_monitor, .performance_monitor_exception) STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) - STD_EXCEPTION_COMMON(0x1502, denorm, .unknown_exception) #ifdef CONFIG_ALTIVEC STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception) #else @@ -1083,9 +960,7 @@ _GLOBAL(do_stab_bolted) rldimi r10,r11,7,52 /* r10 = first ste of the group */ /* Calculate VSID */ - /* This is a kernel address, so protovsid = ESID | 1 << 37 */ - li r9,0x1 - rldimi r11,r9,(CONTEXT_BITS + USER_ESID_BITS),0 + /* This is a kernel address, so protovsid = ESID */ ASM_VSID_SCRAMBLE(r11, r9, 256M) rldic r9,r11,12,16 /* r9 = vsid << 12 */ diff --git a/trunk/arch/powerpc/kernel/fadump.c b/trunk/arch/powerpc/kernel/fadump.c index 06c8202a69cf..18bdf74fa164 100644 --- a/trunk/arch/powerpc/kernel/fadump.c +++ b/trunk/arch/powerpc/kernel/fadump.c @@ -289,7 +289,8 @@ int __init fadump_reserve_mem(void) else memory_limit = memblock_end_of_DRAM(); printk(KERN_INFO "Adjusted memory_limit for firmware-assisted" - " dump, now %#016llx\n", memory_limit); + " dump, now %#016llx\n", + (unsigned long long)memory_limit); } if (memory_limit) memory_boundary = memory_limit; diff --git a/trunk/arch/powerpc/kernel/head_fsl_booke.S b/trunk/arch/powerpc/kernel/head_fsl_booke.S index 6f62a737f607..0f59863c3ade 100644 --- a/trunk/arch/powerpc/kernel/head_fsl_booke.S +++ b/trunk/arch/powerpc/kernel/head_fsl_booke.S @@ -895,11 +895,15 @@ _GLOBAL(__setup_e500mc_ivors) mtspr SPRN_IVOR36,r3 li r3,CriticalDoorbell@l mtspr SPRN_IVOR37,r3 - sync - blr -/* setup ehv ivors for */ -_GLOBAL(__setup_ehv_ivors) + /* + * We only want to touch IVOR38-41 if we're running on hardware + * that supports category E.HV. The architectural way to determine + * this is MMUCFG[LPIDSIZE]. + */ + mfspr r3, SPRN_MMUCFG + andis. r3, r3, MMUCFG_LPIDSIZE@h + beq no_hv li r3,GuestDoorbell@l mtspr SPRN_IVOR38,r3 li r3,CriticalGuestDoorbell@l @@ -908,8 +912,14 @@ _GLOBAL(__setup_ehv_ivors) mtspr SPRN_IVOR40,r3 li r3,Ehvpriv@l mtspr SPRN_IVOR41,r3 +skip_hv_ivors: sync blr +no_hv: + lwz r3, CPU_SPEC_FEATURES(r5) + rlwinm r3, r3, 0, ~CPU_FTR_EMB_HV + stw r3, CPU_SPEC_FEATURES(r5) + b skip_hv_ivors #ifdef CONFIG_SPE /* @@ -1033,34 +1043,6 @@ _GLOBAL(flush_dcache_L1) blr -/* Flush L1 d-cache, invalidate and disable d-cache and i-cache */ -_GLOBAL(__flush_disable_L1) - mflr r10 - bl flush_dcache_L1 /* Flush L1 d-cache */ - mtlr r10 - - mfspr r4, SPRN_L1CSR0 /* Invalidate and disable d-cache */ - li r5, 2 - rlwimi r4, r5, 0, 3 - - msync - isync - mtspr SPRN_L1CSR0, r4 - isync - -1: mfspr r4, SPRN_L1CSR0 /* Wait for the invalidate to finish */ - andi. r4, r4, 2 - bne 1b - - mfspr r4, SPRN_L1CSR1 /* Invalidate and disable i-cache */ - li r5, 2 - rlwimi r4, r5, 0, 3 - - mtspr SPRN_L1CSR1, r4 - isync - - blr - #ifdef CONFIG_SMP /* When we get here, r24 needs to hold the CPU # */ .globl __secondary_start diff --git a/trunk/arch/powerpc/kernel/hw_breakpoint.c b/trunk/arch/powerpc/kernel/hw_breakpoint.c index a89cae481b04..956a4c496de9 100644 --- a/trunk/arch/powerpc/kernel/hw_breakpoint.c +++ b/trunk/arch/powerpc/kernel/hw_breakpoint.c @@ -73,7 +73,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp) * If so, DABR will be populated in single_step_dabr_instruction(). */ if (current->thread.last_hit_ubp != bp) - set_dabr(info->address | info->type | DABR_TRANSLATION, info->dabrx); + set_dabr(info->address | info->type | DABR_TRANSLATION); return 0; } @@ -97,7 +97,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp) } *slot = NULL; - set_dabr(0, 0); + set_dabr(0); } /* @@ -170,13 +170,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) info->address = bp->attr.bp_addr; info->len = bp->attr.bp_len; - info->dabrx = DABRX_ALL; - if (bp->attr.exclude_user) - info->dabrx &= ~DABRX_USER; - if (bp->attr.exclude_kernel) - info->dabrx &= ~DABRX_KERNEL; - if (bp->attr.exclude_hv) - info->dabrx &= ~DABRX_HYP; /* * Since breakpoint length can be a maximum of HW_BREAKPOINT_LEN(8) @@ -204,7 +197,7 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs) info = counter_arch_bp(tsk->thread.last_hit_ubp); regs->msr &= ~MSR_SE; - set_dabr(info->address | info->type | DABR_TRANSLATION, info->dabrx); + set_dabr(info->address | info->type | DABR_TRANSLATION); tsk->thread.last_hit_ubp = NULL; } @@ -222,7 +215,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args) unsigned long dar = regs->dar; /* Disable breakpoints during exception handling */ - set_dabr(0, 0); + set_dabr(0); /* * The counter may be concurrently released but that can only @@ -288,7 +281,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args) if (!info->extraneous_interrupt) perf_bp_event(bp, regs); - set_dabr(info->address | info->type | DABR_TRANSLATION, info->dabrx); + set_dabr(info->address | info->type | DABR_TRANSLATION); out: rcu_read_unlock(); return rc; @@ -301,7 +294,7 @@ int __kprobes single_step_dabr_instruction(struct die_args *args) { struct pt_regs *regs = args->regs; struct perf_event *bp = NULL; - struct arch_hw_breakpoint *info; + struct arch_hw_breakpoint *bp_info; bp = current->thread.last_hit_ubp; /* @@ -311,16 +304,16 @@ int __kprobes single_step_dabr_instruction(struct die_args *args) if (!bp) return NOTIFY_DONE; - info = counter_arch_bp(bp); + bp_info = counter_arch_bp(bp); /* * We shall invoke the user-defined callback function in the single * stepping handler to confirm to 'trigger-after-execute' semantics */ - if (!info->extraneous_interrupt) + if (!bp_info->extraneous_interrupt) perf_bp_event(bp, regs); - set_dabr(info->address | info->type | DABR_TRANSLATION, info->dabrx); + set_dabr(bp_info->address | bp_info->type | DABR_TRANSLATION); current->thread.last_hit_ubp = NULL; /* diff --git a/trunk/arch/powerpc/kernel/ibmebus.c b/trunk/arch/powerpc/kernel/ibmebus.c index 8220baa46faf..b01d14eeca8d 100644 --- a/trunk/arch/powerpc/kernel/ibmebus.c +++ b/trunk/arch/powerpc/kernel/ibmebus.c @@ -47,6 +47,7 @@ #include #include #include +#include static struct device ibmebus_bus_device = { /* fake "parent" device */ .init_name = "ibmebus", diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index 71413f41278f..1f017bb7a7ce 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -489,10 +489,10 @@ void do_IRQ(struct pt_regs *regs) struct pt_regs *old_regs = set_irq_regs(regs); unsigned int irq; - irq_enter(); - trace_irq_entry(regs); + irq_enter(); + check_stack_overflow(); /* @@ -511,10 +511,10 @@ void do_IRQ(struct pt_regs *regs) else __get_cpu_var(irq_stat).spurious_irqs++; - trace_irq_exit(regs); - irq_exit(); set_irq_regs(old_regs); + + trace_irq_exit(regs); } void __init init_IRQ(void) diff --git a/trunk/arch/powerpc/kernel/machine_kexec.c b/trunk/arch/powerpc/kernel/machine_kexec.c index fa9f6c72f557..5df777794403 100644 --- a/trunk/arch/powerpc/kernel/machine_kexec.c +++ b/trunk/arch/powerpc/kernel/machine_kexec.c @@ -165,7 +165,7 @@ void __init reserve_crashkernel(void) if (memory_limit && memory_limit <= crashk_res.end) { memory_limit = crashk_res.end + 1; printk("Adjusted memory limit for crashkernel, now 0x%llx\n", - memory_limit); + (unsigned long long)memory_limit); } printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " @@ -204,12 +204,6 @@ static struct property crashk_size_prop = { .value = &crashk_size, }; -static struct property memory_limit_prop = { - .name = "linux,memory-limit", - .length = sizeof(unsigned long long), - .value = &memory_limit, -}; - static void __init export_crashk_values(struct device_node *node) { struct property *prop; @@ -229,12 +223,6 @@ static void __init export_crashk_values(struct device_node *node) crashk_size = resource_size(&crashk_res); prom_add_property(node, &crashk_size_prop); } - - /* - * memory_limit is required by the kexec-tools to limit the - * crash regions to the actual memory used. - */ - prom_update_property(node, &memory_limit_prop); } static int __init kexec_setup(void) diff --git a/trunk/arch/powerpc/kernel/paca.c b/trunk/arch/powerpc/kernel/paca.c index cd6da855090c..fbe1a12dc7f1 100644 --- a/trunk/arch/powerpc/kernel/paca.c +++ b/trunk/arch/powerpc/kernel/paca.c @@ -142,7 +142,6 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu) new_paca->hw_cpu_id = 0xffff; new_paca->kexec_state = KEXEC_STATE_NONE; new_paca->__current = &init_task; - new_paca->data_offset = 0xfeeeeeeeeeeeeeeeULL; #ifdef CONFIG_PPC_STD_MMU_64 new_paca->slb_shadow_ptr = &slb_shadow[cpu]; #endif /* CONFIG_PPC_STD_MMU_64 */ diff --git a/trunk/arch/powerpc/kernel/pci-common.c b/trunk/arch/powerpc/kernel/pci-common.c index 7f94f760dd0c..2aa04f29e1de 100644 --- a/trunk/arch/powerpc/kernel/pci-common.c +++ b/trunk/arch/powerpc/kernel/pci-common.c @@ -99,26 +99,6 @@ void pcibios_free_controller(struct pci_controller *phb) kfree(phb); } -/* - * The function is used to return the minimal alignment - * for memory or I/O windows of the associated P2P bridge. - * By default, 4KiB alignment for I/O windows and 1MiB for - * memory windows. - */ -resource_size_t pcibios_window_alignment(struct pci_bus *bus, - unsigned long type) -{ - if (ppc_md.pcibios_window_alignment) - return ppc_md.pcibios_window_alignment(bus, type); - - /* - * PCI core will figure out the default - * alignment: 4KiB for I/O and 1MiB for - * memory window. - */ - return 1; -} - static resource_size_t pcibios_io_size(const struct pci_controller *hose) { #ifdef CONFIG_PPC64 @@ -980,14 +960,13 @@ static void __devinit pcibios_fixup_bridge(struct pci_bus *bus) if (i >= 3 && bus->self->transparent) continue; - /* If we're going to reassign everything, we can - * shrink the P2P resource to have size as being - * of 0 in order to save space. + /* If we are going to re-assign everything, mark the resource + * as unset and move it down to 0 */ if (pci_has_flag(PCI_REASSIGN_ALL_RSRC)) { res->flags |= IORESOURCE_UNSET; + res->end -= res->start; res->start = 0; - res->end = -1; continue; } @@ -1249,14 +1228,7 @@ void pcibios_allocate_bus_resources(struct pci_bus *bus) pr_warning("PCI: Cannot allocate resource region " "%d of PCI bridge %d, will remap\n", i, bus->number); clear_resource: - /* The resource might be figured out when doing - * reassignment based on the resources required - * by the downstream PCI devices. Here we set - * the size of the resource to be 0 in order to - * save more space. - */ - res->start = 0; - res->end = -1; + res->start = res->end = 0; res->flags = 0; } diff --git a/trunk/arch/powerpc/kernel/process.c b/trunk/arch/powerpc/kernel/process.c index 50e504c29bb9..1a1f2ddfb581 100644 --- a/trunk/arch/powerpc/kernel/process.c +++ b/trunk/arch/powerpc/kernel/process.c @@ -258,7 +258,6 @@ void do_send_trap(struct pt_regs *regs, unsigned long address, { siginfo_t info; - current->thread.trap_nr = signal_code; if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code, 11, SIGSEGV) == NOTIFY_STOP) return; @@ -276,7 +275,6 @@ void do_dabr(struct pt_regs *regs, unsigned long address, { siginfo_t info; - current->thread.trap_nr = TRAP_HWBKPT; if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code, 11, SIGSEGV) == NOTIFY_STOP) return; @@ -285,7 +283,7 @@ void do_dabr(struct pt_regs *regs, unsigned long address, return; /* Clear the DABR */ - set_dabr(0, 0); + set_dabr(0); /* Deliver the signal to userspace */ info.si_signo = SIGTRAP; @@ -366,19 +364,18 @@ static void set_debug_reg_defaults(struct thread_struct *thread) { if (thread->dabr) { thread->dabr = 0; - thread->dabrx = 0; - set_dabr(0, 0); + set_dabr(0); } } #endif /* !CONFIG_HAVE_HW_BREAKPOINT */ #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ -int set_dabr(unsigned long dabr, unsigned long dabrx) +int set_dabr(unsigned long dabr) { __get_cpu_var(current_dabr) = dabr; if (ppc_md.set_dabr) - return ppc_md.set_dabr(dabr, dabrx); + return ppc_md.set_dabr(dabr); /* XXX should we have a CPU_FTR_HAS_DABR ? */ #ifdef CONFIG_PPC_ADV_DEBUG_REGS @@ -388,8 +385,9 @@ int set_dabr(unsigned long dabr, unsigned long dabrx) #endif #elif defined(CONFIG_PPC_BOOK3S) mtspr(SPRN_DABR, dabr); - mtspr(SPRN_DABRX, dabrx); #endif + + return 0; } @@ -482,7 +480,7 @@ struct task_struct *__switch_to(struct task_struct *prev, */ #ifndef CONFIG_HAVE_HW_BREAKPOINT if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) - set_dabr(new->thread.dabr, new->thread.dabrx); + set_dabr(new->thread.dabr); #endif /* CONFIG_HAVE_HW_BREAKPOINT */ #endif diff --git a/trunk/arch/powerpc/kernel/prom.c b/trunk/arch/powerpc/kernel/prom.c index 37725e86651e..f191bf02943a 100644 --- a/trunk/arch/powerpc/kernel/prom.c +++ b/trunk/arch/powerpc/kernel/prom.c @@ -78,7 +78,7 @@ static int __init early_parse_mem(char *p) return 1; memory_limit = PAGE_ALIGN(memparse(p, &p)); - DBG("memory limit = 0x%llx\n", memory_limit); + DBG("memory limit = 0x%llx\n", (unsigned long long)memory_limit); return 0; } @@ -661,7 +661,7 @@ void __init early_init_devtree(void *params) /* make sure we've parsed cmdline for mem= before this */ if (memory_limit) - first_memblock_size = min_t(u64, first_memblock_size, memory_limit); + first_memblock_size = min(first_memblock_size, memory_limit); setup_initial_memory_limit(memstart_addr, first_memblock_size); /* Reserve MEMBLOCK regions used by kernel, initrd, dt, etc... */ memblock_reserve(PHYSICAL_START, __pa(klimit) - PHYSICAL_START); diff --git a/trunk/arch/powerpc/kernel/prom_init.c b/trunk/arch/powerpc/kernel/prom_init.c index ce68278a5d73..0794a3017b1b 100644 --- a/trunk/arch/powerpc/kernel/prom_init.c +++ b/trunk/arch/powerpc/kernel/prom_init.c @@ -1691,7 +1691,7 @@ static void __init prom_initialize_tce_table(void) * else will impact performance, so we always allocate 8MB. * Anton */ - if (pvr_version_is(PVR_POWER4) || pvr_version_is(PVR_POWER4p)) + if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p)) minsize = 8UL << 20; else minsize = 4UL << 20; diff --git a/trunk/arch/powerpc/kernel/ptrace.c b/trunk/arch/powerpc/kernel/ptrace.c index 79d8e56470df..c10fc28b9092 100644 --- a/trunk/arch/powerpc/kernel/ptrace.c +++ b/trunk/arch/powerpc/kernel/ptrace.c @@ -960,7 +960,6 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, thread->ptrace_bps[0] = bp; ptrace_put_breakpoints(task); thread->dabr = data; - thread->dabrx = DABRX_ALL; return 0; } @@ -984,7 +983,6 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, /* Move contents to the DABR register */ task->thread.dabr = data; - task->thread.dabrx = DABRX_ALL; #else /* CONFIG_PPC_ADV_DEBUG_REGS */ /* As described above, it was assumed 3 bits were passed with the data * address, but we will assume only the mode bits will be passed @@ -1399,7 +1397,6 @@ static long ppc_set_hwdebug(struct task_struct *child, dabr |= DABR_DATA_WRITE; child->thread.dabr = dabr; - child->thread.dabrx = DABRX_ALL; return 1; #endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */ diff --git a/trunk/arch/powerpc/kernel/rtas_flash.c b/trunk/arch/powerpc/kernel/rtas_flash.c index 20b0120db0c3..2c0ee6405633 100644 --- a/trunk/arch/powerpc/kernel/rtas_flash.c +++ b/trunk/arch/powerpc/kernel/rtas_flash.c @@ -21,6 +21,7 @@ #include #include #include +#include #define MODULE_VERS "1.0" #define MODULE_NAME "rtas_flash" @@ -581,7 +582,7 @@ static void rtas_flash_firmware(int reboot_type) flist = (struct flash_block_list *)&rtas_data_buf[0]; flist->num_blocks = 0; flist->next = rtas_firmware_flash_list; - rtas_block_list = __pa(flist); + rtas_block_list = virt_to_abs(flist); if (rtas_block_list >= 4UL*1024*1024*1024) { printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n"); spin_unlock(&rtas_data_buf_lock); @@ -595,13 +596,13 @@ static void rtas_flash_firmware(int reboot_type) for (f = flist; f; f = next) { /* Translate data addrs to absolute */ for (i = 0; i < f->num_blocks; i++) { - f->blocks[i].data = (char *)__pa(f->blocks[i].data); + f->blocks[i].data = (char *)virt_to_abs(f->blocks[i].data); image_size += f->blocks[i].length; } next = f->next; /* Don't translate NULL pointer for last entry */ if (f->next) - f->next = (struct flash_block_list *)__pa(f->next); + f->next = (struct flash_block_list *)virt_to_abs(f->next); else f->next = NULL; /* make num_blocks into the version/length field */ diff --git a/trunk/arch/powerpc/kernel/rtas_pci.c b/trunk/arch/powerpc/kernel/rtas_pci.c index 6de63e3250bb..179af906dcda 100644 --- a/trunk/arch/powerpc/kernel/rtas_pci.c +++ b/trunk/arch/powerpc/kernel/rtas_pci.c @@ -81,7 +81,7 @@ int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val) return PCIBIOS_DEVICE_NOT_FOUND; if (returnval == EEH_IO_ERROR_VALUE(size) && - eeh_dev_check_failure(of_node_to_eeh_dev(pdn->node))) + eeh_dn_check_failure (pdn->node, NULL)) return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_SUCCESSFUL; @@ -275,6 +275,9 @@ void __init find_and_init_phbs(void) of_node_put(root); pci_devs_phb_init(); + /* Create EEH devices for all PHBs */ + eeh_dev_phb_init(); + /* * PCI_PROBE_ONLY and PCI_REASSIGN_ALL_BUS can be set via properties * in chosen. diff --git a/trunk/arch/powerpc/kernel/signal.c b/trunk/arch/powerpc/kernel/signal.c index a2dc75793bd5..5c023c9cf16e 100644 --- a/trunk/arch/powerpc/kernel/signal.c +++ b/trunk/arch/powerpc/kernel/signal.c @@ -11,7 +11,6 @@ #include #include -#include #include #include #include @@ -131,7 +130,7 @@ static int do_signal(struct pt_regs *regs) * triggered inside the kernel. */ if (current->thread.dabr) - set_dabr(current->thread.dabr, current->thread.dabrx); + set_dabr(current->thread.dabr); #endif /* Re-enable the breakpoints for the signal stack */ thread_change_pc(current, regs); @@ -158,11 +157,6 @@ static int do_signal(struct pt_regs *regs) void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags) { - if (thread_info_flags & _TIF_UPROBE) { - clear_thread_flag(TIF_UPROBE); - uprobe_notify_resume(regs); - } - if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs); diff --git a/trunk/arch/powerpc/kernel/smp.c b/trunk/arch/powerpc/kernel/smp.c index a51ed205016e..8d4214afc21d 100644 --- a/trunk/arch/powerpc/kernel/smp.c +++ b/trunk/arch/powerpc/kernel/smp.c @@ -102,7 +102,7 @@ int __devinit smp_generic_kick_cpu(int nr) * Ok it's not there, so it might be soft-unplugged, let's * try to bring it back */ - generic_set_cpu_up(nr); + per_cpu(cpu_state, nr) = CPU_UP_PREPARE; smp_wmb(); smp_send_reschedule(nr); #endif /* CONFIG_HOTPLUG_CPU */ @@ -413,16 +413,6 @@ void generic_set_cpu_dead(unsigned int cpu) per_cpu(cpu_state, cpu) = CPU_DEAD; } -/* - * The cpu_state should be set to CPU_UP_PREPARE in kick_cpu(), otherwise - * the cpu_state is always CPU_DEAD after calling generic_set_cpu_dead(), - * which makes the delay in generic_cpu_die() not happen. - */ -void generic_set_cpu_up(unsigned int cpu) -{ - per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; -} - int generic_check_cpu_restart(unsigned int cpu) { return per_cpu(cpu_state, cpu) == CPU_UP_PREPARE; diff --git a/trunk/arch/powerpc/kernel/time.c b/trunk/arch/powerpc/kernel/time.c index bd693a11d86e..e49e93191b69 100644 --- a/trunk/arch/powerpc/kernel/time.c +++ b/trunk/arch/powerpc/kernel/time.c @@ -493,6 +493,8 @@ void timer_interrupt(struct pt_regs * regs) */ may_hard_irq_enable(); + trace_timer_interrupt_entry(regs); + __get_cpu_var(irq_stat).timer_irqs++; #if defined(CONFIG_PPC32) && defined(CONFIG_PMAC) @@ -503,8 +505,6 @@ void timer_interrupt(struct pt_regs * regs) old_regs = set_irq_regs(regs); irq_enter(); - trace_timer_interrupt_entry(regs); - if (test_irq_work_pending()) { clear_irq_work_pending(); irq_work_run(); @@ -529,10 +529,10 @@ void timer_interrupt(struct pt_regs * regs) } #endif - trace_timer_interrupt_exit(regs); - irq_exit(); set_irq_regs(old_regs); + + trace_timer_interrupt_exit(regs); } /* diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index 32518401af68..ae0843fa7a61 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -251,7 +251,6 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) if (arch_irqs_disabled() && !arch_irq_disabled_regs(regs)) local_irq_enable(); - current->thread.trap_nr = code; memset(&info, 0, sizeof(info)); info.si_signo = signr; info.si_code = code; diff --git a/trunk/arch/powerpc/kernel/uprobes.c b/trunk/arch/powerpc/kernel/uprobes.c deleted file mode 100644 index d2d46d1014f8..000000000000 --- a/trunk/arch/powerpc/kernel/uprobes.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * User-space Probes (UProbes) for powerpc - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * Copyright IBM Corporation, 2007-2012 - * - * Adapted from the x86 port by Ananth N Mavinakayanahalli - */ -#include -#include -#include -#include -#include -#include - -#include - -#define UPROBE_TRAP_NR UINT_MAX - -/** - * arch_uprobe_analyze_insn - * @mm: the probed address space. - * @arch_uprobe: the probepoint information. - * @addr: vaddr to probe. - * Return 0 on success or a -ve number on error. - */ -int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, - struct mm_struct *mm, unsigned long addr) -{ - if (addr & 0x03) - return -EINVAL; - - /* - * We currently don't support a uprobe on an already - * existing breakpoint instruction underneath - */ - if (is_trap(auprobe->ainsn)) - return -ENOTSUPP; - return 0; -} - -/* - * arch_uprobe_pre_xol - prepare to execute out of line. - * @auprobe: the probepoint information. - * @regs: reflects the saved user state of current task. - */ -int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) -{ - struct arch_uprobe_task *autask = ¤t->utask->autask; - - autask->saved_trap_nr = current->thread.trap_nr; - current->thread.trap_nr = UPROBE_TRAP_NR; - regs->nip = current->utask->xol_vaddr; - return 0; -} - -/** - * uprobe_get_swbp_addr - compute address of swbp given post-swbp regs - * @regs: Reflects the saved state of the task after it has hit a breakpoint - * instruction. - * Return the address of the breakpoint instruction. - */ -unsigned long uprobe_get_swbp_addr(struct pt_regs *regs) -{ - return instruction_pointer(regs); -} - -/* - * If xol insn itself traps and generates a signal (SIGILL/SIGSEGV/etc), - * then detect the case where a singlestepped instruction jumps back to its - * own address. It is assumed that anything like do_page_fault/do_trap/etc - * sets thread.trap_nr != UINT_MAX. - * - * arch_uprobe_pre_xol/arch_uprobe_post_xol save/restore thread.trap_nr, - * arch_uprobe_xol_was_trapped() simply checks that ->trap_nr is not equal to - * UPROBE_TRAP_NR == UINT_MAX set by arch_uprobe_pre_xol(). - */ -bool arch_uprobe_xol_was_trapped(struct task_struct *t) -{ - if (t->thread.trap_nr != UPROBE_TRAP_NR) - return true; - - return false; -} - -/* - * Called after single-stepping. To avoid the SMP problems that can - * occur when we temporarily put back the original opcode to - * single-step, we single-stepped a copy of the instruction. - * - * This function prepares to resume execution after the single-step. - */ -int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) -{ - struct uprobe_task *utask = current->utask; - - WARN_ON_ONCE(current->thread.trap_nr != UPROBE_TRAP_NR); - - current->thread.trap_nr = utask->autask.saved_trap_nr; - - /* - * On powerpc, except for loads and stores, most instructions - * including ones that alter code flow (branches, calls, returns) - * are emulated in the kernel. We get here only if the emulation - * support doesn't exist and have to fix-up the next instruction - * to be executed. - */ - regs->nip = utask->vaddr + MAX_UINSN_BYTES; - return 0; -} - -/* callback routine for handling exceptions. */ -int arch_uprobe_exception_notify(struct notifier_block *self, - unsigned long val, void *data) -{ - struct die_args *args = data; - struct pt_regs *regs = args->regs; - - /* regs == NULL is a kernel bug */ - if (WARN_ON(!regs)) - return NOTIFY_DONE; - - /* We are only interested in userspace traps */ - if (!user_mode(regs)) - return NOTIFY_DONE; - - switch (val) { - case DIE_BPT: - if (uprobe_pre_sstep_notifier(regs)) - return NOTIFY_STOP; - break; - case DIE_SSTEP: - if (uprobe_post_sstep_notifier(regs)) - return NOTIFY_STOP; - default: - break; - } - return NOTIFY_DONE; -} - -/* - * This function gets called when XOL instruction either gets trapped or - * the thread has a fatal signal, so reset the instruction pointer to its - * probed address. - */ -void arch_uprobe_abort_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) -{ - struct uprobe_task *utask = current->utask; - - current->thread.trap_nr = utask->autask.saved_trap_nr; - instruction_pointer_set(regs, utask->vaddr); -} - -/* - * See if the instruction can be emulated. - * Returns true if instruction was emulated, false otherwise. - */ -bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) -{ - int ret; - - /* - * emulate_step() returns 1 if the insn was successfully emulated. - * For all other cases, we need to single-step in hardware. - */ - ret = emulate_step(regs, auprobe->ainsn); - if (ret > 0) - return true; - - return false; -} diff --git a/trunk/arch/powerpc/kernel/vdso.c b/trunk/arch/powerpc/kernel/vdso.c index 1b2076f049ce..b67db22e102d 100644 --- a/trunk/arch/powerpc/kernel/vdso.c +++ b/trunk/arch/powerpc/kernel/vdso.c @@ -723,7 +723,9 @@ int __cpuinit vdso_getcpu_init(void) val = (cpu & 0xfff) | ((node & 0xffff) << 16); mtspr(SPRN_SPRG3, val); - get_paca()->sprg3 = val; +#ifdef CONFIG_KVM_BOOK3S_HANDLER + get_paca()->kvm_hstate.sprg3 = val; +#endif put_cpu(); diff --git a/trunk/arch/powerpc/kernel/vio.c b/trunk/arch/powerpc/kernel/vio.c index 201ba59738be..02b32216bbc3 100644 --- a/trunk/arch/powerpc/kernel/vio.c +++ b/trunk/arch/powerpc/kernel/vio.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff --git a/trunk/arch/powerpc/kvm/book3s_32_mmu_host.c b/trunk/arch/powerpc/kvm/book3s_32_mmu_host.c index 00aa61268e0d..837f13e7b6bf 100644 --- a/trunk/arch/powerpc/kvm/book3s_32_mmu_host.c +++ b/trunk/arch/powerpc/kvm/book3s_32_mmu_host.c @@ -141,7 +141,7 @@ extern char etext[]; int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) { pfn_t hpaddr; - u64 vpn; + u64 va; u64 vsid; struct kvmppc_sid_map *map; volatile u32 *pteg; @@ -173,7 +173,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) BUG_ON(!map); vsid = map->host_vsid; - vpn = (vsid << (SID_SHIFT - VPN_SHIFT)) | ((eaddr & ~ESID_MASK) >> VPN_SHIFT) + va = (vsid << SID_SHIFT) | (eaddr & ~ESID_MASK); next_pteg: if (rr == 16) { @@ -244,11 +244,11 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) dprintk_mmu("KVM: %c%c Map 0x%llx: [%lx] 0x%llx (0x%llx) -> %lx\n", orig_pte->may_write ? 'w' : '-', orig_pte->may_execute ? 'x' : '-', - orig_pte->eaddr, (ulong)pteg, vpn, + orig_pte->eaddr, (ulong)pteg, va, orig_pte->vpage, hpaddr); pte->slot = (ulong)&pteg[rr]; - pte->host_vpn = vpn; + pte->host_va = va; pte->pte = *orig_pte; pte->pfn = hpaddr >> PAGE_SHIFT; diff --git a/trunk/arch/powerpc/kvm/book3s_64_mmu_host.c b/trunk/arch/powerpc/kvm/book3s_64_mmu_host.c index 4d72f9ebc554..0688b6b39585 100644 --- a/trunk/arch/powerpc/kvm/book3s_64_mmu_host.c +++ b/trunk/arch/powerpc/kvm/book3s_64_mmu_host.c @@ -33,7 +33,7 @@ void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte) { - ppc_md.hpte_invalidate(pte->slot, pte->host_vpn, + ppc_md.hpte_invalidate(pte->slot, pte->host_va, MMU_PAGE_4K, MMU_SEGSIZE_256M, false); } @@ -80,9 +80,8 @@ static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid) int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) { - unsigned long vpn; pfn_t hpaddr; - ulong hash, hpteg; + ulong hash, hpteg, va; u64 vsid; int ret; int rflags = 0x192; @@ -118,7 +117,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) } vsid = map->host_vsid; - vpn = hpt_vpn(orig_pte->eaddr, vsid, MMU_SEGSIZE_256M); + va = hpt_va(orig_pte->eaddr, vsid, MMU_SEGSIZE_256M); if (!orig_pte->may_write) rflags |= HPTE_R_PP; @@ -130,7 +129,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) else kvmppc_mmu_flush_icache(hpaddr >> PAGE_SHIFT); - hash = hpt_hash(vpn, PTE_SIZE, MMU_SEGSIZE_256M); + hash = hpt_hash(va, PTE_SIZE, MMU_SEGSIZE_256M); map_again: hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); @@ -142,8 +141,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) goto out; } - ret = ppc_md.hpte_insert(hpteg, vpn, hpaddr, rflags, vflags, - MMU_PAGE_4K, MMU_SEGSIZE_256M); + ret = ppc_md.hpte_insert(hpteg, va, hpaddr, rflags, vflags, MMU_PAGE_4K, MMU_SEGSIZE_256M); if (ret < 0) { /* If we couldn't map a primary PTE, try a secondary */ @@ -154,8 +152,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) } else { struct hpte_cache *pte = kvmppc_mmu_hpte_cache_next(vcpu); - trace_kvm_book3s_64_mmu_map(rflags, hpteg, - vpn, hpaddr, orig_pte); + trace_kvm_book3s_64_mmu_map(rflags, hpteg, va, hpaddr, orig_pte); /* The ppc_md code may give us a secondary entry even though we asked for a primary. Fix up. */ @@ -165,7 +162,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) } pte->slot = hpteg + (ret & 7); - pte->host_vpn = vpn; + pte->host_va = va; pte->pte = *orig_pte; pte->pfn = hpaddr >> PAGE_SHIFT; diff --git a/trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S index 74a24bbb9637..44b72feaff7d 100644 --- a/trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -1065,7 +1065,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_206) mtspr SPRN_DABRX,r6 /* Restore SPRG3 */ - ld r3,PACA_SPRG3(r13) + ld r3,HSTATE_SPRG3(r13) mtspr SPRN_SPRG3,r3 /* diff --git a/trunk/arch/powerpc/kvm/trace.h b/trunk/arch/powerpc/kvm/trace.h index ddb6a2149d44..877186b7b1c3 100644 --- a/trunk/arch/powerpc/kvm/trace.h +++ b/trunk/arch/powerpc/kvm/trace.h @@ -189,7 +189,7 @@ TRACE_EVENT(kvm_book3s_mmu_map, TP_ARGS(pte), TP_STRUCT__entry( - __field( u64, host_vpn ) + __field( u64, host_va ) __field( u64, pfn ) __field( ulong, eaddr ) __field( u64, vpage ) @@ -198,7 +198,7 @@ TRACE_EVENT(kvm_book3s_mmu_map, ), TP_fast_assign( - __entry->host_vpn = pte->host_vpn; + __entry->host_va = pte->host_va; __entry->pfn = pte->pfn; __entry->eaddr = pte->pte.eaddr; __entry->vpage = pte->pte.vpage; @@ -208,8 +208,8 @@ TRACE_EVENT(kvm_book3s_mmu_map, (pte->pte.may_execute ? 0x1 : 0); ), - TP_printk("Map: hvpn=%llx pfn=%llx ea=%lx vp=%llx ra=%lx [%x]", - __entry->host_vpn, __entry->pfn, __entry->eaddr, + TP_printk("Map: hva=%llx pfn=%llx ea=%lx vp=%llx ra=%lx [%x]", + __entry->host_va, __entry->pfn, __entry->eaddr, __entry->vpage, __entry->raddr, __entry->flags) ); @@ -218,7 +218,7 @@ TRACE_EVENT(kvm_book3s_mmu_invalidate, TP_ARGS(pte), TP_STRUCT__entry( - __field( u64, host_vpn ) + __field( u64, host_va ) __field( u64, pfn ) __field( ulong, eaddr ) __field( u64, vpage ) @@ -227,7 +227,7 @@ TRACE_EVENT(kvm_book3s_mmu_invalidate, ), TP_fast_assign( - __entry->host_vpn = pte->host_vpn; + __entry->host_va = pte->host_va; __entry->pfn = pte->pfn; __entry->eaddr = pte->pte.eaddr; __entry->vpage = pte->pte.vpage; @@ -238,7 +238,7 @@ TRACE_EVENT(kvm_book3s_mmu_invalidate, ), TP_printk("Flush: hva=%llx pfn=%llx ea=%lx vp=%llx ra=%lx [%x]", - __entry->host_vpn, __entry->pfn, __entry->eaddr, + __entry->host_va, __entry->pfn, __entry->eaddr, __entry->vpage, __entry->raddr, __entry->flags) ); diff --git a/trunk/arch/powerpc/lib/sstep.c b/trunk/arch/powerpc/lib/sstep.c index e15c521846ca..9a52349874ee 100644 --- a/trunk/arch/powerpc/lib/sstep.c +++ b/trunk/arch/powerpc/lib/sstep.c @@ -566,7 +566,7 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) unsigned long int ea; unsigned int cr, mb, me, sh; int err; - unsigned long old_ra, val3; + unsigned long old_ra; long ival; opcode = instr >> 26; @@ -1486,41 +1486,9 @@ int __kprobes emulate_step(struct pt_regs *regs, unsigned int instr) goto ldst_done; case 36: /* stw */ - val = regs->gpr[rd]; - err = write_mem(val, dform_ea(instr, regs), 4, regs); - goto ldst_done; - case 37: /* stwu */ val = regs->gpr[rd]; - val3 = dform_ea(instr, regs); - /* - * For PPC32 we always use stwu to change stack point with r1. So - * this emulated store may corrupt the exception frame, now we - * have to provide the exception frame trampoline, which is pushed - * below the kprobed function stack. So we only update gpr[1] but - * don't emulate the real store operation. We will do real store - * operation safely in exception return code by checking this flag. - */ - if ((ra == 1) && !(regs->msr & MSR_PR) \ - && (val3 >= (regs->gpr[1] - STACK_INT_FRAME_SIZE))) { - /* - * Check if we will touch kernel sack overflow - */ - if (val3 - STACK_INT_FRAME_SIZE <= current->thread.ksp_limit) { - printk(KERN_CRIT "Can't kprobe this since Kernel stack overflow.\n"); - err = -EINVAL; - break; - } - - /* - * Check if we already set since that means we'll - * lose the previous value. - */ - WARN_ON(test_thread_flag(TIF_EMULATE_STACK_STORE)); - set_thread_flag(TIF_EMULATE_STACK_STORE); - err = 0; - } else - err = write_mem(val, val3, 4, regs); + err = write_mem(val, dform_ea(instr, regs), 4, regs); goto ldst_done; case 38: /* stb */ diff --git a/trunk/arch/powerpc/mm/fault.c b/trunk/arch/powerpc/mm/fault.c index 995f924e007f..08ffcf52a856 100644 --- a/trunk/arch/powerpc/mm/fault.c +++ b/trunk/arch/powerpc/mm/fault.c @@ -133,7 +133,6 @@ static int do_sigbus(struct pt_regs *regs, unsigned long address) up_read(¤t->mm->mmap_sem); if (user_mode(regs)) { - current->thread.trap_nr = BUS_ADRERR; info.si_signo = SIGBUS; info.si_errno = 0; info.si_code = BUS_ADRERR; diff --git a/trunk/arch/powerpc/mm/hash_low_64.S b/trunk/arch/powerpc/mm/hash_low_64.S index 56585086413a..602aeb06d298 100644 --- a/trunk/arch/powerpc/mm/hash_low_64.S +++ b/trunk/arch/powerpc/mm/hash_low_64.S @@ -63,7 +63,7 @@ _GLOBAL(__hash_page_4K) /* Save non-volatile registers. * r31 will hold "old PTE" * r30 is "new PTE" - * r29 is vpn + * r29 is "va" * r28 is a hash value * r27 is hashtab mask (maybe dynamic patched instead ?) */ @@ -111,10 +111,10 @@ BEGIN_FTR_SECTION cmpdi r9,0 /* check segment size */ bne 3f END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) - /* Calc vpn and put it in r29 */ - sldi r29,r5,SID_SHIFT - VPN_SHIFT - rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT) - or r29,r28,r29 + /* Calc va and put it in r29 */ + rldicr r29,r5,28,63-28 + rldicl r3,r3,0,36 + or r29,r3,r29 /* Calculate hash value for primary slot and store it in r28 */ rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */ @@ -122,19 +122,14 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) xor r28,r5,r0 b 4f -3: /* Calc vpn and put it in r29 */ - sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT - rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT) - or r29,r28,r29 - - /* - * calculate hash value for primary slot and - * store it in r28 for 1T segment - */ +3: /* Calc VA and hash in r29 and r28 for 1T segment */ + sldi r29,r5,40 /* vsid << 40 */ + clrldi r3,r3,24 /* ea & 0xffffffffff */ rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */ clrldi r5,r5,40 /* vsid & 0xffffff */ rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */ xor r28,r28,r5 + or r29,r3,r29 /* VA */ xor r28,r28,r0 /* hash */ /* Convert linux PTE bits into HW equivalents */ @@ -190,7 +185,7 @@ htab_insert_pte: /* Call ppc_md.hpte_insert */ ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ - mr r4,r29 /* Retrieve vpn */ + mr r4,r29 /* Retrieve va */ li r7,0 /* !bolted, !secondary */ li r8,MMU_PAGE_4K /* page size */ ld r9,STK_PARAM(R9)(r1) /* segment size */ @@ -213,7 +208,7 @@ _GLOBAL(htab_call_hpte_insert1) /* Call ppc_md.hpte_insert */ ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ - mr r4,r29 /* Retrieve vpn */ + mr r4,r29 /* Retrieve va */ li r7,HPTE_V_SECONDARY /* !bolted, secondary */ li r8,MMU_PAGE_4K /* page size */ ld r9,STK_PARAM(R9)(r1) /* segment size */ @@ -283,7 +278,7 @@ htab_modify_pte: add r3,r0,r3 /* add slot idx */ /* Call ppc_md.hpte_updatepp */ - mr r5,r29 /* vpn */ + mr r5,r29 /* va */ li r6,MMU_PAGE_4K /* page size */ ld r7,STK_PARAM(R9)(r1) /* segment size */ ld r8,STK_PARAM(R8)(r1) /* get "local" param */ @@ -344,7 +339,7 @@ _GLOBAL(__hash_page_4K) /* Save non-volatile registers. * r31 will hold "old PTE" * r30 is "new PTE" - * r29 is vpn + * r29 is "va" * r28 is a hash value * r27 is hashtab mask (maybe dynamic patched instead ?) * r26 is the hidx mask @@ -399,14 +394,10 @@ BEGIN_FTR_SECTION cmpdi r9,0 /* check segment size */ bne 3f END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) - /* Calc vpn and put it in r29 */ - sldi r29,r5,SID_SHIFT - VPN_SHIFT - /* - * clrldi r3,r3,64 - SID_SHIFT --> ea & 0xfffffff - * srdi r28,r3,VPN_SHIFT - */ - rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT) - or r29,r28,r29 + /* Calc va and put it in r29 */ + rldicr r29,r5,28,63-28 /* r29 = (vsid << 28) */ + rldicl r3,r3,0,36 /* r3 = (ea & 0x0fffffff) */ + or r29,r3,r29 /* r29 = va */ /* Calculate hash value for primary slot and store it in r28 */ rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */ @@ -414,23 +405,14 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) xor r28,r5,r0 b 4f -3: /* Calc vpn and put it in r29 */ - sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT - /* - * clrldi r3,r3,64 - SID_SHIFT_1T --> ea & 0xffffffffff - * srdi r28,r3,VPN_SHIFT - */ - rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT) - or r29,r28,r29 - - /* - * Calculate hash value for primary slot and - * store it in r28 for 1T segment - */ +3: /* Calc VA and hash in r29 and r28 for 1T segment */ + sldi r29,r5,40 /* vsid << 40 */ + clrldi r3,r3,24 /* ea & 0xffffffffff */ rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */ clrldi r5,r5,40 /* vsid & 0xffffff */ rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */ xor r28,r28,r5 + or r29,r3,r29 /* VA */ xor r28,r28,r0 /* hash */ /* Convert linux PTE bits into HW equivalents */ @@ -506,7 +488,7 @@ htab_special_pfn: /* Call ppc_md.hpte_insert */ ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ - mr r4,r29 /* Retrieve vpn */ + mr r4,r29 /* Retrieve va */ li r7,0 /* !bolted, !secondary */ li r8,MMU_PAGE_4K /* page size */ ld r9,STK_PARAM(R9)(r1) /* segment size */ @@ -533,7 +515,7 @@ _GLOBAL(htab_call_hpte_insert1) /* Call ppc_md.hpte_insert */ ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ - mr r4,r29 /* Retrieve vpn */ + mr r4,r29 /* Retrieve va */ li r7,HPTE_V_SECONDARY /* !bolted, secondary */ li r8,MMU_PAGE_4K /* page size */ ld r9,STK_PARAM(R9)(r1) /* segment size */ @@ -565,7 +547,7 @@ _GLOBAL(htab_call_hpte_remove) * useless now that the segment has been switched to 4k pages. */ htab_inval_old_hpte: - mr r3,r29 /* vpn */ + mr r3,r29 /* virtual addr */ mr r4,r31 /* PTE.pte */ li r5,0 /* PTE.hidx */ li r6,MMU_PAGE_64K /* psize */ @@ -638,7 +620,7 @@ htab_modify_pte: add r3,r0,r3 /* add slot idx */ /* Call ppc_md.hpte_updatepp */ - mr r5,r29 /* vpn */ + mr r5,r29 /* va */ li r6,MMU_PAGE_4K /* page size */ ld r7,STK_PARAM(R9)(r1) /* segment size */ ld r8,STK_PARAM(R8)(r1) /* get "local" param */ @@ -694,7 +676,7 @@ _GLOBAL(__hash_page_64K) /* Save non-volatile registers. * r31 will hold "old PTE" * r30 is "new PTE" - * r29 is vpn + * r29 is "va" * r28 is a hash value * r27 is hashtab mask (maybe dynamic patched instead ?) */ @@ -747,10 +729,10 @@ BEGIN_FTR_SECTION cmpdi r9,0 /* check segment size */ bne 3f END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) - /* Calc vpn and put it in r29 */ - sldi r29,r5,SID_SHIFT - VPN_SHIFT - rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT) - or r29,r28,r29 + /* Calc va and put it in r29 */ + rldicr r29,r5,28,63-28 + rldicl r3,r3,0,36 + or r29,r3,r29 /* Calculate hash value for primary slot and store it in r28 */ rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */ @@ -758,19 +740,14 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) xor r28,r5,r0 b 4f -3: /* Calc vpn and put it in r29 */ - sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT - rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT) - or r29,r28,r29 - - /* - * calculate hash value for primary slot and - * store it in r28 for 1T segment - */ +3: /* Calc VA and hash in r29 and r28 for 1T segment */ + sldi r29,r5,40 /* vsid << 40 */ + clrldi r3,r3,24 /* ea & 0xffffffffff */ rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */ clrldi r5,r5,40 /* vsid & 0xffffff */ rldicl r0,r3,64-16,40 /* (ea >> 16) & 0xffffff */ xor r28,r28,r5 + or r29,r3,r29 /* VA */ xor r28,r28,r0 /* hash */ /* Convert linux PTE bits into HW equivalents */ @@ -829,7 +806,7 @@ ht64_insert_pte: /* Call ppc_md.hpte_insert */ ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ - mr r4,r29 /* Retrieve vpn */ + mr r4,r29 /* Retrieve va */ li r7,0 /* !bolted, !secondary */ li r8,MMU_PAGE_64K ld r9,STK_PARAM(R9)(r1) /* segment size */ @@ -852,7 +829,7 @@ _GLOBAL(ht64_call_hpte_insert1) /* Call ppc_md.hpte_insert */ ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ - mr r4,r29 /* Retrieve vpn */ + mr r4,r29 /* Retrieve va */ li r7,HPTE_V_SECONDARY /* !bolted, secondary */ li r8,MMU_PAGE_64K ld r9,STK_PARAM(R9)(r1) /* segment size */ @@ -922,7 +899,7 @@ ht64_modify_pte: add r3,r0,r3 /* add slot idx */ /* Call ppc_md.hpte_updatepp */ - mr r5,r29 /* vpn */ + mr r5,r29 /* va */ li r6,MMU_PAGE_64K ld r7,STK_PARAM(R9)(r1) /* segment size */ ld r8,STK_PARAM(R8)(r1) /* get "local" param */ diff --git a/trunk/arch/powerpc/mm/hash_native_64.c b/trunk/arch/powerpc/mm/hash_native_64.c index a4a1c728f269..90039bc64119 100644 --- a/trunk/arch/powerpc/mm/hash_native_64.c +++ b/trunk/arch/powerpc/mm/hash_native_64.c @@ -14,10 +14,10 @@ #include #include -#include #include #include +#include #include #include #include @@ -39,35 +39,22 @@ DEFINE_RAW_SPINLOCK(native_tlbie_lock); -static inline void __tlbie(unsigned long vpn, int psize, int ssize) +static inline void __tlbie(unsigned long va, int psize, int ssize) { - unsigned long va; unsigned int penc; - /* - * We need 14 to 65 bits of va for a tlibe of 4K page - * With vpn we ignore the lower VPN_SHIFT bits already. - * And top two bits are already ignored because we can - * only accomadate 76 bits in a 64 bit vpn with a VPN_SHIFT - * of 12. - */ - va = vpn << VPN_SHIFT; - /* - * clear top 16 bits of 64bit va, non SLS segment - * Older versions of the architecture (2.02 and earler) require the - * masking of the top 16 bits. - */ + /* clear top 16 bits, non SLS segment */ va &= ~(0xffffULL << 48); switch (psize) { case MMU_PAGE_4K: + va &= ~0xffful; va |= ssize << 8; asm volatile(ASM_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0), %2) : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206) : "memory"); break; default: - /* We need 14 to 14 + i bits of va */ penc = mmu_psize_defs[psize].penc; va &= ~((1ul << mmu_psize_defs[psize].shift) - 1); va |= penc << 12; @@ -80,28 +67,21 @@ static inline void __tlbie(unsigned long vpn, int psize, int ssize) } } -static inline void __tlbiel(unsigned long vpn, int psize, int ssize) +static inline void __tlbiel(unsigned long va, int psize, int ssize) { - unsigned long va; unsigned int penc; - /* VPN_SHIFT can be atmost 12 */ - va = vpn << VPN_SHIFT; - /* - * clear top 16 bits of 64 bit va, non SLS segment - * Older versions of the architecture (2.02 and earler) require the - * masking of the top 16 bits. - */ + /* clear top 16 bits, non SLS segment */ va &= ~(0xffffULL << 48); switch (psize) { case MMU_PAGE_4K: + va &= ~0xffful; va |= ssize << 8; asm volatile(".long 0x7c000224 | (%0 << 11) | (0 << 21)" : : "r"(va) : "memory"); break; default: - /* We need 14 to 14 + i bits of va */ penc = mmu_psize_defs[psize].penc; va &= ~((1ul << mmu_psize_defs[psize].shift) - 1); va |= penc << 12; @@ -114,7 +94,7 @@ static inline void __tlbiel(unsigned long vpn, int psize, int ssize) } -static inline void tlbie(unsigned long vpn, int psize, int ssize, int local) +static inline void tlbie(unsigned long va, int psize, int ssize, int local) { unsigned int use_local = local && mmu_has_feature(MMU_FTR_TLBIEL); int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE); @@ -125,10 +105,10 @@ static inline void tlbie(unsigned long vpn, int psize, int ssize, int local) raw_spin_lock(&native_tlbie_lock); asm volatile("ptesync": : :"memory"); if (use_local) { - __tlbiel(vpn, psize, ssize); + __tlbiel(va, psize, ssize); asm volatile("ptesync": : :"memory"); } else { - __tlbie(vpn, psize, ssize); + __tlbie(va, psize, ssize); asm volatile("eieio; tlbsync; ptesync": : :"memory"); } if (lock_tlbie && !use_local) @@ -154,7 +134,7 @@ static inline void native_unlock_hpte(struct hash_pte *hptep) clear_bit_unlock(HPTE_LOCK_BIT, word); } -static long native_hpte_insert(unsigned long hpte_group, unsigned long vpn, +static long native_hpte_insert(unsigned long hpte_group, unsigned long va, unsigned long pa, unsigned long rflags, unsigned long vflags, int psize, int ssize) { @@ -163,9 +143,9 @@ static long native_hpte_insert(unsigned long hpte_group, unsigned long vpn, int i; if (!(vflags & HPTE_V_BOLTED)) { - DBG_LOW(" insert(group=%lx, vpn=%016lx, pa=%016lx," + DBG_LOW(" insert(group=%lx, va=%016lx, pa=%016lx," " rflags=%lx, vflags=%lx, psize=%d)\n", - hpte_group, vpn, pa, rflags, vflags, psize); + hpte_group, va, pa, rflags, vflags, psize); } for (i = 0; i < HPTES_PER_GROUP; i++) { @@ -183,7 +163,7 @@ static long native_hpte_insert(unsigned long hpte_group, unsigned long vpn, if (i == HPTES_PER_GROUP) return -1; - hpte_v = hpte_encode_v(vpn, psize, ssize) | vflags | HPTE_V_VALID; + hpte_v = hpte_encode_v(va, psize, ssize) | vflags | HPTE_V_VALID; hpte_r = hpte_encode_r(pa, psize) | rflags; if (!(vflags & HPTE_V_BOLTED)) { @@ -245,17 +225,17 @@ static long native_hpte_remove(unsigned long hpte_group) } static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, - unsigned long vpn, int psize, int ssize, + unsigned long va, int psize, int ssize, int local) { struct hash_pte *hptep = htab_address + slot; unsigned long hpte_v, want_v; int ret = 0; - want_v = hpte_encode_v(vpn, psize, ssize); + want_v = hpte_encode_v(va, psize, ssize); - DBG_LOW(" update(vpn=%016lx, avpnv=%016lx, group=%lx, newpp=%lx)", - vpn, want_v & HPTE_V_AVPN, slot, newpp); + DBG_LOW(" update(va=%016lx, avpnv=%016lx, hash=%016lx, newpp=%x)", + va, want_v & HPTE_V_AVPN, slot, newpp); native_lock_hpte(hptep); @@ -274,12 +254,12 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp, native_unlock_hpte(hptep); /* Ensure it is out of the tlb too. */ - tlbie(vpn, psize, ssize, local); + tlbie(va, psize, ssize, local); return ret; } -static long native_hpte_find(unsigned long vpn, int psize, int ssize) +static long native_hpte_find(unsigned long va, int psize, int ssize) { struct hash_pte *hptep; unsigned long hash; @@ -287,8 +267,8 @@ static long native_hpte_find(unsigned long vpn, int psize, int ssize) long slot; unsigned long want_v, hpte_v; - hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, ssize); - want_v = hpte_encode_v(vpn, psize, ssize); + hash = hpt_hash(va, mmu_psize_defs[psize].shift, ssize); + want_v = hpte_encode_v(va, psize, ssize); /* Bolted mappings are only ever in the primary group */ slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; @@ -315,15 +295,14 @@ static long native_hpte_find(unsigned long vpn, int psize, int ssize) static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea, int psize, int ssize) { - unsigned long vpn; - unsigned long vsid; + unsigned long vsid, va; long slot; struct hash_pte *hptep; vsid = get_kernel_vsid(ea, ssize); - vpn = hpt_vpn(ea, vsid, ssize); + va = hpt_va(ea, vsid, ssize); - slot = native_hpte_find(vpn, psize, ssize); + slot = native_hpte_find(va, psize, ssize); if (slot == -1) panic("could not find page to bolt\n"); hptep = htab_address + slot; @@ -333,10 +312,10 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea, (newpp & (HPTE_R_PP | HPTE_R_N)); /* Ensure it is out of the tlb too. */ - tlbie(vpn, psize, ssize, 0); + tlbie(va, psize, ssize, 0); } -static void native_hpte_invalidate(unsigned long slot, unsigned long vpn, +static void native_hpte_invalidate(unsigned long slot, unsigned long va, int psize, int ssize, int local) { struct hash_pte *hptep = htab_address + slot; @@ -346,9 +325,9 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn, local_irq_save(flags); - DBG_LOW(" invalidate(vpn=%016lx, hash: %lx)\n", vpn, slot); + DBG_LOW(" invalidate(va=%016lx, hash: %x)\n", va, slot); - want_v = hpte_encode_v(vpn, psize, ssize); + want_v = hpte_encode_v(va, psize, ssize); native_lock_hpte(hptep); hpte_v = hptep->v; @@ -360,7 +339,7 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn, hptep->v = 0; /* Invalidate the TLB */ - tlbie(vpn, psize, ssize, local); + tlbie(va, psize, ssize, local); local_irq_restore(flags); } @@ -370,12 +349,11 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long vpn, #define LP_MASK(i) ((0xFF >> (i)) << LP_SHIFT) static void hpte_decode(struct hash_pte *hpte, unsigned long slot, - int *psize, int *ssize, unsigned long *vpn) + int *psize, int *ssize, unsigned long *va) { - unsigned long avpn, pteg, vpi; unsigned long hpte_r = hpte->r; unsigned long hpte_v = hpte->v; - unsigned long vsid, seg_off; + unsigned long avpn; int i, size, shift, penc; if (!(hpte_v & HPTE_V_LARGE)) @@ -402,38 +380,32 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot, } /* This works for all page sizes, and for 256M and 1T segments */ - *ssize = hpte_v >> HPTE_V_SSIZE_SHIFT; shift = mmu_psize_defs[size].shift; + avpn = (HPTE_V_AVPN_VAL(hpte_v) & ~mmu_psize_defs[size].avpnm) << 23; - avpn = (HPTE_V_AVPN_VAL(hpte_v) & ~mmu_psize_defs[size].avpnm); - pteg = slot / HPTES_PER_GROUP; - if (hpte_v & HPTE_V_SECONDARY) - pteg = ~pteg; - - switch (*ssize) { - case MMU_SEGSIZE_256M: - /* We only have 28 - 23 bits of seg_off in avpn */ - seg_off = (avpn & 0x1f) << 23; - vsid = avpn >> 5; - /* We can find more bits from the pteg value */ - if (shift < 23) { - vpi = (vsid ^ pteg) & htab_hash_mask; - seg_off |= vpi << shift; - } - *vpn = vsid << (SID_SHIFT - VPN_SHIFT) | seg_off >> VPN_SHIFT; - case MMU_SEGSIZE_1T: - /* We only have 40 - 23 bits of seg_off in avpn */ - seg_off = (avpn & 0x1ffff) << 23; - vsid = avpn >> 17; - if (shift < 23) { + if (shift < 23) { + unsigned long vpi, vsid, pteg; + + pteg = slot / HPTES_PER_GROUP; + if (hpte_v & HPTE_V_SECONDARY) + pteg = ~pteg; + switch (hpte_v >> HPTE_V_SSIZE_SHIFT) { + case MMU_SEGSIZE_256M: + vpi = ((avpn >> 28) ^ pteg) & htab_hash_mask; + break; + case MMU_SEGSIZE_1T: + vsid = avpn >> 40; vpi = (vsid ^ (vsid << 25) ^ pteg) & htab_hash_mask; - seg_off |= vpi << shift; + break; + default: + avpn = vpi = size = 0; } - *vpn = vsid << (SID_SHIFT_1T - VPN_SHIFT) | seg_off >> VPN_SHIFT; - default: - *vpn = size = 0; + avpn |= (vpi << mmu_psize_defs[size].shift); } + + *va = avpn; *psize = size; + *ssize = hpte_v >> HPTE_V_SSIZE_SHIFT; } /* @@ -446,10 +418,9 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot, */ static void native_hpte_clear(void) { - unsigned long vpn = 0; unsigned long slot, slots, flags; struct hash_pte *hptep = htab_address; - unsigned long hpte_v; + unsigned long hpte_v, va; unsigned long pteg_count; int psize, ssize; @@ -477,9 +448,9 @@ static void native_hpte_clear(void) * already hold the native_tlbie_lock. */ if (hpte_v & HPTE_V_VALID) { - hpte_decode(hptep, slot, &psize, &ssize, &vpn); + hpte_decode(hptep, slot, &psize, &ssize, &va); hptep->v = 0; - __tlbie(vpn, psize, ssize); + __tlbie(va, psize, ssize); } } @@ -494,8 +465,7 @@ static void native_hpte_clear(void) */ static void native_flush_hash_range(unsigned long number, int local) { - unsigned long vpn; - unsigned long hash, index, hidx, shift, slot; + unsigned long va, hash, index, hidx, shift, slot; struct hash_pte *hptep; unsigned long hpte_v; unsigned long want_v; @@ -509,18 +479,18 @@ static void native_flush_hash_range(unsigned long number, int local) local_irq_save(flags); for (i = 0; i < number; i++) { - vpn = batch->vpn[i]; + va = batch->vaddr[i]; pte = batch->pte[i]; - pte_iterate_hashed_subpages(pte, psize, vpn, index, shift) { - hash = hpt_hash(vpn, shift, ssize); + pte_iterate_hashed_subpages(pte, psize, va, index, shift) { + hash = hpt_hash(va, shift, ssize); hidx = __rpte_to_hidx(pte, index); if (hidx & _PTEIDX_SECONDARY) hash = ~hash; slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; slot += hidx & _PTEIDX_GROUP_IX; hptep = htab_address + slot; - want_v = hpte_encode_v(vpn, psize, ssize); + want_v = hpte_encode_v(va, psize, ssize); native_lock_hpte(hptep); hpte_v = hptep->v; if (!HPTE_V_COMPARE(hpte_v, want_v) || @@ -535,12 +505,12 @@ static void native_flush_hash_range(unsigned long number, int local) mmu_psize_defs[psize].tlbiel && local) { asm volatile("ptesync":::"memory"); for (i = 0; i < number; i++) { - vpn = batch->vpn[i]; + va = batch->vaddr[i]; pte = batch->pte[i]; - pte_iterate_hashed_subpages(pte, psize, - vpn, index, shift) { - __tlbiel(vpn, psize, ssize); + pte_iterate_hashed_subpages(pte, psize, va, index, + shift) { + __tlbiel(va, psize, ssize); } pte_iterate_hashed_end(); } asm volatile("ptesync":::"memory"); @@ -552,12 +522,12 @@ static void native_flush_hash_range(unsigned long number, int local) asm volatile("ptesync":::"memory"); for (i = 0; i < number; i++) { - vpn = batch->vpn[i]; + va = batch->vaddr[i]; pte = batch->pte[i]; - pte_iterate_hashed_subpages(pte, psize, - vpn, index, shift) { - __tlbie(vpn, psize, ssize); + pte_iterate_hashed_subpages(pte, psize, va, index, + shift) { + __tlbie(va, psize, ssize); } pte_iterate_hashed_end(); } asm volatile("eieio; tlbsync; ptesync":::"memory"); diff --git a/trunk/arch/powerpc/mm/hash_utils_64.c b/trunk/arch/powerpc/mm/hash_utils_64.c index 3a292be2e079..377e5cbedbbb 100644 --- a/trunk/arch/powerpc/mm/hash_utils_64.c +++ b/trunk/arch/powerpc/mm/hash_utils_64.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -191,18 +192,18 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, vaddr += step, paddr += step) { unsigned long hash, hpteg; unsigned long vsid = get_kernel_vsid(vaddr, ssize); - unsigned long vpn = hpt_vpn(vaddr, vsid, ssize); + unsigned long va = hpt_va(vaddr, vsid, ssize); unsigned long tprot = prot; /* Make kernel text executable */ if (overlaps_kernel_text(vaddr, vaddr + step)) tprot &= ~HPTE_R_N; - hash = hpt_hash(vpn, shift, ssize); + hash = hpt_hash(va, shift, ssize); hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); BUG_ON(!ppc_md.hpte_insert); - ret = ppc_md.hpte_insert(hpteg, vpn, paddr, tprot, + ret = ppc_md.hpte_insert(hpteg, va, paddr, tprot, HPTE_V_BOLTED, psize, ssize); if (ret < 0) @@ -650,7 +651,7 @@ static void __init htab_initialize(void) DBG("Hash table allocated at %lx, size: %lx\n", table, htab_size_bytes); - htab_address = __va(table); + htab_address = abs_to_virt(table); /* htab absolute addr + encoded htabsize */ _SDR1 = table + __ilog2(pteg_count) - 11; @@ -803,19 +804,16 @@ unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap) #ifdef CONFIG_PPC_MM_SLICES unsigned int get_paca_psize(unsigned long addr) { - u64 lpsizes; - unsigned char *hpsizes; - unsigned long index, mask_index; + unsigned long index, slices; if (addr < SLICE_LOW_TOP) { - lpsizes = get_paca()->context.low_slices_psize; + slices = get_paca()->context.low_slices_psize; index = GET_LOW_SLICE_INDEX(addr); - return (lpsizes >> (index * 4)) & 0xF; + } else { + slices = get_paca()->context.high_slices_psize; + index = GET_HIGH_SLICE_INDEX(addr); } - hpsizes = get_paca()->context.high_slices_psize; - index = GET_HIGH_SLICE_INDEX(addr); - mask_index = index & 0x1; - return (hpsizes[index >> 1] >> (mask_index * 4)) & 0xF; + return (slices >> (index * 4)) & 0xF; } #else @@ -1155,21 +1153,21 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, /* WARNING: This is called from hash_low_64.S, if you change this prototype, * do not forget to update the assembly call site ! */ -void flush_hash_page(unsigned long vpn, real_pte_t pte, int psize, int ssize, +void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize, int local) { unsigned long hash, index, shift, hidx, slot; - DBG_LOW("flush_hash_page(vpn=%016lx)\n", vpn); - pte_iterate_hashed_subpages(pte, psize, vpn, index, shift) { - hash = hpt_hash(vpn, shift, ssize); + DBG_LOW("flush_hash_page(va=%016lx)\n", va); + pte_iterate_hashed_subpages(pte, psize, va, index, shift) { + hash = hpt_hash(va, shift, ssize); hidx = __rpte_to_hidx(pte, index); if (hidx & _PTEIDX_SECONDARY) hash = ~hash; slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; slot += hidx & _PTEIDX_GROUP_IX; DBG_LOW(" sub %ld: hash=%lx, hidx=%lx\n", index, slot, hidx); - ppc_md.hpte_invalidate(slot, vpn, psize, ssize, local); + ppc_md.hpte_invalidate(slot, va, psize, ssize, local); } pte_iterate_hashed_end(); } @@ -1183,7 +1181,7 @@ void flush_hash_range(unsigned long number, int local) &__get_cpu_var(ppc64_tlb_batch); for (i = 0; i < number; i++) - flush_hash_page(batch->vpn[i], batch->pte[i], + flush_hash_page(batch->vaddr[i], batch->pte[i], batch->psize, batch->ssize, local); } } @@ -1210,14 +1208,14 @@ static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) { unsigned long hash, hpteg; unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize); - unsigned long vpn = hpt_vpn(vaddr, vsid, mmu_kernel_ssize); + unsigned long va = hpt_va(vaddr, vsid, mmu_kernel_ssize); unsigned long mode = htab_convert_pte_flags(PAGE_KERNEL); int ret; - hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize); + hash = hpt_hash(va, PAGE_SHIFT, mmu_kernel_ssize); hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); - ret = ppc_md.hpte_insert(hpteg, vpn, __pa(vaddr), + ret = ppc_md.hpte_insert(hpteg, va, __pa(vaddr), mode, HPTE_V_BOLTED, mmu_linear_psize, mmu_kernel_ssize); BUG_ON (ret < 0); @@ -1231,9 +1229,9 @@ static void kernel_unmap_linear_page(unsigned long vaddr, unsigned long lmi) { unsigned long hash, hidx, slot; unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize); - unsigned long vpn = hpt_vpn(vaddr, vsid, mmu_kernel_ssize); + unsigned long va = hpt_va(vaddr, vsid, mmu_kernel_ssize); - hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize); + hash = hpt_hash(va, PAGE_SHIFT, mmu_kernel_ssize); spin_lock(&linear_map_hash_lock); BUG_ON(!(linear_map_hash_slots[lmi] & 0x80)); hidx = linear_map_hash_slots[lmi] & 0x7f; @@ -1243,7 +1241,7 @@ static void kernel_unmap_linear_page(unsigned long vaddr, unsigned long lmi) hash = ~hash; slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; slot += hidx & _PTEIDX_GROUP_IX; - ppc_md.hpte_invalidate(slot, vpn, mmu_linear_psize, mmu_kernel_ssize, 0); + ppc_md.hpte_invalidate(slot, va, mmu_linear_psize, mmu_kernel_ssize, 0); } void kernel_map_pages(struct page *page, int numpages, int enable) diff --git a/trunk/arch/powerpc/mm/hugetlbpage-hash64.c b/trunk/arch/powerpc/mm/hugetlbpage-hash64.c index cecad348f604..cc5c273086cf 100644 --- a/trunk/arch/powerpc/mm/hugetlbpage-hash64.c +++ b/trunk/arch/powerpc/mm/hugetlbpage-hash64.c @@ -18,15 +18,14 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, pte_t *ptep, unsigned long trap, int local, int ssize, unsigned int shift, unsigned int mmu_psize) { - unsigned long vpn; unsigned long old_pte, new_pte; - unsigned long rflags, pa, sz; + unsigned long va, rflags, pa, sz; long slot; BUG_ON(shift != mmu_psize_defs[mmu_psize].shift); /* Search the Linux page table for a match with va */ - vpn = hpt_vpn(ea, vsid, ssize); + va = hpt_va(ea, vsid, ssize); /* At this point, we have a pte (old_pte) which can be used to build * or update an HPTE. There are 2 cases: @@ -70,19 +69,19 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, /* There MIGHT be an HPTE for this pte */ unsigned long hash, slot; - hash = hpt_hash(vpn, shift, ssize); + hash = hpt_hash(va, shift, ssize); if (old_pte & _PAGE_F_SECOND) hash = ~hash; slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; slot += (old_pte & _PAGE_F_GIX) >> 12; - if (ppc_md.hpte_updatepp(slot, rflags, vpn, mmu_psize, + if (ppc_md.hpte_updatepp(slot, rflags, va, mmu_psize, ssize, local) == -1) old_pte &= ~_PAGE_HPTEFLAGS; } if (likely(!(old_pte & _PAGE_HASHPTE))) { - unsigned long hash = hpt_hash(vpn, shift, ssize); + unsigned long hash = hpt_hash(va, shift, ssize); unsigned long hpte_group; pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT; @@ -102,14 +101,14 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, _PAGE_COHERENT | _PAGE_GUARDED)); /* Insert into the hash table, primary slot */ - slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, 0, + slot = ppc_md.hpte_insert(hpte_group, va, pa, rflags, 0, mmu_psize, ssize); /* Primary is full, try the secondary */ if (unlikely(slot == -1)) { hpte_group = ((~hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL; - slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, + slot = ppc_md.hpte_insert(hpte_group, va, pa, rflags, HPTE_V_SECONDARY, mmu_psize, ssize); if (slot == -1) { diff --git a/trunk/arch/powerpc/mm/init_64.c b/trunk/arch/powerpc/mm/init_64.c index 95a45293e5ac..620b7acd2fdf 100644 --- a/trunk/arch/powerpc/mm/init_64.c +++ b/trunk/arch/powerpc/mm/init_64.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include "mmu_decl.h" diff --git a/trunk/arch/powerpc/mm/mem.c b/trunk/arch/powerpc/mm/mem.c index 0dba5066c22a..fbdad0e3929a 100644 --- a/trunk/arch/powerpc/mm/mem.c +++ b/trunk/arch/powerpc/mm/mem.c @@ -62,7 +62,7 @@ int init_bootmem_done; int mem_init_done; -unsigned long long memory_limit; +phys_addr_t memory_limit; #ifdef CONFIG_HIGHMEM pte_t *kmap_pte; @@ -300,7 +300,8 @@ void __init mem_init(void) unsigned long reservedpages = 0, codesize, initsize, datasize, bsssize; #ifdef CONFIG_SWIOTLB - swiotlb_init(0); + if (ppc_swiotlb_enable) + swiotlb_init(1); #endif num_physpages = memblock_phys_mem_size() >> PAGE_SHIFT; diff --git a/trunk/arch/powerpc/mm/mmu_context_hash64.c b/trunk/arch/powerpc/mm/mmu_context_hash64.c index 40bc5b0ace54..40677aa0190e 100644 --- a/trunk/arch/powerpc/mm/mmu_context_hash64.c +++ b/trunk/arch/powerpc/mm/mmu_context_hash64.c @@ -30,13 +30,11 @@ static DEFINE_SPINLOCK(mmu_context_lock); static DEFINE_IDA(mmu_context_ida); /* - * 256MB segment - * The proto-VSID space has 2^(CONTEX_BITS + USER_ESID_BITS) - 1 segments - * available for user mappings. Each segment contains 2^28 bytes. Each - * context maps 2^46 bytes (64TB) so we can support 2^19-1 contexts - * (19 == 37 + 28 - 46). + * The proto-VSID space has 2^35 - 1 segments available for user mappings. + * Each segment contains 2^28 bytes. Each context maps 2^44 bytes, + * so we can support 2^19-1 contexts (19 == 35 + 28 - 44). */ -#define MAX_CONTEXT ((1UL << CONTEXT_BITS) - 1) +#define MAX_CONTEXT ((1UL << 19) - 1) int __init_new_context(void) { diff --git a/trunk/arch/powerpc/mm/pgtable_64.c b/trunk/arch/powerpc/mm/pgtable_64.c index e212a271c7a4..249a0631c4db 100644 --- a/trunk/arch/powerpc/mm/pgtable_64.c +++ b/trunk/arch/powerpc/mm/pgtable_64.c @@ -51,23 +51,14 @@ #include #include #include +#include #include #include "mmu_decl.h" -/* Some sanity checking */ -#if TASK_SIZE_USER64 > PGTABLE_RANGE -#error TASK_SIZE_USER64 exceeds pagetable range -#endif - -#ifdef CONFIG_PPC_STD_MMU_64 -#if TASK_SIZE_USER64 > (1UL << (USER_ESID_BITS + SID_SHIFT)) -#error TASK_SIZE_USER64 exceeds user VSID range -#endif -#endif - unsigned long ioremap_bot = IOREMAP_BASE; + #ifdef CONFIG_PPC_MMU_NOHASH static void *early_alloc_pgtable(unsigned long size) { diff --git a/trunk/arch/powerpc/mm/slb_low.S b/trunk/arch/powerpc/mm/slb_low.S index 1a16ca227757..b9ee79ce2200 100644 --- a/trunk/arch/powerpc/mm/slb_low.S +++ b/trunk/arch/powerpc/mm/slb_low.S @@ -56,12 +56,6 @@ _GLOBAL(slb_allocate_realmode) */ _GLOBAL(slb_miss_kernel_load_linear) li r11,0 - li r9,0x1 - /* - * for 1T we shift 12 bits more. slb_finish_load_1T will do - * the necessary adjustment - */ - rldimi r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0 BEGIN_FTR_SECTION b slb_finish_load END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT) @@ -91,12 +85,6 @@ _GLOBAL(slb_miss_kernel_load_vmemmap) _GLOBAL(slb_miss_kernel_load_io) li r11,0 6: - li r9,0x1 - /* - * for 1T we shift 12 bits more. slb_finish_load_1T will do - * the necessary adjustment - */ - rldimi r10,r9,(CONTEXT_BITS + USER_ESID_BITS),0 BEGIN_FTR_SECTION b slb_finish_load END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT) @@ -120,31 +108,17 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT) * between 4k and 64k standard page size */ #ifdef CONFIG_PPC_MM_SLICES - /* r10 have esid */ cmpldi r10,16 - /* below SLICE_LOW_TOP */ - blt 5f - /* - * Handle hpsizes, - * r9 is get_paca()->context.high_slices_psize[index], r11 is mask_index - */ - srdi r11,r10,(SLICE_HIGH_SHIFT - SLICE_LOW_SHIFT + 1) /* index */ - addi r9,r11,PACAHIGHSLICEPSIZE - lbzx r9,r13,r9 /* r9 is hpsizes[r11] */ - /* r11 = (r10 >> (SLICE_HIGH_SHIFT - SLICE_LOW_SHIFT)) & 0x1 */ - rldicl r11,r10,(64 - (SLICE_HIGH_SHIFT - SLICE_LOW_SHIFT)),63 - b 6f -5: - /* - * Handle lpsizes - * r9 is get_paca()->context.low_slices_psize, r11 is index - */ + /* Get the slice index * 4 in r11 and matching slice size mask in r9 */ ld r9,PACALOWSLICESPSIZE(r13) - mr r11,r10 -6: - sldi r11,r11,2 /* index * 4 */ - /* Extract the psize and multiply to get an array offset */ + sldi r11,r10,2 + blt 5f + ld r9,PACAHIGHSLICEPSIZE(r13) + srdi r11,r10,(SLICE_HIGH_SHIFT - SLICE_LOW_SHIFT - 2) + andi. r11,r11,0x3c + +5: /* Extract the psize and multiply to get an array offset */ srd r9,r9,r11 andi. r9,r9,0xf mulli r9,r9,MMUPSIZEDEFSIZE @@ -235,11 +209,7 @@ _GLOBAL(slb_allocate_user) */ slb_finish_load: ASM_VSID_SCRAMBLE(r10,r9,256M) - /* - * bits above VSID_BITS_256M need to be ignored from r10 - * also combine VSID and flags - */ - rldimi r11,r10,SLB_VSID_SHIFT,(64 - (SLB_VSID_SHIFT + VSID_BITS_256M)) + rldimi r11,r10,SLB_VSID_SHIFT,16 /* combine VSID and flags */ /* r3 = EA, r11 = VSID data */ /* @@ -282,10 +252,10 @@ _GLOBAL(slb_compare_rr_to_size) bge 1f /* still room in the slb cache */ - sldi r11,r3,2 /* r11 = offset * sizeof(u32) */ - srdi r10,r10,28 /* get the 36 bits of the ESID */ - add r11,r11,r13 /* r11 = (u32 *)paca + offset */ - stw r10,PACASLBCACHE(r11) /* paca->slb_cache[offset] = esid */ + sldi r11,r3,1 /* r11 = offset * sizeof(u16) */ + rldicl r10,r10,36,28 /* get low 16 bits of the ESID */ + add r11,r11,r13 /* r11 = (u16 *)paca + offset */ + sth r10,PACASLBCACHE(r11) /* paca->slb_cache[offset] = esid */ addi r3,r3,1 /* offset++ */ b 2f 1: /* offset >= SLB_CACHE_ENTRIES */ @@ -303,11 +273,7 @@ _GLOBAL(slb_compare_rr_to_size) slb_finish_load_1T: srdi r10,r10,40-28 /* get 1T ESID */ ASM_VSID_SCRAMBLE(r10,r9,1T) - /* - * bits above VSID_BITS_1T need to be ignored from r10 - * also combine VSID and flags - */ - rldimi r11,r10,SLB_VSID_SHIFT_1T,(64 - (SLB_VSID_SHIFT_1T + VSID_BITS_1T)) + rldimi r11,r10,SLB_VSID_SHIFT_1T,16 /* combine VSID and flags */ li r10,MMU_SEGSIZE_1T rldimi r11,r10,SLB_VSID_SSIZE_SHIFT,0 /* insert segment size */ diff --git a/trunk/arch/powerpc/mm/slice.c b/trunk/arch/powerpc/mm/slice.c index 5829d2a950d4..73709f7ce92c 100644 --- a/trunk/arch/powerpc/mm/slice.c +++ b/trunk/arch/powerpc/mm/slice.c @@ -34,11 +34,6 @@ #include #include -/* some sanity checks */ -#if (PGTABLE_RANGE >> 43) > SLICE_MASK_SIZE -#error PGTABLE_RANGE exceeds slice_mask high_slices size -#endif - static DEFINE_SPINLOCK(slice_convert_lock); @@ -47,7 +42,7 @@ int _slice_debug = 1; static void slice_print_mask(const char *label, struct slice_mask mask) { - char *p, buf[16 + 3 + 64 + 1]; + char *p, buf[16 + 3 + 16 + 1]; int i; if (!_slice_debug) @@ -59,7 +54,7 @@ static void slice_print_mask(const char *label, struct slice_mask mask) *(p++) = '-'; *(p++) = ' '; for (i = 0; i < SLICE_NUM_HIGH; i++) - *(p++) = (mask.high_slices & (1ul << i)) ? '1' : '0'; + *(p++) = (mask.high_slices & (1 << i)) ? '1' : '0'; *(p++) = 0; printk(KERN_DEBUG "%s:%s\n", label, buf); @@ -89,8 +84,8 @@ static struct slice_mask slice_range_to_mask(unsigned long start, } if ((start + len) > SLICE_LOW_TOP) - ret.high_slices = (1ul << (GET_HIGH_SLICE_INDEX(end) + 1)) - - (1ul << GET_HIGH_SLICE_INDEX(start)); + ret.high_slices = (1u << (GET_HIGH_SLICE_INDEX(end) + 1)) + - (1u << GET_HIGH_SLICE_INDEX(start)); return ret; } @@ -140,31 +135,26 @@ static struct slice_mask slice_mask_for_free(struct mm_struct *mm) for (i = 0; i < SLICE_NUM_HIGH; i++) if (!slice_high_has_vma(mm, i)) - ret.high_slices |= 1ul << i; + ret.high_slices |= 1u << i; return ret; } static struct slice_mask slice_mask_for_size(struct mm_struct *mm, int psize) { - unsigned char *hpsizes; - int index, mask_index; struct slice_mask ret = { 0, 0 }; unsigned long i; - u64 lpsizes; + u64 psizes; - lpsizes = mm->context.low_slices_psize; + psizes = mm->context.low_slices_psize; for (i = 0; i < SLICE_NUM_LOW; i++) - if (((lpsizes >> (i * 4)) & 0xf) == psize) + if (((psizes >> (i * 4)) & 0xf) == psize) ret.low_slices |= 1u << i; - hpsizes = mm->context.high_slices_psize; - for (i = 0; i < SLICE_NUM_HIGH; i++) { - mask_index = i & 0x1; - index = i >> 1; - if (((hpsizes[index] >> (mask_index * 4)) & 0xf) == psize) - ret.high_slices |= 1ul << i; - } + psizes = mm->context.high_slices_psize; + for (i = 0; i < SLICE_NUM_HIGH; i++) + if (((psizes >> (i * 4)) & 0xf) == psize) + ret.high_slices |= 1u << i; return ret; } @@ -193,10 +183,8 @@ static void slice_flush_segments(void *parm) static void slice_convert(struct mm_struct *mm, struct slice_mask mask, int psize) { - int index, mask_index; /* Write the new slice psize bits */ - unsigned char *hpsizes; - u64 lpsizes; + u64 lpsizes, hpsizes; unsigned long i, flags; slice_dbg("slice_convert(mm=%p, psize=%d)\n", mm, psize); @@ -213,18 +201,14 @@ static void slice_convert(struct mm_struct *mm, struct slice_mask mask, int psiz lpsizes = (lpsizes & ~(0xful << (i * 4))) | (((unsigned long)psize) << (i * 4)); - /* Assign the value back */ - mm->context.low_slices_psize = lpsizes; - hpsizes = mm->context.high_slices_psize; - for (i = 0; i < SLICE_NUM_HIGH; i++) { - mask_index = i & 0x1; - index = i >> 1; - if (mask.high_slices & (1ul << i)) - hpsizes[index] = (hpsizes[index] & - ~(0xf << (mask_index * 4))) | - (((unsigned long)psize) << (mask_index * 4)); - } + for (i = 0; i < SLICE_NUM_HIGH; i++) + if (mask.high_slices & (1u << i)) + hpsizes = (hpsizes & ~(0xful << (i * 4))) | + (((unsigned long)psize) << (i * 4)); + + mm->context.low_slices_psize = lpsizes; + mm->context.high_slices_psize = hpsizes; slice_dbg(" lsps=%lx, hsps=%lx\n", mm->context.low_slices_psize, @@ -603,19 +587,18 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp, unsigned int get_slice_psize(struct mm_struct *mm, unsigned long addr) { - unsigned char *hpsizes; - int index, mask_index; + u64 psizes; + int index; if (addr < SLICE_LOW_TOP) { - u64 lpsizes; - lpsizes = mm->context.low_slices_psize; + psizes = mm->context.low_slices_psize; index = GET_LOW_SLICE_INDEX(addr); - return (lpsizes >> (index * 4)) & 0xf; + } else { + psizes = mm->context.high_slices_psize; + index = GET_HIGH_SLICE_INDEX(addr); } - hpsizes = mm->context.high_slices_psize; - index = GET_HIGH_SLICE_INDEX(addr); - mask_index = index & 0x1; - return (hpsizes[index >> 1] >> (mask_index * 4)) & 0xf; + + return (psizes >> (index * 4)) & 0xf; } EXPORT_SYMBOL_GPL(get_slice_psize); @@ -635,9 +618,7 @@ EXPORT_SYMBOL_GPL(get_slice_psize); */ void slice_set_user_psize(struct mm_struct *mm, unsigned int psize) { - int index, mask_index; - unsigned char *hpsizes; - unsigned long flags, lpsizes; + unsigned long flags, lpsizes, hpsizes; unsigned int old_psize; int i; @@ -658,21 +639,15 @@ void slice_set_user_psize(struct mm_struct *mm, unsigned int psize) if (((lpsizes >> (i * 4)) & 0xf) == old_psize) lpsizes = (lpsizes & ~(0xful << (i * 4))) | (((unsigned long)psize) << (i * 4)); - /* Assign the value back */ - mm->context.low_slices_psize = lpsizes; hpsizes = mm->context.high_slices_psize; - for (i = 0; i < SLICE_NUM_HIGH; i++) { - mask_index = i & 0x1; - index = i >> 1; - if (((hpsizes[index] >> (mask_index * 4)) & 0xf) == old_psize) - hpsizes[index] = (hpsizes[index] & - ~(0xf << (mask_index * 4))) | - (((unsigned long)psize) << (mask_index * 4)); - } - - + for (i = 0; i < SLICE_NUM_HIGH; i++) + if (((hpsizes >> (i * 4)) & 0xf) == old_psize) + hpsizes = (hpsizes & ~(0xful << (i * 4))) | + (((unsigned long)psize) << (i * 4)); + mm->context.low_slices_psize = lpsizes; + mm->context.high_slices_psize = hpsizes; slice_dbg(" lsps=%lx, hsps=%lx\n", mm->context.low_slices_psize, @@ -685,27 +660,18 @@ void slice_set_user_psize(struct mm_struct *mm, unsigned int psize) void slice_set_psize(struct mm_struct *mm, unsigned long address, unsigned int psize) { - unsigned char *hpsizes; unsigned long i, flags; - u64 *lpsizes; + u64 *p; spin_lock_irqsave(&slice_convert_lock, flags); if (address < SLICE_LOW_TOP) { i = GET_LOW_SLICE_INDEX(address); - lpsizes = &mm->context.low_slices_psize; - *lpsizes = (*lpsizes & ~(0xful << (i * 4))) | - ((unsigned long) psize << (i * 4)); + p = &mm->context.low_slices_psize; } else { - int index, mask_index; i = GET_HIGH_SLICE_INDEX(address); - hpsizes = mm->context.high_slices_psize; - mask_index = i & 0x1; - index = i >> 1; - hpsizes[index] = (hpsizes[index] & - ~(0xf << (mask_index * 4))) | - (((unsigned long)psize) << (mask_index * 4)); + p = &mm->context.high_slices_psize; } - + *p = (*p & ~(0xful << (i * 4))) | ((unsigned long) psize << (i * 4)); spin_unlock_irqrestore(&slice_convert_lock, flags); #ifdef CONFIG_SPU_BASE diff --git a/trunk/arch/powerpc/mm/stab.c b/trunk/arch/powerpc/mm/stab.c index 3f8efa6f2997..9106ebb118f5 100644 --- a/trunk/arch/powerpc/mm/stab.c +++ b/trunk/arch/powerpc/mm/stab.c @@ -20,6 +20,7 @@ #include #include #include +#include struct stab_entry { unsigned long esid_data; @@ -256,7 +257,7 @@ void __init stabs_alloc(void) memset((void *)newstab, 0, HW_PAGE_SIZE); paca[cpu].stab_addr = newstab; - paca[cpu].stab_real = __pa(newstab); + paca[cpu].stab_real = virt_to_abs(newstab); printk(KERN_INFO "Segment table for CPU %d at 0x%llx " "virtual, 0x%llx absolute\n", cpu, paca[cpu].stab_addr, paca[cpu].stab_real); diff --git a/trunk/arch/powerpc/mm/subpage-prot.c b/trunk/arch/powerpc/mm/subpage-prot.c index 7c415ddde948..e4f8f1fc81a5 100644 --- a/trunk/arch/powerpc/mm/subpage-prot.c +++ b/trunk/arch/powerpc/mm/subpage-prot.c @@ -95,8 +95,7 @@ static void subpage_prot_clear(unsigned long addr, unsigned long len) struct mm_struct *mm = current->mm; struct subpage_prot_table *spt = &mm->context.spt; u32 **spm, *spp; - unsigned long i; - size_t nw; + int i, nw; unsigned long next, limit; down_write(&mm->mmap_sem); @@ -145,8 +144,7 @@ long sys_subpage_prot(unsigned long addr, unsigned long len, u32 __user *map) struct mm_struct *mm = current->mm; struct subpage_prot_table *spt = &mm->context.spt; u32 **spm, *spp; - unsigned long i; - size_t nw; + int i, nw; unsigned long next, limit; int err; diff --git a/trunk/arch/powerpc/mm/tlb_hash64.c b/trunk/arch/powerpc/mm/tlb_hash64.c index ae758b3ff72c..31f18207970b 100644 --- a/trunk/arch/powerpc/mm/tlb_hash64.c +++ b/trunk/arch/powerpc/mm/tlb_hash64.c @@ -42,9 +42,8 @@ DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); void hpte_need_flush(struct mm_struct *mm, unsigned long addr, pte_t *ptep, unsigned long pte, int huge) { - unsigned long vpn; struct ppc64_tlb_batch *batch = &get_cpu_var(ppc64_tlb_batch); - unsigned long vsid; + unsigned long vsid, vaddr; unsigned int psize; int ssize; real_pte_t rpte; @@ -87,7 +86,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr, vsid = get_kernel_vsid(addr, mmu_kernel_ssize); ssize = mmu_kernel_ssize; } - vpn = hpt_vpn(addr, vsid, ssize); + vaddr = hpt_va(addr, vsid, ssize); rpte = __real_pte(__pte(pte), ptep); /* @@ -97,7 +96,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr, * and decide to use local invalidates instead... */ if (!batch->active) { - flush_hash_page(vpn, rpte, psize, ssize, 0); + flush_hash_page(vaddr, rpte, psize, ssize, 0); put_cpu_var(ppc64_tlb_batch); return; } @@ -123,7 +122,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr, batch->ssize = ssize; } batch->pte[i] = rpte; - batch->vpn[i] = vpn; + batch->vaddr[i] = vaddr; batch->index = ++i; if (i >= PPC64_TLB_BATCH_NR) __flush_tlb_pending(batch); @@ -147,7 +146,7 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch) if (cpumask_equal(mm_cpumask(batch->mm), tmp)) local = 1; if (i == 1) - flush_hash_page(batch->vpn[0], batch->pte[0], + flush_hash_page(batch->vaddr[0], batch->pte[0], batch->psize, batch->ssize, local); else flush_hash_range(i, local); diff --git a/trunk/arch/powerpc/mm/tlb_low_64e.S b/trunk/arch/powerpc/mm/tlb_low_64e.S index b4113bf86353..f09d48e3268d 100644 --- a/trunk/arch/powerpc/mm/tlb_low_64e.S +++ b/trunk/arch/powerpc/mm/tlb_low_64e.S @@ -20,8 +20,6 @@ #include #include #include -#include -#include #ifdef CONFIG_PPC_64K_PAGES #define VPTE_PMD_SHIFT (PTE_INDEX_SIZE+1) @@ -39,18 +37,12 @@ * * **********************************************************************/ -.macro tlb_prolog_bolted intnum addr - mtspr SPRN_SPRG_GEN_SCRATCH,r13 +.macro tlb_prolog_bolted addr + mtspr SPRN_SPRG_TLB_SCRATCH,r13 mfspr r13,SPRN_SPRG_PACA std r10,PACA_EXTLB+EX_TLB_R10(r13) mfcr r10 std r11,PACA_EXTLB+EX_TLB_R11(r13) -#ifdef CONFIG_KVM_BOOKE_HV -BEGIN_FTR_SECTION - mfspr r11, SPRN_SRR1 -END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV) -#endif - DO_KVM \intnum, SPRN_SRR1 std r16,PACA_EXTLB+EX_TLB_R16(r13) mfspr r16,\addr /* get faulting address */ std r14,PACA_EXTLB+EX_TLB_R14(r13) @@ -69,12 +61,12 @@ END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV) ld r15,PACA_EXTLB+EX_TLB_R15(r13) TLB_MISS_RESTORE_STATS_BOLTED ld r16,PACA_EXTLB+EX_TLB_R16(r13) - mfspr r13,SPRN_SPRG_GEN_SCRATCH + mfspr r13,SPRN_SPRG_TLB_SCRATCH .endm /* Data TLB miss */ START_EXCEPTION(data_tlb_miss_bolted) - tlb_prolog_bolted BOOKE_INTERRUPT_DTLB_MISS SPRN_DEAR + tlb_prolog_bolted SPRN_DEAR /* We need _PAGE_PRESENT and _PAGE_ACCESSED set */ @@ -222,7 +214,7 @@ itlb_miss_fault_bolted: /* Instruction TLB miss */ START_EXCEPTION(instruction_tlb_miss_bolted) - tlb_prolog_bolted BOOKE_INTERRUPT_ITLB_MISS SPRN_SRR0 + tlb_prolog_bolted SPRN_SRR0 rldicl. r10,r16,64-PGTABLE_EADDR_SIZE,PGTABLE_EADDR_SIZE+4 srdi r15,r16,60 /* get region */ diff --git a/trunk/arch/powerpc/oprofile/op_model_power4.c b/trunk/arch/powerpc/oprofile/op_model_power4.c index 315f9495e9b2..95ae77dec3f6 100644 --- a/trunk/arch/powerpc/oprofile/op_model_power4.c +++ b/trunk/arch/powerpc/oprofile/op_model_power4.c @@ -21,13 +21,6 @@ #include #define dbg(args...) -#define OPROFILE_PM_PMCSEL_MSK 0xffULL -#define OPROFILE_PM_UNIT_SHIFT 60 -#define OPROFILE_PM_UNIT_MSK 0xfULL -#define OPROFILE_MAX_PMC_NUM 3 -#define OPROFILE_PMSEL_FIELD_WIDTH 8 -#define OPROFILE_UNIT_FIELD_WIDTH 4 -#define MMCRA_SIAR_VALID_MASK 0x10000000ULL static unsigned long reset_value[OP_MAX_COUNTER]; @@ -38,61 +31,6 @@ static int use_slot_nums; static u32 mmcr0_val; static u64 mmcr1_val; static u64 mmcra_val; -static u32 cntr_marked_events; - -static int power7_marked_instr_event(u64 mmcr1) -{ - u64 psel, unit; - int pmc, cntr_marked_events = 0; - - /* Given the MMCR1 value, look at the field for each counter to - * determine if it is a marked event. Code based on the function - * power7_marked_instr_event() in file arch/powerpc/perf/power7-pmu.c. - */ - for (pmc = 0; pmc < 4; pmc++) { - psel = mmcr1 & (OPROFILE_PM_PMCSEL_MSK - << (OPROFILE_MAX_PMC_NUM - pmc) - * OPROFILE_MAX_PMC_NUM); - psel = (psel >> ((OPROFILE_MAX_PMC_NUM - pmc) - * OPROFILE_PMSEL_FIELD_WIDTH)) & ~1ULL; - unit = mmcr1 & (OPROFILE_PM_UNIT_MSK - << (OPROFILE_PM_UNIT_SHIFT - - (pmc * OPROFILE_PMSEL_FIELD_WIDTH ))); - unit = unit >> (OPROFILE_PM_UNIT_SHIFT - - (pmc * OPROFILE_PMSEL_FIELD_WIDTH)); - - switch (psel >> 4) { - case 2: - cntr_marked_events |= (pmc == 1 || pmc == 3) << pmc; - break; - case 3: - if (psel == 0x3c) { - cntr_marked_events |= (pmc == 0) << pmc; - break; - } - - if (psel == 0x3e) { - cntr_marked_events |= (pmc != 1) << pmc; - break; - } - - cntr_marked_events |= 1 << pmc; - break; - case 4: - case 5: - cntr_marked_events |= (unit == 0xd) << pmc; - break; - case 6: - if (psel == 0x64) - cntr_marked_events |= (pmc >= 2) << pmc; - break; - case 8: - cntr_marked_events |= (unit == 0xd) << pmc; - break; - } - } - return cntr_marked_events; -} static int power4_reg_setup(struct op_counter_config *ctr, struct op_system_config *sys, @@ -109,23 +47,6 @@ static int power4_reg_setup(struct op_counter_config *ctr, mmcr1_val = sys->mmcr1; mmcra_val = sys->mmcra; - /* Power 7+ and newer architectures: - * Determine which counter events in the group (the group of events is - * specified by the bit settings in the MMCR1 register) are marked - * events for use in the interrupt handler. Do the calculation once - * before OProfile starts. Information is used in the interrupt - * handler. Starting with Power 7+ we only record the sample for - * marked events if the SIAR valid bit is set. For non marked events - * the sample is always recorded. - */ - if (pvr_version_is(PVR_POWER7p)) - cntr_marked_events = power7_marked_instr_event(mmcr1_val); - else - cntr_marked_events = 0; /* For older processors, set the bit map - * to zero so the sample will always be - * be recorded. - */ - for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) reset_value[i] = 0x80000000UL - ctr[i].count; @@ -140,10 +61,10 @@ static int power4_reg_setup(struct op_counter_config *ctr, else mmcr0_val |= MMCR0_PROBLEM_DISABLE; - if (pvr_version_is(PVR_POWER4) || pvr_version_is(PVR_POWER4p) || - pvr_version_is(PVR_970) || pvr_version_is(PVR_970FX) || - pvr_version_is(PVR_970MP) || pvr_version_is(PVR_970GX) || - pvr_version_is(PVR_POWER5) || pvr_version_is(PVR_POWER5p)) + if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) || + __is_processor(PV_970) || __is_processor(PV_970FX) || + __is_processor(PV_970MP) || __is_processor(PV_970GX) || + __is_processor(PV_POWER5) || __is_processor(PV_POWER5p)) use_slot_nums = 1; return 0; @@ -163,9 +84,9 @@ extern void ppc_enable_pmcs(void); */ static inline int mmcra_must_set_sample(void) { - if (pvr_version_is(PVR_POWER4) || pvr_version_is(PVR_POWER4p) || - pvr_version_is(PVR_970) || pvr_version_is(PVR_970FX) || - pvr_version_is(PVR_970MP) || pvr_version_is(PVR_970GX)) + if (__is_processor(PV_POWER4) || __is_processor(PV_POWER4p) || + __is_processor(PV_970) || __is_processor(PV_970FX) || + __is_processor(PV_970MP) || __is_processor(PV_970GX)) return 1; return 0; @@ -355,7 +276,7 @@ static bool pmc_overflow(unsigned long val) * PMCs because a user might set a period of less than 256 and we * don't want to mistakenly reset them. */ - if (pvr_version_is(PVR_POWER7) && ((0x80000000 - val) <= 256)) + if (__is_processor(PV_POWER7) && ((0x80000000 - val) <= 256)) return true; return false; @@ -370,7 +291,6 @@ static void power4_handle_interrupt(struct pt_regs *regs, int i; unsigned int mmcr0; unsigned long mmcra; - bool siar_valid = false; mmcra = mfspr(SPRN_MMCRA); @@ -380,29 +300,11 @@ static void power4_handle_interrupt(struct pt_regs *regs, /* set the PMM bit (see comment below) */ mtmsrd(mfmsr() | MSR_PMM); - /* Check that the SIAR valid bit in MMCRA is set to 1. */ - if ((mmcra & MMCRA_SIAR_VALID_MASK) == MMCRA_SIAR_VALID_MASK) - siar_valid = true; - for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) { val = classic_ctr_read(i); if (pmc_overflow(val)) { if (oprofile_running && ctr[i].enabled) { - /* Power 7+ and newer architectures: - * If the event is a marked event, then only - * save the sample if the SIAR valid bit is - * set. If the event is not marked, then - * always save the sample. - * Note, the Sample enable bit in the MMCRA - * register must be set to 1 if the group - * contains a marked event. - */ - if ((siar_valid && - (cntr_marked_events & (1 << i))) - || !(cntr_marked_events & (1 << i))) - oprofile_add_ext_sample(pc, regs, i, - is_kernel); - + oprofile_add_ext_sample(pc, regs, i, is_kernel); classic_ctr_write(i, reset_value[i]); } else { classic_ctr_write(i, 0); diff --git a/trunk/arch/powerpc/perf/core-book3s.c b/trunk/arch/powerpc/perf/core-book3s.c index fb55da91aa45..7cd2dbd6e4c4 100644 --- a/trunk/arch/powerpc/perf/core-book3s.c +++ b/trunk/arch/powerpc/perf/core-book3s.c @@ -1396,7 +1396,7 @@ static bool pmc_overflow(unsigned long val) * PMCs because a user might set a period of less than 256 and we * don't want to mistakenly reset them. */ - if (pvr_version_is(PVR_POWER7) && ((0x80000000 - val) <= 256)) + if (__is_processor(PV_POWER7) && ((0x80000000 - val) <= 256)) return true; return false; diff --git a/trunk/arch/powerpc/platforms/44x/currituck.c b/trunk/arch/powerpc/platforms/44x/currituck.c index 6bd89a0e0dea..9f6c33d63a42 100644 --- a/trunk/arch/powerpc/platforms/44x/currituck.c +++ b/trunk/arch/powerpc/platforms/44x/currituck.c @@ -21,6 +21,7 @@ */ #include +#include #include #include #include @@ -158,8 +159,13 @@ static void __init ppc47x_setup_arch(void) /* No need to check the DMA config as we /know/ our windows are all of * RAM. Lets hope that doesn't change */ - swiotlb_detect_4g(); - +#ifdef CONFIG_SWIOTLB + if ((memblock_end_of_DRAM() - 1) > 0xffffffff) { + ppc_swiotlb_enable = 1; + set_pci_dma_ops(&swiotlb_dma_ops); + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; + } +#endif ppc47x_smp_init(); } diff --git a/trunk/arch/powerpc/platforms/512x/clock.c b/trunk/arch/powerpc/platforms/512x/clock.c index 1d8700ff60b0..9f771e05457c 100644 --- a/trunk/arch/powerpc/platforms/512x/clock.c +++ b/trunk/arch/powerpc/platforms/512x/clock.c @@ -54,14 +54,16 @@ static DEFINE_MUTEX(clocks_mutex); static struct clk *mpc5121_clk_get(struct device *dev, const char *id) { struct clk *p, *clk = ERR_PTR(-ENOENT); - int dev_match = 0; - int id_match = 0; + int dev_match; + int id_match; if (dev == NULL || id == NULL) return clk; mutex_lock(&clocks_mutex); list_for_each_entry(p, &clocks, node) { + dev_match = id_match = 0; + if (dev == p->dev) dev_match++; if (strcmp(id, p->name) == 0) diff --git a/trunk/arch/powerpc/platforms/85xx/Kconfig b/trunk/arch/powerpc/platforms/85xx/Kconfig index 02d02a09942d..159c01e91463 100644 --- a/trunk/arch/powerpc/platforms/85xx/Kconfig +++ b/trunk/arch/powerpc/platforms/85xx/Kconfig @@ -104,13 +104,6 @@ config P1022_DS help This option enables support for the Freescale P1022DS reference board. -config P1022_RDK - bool "Freescale / iVeia P1022 RDK" - select DEFAULT_UIMAGE - help - This option enables support for the Freescale / iVeia P1022RDK - reference board. - config P1023_RDS bool "Freescale P1023 RDS" select DEFAULT_UIMAGE @@ -261,20 +254,6 @@ config P5020_DS help This option enables support for the P5020 DS board -config P5040_DS - bool "Freescale P5040 DS" - select DEFAULT_UIMAGE - select E500 - select PPC_E500MC - select PHYS_64BIT - select SWIOTLB - select ARCH_REQUIRE_GPIOLIB - select GPIO_MPC8XXX - select HAS_RAPIDIO - select PPC_EPAPR_HV_PIC - help - This option enables support for the P5040 DS board - config PPC_QEMU_E500 bool "QEMU generic e500 platform" depends on EXPERIMENTAL diff --git a/trunk/arch/powerpc/platforms/85xx/Makefile b/trunk/arch/powerpc/platforms/85xx/Makefile index 76f679cb04a0..3dfe81175036 100644 --- a/trunk/arch/powerpc/platforms/85xx/Makefile +++ b/trunk/arch/powerpc/platforms/85xx/Makefile @@ -15,13 +15,11 @@ obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o obj-$(CONFIG_MPC85xx_RDB) += mpc85xx_rdb.o obj-$(CONFIG_P1010_RDB) += p1010rdb.o obj-$(CONFIG_P1022_DS) += p1022_ds.o -obj-$(CONFIG_P1022_RDK) += p1022_rdk.o obj-$(CONFIG_P1023_RDS) += p1023_rds.o obj-$(CONFIG_P2041_RDB) += p2041_rdb.o corenet_ds.o obj-$(CONFIG_P3041_DS) += p3041_ds.o corenet_ds.o obj-$(CONFIG_P4080_DS) += p4080_ds.o corenet_ds.o obj-$(CONFIG_P5020_DS) += p5020_ds.o corenet_ds.o -obj-$(CONFIG_P5040_DS) += p5040_ds.o corenet_ds.o obj-$(CONFIG_STX_GP3) += stx_gp3.o obj-$(CONFIG_TQM85xx) += tqm85xx.o obj-$(CONFIG_SBC8548) += sbc8548.o diff --git a/trunk/arch/powerpc/platforms/85xx/common.c b/trunk/arch/powerpc/platforms/85xx/common.c index d0861a0d8360..67dac22b4363 100644 --- a/trunk/arch/powerpc/platforms/85xx/common.c +++ b/trunk/arch/powerpc/platforms/85xx/common.c @@ -27,16 +27,6 @@ static struct of_device_id __initdata mpc85xx_common_ids[] = { { .compatible = "fsl,mpc8548-guts", }, /* Probably unnecessary? */ { .compatible = "gpio-leds", }, - /* For all PCI controllers */ - { .compatible = "fsl,mpc8540-pci", }, - { .compatible = "fsl,mpc8548-pcie", }, - { .compatible = "fsl,p1022-pcie", }, - { .compatible = "fsl,p1010-pcie", }, - { .compatible = "fsl,p1023-pcie", }, - { .compatible = "fsl,p4080-pcie", }, - { .compatible = "fsl,qoriq-pcie-v2.4", }, - { .compatible = "fsl,qoriq-pcie-v2.3", }, - { .compatible = "fsl,qoriq-pcie-v2.2", }, {}, }; diff --git a/trunk/arch/powerpc/platforms/85xx/corenet_ds.c b/trunk/arch/powerpc/platforms/85xx/corenet_ds.c index ed69c9250717..925b02874233 100644 --- a/trunk/arch/powerpc/platforms/85xx/corenet_ds.c +++ b/trunk/arch/powerpc/platforms/85xx/corenet_ds.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -51,16 +52,37 @@ void __init corenet_ds_pic_init(void) */ void __init corenet_ds_setup_arch(void) { +#ifdef CONFIG_PCI + struct device_node *np; + struct pci_controller *hose; +#endif + dma_addr_t max = 0xffffffff; + mpc85xx_smp_init(); -#if defined(CONFIG_PCI) && defined(CONFIG_PPC64) +#ifdef CONFIG_PCI + for_each_node_by_type(np, "pci") { + if (of_device_is_compatible(np, "fsl,p4080-pcie") || + of_device_is_compatible(np, "fsl,qoriq-pcie-v2.2")) { + fsl_add_bridge(np, 0); + hose = pci_find_hose_for_OF_device(np); + max = min(max, hose->dma_window_base_cur + + hose->dma_window_size); + } + } + +#ifdef CONFIG_PPC64 pci_devs_phb_init(); #endif +#endif - fsl_pci_assign_primary(); - - swiotlb_detect_4g(); - +#ifdef CONFIG_SWIOTLB + if ((memblock_end_of_DRAM() - 1) > max) { + ppc_swiotlb_enable = 1; + set_pci_dma_ops(&swiotlb_dma_ops); + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; + } +#endif pr_info("%s board from Freescale Semiconductor\n", ppc_md.name); } @@ -77,12 +99,6 @@ static const struct of_device_id of_device_ids[] __devinitconst = { { .compatible = "fsl,qoriq-pcie-v2.2", }, - { - .compatible = "fsl,qoriq-pcie-v2.3", - }, - { - .compatible = "fsl,qoriq-pcie-v2.4", - }, /* The following two are for the Freescale hypervisor */ { .name = "hypervisor", diff --git a/trunk/arch/powerpc/platforms/85xx/ge_imp3a.c b/trunk/arch/powerpc/platforms/85xx/ge_imp3a.c index e6285ae6f423..b6a728b0a8ca 100644 --- a/trunk/arch/powerpc/platforms/85xx/ge_imp3a.c +++ b/trunk/arch/powerpc/platforms/85xx/ge_imp3a.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -83,39 +84,53 @@ void __init ge_imp3a_pic_init(void) of_node_put(cascade_node); } -static void ge_imp3a_pci_assign_primary(void) +#ifdef CONFIG_PCI +static int primary_phb_addr; +#endif /* CONFIG_PCI */ + +/* + * Setup the architecture + */ +static void __init ge_imp3a_setup_arch(void) { + struct device_node *regs; #ifdef CONFIG_PCI struct device_node *np; - struct resource rsrc; + struct pci_controller *hose; +#endif + dma_addr_t max = 0xffffffff; + if (ppc_md.progress) + ppc_md.progress("ge_imp3a_setup_arch()", 0); + +#ifdef CONFIG_PCI for_each_node_by_type(np, "pci") { if (of_device_is_compatible(np, "fsl,mpc8540-pci") || of_device_is_compatible(np, "fsl,mpc8548-pcie") || of_device_is_compatible(np, "fsl,p2020-pcie")) { + struct resource rsrc; of_address_to_resource(np, 0, &rsrc); - if ((rsrc.start & 0xfffff) == 0x9000) - fsl_pci_primary = np; + if ((rsrc.start & 0xfffff) == primary_phb_addr) + fsl_add_bridge(np, 1); + else + fsl_add_bridge(np, 0); + + hose = pci_find_hose_for_OF_device(np); + max = min(max, hose->dma_window_base_cur + + hose->dma_window_size); } } #endif -} - -/* - * Setup the architecture - */ -static void __init ge_imp3a_setup_arch(void) -{ - struct device_node *regs; - - if (ppc_md.progress) - ppc_md.progress("ge_imp3a_setup_arch()", 0); mpc85xx_smp_init(); - ge_imp3a_pci_assign_primary(); - - swiotlb_detect_4g(); +#ifdef CONFIG_SWIOTLB + if ((memblock_end_of_DRAM() - 1) > max) { + ppc_swiotlb_enable = 1; + set_pci_dma_ops(&swiotlb_dma_ops); + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; + } +#endif /* Remap basic board registers */ regs = of_find_compatible_node(NULL, NULL, "ge,imp3a-fpga-regs"); @@ -200,10 +215,17 @@ static int __init ge_imp3a_probe(void) { unsigned long root = of_get_flat_dt_root(); - return of_flat_dt_is_compatible(root, "ge,IMP3A"); + if (of_flat_dt_is_compatible(root, "ge,IMP3A")) { +#ifdef CONFIG_PCI + primary_phb_addr = 0x9000; +#endif + return 1; + } + + return 0; } -machine_arch_initcall(ge_imp3a, mpc85xx_common_publish_devices); +machine_device_initcall(ge_imp3a, mpc85xx_common_publish_devices); machine_arch_initcall(ge_imp3a, swiotlb_setup_bus_notifier); diff --git a/trunk/arch/powerpc/platforms/85xx/mpc8536_ds.c b/trunk/arch/powerpc/platforms/85xx/mpc8536_ds.c index 15ce4b55f117..767c7cf18a9c 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc8536_ds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc8536_ds.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -45,17 +46,46 @@ void __init mpc8536_ds_pic_init(void) */ static void __init mpc8536_ds_setup_arch(void) { +#ifdef CONFIG_PCI + struct device_node *np; + struct pci_controller *hose; +#endif + dma_addr_t max = 0xffffffff; + if (ppc_md.progress) ppc_md.progress("mpc8536_ds_setup_arch()", 0); - fsl_pci_assign_primary(); +#ifdef CONFIG_PCI + for_each_node_by_type(np, "pci") { + if (of_device_is_compatible(np, "fsl,mpc8540-pci") || + of_device_is_compatible(np, "fsl,mpc8548-pcie")) { + struct resource rsrc; + of_address_to_resource(np, 0, &rsrc); + if ((rsrc.start & 0xfffff) == 0x8000) + fsl_add_bridge(np, 1); + else + fsl_add_bridge(np, 0); + + hose = pci_find_hose_for_OF_device(np); + max = min(max, hose->dma_window_base_cur + + hose->dma_window_size); + } + } + +#endif - swiotlb_detect_4g(); +#ifdef CONFIG_SWIOTLB + if ((memblock_end_of_DRAM() - 1) > max) { + ppc_swiotlb_enable = 1; + set_pci_dma_ops(&swiotlb_dma_ops); + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; + } +#endif printk("MPC8536 DS board from Freescale Semiconductor\n"); } -machine_arch_initcall(mpc8536_ds, mpc85xx_common_publish_devices); +machine_device_initcall(mpc8536_ds, mpc85xx_common_publish_devices); machine_arch_initcall(mpc8536_ds, swiotlb_setup_bus_notifier); diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c index 7d12a19aa7ee..29ee8fcd75a2 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ads.c @@ -137,6 +137,10 @@ static void __init init_ioports(void) static void __init mpc85xx_ads_setup_arch(void) { +#ifdef CONFIG_PCI + struct device_node *np; +#endif + if (ppc_md.progress) ppc_md.progress("mpc85xx_ads_setup_arch()", 0); @@ -146,10 +150,11 @@ static void __init mpc85xx_ads_setup_arch(void) #endif #ifdef CONFIG_PCI + for_each_compatible_node(np, "pci", "fsl,mpc8540-pci") + fsl_add_bridge(np, 1); + ppc_md.pci_exclude_device = mpc85xx_exclude_device; #endif - - fsl_pci_assign_primary(); } static void mpc85xx_ads_show_cpuinfo(struct seq_file *m) @@ -168,7 +173,7 @@ static void mpc85xx_ads_show_cpuinfo(struct seq_file *m) seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); } -machine_arch_initcall(mpc85xx_ads, mpc85xx_common_publish_devices); +machine_device_initcall(mpc85xx_ads, mpc85xx_common_publish_devices); /* * Called very early, device-tree isn't unflattened diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c index c474505ad0d0..11156fb53d83 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_cds.c @@ -276,33 +276,6 @@ machine_device_initcall(mpc85xx_cds, mpc85xx_cds_8259_attach); #endif /* CONFIG_PPC_I8259 */ -static void mpc85xx_cds_pci_assign_primary(void) -{ -#ifdef CONFIG_PCI - struct device_node *np; - - if (fsl_pci_primary) - return; - - /* - * MPC85xx_CDS has ISA bridge but unfortunately there is no - * isa node in device tree. We now looking for i8259 node as - * a workaround for such a broken device tree. This routine - * is for complying to all device trees. - */ - np = of_find_node_by_name(NULL, "i8259"); - while ((fsl_pci_primary = of_get_parent(np))) { - of_node_put(np); - np = fsl_pci_primary; - - if ((of_device_is_compatible(np, "fsl,mpc8540-pci") || - of_device_is_compatible(np, "fsl,mpc8548-pcie")) && - of_device_is_available(np)) - return; - } -#endif -} - /* * Setup the architecture */ @@ -336,12 +309,21 @@ static void __init mpc85xx_cds_setup_arch(void) } #ifdef CONFIG_PCI + for_each_node_by_type(np, "pci") { + if (of_device_is_compatible(np, "fsl,mpc8540-pci") || + of_device_is_compatible(np, "fsl,mpc8548-pcie")) { + struct resource rsrc; + of_address_to_resource(np, 0, &rsrc); + if ((rsrc.start & 0xfffff) == 0x8000) + fsl_add_bridge(np, 1); + else + fsl_add_bridge(np, 0); + } + } + ppc_md.pci_irq_fixup = mpc85xx_cds_pci_irq_fixup; ppc_md.pci_exclude_device = mpc85xx_exclude_device; #endif - - mpc85xx_cds_pci_assign_primary(); - fsl_pci_assign_primary(); } static void mpc85xx_cds_show_cpuinfo(struct seq_file *m) @@ -373,7 +355,7 @@ static int __init mpc85xx_cds_probe(void) return of_flat_dt_is_compatible(root, "MPC85xxCDS"); } -machine_arch_initcall(mpc85xx_cds, mpc85xx_common_publish_devices); +machine_device_initcall(mpc85xx_cds, mpc85xx_common_publish_devices); define_machine(mpc85xx_cds) { .name = "MPC85xx CDS", diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ds.c index 9ebb91ed96a3..6d3265fe7718 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_ds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_ds.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -128,11 +129,13 @@ static int mpc85xx_exclude_device(struct pci_controller *hose, } #endif /* CONFIG_PCI */ -static void __init mpc85xx_ds_uli_init(void) +static void __init mpc85xx_ds_pci_init(void) { #ifdef CONFIG_PCI struct device_node *node; + fsl_pci_init(); + /* See if we have a ULI under the primary */ node = of_find_node_by_name(NULL, "uli1575"); @@ -156,9 +159,7 @@ static void __init mpc85xx_ds_setup_arch(void) if (ppc_md.progress) ppc_md.progress("mpc85xx_ds_setup_arch()", 0); - swiotlb_detect_4g(); - fsl_pci_assign_primary(); - mpc85xx_ds_uli_init(); + mpc85xx_ds_pci_init(); mpc85xx_smp_init(); printk("MPC85xx DS board from Freescale Semiconductor\n"); @@ -174,9 +175,9 @@ static int __init mpc8544_ds_probe(void) return !!of_flat_dt_is_compatible(root, "MPC8544DS"); } -machine_arch_initcall(mpc8544_ds, mpc85xx_common_publish_devices); -machine_arch_initcall(mpc8572_ds, mpc85xx_common_publish_devices); -machine_arch_initcall(p2020_ds, mpc85xx_common_publish_devices); +machine_device_initcall(mpc8544_ds, mpc85xx_common_publish_devices); +machine_device_initcall(mpc8572_ds, mpc85xx_common_publish_devices); +machine_device_initcall(p2020_ds, mpc85xx_common_publish_devices); machine_arch_initcall(mpc8544_ds, swiotlb_setup_bus_notifier); machine_arch_initcall(mpc8572_ds, swiotlb_setup_bus_notifier); diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c index 8498f7323470..8e4b094c553b 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_mds.c @@ -327,16 +327,44 @@ static void __init mpc85xx_mds_qeic_init(void) { } static void __init mpc85xx_mds_setup_arch(void) { +#ifdef CONFIG_PCI + struct pci_controller *hose; + struct device_node *np; +#endif + dma_addr_t max = 0xffffffff; + if (ppc_md.progress) ppc_md.progress("mpc85xx_mds_setup_arch()", 0); +#ifdef CONFIG_PCI + for_each_node_by_type(np, "pci") { + if (of_device_is_compatible(np, "fsl,mpc8540-pci") || + of_device_is_compatible(np, "fsl,mpc8548-pcie")) { + struct resource rsrc; + of_address_to_resource(np, 0, &rsrc); + if ((rsrc.start & 0xfffff) == 0x8000) + fsl_add_bridge(np, 1); + else + fsl_add_bridge(np, 0); + + hose = pci_find_hose_for_OF_device(np); + max = min(max, hose->dma_window_base_cur + + hose->dma_window_size); + } + } +#endif + mpc85xx_smp_init(); mpc85xx_mds_qe_init(); - fsl_pci_assign_primary(); - - swiotlb_detect_4g(); +#ifdef CONFIG_SWIOTLB + if ((memblock_end_of_DRAM() - 1) > max) { + ppc_swiotlb_enable = 1; + set_pci_dma_ops(&swiotlb_dma_ops); + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; + } +#endif } @@ -381,9 +409,9 @@ static int __init mpc85xx_publish_devices(void) return mpc85xx_common_publish_devices(); } -machine_arch_initcall(mpc8568_mds, mpc85xx_publish_devices); -machine_arch_initcall(mpc8569_mds, mpc85xx_publish_devices); -machine_arch_initcall(p1021_mds, mpc85xx_common_publish_devices); +machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices); +machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices); +machine_device_initcall(p1021_mds, mpc85xx_common_publish_devices); machine_arch_initcall(mpc8568_mds, swiotlb_setup_bus_notifier); machine_arch_initcall(mpc8569_mds, swiotlb_setup_bus_notifier); diff --git a/trunk/arch/powerpc/platforms/85xx/mpc85xx_rdb.c b/trunk/arch/powerpc/platforms/85xx/mpc85xx_rdb.c index ede8771d6f02..1910fdcb75b2 100644 --- a/trunk/arch/powerpc/platforms/85xx/mpc85xx_rdb.c +++ b/trunk/arch/powerpc/platforms/85xx/mpc85xx_rdb.c @@ -86,16 +86,22 @@ void __init mpc85xx_rdb_pic_init(void) */ static void __init mpc85xx_rdb_setup_arch(void) { -#ifdef CONFIG_QUICC_ENGINE +#if defined(CONFIG_PCI) || defined(CONFIG_QUICC_ENGINE) struct device_node *np; #endif if (ppc_md.progress) ppc_md.progress("mpc85xx_rdb_setup_arch()", 0); - mpc85xx_smp_init(); +#ifdef CONFIG_PCI + for_each_node_by_type(np, "pci") { + if (of_device_is_compatible(np, "fsl,mpc8548-pcie")) + fsl_add_bridge(np, 0); + } - fsl_pci_assign_primary(); +#endif + + mpc85xx_smp_init(); #ifdef CONFIG_QUICC_ENGINE np = of_find_compatible_node(NULL, NULL, "fsl,qe"); @@ -155,15 +161,15 @@ static void __init mpc85xx_rdb_setup_arch(void) printk(KERN_INFO "MPC85xx RDB board from Freescale Semiconductor\n"); } -machine_arch_initcall(p2020_rdb, mpc85xx_common_publish_devices); -machine_arch_initcall(p2020_rdb_pc, mpc85xx_common_publish_devices); -machine_arch_initcall(p1020_mbg_pc, mpc85xx_common_publish_devices); -machine_arch_initcall(p1020_rdb, mpc85xx_common_publish_devices); -machine_arch_initcall(p1020_rdb_pc, mpc85xx_common_publish_devices); -machine_arch_initcall(p1020_utm_pc, mpc85xx_common_publish_devices); -machine_arch_initcall(p1021_rdb_pc, mpc85xx_common_publish_devices); -machine_arch_initcall(p1025_rdb, mpc85xx_common_publish_devices); -machine_arch_initcall(p1024_rdb, mpc85xx_common_publish_devices); +machine_device_initcall(p2020_rdb, mpc85xx_common_publish_devices); +machine_device_initcall(p2020_rdb_pc, mpc85xx_common_publish_devices); +machine_device_initcall(p1020_mbg_pc, mpc85xx_common_publish_devices); +machine_device_initcall(p1020_rdb, mpc85xx_common_publish_devices); +machine_device_initcall(p1020_rdb_pc, mpc85xx_common_publish_devices); +machine_device_initcall(p1020_utm_pc, mpc85xx_common_publish_devices); +machine_device_initcall(p1021_rdb_pc, mpc85xx_common_publish_devices); +machine_device_initcall(p1025_rdb, mpc85xx_common_publish_devices); +machine_device_initcall(p1024_rdb, mpc85xx_common_publish_devices); /* * Called very early, device-tree isn't unflattened diff --git a/trunk/arch/powerpc/platforms/85xx/p1010rdb.c b/trunk/arch/powerpc/platforms/85xx/p1010rdb.c index 0252961392d5..dbaf44354f0d 100644 --- a/trunk/arch/powerpc/platforms/85xx/p1010rdb.c +++ b/trunk/arch/powerpc/platforms/85xx/p1010rdb.c @@ -46,15 +46,25 @@ void __init p1010_rdb_pic_init(void) */ static void __init p1010_rdb_setup_arch(void) { +#ifdef CONFIG_PCI + struct device_node *np; +#endif + if (ppc_md.progress) ppc_md.progress("p1010_rdb_setup_arch()", 0); - fsl_pci_assign_primary(); +#ifdef CONFIG_PCI + for_each_node_by_type(np, "pci") { + if (of_device_is_compatible(np, "fsl,p1010-pcie")) + fsl_add_bridge(np, 0); + } + +#endif printk(KERN_INFO "P1010 RDB board from Freescale Semiconductor\n"); } -machine_arch_initcall(p1010_rdb, mpc85xx_common_publish_devices); +machine_device_initcall(p1010_rdb, mpc85xx_common_publish_devices); machine_arch_initcall(p1010_rdb, swiotlb_setup_bus_notifier); /* diff --git a/trunk/arch/powerpc/platforms/85xx/p1022_ds.c b/trunk/arch/powerpc/platforms/85xx/p1022_ds.c index 848a3e98e1c1..3c732acf331d 100644 --- a/trunk/arch/powerpc/platforms/85xx/p1022_ds.c +++ b/trunk/arch/powerpc/platforms/85xx/p1022_ds.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -506,9 +507,32 @@ early_param("video", early_video_setup); */ static void __init p1022_ds_setup_arch(void) { +#ifdef CONFIG_PCI + struct device_node *np; +#endif + dma_addr_t max = 0xffffffff; + if (ppc_md.progress) ppc_md.progress("p1022_ds_setup_arch()", 0); +#ifdef CONFIG_PCI + for_each_compatible_node(np, "pci", "fsl,p1022-pcie") { + struct resource rsrc; + struct pci_controller *hose; + + of_address_to_resource(np, 0, &rsrc); + + if ((rsrc.start & 0xfffff) == 0x8000) + fsl_add_bridge(np, 1); + else + fsl_add_bridge(np, 0); + + hose = pci_find_hose_for_OF_device(np); + max = min(max, hose->dma_window_base_cur + + hose->dma_window_size); + } +#endif + #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) diu_ops.get_pixel_format = p1022ds_get_pixel_format; diu_ops.set_gamma_table = p1022ds_set_gamma_table; @@ -577,14 +601,18 @@ static void __init p1022_ds_setup_arch(void) mpc85xx_smp_init(); - fsl_pci_assign_primary(); - - swiotlb_detect_4g(); +#ifdef CONFIG_SWIOTLB + if ((memblock_end_of_DRAM() - 1) > max) { + ppc_swiotlb_enable = 1; + set_pci_dma_ops(&swiotlb_dma_ops); + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; + } +#endif pr_info("Freescale P1022 DS reference board\n"); } -machine_arch_initcall(p1022_ds, mpc85xx_common_publish_devices); +machine_device_initcall(p1022_ds, mpc85xx_common_publish_devices); machine_arch_initcall(p1022_ds, swiotlb_setup_bus_notifier); diff --git a/trunk/arch/powerpc/platforms/85xx/p1022_rdk.c b/trunk/arch/powerpc/platforms/85xx/p1022_rdk.c deleted file mode 100644 index 55ffa1cc380c..000000000000 --- a/trunk/arch/powerpc/platforms/85xx/p1022_rdk.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * P1022 RDK board specific routines - * - * Copyright 2012 Freescale Semiconductor, Inc. - * - * Author: Timur Tabi - * - * Based on p1022_ds.c - * - * This file is licensed under the terms of the GNU General Public License - * version 2. This program is licensed "as is" without any warranty of any - * kind, whether express or implied. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include "smp.h" - -#include "mpc85xx.h" - -#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) - -/* DIU Pixel Clock bits of the CLKDVDR Global Utilities register */ -#define CLKDVDR_PXCKEN 0x80000000 -#define CLKDVDR_PXCKINV 0x10000000 -#define CLKDVDR_PXCKDLY 0x06000000 -#define CLKDVDR_PXCLK_MASK 0x00FF0000 - -/** - * p1022rdk_set_monitor_port: switch the output to a different monitor port - */ -static void p1022rdk_set_monitor_port(enum fsl_diu_monitor_port port) -{ - if (port != FSL_DIU_PORT_DVI) { - pr_err("p1022rdk: unsupported monitor port %i\n", port); - return; - } -} - -/** - * p1022rdk_set_pixel_clock: program the DIU's clock - * - * @pixclock: the wavelength, in picoseconds, of the clock - */ -void p1022rdk_set_pixel_clock(unsigned int pixclock) -{ - struct device_node *guts_np = NULL; - struct ccsr_guts __iomem *guts; - unsigned long freq; - u64 temp; - u32 pxclk; - - /* Map the global utilities registers. */ - guts_np = of_find_compatible_node(NULL, NULL, "fsl,p1022-guts"); - if (!guts_np) { - pr_err("p1022rdk: missing global utilties device node\n"); - return; - } - - guts = of_iomap(guts_np, 0); - of_node_put(guts_np); - if (!guts) { - pr_err("p1022rdk: could not map global utilties device\n"); - return; - } - - /* Convert pixclock from a wavelength to a frequency */ - temp = 1000000000000ULL; - do_div(temp, pixclock); - freq = temp; - - /* - * 'pxclk' is the ratio of the platform clock to the pixel clock. - * This number is programmed into the CLKDVDR register, and the valid - * range of values is 2-255. - */ - pxclk = DIV_ROUND_CLOSEST(fsl_get_sys_freq(), freq); - pxclk = clamp_t(u32, pxclk, 2, 255); - - /* Disable the pixel clock, and set it to non-inverted and no delay */ - clrbits32(&guts->clkdvdr, - CLKDVDR_PXCKEN | CLKDVDR_PXCKDLY | CLKDVDR_PXCLK_MASK); - - /* Enable the clock and set the pxclk */ - setbits32(&guts->clkdvdr, CLKDVDR_PXCKEN | (pxclk << 16)); - - iounmap(guts); -} - -/** - * p1022rdk_valid_monitor_port: set the monitor port for sysfs - */ -enum fsl_diu_monitor_port -p1022rdk_valid_monitor_port(enum fsl_diu_monitor_port port) -{ - return FSL_DIU_PORT_DVI; -} - -#endif - -void __init p1022_rdk_pic_init(void) -{ - struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | - MPIC_SINGLE_DEST_CPU, - 0, 256, " OpenPIC "); - BUG_ON(mpic == NULL); - mpic_init(mpic); -} - -/* - * Setup the architecture - */ -static void __init p1022_rdk_setup_arch(void) -{ - if (ppc_md.progress) - ppc_md.progress("p1022_rdk_setup_arch()", 0); - -#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) - diu_ops.set_monitor_port = p1022rdk_set_monitor_port; - diu_ops.set_pixel_clock = p1022rdk_set_pixel_clock; - diu_ops.valid_monitor_port = p1022rdk_valid_monitor_port; -#endif - - mpc85xx_smp_init(); - - fsl_pci_assign_primary(); - - swiotlb_detect_4g(); - - pr_info("Freescale / iVeia P1022 RDK reference board\n"); -} - -machine_arch_initcall(p1022_rdk, mpc85xx_common_publish_devices); - -machine_arch_initcall(p1022_rdk, swiotlb_setup_bus_notifier); - -/* - * Called very early, device-tree isn't unflattened - */ -static int __init p1022_rdk_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); - - return of_flat_dt_is_compatible(root, "fsl,p1022rdk"); -} - -define_machine(p1022_rdk) { - .name = "P1022 RDK", - .probe = p1022_rdk_probe, - .setup_arch = p1022_rdk_setup_arch, - .init_IRQ = p1022_rdk_pic_init, -#ifdef CONFIG_PCI - .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -#endif - .get_irq = mpic_get_irq, - .restart = fsl_rstcr_restart, - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, -}; diff --git a/trunk/arch/powerpc/platforms/85xx/p1023_rds.c b/trunk/arch/powerpc/platforms/85xx/p1023_rds.c index 9cc60a738834..2990e8b13dc9 100644 --- a/trunk/arch/powerpc/platforms/85xx/p1023_rds.c +++ b/trunk/arch/powerpc/platforms/85xx/p1023_rds.c @@ -80,12 +80,15 @@ static void __init mpc85xx_rds_setup_arch(void) } } - mpc85xx_smp_init(); +#ifdef CONFIG_PCI + for_each_compatible_node(np, "pci", "fsl,p1023-pcie") + fsl_add_bridge(np, 0); +#endif - fsl_pci_assign_primary(); + mpc85xx_smp_init(); } -machine_arch_initcall(p1023_rds, mpc85xx_common_publish_devices); +machine_device_initcall(p1023_rds, mpc85xx_common_publish_devices); static void __init mpc85xx_rds_pic_init(void) { diff --git a/trunk/arch/powerpc/platforms/85xx/p2041_rdb.c b/trunk/arch/powerpc/platforms/85xx/p2041_rdb.c index 000c0892fc40..6541fa2630c0 100644 --- a/trunk/arch/powerpc/platforms/85xx/p2041_rdb.c +++ b/trunk/arch/powerpc/platforms/85xx/p2041_rdb.c @@ -80,7 +80,7 @@ define_machine(p2041_rdb) { .power_save = e500_idle, }; -machine_arch_initcall(p2041_rdb, corenet_ds_publish_devices); +machine_device_initcall(p2041_rdb, corenet_ds_publish_devices); #ifdef CONFIG_SWIOTLB machine_arch_initcall(p2041_rdb, swiotlb_setup_bus_notifier); diff --git a/trunk/arch/powerpc/platforms/85xx/p3041_ds.c b/trunk/arch/powerpc/platforms/85xx/p3041_ds.c index b3edc205daa9..f238efa75891 100644 --- a/trunk/arch/powerpc/platforms/85xx/p3041_ds.c +++ b/trunk/arch/powerpc/platforms/85xx/p3041_ds.c @@ -82,7 +82,7 @@ define_machine(p3041_ds) { .power_save = e500_idle, }; -machine_arch_initcall(p3041_ds, corenet_ds_publish_devices); +machine_device_initcall(p3041_ds, corenet_ds_publish_devices); #ifdef CONFIG_SWIOTLB machine_arch_initcall(p3041_ds, swiotlb_setup_bus_notifier); diff --git a/trunk/arch/powerpc/platforms/85xx/p4080_ds.c b/trunk/arch/powerpc/platforms/85xx/p4080_ds.c index 54df10632aea..c92417dc6574 100644 --- a/trunk/arch/powerpc/platforms/85xx/p4080_ds.c +++ b/trunk/arch/powerpc/platforms/85xx/p4080_ds.c @@ -81,7 +81,7 @@ define_machine(p4080_ds) { .power_save = e500_idle, }; -machine_arch_initcall(p4080_ds, corenet_ds_publish_devices); +machine_device_initcall(p4080_ds, corenet_ds_publish_devices); #ifdef CONFIG_SWIOTLB machine_arch_initcall(p4080_ds, swiotlb_setup_bus_notifier); #endif diff --git a/trunk/arch/powerpc/platforms/85xx/p5020_ds.c b/trunk/arch/powerpc/platforms/85xx/p5020_ds.c index 753a42c29d4d..17bef15a85ed 100644 --- a/trunk/arch/powerpc/platforms/85xx/p5020_ds.c +++ b/trunk/arch/powerpc/platforms/85xx/p5020_ds.c @@ -91,7 +91,7 @@ define_machine(p5020_ds) { #endif }; -machine_arch_initcall(p5020_ds, corenet_ds_publish_devices); +machine_device_initcall(p5020_ds, corenet_ds_publish_devices); #ifdef CONFIG_SWIOTLB machine_arch_initcall(p5020_ds, swiotlb_setup_bus_notifier); diff --git a/trunk/arch/powerpc/platforms/85xx/p5040_ds.c b/trunk/arch/powerpc/platforms/85xx/p5040_ds.c deleted file mode 100644 index 11381851828e..000000000000 --- a/trunk/arch/powerpc/platforms/85xx/p5040_ds.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * P5040 DS Setup - * - * Copyright 2009-2010 Freescale Semiconductor Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include - -#include "corenet_ds.h" - -/* - * Called very early, device-tree isn't unflattened - */ -static int __init p5040_ds_probe(void) -{ - unsigned long root = of_get_flat_dt_root(); -#ifdef CONFIG_SMP - extern struct smp_ops_t smp_85xx_ops; -#endif - - if (of_flat_dt_is_compatible(root, "fsl,P5040DS")) - return 1; - - /* Check if we're running under the Freescale hypervisor */ - if (of_flat_dt_is_compatible(root, "fsl,P5040DS-hv")) { - ppc_md.init_IRQ = ehv_pic_init; - ppc_md.get_irq = ehv_pic_get_irq; - ppc_md.restart = fsl_hv_restart; - ppc_md.power_off = fsl_hv_halt; - ppc_md.halt = fsl_hv_halt; -#ifdef CONFIG_SMP - /* - * Disable the timebase sync operations because we can't write - * to the timebase registers under the hypervisor. - */ - smp_85xx_ops.give_timebase = NULL; - smp_85xx_ops.take_timebase = NULL; -#endif - return 1; - } - - return 0; -} - -define_machine(p5040_ds) { - .name = "P5040 DS", - .probe = p5040_ds_probe, - .setup_arch = corenet_ds_setup_arch, - .init_IRQ = corenet_ds_pic_init, -#ifdef CONFIG_PCI - .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -#endif -/* coreint doesn't play nice with lazy EE, use legacy mpic for now */ -#ifdef CONFIG_PPC64 - .get_irq = mpic_get_irq, -#else - .get_irq = mpic_get_coreint_irq, -#endif - .restart = fsl_rstcr_restart, - .calibrate_decr = generic_calibrate_decr, - .progress = udbg_progress, -#ifdef CONFIG_PPC64 - .power_save = book3e_idle, -#else - .power_save = e500_idle, -#endif -}; - -machine_arch_initcall(p5040_ds, corenet_ds_publish_devices); - -#ifdef CONFIG_SWIOTLB -machine_arch_initcall(p5040_ds, swiotlb_setup_bus_notifier); -#endif diff --git a/trunk/arch/powerpc/platforms/85xx/qemu_e500.c b/trunk/arch/powerpc/platforms/85xx/qemu_e500.c index f6ea5618c733..95a2e53af71b 100644 --- a/trunk/arch/powerpc/platforms/85xx/qemu_e500.c +++ b/trunk/arch/powerpc/platforms/85xx/qemu_e500.c @@ -41,8 +41,7 @@ static void __init qemu_e500_setup_arch(void) { ppc_md.progress("qemu_e500_setup_arch()", 0); - fsl_pci_assign_primary(); - swiotlb_detect_4g(); + fsl_pci_init(); mpc85xx_smp_init(); } @@ -56,7 +55,7 @@ static int __init qemu_e500_probe(void) return !!of_flat_dt_is_compatible(root, "fsl,qemu-e500"); } -machine_arch_initcall(qemu_e500, mpc85xx_common_publish_devices); +machine_device_initcall(qemu_e500, mpc85xx_common_publish_devices); define_machine(qemu_e500) { .name = "QEMU e500", diff --git a/trunk/arch/powerpc/platforms/85xx/sbc8548.c b/trunk/arch/powerpc/platforms/85xx/sbc8548.c index f62121825914..cd3a66bdb54b 100644 --- a/trunk/arch/powerpc/platforms/85xx/sbc8548.c +++ b/trunk/arch/powerpc/platforms/85xx/sbc8548.c @@ -88,11 +88,26 @@ static int __init sbc8548_hw_rev(void) */ static void __init sbc8548_setup_arch(void) { +#ifdef CONFIG_PCI + struct device_node *np; +#endif + if (ppc_md.progress) ppc_md.progress("sbc8548_setup_arch()", 0); - fsl_pci_assign_primary(); - +#ifdef CONFIG_PCI + for_each_node_by_type(np, "pci") { + if (of_device_is_compatible(np, "fsl,mpc8540-pci") || + of_device_is_compatible(np, "fsl,mpc8548-pcie")) { + struct resource rsrc; + of_address_to_resource(np, 0, &rsrc); + if ((rsrc.start & 0xfffff) == 0x8000) + fsl_add_bridge(np, 1); + else + fsl_add_bridge(np, 0); + } + } +#endif sbc_rev = sbc8548_hw_rev(); } @@ -113,7 +128,7 @@ static void sbc8548_show_cpuinfo(struct seq_file *m) seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); } -machine_arch_initcall(sbc8548, mpc85xx_common_publish_devices); +machine_device_initcall(sbc8548, mpc85xx_common_publish_devices); /* * Called very early, device-tree isn't unflattened diff --git a/trunk/arch/powerpc/platforms/85xx/smp.c b/trunk/arch/powerpc/platforms/85xx/smp.c index 6fcfa12e5c56..ff4249044a3c 100644 --- a/trunk/arch/powerpc/platforms/85xx/smp.c +++ b/trunk/arch/powerpc/platforms/85xx/smp.c @@ -2,7 +2,7 @@ * Author: Andy Fleming * Kumar Gala * - * Copyright 2006-2008, 2011-2012 Freescale Semiconductor Inc. + * Copyright 2006-2008, 2011 Freescale Semiconductor Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -17,7 +17,6 @@ #include #include #include -#include #include #include @@ -25,118 +24,33 @@ #include #include #include -#include #include #include #include "smp.h" -struct epapr_spin_table { - u32 addr_h; - u32 addr_l; - u32 r3_h; - u32 r3_l; - u32 reserved; - u32 pir; -}; - -static struct ccsr_guts __iomem *guts; -static u64 timebase; -static int tb_req; -static int tb_valid; - -static void mpc85xx_timebase_freeze(int freeze) -{ - uint32_t mask; - - mask = CCSR_GUTS_DEVDISR_TB0 | CCSR_GUTS_DEVDISR_TB1; - if (freeze) - setbits32(&guts->devdisr, mask); - else - clrbits32(&guts->devdisr, mask); - - in_be32(&guts->devdisr); -} - -static void mpc85xx_give_timebase(void) -{ - unsigned long flags; - - local_irq_save(flags); - - while (!tb_req) - barrier(); - tb_req = 0; - - mpc85xx_timebase_freeze(1); - timebase = get_tb(); - mb(); - tb_valid = 1; - - while (tb_valid) - barrier(); - - mpc85xx_timebase_freeze(0); - - local_irq_restore(flags); -} - -static void mpc85xx_take_timebase(void) -{ - unsigned long flags; - - local_irq_save(flags); - - tb_req = 1; - while (!tb_valid) - barrier(); - - set_tb(timebase >> 32, timebase & 0xffffffff); - isync(); - tb_valid = 0; - - local_irq_restore(flags); -} - -#ifdef CONFIG_HOTPLUG_CPU -static void __cpuinit smp_85xx_mach_cpu_die(void) -{ - unsigned int cpu = smp_processor_id(); - u32 tmp; - - local_irq_disable(); - idle_task_exit(); - generic_set_cpu_dead(cpu); - mb(); - - mtspr(SPRN_TCR, 0); - - __flush_disable_L1(); - tmp = (mfspr(SPRN_HID0) & ~(HID0_DOZE|HID0_SLEEP)) | HID0_NAP; - mtspr(SPRN_HID0, tmp); - isync(); - - /* Enter NAP mode. */ - tmp = mfmsr(); - tmp |= MSR_WE; - mb(); - mtmsr(tmp); - isync(); - - while (1) - ; -} -#endif - -static int __cpuinit smp_85xx_kick_cpu(int nr) +extern void __early_start(void); + +#define BOOT_ENTRY_ADDR_UPPER 0 +#define BOOT_ENTRY_ADDR_LOWER 1 +#define BOOT_ENTRY_R3_UPPER 2 +#define BOOT_ENTRY_R3_LOWER 3 +#define BOOT_ENTRY_RESV 4 +#define BOOT_ENTRY_PIR 5 +#define BOOT_ENTRY_R6_UPPER 6 +#define BOOT_ENTRY_R6_LOWER 7 +#define NUM_BOOT_ENTRY 8 +#define SIZE_BOOT_ENTRY (NUM_BOOT_ENTRY * sizeof(u32)) + +static int __init +smp_85xx_kick_cpu(int nr) { unsigned long flags; const u64 *cpu_rel_addr; - __iomem struct epapr_spin_table *spin_table; + __iomem u32 *bptr_vaddr; struct device_node *np; - int hw_cpu = get_hard_smp_processor_id(nr); + int n = 0, hw_cpu = get_hard_smp_processor_id(nr); int ioremappable; - int ret = 0; WARN_ON(nr < 0 || nr >= NR_CPUS); WARN_ON(hw_cpu < 0 || hw_cpu >= NR_CPUS); @@ -161,81 +75,46 @@ static int __cpuinit smp_85xx_kick_cpu(int nr) /* Map the spin table */ if (ioremappable) - spin_table = ioremap(*cpu_rel_addr, - sizeof(struct epapr_spin_table)); + bptr_vaddr = ioremap(*cpu_rel_addr, SIZE_BOOT_ENTRY); else - spin_table = phys_to_virt(*cpu_rel_addr); + bptr_vaddr = phys_to_virt(*cpu_rel_addr); local_irq_save(flags); -#ifdef CONFIG_PPC32 -#ifdef CONFIG_HOTPLUG_CPU - /* Corresponding to generic_set_cpu_dead() */ - generic_set_cpu_up(nr); - - if (system_state == SYSTEM_RUNNING) { - out_be32(&spin_table->addr_l, 0); - - /* - * We don't set the BPTR register here since it already points - * to the boot page properly. - */ - mpic_reset_core(hw_cpu); - - /* wait until core is ready... */ - if (!spin_event_timeout(in_be32(&spin_table->addr_l) == 1, - 10000, 100)) { - pr_err("%s: timeout waiting for core %d to reset\n", - __func__, hw_cpu); - ret = -ENOENT; - goto out; - } - /* clear the acknowledge status */ - __secondary_hold_acknowledge = -1; - } -#endif - out_be32(&spin_table->pir, hw_cpu); - out_be32(&spin_table->addr_l, __pa(__early_start)); + out_be32(bptr_vaddr + BOOT_ENTRY_PIR, hw_cpu); +#ifdef CONFIG_PPC32 + out_be32(bptr_vaddr + BOOT_ENTRY_ADDR_LOWER, __pa(__early_start)); if (!ioremappable) - flush_dcache_range((ulong)spin_table, - (ulong)spin_table + sizeof(struct epapr_spin_table)); + flush_dcache_range((ulong)bptr_vaddr, + (ulong)(bptr_vaddr + SIZE_BOOT_ENTRY)); /* Wait a bit for the CPU to ack. */ - if (!spin_event_timeout(__secondary_hold_acknowledge == hw_cpu, - 10000, 100)) { - pr_err("%s: timeout waiting for core %d to ack\n", - __func__, hw_cpu); - ret = -ENOENT; - goto out; - } -out: + while ((__secondary_hold_acknowledge != hw_cpu) && (++n < 1000)) + mdelay(1); #else smp_generic_kick_cpu(nr); - out_be32(&spin_table->pir, hw_cpu); - out_be64((u64 *)(&spin_table->addr_h), - __pa((u64)*((unsigned long long *)generic_secondary_smp_init))); + out_be64((u64 *)(bptr_vaddr + BOOT_ENTRY_ADDR_UPPER), + __pa((u64)*((unsigned long long *) generic_secondary_smp_init))); if (!ioremappable) - flush_dcache_range((ulong)spin_table, - (ulong)spin_table + sizeof(struct epapr_spin_table)); + flush_dcache_range((ulong)bptr_vaddr, + (ulong)(bptr_vaddr + SIZE_BOOT_ENTRY)); #endif local_irq_restore(flags); if (ioremappable) - iounmap(spin_table); + iounmap(bptr_vaddr); + + pr_debug("waited %d msecs for CPU #%d.\n", n, nr); - return ret; + return 0; } struct smp_ops_t smp_85xx_ops = { .kick_cpu = smp_85xx_kick_cpu, -#ifdef CONFIG_HOTPLUG_CPU - .cpu_disable = generic_cpu_disable, - .cpu_die = generic_cpu_die, -#endif #ifdef CONFIG_KEXEC .give_timebase = smp_generic_give_timebase, .take_timebase = smp_generic_take_timebase, @@ -339,7 +218,8 @@ static void mpc85xx_smp_machine_kexec(struct kimage *image) } #endif /* CONFIG_KEXEC */ -static void __cpuinit smp_85xx_setup_cpu(int cpu_nr) +static void __init +smp_85xx_setup_cpu(int cpu_nr) { if (smp_85xx_ops.probe == smp_mpic_probe) mpic_setup_this_cpu(); @@ -348,16 +228,6 @@ static void __cpuinit smp_85xx_setup_cpu(int cpu_nr) doorbell_setup_this_cpu(); } -static const struct of_device_id mpc85xx_smp_guts_ids[] = { - { .compatible = "fsl,mpc8572-guts", }, - { .compatible = "fsl,p1020-guts", }, - { .compatible = "fsl,p1021-guts", }, - { .compatible = "fsl,p1022-guts", }, - { .compatible = "fsl,p1023-guts", }, - { .compatible = "fsl,p2020-guts", }, - {}, -}; - void __init mpc85xx_smp_init(void) { struct device_node *np; @@ -379,22 +249,6 @@ void __init mpc85xx_smp_init(void) smp_85xx_ops.cause_ipi = doorbell_cause_ipi; } - np = of_find_matching_node(NULL, mpc85xx_smp_guts_ids); - if (np) { - guts = of_iomap(np, 0); - of_node_put(np); - if (!guts) { - pr_err("%s: Could not map guts node address\n", - __func__); - return; - } - smp_85xx_ops.give_timebase = mpc85xx_give_timebase; - smp_85xx_ops.take_timebase = mpc85xx_take_timebase; -#ifdef CONFIG_HOTPLUG_CPU - ppc_md.cpu_die = smp_85xx_mach_cpu_die; -#endif - } - smp_ops = &smp_85xx_ops; #ifdef CONFIG_KEXEC diff --git a/trunk/arch/powerpc/platforms/85xx/socrates.c b/trunk/arch/powerpc/platforms/85xx/socrates.c index ae368e0e1076..b9c6daa07b66 100644 --- a/trunk/arch/powerpc/platforms/85xx/socrates.c +++ b/trunk/arch/powerpc/platforms/85xx/socrates.c @@ -66,13 +66,20 @@ static void __init socrates_pic_init(void) */ static void __init socrates_setup_arch(void) { +#ifdef CONFIG_PCI + struct device_node *np; +#endif + if (ppc_md.progress) ppc_md.progress("socrates_setup_arch()", 0); - fsl_pci_assign_primary(); +#ifdef CONFIG_PCI + for_each_compatible_node(np, "pci", "fsl,mpc8540-pci") + fsl_add_bridge(np, 1); +#endif } -machine_arch_initcall(socrates, mpc85xx_common_publish_devices); +machine_device_initcall(socrates, mpc85xx_common_publish_devices); /* * Called very early, device-tree isn't unflattened diff --git a/trunk/arch/powerpc/platforms/85xx/stx_gp3.c b/trunk/arch/powerpc/platforms/85xx/stx_gp3.c index 6f4939b6309e..e0508002b086 100644 --- a/trunk/arch/powerpc/platforms/85xx/stx_gp3.c +++ b/trunk/arch/powerpc/platforms/85xx/stx_gp3.c @@ -60,14 +60,21 @@ static void __init stx_gp3_pic_init(void) */ static void __init stx_gp3_setup_arch(void) { +#ifdef CONFIG_PCI + struct device_node *np; +#endif + if (ppc_md.progress) ppc_md.progress("stx_gp3_setup_arch()", 0); - fsl_pci_assign_primary(); - #ifdef CONFIG_CPM2 cpm2_reset(); #endif + +#ifdef CONFIG_PCI + for_each_compatible_node(np, "pci", "fsl,mpc8540-pci") + fsl_add_bridge(np, 1); +#endif } static void stx_gp3_show_cpuinfo(struct seq_file *m) @@ -86,7 +93,7 @@ static void stx_gp3_show_cpuinfo(struct seq_file *m) seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); } -machine_arch_initcall(stx_gp3, mpc85xx_common_publish_devices); +machine_device_initcall(stx_gp3, mpc85xx_common_publish_devices); /* * Called very early, device-tree isn't unflattened diff --git a/trunk/arch/powerpc/platforms/85xx/tqm85xx.c b/trunk/arch/powerpc/platforms/85xx/tqm85xx.c index d8941eea7075..3e70a2035e53 100644 --- a/trunk/arch/powerpc/platforms/85xx/tqm85xx.c +++ b/trunk/arch/powerpc/platforms/85xx/tqm85xx.c @@ -59,6 +59,10 @@ static void __init tqm85xx_pic_init(void) */ static void __init tqm85xx_setup_arch(void) { +#ifdef CONFIG_PCI + struct device_node *np; +#endif + if (ppc_md.progress) ppc_md.progress("tqm85xx_setup_arch()", 0); @@ -66,7 +70,20 @@ static void __init tqm85xx_setup_arch(void) cpm2_reset(); #endif - fsl_pci_assign_primary(); +#ifdef CONFIG_PCI + for_each_node_by_type(np, "pci") { + if (of_device_is_compatible(np, "fsl,mpc8540-pci") || + of_device_is_compatible(np, "fsl,mpc8548-pcie")) { + struct resource rsrc; + if (!of_address_to_resource(np, 0, &rsrc)) { + if ((rsrc.start & 0xfffff) == 0x8000) + fsl_add_bridge(np, 1); + else + fsl_add_bridge(np, 0); + } + } + } +#endif } static void tqm85xx_show_cpuinfo(struct seq_file *m) @@ -106,7 +123,7 @@ static void __devinit tqm85xx_ti1520_fixup(struct pci_dev *pdev) DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1520, tqm85xx_ti1520_fixup); -machine_arch_initcall(tqm85xx, mpc85xx_common_publish_devices); +machine_device_initcall(tqm85xx, mpc85xx_common_publish_devices); static const char *board[] __initdata = { "tqc,tqm8540", diff --git a/trunk/arch/powerpc/platforms/85xx/xes_mpc85xx.c b/trunk/arch/powerpc/platforms/85xx/xes_mpc85xx.c index dcbf7e42dce7..41c687550ea7 100644 --- a/trunk/arch/powerpc/platforms/85xx/xes_mpc85xx.c +++ b/trunk/arch/powerpc/platforms/85xx/xes_mpc85xx.c @@ -111,11 +111,18 @@ static void xes_mpc85xx_fixups(void) } } +#ifdef CONFIG_PCI +static int primary_phb_addr; +#endif + /* * Setup the architecture */ static void __init xes_mpc85xx_setup_arch(void) { +#ifdef CONFIG_PCI + struct device_node *np; +#endif struct device_node *root; const char *model = "Unknown"; @@ -130,14 +137,26 @@ static void __init xes_mpc85xx_setup_arch(void) xes_mpc85xx_fixups(); - mpc85xx_smp_init(); +#ifdef CONFIG_PCI + for_each_node_by_type(np, "pci") { + if (of_device_is_compatible(np, "fsl,mpc8540-pci") || + of_device_is_compatible(np, "fsl,mpc8548-pcie")) { + struct resource rsrc; + of_address_to_resource(np, 0, &rsrc); + if ((rsrc.start & 0xfffff) == primary_phb_addr) + fsl_add_bridge(np, 1); + else + fsl_add_bridge(np, 0); + } + } +#endif - fsl_pci_assign_primary(); + mpc85xx_smp_init(); } -machine_arch_initcall(xes_mpc8572, mpc85xx_common_publish_devices); -machine_arch_initcall(xes_mpc8548, mpc85xx_common_publish_devices); -machine_arch_initcall(xes_mpc8540, mpc85xx_common_publish_devices); +machine_device_initcall(xes_mpc8572, mpc85xx_common_publish_devices); +machine_device_initcall(xes_mpc8548, mpc85xx_common_publish_devices); +machine_device_initcall(xes_mpc8540, mpc85xx_common_publish_devices); /* * Called very early, device-tree isn't unflattened @@ -146,21 +165,42 @@ static int __init xes_mpc8572_probe(void) { unsigned long root = of_get_flat_dt_root(); - return of_flat_dt_is_compatible(root, "xes,MPC8572"); + if (of_flat_dt_is_compatible(root, "xes,MPC8572")) { +#ifdef CONFIG_PCI + primary_phb_addr = 0x8000; +#endif + return 1; + } else { + return 0; + } } static int __init xes_mpc8548_probe(void) { unsigned long root = of_get_flat_dt_root(); - return of_flat_dt_is_compatible(root, "xes,MPC8548"); + if (of_flat_dt_is_compatible(root, "xes,MPC8548")) { +#ifdef CONFIG_PCI + primary_phb_addr = 0xb000; +#endif + return 1; + } else { + return 0; + } } static int __init xes_mpc8540_probe(void) { unsigned long root = of_get_flat_dt_root(); - return of_flat_dt_is_compatible(root, "xes,MPC8540"); + if (of_flat_dt_is_compatible(root, "xes,MPC8540")) { +#ifdef CONFIG_PCI + primary_phb_addr = 0xb000; +#endif + return 1; + } else { + return 0; + } } define_machine(xes_mpc8572) { diff --git a/trunk/arch/powerpc/platforms/86xx/gef_ppc9a.c b/trunk/arch/powerpc/platforms/86xx/gef_ppc9a.c index bf5338754c5a..563aafa8629c 100644 --- a/trunk/arch/powerpc/platforms/86xx/gef_ppc9a.c +++ b/trunk/arch/powerpc/platforms/86xx/gef_ppc9a.c @@ -73,6 +73,13 @@ static void __init gef_ppc9a_init_irq(void) static void __init gef_ppc9a_setup_arch(void) { struct device_node *regs; +#ifdef CONFIG_PCI + struct device_node *np; + + for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") { + fsl_add_bridge(np, 1); + } +#endif printk(KERN_INFO "GE Intelligent Platforms PPC9A 6U VME SBC\n"); @@ -80,8 +87,6 @@ static void __init gef_ppc9a_setup_arch(void) mpc86xx_smp_init(); #endif - fsl_pci_assign_primary(); - /* Remap basic board registers */ regs = of_find_compatible_node(NULL, NULL, "gef,ppc9a-fpga-regs"); if (regs) { @@ -216,7 +221,6 @@ static long __init mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, { .compatible = "gianfar", }, - { .compatible = "fsl,mpc8641-pcie", }, {}, }; @@ -227,7 +231,7 @@ static int __init declare_of_platform_devices(void) return 0; } -machine_arch_initcall(gef_ppc9a, declare_of_platform_devices); +machine_device_initcall(gef_ppc9a, declare_of_platform_devices); define_machine(gef_ppc9a) { .name = "GE PPC9A", diff --git a/trunk/arch/powerpc/platforms/86xx/gef_sbc310.c b/trunk/arch/powerpc/platforms/86xx/gef_sbc310.c index 0b7851330a07..cc6a91ae0889 100644 --- a/trunk/arch/powerpc/platforms/86xx/gef_sbc310.c +++ b/trunk/arch/powerpc/platforms/86xx/gef_sbc310.c @@ -73,14 +73,20 @@ static void __init gef_sbc310_init_irq(void) static void __init gef_sbc310_setup_arch(void) { struct device_node *regs; +#ifdef CONFIG_PCI + struct device_node *np; + + for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") { + fsl_add_bridge(np, 1); + } +#endif + printk(KERN_INFO "GE Intelligent Platforms SBC310 6U VPX SBC\n"); #ifdef CONFIG_SMP mpc86xx_smp_init(); #endif - fsl_pci_assign_primary(); - /* Remap basic board registers */ regs = of_find_compatible_node(NULL, NULL, "gef,fpga-regs"); if (regs) { @@ -203,7 +209,6 @@ static long __init mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, { .compatible = "gianfar", }, - { .compatible = "fsl,mpc8641-pcie", }, {}, }; @@ -214,7 +219,7 @@ static int __init declare_of_platform_devices(void) return 0; } -machine_arch_initcall(gef_sbc310, declare_of_platform_devices); +machine_device_initcall(gef_sbc310, declare_of_platform_devices); define_machine(gef_sbc310) { .name = "GE SBC310", diff --git a/trunk/arch/powerpc/platforms/86xx/gef_sbc610.c b/trunk/arch/powerpc/platforms/86xx/gef_sbc610.c index b9eb174897b1..aead6b337f4a 100644 --- a/trunk/arch/powerpc/platforms/86xx/gef_sbc610.c +++ b/trunk/arch/powerpc/platforms/86xx/gef_sbc610.c @@ -73,6 +73,13 @@ static void __init gef_sbc610_init_irq(void) static void __init gef_sbc610_setup_arch(void) { struct device_node *regs; +#ifdef CONFIG_PCI + struct device_node *np; + + for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") { + fsl_add_bridge(np, 1); + } +#endif printk(KERN_INFO "GE Intelligent Platforms SBC610 6U VPX SBC\n"); @@ -80,8 +87,6 @@ static void __init gef_sbc610_setup_arch(void) mpc86xx_smp_init(); #endif - fsl_pci_assign_primary(); - /* Remap basic board registers */ regs = of_find_compatible_node(NULL, NULL, "gef,fpga-regs"); if (regs) { @@ -193,7 +198,6 @@ static long __init mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, { .compatible = "gianfar", }, - { .compatible = "fsl,mpc8641-pcie", }, {}, }; @@ -204,7 +208,7 @@ static int __init declare_of_platform_devices(void) return 0; } -machine_arch_initcall(gef_sbc610, declare_of_platform_devices); +machine_device_initcall(gef_sbc610, declare_of_platform_devices); define_machine(gef_sbc610) { .name = "GE SBC610", diff --git a/trunk/arch/powerpc/platforms/86xx/mpc8610_hpcd.c b/trunk/arch/powerpc/platforms/86xx/mpc8610_hpcd.c index a817398a56da..62cd3c555bfb 100644 --- a/trunk/arch/powerpc/platforms/86xx/mpc8610_hpcd.c +++ b/trunk/arch/powerpc/platforms/86xx/mpc8610_hpcd.c @@ -91,9 +91,6 @@ static struct of_device_id __initdata mpc8610_ids[] = { { .compatible = "simple-bus", }, /* So that the DMA channel nodes can be probed individually: */ { .compatible = "fsl,eloplus-dma", }, - /* PCI controllers */ - { .compatible = "fsl,mpc8610-pci", }, - { .compatible = "fsl,mpc8641-pcie", }, {} }; @@ -110,7 +107,7 @@ static int __init mpc8610_declare_of_platform_devices(void) return 0; } -machine_arch_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices); +machine_device_initcall(mpc86xx_hpcd, mpc8610_declare_of_platform_devices); #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) @@ -281,13 +278,25 @@ mpc8610hpcd_valid_monitor_port(enum fsl_diu_monitor_port port) static void __init mpc86xx_hpcd_setup_arch(void) { struct resource r; + struct device_node *np; unsigned char *pixis; if (ppc_md.progress) ppc_md.progress("mpc86xx_hpcd_setup_arch()", 0); - fsl_pci_assign_primary(); - +#ifdef CONFIG_PCI + for_each_node_by_type(np, "pci") { + if (of_device_is_compatible(np, "fsl,mpc8610-pci") + || of_device_is_compatible(np, "fsl,mpc8641-pcie")) { + struct resource rsrc; + of_address_to_resource(np, 0, &rsrc); + if ((rsrc.start & 0xfffff) == 0xa000) + fsl_add_bridge(np, 1); + else + fsl_add_bridge(np, 0); + } + } +#endif #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE) diu_ops.get_pixel_format = mpc8610hpcd_get_pixel_format; diu_ops.set_gamma_table = mpc8610hpcd_set_gamma_table; diff --git a/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index e8bf3fae5606..817245bc0219 100644 --- a/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -50,8 +51,15 @@ extern int uli_exclude_device(struct pci_controller *hose, static int mpc86xx_exclude_device(struct pci_controller *hose, u_char bus, u_char devfn) { - if (hose->dn == fsl_pci_primary) + struct device_node* node; + struct resource rsrc; + + node = hose->dn; + of_address_to_resource(node, 0, &rsrc); + + if ((rsrc.start & 0xfffff) == 0x8000) { return uli_exclude_device(hose, bus, devfn); + } return PCIBIOS_SUCCESSFUL; } @@ -61,11 +69,30 @@ static int mpc86xx_exclude_device(struct pci_controller *hose, static void __init mpc86xx_hpcn_setup_arch(void) { +#ifdef CONFIG_PCI + struct device_node *np; + struct pci_controller *hose; +#endif + dma_addr_t max = 0xffffffff; + if (ppc_md.progress) ppc_md.progress("mpc86xx_hpcn_setup_arch()", 0); #ifdef CONFIG_PCI + for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") { + struct resource rsrc; + of_address_to_resource(np, 0, &rsrc); + if ((rsrc.start & 0xfffff) == 0x8000) + fsl_add_bridge(np, 1); + else + fsl_add_bridge(np, 0); + hose = pci_find_hose_for_OF_device(np); + max = min(max, hose->dma_window_base_cur + + hose->dma_window_size); + } + ppc_md.pci_exclude_device = mpc86xx_exclude_device; + #endif printk("MPC86xx HPCN board from Freescale Semiconductor\n"); @@ -74,9 +101,13 @@ mpc86xx_hpcn_setup_arch(void) mpc86xx_smp_init(); #endif - fsl_pci_assign_primary(); - - swiotlb_detect_4g(); +#ifdef CONFIG_SWIOTLB + if ((memblock_end_of_DRAM() - 1) > max) { + ppc_swiotlb_enable = 1; + set_pci_dma_ops(&swiotlb_dma_ops); + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; + } +#endif } @@ -131,7 +162,6 @@ static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, { .compatible = "fsl,srio", }, { .compatible = "gianfar", }, - { .compatible = "fsl,mpc8641-pcie", }, {}, }; @@ -141,7 +171,7 @@ static int __init declare_of_platform_devices(void) return 0; } -machine_arch_initcall(mpc86xx_hpcn, declare_of_platform_devices); +machine_device_initcall(mpc86xx_hpcn, declare_of_platform_devices); machine_arch_initcall(mpc86xx_hpcn, swiotlb_setup_bus_notifier); define_machine(mpc86xx_hpcn) { diff --git a/trunk/arch/powerpc/platforms/86xx/sbc8641d.c b/trunk/arch/powerpc/platforms/86xx/sbc8641d.c index b47a8fd0f3d3..e7007d0d949e 100644 --- a/trunk/arch/powerpc/platforms/86xx/sbc8641d.c +++ b/trunk/arch/powerpc/platforms/86xx/sbc8641d.c @@ -38,16 +38,23 @@ static void __init sbc8641_setup_arch(void) { +#ifdef CONFIG_PCI + struct device_node *np; +#endif + if (ppc_md.progress) ppc_md.progress("sbc8641_setup_arch()", 0); +#ifdef CONFIG_PCI + for_each_compatible_node(np, "pci", "fsl,mpc8641-pcie") + fsl_add_bridge(np, 0); +#endif + printk("SBC8641 board from Wind River\n"); #ifdef CONFIG_SMP mpc86xx_smp_init(); #endif - - fsl_pci_assign_primary(); } @@ -95,7 +102,6 @@ mpc86xx_time_init(void) static __initdata struct of_device_id of_bus_ids[] = { { .compatible = "simple-bus", }, { .compatible = "gianfar", }, - { .compatible = "fsl,mpc8641-pcie", }, {}, }; @@ -105,7 +111,7 @@ static int __init declare_of_platform_devices(void) return 0; } -machine_arch_initcall(sbc8641, declare_of_platform_devices); +machine_device_initcall(sbc8641, declare_of_platform_devices); define_machine(sbc8641) { .name = "SBC8641D", diff --git a/trunk/arch/powerpc/platforms/cell/beat.c b/trunk/arch/powerpc/platforms/cell/beat.c index affcf566d460..852592b2b712 100644 --- a/trunk/arch/powerpc/platforms/cell/beat.c +++ b/trunk/arch/powerpc/platforms/cell/beat.c @@ -136,9 +136,9 @@ ssize_t beat_nvram_get_size(void) return BEAT_NVRAM_SIZE; } -int beat_set_xdabr(unsigned long dabr, unsigned long dabrx) +int beat_set_xdabr(unsigned long dabr) { - if (beat_set_dabr(dabr, dabrx)) + if (beat_set_dabr(dabr, DABRX_KERNEL | DABRX_USER)) return -1; return 0; } diff --git a/trunk/arch/powerpc/platforms/cell/beat.h b/trunk/arch/powerpc/platforms/cell/beat.h index bfcb8e351ae5..32c8efcedc80 100644 --- a/trunk/arch/powerpc/platforms/cell/beat.h +++ b/trunk/arch/powerpc/platforms/cell/beat.h @@ -32,7 +32,7 @@ void beat_get_rtc_time(struct rtc_time *); ssize_t beat_nvram_get_size(void); ssize_t beat_nvram_read(char *, size_t, loff_t *); ssize_t beat_nvram_write(char *, size_t, loff_t *); -int beat_set_xdabr(unsigned long, unsigned long); +int beat_set_xdabr(unsigned long); void beat_power_save(void); void beat_kexec_cpu_down(int, int); diff --git a/trunk/arch/powerpc/platforms/cell/beat_htab.c b/trunk/arch/powerpc/platforms/cell/beat_htab.c index 0f6f83988b3d..943c9d39aa16 100644 --- a/trunk/arch/powerpc/platforms/cell/beat_htab.c +++ b/trunk/arch/powerpc/platforms/cell/beat_htab.c @@ -88,7 +88,7 @@ static inline unsigned int beat_read_mask(unsigned hpte_group) } static long beat_lpar_hpte_insert(unsigned long hpte_group, - unsigned long vpn, unsigned long pa, + unsigned long va, unsigned long pa, unsigned long rflags, unsigned long vflags, int psize, int ssize) { @@ -103,7 +103,7 @@ static long beat_lpar_hpte_insert(unsigned long hpte_group, "rflags=%lx, vflags=%lx, psize=%d)\n", hpte_group, va, pa, rflags, vflags, psize); - hpte_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M) | + hpte_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M) | vflags | HPTE_V_VALID; hpte_r = hpte_encode_r(pa, psize) | rflags; @@ -184,14 +184,14 @@ static void beat_lpar_hptab_clear(void) */ static long beat_lpar_hpte_updatepp(unsigned long slot, unsigned long newpp, - unsigned long vpn, + unsigned long va, int psize, int ssize, int local) { unsigned long lpar_rc; u64 dummy0, dummy1; unsigned long want_v; - want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M); + want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); DBG_LOW(" update: " "avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ", @@ -220,15 +220,15 @@ static long beat_lpar_hpte_updatepp(unsigned long slot, return 0; } -static long beat_lpar_hpte_find(unsigned long vpn, int psize) +static long beat_lpar_hpte_find(unsigned long va, int psize) { unsigned long hash; unsigned long i, j; long slot; unsigned long want_v, hpte_v; - hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, MMU_SEGSIZE_256M); - want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M); + hash = hpt_hash(va, mmu_psize_defs[psize].shift, MMU_SEGSIZE_256M); + want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); for (j = 0; j < 2; j++) { slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; @@ -255,15 +255,14 @@ static void beat_lpar_hpte_updateboltedpp(unsigned long newpp, unsigned long ea, int psize, int ssize) { - unsigned long vpn; - unsigned long lpar_rc, slot, vsid; + unsigned long lpar_rc, slot, vsid, va; u64 dummy0, dummy1; vsid = get_kernel_vsid(ea, MMU_SEGSIZE_256M); - vpn = hpt_vpn(ea, vsid, MMU_SEGSIZE_256M); + va = (vsid << 28) | (ea & 0x0fffffff); raw_spin_lock(&beat_htab_lock); - slot = beat_lpar_hpte_find(vpn, psize); + slot = beat_lpar_hpte_find(va, psize); BUG_ON(slot == -1); lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7, @@ -273,7 +272,7 @@ static void beat_lpar_hpte_updateboltedpp(unsigned long newpp, BUG_ON(lpar_rc != 0); } -static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long vpn, +static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long va, int psize, int ssize, int local) { unsigned long want_v; @@ -283,7 +282,7 @@ static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long vpn, DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n", slot, va, psize, local); - want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M); + want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); raw_spin_lock_irqsave(&beat_htab_lock, flags); dummy1 = beat_lpar_hpte_getword0(slot); @@ -312,7 +311,7 @@ void __init hpte_init_beat(void) } static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, - unsigned long vpn, unsigned long pa, + unsigned long va, unsigned long pa, unsigned long rflags, unsigned long vflags, int psize, int ssize) { @@ -323,11 +322,11 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, return -1; if (!(vflags & HPTE_V_BOLTED)) - DBG_LOW("hpte_insert(group=%lx, vpn=%016lx, pa=%016lx, " + DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, " "rflags=%lx, vflags=%lx, psize=%d)\n", - hpte_group, vpn, pa, rflags, vflags, psize); + hpte_group, va, pa, rflags, vflags, psize); - hpte_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M) | + hpte_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M) | vflags | HPTE_V_VALID; hpte_r = hpte_encode_r(pa, psize) | rflags; @@ -365,14 +364,14 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, */ static long beat_lpar_hpte_updatepp_v3(unsigned long slot, unsigned long newpp, - unsigned long vpn, + unsigned long va, int psize, int ssize, int local) { unsigned long lpar_rc; unsigned long want_v; unsigned long pss; - want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M); + want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc; DBG_LOW(" update: " @@ -393,16 +392,16 @@ static long beat_lpar_hpte_updatepp_v3(unsigned long slot, return 0; } -static void beat_lpar_hpte_invalidate_v3(unsigned long slot, unsigned long vpn, +static void beat_lpar_hpte_invalidate_v3(unsigned long slot, unsigned long va, int psize, int ssize, int local) { unsigned long want_v; unsigned long lpar_rc; unsigned long pss; - DBG_LOW(" inval : slot=%lx, vpn=%016lx, psize: %d, local: %d\n", - slot, vpn, psize, local); - want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M); + DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n", + slot, va, psize, local); + want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc; lpar_rc = beat_invalidate_htab_entry3(0, slot, want_v, pss); diff --git a/trunk/arch/powerpc/platforms/pasemi/iommu.c b/trunk/arch/powerpc/platforms/pasemi/iommu.c index 7d2d036754b5..14943ef01918 100644 --- a/trunk/arch/powerpc/platforms/pasemi/iommu.c +++ b/trunk/arch/powerpc/platforms/pasemi/iommu.c @@ -19,12 +19,12 @@ #undef DEBUG -#include #include #include #include #include #include +#include #include #define IOBMAP_PAGE_SHIFT 12 @@ -99,7 +99,7 @@ static int iobmap_build(struct iommu_table *tbl, long index, ip = ((u32 *)tbl->it_base) + index; while (npages--) { - rpn = __pa(uaddr) >> IOBMAP_PAGE_SHIFT; + rpn = virt_to_abs(uaddr) >> IOBMAP_PAGE_SHIFT; *(ip++) = IOBMAP_L2E_V | rpn; /* invalidate tlb, can be optimized more */ @@ -258,7 +258,7 @@ void __init alloc_iobmap_l2(void) return; #endif /* For 2G space, 8x64 pages (2^21 bytes) is max total l2 size */ - iob_l2_base = (u32 *)__va(memblock_alloc_base(1UL<<21, 1UL<<21, 0x80000000)); + iob_l2_base = (u32 *)abs_to_virt(memblock_alloc_base(1UL<<21, 1UL<<21, 0x80000000)); printk(KERN_INFO "IOBMAP L2 allocated at: %p\n", iob_l2_base); } diff --git a/trunk/arch/powerpc/platforms/powernv/pci-ioda.c b/trunk/arch/powerpc/platforms/powernv/pci-ioda.c index 471aa3ccd9fd..9cda6a1ad0cf 100644 --- a/trunk/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/trunk/arch/powerpc/platforms/powernv/pci-ioda.c @@ -30,10 +30,19 @@ #include #include #include +#include #include "powernv.h" #include "pci.h" +struct resource_wrap { + struct list_head link; + resource_size_t size; + resource_size_t align; + struct pci_dev *dev; /* Set if it's a device */ + struct pci_bus *bus; /* Set if it's a bridge */ +}; + static int __pe_printk(const char *level, const struct pnv_ioda_pe *pe, struct va_format *vaf) { @@ -69,6 +78,273 @@ define_pe_printk_level(pe_err, KERN_ERR); define_pe_printk_level(pe_warn, KERN_WARNING); define_pe_printk_level(pe_info, KERN_INFO); + +/* Calculate resource usage & alignment requirement of a single + * device. This will also assign all resources within the device + * for a given type starting at 0 for the biggest one and then + * assigning in decreasing order of size. + */ +static void __devinit pnv_ioda_calc_dev(struct pci_dev *dev, unsigned int flags, + resource_size_t *size, + resource_size_t *align) +{ + resource_size_t start; + struct resource *r; + int i; + + pr_devel(" -> CDR %s\n", pci_name(dev)); + + *size = *align = 0; + + /* Clear the resources out and mark them all unset */ + for (i = 0; i <= PCI_ROM_RESOURCE; i++) { + r = &dev->resource[i]; + if (!(r->flags & flags)) + continue; + if (r->start) { + r->end -= r->start; + r->start = 0; + } + r->flags |= IORESOURCE_UNSET; + } + + /* We currently keep all memory resources together, we + * will handle prefetch & 64-bit separately in the future + * but for now we stick everybody in M32 + */ + start = 0; + for (;;) { + resource_size_t max_size = 0; + int max_no = -1; + + /* Find next biggest resource */ + for (i = 0; i <= PCI_ROM_RESOURCE; i++) { + r = &dev->resource[i]; + if (!(r->flags & IORESOURCE_UNSET) || + !(r->flags & flags)) + continue; + if (resource_size(r) > max_size) { + max_size = resource_size(r); + max_no = i; + } + } + if (max_no < 0) + break; + r = &dev->resource[max_no]; + if (max_size > *align) + *align = max_size; + *size += max_size; + r->start = start; + start += max_size; + r->end = r->start + max_size - 1; + r->flags &= ~IORESOURCE_UNSET; + pr_devel(" -> R%d %016llx..%016llx\n", + max_no, r->start, r->end); + } + pr_devel(" <- CDR %s size=%llx align=%llx\n", + pci_name(dev), *size, *align); +} + +/* Allocate a resource "wrap" for a given device or bridge and + * insert it at the right position in the sorted list + */ +static void __devinit pnv_ioda_add_wrap(struct list_head *list, + struct pci_bus *bus, + struct pci_dev *dev, + resource_size_t size, + resource_size_t align) +{ + struct resource_wrap *w1, *w = kzalloc(sizeof(*w), GFP_KERNEL); + + w->size = size; + w->align = align; + w->dev = dev; + w->bus = bus; + + list_for_each_entry(w1, list, link) { + if (w1->align < align) { + list_add_tail(&w->link, &w1->link); + return; + } + } + list_add_tail(&w->link, list); +} + +/* Offset device resources of a given type */ +static void __devinit pnv_ioda_offset_dev(struct pci_dev *dev, + unsigned int flags, + resource_size_t offset) +{ + struct resource *r; + int i; + + pr_devel(" -> ODR %s [%x] +%016llx\n", pci_name(dev), flags, offset); + + for (i = 0; i <= PCI_ROM_RESOURCE; i++) { + r = &dev->resource[i]; + if (r->flags & flags) { + dev->resource[i].start += offset; + dev->resource[i].end += offset; + } + } + + pr_devel(" <- ODR %s [%x] +%016llx\n", pci_name(dev), flags, offset); +} + +/* Offset bus resources (& all children) of a given type */ +static void __devinit pnv_ioda_offset_bus(struct pci_bus *bus, + unsigned int flags, + resource_size_t offset) +{ + struct resource *r; + struct pci_dev *dev; + struct pci_bus *cbus; + int i; + + pr_devel(" -> OBR %s [%x] +%016llx\n", + bus->self ? pci_name(bus->self) : "root", flags, offset); + + pci_bus_for_each_resource(bus, r, i) { + if (r && (r->flags & flags)) { + r->start += offset; + r->end += offset; + } + } + list_for_each_entry(dev, &bus->devices, bus_list) + pnv_ioda_offset_dev(dev, flags, offset); + list_for_each_entry(cbus, &bus->children, node) + pnv_ioda_offset_bus(cbus, flags, offset); + + pr_devel(" <- OBR %s [%x]\n", + bus->self ? pci_name(bus->self) : "root", flags); +} + +/* This is the guts of our IODA resource allocation. This is called + * recursively for each bus in the system. It calculates all the + * necessary size and requirements for children and assign them + * resources such that: + * + * - Each function fits in it's own contiguous set of IO/M32 + * segment + * + * - All segments behind a P2P bridge are contiguous and obey + * alignment constraints of those bridges + */ +static void __devinit pnv_ioda_calc_bus(struct pci_bus *bus, unsigned int flags, + resource_size_t *size, + resource_size_t *align) +{ + struct pci_controller *hose = pci_bus_to_host(bus); + struct pnv_phb *phb = hose->private_data; + resource_size_t dev_size, dev_align, start; + resource_size_t min_align, min_balign; + struct pci_dev *cdev; + struct pci_bus *cbus; + struct list_head head; + struct resource_wrap *w; + unsigned int bres; + + *size = *align = 0; + + pr_devel("-> CBR %s [%x]\n", + bus->self ? pci_name(bus->self) : "root", flags); + + /* Calculate alignment requirements based on the type + * of resource we are working on + */ + if (flags & IORESOURCE_IO) { + bres = 0; + min_align = phb->ioda.io_segsize; + min_balign = 0x1000; + } else { + bres = 1; + min_align = phb->ioda.m32_segsize; + min_balign = 0x100000; + } + + /* Gather all our children resources ordered by alignment */ + INIT_LIST_HEAD(&head); + + /* - Busses */ + list_for_each_entry(cbus, &bus->children, node) { + pnv_ioda_calc_bus(cbus, flags, &dev_size, &dev_align); + pnv_ioda_add_wrap(&head, cbus, NULL, dev_size, dev_align); + } + + /* - Devices */ + list_for_each_entry(cdev, &bus->devices, bus_list) { + pnv_ioda_calc_dev(cdev, flags, &dev_size, &dev_align); + /* Align them to segment size */ + if (dev_align < min_align) + dev_align = min_align; + pnv_ioda_add_wrap(&head, NULL, cdev, dev_size, dev_align); + } + if (list_empty(&head)) + goto empty; + + /* Now we can do two things: assign offsets to them within that + * level and get our total alignment & size requirements. The + * assignment algorithm is going to be uber-trivial for now, we + * can try to be smarter later at filling out holes. + */ + if (bus->self) { + /* No offset for downstream bridges */ + start = 0; + } else { + /* Offset from the root */ + if (flags & IORESOURCE_IO) + /* Don't hand out IO 0 */ + start = hose->io_resource.start + 0x1000; + else + start = hose->mem_resources[0].start; + } + while(!list_empty(&head)) { + w = list_first_entry(&head, struct resource_wrap, link); + list_del(&w->link); + if (w->size) { + if (start) { + start = ALIGN(start, w->align); + if (w->dev) + pnv_ioda_offset_dev(w->dev,flags,start); + else if (w->bus) + pnv_ioda_offset_bus(w->bus,flags,start); + } + if (w->align > *align) + *align = w->align; + } + start += w->size; + kfree(w); + } + *size = start; + + /* Align and setup bridge resources */ + *align = max_t(resource_size_t, *align, + max_t(resource_size_t, min_align, min_balign)); + *size = ALIGN(*size, + max_t(resource_size_t, min_align, min_balign)); + empty: + /* Only setup P2P's, not the PHB itself */ + if (bus->self) { + struct resource *res = bus->resource[bres]; + + if (WARN_ON(res == NULL)) + return; + + /* + * FIXME: We should probably export and call + * pci_bridge_check_ranges() to properly re-initialize + * the PCI portion of the flags here, and to detect + * what the bridge actually supports. + */ + res->start = 0; + res->flags = (*size) ? flags : 0; + res->end = (*size) ? (*size - 1) : 0; + } + + pr_devel("<- CBR %s [%x] *size=%016llx *align=%016llx\n", + bus->self ? pci_name(bus->self) : "root", flags,*size,*align); +} + static struct pci_dn *pnv_ioda_get_pdn(struct pci_dev *dev) { struct device_node *np; @@ -79,6 +355,172 @@ static struct pci_dn *pnv_ioda_get_pdn(struct pci_dev *dev) return PCI_DN(np); } +static void __devinit pnv_ioda_setup_pe_segments(struct pci_dev *dev) +{ + struct pci_controller *hose = pci_bus_to_host(dev->bus); + struct pnv_phb *phb = hose->private_data; + struct pci_dn *pdn = pnv_ioda_get_pdn(dev); + unsigned int pe, i; + resource_size_t pos; + struct resource io_res; + struct resource m32_res; + struct pci_bus_region region; + int rc; + + /* Anything not referenced in the device-tree gets PE#0 */ + pe = pdn ? pdn->pe_number : 0; + + /* Calculate the device min/max */ + io_res.start = m32_res.start = (resource_size_t)-1; + io_res.end = m32_res.end = 0; + io_res.flags = IORESOURCE_IO; + m32_res.flags = IORESOURCE_MEM; + + for (i = 0; i <= PCI_ROM_RESOURCE; i++) { + struct resource *r = NULL; + if (dev->resource[i].flags & IORESOURCE_IO) + r = &io_res; + if (dev->resource[i].flags & IORESOURCE_MEM) + r = &m32_res; + if (!r) + continue; + if (dev->resource[i].start < r->start) + r->start = dev->resource[i].start; + if (dev->resource[i].end > r->end) + r->end = dev->resource[i].end; + } + + /* Setup IO segments */ + if (io_res.start < io_res.end) { + pcibios_resource_to_bus(dev, ®ion, &io_res); + pos = region.start; + i = pos / phb->ioda.io_segsize; + while(i < phb->ioda.total_pe && pos <= region.end) { + if (phb->ioda.io_segmap[i]) { + pr_err("%s: Trying to use IO seg #%d which is" + " already used by PE# %d\n", + pci_name(dev), i, + phb->ioda.io_segmap[i]); + /* XXX DO SOMETHING TO DISABLE DEVICE ? */ + break; + } + phb->ioda.io_segmap[i] = pe; + rc = opal_pci_map_pe_mmio_window(phb->opal_id, pe, + OPAL_IO_WINDOW_TYPE, + 0, i); + if (rc != OPAL_SUCCESS) { + pr_err("%s: OPAL error %d setting up mapping" + " for IO seg# %d\n", + pci_name(dev), rc, i); + /* XXX DO SOMETHING TO DISABLE DEVICE ? */ + break; + } + pos += phb->ioda.io_segsize; + i++; + }; + } + + /* Setup M32 segments */ + if (m32_res.start < m32_res.end) { + pcibios_resource_to_bus(dev, ®ion, &m32_res); + pos = region.start; + i = pos / phb->ioda.m32_segsize; + while(i < phb->ioda.total_pe && pos <= region.end) { + if (phb->ioda.m32_segmap[i]) { + pr_err("%s: Trying to use M32 seg #%d which is" + " already used by PE# %d\n", + pci_name(dev), i, + phb->ioda.m32_segmap[i]); + /* XXX DO SOMETHING TO DISABLE DEVICE ? */ + break; + } + phb->ioda.m32_segmap[i] = pe; + rc = opal_pci_map_pe_mmio_window(phb->opal_id, pe, + OPAL_M32_WINDOW_TYPE, + 0, i); + if (rc != OPAL_SUCCESS) { + pr_err("%s: OPAL error %d setting up mapping" + " for M32 seg# %d\n", + pci_name(dev), rc, i); + /* XXX DO SOMETHING TO DISABLE DEVICE ? */ + break; + } + pos += phb->ioda.m32_segsize; + i++; + } + } +} + +/* Check if a resource still fits in the total IO or M32 range + * for a given PHB + */ +static int __devinit pnv_ioda_resource_fit(struct pci_controller *hose, + struct resource *r) +{ + struct resource *bounds; + + if (r->flags & IORESOURCE_IO) + bounds = &hose->io_resource; + else if (r->flags & IORESOURCE_MEM) + bounds = &hose->mem_resources[0]; + else + return 1; + + if (r->start >= bounds->start && r->end <= bounds->end) + return 1; + r->flags = 0; + return 0; +} + +static void __devinit pnv_ioda_update_resources(struct pci_bus *bus) +{ + struct pci_controller *hose = pci_bus_to_host(bus); + struct pci_bus *cbus; + struct pci_dev *cdev; + unsigned int i; + + /* We used to clear all device enables here. However it looks like + * clearing MEM enable causes Obsidian (IPR SCS) to go bonkers, + * and shoot fatal errors to the PHB which in turns fences itself + * and we can't recover from that ... yet. So for now, let's leave + * the enables as-is and hope for the best. + */ + + /* Check if bus resources fit in our IO or M32 range */ + for (i = 0; bus->self && (i < 2); i++) { + struct resource *r = bus->resource[i]; + if (r && !pnv_ioda_resource_fit(hose, r)) + pr_err("%s: Bus %d resource %d disabled, no room\n", + pci_name(bus->self), bus->number, i); + } + + /* Update self if it's not a PHB */ + if (bus->self) + pci_setup_bridge(bus); + + /* Update child devices */ + list_for_each_entry(cdev, &bus->devices, bus_list) { + /* Check if resource fits, if not, disabled it */ + for (i = 0; i <= PCI_ROM_RESOURCE; i++) { + struct resource *r = &cdev->resource[i]; + if (!pnv_ioda_resource_fit(hose, r)) + pr_err("%s: Resource %d disabled, no room\n", + pci_name(cdev), i); + } + + /* Assign segments */ + pnv_ioda_setup_pe_segments(cdev); + + /* Update HW BARs */ + for (i = 0; i <= PCI_ROM_RESOURCE; i++) + pci_update_resource(cdev, i); + } + + /* Update child busses */ + list_for_each_entry(cbus, &bus->children, node) + pnv_ioda_update_resources(cbus); +} + static int __devinit pnv_ioda_alloc_pe(struct pnv_phb *phb) { unsigned long pe; @@ -106,7 +548,7 @@ static void __devinit pnv_ioda_free_pe(struct pnv_phb *phb, int pe) * but in the meantime, we need to protect them to avoid warnings */ #ifdef CONFIG_PCI_MSI -static struct pnv_ioda_pe * __devinit pnv_ioda_get_pe(struct pci_dev *dev) +static struct pnv_ioda_pe * __devinit __pnv_ioda_get_one_pe(struct pci_dev *dev) { struct pci_controller *hose = pci_bus_to_host(dev->bus); struct pnv_phb *phb = hose->private_data; @@ -118,6 +560,19 @@ static struct pnv_ioda_pe * __devinit pnv_ioda_get_pe(struct pci_dev *dev) return NULL; return &phb->ioda.pe_array[pdn->pe_number]; } + +static struct pnv_ioda_pe * __devinit pnv_ioda_get_pe(struct pci_dev *dev) +{ + struct pnv_ioda_pe *pe = __pnv_ioda_get_one_pe(dev); + + while (!pe && dev->bus->self) { + dev = dev->bus->self; + pe = __pnv_ioda_get_one_pe(dev); + if (pe) + pe = pe->bus_pe; + } + return pe; +} #endif /* CONFIG_PCI_MSI */ static int __devinit pnv_ioda_configure_pe(struct pnv_phb *phb, @@ -134,11 +589,7 @@ static int __devinit pnv_ioda_configure_pe(struct pnv_phb *phb, dcomp = OPAL_IGNORE_RID_DEVICE_NUMBER; fcomp = OPAL_IGNORE_RID_FUNCTION_NUMBER; parent = pe->pbus->self; - if (pe->flags & PNV_IODA_PE_BUS_ALL) - count = pe->pbus->busn_res.end - pe->pbus->busn_res.start + 1; - else - count = 1; - + count = pe->pbus->busn_res.end - pe->pbus->busn_res.start + 1; switch(count) { case 1: bcomp = OpalPciBusAll; break; case 2: bcomp = OpalPciBus7Bits; break; @@ -215,13 +666,13 @@ static void __devinit pnv_ioda_link_pe_by_weight(struct pnv_phb *phb, { struct pnv_ioda_pe *lpe; - list_for_each_entry(lpe, &phb->ioda.pe_dma_list, dma_link) { + list_for_each_entry(lpe, &phb->ioda.pe_list, link) { if (lpe->dma_weight < pe->dma_weight) { - list_add_tail(&pe->dma_link, &lpe->dma_link); + list_add_tail(&pe->link, &lpe->link); return; } } - list_add_tail(&pe->dma_link, &phb->ioda.pe_dma_list); + list_add_tail(&pe->link, &phb->ioda.pe_list); } static unsigned int pnv_ioda_dma_weight(struct pci_dev *dev) @@ -248,7 +699,6 @@ static unsigned int pnv_ioda_dma_weight(struct pci_dev *dev) return 10; } -#if 0 static struct pnv_ioda_pe * __devinit pnv_ioda_setup_dev_PE(struct pci_dev *dev) { struct pci_controller *hose = pci_bus_to_host(dev->bus); @@ -317,7 +767,6 @@ static struct pnv_ioda_pe * __devinit pnv_ioda_setup_dev_PE(struct pci_dev *dev) return pe; } -#endif /* Useful for SRIOV case */ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe) { @@ -335,33 +784,34 @@ static void pnv_ioda_setup_same_PE(struct pci_bus *bus, struct pnv_ioda_pe *pe) pdn->pcidev = dev; pdn->pe_number = pe->pe_number; pe->dma_weight += pnv_ioda_dma_weight(dev); - if ((pe->flags & PNV_IODA_PE_BUS_ALL) && dev->subordinate) + if (dev->subordinate) pnv_ioda_setup_same_PE(dev->subordinate, pe); } } -/* - * There're 2 types of PCI bus sensitive PEs: One that is compromised of - * single PCI bus. Another one that contains the primary PCI bus and its - * subordinate PCI devices and buses. The second type of PE is normally - * orgiriated by PCIe-to-PCI bridge or PLX switch downstream ports. - */ -static void __devinit pnv_ioda_setup_bus_PE(struct pci_bus *bus, int all) +static void __devinit pnv_ioda_setup_bus_PE(struct pci_dev *dev, + struct pnv_ioda_pe *ppe) { - struct pci_controller *hose = pci_bus_to_host(bus); + struct pci_controller *hose = pci_bus_to_host(dev->bus); struct pnv_phb *phb = hose->private_data; + struct pci_bus *bus = dev->subordinate; struct pnv_ioda_pe *pe; int pe_num; + if (!bus) { + pr_warning("%s: Bridge without a subordinate bus !\n", + pci_name(dev)); + return; + } pe_num = pnv_ioda_alloc_pe(phb); if (pe_num == IODA_INVALID_PE) { - pr_warning("%s: Not enough PE# available for PCI bus %04x:%02x\n", - __func__, pci_domain_nr(bus), bus->number); + pr_warning("%s: Not enough PE# available, disabling bus\n", + pci_name(dev)); return; } pe = &phb->ioda.pe_array[pe_num]; - pe->flags = (all ? PNV_IODA_PE_BUS_ALL : PNV_IODA_PE_BUS); + ppe->bus_pe = pe; pe->pbus = bus; pe->pdev = NULL; pe->tce32_seg = -1; @@ -369,12 +819,8 @@ static void __devinit pnv_ioda_setup_bus_PE(struct pci_bus *bus, int all) pe->rid = bus->busn_res.start << 8; pe->dma_weight = 0; - if (all) - pe_info(pe, "Secondary bus %d..%d associated with PE#%d\n", - bus->busn_res.start, bus->busn_res.end, pe_num); - else - pe_info(pe, "Secondary bus %d associated with PE#%d\n", - bus->busn_res.start, pe_num); + pe_info(pe, "Secondary busses %pR associated with PE\n", + &bus->busn_res); if (pnv_ioda_configure_pe(phb, pe)) { /* XXX What do we do here ? */ @@ -387,9 +833,6 @@ static void __devinit pnv_ioda_setup_bus_PE(struct pci_bus *bus, int all) /* Associate it with all child devices */ pnv_ioda_setup_same_PE(bus, pe); - /* Put PE to the list */ - list_add_tail(&pe->list, &phb->ioda.pe_list); - /* Account for one DMA PE if at least one DMA capable device exist * below the bridge */ @@ -405,33 +848,17 @@ static void __devinit pnv_ioda_setup_bus_PE(struct pci_bus *bus, int all) static void __devinit pnv_ioda_setup_PEs(struct pci_bus *bus) { struct pci_dev *dev; - - pnv_ioda_setup_bus_PE(bus, 0); + struct pnv_ioda_pe *pe; list_for_each_entry(dev, &bus->devices, bus_list) { - if (dev->subordinate) { - if (pci_pcie_type(dev) == PCI_EXP_TYPE_PCI_BRIDGE) - pnv_ioda_setup_bus_PE(dev->subordinate, 1); - else - pnv_ioda_setup_PEs(dev->subordinate); - } - } -} - -/* - * Configure PEs so that the downstream PCI buses and devices - * could have their associated PE#. Unfortunately, we didn't - * figure out the way to identify the PLX bridge yet. So we - * simply put the PCI bus and the subordinate behind the root - * port to PE# here. The game rule here is expected to be changed - * as soon as we can detected PLX bridge correctly. - */ -static void __devinit pnv_pci_ioda_setup_PEs(void) -{ - struct pci_controller *hose, *tmp; - - list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { - pnv_ioda_setup_PEs(hose->bus); + pe = pnv_ioda_setup_dev_PE(dev); + if (pe == NULL) + continue; + /* Leaving the PCIe domain ... single PE# */ + if (dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) + pnv_ioda_setup_bus_PE(dev, pe); + else if (dev->subordinate) + pnv_ioda_setup_PEs(dev->subordinate); } } @@ -573,7 +1000,7 @@ static void __devinit pnv_ioda_setup_dma(struct pnv_phb *phb) remaining = phb->ioda.tce32_count; tw = phb->ioda.dma_weight; base = 0; - list_for_each_entry(pe, &phb->ioda.pe_dma_list, dma_link) { + list_for_each_entry(pe, &phb->ioda.pe_list, link) { if (!pe->dma_weight) continue; if (!remaining) { @@ -682,151 +1109,34 @@ static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) static void pnv_pci_init_ioda_msis(struct pnv_phb *phb) { } #endif /* CONFIG_PCI_MSI */ -/* - * This function is supposed to be called on basis of PE from top - * to bottom style. So the the I/O or MMIO segment assigned to - * parent PE could be overrided by its child PEs if necessary. +/* This is the starting point of our IODA specific resource + * allocation process */ -static void __devinit pnv_ioda_setup_pe_seg(struct pci_controller *hose, - struct pnv_ioda_pe *pe) -{ - struct pnv_phb *phb = hose->private_data; - struct pci_bus_region region; - struct resource *res; - int i, index; - int rc; - - /* - * NOTE: We only care PCI bus based PE for now. For PCI - * device based PE, for example SRIOV sensitive VF should - * be figured out later. - */ - BUG_ON(!(pe->flags & (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL))); - - pci_bus_for_each_resource(pe->pbus, res, i) { - if (!res || !res->flags || - res->start > res->end) - continue; - - if (res->flags & IORESOURCE_IO) { - region.start = res->start - phb->ioda.io_pci_base; - region.end = res->end - phb->ioda.io_pci_base; - index = region.start / phb->ioda.io_segsize; - - while (index < phb->ioda.total_pe && - region.start <= region.end) { - phb->ioda.io_segmap[index] = pe->pe_number; - rc = opal_pci_map_pe_mmio_window(phb->opal_id, - pe->pe_number, OPAL_IO_WINDOW_TYPE, 0, index); - if (rc != OPAL_SUCCESS) { - pr_err("%s: OPAL error %d when mapping IO " - "segment #%d to PE#%d\n", - __func__, rc, index, pe->pe_number); - break; - } - - region.start += phb->ioda.io_segsize; - index++; - } - } else if (res->flags & IORESOURCE_MEM) { - region.start = res->start - - hose->pci_mem_offset - - phb->ioda.m32_pci_base; - region.end = res->end - - hose->pci_mem_offset - - phb->ioda.m32_pci_base; - index = region.start / phb->ioda.m32_segsize; - - while (index < phb->ioda.total_pe && - region.start <= region.end) { - phb->ioda.m32_segmap[index] = pe->pe_number; - rc = opal_pci_map_pe_mmio_window(phb->opal_id, - pe->pe_number, OPAL_M32_WINDOW_TYPE, 0, index); - if (rc != OPAL_SUCCESS) { - pr_err("%s: OPAL error %d when mapping M32 " - "segment#%d to PE#%d", - __func__, rc, index, pe->pe_number); - break; - } - - region.start += phb->ioda.m32_segsize; - index++; - } - } - } -} - -static void __devinit pnv_pci_ioda_setup_seg(void) -{ - struct pci_controller *tmp, *hose; - struct pnv_phb *phb; - struct pnv_ioda_pe *pe; - - list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { - phb = hose->private_data; - list_for_each_entry(pe, &phb->ioda.pe_list, list) { - pnv_ioda_setup_pe_seg(hose, pe); - } - } -} - -static void __devinit pnv_pci_ioda_setup_DMA(void) +static void __devinit pnv_pci_ioda_fixup_phb(struct pci_controller *hose) { - struct pci_controller *hose, *tmp; - struct pnv_phb *phb; + resource_size_t size, align; + struct pci_bus *child; - list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { - pnv_ioda_setup_dma(hose->private_data); + /* Associate PEs per functions */ + pnv_ioda_setup_PEs(hose->bus); - /* Mark the PHB initialization done */ - phb = hose->private_data; - phb->initialized = 1; - } -} + /* Calculate all resources */ + pnv_ioda_calc_bus(hose->bus, IORESOURCE_IO, &size, &align); + pnv_ioda_calc_bus(hose->bus, IORESOURCE_MEM, &size, &align); -static void __devinit pnv_pci_ioda_fixup(void) -{ - pnv_pci_ioda_setup_PEs(); - pnv_pci_ioda_setup_seg(); - pnv_pci_ioda_setup_DMA(); -} + /* Apply then to HW */ + pnv_ioda_update_resources(hose->bus); -/* - * Returns the alignment for I/O or memory windows for P2P - * bridges. That actually depends on how PEs are segmented. - * For now, we return I/O or M32 segment size for PE sensitive - * P2P bridges. Otherwise, the default values (4KiB for I/O, - * 1MiB for memory) will be returned. - * - * The current PCI bus might be put into one PE, which was - * create against the parent PCI bridge. For that case, we - * needn't enlarge the alignment so that we can save some - * resources. - */ -static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus, - unsigned long type) -{ - struct pci_dev *bridge; - struct pci_controller *hose = pci_bus_to_host(bus); - struct pnv_phb *phb = hose->private_data; - int num_pci_bridges = 0; - - bridge = bus->self; - while (bridge) { - if (pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE) { - num_pci_bridges++; - if (num_pci_bridges >= 2) - return 1; - } + /* Setup DMA */ + pnv_ioda_setup_dma(hose->private_data); - bridge = bridge->bus->self; + /* Configure PCI Express settings */ + list_for_each_entry(child, &hose->bus->children, node) { + struct pci_dev *self = child->self; + if (!self) + continue; + pcie_bus_configure_settings(child, self->pcie_mpss); } - - /* We need support prefetchable memory window later */ - if (type & IORESOURCE_MEM) - return phb->ioda.m32_segsize; - - return phb->ioda.io_segsize; } /* Prevent enabling devices for which we couldn't properly @@ -834,22 +1144,10 @@ static resource_size_t pnv_pci_window_alignment(struct pci_bus *bus, */ static int __devinit pnv_pci_enable_device_hook(struct pci_dev *dev) { - struct pci_controller *hose = pci_bus_to_host(dev->bus); - struct pnv_phb *phb = hose->private_data; - struct pci_dn *pdn; - - /* The function is probably called while the PEs have - * not be created yet. For example, resource reassignment - * during PCI probe period. We just skip the check if - * PEs isn't ready. - */ - if (!phb->initialized) - return 0; + struct pci_dn *pdn = pnv_ioda_get_pdn(dev); - pdn = pnv_ioda_get_pdn(dev); if (!pdn || pdn->pe_number == IODA_INVALID_PE) return -EINVAL; - return 0; } @@ -940,9 +1238,9 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np) /* Allocate aux data & arrays */ size = _ALIGN_UP(phb->ioda.total_pe / 8, sizeof(unsigned long)); m32map_off = size; - size += phb->ioda.total_pe * sizeof(phb->ioda.m32_segmap[0]); + size += phb->ioda.total_pe; iomap_off = size; - size += phb->ioda.total_pe * sizeof(phb->ioda.io_segmap[0]); + size += phb->ioda.total_pe; pemap_off = size; size += phb->ioda.total_pe * sizeof(struct pnv_ioda_pe); aux = alloc_bootmem(size); @@ -953,7 +1251,6 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np) phb->ioda.pe_array = aux + pemap_off; set_bit(0, phb->ioda.pe_alloc); - INIT_LIST_HEAD(&phb->ioda.pe_dma_list); INIT_LIST_HEAD(&phb->ioda.pe_list); /* Calculate how many 32-bit TCE segments we have */ @@ -1002,17 +1299,14 @@ void __init pnv_pci_init_ioda1_phb(struct device_node *np) /* Setup MSI support */ pnv_pci_init_ioda_msis(phb); - /* - * We pass the PCI probe flag PCI_REASSIGN_ALL_RSRC here - * to let the PCI core do resource assignment. It's supposed - * that the PCI core will do correct I/O and MMIO alignment - * for the P2P bridge bars so that each PCI bus (excluding - * the child P2P bridges) can form individual PE. + /* We set both PCI_PROBE_ONLY and PCI_REASSIGN_ALL_RSRC. This is an + * odd combination which essentially means that we skip all resource + * fixups and assignments in the generic code, and do it all + * ourselves here */ - ppc_md.pcibios_fixup = pnv_pci_ioda_fixup; + ppc_md.pcibios_fixup_phb = pnv_pci_ioda_fixup_phb; ppc_md.pcibios_enable_device_hook = pnv_pci_enable_device_hook; - ppc_md.pcibios_window_alignment = pnv_pci_window_alignment; - pci_add_flags(PCI_REASSIGN_ALL_RSRC); + pci_add_flags(PCI_PROBE_ONLY | PCI_REASSIGN_ALL_RSRC); /* Reset IODA tables to a clean state */ rc = opal_pci_reset(phb_id, OPAL_PCI_IODA_TABLE_RESET, OPAL_ASSERT_RESET); diff --git a/trunk/arch/powerpc/platforms/powernv/pci-p5ioc2.c b/trunk/arch/powerpc/platforms/powernv/pci-p5ioc2.c index 6b4bef4e9d82..264967770c3a 100644 --- a/trunk/arch/powerpc/platforms/powernv/pci-p5ioc2.c +++ b/trunk/arch/powerpc/platforms/powernv/pci-p5ioc2.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "powernv.h" #include "pci.h" diff --git a/trunk/arch/powerpc/platforms/powernv/pci.c b/trunk/arch/powerpc/platforms/powernv/pci.c index c01688a1a741..be3cfc5ceabb 100644 --- a/trunk/arch/powerpc/platforms/powernv/pci.c +++ b/trunk/arch/powerpc/platforms/powernv/pci.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include "powernv.h" @@ -446,11 +447,6 @@ static void pnv_tce_free(struct iommu_table *tbl, long index, long npages) pnv_tce_invalidate(tbl, tces, tcep - 1); } -static unsigned long pnv_tce_get(struct iommu_table *tbl, long index) -{ - return ((u64 *)tbl->it_base)[index - tbl->it_offset]; -} - void pnv_pci_setup_iommu_table(struct iommu_table *tbl, void *tce_mem, u64 tce_size, u64 dma_offset) @@ -601,7 +597,6 @@ void __init pnv_pci_init(void) ppc_md.pci_dma_dev_setup = pnv_pci_dma_dev_setup; ppc_md.tce_build = pnv_tce_build; ppc_md.tce_free = pnv_tce_free; - ppc_md.tce_get = pnv_tce_get; ppc_md.pci_probe_mode = pnv_pci_probe_mode; set_pci_dma_ops(&dma_iommu_ops); diff --git a/trunk/arch/powerpc/platforms/powernv/pci.h b/trunk/arch/powerpc/platforms/powernv/pci.h index 7cfb7c883deb..8bc479634643 100644 --- a/trunk/arch/powerpc/platforms/powernv/pci.h +++ b/trunk/arch/powerpc/platforms/powernv/pci.h @@ -17,14 +17,9 @@ enum pnv_phb_model { }; #define PNV_PCI_DIAG_BUF_SIZE 4096 -#define PNV_IODA_PE_DEV (1 << 0) /* PE has single PCI device */ -#define PNV_IODA_PE_BUS (1 << 1) /* PE has primary PCI bus */ -#define PNV_IODA_PE_BUS_ALL (1 << 2) /* PE has subordinate buses */ /* Data associated with a PE, including IOMMU tracking etc.. */ struct pnv_ioda_pe { - unsigned long flags; - /* A PE can be associated with a single device or an * entire bus (& children). In the former case, pdev * is populated, in the later case, pbus is. @@ -45,6 +40,11 @@ struct pnv_ioda_pe { */ unsigned int dma_weight; + /* This is a PCI-E -> PCI-X bridge, this points to the + * corresponding bus PE + */ + struct pnv_ioda_pe *bus_pe; + /* "Base" iommu table, ie, 4K TCEs, 32-bit DMA */ int tce32_seg; int tce32_segcount; @@ -59,8 +59,7 @@ struct pnv_ioda_pe { int mve_number; /* Link in list of PE#s */ - struct list_head dma_link; - struct list_head list; + struct list_head link; }; struct pnv_phb { @@ -69,7 +68,6 @@ struct pnv_phb { enum pnv_phb_model model; u64 opal_id; void __iomem *regs; - int initialized; spinlock_t lock; #ifdef CONFIG_PCI_MSI @@ -109,11 +107,6 @@ struct pnv_phb { unsigned int *io_segmap; struct pnv_ioda_pe *pe_array; - /* Sorted list of used PE's based - * on the sequence of creation - */ - struct list_head pe_list; - /* Reverse map of PEs, will have to extend if * we are to support more than 256 PEs, indexed * bus { bus, devfn } @@ -132,7 +125,7 @@ struct pnv_phb { /* Sorted list of used PE's, sorted at * boot for resource allocation purposes */ - struct list_head pe_dma_list; + struct list_head pe_list; } ioda; }; diff --git a/trunk/arch/powerpc/platforms/ps3/htab.c b/trunk/arch/powerpc/platforms/ps3/htab.c index d00d7b0a3bda..3124cf791ebb 100644 --- a/trunk/arch/powerpc/platforms/ps3/htab.c +++ b/trunk/arch/powerpc/platforms/ps3/htab.c @@ -43,7 +43,7 @@ enum ps3_lpar_vas_id { static DEFINE_SPINLOCK(ps3_htab_lock); -static long ps3_hpte_insert(unsigned long hpte_group, unsigned long vpn, +static long ps3_hpte_insert(unsigned long hpte_group, unsigned long va, unsigned long pa, unsigned long rflags, unsigned long vflags, int psize, int ssize) { @@ -61,7 +61,7 @@ static long ps3_hpte_insert(unsigned long hpte_group, unsigned long vpn, */ vflags &= ~HPTE_V_SECONDARY; - hpte_v = hpte_encode_v(vpn, psize, ssize) | vflags | HPTE_V_VALID; + hpte_v = hpte_encode_v(va, psize, ssize) | vflags | HPTE_V_VALID; hpte_r = hpte_encode_r(ps3_mm_phys_to_lpar(pa), psize) | rflags; spin_lock_irqsave(&ps3_htab_lock, flags); @@ -75,8 +75,8 @@ static long ps3_hpte_insert(unsigned long hpte_group, unsigned long vpn, if (result) { /* all entries bolted !*/ - pr_info("%s:result=%d vpn=%lx pa=%lx ix=%lx v=%llx r=%llx\n", - __func__, result, vpn, pa, hpte_group, hpte_v, hpte_r); + pr_info("%s:result=%d va=%lx pa=%lx ix=%lx v=%llx r=%llx\n", + __func__, result, va, pa, hpte_group, hpte_v, hpte_r); BUG(); } @@ -107,7 +107,7 @@ static long ps3_hpte_remove(unsigned long hpte_group) } static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp, - unsigned long vpn, int psize, int ssize, int local) + unsigned long va, int psize, int ssize, int local) { int result; u64 hpte_v, want_v, hpte_rs; @@ -115,7 +115,7 @@ static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp, unsigned long flags; long ret; - want_v = hpte_encode_v(vpn, psize, ssize); + want_v = hpte_encode_v(va, psize, ssize); spin_lock_irqsave(&ps3_htab_lock, flags); @@ -125,8 +125,8 @@ static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp, &hpte_rs); if (result) { - pr_info("%s: res=%d read vpn=%lx slot=%lx psize=%d\n", - __func__, result, vpn, slot, psize); + pr_info("%s: res=%d read va=%lx slot=%lx psize=%d\n", + __func__, result, va, slot, psize); BUG(); } @@ -159,7 +159,7 @@ static void ps3_hpte_updateboltedpp(unsigned long newpp, unsigned long ea, panic("ps3_hpte_updateboltedpp() not implemented"); } -static void ps3_hpte_invalidate(unsigned long slot, unsigned long vpn, +static void ps3_hpte_invalidate(unsigned long slot, unsigned long va, int psize, int ssize, int local) { unsigned long flags; @@ -170,8 +170,8 @@ static void ps3_hpte_invalidate(unsigned long slot, unsigned long vpn, result = lv1_write_htab_entry(PS3_LPAR_VAS_ID_CURRENT, slot, 0, 0); if (result) { - pr_info("%s: res=%d vpn=%lx slot=%lx psize=%d\n", - __func__, result, vpn, slot, psize); + pr_info("%s: res=%d va=%lx slot=%lx psize=%d\n", + __func__, result, va, slot, psize); BUG(); } diff --git a/trunk/arch/powerpc/platforms/ps3/setup.c b/trunk/arch/powerpc/platforms/ps3/setup.c index 3f509f86432c..2d664c5a83b0 100644 --- a/trunk/arch/powerpc/platforms/ps3/setup.c +++ b/trunk/arch/powerpc/platforms/ps3/setup.c @@ -184,15 +184,11 @@ early_param("ps3flash", early_parse_ps3flash); #define prealloc_ps3flash_bounce_buffer() do { } while (0) #endif -static int ps3_set_dabr(unsigned long dabr, unsigned long dabrx) +static int ps3_set_dabr(unsigned long dabr) { - /* Have to set at least one bit in the DABRX */ - if (dabrx == 0 && dabr == 0) - dabrx = DABRX_USER; - /* hypervisor only allows us to set BTI, Kernel and user */ - dabrx &= DABRX_BTI | DABRX_KERNEL | DABRX_USER; + enum {DABR_USER = 1, DABR_KERNEL = 2,}; - return lv1_set_dabr(dabr, dabrx) ? -1 : 0; + return lv1_set_dabr(dabr, DABR_KERNEL | DABR_USER) ? -1 : 0; } static void __init ps3_setup_arch(void) diff --git a/trunk/arch/powerpc/platforms/pseries/Makefile b/trunk/arch/powerpc/platforms/pseries/Makefile index 890622b87c8f..c222189f5bb2 100644 --- a/trunk/arch/powerpc/platforms/pseries/Makefile +++ b/trunk/arch/powerpc/platforms/pseries/Makefile @@ -6,9 +6,8 @@ obj-y := lpar.o hvCall.o nvram.o reconfig.o \ firmware.o power.o dlpar.o mobility.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SCANLOG) += scanlog.o -obj-$(CONFIG_EEH) += eeh.o eeh_pe.o eeh_dev.o eeh_cache.o \ - eeh_driver.o eeh_event.o eeh_sysfs.o \ - eeh_pseries.o +obj-$(CONFIG_EEH) += eeh.o eeh_dev.o eeh_cache.o eeh_driver.o \ + eeh_event.o eeh_sysfs.o eeh_pseries.o obj-$(CONFIG_KEXEC) += kexec.o obj-$(CONFIG_PCI) += pci.o pci_dlpar.o obj-$(CONFIG_PSERIES_MSI) += msi.o diff --git a/trunk/arch/powerpc/platforms/pseries/eeh.c b/trunk/arch/powerpc/platforms/pseries/eeh.c index 9a04322b1736..ecd394cf34e6 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh.c @@ -92,20 +92,6 @@ struct eeh_ops *eeh_ops = NULL; int eeh_subsystem_enabled; EXPORT_SYMBOL(eeh_subsystem_enabled); -/* - * EEH probe mode support. The intention is to support multiple - * platforms for EEH. Some platforms like pSeries do PCI emunation - * based on device tree. However, other platforms like powernv probe - * PCI devices from hardware. The flag is used to distinguish that. - * In addition, struct eeh_ops::probe would be invoked for particular - * OF node or PCI device so that the corresponding PE would be created - * there. - */ -int eeh_probe_mode; - -/* Global EEH mutex */ -DEFINE_MUTEX(eeh_mutex); - /* Lock to avoid races due to multiple reports of an error */ static DEFINE_RAW_SPINLOCK(confirm_error_lock); @@ -218,12 +204,22 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len) } } + /* Gather status on devices under the bridge */ + if (dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) { + struct device_node *child; + + for_each_child_of_node(dn, child) { + if (of_node_to_eeh_dev(child)) + n += eeh_gather_pci_data(of_node_to_eeh_dev(child), buf+n, len-n); + } + } + return n; } /** * eeh_slot_error_detail - Generate combined log including driver log and error log - * @pe: EEH PE + * @edev: device to report error log for * @severity: temporary or permanent error log * * This routine should be called to generate the combined log, which @@ -231,22 +227,17 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char * buf, size_t len) * out from the config space of the corresponding PCI device, while * the error log is fetched through platform dependent function call. */ -void eeh_slot_error_detail(struct eeh_pe *pe, int severity) +void eeh_slot_error_detail(struct eeh_dev *edev, int severity) { size_t loglen = 0; - struct eeh_dev *edev; - - eeh_pci_enable(pe, EEH_OPT_THAW_MMIO); - eeh_ops->configure_bridge(pe); - eeh_pe_restore_bars(pe); - pci_regs_buf[0] = 0; - eeh_pe_for_each_dev(pe, edev) { - loglen += eeh_gather_pci_data(edev, pci_regs_buf, - EEH_PCI_REGS_LOG_LEN); - } - eeh_ops->get_log(pe, severity, pci_regs_buf, loglen); + eeh_pci_enable(edev, EEH_OPT_THAW_MMIO); + eeh_ops->configure_bridge(eeh_dev_to_of_node(edev)); + eeh_restore_bars(edev); + loglen = eeh_gather_pci_data(edev, pci_regs_buf, EEH_PCI_REGS_LOG_LEN); + + eeh_ops->get_log(eeh_dev_to_of_node(edev), severity, pci_regs_buf, loglen); } /** @@ -270,8 +261,126 @@ static inline unsigned long eeh_token_to_phys(unsigned long token) } /** - * eeh_dev_check_failure - Check if all 1's data is due to EEH slot freeze - * @edev: eeh device + * eeh_find_device_pe - Retrieve the PE for the given device + * @dn: device node + * + * Return the PE under which this device lies + */ +struct device_node *eeh_find_device_pe(struct device_node *dn) +{ + while (dn->parent && of_node_to_eeh_dev(dn->parent) && + (of_node_to_eeh_dev(dn->parent)->mode & EEH_MODE_SUPPORTED)) { + dn = dn->parent; + } + return dn; +} + +/** + * __eeh_mark_slot - Mark all child devices as failed + * @parent: parent device + * @mode_flag: failure flag + * + * Mark all devices that are children of this device as failed. + * Mark the device driver too, so that it can see the failure + * immediately; this is critical, since some drivers poll + * status registers in interrupts ... If a driver is polling, + * and the slot is frozen, then the driver can deadlock in + * an interrupt context, which is bad. + */ +static void __eeh_mark_slot(struct device_node *parent, int mode_flag) +{ + struct device_node *dn; + + for_each_child_of_node(parent, dn) { + if (of_node_to_eeh_dev(dn)) { + /* Mark the pci device driver too */ + struct pci_dev *dev = of_node_to_eeh_dev(dn)->pdev; + + of_node_to_eeh_dev(dn)->mode |= mode_flag; + + if (dev && dev->driver) + dev->error_state = pci_channel_io_frozen; + + __eeh_mark_slot(dn, mode_flag); + } + } +} + +/** + * eeh_mark_slot - Mark the indicated device and its children as failed + * @dn: parent device + * @mode_flag: failure flag + * + * Mark the indicated device and its child devices as failed. + * The device drivers are marked as failed as well. + */ +void eeh_mark_slot(struct device_node *dn, int mode_flag) +{ + struct pci_dev *dev; + dn = eeh_find_device_pe(dn); + + /* Back up one, since config addrs might be shared */ + if (!pcibios_find_pci_bus(dn) && of_node_to_eeh_dev(dn->parent)) + dn = dn->parent; + + of_node_to_eeh_dev(dn)->mode |= mode_flag; + + /* Mark the pci device too */ + dev = of_node_to_eeh_dev(dn)->pdev; + if (dev) + dev->error_state = pci_channel_io_frozen; + + __eeh_mark_slot(dn, mode_flag); +} + +/** + * __eeh_clear_slot - Clear failure flag for the child devices + * @parent: parent device + * @mode_flag: flag to be cleared + * + * Clear failure flag for the child devices. + */ +static void __eeh_clear_slot(struct device_node *parent, int mode_flag) +{ + struct device_node *dn; + + for_each_child_of_node(parent, dn) { + if (of_node_to_eeh_dev(dn)) { + of_node_to_eeh_dev(dn)->mode &= ~mode_flag; + of_node_to_eeh_dev(dn)->check_count = 0; + __eeh_clear_slot(dn, mode_flag); + } + } +} + +/** + * eeh_clear_slot - Clear failure flag for the indicated device and its children + * @dn: parent device + * @mode_flag: flag to be cleared + * + * Clear failure flag for the indicated device and its children. + */ +void eeh_clear_slot(struct device_node *dn, int mode_flag) +{ + unsigned long flags; + raw_spin_lock_irqsave(&confirm_error_lock, flags); + + dn = eeh_find_device_pe(dn); + + /* Back up one, since config addrs might be shared */ + if (!pcibios_find_pci_bus(dn) && of_node_to_eeh_dev(dn->parent)) + dn = dn->parent; + + of_node_to_eeh_dev(dn)->mode &= ~mode_flag; + of_node_to_eeh_dev(dn)->check_count = 0; + __eeh_clear_slot(dn, mode_flag); + raw_spin_unlock_irqrestore(&confirm_error_lock, flags); +} + +/** + * eeh_dn_check_failure - Check if all 1's data is due to EEH slot freeze + * @dn: device node + * @dev: pci device, if known * * Check for an EEH failure for the given device node. Call this * routine if the result of a read was all 0xff's and you want to @@ -283,13 +392,11 @@ static inline unsigned long eeh_token_to_phys(unsigned long token) * * It is safe to call this routine in an interrupt context. */ -int eeh_dev_check_failure(struct eeh_dev *edev) +int eeh_dn_check_failure(struct device_node *dn, struct pci_dev *dev) { int ret; unsigned long flags; - struct device_node *dn; - struct pci_dev *dev; - struct eeh_pe *pe; + struct eeh_dev *edev; int rc = 0; const char *location; @@ -298,23 +405,23 @@ int eeh_dev_check_failure(struct eeh_dev *edev) if (!eeh_subsystem_enabled) return 0; - if (!edev) { + if (!dn) { eeh_stats.no_dn++; return 0; } - dn = eeh_dev_to_of_node(edev); - dev = eeh_dev_to_pci_dev(edev); - pe = edev->pe; + dn = eeh_find_device_pe(dn); + edev = of_node_to_eeh_dev(dn); /* Access to IO BARs might get this far and still not want checking. */ - if (!pe) { + if (!(edev->mode & EEH_MODE_SUPPORTED) || + edev->mode & EEH_MODE_NOCHECK) { eeh_stats.ignored_check++; - pr_debug("EEH: Ignored check for %s %s\n", - eeh_pci_name(dev), dn->full_name); + pr_debug("EEH: Ignored check (%x) for %s %s\n", + edev->mode, eeh_pci_name(dev), dn->full_name); return 0; } - if (!pe->addr && !pe->config_addr) { + if (!edev->config_addr && !edev->pe_config_addr) { eeh_stats.no_cfg_addr++; return 0; } @@ -327,13 +434,13 @@ int eeh_dev_check_failure(struct eeh_dev *edev) */ raw_spin_lock_irqsave(&confirm_error_lock, flags); rc = 1; - if (pe->state & EEH_PE_ISOLATED) { - pe->check_count++; - if (pe->check_count % EEH_MAX_FAILS == 0) { + if (edev->mode & EEH_MODE_ISOLATED) { + edev->check_count++; + if (edev->check_count % EEH_MAX_FAILS == 0) { location = of_get_property(dn, "ibm,loc-code", NULL); printk(KERN_ERR "EEH: %d reads ignored for recovering device at " "location=%s driver=%s pci addr=%s\n", - pe->check_count, location, + edev->check_count, location, eeh_driver_name(dev), eeh_pci_name(dev)); printk(KERN_ERR "EEH: Might be infinite loop in %s driver\n", eeh_driver_name(dev)); @@ -349,7 +456,7 @@ int eeh_dev_check_failure(struct eeh_dev *edev) * function zero of a multi-function device. * In any case they must share a common PHB. */ - ret = eeh_ops->get_state(pe, NULL); + ret = eeh_ops->get_state(dn, NULL); /* Note that config-io to empty slots may fail; * they are empty when they don't have children. @@ -362,7 +469,7 @@ int eeh_dev_check_failure(struct eeh_dev *edev) (ret & (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) == (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) { eeh_stats.false_positives++; - pe->false_positives++; + edev->false_positives ++; rc = 0; goto dn_unlock; } @@ -373,10 +480,10 @@ int eeh_dev_check_failure(struct eeh_dev *edev) * with other functions on this device, and functions under * bridges. */ - eeh_pe_state_mark(pe, EEH_PE_ISOLATED); + eeh_mark_slot(dn, EEH_MODE_ISOLATED); raw_spin_unlock_irqrestore(&confirm_error_lock, flags); - eeh_send_failure_event(pe); + eeh_send_failure_event(edev); /* Most EEH events are due to device driver bugs. Having * a stack trace will help the device-driver authors figure @@ -390,7 +497,7 @@ int eeh_dev_check_failure(struct eeh_dev *edev) return rc; } -EXPORT_SYMBOL_GPL(eeh_dev_check_failure); +EXPORT_SYMBOL_GPL(eeh_dn_check_failure); /** * eeh_check_failure - Check if all 1's data is due to EEH slot freeze @@ -407,19 +514,21 @@ EXPORT_SYMBOL_GPL(eeh_dev_check_failure); unsigned long eeh_check_failure(const volatile void __iomem *token, unsigned long val) { unsigned long addr; - struct eeh_dev *edev; + struct pci_dev *dev; + struct device_node *dn; /* Finding the phys addr + pci device; this is pretty quick. */ addr = eeh_token_to_phys((unsigned long __force) token); - edev = eeh_addr_cache_get_dev(addr); - if (!edev) { + dev = pci_addr_cache_get_device(addr); + if (!dev) { eeh_stats.no_device++; return val; } - eeh_dev_check_failure(edev); + dn = pci_device_to_OF_node(dev); + eeh_dn_check_failure(dn, dev); - pci_dev_put(eeh_dev_to_pci_dev(edev)); + pci_dev_put(dev); return val; } @@ -428,22 +537,23 @@ EXPORT_SYMBOL(eeh_check_failure); /** * eeh_pci_enable - Enable MMIO or DMA transfers for this slot - * @pe: EEH PE + * @edev: pci device node * * This routine should be called to reenable frozen MMIO or DMA * so that it would work correctly again. It's useful while doing * recovery or log collection on the indicated device. */ -int eeh_pci_enable(struct eeh_pe *pe, int function) +int eeh_pci_enable(struct eeh_dev *edev, int function) { int rc; + struct device_node *dn = eeh_dev_to_of_node(edev); - rc = eeh_ops->set_option(pe, function); + rc = eeh_ops->set_option(dn, function); if (rc) - pr_warning("%s: Unexpected state change %d on PHB#%d-PE#%x, err=%d\n", - __func__, function, pe->phb->global_number, pe->addr, rc); + printk(KERN_WARNING "EEH: Unexpected state change %d, err=%d dn=%s\n", + function, rc, dn->full_name); - rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC); + rc = eeh_ops->wait_state(dn, PCI_BUS_RESET_WAIT_MSEC); if (rc > 0 && (rc & EEH_STATE_MMIO_ENABLED) && (function == EEH_OPT_THAW_MMIO)) return 0; @@ -461,24 +571,17 @@ int eeh_pci_enable(struct eeh_pe *pe, int function) */ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state) { - struct eeh_dev *edev = pci_dev_to_eeh_dev(dev); - struct eeh_pe *pe = edev->pe; - - if (!pe) { - pr_err("%s: No PE found on PCI device %s\n", - __func__, pci_name(dev)); - return -EINVAL; - } + struct device_node *dn = pci_device_to_OF_node(dev); switch (state) { case pcie_deassert_reset: - eeh_ops->reset(pe, EEH_RESET_DEACTIVATE); + eeh_ops->reset(dn, EEH_RESET_DEACTIVATE); break; case pcie_hot_reset: - eeh_ops->reset(pe, EEH_RESET_HOT); + eeh_ops->reset(dn, EEH_RESET_HOT); break; case pcie_warm_reset: - eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL); + eeh_ops->reset(dn, EEH_RESET_FUNDAMENTAL); break; default: return -EINVAL; @@ -488,37 +591,66 @@ int pcibios_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state stat } /** - * eeh_set_pe_freset - Check the required reset for the indicated device - * @data: EEH device - * @flag: return value + * __eeh_set_pe_freset - Check the required reset for child devices + * @parent: parent device + * @freset: return value + * + * Each device might have its preferred reset type: fundamental or + * hot reset. The routine is used to collect the information from + * the child devices so that they could be reset accordingly. + */ +void __eeh_set_pe_freset(struct device_node *parent, unsigned int *freset) +{ + struct device_node *dn; + + for_each_child_of_node(parent, dn) { + if (of_node_to_eeh_dev(dn)) { + struct pci_dev *dev = of_node_to_eeh_dev(dn)->pdev; + + if (dev && dev->driver) + *freset |= dev->needs_freset; + + __eeh_set_pe_freset(dn, freset); + } + } +} + +/** + * eeh_set_pe_freset - Check the required reset for the indicated device and its children + * @dn: parent device + * @freset: return value * * Each device might have its preferred reset type: fundamental or * hot reset. The routine is used to collected the information for * the indicated device and its children so that the bunch of the * devices could be reset properly. */ -static void *eeh_set_dev_freset(void *data, void *flag) +void eeh_set_pe_freset(struct device_node *dn, unsigned int *freset) { struct pci_dev *dev; - unsigned int *freset = (unsigned int *)flag; - struct eeh_dev *edev = (struct eeh_dev *)data; + dn = eeh_find_device_pe(dn); + + /* Back up one, since config addrs might be shared */ + if (!pcibios_find_pci_bus(dn) && of_node_to_eeh_dev(dn->parent)) + dn = dn->parent; - dev = eeh_dev_to_pci_dev(edev); + dev = of_node_to_eeh_dev(dn)->pdev; if (dev) *freset |= dev->needs_freset; - return NULL; + __eeh_set_pe_freset(dn, freset); } /** * eeh_reset_pe_once - Assert the pci #RST line for 1/4 second - * @pe: EEH PE + * @edev: pci device node to be reset. * * Assert the PCI #RST line for 1/4 second. */ -static void eeh_reset_pe_once(struct eeh_pe *pe) +static void eeh_reset_pe_once(struct eeh_dev *edev) { unsigned int freset = 0; + struct device_node *dn = eeh_dev_to_of_node(edev); /* Determine type of EEH reset required for * Partitionable Endpoint, a hot-reset (1) @@ -526,12 +658,12 @@ static void eeh_reset_pe_once(struct eeh_pe *pe) * A fundamental reset required by any device under * Partitionable Endpoint trumps hot-reset. */ - eeh_pe_dev_traverse(pe, eeh_set_dev_freset, &freset); + eeh_set_pe_freset(dn, &freset); if (freset) - eeh_ops->reset(pe, EEH_RESET_FUNDAMENTAL); + eeh_ops->reset(dn, EEH_RESET_FUNDAMENTAL); else - eeh_ops->reset(pe, EEH_RESET_HOT); + eeh_ops->reset(dn, EEH_RESET_HOT); /* The PCI bus requires that the reset be held high for at least * a 100 milliseconds. We wait a bit longer 'just in case'. @@ -543,9 +675,9 @@ static void eeh_reset_pe_once(struct eeh_pe *pe) * pci slot reset line is dropped. Make sure we don't miss * these, and clear the flag now. */ - eeh_pe_state_clear(pe, EEH_PE_ISOLATED); + eeh_clear_slot(dn, EEH_MODE_ISOLATED); - eeh_ops->reset(pe, EEH_RESET_DEACTIVATE); + eeh_ops->reset(dn, EEH_RESET_DEACTIVATE); /* After a PCI slot has been reset, the PCI Express spec requires * a 1.5 second idle time for the bus to stabilize, before starting @@ -557,36 +689,116 @@ static void eeh_reset_pe_once(struct eeh_pe *pe) /** * eeh_reset_pe - Reset the indicated PE - * @pe: EEH PE + * @edev: PCI device associated EEH device * * This routine should be called to reset indicated device, including * PE. A PE might include multiple PCI devices and sometimes PCI bridges * might be involved as well. */ -int eeh_reset_pe(struct eeh_pe *pe) +int eeh_reset_pe(struct eeh_dev *edev) { int i, rc; + struct device_node *dn = eeh_dev_to_of_node(edev); /* Take three shots at resetting the bus */ for (i=0; i<3; i++) { - eeh_reset_pe_once(pe); + eeh_reset_pe_once(edev); - rc = eeh_ops->wait_state(pe, PCI_BUS_RESET_WAIT_MSEC); + rc = eeh_ops->wait_state(dn, PCI_BUS_RESET_WAIT_MSEC); if (rc == (EEH_STATE_MMIO_ACTIVE | EEH_STATE_DMA_ACTIVE)) return 0; if (rc < 0) { - pr_err("%s: Unrecoverable slot failure on PHB#%d-PE#%x", - __func__, pe->phb->global_number, pe->addr); + printk(KERN_ERR "EEH: unrecoverable slot failure %s\n", + dn->full_name); return -1; } - pr_err("EEH: bus reset %d failed on PHB#%d-PE#%x, rc=%d\n", - i+1, pe->phb->global_number, pe->addr, rc); + printk(KERN_ERR "EEH: bus reset %d failed on slot %s, rc=%d\n", + i+1, dn->full_name, rc); } return -1; } +/** Save and restore of PCI BARs + * + * Although firmware will set up BARs during boot, it doesn't + * set up device BAR's after a device reset, although it will, + * if requested, set up bridge configuration. Thus, we need to + * configure the PCI devices ourselves. + */ + +/** + * eeh_restore_one_device_bars - Restore the Base Address Registers for one device + * @edev: PCI device associated EEH device + * + * Loads the PCI configuration space base address registers, + * the expansion ROM base address, the latency timer, and etc. + * from the saved values in the device node. + */ +static inline void eeh_restore_one_device_bars(struct eeh_dev *edev) +{ + int i; + u32 cmd; + struct device_node *dn = eeh_dev_to_of_node(edev); + + if (!edev->phb) + return; + + for (i=4; i<10; i++) { + eeh_ops->write_config(dn, i*4, 4, edev->config_space[i]); + } + + /* 12 == Expansion ROM Address */ + eeh_ops->write_config(dn, 12*4, 4, edev->config_space[12]); + +#define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF)) +#define SAVED_BYTE(OFF) (((u8 *)(edev->config_space))[BYTE_SWAP(OFF)]) + + eeh_ops->write_config(dn, PCI_CACHE_LINE_SIZE, 1, + SAVED_BYTE(PCI_CACHE_LINE_SIZE)); + + eeh_ops->write_config(dn, PCI_LATENCY_TIMER, 1, + SAVED_BYTE(PCI_LATENCY_TIMER)); + + /* max latency, min grant, interrupt pin and line */ + eeh_ops->write_config(dn, 15*4, 4, edev->config_space[15]); + + /* Restore PERR & SERR bits, some devices require it, + * don't touch the other command bits + */ + eeh_ops->read_config(dn, PCI_COMMAND, 4, &cmd); + if (edev->config_space[1] & PCI_COMMAND_PARITY) + cmd |= PCI_COMMAND_PARITY; + else + cmd &= ~PCI_COMMAND_PARITY; + if (edev->config_space[1] & PCI_COMMAND_SERR) + cmd |= PCI_COMMAND_SERR; + else + cmd &= ~PCI_COMMAND_SERR; + eeh_ops->write_config(dn, PCI_COMMAND, 4, cmd); +} + +/** + * eeh_restore_bars - Restore the PCI config space info + * @edev: EEH device + * + * This routine performs a recursive walk to the children + * of this device as well. + */ +void eeh_restore_bars(struct eeh_dev *edev) +{ + struct device_node *dn; + if (!edev) + return; + + if ((edev->mode & EEH_MODE_SUPPORTED) && !IS_BRIDGE(edev->class_code)) + eeh_restore_one_device_bars(edev); + + for_each_child_of_node(eeh_dev_to_of_node(edev), dn) + eeh_restore_bars(of_node_to_eeh_dev(dn)); +} + /** * eeh_save_bars - Save device bars * @edev: PCI device associated EEH device @@ -596,7 +808,7 @@ int eeh_reset_pe(struct eeh_pe *pe) * PCI devices are added individually; but, for the restore, * an entire slot is reset at a time. */ -void eeh_save_bars(struct eeh_dev *edev) +static void eeh_save_bars(struct eeh_dev *edev) { int i; struct device_node *dn; @@ -609,6 +821,102 @@ void eeh_save_bars(struct eeh_dev *edev) eeh_ops->read_config(dn, i * 4, 4, &edev->config_space[i]); } +/** + * eeh_early_enable - Early enable EEH on the indicated device + * @dn: device node + * @data: BUID + * + * Enable EEH functionality on the specified PCI device. The function + * is expected to be called before real PCI probing is done. However, + * the PHBs have been initialized at this point. + */ +static void *eeh_early_enable(struct device_node *dn, void *data) +{ + int ret; + const u32 *class_code = of_get_property(dn, "class-code", NULL); + const u32 *vendor_id = of_get_property(dn, "vendor-id", NULL); + const u32 *device_id = of_get_property(dn, "device-id", NULL); + const u32 *regs; + int enable; + struct eeh_dev *edev = of_node_to_eeh_dev(dn); + + edev->class_code = 0; + edev->mode = 0; + edev->check_count = 0; + edev->freeze_count = 0; + edev->false_positives = 0; + + if (!of_device_is_available(dn)) + return NULL; + + /* Ignore bad nodes. */ + if (!class_code || !vendor_id || !device_id) + return NULL; + + /* There is nothing to check on PCI to ISA bridges */ + if (dn->type && !strcmp(dn->type, "isa")) { + edev->mode |= EEH_MODE_NOCHECK; + return NULL; + } + edev->class_code = *class_code; + + /* Ok... see if this device supports EEH. Some do, some don't, + * and the only way to find out is to check each and every one. + */ + regs = of_get_property(dn, "reg", NULL); + if (regs) { + /* First register entry is addr (00BBSS00) */ + /* Try to enable eeh */ + ret = eeh_ops->set_option(dn, EEH_OPT_ENABLE); + + enable = 0; + if (ret == 0) { + edev->config_addr = regs[0]; + + /* If the newer, better, ibm,get-config-addr-info is supported, + * then use that instead. + */ + edev->pe_config_addr = eeh_ops->get_pe_addr(dn); + + /* Some older systems (Power4) allow the + * ibm,set-eeh-option call to succeed even on nodes + * where EEH is not supported. Verify support + * explicitly. + */ + ret = eeh_ops->get_state(dn, NULL); + if (ret > 0 && ret != EEH_STATE_NOT_SUPPORT) + enable = 1; + } + + if (enable) { + eeh_subsystem_enabled = 1; + edev->mode |= EEH_MODE_SUPPORTED; + + pr_debug("EEH: %s: eeh enabled, config=%x pe_config=%x\n", + dn->full_name, edev->config_addr, + edev->pe_config_addr); + } else { + + /* This device doesn't support EEH, but it may have an + * EEH parent, in which case we mark it as supported. + */ + if (dn->parent && of_node_to_eeh_dev(dn->parent) && + (of_node_to_eeh_dev(dn->parent)->mode & EEH_MODE_SUPPORTED)) { + /* Parent supports EEH. */ + edev->mode |= EEH_MODE_SUPPORTED; + edev->config_addr = of_node_to_eeh_dev(dn->parent)->config_addr; + return NULL; + } + } + } else { + printk(KERN_WARNING "EEH: %s: unable to get reg property.\n", + dn->full_name); + } + + eeh_save_bars(edev); + return NULL; +} + /** * eeh_ops_register - Register platform dependent EEH operations * @ops: platform dependent EEH operations @@ -674,7 +982,7 @@ int __exit eeh_ops_unregister(const char *name) * Even if force-off is set, the EEH hardware is still enabled, so that * newer systems can boot. */ -static int __init eeh_init(void) +void __init eeh_init(void) { struct pci_controller *hose, *tmp; struct device_node *phb; @@ -684,34 +992,27 @@ static int __init eeh_init(void) if (!eeh_ops) { pr_warning("%s: Platform EEH operation not found\n", __func__); - return -EEXIST; + return; } else if ((ret = eeh_ops->init())) { pr_warning("%s: Failed to call platform init function (%d)\n", __func__, ret); - return ret; + return; } raw_spin_lock_init(&confirm_error_lock); /* Enable EEH for all adapters */ - if (eeh_probe_mode_devtree()) { - list_for_each_entry_safe(hose, tmp, - &hose_list, list_node) { - phb = hose->dn; - traverse_pci_devices(phb, eeh_ops->of_probe, NULL); - } + list_for_each_entry_safe(hose, tmp, &hose_list, list_node) { + phb = hose->dn; + traverse_pci_devices(phb, eeh_early_enable, NULL); } if (eeh_subsystem_enabled) - pr_info("EEH: PCI Enhanced I/O Error Handling Enabled\n"); + printk(KERN_INFO "EEH: PCI Enhanced I/O Error Handling Enabled\n"); else - pr_warning("EEH: No capable adapters found\n"); - - return ret; + printk(KERN_WARNING "EEH: No capable adapters found\n"); } -core_initcall_sync(eeh_init); - /** * eeh_add_device_early - Enable EEH for the indicated device_node * @dn: device node for which to set up EEH @@ -728,7 +1029,7 @@ static void eeh_add_device_early(struct device_node *dn) { struct pci_controller *phb; - if (!of_node_to_eeh_dev(dn)) + if (!dn || !of_node_to_eeh_dev(dn)) return; phb = of_node_to_eeh_dev(dn)->phb; @@ -736,8 +1037,7 @@ static void eeh_add_device_early(struct device_node *dn) if (NULL == phb || 0 == phb->buid) return; - /* FIXME: hotplug support on POWERNV */ - eeh_ops->of_probe(dn, NULL); + eeh_early_enable(dn, NULL); } /** @@ -787,7 +1087,7 @@ static void eeh_add_device_late(struct pci_dev *dev) edev->pdev = dev; dev->dev.archdata.edev = edev; - eeh_addr_cache_insert_dev(dev); + pci_addr_cache_insert_device(dev); eeh_sysfs_add_device(dev); } @@ -817,7 +1117,6 @@ EXPORT_SYMBOL_GPL(eeh_add_device_tree_late); /** * eeh_remove_device - Undo EEH setup for the indicated pci device * @dev: pci device to be removed - * @purge_pe: remove the PE or not * * This routine should be called when a device is removed from * a running system (e.g. by hotplug or dlpar). It unregisters @@ -825,7 +1124,7 @@ EXPORT_SYMBOL_GPL(eeh_add_device_tree_late); * this device will no longer be detected after this call; thus, * i/o errors affecting this slot may leave this device unusable. */ -static void eeh_remove_device(struct pci_dev *dev, int purge_pe) +static void eeh_remove_device(struct pci_dev *dev) { struct eeh_dev *edev; @@ -844,30 +1143,28 @@ static void eeh_remove_device(struct pci_dev *dev, int purge_pe) dev->dev.archdata.edev = NULL; pci_dev_put(dev); - eeh_rmv_from_parent_pe(edev, purge_pe); - eeh_addr_cache_rmv_dev(dev); + pci_addr_cache_remove_device(dev); eeh_sysfs_remove_device(dev); } /** * eeh_remove_bus_device - Undo EEH setup for the indicated PCI device * @dev: PCI device - * @purge_pe: remove the corresponding PE or not * * This routine must be called when a device is removed from the * running system through hotplug or dlpar. The corresponding * PCI address cache will be removed. */ -void eeh_remove_bus_device(struct pci_dev *dev, int purge_pe) +void eeh_remove_bus_device(struct pci_dev *dev) { struct pci_bus *bus = dev->subordinate; struct pci_dev *child, *tmp; - eeh_remove_device(dev, purge_pe); + eeh_remove_device(dev); if (bus && dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { list_for_each_entry_safe(child, tmp, &bus->devices, bus_list) - eeh_remove_bus_device(child, purge_pe); + eeh_remove_bus_device(child); } } EXPORT_SYMBOL_GPL(eeh_remove_bus_device); diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_cache.c b/trunk/arch/powerpc/platforms/pseries/eeh_cache.c index 5a4c87903057..e5ae1c687c66 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_cache.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_cache.c @@ -50,7 +50,6 @@ struct pci_io_addr_range { struct rb_node rb_node; unsigned long addr_lo; unsigned long addr_hi; - struct eeh_dev *edev; struct pci_dev *pcidev; unsigned int flags; }; @@ -60,7 +59,7 @@ static struct pci_io_addr_cache { spinlock_t piar_lock; } pci_io_addr_cache_root; -static inline struct eeh_dev *__eeh_addr_cache_get_device(unsigned long addr) +static inline struct pci_dev *__pci_addr_cache_get_device(unsigned long addr) { struct rb_node *n = pci_io_addr_cache_root.rb_root.rb_node; @@ -75,7 +74,7 @@ static inline struct eeh_dev *__eeh_addr_cache_get_device(unsigned long addr) n = n->rb_right; } else { pci_dev_get(piar->pcidev); - return piar->edev; + return piar->pcidev; } } } @@ -84,7 +83,7 @@ static inline struct eeh_dev *__eeh_addr_cache_get_device(unsigned long addr) } /** - * eeh_addr_cache_get_dev - Get device, given only address + * pci_addr_cache_get_device - Get device, given only address * @addr: mmio (PIO) phys address or i/o port number * * Given an mmio phys address, or a port number, find a pci device @@ -93,15 +92,15 @@ static inline struct eeh_dev *__eeh_addr_cache_get_device(unsigned long addr) * from zero (that is, they do *not* have pci_io_addr added in). * It is safe to call this function within an interrupt. */ -struct eeh_dev *eeh_addr_cache_get_dev(unsigned long addr) +struct pci_dev *pci_addr_cache_get_device(unsigned long addr) { - struct eeh_dev *edev; + struct pci_dev *dev; unsigned long flags; spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags); - edev = __eeh_addr_cache_get_device(addr); + dev = __pci_addr_cache_get_device(addr); spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags); - return edev; + return dev; } #ifdef DEBUG @@ -109,7 +108,7 @@ struct eeh_dev *eeh_addr_cache_get_dev(unsigned long addr) * Handy-dandy debug print routine, does nothing more * than print out the contents of our addr cache. */ -static void eeh_addr_cache_print(struct pci_io_addr_cache *cache) +static void pci_addr_cache_print(struct pci_io_addr_cache *cache) { struct rb_node *n; int cnt = 0; @@ -118,7 +117,7 @@ static void eeh_addr_cache_print(struct pci_io_addr_cache *cache) while (n) { struct pci_io_addr_range *piar; piar = rb_entry(n, struct pci_io_addr_range, rb_node); - pr_debug("PCI: %s addr range %d [%lx-%lx]: %s\n", + printk(KERN_DEBUG "PCI: %s addr range %d [%lx-%lx]: %s\n", (piar->flags & IORESOURCE_IO) ? "i/o" : "mem", cnt, piar->addr_lo, piar->addr_hi, pci_name(piar->pcidev)); cnt++; @@ -129,7 +128,7 @@ static void eeh_addr_cache_print(struct pci_io_addr_cache *cache) /* Insert address range into the rb tree. */ static struct pci_io_addr_range * -eeh_addr_cache_insert(struct pci_dev *dev, unsigned long alo, +pci_addr_cache_insert(struct pci_dev *dev, unsigned long alo, unsigned long ahi, unsigned int flags) { struct rb_node **p = &pci_io_addr_cache_root.rb_root.rb_node; @@ -147,24 +146,23 @@ eeh_addr_cache_insert(struct pci_dev *dev, unsigned long alo, } else { if (dev != piar->pcidev || alo != piar->addr_lo || ahi != piar->addr_hi) { - pr_warning("PIAR: overlapping address range\n"); + printk(KERN_WARNING "PIAR: overlapping address range\n"); } return piar; } } - piar = kzalloc(sizeof(struct pci_io_addr_range), GFP_ATOMIC); + piar = kmalloc(sizeof(struct pci_io_addr_range), GFP_ATOMIC); if (!piar) return NULL; pci_dev_get(dev); piar->addr_lo = alo; piar->addr_hi = ahi; - piar->edev = pci_dev_to_eeh_dev(dev); piar->pcidev = dev; piar->flags = flags; #ifdef DEBUG - pr_debug("PIAR: insert range=[%lx:%lx] dev=%s\n", + printk(KERN_DEBUG "PIAR: insert range=[%lx:%lx] dev=%s\n", alo, ahi, pci_name(dev)); #endif @@ -174,7 +172,7 @@ eeh_addr_cache_insert(struct pci_dev *dev, unsigned long alo, return piar; } -static void __eeh_addr_cache_insert_dev(struct pci_dev *dev) +static void __pci_addr_cache_insert_device(struct pci_dev *dev) { struct device_node *dn; struct eeh_dev *edev; @@ -182,7 +180,7 @@ static void __eeh_addr_cache_insert_dev(struct pci_dev *dev) dn = pci_device_to_OF_node(dev); if (!dn) { - pr_warning("PCI: no pci dn found for dev=%s\n", pci_name(dev)); + printk(KERN_WARNING "PCI: no pci dn found for dev=%s\n", pci_name(dev)); return; } @@ -194,7 +192,8 @@ static void __eeh_addr_cache_insert_dev(struct pci_dev *dev) } /* Skip any devices for which EEH is not enabled. */ - if (!edev->pe) { + if (!(edev->mode & EEH_MODE_SUPPORTED) || + edev->mode & EEH_MODE_NOCHECK) { #ifdef DEBUG pr_info("PCI: skip building address cache for=%s - %s\n", pci_name(dev), dn->full_name); @@ -213,19 +212,19 @@ static void __eeh_addr_cache_insert_dev(struct pci_dev *dev) continue; if (start == 0 || ~start == 0 || end == 0 || ~end == 0) continue; - eeh_addr_cache_insert(dev, start, end, flags); + pci_addr_cache_insert(dev, start, end, flags); } } /** - * eeh_addr_cache_insert_dev - Add a device to the address cache + * pci_addr_cache_insert_device - Add a device to the address cache * @dev: PCI device whose I/O addresses we are interested in. * * In order to support the fast lookup of devices based on addresses, * we maintain a cache of devices that can be quickly searched. * This routine adds a device to that cache. */ -void eeh_addr_cache_insert_dev(struct pci_dev *dev) +void pci_addr_cache_insert_device(struct pci_dev *dev) { unsigned long flags; @@ -234,11 +233,11 @@ void eeh_addr_cache_insert_dev(struct pci_dev *dev) return; spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags); - __eeh_addr_cache_insert_dev(dev); + __pci_addr_cache_insert_device(dev); spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags); } -static inline void __eeh_addr_cache_rmv_dev(struct pci_dev *dev) +static inline void __pci_addr_cache_remove_device(struct pci_dev *dev) { struct rb_node *n; @@ -259,7 +258,7 @@ static inline void __eeh_addr_cache_rmv_dev(struct pci_dev *dev) } /** - * eeh_addr_cache_rmv_dev - remove pci device from addr cache + * pci_addr_cache_remove_device - remove pci device from addr cache * @dev: device to remove * * Remove a device from the addr-cache tree. @@ -267,17 +266,17 @@ static inline void __eeh_addr_cache_rmv_dev(struct pci_dev *dev) * the tree multiple times (once per resource). * But so what; device removal doesn't need to be that fast. */ -void eeh_addr_cache_rmv_dev(struct pci_dev *dev) +void pci_addr_cache_remove_device(struct pci_dev *dev) { unsigned long flags; spin_lock_irqsave(&pci_io_addr_cache_root.piar_lock, flags); - __eeh_addr_cache_rmv_dev(dev); + __pci_addr_cache_remove_device(dev); spin_unlock_irqrestore(&pci_io_addr_cache_root.piar_lock, flags); } /** - * eeh_addr_cache_build - Build a cache of I/O addresses + * pci_addr_cache_build - Build a cache of I/O addresses * * Build a cache of pci i/o addresses. This cache will be used to * find the pci device that corresponds to a given address. @@ -285,7 +284,7 @@ void eeh_addr_cache_rmv_dev(struct pci_dev *dev) * Must be run late in boot process, after the pci controllers * have been scanned for devices (after all device resources are known). */ -void __init eeh_addr_cache_build(void) +void __init pci_addr_cache_build(void) { struct device_node *dn; struct eeh_dev *edev; @@ -294,7 +293,7 @@ void __init eeh_addr_cache_build(void) spin_lock_init(&pci_io_addr_cache_root.piar_lock); for_each_pci_dev(dev) { - eeh_addr_cache_insert_dev(dev); + pci_addr_cache_insert_device(dev); dn = pci_device_to_OF_node(dev); if (!dn) @@ -313,7 +312,7 @@ void __init eeh_addr_cache_build(void) #ifdef DEBUG /* Verify tree built up above, echo back the list of addrs. */ - eeh_addr_cache_print(&pci_io_addr_cache_root); + pci_addr_cache_print(&pci_io_addr_cache_root); #endif } diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_dev.c b/trunk/arch/powerpc/platforms/pseries/eeh_dev.c index 66442341d3a6..c4507d095900 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_dev.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_dev.c @@ -55,7 +55,7 @@ void * __devinit eeh_dev_init(struct device_node *dn, void *data) struct eeh_dev *edev; /* Allocate EEH device */ - edev = kzalloc(sizeof(*edev), GFP_KERNEL); + edev = zalloc_maybe_bootmem(sizeof(*edev), GFP_KERNEL); if (!edev) { pr_warning("%s: out of memory\n", __func__); return NULL; @@ -65,7 +65,6 @@ void * __devinit eeh_dev_init(struct device_node *dn, void *data) PCI_DN(dn)->edev = edev; edev->dn = dn; edev->phb = phb; - INIT_LIST_HEAD(&edev->list); return NULL; } @@ -81,9 +80,6 @@ void __devinit eeh_dev_phb_init_dynamic(struct pci_controller *phb) { struct device_node *dn = phb->dn; - /* EEH PE for PHB */ - eeh_phb_pe_create(phb); - /* EEH device for PHB */ eeh_dev_init(dn, phb); @@ -97,16 +93,10 @@ void __devinit eeh_dev_phb_init_dynamic(struct pci_controller *phb) * Scan all the existing PHBs and create EEH devices for their OF * nodes and their children OF nodes */ -static int __init eeh_dev_phb_init(void) +void __init eeh_dev_phb_init(void) { struct pci_controller *phb, *tmp; list_for_each_entry_safe(phb, tmp, &hose_list, list_node) eeh_dev_phb_init_dynamic(phb); - - pr_info("EEH: devices created\n"); - - return 0; } - -core_initcall(eeh_dev_phb_init); diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_driver.c b/trunk/arch/powerpc/platforms/pseries/eeh_driver.c index a3fefb61097c..baf92cd9dfab 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_driver.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -48,41 +47,6 @@ static inline const char *eeh_pcid_name(struct pci_dev *pdev) return ""; } -/** - * eeh_pcid_get - Get the PCI device driver - * @pdev: PCI device - * - * The function is used to retrieve the PCI device driver for - * the indicated PCI device. Besides, we will increase the reference - * of the PCI device driver to prevent that being unloaded on - * the fly. Otherwise, kernel crash would be seen. - */ -static inline struct pci_driver *eeh_pcid_get(struct pci_dev *pdev) -{ - if (!pdev || !pdev->driver) - return NULL; - - if (!try_module_get(pdev->driver->driver.owner)) - return NULL; - - return pdev->driver; -} - -/** - * eeh_pcid_put - Dereference on the PCI device driver - * @pdev: PCI device - * - * The function is called to do dereference on the PCI device - * driver of the indicated PCI device. - */ -static inline void eeh_pcid_put(struct pci_dev *pdev) -{ - if (!pdev || !pdev->driver) - return; - - module_put(pdev->driver->driver.owner); -} - #if 0 static void print_device_node_tree(struct pci_dn *pdn, int dent) { @@ -129,7 +93,7 @@ static void eeh_disable_irq(struct pci_dev *dev) if (!irq_has_action(dev->irq)) return; - edev->mode |= EEH_DEV_IRQ_DISABLED; + edev->mode |= EEH_MODE_IRQ_DISABLED; disable_irq_nosync(dev->irq); } @@ -144,44 +108,36 @@ static void eeh_enable_irq(struct pci_dev *dev) { struct eeh_dev *edev = pci_dev_to_eeh_dev(dev); - if ((edev->mode) & EEH_DEV_IRQ_DISABLED) { - edev->mode &= ~EEH_DEV_IRQ_DISABLED; + if ((edev->mode) & EEH_MODE_IRQ_DISABLED) { + edev->mode &= ~EEH_MODE_IRQ_DISABLED; enable_irq(dev->irq); } } /** * eeh_report_error - Report pci error to each device driver - * @data: eeh device + * @dev: PCI device * @userdata: return value * * Report an EEH error to each device driver, collect up and * merge the device driver responses. Cumulative response * passed back in "userdata". */ -static void *eeh_report_error(void *data, void *userdata) +static int eeh_report_error(struct pci_dev *dev, void *userdata) { - struct eeh_dev *edev = (struct eeh_dev *)data; - struct pci_dev *dev = eeh_dev_to_pci_dev(edev); enum pci_ers_result rc, *res = userdata; - struct pci_driver *driver; + struct pci_driver *driver = dev->driver; - /* We might not have the associated PCI device, - * then we should continue for next one. - */ - if (!dev) return NULL; dev->error_state = pci_channel_io_frozen; - driver = eeh_pcid_get(dev); - if (!driver) return NULL; + if (!driver) + return 0; eeh_disable_irq(dev); if (!driver->err_handler || - !driver->err_handler->error_detected) { - eeh_pcid_put(dev); - return NULL; - } + !driver->err_handler->error_detected) + return 0; rc = driver->err_handler->error_detected(dev, pci_channel_io_frozen); @@ -189,34 +145,27 @@ static void *eeh_report_error(void *data, void *userdata) if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; if (*res == PCI_ERS_RESULT_NONE) *res = rc; - eeh_pcid_put(dev); - return NULL; + return 0; } /** * eeh_report_mmio_enabled - Tell drivers that MMIO has been enabled - * @data: eeh device + * @dev: PCI device * @userdata: return value * * Tells each device driver that IO ports, MMIO and config space I/O * are now enabled. Collects up and merges the device driver responses. * Cumulative response passed back in "userdata". */ -static void *eeh_report_mmio_enabled(void *data, void *userdata) +static int eeh_report_mmio_enabled(struct pci_dev *dev, void *userdata) { - struct eeh_dev *edev = (struct eeh_dev *)data; - struct pci_dev *dev = eeh_dev_to_pci_dev(edev); enum pci_ers_result rc, *res = userdata; - struct pci_driver *driver; + struct pci_driver *driver = dev->driver; - driver = eeh_pcid_get(dev); - if (!driver) return NULL; - - if (!driver->err_handler || - !driver->err_handler->mmio_enabled) { - eeh_pcid_put(dev); - return NULL; - } + if (!driver || + !driver->err_handler || + !driver->err_handler->mmio_enabled) + return 0; rc = driver->err_handler->mmio_enabled(dev); @@ -224,13 +173,12 @@ static void *eeh_report_mmio_enabled(void *data, void *userdata) if (rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; if (*res == PCI_ERS_RESULT_NONE) *res = rc; - eeh_pcid_put(dev); - return NULL; + return 0; } /** * eeh_report_reset - Tell device that slot has been reset - * @data: eeh device + * @dev: PCI device * @userdata: return value * * This routine must be called while EEH tries to reset particular @@ -238,26 +186,21 @@ static void *eeh_report_mmio_enabled(void *data, void *userdata) * some actions, usually to save data the driver needs so that the * driver can work again while the device is recovered. */ -static void *eeh_report_reset(void *data, void *userdata) +static int eeh_report_reset(struct pci_dev *dev, void *userdata) { - struct eeh_dev *edev = (struct eeh_dev *)data; - struct pci_dev *dev = eeh_dev_to_pci_dev(edev); enum pci_ers_result rc, *res = userdata; - struct pci_driver *driver; + struct pci_driver *driver = dev->driver; - if (!dev) return NULL; - dev->error_state = pci_channel_io_normal; + if (!driver) + return 0; - driver = eeh_pcid_get(dev); - if (!driver) return NULL; + dev->error_state = pci_channel_io_normal; eeh_enable_irq(dev); if (!driver->err_handler || - !driver->err_handler->slot_reset) { - eeh_pcid_put(dev); - return NULL; - } + !driver->err_handler->slot_reset) + return 0; rc = driver->err_handler->slot_reset(dev); if ((*res == PCI_ERS_RESULT_NONE) || @@ -265,115 +208,109 @@ static void *eeh_report_reset(void *data, void *userdata) if (*res == PCI_ERS_RESULT_DISCONNECT && rc == PCI_ERS_RESULT_NEED_RESET) *res = rc; - eeh_pcid_put(dev); - return NULL; + return 0; } /** * eeh_report_resume - Tell device to resume normal operations - * @data: eeh device + * @dev: PCI device * @userdata: return value * * This routine must be called to notify the device driver that it * could resume so that the device driver can do some initialization * to make the recovered device work again. */ -static void *eeh_report_resume(void *data, void *userdata) +static int eeh_report_resume(struct pci_dev *dev, void *userdata) { - struct eeh_dev *edev = (struct eeh_dev *)data; - struct pci_dev *dev = eeh_dev_to_pci_dev(edev); - struct pci_driver *driver; + struct pci_driver *driver = dev->driver; - if (!dev) return NULL; dev->error_state = pci_channel_io_normal; - driver = eeh_pcid_get(dev); - if (!driver) return NULL; + if (!driver) + return 0; eeh_enable_irq(dev); if (!driver->err_handler || - !driver->err_handler->resume) { - eeh_pcid_put(dev); - return NULL; - } + !driver->err_handler->resume) + return 0; driver->err_handler->resume(dev); - eeh_pcid_put(dev); - return NULL; + return 0; } /** * eeh_report_failure - Tell device driver that device is dead. - * @data: eeh device + * @dev: PCI device * @userdata: return value * * This informs the device driver that the device is permanently * dead, and that no further recovery attempts will be made on it. */ -static void *eeh_report_failure(void *data, void *userdata) +static int eeh_report_failure(struct pci_dev *dev, void *userdata) { - struct eeh_dev *edev = (struct eeh_dev *)data; - struct pci_dev *dev = eeh_dev_to_pci_dev(edev); - struct pci_driver *driver; + struct pci_driver *driver = dev->driver; - if (!dev) return NULL; dev->error_state = pci_channel_io_perm_failure; - driver = eeh_pcid_get(dev); - if (!driver) return NULL; + if (!driver) + return 0; eeh_disable_irq(dev); if (!driver->err_handler || - !driver->err_handler->error_detected) { - eeh_pcid_put(dev); - return NULL; - } + !driver->err_handler->error_detected) + return 0; driver->err_handler->error_detected(dev, pci_channel_io_perm_failure); - eeh_pcid_put(dev); - return NULL; + return 0; } /** * eeh_reset_device - Perform actual reset of a pci slot - * @pe: EEH PE + * @edev: PE associated EEH device * @bus: PCI bus corresponding to the isolcated slot * * This routine must be called to do reset on the indicated PE. * During the reset, udev might be invoked because those affected * PCI devices will be removed and then added. */ -static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) +static int eeh_reset_device(struct eeh_dev *edev, struct pci_bus *bus) { + struct device_node *dn; int cnt, rc; /* pcibios will clear the counter; save the value */ - cnt = pe->freeze_count; + cnt = edev->freeze_count; - /* - * We don't remove the corresponding PE instances because - * we need the information afterwords. The attached EEH - * devices are expected to be attached soon when calling - * into pcibios_add_pci_devices(). - */ if (bus) - __pcibios_remove_pci_devices(bus, 0); + pcibios_remove_pci_devices(bus); /* Reset the pci controller. (Asserts RST#; resets config space). * Reconfigure bridges and devices. Don't try to bring the system * up if the reset failed for some reason. */ - rc = eeh_reset_pe(pe); + rc = eeh_reset_pe(edev); if (rc) return rc; - /* Restore PE */ - eeh_ops->configure_bridge(pe); - eeh_pe_restore_bars(pe); + /* Walk over all functions on this device. */ + dn = eeh_dev_to_of_node(edev); + if (!pcibios_find_pci_bus(dn) && of_node_to_eeh_dev(dn->parent)) + dn = dn->parent->child; + + while (dn) { + struct eeh_dev *pedev = of_node_to_eeh_dev(dn); + + /* On Power4, always true because eeh_pe_config_addr=0 */ + if (edev->pe_config_addr == pedev->pe_config_addr) { + eeh_ops->configure_bridge(dn); + eeh_restore_bars(pedev); + } + dn = dn->sibling; + } /* Give the system 5 seconds to finish running the user-space * hotplug shutdown scripts, e.g. ifdown for ethernet. Yes, @@ -385,7 +322,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) ssleep(5); pcibios_add_pci_devices(bus); } - pe->freeze_count = cnt; + edev->freeze_count = cnt; return 0; } @@ -397,7 +334,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) /** * eeh_handle_event - Reset a PCI device after hard lockup. - * @pe: EEH PE + * @event: EEH event * * While PHB detects address or data parity errors on particular PCI * slot, the associated PE will be frozen. Besides, DMA's occurring @@ -412,24 +349,69 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus) * drivers (which cause a second set of hotplug events to go out to * userspace). */ -void eeh_handle_event(struct eeh_pe *pe) +struct eeh_dev *handle_eeh_events(struct eeh_event *event) { + struct device_node *frozen_dn; + struct eeh_dev *frozen_edev; struct pci_bus *frozen_bus; int rc = 0; enum pci_ers_result result = PCI_ERS_RESULT_NONE; + const char *location, *pci_str, *drv_str, *bus_pci_str, *bus_drv_str; + + frozen_dn = eeh_find_device_pe(eeh_dev_to_of_node(event->edev)); + if (!frozen_dn) { + location = of_get_property(eeh_dev_to_of_node(event->edev), "ibm,loc-code", NULL); + location = location ? location : "unknown"; + printk(KERN_ERR "EEH: Error: Cannot find partition endpoint " + "for location=%s pci addr=%s\n", + location, eeh_pci_name(eeh_dev_to_pci_dev(event->edev))); + return NULL; + } + + frozen_bus = pcibios_find_pci_bus(frozen_dn); + location = of_get_property(frozen_dn, "ibm,loc-code", NULL); + location = location ? location : "unknown"; + + /* There are two different styles for coming up with the PE. + * In the old style, it was the highest EEH-capable device + * which was always an EADS pci bridge. In the new style, + * there might not be any EADS bridges, and even when there are, + * the firmware marks them as "EEH incapable". So another + * two-step is needed to find the pci bus.. + */ + if (!frozen_bus) + frozen_bus = pcibios_find_pci_bus(frozen_dn->parent); - frozen_bus = eeh_pe_bus_get(pe); if (!frozen_bus) { - pr_err("%s: Cannot find PCI bus for PHB#%d-PE#%x\n", - __func__, pe->phb->global_number, pe->addr); - return; + printk(KERN_ERR "EEH: Cannot find PCI bus " + "for location=%s dn=%s\n", + location, frozen_dn->full_name); + return NULL; } - pe->freeze_count++; - if (pe->freeze_count > EEH_MAX_ALLOWED_FREEZES) + frozen_edev = of_node_to_eeh_dev(frozen_dn); + frozen_edev->freeze_count++; + pci_str = eeh_pci_name(eeh_dev_to_pci_dev(event->edev)); + drv_str = eeh_pcid_name(eeh_dev_to_pci_dev(event->edev)); + + if (frozen_edev->freeze_count > EEH_MAX_ALLOWED_FREEZES) goto excess_failures; - pr_warning("EEH: This PCI device has failed %d times in the last hour\n", - pe->freeze_count); + + printk(KERN_WARNING + "EEH: This PCI device has failed %d times in the last hour:\n", + frozen_edev->freeze_count); + + if (frozen_edev->pdev) { + bus_pci_str = pci_name(frozen_edev->pdev); + bus_drv_str = eeh_pcid_name(frozen_edev->pdev); + printk(KERN_WARNING + "EEH: Bus location=%s driver=%s pci addr=%s\n", + location, bus_drv_str, bus_pci_str); + } + + printk(KERN_WARNING + "EEH: Device location=%s driver=%s pci addr=%s\n", + location, drv_str, pci_str); /* Walk the various device drivers attached to this slot through * a reset sequence, giving each an opportunity to do what it needs @@ -437,12 +419,12 @@ void eeh_handle_event(struct eeh_pe *pe) * status ... if any child can't handle the reset, then the entire * slot is dlpar removed and added. */ - eeh_pe_dev_traverse(pe, eeh_report_error, &result); + pci_walk_bus(frozen_bus, eeh_report_error, &result); /* Get the current PCI slot state. This can take a long time, * sometimes over 3 seconds for certain systems. */ - rc = eeh_ops->wait_state(pe, MAX_WAIT_FOR_RECOVERY*1000); + rc = eeh_ops->wait_state(eeh_dev_to_of_node(frozen_edev), MAX_WAIT_FOR_RECOVERY*1000); if (rc < 0 || rc == EEH_STATE_NOT_SUPPORT) { printk(KERN_WARNING "EEH: Permanent failure\n"); goto hard_fail; @@ -452,14 +434,14 @@ void eeh_handle_event(struct eeh_pe *pe) * don't post the error log until after all dev drivers * have been informed. */ - eeh_slot_error_detail(pe, EEH_LOG_TEMP); + eeh_slot_error_detail(frozen_edev, EEH_LOG_TEMP); /* If all device drivers were EEH-unaware, then shut * down all of the device drivers, and hope they * go down willingly, without panicing the system. */ if (result == PCI_ERS_RESULT_NONE) { - rc = eeh_reset_device(pe, frozen_bus); + rc = eeh_reset_device(frozen_edev, frozen_bus); if (rc) { printk(KERN_WARNING "EEH: Unable to reset, rc=%d\n", rc); goto hard_fail; @@ -468,7 +450,7 @@ void eeh_handle_event(struct eeh_pe *pe) /* If all devices reported they can proceed, then re-enable MMIO */ if (result == PCI_ERS_RESULT_CAN_RECOVER) { - rc = eeh_pci_enable(pe, EEH_OPT_THAW_MMIO); + rc = eeh_pci_enable(frozen_edev, EEH_OPT_THAW_MMIO); if (rc < 0) goto hard_fail; @@ -476,13 +458,13 @@ void eeh_handle_event(struct eeh_pe *pe) result = PCI_ERS_RESULT_NEED_RESET; } else { result = PCI_ERS_RESULT_NONE; - eeh_pe_dev_traverse(pe, eeh_report_mmio_enabled, &result); + pci_walk_bus(frozen_bus, eeh_report_mmio_enabled, &result); } } /* If all devices reported they can proceed, then re-enable DMA */ if (result == PCI_ERS_RESULT_CAN_RECOVER) { - rc = eeh_pci_enable(pe, EEH_OPT_THAW_DMA); + rc = eeh_pci_enable(frozen_edev, EEH_OPT_THAW_DMA); if (rc < 0) goto hard_fail; @@ -500,13 +482,13 @@ void eeh_handle_event(struct eeh_pe *pe) /* If any device called out for a reset, then reset the slot */ if (result == PCI_ERS_RESULT_NEED_RESET) { - rc = eeh_reset_device(pe, NULL); + rc = eeh_reset_device(frozen_edev, NULL); if (rc) { printk(KERN_WARNING "EEH: Cannot reset, rc=%d\n", rc); goto hard_fail; } result = PCI_ERS_RESULT_NONE; - eeh_pe_dev_traverse(pe, eeh_report_reset, &result); + pci_walk_bus(frozen_bus, eeh_report_reset, &result); } /* All devices should claim they have recovered by now. */ @@ -517,9 +499,9 @@ void eeh_handle_event(struct eeh_pe *pe) } /* Tell all device drivers that they can resume operations */ - eeh_pe_dev_traverse(pe, eeh_report_resume, NULL); + pci_walk_bus(frozen_bus, eeh_report_resume, NULL); - return; + return frozen_edev; excess_failures: /* @@ -527,26 +509,30 @@ void eeh_handle_event(struct eeh_pe *pe) * are due to poorly seated PCI cards. Only 10% or so are * due to actual, failed cards. */ - pr_err("EEH: PHB#%d-PE#%x has failed %d times in the\n" - "last hour and has been permanently disabled.\n" - "Please try reseating or replacing it.\n", - pe->phb->global_number, pe->addr, - pe->freeze_count); + printk(KERN_ERR + "EEH: PCI device at location=%s driver=%s pci addr=%s\n" + "has failed %d times in the last hour " + "and has been permanently disabled.\n" + "Please try reseating this device or replacing it.\n", + location, drv_str, pci_str, frozen_edev->freeze_count); goto perm_error; hard_fail: - pr_err("EEH: Unable to recover from failure from PHB#%d-PE#%x.\n" - "Please try reseating or replacing it\n", - pe->phb->global_number, pe->addr); + printk(KERN_ERR + "EEH: Unable to recover from failure of PCI device " + "at location=%s driver=%s pci addr=%s\n" + "Please try reseating this device or replacing it.\n", + location, drv_str, pci_str); perm_error: - eeh_slot_error_detail(pe, EEH_LOG_PERM); + eeh_slot_error_detail(frozen_edev, EEH_LOG_PERM); /* Notify all devices that they're about to go down. */ - eeh_pe_dev_traverse(pe, eeh_report_failure, NULL); + pci_walk_bus(frozen_bus, eeh_report_failure, NULL); /* Shut down the device drivers for good. */ - if (frozen_bus) - pcibios_remove_pci_devices(frozen_bus); + pcibios_remove_pci_devices(frozen_bus); + + return NULL; } diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_event.c b/trunk/arch/powerpc/platforms/pseries/eeh_event.c index 51faaac8abe6..fb506317ebb0 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_event.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_event.c @@ -57,7 +57,7 @@ static int eeh_event_handler(void * dummy) { unsigned long flags; struct eeh_event *event; - struct eeh_pe *pe; + struct eeh_dev *edev; set_task_comm(current, "eehd"); @@ -76,23 +76,28 @@ static int eeh_event_handler(void * dummy) /* Serialize processing of EEH events */ mutex_lock(&eeh_event_mutex); - pe = event->pe; - eeh_pe_state_mark(pe, EEH_PE_RECOVERING); - pr_info("EEH: Detected PCI bus error on PHB#%d-PE#%x\n", - pe->phb->global_number, pe->addr); + edev = event->edev; + eeh_mark_slot(eeh_dev_to_of_node(edev), EEH_MODE_RECOVERING); + + printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n", + eeh_pci_name(edev->pdev)); set_current_state(TASK_INTERRUPTIBLE); /* Don't add to load average */ - eeh_handle_event(pe); - eeh_pe_state_clear(pe, EEH_PE_RECOVERING); + edev = handle_eeh_events(event); + + if (edev) { + eeh_clear_slot(eeh_dev_to_of_node(edev), EEH_MODE_RECOVERING); + pci_dev_put(edev->pdev); + } kfree(event); mutex_unlock(&eeh_event_mutex); /* If there are no new errors after an hour, clear the counter. */ - if (pe && pe->freeze_count > 0) { + if (edev && edev->freeze_count>0) { msleep_interruptible(3600*1000); - if (pe->freeze_count > 0) - pe->freeze_count--; + if (edev->freeze_count>0) + edev->freeze_count--; } @@ -114,23 +119,36 @@ static void eeh_thread_launcher(struct work_struct *dummy) /** * eeh_send_failure_event - Generate a PCI error event - * @pe: EEH PE + * @edev: EEH device * * This routine can be called within an interrupt context; * the actual event will be delivered in a normal context * (from a workqueue). */ -int eeh_send_failure_event(struct eeh_pe *pe) +int eeh_send_failure_event(struct eeh_dev *edev) { unsigned long flags; struct eeh_event *event; - - event = kzalloc(sizeof(*event), GFP_ATOMIC); - if (!event) { - pr_err("EEH: out of memory, event not handled\n"); - return -ENOMEM; + struct device_node *dn = eeh_dev_to_of_node(edev); + const char *location; + + if (!mem_init_done) { + printk(KERN_ERR "EEH: event during early boot not handled\n"); + location = of_get_property(dn, "ibm,loc-code", NULL); + printk(KERN_ERR "EEH: device node = %s\n", dn->full_name); + printk(KERN_ERR "EEH: PCI location = %s\n", location); + return 1; } - event->pe = pe; + event = kmalloc(sizeof(*event), GFP_ATOMIC); + if (event == NULL) { + printk(KERN_ERR "EEH: out of memory, event not handled\n"); + return 1; + } + + if (edev->pdev) + pci_dev_get(edev->pdev); + + event->edev = edev; /* We may or may not be called in an interrupt context */ spin_lock_irqsave(&eeh_eventlist_lock, flags); diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_pe.c b/trunk/arch/powerpc/platforms/pseries/eeh_pe.c deleted file mode 100644 index 9d35543736ed..000000000000 --- a/trunk/arch/powerpc/platforms/pseries/eeh_pe.c +++ /dev/null @@ -1,655 +0,0 @@ -/* - * The file intends to implement PE based on the information from - * platforms. Basically, there have 3 types of PEs: PHB/Bus/Device. - * All the PEs should be organized as hierarchy tree. The first level - * of the tree will be associated to existing PHBs since the particular - * PE is only meaningful in one PHB domain. - * - * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2012. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -static LIST_HEAD(eeh_phb_pe); - -/** - * eeh_pe_alloc - Allocate PE - * @phb: PCI controller - * @type: PE type - * - * Allocate PE instance dynamically. - */ -static struct eeh_pe *eeh_pe_alloc(struct pci_controller *phb, int type) -{ - struct eeh_pe *pe; - - /* Allocate PHB PE */ - pe = kzalloc(sizeof(struct eeh_pe), GFP_KERNEL); - if (!pe) return NULL; - - /* Initialize PHB PE */ - pe->type = type; - pe->phb = phb; - INIT_LIST_HEAD(&pe->child_list); - INIT_LIST_HEAD(&pe->child); - INIT_LIST_HEAD(&pe->edevs); - - return pe; -} - -/** - * eeh_phb_pe_create - Create PHB PE - * @phb: PCI controller - * - * The function should be called while the PHB is detected during - * system boot or PCI hotplug in order to create PHB PE. - */ -int __devinit eeh_phb_pe_create(struct pci_controller *phb) -{ - struct eeh_pe *pe; - - /* Allocate PHB PE */ - pe = eeh_pe_alloc(phb, EEH_PE_PHB); - if (!pe) { - pr_err("%s: out of memory!\n", __func__); - return -ENOMEM; - } - - /* Put it into the list */ - eeh_lock(); - list_add_tail(&pe->child, &eeh_phb_pe); - eeh_unlock(); - - pr_debug("EEH: Add PE for PHB#%d\n", phb->global_number); - - return 0; -} - -/** - * eeh_phb_pe_get - Retrieve PHB PE based on the given PHB - * @phb: PCI controller - * - * The overall PEs form hierarchy tree. The first layer of the - * hierarchy tree is composed of PHB PEs. The function is used - * to retrieve the corresponding PHB PE according to the given PHB. - */ -static struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb) -{ - struct eeh_pe *pe; - - list_for_each_entry(pe, &eeh_phb_pe, child) { - /* - * Actually, we needn't check the type since - * the PE for PHB has been determined when that - * was created. - */ - if ((pe->type & EEH_PE_PHB) && - pe->phb == phb) { - eeh_unlock(); - return pe; - } - } - - return NULL; -} - -/** - * eeh_pe_next - Retrieve the next PE in the tree - * @pe: current PE - * @root: root PE - * - * The function is used to retrieve the next PE in the - * hierarchy PE tree. - */ -static struct eeh_pe *eeh_pe_next(struct eeh_pe *pe, - struct eeh_pe *root) -{ - struct list_head *next = pe->child_list.next; - - if (next == &pe->child_list) { - while (1) { - if (pe == root) - return NULL; - next = pe->child.next; - if (next != &pe->parent->child_list) - break; - pe = pe->parent; - } - } - - return list_entry(next, struct eeh_pe, child); -} - -/** - * eeh_pe_traverse - Traverse PEs in the specified PHB - * @root: root PE - * @fn: callback - * @flag: extra parameter to callback - * - * The function is used to traverse the specified PE and its - * child PEs. The traversing is to be terminated once the - * callback returns something other than NULL, or no more PEs - * to be traversed. - */ -static void *eeh_pe_traverse(struct eeh_pe *root, - eeh_traverse_func fn, void *flag) -{ - struct eeh_pe *pe; - void *ret; - - for (pe = root; pe; pe = eeh_pe_next(pe, root)) { - ret = fn(pe, flag); - if (ret) return ret; - } - - return NULL; -} - -/** - * eeh_pe_dev_traverse - Traverse the devices from the PE - * @root: EEH PE - * @fn: function callback - * @flag: extra parameter to callback - * - * The function is used to traverse the devices of the specified - * PE and its child PEs. - */ -void *eeh_pe_dev_traverse(struct eeh_pe *root, - eeh_traverse_func fn, void *flag) -{ - struct eeh_pe *pe; - struct eeh_dev *edev; - void *ret; - - if (!root) { - pr_warning("%s: Invalid PE %p\n", __func__, root); - return NULL; - } - - eeh_lock(); - - /* Traverse root PE */ - for (pe = root; pe; pe = eeh_pe_next(pe, root)) { - eeh_pe_for_each_dev(pe, edev) { - ret = fn(edev, flag); - if (ret) { - eeh_unlock(); - return ret; - } - } - } - - eeh_unlock(); - - return NULL; -} - -/** - * __eeh_pe_get - Check the PE address - * @data: EEH PE - * @flag: EEH device - * - * For one particular PE, it can be identified by PE address - * or tranditional BDF address. BDF address is composed of - * Bus/Device/Function number. The extra data referred by flag - * indicates which type of address should be used. - */ -static void *__eeh_pe_get(void *data, void *flag) -{ - struct eeh_pe *pe = (struct eeh_pe *)data; - struct eeh_dev *edev = (struct eeh_dev *)flag; - - /* Unexpected PHB PE */ - if (pe->type & EEH_PE_PHB) - return NULL; - - /* We prefer PE address */ - if (edev->pe_config_addr && - (edev->pe_config_addr == pe->addr)) - return pe; - - /* Try BDF address */ - if (edev->pe_config_addr && - (edev->config_addr == pe->config_addr)) - return pe; - - return NULL; -} - -/** - * eeh_pe_get - Search PE based on the given address - * @edev: EEH device - * - * Search the corresponding PE based on the specified address which - * is included in the eeh device. The function is used to check if - * the associated PE has been created against the PE address. It's - * notable that the PE address has 2 format: traditional PE address - * which is composed of PCI bus/device/function number, or unified - * PE address. - */ -static struct eeh_pe *eeh_pe_get(struct eeh_dev *edev) -{ - struct eeh_pe *root = eeh_phb_pe_get(edev->phb); - struct eeh_pe *pe; - - pe = eeh_pe_traverse(root, __eeh_pe_get, edev); - - return pe; -} - -/** - * eeh_pe_get_parent - Retrieve the parent PE - * @edev: EEH device - * - * The whole PEs existing in the system are organized as hierarchy - * tree. The function is used to retrieve the parent PE according - * to the parent EEH device. - */ -static struct eeh_pe *eeh_pe_get_parent(struct eeh_dev *edev) -{ - struct device_node *dn; - struct eeh_dev *parent; - - /* - * It might have the case for the indirect parent - * EEH device already having associated PE, but - * the direct parent EEH device doesn't have yet. - */ - dn = edev->dn->parent; - while (dn) { - /* We're poking out of PCI territory */ - if (!PCI_DN(dn)) return NULL; - - parent = of_node_to_eeh_dev(dn); - /* We're poking out of PCI territory */ - if (!parent) return NULL; - - if (parent->pe) - return parent->pe; - - dn = dn->parent; - } - - return NULL; -} - -/** - * eeh_add_to_parent_pe - Add EEH device to parent PE - * @edev: EEH device - * - * Add EEH device to the parent PE. If the parent PE already - * exists, the PE type will be changed to EEH_PE_BUS. Otherwise, - * we have to create new PE to hold the EEH device and the new - * PE will be linked to its parent PE as well. - */ -int eeh_add_to_parent_pe(struct eeh_dev *edev) -{ - struct eeh_pe *pe, *parent; - - eeh_lock(); - - /* - * Search the PE has been existing or not according - * to the PE address. If that has been existing, the - * PE should be composed of PCI bus and its subordinate - * components. - */ - pe = eeh_pe_get(edev); - if (pe && !(pe->type & EEH_PE_INVALID)) { - if (!edev->pe_config_addr) { - eeh_unlock(); - pr_err("%s: PE with addr 0x%x already exists\n", - __func__, edev->config_addr); - return -EEXIST; - } - - /* Mark the PE as type of PCI bus */ - pe->type = EEH_PE_BUS; - edev->pe = pe; - - /* Put the edev to PE */ - list_add_tail(&edev->list, &pe->edevs); - eeh_unlock(); - pr_debug("EEH: Add %s to Bus PE#%x\n", - edev->dn->full_name, pe->addr); - - return 0; - } else if (pe && (pe->type & EEH_PE_INVALID)) { - list_add_tail(&edev->list, &pe->edevs); - edev->pe = pe; - /* - * We're running to here because of PCI hotplug caused by - * EEH recovery. We need clear EEH_PE_INVALID until the top. - */ - parent = pe; - while (parent) { - if (!(parent->type & EEH_PE_INVALID)) - break; - parent->type &= ~EEH_PE_INVALID; - parent = parent->parent; - } - eeh_unlock(); - pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n", - edev->dn->full_name, pe->addr, pe->parent->addr); - - return 0; - } - - /* Create a new EEH PE */ - pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE); - if (!pe) { - eeh_unlock(); - pr_err("%s: out of memory!\n", __func__); - return -ENOMEM; - } - pe->addr = edev->pe_config_addr; - pe->config_addr = edev->config_addr; - - /* - * Put the new EEH PE into hierarchy tree. If the parent - * can't be found, the newly created PE will be attached - * to PHB directly. Otherwise, we have to associate the - * PE with its parent. - */ - parent = eeh_pe_get_parent(edev); - if (!parent) { - parent = eeh_phb_pe_get(edev->phb); - if (!parent) { - eeh_unlock(); - pr_err("%s: No PHB PE is found (PHB Domain=%d)\n", - __func__, edev->phb->global_number); - edev->pe = NULL; - kfree(pe); - return -EEXIST; - } - } - pe->parent = parent; - - /* - * Put the newly created PE into the child list and - * link the EEH device accordingly. - */ - list_add_tail(&pe->child, &parent->child_list); - list_add_tail(&edev->list, &pe->edevs); - edev->pe = pe; - eeh_unlock(); - pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n", - edev->dn->full_name, pe->addr, pe->parent->addr); - - return 0; -} - -/** - * eeh_rmv_from_parent_pe - Remove one EEH device from the associated PE - * @edev: EEH device - * @purge_pe: remove PE or not - * - * The PE hierarchy tree might be changed when doing PCI hotplug. - * Also, the PCI devices or buses could be removed from the system - * during EEH recovery. So we have to call the function remove the - * corresponding PE accordingly if necessary. - */ -int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe) -{ - struct eeh_pe *pe, *parent, *child; - int cnt; - - if (!edev->pe) { - pr_warning("%s: No PE found for EEH device %s\n", - __func__, edev->dn->full_name); - return -EEXIST; - } - - eeh_lock(); - - /* Remove the EEH device */ - pe = edev->pe; - edev->pe = NULL; - list_del(&edev->list); - - /* - * Check if the parent PE includes any EEH devices. - * If not, we should delete that. Also, we should - * delete the parent PE if it doesn't have associated - * child PEs and EEH devices. - */ - while (1) { - parent = pe->parent; - if (pe->type & EEH_PE_PHB) - break; - - if (purge_pe) { - if (list_empty(&pe->edevs) && - list_empty(&pe->child_list)) { - list_del(&pe->child); - kfree(pe); - } else { - break; - } - } else { - if (list_empty(&pe->edevs)) { - cnt = 0; - list_for_each_entry(child, &pe->child_list, child) { - if (!(pe->type & EEH_PE_INVALID)) { - cnt++; - break; - } - } - - if (!cnt) - pe->type |= EEH_PE_INVALID; - else - break; - } - } - - pe = parent; - } - - eeh_unlock(); - - return 0; -} - -/** - * __eeh_pe_state_mark - Mark the state for the PE - * @data: EEH PE - * @flag: state - * - * The function is used to mark the indicated state for the given - * PE. Also, the associated PCI devices will be put into IO frozen - * state as well. - */ -static void *__eeh_pe_state_mark(void *data, void *flag) -{ - struct eeh_pe *pe = (struct eeh_pe *)data; - int state = *((int *)flag); - struct eeh_dev *tmp; - struct pci_dev *pdev; - - /* - * Mark the PE with the indicated state. Also, - * the associated PCI device will be put into - * I/O frozen state to avoid I/O accesses from - * the PCI device driver. - */ - pe->state |= state; - eeh_pe_for_each_dev(pe, tmp) { - pdev = eeh_dev_to_pci_dev(tmp); - if (pdev) - pdev->error_state = pci_channel_io_frozen; - } - - return NULL; -} - -/** - * eeh_pe_state_mark - Mark specified state for PE and its associated device - * @pe: EEH PE - * - * EEH error affects the current PE and its child PEs. The function - * is used to mark appropriate state for the affected PEs and the - * associated devices. - */ -void eeh_pe_state_mark(struct eeh_pe *pe, int state) -{ - eeh_lock(); - eeh_pe_traverse(pe, __eeh_pe_state_mark, &state); - eeh_unlock(); -} - -/** - * __eeh_pe_state_clear - Clear state for the PE - * @data: EEH PE - * @flag: state - * - * The function is used to clear the indicated state from the - * given PE. Besides, we also clear the check count of the PE - * as well. - */ -static void *__eeh_pe_state_clear(void *data, void *flag) -{ - struct eeh_pe *pe = (struct eeh_pe *)data; - int state = *((int *)flag); - - pe->state &= ~state; - pe->check_count = 0; - - return NULL; -} - -/** - * eeh_pe_state_clear - Clear state for the PE and its children - * @pe: PE - * @state: state to be cleared - * - * When the PE and its children has been recovered from error, - * we need clear the error state for that. The function is used - * for the purpose. - */ -void eeh_pe_state_clear(struct eeh_pe *pe, int state) -{ - eeh_lock(); - eeh_pe_traverse(pe, __eeh_pe_state_clear, &state); - eeh_unlock(); -} - -/** - * eeh_restore_one_device_bars - Restore the Base Address Registers for one device - * @data: EEH device - * @flag: Unused - * - * Loads the PCI configuration space base address registers, - * the expansion ROM base address, the latency timer, and etc. - * from the saved values in the device node. - */ -static void *eeh_restore_one_device_bars(void *data, void *flag) -{ - int i; - u32 cmd; - struct eeh_dev *edev = (struct eeh_dev *)data; - struct device_node *dn = eeh_dev_to_of_node(edev); - - for (i = 4; i < 10; i++) - eeh_ops->write_config(dn, i*4, 4, edev->config_space[i]); - /* 12 == Expansion ROM Address */ - eeh_ops->write_config(dn, 12*4, 4, edev->config_space[12]); - -#define BYTE_SWAP(OFF) (8*((OFF)/4)+3-(OFF)) -#define SAVED_BYTE(OFF) (((u8 *)(edev->config_space))[BYTE_SWAP(OFF)]) - - eeh_ops->write_config(dn, PCI_CACHE_LINE_SIZE, 1, - SAVED_BYTE(PCI_CACHE_LINE_SIZE)); - eeh_ops->write_config(dn, PCI_LATENCY_TIMER, 1, - SAVED_BYTE(PCI_LATENCY_TIMER)); - - /* max latency, min grant, interrupt pin and line */ - eeh_ops->write_config(dn, 15*4, 4, edev->config_space[15]); - - /* - * Restore PERR & SERR bits, some devices require it, - * don't touch the other command bits - */ - eeh_ops->read_config(dn, PCI_COMMAND, 4, &cmd); - if (edev->config_space[1] & PCI_COMMAND_PARITY) - cmd |= PCI_COMMAND_PARITY; - else - cmd &= ~PCI_COMMAND_PARITY; - if (edev->config_space[1] & PCI_COMMAND_SERR) - cmd |= PCI_COMMAND_SERR; - else - cmd &= ~PCI_COMMAND_SERR; - eeh_ops->write_config(dn, PCI_COMMAND, 4, cmd); - - return NULL; -} - -/** - * eeh_pe_restore_bars - Restore the PCI config space info - * @pe: EEH PE - * - * This routine performs a recursive walk to the children - * of this device as well. - */ -void eeh_pe_restore_bars(struct eeh_pe *pe) -{ - /* - * We needn't take the EEH lock since eeh_pe_dev_traverse() - * will take that. - */ - eeh_pe_dev_traverse(pe, eeh_restore_one_device_bars, NULL); -} - -/** - * eeh_pe_bus_get - Retrieve PCI bus according to the given PE - * @pe: EEH PE - * - * Retrieve the PCI bus according to the given PE. Basically, - * there're 3 types of PEs: PHB/Bus/Device. For PHB PE, the - * primary PCI bus will be retrieved. The parent bus will be - * returned for BUS PE. However, we don't have associated PCI - * bus for DEVICE PE. - */ -struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe) -{ - struct pci_bus *bus = NULL; - struct eeh_dev *edev; - struct pci_dev *pdev; - - eeh_lock(); - - if (pe->type & EEH_PE_PHB) { - bus = pe->phb->bus; - } else if (pe->type & EEH_PE_BUS) { - edev = list_first_entry(&pe->edevs, struct eeh_dev, list); - pdev = eeh_dev_to_pci_dev(edev); - if (pdev) - bus = pdev->bus; - } - - eeh_unlock(); - - return bus; -} diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_pseries.c b/trunk/arch/powerpc/platforms/pseries/eeh_pseries.c index 19506f935737..c33360ec4f4f 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_pseries.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_pseries.c @@ -129,117 +129,27 @@ static int pseries_eeh_init(void) eeh_error_buf_size = RTAS_ERROR_LOG_MAX; } - /* Set EEH probe mode */ - eeh_probe_mode_set(EEH_PROBE_MODE_DEVTREE); - return 0; } -/** - * pseries_eeh_of_probe - EEH probe on the given device - * @dn: OF node - * @flag: Unused - * - * When EEH module is installed during system boot, all PCI devices - * are checked one by one to see if it supports EEH. The function - * is introduced for the purpose. - */ -static void *pseries_eeh_of_probe(struct device_node *dn, void *flag) -{ - struct eeh_dev *edev; - struct eeh_pe pe; - const u32 *class_code, *vendor_id, *device_id; - const u32 *regs; - int enable = 0; - int ret; - - /* Retrieve OF node and eeh device */ - edev = of_node_to_eeh_dev(dn); - if (!of_device_is_available(dn)) - return NULL; - - /* Retrieve class/vendor/device IDs */ - class_code = of_get_property(dn, "class-code", NULL); - vendor_id = of_get_property(dn, "vendor-id", NULL); - device_id = of_get_property(dn, "device-id", NULL); - - /* Skip for bad OF node or PCI-ISA bridge */ - if (!class_code || !vendor_id || !device_id) - return NULL; - if (dn->type && !strcmp(dn->type, "isa")) - return NULL; - - /* Update class code and mode of eeh device */ - edev->class_code = *class_code; - edev->mode = 0; - - /* Retrieve the device address */ - regs = of_get_property(dn, "reg", NULL); - if (!regs) { - pr_warning("%s: OF node property %s::reg not found\n", - __func__, dn->full_name); - return NULL; - } - - /* Initialize the fake PE */ - memset(&pe, 0, sizeof(struct eeh_pe)); - pe.phb = edev->phb; - pe.config_addr = regs[0]; - - /* Enable EEH on the device */ - ret = eeh_ops->set_option(&pe, EEH_OPT_ENABLE); - if (!ret) { - edev->config_addr = regs[0]; - /* Retrieve PE address */ - edev->pe_config_addr = eeh_ops->get_pe_addr(&pe); - pe.addr = edev->pe_config_addr; - - /* Some older systems (Power4) allow the ibm,set-eeh-option - * call to succeed even on nodes where EEH is not supported. - * Verify support explicitly. - */ - ret = eeh_ops->get_state(&pe, NULL); - if (ret > 0 && ret != EEH_STATE_NOT_SUPPORT) - enable = 1; - - if (enable) { - eeh_subsystem_enabled = 1; - eeh_add_to_parent_pe(edev); - - pr_debug("%s: EEH enabled on %s PHB#%d-PE#%x, config addr#%x\n", - __func__, dn->full_name, pe.phb->global_number, - pe.addr, pe.config_addr); - } else if (dn->parent && of_node_to_eeh_dev(dn->parent) && - (of_node_to_eeh_dev(dn->parent))->pe) { - /* This device doesn't support EEH, but it may have an - * EEH parent, in which case we mark it as supported. - */ - edev->config_addr = of_node_to_eeh_dev(dn->parent)->config_addr; - edev->pe_config_addr = of_node_to_eeh_dev(dn->parent)->pe_config_addr; - eeh_add_to_parent_pe(edev); - } - } - - /* Save memory bars */ - eeh_save_bars(edev); - - return NULL; -} - /** * pseries_eeh_set_option - Initialize EEH or MMIO/DMA reenable - * @pe: EEH PE + * @dn: device node * @option: operation to be issued * * The function is used to control the EEH functionality globally. * Currently, following options are support according to PAPR: * Enable EEH, Disable EEH, Enable MMIO and Enable DMA */ -static int pseries_eeh_set_option(struct eeh_pe *pe, int option) +static int pseries_eeh_set_option(struct device_node *dn, int option) { int ret = 0; + struct eeh_dev *edev; + const u32 *reg; int config_addr; + edev = of_node_to_eeh_dev(dn); + /* * When we're enabling or disabling EEH functioality on * the particular PE, the PE config address is possibly @@ -249,11 +159,15 @@ static int pseries_eeh_set_option(struct eeh_pe *pe, int option) switch (option) { case EEH_OPT_DISABLE: case EEH_OPT_ENABLE: + reg = of_get_property(dn, "reg", NULL); + config_addr = reg[0]; + break; + case EEH_OPT_THAW_MMIO: case EEH_OPT_THAW_DMA: - config_addr = pe->config_addr; - if (pe->addr) - config_addr = pe->addr; + config_addr = edev->config_addr; + if (edev->pe_config_addr) + config_addr = edev->pe_config_addr; break; default: @@ -263,15 +177,15 @@ static int pseries_eeh_set_option(struct eeh_pe *pe, int option) } ret = rtas_call(ibm_set_eeh_option, 4, 1, NULL, - config_addr, BUID_HI(pe->phb->buid), - BUID_LO(pe->phb->buid), option); + config_addr, BUID_HI(edev->phb->buid), + BUID_LO(edev->phb->buid), option); return ret; } /** * pseries_eeh_get_pe_addr - Retrieve PE address - * @pe: EEH PE + * @dn: device node * * Retrieve the assocated PE address. Actually, there're 2 RTAS * function calls dedicated for the purpose. We need implement @@ -282,11 +196,14 @@ static int pseries_eeh_set_option(struct eeh_pe *pe, int option) * It's notable that zero'ed return value means invalid PE config * address. */ -static int pseries_eeh_get_pe_addr(struct eeh_pe *pe) +static int pseries_eeh_get_pe_addr(struct device_node *dn) { + struct eeh_dev *edev; int ret = 0; int rets[3]; + edev = of_node_to_eeh_dev(dn); + if (ibm_get_config_addr_info2 != RTAS_UNKNOWN_SERVICE) { /* * First of all, we need to make sure there has one PE @@ -294,18 +211,18 @@ static int pseries_eeh_get_pe_addr(struct eeh_pe *pe) * meaningless. */ ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets, - pe->config_addr, BUID_HI(pe->phb->buid), - BUID_LO(pe->phb->buid), 1); + edev->config_addr, BUID_HI(edev->phb->buid), + BUID_LO(edev->phb->buid), 1); if (ret || (rets[0] == 0)) return 0; /* Retrieve the associated PE config address */ ret = rtas_call(ibm_get_config_addr_info2, 4, 2, rets, - pe->config_addr, BUID_HI(pe->phb->buid), - BUID_LO(pe->phb->buid), 0); + edev->config_addr, BUID_HI(edev->phb->buid), + BUID_LO(edev->phb->buid), 0); if (ret) { - pr_warning("%s: Failed to get address for PHB#%d-PE#%x\n", - __func__, pe->phb->global_number, pe->config_addr); + pr_warning("%s: Failed to get PE address for %s\n", + __func__, dn->full_name); return 0; } @@ -314,11 +231,11 @@ static int pseries_eeh_get_pe_addr(struct eeh_pe *pe) if (ibm_get_config_addr_info != RTAS_UNKNOWN_SERVICE) { ret = rtas_call(ibm_get_config_addr_info, 4, 2, rets, - pe->config_addr, BUID_HI(pe->phb->buid), - BUID_LO(pe->phb->buid), 0); + edev->config_addr, BUID_HI(edev->phb->buid), + BUID_LO(edev->phb->buid), 0); if (ret) { - pr_warning("%s: Failed to get address for PHB#%d-PE#%x\n", - __func__, pe->phb->global_number, pe->config_addr); + pr_warning("%s: Failed to get PE address for %s\n", + __func__, dn->full_name); return 0; } @@ -330,7 +247,7 @@ static int pseries_eeh_get_pe_addr(struct eeh_pe *pe) /** * pseries_eeh_get_state - Retrieve PE state - * @pe: EEH PE + * @dn: PE associated device node * @state: return value * * Retrieve the state of the specified PE. On RTAS compliant @@ -341,28 +258,30 @@ static int pseries_eeh_get_pe_addr(struct eeh_pe *pe) * RTAS calls for the purpose, we need to try the new one and back * to the old one if the new one couldn't work properly. */ -static int pseries_eeh_get_state(struct eeh_pe *pe, int *state) +static int pseries_eeh_get_state(struct device_node *dn, int *state) { + struct eeh_dev *edev; int config_addr; int ret; int rets[4]; int result; /* Figure out PE config address if possible */ - config_addr = pe->config_addr; - if (pe->addr) - config_addr = pe->addr; + edev = of_node_to_eeh_dev(dn); + config_addr = edev->config_addr; + if (edev->pe_config_addr) + config_addr = edev->pe_config_addr; if (ibm_read_slot_reset_state2 != RTAS_UNKNOWN_SERVICE) { ret = rtas_call(ibm_read_slot_reset_state2, 3, 4, rets, - config_addr, BUID_HI(pe->phb->buid), - BUID_LO(pe->phb->buid)); + config_addr, BUID_HI(edev->phb->buid), + BUID_LO(edev->phb->buid)); } else if (ibm_read_slot_reset_state != RTAS_UNKNOWN_SERVICE) { /* Fake PE unavailable info */ rets[2] = 0; ret = rtas_call(ibm_read_slot_reset_state, 3, 3, rets, - config_addr, BUID_HI(pe->phb->buid), - BUID_LO(pe->phb->buid)); + config_addr, BUID_HI(edev->phb->buid), + BUID_LO(edev->phb->buid)); } else { return EEH_STATE_NOT_SUPPORT; } @@ -414,32 +333,34 @@ static int pseries_eeh_get_state(struct eeh_pe *pe, int *state) /** * pseries_eeh_reset - Reset the specified PE - * @pe: EEH PE + * @dn: PE associated device node * @option: reset option * * Reset the specified PE */ -static int pseries_eeh_reset(struct eeh_pe *pe, int option) +static int pseries_eeh_reset(struct device_node *dn, int option) { + struct eeh_dev *edev; int config_addr; int ret; /* Figure out PE address */ - config_addr = pe->config_addr; - if (pe->addr) - config_addr = pe->addr; + edev = of_node_to_eeh_dev(dn); + config_addr = edev->config_addr; + if (edev->pe_config_addr) + config_addr = edev->pe_config_addr; /* Reset PE through RTAS call */ ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL, - config_addr, BUID_HI(pe->phb->buid), - BUID_LO(pe->phb->buid), option); + config_addr, BUID_HI(edev->phb->buid), + BUID_LO(edev->phb->buid), option); /* If fundamental-reset not supported, try hot-reset */ if (option == EEH_RESET_FUNDAMENTAL && ret == -8) { ret = rtas_call(ibm_set_slot_reset, 4, 1, NULL, - config_addr, BUID_HI(pe->phb->buid), - BUID_LO(pe->phb->buid), EEH_RESET_HOT); + config_addr, BUID_HI(edev->phb->buid), + BUID_LO(edev->phb->buid), EEH_RESET_HOT); } return ret; @@ -447,13 +368,13 @@ static int pseries_eeh_reset(struct eeh_pe *pe, int option) /** * pseries_eeh_wait_state - Wait for PE state - * @pe: EEH PE + * @dn: PE associated device node * @max_wait: maximal period in microsecond * * Wait for the state of associated PE. It might take some time * to retrieve the PE's state. */ -static int pseries_eeh_wait_state(struct eeh_pe *pe, int max_wait) +static int pseries_eeh_wait_state(struct device_node *dn, int max_wait) { int ret; int mwait; @@ -470,7 +391,7 @@ static int pseries_eeh_wait_state(struct eeh_pe *pe, int max_wait) #define EEH_STATE_MAX_WAIT_TIME (300 * 1000) while (1) { - ret = pseries_eeh_get_state(pe, &mwait); + ret = pseries_eeh_get_state(dn, &mwait); /* * If the PE's state is temporarily unavailable, @@ -505,7 +426,7 @@ static int pseries_eeh_wait_state(struct eeh_pe *pe, int max_wait) /** * pseries_eeh_get_log - Retrieve error log - * @pe: EEH PE + * @dn: device node * @severity: temporary or permanent error log * @drv_log: driver log to be combined with retrieved error log * @len: length of driver log @@ -514,22 +435,24 @@ static int pseries_eeh_wait_state(struct eeh_pe *pe, int max_wait) * Actually, the error will be retrieved through the dedicated * RTAS call. */ -static int pseries_eeh_get_log(struct eeh_pe *pe, int severity, char *drv_log, unsigned long len) +static int pseries_eeh_get_log(struct device_node *dn, int severity, char *drv_log, unsigned long len) { + struct eeh_dev *edev; int config_addr; unsigned long flags; int ret; + edev = of_node_to_eeh_dev(dn); spin_lock_irqsave(&slot_errbuf_lock, flags); memset(slot_errbuf, 0, eeh_error_buf_size); /* Figure out the PE address */ - config_addr = pe->config_addr; - if (pe->addr) - config_addr = pe->addr; + config_addr = edev->config_addr; + if (edev->pe_config_addr) + config_addr = edev->pe_config_addr; ret = rtas_call(ibm_slot_error_detail, 8, 1, NULL, config_addr, - BUID_HI(pe->phb->buid), BUID_LO(pe->phb->buid), + BUID_HI(edev->phb->buid), BUID_LO(edev->phb->buid), virt_to_phys(drv_log), len, virt_to_phys(slot_errbuf), eeh_error_buf_size, severity); @@ -542,38 +465,40 @@ static int pseries_eeh_get_log(struct eeh_pe *pe, int severity, char *drv_log, u /** * pseries_eeh_configure_bridge - Configure PCI bridges in the indicated PE - * @pe: EEH PE + * @dn: PE associated device node * * The function will be called to reconfigure the bridges included * in the specified PE so that the mulfunctional PE would be recovered * again. */ -static int pseries_eeh_configure_bridge(struct eeh_pe *pe) +static int pseries_eeh_configure_bridge(struct device_node *dn) { + struct eeh_dev *edev; int config_addr; int ret; /* Figure out the PE address */ - config_addr = pe->config_addr; - if (pe->addr) - config_addr = pe->addr; + edev = of_node_to_eeh_dev(dn); + config_addr = edev->config_addr; + if (edev->pe_config_addr) + config_addr = edev->pe_config_addr; /* Use new configure-pe function, if supported */ if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) { ret = rtas_call(ibm_configure_pe, 3, 1, NULL, - config_addr, BUID_HI(pe->phb->buid), - BUID_LO(pe->phb->buid)); + config_addr, BUID_HI(edev->phb->buid), + BUID_LO(edev->phb->buid)); } else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) { ret = rtas_call(ibm_configure_bridge, 3, 1, NULL, - config_addr, BUID_HI(pe->phb->buid), - BUID_LO(pe->phb->buid)); + config_addr, BUID_HI(edev->phb->buid), + BUID_LO(edev->phb->buid)); } else { return -EFAULT; } if (ret) - pr_warning("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n", - __func__, pe->phb->global_number, pe->addr, ret); + pr_warning("%s: Unable to configure bridge %d for %s\n", + __func__, ret, dn->full_name); return ret; } @@ -617,8 +542,6 @@ static int pseries_eeh_write_config(struct device_node *dn, int where, int size, static struct eeh_ops pseries_eeh_ops = { .name = "pseries", .init = pseries_eeh_init, - .of_probe = pseries_eeh_of_probe, - .dev_probe = NULL, .set_option = pseries_eeh_set_option, .get_pe_addr = pseries_eeh_get_pe_addr, .get_state = pseries_eeh_get_state, @@ -636,21 +559,7 @@ static struct eeh_ops pseries_eeh_ops = { * EEH initialization on pseries platform. This function should be * called before any EEH related functions. */ -static int __init eeh_pseries_init(void) +int __init eeh_pseries_init(void) { - int ret = -EINVAL; - - if (!machine_is(pseries)) - return ret; - - ret = eeh_ops_register(&pseries_eeh_ops); - if (!ret) - pr_info("EEH: pSeries platform initialized\n"); - else - pr_info("EEH: pSeries platform initialization failure (%d)\n", - ret); - - return ret; + return eeh_ops_register(&pseries_eeh_ops); } - -early_initcall(eeh_pseries_init); diff --git a/trunk/arch/powerpc/platforms/pseries/eeh_sysfs.c b/trunk/arch/powerpc/platforms/pseries/eeh_sysfs.c index d37708360f2e..243b3510d70f 100644 --- a/trunk/arch/powerpc/platforms/pseries/eeh_sysfs.c +++ b/trunk/arch/powerpc/platforms/pseries/eeh_sysfs.c @@ -53,6 +53,9 @@ static DEVICE_ATTR(_name, S_IRUGO, eeh_show_##_name, NULL); EEH_SHOW_ATTR(eeh_mode, mode, "0x%x"); EEH_SHOW_ATTR(eeh_config_addr, config_addr, "0x%x"); EEH_SHOW_ATTR(eeh_pe_config_addr, pe_config_addr, "0x%x"); +EEH_SHOW_ATTR(eeh_check_count, check_count, "%d" ); +EEH_SHOW_ATTR(eeh_freeze_count, freeze_count, "%d" ); +EEH_SHOW_ATTR(eeh_false_positives, false_positives, "%d" ); void eeh_sysfs_add_device(struct pci_dev *pdev) { @@ -61,6 +64,9 @@ void eeh_sysfs_add_device(struct pci_dev *pdev) rc += device_create_file(&pdev->dev, &dev_attr_eeh_mode); rc += device_create_file(&pdev->dev, &dev_attr_eeh_config_addr); rc += device_create_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); + rc += device_create_file(&pdev->dev, &dev_attr_eeh_check_count); + rc += device_create_file(&pdev->dev, &dev_attr_eeh_false_positives); + rc += device_create_file(&pdev->dev, &dev_attr_eeh_freeze_count); if (rc) printk(KERN_WARNING "EEH: Unable to create sysfs entries\n"); @@ -71,5 +77,8 @@ void eeh_sysfs_remove_device(struct pci_dev *pdev) device_remove_file(&pdev->dev, &dev_attr_eeh_mode); device_remove_file(&pdev->dev, &dev_attr_eeh_config_addr); device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr); + device_remove_file(&pdev->dev, &dev_attr_eeh_check_count); + device_remove_file(&pdev->dev, &dev_attr_eeh_false_positives); + device_remove_file(&pdev->dev, &dev_attr_eeh_freeze_count); } diff --git a/trunk/arch/powerpc/platforms/pseries/iommu.c b/trunk/arch/powerpc/platforms/pseries/iommu.c index 6153eea27ce7..bca220f2873c 100644 --- a/trunk/arch/powerpc/platforms/pseries/iommu.c +++ b/trunk/arch/powerpc/platforms/pseries/iommu.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include /* for show_stack */ #include @@ -42,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -99,7 +99,7 @@ static int tce_build_pSeries(struct iommu_table *tbl, long index, while (npages--) { /* can't move this out since we might cross MEMBLOCK boundary */ - rpn = __pa(uaddr) >> TCE_SHIFT; + rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; uaddr += TCE_PAGE_SIZE; @@ -148,7 +148,7 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, int ret = 0; long tcenum_start = tcenum, npages_start = npages; - rpn = __pa(uaddr) >> TCE_SHIFT; + rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; proto_tce = TCE_PCI_READ; if (direction != DMA_TO_DEVICE) proto_tce |= TCE_PCI_WRITE; @@ -217,7 +217,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, __get_cpu_var(tce_page) = tcep; } - rpn = __pa(uaddr) >> TCE_SHIFT; + rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; proto_tce = TCE_PCI_READ; if (direction != DMA_TO_DEVICE) proto_tce |= TCE_PCI_WRITE; @@ -237,7 +237,7 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, rc = plpar_tce_put_indirect((u64)tbl->it_index, (u64)tcenum << 12, - (u64)__pa(tcep), + (u64)virt_to_abs(tcep), limit); npages -= limit; @@ -441,7 +441,7 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn, rc = plpar_tce_put_indirect(liobn, dma_offset, - (u64)__pa(tcep), + (u64)virt_to_abs(tcep), limit); num_tce -= limit; diff --git a/trunk/arch/powerpc/platforms/pseries/lpar.c b/trunk/arch/powerpc/platforms/pseries/lpar.c index 0da39fed355a..5f3ef876ded2 100644 --- a/trunk/arch/powerpc/platforms/pseries/lpar.c +++ b/trunk/arch/powerpc/platforms/pseries/lpar.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -107,9 +108,9 @@ void vpa_init(int cpu) } static long pSeries_lpar_hpte_insert(unsigned long hpte_group, - unsigned long vpn, unsigned long pa, - unsigned long rflags, unsigned long vflags, - int psize, int ssize) + unsigned long va, unsigned long pa, + unsigned long rflags, unsigned long vflags, + int psize, int ssize) { unsigned long lpar_rc; unsigned long flags; @@ -117,11 +118,11 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group, unsigned long hpte_v, hpte_r; if (!(vflags & HPTE_V_BOLTED)) - pr_devel("hpte_insert(group=%lx, vpn=%016lx, " - "pa=%016lx, rflags=%lx, vflags=%lx, psize=%d)\n", - hpte_group, vpn, pa, rflags, vflags, psize); + pr_devel("hpte_insert(group=%lx, va=%016lx, pa=%016lx, " + "rflags=%lx, vflags=%lx, psize=%d)\n", + hpte_group, va, pa, rflags, vflags, psize); - hpte_v = hpte_encode_v(vpn, psize, ssize) | vflags | HPTE_V_VALID; + hpte_v = hpte_encode_v(va, psize, ssize) | vflags | HPTE_V_VALID; hpte_r = hpte_encode_r(pa, psize) | rflags; if (!(vflags & HPTE_V_BOLTED)) @@ -225,6 +226,22 @@ static void pSeries_lpar_hptab_clear(void) } } +/* + * This computes the AVPN and B fields of the first dword of a HPTE, + * for use when we want to match an existing PTE. The bottom 7 bits + * of the returned value are zero. + */ +static inline unsigned long hpte_encode_avpn(unsigned long va, int psize, + int ssize) +{ + unsigned long v; + + v = (va >> 23) & ~(mmu_psize_defs[psize].avpnm); + v <<= HPTE_V_AVPN_SHIFT; + v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT; + return v; +} + /* * NOTE: for updatepp ops we are fortunate that the linux "newpp" bits and * the low 3 bits of flags happen to line up. So no transform is needed. @@ -233,14 +250,14 @@ static void pSeries_lpar_hptab_clear(void) */ static long pSeries_lpar_hpte_updatepp(unsigned long slot, unsigned long newpp, - unsigned long vpn, + unsigned long va, int psize, int ssize, int local) { unsigned long lpar_rc; unsigned long flags = (newpp & 7) | H_AVPN; unsigned long want_v; - want_v = hpte_encode_avpn(vpn, psize, ssize); + want_v = hpte_encode_avpn(va, psize, ssize); pr_devel(" update: avpnv=%016lx, hash=%016lx, f=%lx, psize: %d ...", want_v, slot, flags, psize); @@ -278,15 +295,15 @@ static unsigned long pSeries_lpar_hpte_getword0(unsigned long slot) return dword0; } -static long pSeries_lpar_hpte_find(unsigned long vpn, int psize, int ssize) +static long pSeries_lpar_hpte_find(unsigned long va, int psize, int ssize) { unsigned long hash; unsigned long i; long slot; unsigned long want_v, hpte_v; - hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, ssize); - want_v = hpte_encode_avpn(vpn, psize, ssize); + hash = hpt_hash(va, mmu_psize_defs[psize].shift, ssize); + want_v = hpte_encode_avpn(va, psize, ssize); /* Bolted entries are always in the primary group */ slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; @@ -306,13 +323,12 @@ static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp, unsigned long ea, int psize, int ssize) { - unsigned long vpn; - unsigned long lpar_rc, slot, vsid, flags; + unsigned long lpar_rc, slot, vsid, va, flags; vsid = get_kernel_vsid(ea, ssize); - vpn = hpt_vpn(ea, vsid, ssize); + va = hpt_va(ea, vsid, ssize); - slot = pSeries_lpar_hpte_find(vpn, psize, ssize); + slot = pSeries_lpar_hpte_find(va, psize, ssize); BUG_ON(slot == -1); flags = newpp & 7; @@ -321,17 +337,17 @@ static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp, BUG_ON(lpar_rc != H_SUCCESS); } -static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long vpn, +static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va, int psize, int ssize, int local) { unsigned long want_v; unsigned long lpar_rc; unsigned long dummy1, dummy2; - pr_devel(" inval : slot=%lx, vpn=%016lx, psize: %d, local: %d\n", - slot, vpn, psize, local); + pr_devel(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n", + slot, va, psize, local); - want_v = hpte_encode_avpn(vpn, psize, ssize); + want_v = hpte_encode_avpn(va, psize, ssize); lpar_rc = plpar_pte_remove(H_AVPN, slot, want_v, &dummy1, &dummy2); if (lpar_rc == H_NOT_FOUND) return; @@ -342,16 +358,15 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long vpn, static void pSeries_lpar_hpte_removebolted(unsigned long ea, int psize, int ssize) { - unsigned long vpn; - unsigned long slot, vsid; + unsigned long slot, vsid, va; vsid = get_kernel_vsid(ea, ssize); - vpn = hpt_vpn(ea, vsid, ssize); + va = hpt_va(ea, vsid, ssize); - slot = pSeries_lpar_hpte_find(vpn, psize, ssize); + slot = pSeries_lpar_hpte_find(va, psize, ssize); BUG_ON(slot == -1); - pSeries_lpar_hpte_invalidate(slot, vpn, psize, ssize, 0); + pSeries_lpar_hpte_invalidate(slot, va, psize, ssize, 0); } /* Flag bits for H_BULK_REMOVE */ @@ -367,12 +382,12 @@ static void pSeries_lpar_hpte_removebolted(unsigned long ea, */ static void pSeries_lpar_flush_hash_range(unsigned long number, int local) { - unsigned long vpn; unsigned long i, pix, rc; unsigned long flags = 0; struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE); unsigned long param[9]; + unsigned long va; unsigned long hash, index, shift, hidx, slot; real_pte_t pte; int psize, ssize; @@ -384,21 +399,21 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local) ssize = batch->ssize; pix = 0; for (i = 0; i < number; i++) { - vpn = batch->vpn[i]; + va = batch->vaddr[i]; pte = batch->pte[i]; - pte_iterate_hashed_subpages(pte, psize, vpn, index, shift) { - hash = hpt_hash(vpn, shift, ssize); + pte_iterate_hashed_subpages(pte, psize, va, index, shift) { + hash = hpt_hash(va, shift, ssize); hidx = __rpte_to_hidx(pte, index); if (hidx & _PTEIDX_SECONDARY) hash = ~hash; slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; slot += hidx & _PTEIDX_GROUP_IX; if (!firmware_has_feature(FW_FEATURE_BULK_REMOVE)) { - pSeries_lpar_hpte_invalidate(slot, vpn, psize, + pSeries_lpar_hpte_invalidate(slot, va, psize, ssize, local); } else { param[pix] = HBR_REQUEST | HBR_AVPN | slot; - param[pix+1] = hpte_encode_avpn(vpn, psize, + param[pix+1] = hpte_encode_avpn(va, psize, ssize); pix += 2; if (pix == 8) { diff --git a/trunk/arch/powerpc/platforms/pseries/msi.c b/trunk/arch/powerpc/platforms/pseries/msi.c index d19f4977c834..109fdb75578d 100644 --- a/trunk/arch/powerpc/platforms/pseries/msi.c +++ b/trunk/arch/powerpc/platforms/pseries/msi.c @@ -210,7 +210,6 @@ static struct device_node *find_pe_total_msi(struct pci_dev *dev, int *total) static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) { struct device_node *dn; - struct eeh_dev *edev; /* Found our PE and assume 8 at that point. */ @@ -218,10 +217,7 @@ static struct device_node *find_pe_dn(struct pci_dev *dev, int *total) if (!dn) return NULL; - /* Get the top level device in the PE */ - edev = of_node_to_eeh_dev(dn); - edev = list_first_entry(&edev->pe->edevs, struct eeh_dev, list); - dn = eeh_dev_to_of_node(edev); + dn = eeh_find_device_pe(dn); if (!dn) return NULL; @@ -391,13 +387,12 @@ static int check_msix_entries(struct pci_dev *pdev) return 0; } -static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) +static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) { struct pci_dn *pdn; int hwirq, virq, i, rc; struct msi_desc *entry; struct msi_msg msg; - int nvec = nvec_in; pdn = get_pdn(pdev); if (!pdn) @@ -406,24 +401,11 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) if (type == PCI_CAP_ID_MSIX && check_msix_entries(pdev)) return -EINVAL; - /* - * Firmware currently refuse any non power of two allocation - * so we round up if the quota will allow it. - */ - if (type == PCI_CAP_ID_MSIX) { - int m = roundup_pow_of_two(nvec); - int quota = msi_quota_for_device(pdev, m); - - if (quota >= m) - nvec = m; - } - /* * Try the new more explicit firmware interface, if that fails fall * back to the old interface. The old interface is known to never * return MSI-Xs. */ -again: if (type == PCI_CAP_ID_MSI) { rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec); @@ -435,10 +417,6 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec); if (rc != nvec) { - if (nvec != nvec_in) { - nvec = nvec_in; - goto again; - } pr_debug("rtas_msi: rtas_change_msi() failed\n"); return rc; } diff --git a/trunk/arch/powerpc/platforms/pseries/pci.c b/trunk/arch/powerpc/platforms/pseries/pci.c index 56b864d777ee..2c6ded29f73d 100644 --- a/trunk/arch/powerpc/platforms/pseries/pci.c +++ b/trunk/arch/powerpc/platforms/pseries/pci.c @@ -73,7 +73,7 @@ void __init pSeries_final_fixup(void) { pSeries_request_regions(); - eeh_addr_cache_build(); + pci_addr_cache_build(); } /* diff --git a/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c b/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c index 261a577a3dd2..3ccebc83dc02 100644 --- a/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c +++ b/trunk/arch/powerpc/platforms/pseries/pci_dlpar.c @@ -65,43 +65,27 @@ pcibios_find_pci_bus(struct device_node *dn) EXPORT_SYMBOL_GPL(pcibios_find_pci_bus); /** - * __pcibios_remove_pci_devices - remove all devices under this bus - * @bus: the indicated PCI bus - * @purge_pe: destroy the PE on removal of PCI devices + * pcibios_remove_pci_devices - remove all devices under this bus * * Remove all of the PCI devices under this bus both from the * linux pci device tree, and from the powerpc EEH address cache. - * By default, the corresponding PE will be destroied during the - * normal PCI hotplug path. For PCI hotplug during EEH recovery, - * the corresponding PE won't be destroied and deallocated. */ -void __pcibios_remove_pci_devices(struct pci_bus *bus, int purge_pe) +void pcibios_remove_pci_devices(struct pci_bus *bus) { - struct pci_dev *dev, *tmp; + struct pci_dev *dev, *tmp; struct pci_bus *child_bus; /* First go down child busses */ list_for_each_entry(child_bus, &bus->children, node) - __pcibios_remove_pci_devices(child_bus, purge_pe); + pcibios_remove_pci_devices(child_bus); pr_debug("PCI: Removing devices on bus %04x:%02x\n", - pci_domain_nr(bus), bus->number); + pci_domain_nr(bus), bus->number); list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { pr_debug(" * Removing %s...\n", pci_name(dev)); - eeh_remove_bus_device(dev, purge_pe); - pci_stop_and_remove_bus_device(dev); - } -} - -/** - * pcibios_remove_pci_devices - remove all devices under this bus - * - * Remove all of the PCI devices under this bus both from the - * linux pci device tree, and from the powerpc EEH address cache. - */ -void pcibios_remove_pci_devices(struct pci_bus *bus) -{ - __pcibios_remove_pci_devices(bus, 1); + eeh_remove_bus_device(dev); + pci_stop_and_remove_bus_device(dev); + } } EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices); diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index e3cb7ae61658..51ecac920dd8 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -388,8 +388,10 @@ static void __init pSeries_setup_arch(void) /* Find and initialize PCI host bridges */ init_pci_config_tokens(); + eeh_pseries_init(); find_and_init_phbs(); pSeries_reconfig_notifier_register(&pci_dn_reconfig_nb); + eeh_init(); pSeries_nvram_init(); @@ -414,20 +416,16 @@ static int __init pSeries_init_panel(void) } machine_arch_initcall(pseries, pSeries_init_panel); -static int pseries_set_dabr(unsigned long dabr, unsigned long dabrx) +static int pseries_set_dabr(unsigned long dabr) { return plpar_hcall_norets(H_SET_DABR, dabr); } -static int pseries_set_xdabr(unsigned long dabr, unsigned long dabrx) +static int pseries_set_xdabr(unsigned long dabr) { - /* Have to set at least one bit in the DABRX according to PAPR */ - if (dabrx == 0 && dabr == 0) - dabrx = DABRX_USER; - /* PAPR says we can only set kernel and user bits */ - dabrx &= DABRX_KERNEL | DABRX_USER; - - return plpar_hcall_norets(H_SET_XDABR, dabr, dabrx); + /* We want to catch accesses from kernel and userspace */ + return plpar_hcall_norets(H_SET_XDABR, dabr, + H_DABRX_KERNEL | H_DABRX_USER); } #define CMO_CHARACTERISTICS_TOKEN 44 @@ -531,10 +529,10 @@ static void __init pSeries_init_early(void) if (firmware_has_feature(FW_FEATURE_LPAR)) hvc_vio_init_early(); #endif - if (firmware_has_feature(FW_FEATURE_XDABR)) - ppc_md.set_dabr = pseries_set_xdabr; - else if (firmware_has_feature(FW_FEATURE_DABR)) + if (firmware_has_feature(FW_FEATURE_DABR)) ppc_md.set_dabr = pseries_set_dabr; + else if (firmware_has_feature(FW_FEATURE_XDABR)) + ppc_md.set_dabr = pseries_set_xdabr; pSeries_cmo_feature_init(); iommu_init_early_pSeries(); diff --git a/trunk/arch/powerpc/sysdev/Makefile b/trunk/arch/powerpc/sysdev/Makefile index a57600b3a4e3..1bd7ecb24620 100644 --- a/trunk/arch/powerpc/sysdev/Makefile +++ b/trunk/arch/powerpc/sysdev/Makefile @@ -15,7 +15,7 @@ obj-$(CONFIG_PPC_DCR_NATIVE) += dcr-low.o obj-$(CONFIG_PPC_PMI) += pmi.o obj-$(CONFIG_U3_DART) += dart_iommu.o obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o -obj-$(CONFIG_FSL_SOC) += fsl_soc.o fsl_mpic_err.o +obj-$(CONFIG_FSL_SOC) += fsl_soc.o obj-$(CONFIG_FSL_PCI) += fsl_pci.o $(fsl-msi-obj-y) obj-$(CONFIG_FSL_PMC) += fsl_pmc.o obj-$(CONFIG_FSL_LBC) += fsl_lbc.o diff --git a/trunk/arch/powerpc/sysdev/dart_iommu.c b/trunk/arch/powerpc/sysdev/dart_iommu.c index 8ef63a01e345..4f2680f431b5 100644 --- a/trunk/arch/powerpc/sysdev/dart_iommu.c +++ b/trunk/arch/powerpc/sysdev/dart_iommu.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -166,7 +167,7 @@ static int dart_build(struct iommu_table *tbl, long index, */ l = npages; while (l--) { - rpn = __pa(uaddr) >> DART_PAGE_SHIFT; + rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT; *(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK); @@ -243,7 +244,7 @@ static int __init dart_init(struct device_node *dart_node) panic("DART: Cannot map registers!"); /* Map in DART table */ - dart_vbase = ioremap(__pa(dart_tablebase), dart_tablesize); + dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize); /* Fill initial table */ for (i = 0; i < dart_tablesize/4; i++) @@ -462,7 +463,7 @@ void __init alloc_dart_table(void) * will blow up an entire large page anyway in the kernel mapping */ dart_tablebase = (unsigned long) - __va(memblock_alloc_base(1UL<<24, 1UL<<24, 0x80000000L)); + abs_to_virt(memblock_alloc_base(1UL<<24, 1UL<<24, 0x80000000L)); printk(KERN_INFO "DART table allocated at: %lx\n", dart_tablebase); } diff --git a/trunk/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c b/trunk/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c index d131c8a1cb15..68ac3aacb191 100644 --- a/trunk/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c +++ b/trunk/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c @@ -193,16 +193,6 @@ static struct of_device_id mpc85xx_l2ctlr_of_match[] = { { .compatible = "fsl,mpc8548-l2-cache-controller", }, - { .compatible = "fsl,mpc8544-l2-cache-controller",}, - { .compatible = "fsl,mpc8572-l2-cache-controller",}, - { .compatible = "fsl,mpc8536-l2-cache-controller",}, - { .compatible = "fsl,p1021-l2-cache-controller",}, - { .compatible = "fsl,p1012-l2-cache-controller",}, - { .compatible = "fsl,p1025-l2-cache-controller",}, - { .compatible = "fsl,p1016-l2-cache-controller",}, - { .compatible = "fsl,p1024-l2-cache-controller",}, - { .compatible = "fsl,p1015-l2-cache-controller",}, - { .compatible = "fsl,p1010-l2-cache-controller",}, {}, }; diff --git a/trunk/arch/powerpc/sysdev/fsl_mpic_err.c b/trunk/arch/powerpc/sysdev/fsl_mpic_err.c deleted file mode 100644 index b83f32562a37..000000000000 --- a/trunk/arch/powerpc/sysdev/fsl_mpic_err.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2012 Freescale Semiconductor, Inc. - * - * Author: Varun Sethi - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; version 2 of the - * License. - * - */ - -#include -#include -#include - -#include -#include -#include - -#include "mpic.h" - -#define MPIC_ERR_INT_BASE 0x3900 -#define MPIC_ERR_INT_EISR 0x0000 -#define MPIC_ERR_INT_EIMR 0x0010 - -static inline u32 mpic_fsl_err_read(u32 __iomem *base, unsigned int err_reg) -{ - return in_be32(base + (err_reg >> 2)); -} - -static inline void mpic_fsl_err_write(u32 __iomem *base, u32 value) -{ - out_be32(base + (MPIC_ERR_INT_EIMR >> 2), value); -} - -static void fsl_mpic_mask_err(struct irq_data *d) -{ - u32 eimr; - struct mpic *mpic = irq_data_get_irq_chip_data(d); - unsigned int src = virq_to_hw(d->irq) - mpic->err_int_vecs[0]; - - eimr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EIMR); - eimr |= (1 << (31 - src)); - mpic_fsl_err_write(mpic->err_regs, eimr); -} - -static void fsl_mpic_unmask_err(struct irq_data *d) -{ - u32 eimr; - struct mpic *mpic = irq_data_get_irq_chip_data(d); - unsigned int src = virq_to_hw(d->irq) - mpic->err_int_vecs[0]; - - eimr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EIMR); - eimr &= ~(1 << (31 - src)); - mpic_fsl_err_write(mpic->err_regs, eimr); -} - -static struct irq_chip fsl_mpic_err_chip = { - .irq_disable = fsl_mpic_mask_err, - .irq_mask = fsl_mpic_mask_err, - .irq_unmask = fsl_mpic_unmask_err, -}; - -int mpic_setup_error_int(struct mpic *mpic, int intvec) -{ - int i; - - mpic->err_regs = ioremap(mpic->paddr + MPIC_ERR_INT_BASE, 0x1000); - if (!mpic->err_regs) { - pr_err("could not map mpic error registers\n"); - return -ENOMEM; - } - mpic->hc_err = fsl_mpic_err_chip; - mpic->hc_err.name = mpic->name; - mpic->flags |= MPIC_FSL_HAS_EIMR; - /* allocate interrupt vectors for error interrupts */ - for (i = MPIC_MAX_ERR - 1; i >= 0; i--) - mpic->err_int_vecs[i] = --intvec; - - return 0; -} - -int mpic_map_error_int(struct mpic *mpic, unsigned int virq, irq_hw_number_t hw) -{ - if ((mpic->flags & MPIC_FSL_HAS_EIMR) && - (hw >= mpic->err_int_vecs[0] && - hw <= mpic->err_int_vecs[MPIC_MAX_ERR - 1])) { - WARN_ON(mpic->flags & MPIC_SECONDARY); - - pr_debug("mpic: mapping as Error Interrupt\n"); - irq_set_chip_data(virq, mpic); - irq_set_chip_and_handler(virq, &mpic->hc_err, - handle_level_irq); - return 1; - } - - return 0; -} - -static irqreturn_t fsl_error_int_handler(int irq, void *data) -{ - struct mpic *mpic = (struct mpic *) data; - u32 eisr, eimr; - int errint; - unsigned int cascade_irq; - - eisr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EISR); - eimr = mpic_fsl_err_read(mpic->err_regs, MPIC_ERR_INT_EIMR); - - if (!(eisr & ~eimr)) - return IRQ_NONE; - - while (eisr) { - errint = __builtin_clz(eisr); - cascade_irq = irq_linear_revmap(mpic->irqhost, - mpic->err_int_vecs[errint]); - WARN_ON(cascade_irq == NO_IRQ); - if (cascade_irq != NO_IRQ) { - generic_handle_irq(cascade_irq); - } else { - eimr |= 1 << (31 - errint); - mpic_fsl_err_write(mpic->err_regs, eimr); - } - eisr &= ~(1 << (31 - errint)); - } - - return IRQ_HANDLED; -} - -void mpic_err_int_init(struct mpic *mpic, irq_hw_number_t irqnum) -{ - unsigned int virq; - int ret; - - virq = irq_create_mapping(mpic->irqhost, irqnum); - if (virq == NO_IRQ) { - pr_err("Error interrupt setup failed\n"); - return; - } - - /* Mask all error interrupts */ - mpic_fsl_err_write(mpic->err_regs, ~0); - - ret = request_irq(virq, fsl_error_int_handler, IRQF_NO_THREAD, - "mpic-error-int", mpic); - if (ret) - pr_err("Failed to register error interrupt handler\n"); -} diff --git a/trunk/arch/powerpc/sysdev/fsl_pci.c b/trunk/arch/powerpc/sysdev/fsl_pci.c index 2ff35765a6ad..c37f46136321 100644 --- a/trunk/arch/powerpc/sysdev/fsl_pci.c +++ b/trunk/arch/powerpc/sysdev/fsl_pci.c @@ -143,20 +143,18 @@ static void __init setup_pci_atmu(struct pci_controller *hose, pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n", (u64)rsrc->start, (u64)resource_size(rsrc)); + if (of_device_is_compatible(hose->dn, "fsl,qoriq-pcie-v2.2")) { + win_idx = 2; + start_idx = 0; + end_idx = 3; + } + pci = ioremap(rsrc->start, resource_size(rsrc)); if (!pci) { dev_err(hose->parent, "Unable to map ATMU registers\n"); return; } - if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) { - if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) { - win_idx = 2; - start_idx = 0; - end_idx = 3; - } - } - /* Disable all windows (except powar0 since it's ignored) */ for(i = 1; i < 5; i++) out_be32(&pci->pow[i].powar, 0); @@ -820,7 +818,6 @@ static const struct of_device_id pci_ids[] = { { .compatible = "fsl,p1010-pcie", }, { .compatible = "fsl,p1023-pcie", }, { .compatible = "fsl,p4080-pcie", }, - { .compatible = "fsl,qoriq-pcie-v2.4", }, { .compatible = "fsl,qoriq-pcie-v2.3", }, { .compatible = "fsl,qoriq-pcie-v2.2", }, {}, @@ -828,78 +825,57 @@ static const struct of_device_id pci_ids[] = { struct device_node *fsl_pci_primary; -void fsl_pci_assign_primary(void) +void __devinit fsl_pci_init(void) { - struct device_node *np; + int ret; + struct device_node *node; + struct pci_controller *hose; + dma_addr_t max = 0xffffffff; /* Callers can specify the primary bus using other means. */ - if (fsl_pci_primary) - return; - - /* If a PCI host bridge contains an ISA node, it's primary. */ - np = of_find_node_by_type(NULL, "isa"); - while ((fsl_pci_primary = of_get_parent(np))) { - of_node_put(np); - np = fsl_pci_primary; - - if (of_match_node(pci_ids, np) && of_device_is_available(np)) - return; + if (!fsl_pci_primary) { + /* If a PCI host bridge contains an ISA node, it's primary. */ + node = of_find_node_by_type(NULL, "isa"); + while ((fsl_pci_primary = of_get_parent(node))) { + of_node_put(node); + node = fsl_pci_primary; + + if (of_match_node(pci_ids, node)) + break; + } } - /* - * If there's no PCI host bridge with ISA, arbitrarily - * designate one as primary. This can go away once - * various bugs with primary-less systems are fixed. - */ - for_each_matching_node(np, pci_ids) { - if (of_device_is_available(np)) { - fsl_pci_primary = np; - of_node_put(np); - return; + node = NULL; + for_each_node_by_type(node, "pci") { + if (of_match_node(pci_ids, node)) { + /* + * If there's no PCI host bridge with ISA, arbitrarily + * designate one as primary. This can go away once + * various bugs with primary-less systems are fixed. + */ + if (!fsl_pci_primary) + fsl_pci_primary = node; + + ret = fsl_add_bridge(node, fsl_pci_primary == node); + if (ret == 0) { + hose = pci_find_hose_for_OF_device(node); + max = min(max, hose->dma_window_base_cur + + hose->dma_window_size); + } } } -} - -static int __devinit fsl_pci_probe(struct platform_device *pdev) -{ - int ret; - struct device_node *node; - struct pci_controller *hose; - - node = pdev->dev.of_node; - ret = fsl_add_bridge(node, fsl_pci_primary == node); #ifdef CONFIG_SWIOTLB - if (ret == 0) { - hose = pci_find_hose_for_OF_device(pdev->dev.of_node); - - /* - * if we couldn't map all of DRAM via the dma windows - * we need SWIOTLB to handle buffers located outside of - * dma capable memory region - */ - if (memblock_end_of_DRAM() - 1 > hose->dma_window_base_cur + - hose->dma_window_size) - ppc_swiotlb_enable = 1; + /* + * if we couldn't map all of DRAM via the dma windows + * we need SWIOTLB to handle buffers located outside of + * dma capable memory region + */ + if (memblock_end_of_DRAM() - 1 > max) { + ppc_swiotlb_enable = 1; + set_pci_dma_ops(&swiotlb_dma_ops); + ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_swiotlb; } #endif - - mpc85xx_pci_err_probe(pdev); - - return 0; -} - -static struct platform_driver fsl_pci_driver = { - .driver = { - .name = "fsl-pci", - .of_match_table = pci_ids, - }, - .probe = fsl_pci_probe, -}; - -static int __init fsl_pci_init(void) -{ - return platform_driver_register(&fsl_pci_driver); } -arch_initcall(fsl_pci_init); #endif diff --git a/trunk/arch/powerpc/sysdev/fsl_pci.h b/trunk/arch/powerpc/sysdev/fsl_pci.h index d078537adece..baa0fd18289f 100644 --- a/trunk/arch/powerpc/sysdev/fsl_pci.h +++ b/trunk/arch/powerpc/sysdev/fsl_pci.h @@ -16,7 +16,6 @@ #define PCIE_LTSSM 0x0404 /* PCIE Link Training and Status */ #define PCIE_LTSSM_L0 0x16 /* L0 state */ -#define PCIE_IP_REV_2_2 0x02080202 /* PCIE IP block version Rev2.2 */ #define PIWAR_EN 0x80000000 /* Enable */ #define PIWAR_PF 0x20000000 /* prefetch */ #define PIWAR_TGI_LOCAL 0x00f00000 /* target - local memory */ @@ -58,9 +57,7 @@ struct ccsr_pci { __be32 pex_pme_mes_disr; /* 0x.024 - PCIE PME and message disable register */ __be32 pex_pme_mes_ier; /* 0x.028 - PCIE PME and message interrupt enable register */ __be32 pex_pmcr; /* 0x.02c - PCIE power management command register */ - u8 res3[3016]; - __be32 block_rev1; /* 0x.bf8 - PCIE Block Revision register 1 */ - __be32 block_rev2; /* 0x.bfc - PCIE Block Revision register 2 */ + u8 res3[3024]; /* PCI/PCI Express outbound window 0-4 * Window 0 is the default window and is the only window enabled upon reset. @@ -98,19 +95,10 @@ u64 fsl_pci_immrbar_base(struct pci_controller *hose); extern struct device_node *fsl_pci_primary; -#ifdef CONFIG_PCI -void fsl_pci_assign_primary(void); +#ifdef CONFIG_FSL_PCI +void fsl_pci_init(void); #else -static inline void fsl_pci_assign_primary(void) {} -#endif - -#ifdef CONFIG_EDAC_MPC85XX -int mpc85xx_pci_err_probe(struct platform_device *op); -#else -static inline int mpc85xx_pci_err_probe(struct platform_device *op) -{ - return -ENOTSUPP; -} +static inline void fsl_pci_init(void) {} #endif #endif /* __POWERPC_FSL_PCI_H */ diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index 9c6e535daad2..bfc6211e5422 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -6,7 +6,7 @@ * with various broken implementations of this HW. * * Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp. - * Copyright 2010-2012 Freescale Semiconductor, Inc. + * Copyright 2010-2011 Freescale Semiconductor, Inc. * * This file is subject to the terms and conditions of the GNU General Public * License. See the file COPYING in the main directory of this archive @@ -221,24 +221,24 @@ static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 valu _mpic_write(mpic->reg_type, &mpic->gregs, offset, value); } -static inline unsigned int mpic_tm_offset(struct mpic *mpic, unsigned int tm) -{ - return (tm >> 2) * MPIC_TIMER_GROUP_STRIDE + - (tm & 3) * MPIC_INFO(TIMER_STRIDE); -} - static inline u32 _mpic_tm_read(struct mpic *mpic, unsigned int tm) { - unsigned int offset = mpic_tm_offset(mpic, tm) + - MPIC_INFO(TIMER_VECTOR_PRI); + unsigned int offset = MPIC_INFO(TIMER_VECTOR_PRI) + + ((tm & 3) * MPIC_INFO(TIMER_STRIDE)); + + if (tm >= 4) + offset += 0x1000 / 4; return _mpic_read(mpic->reg_type, &mpic->tmregs, offset); } static inline void _mpic_tm_write(struct mpic *mpic, unsigned int tm, u32 value) { - unsigned int offset = mpic_tm_offset(mpic, tm) + - MPIC_INFO(TIMER_VECTOR_PRI); + unsigned int offset = MPIC_INFO(TIMER_VECTOR_PRI) + + ((tm & 3) * MPIC_INFO(TIMER_STRIDE)); + + if (tm >= 4) + offset += 0x1000 / 4; _mpic_write(mpic->reg_type, &mpic->tmregs, offset, value); } @@ -1026,9 +1026,6 @@ static int mpic_host_map(struct irq_domain *h, unsigned int virq, return 0; } - if (mpic_map_error_int(mpic, virq, hw)) - return 0; - if (hw >= mpic->num_sources) return -EINVAL; @@ -1088,16 +1085,7 @@ static int mpic_host_xlate(struct irq_domain *h, struct device_node *ct, */ switch (intspec[2]) { case 0: - break; - case 1: - if (!(mpic->flags & MPIC_FSL_HAS_EIMR)) - break; - - if (intspec[3] >= ARRAY_SIZE(mpic->err_int_vecs)) - return -EINVAL; - - *out_hwirq = mpic->err_int_vecs[intspec[3]]; - + case 1: /* no EISR/EIMR support for now, treat as shared IRQ */ break; case 2: if (intspec[0] >= ARRAY_SIZE(mpic->ipi_vecs)) @@ -1313,42 +1301,6 @@ struct mpic * __init mpic_alloc(struct device_node *node, mpic_map(mpic, mpic->paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000); mpic_map(mpic, mpic->paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000); - if (mpic->flags & MPIC_FSL) { - u32 brr1, version; - int ret; - - /* - * Yes, Freescale really did put global registers in the - * magic per-cpu area -- and they don't even show up in the - * non-magic per-cpu copies that this driver normally uses. - */ - mpic_map(mpic, mpic->paddr, &mpic->thiscpuregs, - MPIC_CPU_THISBASE, 0x1000); - - brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs, - MPIC_FSL_BRR1); - version = brr1 & MPIC_FSL_BRR1_VER; - - /* Error interrupt mask register (EIMR) is required for - * handling individual device error interrupts. EIMR - * was added in MPIC version 4.1. - * - * Over here we reserve vector number space for error - * interrupt vectors. This space is stolen from the - * global vector number space, as in case of ipis - * and timer interrupts. - * - * Available vector space = intvec_top - 12, where 12 - * is the number of vectors which have been consumed by - * ipis and timer interrupts. - */ - if (version >= 0x401) { - ret = mpic_setup_error_int(mpic, intvec_top - 12); - if (ret) - return NULL; - } - } - /* Reset */ /* When using a device-node, reset requests are only honored if the MPIC @@ -1488,7 +1440,6 @@ void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, void __init mpic_init(struct mpic *mpic) { int i, cpu; - int num_timers = 4; BUG_ON(mpic->num_sources == 0); @@ -1497,34 +1448,15 @@ void __init mpic_init(struct mpic *mpic) /* Set current processor priority to max */ mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf); - if (mpic->flags & MPIC_FSL) { - u32 brr1 = _mpic_read(mpic->reg_type, &mpic->thiscpuregs, - MPIC_FSL_BRR1); - u32 version = brr1 & MPIC_FSL_BRR1_VER; - - /* - * Timer group B is present at the latest in MPIC 3.1 (e.g. - * mpc8536). It is not present in MPIC 2.0 (e.g. mpc8544). - * I don't know about the status of intermediate versions (or - * whether they even exist). - */ - if (version >= 0x0301) - num_timers = 8; - } - - /* FSL mpic error interrupt intialization */ - if (mpic->flags & MPIC_FSL_HAS_EIMR) - mpic_err_int_init(mpic, MPIC_FSL_ERR_INT); - /* Initialize timers to our reserved vectors and mask them for now */ - for (i = 0; i < num_timers; i++) { - unsigned int offset = mpic_tm_offset(mpic, i); - + for (i = 0; i < 4; i++) { mpic_write(mpic->tmregs, - offset + MPIC_INFO(TIMER_DESTINATION), + i * MPIC_INFO(TIMER_STRIDE) + + MPIC_INFO(TIMER_DESTINATION), 1 << hard_smp_processor_id()); mpic_write(mpic->tmregs, - offset + MPIC_INFO(TIMER_VECTOR_PRI), + i * MPIC_INFO(TIMER_STRIDE) + + MPIC_INFO(TIMER_VECTOR_PRI), MPIC_VECPRI_MASK | (9 << MPIC_VECPRI_PRIORITY_SHIFT) | (mpic->timer_vecs[0] + i)); diff --git a/trunk/arch/powerpc/sysdev/mpic.h b/trunk/arch/powerpc/sysdev/mpic.h index 24bf07a63924..13f3e8913a93 100644 --- a/trunk/arch/powerpc/sysdev/mpic.h +++ b/trunk/arch/powerpc/sysdev/mpic.h @@ -40,26 +40,4 @@ extern int mpic_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool force); extern void mpic_reset_core(int cpu); -#ifdef CONFIG_FSL_SOC -extern int mpic_map_error_int(struct mpic *mpic, unsigned int virq, irq_hw_number_t hw); -extern void mpic_err_int_init(struct mpic *mpic, irq_hw_number_t irqnum); -extern int mpic_setup_error_int(struct mpic *mpic, int intvec); -#else -static inline int mpic_map_error_int(struct mpic *mpic, unsigned int virq, irq_hw_number_t hw) -{ - return 0; -} - - -static inline void mpic_err_int_init(struct mpic *mpic, irq_hw_number_t irqnum) -{ - return; -} - -static inline int mpic_setup_error_int(struct mpic *mpic, int intvec) -{ - return -1; -} -#endif - #endif /* _POWERPC_SYSDEV_MPIC_H */ diff --git a/trunk/arch/powerpc/xmon/xmon.c b/trunk/arch/powerpc/xmon/xmon.c index 3a56a639a92e..9b49c65ee7a4 100644 --- a/trunk/arch/powerpc/xmon/xmon.c +++ b/trunk/arch/powerpc/xmon/xmon.c @@ -60,8 +60,6 @@ static cpumask_t cpus_in_xmon = CPU_MASK_NONE; static unsigned long xmon_taken = 1; static int xmon_owner; static int xmon_gate; -#else -#define xmon_owner 0 #endif /* CONFIG_SMP */ static unsigned long in_xmon __read_mostly = 0; @@ -204,13 +202,7 @@ Commands:\n\ di dump instructions\n\ df dump float values\n\ dd dump double values\n\ - dl dump the kernel log buffer\n" -#ifdef CONFIG_PPC64 - "\ - dp[#] dump paca for current cpu, or cpu #\n\ - dpa dump paca for all possible cpus\n" -#endif - "\ + dl dump the kernel log buffer\n\ dr dump stream of raw bytes\n\ e print exception information\n\ f flush cache\n\ @@ -748,7 +740,7 @@ static void insert_bpts(void) static void insert_cpu_bpts(void) { if (dabr.enabled) - set_dabr(dabr.address | (dabr.enabled & 7), DABRX_ALL); + set_dabr(dabr.address | (dabr.enabled & 7)); if (iabr && cpu_has_feature(CPU_FTR_IABR)) mtspr(SPRN_IABR, iabr->address | (iabr->enabled & (BP_IABR|BP_IABR_TE))); @@ -776,7 +768,7 @@ static void remove_bpts(void) static void remove_cpu_bpts(void) { - set_dabr(0, 0); + set_dabr(0); if (cpu_has_feature(CPU_FTR_IABR)) mtspr(SPRN_IABR, 0); } @@ -2017,95 +2009,6 @@ static void xmon_rawdump (unsigned long adrs, long ndump) printf("\n"); } -#ifdef CONFIG_PPC64 -static void dump_one_paca(int cpu) -{ - struct paca_struct *p; - - if (setjmp(bus_error_jmp) != 0) { - printf("*** Error dumping paca for cpu 0x%x!\n", cpu); - return; - } - - catch_memory_errors = 1; - sync(); - - p = &paca[cpu]; - - printf("paca for cpu 0x%x @ %p:\n", cpu, p); - - printf(" %-*s = %s\n", 16, "possible", cpu_possible(cpu) ? "yes" : "no"); - printf(" %-*s = %s\n", 16, "present", cpu_present(cpu) ? "yes" : "no"); - printf(" %-*s = %s\n", 16, "online", cpu_online(cpu) ? "yes" : "no"); - -#define DUMP(paca, name, format) \ - printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, paca->name, \ - offsetof(struct paca_struct, name)); - - DUMP(p, lock_token, "x"); - DUMP(p, paca_index, "x"); - DUMP(p, kernel_toc, "lx"); - DUMP(p, kernelbase, "lx"); - DUMP(p, kernel_msr, "lx"); -#ifdef CONFIG_PPC_STD_MMU_64 - DUMP(p, stab_real, "lx"); - DUMP(p, stab_addr, "lx"); -#endif - DUMP(p, emergency_sp, "p"); - DUMP(p, data_offset, "lx"); - DUMP(p, hw_cpu_id, "x"); - DUMP(p, cpu_start, "x"); - DUMP(p, kexec_state, "x"); - DUMP(p, __current, "p"); - DUMP(p, kstack, "lx"); - DUMP(p, stab_rr, "lx"); - DUMP(p, saved_r1, "lx"); - DUMP(p, trap_save, "x"); - DUMP(p, soft_enabled, "x"); - DUMP(p, irq_happened, "x"); - DUMP(p, io_sync, "x"); - DUMP(p, irq_work_pending, "x"); - DUMP(p, nap_state_lost, "x"); - -#undef DUMP - - catch_memory_errors = 0; - sync(); -} - -static void dump_all_pacas(void) -{ - int cpu; - - if (num_possible_cpus() == 0) { - printf("No possible cpus, use 'dp #' to dump individual cpus\n"); - return; - } - - for_each_possible_cpu(cpu) - dump_one_paca(cpu); -} - -static void dump_pacas(void) -{ - unsigned long num; - int c; - - c = inchar(); - if (c == 'a') { - dump_all_pacas(); - return; - } - - termch = c; /* Put c back, it wasn't 'a' */ - - if (scanhex(&num)) - dump_one_paca(num); - else - dump_one_paca(xmon_owner); -} -#endif - #define isxdigit(c) (('0' <= (c) && (c) <= '9') \ || ('a' <= (c) && (c) <= 'f') \ || ('A' <= (c) && (c) <= 'F')) @@ -2115,14 +2018,6 @@ dump(void) int c; c = inchar(); - -#ifdef CONFIG_PPC64 - if (c == 'p') { - dump_pacas(); - return; - } -#endif - if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n') termch = c; scanhex((void *)&adrs); diff --git a/trunk/arch/tile/kernel/pci.c b/trunk/arch/tile/kernel/pci.c index d2292be6fb90..33c10864d2f7 100644 --- a/trunk/arch/tile/kernel/pci.c +++ b/trunk/arch/tile/kernel/pci.c @@ -246,13 +246,16 @@ static void __devinit fixup_read_and_payload_sizes(void) /* Scan for the smallest maximum payload size. */ while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + int pcie_caps_offset; u32 devcap; int max_payload; - if (!pci_is_pcie(dev)) + pcie_caps_offset = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (pcie_caps_offset == 0) continue; - pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &devcap); + pci_read_config_dword(dev, pcie_caps_offset + PCI_EXP_DEVCAP, + &devcap); max_payload = devcap & PCI_EXP_DEVCAP_PAYLOAD; if (max_payload < smallest_max_payload) smallest_max_payload = max_payload; @@ -260,10 +263,21 @@ static void __devinit fixup_read_and_payload_sizes(void) /* Now, set the max_payload_size for all devices to that value. */ new_values = (max_read_size << 12) | (smallest_max_payload << 5); - while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) - pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, - PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ, - new_values); + while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { + int pcie_caps_offset; + u16 devctl; + + pcie_caps_offset = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (pcie_caps_offset == 0) + continue; + + pci_read_config_word(dev, pcie_caps_offset + PCI_EXP_DEVCTL, + &devctl); + devctl &= ~(PCI_EXP_DEVCTL_PAYLOAD | PCI_EXP_DEVCTL_READRQ); + devctl |= new_values; + pci_write_config_word(dev, pcie_caps_offset + PCI_EXP_DEVCTL, + devctl); + } } diff --git a/trunk/drivers/crypto/nx/nx.c b/trunk/drivers/crypto/nx/nx.c index 638110efae9b..d7f179cc2e98 100644 --- a/trunk/drivers/crypto/nx/nx.c +++ b/trunk/drivers/crypto/nx/nx.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -103,10 +104,10 @@ struct nx_sg *nx_build_sg_list(struct nx_sg *sg_head, /* determine the start and end for this address range - slightly * different if this is in VMALLOC_REGION */ if (is_vmalloc_addr(start_addr)) - sg_addr = page_to_phys(vmalloc_to_page(start_addr)) + sg_addr = phys_to_abs(page_to_phys(vmalloc_to_page(start_addr))) + offset_in_page(sg_addr); else - sg_addr = __pa(sg_addr); + sg_addr = virt_to_abs(sg_addr); end_addr = sg_addr + len; @@ -264,17 +265,17 @@ void nx_ctx_init(struct nx_crypto_ctx *nx_ctx, unsigned int function) nx_ctx->csbcpb->csb.valid |= NX_CSB_VALID_BIT; nx_ctx->op.flags = function; - nx_ctx->op.csbcpb = __pa(nx_ctx->csbcpb); - nx_ctx->op.in = __pa(nx_ctx->in_sg); - nx_ctx->op.out = __pa(nx_ctx->out_sg); + nx_ctx->op.csbcpb = virt_to_abs(nx_ctx->csbcpb); + nx_ctx->op.in = virt_to_abs(nx_ctx->in_sg); + nx_ctx->op.out = virt_to_abs(nx_ctx->out_sg); if (nx_ctx->csbcpb_aead) { nx_ctx->csbcpb_aead->csb.valid |= NX_CSB_VALID_BIT; nx_ctx->op_aead.flags = function; - nx_ctx->op_aead.csbcpb = __pa(nx_ctx->csbcpb_aead); - nx_ctx->op_aead.in = __pa(nx_ctx->in_sg); - nx_ctx->op_aead.out = __pa(nx_ctx->out_sg); + nx_ctx->op_aead.csbcpb = virt_to_abs(nx_ctx->csbcpb_aead); + nx_ctx->op_aead.in = virt_to_abs(nx_ctx->in_sg); + nx_ctx->op_aead.out = virt_to_abs(nx_ctx->out_sg); } } diff --git a/trunk/drivers/edac/mpc85xx_edac.c b/trunk/drivers/edac/mpc85xx_edac.c index 4fe66fa183ec..a1e791ec25d3 100644 --- a/trunk/drivers/edac/mpc85xx_edac.c +++ b/trunk/drivers/edac/mpc85xx_edac.c @@ -212,7 +212,7 @@ static irqreturn_t mpc85xx_pci_isr(int irq, void *dev_id) return IRQ_HANDLED; } -int __devinit mpc85xx_pci_err_probe(struct platform_device *op) +static int __devinit mpc85xx_pci_err_probe(struct platform_device *op) { struct edac_pci_ctl_info *pci; struct mpc85xx_pci_pdata *pdata; @@ -226,16 +226,6 @@ int __devinit mpc85xx_pci_err_probe(struct platform_device *op) if (!pci) return -ENOMEM; - /* make sure error reporting method is sane */ - switch (edac_op_state) { - case EDAC_OPSTATE_POLL: - case EDAC_OPSTATE_INT: - break; - default: - edac_op_state = EDAC_OPSTATE_INT; - break; - } - pdata = pci->pvt_info; pdata->name = "mpc85xx_pci_err"; pdata->irq = NO_IRQ; @@ -325,7 +315,6 @@ int __devinit mpc85xx_pci_err_probe(struct platform_device *op) devres_release_group(&op->dev, mpc85xx_pci_err_probe); return res; } -EXPORT_SYMBOL(mpc85xx_pci_err_probe); static int mpc85xx_pci_err_remove(struct platform_device *op) { @@ -349,6 +338,27 @@ static int mpc85xx_pci_err_remove(struct platform_device *op) return 0; } +static struct of_device_id mpc85xx_pci_err_of_match[] = { + { + .compatible = "fsl,mpc8540-pcix", + }, + { + .compatible = "fsl,mpc8540-pci", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, mpc85xx_pci_err_of_match); + +static struct platform_driver mpc85xx_pci_err_driver = { + .probe = mpc85xx_pci_err_probe, + .remove = __devexit_p(mpc85xx_pci_err_remove), + .driver = { + .name = "mpc85xx_pci_err", + .owner = THIS_MODULE, + .of_match_table = mpc85xx_pci_err_of_match, + }, +}; + #endif /* CONFIG_PCI */ /**************************** L2 Err device ***************************/ @@ -1200,6 +1210,12 @@ static int __init mpc85xx_mc_init(void) if (res) printk(KERN_WARNING EDAC_MOD_STR "L2 fails to register\n"); +#ifdef CONFIG_PCI + res = platform_driver_register(&mpc85xx_pci_err_driver); + if (res) + printk(KERN_WARNING EDAC_MOD_STR "PCI fails to register\n"); +#endif + #ifdef CONFIG_FSL_SOC_BOOKE pvr = mfspr(SPRN_PVR); @@ -1235,6 +1251,9 @@ static void __exit mpc85xx_mc_exit(void) (PVR_VER(pvr) == PVR_VER_E500V2)) { on_each_cpu(mpc85xx_mc_restore_hid1, NULL, 0); } +#endif +#ifdef CONFIG_PCI + platform_driver_unregister(&mpc85xx_pci_err_driver); #endif platform_driver_unregister(&mpc85xx_l2_err_driver); platform_driver_unregister(&mpc85xx_mc_err_driver); diff --git a/trunk/drivers/gpu/drm/radeon/evergreen.c b/trunk/drivers/gpu/drm/radeon/evergreen.c index ed3340adeb6f..e93b80a6d4e9 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen.c @@ -77,9 +77,13 @@ void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw, void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) { u16 ctl, v; - int err; + int cap, err; - err = pcie_capability_read_word(rdev->pdev, PCI_EXP_DEVCTL, &ctl); + cap = pci_pcie_cap(rdev->pdev); + if (!cap) + return; + + err = pci_read_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, &ctl); if (err) return; @@ -91,7 +95,7 @@ void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) if ((v == 0) || (v == 6) || (v == 7)) { ctl &= ~PCI_EXP_DEVCTL_READRQ; ctl |= (2 << 12); - pcie_capability_write_word(rdev->pdev, PCI_EXP_DEVCTL, ctl); + pci_write_config_word(rdev->pdev, cap + PCI_EXP_DEVCTL, ctl); } } diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_cq.c b/trunk/drivers/infiniband/hw/ehca/ehca_cq.c index 8f5290147e8a..d9b0ebcb67d7 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_cq.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_cq.c @@ -220,7 +220,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector, cq = ERR_PTR(-EAGAIN); goto create_cq_exit4; } - rpage = __pa(vpage); + rpage = virt_to_abs(vpage); h_ret = hipz_h_register_rpage_cq(adapter_handle, my_cq->ipz_cq_handle, diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_eq.c b/trunk/drivers/infiniband/hw/ehca/ehca_eq.c index 90da6747d395..818d721fc448 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_eq.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_eq.c @@ -101,7 +101,7 @@ int ehca_create_eq(struct ehca_shca *shca, if (!vpage) goto create_eq_exit2; - rpage = __pa(vpage); + rpage = virt_to_abs(vpage); h_ret = hipz_h_register_rpage_eq(shca->ipz_hca_handle, eq->ipz_eq_handle, &eq->pf, diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c b/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c index 87844869dcc2..b781b2cb0624 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_mrmw.c @@ -1136,7 +1136,7 @@ int ehca_reg_mr_rpages(struct ehca_shca *shca, } if (rnum > 1) { - rpage = __pa(kpage); + rpage = virt_to_abs(kpage); if (!rpage) { ehca_err(&shca->ib_device, "kpage=%p i=%x", kpage, i); @@ -1231,7 +1231,7 @@ inline int ehca_rereg_mr_rereg1(struct ehca_shca *shca, pginfo->num_kpages, pginfo->num_hwpages, kpage); goto ehca_rereg_mr_rereg1_exit1; } - rpage = __pa(kpage); + rpage = virt_to_abs(kpage); if (!rpage) { ehca_err(&shca->ib_device, "kpage=%p", kpage); ret = -EFAULT; @@ -1525,7 +1525,7 @@ static inline void *ehca_calc_sectbase(int top, int dir, int idx) unsigned long ret = idx; ret |= dir << EHCA_DIR_INDEX_SHIFT; ret |= top << EHCA_TOP_INDEX_SHIFT; - return __va(ret << SECTION_SIZE_BITS); + return abs_to_virt(ret << SECTION_SIZE_BITS); } #define ehca_bmap_valid(entry) \ @@ -1537,7 +1537,7 @@ static u64 ehca_reg_mr_section(int top, int dir, int idx, u64 *kpage, { u64 h_ret = 0; unsigned long page = 0; - u64 rpage = __pa(kpage); + u64 rpage = virt_to_abs(kpage); int page_count; void *sectbase = ehca_calc_sectbase(top, dir, idx); @@ -1553,7 +1553,7 @@ static u64 ehca_reg_mr_section(int top, int dir, int idx, u64 *kpage, for (rnum = 0; (rnum < MAX_RPAGES) && (page < page_count); rnum++) { void *pg = sectbase + ((page++) * pginfo->hwpage_size); - kpage[rnum] = __pa(pg); + kpage[rnum] = virt_to_abs(pg); } h_ret = hipz_h_register_rpage_mr(shca->ipz_hca_handle, mr, @@ -1870,8 +1870,9 @@ static int ehca_set_pagebuf_user1(struct ehca_mr_pginfo *pginfo, for (i = pginfo->u.usr.next_nmap; i < chunk->nmap; ) { pgaddr = page_to_pfn(sg_page(&chunk->page_list[i])) << PAGE_SHIFT ; - *kpage = pgaddr + (pginfo->next_hwpage * - pginfo->hwpage_size); + *kpage = phys_to_abs(pgaddr + + (pginfo->next_hwpage * + pginfo->hwpage_size)); if ( !(*kpage) ) { ehca_gen_err("pgaddr=%llx " "chunk->page_list[i]=%llx " @@ -1926,7 +1927,7 @@ static int ehca_check_kpages_per_ate(struct scatterlist *page_list, u64 pgaddr = page_to_pfn(sg_page(&page_list[t])) << PAGE_SHIFT; if (ehca_debug_level >= 3) ehca_gen_dbg("chunk_page=%llx value=%016llx", pgaddr, - *(u64 *)__va(pgaddr)); + *(u64 *)abs_to_virt(phys_to_abs(pgaddr))); if (pgaddr - PAGE_SIZE != *prev_pgaddr) { ehca_gen_err("uncontiguous page found pgaddr=%llx " "prev_pgaddr=%llx page_list_i=%x", @@ -1961,7 +1962,7 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo, if (nr_kpages == kpages_per_hwpage) { pgaddr = ( page_to_pfn(sg_page(&chunk->page_list[i])) << PAGE_SHIFT ); - *kpage = pgaddr; + *kpage = phys_to_abs(pgaddr); if ( !(*kpage) ) { ehca_gen_err("pgaddr=%llx i=%x", pgaddr, i); @@ -1989,11 +1990,13 @@ static int ehca_set_pagebuf_user2(struct ehca_mr_pginfo *pginfo, (pginfo->hwpage_size - 1)) >> PAGE_SHIFT; nr_kpages -= pginfo->kpage_cnt; - *kpage = pgaddr & - ~(pginfo->hwpage_size - 1); + *kpage = phys_to_abs( + pgaddr & + ~(pginfo->hwpage_size - 1)); } if (ehca_debug_level >= 3) { - u64 val = *(u64 *)__va(pgaddr); + u64 val = *(u64 *)abs_to_virt( + phys_to_abs(pgaddr)); ehca_gen_dbg("kpage=%llx chunk_page=%llx " "value=%016llx", *kpage, pgaddr, val); @@ -2081,8 +2084,9 @@ static int ehca_set_pagebuf_phys(struct ehca_mr_pginfo *pginfo, pginfo->num_hwpages, i); return -EFAULT; } - *kpage = (pbuf->addr & ~(pginfo->hwpage_size - 1)) + - (pginfo->next_hwpage * pginfo->hwpage_size); + *kpage = phys_to_abs( + (pbuf->addr & ~(pginfo->hwpage_size - 1)) + + (pginfo->next_hwpage * pginfo->hwpage_size)); if ( !(*kpage) && pbuf->addr ) { ehca_gen_err("pbuf->addr=%llx pbuf->size=%llx " "next_hwpage=%llx", pbuf->addr, @@ -2120,8 +2124,8 @@ static int ehca_set_pagebuf_fmr(struct ehca_mr_pginfo *pginfo, /* loop over desired page_list entries */ fmrlist = pginfo->u.fmr.page_list + pginfo->u.fmr.next_listelem; for (i = 0; i < number; i++) { - *kpage = (*fmrlist & ~(pginfo->hwpage_size - 1)) + - pginfo->next_hwpage * pginfo->hwpage_size; + *kpage = phys_to_abs((*fmrlist & ~(pginfo->hwpage_size - 1)) + + pginfo->next_hwpage * pginfo->hwpage_size); if ( !(*kpage) ) { ehca_gen_err("*fmrlist=%llx fmrlist=%p " "next_listelem=%llx next_hwpage=%llx", @@ -2148,7 +2152,8 @@ static int ehca_set_pagebuf_fmr(struct ehca_mr_pginfo *pginfo, u64 prev = *kpage; /* check if adrs are contiguous */ for (j = 1; j < cnt_per_hwpage; j++) { - u64 p = fmrlist[j] & ~(pginfo->hwpage_size - 1); + u64 p = phys_to_abs(fmrlist[j] & + ~(pginfo->hwpage_size - 1)); if (prev + pginfo->u.fmr.fmr_pgsize != p) { ehca_gen_err("uncontiguous fmr pages " "found prev=%llx p=%llx " @@ -2383,8 +2388,8 @@ static int ehca_update_busmap(unsigned long pfn, unsigned long nr_pages) memset(ehca_bmap, 0xFF, EHCA_TOP_MAP_SIZE); } - start_section = (pfn * PAGE_SIZE) / EHCA_SECTSIZE; - end_section = ((pfn + nr_pages) * PAGE_SIZE) / EHCA_SECTSIZE; + start_section = phys_to_abs(pfn * PAGE_SIZE) / EHCA_SECTSIZE; + end_section = phys_to_abs((pfn + nr_pages) * PAGE_SIZE) / EHCA_SECTSIZE; for (i = start_section; i < end_section; i++) { int ret; top = ehca_calc_index(i, EHCA_TOP_INDEX_SHIFT); @@ -2503,7 +2508,7 @@ static u64 ehca_map_vaddr(void *caddr) if (!ehca_bmap) return EHCA_INVAL_ADDR; - abs_addr = __pa(caddr); + abs_addr = virt_to_abs(caddr); top = ehca_calc_index(abs_addr, EHCA_TOP_INDEX_SHIFT + EHCA_SECTSHIFT); if (!ehca_bmap_valid(ehca_bmap->top[top])) return EHCA_INVAL_ADDR; diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_qp.c b/trunk/drivers/infiniband/hw/ehca/ehca_qp.c index 149393915ae5..964f85520798 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_qp.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_qp.c @@ -321,7 +321,7 @@ static inline int init_qp_queue(struct ehca_shca *shca, ret = -EINVAL; goto init_qp_queue1; } - rpage = __pa(vpage); + rpage = virt_to_abs(vpage); h_ret = hipz_h_register_rpage_qp(ipz_hca_handle, my_qp->ipz_qp_handle, @@ -1094,7 +1094,7 @@ static int prepare_sqe_rts(struct ehca_qp *my_qp, struct ehca_shca *shca, ehca_dbg(&shca->ib_device, "qp_num=%x bad_send_wqe_p=%p", qp_num, bad_send_wqe_p); /* convert wqe pointer to vadr */ - bad_send_wqe_v = __va((u64)bad_send_wqe_p); + bad_send_wqe_v = abs_to_virt((u64)bad_send_wqe_p); if (ehca_debug_level >= 2) ehca_dmp(bad_send_wqe_v, 32, "qp_num=%x bad_wqe", qp_num); squeue = &my_qp->ipz_squeue; @@ -1138,7 +1138,7 @@ static int calc_left_cqes(u64 wqe_p, struct ipz_queue *ipz_queue, /* convert real to abs address */ wqe_p = wqe_p & (~(1UL << 63)); - wqe_v = __va(wqe_p); + wqe_v = abs_to_virt(wqe_p); if (ipz_queue_abs_to_offset(ipz_queue, wqe_p, &q_ofs)) { ehca_gen_err("Invalid offset for calculating left cqes " diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_reqs.c b/trunk/drivers/infiniband/hw/ehca/ehca_reqs.c index 47f94984353d..fd05f48f6b0b 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_reqs.c +++ b/trunk/drivers/infiniband/hw/ehca/ehca_reqs.c @@ -135,7 +135,7 @@ static void trace_send_wr_ud(const struct ib_send_wr *send_wr) mad_hdr->attr_mod); } for (j = 0; j < send_wr->num_sge; j++) { - u8 *data = __va(sge->addr); + u8 *data = (u8 *)abs_to_virt(sge->addr); ehca_gen_dbg("send_wr#%x sge#%x addr=%p length=%x " "lkey=%x", idx, j, data, sge->length, sge->lkey); diff --git a/trunk/drivers/infiniband/hw/ehca/ehca_tools.h b/trunk/drivers/infiniband/hw/ehca/ehca_tools.h index d280b12aae64..54c0d23bad92 100644 --- a/trunk/drivers/infiniband/hw/ehca/ehca_tools.h +++ b/trunk/drivers/infiniband/hw/ehca/ehca_tools.h @@ -59,6 +59,7 @@ #include #include +#include #include #include #include diff --git a/trunk/drivers/infiniband/hw/ehca/hcp_if.c b/trunk/drivers/infiniband/hw/ehca/hcp_if.c index 2d41d04fd959..e6f9cdd94c7a 100644 --- a/trunk/drivers/infiniband/hw/ehca/hcp_if.c +++ b/trunk/drivers/infiniband/hw/ehca/hcp_if.c @@ -396,7 +396,7 @@ u64 hipz_h_query_port(const struct ipz_adapter_handle adapter_handle, struct hipz_query_port *query_port_response_block) { u64 ret; - u64 r_cb = __pa(query_port_response_block); + u64 r_cb = virt_to_abs(query_port_response_block); if (r_cb & (EHCA_PAGESIZE-1)) { ehca_gen_err("response block not page aligned"); @@ -438,7 +438,7 @@ u64 hipz_h_modify_port(const struct ipz_adapter_handle adapter_handle, u64 hipz_h_query_hca(const struct ipz_adapter_handle adapter_handle, struct hipz_query_hca *query_hca_rblock) { - u64 r_cb = __pa(query_hca_rblock); + u64 r_cb = virt_to_abs(query_hca_rblock); if (r_cb & (EHCA_PAGESIZE-1)) { ehca_gen_err("response_block=%p not page aligned", @@ -577,7 +577,7 @@ u64 hipz_h_modify_qp(const struct ipz_adapter_handle adapter_handle, adapter_handle.handle, /* r4 */ qp_handle.handle, /* r5 */ update_mask, /* r6 */ - __pa(mqpcb), /* r7 */ + virt_to_abs(mqpcb), /* r7 */ 0, 0, 0, 0, 0); if (ret == H_NOT_ENOUGH_RESOURCES) @@ -595,7 +595,7 @@ u64 hipz_h_query_qp(const struct ipz_adapter_handle adapter_handle, return ehca_plpar_hcall_norets(H_QUERY_QP, adapter_handle.handle, /* r4 */ qp_handle.handle, /* r5 */ - __pa(qqpcb), /* r6 */ + virt_to_abs(qqpcb), /* r6 */ 0, 0, 0, 0); } @@ -787,7 +787,7 @@ u64 hipz_h_register_rpage_mr(const struct ipz_adapter_handle adapter_handle, if (count > 1) { u64 *kpage; int i; - kpage = __va(logical_address_of_page); + kpage = (u64 *)abs_to_virt(logical_address_of_page); for (i = 0; i < count; i++) ehca_gen_dbg("kpage[%d]=%p", i, (void *)kpage[i]); @@ -944,7 +944,7 @@ u64 hipz_h_error_data(const struct ipz_adapter_handle adapter_handle, void *rblock, unsigned long *byte_count) { - u64 r_cb = __pa(rblock); + u64 r_cb = virt_to_abs(rblock); if (r_cb & (EHCA_PAGESIZE-1)) { ehca_gen_err("rblock not page aligned."); diff --git a/trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.c b/trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.c index 62c71fadb4d9..1898d6e7cce5 100644 --- a/trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.c +++ b/trunk/drivers/infiniband/hw/ehca/ipz_pt_fn.c @@ -81,7 +81,7 @@ int ipz_queue_abs_to_offset(struct ipz_queue *queue, u64 addr, u64 *q_offset) { int i; for (i = 0; i < queue->queue_length / queue->pagesize; i++) { - u64 page = __pa(queue->queue_pages[i]); + u64 page = (u64)virt_to_abs(queue->queue_pages[i]); if (addr >= page && addr < page + queue->pagesize) { *q_offset = addr - page + i * queue->pagesize; return 0; diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_reset.c b/trunk/drivers/infiniband/hw/mthca/mthca_reset.c index 74c6a9426047..4fa3534ec233 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_reset.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_reset.c @@ -241,16 +241,16 @@ int mthca_reset(struct mthca_dev *mdev) if (hca_pcie_cap) { devctl = hca_header[(hca_pcie_cap + PCI_EXP_DEVCTL) / 4]; - if (pcie_capability_write_word(mdev->pdev, PCI_EXP_DEVCTL, - devctl)) { + if (pci_write_config_word(mdev->pdev, hca_pcie_cap + PCI_EXP_DEVCTL, + devctl)) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA PCI Express " "Device Control register, aborting.\n"); goto out; } linkctl = hca_header[(hca_pcie_cap + PCI_EXP_LNKCTL) / 4]; - if (pcie_capability_write_word(mdev->pdev, PCI_EXP_LNKCTL, - linkctl)) { + if (pci_write_config_word(mdev->pdev, hca_pcie_cap + PCI_EXP_LNKCTL, + linkctl)) { err = -ENODEV; mthca_err(mdev, "Couldn't restore HCA PCI Express " "Link control register, aborting.\n"); diff --git a/trunk/drivers/infiniband/hw/qib/qib_pcie.c b/trunk/drivers/infiniband/hw/qib/qib_pcie.c index 900137173210..062c301ebf53 100644 --- a/trunk/drivers/infiniband/hw/qib/qib_pcie.c +++ b/trunk/drivers/infiniband/hw/qib/qib_pcie.c @@ -273,9 +273,10 @@ int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent, struct qib_msix_entry *entry) { u16 linkstat, speed; - int pos = 0, ret = 1; + int pos = 0, pose, ret = 1; - if (!pci_is_pcie(dd->pcidev)) { + pose = pci_pcie_cap(dd->pcidev); + if (!pose) { qib_dev_err(dd, "Can't find PCI Express capability!\n"); /* set up something... */ dd->lbus_width = 1; @@ -297,7 +298,7 @@ int qib_pcie_params(struct qib_devdata *dd, u32 minw, u32 *nent, if (!pos) qib_enable_intx(dd->pcidev); - pcie_capability_read_word(dd->pcidev, PCI_EXP_LNKSTA, &linkstat); + pci_read_config_word(dd->pcidev, pose + PCI_EXP_LNKSTA, &linkstat); /* * speed is bits 0-3, linkwidth is bits 4-8 * no defines for them in headers @@ -515,6 +516,7 @@ static int qib_tune_pcie_coalesce(struct qib_devdata *dd) { int r; struct pci_dev *parent; + int ppos; u16 devid; u32 mask, bits, val; @@ -527,7 +529,8 @@ static int qib_tune_pcie_coalesce(struct qib_devdata *dd) qib_devinfo(dd->pcidev, "Parent not root\n"); return 1; } - if (!pci_is_pcie(parent)) + ppos = pci_pcie_cap(parent); + if (!ppos) return 1; if (parent->vendor != 0x8086) return 1; @@ -584,6 +587,7 @@ static int qib_tune_pcie_caps(struct qib_devdata *dd) { int ret = 1; /* Assume the worst */ struct pci_dev *parent; + int ppos, epos; u16 pcaps, pctl, ecaps, ectl; int rc_sup, ep_sup; int rc_cur, ep_cur; @@ -594,15 +598,19 @@ static int qib_tune_pcie_caps(struct qib_devdata *dd) qib_devinfo(dd->pcidev, "Parent not root\n"); goto bail; } - - if (!pci_is_pcie(parent) || !pci_is_pcie(dd->pcidev)) + ppos = pci_pcie_cap(parent); + if (ppos) { + pci_read_config_word(parent, ppos + PCI_EXP_DEVCAP, &pcaps); + pci_read_config_word(parent, ppos + PCI_EXP_DEVCTL, &pctl); + } else goto bail; - pcie_capability_read_word(parent, PCI_EXP_DEVCAP, &pcaps); - pcie_capability_read_word(parent, PCI_EXP_DEVCTL, &pctl); /* Find out supported and configured values for endpoint (us) */ - pcie_capability_read_word(dd->pcidev, PCI_EXP_DEVCAP, &ecaps); - pcie_capability_read_word(dd->pcidev, PCI_EXP_DEVCTL, &ectl); - + epos = pci_pcie_cap(dd->pcidev); + if (epos) { + pci_read_config_word(dd->pcidev, epos + PCI_EXP_DEVCAP, &ecaps); + pci_read_config_word(dd->pcidev, epos + PCI_EXP_DEVCTL, &ectl); + } else + goto bail; ret = 0; /* Find max payload supported by root, endpoint */ rc_sup = fld2val(pcaps, PCI_EXP_DEVCAP_PAYLOAD); @@ -621,14 +629,14 @@ static int qib_tune_pcie_caps(struct qib_devdata *dd) rc_cur = rc_sup; pctl = (pctl & ~PCI_EXP_DEVCTL_PAYLOAD) | val2fld(rc_cur, PCI_EXP_DEVCTL_PAYLOAD); - pcie_capability_write_word(parent, PCI_EXP_DEVCTL, pctl); + pci_write_config_word(parent, ppos + PCI_EXP_DEVCTL, pctl); } /* If less than (allowed, supported), bump endpoint payload */ if (rc_sup > ep_cur) { ep_cur = rc_sup; ectl = (ectl & ~PCI_EXP_DEVCTL_PAYLOAD) | val2fld(ep_cur, PCI_EXP_DEVCTL_PAYLOAD); - pcie_capability_write_word(dd->pcidev, PCI_EXP_DEVCTL, ectl); + pci_write_config_word(dd->pcidev, epos + PCI_EXP_DEVCTL, ectl); } /* @@ -646,13 +654,13 @@ static int qib_tune_pcie_caps(struct qib_devdata *dd) rc_cur = rc_sup; pctl = (pctl & ~PCI_EXP_DEVCTL_READRQ) | val2fld(rc_cur, PCI_EXP_DEVCTL_READRQ); - pcie_capability_write_word(parent, PCI_EXP_DEVCTL, pctl); + pci_write_config_word(parent, ppos + PCI_EXP_DEVCTL, pctl); } if (rc_sup > ep_cur) { ep_cur = rc_sup; ectl = (ectl & ~PCI_EXP_DEVCTL_READRQ) | val2fld(ep_cur, PCI_EXP_DEVCTL_READRQ); - pcie_capability_write_word(dd->pcidev, PCI_EXP_DEVCTL, ectl); + pci_write_config_word(dd->pcidev, epos + PCI_EXP_DEVCTL, ectl); } bail: return ret; diff --git a/trunk/drivers/iommu/intel-iommu.c b/trunk/drivers/iommu/intel-iommu.c index db820d7dd0bc..2297ec193eb4 100644 --- a/trunk/drivers/iommu/intel-iommu.c +++ b/trunk/drivers/iommu/intel-iommu.c @@ -2351,7 +2351,7 @@ static int iommu_should_identity_map(struct pci_dev *pdev, int startup) return 0; if (pdev->class >> 8 == PCI_CLASS_BRIDGE_PCI) return 0; - } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE) + } else if (pdev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) return 0; /* @@ -3546,10 +3546,10 @@ int dmar_find_matched_atsr_unit(struct pci_dev *dev) struct pci_dev *bridge = bus->self; if (!bridge || !pci_is_pcie(bridge) || - pci_pcie_type(bridge) == PCI_EXP_TYPE_PCI_BRIDGE) + bridge->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) return 0; - if (pci_pcie_type(bridge) == PCI_EXP_TYPE_ROOT_PORT) { + if (bridge->pcie_type == PCI_EXP_TYPE_ROOT_PORT) { for (i = 0; i < atsru->devices_cnt; i++) if (atsru->devices[i] == bridge) return 1; diff --git a/trunk/drivers/macintosh/smu.c b/trunk/drivers/macintosh/smu.c index 7d5a6b40b31c..54ac7ffacb40 100644 --- a/trunk/drivers/macintosh/smu.c +++ b/trunk/drivers/macintosh/smu.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #define VERSION "0.7" @@ -501,7 +502,7 @@ int __init smu_init (void) * 32 bits value safely */ smu->cmd_buf_abs = (u32)smu_cmdbuf_abs; - smu->cmd_buf = __va(smu_cmdbuf_abs); + smu->cmd_buf = (struct smu_cmd_buf *)abs_to_virt(smu_cmdbuf_abs); smu->db_node = of_find_node_by_name(NULL, "smu-doorbell"); if (smu->db_node == NULL) { diff --git a/trunk/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/trunk/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index 8892e2b64498..1bf5bbfe778e 100644 --- a/trunk/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/trunk/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -149,7 +149,7 @@ static void atl1c_reset_pcie(struct atl1c_hw *hw, u32 flag) data &= ~(PCI_ERR_UNC_DLP | PCI_ERR_UNC_FCP); pci_write_config_dword(pdev, pos + PCI_ERR_UNCOR_SEVER, data); /* clear error status */ - pcie_capability_write_word(pdev, PCI_EXP_DEVSTA, + pci_write_config_word(pdev, pci_pcie_cap(pdev) + PCI_EXP_DEVSTA, PCI_EXP_DEVSTA_NFED | PCI_EXP_DEVSTA_FED | PCI_EXP_DEVSTA_CED | diff --git a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 605c4574d32d..21054987257a 100644 --- a/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/trunk/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -1162,9 +1162,14 @@ static int bnx2x_send_final_clnup(struct bnx2x *bp, u8 clnup_func, static u8 bnx2x_is_pcie_pending(struct pci_dev *dev) { + int pos; u16 status; - pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status); + pos = pci_pcie_cap(dev); + if (!pos) + return false; + + pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &status); return status & PCI_EXP_DEVSTA_TRPND; } @@ -6130,7 +6135,8 @@ static void bnx2x_init_pxp(struct bnx2x *bp) u16 devctl; int r_order, w_order; - pcie_capability_read_word(bp->pdev, PCI_EXP_DEVCTL, &devctl); + pci_read_config_word(bp->pdev, + pci_pcie_cap(bp->pdev) + PCI_EXP_DEVCTL, &devctl); DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl); w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5); if (bp->mrrs == -1) @@ -9368,7 +9374,7 @@ static int __devinit bnx2x_prev_mark_path(struct bnx2x *bp) static int __devinit bnx2x_do_flr(struct bnx2x *bp) { - int i; + int i, pos; u16 status; struct pci_dev *dev = bp->pdev; @@ -9385,12 +9391,16 @@ static int __devinit bnx2x_do_flr(struct bnx2x *bp) return -EINVAL; } + pos = pci_pcie_cap(dev); + if (!pos) + return -ENOTTY; + /* Wait for Transaction Pending bit clean */ for (i = 0; i < 4; i++) { if (i) msleep((1 << (i - 1)) * 100); - pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status); + pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &status); if (!(status & PCI_EXP_DEVSTA_TRPND)) goto clear; } diff --git a/trunk/drivers/net/ethernet/broadcom/tg3.c b/trunk/drivers/net/ethernet/broadcom/tg3.c index 8325fd8d4e5b..bf906c51d82a 100644 --- a/trunk/drivers/net/ethernet/broadcom/tg3.c +++ b/trunk/drivers/net/ethernet/broadcom/tg3.c @@ -3653,9 +3653,17 @@ static int tg3_power_down_prepare(struct tg3 *tp) tg3_enable_register_access(tp); /* Restore the CLKREQ setting. */ - if (tg3_flag(tp, CLKREQ_BUG)) - pcie_capability_set_word(tp->pdev, PCI_EXP_LNKCTL, - PCI_EXP_LNKCTL_CLKREQ_EN); + if (tg3_flag(tp, CLKREQ_BUG)) { + u16 lnkctl; + + pci_read_config_word(tp->pdev, + pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL, + &lnkctl); + lnkctl |= PCI_EXP_LNKCTL_CLKREQ_EN; + pci_write_config_word(tp->pdev, + pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL, + lnkctl); + } misc_host_ctrl = tr32(TG3PCI_MISC_HOST_CTRL); tw32(TG3PCI_MISC_HOST_CTRL, @@ -4426,13 +4434,20 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) /* Prevent send BD corruption. */ if (tg3_flag(tp, CLKREQ_BUG)) { + u16 oldlnkctl, newlnkctl; + + pci_read_config_word(tp->pdev, + pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL, + &oldlnkctl); if (tp->link_config.active_speed == SPEED_100 || tp->link_config.active_speed == SPEED_10) - pcie_capability_clear_word(tp->pdev, PCI_EXP_LNKCTL, - PCI_EXP_LNKCTL_CLKREQ_EN); + newlnkctl = oldlnkctl & ~PCI_EXP_LNKCTL_CLKREQ_EN; else - pcie_capability_set_word(tp->pdev, PCI_EXP_LNKCTL, - PCI_EXP_LNKCTL_CLKREQ_EN); + newlnkctl = oldlnkctl | PCI_EXP_LNKCTL_CLKREQ_EN; + if (newlnkctl != oldlnkctl) + pci_write_config_word(tp->pdev, + pci_pcie_cap(tp->pdev) + + PCI_EXP_LNKCTL, newlnkctl); } if (current_link_up != netif_carrier_ok(tp->dev)) { @@ -8039,7 +8054,7 @@ static int tg3_chip_reset(struct tg3 *tp) udelay(120); - if (tg3_flag(tp, PCI_EXPRESS) && pci_is_pcie(tp->pdev)) { + if (tg3_flag(tp, PCI_EXPRESS) && pci_pcie_cap(tp->pdev)) { u16 val16; if (tp->pci_chip_rev_id == CHIPREV_ID_5750_A0) { @@ -8056,17 +8071,24 @@ static int tg3_chip_reset(struct tg3 *tp) } /* Clear the "no snoop" and "relaxed ordering" bits. */ - val16 = PCI_EXP_DEVCTL_RELAX_EN | PCI_EXP_DEVCTL_NOSNOOP_EN; + pci_read_config_word(tp->pdev, + pci_pcie_cap(tp->pdev) + PCI_EXP_DEVCTL, + &val16); + val16 &= ~(PCI_EXP_DEVCTL_RELAX_EN | + PCI_EXP_DEVCTL_NOSNOOP_EN); /* * Older PCIe devices only support the 128 byte * MPS setting. Enforce the restriction. */ if (!tg3_flag(tp, CPMU_PRESENT)) - val16 |= PCI_EXP_DEVCTL_PAYLOAD; - pcie_capability_clear_word(tp->pdev, PCI_EXP_DEVCTL, val16); + val16 &= ~PCI_EXP_DEVCTL_PAYLOAD; + pci_write_config_word(tp->pdev, + pci_pcie_cap(tp->pdev) + PCI_EXP_DEVCTL, + val16); /* Clear error status */ - pcie_capability_write_word(tp->pdev, PCI_EXP_DEVSTA, + pci_write_config_word(tp->pdev, + pci_pcie_cap(tp->pdev) + PCI_EXP_DEVSTA, PCI_EXP_DEVSTA_CED | PCI_EXP_DEVSTA_NFED | PCI_EXP_DEVSTA_FED | @@ -14543,7 +14565,9 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tg3_flag_set(tp, PCI_EXPRESS); - pcie_capability_read_word(tp->pdev, PCI_EXP_LNKCTL, &lnkctl); + pci_read_config_word(tp->pdev, + pci_pcie_cap(tp->pdev) + PCI_EXP_LNKCTL, + &lnkctl); if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN) { if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c b/trunk/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c index aef45d3113ba..bff8a3cdd3df 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c +++ b/trunk/drivers/net/ethernet/chelsio/cxgb3/t3_hw.c @@ -3289,18 +3289,22 @@ static void config_pcie(struct adapter *adap) unsigned int log2_width, pldsize; unsigned int fst_trn_rx, fst_trn_tx, acklat, rpllmt; - pcie_capability_read_word(adap->pdev, PCI_EXP_DEVCTL, &val); + pci_read_config_word(adap->pdev, + adap->pdev->pcie_cap + PCI_EXP_DEVCTL, + &val); pldsize = (val & PCI_EXP_DEVCTL_PAYLOAD) >> 5; pci_read_config_word(adap->pdev, 0x2, &devid); if (devid == 0x37) { - pcie_capability_write_word(adap->pdev, PCI_EXP_DEVCTL, - val & ~PCI_EXP_DEVCTL_READRQ & - ~PCI_EXP_DEVCTL_PAYLOAD); + pci_write_config_word(adap->pdev, + adap->pdev->pcie_cap + PCI_EXP_DEVCTL, + val & ~PCI_EXP_DEVCTL_READRQ & + ~PCI_EXP_DEVCTL_PAYLOAD); pldsize = 0; } - pcie_capability_read_word(adap->pdev, PCI_EXP_LNKCTL, &val); + pci_read_config_word(adap->pdev, adap->pdev->pcie_cap + PCI_EXP_LNKCTL, + &val); fst_trn_tx = G_NUMFSTTRNSEQ(t3_read_reg(adap, A_PCIE_PEX_CTRL0)); fst_trn_rx = adap->params.rev == 0 ? fst_trn_tx : @@ -3421,13 +3425,15 @@ int t3_init_hw(struct adapter *adapter, u32 fw_params) static void get_pci_mode(struct adapter *adapter, struct pci_params *p) { static unsigned short speed_map[] = { 33, 66, 100, 133 }; - u32 pci_mode; + u32 pci_mode, pcie_cap; - if (pci_is_pcie(adapter->pdev)) { + pcie_cap = pci_pcie_cap(adapter->pdev); + if (pcie_cap) { u16 val; p->variant = PCI_VARIANT_PCIE; - pcie_capability_read_word(adapter->pdev, PCI_EXP_LNKSTA, &val); + pci_read_config_word(adapter->pdev, pcie_cap + PCI_EXP_LNKSTA, + &val); p->width = (val >> 4) & 0x3f; return; } diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 4a20821511e7..5ed49af23d6a 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c @@ -3694,7 +3694,15 @@ static void __devinit print_port_info(const struct net_device *dev) static void __devinit enable_pcie_relaxed_ordering(struct pci_dev *dev) { - pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN); + u16 v; + int pos; + + pos = pci_pcie_cap(dev); + if (pos > 0) { + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &v); + v |= PCI_EXP_DEVCTL_RELAX_EN; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, v); + } } /* diff --git a/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index af1601323173..fa947dfa4c30 100644 --- a/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/trunk/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -2741,9 +2741,11 @@ static void __devinit get_pci_mode(struct adapter *adapter, struct pci_params *p) { u16 val; + u32 pcie_cap = pci_pcie_cap(adapter->pdev); - if (pci_is_pcie(adapter->pdev)) { - pcie_capability_read_word(adapter->pdev, PCI_EXP_LNKSTA, &val); + if (pcie_cap) { + pci_read_config_word(adapter->pdev, pcie_cap + PCI_EXP_LNKSTA, + &val); p->speed = val & PCI_EXP_LNKSTA_CLS; p->width = (val & PCI_EXP_LNKSTA_NLW) >> 4; } diff --git a/trunk/drivers/net/ethernet/ibm/ehea/ehea.h b/trunk/drivers/net/ethernet/ibm/ehea/ehea.h index 6be7b9839f35..b8e46cc31e53 100644 --- a/trunk/drivers/net/ethernet/ibm/ehea/ehea.h +++ b/trunk/drivers/net/ethernet/ibm/ehea/ehea.h @@ -35,6 +35,7 @@ #include #include +#include #include #define DRV_NAME "ehea" diff --git a/trunk/drivers/net/ethernet/ibm/ehea/ehea_phyp.c b/trunk/drivers/net/ethernet/ibm/ehea/ehea_phyp.c index d3a130ccdcc8..30f903332e92 100644 --- a/trunk/drivers/net/ethernet/ibm/ehea/ehea_phyp.c +++ b/trunk/drivers/net/ethernet/ibm/ehea/ehea_phyp.c @@ -141,7 +141,7 @@ u64 ehea_h_query_ehea_qp(const u64 adapter_handle, const u8 qp_category, qp_category, /* R5 */ qp_handle, /* R6 */ sel_mask, /* R7 */ - __pa(cb_addr), /* R8 */ + virt_to_abs(cb_addr), /* R8 */ 0, 0); } @@ -415,7 +415,7 @@ u64 ehea_h_modify_ehea_qp(const u64 adapter_handle, const u8 cat, (u64) cat, /* R5 */ qp_handle, /* R6 */ sel_mask, /* R7 */ - __pa(cb_addr), /* R8 */ + virt_to_abs(cb_addr), /* R8 */ 0, 0, 0, 0); /* R9-R12 */ *inv_attr_id = outs[0]; @@ -528,7 +528,7 @@ u64 ehea_h_query_ehea(const u64 adapter_handle, void *cb_addr) { u64 hret, cb_logaddr; - cb_logaddr = __pa(cb_addr); + cb_logaddr = virt_to_abs(cb_addr); hret = ehea_plpar_hcall_norets(H_QUERY_HEA, adapter_handle, /* R4 */ @@ -545,7 +545,7 @@ u64 ehea_h_query_ehea_port(const u64 adapter_handle, const u16 port_num, void *cb_addr) { u64 port_info; - u64 cb_logaddr = __pa(cb_addr); + u64 cb_logaddr = virt_to_abs(cb_addr); u64 arr_index = 0; port_info = EHEA_BMASK_SET(H_MEHEAPORT_CAT, cb_cat) @@ -567,7 +567,7 @@ u64 ehea_h_modify_ehea_port(const u64 adapter_handle, const u16 port_num, unsigned long outs[PLPAR_HCALL9_BUFSIZE]; u64 port_info; u64 arr_index = 0; - u64 cb_logaddr = __pa(cb_addr); + u64 cb_logaddr = virt_to_abs(cb_addr); port_info = EHEA_BMASK_SET(H_MEHEAPORT_CAT, cb_cat) | EHEA_BMASK_SET(H_MEHEAPORT_PN, port_num); @@ -621,6 +621,6 @@ u64 ehea_h_error_data(const u64 adapter_handle, const u64 ressource_handle, return ehea_plpar_hcall_norets(H_ERROR_DATA, adapter_handle, /* R4 */ ressource_handle, /* R5 */ - __pa(rblock), /* R6 */ + virt_to_abs(rblock), /* R6 */ 0, 0, 0, 0); /* R7-R12 */ } diff --git a/trunk/drivers/net/ethernet/ibm/ehea/ehea_qmr.c b/trunk/drivers/net/ethernet/ibm/ehea/ehea_qmr.c index 27f881758d16..cb66f574dc97 100644 --- a/trunk/drivers/net/ethernet/ibm/ehea/ehea_qmr.c +++ b/trunk/drivers/net/ethernet/ibm/ehea/ehea_qmr.c @@ -163,7 +163,7 @@ struct ehea_cq *ehea_create_cq(struct ehea_adapter *adapter, goto out_kill_hwq; } - rpage = __pa(vpage); + rpage = virt_to_abs(vpage); hret = ehea_h_register_rpage(adapter->handle, 0, EHEA_CQ_REGISTER_ORIG, cq->fw_handle, rpage, 1); @@ -290,7 +290,7 @@ struct ehea_eq *ehea_create_eq(struct ehea_adapter *adapter, goto out_kill_hwq; } - rpage = __pa(vpage); + rpage = virt_to_abs(vpage); hret = ehea_h_register_rpage(adapter->handle, 0, EHEA_EQ_REGISTER_ORIG, @@ -395,7 +395,7 @@ static int ehea_qp_alloc_register(struct ehea_qp *qp, struct hw_queue *hw_queue, pr_err("hw_qpageit_get_inc failed\n"); goto out_kill_hwq; } - rpage = __pa(vpage); + rpage = virt_to_abs(vpage); hret = ehea_h_register_rpage(adapter->handle, 0, h_call_q_selector, qp->fw_handle, rpage, 1); @@ -790,7 +790,7 @@ u64 ehea_map_vaddr(void *caddr) if (!ehea_bmap) return EHEA_INVAL_ADDR; - index = __pa(caddr) >> SECTION_SIZE_BITS; + index = virt_to_abs(caddr) >> SECTION_SIZE_BITS; top = (index >> EHEA_TOP_INDEX_SHIFT) & EHEA_INDEX_MASK; if (!ehea_bmap->top[top]) return EHEA_INVAL_ADDR; @@ -812,7 +812,7 @@ static inline void *ehea_calc_sectbase(int top, int dir, int idx) unsigned long ret = idx; ret |= dir << EHEA_DIR_INDEX_SHIFT; ret |= top << EHEA_TOP_INDEX_SHIFT; - return __va(ret << SECTION_SIZE_BITS); + return abs_to_virt(ret << SECTION_SIZE_BITS); } static u64 ehea_reg_mr_section(int top, int dir, int idx, u64 *pt, @@ -822,7 +822,7 @@ static u64 ehea_reg_mr_section(int top, int dir, int idx, u64 *pt, void *pg; u64 j, m, hret; unsigned long k = 0; - u64 pt_abs = __pa(pt); + u64 pt_abs = virt_to_abs(pt); void *sectbase = ehea_calc_sectbase(top, dir, idx); @@ -830,7 +830,7 @@ static u64 ehea_reg_mr_section(int top, int dir, int idx, u64 *pt, for (m = 0; m < EHEA_MAX_RPAGE; m++) { pg = sectbase + ((k++) * EHEA_PAGESIZE); - pt[m] = __pa(pg); + pt[m] = virt_to_abs(pg); } hret = ehea_h_register_rpage_mr(adapter->handle, mr->handle, 0, 0, pt_abs, EHEA_MAX_RPAGE); diff --git a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c index acc030efb67b..d01a099475a1 100644 --- a/trunk/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/trunk/drivers/net/ethernet/intel/e1000e/netdev.c @@ -5584,15 +5584,16 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep, */ if (adapter->flags & FLAG_IS_QUAD_PORT) { struct pci_dev *us_dev = pdev->bus->self; + int pos = pci_pcie_cap(us_dev); u16 devctl; - pcie_capability_read_word(us_dev, PCI_EXP_DEVCTL, &devctl); - pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, - (devctl & ~PCI_EXP_DEVCTL_CERE)); + pci_read_config_word(us_dev, pos + PCI_EXP_DEVCTL, &devctl); + pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, + (devctl & ~PCI_EXP_DEVCTL_CERE)); e1000_power_off(pdev, sleep, wake); - pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, devctl); + pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, devctl); } else { e1000_power_off(pdev, sleep, wake); } @@ -5606,15 +5607,25 @@ static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state) #else static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state) { + int pos; + u16 reg16; + /* * Both device and parent should have the same ASPM setting. * Disable ASPM in downstream component first and then upstream. */ - pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, state); + pos = pci_pcie_cap(pdev); + pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); + reg16 &= ~state; + pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); + + if (!pdev->bus->self) + return; - if (pdev->bus->self) - pcie_capability_clear_word(pdev->bus->self, PCI_EXP_LNKCTL, - state); + pos = pci_pcie_cap(pdev->bus->self); + pci_read_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, ®16); + reg16 &= ~state; + pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16); } #endif static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state) diff --git a/trunk/drivers/net/ethernet/intel/igb/igb_main.c b/trunk/drivers/net/ethernet/intel/igb/igb_main.c index 2036ae365bae..48cc4fb1a307 100644 --- a/trunk/drivers/net/ethernet/intel/igb/igb_main.c +++ b/trunk/drivers/net/ethernet/intel/igb/igb_main.c @@ -6538,20 +6538,28 @@ static int igb_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) s32 igb_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value) { struct igb_adapter *adapter = hw->back; + u16 cap_offset; - if (pcie_capability_read_word(adapter->pdev, reg, value)) + cap_offset = adapter->pdev->pcie_cap; + if (!cap_offset) return -E1000_ERR_CONFIG; + pci_read_config_word(adapter->pdev, cap_offset + reg, value); + return 0; } s32 igb_write_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value) { struct igb_adapter *adapter = hw->back; + u16 cap_offset; - if (pcie_capability_write_word(adapter->pdev, reg, *value)) + cap_offset = adapter->pdev->pcie_cap; + if (!cap_offset) return -E1000_ERR_CONFIG; + pci_write_config_word(adapter->pdev, cap_offset + reg, *value); + return 0; } diff --git a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 976570d4c939..4326f74f7137 100644 --- a/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -7527,7 +7527,7 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, goto skip_bad_vf_detection; bdev = pdev->bus->self; - while (bdev && (pci_pcie_type(bdev) != PCI_EXP_TYPE_ROOT_PORT)) + while (bdev && (bdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT)) bdev = bdev->bus->self; if (!bdev) diff --git a/trunk/drivers/net/ethernet/mellanox/mlx4/reset.c b/trunk/drivers/net/ethernet/mellanox/mlx4/reset.c index dd1b5093d8b1..11e7c1cb99bf 100644 --- a/trunk/drivers/net/ethernet/mellanox/mlx4/reset.c +++ b/trunk/drivers/net/ethernet/mellanox/mlx4/reset.c @@ -141,16 +141,16 @@ int mlx4_reset(struct mlx4_dev *dev) /* Now restore the PCI headers */ if (pcie_cap) { devctl = hca_header[(pcie_cap + PCI_EXP_DEVCTL) / 4]; - if (pcie_capability_write_word(dev->pdev, PCI_EXP_DEVCTL, - devctl)) { + if (pci_write_config_word(dev->pdev, pcie_cap + PCI_EXP_DEVCTL, + devctl)) { err = -ENODEV; mlx4_err(dev, "Couldn't restore HCA PCI Express " "Device Control register, aborting.\n"); goto out; } linkctl = hca_header[(pcie_cap + PCI_EXP_LNKCTL) / 4]; - if (pcie_capability_write_word(dev->pdev, PCI_EXP_LNKCTL, - linkctl)) { + if (pci_write_config_word(dev->pdev, pcie_cap + PCI_EXP_LNKCTL, + linkctl)) { err = -ENODEV; mlx4_err(dev, "Couldn't restore HCA PCI Express " "Link control register, aborting.\n"); diff --git a/trunk/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/trunk/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index 83516e3369c9..fa85cf1353fd 100644 --- a/trunk/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/trunk/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -1078,16 +1078,22 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) #ifdef CONFIG_MYRI10GE_DCA static int myri10ge_toggle_relaxed(struct pci_dev *pdev, int on) { - int ret; + int ret, cap, err; u16 ctl; - pcie_capability_read_word(pdev, PCI_EXP_DEVCTL, &ctl); + cap = pci_pcie_cap(pdev); + if (!cap) + return 0; + + err = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl); + if (err) + return 0; ret = (ctl & PCI_EXP_DEVCTL_RELAX_EN) >> 4; if (ret != on) { ctl &= ~PCI_EXP_DEVCTL_RELAX_EN; ctl |= (on << 4); - pcie_capability_write_word(pdev, PCI_EXP_DEVCTL, ctl); + pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl); } return ret; } @@ -3186,13 +3192,18 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) struct device *dev = &mgp->pdev->dev; int cap; unsigned err_cap; + u16 val; + u8 ext_type; int ret; if (!myri10ge_ecrc_enable || !bridge) return; /* check that the bridge is a root port */ - if (pci_pcie_type(bridge) != PCI_EXP_TYPE_ROOT_PORT) { + cap = pci_pcie_cap(bridge); + pci_read_config_word(bridge, cap + PCI_CAP_FLAGS, &val); + ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4; + if (ext_type != PCI_EXP_TYPE_ROOT_PORT) { if (myri10ge_ecrc_enable > 1) { struct pci_dev *prev_bridge, *old_bridge = bridge; @@ -3207,8 +3218,11 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) " to force ECRC\n"); return; } - } while (pci_pcie_type(bridge) != - PCI_EXP_TYPE_ROOT_PORT); + cap = pci_pcie_cap(bridge); + pci_read_config_word(bridge, + cap + PCI_CAP_FLAGS, &val); + ext_type = (val & PCI_EXP_FLAGS_TYPE) >> 4; + } while (ext_type != PCI_EXP_TYPE_ROOT_PORT); dev_info(dev, "Forcing ECRC on non-root port %s" @@ -3321,10 +3335,11 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) int overridden = 0; if (myri10ge_force_firmware == 0) { - int link_width; + int link_width, exp_cap; u16 lnk; - pcie_capability_read_word(mgp->pdev, PCI_EXP_LNKSTA, &lnk); + exp_cap = pci_pcie_cap(mgp->pdev); + pci_read_config_word(mgp->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk); link_width = (lnk >> 4) & 0x3f; /* Check to see if Link is less than 8 or if the diff --git a/trunk/drivers/net/ethernet/neterion/vxge/vxge-config.c b/trunk/drivers/net/ethernet/neterion/vxge/vxge-config.c index c2e420a84d22..32d06824fe3e 100644 --- a/trunk/drivers/net/ethernet/neterion/vxge/vxge-config.c +++ b/trunk/drivers/net/ethernet/neterion/vxge/vxge-config.c @@ -757,7 +757,7 @@ __vxge_hw_verify_pci_e_info(struct __vxge_hw_device *hldev) u16 lnk; /* Get the negotiated link width and speed from PCI config space */ - pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnk); + pci_read_config_word(dev, dev->pcie_cap + PCI_EXP_LNKSTA, &lnk); if ((lnk & PCI_EXP_LNKSTA_CLS) != 1) return VXGE_HW_ERR_INVALID_PCI_INFO; @@ -1982,7 +1982,7 @@ u16 vxge_hw_device_link_width_get(struct __vxge_hw_device *hldev) struct pci_dev *dev = hldev->pdev; u16 lnk; - pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnk); + pci_read_config_word(dev, dev->pcie_cap + PCI_EXP_LNKSTA, &lnk); return (lnk & VXGE_HW_PCI_EXP_LNKCAP_LNK_WIDTH) >> 4; } diff --git a/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 01d6141cedd9..342b3a79bd0f 100644 --- a/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/trunk/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -1382,7 +1382,7 @@ static void netxen_mask_aer_correctable(struct netxen_adapter *adapter) adapter->ahw.board_type != NETXEN_BRDTYPE_P3_10G_TP) return; - if (pci_pcie_type(root) != PCI_EXP_TYPE_ROOT_PORT) + if (root->pcie_type != PCI_EXP_TYPE_ROOT_PORT) return; aer_pos = pci_find_ext_capability(root, PCI_EXT_CAP_ID_ERR); diff --git a/trunk/drivers/net/ethernet/realtek/r8169.c b/trunk/drivers/net/ethernet/realtek/r8169.c index a7cc56007b33..b47d5b35024e 100644 --- a/trunk/drivers/net/ethernet/realtek/r8169.c +++ b/trunk/drivers/net/ethernet/realtek/r8169.c @@ -833,8 +833,15 @@ static void rtl_unlock_work(struct rtl8169_private *tp) static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force) { - pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL, - PCI_EXP_DEVCTL_READRQ, force); + int cap = pci_pcie_cap(pdev); + + if (cap) { + u16 ctl; + + pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl); + ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force; + pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl); + } } struct rtl_cond { @@ -4732,14 +4739,28 @@ static void rtl_ephy_init(struct rtl8169_private *tp, const struct ephy_info *e, static void rtl_disable_clock_request(struct pci_dev *pdev) { - pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, - PCI_EXP_LNKCTL_CLKREQ_EN); + int cap = pci_pcie_cap(pdev); + + if (cap) { + u16 ctl; + + pci_read_config_word(pdev, cap + PCI_EXP_LNKCTL, &ctl); + ctl &= ~PCI_EXP_LNKCTL_CLKREQ_EN; + pci_write_config_word(pdev, cap + PCI_EXP_LNKCTL, ctl); + } } static void rtl_enable_clock_request(struct pci_dev *pdev) { - pcie_capability_set_word(pdev, PCI_EXP_LNKCTL, - PCI_EXP_LNKCTL_CLKREQ_EN); + int cap = pci_pcie_cap(pdev); + + if (cap) { + u16 ctl; + + pci_read_config_word(pdev, cap + PCI_EXP_LNKCTL, &ctl); + ctl |= PCI_EXP_LNKCTL_CLKREQ_EN; + pci_write_config_word(pdev, cap + PCI_EXP_LNKCTL, ctl); + } } #define R8168_CPCMD_QUIRK_MASK (\ @@ -5384,9 +5405,14 @@ static void rtl_hw_start_8101(struct net_device *dev) tp->event_slow &= ~RxFIFOOver; if (tp->mac_version == RTL_GIGA_MAC_VER_13 || - tp->mac_version == RTL_GIGA_MAC_VER_16) - pcie_capability_set_word(pdev, PCI_EXP_DEVCTL, - PCI_EXP_DEVCTL_NOSNOOP_EN); + tp->mac_version == RTL_GIGA_MAC_VER_16) { + int cap = pci_pcie_cap(pdev); + + if (cap) { + pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_NOSNOOP_EN); + } + } RTL_W8(Cfg9346, Cfg9346_Unlock); diff --git a/trunk/drivers/net/ethernet/sun/niu.c b/trunk/drivers/net/ethernet/sun/niu.c index 3208dca66758..c2a0fe393267 100644 --- a/trunk/drivers/net/ethernet/sun/niu.c +++ b/trunk/drivers/net/ethernet/sun/niu.c @@ -9762,8 +9762,9 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev, union niu_parent_id parent_id; struct net_device *dev; struct niu *np; - int err; + int err, pos; u64 dma_mask; + u16 val16; niu_driver_version(); @@ -9786,7 +9787,8 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev, goto err_out_disable_pdev; } - if (!pci_is_pcie(pdev)) { + pos = pci_pcie_cap(pdev); + if (pos <= 0) { dev_err(&pdev->dev, "Cannot find PCI Express capability, aborting\n"); goto err_out_free_res; } @@ -9811,11 +9813,14 @@ static int __devinit niu_pci_init_one(struct pci_dev *pdev, goto err_out_free_dev; } - pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL, - PCI_EXP_DEVCTL_NOSNOOP_EN, - PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | - PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE | - PCI_EXP_DEVCTL_RELAX_EN); + pci_read_config_word(pdev, pos + PCI_EXP_DEVCTL, &val16); + val16 &= ~PCI_EXP_DEVCTL_NOSNOOP_EN; + val16 |= (PCI_EXP_DEVCTL_CERE | + PCI_EXP_DEVCTL_NFERE | + PCI_EXP_DEVCTL_FERE | + PCI_EXP_DEVCTL_URRE | + PCI_EXP_DEVCTL_RELAX_EN); + pci_write_config_word(pdev, pos + PCI_EXP_DEVCTL, val16); dma_mask = DMA_BIT_MASK(44); err = pci_set_dma_mask(pdev, dma_mask); diff --git a/trunk/drivers/net/wireless/ath/ath9k/pci.c b/trunk/drivers/net/wireless/ath/ath9k/pci.c index ef11dc639461..a978984d78a5 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/pci.c +++ b/trunk/drivers/net/wireless/ath/ath9k/pci.c @@ -113,32 +113,41 @@ static void ath_pci_aspm_init(struct ath_common *common) struct ath_hw *ah = sc->sc_ah; struct pci_dev *pdev = to_pci_dev(sc->dev); struct pci_dev *parent; - u16 aspm; + int pos; + u8 aspm; if (!ah->is_pciexpress) return; + pos = pci_pcie_cap(pdev); + if (!pos) + return; + parent = pdev->bus->self; if (!parent) return; if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { /* Bluetooth coexistance requires disabling ASPM. */ - pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, - PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); + pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &aspm); + aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); + pci_write_config_byte(pdev, pos + PCI_EXP_LNKCTL, aspm); /* * Both upstream and downstream PCIe components should * have the same ASPM settings. */ - pcie_capability_clear_word(parent, PCI_EXP_LNKCTL, - PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); + pos = pci_pcie_cap(parent); + pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm); + aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); + pci_write_config_byte(parent, pos + PCI_EXP_LNKCTL, aspm); ath_info(common, "Disabling ASPM since BTCOEX is enabled\n"); return; } - pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &aspm); + pos = pci_pcie_cap(parent); + pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm); if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { ah->aspm_enabled = true; /* Initialize PCIe PM and SERDES registers. */ diff --git a/trunk/drivers/net/wireless/iwlegacy/common.h b/trunk/drivers/net/wireless/iwlegacy/common.h index 724682669060..5f5017767b99 100644 --- a/trunk/drivers/net/wireless/iwlegacy/common.h +++ b/trunk/drivers/net/wireless/iwlegacy/common.h @@ -1832,8 +1832,10 @@ int il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd); static inline u16 il_pcie_link_ctl(struct il_priv *il) { + int pos; u16 pci_lnk_ctl; - pcie_capability_read_word(il->pci_dev, PCI_EXP_LNKCTL, &pci_lnk_ctl); + pos = pci_pcie_cap(il->pci_dev); + pci_read_config_word(il->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); return pci_lnk_ctl; } diff --git a/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c b/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c index e316ca4632b1..1e86ea2266d4 100644 --- a/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/trunk/drivers/net/wireless/iwlwifi/pcie/trans.c @@ -675,10 +675,13 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans) static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + int pos; u16 pci_lnk_ctl; - pcie_capability_read_word(trans_pcie->pci_dev, PCI_EXP_LNKCTL, - &pci_lnk_ctl); + struct pci_dev *pci_dev = trans_pcie->pci_dev; + + pos = pci_pcie_cap(pci_dev); + pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); return pci_lnk_ctl; } diff --git a/trunk/drivers/net/wireless/rtlwifi/pci.c b/trunk/drivers/net/wireless/rtlwifi/pci.c index 5983631a1b1a..80f75d3ba84a 100644 --- a/trunk/drivers/net/wireless/rtlwifi/pci.c +++ b/trunk/drivers/net/wireless/rtlwifi/pci.c @@ -372,11 +372,13 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev, struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); u8 tmp; - u16 linkctrl_reg; + int pos; + u8 linkctrl_reg; /*Link Control Register */ - pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &linkctrl_reg); - pcipriv->ndis_adapter.linkctrl_reg = (u8)linkctrl_reg; + pos = pci_pcie_cap(pdev); + pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &linkctrl_reg); + pcipriv->ndis_adapter.linkctrl_reg = linkctrl_reg; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Link Control Register =%x\n", pcipriv->ndis_adapter.linkctrl_reg); diff --git a/trunk/drivers/pci/access.c b/trunk/drivers/pci/access.c index 3af0478c057b..ba91a7e17519 100644 --- a/trunk/drivers/pci/access.c +++ b/trunk/drivers/pci/access.c @@ -469,205 +469,3 @@ void pci_cfg_access_unlock(struct pci_dev *dev) raw_spin_unlock_irqrestore(&pci_lock, flags); } EXPORT_SYMBOL_GPL(pci_cfg_access_unlock); - -static inline int pcie_cap_version(const struct pci_dev *dev) -{ - return dev->pcie_flags_reg & PCI_EXP_FLAGS_VERS; -} - -static inline bool pcie_cap_has_devctl(const struct pci_dev *dev) -{ - return true; -} - -static inline bool pcie_cap_has_lnkctl(const struct pci_dev *dev) -{ - int type = pci_pcie_type(dev); - - return pcie_cap_version(dev) > 1 || - type == PCI_EXP_TYPE_ROOT_PORT || - type == PCI_EXP_TYPE_ENDPOINT || - type == PCI_EXP_TYPE_LEG_END; -} - -static inline bool pcie_cap_has_sltctl(const struct pci_dev *dev) -{ - int type = pci_pcie_type(dev); - - return pcie_cap_version(dev) > 1 || - type == PCI_EXP_TYPE_ROOT_PORT || - (type == PCI_EXP_TYPE_DOWNSTREAM && - dev->pcie_flags_reg & PCI_EXP_FLAGS_SLOT); -} - -static inline bool pcie_cap_has_rtctl(const struct pci_dev *dev) -{ - int type = pci_pcie_type(dev); - - return pcie_cap_version(dev) > 1 || - type == PCI_EXP_TYPE_ROOT_PORT || - type == PCI_EXP_TYPE_RC_EC; -} - -static bool pcie_capability_reg_implemented(struct pci_dev *dev, int pos) -{ - if (!pci_is_pcie(dev)) - return false; - - switch (pos) { - case PCI_EXP_FLAGS_TYPE: - return true; - case PCI_EXP_DEVCAP: - case PCI_EXP_DEVCTL: - case PCI_EXP_DEVSTA: - return pcie_cap_has_devctl(dev); - case PCI_EXP_LNKCAP: - case PCI_EXP_LNKCTL: - case PCI_EXP_LNKSTA: - return pcie_cap_has_lnkctl(dev); - case PCI_EXP_SLTCAP: - case PCI_EXP_SLTCTL: - case PCI_EXP_SLTSTA: - return pcie_cap_has_sltctl(dev); - case PCI_EXP_RTCTL: - case PCI_EXP_RTCAP: - case PCI_EXP_RTSTA: - return pcie_cap_has_rtctl(dev); - case PCI_EXP_DEVCAP2: - case PCI_EXP_DEVCTL2: - case PCI_EXP_LNKCAP2: - case PCI_EXP_LNKCTL2: - case PCI_EXP_LNKSTA2: - return pcie_cap_version(dev) > 1; - default: - return false; - } -} - -/* - * Note that these accessor functions are only for the "PCI Express - * Capability" (see PCIe spec r3.0, sec 7.8). They do not apply to the - * other "PCI Express Extended Capabilities" (AER, VC, ACS, MFVC, etc.) - */ -int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val) -{ - int ret; - - *val = 0; - if (pos & 1) - return -EINVAL; - - if (pcie_capability_reg_implemented(dev, pos)) { - ret = pci_read_config_word(dev, pci_pcie_cap(dev) + pos, val); - /* - * Reset *val to 0 if pci_read_config_word() fails, it may - * have been written as 0xFFFF if hardware error happens - * during pci_read_config_word(). - */ - if (ret) - *val = 0; - return ret; - } - - /* - * For Functions that do not implement the Slot Capabilities, - * Slot Status, and Slot Control registers, these spaces must - * be hardwired to 0b, with the exception of the Presence Detect - * State bit in the Slot Status register of Downstream Ports, - * which must be hardwired to 1b. (PCIe Base Spec 3.0, sec 7.8) - */ - if (pci_is_pcie(dev) && pos == PCI_EXP_SLTSTA && - pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { - *val = PCI_EXP_SLTSTA_PDS; - } - - return 0; -} -EXPORT_SYMBOL(pcie_capability_read_word); - -int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val) -{ - int ret; - - *val = 0; - if (pos & 3) - return -EINVAL; - - if (pcie_capability_reg_implemented(dev, pos)) { - ret = pci_read_config_dword(dev, pci_pcie_cap(dev) + pos, val); - /* - * Reset *val to 0 if pci_read_config_dword() fails, it may - * have been written as 0xFFFFFFFF if hardware error happens - * during pci_read_config_dword(). - */ - if (ret) - *val = 0; - return ret; - } - - if (pci_is_pcie(dev) && pos == PCI_EXP_SLTCTL && - pci_pcie_type(dev) == PCI_EXP_TYPE_DOWNSTREAM) { - *val = PCI_EXP_SLTSTA_PDS; - } - - return 0; -} -EXPORT_SYMBOL(pcie_capability_read_dword); - -int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val) -{ - if (pos & 1) - return -EINVAL; - - if (!pcie_capability_reg_implemented(dev, pos)) - return 0; - - return pci_write_config_word(dev, pci_pcie_cap(dev) + pos, val); -} -EXPORT_SYMBOL(pcie_capability_write_word); - -int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val) -{ - if (pos & 3) - return -EINVAL; - - if (!pcie_capability_reg_implemented(dev, pos)) - return 0; - - return pci_write_config_dword(dev, pci_pcie_cap(dev) + pos, val); -} -EXPORT_SYMBOL(pcie_capability_write_dword); - -int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos, - u16 clear, u16 set) -{ - int ret; - u16 val; - - ret = pcie_capability_read_word(dev, pos, &val); - if (!ret) { - val &= ~clear; - val |= set; - ret = pcie_capability_write_word(dev, pos, val); - } - - return ret; -} -EXPORT_SYMBOL(pcie_capability_clear_and_set_word); - -int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos, - u32 clear, u32 set) -{ - int ret; - u32 val; - - ret = pcie_capability_read_dword(dev, pos, &val); - if (!ret) { - val &= ~clear; - val |= set; - ret = pcie_capability_write_dword(dev, pos, val); - } - - return ret; -} -EXPORT_SYMBOL(pcie_capability_clear_and_set_dword); diff --git a/trunk/drivers/pci/hotplug/pciehp_acpi.c b/trunk/drivers/pci/hotplug/pciehp_acpi.c index 24d709b7388c..376d70d17176 100644 --- a/trunk/drivers/pci/hotplug/pciehp_acpi.c +++ b/trunk/drivers/pci/hotplug/pciehp_acpi.c @@ -81,12 +81,16 @@ static struct list_head __initdata dummy_slots = LIST_HEAD_INIT(dummy_slots); /* Dummy driver for dumplicate name detection */ static int __init dummy_probe(struct pcie_device *dev) { + int pos; u32 slot_cap; acpi_handle handle; struct dummy_slot *slot, *tmp; struct pci_dev *pdev = dev->port; - pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap); + pos = pci_pcie_cap(pdev); + if (!pos) + return -ENODEV; + pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap); slot = kzalloc(sizeof(*slot), GFP_KERNEL); if (!slot) return -ENOMEM; diff --git a/trunk/drivers/pci/hotplug/pciehp_hpc.c b/trunk/drivers/pci/hotplug/pciehp_hpc.c index 13b2eaf7ba43..302451e8289d 100644 --- a/trunk/drivers/pci/hotplug/pciehp_hpc.c +++ b/trunk/drivers/pci/hotplug/pciehp_hpc.c @@ -44,25 +44,25 @@ static inline int pciehp_readw(struct controller *ctrl, int reg, u16 *value) { struct pci_dev *dev = ctrl->pcie->port; - return pcie_capability_read_word(dev, reg, value); + return pci_read_config_word(dev, pci_pcie_cap(dev) + reg, value); } static inline int pciehp_readl(struct controller *ctrl, int reg, u32 *value) { struct pci_dev *dev = ctrl->pcie->port; - return pcie_capability_read_dword(dev, reg, value); + return pci_read_config_dword(dev, pci_pcie_cap(dev) + reg, value); } static inline int pciehp_writew(struct controller *ctrl, int reg, u16 value) { struct pci_dev *dev = ctrl->pcie->port; - return pcie_capability_write_word(dev, reg, value); + return pci_write_config_word(dev, pci_pcie_cap(dev) + reg, value); } static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) { struct pci_dev *dev = ctrl->pcie->port; - return pcie_capability_write_dword(dev, reg, value); + return pci_write_config_dword(dev, pci_pcie_cap(dev) + reg, value); } /* Power Control Command */ @@ -855,6 +855,10 @@ struct controller *pcie_init(struct pcie_device *dev) goto abort; } ctrl->pcie = dev; + if (!pci_pcie_cap(pdev)) { + ctrl_err(ctrl, "Cannot find PCI Express capability\n"); + goto abort_ctrl; + } if (pciehp_readl(ctrl, PCI_EXP_SLTCAP, &slot_cap)) { ctrl_err(ctrl, "Cannot read SLOTCAP register\n"); goto abort_ctrl; diff --git a/trunk/drivers/pci/hotplug/pcihp_slot.c b/trunk/drivers/pci/hotplug/pcihp_slot.c index fec2d5b75440..8c05a18c9770 100644 --- a/trunk/drivers/pci/hotplug/pcihp_slot.c +++ b/trunk/drivers/pci/hotplug/pcihp_slot.c @@ -96,11 +96,17 @@ static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp) static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) { int pos; + u16 reg16; u32 reg32; if (!hpp) return; + /* Find PCI Express capability */ + pos = pci_pcie_cap(dev); + if (!pos) + return; + if (hpp->revision > 1) { dev_warn(&dev->dev, "PCIe settings rev %d not supported\n", hpp->revision); @@ -108,13 +114,17 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp) } /* Initialize Device Control Register */ - pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, - ~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or); + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, ®16); + reg16 = (reg16 & hpp->pci_exp_devctl_and) | hpp->pci_exp_devctl_or; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16); /* Initialize Link Control Register */ - if (dev->subordinate) - pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL, - ~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or); + if (dev->subordinate) { + pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, ®16); + reg16 = (reg16 & hpp->pci_exp_lnkctl_and) + | hpp->pci_exp_lnkctl_or; + pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, reg16); + } /* Find Advanced Error Reporting Enhanced Capability */ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); diff --git a/trunk/drivers/pci/hotplug/rpadlpar_core.c b/trunk/drivers/pci/hotplug/rpadlpar_core.c index b29e20b7862f..1e117c2a3cad 100644 --- a/trunk/drivers/pci/hotplug/rpadlpar_core.c +++ b/trunk/drivers/pci/hotplug/rpadlpar_core.c @@ -388,7 +388,7 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn) /* Remove the EADS bridge device itself */ BUG_ON(!bus->self); pr_debug("PCI: Now removing bridge device %s\n", pci_name(bus->self)); - eeh_remove_bus_device(bus->self, true); + eeh_remove_bus_device(bus->self); pci_stop_and_remove_bus_device(bus->self); return 0; diff --git a/trunk/drivers/pci/iov.c b/trunk/drivers/pci/iov.c index aeccc911abb8..74bbaf82638d 100644 --- a/trunk/drivers/pci/iov.c +++ b/trunk/drivers/pci/iov.c @@ -433,8 +433,8 @@ static int sriov_init(struct pci_dev *dev, int pos) struct resource *res; struct pci_dev *pdev; - if (pci_pcie_type(dev) != PCI_EXP_TYPE_RC_END && - pci_pcie_type(dev) != PCI_EXP_TYPE_ENDPOINT) + if (dev->pcie_type != PCI_EXP_TYPE_RC_END && + dev->pcie_type != PCI_EXP_TYPE_ENDPOINT) return -ENODEV; pci_read_config_word(dev, pos + PCI_SRIOV_CTRL, &ctrl); @@ -503,7 +503,7 @@ static int sriov_init(struct pci_dev *dev, int pos) iov->self = dev; pci_read_config_dword(dev, pos + PCI_SRIOV_CAP, &iov->cap); pci_read_config_byte(dev, pos + PCI_SRIOV_FUNC_LINK, &iov->link); - if (pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END) + if (dev->pcie_type == PCI_EXP_TYPE_RC_END) iov->link = PCI_DEVFN(PCI_SLOT(dev->devfn), iov->link); if (pdev) diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index 292cb2e0ff7f..ab4bf5a4c2f1 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -253,6 +253,38 @@ int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap) return pos; } +/** + * pci_pcie_cap2 - query for devices' PCI_CAP_ID_EXP v2 capability structure + * @dev: PCI device to check + * + * Like pci_pcie_cap() but also checks that the PCIe capability version is + * >= 2. Note that v1 capability structures could be sparse in that not + * all register fields were required. v2 requires the entire structure to + * be present size wise, while still allowing for non-implemented registers + * to exist but they must be hardwired to 0. + * + * Due to the differences in the versions of capability structures, one + * must be careful not to try and access non-existant registers that may + * exist in early versions - v1 - of Express devices. + * + * Returns the offset of the PCIe capability structure as long as the + * capability version is >= 2; otherwise 0 is returned. + */ +static int pci_pcie_cap2(struct pci_dev *dev) +{ + u16 flags; + int pos; + + pos = pci_pcie_cap(dev); + if (pos) { + pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags); + if ((flags & PCI_EXP_FLAGS_VERS) < 2) + pos = 0; + } + + return pos; +} + /** * pci_find_ext_capability - Find an extended capability * @dev: PCI device to query @@ -822,6 +854,21 @@ EXPORT_SYMBOL(pci_choose_state); #define PCI_EXP_SAVE_REGS 7 +#define pcie_cap_has_devctl(type, flags) 1 +#define pcie_cap_has_lnkctl(type, flags) \ + ((flags & PCI_EXP_FLAGS_VERS) > 1 || \ + (type == PCI_EXP_TYPE_ROOT_PORT || \ + type == PCI_EXP_TYPE_ENDPOINT || \ + type == PCI_EXP_TYPE_LEG_END)) +#define pcie_cap_has_sltctl(type, flags) \ + ((flags & PCI_EXP_FLAGS_VERS) > 1 || \ + ((type == PCI_EXP_TYPE_ROOT_PORT) || \ + (type == PCI_EXP_TYPE_DOWNSTREAM && \ + (flags & PCI_EXP_FLAGS_SLOT)))) +#define pcie_cap_has_rtctl(type, flags) \ + ((flags & PCI_EXP_FLAGS_VERS) > 1 || \ + (type == PCI_EXP_TYPE_ROOT_PORT || \ + type == PCI_EXP_TYPE_RC_EC)) static struct pci_cap_saved_state *pci_find_saved_cap( struct pci_dev *pci_dev, char cap) @@ -838,11 +885,13 @@ static struct pci_cap_saved_state *pci_find_saved_cap( static int pci_save_pcie_state(struct pci_dev *dev) { - int i = 0; + int pos, i = 0; struct pci_cap_saved_state *save_state; u16 *cap; + u16 flags; - if (!pci_is_pcie(dev)) + pos = pci_pcie_cap(dev); + if (!pos) return 0; save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); @@ -850,37 +899,60 @@ static int pci_save_pcie_state(struct pci_dev *dev) dev_err(&dev->dev, "buffer not found in %s\n", __func__); return -ENOMEM; } - cap = (u16 *)&save_state->cap.data[0]; - pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &cap[i++]); - pcie_capability_read_word(dev, PCI_EXP_LNKCTL, &cap[i++]); - pcie_capability_read_word(dev, PCI_EXP_SLTCTL, &cap[i++]); - pcie_capability_read_word(dev, PCI_EXP_RTCTL, &cap[i++]); - pcie_capability_read_word(dev, PCI_EXP_DEVCTL2, &cap[i++]); - pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &cap[i++]); - pcie_capability_read_word(dev, PCI_EXP_SLTCTL2, &cap[i++]); + pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags); + + if (pcie_cap_has_devctl(dev->pcie_type, flags)) + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &cap[i++]); + if (pcie_cap_has_lnkctl(dev->pcie_type, flags)) + pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]); + if (pcie_cap_has_sltctl(dev->pcie_type, flags)) + pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]); + if (pcie_cap_has_rtctl(dev->pcie_type, flags)) + pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]); + + pos = pci_pcie_cap2(dev); + if (!pos) + return 0; + + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]); + pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]); + pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]); return 0; } static void pci_restore_pcie_state(struct pci_dev *dev) { - int i = 0; + int i = 0, pos; struct pci_cap_saved_state *save_state; u16 *cap; + u16 flags; save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); - if (!save_state) + pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (!save_state || pos <= 0) return; - cap = (u16 *)&save_state->cap.data[0]; - pcie_capability_write_word(dev, PCI_EXP_DEVCTL, cap[i++]); - pcie_capability_write_word(dev, PCI_EXP_LNKCTL, cap[i++]); - pcie_capability_write_word(dev, PCI_EXP_SLTCTL, cap[i++]); - pcie_capability_write_word(dev, PCI_EXP_RTCTL, cap[i++]); - pcie_capability_write_word(dev, PCI_EXP_DEVCTL2, cap[i++]); - pcie_capability_write_word(dev, PCI_EXP_LNKCTL2, cap[i++]); - pcie_capability_write_word(dev, PCI_EXP_SLTCTL2, cap[i++]); + + pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags); + + if (pcie_cap_has_devctl(dev->pcie_type, flags)) + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, cap[i++]); + if (pcie_cap_has_lnkctl(dev->pcie_type, flags)) + pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]); + if (pcie_cap_has_sltctl(dev->pcie_type, flags)) + pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]); + if (pcie_cap_has_rtctl(dev->pcie_type, flags)) + pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]); + + pos = pci_pcie_cap2(dev); + if (!pos) + return; + + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]); + pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]); + pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]); } @@ -1995,24 +2067,35 @@ void pci_free_cap_save_buffers(struct pci_dev *dev) */ void pci_enable_ari(struct pci_dev *dev) { + int pos; u32 cap; + u16 ctrl; struct pci_dev *bridge; if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn) return; - if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI)) + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ARI); + if (!pos) return; bridge = dev->bus->self; if (!bridge) return; - pcie_capability_read_dword(bridge, PCI_EXP_DEVCAP2, &cap); + /* ARI is a PCIe cap v2 feature */ + pos = pci_pcie_cap2(bridge); + if (!pos) + return; + + pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap); if (!(cap & PCI_EXP_DEVCAP2_ARI)) return; - pcie_capability_set_word(bridge, PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_ARI); + pci_read_config_word(bridge, pos + PCI_EXP_DEVCTL2, &ctrl); + ctrl |= PCI_EXP_DEVCTL2_ARI; + pci_write_config_word(bridge, pos + PCI_EXP_DEVCTL2, ctrl); + bridge->ari_enabled = 1; } @@ -2027,14 +2110,20 @@ void pci_enable_ari(struct pci_dev *dev) */ void pci_enable_ido(struct pci_dev *dev, unsigned long type) { - u16 ctrl = 0; + int pos; + u16 ctrl; + /* ID-based Ordering is a PCIe cap v2 feature */ + pos = pci_pcie_cap2(dev); + if (!pos) + return; + + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); if (type & PCI_EXP_IDO_REQUEST) ctrl |= PCI_EXP_IDO_REQ_EN; if (type & PCI_EXP_IDO_COMPLETION) ctrl |= PCI_EXP_IDO_CMP_EN; - if (ctrl) - pcie_capability_set_word(dev, PCI_EXP_DEVCTL2, ctrl); + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); } EXPORT_SYMBOL(pci_enable_ido); @@ -2045,14 +2134,20 @@ EXPORT_SYMBOL(pci_enable_ido); */ void pci_disable_ido(struct pci_dev *dev, unsigned long type) { - u16 ctrl = 0; + int pos; + u16 ctrl; + /* ID-based Ordering is a PCIe cap v2 feature */ + pos = pci_pcie_cap2(dev); + if (!pos) + return; + + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); if (type & PCI_EXP_IDO_REQUEST) - ctrl |= PCI_EXP_IDO_REQ_EN; + ctrl &= ~PCI_EXP_IDO_REQ_EN; if (type & PCI_EXP_IDO_COMPLETION) - ctrl |= PCI_EXP_IDO_CMP_EN; - if (ctrl) - pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2, ctrl); + ctrl &= ~PCI_EXP_IDO_CMP_EN; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); } EXPORT_SYMBOL(pci_disable_ido); @@ -2077,11 +2172,17 @@ EXPORT_SYMBOL(pci_disable_ido); */ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type) { + int pos; u32 cap; u16 ctrl; int ret; - pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap); + /* OBFF is a PCIe cap v2 feature */ + pos = pci_pcie_cap2(dev); + if (!pos) + return -ENOTSUPP; + + pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap); if (!(cap & PCI_EXP_OBFF_MASK)) return -ENOTSUPP; /* no OBFF support at all */ @@ -2092,7 +2193,7 @@ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type) return ret; } - pcie_capability_read_word(dev, PCI_EXP_DEVCTL2, &ctrl); + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); if (cap & PCI_EXP_OBFF_WAKE) ctrl |= PCI_EXP_OBFF_WAKE_EN; else { @@ -2110,7 +2211,7 @@ int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type) return -ENOTSUPP; } } - pcie_capability_write_word(dev, PCI_EXP_DEVCTL2, ctrl); + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); return 0; } @@ -2124,7 +2225,17 @@ EXPORT_SYMBOL(pci_enable_obff); */ void pci_disable_obff(struct pci_dev *dev) { - pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2, PCI_EXP_OBFF_WAKE_EN); + int pos; + u16 ctrl; + + /* OBFF is a PCIe cap v2 feature */ + pos = pci_pcie_cap2(dev); + if (!pos) + return; + + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); + ctrl &= ~PCI_EXP_OBFF_WAKE_EN; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); } EXPORT_SYMBOL(pci_disable_obff); @@ -2137,9 +2248,15 @@ EXPORT_SYMBOL(pci_disable_obff); */ static bool pci_ltr_supported(struct pci_dev *dev) { + int pos; u32 cap; - pcie_capability_read_dword(dev, PCI_EXP_DEVCAP2, &cap); + /* LTR is a PCIe cap v2 feature */ + pos = pci_pcie_cap2(dev); + if (!pos) + return false; + + pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap); return cap & PCI_EXP_DEVCAP2_LTR; } @@ -2156,15 +2273,22 @@ static bool pci_ltr_supported(struct pci_dev *dev) */ int pci_enable_ltr(struct pci_dev *dev) { + int pos; + u16 ctrl; int ret; + if (!pci_ltr_supported(dev)) + return -ENOTSUPP; + + /* LTR is a PCIe cap v2 feature */ + pos = pci_pcie_cap2(dev); + if (!pos) + return -ENOTSUPP; + /* Only primary function can enable/disable LTR */ if (PCI_FUNC(dev->devfn) != 0) return -EINVAL; - if (!pci_ltr_supported(dev)) - return -ENOTSUPP; - /* Enable upstream ports first */ if (dev->bus->self) { ret = pci_enable_ltr(dev->bus->self); @@ -2172,7 +2296,11 @@ int pci_enable_ltr(struct pci_dev *dev) return ret; } - return pcie_capability_set_word(dev, PCI_EXP_DEVCTL2, PCI_EXP_LTR_EN); + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); + ctrl |= PCI_EXP_LTR_EN; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); + + return 0; } EXPORT_SYMBOL(pci_enable_ltr); @@ -2182,14 +2310,24 @@ EXPORT_SYMBOL(pci_enable_ltr); */ void pci_disable_ltr(struct pci_dev *dev) { - /* Only primary function can enable/disable LTR */ - if (PCI_FUNC(dev->devfn) != 0) - return; + int pos; + u16 ctrl; if (!pci_ltr_supported(dev)) return; - pcie_capability_clear_word(dev, PCI_EXP_DEVCTL2, PCI_EXP_LTR_EN); + /* LTR is a PCIe cap v2 feature */ + pos = pci_pcie_cap2(dev); + if (!pos) + return; + + /* Only primary function can enable/disable LTR */ + if (PCI_FUNC(dev->devfn) != 0) + return; + + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl); + ctrl &= ~PCI_EXP_LTR_EN; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl); } EXPORT_SYMBOL(pci_disable_ltr); @@ -2272,6 +2410,9 @@ void pci_enable_acs(struct pci_dev *dev) if (!pci_acs_enable) return; + if (!pci_is_pcie(dev)) + return; + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ACS); if (!pos) return; @@ -2319,8 +2460,8 @@ bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags) acs_flags &= (PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_EC | PCI_ACS_DT); - if (pci_pcie_type(pdev) == PCI_EXP_TYPE_DOWNSTREAM || - pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT || + if (pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM || + pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT || pdev->multifunction) { pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ACS); if (!pos) @@ -3036,10 +3177,15 @@ EXPORT_SYMBOL(pci_set_dma_seg_boundary); static int pcie_flr(struct pci_dev *dev, int probe) { int i; + int pos; u32 cap; - u16 status; + u16 status, control; - pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap); + pos = pci_pcie_cap(dev); + if (!pos) + return -ENOTTY; + + pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP, &cap); if (!(cap & PCI_EXP_DEVCAP_FLR)) return -ENOTTY; @@ -3051,7 +3197,7 @@ static int pcie_flr(struct pci_dev *dev, int probe) if (i) msleep((1 << (i - 1)) * 100); - pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status); + pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &status); if (!(status & PCI_EXP_DEVSTA_TRPND)) goto clear; } @@ -3060,7 +3206,9 @@ static int pcie_flr(struct pci_dev *dev, int probe) "proceeding with reset anyway\n"); clear: - pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR); + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &control); + control |= PCI_EXP_DEVCTL_BCR_FLR; + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, control); msleep(100); @@ -3428,11 +3576,18 @@ EXPORT_SYMBOL(pcix_set_mmrbc); */ int pcie_get_readrq(struct pci_dev *dev) { + int ret, cap; u16 ctl; - pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl); + cap = pci_pcie_cap(dev); + if (!cap) + return -EINVAL; + + ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl); + if (!ret) + ret = 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12); - return 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12); + return ret; } EXPORT_SYMBOL(pcie_get_readrq); @@ -3446,11 +3601,19 @@ EXPORT_SYMBOL(pcie_get_readrq); */ int pcie_set_readrq(struct pci_dev *dev, int rq) { - u16 v; + int cap, err = -EINVAL; + u16 ctl, v; if (rq < 128 || rq > 4096 || !is_power_of_2(rq)) - return -EINVAL; + goto out; + cap = pci_pcie_cap(dev); + if (!cap) + goto out; + + err = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl); + if (err) + goto out; /* * If using the "performance" PCIe config, we clamp the * read rq size to the max packet size to prevent the @@ -3468,8 +3631,14 @@ int pcie_set_readrq(struct pci_dev *dev, int rq) v = (ffs(rq) - 8) << 12; - return pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, - PCI_EXP_DEVCTL_READRQ, v); + if ((ctl & PCI_EXP_DEVCTL_READRQ) != v) { + ctl &= ~PCI_EXP_DEVCTL_READRQ; + ctl |= v; + err = pci_write_config_word(dev, cap + PCI_EXP_DEVCTL, ctl); + } + +out: + return err; } EXPORT_SYMBOL(pcie_set_readrq); @@ -3482,11 +3651,18 @@ EXPORT_SYMBOL(pcie_set_readrq); */ int pcie_get_mps(struct pci_dev *dev) { + int ret, cap; u16 ctl; - pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl); + cap = pci_pcie_cap(dev); + if (!cap) + return -EINVAL; + + ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl); + if (!ret) + ret = 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5); - return 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5); + return ret; } /** @@ -3499,18 +3675,32 @@ int pcie_get_mps(struct pci_dev *dev) */ int pcie_set_mps(struct pci_dev *dev, int mps) { - u16 v; + int cap, err = -EINVAL; + u16 ctl, v; if (mps < 128 || mps > 4096 || !is_power_of_2(mps)) - return -EINVAL; + goto out; v = ffs(mps) - 8; if (v > dev->pcie_mpss) - return -EINVAL; + goto out; v <<= 5; - return pcie_capability_clear_and_set_word(dev, PCI_EXP_DEVCTL, - PCI_EXP_DEVCTL_PAYLOAD, v); + cap = pci_pcie_cap(dev); + if (!cap) + goto out; + + err = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl); + if (err) + goto out; + + if ((ctl & PCI_EXP_DEVCTL_PAYLOAD) != v) { + ctl &= ~PCI_EXP_DEVCTL_PAYLOAD; + ctl |= v; + err = pci_write_config_word(dev, cap + PCI_EXP_DEVCTL, ctl); + } +out: + return err; } /** diff --git a/trunk/drivers/pci/pcie/aer/aer_inject.c b/trunk/drivers/pci/pcie/aer/aer_inject.c index 4e24cb8a94ae..52229863e9fe 100644 --- a/trunk/drivers/pci/pcie/aer/aer_inject.c +++ b/trunk/drivers/pci/pcie/aer/aer_inject.c @@ -288,7 +288,7 @@ static struct pci_dev *pcie_find_root_port(struct pci_dev *dev) while (1) { if (!pci_is_pcie(dev)) break; - if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) + if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) return dev; if (!dev->bus->self) break; diff --git a/trunk/drivers/pci/pcie/aer/aerdrv.c b/trunk/drivers/pci/pcie/aer/aerdrv.c index c78778fc0cba..58ad7917553c 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv.c @@ -81,11 +81,10 @@ bool pci_aer_available(void) static int set_device_error_reporting(struct pci_dev *dev, void *data) { bool enable = *((bool *)data); - int type = pci_pcie_type(dev); - if ((type == PCI_EXP_TYPE_ROOT_PORT) || - (type == PCI_EXP_TYPE_UPSTREAM) || - (type == PCI_EXP_TYPE_DOWNSTREAM)) { + if ((dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) || + (dev->pcie_type == PCI_EXP_TYPE_UPSTREAM) || + (dev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM)) { if (enable) pci_enable_pcie_error_reporting(dev); else @@ -122,17 +121,19 @@ static void set_downstream_devices_error_reporting(struct pci_dev *dev, static void aer_enable_rootport(struct aer_rpc *rpc) { struct pci_dev *pdev = rpc->rpd->port; - int aer_pos; + int pos, aer_pos; u16 reg16; u32 reg32; + pos = pci_pcie_cap(pdev); /* Clear PCIe Capability's Device Status */ - pcie_capability_read_word(pdev, PCI_EXP_DEVSTA, ®16); - pcie_capability_write_word(pdev, PCI_EXP_DEVSTA, reg16); + pci_read_config_word(pdev, pos+PCI_EXP_DEVSTA, ®16); + pci_write_config_word(pdev, pos+PCI_EXP_DEVSTA, reg16); /* Disable system error generation in response to error messages */ - pcie_capability_clear_word(pdev, PCI_EXP_RTCTL, - SYSTEM_ERROR_INTR_ON_MESG_MASK); + pci_read_config_word(pdev, pos + PCI_EXP_RTCTL, ®16); + reg16 &= ~(SYSTEM_ERROR_INTR_ON_MESG_MASK); + pci_write_config_word(pdev, pos + PCI_EXP_RTCTL, reg16); aer_pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ERR); /* Clear error status */ @@ -394,8 +395,9 @@ static void aer_error_resume(struct pci_dev *dev) u16 reg16; /* Clean up Root device status */ - pcie_capability_read_word(dev, PCI_EXP_DEVSTA, ®16); - pcie_capability_write_word(dev, PCI_EXP_DEVSTA, reg16); + pos = pci_pcie_cap(dev); + pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, ®16); + pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, reg16); /* Clean AER Root Error Status */ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_acpi.c b/trunk/drivers/pci/pcie/aer/aerdrv_acpi.c index 5194a7d41730..124f20ff11b2 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_acpi.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_acpi.c @@ -60,7 +60,7 @@ static int aer_hest_parse(struct acpi_hest_header *hest_hdr, void *data) p = (struct acpi_hest_aer_common *)(hest_hdr + 1); if (p->flags & ACPI_HEST_GLOBAL) { if ((pci_is_pcie(info->pci_dev) && - pci_pcie_type(info->pci_dev) == pcie_type) || bridge) + info->pci_dev->pcie_type == pcie_type) || bridge) ff = !!(p->flags & ACPI_HEST_FIRMWARE_FIRST); } else if (hest_match_pci(p, info->pci_dev)) diff --git a/trunk/drivers/pci/pcie/aer/aerdrv_core.c b/trunk/drivers/pci/pcie/aer/aerdrv_core.c index cefc0ddcacf6..0ca053538146 100644 --- a/trunk/drivers/pci/pcie/aer/aerdrv_core.c +++ b/trunk/drivers/pci/pcie/aer/aerdrv_core.c @@ -32,28 +32,53 @@ static bool nosourceid; module_param(forceload, bool, 0); module_param(nosourceid, bool, 0); -#define PCI_EXP_AER_FLAGS (PCI_EXP_DEVCTL_CERE | PCI_EXP_DEVCTL_NFERE | \ - PCI_EXP_DEVCTL_FERE | PCI_EXP_DEVCTL_URRE) - int pci_enable_pcie_error_reporting(struct pci_dev *dev) { + u16 reg16 = 0; + int pos; + if (pcie_aer_get_firmware_first(dev)) return -EIO; - if (!pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); + if (!pos) + return -EIO; + + pos = pci_pcie_cap(dev); + if (!pos) return -EIO; - return pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_AER_FLAGS); + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, ®16); + reg16 |= (PCI_EXP_DEVCTL_CERE | + PCI_EXP_DEVCTL_NFERE | + PCI_EXP_DEVCTL_FERE | + PCI_EXP_DEVCTL_URRE); + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16); + + return 0; } EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting); int pci_disable_pcie_error_reporting(struct pci_dev *dev) { + u16 reg16 = 0; + int pos; + if (pcie_aer_get_firmware_first(dev)) return -EIO; - return pcie_capability_clear_word(dev, PCI_EXP_DEVCTL, - PCI_EXP_AER_FLAGS); + pos = pci_pcie_cap(dev); + if (!pos) + return -EIO; + + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, ®16); + reg16 &= ~(PCI_EXP_DEVCTL_CERE | + PCI_EXP_DEVCTL_NFERE | + PCI_EXP_DEVCTL_FERE | + PCI_EXP_DEVCTL_URRE); + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, reg16); + + return 0; } EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting); @@ -126,12 +151,18 @@ static bool is_error_source(struct pci_dev *dev, struct aer_err_info *e_info) */ if (atomic_read(&dev->enable_cnt) == 0) return false; + pos = pci_pcie_cap(dev); + if (!pos) + return false; /* Check if AER is enabled */ - pcie_capability_read_word(dev, PCI_EXP_DEVCTL, ®16); - if (!(reg16 & PCI_EXP_AER_FLAGS)) + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, ®16); + if (!(reg16 & ( + PCI_EXP_DEVCTL_CERE | + PCI_EXP_DEVCTL_NFERE | + PCI_EXP_DEVCTL_FERE | + PCI_EXP_DEVCTL_URRE))) return false; - pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); if (!pos) return false; @@ -434,7 +465,7 @@ static pci_ers_result_t reset_link(struct pci_dev *dev) if (driver && driver->reset_link) { status = driver->reset_link(udev); - } else if (pci_pcie_type(udev) == PCI_EXP_TYPE_DOWNSTREAM) { + } else if (udev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) { status = default_downstream_reset_link(udev); } else { dev_printk(KERN_DEBUG, &dev->dev, diff --git a/trunk/drivers/pci/pcie/aspm.c b/trunk/drivers/pci/pcie/aspm.c index 213753b283a6..b500840a143b 100644 --- a/trunk/drivers/pci/pcie/aspm.c +++ b/trunk/drivers/pci/pcie/aspm.c @@ -125,16 +125,21 @@ static int policy_to_clkpm_state(struct pcie_link_state *link) static void pcie_set_clkpm_nocheck(struct pcie_link_state *link, int enable) { + int pos; + u16 reg16; struct pci_dev *child; struct pci_bus *linkbus = link->pdev->subordinate; list_for_each_entry(child, &linkbus->devices, bus_list) { + pos = pci_pcie_cap(child); + if (!pos) + return; + pci_read_config_word(child, pos + PCI_EXP_LNKCTL, ®16); if (enable) - pcie_capability_set_word(child, PCI_EXP_LNKCTL, - PCI_EXP_LNKCTL_CLKREQ_EN); + reg16 |= PCI_EXP_LNKCTL_CLKREQ_EN; else - pcie_capability_clear_word(child, PCI_EXP_LNKCTL, - PCI_EXP_LNKCTL_CLKREQ_EN); + reg16 &= ~PCI_EXP_LNKCTL_CLKREQ_EN; + pci_write_config_word(child, pos + PCI_EXP_LNKCTL, reg16); } link->clkpm_enabled = !!enable; } @@ -152,7 +157,7 @@ static void pcie_set_clkpm(struct pcie_link_state *link, int enable) static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) { - int capable = 1, enabled = 1; + int pos, capable = 1, enabled = 1; u32 reg32; u16 reg16; struct pci_dev *child; @@ -160,13 +165,16 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) /* All functions should have the same cap and state, take the worst */ list_for_each_entry(child, &linkbus->devices, bus_list) { - pcie_capability_read_dword(child, PCI_EXP_LNKCAP, ®32); + pos = pci_pcie_cap(child); + if (!pos) + return; + pci_read_config_dword(child, pos + PCI_EXP_LNKCAP, ®32); if (!(reg32 & PCI_EXP_LNKCAP_CLKPM)) { capable = 0; enabled = 0; break; } - pcie_capability_read_word(child, PCI_EXP_LNKCTL, ®16); + pci_read_config_word(child, pos + PCI_EXP_LNKCTL, ®16); if (!(reg16 & PCI_EXP_LNKCTL_CLKREQ_EN)) enabled = 0; } @@ -182,7 +190,7 @@ static void pcie_clkpm_cap_init(struct pcie_link_state *link, int blacklist) */ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) { - int same_clock = 1; + int ppos, cpos, same_clock = 1; u16 reg16, parent_reg, child_reg[8]; unsigned long start_jiffies; struct pci_dev *child, *parent = link->pdev; @@ -195,43 +203,46 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) BUG_ON(!pci_is_pcie(child)); /* Check downstream component if bit Slot Clock Configuration is 1 */ - pcie_capability_read_word(child, PCI_EXP_LNKSTA, ®16); + cpos = pci_pcie_cap(child); + pci_read_config_word(child, cpos + PCI_EXP_LNKSTA, ®16); if (!(reg16 & PCI_EXP_LNKSTA_SLC)) same_clock = 0; /* Check upstream component if bit Slot Clock Configuration is 1 */ - pcie_capability_read_word(parent, PCI_EXP_LNKSTA, ®16); + ppos = pci_pcie_cap(parent); + pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, ®16); if (!(reg16 & PCI_EXP_LNKSTA_SLC)) same_clock = 0; /* Configure downstream component, all functions */ list_for_each_entry(child, &linkbus->devices, bus_list) { - pcie_capability_read_word(child, PCI_EXP_LNKCTL, ®16); + cpos = pci_pcie_cap(child); + pci_read_config_word(child, cpos + PCI_EXP_LNKCTL, ®16); child_reg[PCI_FUNC(child->devfn)] = reg16; if (same_clock) reg16 |= PCI_EXP_LNKCTL_CCC; else reg16 &= ~PCI_EXP_LNKCTL_CCC; - pcie_capability_write_word(child, PCI_EXP_LNKCTL, reg16); + pci_write_config_word(child, cpos + PCI_EXP_LNKCTL, reg16); } /* Configure upstream component */ - pcie_capability_read_word(parent, PCI_EXP_LNKCTL, ®16); + pci_read_config_word(parent, ppos + PCI_EXP_LNKCTL, ®16); parent_reg = reg16; if (same_clock) reg16 |= PCI_EXP_LNKCTL_CCC; else reg16 &= ~PCI_EXP_LNKCTL_CCC; - pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); + pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, reg16); /* Retrain link */ reg16 |= PCI_EXP_LNKCTL_RL; - pcie_capability_write_word(parent, PCI_EXP_LNKCTL, reg16); + pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, reg16); /* Wait for link training end. Break out after waiting for timeout */ start_jiffies = jiffies; for (;;) { - pcie_capability_read_word(parent, PCI_EXP_LNKSTA, ®16); + pci_read_config_word(parent, ppos + PCI_EXP_LNKSTA, ®16); if (!(reg16 & PCI_EXP_LNKSTA_LT)) break; if (time_after(jiffies, start_jiffies + LINK_RETRAIN_TIMEOUT)) @@ -244,10 +255,12 @@ static void pcie_aspm_configure_common_clock(struct pcie_link_state *link) /* Training failed. Restore common clock configurations */ dev_printk(KERN_ERR, &parent->dev, "ASPM: Could not configure common clock\n"); - list_for_each_entry(child, &linkbus->devices, bus_list) - pcie_capability_write_word(child, PCI_EXP_LNKCTL, - child_reg[PCI_FUNC(child->devfn)]); - pcie_capability_write_word(parent, PCI_EXP_LNKCTL, parent_reg); + list_for_each_entry(child, &linkbus->devices, bus_list) { + cpos = pci_pcie_cap(child); + pci_write_config_word(child, cpos + PCI_EXP_LNKCTL, + child_reg[PCI_FUNC(child->devfn)]); + } + pci_write_config_word(parent, ppos + PCI_EXP_LNKCTL, parent_reg); } /* Convert L0s latency encoding to ns */ @@ -292,14 +305,16 @@ struct aspm_register_info { static void pcie_get_aspm_reg(struct pci_dev *pdev, struct aspm_register_info *info) { + int pos; u16 reg16; u32 reg32; - pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, ®32); + pos = pci_pcie_cap(pdev); + pci_read_config_dword(pdev, pos + PCI_EXP_LNKCAP, ®32); info->support = (reg32 & PCI_EXP_LNKCAP_ASPMS) >> 10; info->latency_encoding_l0s = (reg32 & PCI_EXP_LNKCAP_L0SEL) >> 12; info->latency_encoding_l1 = (reg32 & PCI_EXP_LNKCAP_L1EL) >> 15; - pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, ®16); + pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); info->enabled = reg16 & PCI_EXP_LNKCTL_ASPMC; } @@ -397,7 +412,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) * do ASPM for now. */ list_for_each_entry(child, &linkbus->devices, bus_list) { - if (pci_pcie_type(child) == PCI_EXP_TYPE_PCI_BRIDGE) { + if (child->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) { link->aspm_disable = ASPM_STATE_ALL; break; } @@ -405,15 +420,17 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) /* Get and check endpoint acceptable latencies */ list_for_each_entry(child, &linkbus->devices, bus_list) { + int pos; u32 reg32, encoding; struct aspm_latency *acceptable = &link->acceptable[PCI_FUNC(child->devfn)]; - if (pci_pcie_type(child) != PCI_EXP_TYPE_ENDPOINT && - pci_pcie_type(child) != PCI_EXP_TYPE_LEG_END) + if (child->pcie_type != PCI_EXP_TYPE_ENDPOINT && + child->pcie_type != PCI_EXP_TYPE_LEG_END) continue; - pcie_capability_read_dword(child, PCI_EXP_DEVCAP, ®32); + pos = pci_pcie_cap(child); + pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, ®32); /* Calculate endpoint L0s acceptable latency */ encoding = (reg32 & PCI_EXP_DEVCAP_L0S) >> 6; acceptable->l0s = calc_l0s_acceptable(encoding); @@ -427,7 +444,13 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) static void pcie_config_aspm_dev(struct pci_dev *pdev, u32 val) { - pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL, 0x3, val); + u16 reg16; + int pos = pci_pcie_cap(pdev); + + pci_read_config_word(pdev, pos + PCI_EXP_LNKCTL, ®16); + reg16 &= ~0x3; + reg16 |= val; + pci_write_config_word(pdev, pos + PCI_EXP_LNKCTL, reg16); } static void pcie_config_aspm_link(struct pcie_link_state *link, u32 state) @@ -482,6 +505,7 @@ static void free_link_state(struct pcie_link_state *link) static int pcie_aspm_sanity_check(struct pci_dev *pdev) { struct pci_dev *child; + int pos; u32 reg32; /* @@ -489,7 +513,8 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) * very strange. Disable ASPM for the whole slot */ list_for_each_entry(child, &pdev->subordinate->devices, bus_list) { - if (!pci_is_pcie(child)) + pos = pci_pcie_cap(child); + if (!pos) return -EINVAL; /* @@ -505,7 +530,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) * Disable ASPM for pre-1.1 PCIe device, we follow MS to use * RBER bit to determine if a function is 1.1 version device */ - pcie_capability_read_dword(child, PCI_EXP_DEVCAP, ®32); + pci_read_config_dword(child, pos + PCI_EXP_DEVCAP, ®32); if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) { dev_printk(KERN_INFO, &child->dev, "disabling ASPM" " on pre-1.1 PCIe device. You can enable it" @@ -527,7 +552,7 @@ static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev) INIT_LIST_HEAD(&link->children); INIT_LIST_HEAD(&link->link); link->pdev = pdev; - if (pci_pcie_type(pdev) == PCI_EXP_TYPE_DOWNSTREAM) { + if (pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) { struct pcie_link_state *parent; parent = pdev->bus->parent->self->link_state; if (!parent) { @@ -560,12 +585,12 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) if (!pci_is_pcie(pdev) || pdev->link_state) return; - if (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT && - pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM) + if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && + pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) return; /* VIA has a strange chipset, root port is under a bridge */ - if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT && + if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT && pdev->bus->self) return; @@ -622,8 +647,8 @@ static void pcie_update_aspm_capable(struct pcie_link_state *root) if (link->root != root) continue; list_for_each_entry(child, &linkbus->devices, bus_list) { - if ((pci_pcie_type(child) != PCI_EXP_TYPE_ENDPOINT) && - (pci_pcie_type(child) != PCI_EXP_TYPE_LEG_END)) + if ((child->pcie_type != PCI_EXP_TYPE_ENDPOINT) && + (child->pcie_type != PCI_EXP_TYPE_LEG_END)) continue; pcie_aspm_check_latency(child); } @@ -638,8 +663,8 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) if (!pci_is_pcie(pdev) || !parent || !parent->link_state) return; - if ((pci_pcie_type(parent) != PCI_EXP_TYPE_ROOT_PORT) && - (pci_pcie_type(parent) != PCI_EXP_TYPE_DOWNSTREAM)) + if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && + (parent->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) return; down_read(&pci_bus_sem); @@ -679,8 +704,8 @@ void pcie_aspm_pm_state_change(struct pci_dev *pdev) if (aspm_disabled || !pci_is_pcie(pdev) || !link) return; - if ((pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT) && - (pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM)) + if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && + (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) return; /* * Devices changed PM state, we should recheck if latency @@ -704,8 +729,8 @@ void pcie_aspm_powersave_config_link(struct pci_dev *pdev) if (aspm_policy != POLICY_POWERSAVE) return; - if ((pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT) && - (pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM)) + if ((pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && + (pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM)) return; down_read(&pci_bus_sem); @@ -732,8 +757,8 @@ static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem, if (!pci_is_pcie(pdev)) return; - if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT || - pci_pcie_type(pdev) == PCI_EXP_TYPE_DOWNSTREAM) + if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT || + pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM) parent = pdev; if (!parent || !parent->link_state) return; @@ -908,8 +933,8 @@ void pcie_aspm_create_sysfs_dev_files(struct pci_dev *pdev) struct pcie_link_state *link_state = pdev->link_state; if (!pci_is_pcie(pdev) || - (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT && - pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) + (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && + pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) return; if (link_state->aspm_support) @@ -925,8 +950,8 @@ void pcie_aspm_remove_sysfs_dev_files(struct pci_dev *pdev) struct pcie_link_state *link_state = pdev->link_state; if (!pci_is_pcie(pdev) || - (pci_pcie_type(pdev) != PCI_EXP_TYPE_ROOT_PORT && - pci_pcie_type(pdev) != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) + (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && + pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) || !link_state) return; if (link_state->aspm_support) diff --git a/trunk/drivers/pci/pcie/pme.c b/trunk/drivers/pci/pcie/pme.c index 9ca0dc9ffd84..001f1b78f39c 100644 --- a/trunk/drivers/pci/pcie/pme.c +++ b/trunk/drivers/pci/pcie/pme.c @@ -57,12 +57,17 @@ struct pcie_pme_service_data { */ void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable) { + int rtctl_pos; + u16 rtctl; + + rtctl_pos = pci_pcie_cap(dev) + PCI_EXP_RTCTL; + + pci_read_config_word(dev, rtctl_pos, &rtctl); if (enable) - pcie_capability_set_word(dev, PCI_EXP_RTCTL, - PCI_EXP_RTCTL_PMEIE); + rtctl |= PCI_EXP_RTCTL_PMEIE; else - pcie_capability_clear_word(dev, PCI_EXP_RTCTL, - PCI_EXP_RTCTL_PMEIE); + rtctl &= ~PCI_EXP_RTCTL_PMEIE; + pci_write_config_word(dev, rtctl_pos, rtctl); } /** @@ -115,7 +120,7 @@ static bool pcie_pme_from_pci_bridge(struct pci_bus *bus, u8 devfn) if (!dev) return false; - if (pci_is_pcie(dev) && pci_pcie_type(dev) == PCI_EXP_TYPE_PCI_BRIDGE) { + if (pci_is_pcie(dev) && dev->pcie_type == PCI_EXP_TYPE_PCI_BRIDGE) { down_read(&pci_bus_sem); if (pcie_pme_walk_bus(bus)) found = true; @@ -221,15 +226,18 @@ static void pcie_pme_work_fn(struct work_struct *work) struct pcie_pme_service_data *data = container_of(work, struct pcie_pme_service_data, work); struct pci_dev *port = data->srv->port; + int rtsta_pos; u32 rtsta; + rtsta_pos = pci_pcie_cap(port) + PCI_EXP_RTSTA; + spin_lock_irq(&data->lock); for (;;) { if (data->noirq) break; - pcie_capability_read_dword(port, PCI_EXP_RTSTA, &rtsta); + pci_read_config_dword(port, rtsta_pos, &rtsta); if (rtsta & PCI_EXP_RTSTA_PME) { /* * Clear PME status of the port. If there are other @@ -268,14 +276,17 @@ static irqreturn_t pcie_pme_irq(int irq, void *context) { struct pci_dev *port; struct pcie_pme_service_data *data; + int rtsta_pos; u32 rtsta; unsigned long flags; port = ((struct pcie_device *)context)->port; data = get_service_data((struct pcie_device *)context); + rtsta_pos = pci_pcie_cap(port) + PCI_EXP_RTSTA; + spin_lock_irqsave(&data->lock, flags); - pcie_capability_read_dword(port, PCI_EXP_RTSTA, &rtsta); + pci_read_config_dword(port, rtsta_pos, &rtsta); if (!(rtsta & PCI_EXP_RTSTA_PME)) { spin_unlock_irqrestore(&data->lock, flags); @@ -324,13 +335,13 @@ static void pcie_pme_mark_devices(struct pci_dev *port) struct pci_dev *dev; /* Check if this is a root port event collector. */ - if (pci_pcie_type(port) != PCI_EXP_TYPE_RC_EC || !bus) + if (port->pcie_type != PCI_EXP_TYPE_RC_EC || !bus) return; down_read(&pci_bus_sem); list_for_each_entry(dev, &bus->devices, bus_list) if (pci_is_pcie(dev) - && pci_pcie_type(dev) == PCI_EXP_TYPE_RC_END) + && dev->pcie_type == PCI_EXP_TYPE_RC_END) pcie_pme_set_native(dev, NULL); up_read(&pci_bus_sem); } diff --git a/trunk/drivers/pci/pcie/portdrv_bus.c b/trunk/drivers/pci/pcie/portdrv_bus.c index 67be55a7f260..18bf90f748f6 100644 --- a/trunk/drivers/pci/pcie/portdrv_bus.c +++ b/trunk/drivers/pci/pcie/portdrv_bus.c @@ -38,7 +38,7 @@ static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) return 0; if ((driver->port_type != PCIE_ANY_PORT) && - (driver->port_type != pci_pcie_type(pciedev->port))) + (driver->port_type != pciedev->port->pcie_type)) return 0; return 1; diff --git a/trunk/drivers/pci/pcie/portdrv_core.c b/trunk/drivers/pci/pcie/portdrv_core.c index aede99171e90..75915b30ad19 100644 --- a/trunk/drivers/pci/pcie/portdrv_core.c +++ b/trunk/drivers/pci/pcie/portdrv_core.c @@ -246,7 +246,8 @@ static void cleanup_service_irqs(struct pci_dev *dev) */ static int get_port_device_capability(struct pci_dev *dev) { - int services = 0; + int services = 0, pos; + u16 reg16; u32 reg32; int cap_mask = 0; int err; @@ -264,9 +265,11 @@ static int get_port_device_capability(struct pci_dev *dev) return 0; } + pos = pci_pcie_cap(dev); + pci_read_config_word(dev, pos + PCI_EXP_FLAGS, ®16); /* Hot-Plug Capable */ - if (cap_mask & PCIE_PORT_SERVICE_HP) { - pcie_capability_read_dword(dev, PCI_EXP_SLTCAP, ®32); + if ((cap_mask & PCIE_PORT_SERVICE_HP) && (reg16 & PCI_EXP_FLAGS_SLOT)) { + pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, ®32); if (reg32 & PCI_EXP_SLTCAP_HPC) { services |= PCIE_PORT_SERVICE_HP; /* @@ -274,8 +277,10 @@ static int get_port_device_capability(struct pci_dev *dev) * enabled by the BIOS and the hot-plug service driver * is not loaded. */ - pcie_capability_clear_word(dev, PCI_EXP_SLTCTL, - PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE); + pos += PCI_EXP_SLTCTL; + pci_read_config_word(dev, pos, ®16); + reg16 &= ~(PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE); + pci_write_config_word(dev, pos, reg16); } } /* AER capable */ @@ -293,7 +298,7 @@ static int get_port_device_capability(struct pci_dev *dev) services |= PCIE_PORT_SERVICE_VC; /* Root ports are capable of generating PME too */ if ((cap_mask & PCIE_PORT_SERVICE_PME) - && pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT) { + && dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) { services |= PCIE_PORT_SERVICE_PME; /* * Disable PME interrupt on this port in case it's been enabled @@ -331,7 +336,7 @@ static int pcie_device_init(struct pci_dev *pdev, int service, int irq) device->release = release_pcie_device; /* callback to free pcie dev */ dev_set_name(device, "%s:pcie%02x", pci_name(pdev), - get_descriptor_id(pci_pcie_type(pdev), service)); + get_descriptor_id(pdev->pcie_type, service)); device->parent = &pdev->dev; device_enable_async_suspend(device); diff --git a/trunk/drivers/pci/pcie/portdrv_pci.c b/trunk/drivers/pci/pcie/portdrv_pci.c index b0340bc3aae4..e76b44777dbf 100644 --- a/trunk/drivers/pci/pcie/portdrv_pci.c +++ b/trunk/drivers/pci/pcie/portdrv_pci.c @@ -64,7 +64,14 @@ __setup("pcie_ports=", pcie_port_setup); */ void pcie_clear_root_pme_status(struct pci_dev *dev) { - pcie_capability_set_dword(dev, PCI_EXP_RTSTA, PCI_EXP_RTSTA_PME); + int rtsta_pos; + u32 rtsta; + + rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA; + + pci_read_config_dword(dev, rtsta_pos, &rtsta); + rtsta |= PCI_EXP_RTSTA_PME; + pci_write_config_dword(dev, rtsta_pos, rtsta); } static int pcie_portdrv_restore_config(struct pci_dev *dev) @@ -88,7 +95,7 @@ static int pcie_port_resume_noirq(struct device *dev) * which breaks ACPI-based runtime wakeup on PCI Express, so clear those * bits now just in case (shouldn't hurt). */ - if (pci_pcie_type(pdev) == PCI_EXP_TYPE_ROOT_PORT) + if(pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) pcie_clear_root_pme_status(pdev); return 0; } @@ -188,9 +195,9 @@ static int __devinit pcie_portdrv_probe(struct pci_dev *dev, int status; if (!pci_is_pcie(dev) || - ((pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT) && - (pci_pcie_type(dev) != PCI_EXP_TYPE_UPSTREAM) && - (pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM))) + ((dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && + (dev->pcie_type != PCI_EXP_TYPE_UPSTREAM) && + (dev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM))) return -ENODEV; if (!dev->irq && dev->pin) { diff --git a/trunk/drivers/pci/probe.c b/trunk/drivers/pci/probe.c index 3cdba8b3f816..9f8a6b79a8ec 100644 --- a/trunk/drivers/pci/probe.c +++ b/trunk/drivers/pci/probe.c @@ -606,10 +606,10 @@ static void pci_set_bus_speed(struct pci_bus *bus) u32 linkcap; u16 linksta; - pcie_capability_read_dword(bridge, PCI_EXP_LNKCAP, &linkcap); + pci_read_config_dword(bridge, pos + PCI_EXP_LNKCAP, &linkcap); bus->max_bus_speed = pcie_link_speed[linkcap & 0xf]; - pcie_capability_read_word(bridge, PCI_EXP_LNKSTA, &linksta); + pci_read_config_word(bridge, pos + PCI_EXP_LNKSTA, &linksta); pcie_update_link_speed(bus, linksta); } } @@ -932,16 +932,24 @@ void set_pcie_port_type(struct pci_dev *pdev) pdev->is_pcie = 1; pdev->pcie_cap = pos; pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); - pdev->pcie_flags_reg = reg16; + pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4; pci_read_config_word(pdev, pos + PCI_EXP_DEVCAP, ®16); pdev->pcie_mpss = reg16 & PCI_EXP_DEVCAP_PAYLOAD; } void set_pcie_hotplug_bridge(struct pci_dev *pdev) { + int pos; + u16 reg16; u32 reg32; - pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, ®32); + pos = pci_pcie_cap(pdev); + if (!pos) + return; + pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, ®16); + if (!(reg16 & PCI_EXP_FLAGS_SLOT)) + return; + pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, ®32); if (reg32 & PCI_EXP_SLTCAP_HPC) pdev->is_hotplug_bridge = 1; } @@ -1155,7 +1163,8 @@ int pci_cfg_space_size(struct pci_dev *dev) if (class == PCI_CLASS_BRIDGE_HOST) return pci_cfg_space_size_ext(dev); - if (!pci_is_pcie(dev)) { + pos = pci_pcie_cap(dev); + if (!pos) { pos = pci_find_capability(dev, PCI_CAP_ID_PCIX); if (!pos) goto fail; @@ -1377,9 +1386,9 @@ static int only_one_child(struct pci_bus *bus) if (!parent || !pci_is_pcie(parent)) return 0; - if (pci_pcie_type(parent) == PCI_EXP_TYPE_ROOT_PORT) + if (parent->pcie_type == PCI_EXP_TYPE_ROOT_PORT) return 1; - if (pci_pcie_type(parent) == PCI_EXP_TYPE_DOWNSTREAM && + if (parent->pcie_type == PCI_EXP_TYPE_DOWNSTREAM && !pci_has_flag(PCI_SCAN_ALL_PCIE_DEVS)) return 1; return 0; @@ -1456,7 +1465,7 @@ static int pcie_find_smpss(struct pci_dev *dev, void *data) */ if (dev->is_hotplug_bridge && (!list_is_singular(&dev->bus->devices) || (dev->bus->self && - pci_pcie_type(dev->bus->self) != PCI_EXP_TYPE_ROOT_PORT))) + dev->bus->self->pcie_type != PCI_EXP_TYPE_ROOT_PORT))) *smpss = 0; if (*smpss > dev->pcie_mpss) @@ -1472,8 +1481,7 @@ static void pcie_write_mps(struct pci_dev *dev, int mps) if (pcie_bus_config == PCIE_BUS_PERFORMANCE) { mps = 128 << dev->pcie_mpss; - if (pci_pcie_type(dev) != PCI_EXP_TYPE_ROOT_PORT && - dev->bus->self) + if (dev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && dev->bus->self) /* For "Performance", the assumption is made that * downstream communication will never be larger than * the MRRS. So, the MPS only needs to be configured diff --git a/trunk/drivers/pci/quirks.c b/trunk/drivers/pci/quirks.c index 7a451ff56ecc..51553179e967 100644 --- a/trunk/drivers/pci/quirks.c +++ b/trunk/drivers/pci/quirks.c @@ -3081,36 +3081,17 @@ static int reset_intel_generic_dev(struct pci_dev *dev, int probe) static int reset_intel_82599_sfp_virtfn(struct pci_dev *dev, int probe) { - int i; - u16 status; + int pos; - /* - * http://www.intel.com/content/dam/doc/datasheet/82599-10-gbe-controller-datasheet.pdf - * - * The 82599 supports FLR on VFs, but FLR support is reported only - * in the PF DEVCAP (sec 9.3.10.4), not in the VF DEVCAP (sec 9.5). - * Therefore, we can't use pcie_flr(), which checks the VF DEVCAP. - */ + pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (!pos) + return -ENOTTY; if (probe) return 0; - /* Wait for Transaction Pending bit clean */ - for (i = 0; i < 4; i++) { - if (i) - msleep((1 << (i - 1)) * 100); - - pcie_capability_read_word(dev, PCI_EXP_DEVSTA, &status); - if (!(status & PCI_EXP_DEVSTA_TRPND)) - goto clear; - } - - dev_err(&dev->dev, "transaction is not cleared; " - "proceeding with reset anyway\n"); - -clear: - pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_BCR_FLR); - + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_BCR_FLR); msleep(100); return 0; diff --git a/trunk/drivers/pci/search.c b/trunk/drivers/pci/search.c index 621b162ceb69..993d4a0a2469 100644 --- a/trunk/drivers/pci/search.c +++ b/trunk/drivers/pci/search.c @@ -41,7 +41,7 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev) continue; } /* PCI device should connect to a PCIe bridge */ - if (pci_pcie_type(pdev) != PCI_EXP_TYPE_PCI_BRIDGE) { + if (pdev->pcie_type != PCI_EXP_TYPE_PCI_BRIDGE) { /* Busted hardware? */ WARN_ON_ONCE(1); return NULL; diff --git a/trunk/drivers/pci/setup-bus.c b/trunk/drivers/pci/setup-bus.c index 1e808ca338f8..fb506137aaee 100644 --- a/trunk/drivers/pci/setup-bus.c +++ b/trunk/drivers/pci/setup-bus.c @@ -697,38 +697,6 @@ static resource_size_t calculate_memsize(resource_size_t size, return size; } -resource_size_t __weak pcibios_window_alignment(struct pci_bus *bus, - unsigned long type) -{ - return 1; -} - -#define PCI_P2P_DEFAULT_MEM_ALIGN 0x100000 /* 1MiB */ -#define PCI_P2P_DEFAULT_IO_ALIGN 0x1000 /* 4KiB */ -#define PCI_P2P_DEFAULT_IO_ALIGN_1K 0x400 /* 1KiB */ - -static resource_size_t window_alignment(struct pci_bus *bus, - unsigned long type) -{ - resource_size_t align = 1, arch_align; - - if (type & IORESOURCE_MEM) - align = PCI_P2P_DEFAULT_MEM_ALIGN; - else if (type & IORESOURCE_IO) { - /* - * Per spec, I/O windows are 4K-aligned, but some - * bridges have an extension to support 1K alignment. - */ - if (bus->self->io_window_1k) - align = PCI_P2P_DEFAULT_IO_ALIGN_1K; - else - align = PCI_P2P_DEFAULT_IO_ALIGN; - } - - arch_align = pcibios_window_alignment(bus, type); - return max(align, arch_align); -} - /** * pbus_size_io() - size the io window of a given bus * @@ -749,12 +717,17 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); unsigned long size = 0, size0 = 0, size1 = 0; resource_size_t children_add_size = 0; - resource_size_t min_align, io_align, align; + resource_size_t min_align = 4096, align; if (!b_res) return; - io_align = min_align = window_alignment(bus, IORESOURCE_IO); + /* + * Per spec, I/O windows are 4K-aligned, but some bridges have an + * extension to support 1K alignment. + */ + if (bus->self->io_window_1k) + min_align = 1024; list_for_each_entry(dev, &bus->devices, bus_list) { int i; @@ -781,8 +754,8 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, } } - if (min_align > io_align) - min_align = io_align; + if (min_align > 4096) + min_align = 4096; size0 = calculate_iosize(size, min_size, size1, resource_size(b_res), min_align); @@ -812,28 +785,6 @@ static void pbus_size_io(struct pci_bus *bus, resource_size_t min_size, } } -static inline resource_size_t calculate_mem_align(resource_size_t *aligns, - int max_order) -{ - resource_size_t align = 0; - resource_size_t min_align = 0; - int order; - - for (order = 0; order <= max_order; order++) { - resource_size_t align1 = 1; - - align1 <<= (order + 20); - - if (!align) - min_align = align1; - else if (ALIGN(align + min_align, min_align) < align1) - min_align = align1 >> 1; - align += aligns[order]; - } - - return min_align; -} - /** * pbus_size_mem() - size the memory window of a given bus * @@ -913,9 +864,19 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, children_add_size += get_res_add_size(realloc_head, r); } } + align = 0; + min_align = 0; + for (order = 0; order <= max_order; order++) { + resource_size_t align1 = 1; - min_align = calculate_mem_align(aligns, max_order); - min_align = max(min_align, window_alignment(bus, b_res->flags & mask)); + align1 <<= (order + 20); + + if (!align) + min_align = align1; + else if (ALIGN(align + min_align, min_align) < align1) + min_align = align1 >> 1; + align += aligns[order]; + } size0 = calculate_memsize(size, min_size, 0, resource_size(b_res), min_align); if (children_add_size > add_size) add_size = children_add_size; diff --git a/trunk/drivers/rapidio/devices/tsi721.c b/trunk/drivers/rapidio/devices/tsi721.c index d5e1625bbac2..5d44252b7342 100644 --- a/trunk/drivers/rapidio/devices/tsi721.c +++ b/trunk/drivers/rapidio/devices/tsi721.c @@ -2219,7 +2219,9 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, const struct pci_device_id *id) { struct tsi721_device *priv; + int cap; int err; + u32 regval; priv = kzalloc(sizeof(struct tsi721_device), GFP_KERNEL); if (priv == NULL) { @@ -2328,16 +2330,20 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, dev_info(&pdev->dev, "Unable to set consistent DMA mask\n"); } - BUG_ON(!pci_is_pcie(pdev)); + cap = pci_pcie_cap(pdev); + BUG_ON(cap == 0); /* Clear "no snoop" and "relaxed ordering" bits, use default MRRS. */ - pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL, - PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN | - PCI_EXP_DEVCTL_NOSNOOP_EN, - 0x2 << MAX_READ_REQUEST_SZ_SHIFT); + pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL, ®val); + regval &= ~(PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN | + PCI_EXP_DEVCTL_NOSNOOP_EN); + regval |= 0x2 << MAX_READ_REQUEST_SZ_SHIFT; + pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL, regval); /* Adjust PCIe completion timeout. */ - pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL2, 0xf, 0x2); + pci_read_config_dword(pdev, cap + PCI_EXP_DEVCTL2, ®val); + regval &= ~(0x0f); + pci_write_config_dword(pdev, cap + PCI_EXP_DEVCTL2, regval | 0x2); /* * FIXUP: correct offsets of MSI-X tables in the MSI-X Capability Block diff --git a/trunk/drivers/scsi/ipr.c b/trunk/drivers/scsi/ipr.c index 6077c43edacc..467dc38246f9 100644 --- a/trunk/drivers/scsi/ipr.c +++ b/trunk/drivers/scsi/ipr.c @@ -6304,14 +6304,14 @@ static struct ata_port_info sata_port_info = { #ifdef CONFIG_PPC_PSERIES static const u16 ipr_blocked_processors[] = { - PVR_NORTHSTAR, - PVR_PULSAR, - PVR_POWER4, - PVR_ICESTAR, - PVR_SSTAR, - PVR_POWER4p, - PVR_630, - PVR_630p + PV_NORTHSTAR, + PV_PULSAR, + PV_POWER4, + PV_ICESTAR, + PV_SSTAR, + PV_POWER4p, + PV_630, + PV_630p }; /** @@ -6331,7 +6331,7 @@ static int ipr_invalid_adapter(struct ipr_ioa_cfg *ioa_cfg) if ((ioa_cfg->type == 0x5702) && (ioa_cfg->pdev->revision < 4)) { for (i = 0; i < ARRAY_SIZE(ipr_blocked_processors); i++){ - if (pvr_version_is(ipr_blocked_processors[i])) + if (__is_processor(ipr_blocked_processors[i])) return 1; } } diff --git a/trunk/drivers/scsi/qla2xxx/qla_nx.c b/trunk/drivers/scsi/qla2xxx/qla_nx.c index 7cfdf2bd8edb..9ce3a8f8754f 100644 --- a/trunk/drivers/scsi/qla2xxx/qla_nx.c +++ b/trunk/drivers/scsi/qla2xxx/qla_nx.c @@ -1615,11 +1615,13 @@ qla82xx_get_fw_offs(struct qla_hw_data *ha) char * qla82xx_pci_info_str(struct scsi_qla_host *vha, char *str) { + int pcie_reg; struct qla_hw_data *ha = vha->hw; char lwstr[6]; uint16_t lnk; - pcie_capability_read_word(ha->pdev, PCI_EXP_LNKSTA, &lnk); + pcie_reg = pci_pcie_cap(ha->pdev); + pci_read_config_word(ha->pdev, pcie_reg + PCI_EXP_LNKSTA, &lnk); ha->link_width = (lnk >> 4) & 0x3f; strcpy(str, "PCIe ("); @@ -2495,6 +2497,7 @@ qla82xx_load_fw(scsi_qla_host_t *vha) int qla82xx_start_firmware(scsi_qla_host_t *vha) { + int pcie_cap; uint16_t lnk; struct qla_hw_data *ha = vha->hw; @@ -2525,7 +2528,8 @@ qla82xx_start_firmware(scsi_qla_host_t *vha) } /* Negotiated Link width */ - pcie_capability_read_word(ha->pdev, PCI_EXP_LNKSTA, &lnk); + pcie_cap = pci_pcie_cap(ha->pdev); + pci_read_config_word(ha->pdev, pcie_cap + PCI_EXP_LNKSTA, &lnk); ha->link_width = (lnk >> 4) & 0x3f; /* Synchronize with Receive peg */ diff --git a/trunk/drivers/scsi/qla4xxx/ql4_nx.c b/trunk/drivers/scsi/qla4xxx/ql4_nx.c index 807bf76f1b6a..939d7261c37a 100644 --- a/trunk/drivers/scsi/qla4xxx/ql4_nx.c +++ b/trunk/drivers/scsi/qla4xxx/ql4_nx.c @@ -1566,6 +1566,7 @@ qla4_8xxx_set_qsnt_ready(struct scsi_qla_host *ha) static int qla4_8xxx_start_firmware(struct scsi_qla_host *ha, uint32_t image_start) { + int pcie_cap; uint16_t lnk; /* scrub dma mask expansion register */ @@ -1589,7 +1590,8 @@ qla4_8xxx_start_firmware(struct scsi_qla_host *ha, uint32_t image_start) } /* Negotiated Link width */ - pcie_capability_read_word(ha->pdev, PCI_EXP_LNKSTA, &lnk); + pcie_cap = pci_pcie_cap(ha->pdev); + pci_read_config_word(ha->pdev, pcie_cap + PCI_EXP_LNKSTA, &lnk); ha->link_width = (lnk >> 4) & 0x3f; /* Synchronize with Receive peg */ diff --git a/trunk/drivers/staging/et131x/et131x.c b/trunk/drivers/staging/et131x/et131x.c index 49553f88c7b3..029725c89e58 100644 --- a/trunk/drivers/staging/et131x/et131x.c +++ b/trunk/drivers/staging/et131x/et131x.c @@ -3995,14 +3995,16 @@ static void et131x_hwaddr_init(struct et131x_adapter *adapter) static int et131x_pci_init(struct et131x_adapter *adapter, struct pci_dev *pdev) { + int cap = pci_pcie_cap(pdev); u16 max_payload; + u16 ctl; int i, rc; rc = et131x_init_eeprom(adapter); if (rc < 0) goto out; - if (!pci_is_pcie(pdev)) { + if (!cap) { dev_err(&pdev->dev, "Missing PCIe capabilities\n"); goto err_out; } @@ -4010,7 +4012,7 @@ static int et131x_pci_init(struct et131x_adapter *adapter, /* Let's set up the PORT LOGIC Register. First we need to know what * the max_payload_size is */ - if (pcie_capability_read_word(pdev, PCI_EXP_DEVCAP, &max_payload)) { + if (pci_read_config_word(pdev, cap + PCI_EXP_DEVCAP, &max_payload)) { dev_err(&pdev->dev, "Could not read PCI config space for Max Payload Size\n"); goto err_out; @@ -4047,10 +4049,17 @@ static int et131x_pci_init(struct et131x_adapter *adapter, } /* Change the max read size to 2k */ - if (pcie_capability_clear_and_set_word(pdev, PCI_EXP_DEVCTL, - PCI_EXP_DEVCTL_READRQ, 0x4 << 12)) { + if (pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl)) { dev_err(&pdev->dev, - "Couldn't change PCI config space for Max read size\n"); + "Could not read PCI config space for Max read size\n"); + goto err_out; + } + + ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | (0x04 << 12); + + if (pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl)) { + dev_err(&pdev->dev, + "Could not write PCI config space for Max read size\n"); goto err_out; } diff --git a/trunk/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c b/trunk/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c index 5abbee37cdca..ddadcc3e4e7c 100644 --- a/trunk/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c +++ b/trunk/drivers/staging/rtl8192e/rtl8192e/rtl_pci.c @@ -31,10 +31,12 @@ static void rtl8192_parse_pci_configuration(struct pci_dev *pdev, struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); u8 tmp; - u16 LinkCtrlReg; + int pos; + u8 LinkCtrlReg; - pcie_capability_read_word(priv->pdev, PCI_EXP_LNKCTL, &LinkCtrlReg); - priv->NdisAdapter.LinkCtrlReg = (u8)LinkCtrlReg; + pos = pci_find_capability(priv->pdev, PCI_CAP_ID_EXP); + pci_read_config_byte(priv->pdev, pos + PCI_EXP_LNKCTL, &LinkCtrlReg); + priv->NdisAdapter.LinkCtrlReg = LinkCtrlReg; RT_TRACE(COMP_INIT, "Link Control Register =%x\n", priv->NdisAdapter.LinkCtrlReg); diff --git a/trunk/drivers/tty/hvc/hvc_console.c b/trunk/drivers/tty/hvc/hvc_console.c index f1d4d96a4a07..2d691eb7c40a 100644 --- a/trunk/drivers/tty/hvc/hvc_console.c +++ b/trunk/drivers/tty/hvc/hvc_console.c @@ -245,20 +245,6 @@ static void hvc_port_destruct(struct tty_port *port) kfree(hp); } -static void hvc_check_console(int index) -{ - /* Already enabled, bail out */ - if (hvc_console.flags & CON_ENABLED) - return; - - /* If this index is what the user requested, then register - * now (setup won't fail at this point). It's ok to just - * call register again if previously .setup failed. - */ - if (index == hvc_console.index) - register_console(&hvc_console); -} - /* * hvc_instantiate() is an early console discovery method which locates * consoles * prior to the vio subsystem discovering them. Hotplugged @@ -289,8 +275,12 @@ int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops) if (last_hvc < index) last_hvc = index; - /* check if we need to re-register the kernel console */ - hvc_check_console(index); + /* if this index is what the user requested, then register + * now (setup won't fail at this point). It's ok to just + * call register again if previously .setup failed. + */ + if (index == hvc_console.index) + register_console(&hvc_console); return 0; } @@ -868,15 +858,10 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data, i = ++last_hvc; hp->index = i; - cons_ops[i] = ops; - vtermnos[i] = vtermno; list_add_tail(&(hp->next), &hvc_structs); spin_unlock(&hvc_structs_lock); - /* check if we need to re-register the kernel console */ - hvc_check_console(i); - return hp; } EXPORT_SYMBOL_GPL(hvc_alloc); @@ -889,12 +874,8 @@ int hvc_remove(struct hvc_struct *hp) tty = tty_port_tty_get(&hp->port); spin_lock_irqsave(&hp->lock, flags); - if (hp->index < MAX_NR_HVC_CONSOLES) { - console_lock(); + if (hp->index < MAX_NR_HVC_CONSOLES) vtermnos[hp->index] = -1; - cons_ops[hp->index] = NULL; - console_unlock(); - } /* Don't whack hp->irq because tty_hangup() will need to free the irq. */ diff --git a/trunk/drivers/tty/hvc/hvc_vio.c b/trunk/drivers/tty/hvc/hvc_vio.c index 070c0ee68642..ee307799271a 100644 --- a/trunk/drivers/tty/hvc/hvc_vio.c +++ b/trunk/drivers/tty/hvc/hvc_vio.c @@ -230,69 +230,6 @@ static const struct hv_ops hvterm_hvsi_ops = { .tiocmset = hvterm_hvsi_tiocmset, }; -static void udbg_hvc_putc(char c) -{ - int count = -1; - - if (!hvterm_privs[0]) - return; - - if (c == '\n') - udbg_hvc_putc('\r'); - - do { - switch(hvterm_privs[0]->proto) { - case HV_PROTOCOL_RAW: - count = hvterm_raw_put_chars(0, &c, 1); - break; - case HV_PROTOCOL_HVSI: - count = hvterm_hvsi_put_chars(0, &c, 1); - break; - } - } while(count == 0); -} - -static int udbg_hvc_getc_poll(void) -{ - int rc = 0; - char c; - - if (!hvterm_privs[0]) - return -1; - - switch(hvterm_privs[0]->proto) { - case HV_PROTOCOL_RAW: - rc = hvterm_raw_get_chars(0, &c, 1); - break; - case HV_PROTOCOL_HVSI: - rc = hvterm_hvsi_get_chars(0, &c, 1); - break; - } - if (!rc) - return -1; - return c; -} - -static int udbg_hvc_getc(void) -{ - int ch; - - if (!hvterm_privs[0]) - return -1; - - for (;;) { - ch = udbg_hvc_getc_poll(); - if (ch == -1) { - /* This shouldn't be needed...but... */ - volatile unsigned long delay; - for (delay=0; delay < 2000000; delay++) - ; - } else { - return ch; - } - } -} - static int __devinit hvc_vio_probe(struct vio_dev *vdev, const struct vio_device_id *id) { @@ -352,13 +289,6 @@ static int __devinit hvc_vio_probe(struct vio_dev *vdev, return PTR_ERR(hp); dev_set_drvdata(&vdev->dev, hp); - /* register udbg if it's not there already for console 0 */ - if (hp->index == 0 && !udbg_putc) { - udbg_putc = udbg_hvc_putc; - udbg_getc = udbg_hvc_getc; - udbg_getc_poll = udbg_hvc_getc_poll; - } - return 0; } @@ -401,6 +331,59 @@ static void __exit hvc_vio_exit(void) } module_exit(hvc_vio_exit); +static void udbg_hvc_putc(char c) +{ + int count = -1; + + if (c == '\n') + udbg_hvc_putc('\r'); + + do { + switch(hvterm_priv0.proto) { + case HV_PROTOCOL_RAW: + count = hvterm_raw_put_chars(0, &c, 1); + break; + case HV_PROTOCOL_HVSI: + count = hvterm_hvsi_put_chars(0, &c, 1); + break; + } + } while(count == 0); +} + +static int udbg_hvc_getc_poll(void) +{ + int rc = 0; + char c; + + switch(hvterm_priv0.proto) { + case HV_PROTOCOL_RAW: + rc = hvterm_raw_get_chars(0, &c, 1); + break; + case HV_PROTOCOL_HVSI: + rc = hvterm_hvsi_get_chars(0, &c, 1); + break; + } + if (!rc) + return -1; + return c; +} + +static int udbg_hvc_getc(void) +{ + int ch; + for (;;) { + ch = udbg_hvc_getc_poll(); + if (ch == -1) { + /* This shouldn't be needed...but... */ + volatile unsigned long delay; + for (delay=0; delay < 2000000; delay++) + ; + } else { + return ch; + } + } +} + void __init hvc_vio_init_early(void) { struct device_node *stdout_node; diff --git a/trunk/drivers/video/ps3fb.c b/trunk/drivers/video/ps3fb.c index 4e292f29bf5d..213fbbcf613b 100644 --- a/trunk/drivers/video/ps3fb.c +++ b/trunk/drivers/video/ps3fb.c @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -1140,7 +1141,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) */ fb_start = ps3fb_videomemory.address + GPU_FB_START; info->screen_base = (char __force __iomem *)fb_start; - info->fix.smem_start = __pa(fb_start); + info->fix.smem_start = virt_to_abs(fb_start); info->fix.smem_len = ps3fb_videomemory.size - GPU_FB_START; info->pseudo_palette = par->pseudo_palette; diff --git a/trunk/include/linux/pci.h b/trunk/include/linux/pci.h index 2c755243eef2..5faa8310eec9 100644 --- a/trunk/include/linux/pci.h +++ b/trunk/include/linux/pci.h @@ -254,10 +254,10 @@ struct pci_dev { u8 revision; /* PCI revision, low byte of class word */ u8 hdr_type; /* PCI header type (`multi' flag masked out) */ u8 pcie_cap; /* PCI-E capability offset */ + u8 pcie_type:4; /* PCI-E device/port type */ u8 pcie_mpss:3; /* PCI-E Max Payload Size Supported */ u8 rom_base_reg; /* which config register controls the ROM */ u8 pin; /* which interrupt pin this device uses */ - u16 pcie_flags_reg; /* cached PCI-E Capabilities Register */ struct pci_driver *driver; /* which driver has allocated this device */ u64 dma_mask; /* Mask of the bits of bus address this @@ -816,39 +816,6 @@ static inline int pci_write_config_dword(const struct pci_dev *dev, int where, return pci_bus_write_config_dword(dev->bus, dev->devfn, where, val); } -int pcie_capability_read_word(struct pci_dev *dev, int pos, u16 *val); -int pcie_capability_read_dword(struct pci_dev *dev, int pos, u32 *val); -int pcie_capability_write_word(struct pci_dev *dev, int pos, u16 val); -int pcie_capability_write_dword(struct pci_dev *dev, int pos, u32 val); -int pcie_capability_clear_and_set_word(struct pci_dev *dev, int pos, - u16 clear, u16 set); -int pcie_capability_clear_and_set_dword(struct pci_dev *dev, int pos, - u32 clear, u32 set); - -static inline int pcie_capability_set_word(struct pci_dev *dev, int pos, - u16 set) -{ - return pcie_capability_clear_and_set_word(dev, pos, 0, set); -} - -static inline int pcie_capability_set_dword(struct pci_dev *dev, int pos, - u32 set) -{ - return pcie_capability_clear_and_set_dword(dev, pos, 0, set); -} - -static inline int pcie_capability_clear_word(struct pci_dev *dev, int pos, - u16 clear) -{ - return pcie_capability_clear_and_set_word(dev, pos, clear, 0); -} - -static inline int pcie_capability_clear_dword(struct pci_dev *dev, int pos, - u32 clear) -{ - return pcie_capability_clear_and_set_dword(dev, pos, clear, 0); -} - /* user-space driven config access */ int pci_user_read_config_byte(struct pci_dev *dev, int where, u8 *val); int pci_user_read_config_word(struct pci_dev *dev, int where, u16 *val); @@ -1064,8 +1031,6 @@ int pci_cfg_space_size_ext(struct pci_dev *dev); int pci_cfg_space_size(struct pci_dev *dev); unsigned char pci_bus_max_busnr(struct pci_bus *bus); void pci_setup_bridge(struct pci_bus *bus); -resource_size_t pcibios_window_alignment(struct pci_bus *bus, - unsigned long type); #define PCI_VGA_STATE_CHANGE_BRIDGE (1 << 0) #define PCI_VGA_STATE_CHANGE_DECODES (1 << 1) @@ -1685,15 +1650,6 @@ static inline bool pci_is_pcie(struct pci_dev *dev) return !!pci_pcie_cap(dev); } -/** - * pci_pcie_type - get the PCIe device/port type - * @dev: PCI device - */ -static inline int pci_pcie_type(const struct pci_dev *dev) -{ - return (dev->pcie_flags_reg & PCI_EXP_FLAGS_TYPE) >> 4; -} - void pci_request_acs(void); bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags); bool pci_acs_path_enabled(struct pci_dev *start, diff --git a/trunk/include/linux/pci_regs.h b/trunk/include/linux/pci_regs.h index 3958f70f3202..7fb75b143755 100644 --- a/trunk/include/linux/pci_regs.h +++ b/trunk/include/linux/pci_regs.h @@ -549,7 +549,6 @@ #define PCI_EXP_LNKCAP2_SLS_8_0GB 0x04 /* Current Link Speed 8.0GT/s */ #define PCI_EXP_LNKCAP2_CROSSLINK 0x100 /* Crosslink supported */ #define PCI_EXP_LNKCTL2 48 /* Link Control 2 */ -#define PCI_EXP_LNKSTA2 50 /* Link Status 2 */ #define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */ /* Extended Capabilities (PCI-X 2.0 and Express) */