The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH] irqchip/irq-imgpdc: Remove unused driver
@ 2026-07-06 16:53 Ben Hutchings
  2026-07-06 21:27 ` [tip: irq/drivers] " tip-bot2 for Ben Hutchings
  0 siblings, 1 reply; 2+ messages in thread
From: Ben Hutchings @ 2026-07-06 16:53 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 16350 bytes --]

The irq-imgpdc driver is controlled by CONFIG_IMGPDC_IRQ, which cannot
be enabled.  It used to be selected by CONFIG_SOC_TZ1090, but that was
removd along with the metag architecture in Linux 4.17.

Signed-off-by: Ben Hutchings <benh@debian.org>
---
 drivers/irqchip/Kconfig      |   5 -
 drivers/irqchip/Makefile     |   1 -
 drivers/irqchip/irq-imgpdc.c | 495 -----------------------------------
 3 files changed, 501 deletions(-)
 delete mode 100644 drivers/irqchip/irq-imgpdc.c

diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 42f2278a702d..20b77fbc51ee 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -212,11 +212,6 @@ config HISILICON_IRQ_MBIGEN
 	select ARM_GIC_V3
 	select ARM_GIC_V3_ITS
 
-config IMGPDC_IRQ
-	bool
-	select GENERIC_IRQ_CHIP
-	select IRQ_DOMAIN
-
 config IXP4XX_IRQ
 	bool
 	select IRQ_DOMAIN
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 74912429c59f..ab33cccd8471 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -44,7 +44,6 @@ obj-$(CONFIG_ARMADA_370_XP_IRQ)		+= irq-armada-370-xp.o
 obj-$(CONFIG_ATMEL_AIC_IRQ)		+= irq-atmel-aic-common.o irq-atmel-aic.o
 obj-$(CONFIG_ATMEL_AIC5_IRQ)	+= irq-atmel-aic-common.o irq-atmel-aic5.o
 obj-$(CONFIG_I8259)			+= irq-i8259.o
-obj-$(CONFIG_IMGPDC_IRQ)		+= irq-imgpdc.o
 obj-$(CONFIG_IRQ_MIPS_CPU)		+= irq-mips-cpu.o
 obj-$(CONFIG_IXP4XX_IRQ)		+= irq-ixp4xx.o
 obj-$(CONFIG_JCORE_AIC)			+= irq-jcore-aic.o
diff --git a/drivers/irqchip/irq-imgpdc.c b/drivers/irqchip/irq-imgpdc.c
deleted file mode 100644
index 4feef4ab5fec..000000000000
--- a/drivers/irqchip/irq-imgpdc.c
+++ /dev/null
@@ -1,495 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * IMG PowerDown Controller (PDC)
- *
- * Copyright 2010-2013 Imagination Technologies Ltd.
- *
- * Exposes the syswake and PDC peripheral wake interrupts to the system.
- *
- */
-
-#include <linux/bitops.h>
-#include <linux/interrupt.h>
-#include <linux/irqdomain.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/spinlock.h>
-
-/* PDC interrupt register numbers */
-
-#define PDC_IRQ_STATUS			0x310
-#define PDC_IRQ_ENABLE			0x314
-#define PDC_IRQ_CLEAR			0x318
-#define PDC_IRQ_ROUTE			0x31c
-#define PDC_SYS_WAKE_BASE		0x330
-#define PDC_SYS_WAKE_STRIDE		0x8
-#define PDC_SYS_WAKE_CONFIG_BASE	0x334
-#define PDC_SYS_WAKE_CONFIG_STRIDE	0x8
-
-/* PDC interrupt register field masks */
-
-#define PDC_IRQ_SYS3			0x08
-#define PDC_IRQ_SYS2			0x04
-#define PDC_IRQ_SYS1			0x02
-#define PDC_IRQ_SYS0			0x01
-#define PDC_IRQ_ROUTE_WU_EN_SYS3	0x08000000
-#define PDC_IRQ_ROUTE_WU_EN_SYS2	0x04000000
-#define PDC_IRQ_ROUTE_WU_EN_SYS1	0x02000000
-#define PDC_IRQ_ROUTE_WU_EN_SYS0	0x01000000
-#define PDC_IRQ_ROUTE_WU_EN_WD		0x00040000
-#define PDC_IRQ_ROUTE_WU_EN_IR		0x00020000
-#define PDC_IRQ_ROUTE_WU_EN_RTC		0x00010000
-#define PDC_IRQ_ROUTE_EXT_EN_SYS3	0x00000800
-#define PDC_IRQ_ROUTE_EXT_EN_SYS2	0x00000400
-#define PDC_IRQ_ROUTE_EXT_EN_SYS1	0x00000200
-#define PDC_IRQ_ROUTE_EXT_EN_SYS0	0x00000100
-#define PDC_IRQ_ROUTE_EXT_EN_WD		0x00000004
-#define PDC_IRQ_ROUTE_EXT_EN_IR		0x00000002
-#define PDC_IRQ_ROUTE_EXT_EN_RTC	0x00000001
-#define PDC_SYS_WAKE_RESET		0x00000010
-#define PDC_SYS_WAKE_INT_MODE		0x0000000e
-#define PDC_SYS_WAKE_INT_MODE_SHIFT	1
-#define PDC_SYS_WAKE_PIN_VAL		0x00000001
-
-/* PDC interrupt constants */
-
-#define PDC_SYS_WAKE_INT_LOW		0x0
-#define PDC_SYS_WAKE_INT_HIGH		0x1
-#define PDC_SYS_WAKE_INT_DOWN		0x2
-#define PDC_SYS_WAKE_INT_UP		0x3
-#define PDC_SYS_WAKE_INT_CHANGE		0x6
-#define PDC_SYS_WAKE_INT_NONE		0x4
-
-/**
- * struct pdc_intc_priv - private pdc interrupt data.
- * @nr_perips:		Number of peripheral interrupt signals.
- * @nr_syswakes:	Number of syswake signals.
- * @perip_irqs:		List of peripheral IRQ numbers handled.
- * @syswake_irq:	Shared PDC syswake IRQ number.
- * @domain:		IRQ domain for PDC peripheral and syswake IRQs.
- * @pdc_base:		Base of PDC registers.
- * @irq_route:		Cached version of PDC_IRQ_ROUTE register.
- * @lock:		Lock to protect the PDC syswake registers and the cached
- *			values of those registers in this struct.
- */
-struct pdc_intc_priv {
-	unsigned int		nr_perips;
-	unsigned int		nr_syswakes;
-	unsigned int		*perip_irqs;
-	unsigned int		syswake_irq;
-	struct irq_domain	*domain;
-	void __iomem		*pdc_base;
-
-	u32			irq_route;
-	raw_spinlock_t		lock;
-};
-
-static void pdc_write(struct pdc_intc_priv *priv, unsigned int reg_offs,
-		      unsigned int data)
-{
-	iowrite32(data, priv->pdc_base + reg_offs);
-}
-
-static unsigned int pdc_read(struct pdc_intc_priv *priv,
-			     unsigned int reg_offs)
-{
-	return ioread32(priv->pdc_base + reg_offs);
-}
-
-/* Generic IRQ callbacks */
-
-#define SYS0_HWIRQ	8
-
-static unsigned int hwirq_is_syswake(irq_hw_number_t hw)
-{
-	return hw >= SYS0_HWIRQ;
-}
-
-static unsigned int hwirq_to_syswake(irq_hw_number_t hw)
-{
-	return hw - SYS0_HWIRQ;
-}
-
-static irq_hw_number_t syswake_to_hwirq(unsigned int syswake)
-{
-	return SYS0_HWIRQ + syswake;
-}
-
-static struct pdc_intc_priv *irqd_to_priv(struct irq_data *data)
-{
-	return (struct pdc_intc_priv *)data->domain->host_data;
-}
-
-/*
- * perip_irq_mask() and perip_irq_unmask() use IRQ_ROUTE which also contains
- * wake bits, therefore we cannot use the generic irqchip mask callbacks as they
- * cache the mask.
- */
-
-static void perip_irq_mask(struct irq_data *data)
-{
-	struct pdc_intc_priv *priv = irqd_to_priv(data);
-
-	raw_spin_lock(&priv->lock);
-	priv->irq_route &= ~data->mask;
-	pdc_write(priv, PDC_IRQ_ROUTE, priv->irq_route);
-	raw_spin_unlock(&priv->lock);
-}
-
-static void perip_irq_unmask(struct irq_data *data)
-{
-	struct pdc_intc_priv *priv = irqd_to_priv(data);
-
-	raw_spin_lock(&priv->lock);
-	priv->irq_route |= data->mask;
-	pdc_write(priv, PDC_IRQ_ROUTE, priv->irq_route);
-	raw_spin_unlock(&priv->lock);
-}
-
-static int syswake_irq_set_type(struct irq_data *data, unsigned int flow_type)
-{
-	struct pdc_intc_priv *priv = irqd_to_priv(data);
-	unsigned int syswake = hwirq_to_syswake(data->hwirq);
-	unsigned int irq_mode;
-	unsigned int soc_sys_wake_regoff, soc_sys_wake;
-
-	/* translate to syswake IRQ mode */
-	switch (flow_type) {
-	case IRQ_TYPE_EDGE_BOTH:
-		irq_mode = PDC_SYS_WAKE_INT_CHANGE;
-		break;
-	case IRQ_TYPE_EDGE_RISING:
-		irq_mode = PDC_SYS_WAKE_INT_UP;
-		break;
-	case IRQ_TYPE_EDGE_FALLING:
-		irq_mode = PDC_SYS_WAKE_INT_DOWN;
-		break;
-	case IRQ_TYPE_LEVEL_HIGH:
-		irq_mode = PDC_SYS_WAKE_INT_HIGH;
-		break;
-	case IRQ_TYPE_LEVEL_LOW:
-		irq_mode = PDC_SYS_WAKE_INT_LOW;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	raw_spin_lock(&priv->lock);
-
-	/* set the IRQ mode */
-	soc_sys_wake_regoff = PDC_SYS_WAKE_BASE + syswake*PDC_SYS_WAKE_STRIDE;
-	soc_sys_wake = pdc_read(priv, soc_sys_wake_regoff);
-	soc_sys_wake &= ~PDC_SYS_WAKE_INT_MODE;
-	soc_sys_wake |= irq_mode << PDC_SYS_WAKE_INT_MODE_SHIFT;
-	pdc_write(priv, soc_sys_wake_regoff, soc_sys_wake);
-
-	/* and update the handler */
-	irq_setup_alt_chip(data, flow_type);
-
-	raw_spin_unlock(&priv->lock);
-
-	return 0;
-}
-
-/* applies to both peripheral and syswake interrupts */
-static int pdc_irq_set_wake(struct irq_data *data, unsigned int on)
-{
-	struct pdc_intc_priv *priv = irqd_to_priv(data);
-	irq_hw_number_t hw = data->hwirq;
-	unsigned int mask = (1 << 16) << hw;
-	unsigned int dst_irq;
-
-	raw_spin_lock(&priv->lock);
-	if (on)
-		priv->irq_route |= mask;
-	else
-		priv->irq_route &= ~mask;
-	pdc_write(priv, PDC_IRQ_ROUTE, priv->irq_route);
-	raw_spin_unlock(&priv->lock);
-
-	/* control the destination IRQ wakeup too for standby mode */
-	if (hwirq_is_syswake(hw))
-		dst_irq = priv->syswake_irq;
-	else
-		dst_irq = priv->perip_irqs[hw];
-	irq_set_irq_wake(dst_irq, on);
-
-	return 0;
-}
-
-static void pdc_intc_perip_isr(struct irq_desc *desc)
-{
-	unsigned int irq = irq_desc_get_irq(desc);
-	struct pdc_intc_priv *priv;
-	unsigned int i;
-
-	priv = (struct pdc_intc_priv *)irq_desc_get_handler_data(desc);
-
-	/* find the peripheral number */
-	for (i = 0; i < priv->nr_perips; ++i)
-		if (irq == priv->perip_irqs[i])
-			goto found;
-
-	/* should never get here */
-	return;
-found:
-
-	/* pass on the interrupt */
-	generic_handle_domain_irq(priv->domain, i);
-}
-
-static void pdc_intc_syswake_isr(struct irq_desc *desc)
-{
-	struct pdc_intc_priv *priv;
-	unsigned int syswake;
-	unsigned int status;
-
-	priv = (struct pdc_intc_priv *)irq_desc_get_handler_data(desc);
-
-	status = pdc_read(priv, PDC_IRQ_STATUS) &
-		 pdc_read(priv, PDC_IRQ_ENABLE);
-	status &= (1 << priv->nr_syswakes) - 1;
-
-	for (syswake = 0; status; status >>= 1, ++syswake) {
-		/* Has this sys_wake triggered? */
-		if (!(status & 1))
-			continue;
-
-		generic_handle_domain_irq(priv->domain, syswake_to_hwirq(syswake));
-	}
-}
-
-static void pdc_intc_setup(struct pdc_intc_priv *priv)
-{
-	int i;
-	unsigned int soc_sys_wake_regoff;
-	unsigned int soc_sys_wake;
-
-	/*
-	 * Mask all syswake interrupts before routing, or we could receive an
-	 * interrupt before we're ready to handle it.
-	 */
-	pdc_write(priv, PDC_IRQ_ENABLE, 0);
-
-	/*
-	 * Enable routing of all syswakes
-	 * Disable all wake sources
-	 */
-	priv->irq_route = ((PDC_IRQ_ROUTE_EXT_EN_SYS0 << priv->nr_syswakes) -
-				PDC_IRQ_ROUTE_EXT_EN_SYS0);
-	pdc_write(priv, PDC_IRQ_ROUTE, priv->irq_route);
-
-	/* Initialise syswake IRQ */
-	for (i = 0; i < priv->nr_syswakes; ++i) {
-		/* set the IRQ mode to none */
-		soc_sys_wake_regoff = PDC_SYS_WAKE_BASE + i*PDC_SYS_WAKE_STRIDE;
-		soc_sys_wake = PDC_SYS_WAKE_INT_NONE
-				<< PDC_SYS_WAKE_INT_MODE_SHIFT;
-		pdc_write(priv, soc_sys_wake_regoff, soc_sys_wake);
-	}
-}
-
-static int pdc_intc_probe(struct platform_device *pdev)
-{
-	struct pdc_intc_priv *priv;
-	struct device_node *node = pdev->dev.of_node;
-	struct resource *res_regs;
-	struct irq_chip_generic *gc;
-	unsigned int i;
-	int irq, ret;
-	u32 val;
-
-	if (!node)
-		return -ENOENT;
-
-	/* Get registers */
-	res_regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res_regs == NULL) {
-		dev_err(&pdev->dev, "cannot find registers resource\n");
-		return -ENOENT;
-	}
-
-	/* Allocate driver data */
-	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-	raw_spin_lock_init(&priv->lock);
-	platform_set_drvdata(pdev, priv);
-
-	/* Ioremap the registers */
-	priv->pdc_base = devm_ioremap(&pdev->dev, res_regs->start,
-				      resource_size(res_regs));
-	if (!priv->pdc_base)
-		return -EIO;
-
-	/* Get number of peripherals */
-	ret = of_property_read_u32(node, "num-perips", &val);
-	if (ret) {
-		dev_err(&pdev->dev, "No num-perips node property found\n");
-		return -EINVAL;
-	}
-	if (val > SYS0_HWIRQ) {
-		dev_err(&pdev->dev, "num-perips (%u) out of range\n", val);
-		return -EINVAL;
-	}
-	priv->nr_perips = val;
-
-	/* Get number of syswakes */
-	ret = of_property_read_u32(node, "num-syswakes", &val);
-	if (ret) {
-		dev_err(&pdev->dev, "No num-syswakes node property found\n");
-		return -EINVAL;
-	}
-	if (val > SYS0_HWIRQ) {
-		dev_err(&pdev->dev, "num-syswakes (%u) out of range\n", val);
-		return -EINVAL;
-	}
-	priv->nr_syswakes = val;
-
-	/* Get peripheral IRQ numbers */
-	priv->perip_irqs = devm_kcalloc(&pdev->dev, 4, priv->nr_perips,
-					GFP_KERNEL);
-	if (!priv->perip_irqs)
-		return -ENOMEM;
-	for (i = 0; i < priv->nr_perips; ++i) {
-		irq = platform_get_irq(pdev, 1 + i);
-		if (irq < 0)
-			return irq;
-		priv->perip_irqs[i] = irq;
-	}
-	/* check if too many were provided */
-	if (platform_get_irq(pdev, 1 + i) >= 0) {
-		dev_err(&pdev->dev, "surplus perip IRQs detected\n");
-		return -EINVAL;
-	}
-
-	/* Get syswake IRQ number */
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
-	priv->syswake_irq = irq;
-
-	/* Set up an IRQ domain */
-	priv->domain = irq_domain_create_linear(dev_fwnode(&pdev->dev), 16, &irq_generic_chip_ops,
-						priv);
-	if (unlikely(!priv->domain)) {
-		dev_err(&pdev->dev, "cannot add IRQ domain\n");
-		return -ENOMEM;
-	}
-	priv->domain->flags |= IRQ_DOMAIN_FLAG_DESTROY_GC;
-
-	/*
-	 * Set up 2 generic irq chips with 2 chip types.
-	 * The first one for peripheral irqs (only 1 chip type used)
-	 * The second one for syswake irqs (edge and level chip types)
-	 */
-	ret = irq_alloc_domain_generic_chips(priv->domain, 8, 2, "pdc",
-					     handle_level_irq, 0, 0,
-					     IRQ_GC_INIT_NESTED_LOCK);
-	if (ret)
-		goto err_generic;
-
-	/* peripheral interrupt chip */
-
-	gc = irq_get_domain_generic_chip(priv->domain, 0);
-	gc->unused	= ~(BIT(priv->nr_perips) - 1);
-	gc->reg_base	= priv->pdc_base;
-	/*
-	 * IRQ_ROUTE contains wake bits, so we can't use the generic versions as
-	 * they cache the mask
-	 */
-	gc->chip_types[0].regs.mask		= PDC_IRQ_ROUTE;
-	gc->chip_types[0].chip.irq_mask		= perip_irq_mask;
-	gc->chip_types[0].chip.irq_unmask	= perip_irq_unmask;
-	gc->chip_types[0].chip.irq_set_wake	= pdc_irq_set_wake;
-
-	/* syswake interrupt chip */
-
-	gc = irq_get_domain_generic_chip(priv->domain, 8);
-	gc->unused	= ~(BIT(priv->nr_syswakes) - 1);
-	gc->reg_base	= priv->pdc_base;
-
-	/* edge interrupts */
-	gc->chip_types[0].type			= IRQ_TYPE_EDGE_BOTH;
-	gc->chip_types[0].handler		= handle_edge_irq;
-	gc->chip_types[0].regs.ack		= PDC_IRQ_CLEAR;
-	gc->chip_types[0].regs.mask		= PDC_IRQ_ENABLE;
-	gc->chip_types[0].chip.irq_ack		= irq_gc_ack_set_bit;
-	gc->chip_types[0].chip.irq_mask		= irq_gc_mask_clr_bit;
-	gc->chip_types[0].chip.irq_unmask	= irq_gc_mask_set_bit;
-	gc->chip_types[0].chip.irq_set_type	= syswake_irq_set_type;
-	gc->chip_types[0].chip.irq_set_wake	= pdc_irq_set_wake;
-	/* for standby we pass on to the shared syswake IRQ */
-	gc->chip_types[0].chip.flags		= IRQCHIP_MASK_ON_SUSPEND;
-
-	/* level interrupts */
-	gc->chip_types[1].type			= IRQ_TYPE_LEVEL_MASK;
-	gc->chip_types[1].handler		= handle_level_irq;
-	gc->chip_types[1].regs.ack		= PDC_IRQ_CLEAR;
-	gc->chip_types[1].regs.mask		= PDC_IRQ_ENABLE;
-	gc->chip_types[1].chip.irq_ack		= irq_gc_ack_set_bit;
-	gc->chip_types[1].chip.irq_mask		= irq_gc_mask_clr_bit;
-	gc->chip_types[1].chip.irq_unmask	= irq_gc_mask_set_bit;
-	gc->chip_types[1].chip.irq_set_type	= syswake_irq_set_type;
-	gc->chip_types[1].chip.irq_set_wake	= pdc_irq_set_wake;
-	/* for standby we pass on to the shared syswake IRQ */
-	gc->chip_types[1].chip.flags		= IRQCHIP_MASK_ON_SUSPEND;
-
-	/* Set up the hardware to enable interrupt routing */
-	pdc_intc_setup(priv);
-
-	/* Setup chained handlers for the peripheral IRQs */
-	for (i = 0; i < priv->nr_perips; ++i) {
-		irq = priv->perip_irqs[i];
-		irq_set_chained_handler_and_data(irq, pdc_intc_perip_isr,
-						 priv);
-	}
-
-	/* Setup chained handler for the syswake IRQ */
-	irq_set_chained_handler_and_data(priv->syswake_irq,
-					 pdc_intc_syswake_isr, priv);
-
-	dev_info(&pdev->dev,
-		 "PDC IRQ controller initialised (%u perip IRQs, %u syswake IRQs)\n",
-		 priv->nr_perips,
-		 priv->nr_syswakes);
-
-	return 0;
-err_generic:
-	irq_domain_remove(priv->domain);
-	return ret;
-}
-
-static void pdc_intc_remove(struct platform_device *pdev)
-{
-	struct pdc_intc_priv *priv = platform_get_drvdata(pdev);
-
-	for (unsigned int i = 0; i < priv->nr_perips; ++i)
-		irq_set_chained_handler_and_data(priv->perip_irqs[i], NULL, NULL);
-
-	irq_set_chained_handler_and_data(priv->syswake_irq, NULL, NULL);
-
-	irq_domain_remove(priv->domain);
-}
-
-static const struct of_device_id pdc_intc_match[] = {
-	{ .compatible = "img,pdc-intc" },
-	{}
-};
-
-static struct platform_driver pdc_intc_driver = {
-	.driver = {
-		.name		= "pdc-intc",
-		.of_match_table	= pdc_intc_match,
-	},
-	.probe		= pdc_intc_probe,
-	.remove		= pdc_intc_remove,
-};
-
-static int __init pdc_intc_init(void)
-{
-	return platform_driver_register(&pdc_intc_driver);
-}
-core_initcall(pdc_intc_init);

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-07-06 21:27 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-06 16:53 [PATCH] irqchip/irq-imgpdc: Remove unused driver Ben Hutchings
2026-07-06 21:27 ` [tip: irq/drivers] " tip-bot2 for Ben Hutchings

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox