Skip to content

Commit af95dc6

Browse files
committed
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
2 parents a5e0a4b + c824581 commit af95dc6

File tree

4 files changed

+43
-19
lines changed

4 files changed

+43
-19
lines changed

drivers/pci/controller/dwc/pcie-qcom.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
#define PARF_PHY_REFCLK 0x4c
4444
#define PARF_CONFIG_BITS 0x50
4545
#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 */
4746
#define PARF_MHI_CLOCK_RESET_CTRL 0x174
4847
#define PARF_AXI_MSTR_WR_ADDR_HALT 0x178
4948
#define PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1a8
@@ -797,8 +796,7 @@ static int qcom_pcie_post_init_2_3_3(struct qcom_pcie *pcie)
797796
u16 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
798797
u32 val;
799798

800-
writel(SLV_ADDR_SPACE_SZ,
801-
pcie->parf + PARF_SLV_ADDR_SPACE_SIZE_2_3_3);
799+
writel(SLV_ADDR_SPACE_SZ, pcie->parf + PARF_SLV_ADDR_SPACE_SIZE);
802800

803801
val = readl(pcie->parf + PARF_PHY_CTRL);
804802
val &= ~PHY_TEST_PWR_DOWN;

drivers/pci/of.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -657,30 +657,33 @@ void of_pci_make_dev_node(struct pci_dev *pdev)
657657

658658
cset = kmalloc(sizeof(*cset), GFP_KERNEL);
659659
if (!cset)
660-
goto failed;
660+
goto out_free_name;
661661
of_changeset_init(cset);
662662

663663
np = of_changeset_create_node(cset, ppnode, name);
664664
if (!np)
665-
goto failed;
666-
np->data = cset;
665+
goto out_destroy_cset;
667666

668667
ret = of_pci_add_properties(pdev, cset, np);
669668
if (ret)
670-
goto failed;
669+
goto out_free_node;
671670

672671
ret = of_changeset_apply(cset);
673672
if (ret)
674-
goto failed;
673+
goto out_free_node;
675674

675+
np->data = cset;
676676
pdev->dev.of_node = np;
677677
kfree(name);
678678

679679
return;
680680

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:
684687
kfree(name);
685688
}
686689
#endif

drivers/pci/of_property.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@ static int of_pci_prop_interrupts(struct pci_dev *pdev,
186186
static int of_pci_prop_intr_map(struct pci_dev *pdev, struct of_changeset *ocs,
187187
struct device_node *np)
188188
{
189+
u32 i, addr_sz[OF_PCI_MAX_INT_PIN] = { 0 }, map_sz = 0;
189190
struct of_phandle_args out_irq[OF_PCI_MAX_INT_PIN];
190-
u32 i, addr_sz[OF_PCI_MAX_INT_PIN], map_sz = 0;
191191
__be32 laddr[OF_PCI_ADDRESS_CELLS] = { 0 };
192192
u32 int_map_mask[] = { 0xffff00, 0, 0, 7 };
193193
struct device_node *pnode;
@@ -213,33 +213,44 @@ static int of_pci_prop_intr_map(struct pci_dev *pdev, struct of_changeset *ocs,
213213
out_irq[i].args[0] = pin;
214214
ret = of_irq_parse_raw(laddr, &out_irq[i]);
215215
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);
217218
continue;
218219
}
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]);
223222
}
224223

225224
list_for_each_entry(child, &pdev->subordinate->devices, bus_list) {
226225
for (pin = 1; pin <= OF_PCI_MAX_INT_PIN; pin++) {
227226
i = pci_swizzle_interrupt_pin(child, pin) - 1;
227+
if (!out_irq[i].np)
228+
continue;
228229
map_sz += 5 + addr_sz[i] + out_irq[i].args_count;
229230
}
230231
}
231232

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;
239+
232240
int_map = kcalloc(map_sz, sizeof(u32), GFP_KERNEL);
233241
mapp = int_map;
234242

235243
list_for_each_entry(child, &pdev->subordinate->devices, bus_list) {
236244
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+
237249
*mapp = (child->bus->number << 16) |
238250
(child->devfn << 8);
239251
mapp += OF_PCI_ADDRESS_CELLS;
240252
*mapp = pin;
241253
mapp++;
242-
i = pci_swizzle_interrupt_pin(child, pin) - 1;
243254
*mapp = out_irq[i].np->phandle;
244255
mapp++;
245256
if (addr_sz[i]) {

drivers/pci/pci-driver.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,19 @@ static void pci_pm_default_resume_early(struct pci_dev *pci_dev)
572572

573573
static void pci_pm_bridge_power_up_actions(struct pci_dev *pci_dev)
574574
{
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+
}
576588

577589
/*
578590
* When powering on a bridge from D3cold, the whole hierarchy may be

0 commit comments

Comments
 (0)