[PATCH 3/4] irqchip/ath79-misc: convert to a platform driver
From: Rosen Penev
Date: Thu Nov 12 2026 - 18:15:09 EST
The MISC interrupt controller is cascaded from a CPU interrupt, and its
users are all platform devices, which defer their probe until it is
available. The performance counter interrupt, the only one needed
before the early initcalls, is now mapped on demand.
Probe the controller as a platform driver, and use device-managed
resources, which also fixes the leak of the register mapping when the
irq domain cannot be created.
Signed-off-by: Rosen Penev <rosenp@xxxxxxxxx>
---
drivers/irqchip/irq-ath79-misc.c | 78 ++++++++++++++------------------
1 file changed, 34 insertions(+), 44 deletions(-)
diff --git a/drivers/irqchip/irq-ath79-misc.c b/drivers/irqchip/irq-ath79-misc.c
index 5cedea5234e0..b06ece446746 100644
--- a/drivers/irqchip/irq-ath79-misc.c
+++ b/drivers/irqchip/irq-ath79-misc.c
@@ -12,8 +12,9 @@
#include <linux/irqchip.h>
#include <linux/irqchip/chained_irq.h>
-#include <linux/of_address.h>
-#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
#include <asm/time.h>
@@ -124,65 +125,54 @@ static const struct irq_domain_ops misc_irq_domain_ops = {
.map = misc_map,
};
-static void __init ath79_misc_intc_domain_init(
- struct irq_domain *domain, int irq)
-{
- void __iomem *base = domain->host_data;
-
- /* Disable and clear all interrupts */
- __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
- __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
-
- irq_set_chained_handler_and_data(irq, ath79_misc_irq_handler, domain);
-}
-
-static int __init ath79_misc_intc_of_init(
- struct device_node *node, struct device_node *parent)
+static int ath79_misc_intc_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
struct irq_domain *domain;
void __iomem *base;
int irq;
- irq = irq_of_parse_and_map(node, 0);
- if (!irq) {
- pr_err("Failed to get MISC IRQ\n");
- return -EINVAL;
- }
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
- base = of_iomap(node, 0);
- if (!base) {
- pr_err("Failed to get MISC IRQ registers\n");
- return -ENOMEM;
- }
+ base = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
- domain = irq_domain_create_linear(of_fwnode_handle(node), ATH79_MISC_IRQ_COUNT,
- &misc_irq_domain_ops, base);
- if (!domain) {
- pr_err("Failed to add MISC irqdomain\n");
- return -EINVAL;
- }
+ domain = devm_irq_domain_create_linear(dev, dev_fwnode(dev),
+ ATH79_MISC_IRQ_COUNT,
+ &misc_irq_domain_ops, base);
+ if (!domain)
+ return dev_err_probe(dev, -ENOMEM, "failed to add the irq domain\n");
+
+ /* Disable and clear all interrupts */
+ __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+ __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
- ath79_misc_intc_domain_init(domain, irq);
+ irq_set_chained_handler_and_data(irq, ath79_misc_irq_handler, domain);
ath79_misc_domain = domain;
+
return 0;
}
-static int __init ar7100_misc_intc_of_init(
- struct device_node *node, struct device_node *parent)
+static int ar7100_misc_intc_probe(struct platform_device *pdev,
+ struct device_node *parent)
{
ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
- return ath79_misc_intc_of_init(node, parent);
+ return ath79_misc_intc_probe(pdev);
}
-IRQCHIP_DECLARE(ar7100_misc_intc, "qca,ar7100-misc-intc",
- ar7100_misc_intc_of_init);
-
-static int __init ar7240_misc_intc_of_init(
- struct device_node *node, struct device_node *parent)
+static int ar7240_misc_intc_probe(struct platform_device *pdev,
+ struct device_node *parent)
{
ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
- return ath79_misc_intc_of_init(node, parent);
+ return ath79_misc_intc_probe(pdev);
}
-IRQCHIP_DECLARE(ar7240_misc_intc, "qca,ar7240-misc-intc",
- ar7240_misc_intc_of_init);
+IRQCHIP_PLATFORM_DRIVER_BEGIN(ath79_misc_intc)
+IRQCHIP_MATCH("qca,ar7100-misc-intc", ar7100_misc_intc_probe)
+IRQCHIP_MATCH("qca,ar7240-misc-intc", ar7240_misc_intc_probe)
+IRQCHIP_PLATFORM_DRIVER_END(ath79_misc_intc)
+MODULE_DESCRIPTION("Atheros AR71xx/AR724x/AR913x MISC interrupt controller");
+MODULE_LICENSE("GPL");
--
2.56.1