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: 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
This commit is contained in:
Родитель
d60ff2e766
Коммит
c1fe8d054c
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -2,10 +2,11 @@
|
|||
#include <linux/linkage.h>
|
||||
#include <asm/assembler.h>
|
||||
#include <mach/hardware.h>
|
||||
#include <mach/entry-macro.S>
|
||||
|
||||
.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
|
||||
|
|
|
@ -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
|
|
@ -14,6 +14,99 @@
|
|||
#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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче