From 5fae405838527c136a920eb7b9a2edfc5d2b6198 Mon Sep 17 00:00:00 2001 From: Pannaga Bhushan Date: Mon, 24 May 2010 15:08:31 +0900 Subject: ARM: S5P: Fix the platform external interrupt issues. This patch does the following: 1. Corrects the common platform code for external interrupts for using the VIC mask/unmask bits also. 2. Moves the common defines related to external interrupt for plat-s5p to common files. 3. Based on the new common defines, corresponding changes are made in the affected platforms (S5P6440, S5P6442 and S5PC100). Signed-off-by: Pannaga Bhushan Signed-off-by: Kukjin Kim Signed-off-by: Ben Dooks --- arch/arm/plat-s5p/Kconfig | 1 + arch/arm/plat-s5p/include/plat/irqs.h | 7 +++++++ arch/arm/plat-s5p/irq-eint.c | 15 ++++++++++----- 3 files changed, 18 insertions(+), 5 deletions(-) (limited to 'arch/arm/plat-s5p') diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig index 5cb2dd1da632..11d6a1bbd90d 100644 --- a/arch/arm/plat-s5p/Kconfig +++ b/arch/arm/plat-s5p/Kconfig @@ -29,3 +29,4 @@ config S5P_EXT_INT bool help Use the external interrupts (other than GPIO interrupts.) + Note: Do not choose this for S5P6440. diff --git a/arch/arm/plat-s5p/include/plat/irqs.h b/arch/arm/plat-s5p/include/plat/irqs.h index 9ff3d718be39..3fb3a3a17465 100644 --- a/arch/arm/plat-s5p/include/plat/irqs.h +++ b/arch/arm/plat-s5p/include/plat/irqs.h @@ -87,4 +87,11 @@ #define IRQ_TIMER3 S5P_TIMER_IRQ(3) #define IRQ_TIMER4 S5P_TIMER_IRQ(4) +#define IRQ_EINT(x) ((x) < 16 ? ((x) + S5P_EINT_BASE1) \ + : ((x) - 16 + S5P_EINT_BASE2)) + +#define EINT_OFFSET(irq) ((irq) < S5P_EINT_BASE2 ? \ + ((irq) - S5P_EINT_BASE1) : \ + ((irq) + 16 - S5P_EINT_BASE2)) + #endif /* __ASM_PLAT_S5P_IRQS_H */ diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c index eaa70aa0127b..e56c8075df97 100644 --- a/arch/arm/plat-s5p/irq-eint.c +++ b/arch/arm/plat-s5p/irq-eint.c @@ -60,7 +60,7 @@ static void s5p_irq_eint_maskack(unsigned int irq) static int s5p_irq_eint_set_type(unsigned int irq, unsigned int type) { - int offs = eint_offset(irq); + int offs = EINT_OFFSET(irq); int shift; u32 ctrl, mask; u32 newvalue = 0; @@ -139,17 +139,16 @@ static struct irq_chip s5p_irq_eint = { */ static inline void s5p_irq_demux_eint(unsigned int start) { - u32 status; + u32 status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); u32 mask = __raw_readl(S5P_EINT_MASK(EINT_REG_NR(start))); unsigned int irq; - status = __raw_readl(S5P_EINT_PEND(EINT_REG_NR(start))); status &= ~mask; status &= 0xff; while (status) { - irq = fls(status); - generic_handle_irq(irq - 1 + start); + irq = fls(status) - 1; + generic_handle_irq(irq + start); status &= ~(1 << irq); } } @@ -162,12 +161,18 @@ static void s5p_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc) static inline void s5p_irq_vic_eint_mask(unsigned int irq) { + void __iomem *base = get_irq_chip_data(irq); + s5p_irq_eint_mask(irq); + writel(1 << EINT_OFFSET(irq), base + VIC_INT_ENABLE_CLEAR); } static void s5p_irq_vic_eint_unmask(unsigned int irq) { + void __iomem *base = get_irq_chip_data(irq); + s5p_irq_eint_unmask(irq); + writel(1 << EINT_OFFSET(irq), base + VIC_INT_ENABLE); } static inline void s5p_irq_vic_eint_ack(unsigned int irq) -- cgit v1.2.3