iMX8 Mini interrupts

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

iMX8 Mini interrupts

2,073 Views
dhague262
Contributor I

I'm confused about how to figure determine the interrupt source when you get an IRQ or FIQ interrupt.  The manual lists 128 IRQ's but how do you determine which one you got in the IRQ_Handler?  Is there a register I need to read or something?

 

0 Kudos
Reply
5 Replies

2,054 Views
Zhiming_Liu
NXP TechSupport
NXP TechSupport

Hi @dhague262 

Are you talking about the M core program?

0 Kudos
Reply

2,045 Views
dhague262
Contributor I

No, I'm talking about the Cortex-A53 core.

Thanks

 

0 Kudos
Reply

2,025 Views
Zhiming_Liu
NXP TechSupport
NXP TechSupport

The chip uses GICv3 IP, you can refer gic_irq_domain_translate function in the gicv3 driver.

 

switch (fwspec->param[0]) {
		case 0:			/* SPI */
			*hwirq = fwspec->param[1] + 32;
			break;
		case 1:			/* PPI */
			*hwirq = fwspec->param[1] + 16;
			break;
		case 2:			/* ESPI */
			*hwirq = fwspec->param[1] + ESPI_BASE_INTID;
			break;
		case 3:			/* EPPI */
			*hwirq = fwspec->param[1] + EPPI_BASE_INTID;
			break;
		case GIC_IRQ_TYPE_LPI:	/* LPI */
			*hwirq = fwspec->param[1];
			break;
		case GIC_IRQ_TYPE_PARTITION:
			*hwirq = fwspec->param[1];
			if (fwspec->param[1] >= 16)
				*hwirq += EPPI_BASE_INTID - 16;
			else
				*hwirq += 16;
			break;
		default:
			return -EINVAL;
		}

*type = fwspec->param[2] & IRQ_TYPE_SENSE_MASK;

 

There will be a software irq corresponding to the hardware irq(hwirq)

 

struct irq_data {
	u32			mask;
	unsigned int		irq;------------------------>software irq
	unsigned long		hwirq;---------------------->hardware irq
	struct irq_common_data	*common;
	struct irq_chip		*chip;-------------------->chip ops
	struct irq_domain	*domain;
	void			*chip_data;
};

 

 The irq like 128 in manual actually is irq offset, if the irq is SPI type, you can see that the gicv3 driver willl calculate the real irq number: 128+32. When the GICV3 driver detect the hardware irq signal, the kernel will find it's struct irq_data and the software irq(struct irq_data->irq).

 

We will register the software irq number and  irq handler in driver using request_threaded_irq in driver. Fill the irq handler to the struct irqaction.

 

int request_threaded_irq(unsigned int irq, irq_handler_t handler,
			 irq_handler_t thread_fn, unsigned long irqflags,
			 const char *devname, void *dev_id)

 

Now, we have the hardware irq, software irq and it's handler.

When the interrupt is detected, the GICv3 driver will use generic_handle_irq(irq) to handle the interrupt. For example, if the interrupt is SPI type, the kernel will goto the handle_fasteoi_irq.

In this function, the calltrace of irq handler we define is below, as the struct irq_desc maintain the hwirq, irq and irqaction->handler, the kernel will use hwirq to find the irq and then find the handler.

 

handle_irq_event
->handle_irq_event_percpu
->__handle_irq_event_percpu
->res = action->handler(irq, action->dev_id)---->the handler we define

 

 

0 Kudos
Reply

2,010 Views
dhague262
Contributor I

Thanks, QMiller!   This is good info.   But where can I find the gicv3 driver?  I'm writing bare-metal code to run under ThreadX so I don't have this driver.   I'm guessing its a Linux driver somewhere but I could certainly use it as a reference.

 

0 Kudos
Reply

2,007 Views
Zhiming_Liu
NXP TechSupport
NXP TechSupport

You can refer below files:

1.exception vector: arch/arm64/kernel/entry.S

2.GICv3 driver: drivers/irqchip/irq-gic-v3.c

 

0 Kudos
Reply