Merge tag 'pci-v5.8-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas: "Enumeration: - Program MPS for RCiEP devices (Ashok Raj) - Fix pci_register_host_bridge() device_register() error handling (Rob Herring) - Fix pci_host_bridge struct device release/free handling (Rob Herring) Resource management: - Allow resizing BARs for devices on root bus (Ard Biesheuvel) Power management: - Reduce Thunderbolt resume time by working around devices that don't support DLL Link Active reporting (Mika Westerberg) - Work around a Pericom USB controller OHCI/EHCI PME# defect (Kai-Heng Feng) Virtualization: - Add ACS quirk for Intel Root Complex Integrated Endpoints (Ashok Raj) - Avoid FLR for AMD Starship USB 3.0 (Kevin Buettner) - Avoid FLR for AMD Matisse HD Audio & USB 3.0 (Marcos Scriven) Error handling: - Use only _OSC (not HEST FIRMWARE_FIRST) to determine AER ownership (Alexandru Gagniuc, Kuppuswamy Sathyanarayanan) - Reduce verbosity by logging only ACPI_NOTIFY_DISCONNECT_RECOVER events (Kuppuswamy Sathyanarayanan) - Don't enable AER by default in Kconfig (Bjorn Helgaas) Peer-to-peer DMA: - Add AMD Zen Raven and Renoir Root Ports to whitelist (Alex Deucher) ASPM: - Allow ASPM on links to PCIe-to-PCI/PCI-X Bridges (Kai-Heng Feng) Endpoint framework: - Fix DMA channel release in test (Kunihiko Hayashi) - Add page size as argument to pci_epc_mem_init() (Lad Prabhakar) - Add support to handle multiple base for mapping outbound memory (Lad Prabhakar) Generic host bridge driver: - Support building as module (Rob Herring) - Eliminate pci_host_common_probe wrappers (Rob Herring) Amlogic Meson PCIe controller driver: - Don't use FAST_LINK_MODE to set up link (Marc Zyngier) Broadcom STB PCIe controller driver: - Disable ASPM L0s if 'aspm-no-l0s' in DT (Jim Quinlan) - Fix clk_put() error (Jim Quinlan) - Fix window register offset (Jim Quinlan) - Assert fundamental reset on initialization (Nicolas Saenz Julienne) - Add notify xHCI reset property (Nicolas Saenz Julienne) - Add init routine for Raspberry Pi 4 VL805 USB controller (Nicolas Saenz Julienne) - Sync with Raspberry Pi 4 firmware for VL805 initialization (Nicolas Saenz Julienne) Cadence PCIe controller driver: - Remove "cdns,max-outbound-regions" DT property (replaced by "ranges") (Kishon Vijay Abraham I) - Read 32-bit (not 16-bit) Vendor ID/Device ID property from DT (Kishon Vijay Abraham I) Marvell Aardvark PCIe controller driver: - Improve link training (Marek Behún) - Add PHY support (Marek Behún) - Add "phys", "max-link-speed", "reset-gpios" to dt-binding (Marek Behún) - Train link immediately after enabling training to work around detection issues with some cards (Pali Rohár) - Issue PERST via GPIO to work around detection issues (Pali Rohár) - Don't blindly enable ASPM L0s (Pali Rohár) - Replace custom macros by standard linux/pci_regs.h macros (Pali Rohár) Microsoft Hyper-V host bridge driver: - Fix probe failure path to release resource (Wei Hu) - Retry PCI bus D0 entry on invalid device state for kdump (Wei Hu) Renesas R-Car PCIe controller driver: - Fix incorrect programming of OB windows (Andrew Murray) - Add suspend/resume (Kazufumi Ikeda) - Rename pcie-rcar.c to pcie-rcar-host.c (Lad Prabhakar) - Add endpoint controller driver (Lad Prabhakar) - Fix PCIEPAMR mask calculation (Lad Prabhakar) - Add r8a77961 to DT binding (Yoshihiro Shimoda) Socionext UniPhier Pro5 controller driver: - Add endpoint controller driver (Kunihiko Hayashi) Synopsys DesignWare PCIe controller driver: - Program outbound ATU upper limit register (Alan Mikhak) - Fix inner MSI IRQ domain registration (Marc Zyngier) Miscellaneous: - Check for platform_get_irq() failure consistently (negative return means failure) (Aman Sharma) - Fix several runtime PM get/put imbalances (Dinghao Liu) - Use flexible-array and struct_size() helpers for code cleanup (Gustavo A. R. Silva) - Update & fix issues in bridge emulation of PCIe registers (Jon Derrick) - Add macros for bridge window names (PCI_BRIDGE_IO_WINDOW, etc) (Krzysztof Wilczyński) - Work around Intel PCH MROMs that have invalid BARs (Xiaochun Lee)" * tag 'pci-v5.8-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (100 commits) PCI: uniphier: Add Socionext UniPhier Pro5 PCIe endpoint controller driver PCI: Add ACS quirk for Intel Root Complex Integrated Endpoints PCI/DPC: Print IRQ number used by port PCI/AER: Use "aer" variable for capability offset PCI/AER: Remove redundant dev->aer_cap checks PCI/AER: Remove redundant pci_is_pcie() checks PCI/AER: Remove HEST/FIRMWARE_FIRST parsing for AER ownership PCI: tegra: Fix runtime PM imbalance on error PCI: vmd: Filter resource type bits from shadow register PCI: tegra194: Fix runtime PM imbalance on error dt-bindings: PCI: Add UniPhier PCIe endpoint controller description PCI: hv: Use struct_size() helper PCI: Rename _DSM constants to align with spec PCI: Avoid FLR for AMD Starship USB 3.0 PCI: Avoid FLR for AMD Matisse HD Audio & USB 3.0 x86/PCI: Drop unused xen_register_pirq() gsi_override parameter PCI: dwc: Use private data pointer of "struct irq_domain" to get pcie_port PCI: amlogic: meson: Don't use FAST_LINK_MODE to set up link PCI: dwc: Fix inner MSI IRQ domain registration PCI: dwc: pci-dra7xx: Use devm_platform_ioremap_resource_byname() ...
This commit is contained in:
@@ -480,6 +480,9 @@ struct hv_pcibus_device {
|
||||
|
||||
struct workqueue_struct *wq;
|
||||
|
||||
/* Highest slot of child device with resources allocated */
|
||||
int wslot_res_allocated;
|
||||
|
||||
/* hypercall arg, must not cross page boundary */
|
||||
struct hv_retarget_device_interrupt retarget_msi_interrupt_params;
|
||||
|
||||
@@ -2210,10 +2213,8 @@ static void hv_pci_devices_present(struct hv_pcibus_device *hbus,
|
||||
struct hv_dr_state *dr;
|
||||
int i;
|
||||
|
||||
dr = kzalloc(offsetof(struct hv_dr_state, func) +
|
||||
(sizeof(struct hv_pcidev_description) *
|
||||
(relations->device_count)), GFP_NOWAIT);
|
||||
|
||||
dr = kzalloc(struct_size(dr, func, relations->device_count),
|
||||
GFP_NOWAIT);
|
||||
if (!dr)
|
||||
return;
|
||||
|
||||
@@ -2247,10 +2248,8 @@ static void hv_pci_devices_present2(struct hv_pcibus_device *hbus,
|
||||
struct hv_dr_state *dr;
|
||||
int i;
|
||||
|
||||
dr = kzalloc(offsetof(struct hv_dr_state, func) +
|
||||
(sizeof(struct hv_pcidev_description) *
|
||||
(relations->device_count)), GFP_NOWAIT);
|
||||
|
||||
dr = kzalloc(struct_size(dr, func, relations->device_count),
|
||||
GFP_NOWAIT);
|
||||
if (!dr)
|
||||
return;
|
||||
|
||||
@@ -2444,9 +2443,8 @@ static void hv_pci_onchannelcallback(void *context)
|
||||
|
||||
bus_rel = (struct pci_bus_relations *)buffer;
|
||||
if (bytes_recvd <
|
||||
offsetof(struct pci_bus_relations, func) +
|
||||
(sizeof(struct pci_function_description) *
|
||||
(bus_rel->device_count))) {
|
||||
struct_size(bus_rel, func,
|
||||
bus_rel->device_count)) {
|
||||
dev_err(&hbus->hdev->device,
|
||||
"bus relations too small\n");
|
||||
break;
|
||||
@@ -2459,9 +2457,8 @@ static void hv_pci_onchannelcallback(void *context)
|
||||
|
||||
bus_rel2 = (struct pci_bus_relations2 *)buffer;
|
||||
if (bytes_recvd <
|
||||
offsetof(struct pci_bus_relations2, func) +
|
||||
(sizeof(struct pci_function_description2) *
|
||||
(bus_rel2->device_count))) {
|
||||
struct_size(bus_rel2, func,
|
||||
bus_rel2->device_count)) {
|
||||
dev_err(&hbus->hdev->device,
|
||||
"bus relations v2 too small\n");
|
||||
break;
|
||||
@@ -2748,6 +2745,8 @@ static void hv_free_config_window(struct hv_pcibus_device *hbus)
|
||||
vmbus_free_mmio(hbus->mem_config->start, PCI_CONFIG_MMIO_LENGTH);
|
||||
}
|
||||
|
||||
static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs);
|
||||
|
||||
/**
|
||||
* hv_pci_enter_d0() - Bring the "bus" into the D0 power state
|
||||
* @hdev: VMBus's tracking struct for this root PCI bus
|
||||
@@ -2760,8 +2759,10 @@ static int hv_pci_enter_d0(struct hv_device *hdev)
|
||||
struct pci_bus_d0_entry *d0_entry;
|
||||
struct hv_pci_compl comp_pkt;
|
||||
struct pci_packet *pkt;
|
||||
bool retry = true;
|
||||
int ret;
|
||||
|
||||
enter_d0_retry:
|
||||
/*
|
||||
* Tell the host that the bus is ready to use, and moved into the
|
||||
* powered-on state. This includes telling the host which region
|
||||
@@ -2788,6 +2789,38 @@ static int hv_pci_enter_d0(struct hv_device *hdev)
|
||||
if (ret)
|
||||
goto exit;
|
||||
|
||||
/*
|
||||
* In certain case (Kdump) the pci device of interest was
|
||||
* not cleanly shut down and resource is still held on host
|
||||
* side, the host could return invalid device status.
|
||||
* We need to explicitly request host to release the resource
|
||||
* and try to enter D0 again.
|
||||
*/
|
||||
if (comp_pkt.completion_status < 0 && retry) {
|
||||
retry = false;
|
||||
|
||||
dev_err(&hdev->device, "Retrying D0 Entry\n");
|
||||
|
||||
/*
|
||||
* Hv_pci_bus_exit() calls hv_send_resource_released()
|
||||
* to free up resources of its child devices.
|
||||
* In the kdump kernel we need to set the
|
||||
* wslot_res_allocated to 255 so it scans all child
|
||||
* devices to release resources allocated in the
|
||||
* normal kernel before panic happened.
|
||||
*/
|
||||
hbus->wslot_res_allocated = 255;
|
||||
|
||||
ret = hv_pci_bus_exit(hdev, true);
|
||||
|
||||
if (ret == 0) {
|
||||
kfree(pkt);
|
||||
goto enter_d0_retry;
|
||||
}
|
||||
dev_err(&hdev->device,
|
||||
"Retrying D0 failed with ret %d\n", ret);
|
||||
}
|
||||
|
||||
if (comp_pkt.completion_status < 0) {
|
||||
dev_err(&hdev->device,
|
||||
"PCI Pass-through VSP failed D0 Entry with status %x\n",
|
||||
@@ -2859,7 +2892,7 @@ static int hv_send_resources_allocated(struct hv_device *hdev)
|
||||
struct hv_pci_dev *hpdev;
|
||||
struct pci_packet *pkt;
|
||||
size_t size_res;
|
||||
u32 wslot;
|
||||
int wslot;
|
||||
int ret;
|
||||
|
||||
size_res = (hbus->protocol_version < PCI_PROTOCOL_VERSION_1_2)
|
||||
@@ -2912,6 +2945,8 @@ static int hv_send_resources_allocated(struct hv_device *hdev)
|
||||
comp_pkt.completion_status);
|
||||
break;
|
||||
}
|
||||
|
||||
hbus->wslot_res_allocated = wslot;
|
||||
}
|
||||
|
||||
kfree(pkt);
|
||||
@@ -2930,10 +2965,10 @@ static int hv_send_resources_released(struct hv_device *hdev)
|
||||
struct hv_pcibus_device *hbus = hv_get_drvdata(hdev);
|
||||
struct pci_child_message pkt;
|
||||
struct hv_pci_dev *hpdev;
|
||||
u32 wslot;
|
||||
int wslot;
|
||||
int ret;
|
||||
|
||||
for (wslot = 0; wslot < 256; wslot++) {
|
||||
for (wslot = hbus->wslot_res_allocated; wslot >= 0; wslot--) {
|
||||
hpdev = get_pcichild_wslot(hbus, wslot);
|
||||
if (!hpdev)
|
||||
continue;
|
||||
@@ -2948,8 +2983,12 @@ static int hv_send_resources_released(struct hv_device *hdev)
|
||||
VM_PKT_DATA_INBAND, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
hbus->wslot_res_allocated = wslot - 1;
|
||||
}
|
||||
|
||||
hbus->wslot_res_allocated = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3049,6 +3088,7 @@ static int hv_pci_probe(struct hv_device *hdev,
|
||||
if (!hbus)
|
||||
return -ENOMEM;
|
||||
hbus->state = hv_pcibus_init;
|
||||
hbus->wslot_res_allocated = -1;
|
||||
|
||||
/*
|
||||
* The PCI bus "domain" is what is called "segment" in ACPI and other
|
||||
@@ -3148,7 +3188,7 @@ static int hv_pci_probe(struct hv_device *hdev,
|
||||
|
||||
ret = hv_pci_allocate_bridge_windows(hbus);
|
||||
if (ret)
|
||||
goto free_irq_domain;
|
||||
goto exit_d0;
|
||||
|
||||
ret = hv_send_resources_allocated(hdev);
|
||||
if (ret)
|
||||
@@ -3166,6 +3206,8 @@ static int hv_pci_probe(struct hv_device *hdev,
|
||||
|
||||
free_windows:
|
||||
hv_pci_free_bridge_windows(hbus);
|
||||
exit_d0:
|
||||
(void) hv_pci_bus_exit(hdev, true);
|
||||
free_irq_domain:
|
||||
irq_domain_remove(hbus->irq_domain);
|
||||
free_fwnode:
|
||||
@@ -3185,7 +3227,7 @@ free_bus:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hv_pci_bus_exit(struct hv_device *hdev, bool hibernating)
|
||||
static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs)
|
||||
{
|
||||
struct hv_pcibus_device *hbus = hv_get_drvdata(hdev);
|
||||
struct {
|
||||
@@ -3203,7 +3245,7 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool hibernating)
|
||||
if (hdev->channel->rescind)
|
||||
return 0;
|
||||
|
||||
if (!hibernating) {
|
||||
if (!keep_devs) {
|
||||
/* Delete any children which might still exist. */
|
||||
dr = kzalloc(sizeof(*dr), GFP_KERNEL);
|
||||
if (dr && hv_pci_start_relations_work(hbus, dr))
|
||||
|
Reference in New Issue
Block a user