[RFC PATCH 2/2] pxa: preliminary support for MULTI_IRQ_HANDLER
Eric Miao
eric.y.miao at gmail.com
Sat May 22 00:24:23 EDT 2010
commit 4cbce4923d528c9de8556bad8b935efe6170842b
Author: Eric Miao <eric.y.miao at gmail.com>
Date: Sat May 22 12:22:52 2010 +0800
[ARM] pxa: preliminary support for MULTI_IRQ_HANDLER
Signed-off-by: Eric Miao <eric.y.miao at gmail.com>
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 3b51741..bec042d 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -470,6 +470,7 @@ config MACH_CORGI
depends on PXA_SHARPSL
select PXA25x
select PXA_SHARP_C7xx
+ select MULTI_IRQ_HANDLER
config MACH_SHEPHERD
bool "Enable Sharp SL-C750 (Shepherd) Support"
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 3d1dcb9..c910d2b 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -729,6 +729,7 @@ MACHINE_START(CORGI, "SHARP Corgi")
.fixup = fixup_corgi,
.map_io = pxa_map_io,
.init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
.init_machine = corgi_init,
.timer = &pxa_timer,
MACHINE_END
@@ -741,6 +742,7 @@ MACHINE_START(SHEPHERD, "SHARP Shepherd")
.fixup = fixup_corgi,
.map_io = pxa_map_io,
.init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
.init_machine = corgi_init,
.timer = &pxa_timer,
MACHINE_END
@@ -753,6 +755,7 @@ MACHINE_START(HUSKY, "SHARP Husky")
.fixup = fixup_corgi,
.map_io = pxa_map_io,
.init_irq = pxa25x_init_irq,
+ .handle_irq = pxa25x_handle_irq,
.init_machine = corgi_init,
.timer = &pxa_timer,
MACHINE_END
diff --git a/arch/arm/mach-pxa/generic.h b/arch/arm/mach-pxa/generic.h
index 890fb90..437e9a3 100644
--- a/arch/arm/mach-pxa/generic.h
+++ b/arch/arm/mach-pxa/generic.h
@@ -22,6 +22,9 @@ extern void __init pxa27x_init_irq(void);
extern void __init pxa3xx_init_irq(void);
extern void __init pxa_map_io(void);
+extern void pxa25x_handle_irq(struct pt_regs *);
+extern void pxa27x_handle_irq(struct pt_regs *);
+
extern unsigned int get_clk_frequency_khz(int info);
#define SET_BANK(__nr,__start,__size) \
diff --git a/arch/arm/mach-pxa/include/mach/entry-macro.S
b/arch/arm/mach-pxa/include/mach/entry-macro.S
index a73bc86..1ee5368 100644
--- a/arch/arm/mach-pxa/include/mach/entry-macro.S
+++ b/arch/arm/mach-pxa/include/mach/entry-macro.S
@@ -13,10 +13,11 @@
.macro disable_fiq
.endm
- .macro get_irqnr_preamble, base, tmp
+ .macro arch_ret_to_user, tmp1, tmp2
.endm
- .macro arch_ret_to_user, tmp1, tmp2
+#ifndef CONFIG_MULTI_IRQ_HANDLER
+ .macro get_irqnr_preamble, base, tmp
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
@@ -49,3 +50,4 @@
add \irqnr, \irqnr, #(PXA_IRQ(0))
1001:
.endm
+#endif
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index a9396a9..24934de 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -37,6 +37,7 @@
#define IPR(i) (((i) < 32) ? (0x01c + ((i) << 2)) : \
((i) < 64) ? (0x0b0 + (((i) - 32) << 2)) : \
(0x144 + (((i) - 64) << 2)))
+#define ICHP_VAL_IRQ (1 << 31)
#define IPR_VALID (1 << 31)
#define MAX_INTERNAL_IRQS 128
@@ -75,6 +76,7 @@ static struct irq_chip pxa_internal_irq_chip = {
.name = "SC",
.ack = pxa_mask_irq,
.mask = pxa_mask_irq,
+ .mask_ack = pxa_mask_irq,
.unmask = pxa_unmask_irq,
};
@@ -148,6 +150,44 @@ static void __init pxa_init_low_gpio_irq(set_wake_t fn)
pxa_low_gpio_chip.set_wake = fn;
}
+#ifdef CONFIG_PXA25x
+asmlinkage void pxa25x_handle_irq(struct pt_regs *reg)
+{
+ uint32_t icip, icmr, mask;
+ unsigned int irq;
+
+ do {
+ icip = __raw_readl(IRQ_BASE + ICIP);
+ icmr = __raw_readl(IRQ_BASE + ICMR);
+ mask = icip & icmr;
+
+ if (mask == 0)
+ break;
+
+ irq = fls(mask) - 1;
+ asm_do_IRQ(irq, reg);
+ } while (1);
+}
+#endif
+
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
+asmlinkage void pxa27x_handle_irq(struct pt_regs *reg)
+{
+ uint32_t ichp;
+ unsigned int irq;
+
+ do {
+ __asm__ __volatile__("mrc p6, 0, %0, c5, c0, 0\n": "=r"(ichp));
+
+ if ((ichp & ICHP_VAL_IRQ) == 0)
+ break;
+
+ irq = PXA_IRQ((ichp & ~ICHP_VAL_IRQ) >> 16);
+ asm_do_IRQ(irq, reg);
+ } while (1);
+}
+#endif
+
static inline void __iomem *irq_base(int i)
{
static unsigned long phys_base[] = {
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 4d2413e..e8bdf16 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -855,6 +855,7 @@ MACHINE_START(SPITZ, "SHARP Spitz")
.fixup = fixup_spitz,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
.init_machine = spitz_init,
.timer = &pxa_timer,
MACHINE_END
@@ -867,6 +868,7 @@ MACHINE_START(BORZOI, "SHARP Borzoi")
.fixup = fixup_spitz,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
.init_machine = spitz_init,
.timer = &pxa_timer,
MACHINE_END
@@ -879,6 +881,7 @@ MACHINE_START(AKITA, "SHARP Akita")
.fixup = fixup_spitz,
.map_io = pxa_map_io,
.init_irq = pxa27x_init_irq,
+ .handle_irq = pxa27x_handle_irq,
.init_machine = akita_init,
.timer = &pxa_timer,
MACHINE_END
More information about the linux-arm-kernel
mailing list