mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
Merge branch 'pci/controller/altera'
- Do not dispose of the parent IRQ mapping, which belongs to the parent interrupt controller (Mahesh Vaidya) - Fix chained IRQ handler ordering issue and resource leaks on probe failure (Mahesh Vaidya) * pci/controller/altera: PCI: altera: Fix resource leaks on probe failure PCI: altera: Do not dispose parent IRQ mapping
This commit is contained in:
commit
bf27eed040
|
|
@ -864,11 +864,25 @@ static int altera_pcie_init_irq_domain(struct altera_pcie *pcie)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void altera_pcie_disable_irq(struct altera_pcie *pcie)
|
||||
{
|
||||
if (pcie->pcie_data->version == ALTERA_PCIE_V1 ||
|
||||
pcie->pcie_data->version == ALTERA_PCIE_V2) {
|
||||
/* Disable all P2A interrupts */
|
||||
cra_writel(pcie, 0, P2A_INT_ENABLE);
|
||||
} else if (pcie->pcie_data->version == ALTERA_PCIE_V3) {
|
||||
/* Disable port-level interrupts (CFG_AER, etc.) */
|
||||
writel(0, pcie->hip_base +
|
||||
pcie->pcie_data->port_conf_offset +
|
||||
pcie->pcie_data->port_irq_enable_offset);
|
||||
}
|
||||
}
|
||||
|
||||
static void altera_pcie_irq_teardown(struct altera_pcie *pcie)
|
||||
{
|
||||
altera_pcie_disable_irq(pcie);
|
||||
irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
|
||||
irq_domain_remove(pcie->irq_domain);
|
||||
irq_dispose_mapping(pcie->irq);
|
||||
}
|
||||
|
||||
static int altera_pcie_parse_dt(struct altera_pcie *pcie)
|
||||
|
|
@ -891,7 +905,6 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie)
|
|||
if (pcie->irq < 0)
|
||||
return pcie->irq;
|
||||
|
||||
irq_set_chained_handler_and_data(pcie->irq, pcie->pcie_data->ops->rp_isr, pcie);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1020,6 +1033,14 @@ static int altera_pcie_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The chained handler uses pcie->irq_domain, so set it only after the
|
||||
* INTx domain has been created.
|
||||
*/
|
||||
irq_set_chained_handler_and_data(pcie->irq,
|
||||
pcie->pcie_data->ops->rp_isr,
|
||||
pcie);
|
||||
|
||||
if (pcie->pcie_data->version == ALTERA_PCIE_V1 ||
|
||||
pcie->pcie_data->version == ALTERA_PCIE_V2) {
|
||||
/* clear all interrupts */
|
||||
|
|
@ -1037,7 +1058,16 @@ static int altera_pcie_probe(struct platform_device *pdev)
|
|||
bridge->busnr = pcie->root_bus_nr;
|
||||
bridge->ops = &altera_pcie_ops;
|
||||
|
||||
return pci_host_probe(bridge);
|
||||
ret = pci_host_probe(bridge);
|
||||
if (ret)
|
||||
goto err_teardown_irq;
|
||||
|
||||
return 0;
|
||||
|
||||
err_teardown_irq:
|
||||
altera_pcie_irq_teardown(pcie);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void altera_pcie_remove(struct platform_device *pdev)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user