From: Linus Torvalds Date: Thu, 22 Oct 2020 19:41:00 +0000 (-0700) Subject: Merge tag 'pci-v5.10-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaa... X-Git-Tag: v5.10-rc1~58 X-Git-Url: https://repo.jachan.dev/linux.git/commitdiff_plain/00937f36b09e89c74e4a059dbb8acbf4b971d5eb?hp=-c Merge tag 'pci-v5.10-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci Pull PCI updates from Bjorn Helgaas: "Enumeration: - Print IRQ number used by PCIe Link Bandwidth Notification (Dongdong Liu) - Add schedule point in pci_read_config() to reduce max latency (Jiang Biao) - Add Kconfig options for MPS/MRRS strategy (Jim Quinlan) Resource management: - Fix pci_iounmap() memory leak when !CONFIG_GENERIC_IOMAP (Lorenzo Pieralisi) PCIe native device hotplug: - Reduce noisiness on hot removal (Lukas Wunner) Power management: - Revert "PCI/PM: Apply D2 delay as milliseconds, not microseconds" that was done on the basis of spec typo (Bjorn Helgaas) - Rename pci_dev.d3_delay to d3hot_delay to remove D3hot/D3cold ambiguity (Krzysztof Wilczyński) - Remove unused pcibios_pm_ops (Vaibhav Gupta) IOMMU: - Enable Translation Blocking for external devices to harden against DMA attacks (Rajat Jain) Error handling: - Add an ACPI APEI notifier chain for vendor CPER records to enable device-specific error handling (Shiju Jose) ASPM: - Remove struct aspm_register_info to simplify code (Saheed O. Bolarinwa) Amlogic Meson PCIe controller driver: - Build as module by default (Kevin Hilman) Ampere Altra PCIe controller driver: - Add MCFG quirk to work around non-standard ECAM implementation (Tuan Phan) Broadcom iProc PCIe controller driver: - Set affinity mask on MSI interrupts (Mark Tomlinson) Broadcom STB PCIe controller driver: - Make PCIE_BRCMSTB depend on ARCH_BRCMSTB (Jim Quinlan) - Add DT bindings for more Brcmstb chips (Jim Quinlan) - Add bcm7278 register info (Jim Quinlan) - Add bcm7278 PERST# support (Jim Quinlan) - Add suspend and resume pm_ops (Jim Quinlan) - Add control of rescal reset (Jim Quinlan) - Set additional internal memory DMA viewport sizes (Jim Quinlan) - Accommodate MSI for older chips (Jim Quinlan) - Set bus max burst size by chip type (Jim Quinlan) - Add support for bcm7211, bcm7216, bcm7445, bcm7278 (Jim Quinlan) Freescale i.MX6 PCIe controller driver: - Use dev_err_probe() to reduce redundant messages (Anson Huang) Freescale Layerscape PCIe controller driver: - Enforce 4K DMA buffer alignment in endpoint test (Hou Zhiqiang) - Add DT compatible strings for ls1088a, ls2088a (Xiaowei Bao) - Add endpoint support for ls1088a, ls2088a (Xiaowei Bao) - Add endpoint test support for lS1088a (Xiaowei Bao) - Add MSI-X support for ls1088a (Xiaowei Bao) HiSilicon HIP PCIe controller driver: - Handle HIP-specific errors via ACPI APEI (Yicong Yang) HiSilicon Kirin PCIe controller driver: - Return -EPROBE_DEFER if the GPIO isn't ready (Bean Huo) Intel VMD host bridge driver: - Factor out physical offset, bus offset, IRQ domain, IRQ allocation (Jon Derrick) - Use generic PCI PM correctly (Jon Derrick) Marvell Aardvark PCIe controller driver: - Fix compilation on s390 (Pali Rohár) - Implement driver 'remove' function and allow to build it as module (Pali Rohár) - Move PCIe reset card code to advk_pcie_train_link() (Pali Rohár) - Convert mvebu a3700 internal SMCC firmware return codes to errno (Pali Rohár) - Fix initialization with old Marvell's Arm Trusted Firmware (Pali Rohár) Microsoft Hyper-V host bridge driver: - Fix hibernation in case interrupts are not re-created (Dexuan Cui) NVIDIA Tegra PCIe controller driver: - Stop checking return value of debugfs_create() functions (Greg Kroah-Hartman) - Convert to use DEFINE_SEQ_ATTRIBUTE macro (Liu Shixin) Qualcomm PCIe controller driver: - Reset PCIe to work around Qsdk U-Boot issue (Ansuel Smith) Renesas R-Car PCIe controller driver: - Add DT documentation for r8a774a1, r8a774b1, r8a774e1 endpoints (Lad Prabhakar) - Add RZ/G2M, RZ/G2N, RZ/G2H IDs to endpoint test (Lad Prabhakar) - Add DT support for r8a7742 (Lad Prabhakar) Socionext UniPhier Pro5 controller driver: - Add DT descriptions of iATU register (host and endpoint) (Kunihiko Hayashi) Synopsys DesignWare PCIe controller driver: - Add link up check in dw_child_pcie_ops.map_bus() (racy, but seems unavoidable) (Hou Zhiqiang) - Fix endpoint Header Type check so multi-function devices work (Hou Zhiqiang) - Skip PCIE_MSI_INTR0* programming if MSI is disabled (Jisheng Zhang) - Stop leaking MSI page in suspend/resume (Jisheng Zhang) - Add common iATU register support instead of keystone-specific code (Kunihiko Hayashi) - Major config space access and other cleanups in dwc core and drivers that use it (al, exynos, histb, imx6, intel-gw, keystone, kirin, meson, qcom, tegra) (Rob Herring) - Add multiple PFs support for endpoint (Xiaowei Bao) - Add MSI-X doorbell mode in endpoint mode (Xiaowei Bao) Miscellaneous: - Use fallthrough pseudo-keyword (Gustavo A. R. Silva) - Fix "0 used as NULL pointer" warnings (Gustavo Pimentel) - Fix "cast truncates bits from constant value" warnings (Gustavo Pimentel) - Remove redundant zeroing for sg_init_table() (Julia Lawall) - Use scnprintf(), not snprintf(), in sysfs "show" functions (Krzysztof Wilczyński) - Remove unused assignments (Krzysztof Wilczyński) - Fix "0 used as NULL pointer" warning (Krzysztof Wilczyński) - Simplify bool comparisons (Krzysztof Wilczyński) - Use for_each_child_of_node() and for_each_node_by_name() (Qinglang Miao) - Simplify return expressions (Qinglang Miao)" * tag 'pci-v5.10-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (147 commits) PCI: vmd: Update VMD PM to correctly use generic PCI PM PCI: vmd: Create IRQ allocation helper PCI: vmd: Create IRQ Domain configuration helper PCI: vmd: Create bus offset configuration helper PCI: vmd: Create physical offset helper PCI: v3-semi: Remove unneeded break PCI: dwc: Add link up check in dw_child_pcie_ops.map_bus() PCI/ASPM: Remove struct pcie_link_state.l1ss PCI/ASPM: Remove struct aspm_register_info.l1ss_cap PCI/ASPM: Pass L1SS Capabilities value, not struct aspm_register_info PCI/ASPM: Remove struct aspm_register_info.l1ss_ctl1 PCI/ASPM: Remove struct aspm_register_info.l1ss_ctl2 (unused) PCI/ASPM: Remove struct aspm_register_info.l1ss_cap_ptr PCI/ASPM: Remove struct aspm_register_info.latency_encoding PCI/ASPM: Remove struct aspm_register_info.enabled PCI/ASPM: Remove struct aspm_register_info.support PCI/ASPM: Use 'parent' and 'child' for readability PCI/ASPM: Move LTR path check to where it's used PCI/ASPM: Move pci_clear_and_set_dword() earlier PCI: dwc: Fix MSI page leakage in suspend/resume ... --- 00937f36b09e89c74e4a059dbb8acbf4b971d5eb diff --combined Documentation/devicetree/bindings/pci/rcar-pci-ep.yaml index 53d5952b7e57,a059c96c294b..84eeb7fe6e01 --- a/Documentation/devicetree/bindings/pci/rcar-pci-ep.yaml +++ b/Documentation/devicetree/bindings/pci/rcar-pci-ep.yaml @@@ -14,8 -14,12 +14,12 @@@ maintainers properties: compatible: items: - - const: renesas,r8a774c0-pcie-ep - - const: renesas,rcar-gen3-pcie-ep + - enum: + - renesas,r8a774a1-pcie-ep # RZ/G2M + - renesas,r8a774b1-pcie-ep # RZ/G2N + - renesas,r8a774c0-pcie-ep # RZ/G2E + - renesas,r8a774e1-pcie-ep # RZ/G2H + - const: renesas,rcar-gen3-pcie-ep # R-Car Gen3 and RZ/G2 reg: maxItems: 5 @@@ -55,8 -59,6 +59,8 @@@ required - clock-names - max-functions +additionalProperties: false + examples: - | #include diff --combined drivers/net/ethernet/marvell/sky2.c index 344864275ed5,dd11c06ca7f9..25981a7a43b5 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@@ -1376,7 -1376,7 +1376,7 @@@ static int sky2_ioctl(struct net_devic case SIOCGMIIPHY: data->phy_id = PHY_ADDR_MARV; - /* fallthru */ + fallthrough; case SIOCGMIIREG: { u16 val = 0; @@@ -2764,7 -2764,7 +2764,7 @@@ static int sky2_status_intr(struct sky2 case OP_RXCHKSVLAN: sky2_rx_tag(sky2, length); - /* fall through */ + fallthrough; case OP_RXCHKS: if (likely(dev->features & NETIF_F_RXCSUM)) sky2_rx_checksum(sky2, status); @@@ -5105,7 -5105,7 +5105,7 @@@ static int sky2_probe(struct pci_dev *p INIT_WORK(&hw->restart_work, sky2_restart); pci_set_drvdata(pdev, hw); - pdev->d3_delay = 300; + pdev->d3hot_delay = 300; return 0; diff --combined drivers/pci/Kconfig index 438a792d2cf7,d323b25ae27e..0c473d75e625 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@@ -56,9 -56,6 +56,9 @@@ config PCI_MSI_IRQ_DOMAI depends on PCI_MSI select GENERIC_MSI_IRQ_DOMAIN +config PCI_MSI_ARCH_FALLBACKS + bool + config PCI_QUIRKS default y bool "Enable PCI quirk workarounds" if EXPERT @@@ -190,6 -187,68 +190,68 @@@ config PCI_HYPER The PCI device frontend driver allows the kernel to import arbitrary PCI devices from a PCI backend to support PCI driver domains. + choice + prompt "PCI Express hierarchy optimization setting" + default PCIE_BUS_DEFAULT + depends on PCI && EXPERT + help + MPS (Max Payload Size) and MRRS (Max Read Request Size) are PCIe + device parameters that affect performance and the ability to + support hotplug and peer-to-peer DMA. + + The following choices set the MPS and MRRS optimization strategy + at compile-time. The choices are the same as those offered for + the kernel command-line parameter 'pci', i.e., + 'pci=pcie_bus_tune_off', 'pci=pcie_bus_safe', + 'pci=pcie_bus_perf', and 'pci=pcie_bus_peer2peer'. + + This is a compile-time setting and can be overridden by the above + command-line parameters. If unsure, choose PCIE_BUS_DEFAULT. + + config PCIE_BUS_TUNE_OFF + bool "Tune Off" + depends on PCI + help + Use the BIOS defaults; don't touch MPS at all. This is the same + as booting with 'pci=pcie_bus_tune_off'. + + config PCIE_BUS_DEFAULT + bool "Default" + depends on PCI + help + Default choice; ensure that the MPS matches upstream bridge. + + config PCIE_BUS_SAFE + bool "Safe" + depends on PCI + help + Use largest MPS that boot-time devices support. If you have a + closed system with no possibility of adding new devices, this + will use the largest MPS that's supported by all devices. This + is the same as booting with 'pci=pcie_bus_safe'. + + config PCIE_BUS_PERFORMANCE + bool "Performance" + depends on PCI + help + Use MPS and MRRS for best performance. Ensure that a given + device's MPS is no larger than its parent MPS, which allows us to + keep all switches/bridges to the max MPS supported by their + parent. This is the same as booting with 'pci=pcie_bus_perf'. + + config PCIE_BUS_PEER2PEER + bool "Peer2peer" + depends on PCI + help + Set MPS = 128 for all devices. MPS configuration effected by the + other options could cause the MPS on one root port to be + different than that of the MPS on another, which may cause + hot-added devices or peer-to-peer DMA to fail. Set MPS to the + smallest possible value (128B) system-wide to avoid these issues. + This is the same as booting with 'pci=pcie_bus_peer2peer'. + + endchoice + source "drivers/pci/hotplug/Kconfig" source "drivers/pci/controller/Kconfig" source "drivers/pci/endpoint/Kconfig" diff --combined drivers/pci/controller/Kconfig index 4a7afbe189f8,6ebe69dd1229..64e2f5e379aa --- a/drivers/pci/controller/Kconfig +++ b/drivers/pci/controller/Kconfig @@@ -12,7 -12,7 +12,7 @@@ config PCI_MVEB select PCI_BRIDGE_EMUL config PCI_AARDVARK - bool "Aardvark PCIe controller" + tristate "Aardvark PCIe controller" depends on (ARCH_MVEBU && ARM64) || COMPILE_TEST depends on OF depends on PCI_MSI_IRQ_DOMAIN @@@ -41,7 -41,6 +41,7 @@@ config PCI_TEGR bool "NVIDIA Tegra PCIe controller" depends on ARCH_TEGRA || COMPILE_TEST depends on PCI_MSI_IRQ_DOMAIN + select PCI_MSI_ARCH_FALLBACKS help Say Y here if you want support for the PCIe host controller found on NVIDIA Tegra SoCs. @@@ -68,7 -67,6 +68,7 @@@ config PCIE_RCAR_HOS bool "Renesas R-Car PCIe host controller" depends on ARCH_RENESAS || COMPILE_TEST depends on PCI_MSI_IRQ_DOMAIN + select PCI_MSI_ARCH_FALLBACKS help Say Y here if you want PCIe controller support on R-Car SoCs in host mode. @@@ -97,7 -95,6 +97,7 @@@ config PCI_HOST_GENERI config PCIE_XILINX bool "Xilinx AXI PCIe host bridge support" depends on OF || COMPILE_TEST + select PCI_MSI_ARCH_FALLBACKS help Say 'Y' here if you want kernel to support the Xilinx AXI PCIe Host Bridge driver. @@@ -273,9 -270,10 +273,10 @@@ config VM config PCIE_BRCMSTB tristate "Broadcom Brcmstb PCIe host controller" - depends on ARCH_BCM2835 || COMPILE_TEST + depends on ARCH_BRCMSTB || ARCH_BCM2835 || COMPILE_TEST depends on OF depends on PCI_MSI_IRQ_DOMAIN + default ARCH_BRCMSTB help Say Y here to enable PCIe host controller support for Broadcom STB based SoCs, like the Raspberry Pi 4. @@@ -297,6 -295,13 +298,13 @@@ config PCI_LOONGSO Say Y here if you want to enable PCI controller support on Loongson systems. + config PCIE_HISI_ERR + depends on ACPI_APEI_GHES && (ARM64 || COMPILE_TEST) + bool "HiSilicon HIP PCIe controller error handling driver" + help + Say Y here if you want error handling support + for the PCIe controller's errors on HiSilicon HIP SoCs + source "drivers/pci/controller/dwc/Kconfig" source "drivers/pci/controller/mobiveil/Kconfig" source "drivers/pci/controller/cadence/Kconfig" diff --combined drivers/pci/controller/pci-hyperv.c index 4e992403fffe,a9df492fbffa..03ed5cb1c4b2 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c @@@ -1276,11 -1276,25 +1276,25 @@@ static void hv_irq_unmask(struct irq_da exit_unlock: spin_unlock_irqrestore(&hbus->retarget_msi_interrupt_lock, flags); - if (res) { + /* + * During hibernation, when a CPU is offlined, the kernel tries + * to move the interrupt to the remaining CPUs that haven't + * been offlined yet. In this case, the below hv_do_hypercall() + * always fails since the vmbus channel has been closed: + * refer to cpu_disable_common() -> fixup_irqs() -> + * irq_migrate_all_off_this_cpu() -> migrate_one_irq(). + * + * Suppress the error message for hibernation because the failure + * during hibernation does not matter (at this time all the devices + * have been frozen). Note: the correct affinity info is still updated + * into the irqdata data structure in migrate_one_irq() -> + * irq_do_set_affinity() -> hv_set_affinity(), so later when the VM + * resumes, hv_pci_restore_msi_state() is able to correctly restore + * the interrupt with the correct affinity. + */ + if (res && hbus->state != hv_pcibus_removing) dev_err(&hbus->hdev->device, "%s() failed: %#llx", __func__, res); - return; - } pci_msi_unmask_irq(data); } @@@ -1531,8 -1545,16 +1545,8 @@@ static struct irq_chip hv_msi_irq_chip .irq_unmask = hv_irq_unmask, }; -static irq_hw_number_t hv_msi_domain_ops_get_hwirq(struct msi_domain_info *info, - msi_alloc_info_t *arg) -{ - return arg->msi_hwirq; -} - static struct msi_domain_ops hv_msi_ops = { - .get_hwirq = hv_msi_domain_ops_get_hwirq, .msi_prepare = pci_msi_prepare, - .set_desc = pci_msi_set_desc, .msi_free = hv_msi_free, }; @@@ -2507,10 -2529,7 +2521,10 @@@ static void hv_pci_onchannelcallback(vo /** * hv_pci_protocol_negotiation() - Set up protocol - * @hdev: VMBus's tracking struct for this root PCI bus + * @hdev: VMBus's tracking struct for this root PCI bus. + * @version: Array of supported channel protocol versions in + * the order of probing - highest go first. + * @num_version: Number of elements in the version array. * * This driver is intended to support running on Windows 10 * (server) and later versions. It will not run on earlier @@@ -3367,6 -3386,34 +3381,34 @@@ static int hv_pci_suspend(struct hv_dev return 0; } + static int hv_pci_restore_msi_msg(struct pci_dev *pdev, void *arg) + { + struct msi_desc *entry; + struct irq_data *irq_data; + + for_each_pci_msi_entry(entry, pdev) { + irq_data = irq_get_irq_data(entry->irq); + if (WARN_ON_ONCE(!irq_data)) + return -EINVAL; + + hv_compose_msi_msg(irq_data, &entry->msg); + } + + return 0; + } + + /* + * Upon resume, pci_restore_msi_state() -> ... -> __pci_write_msi_msg() + * directly writes the MSI/MSI-X registers via MMIO, but since Hyper-V + * doesn't trap and emulate the MMIO accesses, here hv_compose_msi_msg() + * must be used to ask Hyper-V to re-create the IOMMU Interrupt Remapping + * Table entries. + */ + static void hv_pci_restore_msi_state(struct hv_pcibus_device *hbus) + { + pci_walk_bus(hbus->pci_bus, hv_pci_restore_msi_msg, NULL); + } + static int hv_pci_resume(struct hv_device *hdev) { struct hv_pcibus_device *hbus = hv_get_drvdata(hdev); @@@ -3400,6 -3447,8 +3442,8 @@@ prepopulate_bars(hbus); + hv_pci_restore_msi_state(hbus); + hbus->state = hv_pcibus_installed; return 0; out: diff --combined drivers/pci/controller/pcie-brcmstb.c index bac63d04297f,afa7ba1d9a38..bea86899bd5d --- a/drivers/pci/controller/pcie-brcmstb.c +++ b/drivers/pci/controller/pcie-brcmstb.c @@@ -23,11 -23,14 +23,12 @@@ #include #include #include + #include #include #include #include #include -#include - #include "../pci.h" /* BRCM_PCIE_CAP_REGS - Offset for the mandatory capability config regs */ @@@ -52,8 -55,11 +53,11 @@@ #define PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK 0x1000 #define PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK 0x2000 #define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK 0x300000 - #define PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_128 0x0 + #define PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK 0xf8000000 + #define PCIE_MISC_MISC_CTRL_SCB1_SIZE_MASK 0x07c00000 + #define PCIE_MISC_MISC_CTRL_SCB2_SIZE_MASK 0x0000001f + #define SCB_SIZE_MASK(x) PCIE_MISC_MISC_CTRL_SCB ## x ## _SIZE_MASK #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LO 0x400c #define PCIE_MEM_WIN0_LO(win) \ @@@ -77,10 -83,12 +81,12 @@@ #define PCIE_MISC_MSI_BAR_CONFIG_HI 0x4048 #define PCIE_MISC_MSI_DATA_CONFIG 0x404c - #define PCIE_MISC_MSI_DATA_CONFIG_VAL 0xffe06540 + #define PCIE_MISC_MSI_DATA_CONFIG_VAL_32 0xffe06540 + #define PCIE_MISC_MSI_DATA_CONFIG_VAL_8 0xfff86540 #define PCIE_MISC_PCIE_CTRL 0x4064 #define PCIE_MISC_PCIE_CTRL_PCIE_L23_REQUEST_MASK 0x1 + #define PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK 0x4 #define PCIE_MISC_PCIE_STATUS 0x4068 #define PCIE_MISC_PCIE_STATUS_PCIE_PORT_MASK 0x80 @@@ -88,6 -96,9 +94,9 @@@ #define PCIE_MISC_PCIE_STATUS_PCIE_PHYLINKUP_MASK 0x10 #define PCIE_MISC_PCIE_STATUS_PCIE_LINK_IN_L23_MASK 0x40 + #define PCIE_MISC_REVISION 0x406c + #define BRCM_PCIE_HW_REV_33 0x0303 + #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT 0x4070 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_LIMIT_MASK 0xfff00000 #define PCIE_MISC_CPU_2_PCIE_MEM_WIN0_BASE_LIMIT_BASE_MASK 0xfff0 @@@ -108,10 -119,14 +117,14 @@@ #define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2 #define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000 - #define PCIE_MSI_INTR2_STATUS 0x4500 - #define PCIE_MSI_INTR2_CLR 0x4508 - #define PCIE_MSI_INTR2_MASK_SET 0x4510 - #define PCIE_MSI_INTR2_MASK_CLR 0x4514 + + #define PCIE_INTR2_CPU_BASE 0x4300 + #define PCIE_MSI_INTR2_BASE 0x4500 + /* Offsets from PCIE_INTR2_CPU_BASE and PCIE_MSI_INTR2_BASE */ + #define MSI_INT_STATUS 0x0 + #define MSI_INT_CLR 0x8 + #define MSI_INT_MASK_SET 0x10 + #define MSI_INT_MASK_CLR 0x14 #define PCIE_EXT_CFG_DATA 0x8000 @@@ -120,13 -135,19 +133,19 @@@ #define PCIE_EXT_SLOT_SHIFT 15 #define PCIE_EXT_FUNC_SHIFT 12 - #define PCIE_RGR1_SW_INIT_1 0x9210 #define PCIE_RGR1_SW_INIT_1_PERST_MASK 0x1 - #define PCIE_RGR1_SW_INIT_1_INIT_MASK 0x2 + #define PCIE_RGR1_SW_INIT_1_PERST_SHIFT 0x0 + + #define RGR1_SW_INIT_1_INIT_GENERIC_MASK 0x2 + #define RGR1_SW_INIT_1_INIT_GENERIC_SHIFT 0x1 + #define RGR1_SW_INIT_1_INIT_7278_MASK 0x1 + #define RGR1_SW_INIT_1_INIT_7278_SHIFT 0x0 /* PCIe parameters */ #define BRCM_NUM_PCIE_OUT_WINS 0x4 #define BRCM_INT_PCI_MSI_NR 32 + #define BRCM_INT_PCI_MSI_LEGACY_NR 8 + #define BRCM_INT_PCI_MSI_SHIFT 0 /* MSI target adresses */ #define BRCM_MSI_TARGET_ADDR_LT_4GB 0x0fffffffcULL @@@ -151,6 -172,85 +170,85 @@@ #define SSC_STATUS_OFFSET 0x1 #define SSC_STATUS_SSC_MASK 0x400 #define SSC_STATUS_PLL_LOCK_MASK 0x800 + #define PCIE_BRCM_MAX_MEMC 3 + + #define IDX_ADDR(pcie) (pcie->reg_offsets[EXT_CFG_INDEX]) + #define DATA_ADDR(pcie) (pcie->reg_offsets[EXT_CFG_DATA]) + #define PCIE_RGR1_SW_INIT_1(pcie) (pcie->reg_offsets[RGR1_SW_INIT_1]) + + /* Rescal registers */ + #define PCIE_DVT_PMU_PCIE_PHY_CTRL 0xc700 + #define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS 0x3 + #define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_MASK 0x4 + #define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_SHIFT 0x2 + #define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_MASK 0x2 + #define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_SHIFT 0x1 + #define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_MASK 0x1 + #define PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_SHIFT 0x0 + + /* Forward declarations */ + struct brcm_pcie; + static inline void brcm_pcie_bridge_sw_init_set_7278(struct brcm_pcie *pcie, u32 val); + static inline void brcm_pcie_bridge_sw_init_set_generic(struct brcm_pcie *pcie, u32 val); + static inline void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val); + static inline void brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val); + + enum { + RGR1_SW_INIT_1, + EXT_CFG_INDEX, + EXT_CFG_DATA, + }; + + enum { + RGR1_SW_INIT_1_INIT_MASK, + RGR1_SW_INIT_1_INIT_SHIFT, + }; + + enum pcie_type { + GENERIC, + BCM7278, + BCM2711, + }; + + struct pcie_cfg_data { + const int *offsets; + const enum pcie_type type; + void (*perst_set)(struct brcm_pcie *pcie, u32 val); + void (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val); + }; + + static const int pcie_offsets[] = { + [RGR1_SW_INIT_1] = 0x9210, + [EXT_CFG_INDEX] = 0x9000, + [EXT_CFG_DATA] = 0x9004, + }; + + static const struct pcie_cfg_data generic_cfg = { + .offsets = pcie_offsets, + .type = GENERIC, + .perst_set = brcm_pcie_perst_set_generic, + .bridge_sw_init_set = brcm_pcie_bridge_sw_init_set_generic, + }; + + static const int pcie_offset_bcm7278[] = { + [RGR1_SW_INIT_1] = 0xc010, + [EXT_CFG_INDEX] = 0x9000, + [EXT_CFG_DATA] = 0x9004, + }; + + static const struct pcie_cfg_data bcm7278_cfg = { + .offsets = pcie_offset_bcm7278, + .type = BCM7278, + .perst_set = brcm_pcie_perst_set_7278, + .bridge_sw_init_set = brcm_pcie_bridge_sw_init_set_7278, + }; + + static const struct pcie_cfg_data bcm2711_cfg = { + .offsets = pcie_offsets, + .type = BCM2711, + .perst_set = brcm_pcie_perst_set_generic, + .bridge_sw_init_set = brcm_pcie_bridge_sw_init_set_generic, + }; struct brcm_msi { struct device *dev; @@@ -163,6 -263,12 +261,12 @@@ int irq; /* used indicates which MSI interrupts have been alloc'd */ unsigned long used; + bool legacy; + /* Some chips have MSIs in bits [31..24] of a shared register. */ + int legacy_shift; + int nr; /* No. of MSI available, depends on chip */ + /* This is the base pointer for interrupt status/set/clr regs */ + void __iomem *intr_base; }; /* Internal PCIe Host Controller Information.*/ @@@ -175,6 -281,14 +279,14 @@@ struct brcm_pcie int gen; u64 msi_target_addr; struct brcm_msi *msi; + const int *reg_offsets; + enum pcie_type type; + struct reset_control *rescal; + int num_memc; + u64 memc_size[PCIE_BRCM_MAX_MEMC]; + u32 hw_rev; + void (*perst_set)(struct brcm_pcie *pcie, u32 val); + void (*bridge_sw_init_set)(struct brcm_pcie *pcie, u32 val); }; /* @@@ -365,8 -479,10 +477,10 @@@ static void brcm_pcie_msi_isr(struct ir msi = irq_desc_get_handler_data(desc); dev = msi->dev; - status = readl(msi->base + PCIE_MSI_INTR2_STATUS); - for_each_set_bit(bit, &status, BRCM_INT_PCI_MSI_NR) { + status = readl(msi->intr_base + MSI_INT_STATUS); + status >>= msi->legacy_shift; + + for_each_set_bit(bit, &status, msi->nr) { virq = irq_find_mapping(msi->inner_domain, bit); if (virq) generic_handle_irq(virq); @@@ -383,7 -499,7 +497,7 @@@ static void brcm_msi_compose_msi_msg(st msg->address_lo = lower_32_bits(msi->target_addr); msg->address_hi = upper_32_bits(msi->target_addr); - msg->data = (0xffff & PCIE_MISC_MSI_DATA_CONFIG_VAL) | data->hwirq; + msg->data = (0xffff & PCIE_MISC_MSI_DATA_CONFIG_VAL_32) | data->hwirq; } static int brcm_msi_set_affinity(struct irq_data *irq_data, @@@ -395,8 -511,9 +509,9 @@@ static void brcm_msi_ack_irq(struct irq_data *data) { struct brcm_msi *msi = irq_data_get_irq_chip_data(data); + const int shift_amt = data->hwirq + msi->legacy_shift; - writel(1 << data->hwirq, msi->base + PCIE_MSI_INTR2_CLR); + writel(1 << shift_amt, msi->intr_base + MSI_INT_CLR); } @@@ -412,7 -529,7 +527,7 @@@ static int brcm_msi_alloc(struct brcm_m int hwirq; mutex_lock(&msi->lock); - hwirq = bitmap_find_free_region(&msi->used, BRCM_INT_PCI_MSI_NR, 0); + hwirq = bitmap_find_free_region(&msi->used, msi->nr, 0); mutex_unlock(&msi->lock); return hwirq; @@@ -461,8 -578,7 +576,7 @@@ static int brcm_allocate_domains(struc struct fwnode_handle *fwnode = of_node_to_fwnode(msi->np); struct device *dev = msi->dev; - msi->inner_domain = irq_domain_add_linear(NULL, BRCM_INT_PCI_MSI_NR, - &msi_domain_ops, msi); + msi->inner_domain = irq_domain_add_linear(NULL, msi->nr, &msi_domain_ops, msi); if (!msi->inner_domain) { dev_err(dev, "failed to create IRQ domain\n"); return -ENOMEM; @@@ -499,7 -615,10 +613,10 @@@ static void brcm_msi_remove(struct brcm static void brcm_msi_set_regs(struct brcm_msi *msi) { - writel(0xffffffff, msi->base + PCIE_MSI_INTR2_MASK_CLR); + u32 val = __GENMASK(31, msi->legacy_shift); + + writel(val, msi->intr_base + MSI_INT_MASK_CLR); + writel(val, msi->intr_base + MSI_INT_CLR); /* * The 0 bit of PCIE_MISC_MSI_BAR_CONFIG_LO is repurposed to MSI @@@ -510,8 -629,8 +627,8 @@@ writel(upper_32_bits(msi->target_addr), msi->base + PCIE_MISC_MSI_BAR_CONFIG_HI); - writel(PCIE_MISC_MSI_DATA_CONFIG_VAL, - msi->base + PCIE_MISC_MSI_DATA_CONFIG); + val = msi->legacy ? PCIE_MISC_MSI_DATA_CONFIG_VAL_8 : PCIE_MISC_MSI_DATA_CONFIG_VAL_32; + writel(val, msi->base + PCIE_MISC_MSI_DATA_CONFIG); } static int brcm_pcie_enable_msi(struct brcm_pcie *pcie) @@@ -536,6 -655,17 +653,17 @@@ msi->np = pcie->np; msi->target_addr = pcie->msi_target_addr; msi->irq = irq; + msi->legacy = pcie->hw_rev < BRCM_PCIE_HW_REV_33; + + if (msi->legacy) { + msi->intr_base = msi->base + PCIE_INTR2_CPU_BASE; + msi->nr = BRCM_INT_PCI_MSI_LEGACY_NR; + msi->legacy_shift = 24; + } else { + msi->intr_base = msi->base + PCIE_MSI_INTR2_BASE; + msi->nr = BRCM_INT_PCI_MSI_NR; + msi->legacy_shift = 0; + } ret = brcm_allocate_domains(msi); if (ret) @@@ -599,22 -729,43 +727,43 @@@ static struct pci_ops brcm_pcie_ops = .write = pci_generic_config_write, }; - static inline void brcm_pcie_bridge_sw_init_set(struct brcm_pcie *pcie, u32 val) + static inline void brcm_pcie_bridge_sw_init_set_generic(struct brcm_pcie *pcie, u32 val) + { + u32 tmp, mask = RGR1_SW_INIT_1_INIT_GENERIC_MASK; + u32 shift = RGR1_SW_INIT_1_INIT_GENERIC_SHIFT; + + tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1(pcie)); + tmp = (tmp & ~mask) | ((val << shift) & mask); + writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1(pcie)); + } + + static inline void brcm_pcie_bridge_sw_init_set_7278(struct brcm_pcie *pcie, u32 val) + { + u32 tmp, mask = RGR1_SW_INIT_1_INIT_7278_MASK; + u32 shift = RGR1_SW_INIT_1_INIT_7278_SHIFT; + + tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1(pcie)); + tmp = (tmp & ~mask) | ((val << shift) & mask); + writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1(pcie)); + } + + static inline void brcm_pcie_perst_set_7278(struct brcm_pcie *pcie, u32 val) { u32 tmp; - tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1); - u32p_replace_bits(&tmp, val, PCIE_RGR1_SW_INIT_1_INIT_MASK); - writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1); + /* Perst bit has moved and assert value is 0 */ + tmp = readl(pcie->base + PCIE_MISC_PCIE_CTRL); + u32p_replace_bits(&tmp, !val, PCIE_MISC_PCIE_CTRL_PCIE_PERSTB_MASK); + writel(tmp, pcie->base + PCIE_MISC_PCIE_CTRL); } - static inline void brcm_pcie_perst_set(struct brcm_pcie *pcie, u32 val) + static inline void brcm_pcie_perst_set_generic(struct brcm_pcie *pcie, u32 val) { u32 tmp; - tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1); + tmp = readl(pcie->base + PCIE_RGR1_SW_INIT_1(pcie)); u32p_replace_bits(&tmp, val, PCIE_RGR1_SW_INIT_1_PERST_MASK); - writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1); + writel(tmp, pcie->base + PCIE_RGR1_SW_INIT_1(pcie)); } static inline int brcm_pcie_get_rc_bar2_size_and_offset(struct brcm_pcie *pcie, @@@ -622,22 -773,44 +771,44 @@@ u64 *rc_bar2_offset) { struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie); - struct device *dev = pcie->dev; struct resource_entry *entry; + struct device *dev = pcie->dev; + u64 lowest_pcie_addr = ~(u64)0; + int ret, i = 0; + u64 size = 0; - entry = resource_list_first_type(&bridge->dma_ranges, IORESOURCE_MEM); - if (!entry) - return -ENODEV; + resource_list_for_each_entry(entry, &bridge->dma_ranges) { + u64 pcie_beg = entry->res->start - entry->offset; + size += entry->res->end - entry->res->start + 1; + if (pcie_beg < lowest_pcie_addr) + lowest_pcie_addr = pcie_beg; + } - /* - * The controller expects the inbound window offset to be calculated as - * the difference between PCIe's address space and CPU's. The offset - * provided by the firmware is calculated the opposite way, so we - * negate it. - */ - *rc_bar2_offset = -entry->offset; - *rc_bar2_size = 1ULL << fls64(entry->res->end - entry->res->start); + if (lowest_pcie_addr == ~(u64)0) { + dev_err(dev, "DT node has no dma-ranges\n"); + return -EINVAL; + } + + ret = of_property_read_variable_u64_array(pcie->np, "brcm,scb-sizes", pcie->memc_size, 1, + PCIE_BRCM_MAX_MEMC); + + if (ret <= 0) { + /* Make an educated guess */ + pcie->num_memc = 1; + pcie->memc_size[0] = 1ULL << fls64(size - 1); + } else { + pcie->num_memc = ret; + } + + /* Each memc is viewed through a "port" that is a power of 2 */ + for (i = 0, size = 0; i < pcie->num_memc; i++) + size += pcie->memc_size[i]; + + /* System memory starts at this address in PCIe-space */ + *rc_bar2_offset = lowest_pcie_addr; + /* The sum of all memc views must also be a power of 2 */ + *rc_bar2_size = 1ULL << fls64(size - 1); /* * We validate the inbound memory view even though we should trust @@@ -689,22 -862,19 +860,19 @@@ static int brcm_pcie_setup(struct brcm_ void __iomem *base = pcie->base; struct device *dev = pcie->dev; struct resource_entry *entry; - unsigned int scb_size_val; bool ssc_good = false; struct resource *res; int num_out_wins = 0; u16 nlw, cls, lnksta; - int i, ret; - u32 tmp, aspm_support; + int i, ret, memc; + u32 tmp, burst, aspm_support; /* Reset the bridge */ - brcm_pcie_bridge_sw_init_set(pcie, 1); - brcm_pcie_perst_set(pcie, 1); - + pcie->bridge_sw_init_set(pcie, 1); usleep_range(100, 200); /* Take the bridge out of reset */ - brcm_pcie_bridge_sw_init_set(pcie, 0); + pcie->bridge_sw_init_set(pcie, 0); tmp = readl(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG); tmp &= ~PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK; @@@ -712,11 -882,22 +880,22 @@@ /* Wait for SerDes to be stable */ usleep_range(100, 200); + /* + * SCB_MAX_BURST_SIZE is a two bit field. For GENERIC chips it + * is encoded as 0=128, 1=256, 2=512, 3=Rsvd, for BCM7278 it + * is encoded as 0=Rsvd, 1=128, 2=256, 3=512. + */ + if (pcie->type == BCM2711) + burst = 0x0; /* 128B */ + else if (pcie->type == BCM7278) + burst = 0x3; /* 512 bytes */ + else + burst = 0x2; /* 512 bytes */ + /* Set SCB_MAX_BURST_SIZE, CFG_READ_UR_MODE, SCB_ACCESS_EN */ u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_SCB_ACCESS_EN_MASK); u32p_replace_bits(&tmp, 1, PCIE_MISC_MISC_CTRL_CFG_READ_UR_MODE_MASK); - u32p_replace_bits(&tmp, PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_128, - PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK); + u32p_replace_bits(&tmp, burst, PCIE_MISC_MISC_CTRL_MAX_BURST_SIZE_MASK); writel(tmp, base + PCIE_MISC_MISC_CTRL); ret = brcm_pcie_get_rc_bar2_size_and_offset(pcie, &rc_bar2_size, @@@ -731,11 -912,17 +910,17 @@@ writel(upper_32_bits(rc_bar2_offset), base + PCIE_MISC_RC_BAR2_CONFIG_HI); - scb_size_val = rc_bar2_size ? - ilog2(rc_bar2_size) - 15 : 0xf; /* 0xf is 1GB */ tmp = readl(base + PCIE_MISC_MISC_CTRL); - u32p_replace_bits(&tmp, scb_size_val, - PCIE_MISC_MISC_CTRL_SCB0_SIZE_MASK); + for (memc = 0; memc < pcie->num_memc; memc++) { + u32 scb_size_val = ilog2(pcie->memc_size[memc]) - 15; + + if (memc == 0) + u32p_replace_bits(&tmp, scb_size_val, SCB_SIZE_MASK(0)); + else if (memc == 1) + u32p_replace_bits(&tmp, scb_size_val, SCB_SIZE_MASK(1)); + else if (memc == 2) + u32p_replace_bits(&tmp, scb_size_val, SCB_SIZE_MASK(2)); + } writel(tmp, base + PCIE_MISC_MISC_CTRL); /* @@@ -760,17 -947,11 +945,11 @@@ tmp &= ~PCIE_MISC_RC_BAR3_CONFIG_LO_SIZE_MASK; writel(tmp, base + PCIE_MISC_RC_BAR3_CONFIG_LO); - /* Mask all interrupts since we are not handling any yet */ - writel(0xffffffff, pcie->base + PCIE_MSI_INTR2_MASK_SET); - - /* clear any interrupts we find on boot */ - writel(0xffffffff, pcie->base + PCIE_MSI_INTR2_CLR); - if (pcie->gen) brcm_pcie_set_gen(pcie, pcie->gen); /* Unassert the fundamental reset */ - brcm_pcie_perst_set(pcie, 0); + pcie->perst_set(pcie, 0); /* * Give the RC/EP time to wake up, before trying to configure RC. @@@ -882,6 -1063,52 +1061,52 @@@ static void brcm_pcie_enter_l23(struct dev_err(pcie->dev, "failed to enter low-power link state\n"); } + static int brcm_phy_cntl(struct brcm_pcie *pcie, const int start) + { + static const u32 shifts[PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS] = { + PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_SHIFT, + PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_SHIFT, + PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_SHIFT,}; + static const u32 masks[PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS] = { + PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_PWRDN_MASK, + PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_RESET_MASK, + PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_DIG_RESET_MASK,}; + const int beg = start ? 0 : PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS - 1; + const int end = start ? PCIE_DVT_PMU_PCIE_PHY_CTRL_DAST_NFLDS : -1; + u32 tmp, combined_mask = 0; + u32 val; + void __iomem *base = pcie->base; + int i, ret; + + for (i = beg; i != end; start ? i++ : i--) { + val = start ? BIT_MASK(shifts[i]) : 0; + tmp = readl(base + PCIE_DVT_PMU_PCIE_PHY_CTRL); + tmp = (tmp & ~masks[i]) | (val & masks[i]); + writel(tmp, base + PCIE_DVT_PMU_PCIE_PHY_CTRL); + usleep_range(50, 200); + combined_mask |= masks[i]; + } + + tmp = readl(base + PCIE_DVT_PMU_PCIE_PHY_CTRL); + val = start ? combined_mask : 0; + + ret = (tmp & combined_mask) == val ? 0 : -EIO; + if (ret) + dev_err(pcie->dev, "failed to %s phy\n", (start ? "start" : "stop")); + + return ret; + } + + static inline int brcm_phy_start(struct brcm_pcie *pcie) + { + return pcie->rescal ? brcm_phy_cntl(pcie, 1) : 0; + } + + static inline int brcm_phy_stop(struct brcm_pcie *pcie) + { + return pcie->rescal ? brcm_phy_cntl(pcie, 0) : 0; + } + static void brcm_pcie_turn_off(struct brcm_pcie *pcie) { void __iomem *base = pcie->base; @@@ -890,7 -1117,7 +1115,7 @@@ if (brcm_pcie_link_up(pcie)) brcm_pcie_enter_l23(pcie); /* Assert fundamental reset */ - brcm_pcie_perst_set(pcie, 1); + pcie->perst_set(pcie, 1); /* Deassert request for L23 in case it was asserted */ tmp = readl(base + PCIE_MISC_PCIE_CTRL); @@@ -903,13 -1130,66 +1128,66 @@@ writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG); /* Shutdown PCIe bridge */ - brcm_pcie_bridge_sw_init_set(pcie, 1); + pcie->bridge_sw_init_set(pcie, 1); + } + + static int brcm_pcie_suspend(struct device *dev) + { + struct brcm_pcie *pcie = dev_get_drvdata(dev); + int ret; + + brcm_pcie_turn_off(pcie); + ret = brcm_phy_stop(pcie); + clk_disable_unprepare(pcie->clk); + + return ret; + } + + static int brcm_pcie_resume(struct device *dev) + { + struct brcm_pcie *pcie = dev_get_drvdata(dev); + void __iomem *base; + u32 tmp; + int ret; + + base = pcie->base; + clk_prepare_enable(pcie->clk); + + ret = brcm_phy_start(pcie); + if (ret) + goto err; + + /* Take bridge out of reset so we can access the SERDES reg */ + pcie->bridge_sw_init_set(pcie, 0); + + /* SERDES_IDDQ = 0 */ + tmp = readl(base + PCIE_MISC_HARD_PCIE_HARD_DEBUG); + u32p_replace_bits(&tmp, 0, PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK); + writel(tmp, base + PCIE_MISC_HARD_PCIE_HARD_DEBUG); + + /* wait for serdes to be stable */ + udelay(100); + + ret = brcm_pcie_setup(pcie); + if (ret) + goto err; + + if (pcie->msi) + brcm_msi_set_regs(pcie->msi); + + return 0; + + err: + clk_disable_unprepare(pcie->clk); + return ret; } static void __brcm_pcie_remove(struct brcm_pcie *pcie) { brcm_msi_remove(pcie); brcm_pcie_turn_off(pcie); + brcm_phy_stop(pcie); + reset_control_assert(pcie->rescal); clk_disable_unprepare(pcie->clk); } @@@ -925,20 -1205,55 +1203,40 @@@ static int brcm_pcie_remove(struct plat return 0; } + static const struct of_device_id brcm_pcie_match[] = { + { .compatible = "brcm,bcm2711-pcie", .data = &bcm2711_cfg }, + { .compatible = "brcm,bcm7211-pcie", .data = &generic_cfg }, + { .compatible = "brcm,bcm7278-pcie", .data = &bcm7278_cfg }, + { .compatible = "brcm,bcm7216-pcie", .data = &bcm7278_cfg }, + { .compatible = "brcm,bcm7445-pcie", .data = &generic_cfg }, + {}, + }; + static int brcm_pcie_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node, *msi_np; struct pci_host_bridge *bridge; - struct device_node *fw_np; + const struct pcie_cfg_data *data; struct brcm_pcie *pcie; int ret; - /* - * We have to wait for Raspberry Pi's firmware interface to be up as a - * PCI fixup, rpi_firmware_init_vl805(), depends on it. This driver's - * probe can race with the firmware interface's (see - * drivers/firmware/raspberrypi.c) and potentially break the PCI fixup. - */ - fw_np = of_find_compatible_node(NULL, NULL, - "raspberrypi,bcm2835-firmware"); - if (fw_np && !rpi_firmware_get(fw_np)) { - of_node_put(fw_np); - return -EPROBE_DEFER; - } - of_node_put(fw_np); - bridge = devm_pci_alloc_host_bridge(&pdev->dev, sizeof(*pcie)); if (!bridge) return -ENOMEM; + data = of_device_get_match_data(&pdev->dev); + if (!data) { + pr_err("failed to look up compatible string\n"); + return -EINVAL; + } + pcie = pci_host_bridge_priv(bridge); pcie->dev = &pdev->dev; pcie->np = np; + pcie->reg_offsets = data->offsets; + pcie->type = data->type; + pcie->perst_set = data->perst_set; + pcie->bridge_sw_init_set = data->bridge_sw_init_set; pcie->base = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(pcie->base)) @@@ -958,11 -1273,29 +1256,29 @@@ dev_err(&pdev->dev, "could not enable clock\n"); return ret; } + pcie->rescal = devm_reset_control_get_optional_shared(&pdev->dev, "rescal"); + if (IS_ERR(pcie->rescal)) { + clk_disable_unprepare(pcie->clk); + return PTR_ERR(pcie->rescal); + } + + ret = reset_control_deassert(pcie->rescal); + if (ret) + dev_err(&pdev->dev, "failed to deassert 'rescal'\n"); + + ret = brcm_phy_start(pcie); + if (ret) { + reset_control_assert(pcie->rescal); + clk_disable_unprepare(pcie->clk); + return ret; + } ret = brcm_pcie_setup(pcie); if (ret) goto fail; + pcie->hw_rev = readl(pcie->base + PCIE_MISC_REVISION); + msi_np = of_parse_phandle(pcie->np, "msi-parent", 0); if (pci_msi_enabled() && msi_np == pcie->np) { ret = brcm_pcie_enable_msi(pcie); @@@ -983,18 -1316,20 +1299,20 @@@ fail return ret; } - static const struct of_device_id brcm_pcie_match[] = { - { .compatible = "brcm,bcm2711-pcie" }, - {}, - }; MODULE_DEVICE_TABLE(of, brcm_pcie_match); + static const struct dev_pm_ops brcm_pcie_pm_ops = { + .suspend = brcm_pcie_suspend, + .resume = brcm_pcie_resume, + }; + static struct platform_driver brcm_pcie_driver = { .probe = brcm_pcie_probe, .remove = brcm_pcie_remove, .driver = { .name = "brcm-pcie", .of_match_table = brcm_pcie_match, + .pm = &brcm_pcie_pm_ops, }, }; module_platform_driver(brcm_pcie_driver); diff --combined drivers/pci/controller/vmd.c index aa1b12bac9a1,c8d46bd01e87..f375c21ceeb1 --- a/drivers/pci/controller/vmd.c +++ b/drivers/pci/controller/vmd.c @@@ -298,6 -298,34 +298,33 @@@ static struct msi_domain_info vmd_msi_d .chip = &vmd_msi_controller, }; + static int vmd_create_irq_domain(struct vmd_dev *vmd) + { + struct fwnode_handle *fn; + + fn = irq_domain_alloc_named_id_fwnode("VMD-MSI", vmd->sysdata.domain); + if (!fn) + return -ENODEV; + - vmd->irq_domain = pci_msi_create_irq_domain(fn, &vmd_msi_domain_info, - x86_vector_domain); ++ vmd->irq_domain = pci_msi_create_irq_domain(fn, &vmd_msi_domain_info, NULL); + if (!vmd->irq_domain) { + irq_domain_free_fwnode(fn); + return -ENODEV; + } + + return 0; + } + + static void vmd_remove_irq_domain(struct vmd_dev *vmd) + { + if (vmd->irq_domain) { + struct fwnode_handle *fn = vmd->irq_domain->fwnode; + + irq_domain_remove(vmd->irq_domain); + irq_domain_free_fwnode(fn); + } + } + static char __iomem *vmd_cfg_addr(struct vmd_dev *vmd, struct pci_bus *bus, unsigned int devfn, int reg, int len) { @@@ -417,97 -445,175 +444,175 @@@ static int vmd_find_free_domain(void return domain + 1; } - static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) + static int vmd_get_phys_offsets(struct vmd_dev *vmd, bool native_hint, + resource_size_t *offset1, + resource_size_t *offset2) { - struct pci_sysdata *sd = &vmd->sysdata; - struct fwnode_handle *fn; - struct resource *res; - u32 upper_bits; - unsigned long flags; - LIST_HEAD(resources); - resource_size_t offset[2] = {0}; - resource_size_t membar2_offset = 0x2000; - struct pci_bus *child; + struct pci_dev *dev = vmd->dev; + u64 phys1, phys2; - /* - * Shadow registers may exist in certain VMD device ids which allow - * guests to correctly assign host physical addresses to the root ports - * and child devices. These registers will either return the host value - * or 0, depending on an enable bit in the VMD device. - */ - if (features & VMD_FEAT_HAS_MEMBAR_SHADOW) { + if (native_hint) { u32 vmlock; int ret; - membar2_offset = MB2_SHADOW_OFFSET + MB2_SHADOW_SIZE; - ret = pci_read_config_dword(vmd->dev, PCI_REG_VMLOCK, &vmlock); + ret = pci_read_config_dword(dev, PCI_REG_VMLOCK, &vmlock); if (ret || vmlock == ~0) return -ENODEV; if (MB2_SHADOW_EN(vmlock)) { void __iomem *membar2; - membar2 = pci_iomap(vmd->dev, VMD_MEMBAR2, 0); + membar2 = pci_iomap(dev, VMD_MEMBAR2, 0); if (!membar2) return -ENOMEM; - offset[0] = vmd->dev->resource[VMD_MEMBAR1].start - - (readq(membar2 + MB2_SHADOW_OFFSET) & - PCI_BASE_ADDRESS_MEM_MASK); - offset[1] = vmd->dev->resource[VMD_MEMBAR2].start - - (readq(membar2 + MB2_SHADOW_OFFSET + 8) & - PCI_BASE_ADDRESS_MEM_MASK); - pci_iounmap(vmd->dev, membar2); - } - } - - if (features & VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP) { - int pos = pci_find_capability(vmd->dev, PCI_CAP_ID_VNDR); + phys1 = readq(membar2 + MB2_SHADOW_OFFSET); + phys2 = readq(membar2 + MB2_SHADOW_OFFSET + 8); + pci_iounmap(dev, membar2); + } else + return 0; + } else { + /* Hypervisor-Emulated Vendor-Specific Capability */ + int pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); u32 reg, regu; - pci_read_config_dword(vmd->dev, pos + 4, ®); + pci_read_config_dword(dev, pos + 4, ®); /* "SHDW" */ if (pos && reg == 0x53484457) { - pci_read_config_dword(vmd->dev, pos + 8, ®); - pci_read_config_dword(vmd->dev, pos + 12, ®u); - offset[0] = vmd->dev->resource[VMD_MEMBAR1].start - - (((u64) regu << 32 | reg) & - PCI_BASE_ADDRESS_MEM_MASK); - - pci_read_config_dword(vmd->dev, pos + 16, ®); - pci_read_config_dword(vmd->dev, pos + 20, ®u); - offset[1] = vmd->dev->resource[VMD_MEMBAR2].start - - (((u64) regu << 32 | reg) & - PCI_BASE_ADDRESS_MEM_MASK); + pci_read_config_dword(dev, pos + 8, ®); + pci_read_config_dword(dev, pos + 12, ®u); + phys1 = (u64) regu << 32 | reg; + + pci_read_config_dword(dev, pos + 16, ®); + pci_read_config_dword(dev, pos + 20, ®u); + phys2 = (u64) regu << 32 | reg; + } else + return 0; + } + + *offset1 = dev->resource[VMD_MEMBAR1].start - + (phys1 & PCI_BASE_ADDRESS_MEM_MASK); + *offset2 = dev->resource[VMD_MEMBAR2].start - + (phys2 & PCI_BASE_ADDRESS_MEM_MASK); + + return 0; + } + + static int vmd_get_bus_number_start(struct vmd_dev *vmd) + { + struct pci_dev *dev = vmd->dev; + u16 reg; + + pci_read_config_word(dev, PCI_REG_VMCAP, ®); + if (BUS_RESTRICT_CAP(reg)) { + pci_read_config_word(dev, PCI_REG_VMCONFIG, ®); + + switch (BUS_RESTRICT_CFG(reg)) { + case 0: + vmd->busn_start = 0; + break; + case 1: + vmd->busn_start = 128; + break; + case 2: + vmd->busn_start = 224; + break; + default: + pci_err(dev, "Unknown Bus Offset Setting (%d)\n", + BUS_RESTRICT_CFG(reg)); + return -ENODEV; } } + return 0; + } + + static irqreturn_t vmd_irq(int irq, void *data) + { + struct vmd_irq_list *irqs = data; + struct vmd_irq *vmdirq; + int idx; + + idx = srcu_read_lock(&irqs->srcu); + list_for_each_entry_rcu(vmdirq, &irqs->irq_list, node) + generic_handle_irq(vmdirq->virq); + srcu_read_unlock(&irqs->srcu, idx); + + return IRQ_HANDLED; + } + + static int vmd_alloc_irqs(struct vmd_dev *vmd) + { + struct pci_dev *dev = vmd->dev; + int i, err; + + vmd->msix_count = pci_msix_vec_count(dev); + if (vmd->msix_count < 0) + return -ENODEV; + + vmd->msix_count = pci_alloc_irq_vectors(dev, 1, vmd->msix_count, + PCI_IRQ_MSIX); + if (vmd->msix_count < 0) + return vmd->msix_count; + + vmd->irqs = devm_kcalloc(&dev->dev, vmd->msix_count, sizeof(*vmd->irqs), + GFP_KERNEL); + if (!vmd->irqs) + return -ENOMEM; + + for (i = 0; i < vmd->msix_count; i++) { + err = init_srcu_struct(&vmd->irqs[i].srcu); + if (err) + return err; + + INIT_LIST_HEAD(&vmd->irqs[i].irq_list); + err = devm_request_irq(&dev->dev, pci_irq_vector(dev, i), + vmd_irq, IRQF_NO_THREAD, + "vmd", &vmd->irqs[i]); + if (err) + return err; + } + + return 0; + } + + static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) + { + struct pci_sysdata *sd = &vmd->sysdata; + struct resource *res; + u32 upper_bits; + unsigned long flags; + LIST_HEAD(resources); + resource_size_t offset[2] = {0}; + resource_size_t membar2_offset = 0x2000; + struct pci_bus *child; + int ret; + + /* + * Shadow registers may exist in certain VMD device ids which allow + * guests to correctly assign host physical addresses to the root ports + * and child devices. These registers will either return the host value + * or 0, depending on an enable bit in the VMD device. + */ + if (features & VMD_FEAT_HAS_MEMBAR_SHADOW) { + membar2_offset = MB2_SHADOW_OFFSET + MB2_SHADOW_SIZE; + ret = vmd_get_phys_offsets(vmd, true, &offset[0], &offset[1]); + if (ret) + return ret; + } else if (features & VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP) { + ret = vmd_get_phys_offsets(vmd, false, &offset[0], &offset[1]); + if (ret) + return ret; + } + /* * Certain VMD devices may have a root port configuration option which * limits the bus range to between 0-127, 128-255, or 224-255 */ if (features & VMD_FEAT_HAS_BUS_RESTRICTIONS) { - u16 reg16; - - pci_read_config_word(vmd->dev, PCI_REG_VMCAP, ®16); - if (BUS_RESTRICT_CAP(reg16)) { - pci_read_config_word(vmd->dev, PCI_REG_VMCONFIG, - ®16); - - switch (BUS_RESTRICT_CFG(reg16)) { - case 1: - vmd->busn_start = 128; - break; - case 2: - vmd->busn_start = 224; - break; - case 3: - pci_err(vmd->dev, "Unknown Bus Offset Setting\n"); - return -ENODEV; - default: - break; - } - } + ret = vmd_get_bus_number_start(vmd); + if (ret) + return ret; } res = &vmd->dev->resource[VMD_CFGBAR]; @@@ -568,24 -674,10 +673,16 @@@ sd->node = pcibus_to_node(vmd->dev->bus); - fn = irq_domain_alloc_named_id_fwnode("VMD-MSI", vmd->sysdata.domain); - if (!fn) - return -ENODEV; - - vmd->irq_domain = pci_msi_create_irq_domain(fn, &vmd_msi_domain_info, - NULL); - - if (!vmd->irq_domain) { - irq_domain_free_fwnode(fn); - return -ENODEV; - } + ret = vmd_create_irq_domain(vmd); + if (ret) + return ret; + /* + * Override the irq domain bus token so the domain can be distinguished + * from a regular PCI/MSI domain. + */ + irq_domain_update_bus_token(vmd->irq_domain, DOMAIN_BUS_VMD_MSI); + pci_add_resource(&resources, &vmd->resources[0]); pci_add_resource_offset(&resources, &vmd->resources[1], offset[0]); pci_add_resource_offset(&resources, &vmd->resources[2], offset[1]); @@@ -594,13 -686,13 +691,13 @@@ &vmd_ops, sd, &resources); if (!vmd->bus) { pci_free_resource_list(&resources); - irq_domain_remove(vmd->irq_domain); - irq_domain_free_fwnode(fn); + vmd_remove_irq_domain(vmd); return -ENODEV; } vmd_attach_resources(vmd); - dev_set_msi_domain(&vmd->bus->dev, vmd->irq_domain); + if (vmd->irq_domain) + dev_set_msi_domain(&vmd->bus->dev, vmd->irq_domain); pci_scan_child_bus(vmd->bus); pci_assign_unassigned_bus_resources(vmd->bus); @@@ -620,24 -712,10 +717,10 @@@ return 0; } - static irqreturn_t vmd_irq(int irq, void *data) - { - struct vmd_irq_list *irqs = data; - struct vmd_irq *vmdirq; - int idx; - - idx = srcu_read_lock(&irqs->srcu); - list_for_each_entry_rcu(vmdirq, &irqs->irq_list, node) - generic_handle_irq(vmdirq->virq); - srcu_read_unlock(&irqs->srcu, idx); - - return IRQ_HANDLED; - } - static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id) { struct vmd_dev *vmd; - int i, err; + int err; if (resource_size(&dev->resource[VMD_CFGBAR]) < (1 << 20)) return -ENOMEM; @@@ -660,32 -738,9 +743,9 @@@ dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32))) return -ENODEV; - vmd->msix_count = pci_msix_vec_count(dev); - if (vmd->msix_count < 0) - return -ENODEV; - - vmd->msix_count = pci_alloc_irq_vectors(dev, 1, vmd->msix_count, - PCI_IRQ_MSIX); - if (vmd->msix_count < 0) - return vmd->msix_count; - - vmd->irqs = devm_kcalloc(&dev->dev, vmd->msix_count, sizeof(*vmd->irqs), - GFP_KERNEL); - if (!vmd->irqs) - return -ENOMEM; - - for (i = 0; i < vmd->msix_count; i++) { - err = init_srcu_struct(&vmd->irqs[i].srcu); - if (err) - return err; - - INIT_LIST_HEAD(&vmd->irqs[i].irq_list); - err = devm_request_irq(&dev->dev, pci_irq_vector(dev, i), - vmd_irq, IRQF_NO_THREAD, - "vmd", &vmd->irqs[i]); - if (err) - return err; - } + err = vmd_alloc_irqs(vmd); + if (err) + return err; spin_lock_init(&vmd->cfg_lock); pci_set_drvdata(dev, vmd); @@@ -709,15 -764,13 +769,13 @@@ static void vmd_cleanup_srcu(struct vmd static void vmd_remove(struct pci_dev *dev) { struct vmd_dev *vmd = pci_get_drvdata(dev); - struct fwnode_handle *fn = vmd->irq_domain->fwnode; sysfs_remove_link(&vmd->dev->dev.kobj, "domain"); pci_stop_root_bus(vmd->bus); pci_remove_root_bus(vmd->bus); vmd_cleanup_srcu(vmd); vmd_detach_resources(vmd); - irq_domain_remove(vmd->irq_domain); - irq_domain_free_fwnode(fn); + vmd_remove_irq_domain(vmd); } #ifdef CONFIG_PM_SLEEP @@@ -730,7 -783,6 +788,6 @@@ static int vmd_suspend(struct device *d for (i = 0; i < vmd->msix_count; i++) devm_free_irq(dev, pci_irq_vector(pdev, i), &vmd->irqs[i]); - pci_save_state(pdev); return 0; } @@@ -748,7 -800,6 +805,6 @@@ static int vmd_resume(struct device *de return err; } - pci_restore_state(pdev); return 0; } #endif diff --combined drivers/pci/hotplug/pciehp_ctrl.c index 9f85815b4f53,2f5f4bb42dcc..529c34808440 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@@ -73,10 -73,8 +73,8 @@@ static int board_added(struct controlle /* Check link training status */ retval = pciehp_check_link_status(ctrl); - if (retval) { - ctrl_err(ctrl, "Failed to check link status\n"); + if (retval) goto err_exit; - } /* Check for a power fault */ if (ctrl->power_fault_detected || pciehp_query_power_fault(ctrl)) { @@@ -236,7 -234,7 +234,7 @@@ void pciehp_handle_presence_or_link_cha switch (ctrl->state) { case BLINKINGOFF_STATE: cancel_delayed_work(&ctrl->button_work); - /* fall through */ + fallthrough; case ON_STATE: ctrl->state = POWEROFF_STATE; mutex_unlock(&ctrl->state_lock); @@@ -265,7 -263,7 +263,7 @@@ switch (ctrl->state) { case BLINKINGON_STATE: cancel_delayed_work(&ctrl->button_work); - /* fall through */ + fallthrough; case OFF_STATE: ctrl->state = POWERON_STATE; mutex_unlock(&ctrl->state_lock); diff --combined drivers/pci/hotplug/shpchp_ctrl.c index 65502e3f7b4f,aedd9dfd2a16..6a6705e0cf17 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@@ -299,7 -299,6 +299,6 @@@ static int board_added(struct slot *p_s if (p_slot->status == 0xFF) { /* power fault occurred, but it was benign */ ctrl_dbg(ctrl, "%s: Power fault\n", __func__); - rc = POWER_FAILURE; p_slot->status = 0; goto err_exit; } @@@ -642,7 -641,7 +641,7 @@@ int shpchp_sysfs_enable_slot(struct slo switch (p_slot->state) { case BLINKINGON_STATE: cancel_delayed_work(&p_slot->work); - /* fall through */ + fallthrough; case STATIC_STATE: p_slot->state = POWERON_STATE; mutex_unlock(&p_slot->lock); @@@ -678,7 -677,7 +677,7 @@@ int shpchp_sysfs_disable_slot(struct sl switch (p_slot->state) { case BLINKINGOFF_STATE: cancel_delayed_work(&p_slot->work); - /* fall through */ + fallthrough; case STATIC_STATE: p_slot->state = POWEROFF_STATE; mutex_unlock(&p_slot->lock); diff --combined drivers/pci/p2pdma.c index 9d53c16b7329,85fc9936fa9e..de1c331dbed4 --- a/drivers/pci/p2pdma.c +++ b/drivers/pci/p2pdma.c @@@ -53,7 -53,7 +53,7 @@@ static ssize_t size_show(struct device if (pdev->p2pdma->pool) size = gen_pool_size(pdev->p2pdma->pool); - return snprintf(buf, PAGE_SIZE, "%zd\n", size); + return scnprintf(buf, PAGE_SIZE, "%zd\n", size); } static DEVICE_ATTR_RO(size); @@@ -66,7 -66,7 +66,7 @@@ static ssize_t available_show(struct de if (pdev->p2pdma->pool) avail = gen_pool_avail(pdev->p2pdma->pool); - return snprintf(buf, PAGE_SIZE, "%zd\n", avail); + return scnprintf(buf, PAGE_SIZE, "%zd\n", avail); } static DEVICE_ATTR_RO(available); @@@ -75,8 -75,8 +75,8 @@@ static ssize_t published_show(struct de { struct pci_dev *pdev = to_pci_dev(dev); - return snprintf(buf, PAGE_SIZE, "%d\n", - pdev->p2pdma->p2pmem_published); + return scnprintf(buf, PAGE_SIZE, "%d\n", + pdev->p2pdma->p2pmem_published); } static DEVICE_ATTR_RO(published); @@@ -185,9 -185,9 +185,9 @@@ int pci_p2pdma_add_resource(struct pci_ return -ENOMEM; pgmap = &p2p_pgmap->pgmap; - pgmap->res.start = pci_resource_start(pdev, bar) + offset; - pgmap->res.end = pgmap->res.start + size - 1; - pgmap->res.flags = pci_resource_flags(pdev, bar); + pgmap->range.start = pci_resource_start(pdev, bar) + offset; + pgmap->range.end = pgmap->range.start + size - 1; + pgmap->nr_range = 1; pgmap->type = MEMORY_DEVICE_PCI_P2PDMA; p2p_pgmap->provider = pdev; @@@ -202,13 -202,13 +202,13 @@@ error = gen_pool_add_owner(pdev->p2pdma->pool, (unsigned long)addr, pci_bus_address(pdev, bar) + offset, - resource_size(&pgmap->res), dev_to_node(&pdev->dev), + range_len(&pgmap->range), dev_to_node(&pdev->dev), pgmap->ref); if (error) goto pages_free; - pci_info(pdev, "added peer-to-peer DMA memory %pR\n", - &pgmap->res); + pci_info(pdev, "added peer-to-peer DMA memory %#llx-%#llx\n", + pgmap->range.start, pgmap->range.end); return 0; @@@ -556,14 -556,13 +556,14 @@@ int pci_p2pdma_distance_many(struct pci return -1; for (i = 0; i < num_clients; i++) { - if (IS_ENABLED(CONFIG_DMA_VIRT_OPS) && - clients[i]->dma_ops == &dma_virt_ops) { +#ifdef CONFIG_DMA_VIRT_OPS + if (clients[i]->dma_ops == &dma_virt_ops) { if (verbose) dev_warn(clients[i], "cannot be used for peer-to-peer DMA because the driver makes use of dma_virt_ops\n"); return -1; } +#endif pci_client = find_parent_pci_dev(clients[i]); if (!pci_client) { @@@ -762,7 -761,7 +762,7 @@@ struct scatterlist *pci_p2pmem_alloc_sg struct scatterlist *sg; void *addr; - sg = kzalloc(sizeof(*sg), GFP_KERNEL); + sg = kmalloc(sizeof(*sg), GFP_KERNEL); if (!sg) return NULL; @@@ -843,10 -842,9 +843,10 @@@ static int __pci_p2pdma_map_sg(struct p * this should never happen because it will be prevented * by the check in pci_p2pdma_distance_many() */ - if (WARN_ON_ONCE(IS_ENABLED(CONFIG_DMA_VIRT_OPS) && - dev->dma_ops == &dma_virt_ops)) +#ifdef CONFIG_DMA_VIRT_OPS + if (WARN_ON_ONCE(dev->dma_ops == &dma_virt_ops)) return 0; +#endif for_each_sg(sg, s, nents, i) { paddr = sg_phys(s); diff --combined drivers/pci/pci-acpi.c index d9aa551f8423,154db9a47511..bf03648c2072 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@@ -944,16 -944,6 +944,16 @@@ static bool acpi_pci_bridge_d3(struct p if (!dev->is_hotplug_bridge) return false; + /* Assume D3 support if the bridge is power-manageable by ACPI. */ + adev = ACPI_COMPANION(&dev->dev); + if (!adev && !pci_dev_is_added(dev)) { + adev = acpi_pci_find_companion(&dev->dev); + ACPI_COMPANION_SET(&dev->dev, adev); + } + + if (adev && acpi_device_power_manageable(adev)) + return true; + /* * Look for a special _DSD property for the root port and if it * is set we know the hierarchy behind it supports D3 just fine. @@@ -1177,7 -1167,7 +1177,7 @@@ static struct acpi_device *acpi_pci_fin * @pdev: the PCI device whose delay is to be updated * @handle: ACPI handle of this device * - * Update the d3_delay and d3cold_delay of a PCI device from the ACPI _DSM + * Update the d3hot_delay and d3cold_delay of a PCI device from the ACPI _DSM * control method of either the device itself or the PCI host bridge. * * Function 8, "Reset Delay," applies to the entire hierarchy below a PCI @@@ -1216,8 -1206,8 +1216,8 @@@ static void pci_acpi_optimize_delay(str } if (elements[3].type == ACPI_TYPE_INTEGER) { value = (int)elements[3].integer.value / 1000; - if (value < PCI_PM_D3_WAIT) - pdev->d3_delay = value; + if (value < PCI_PM_D3HOT_WAIT) + pdev->d3hot_delay = value; } } ACPI_FREE(obj); diff --combined drivers/pci/pci-driver.c index d1b7169c0684,40be221e69cf..8b587fc97f7b --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@@ -19,7 -19,6 +19,7 @@@ #include #include #include +#include #include "pci.h" #include "pcie/portdrv.h" @@@ -970,12 -969,6 +970,6 @@@ static int pci_pm_resume(struct device #ifdef CONFIG_HIBERNATE_CALLBACKS - /* - * pcibios_pm_ops - provide arch-specific hooks when a PCI device is doing - * a hibernate transition - */ - struct dev_pm_ops __weak pcibios_pm_ops; - static int pci_pm_freeze(struct device *dev) { struct pci_dev *pci_dev = to_pci_dev(dev); @@@ -1034,9 -1027,6 +1028,6 @@@ static int pci_pm_freeze_noirq(struct d pci_pm_set_unknown_state(pci_dev); - if (pcibios_pm_ops.freeze_noirq) - return pcibios_pm_ops.freeze_noirq(dev); - return 0; } @@@ -1044,13 -1034,6 +1035,6 @@@ static int pci_pm_thaw_noirq(struct dev { struct pci_dev *pci_dev = to_pci_dev(dev); const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - int error; - - if (pcibios_pm_ops.thaw_noirq) { - error = pcibios_pm_ops.thaw_noirq(dev); - if (error) - return error; - } /* * The pm->thaw_noirq() callback assumes the device has been @@@ -1175,9 -1158,6 +1159,6 @@@ static int pci_pm_poweroff_noirq(struc pci_fixup_device(pci_fixup_suspend_late, pci_dev); - if (pcibios_pm_ops.poweroff_noirq) - return pcibios_pm_ops.poweroff_noirq(dev); - return 0; } @@@ -1185,13 -1165,6 +1166,6 @@@ static int pci_pm_restore_noirq(struct { struct pci_dev *pci_dev = to_pci_dev(dev); const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - int error; - - if (pcibios_pm_ops.restore_noirq) { - error = pcibios_pm_ops.restore_noirq(dev); - if (error) - return error; - } pci_pm_default_resume_early(pci_dev); pci_fixup_device(pci_fixup_resume_early, pci_dev); diff --combined drivers/pci/pci.c index e39c5499770f,0e63e0e77708..6d4d5a2f923d --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@@ -15,7 -15,6 +15,6 @@@ #include #include #include - #include #include #include #include @@@ -30,8 -29,6 +29,6 @@@ #include #include #include - #include - #include #include #include #include "pci.h" @@@ -49,7 -46,7 +46,7 @@@ EXPORT_SYMBOL(isa_dma_bridge_buggy) int pci_pci_problems; EXPORT_SYMBOL(pci_pci_problems); - unsigned int pci_pm_d3_delay; + unsigned int pci_pm_d3hot_delay; static void pci_pme_list_scan(struct work_struct *work); @@@ -66,10 -63,10 +63,10 @@@ struct pci_pme_device static void pci_dev_d3_sleep(struct pci_dev *dev) { - unsigned int delay = dev->d3_delay; + unsigned int delay = dev->d3hot_delay; - if (delay < pci_pm_d3_delay) - delay = pci_pm_d3_delay; + if (delay < pci_pm_d3hot_delay) + delay = pci_pm_d3hot_delay; if (delay) msleep(delay); @@@ -101,7 -98,19 +98,19 @@@ unsigned long pci_hotplug_mmio_pref_siz #define DEFAULT_HOTPLUG_BUS_SIZE 1 unsigned long pci_hotplug_bus_size = DEFAULT_HOTPLUG_BUS_SIZE; + + /* PCIe MPS/MRRS strategy; can be overridden by kernel command-line param */ + #ifdef CONFIG_PCIE_BUS_TUNE_OFF + enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_TUNE_OFF; + #elif defined CONFIG_PCIE_BUS_SAFE + enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_SAFE; + #elif defined CONFIG_PCIE_BUS_PERFORMANCE + enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_PERFORMANCE; + #elif defined CONFIG_PCIE_BUS_PEER2PEER + enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_PEER2PEER; + #else enum pcie_bus_config_types pcie_bus_config = PCIE_BUS_DEFAULT; + #endif /* * The default CLS is used if arch didn't set CLS explicitly and not @@@ -876,6 -885,10 +885,10 @@@ static void pci_std_enable_acs(struct p /* Upstream Forwarding */ ctrl |= (cap & PCI_ACS_UF); + /* Enable Translation Blocking for external devices */ + if (dev->external_facing || dev->untrusted) + ctrl |= (cap & PCI_ACS_TB); + pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl); } @@@ -1049,7 -1062,7 +1062,7 @@@ static int pci_raw_set_power_state(stru if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) need_restore = true; - /* Fall-through - force to D0 */ + fallthrough; /* force to D0 */ default: pmcsr = 0; break; @@@ -1065,7 -1078,7 +1078,7 @@@ if (state == PCI_D3hot || dev->current_state == PCI_D3hot) pci_dev_d3_sleep(dev); else if (state == PCI_D2 || dev->current_state == PCI_D2) - msleep(PCI_PM_D2_DELAY); + udelay(PCI_PM_D2_DELAY); pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr); dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK); @@@ -2541,7 -2554,7 +2554,7 @@@ static pci_power_t pci_target_state(str case PCI_D2: if (pci_no_d1d2(dev)) break; - /* else, fall through */ + fallthrough; default: target_state = state; } @@@ -3013,7 -3026,7 +3026,7 @@@ void pci_pm_init(struct pci_dev *dev } dev->pm_cap = pm; - dev->d3_delay = PCI_PM_D3_WAIT; + dev->d3hot_delay = PCI_PM_D3HOT_WAIT; dev->d3cold_delay = PCI_PM_D3COLD_WAIT; dev->bridge_d3 = pci_bridge_d3_possible(dev); dev->d3cold_allowed = true; @@@ -3038,7 -3051,7 +3051,7 @@@ (pmc & PCI_PM_CAP_PME_D0) ? " D0" : "", (pmc & PCI_PM_CAP_PME_D1) ? " D1" : "", (pmc & PCI_PM_CAP_PME_D2) ? " D2" : "", - (pmc & PCI_PM_CAP_PME_D3) ? " D3hot" : "", + (pmc & PCI_PM_CAP_PME_D3hot) ? " D3hot" : "", (pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : ""); dev->pme_support = pmc >> PCI_PM_CAP_PME_SHIFT; dev->pme_poll = true; @@@ -4621,7 -4634,7 +4634,7 @@@ static int pci_af_flr(struct pci_dev *d * * NOTE: This causes the caller to sleep for twice the device power transition * cooldown period, which for the D0->D3hot and D3hot->D0 transitions is 10 ms - * by default (i.e. unless the @dev's d3_delay field has a different value). + * by default (i.e. unless the @dev's d3hot_delay field has a different value). * Moreover, only devices in D0 can be reset by this function. */ static int pci_pm_reset(struct pci_dev *dev, int probe) @@@ -4701,9 -4714,7 +4714,7 @@@ static bool pcie_wait_for_link_delay(st } if (active && ret) msleep(delay); - else if (ret != active) - pci_info(pdev, "Data Link Layer Link Active not %s in 1000 msec\n", - active ? "set" : "cleared"); + return ret == active; } @@@ -4828,6 -4839,7 +4839,7 @@@ void pci_bridge_wait_for_secondary_bus( delay); if (!pcie_wait_for_link_delay(dev, true, delay)) { /* Did not train, no need to wait any further */ + pci_info(dev, "Data Link Layer Link Active not set in 1000 msec\n"); return; } } @@@ -4920,16 -4932,10 +4932,10 @@@ static int pci_reset_hotplug_slot(struc static int pci_dev_reset_slot_function(struct pci_dev *dev, int probe) { - struct pci_dev *pdev; - - if (dev->subordinate || !dev->slot || + if (dev->multifunction || dev->subordinate || !dev->slot || dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET) return -ENOTTY; - list_for_each_entry(pdev, &dev->bus->devices, bus_list) - if (pdev != dev && pdev->slot == dev->slot) - return -ENOTTY; - return pci_reset_hotplug_slot(dev->slot->hotplug, probe); } @@@ -6005,7 -6011,7 +6011,7 @@@ int pci_set_vga_state(struct pci_dev *d if (flags & PCI_VGA_STATE_CHANGE_DECODES) { pci_read_config_word(dev, PCI_COMMAND, &cmd); - if (decode == true) + if (decode) cmd |= command_bits; else cmd &= ~command_bits; @@@ -6021,7 -6027,7 +6027,7 @@@ if (bridge) { pci_read_config_word(bridge, PCI_BRIDGE_CONTROL, &cmd); - if (decode == true) + if (decode) cmd |= PCI_BRIDGE_CTL_VGA; else cmd &= ~PCI_BRIDGE_CTL_VGA; @@@ -6350,7 -6356,7 +6356,7 @@@ static ssize_t resource_alignment_show( spin_lock(&resource_alignment_lock); if (resource_alignment_param) - count = snprintf(buf, PAGE_SIZE, "%s", resource_alignment_param); + count = scnprintf(buf, PAGE_SIZE, "%s", resource_alignment_param); spin_unlock(&resource_alignment_lock); /* diff --combined drivers/pci/quirks.c index 01f23e30bd8f,eefed9d26945..f70692ac79c5 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@@ -1730,7 -1730,7 +1730,7 @@@ static void quirk_jmicron_ata(struct pc case PCI_DEVICE_ID_JMICRON_JMB366: /* Redirect IDE second PATA port to the right spot */ conf5 |= (1 << 24); - /* Fall through */ + fallthrough; case PCI_DEVICE_ID_JMICRON_JMB361: case PCI_DEVICE_ID_JMICRON_JMB363: case PCI_DEVICE_ID_JMICRON_JMB369: @@@ -1846,7 -1846,7 +1846,7 @@@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_I */ static void quirk_intel_pcie_pm(struct pci_dev *dev) { - pci_pm_d3_delay = 120; + pci_pm_d3hot_delay = 120; dev->no_d1d2 = 1; } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x25e2, quirk_intel_pcie_pm); @@@ -1873,12 -1873,12 +1873,12 @@@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_I static void quirk_d3hot_delay(struct pci_dev *dev, unsigned int delay) { - if (dev->d3_delay >= delay) + if (dev->d3hot_delay >= delay) return; - dev->d3_delay = delay; + dev->d3hot_delay = delay; pci_info(dev, "extending delay after power-on from D3hot to %d msec\n", - dev->d3_delay); + dev->d3hot_delay); } static void quirk_radeon_pm(struct pci_dev *dev) @@@ -2224,7 -2224,7 +2224,7 @@@ static void quirk_netmos(struct pci_de if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM && dev->subsystem_device == 0x0299) return; - /* else, fall through */ + fallthrough; case PCI_DEVICE_ID_NETMOS_9735: case PCI_DEVICE_ID_NETMOS_9745: case PCI_DEVICE_ID_NETMOS_9845: @@@ -3387,36 -3387,36 +3387,36 @@@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_I * PCI devices which are on Intel chips can skip the 10ms delay * before entering D3 mode. */ - static void quirk_remove_d3_delay(struct pci_dev *dev) - { - dev->d3_delay = 0; - } - /* C600 Series devices do not need 10ms d3_delay */ - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0412, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c00, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c0c, quirk_remove_d3_delay); - /* Lynxpoint-H PCH devices do not need 10ms d3_delay */ - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c02, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c18, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c1c, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c20, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c22, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c26, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c2d, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c31, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3a, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3d, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c4e, quirk_remove_d3_delay); - /* Intel Cherrytrail devices do not need 10ms d3_delay */ - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2280, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2298, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x229c, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b0, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b5, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b7, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b8, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22d8, quirk_remove_d3_delay); - DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22dc, quirk_remove_d3_delay); + static void quirk_remove_d3hot_delay(struct pci_dev *dev) + { + dev->d3hot_delay = 0; + } + /* C600 Series devices do not need 10ms d3hot_delay */ + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0412, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c00, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x0c0c, quirk_remove_d3hot_delay); + /* Lynxpoint-H PCH devices do not need 10ms d3hot_delay */ + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c02, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c18, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c1c, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c20, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c22, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c26, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c2d, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c31, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3a, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c3d, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x8c4e, quirk_remove_d3hot_delay); + /* Intel Cherrytrail devices do not need 10ms d3hot_delay */ + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2280, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x2298, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x229c, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b0, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b5, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b7, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22b8, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22d8, quirk_remove_d3hot_delay); + DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, 0x22dc, quirk_remove_d3hot_delay); /* * Some devices may pass our check in pci_intx_mask_supported() if @@@ -3673,6 -3673,63 +3673,6 @@@ static void quirk_apple_poweroff_thunde DECLARE_PCI_FIXUP_SUSPEND_LATE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C, quirk_apple_poweroff_thunderbolt); - -/* - * Apple: Wait for the Thunderbolt controller to reestablish PCI tunnels - * - * During suspend the Thunderbolt controller is reset and all PCI - * tunnels are lost. The NHI driver will try to reestablish all tunnels - * during resume. We have to manually wait for the NHI since there is - * no parent child relationship between the NHI and the tunneled - * bridges. - */ -static void quirk_apple_wait_for_thunderbolt(struct pci_dev *dev) -{ - struct pci_dev *sibling = NULL; - struct pci_dev *nhi = NULL; - - if (!x86_apple_machine) - return; - if (pci_pcie_type(dev) != PCI_EXP_TYPE_DOWNSTREAM) - return; - - /* - * Find the NHI and confirm that we are a bridge on the Thunderbolt - * host controller and not on a Thunderbolt endpoint. - */ - sibling = pci_get_slot(dev->bus, 0x0); - if (sibling == dev) - goto out; /* we are the downstream bridge to the NHI */ - if (!sibling || !sibling->subordinate) - goto out; - nhi = pci_get_slot(sibling->subordinate, 0x0); - if (!nhi) - goto out; - if (nhi->vendor != PCI_VENDOR_ID_INTEL - || (nhi->device != PCI_DEVICE_ID_INTEL_LIGHT_RIDGE && - nhi->device != PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C && - nhi->device != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_NHI && - nhi->device != PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_NHI) - || nhi->class != PCI_CLASS_SYSTEM_OTHER << 8) - goto out; - pci_info(dev, "quirk: waiting for Thunderbolt to reestablish PCI tunnels...\n"); - device_pm_wait_for_dev(&dev->dev, &nhi->dev); -out: - pci_dev_put(nhi); - pci_dev_put(sibling); -} -DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_LIGHT_RIDGE, - quirk_apple_wait_for_thunderbolt); -DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_CACTUS_RIDGE_4C, - quirk_apple_wait_for_thunderbolt); -DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_FALCON_RIDGE_2C_BRIDGE, - quirk_apple_wait_for_thunderbolt); -DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_FALCON_RIDGE_4C_BRIDGE, - quirk_apple_wait_for_thunderbolt); #endif /* @@@ -4892,6 -4949,13 +4892,13 @@@ static void pci_quirk_enable_intel_rp_m } } + /* + * Currently this quirk does the equivalent of + * PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF + * + * TODO: This quirk also needs to do equivalent of PCI_ACS_TB, + * if dev->external_facing || dev->untrusted + */ static int pci_quirk_enable_intel_pch_acs(struct pci_dev *dev) { if (!pci_quirk_intel_pch_acs_match(dev)) @@@ -4931,6 -4995,9 +4938,9 @@@ static int pci_quirk_enable_intel_spt_p ctrl |= (cap & PCI_ACS_CR); ctrl |= (cap & PCI_ACS_UF); + if (dev->external_facing || dev->untrusted) + ctrl |= (cap & PCI_ACS_TB); + pci_write_config_dword(dev, pos + INTEL_SPT_ACS_CTRL, ctrl); pci_info(dev, "Intel SPT PCH root port ACS workaround enabled\n"); diff --combined drivers/staging/media/atomisp/pci/atomisp_v4l2.c index 376205e97a89,beba430a197e..0295e2e32d79 --- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c +++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c @@@ -1086,7 -1086,7 +1086,7 @@@ static int atomisp_subdev_probe(struct case RAW_CAMERA: dev_dbg(isp->dev, "raw_index: %d\n", raw_index); raw_index = isp->input_cnt; - /* fall through */ + fallthrough; case SOC_CAMERA: dev_dbg(isp->dev, "SOC_INDEX: %d\n", isp->input_cnt); if (isp->input_cnt >= ATOM_ISP_MAX_INPUTS) { @@@ -1429,6 -1429,7 +1429,6 @@@ atomisp_load_firmware(struct atomisp_de */ static bool is_valid_device(struct pci_dev *pdev, const struct pci_device_id *id) { - unsigned int a0_max_id = 0; const char *name; const char *product; @@@ -1436,9 -1437,11 +1436,9 @@@ switch (id->device & ATOMISP_PCI_DEVICE_SOC_MASK) { case ATOMISP_PCI_DEVICE_SOC_MRFLD: - a0_max_id = ATOMISP_PCI_REV_MRFLD_A0_MAX; name = "Merrifield"; break; case ATOMISP_PCI_DEVICE_SOC_BYT: - a0_max_id = ATOMISP_PCI_REV_BYT_A0_MAX; name = "Baytrail"; break; case ATOMISP_PCI_DEVICE_SOC_ANN: @@@ -1570,7 -1573,7 +1570,7 @@@ static int atomisp_pci_probe(struct pci spin_lock_init(&isp->lock); /* This is not a true PCI device on SoC, so the delay is not needed. */ - pdev->d3_delay = 0; + pdev->d3hot_delay = 0; pci_set_drvdata(pdev, isp); @@@ -1705,8 -1708,8 +1705,8 @@@ pci_set_master(pdev); - err = pci_enable_msi(pdev); - if (err) { + err = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI); + if (err < 0) { dev_err(&pdev->dev, "Failed to enable msi (%d)\n", err); goto enable_msi_fail; } @@@ -1824,7 -1827,7 +1824,7 @@@ register_entities_fail initialize_modules_fail: cpu_latency_qos_remove_request(&isp->pm_qos); atomisp_msi_irq_uninit(isp); - pci_disable_msi(pdev); + pci_free_irq_vectors(pdev); enable_msi_fail: fw_validation_fail: release_firmware(isp->firmware);