[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200117001706.40620-1-jiaxun.yang@flygoat.com>
Date: Fri, 17 Jan 2020 08:17:05 +0800
From: Jiaxun Yang <jiaxun.yang@...goat.com>
To: linux-mips@...r.kernel.org
Cc: chenhc@...ote.com, paul.burton@...s.com,
linux-kernel@...r.kernel.org, maz@...nel.org, tglx@...utronix.de,
Jiaxun Yang <jiaxun.yang@...goat.com>
Subject: [PATCH v1 1/2] genirq: Check for level based percpu irq
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@...goat.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
Powered by blists - more mailing lists