X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=arch%2Farm%2Fmach-pxa%2Firq.c;h=07acb45b16ea83ac26be925293943a1f14def698;hb=2c8086a5d073e8e72122a5b84febde236a39845b;hp=4619d5fe606c2bad027ee2bf023f6c045d3ab882;hpb=5f757f91e70a97eda8f0cc13bddc853209b2d173;p=karo-tx-linux.git diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c index 4619d5fe606c..07acb45b16ea 100644 --- a/arch/arm/mach-pxa/irq.c +++ b/arch/arm/mach-pxa/irq.c @@ -30,33 +30,12 @@ static void pxa_mask_low_irq(unsigned int irq) { - ICMR &= ~(1 << (irq + PXA_IRQ_SKIP)); + ICMR &= ~(1 << irq); } static void pxa_unmask_low_irq(unsigned int irq) { - ICMR |= (1 << (irq + PXA_IRQ_SKIP)); -} - -static int pxa_set_wake(unsigned int irq, unsigned int on) -{ - u32 mask; - - switch (irq) { - case IRQ_RTCAlrm: - mask = PWER_RTC; - break; -#ifdef CONFIG_PXA27x - /* REVISIT can handle USBH1, USBH2, USB, MSL, USIM, ... */ -#endif - default: - return -EINVAL; - } - if (on) - PWER |= mask; - else - PWER &= ~mask; - return 0; + ICMR |= (1 << irq); } static struct irq_chip pxa_internal_chip_low = { @@ -64,10 +43,29 @@ static struct irq_chip pxa_internal_chip_low = { .ack = pxa_mask_low_irq, .mask = pxa_mask_low_irq, .unmask = pxa_unmask_low_irq, - .set_wake = pxa_set_wake, }; -#if PXA_INTERNAL_IRQS > 32 +void __init pxa_init_irq_low(void) +{ + int irq; + + /* disable all IRQs */ + ICMR = 0; + + /* all IRQs are IRQ, not FIQ */ + ICLR = 0; + + /* only unmasked interrupts kick us out of idle */ + ICCR = 1; + + for (irq = PXA_IRQ(0); irq <= PXA_IRQ(31); irq++) { + set_irq_chip(irq, &pxa_internal_chip_low); + set_irq_handler(irq, handle_level_irq); + set_irq_flags(irq, IRQF_VALID); + } +} + +#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx) /* * This is for the second set of internal IRQs as found on the PXA27x. @@ -75,12 +73,12 @@ static struct irq_chip pxa_internal_chip_low = { static void pxa_mask_high_irq(unsigned int irq) { - ICMR2 &= ~(1 << (irq - 32 + PXA_IRQ_SKIP)); + ICMR2 &= ~(1 << (irq - 32)); } static void pxa_unmask_high_irq(unsigned int irq) { - ICMR2 |= (1 << (irq - 32 + PXA_IRQ_SKIP)); + ICMR2 |= (1 << (irq - 32)); } static struct irq_chip pxa_internal_chip_high = { @@ -90,26 +88,19 @@ static struct irq_chip pxa_internal_chip_high = { .unmask = pxa_unmask_high_irq, }; -#endif +void __init pxa_init_irq_high(void) +{ + int irq; -/* Note that if an input/irq line ever gets changed to an output during - * suspend, the relevant PWER, PRER, and PFER bits should be cleared. - */ -#ifdef CONFIG_PXA27x + ICMR2 = 0; + ICLR2 = 0; -/* PXA27x: Various gpios can issue wakeup events. This logic only - * handles the simple cases, not the WEMUX2 and WEMUX3 options - */ -#define PXA27x_GPIO_NOWAKE_MASK \ - ((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2)) -#define WAKEMASK(gpio) \ - (((gpio) <= 15) \ - ? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \ - : ((gpio == 35) ? (1 << 24) : 0)) -#else - -/* pxa 210, 250, 255, 26x: gpios 0..15 can issue wakeups */ -#define WAKEMASK(gpio) (((gpio) <= 15) ? (1 << (gpio)) : 0) + for (irq = PXA_IRQ(32); irq < PXA_IRQ(64); irq++) { + set_irq_chip(irq, &pxa_internal_chip_high); + set_irq_handler(irq, handle_level_irq); + set_irq_flags(irq, IRQF_VALID); + } +} #endif /* @@ -125,11 +116,9 @@ static long GPIO_IRQ_mask[4]; static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) { int gpio, idx; - u32 mask; gpio = IRQ_TO_GPIO(irq); idx = gpio >> 5; - mask = WAKEMASK(gpio); if (type == IRQT_PROBE) { /* Don't mess with enabled GPIOs using preconfigured edges or @@ -149,19 +138,15 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) if (type & __IRQT_RISEDGE) { /* printk("rising "); */ __set_bit (gpio, GPIO_IRQ_rising_edge); - PRER |= mask; } else { __clear_bit (gpio, GPIO_IRQ_rising_edge); - PRER &= ~mask; } if (type & __IRQT_FALEDGE) { /* printk("falling "); */ __set_bit (gpio, GPIO_IRQ_falling_edge); - PFER |= mask; } else { __clear_bit (gpio, GPIO_IRQ_falling_edge); - PFER &= ~mask; } /* printk("edges\n"); */ @@ -180,29 +165,12 @@ static void pxa_ack_low_gpio(unsigned int irq) GEDR0 = (1 << (irq - IRQ_GPIO0)); } -static int pxa_set_gpio_wake(unsigned int irq, unsigned int on) -{ - int gpio = IRQ_TO_GPIO(irq); - u32 mask = WAKEMASK(gpio); - - if (!mask) - return -EINVAL; - - if (on) - PWER |= mask; - else - PWER &= ~mask; - return 0; -} - - static struct irq_chip pxa_low_gpio_chip = { .name = "GPIO-l", .ack = pxa_ack_low_gpio, .mask = pxa_mask_low_irq, .unmask = pxa_unmask_low_irq, .set_type = pxa_gpio_irq_type, - .set_wake = pxa_set_gpio_wake, }; /* @@ -217,7 +185,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) do { loop = 0; - mask = GEDR0 & ~3; + mask = GEDR0 & GPIO_IRQ_mask[0] & ~3; if (mask) { GEDR0 = mask; irq = IRQ_GPIO(2); @@ -233,7 +201,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) loop = 1; } - mask = GEDR1; + mask = GEDR1 & GPIO_IRQ_mask[1]; if (mask) { GEDR1 = mask; irq = IRQ_GPIO(32); @@ -248,7 +216,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) loop = 1; } - mask = GEDR2; + mask = GEDR2 & GPIO_IRQ_mask[2]; if (mask) { GEDR2 = mask; irq = IRQ_GPIO(64); @@ -263,8 +231,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) loop = 1; } -#if PXA_LAST_GPIO >= 96 - mask = GEDR3; + mask = GEDR3 & GPIO_IRQ_mask[3]; if (mask) { GEDR3 = mask; irq = IRQ_GPIO(96); @@ -278,7 +245,6 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) } while (mask); loop = 1; } -#endif } while (loop); } @@ -311,67 +277,31 @@ static struct irq_chip pxa_muxed_gpio_chip = { .mask = pxa_mask_muxed_gpio, .unmask = pxa_unmask_muxed_gpio, .set_type = pxa_gpio_irq_type, - .set_wake = pxa_set_gpio_wake, }; - -void __init pxa_init_irq(void) +void __init pxa_init_irq_gpio(int gpio_nr) { - int irq; - - /* disable all IRQs */ - ICMR = 0; + int irq, i; - /* all IRQs are IRQ, not FIQ */ - ICLR = 0; + pxa_last_gpio = gpio_nr - 1; /* clear all GPIO edge detects */ - GFER0 = 0; - GFER1 = 0; - GFER2 = 0; - GRER0 = 0; - GRER1 = 0; - GRER2 = 0; - GEDR0 = GEDR0; - GEDR1 = GEDR1; - GEDR2 = GEDR2; - -#ifdef CONFIG_PXA27x - /* And similarly for the extra regs on the PXA27x */ - ICMR2 = 0; - ICLR2 = 0; - GFER3 = 0; - GRER3 = 0; - GEDR3 = GEDR3; -#endif - - /* only unmasked interrupts kick us out of idle */ - ICCR = 1; + for (i = 0; i < gpio_nr; i += 32) { + GFER(i) = 0; + GRER(i) = 0; + GEDR(i) = GEDR(i); + } /* GPIO 0 and 1 must have their mask bit always set */ GPIO_IRQ_mask[0] = 3; - for (irq = PXA_IRQ(PXA_IRQ_SKIP); irq <= PXA_IRQ(31); irq++) { - set_irq_chip(irq, &pxa_internal_chip_low); - set_irq_handler(irq, handle_level_irq); - set_irq_flags(irq, IRQF_VALID); - } - -#if PXA_INTERNAL_IRQS > 32 - for (irq = PXA_IRQ(32); irq < PXA_IRQ(PXA_INTERNAL_IRQS); irq++) { - set_irq_chip(irq, &pxa_internal_chip_high); - set_irq_handler(irq, handle_level_irq); - set_irq_flags(irq, IRQF_VALID); - } -#endif - for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) { set_irq_chip(irq, &pxa_low_gpio_chip); set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); } - for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(PXA_LAST_GPIO); irq++) { + for (irq = IRQ_GPIO(2); irq < IRQ_GPIO(gpio_nr); irq++) { set_irq_chip(irq, &pxa_muxed_gpio_chip); set_irq_handler(irq, handle_edge_irq); set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); @@ -381,3 +311,13 @@ void __init pxa_init_irq(void) set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low); set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler); } + +void __init pxa_init_irq_set_wake(int (*set_wake)(unsigned int, unsigned int)) +{ + pxa_internal_chip_low.set_wake = set_wake; +#ifdef CONFIG_PXA27x + pxa_internal_chip_high.set_wake = set_wake; +#endif + pxa_low_gpio_chip.set_wake = set_wake; + pxa_muxed_gpio_chip.set_wake = set_wake; +}