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:
parent
d60ff2e766
commit
c1fe8d054c
@ -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
|
||||||
|
@ -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 <linux/linkage.h>
|
||||||
#include <asm/assembler.h>
|
#include <asm/assembler.h>
|
||||||
#include <mach/hardware.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
|
.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
|
||||||
|
@ -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 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)
|
|||||||
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user