]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ARM: riscpc: use GENERIC_IRQ_MULTI_HANDLER
authorArnd Bergmann <arnd@arndb.de>
Tue, 30 Nov 2021 07:19:13 +0000 (08:19 +0100)
committerArd Biesheuvel <ardb@kernel.org>
Fri, 3 Dec 2021 17:43:38 +0000 (18:43 +0100)
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@arndb.de>
[ardb: drop obsolete IOMD_IRQREQC/IOMD_IRQREQD handling]
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Tested-by: Marc Zyngier <maz@kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin@arm.com> # ARMv7M
arch/arm/Kconfig
arch/arm/include/asm/hardware/entry-macro-iomd.S [deleted file]
arch/arm/mach-rpc/fiq.S
arch/arm/mach-rpc/include/mach/entry-macro.S [deleted file]
arch/arm/mach-rpc/irq.c

index e2ab72f2bf4ac45ec0cb8a92d16997d683109cd3..25f1868e5703566bfc1ad3e7d545422223db5ef2 100644 (file)
@@ -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 (file)
index 81441df..0000000
+++ /dev/null
@@ -1,84 +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
-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
index 0de83e9b0b39398231b5b543a6e6d0762961cfd5..087bdf4bc0931843403401b8a6ae41f6d0456a7d 100644 (file)
@@ -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 (file)
index a6d1a9f..0000000
+++ /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
index 803aeb126f0e9f9d6eaa061e26d7b21df6cc51b6..dc29384b6ef86376cc9b5a228ee2891b57aea667 100644 (file)
 #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 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;
+       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 +175,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;