diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-07 12:45:58 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-07 12:45:58 -0700 |
commit | 3a3869f1c443383ef8354ffa0e5fb8df65d8b549 (patch) | |
tree | 7972a4444f04a91f4baab5896df33d4e55d9909d /drivers/pci/dwc/pcie-designware-host.c | |
parent | 3036bc45364f98515a2c446d7fac2c34dcfbeff4 (diff) | |
parent | 488ad6d3678beee65bcd74e6a9764bd7cee9d3d3 (diff) |
Merge tag 'pci-v4.18-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas:
- unify AER decoding for native and ACPI CPER sources (Alexandru
Gagniuc)
- add TLP header info to AER tracepoint (Thomas Tai)
- add generic pcie_wait_for_link() interface (Oza Pawandeep)
- handle AER ERR_FATAL by removing and re-enumerating devices, as
Downstream Port Containment does (Oza Pawandeep)
- factor out common code between AER and DPC recovery (Oza Pawandeep)
- stop triggering DPC for ERR_NONFATAL errors (Oza Pawandeep)
- share ERR_FATAL recovery path between AER and DPC (Oza Pawandeep)
- disable ASPM L1.2 substate if we don't have LTR (Bjorn Helgaas)
- respect platform ownership of LTR (Bjorn Helgaas)
- clear interrupt status in top half to avoid interrupt storm (Oza
Pawandeep)
- neaten pci=earlydump output (Andy Shevchenko)
- avoid errors when extended config space inaccessible (Gilles Buloz)
- prevent sysfs disable of device while driver attached (Christoph
Hellwig)
- use core interface to report PCIe link properties in bnx2x, bnxt_en,
cxgb4, ixgbe (Bjorn Helgaas)
- remove unused pcie_get_minimum_link() (Bjorn Helgaas)
- fix use-before-set error in ibmphp (Dan Carpenter)
- fix pciehp timeouts caused by Command Completed errata (Bjorn
Helgaas)
- fix refcounting in pnv_php hotplug (Julia Lawall)
- clear pciehp Presence Detect and Data Link Layer Status Changed on
resume so we don't miss hotplug events (Mika Westerberg)
- only request pciehp control if we support it, so platform can use
ACPI hotplug otherwise (Mika Westerberg)
- convert SHPC to be builtin only (Mika Westerberg)
- request SHPC control via _OSC if we support it (Mika Westerberg)
- simplify SHPC handoff from firmware (Mika Westerberg)
- fix an SHPC quirk that mistakenly included *all* AMD bridges as well
as devices from any vendor with device ID 0x7458 (Bjorn Helgaas)
- assign a bus number even to non-native hotplug bridges to leave
space for acpiphp additions, to fix a common Thunderbolt xHCI
hot-add failure (Mika Westerberg)
- keep acpiphp from scanning native hotplug bridges, to fix common
Thunderbolt hot-add failures (Mika Westerberg)
- improve "partially hidden behind bridge" messages from core (Mika
Westerberg)
- add macros for PCIe Link Control 2 register (Frederick Lawler)
- replace IB/hfi1 custom macros with PCI core versions (Frederick
Lawler)
- remove dead microblaze and xtensa code (Bjorn Helgaas)
- use dev_printk() when possible in xtensa and mips (Bjorn Helgaas)
- remove unused pcie_port_acpi_setup() and portdrv_acpi.c (Bjorn
Helgaas)
- add managed interface to get PCI host bridge resources from OF (Jan
Kiszka)
- add support for unbinding generic PCI host controller (Jan Kiszka)
- fix memory leaks when unbinding generic PCI host controller (Jan
Kiszka)
- request legacy VGA framebuffer only for VGA devices to avoid false
device conflicts (Bjorn Helgaas)
- turn on PCI_COMMAND_IO & PCI_COMMAND_MEMORY in pci_enable_device()
like everybody else, not in pcibios_fixup_bus() (Bjorn Helgaas)
- add generic enable function for simple SR-IOV hardware (Alexander
Duyck)
- use generic SR-IOV enable for ena, nvme (Alexander Duyck)
- add ACS quirk for Intel 7th & 8th Gen mobile (Alex Williamson)
- add ACS quirk for Intel 300 series (Mika Westerberg)
- enable register clock for Armada 7K/8K (Gregory CLEMENT)
- reduce Keystone "link already up" log level (Fabio Estevam)
- move private DT functions to drivers/pci/ (Rob Herring)
- factor out dwc CONFIG_PCI Kconfig dependencies (Rob Herring)
- add DesignWare support to the endpoint test driver (Gustavo
Pimentel)
- add DesignWare support for endpoint mode (Gustavo Pimentel)
- use devm_ioremap_resource() instead of devm_ioremap() in dra7xx and
artpec6 (Gustavo Pimentel)
- fix Qualcomm bitwise NOT issue (Dan Carpenter)
- add Qualcomm runtime PM support (Srinivas Kandagatla)
- fix DesignWare enumeration below bridges (Koen Vandeputte)
- use usleep() instead of mdelay() in endpoint test (Jia-Ju Bai)
- add configfs entries for pci_epf_driver device IDs (Kishon Vijay
Abraham I)
- clean up pci_endpoint_test driver (Gustavo Pimentel)
- update Layerscape maintainer email addresses (Minghuan Lian)
- add COMPILE_TEST to improve build test coverage (Rob Herring)
- fix Hyper-V bus registration failure caused by domain/serial number
confusion (Sridhar Pitchai)
- improve Hyper-V refcounting and coding style (Stephen Hemminger)
- avoid potential Hyper-V hang waiting for a response that will never
come (Dexuan Cui)
- implement Mediatek chained IRQ handling (Honghui Zhang)
- fix vendor ID & class type for Mediatek MT7622 (Honghui Zhang)
- add Mobiveil PCIe host controller driver (Subrahmanya Lingappa)
- add Mobiveil MSI support (Subrahmanya Lingappa)
- clean up clocks, MSI, IRQ mappings in R-Car probe failure paths
(Marek Vasut)
- poll more frequently (5us vs 5ms) while waiting for R-Car data link
active (Marek Vasut)
- use generic OF parsing interface in R-Car (Vladimir Zapolskiy)
- add R-Car V3H (R8A77980) "compatible" string (Sergei Shtylyov)
- add R-Car gen3 PHY support (Sergei Shtylyov)
- improve R-Car PHYRDY polling (Sergei Shtylyov)
- clean up R-Car macros (Marek Vasut)
- use runtime PM for R-Car controller clock (Dien Pham)
- update arm64 defconfig for Rockchip (Shawn Lin)
- refactor Rockchip code to facilitate both root port and endpoint
mode (Shawn Lin)
- add Rockchip endpoint mode driver (Shawn Lin)
- support VMD "membar shadow" feature (Jon Derrick)
- support VMD bus number offsets (Jon Derrick)
- add VMD "no AER source ID" quirk for more device IDs (Jon Derrick)
- remove unnecessary host controller CONFIG_PCIEPORTBUS Kconfig
selections (Bjorn Helgaas)
- clean up quirks.c organization and whitespace (Bjorn Helgaas)
* tag 'pci-v4.18-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (144 commits)
PCI/AER: Replace struct pcie_device with pci_dev
PCI/AER: Remove unused parameters
PCI: qcom: Include gpio/consumer.h
PCI: Improve "partially hidden behind bridge" log message
PCI: Improve pci_scan_bridge() and pci_scan_bridge_extend() doc
PCI: Move resource distribution for single bridge outside loop
PCI: Account for all bridges on bus when distributing bus numbers
ACPI / hotplug / PCI: Drop unnecessary parentheses
ACPI / hotplug / PCI: Mark stale PCI devices disconnected
ACPI / hotplug / PCI: Don't scan bridges managed by native hotplug
PCI: hotplug: Add hotplug_is_native()
PCI: shpchp: Add shpchp_is_native()
PCI: shpchp: Fix AMD POGO identification
PCI: mobiveil: Add MSI support
PCI: mobiveil: Add Mobiveil PCIe Host Bridge IP driver
PCI/AER: Decode Error Source Requester ID
PCI/AER: Remove aer_recover_work_func() forward declaration
PCI/DPC: Use the generic pcie_do_fatal_recovery() path
PCI/AER: Pass service type to pcie_do_fatal_recovery()
PCI/DPC: Disable ERR_NONFATAL handling by DPC
...
Diffstat (limited to 'drivers/pci/dwc/pcie-designware-host.c')
-rw-r--r-- | drivers/pci/dwc/pcie-designware-host.c | 80 |
1 files changed, 45 insertions, 35 deletions
diff --git a/drivers/pci/dwc/pcie-designware-host.c b/drivers/pci/dwc/pcie-designware-host.c index 6c409079d514..cba1432e395d 100644 --- a/drivers/pci/dwc/pcie-designware-host.c +++ b/drivers/pci/dwc/pcie-designware-host.c @@ -15,6 +15,7 @@ #include <linux/pci_regs.h> #include <linux/platform_device.h> +#include "../pci.h" #include "pcie-designware.h" static struct pci_ops dw_pcie_ops; @@ -83,18 +84,23 @@ irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL; for (i = 0; i < num_ctrls; i++) { - dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_STATUS + i * 12, 4, - &val); + dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_STATUS + + (i * MSI_REG_CTRL_BLOCK_SIZE), + 4, &val); if (!val) continue; ret = IRQ_HANDLED; pos = 0; - while ((pos = find_next_bit((unsigned long *) &val, 32, - pos)) != 32) { - irq = irq_find_mapping(pp->irq_domain, i * 32 + pos); + while ((pos = find_next_bit((unsigned long *) &val, + MAX_MSI_IRQS_PER_CTRL, + pos)) != MAX_MSI_IRQS_PER_CTRL) { + irq = irq_find_mapping(pp->irq_domain, + (i * MAX_MSI_IRQS_PER_CTRL) + + pos); generic_handle_irq(irq); - dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + i * 12, + dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + + (i * MSI_REG_CTRL_BLOCK_SIZE), 4, 1 << pos); pos++; } @@ -157,9 +163,9 @@ static void dw_pci_bottom_mask(struct irq_data *data) if (pp->ops->msi_clear_irq) { pp->ops->msi_clear_irq(pp, data->hwirq); } else { - ctrl = data->hwirq / 32; - res = ctrl * 12; - bit = data->hwirq % 32; + ctrl = data->hwirq / MAX_MSI_IRQS_PER_CTRL; + res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; + bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL; pp->irq_status[ctrl] &= ~(1 << bit); dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, @@ -180,9 +186,9 @@ static void dw_pci_bottom_unmask(struct irq_data *data) if (pp->ops->msi_set_irq) { pp->ops->msi_set_irq(pp, data->hwirq); } else { - ctrl = data->hwirq / 32; - res = ctrl * 12; - bit = data->hwirq % 32; + ctrl = data->hwirq / MAX_MSI_IRQS_PER_CTRL; + res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; + bit = data->hwirq % MAX_MSI_IRQS_PER_CTRL; pp->irq_status[ctrl] |= 1 << bit; dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, @@ -248,8 +254,10 @@ static void dw_pcie_irq_domain_free(struct irq_domain *domain, unsigned long flags; raw_spin_lock_irqsave(&pp->lock, flags); + bitmap_release_region(pp->msi_irq_in_use, data->hwirq, order_base_2(nr_irqs)); + raw_spin_unlock_irqrestore(&pp->lock, flags); } @@ -266,7 +274,7 @@ int dw_pcie_allocate_domains(struct pcie_port *pp) pp->irq_domain = irq_domain_create_linear(fwnode, pp->num_vectors, &dw_pcie_msi_domain_ops, pp); if (!pp->irq_domain) { - dev_err(pci->dev, "failed to create IRQ domain\n"); + dev_err(pci->dev, "Failed to create IRQ domain\n"); return -ENOMEM; } @@ -274,7 +282,7 @@ int dw_pcie_allocate_domains(struct pcie_port *pp) &dw_pcie_msi_domain_info, pp->irq_domain); if (!pp->msi_domain) { - dev_err(pci->dev, "failed to create MSI domain\n"); + dev_err(pci->dev, "Failed to create MSI domain\n"); irq_domain_remove(pp->irq_domain); return -ENOMEM; } @@ -301,13 +309,13 @@ void dw_pcie_msi_init(struct pcie_port *pp) page = alloc_page(GFP_KERNEL); pp->msi_data = dma_map_page(dev, page, 0, PAGE_SIZE, DMA_FROM_DEVICE); if (dma_mapping_error(dev, pp->msi_data)) { - dev_err(dev, "failed to map MSI data\n"); + dev_err(dev, "Failed to map MSI data\n"); __free_page(page); return; } msi_target = (u64)pp->msi_data; - /* program the msi_data */ + /* Program the msi_data */ dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_LO, 4, lower_32_bits(msi_target)); dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_HI, 4, @@ -330,19 +338,19 @@ int dw_pcie_host_init(struct pcie_port *pp) cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); if (cfg_res) { - pp->cfg0_size = resource_size(cfg_res) / 2; - pp->cfg1_size = resource_size(cfg_res) / 2; + pp->cfg0_size = resource_size(cfg_res) >> 1; + pp->cfg1_size = resource_size(cfg_res) >> 1; pp->cfg0_base = cfg_res->start; pp->cfg1_base = cfg_res->start + pp->cfg0_size; } else if (!pp->va_cfg0_base) { - dev_err(dev, "missing *config* reg space\n"); + dev_err(dev, "Missing *config* reg space\n"); } bridge = pci_alloc_host_bridge(0); if (!bridge) return -ENOMEM; - ret = of_pci_get_host_bridge_resources(np, 0, 0xff, + ret = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &bridge->windows, &pp->io_base); if (ret) return ret; @@ -357,7 +365,7 @@ int dw_pcie_host_init(struct pcie_port *pp) case IORESOURCE_IO: ret = pci_remap_iospace(win->res, pp->io_base); if (ret) { - dev_warn(dev, "error %d: failed to map resource %pR\n", + dev_warn(dev, "Error %d: failed to map resource %pR\n", ret, win->res); resource_list_destroy_entry(win); } else { @@ -375,8 +383,8 @@ int dw_pcie_host_init(struct pcie_port *pp) break; case 0: pp->cfg = win->res; - pp->cfg0_size = resource_size(pp->cfg) / 2; - pp->cfg1_size = resource_size(pp->cfg) / 2; + pp->cfg0_size = resource_size(pp->cfg) >> 1; + pp->cfg1_size = resource_size(pp->cfg) >> 1; pp->cfg0_base = pp->cfg->start; pp->cfg1_base = pp->cfg->start + pp->cfg0_size; break; @@ -391,7 +399,7 @@ int dw_pcie_host_init(struct pcie_port *pp) pp->cfg->start, resource_size(pp->cfg)); if (!pci->dbi_base) { - dev_err(dev, "error with ioremap\n"); + dev_err(dev, "Error with ioremap\n"); ret = -ENOMEM; goto error; } @@ -403,7 +411,7 @@ int dw_pcie_host_init(struct pcie_port *pp) pp->va_cfg0_base = devm_pci_remap_cfgspace(dev, pp->cfg0_base, pp->cfg0_size); if (!pp->va_cfg0_base) { - dev_err(dev, "error with ioremap in function\n"); + dev_err(dev, "Error with ioremap in function\n"); ret = -ENOMEM; goto error; } @@ -414,7 +422,7 @@ int dw_pcie_host_init(struct pcie_port *pp) pp->cfg1_base, pp->cfg1_size); if (!pp->va_cfg1_base) { - dev_err(dev, "error with ioremap\n"); + dev_err(dev, "Error with ioremap\n"); ret = -ENOMEM; goto error; } @@ -586,7 +594,7 @@ static int dw_pcie_valid_device(struct pcie_port *pp, struct pci_bus *bus, return 0; } - /* access only one slot on each root port */ + /* Access only one slot on each root port */ if (bus->number == pp->root_bus_nr && dev > 0) return 0; @@ -650,13 +658,15 @@ void dw_pcie_setup_rc(struct pcie_port *pp) /* Initialize IRQ Status array */ for (ctrl = 0; ctrl < num_ctrls; ctrl++) - dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + (ctrl * 12), 4, - &pp->irq_status[ctrl]); - /* setup RC BARs */ + dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + + (ctrl * MSI_REG_CTRL_BLOCK_SIZE), + 4, &pp->irq_status[ctrl]); + + /* Setup RC BARs */ dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_0, 0x00000004); dw_pcie_writel_dbi(pci, PCI_BASE_ADDRESS_1, 0x00000000); - /* setup interrupt pins */ + /* Setup interrupt pins */ dw_pcie_dbi_ro_wr_en(pci); val = dw_pcie_readl_dbi(pci, PCI_INTERRUPT_LINE); val &= 0xffff00ff; @@ -664,13 +674,13 @@ void dw_pcie_setup_rc(struct pcie_port *pp) dw_pcie_writel_dbi(pci, PCI_INTERRUPT_LINE, val); dw_pcie_dbi_ro_wr_dis(pci); - /* setup bus numbers */ + /* Setup bus numbers */ val = dw_pcie_readl_dbi(pci, PCI_PRIMARY_BUS); val &= 0xff000000; val |= 0x00ff0100; dw_pcie_writel_dbi(pci, PCI_PRIMARY_BUS, val); - /* setup command register */ + /* Setup command register */ val = dw_pcie_readl_dbi(pci, PCI_COMMAND); val &= 0xffff0000; val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | @@ -683,7 +693,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp) * we should not program the ATU here. */ if (!pp->ops->rd_other_conf) { - /* get iATU unroll support */ + /* Get iATU unroll support */ pci->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pci); dev_dbg(pci->dev, "iATU unroll: %s\n", pci->iatu_unroll_enabled ? "enabled" : "disabled"); @@ -701,7 +711,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp) /* Enable write permission for the DBI read-only register */ dw_pcie_dbi_ro_wr_en(pci); - /* program correct class for RC */ + /* Program correct class for RC */ dw_pcie_wr_own_conf(pp, PCI_CLASS_DEVICE, 2, PCI_CLASS_BRIDGE_PCI); /* Better disable write permission right after the update */ dw_pcie_dbi_ro_wr_dis(pci); |