Messages in this thread Patch in this message | | | From | Jiaxun Yang <> | Subject | [PATCH v1 1/2] genirq: Check for level based percpu irq | Date | Fri, 17 Jan 2020 08:17:05 +0800 |
| |
MIPS processors implemented their IPI IRQ and CPU interrupt line as level triggered IRQ. However, our current percpu_irq flow is trying do it in a level triggered manner.
Thus we attempt to determine whether it is or not level triggered type by checking if both ack and eoi operation not exist. And handle it in mask/unmask way.
Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com> --- kernel/irq/chip.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index b3fa2d87d2f3..4fafe572d022 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -893,6 +893,7 @@ void handle_edge_eoi_irq(struct irq_desc *desc) void handle_percpu_irq(struct irq_desc *desc) { struct irq_chip *chip = irq_desc_get_chip(desc); + bool is_level = !chip->irq_ack && !chip->irq_eoi; /* * PER CPU interrupts are not serialized. Do not touch @@ -900,12 +901,16 @@ void handle_percpu_irq(struct irq_desc *desc) */ __kstat_incr_irqs_this_cpu(desc); - if (chip->irq_ack) + if (is_level) + chip->irq_mask(&desc->irq_data); + else if (chip->irq_ack) chip->irq_ack(&desc->irq_data); handle_irq_event_percpu(desc); - if (chip->irq_eoi) + if (is_level) + chip->irq_unmask(&desc->irq_data); + else if (chip->irq_eoi) chip->irq_eoi(&desc->irq_data); } @@ -925,6 +930,7 @@ void handle_percpu_devid_irq(struct irq_desc *desc) struct irq_chip *chip = irq_desc_get_chip(desc); struct irqaction *action = desc->action; unsigned int irq = irq_desc_get_irq(desc); + bool is_level = !chip->irq_ack && !chip->irq_eoi; irqreturn_t res; /* @@ -933,7 +939,9 @@ void handle_percpu_devid_irq(struct irq_desc *desc) */ __kstat_incr_irqs_this_cpu(desc); - if (chip->irq_ack) + if (is_level) + chip->irq_mask(&desc->irq_data); + else if (chip->irq_ack) chip->irq_ack(&desc->irq_data); if (likely(action)) { @@ -951,7 +959,9 @@ void handle_percpu_devid_irq(struct irq_desc *desc) enabled ? " and unmasked" : "", irq, cpu); } - if (chip->irq_eoi) + if (is_level) + chip->irq_unmask(&desc->irq_data); + else if (chip->irq_eoi) chip->irq_eoi(&desc->irq_data); } -- 2.24.1
| |