Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pci-v6.6-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci

Pull PCI fixes from Bjorn Helgaas:

- Fix a qcom register offset that broke IPQ8074 PCIe controller
enumeration (Sricharan Ramabadhran)

- Handle interrupt parsing failures when creating a device tree node to
avoid using uninitialized data (Lizhi Hou)

- Clean up if adding PCI device node fails when creating a device tree
node to avoid a memory leak (Lizhi Hou)

- If a link is down, mark all downstream devices as "disconnected" so
we don't wait for them on resume (Mika Westerberg)

* tag 'pci-v6.6-fixes-2' of git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci:
PCI/PM: Mark devices disconnected if upstream PCIe link is down on resume
PCI: of: Destroy changeset when adding PCI device node fails
PCI: of_property: Handle interrupt parsing failures
PCI: qcom: Fix IPQ8074 enumeration

+43 -19
+1 -3
drivers/pci/controller/dwc/pcie-qcom.c
··· 43 43 #define PARF_PHY_REFCLK 0x4c 44 44 #define PARF_CONFIG_BITS 0x50 45 45 #define PARF_DBI_BASE_ADDR 0x168 46 - #define PARF_SLV_ADDR_SPACE_SIZE_2_3_3 0x16c /* Register offset specific to IP ver 2.3.3 */ 47 46 #define PARF_MHI_CLOCK_RESET_CTRL 0x174 48 47 #define PARF_AXI_MSTR_WR_ADDR_HALT 0x178 49 48 #define PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1a8 ··· 796 797 u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); 797 798 u32 val; 798 799 799 - writel(SLV_ADDR_SPACE_SZ, 800 - pcie->parf + PARF_SLV_ADDR_SPACE_SIZE_2_3_3); 800 + writel(SLV_ADDR_SPACE_SZ, pcie->parf + PARF_SLV_ADDR_SPACE_SIZE); 801 801 802 802 val = readl(pcie->parf + PARF_PHY_CTRL); 803 803 val &= ~PHY_TEST_PWR_DOWN;
+11 -8
drivers/pci/of.c
··· 657 657 658 658 cset = kmalloc(sizeof(*cset), GFP_KERNEL); 659 659 if (!cset) 660 - goto failed; 660 + goto out_free_name; 661 661 of_changeset_init(cset); 662 662 663 663 np = of_changeset_create_node(cset, ppnode, name); 664 664 if (!np) 665 - goto failed; 666 - np->data = cset; 665 + goto out_destroy_cset; 667 666 668 667 ret = of_pci_add_properties(pdev, cset, np); 669 668 if (ret) 670 - goto failed; 669 + goto out_free_node; 671 670 672 671 ret = of_changeset_apply(cset); 673 672 if (ret) 674 - goto failed; 673 + goto out_free_node; 675 674 675 + np->data = cset; 676 676 pdev->dev.of_node = np; 677 677 kfree(name); 678 678 679 679 return; 680 680 681 - failed: 682 - if (np) 683 - of_node_put(np); 681 + out_free_node: 682 + of_node_put(np); 683 + out_destroy_cset: 684 + of_changeset_destroy(cset); 685 + kfree(cset); 686 + out_free_name: 684 687 kfree(name); 685 688 } 686 689 #endif
+18 -7
drivers/pci/of_property.c
··· 186 186 static int of_pci_prop_intr_map(struct pci_dev *pdev, struct of_changeset *ocs, 187 187 struct device_node *np) 188 188 { 189 + u32 i, addr_sz[OF_PCI_MAX_INT_PIN] = { 0 }, map_sz = 0; 189 190 struct of_phandle_args out_irq[OF_PCI_MAX_INT_PIN]; 190 - u32 i, addr_sz[OF_PCI_MAX_INT_PIN], map_sz = 0; 191 191 __be32 laddr[OF_PCI_ADDRESS_CELLS] = { 0 }; 192 192 u32 int_map_mask[] = { 0xffff00, 0, 0, 7 }; 193 193 struct device_node *pnode; ··· 213 213 out_irq[i].args[0] = pin; 214 214 ret = of_irq_parse_raw(laddr, &out_irq[i]); 215 215 if (ret) { 216 - pci_err(pdev, "parse irq %d failed, ret %d", pin, ret); 216 + out_irq[i].np = NULL; 217 + pci_dbg(pdev, "parse irq %d failed, ret %d", pin, ret); 217 218 continue; 218 219 } 219 - ret = of_property_read_u32(out_irq[i].np, "#address-cells", 220 - &addr_sz[i]); 221 - if (ret) 222 - addr_sz[i] = 0; 220 + of_property_read_u32(out_irq[i].np, "#address-cells", 221 + &addr_sz[i]); 223 222 } 224 223 225 224 list_for_each_entry(child, &pdev->subordinate->devices, bus_list) { 226 225 for (pin = 1; pin <= OF_PCI_MAX_INT_PIN; pin++) { 227 226 i = pci_swizzle_interrupt_pin(child, pin) - 1; 227 + if (!out_irq[i].np) 228 + continue; 228 229 map_sz += 5 + addr_sz[i] + out_irq[i].args_count; 229 230 } 230 231 } 232 + 233 + /* 234 + * Parsing interrupt failed for all pins. In this case, it does not 235 + * need to generate interrupt-map property. 236 + */ 237 + if (!map_sz) 238 + return 0; 231 239 232 240 int_map = kcalloc(map_sz, sizeof(u32), GFP_KERNEL); 233 241 mapp = int_map; 234 242 235 243 list_for_each_entry(child, &pdev->subordinate->devices, bus_list) { 236 244 for (pin = 1; pin <= OF_PCI_MAX_INT_PIN; pin++) { 245 + i = pci_swizzle_interrupt_pin(child, pin) - 1; 246 + if (!out_irq[i].np) 247 + continue; 248 + 237 249 *mapp = (child->bus->number << 16) | 238 250 (child->devfn << 8); 239 251 mapp += OF_PCI_ADDRESS_CELLS; 240 252 *mapp = pin; 241 253 mapp++; 242 - i = pci_swizzle_interrupt_pin(child, pin) - 1; 243 254 *mapp = out_irq[i].np->phandle; 244 255 mapp++; 245 256 if (addr_sz[i]) {
+13 -1
drivers/pci/pci-driver.c
··· 572 572 573 573 static void pci_pm_bridge_power_up_actions(struct pci_dev *pci_dev) 574 574 { 575 - pci_bridge_wait_for_secondary_bus(pci_dev, "resume"); 575 + int ret; 576 + 577 + ret = pci_bridge_wait_for_secondary_bus(pci_dev, "resume"); 578 + if (ret) { 579 + /* 580 + * The downstream link failed to come up, so mark the 581 + * devices below as disconnected to make sure we don't 582 + * attempt to resume them. 583 + */ 584 + pci_walk_bus(pci_dev->subordinate, pci_dev_set_disconnected, 585 + NULL); 586 + return; 587 + } 576 588 577 589 /* 578 590 * When powering on a bridge from D3cold, the whole hierarchy may be