Skip to content

Commit 1571d67

Browse files
paliLorenzo Pieralisi
authored andcommitted
PCI: aardvark: Rewrite IRQ code to chained IRQ handler
Rewrite the code to use irq_set_chained_handler_and_data() handler with chained_irq_enter() and chained_irq_exit() processing instead of using devm_request_irq(). advk_pcie_irq_handler() reads IRQ status bits and calls other functions based on which bits are set. These functions then read its own IRQ status bits and calls other aardvark functions based on these bits. Finally generic_handle_domain_irq() with translated linux IRQ numbers are called. Link: https://lore.kernel.org/r/20220110015018.26359-5-kabel@kernel.org Signed-off-by: Pali Rohár <pali@kernel.org> Signed-off-by: Marek Behún <kabel@kernel.org> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
1 parent b0b0b8b commit 1571d67

1 file changed

Lines changed: 26 additions & 22 deletions

File tree

drivers/pci/controller/pci-aardvark.c

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ struct advk_pcie {
268268
u32 actions;
269269
} wins[OB_WIN_COUNT];
270270
u8 wins_count;
271+
int irq;
271272
struct irq_domain *irq_domain;
272273
struct irq_chip irq_chip;
273274
raw_spinlock_t irq_lock;
@@ -1428,21 +1429,26 @@ static void advk_pcie_handle_int(struct advk_pcie *pcie)
14281429
}
14291430
}
14301431

1431-
static irqreturn_t advk_pcie_irq_handler(int irq, void *arg)
1432+
static void advk_pcie_irq_handler(struct irq_desc *desc)
14321433
{
1433-
struct advk_pcie *pcie = arg;
1434-
u32 status;
1434+
struct advk_pcie *pcie = irq_desc_get_handler_data(desc);
1435+
struct irq_chip *chip = irq_desc_get_chip(desc);
1436+
u32 val, mask, status;
14351437

1436-
status = advk_readl(pcie, HOST_CTRL_INT_STATUS_REG);
1437-
if (!(status & PCIE_IRQ_CORE_INT))
1438-
return IRQ_NONE;
1438+
chained_irq_enter(chip, desc);
14391439

1440-
advk_pcie_handle_int(pcie);
1440+
val = advk_readl(pcie, HOST_CTRL_INT_STATUS_REG);
1441+
mask = advk_readl(pcie, HOST_CTRL_INT_MASK_REG);
1442+
status = val & ((~mask) & PCIE_IRQ_ALL_MASK);
14411443

1442-
/* Clear interrupt */
1443-
advk_writel(pcie, PCIE_IRQ_CORE_INT, HOST_CTRL_INT_STATUS_REG);
1444+
if (status & PCIE_IRQ_CORE_INT) {
1445+
advk_pcie_handle_int(pcie);
14441446

1445-
return IRQ_HANDLED;
1447+
/* Clear interrupt */
1448+
advk_writel(pcie, PCIE_IRQ_CORE_INT, HOST_CTRL_INT_STATUS_REG);
1449+
}
1450+
1451+
chained_irq_exit(chip, desc);
14461452
}
14471453

14481454
static void __maybe_unused advk_pcie_disable_phy(struct advk_pcie *pcie)
@@ -1509,7 +1515,7 @@ static int advk_pcie_probe(struct platform_device *pdev)
15091515
struct advk_pcie *pcie;
15101516
struct pci_host_bridge *bridge;
15111517
struct resource_entry *entry;
1512-
int ret, irq;
1518+
int ret;
15131519

15141520
bridge = devm_pci_alloc_host_bridge(dev, sizeof(struct advk_pcie));
15151521
if (!bridge)
@@ -1595,17 +1601,9 @@ static int advk_pcie_probe(struct platform_device *pdev)
15951601
if (IS_ERR(pcie->base))
15961602
return PTR_ERR(pcie->base);
15971603

1598-
irq = platform_get_irq(pdev, 0);
1599-
if (irq < 0)
1600-
return irq;
1601-
1602-
ret = devm_request_irq(dev, irq, advk_pcie_irq_handler,
1603-
IRQF_SHARED | IRQF_NO_THREAD, "advk-pcie",
1604-
pcie);
1605-
if (ret) {
1606-
dev_err(dev, "Failed to register interrupt\n");
1607-
return ret;
1608-
}
1604+
pcie->irq = platform_get_irq(pdev, 0);
1605+
if (pcie->irq < 0)
1606+
return pcie->irq;
16091607

16101608
pcie->reset_gpio = devm_gpiod_get_from_of_node(dev, dev->of_node,
16111609
"reset-gpios", 0,
@@ -1654,11 +1652,14 @@ static int advk_pcie_probe(struct platform_device *pdev)
16541652
return ret;
16551653
}
16561654

1655+
irq_set_chained_handler_and_data(pcie->irq, advk_pcie_irq_handler, pcie);
1656+
16571657
bridge->sysdata = pcie;
16581658
bridge->ops = &advk_pcie_ops;
16591659

16601660
ret = pci_host_probe(bridge);
16611661
if (ret < 0) {
1662+
irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
16621663
advk_pcie_remove_msi_irq_domain(pcie);
16631664
advk_pcie_remove_irq_domain(pcie);
16641665
return ret;
@@ -1706,6 +1707,9 @@ static int advk_pcie_remove(struct platform_device *pdev)
17061707
advk_writel(pcie, PCIE_ISR1_ALL_MASK, PCIE_ISR1_REG);
17071708
advk_writel(pcie, PCIE_IRQ_ALL_MASK, HOST_CTRL_INT_STATUS_REG);
17081709

1710+
/* Remove IRQ handler */
1711+
irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
1712+
17091713
/* Remove IRQ domains */
17101714
advk_pcie_remove_msi_irq_domain(pcie);
17111715
advk_pcie_remove_irq_domain(pcie);

0 commit comments

Comments
 (0)