Commit c1fe8d05 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Ard Biesheuvel

ARM: riscpc: use GENERIC_IRQ_MULTI_HANDLER

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: default avatarArnd Bergmann <arnd@arndb.de>
[ardb: drop obsolete IOMD_IRQREQC/IOMD_IRQREQD handling]
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
Tested-by: default avatarMarc Zyngier <maz@kernel.org>
Tested-by: Vladimir Murzin <vladimir.murzin@arm.com> # ARMv7M
parent d60ff2e7
...@@ -444,6 +444,7 @@ config ARCH_RPC ...@@ -444,6 +444,7 @@ config ARCH_RPC
select ARM_HAS_SG_CHAIN select ARM_HAS_SG_CHAIN
select CPU_SA110 select CPU_SA110
select FIQ select FIQ
select GENERIC_IRQ_MULTI_HANDLER
select HAVE_PATA_PLATFORM select HAVE_PATA_PLATFORM
select ISA_DMA_API select ISA_DMA_API
select LEGACY_TIMER_TICK select LEGACY_TIMER_TICK
......
/*
* 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
...@@ -2,10 +2,11 @@ ...@@ -2,10 +2,11 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/assembler.h> #include <asm/assembler.h>
#include <mach/hardware.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 .global rpc_default_fiq_end
ENTRY(rpc_default_fiq_start) ENTRY(rpc_default_fiq_start)
mov r12, #ioc_base_high mov r12, #ioc_base_high
......
/* 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
...@@ -14,6 +14,99 @@ ...@@ -14,6 +14,99 @@
#define CLR 0x04 #define CLR 0x04
#define MASK 0x08 #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) static void __iomem *iomd_get_base(struct irq_data *d)
{ {
void *cd = irq_data_get_irq_chip_data(d); void *cd = irq_data_get_irq_chip_data(d);
...@@ -82,6 +175,8 @@ void __init rpc_init_irq(void) ...@@ -82,6 +175,8 @@ void __init rpc_init_irq(void)
set_fiq_handler(&rpc_default_fiq_start, set_fiq_handler(&rpc_default_fiq_start,
&rpc_default_fiq_end - &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++) { for (irq = 0; irq < NR_IRQS; irq++) {
clr = IRQ_NOREQUEST; clr = IRQ_NOREQUEST;
set = 0; set = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment