| pm-irq1.patch | | S3C2410 Power Managment - IRQ wakeup control | | Files affected: | arch/arm/mach-s3c2410/irq.c | 81 74 + 7 - 0 ! | 1 files changed, 74 insertions(+), 7 deletions(-) | | Ben Dooks, Thu, 07 Oct 2004 15:13:27 +0100 --- linux-2.6.9-rc3-bk5-rmktimer/arch/arm/mach-s3c2410/irq.c 2004-10-07 12:15:25.000000000 +0100 +++ linux-2.6.9-rc3-bk5-rmktimer-pm1/arch/arm/mach-s3c2410/irq.c 2004-10-05 23:39:43.000000000 +0100 @@ -33,9 +33,11 @@ * * 05-Oct-2004 Ben Dooks * Tidy up KF's patch and sort out new release + * + * 05-Oct-2004 Ben Dooks + * Add support for power management controls */ - #include #include #include @@ -52,10 +54,73 @@ #include #include +#include "pm.h" #define irqdbf(x...) #define irqdbf2(x...) +#define EXTINT_OFF (IRQ_EINT4 - 4) + +/* wakeup irq control */ + +#ifdef CONFIG_PM + +/* state for IRQs over sleep */ + +/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources + * + * set bit to 1 in allow bitfield to enable the wakeup settings on it +*/ + +unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL; +unsigned long s3c_irqwake_intmask = 0xffffffffL; +unsigned long s3c_irqwake_eintallow = 0x0000fff0L; +unsigned long s3c_irqwake_eintmask = 0xffffffffL; + +static int +s3c_irq_wake(unsigned int irqno, unsigned int state) +{ + unsigned long irqbit = 1 << (irqno - IRQ_EINT0); + + if (!(s3c_irqwake_intallow & irqbit)) + return -ENOENT; + + printk(KERN_INFO "wake %s for irq %d\n", + state ? "enabled" : "disabled", irqno); + + if (!state) + s3c_irqwake_intmask |= irqbit; + else + s3c_irqwake_intmask &= irqbit; + + return 0; +} + +static int +s3c_irqext_wake(unsigned int irqno, unsigned int state) +{ + unsigned long bit = 1L << (irqno - EXTINT_OFF); + + if (!(s3c_irqwake_eintallow & bit)) + return -ENOENT; + + printk(KERN_INFO "wake %s for irq %d\n", + state ? "enabled" : "disabled", irqno); + + if (!state) + s3c_irqwake_eintmask |= bit; + else + s3c_irqwake_eintmask &= ~bit; + + return 0; +} + +#else +#define s3c_irqext_wake NULL +#define s3c_irq_wake NULL +#endif + + static void s3c_irq_mask(unsigned int irqno) { @@ -109,21 +174,21 @@ static struct irqchip s3c_irq_level_chip = { .ack = s3c_irq_maskack, .mask = s3c_irq_mask, - .unmask = s3c_irq_unmask + .unmask = s3c_irq_unmask, + .wake = s3c_irq_wake }; static struct irqchip s3c_irq_chip = { .ack = s3c_irq_ack, .mask = s3c_irq_mask, - .unmask = s3c_irq_unmask + .unmask = s3c_irq_unmask, + .wake = s3c_irq_wake }; /* S3C2410_EINTMASK * S3C2410_EINTPEND */ -#define EXTINT_OFF (IRQ_EINT4 - 4) - static void s3c_irqext_mask(unsigned int irqno) { @@ -276,14 +341,16 @@ .mask = s3c_irqext_mask, .unmask = s3c_irqext_unmask, .ack = s3c_irqext_ack, - .type = s3c_irqext_type + .type = s3c_irqext_type, + .wake = s3c_irqext_wake }; static struct irqchip s3c_irq_eint0t4 = { .ack = s3c_irq_ack, .mask = s3c_irq_mask, .unmask = s3c_irq_unmask, - .type = s3c_irqext_type + .wake = s3c_irq_wake, + .type = s3c_irqext_type, }; /* mask values for the parent registers for each of the interrupt types */