diff options
Diffstat (limited to 'drivers/pci/host')
25 files changed, 3678 insertions, 1792 deletions
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 0d0177ce436c..a96e23bda664 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -5,13 +5,14 @@ menu "PCI host controller drivers" config PCI_MVEBU bool "Marvell EBU PCIe controller" - depends on ARCH_MVEBU || ARCH_DOVE + depends on ARCH_MVEBU || ARCH_DOVE || COMPILE_TEST + depends on MVEBU_MBUS depends on ARM depends on OF config PCI_AARDVARK bool "Aardvark PCIe controller" - depends on ARCH_MVEBU && ARM64 + depends on (ARCH_MVEBU && ARM64) || COMPILE_TEST depends on OF depends on PCI_MSI_IRQ_DOMAIN help @@ -21,7 +22,7 @@ config PCI_AARDVARK config PCIE_XILINX_NWL bool "NWL PCIe Core" - depends on ARCH_ZYNQMP + depends on ARCH_ZYNQMP || COMPILE_TEST depends on PCI_MSI_IRQ_DOMAIN help Say 'Y' here if you want kernel support for Xilinx @@ -32,12 +33,11 @@ config PCIE_XILINX_NWL config PCI_FTPCI100 bool "Faraday Technology FTPCI100 PCI controller" depends on OF - depends on ARM default ARCH_GEMINI config PCI_TEGRA bool "NVIDIA Tegra PCIe controller" - depends on ARCH_TEGRA + depends on ARCH_TEGRA || COMPILE_TEST depends on PCI_MSI_IRQ_DOMAIN help Say Y here if you want support for the PCIe host controller found @@ -45,8 +45,8 @@ config PCI_TEGRA config PCI_RCAR_GEN2 bool "Renesas R-Car Gen2 Internal PCI controller" - depends on ARM depends on ARCH_RENESAS || COMPILE_TEST + depends on ARM help Say Y here if you want internal PCI support on R-Car Gen2 SoC. There are 3 internal PCI controllers available with a single @@ -54,7 +54,7 @@ config PCI_RCAR_GEN2 config PCIE_RCAR bool "Renesas R-Car PCIe controller" - depends on ARCH_RENESAS || (ARM && COMPILE_TEST) + depends on ARCH_RENESAS || COMPILE_TEST depends on PCI_MSI_IRQ_DOMAIN help Say Y here if you want PCIe controller support on R-Car SoCs. @@ -65,25 +65,25 @@ config PCI_HOST_COMMON config PCI_HOST_GENERIC bool "Generic PCI host controller" - depends on (ARM || ARM64) && OF + depends on OF select PCI_HOST_COMMON select IRQ_DOMAIN + select PCI_DOMAINS help Say Y here if you want to support a simple generic PCI host controller, such as the one emulated by kvmtool. config PCIE_XILINX bool "Xilinx AXI PCIe host bridge support" - depends on ARCH_ZYNQ || MICROBLAZE || (MIPS && PCI_DRIVERS_GENERIC) + depends on ARCH_ZYNQ || MICROBLAZE || (MIPS && PCI_DRIVERS_GENERIC) || COMPILE_TEST help Say 'Y' here if you want kernel to support the Xilinx AXI PCIe Host Bridge driver. config PCI_XGENE bool "X-Gene PCIe controller" - depends on ARM64 + depends on ARM64 || COMPILE_TEST depends on OF || (ACPI && PCI_QUIRKS) - select PCIEPORTBUS help Say Y here if you want internal PCI support on APM X-Gene SoC. There are 5 internal PCIe ports available. Each port is GEN3 capable @@ -101,7 +101,7 @@ config PCI_XGENE_MSI config PCI_V3_SEMI bool "V3 Semiconductor PCI controller" depends on OF - depends on ARM + depends on ARM || COMPILE_TEST default ARCH_INTEGRATOR_AP config PCI_VERSATILE @@ -147,8 +147,7 @@ config PCIE_IPROC_MSI config PCIE_ALTERA bool "Altera PCIe controller" - depends on ARM || NIOS2 - depends on OF_PCI + depends on ARM || NIOS2 || COMPILE_TEST select PCI_DOMAINS help Say Y here if you want to enable PCIe controller support on Altera @@ -164,7 +163,7 @@ config PCIE_ALTERA_MSI config PCI_HOST_THUNDER_PEM bool "Cavium Thunder PCIe controller to off-chip devices" - depends on ARM64 + depends on ARM64 || COMPILE_TEST depends on OF || (ACPI && PCI_QUIRKS) select PCI_HOST_COMMON help @@ -172,29 +171,45 @@ config PCI_HOST_THUNDER_PEM config PCI_HOST_THUNDER_ECAM bool "Cavium Thunder ECAM controller to on-chip devices on pass-1.x silicon" - depends on ARM64 + depends on ARM64 || COMPILE_TEST depends on OF || (ACPI && PCI_QUIRKS) select PCI_HOST_COMMON help Say Y here if you want ECAM support for CN88XX-Pass-1.x Cavium Thunder SoCs. config PCIE_ROCKCHIP - tristate "Rockchip PCIe controller" + bool + depends on PCI + +config PCIE_ROCKCHIP_HOST + tristate "Rockchip PCIe host controller" depends on ARCH_ROCKCHIP || COMPILE_TEST depends on OF depends on PCI_MSI_IRQ_DOMAIN select MFD_SYSCON + select PCIE_ROCKCHIP help Say Y here if you want internal PCI support on Rockchip SoC. There is 1 internal PCIe port available to support GEN2 with 4 slots. +config PCIE_ROCKCHIP_EP + bool "Rockchip PCIe endpoint controller" + depends on ARCH_ROCKCHIP || COMPILE_TEST + depends on OF + depends on PCI_ENDPOINT + select MFD_SYSCON + select PCIE_ROCKCHIP + help + Say Y here if you want to support Rockchip PCIe controller in + endpoint mode on Rockchip SoC. There is 1 internal PCIe port + available to support GEN2 with 4 slots. + config PCIE_MEDIATEK bool "MediaTek PCIe controller" - depends on (ARM || ARM64) && (ARCH_MEDIATEK || COMPILE_TEST) + depends on ARCH_MEDIATEK || COMPILE_TEST depends on OF - depends on PCI - select PCIEPORTBUS + depends on PCI_MSI_IRQ_DOMAIN help Say Y here if you want to enable PCIe controller support on MediaTek SoCs. diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 3b1059190867..11d21b026d37 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -20,6 +20,8 @@ obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o +obj-$(CONFIG_PCIE_ROCKCHIP_EP) += pcie-rockchip-ep.o +obj-$(CONFIG_PCIE_ROCKCHIP_HOST) += pcie-rockchip-host.o obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o obj-$(CONFIG_VMD) += vmd.o diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c index 9abf549631b4..d3172d5d3d35 100644 --- a/drivers/pci/host/pci-aardvark.c +++ b/drivers/pci/host/pci-aardvark.c @@ -19,6 +19,8 @@ #include <linux/of_address.h> #include <linux/of_pci.h> +#include "../pci.h" + /* PCIe core registers */ #define PCIE_CORE_CMD_STATUS_REG 0x4 #define PCIE_CORE_CMD_IO_ACCESS_EN BIT(0) @@ -822,14 +824,13 @@ static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie) { int err, res_valid = 0; struct device *dev = &pcie->pdev->dev; - struct device_node *np = dev->of_node; struct resource_entry *win, *tmp; resource_size_t iobase; INIT_LIST_HEAD(&pcie->resources); - err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pcie->resources, - &iobase); + err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, + &pcie->resources, &iobase); if (err) return err; diff --git a/drivers/pci/host/pci-ftpci100.c b/drivers/pci/host/pci-ftpci100.c index 5008fd87956a..a1ebe9ed441f 100644 --- a/drivers/pci/host/pci-ftpci100.c +++ b/drivers/pci/host/pci-ftpci100.c @@ -28,6 +28,8 @@ #include <linux/irq.h> #include <linux/clk.h> +#include "../pci.h" + /* * Special configuration registers directly in the first few words * in I/O space. @@ -476,8 +478,8 @@ static int faraday_pci_probe(struct platform_device *pdev) if (IS_ERR(p->base)) return PTR_ERR(p->base); - ret = of_pci_get_host_bridge_resources(dev->of_node, 0, 0xff, - &res, &io_base); + ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, + &res, &io_base); if (ret) return ret; diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index 5d028f53fdcd..d8f10451f273 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -101,5 +101,18 @@ int pci_host_common_probe(struct platform_device *pdev, return ret; } + platform_set_drvdata(pdev, bridge->bus); + return 0; +} + +int pci_host_common_remove(struct platform_device *pdev) +{ + struct pci_bus *bus = platform_get_drvdata(pdev); + + pci_lock_rescan_remove(); + pci_stop_root_bus(bus); + pci_remove_root_bus(bus); + pci_unlock_rescan_remove(); + return 0; } diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c index 45319ee3b484..dea3ec7592a2 100644 --- a/drivers/pci/host/pci-host-generic.c +++ b/drivers/pci/host/pci-host-generic.c @@ -95,5 +95,6 @@ static struct platform_driver gen_pci_driver = { .suppress_bind_attrs = true, }, .probe = gen_pci_probe, + .remove = pci_host_common_remove, }; builtin_platform_driver(gen_pci_driver); diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c index 50cdefe3f6d3..6cc5036ac83c 100644 --- a/drivers/pci/host/pci-hyperv.c +++ b/drivers/pci/host/pci-hyperv.c @@ -433,7 +433,7 @@ enum hv_pcibus_state { struct hv_pcibus_device { struct pci_sysdata sysdata; enum hv_pcibus_state state; - atomic_t remove_lock; + refcount_t remove_lock; struct hv_device *hdev; resource_size_t low_mmio_space; resource_size_t high_mmio_space; @@ -488,17 +488,6 @@ enum hv_pcichild_state { hv_pcichild_maximum }; -enum hv_pcidev_ref_reason { - hv_pcidev_ref_invalid = 0, - hv_pcidev_ref_initial, - hv_pcidev_ref_by_slot, - hv_pcidev_ref_packet, - hv_pcidev_ref_pnp, - hv_pcidev_ref_childlist, - hv_pcidev_irqdata, - hv_pcidev_ref_max -}; - struct hv_pci_dev { /* List protected by pci_rescan_remove_lock */ struct list_head list_entry; @@ -548,14 +537,41 @@ static void hv_pci_generic_compl(void *context, struct pci_response *resp, static struct hv_pci_dev *get_pcichild_wslot(struct hv_pcibus_device *hbus, u32 wslot); -static void get_pcichild(struct hv_pci_dev *hv_pcidev, - enum hv_pcidev_ref_reason reason); -static void put_pcichild(struct hv_pci_dev *hv_pcidev, - enum hv_pcidev_ref_reason reason); + +static void get_pcichild(struct hv_pci_dev *hpdev) +{ + refcount_inc(&hpdev->refs); +} + +static void put_pcichild(struct hv_pci_dev *hpdev) +{ + if (refcount_dec_and_test(&hpdev->refs)) + kfree(hpdev); +} static void get_hvpcibus(struct hv_pcibus_device *hv_pcibus); static void put_hvpcibus(struct hv_pcibus_device *hv_pcibus); +/* + * There is no good way to get notified from vmbus_onoffer_rescind(), + * so let's use polling here, since this is not a hot path. + */ +static int wait_for_response(struct hv_device *hdev, + struct completion *comp) +{ + while (true) { + if (hdev->channel->rescind) { + dev_warn_once(&hdev->device, "The device is gone.\n"); + return -ENODEV; + } + + if (wait_for_completion_timeout(comp, HZ / 10)) + break; + } + + return 0; +} + /** * devfn_to_wslot() - Convert from Linux PCI slot to Windows * @devfn: The Linux representation of PCI slot @@ -762,7 +778,7 @@ static int hv_pcifront_read_config(struct pci_bus *bus, unsigned int devfn, _hv_pcifront_read_config(hpdev, where, size, val); - put_pcichild(hpdev, hv_pcidev_ref_by_slot); + put_pcichild(hpdev); return PCIBIOS_SUCCESSFUL; } @@ -790,7 +806,7 @@ static int hv_pcifront_write_config(struct pci_bus *bus, unsigned int devfn, _hv_pcifront_write_config(hpdev, where, size, val); - put_pcichild(hpdev, hv_pcidev_ref_by_slot); + put_pcichild(hpdev); return PCIBIOS_SUCCESSFUL; } @@ -856,7 +872,7 @@ static void hv_msi_free(struct irq_domain *domain, struct msi_domain_info *info, } hv_int_desc_free(hpdev, int_desc); - put_pcichild(hpdev, hv_pcidev_ref_by_slot); + put_pcichild(hpdev); } static int hv_set_affinity(struct irq_data *data, const struct cpumask *dest, @@ -1186,13 +1202,13 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) msg->address_lo = comp.int_desc.address & 0xffffffff; msg->data = comp.int_desc.data; - put_pcichild(hpdev, hv_pcidev_ref_by_slot); + put_pcichild(hpdev); return; free_int_desc: kfree(int_desc); drop_reference: - put_pcichild(hpdev, hv_pcidev_ref_by_slot); + put_pcichild(hpdev); return_null_message: msg->address_hi = 0; msg->address_lo = 0; @@ -1283,7 +1299,6 @@ static u64 get_bar_size(u64 bar_val) */ static void survey_child_resources(struct hv_pcibus_device *hbus) { - struct list_head *iter; struct hv_pci_dev *hpdev; resource_size_t bar_size = 0; unsigned long flags; @@ -1309,8 +1324,7 @@ static void survey_child_resources(struct hv_pcibus_device *hbus) * for a child device are a power of 2 in size and aligned in memory, * so it's sufficient to just add them up without tracking alignment. */ - list_for_each(iter, &hbus->children) { - hpdev = container_of(iter, struct hv_pci_dev, list_entry); + list_for_each_entry(hpdev, &hbus->children, list_entry) { for (i = 0; i < 6; i++) { if (hpdev->probed_bar[i] & PCI_BASE_ADDRESS_SPACE_IO) dev_err(&hbus->hdev->device, @@ -1363,7 +1377,6 @@ static void prepopulate_bars(struct hv_pcibus_device *hbus) resource_size_t low_base = 0; resource_size_t bar_size; struct hv_pci_dev *hpdev; - struct list_head *iter; unsigned long flags; u64 bar_val; u32 command; @@ -1385,9 +1398,7 @@ static void prepopulate_bars(struct hv_pcibus_device *hbus) /* Pick addresses for the BARs. */ do { - list_for_each(iter, &hbus->children) { - hpdev = container_of(iter, struct hv_pci_dev, - list_entry); + list_for_each_entry(hpdev, &hbus->children, list_entry) { for (i = 0; i < 6; i++) { bar_val = hpdev->probed_bar[i]; if (bar_val == 0) @@ -1508,19 +1519,6 @@ static void q_resource_requirements(void *context, struct pci_response *resp, complete(&completion->host_event); } -static void get_pcichild(struct hv_pci_dev *hpdev, - enum hv_pcidev_ref_reason reason) -{ - refcount_inc(&hpdev->refs); -} - -static void put_pcichild(struct hv_pci_dev *hpdev, - enum hv_pcidev_ref_reason reason) -{ - if (refcount_dec_and_test(&hpdev->refs)) - kfree(hpdev); -} - /** * new_pcichild_device() - Create a new child device * @hbus: The internal struct tracking this root PCI bus. @@ -1568,24 +1566,14 @@ static struct hv_pci_dev *new_pcichild_device(struct hv_pcibus_device *hbus, if (ret) goto error; - wait_for_completion(&comp_pkt.host_event); + if (wait_for_response(hbus->hdev, &comp_pkt.host_event)) + goto error; hpdev->desc = *desc; refcount_set(&hpdev->refs, 1); - get_pcichild(hpdev, hv_pcidev_ref_childlist); + get_pcichild(hpdev); spin_lock_irqsave(&hbus->device_list_lock, flags); - /* - * When a device is being added to the bus, we set the PCI domain - * number to be the device serial number, which is non-zero and - * unique on the same VM. The serial numbers start with 1, and - * increase by 1 for each device. So device names including this - * can have shorter names than based on the bus instance UUID. - * Only the first device serial number is used for domain, so the - * domain number will not change after the first device is added. - */ - if (list_empty(&hbus->children)) - hbus->sysdata.domain = desc->ser; list_add_tail(&hpdev->list_entry, &hbus->children); spin_unlock_irqrestore(&hbus->device_list_lock, flags); return hpdev; @@ -1618,7 +1606,7 @@ static struct hv_pci_dev *get_pcichild_wslot(struct hv_pcibus_device *hbus, list_for_each_entry(iter, &hbus->children, list_entry) { if (iter->desc.win_slot.slot == wslot) { hpdev = iter; - get_pcichild(hpdev, hv_pcidev_ref_by_slot); + get_pcichild(hpdev); break; } } @@ -1654,7 +1642,6 @@ static void pci_devices_present_work(struct work_struct *work) { u32 child_no; bool found; - struct list_head *iter; struct pci_function_description *new_desc; struct hv_pci_dev *hpdev; struct hv_pcibus_device *hbus; @@ -1691,10 +1678,8 @@ static void pci_devices_present_work(struct work_struct *work) /* First, mark all existing children as reported missing. */ spin_lock_irqsave(&hbus->device_list_lock, flags); - list_for_each(iter, &hbus->children) { - hpdev = container_of(iter, struct hv_pci_dev, - list_entry); - hpdev->reported_missing = true; + list_for_each_entry(hpdev, &hbus->children, list_entry) { + hpdev->reported_missing = true; } spin_unlock_irqrestore(&hbus->device_list_lock, flags); @@ -1704,11 +1689,8 @@ static void pci_devices_present_work(struct work_struct *work) new_desc = &dr->func[child_no]; spin_lock_irqsave(&hbus->device_list_lock, flags); - list_for_each(iter, &hbus->children) { - hpdev = container_of(iter, struct hv_pci_dev, - list_entry); - if ((hpdev->desc.win_slot.slot == - new_desc->win_slot.slot) && + list_for_each_entry(hpdev, &hbus->children, list_entry) { + if ((hpdev->desc.win_slot.slot == new_desc->win_slot.slot) && (hpdev->desc.v_id == new_desc->v_id) && (hpdev->desc.d_id == new_desc->d_id) && (hpdev->desc.ser == new_desc->ser)) { @@ -1730,12 +1712,10 @@ static void pci_devices_present_work(struct work_struct *work) spin_lock_irqsave(&hbus->device_list_lock, flags); do { found = false; - list_for_each(iter, &hbus->children) { - hpdev = container_of(iter, struct hv_pci_dev, - list_entry); + list_for_each_entry(hpdev, &hbus->children, list_entry) { if (hpdev->reported_missing) { found = true; - put_pcichild(hpdev, hv_pcidev_ref_childlist); + put_pcichild(hpdev); list_move_tail(&hpdev->list_entry, &removed); break; } @@ -1748,7 +1728,7 @@ static void pci_devices_present_work(struct work_struct *work) hpdev = list_first_entry(&removed, struct hv_pci_dev, list_entry); list_del(&hpdev->list_entry); - put_pcichild(hpdev, hv_pcidev_ref_initial); + put_pcichild(hpdev); } switch (hbus->state) { @@ -1883,8 +1863,8 @@ static void hv_eject_device_work(struct work_struct *work) sizeof(*ejct_pkt), (unsigned long)&ctxt.pkt, VM_PKT_DATA_INBAND, 0); - put_pcichild(hpdev, hv_pcidev_ref_childlist); - put_pcichild(hpdev, hv_pcidev_ref_pnp); + put_pcichild(hpdev); + put_pcichild(hpdev); put_hvpcibus(hpdev->hbus); } @@ -1899,7 +1879,7 @@ static void hv_eject_device_work(struct work_struct *work) static void hv_pci_eject_device(struct hv_pci_dev *hpdev) { hpdev->state = hv_pcichild_ejecting; - get_pcichild(hpdev, hv_pcidev_ref_pnp); + get_pcichild(hpdev); INIT_WORK(&hpdev->wrk, hv_eject_device_work); get_hvpcibus(hpdev->hbus); queue_work(hpdev->hbus->wq, &hpdev->wrk); @@ -1999,8 +1979,7 @@ static void hv_pci_onchannelcallback(void *context) dev_message->wslot.slot); if (hpdev) { hv_pci_eject_device(hpdev); - put_pcichild(hpdev, - hv_pcidev_ref_by_slot); + put_pcichild(hpdev); } break; @@ -2069,15 +2048,16 @@ static int hv_pci_protocol_negotiation(struct hv_device *hdev) sizeof(struct pci_version_request), (unsigned long)pkt, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (!ret) + ret = wait_for_response(hdev, &comp_pkt.host_event); + if (ret) { dev_err(&hdev->device, - "PCI Pass-through VSP failed sending version reqquest: %#x", + "PCI Pass-through VSP failed to request version: %d", ret); goto exit; } - wait_for_completion(&comp_pkt.host_event); - if (comp_pkt.completion_status >= 0) { pci_protocol_version = pci_protocol_versions[i]; dev_info(&hdev->device, @@ -2286,11 +2266,12 @@ static int hv_pci_enter_d0(struct hv_device *hdev) ret = vmbus_sendpacket(hdev->channel, d0_entry, sizeof(*d0_entry), (unsigned long)pkt, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (!ret) + ret = wait_for_response(hdev, &comp_pkt.host_event); + if (ret) goto exit; - wait_for_completion(&comp_pkt.host_event); - if (comp_pkt.completion_status < 0) { dev_err(&hdev->device, "PCI Pass-through VSP failed D0 Entry with status %x\n", @@ -2330,11 +2311,10 @@ static int hv_pci_query_relations(struct hv_device *hdev) ret = vmbus_sendpacket(hdev->channel, &message, sizeof(message), 0, VM_PKT_DATA_INBAND, 0); - if (ret) - return ret; + if (!ret) + ret = wait_for_response(hdev, &comp); - wait_for_completion(&comp); - return 0; + return ret; } /** @@ -2398,17 +2378,17 @@ static int hv_send_resources_allocated(struct hv_device *hdev) PCI_RESOURCES_ASSIGNED2; res_assigned2->wslot.slot = hpdev->desc.win_slot.slot; } - put_pcichild(hpdev, hv_pcidev_ref_by_slot); + put_pcichild(hpdev); ret = vmbus_sendpacket(hdev->channel, &pkt->message, size_res, (unsigned long)pkt, VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + if (!ret) + ret = wait_for_response(hdev, &comp_pkt.host_event); if (ret) break; - wait_for_completion(&comp_pkt.host_event); - if (comp_pkt.completion_status < 0) { ret = -EPROTO; dev_err(&hdev->device, @@ -2446,7 +2426,7 @@ static int hv_send_resources_released(struct hv_device *hdev) pkt.message_type.type = PCI_RESOURCES_RELEASED; pkt.wslot.slot = hpdev->desc.win_slot.slot; - put_pcichild(hpdev, hv_pcidev_ref_by_slot); + put_pcichild(hpdev); ret = vmbus_sendpacket(hdev->channel, &pkt, sizeof(pkt), 0, VM_PKT_DATA_INBAND, 0); @@ -2459,12 +2439,12 @@ static int hv_send_resources_released(struct hv_device *hdev) static void get_hvpcibus(struct hv_pcibus_device *hbus) { - atomic_inc(&hbus->remove_lock); + refcount_inc(&hbus->remove_lock); } static void put_hvpcibus(struct hv_pcibus_device *hbus) { - if (atomic_dec_and_test(&hbus->remove_lock)) + if (refcount_dec_and_test(&hbus->remove_lock)) complete(&hbus->remove_event); } @@ -2508,7 +2488,7 @@ static int hv_pci_probe(struct hv_device *hdev, hdev->dev_instance.b[8] << 8; hbus->hdev = hdev; - atomic_inc(&hbus->remove_lock); + refcount_set(&hbus->remove_lock, 1); INIT_LIST_HEAD(&hbus->children); INIT_LIST_HEAD(&hbus->dr_list); INIT_LIST_HEAD(&hbus->resources_for_children); diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c index 5d4dccfc9d81..23e270839e6a 100644 --- a/drivers/pci/host/pci-mvebu.c +++ b/drivers/pci/host/pci-mvebu.c @@ -21,6 +21,8 @@ #include <linux/of_pci.h> #include <linux/of_platform.h> +#include "../pci.h" + /* * PCIe unit register offsets. */ diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c index dd4f1a6b57c5..326171cb1a97 100644 --- a/drivers/pci/host/pci-rcar-gen2.c +++ b/drivers/pci/host/pci-rcar-gen2.c @@ -21,6 +21,8 @@ #include <linux/sizes.h> #include <linux/slab.h> +#include "../pci.h" + /* AHB-PCI Bridge PCI communication registers */ #define RCAR_AHBPCI_PCICOM_OFFSET 0x800 diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c index 389e74be846c..f4f53d092e00 100644 --- a/drivers/pci/host/pci-tegra.c +++ b/drivers/pci/host/pci-tegra.c @@ -40,6 +40,8 @@ #include <soc/tegra/cpuidle.h> #include <soc/tegra/pmc.h> +#include "../pci.h" + #define INT_PCI_MSI_NR (8 * 32) /* register definitions */ diff --git a/drivers/pci/host/pci-v3-semi.c b/drivers/pci/host/pci-v3-semi.c index 0a4dea796663..68b8bfbdb867 100644 --- a/drivers/pci/host/pci-v3-semi.c +++ b/drivers/pci/host/pci-v3-semi.c @@ -33,6 +33,8 @@ #include <linux/regmap.h> #include <linux/clk.h> +#include "../pci.h" + #define V3_PCI_VENDOR 0x00000000 #define V3_PCI_DEVICE 0x00000002 #define V3_PCI_CMD 0x00000004 @@ -791,7 +793,8 @@ static int v3_pci_probe(struct platform_device *pdev) if (IS_ERR(v3->config_base)) return PTR_ERR(v3->config_base); - ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &io_base); + ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res, + &io_base); if (ret) return ret; diff --git a/drivers/pci/host/pci-versatile.c b/drivers/pci/host/pci-versatile.c index 5b3876f5312b..994f32061b32 100644 --- a/drivers/pci/host/pci-versatile.c +++ b/drivers/pci/host/pci-versatile.c @@ -15,6 +15,8 @@ #include <linux/pci.h> #include <linux/platform_device.h> +#include "../pci.h" + static void __iomem *versatile_pci_base; static void __iomem *versatile_cfg_base[2]; @@ -64,11 +66,10 @@ static int versatile_pci_parse_request_of_pci_ranges(struct device *dev, struct list_head *res) { int err, mem = 1, res_valid = 0; - struct device_node *np = dev->of_node; resource_size_t iobase; struct resource_entry *win, *tmp; - err = of_pci_get_host_bridge_resources(np, 0, 0xff, res, &iobase); + err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, res, &iobase); if (err) return err; diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c index 0a0d7ee6d3c9..d854d67e873c 100644 --- a/drivers/pci/host/pci-xgene.c +++ b/drivers/pci/host/pci-xgene.c @@ -22,6 +22,8 @@ #include <linux/platform_device.h> #include <linux/slab.h> +#include "../pci.h" + #define PCIECORE_CTLANDSTATUS 0x50 #define PIM1_1L 0x80 #define IBAR2 0x98 @@ -632,7 +634,8 @@ static int xgene_pcie_probe(struct platform_device *pdev) if (ret) return ret; - ret = of_pci_get_host_bridge_resources(dn, 0, 0xff, &res, &iobase); + ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &res, + &iobase); if (ret) return ret; diff --git a/drivers/pci/host/pcie-altera.c b/drivers/pci/host/pcie-altera.c index a6af62e0256d..7d05e51205b3 100644 --- a/drivers/pci/host/pcie-altera.c +++ b/drivers/pci/host/pcie-altera.c @@ -17,6 +17,8 @@ #include <linux/platform_device.h> #include <linux/slab.h> +#include "../pci.h" + #define RP_TX_REG0 0x2000 #define RP_TX_REG1 0x2004 #define RP_TX_CNTRL 0x2008 @@ -488,11 +490,10 @@ static int altera_pcie_parse_request_of_pci_ranges(struct altera_pcie *pcie) { int err, res_valid = 0; struct device *dev = &pcie->pdev->dev; - struct device_node *np = dev->of_node; struct resource_entry *win; - err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pcie->resources, - NULL); + err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, + &pcie->resources, NULL); if (err) return err; diff --git a/drivers/pci/host/pcie-iproc-platform.c b/drivers/pci/host/pcie-iproc-platform.c index e764a2a2693c..f30f5f3fb5c1 100644 --- a/drivers/pci/host/pcie-iproc-platform.c +++ b/drivers/pci/host/pcie-iproc-platform.c @@ -16,6 +16,7 @@ #include <linux/of_platform.h> #include <linux/phy/phy.h> +#include "../pci.h" #include "pcie-iproc.h" static const struct of_device_id iproc_pcie_of_match_table[] = { @@ -99,8 +100,8 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev) pcie->phy = NULL; } - ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &resources, - &iobase); + ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &resources, + &iobase); if (ret) { dev_err(dev, "unable to get PCI host bridge resources\n"); return ret; diff --git a/drivers/pci/host/pcie-mediatek.c b/drivers/pci/host/pcie-mediatek.c index a8b20c5012a9..0baabe30858f 100644 --- a/drivers/pci/host/pcie-mediatek.c +++ b/drivers/pci/host/pcie-mediatek.c @@ -11,8 +11,10 @@ #include <linux/delay.h> #include <linux/iopoll.h> #include <linux/irq.h> +#include <linux/irqchip/chained_irq.h> #include <linux/irqdomain.h> #include <linux/kernel.h> |