diff options
author | Scott Wood <scottwood@freescale.com> | 2013-11-01 21:17:16 (GMT) |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2013-11-03 22:47:10 (GMT) |
commit | 31110de40dca4d4aeff4f253b3def948b88fa590 (patch) | |
tree | 0d811783836d52f15e37b4244de54f44ed4f93ad /arch/powerpc/platforms/pseries/msi.c | |
parent | ae60d5d27c429b13cf28a09ab8b9d30682433c5a (diff) | |
parent | 8bb495e3f02401ee6f76d1b1d77f3ac9f079e376 (diff) | |
download | linux-fsl-qoriq-31110de40dca4d4aeff4f253b3def948b88fa590.tar.xz |
Merge tag 'v3.10' into sdk-kernel-3.10
git rebase --continue
Linux 3.10
Conflicts:
Documentation/virtual/kvm/api.txt
arch/ia64/kvm/Makefile
arch/powerpc/Kconfig
arch/powerpc/Makefile
arch/powerpc/boot/dts/b4420qds.dts
arch/powerpc/boot/dts/b4860qds.dts
arch/powerpc/boot/dts/b4qds.dts
arch/powerpc/boot/dts/fsl/b4420si-post.dtsi
arch/powerpc/boot/dts/fsl/b4420si-pre.dtsi
arch/powerpc/boot/dts/fsl/b4860si-post.dtsi
arch/powerpc/boot/dts/fsl/b4860si-pre.dtsi
arch/powerpc/boot/dts/fsl/b4si-post.dtsi
arch/powerpc/boot/dts/fsl/p1010si-post.dtsi
arch/powerpc/boot/dts/fsl/p2041si-post.dtsi
arch/powerpc/boot/dts/fsl/p3041si-post.dtsi
arch/powerpc/boot/dts/fsl/p4080si-post.dtsi
arch/powerpc/boot/dts/fsl/p5020si-post.dtsi
arch/powerpc/boot/dts/fsl/p5040si-post.dtsi
arch/powerpc/boot/dts/fsl/qonverge-usb2-dr-0.dtsi
arch/powerpc/boot/dts/fsl/qoriq-sec5.0-0.dtsi
arch/powerpc/boot/dts/fsl/t4240si-post.dtsi
arch/powerpc/boot/dts/fsl/t4240si-pre.dtsi
arch/powerpc/boot/dts/p1025rdb_36b.dts
arch/powerpc/boot/dts/t4240qds.dts
arch/powerpc/configs/corenet64_smp_defconfig
arch/powerpc/configs/mpc85xx_defconfig
arch/powerpc/configs/mpc85xx_smp_defconfig
arch/powerpc/include/asm/cputable.h
arch/powerpc/include/asm/kvm_host.h
arch/powerpc/include/asm/kvm_ppc.h
arch/powerpc/include/asm/machdep.h
arch/powerpc/include/uapi/asm/kvm.h
arch/powerpc/kernel/cpu_setup_fsl_booke.S
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/idle.c
arch/powerpc/kernel/pci-common.c
arch/powerpc/kvm/Kconfig
arch/powerpc/kvm/book3s.c
arch/powerpc/kvm/booke.c
arch/powerpc/kvm/e500.c
arch/powerpc/kvm/e500_mmu.c
arch/powerpc/kvm/e500_mmu_host.c
arch/powerpc/kvm/e500mc.c
arch/powerpc/kvm/emulate.c
arch/powerpc/kvm/irq.h
arch/powerpc/kvm/mpic.c
arch/powerpc/kvm/powerpc.c
arch/powerpc/mm/tlb_nohash.c
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/85xx/b4_qds.c
arch/powerpc/platforms/85xx/t4240_qds.c
arch/powerpc/platforms/pseries/smp.c
arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
arch/powerpc/sysdev/fsl_msi.c
arch/powerpc/sysdev/fsl_pci.c
arch/powerpc/sysdev/fsl_pci.h
arch/powerpc/sysdev/mpic.c
arch/x86/kvm/Makefile
arch/x86/kvm/x86.c
drivers/Kconfig
drivers/clk/Kconfig
drivers/cpufreq/Makefile
drivers/crypto/caam/caamalg.c
drivers/crypto/caam/intern.h
drivers/crypto/caam/jr.c
drivers/crypto/caam/regs.h
drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
drivers/iommu/Makefile
drivers/iommu/amd_iommu.c
drivers/iommu/exynos-iommu.c
drivers/iommu/intel-iommu.c
drivers/iommu/iommu.c
drivers/iommu/msm_iommu.c
drivers/iommu/omap-iommu.c
drivers/iommu/tegra-gart.c
drivers/iommu/tegra-smmu.c
drivers/misc/Makefile
drivers/mmc/card/block.c
drivers/mmc/card/queue.c
drivers/mmc/core/core.c
drivers/mtd/nand/fsl_ifc_nand.c
drivers/net/ethernet/3com/3c501.c
drivers/net/ethernet/8390/3c503.c
drivers/net/ethernet/dec/ewrk3.c
drivers/net/ethernet/freescale/fec.c
drivers/net/ethernet/freescale/gianfar.c
drivers/net/ethernet/freescale/gianfar.h
drivers/net/ethernet/i825xx/3c505.c
drivers/net/ethernet/i825xx/3c507.c
drivers/rtc/rtc-ds3232.c
drivers/s390/net/qeth_core_main.c
drivers/staging/Kconfig
drivers/staging/Makefile
drivers/staging/ccg/u_ether.c
drivers/usb/gadget/fsl_udc_core.c
drivers/usb/otg/fsl_otg.c
drivers/vfio/vfio.c
drivers/watchdog/Kconfig
include/linux/iommu.h
include/linux/kvm_host.h
include/linux/mmc/sdhci.h
include/linux/msi.h
include/linux/netdev_features.h
include/linux/pci.h
include/linux/skbuff.h
include/net/ip6_route.h
include/net/sch_generic.h
include/net/xfrm.h
include/uapi/linux/kvm.h
net/core/netpoll.c
virt/kvm/irqchip.c
virt/kvm/kvm_main.c
Diffstat (limited to 'arch/powerpc/platforms/pseries/msi.c')
-rw-r--r-- | arch/powerpc/platforms/pseries/msi.c | 70 |
1 files changed, 45 insertions, 25 deletions
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c index e5b0847..6d2f0ab 100644 --- a/arch/powerpc/platforms/pseries/msi.c +++ b/arch/powerpc/platforms/pseries/msi.c @@ -24,26 +24,7 @@ static int query_token, change_token; #define RTAS_RESET_FN 2 #define RTAS_CHANGE_MSI_FN 3 #define RTAS_CHANGE_MSIX_FN 4 - -static struct pci_dn *get_pdn(struct pci_dev *pdev) -{ - struct device_node *dn; - struct pci_dn *pdn; - - dn = pci_device_to_OF_node(pdev); - if (!dn) { - dev_dbg(&pdev->dev, "rtas_msi: No OF device node\n"); - return NULL; - } - - pdn = PCI_DN(dn); - if (!pdn) { - dev_dbg(&pdev->dev, "rtas_msi: No PCI DN\n"); - return NULL; - } - - return pdn; -} +#define RTAS_CHANGE_32MSI_FN 5 /* RTAS Helpers */ @@ -58,7 +39,8 @@ static int rtas_change_msi(struct pci_dn *pdn, u32 func, u32 num_irqs) seq_num = 1; do { - if (func == RTAS_CHANGE_MSI_FN || func == RTAS_CHANGE_MSIX_FN) + if (func == RTAS_CHANGE_MSI_FN || func == RTAS_CHANGE_MSIX_FN || + func == RTAS_CHANGE_32MSI_FN) rc = rtas_call(change_token, 6, 4, rtas_ret, addr, BUID_HI(buid), BUID_LO(buid), func, num_irqs, seq_num); @@ -89,7 +71,7 @@ static void rtas_disable_msi(struct pci_dev *pdev) { struct pci_dn *pdn; - pdn = get_pdn(pdev); + pdn = pci_get_pdn(pdev); if (!pdn) return; @@ -150,7 +132,7 @@ static int check_req(struct pci_dev *pdev, int nvec, char *prop_name) struct pci_dn *pdn; const u32 *req_msi; - pdn = get_pdn(pdev); + pdn = pci_get_pdn(pdev); if (!pdn) return -ENODEV; @@ -392,6 +374,23 @@ static int check_msix_entries(struct pci_dev *pdev) return 0; } +static void rtas_hack_32bit_msi_gen2(struct pci_dev *pdev) +{ + u32 addr_hi, addr_lo; + + /* + * We should only get in here for IODA1 configs. This is based on the + * fact that we using RTAS for MSIs, we don't have the 32 bit MSI RTAS + * support, and we are in a PCIe Gen2 slot. + */ + dev_info(&pdev->dev, + "rtas_msi: No 32 bit MSI firmware support, forcing 32 bit MSI\n"); + pci_read_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_HI, &addr_hi); + addr_lo = 0xffff0000 | ((addr_hi >> (48 - 32)) << 4); + pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_LO, addr_lo); + pci_write_config_dword(pdev, pdev->msi_cap + PCI_MSI_ADDRESS_HI, 0); +} + static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) { struct pci_dn *pdn; @@ -399,8 +398,9 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) struct msi_desc *entry; struct msi_msg msg; int nvec = nvec_in; + int use_32bit_msi_hack = 0; - pdn = get_pdn(pdev); + pdn = pci_get_pdn(pdev); if (!pdn) return -ENODEV; @@ -426,12 +426,31 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec_in, int type) */ again: if (type == PCI_CAP_ID_MSI) { - rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec); + if (pdn->force_32bit_msi) { + rc = rtas_change_msi(pdn, RTAS_CHANGE_32MSI_FN, nvec); + if (rc < 0) { + /* + * We only want to run the 32 bit MSI hack below if + * the max bus speed is Gen2 speed + */ + if (pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT) + return rc; + + use_32bit_msi_hack = 1; + } + } else + rc = -1; + + if (rc < 0) + rc = rtas_change_msi(pdn, RTAS_CHANGE_MSI_FN, nvec); if (rc < 0) { pr_debug("rtas_msi: trying the old firmware call.\n"); rc = rtas_change_msi(pdn, RTAS_CHANGE_FN, nvec); } + + if (use_32bit_msi_hack && rc > 0) + rtas_hack_32bit_msi_gen2(pdev); } else rc = rtas_change_msi(pdn, RTAS_CHANGE_MSIX_FN, nvec); @@ -512,3 +531,4 @@ static int rtas_msi_init(void) return 0; } arch_initcall(rtas_msi_init); + |