过去我曾询问有关中断处理ARM的问题,这对我帮助很大。
我有几个基本的疑问,希望它不会太愚蠢。
首先在设备驱动程序中生成中断并希望处理它的设备 使用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)
通常是第一个参数,irq编号已在DTS文件中定义,并且特定于Soc包
“irq number”表示什么,是告诉特定的硬连线从设备的中断引脚到中断控制器(GICVv2 / 3)?
因此,当中断到来时,设备将断言此硬连线irq线,特定时钟上的GIC将检测/读取它。
事实上,GIC的分销商部分会看到来自外设的所有全局中断,并将其传递给GIC的特定CPU接口(GIC的第2个) 重要组成部分)
Distributor如何知道需要发送哪个CPU接口中断(这两者之间的内容)?
CPU接口现在将在特定时钟上断言CPU内核与中断控制器和CPU内核之间的IRQ线 会感觉到它。
CPU核心现在将执行irq-gic.c并读取GIC_IIAR。
读取GIC_IIAR的内容是什么,它是否返回中断源,我们用作request_irq的第一个参数的相同数字?
CPU核心如何了解中断源并调用适当的中断处理程序?
试图提供一些调试日志,以便查看GIC_IAR返回的内容。 GIC_IAR的返回值与request_irq
中使用的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是30
[0.003932] *** sumit1是30
root @ localhost:〜#dmesg | grep amit
[1.032009] sun8i-emac 1c30000.ethernet:*** amit priv-&gt; irq is 19