lkml.org 
[lkml]   [2020]   [Jan]   [16]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v1 1/2] genirq: Check for level based percpu irq
Date
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
\
 
 \ /
  Last update: 2020-01-17 01:18    [W:0.110 / U:0.732 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site