summaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap2/irq.c
diff options
context:
space:
mode:
authorJim Wylder <jwylder@motorola.com>2014-05-08 13:30:07 -0500
committerJim Wylder <jwylder@motorola.com>2014-05-12 18:33:27 -0500
commit54c1f5bc458eae45c865fdddc5ccc601a866f98e (patch)
tree754a1d6215c662f820c4dd016ee3106c2819dd6f /arch/arm/mach-omap2/irq.c
parent31ebd339fb0df3e87958a43933413a76821080b6 (diff)
downloadolio-linux-3.10-54c1f5bc458eae45c865fdddc5ccc601a866f98e.tar.xz
olio-linux-3.10-54c1f5bc458eae45c865fdddc5ccc601a866f98e.zip
IKXCLOCK-1044 arm: OMAP: offmode translate pad wkups to isr
When hitting offmode, gpio banks 2 - 6 irqstatus will be cleared. If a wakeable pin is asserted, the device will wakeup, but the interrupt will not be triggered. To work around this, allow each gpio bank to have one associated wakeup pad. (The limit is just for simplicity) Then if the device wakes-up from off mode, and the pad is the source of the wakeup, then generate a software interrupt, and fill in the bank with the secret information to handle it. Change-Id: I6187b5e25e6fec96971ee30dbbea5c128a1e369c Conflicts: arch/arm/mach-omap2/pm34xx.c drivers/gpio/gpio-omap.c include/linux/platform_data/gpio-omap.h
Diffstat (limited to 'arch/arm/mach-omap2/irq.c')
-rw-r--r--arch/arm/mach-omap2/irq.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index 3926f370448..9a2bc4ba235 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -40,7 +40,10 @@
#define INTC_MIR0 0x0084
#define INTC_MIR_CLEAR0 0x0088
#define INTC_MIR_SET0 0x008c
+#define INTC_ISR_SET0 0x0090
+#define INTC_ISR_CLEAR0 0x0094
#define INTC_PENDING_IRQ0 0x0098
+
/* Number of IRQ state bits in each MIR register */
#define IRQ_BITS_PER_REG 32
@@ -51,6 +54,9 @@
#define INTCPS_NR_MIR_REGS 3
#define INTCPS_NR_IRQS 96
+#define INTCPS_ISR_SET(n) (INTC_ISR_SET0 + (0x20 * (n)))
+#define INTCPS_ISR_CLR(n) (INTC_ISR_CLEAR0 + (0x20 * (n)))
+
/*
* OMAP2 has a number of different interrupt controllers, each interrupt
* controller is identified as its own "bank". Register definitions are
@@ -122,6 +128,24 @@ static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
intc_bank_write_reg(1 << 0, bank, INTC_SYSCONFIG);
}
+void omap_clr_soft_irq(int irq)
+{
+ u32 shift = (irq - domain->revmap_data.legacy.first_irq);
+ u32 offset = INTCPS_ISR_CLR(shift / (IRQ_BITS_PER_REG - 1));
+ u32 isr = 1 << (shift % IRQ_BITS_PER_REG);
+
+ __raw_writel(isr, OMAP2_L4_IO_ADDRESS(OMAP34XX_IC_BASE + offset));
+}
+
+void omap_set_soft_irq(int irq)
+{
+ u32 shift = (irq - domain->revmap_data.legacy.first_irq);
+ u32 offset = INTCPS_ISR_SET(shift / (IRQ_BITS_PER_REG - 1));
+ u32 isr = 1 << (shift % IRQ_BITS_PER_REG);
+
+ __raw_writel(isr, OMAP2_L4_IO_ADDRESS(OMAP34XX_IC_BASE + offset));
+}
+
int omap_irq_pending(void)
{
int i;
@@ -179,6 +203,7 @@ static void __init omap_init_irq(u32 base, int nr_irqs,
domain = irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
&irq_domain_simple_ops, NULL);
+
for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
struct omap_irq_bank *bank = irq_banks + i;