[PATCH v3 01/14] ARM: riscpc: use GENERIC_IRQ_MULTI_HANDLER
Ard Biesheuvel
ardb at kernel.org
Fri Dec 3 02:08:50 PST 2021
From: Arnd Bergmann <arnd at arndb.de>
This is one of the last platforms using the old entry path.
While this code path is spread over a few files, it is fairly
straightforward to convert it into an equivalent C version,
leaving the existing algorithm and all the priority handling
the same.
Unlike most irqchip drivers, this means reading the status
register(s) in a loop and always handling the highest-priority
irq first.
The IOMD_IRQREQC and IOMD_IRQREQD registers are not actaully
used here, but I left the code in place for the time being,
to keep the conversion as direct as possible. It could be
removed in a cleanup on top.
Signed-off-by: Arnd Bergmann <arnd at arndb.de>
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
arch/arm/Kconfig | 1 +
arch/arm/include/asm/hardware/entry-macro-iomd.S | 131 ------------------
arch/arm/mach-rpc/fiq.S | 5 +-
arch/arm/mach-rpc/include/mach/entry-macro.S | 13 --
arch/arm/mach-rpc/irq.c | 145 ++++++++++++++++++++
5 files changed, 149 insertions(+), 146 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index e2ab72f2bf4a..25f1868e5703 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -444,6 +444,7 @@ config ARCH_RPC
select ARM_HAS_SG_CHAIN
select CPU_SA110
select FIQ
+ select GENERIC_IRQ_MULTI_HANDLER
select HAVE_PATA_PLATFORM
select ISA_DMA_API
select LEGACY_TIMER_TICK
diff --git a/arch/arm/include/asm/hardware/entry-macro-iomd.S b/arch/arm/include/asm/hardware/entry-macro-iomd.S
deleted file mode 100644
index f7692731e514..000000000000
--- a/arch/arm/include/asm/hardware/entry-macro-iomd.S
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * arch/arm/include/asm/hardware/entry-macro-iomd.S
- *
- * Low-level IRQ helper macros for IOC/IOMD based platforms
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-/* IOC / IOMD based hardware */
-#include <asm/hardware/iomd.h>
-
- .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
- ldrb \irqstat, [\base, #IOMD_IRQREQB] @ get high priority first
- ldr \tmp, =irq_prio_h
- teq \irqstat, #0
-#ifdef IOMD_BASE
- ldrbeq \irqstat, [\base, #IOMD_DMAREQ] @ get dma
- addeq \tmp, \tmp, #256 @ irq_prio_h table size
- teqeq \irqstat, #0
- bne 2406f
-#endif
- ldrbeq \irqstat, [\base, #IOMD_IRQREQA] @ get low priority
- addeq \tmp, \tmp, #256 @ irq_prio_d table size
- teqeq \irqstat, #0
-#ifdef IOMD_IRQREQC
- ldrbeq \irqstat, [\base, #IOMD_IRQREQC]
- addeq \tmp, \tmp, #256 @ irq_prio_l table size
- teqeq \irqstat, #0
-#endif
-#ifdef IOMD_IRQREQD
- ldrbeq \irqstat, [\base, #IOMD_IRQREQD]
- addeq \tmp, \tmp, #256 @ irq_prio_lc table size
- teqeq \irqstat, #0
-#endif
-2406: ldrbne \irqnr, [\tmp, \irqstat] @ get IRQ number
- .endm
-
-/*
- * Interrupt table (incorporates priority). Please note that we
- * rely on the order of these tables (see above code).
- */
- .align 5
-irq_prio_h: .byte 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
- .byte 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10
-#ifdef IOMD_BASE
-irq_prio_d: .byte 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
- .byte 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16
-#endif
-irq_prio_l: .byte 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
- .byte 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3
- .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
- .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
- .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
- .byte 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3
- .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
- .byte 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
- .byte 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
-#ifdef IOMD_IRQREQC
-irq_prio_lc: .byte 24,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
- .byte 28,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27
- .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
- .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
- .byte 30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
- .byte 30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27
- .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
- .byte 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
- .byte 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31
-#endif
-#ifdef IOMD_IRQREQD
-irq_prio_ld: .byte 40,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
- .byte 44,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43
- .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
- .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
- .byte 46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
- .byte 46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43
- .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
- .byte 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
- .byte 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47
-#endif
-
diff --git a/arch/arm/mach-rpc/fiq.S b/arch/arm/mach-rpc/fiq.S
index 0de83e9b0b39..087bdf4bc093 100644
--- a/arch/arm/mach-rpc/fiq.S
+++ b/arch/arm/mach-rpc/fiq.S
@@ -2,10 +2,11 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <mach/hardware.h>
-#include <mach/entry-macro.S>
- .text
+ .equ ioc_base_high, IOC_BASE & 0xff000000
+ .equ ioc_base_low, IOC_BASE & 0x00ff0000
+ .text
.global rpc_default_fiq_end
ENTRY(rpc_default_fiq_start)
mov r12, #ioc_base_high
diff --git a/arch/arm/mach-rpc/include/mach/entry-macro.S b/arch/arm/mach-rpc/include/mach/entry-macro.S
deleted file mode 100644
index a6d1a9f4bb79..000000000000
--- a/arch/arm/mach-rpc/include/mach/entry-macro.S
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#include <mach/hardware.h>
-#include <asm/hardware/entry-macro-iomd.S>
-
- .equ ioc_base_high, IOC_BASE & 0xff000000
- .equ ioc_base_low, IOC_BASE & 0x00ff0000
-
- .macro get_irqnr_preamble, base, tmp
- mov \base, #ioc_base_high @ point at IOC
- .if ioc_base_low
- orr \base, \base, #ioc_base_low
- .endif
- .endm
diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c
index 803aeb126f0e..ff473746f6a3 100644
--- a/arch/arm/mach-rpc/irq.c
+++ b/arch/arm/mach-rpc/irq.c
@@ -14,6 +14,149 @@
#define CLR 0x04
#define MASK 0x08
+static const u8 irq_prio_h[256] = {
+ 0, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10,
+ 12, 8, 9, 8,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10,
+ 14,14,14,14,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
+ 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
+ 15,15,15,15,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+ 13,13,13,13,10,10,10,10,11,11,11,11,10,10,10,10,
+};
+
+static const u8 irq_prio_d[256] = {
+ 0,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 20,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 23,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 22,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+ 21,16,17,16,18,16,17,16,19,16,17,16,18,16,17,16,
+};
+
+static const u8 irq_prio_l[256] = {
+ 0, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 0, 1, 0, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3,
+ 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+};
+
+static const u8 irq_prio_lc[256] = {
+ 24,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27,
+ 28,24,25,24,26,26,26,26,27,27,27,27,27,27,27,27,
+ 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,
+ 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,
+ 30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27,
+ 30,30,30,30,30,30,30,30,27,27,27,27,27,27,27,27,
+ 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,
+ 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,
+ 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+ 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+ 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+ 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+ 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+ 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+ 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+ 31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,
+};
+
+static const u8 irq_prio_ld[256] = {
+ 40,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43,
+ 44,40,41,40,42,42,42,42,43,43,43,43,43,43,43,43,
+ 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
+ 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
+ 46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43,
+ 46,46,46,46,46,46,46,46,43,43,43,43,43,43,43,43,
+ 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
+ 45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,
+ 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+ 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+ 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+ 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+ 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+ 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+ 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+ 47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,47,
+};
+
+static int iomd_get_irq_nr(void)
+{
+ int irq;
+ u8 reg;
+
+ /* get highest priority first */
+ reg = readb(IOC_BASE + IOMD_IRQREQB);
+ irq = irq_prio_h[reg];
+ if (irq)
+ return irq;
+
+ /* get DMA */
+ reg = readb(IOC_BASE + IOMD_DMAREQ);
+ irq = irq_prio_d[reg];
+ if (irq)
+ return irq;
+
+ /* get low priority */
+ reg = readb(IOC_BASE + IOMD_IRQREQA);
+ irq = irq_prio_l[reg];
+ if (irq)
+ return irq;
+#ifdef IOMD_IRQREQC
+ reg = readb(IOC_BASE + IOMD_IRQREQC);
+ irq = irq_prio_lc[reg];
+ if (irq)
+ return irq;
+#endif
+#ifdef IOMD_IRQREQD
+ reg = readb(IOC_BASE + IOMD_IRQREQD);
+ irq = irq_prio_ld[reg];
+ if (irq)
+ return irq;
+#endif
+ return 0;
+}
+
+static void iomd_handle_irq(struct pt_regs *regs)
+{
+ int irq;
+
+ do {
+ irq = iomd_get_irq_nr();
+ if (irq)
+ generic_handle_irq(irq);
+ } while (irq);
+}
+
static void __iomem *iomd_get_base(struct irq_data *d)
{
void *cd = irq_data_get_irq_chip_data(d);
@@ -82,6 +225,8 @@ void __init rpc_init_irq(void)
set_fiq_handler(&rpc_default_fiq_start,
&rpc_default_fiq_end - &rpc_default_fiq_start);
+ set_handle_irq(iomd_handle_irq);
+
for (irq = 0; irq < NR_IRQS; irq++) {
clr = IRQ_NOREQUEST;
set = 0;
--
2.30.2
More information about the linux-arm-kernel
mailing list