In past I have asked questions on Interrupt handing on ARM and it helped me quite a lot.
I have few more basic doubt, hope it will not be much stupid.
Device that generates interrupt and wanted it to handled, first in Device driver register the handler using request_irq()
int request_irq(unsigned int irq,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long irqflags,
const char *devname,
void *dev_id)
Generally first parameter to it, an irq number has been defined in DTS file and specific to Soc package
What "irq number" signifies, is it to tell that a particular hardwired line goes from device's interrupt pin to interrupt controller(GICVv2/3) ?
So, when an Interrupt comes device would assert this hardwired irq line and GIC on particular clock would sense/read it.
In fact GIC's distributor part would see all the global interrupt from peripheral and passes it to particular CPU interface of GIC(GIC's 2nd important component)
How Distributor gets to know to which CPU interface interrupt need to be send(what goes between these two) ?
CPU interface would now assert the IRQ line that goes between CPU core and interrupt controller and CPU core on a particular clock would sense it.
CPU core would now executes irq-gic.c and read the GIC_IIAR.
What read to GIC_IIAR returns, does it return the Interrupt source, the same number we used as first parameter to request_irq ?
How CPU core would get to know about the Interrupt source and call the appropriate Interrupt handler ?
EDIT
Tried to provide few debug logs, in order to see what GIC_IAR return. Return value from GIC_IAR is different from irq number used in request_irq
diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
index fbc4ae2..fc2cc46 100644
--- a/drivers/irqchip/irq-gic.c
+++ b/drivers/irqchip/irq-gic.c
@@ -336,7 +336,9 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
do {
irqstat = readl_relaxed(cpu_base + GIC_CPU_INTACK);
+ printk_once(KERN_ALERT "***sumit0 is %d\n", irqstat);
irqnr = irqstat & GICC_IAR_INT_ID_MASK;
+ printk_once(KERN_ALERT "***sumit1 is %d\n", irqnr);
if (likely(irqnr > 15 && irqnr < 1020)) {
if (static_key_true(&supports_deactivate))
diff --git a/drivers/net/ethernet/allwinner/sun8i-emac.c b/drivers /net/ethernet/allwinner/sun8i-emac.c
index 155df32..ca3240c 100644
--- a/drivers/net/ethernet/allwinner/sun8i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun8i-emac.c
@@ -1850,6 +1850,7 @@ static int sun8i_emac_probe(struct platform_device *pdev)
}
priv->irq = platform_get_irq(pdev, 0);
+ dev_info(&pdev->dev, "***amit priv->irq is %d\n", priv->irq);
if (priv->irq < 0) {
ret = priv->irq;
dev_err(&pdev->dev, "Cannot claim IRQ: %d\n", ret);
(END)
root@localhost:~# dmesg | grep sumit
[ 0.003926] ***sumit0 is 30
[ 0.003932] ***sumit1 is 30
root@localhost:~# dmesg | grep amit
[ 1.032009] sun8i-emac 1c30000.ethernet: ***amit priv->irq is 19