xref: /openbmc/linux/arch/arm/mach-pxa/irq.c (revision 53665a50)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  *  linux/arch/arm/mach-pxa/irq.c
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  *  Generic PXA IRQ handling, GPIO IRQ demultiplexing, etc.
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  *  Author:	Nicolas Pitre
71da177e4SLinus Torvalds  *  Created:	Jun 15, 2001
81da177e4SLinus Torvalds  *  Copyright:	MontaVista Software Inc.
91da177e4SLinus Torvalds  *
101da177e4SLinus Torvalds  *  This program is free software; you can redistribute it and/or modify
111da177e4SLinus Torvalds  *  it under the terms of the GNU General Public License version 2 as
121da177e4SLinus Torvalds  *  published by the Free Software Foundation.
131da177e4SLinus Torvalds  */
141da177e4SLinus Torvalds 
151da177e4SLinus Torvalds #include <linux/init.h>
161da177e4SLinus Torvalds #include <linux/module.h>
171da177e4SLinus Torvalds #include <linux/interrupt.h>
181da177e4SLinus Torvalds 
191da177e4SLinus Torvalds #include <asm/hardware.h>
201da177e4SLinus Torvalds #include <asm/irq.h>
211da177e4SLinus Torvalds #include <asm/mach/irq.h>
221da177e4SLinus Torvalds #include <asm/arch/pxa-regs.h>
231da177e4SLinus Torvalds 
241da177e4SLinus Torvalds #include "generic.h"
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds 
271da177e4SLinus Torvalds /*
281da177e4SLinus Torvalds  * This is for peripheral IRQs internal to the PXA chip.
291da177e4SLinus Torvalds  */
301da177e4SLinus Torvalds 
311da177e4SLinus Torvalds static void pxa_mask_low_irq(unsigned int irq)
321da177e4SLinus Torvalds {
33486c9551SEric Miao 	ICMR &= ~(1 << irq);
341da177e4SLinus Torvalds }
351da177e4SLinus Torvalds 
361da177e4SLinus Torvalds static void pxa_unmask_low_irq(unsigned int irq)
371da177e4SLinus Torvalds {
38486c9551SEric Miao 	ICMR |= (1 << irq);
391da177e4SLinus Torvalds }
401da177e4SLinus Torvalds 
414fe4a2bfSPhilipp Zabel static int pxa_set_wake(unsigned int irq, unsigned int on)
424fe4a2bfSPhilipp Zabel {
434fe4a2bfSPhilipp Zabel 	u32	mask;
444fe4a2bfSPhilipp Zabel 
454fe4a2bfSPhilipp Zabel 	switch (irq) {
464fe4a2bfSPhilipp Zabel 	case IRQ_RTCAlrm:
474fe4a2bfSPhilipp Zabel 		mask = PWER_RTC;
484fe4a2bfSPhilipp Zabel 		break;
494fe4a2bfSPhilipp Zabel #ifdef CONFIG_PXA27x
504fe4a2bfSPhilipp Zabel 	/* REVISIT can handle USBH1, USBH2, USB, MSL, USIM, ... */
514fe4a2bfSPhilipp Zabel #endif
524fe4a2bfSPhilipp Zabel 	default:
534fe4a2bfSPhilipp Zabel 		return -EINVAL;
544fe4a2bfSPhilipp Zabel 	}
554fe4a2bfSPhilipp Zabel 	if (on)
564fe4a2bfSPhilipp Zabel 		PWER |= mask;
574fe4a2bfSPhilipp Zabel 	else
584fe4a2bfSPhilipp Zabel 		PWER &= ~mask;
594fe4a2bfSPhilipp Zabel 	return 0;
604fe4a2bfSPhilipp Zabel }
614fe4a2bfSPhilipp Zabel 
6238c677cbSDavid Brownell static struct irq_chip pxa_internal_chip_low = {
6338c677cbSDavid Brownell 	.name		= "SC",
641da177e4SLinus Torvalds 	.ack		= pxa_mask_low_irq,
651da177e4SLinus Torvalds 	.mask		= pxa_mask_low_irq,
661da177e4SLinus Torvalds 	.unmask		= pxa_unmask_low_irq,
674fe4a2bfSPhilipp Zabel 	.set_wake	= pxa_set_wake,
681da177e4SLinus Torvalds };
691da177e4SLinus Torvalds 
7053665a50SEric Miao void __init pxa_init_irq_low(void)
7153665a50SEric Miao {
7253665a50SEric Miao 	int irq;
7353665a50SEric Miao 
7453665a50SEric Miao 	/* disable all IRQs */
7553665a50SEric Miao 	ICMR = 0;
7653665a50SEric Miao 
7753665a50SEric Miao 	/* all IRQs are IRQ, not FIQ */
7853665a50SEric Miao 	ICLR = 0;
7953665a50SEric Miao 
8053665a50SEric Miao 	/* only unmasked interrupts kick us out of idle */
8153665a50SEric Miao 	ICCR = 1;
8253665a50SEric Miao 
8353665a50SEric Miao 	for (irq = PXA_IRQ(0); irq <= PXA_IRQ(31); irq++) {
8453665a50SEric Miao 		set_irq_chip(irq, &pxa_internal_chip_low);
8553665a50SEric Miao 		set_irq_handler(irq, handle_level_irq);
8653665a50SEric Miao 		set_irq_flags(irq, IRQF_VALID);
8753665a50SEric Miao 	}
8853665a50SEric Miao }
8953665a50SEric Miao 
90c08b7b3eSEric Miao #ifdef CONFIG_PXA27x
911da177e4SLinus Torvalds 
921da177e4SLinus Torvalds /*
931da177e4SLinus Torvalds  * This is for the second set of internal IRQs as found on the PXA27x.
941da177e4SLinus Torvalds  */
951da177e4SLinus Torvalds 
961da177e4SLinus Torvalds static void pxa_mask_high_irq(unsigned int irq)
971da177e4SLinus Torvalds {
98486c9551SEric Miao 	ICMR2 &= ~(1 << (irq - 32));
991da177e4SLinus Torvalds }
1001da177e4SLinus Torvalds 
1011da177e4SLinus Torvalds static void pxa_unmask_high_irq(unsigned int irq)
1021da177e4SLinus Torvalds {
103486c9551SEric Miao 	ICMR2 |= (1 << (irq - 32));
1041da177e4SLinus Torvalds }
1051da177e4SLinus Torvalds 
10638c677cbSDavid Brownell static struct irq_chip pxa_internal_chip_high = {
10738c677cbSDavid Brownell 	.name		= "SC-hi",
1081da177e4SLinus Torvalds 	.ack		= pxa_mask_high_irq,
1091da177e4SLinus Torvalds 	.mask		= pxa_mask_high_irq,
1101da177e4SLinus Torvalds 	.unmask		= pxa_unmask_high_irq,
1111da177e4SLinus Torvalds };
1121da177e4SLinus Torvalds 
113c08b7b3eSEric Miao void __init pxa_init_irq_high(void)
114c08b7b3eSEric Miao {
115c08b7b3eSEric Miao 	int irq;
116c08b7b3eSEric Miao 
117c08b7b3eSEric Miao 	ICMR2 = 0;
118c08b7b3eSEric Miao 	ICLR2 = 0;
119c08b7b3eSEric Miao 
120c08b7b3eSEric Miao 	for (irq = PXA_IRQ(32); irq < PXA_IRQ(64); irq++) {
121c08b7b3eSEric Miao 		set_irq_chip(irq, &pxa_internal_chip_high);
122c08b7b3eSEric Miao 		set_irq_handler(irq, handle_level_irq);
123c08b7b3eSEric Miao 		set_irq_flags(irq, IRQF_VALID);
124c08b7b3eSEric Miao 	}
125c08b7b3eSEric Miao }
1261da177e4SLinus Torvalds #endif
1271da177e4SLinus Torvalds 
1284fe4a2bfSPhilipp Zabel /* Note that if an input/irq line ever gets changed to an output during
1294fe4a2bfSPhilipp Zabel  * suspend, the relevant PWER, PRER, and PFER bits should be cleared.
1304fe4a2bfSPhilipp Zabel  */
1314fe4a2bfSPhilipp Zabel #ifdef CONFIG_PXA27x
1324fe4a2bfSPhilipp Zabel 
1334fe4a2bfSPhilipp Zabel /* PXA27x:  Various gpios can issue wakeup events.  This logic only
1344fe4a2bfSPhilipp Zabel  * handles the simple cases, not the WEMUX2 and WEMUX3 options
1354fe4a2bfSPhilipp Zabel  */
1364fe4a2bfSPhilipp Zabel #define PXA27x_GPIO_NOWAKE_MASK \
1374fe4a2bfSPhilipp Zabel 	((1 << 8) | (1 << 7) | (1 << 6) | (1 << 5) | (1 << 2))
1384fe4a2bfSPhilipp Zabel #define	WAKEMASK(gpio) \
1394fe4a2bfSPhilipp Zabel 	(((gpio) <= 15) \
1404fe4a2bfSPhilipp Zabel 		? ((1 << (gpio)) & ~PXA27x_GPIO_NOWAKE_MASK) \
1414fe4a2bfSPhilipp Zabel 		: ((gpio == 35) ? (1 << 24) : 0))
1424fe4a2bfSPhilipp Zabel #else
1434fe4a2bfSPhilipp Zabel 
1444fe4a2bfSPhilipp Zabel /* pxa 210, 250, 255, 26x:  gpios 0..15 can issue wakeups */
1454fe4a2bfSPhilipp Zabel #define	WAKEMASK(gpio) (((gpio) <= 15) ? (1 << (gpio)) : 0)
1464fe4a2bfSPhilipp Zabel #endif
1474fe4a2bfSPhilipp Zabel 
1481da177e4SLinus Torvalds /*
1491da177e4SLinus Torvalds  * PXA GPIO edge detection for IRQs:
1501da177e4SLinus Torvalds  * IRQs are generated on Falling-Edge, Rising-Edge, or both.
1511da177e4SLinus Torvalds  * Use this instead of directly setting GRER/GFER.
1521da177e4SLinus Torvalds  */
1531da177e4SLinus Torvalds 
1541da177e4SLinus Torvalds static long GPIO_IRQ_rising_edge[4];
1551da177e4SLinus Torvalds static long GPIO_IRQ_falling_edge[4];
1561da177e4SLinus Torvalds static long GPIO_IRQ_mask[4];
1571da177e4SLinus Torvalds 
1581da177e4SLinus Torvalds static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
1591da177e4SLinus Torvalds {
1601da177e4SLinus Torvalds 	int gpio, idx;
1614fe4a2bfSPhilipp Zabel 	u32 mask;
1621da177e4SLinus Torvalds 
1631da177e4SLinus Torvalds 	gpio = IRQ_TO_GPIO(irq);
1641da177e4SLinus Torvalds 	idx = gpio >> 5;
1654fe4a2bfSPhilipp Zabel 	mask = WAKEMASK(gpio);
1661da177e4SLinus Torvalds 
1671da177e4SLinus Torvalds 	if (type == IRQT_PROBE) {
1681da177e4SLinus Torvalds 	    /* Don't mess with enabled GPIOs using preconfigured edges or
169e033108bSGuennadi Liakhovetski 	       GPIOs set to alternate function or to output during probe */
170e033108bSGuennadi Liakhovetski 		if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx] | GPDR(gpio)) &
1711da177e4SLinus Torvalds 		    GPIO_bit(gpio))
1721da177e4SLinus Torvalds 			return 0;
1731da177e4SLinus Torvalds 		if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2)))
1741da177e4SLinus Torvalds 			return 0;
1751da177e4SLinus Torvalds 		type = __IRQT_RISEDGE | __IRQT_FALEDGE;
1761da177e4SLinus Torvalds 	}
1771da177e4SLinus Torvalds 
1781da177e4SLinus Torvalds 	/* printk(KERN_DEBUG "IRQ%d (GPIO%d): ", irq, gpio); */
1791da177e4SLinus Torvalds 
1801da177e4SLinus Torvalds 	pxa_gpio_mode(gpio | GPIO_IN);
1811da177e4SLinus Torvalds 
1821da177e4SLinus Torvalds 	if (type & __IRQT_RISEDGE) {
1831da177e4SLinus Torvalds 		/* printk("rising "); */
1841da177e4SLinus Torvalds 		__set_bit (gpio, GPIO_IRQ_rising_edge);
1854fe4a2bfSPhilipp Zabel 		PRER |= mask;
1864fe4a2bfSPhilipp Zabel 	} else {
1871da177e4SLinus Torvalds 		__clear_bit (gpio, GPIO_IRQ_rising_edge);
1884fe4a2bfSPhilipp Zabel 		PRER &= ~mask;
1894fe4a2bfSPhilipp Zabel 	}
1901da177e4SLinus Torvalds 
1911da177e4SLinus Torvalds 	if (type & __IRQT_FALEDGE) {
1921da177e4SLinus Torvalds 		/* printk("falling "); */
1931da177e4SLinus Torvalds 		__set_bit (gpio, GPIO_IRQ_falling_edge);
1944fe4a2bfSPhilipp Zabel 		PFER |= mask;
1954fe4a2bfSPhilipp Zabel 	} else {
1961da177e4SLinus Torvalds 		__clear_bit (gpio, GPIO_IRQ_falling_edge);
1974fe4a2bfSPhilipp Zabel 		PFER &= ~mask;
1984fe4a2bfSPhilipp Zabel 	}
1991da177e4SLinus Torvalds 
2001da177e4SLinus Torvalds 	/* printk("edges\n"); */
2011da177e4SLinus Torvalds 
2021da177e4SLinus Torvalds 	GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx];
2031da177e4SLinus Torvalds 	GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx];
2041da177e4SLinus Torvalds 	return 0;
2051da177e4SLinus Torvalds }
2061da177e4SLinus Torvalds 
2071da177e4SLinus Torvalds /*
2081da177e4SLinus Torvalds  * GPIO IRQs must be acknowledged.  This is for GPIO 0 and 1.
2091da177e4SLinus Torvalds  */
2101da177e4SLinus Torvalds 
2111da177e4SLinus Torvalds static void pxa_ack_low_gpio(unsigned int irq)
2121da177e4SLinus Torvalds {
2131da177e4SLinus Torvalds 	GEDR0 = (1 << (irq - IRQ_GPIO0));
2141da177e4SLinus Torvalds }
2151da177e4SLinus Torvalds 
2164fe4a2bfSPhilipp Zabel static int pxa_set_gpio_wake(unsigned int irq, unsigned int on)
2174fe4a2bfSPhilipp Zabel {
2184fe4a2bfSPhilipp Zabel 	int	gpio = IRQ_TO_GPIO(irq);
2194fe4a2bfSPhilipp Zabel 	u32	mask = WAKEMASK(gpio);
2204fe4a2bfSPhilipp Zabel 
2214fe4a2bfSPhilipp Zabel 	if (!mask)
2224fe4a2bfSPhilipp Zabel 		return -EINVAL;
2234fe4a2bfSPhilipp Zabel 
2244fe4a2bfSPhilipp Zabel 	if (on)
2254fe4a2bfSPhilipp Zabel 		PWER |= mask;
2264fe4a2bfSPhilipp Zabel 	else
2274fe4a2bfSPhilipp Zabel 		PWER &= ~mask;
2284fe4a2bfSPhilipp Zabel 	return 0;
2294fe4a2bfSPhilipp Zabel }
2304fe4a2bfSPhilipp Zabel 
2314fe4a2bfSPhilipp Zabel 
23238c677cbSDavid Brownell static struct irq_chip pxa_low_gpio_chip = {
23338c677cbSDavid Brownell 	.name		= "GPIO-l",
2341da177e4SLinus Torvalds 	.ack		= pxa_ack_low_gpio,
2351da177e4SLinus Torvalds 	.mask		= pxa_mask_low_irq,
2361da177e4SLinus Torvalds 	.unmask		= pxa_unmask_low_irq,
2377801907bSRussell King 	.set_type	= pxa_gpio_irq_type,
2384fe4a2bfSPhilipp Zabel 	.set_wake	= pxa_set_gpio_wake,
2391da177e4SLinus Torvalds };
2401da177e4SLinus Torvalds 
2411da177e4SLinus Torvalds /*
2421da177e4SLinus Torvalds  * Demux handler for GPIO>=2 edge detect interrupts
2431da177e4SLinus Torvalds  */
2441da177e4SLinus Torvalds 
24510dd5ce2SRussell King static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc)
2461da177e4SLinus Torvalds {
2471da177e4SLinus Torvalds 	unsigned int mask;
2481da177e4SLinus Torvalds 	int loop;
2491da177e4SLinus Torvalds 
2501da177e4SLinus Torvalds 	do {
2511da177e4SLinus Torvalds 		loop = 0;
2521da177e4SLinus Torvalds 
2531da177e4SLinus Torvalds 		mask = GEDR0 & ~3;
2541da177e4SLinus Torvalds 		if (mask) {
2551da177e4SLinus Torvalds 			GEDR0 = mask;
2561da177e4SLinus Torvalds 			irq = IRQ_GPIO(2);
2571da177e4SLinus Torvalds 			desc = irq_desc + irq;
2581da177e4SLinus Torvalds 			mask >>= 2;
2591da177e4SLinus Torvalds 			do {
2601da177e4SLinus Torvalds 				if (mask & 1)
2610cd61b68SLinus Torvalds 					desc_handle_irq(irq, desc);
2621da177e4SLinus Torvalds 				irq++;
2631da177e4SLinus Torvalds 				desc++;
2641da177e4SLinus Torvalds 				mask >>= 1;
2651da177e4SLinus Torvalds 			} while (mask);
2661da177e4SLinus Torvalds 			loop = 1;
2671da177e4SLinus Torvalds 		}
2681da177e4SLinus Torvalds 
2691da177e4SLinus Torvalds 		mask = GEDR1;
2701da177e4SLinus Torvalds 		if (mask) {
2711da177e4SLinus Torvalds 			GEDR1 = mask;
2721da177e4SLinus Torvalds 			irq = IRQ_GPIO(32);
2731da177e4SLinus Torvalds 			desc = irq_desc + irq;
2741da177e4SLinus Torvalds 			do {
2751da177e4SLinus Torvalds 				if (mask & 1)
2760cd61b68SLinus Torvalds 					desc_handle_irq(irq, desc);
2771da177e4SLinus Torvalds 				irq++;
2781da177e4SLinus Torvalds 				desc++;
2791da177e4SLinus Torvalds 				mask >>= 1;
2801da177e4SLinus Torvalds 			} while (mask);
2811da177e4SLinus Torvalds 			loop = 1;
2821da177e4SLinus Torvalds 		}
2831da177e4SLinus Torvalds 
2841da177e4SLinus Torvalds 		mask = GEDR2;
2851da177e4SLinus Torvalds 		if (mask) {
2861da177e4SLinus Torvalds 			GEDR2 = mask;
2871da177e4SLinus Torvalds 			irq = IRQ_GPIO(64);
2881da177e4SLinus Torvalds 			desc = irq_desc + irq;
2891da177e4SLinus Torvalds 			do {
2901da177e4SLinus Torvalds 				if (mask & 1)
2910cd61b68SLinus Torvalds 					desc_handle_irq(irq, desc);
2921da177e4SLinus Torvalds 				irq++;
2931da177e4SLinus Torvalds 				desc++;
2941da177e4SLinus Torvalds 				mask >>= 1;
2951da177e4SLinus Torvalds 			} while (mask);
2961da177e4SLinus Torvalds 			loop = 1;
2971da177e4SLinus Torvalds 		}
2981da177e4SLinus Torvalds 
2991da177e4SLinus Torvalds #if PXA_LAST_GPIO >= 96
3001da177e4SLinus Torvalds 		mask = GEDR3;
3011da177e4SLinus Torvalds 		if (mask) {
3021da177e4SLinus Torvalds 			GEDR3 = mask;
3031da177e4SLinus Torvalds 			irq = IRQ_GPIO(96);
3041da177e4SLinus Torvalds 			desc = irq_desc + irq;
3051da177e4SLinus Torvalds 			do {
3061da177e4SLinus Torvalds 				if (mask & 1)
3070cd61b68SLinus Torvalds 					desc_handle_irq(irq, desc);
3081da177e4SLinus Torvalds 				irq++;
3091da177e4SLinus Torvalds 				desc++;
3101da177e4SLinus Torvalds 				mask >>= 1;
3111da177e4SLinus Torvalds 			} while (mask);
3121da177e4SLinus Torvalds 			loop = 1;
3131da177e4SLinus Torvalds 		}
3141da177e4SLinus Torvalds #endif
3151da177e4SLinus Torvalds 	} while (loop);
3161da177e4SLinus Torvalds }
3171da177e4SLinus Torvalds 
3181da177e4SLinus Torvalds static void pxa_ack_muxed_gpio(unsigned int irq)
3191da177e4SLinus Torvalds {
3201da177e4SLinus Torvalds 	int gpio = irq - IRQ_GPIO(2) + 2;
3211da177e4SLinus Torvalds 	GEDR(gpio) = GPIO_bit(gpio);
3221da177e4SLinus Torvalds }
3231da177e4SLinus Torvalds 
3241da177e4SLinus Torvalds static void pxa_mask_muxed_gpio(unsigned int irq)
3251da177e4SLinus Torvalds {
3261da177e4SLinus Torvalds 	int gpio = irq - IRQ_GPIO(2) + 2;
3271da177e4SLinus Torvalds 	__clear_bit(gpio, GPIO_IRQ_mask);
3281da177e4SLinus Torvalds 	GRER(gpio) &= ~GPIO_bit(gpio);
3291da177e4SLinus Torvalds 	GFER(gpio) &= ~GPIO_bit(gpio);
3301da177e4SLinus Torvalds }
3311da177e4SLinus Torvalds 
3321da177e4SLinus Torvalds static void pxa_unmask_muxed_gpio(unsigned int irq)
3331da177e4SLinus Torvalds {
3341da177e4SLinus Torvalds 	int gpio = irq - IRQ_GPIO(2) + 2;
3351da177e4SLinus Torvalds 	int idx = gpio >> 5;
3361da177e4SLinus Torvalds 	__set_bit(gpio, GPIO_IRQ_mask);
3371da177e4SLinus Torvalds 	GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx];
3381da177e4SLinus Torvalds 	GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx];
3391da177e4SLinus Torvalds }
3401da177e4SLinus Torvalds 
34138c677cbSDavid Brownell static struct irq_chip pxa_muxed_gpio_chip = {
34238c677cbSDavid Brownell 	.name		= "GPIO",
3431da177e4SLinus Torvalds 	.ack		= pxa_ack_muxed_gpio,
3441da177e4SLinus Torvalds 	.mask		= pxa_mask_muxed_gpio,
3451da177e4SLinus Torvalds 	.unmask		= pxa_unmask_muxed_gpio,
3467801907bSRussell King 	.set_type	= pxa_gpio_irq_type,
3474fe4a2bfSPhilipp Zabel 	.set_wake	= pxa_set_gpio_wake,
3481da177e4SLinus Torvalds };
3491da177e4SLinus Torvalds 
3501da177e4SLinus Torvalds void __init pxa_init_irq(void)
3511da177e4SLinus Torvalds {
3521da177e4SLinus Torvalds 	int irq;
3531da177e4SLinus Torvalds 
3541da177e4SLinus Torvalds 	/* clear all GPIO edge detects */
3551da177e4SLinus Torvalds 	GFER0 = 0;
3561da177e4SLinus Torvalds 	GFER1 = 0;
3571da177e4SLinus Torvalds 	GFER2 = 0;
3581da177e4SLinus Torvalds 	GRER0 = 0;
3591da177e4SLinus Torvalds 	GRER1 = 0;
3601da177e4SLinus Torvalds 	GRER2 = 0;
3611da177e4SLinus Torvalds 	GEDR0 = GEDR0;
3621da177e4SLinus Torvalds 	GEDR1 = GEDR1;
3631da177e4SLinus Torvalds 	GEDR2 = GEDR2;
3641da177e4SLinus Torvalds 
3651da177e4SLinus Torvalds #ifdef CONFIG_PXA27x
3661da177e4SLinus Torvalds 	/* And similarly for the extra regs on the PXA27x */
3671da177e4SLinus Torvalds 	GFER3 = 0;
3681da177e4SLinus Torvalds 	GRER3 = 0;
3691da177e4SLinus Torvalds 	GEDR3 = GEDR3;
3701da177e4SLinus Torvalds #endif
3711da177e4SLinus Torvalds 
3721da177e4SLinus Torvalds 	/* GPIO 0 and 1 must have their mask bit always set */
3731da177e4SLinus Torvalds 	GPIO_IRQ_mask[0] = 3;
3741da177e4SLinus Torvalds 
37553665a50SEric Miao 	pxa_init_irq_low();
376c08b7b3eSEric Miao #ifdef CONFIG_PXA27x
377c08b7b3eSEric Miao 	pxa_init_irq_high();
3781da177e4SLinus Torvalds #endif
3791da177e4SLinus Torvalds 
3801da177e4SLinus Torvalds 	for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
3811da177e4SLinus Torvalds 		set_irq_chip(irq, &pxa_low_gpio_chip);
38210dd5ce2SRussell King 		set_irq_handler(irq, handle_edge_irq);
3831da177e4SLinus Torvalds 		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
3841da177e4SLinus Torvalds 	}
3851da177e4SLinus Torvalds 
3861da177e4SLinus Torvalds 	for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(PXA_LAST_GPIO); irq++) {
3871da177e4SLinus Torvalds 		set_irq_chip(irq, &pxa_muxed_gpio_chip);
38810dd5ce2SRussell King 		set_irq_handler(irq, handle_edge_irq);
3891da177e4SLinus Torvalds 		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
3901da177e4SLinus Torvalds 	}
3911da177e4SLinus Torvalds 
3921da177e4SLinus Torvalds 	/* Install handler for GPIO>=2 edge detect interrupts */
3931da177e4SLinus Torvalds 	set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low);
3941da177e4SLinus Torvalds 	set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler);
3951da177e4SLinus Torvalds }
396