xref: /openbmc/linux/arch/arm/mach-pxa/irq.c (revision 1da177e4)
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 #include <linux/ptrace.h>
191da177e4SLinus Torvalds 
201da177e4SLinus Torvalds #include <asm/hardware.h>
211da177e4SLinus Torvalds #include <asm/irq.h>
221da177e4SLinus Torvalds #include <asm/mach/irq.h>
231da177e4SLinus Torvalds #include <asm/arch/pxa-regs.h>
241da177e4SLinus Torvalds 
251da177e4SLinus Torvalds #include "generic.h"
261da177e4SLinus Torvalds 
271da177e4SLinus Torvalds 
281da177e4SLinus Torvalds /*
291da177e4SLinus Torvalds  * This is for peripheral IRQs internal to the PXA chip.
301da177e4SLinus Torvalds  */
311da177e4SLinus Torvalds 
321da177e4SLinus Torvalds static void pxa_mask_low_irq(unsigned int irq)
331da177e4SLinus Torvalds {
341da177e4SLinus Torvalds 	ICMR &= ~(1 << (irq + PXA_IRQ_SKIP));
351da177e4SLinus Torvalds }
361da177e4SLinus Torvalds 
371da177e4SLinus Torvalds static void pxa_unmask_low_irq(unsigned int irq)
381da177e4SLinus Torvalds {
391da177e4SLinus Torvalds 	ICMR |= (1 << (irq + PXA_IRQ_SKIP));
401da177e4SLinus Torvalds }
411da177e4SLinus Torvalds 
421da177e4SLinus Torvalds static struct irqchip pxa_internal_chip_low = {
431da177e4SLinus Torvalds 	.ack		= pxa_mask_low_irq,
441da177e4SLinus Torvalds 	.mask		= pxa_mask_low_irq,
451da177e4SLinus Torvalds 	.unmask		= pxa_unmask_low_irq,
461da177e4SLinus Torvalds };
471da177e4SLinus Torvalds 
481da177e4SLinus Torvalds #if PXA_INTERNAL_IRQS > 32
491da177e4SLinus Torvalds 
501da177e4SLinus Torvalds /*
511da177e4SLinus Torvalds  * This is for the second set of internal IRQs as found on the PXA27x.
521da177e4SLinus Torvalds  */
531da177e4SLinus Torvalds 
541da177e4SLinus Torvalds static void pxa_mask_high_irq(unsigned int irq)
551da177e4SLinus Torvalds {
561da177e4SLinus Torvalds 	ICMR2 &= ~(1 << (irq - 32 + PXA_IRQ_SKIP));
571da177e4SLinus Torvalds }
581da177e4SLinus Torvalds 
591da177e4SLinus Torvalds static void pxa_unmask_high_irq(unsigned int irq)
601da177e4SLinus Torvalds {
611da177e4SLinus Torvalds 	ICMR2 |= (1 << (irq - 32 + PXA_IRQ_SKIP));
621da177e4SLinus Torvalds }
631da177e4SLinus Torvalds 
641da177e4SLinus Torvalds static struct irqchip pxa_internal_chip_high = {
651da177e4SLinus Torvalds 	.ack		= pxa_mask_high_irq,
661da177e4SLinus Torvalds 	.mask		= pxa_mask_high_irq,
671da177e4SLinus Torvalds 	.unmask		= pxa_unmask_high_irq,
681da177e4SLinus Torvalds };
691da177e4SLinus Torvalds 
701da177e4SLinus Torvalds #endif
711da177e4SLinus Torvalds 
721da177e4SLinus Torvalds /*
731da177e4SLinus Torvalds  * PXA GPIO edge detection for IRQs:
741da177e4SLinus Torvalds  * IRQs are generated on Falling-Edge, Rising-Edge, or both.
751da177e4SLinus Torvalds  * Use this instead of directly setting GRER/GFER.
761da177e4SLinus Torvalds  */
771da177e4SLinus Torvalds 
781da177e4SLinus Torvalds static long GPIO_IRQ_rising_edge[4];
791da177e4SLinus Torvalds static long GPIO_IRQ_falling_edge[4];
801da177e4SLinus Torvalds static long GPIO_IRQ_mask[4];
811da177e4SLinus Torvalds 
821da177e4SLinus Torvalds static int pxa_gpio_irq_type(unsigned int irq, unsigned int type)
831da177e4SLinus Torvalds {
841da177e4SLinus Torvalds 	int gpio, idx;
851da177e4SLinus Torvalds 
861da177e4SLinus Torvalds 	gpio = IRQ_TO_GPIO(irq);
871da177e4SLinus Torvalds 	idx = gpio >> 5;
881da177e4SLinus Torvalds 
891da177e4SLinus Torvalds 	if (type == IRQT_PROBE) {
901da177e4SLinus Torvalds 	    /* Don't mess with enabled GPIOs using preconfigured edges or
911da177e4SLinus Torvalds 	       GPIOs set to alternate function during probe */
921da177e4SLinus Torvalds 		if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx]) &
931da177e4SLinus Torvalds 		    GPIO_bit(gpio))
941da177e4SLinus Torvalds 			return 0;
951da177e4SLinus Torvalds 		if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2)))
961da177e4SLinus Torvalds 			return 0;
971da177e4SLinus Torvalds 		type = __IRQT_RISEDGE | __IRQT_FALEDGE;
981da177e4SLinus Torvalds 	}
991da177e4SLinus Torvalds 
1001da177e4SLinus Torvalds 	/* printk(KERN_DEBUG "IRQ%d (GPIO%d): ", irq, gpio); */
1011da177e4SLinus Torvalds 
1021da177e4SLinus Torvalds 	pxa_gpio_mode(gpio | GPIO_IN);
1031da177e4SLinus Torvalds 
1041da177e4SLinus Torvalds 	if (type & __IRQT_RISEDGE) {
1051da177e4SLinus Torvalds 		/* printk("rising "); */
1061da177e4SLinus Torvalds 		__set_bit (gpio, GPIO_IRQ_rising_edge);
1071da177e4SLinus Torvalds 	} else
1081da177e4SLinus Torvalds 		__clear_bit (gpio, GPIO_IRQ_rising_edge);
1091da177e4SLinus Torvalds 
1101da177e4SLinus Torvalds 	if (type & __IRQT_FALEDGE) {
1111da177e4SLinus Torvalds 		/* printk("falling "); */
1121da177e4SLinus Torvalds 		__set_bit (gpio, GPIO_IRQ_falling_edge);
1131da177e4SLinus Torvalds 	} else
1141da177e4SLinus Torvalds 		__clear_bit (gpio, GPIO_IRQ_falling_edge);
1151da177e4SLinus Torvalds 
1161da177e4SLinus Torvalds 	/* printk("edges\n"); */
1171da177e4SLinus Torvalds 
1181da177e4SLinus Torvalds 	GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx];
1191da177e4SLinus Torvalds 	GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx];
1201da177e4SLinus Torvalds 	return 0;
1211da177e4SLinus Torvalds }
1221da177e4SLinus Torvalds 
1231da177e4SLinus Torvalds /*
1241da177e4SLinus Torvalds  * GPIO IRQs must be acknowledged.  This is for GPIO 0 and 1.
1251da177e4SLinus Torvalds  */
1261da177e4SLinus Torvalds 
1271da177e4SLinus Torvalds static void pxa_ack_low_gpio(unsigned int irq)
1281da177e4SLinus Torvalds {
1291da177e4SLinus Torvalds 	GEDR0 = (1 << (irq - IRQ_GPIO0));
1301da177e4SLinus Torvalds }
1311da177e4SLinus Torvalds 
1321da177e4SLinus Torvalds static struct irqchip pxa_low_gpio_chip = {
1331da177e4SLinus Torvalds 	.ack		= pxa_ack_low_gpio,
1341da177e4SLinus Torvalds 	.mask		= pxa_mask_low_irq,
1351da177e4SLinus Torvalds 	.unmask		= pxa_unmask_low_irq,
1361da177e4SLinus Torvalds 	.type		= pxa_gpio_irq_type,
1371da177e4SLinus Torvalds };
1381da177e4SLinus Torvalds 
1391da177e4SLinus Torvalds /*
1401da177e4SLinus Torvalds  * Demux handler for GPIO>=2 edge detect interrupts
1411da177e4SLinus Torvalds  */
1421da177e4SLinus Torvalds 
1431da177e4SLinus Torvalds static void pxa_gpio_demux_handler(unsigned int irq, struct irqdesc *desc,
1441da177e4SLinus Torvalds 				   struct pt_regs *regs)
1451da177e4SLinus Torvalds {
1461da177e4SLinus Torvalds 	unsigned int mask;
1471da177e4SLinus Torvalds 	int loop;
1481da177e4SLinus Torvalds 
1491da177e4SLinus Torvalds 	do {
1501da177e4SLinus Torvalds 		loop = 0;
1511da177e4SLinus Torvalds 
1521da177e4SLinus Torvalds 		mask = GEDR0 & ~3;
1531da177e4SLinus Torvalds 		if (mask) {
1541da177e4SLinus Torvalds 			GEDR0 = mask;
1551da177e4SLinus Torvalds 			irq = IRQ_GPIO(2);
1561da177e4SLinus Torvalds 			desc = irq_desc + irq;
1571da177e4SLinus Torvalds 			mask >>= 2;
1581da177e4SLinus Torvalds 			do {
1591da177e4SLinus Torvalds 				if (mask & 1)
1601da177e4SLinus Torvalds 					desc->handle(irq, desc, regs);
1611da177e4SLinus Torvalds 				irq++;
1621da177e4SLinus Torvalds 				desc++;
1631da177e4SLinus Torvalds 				mask >>= 1;
1641da177e4SLinus Torvalds 			} while (mask);
1651da177e4SLinus Torvalds 			loop = 1;
1661da177e4SLinus Torvalds 		}
1671da177e4SLinus Torvalds 
1681da177e4SLinus Torvalds 		mask = GEDR1;
1691da177e4SLinus Torvalds 		if (mask) {
1701da177e4SLinus Torvalds 			GEDR1 = mask;
1711da177e4SLinus Torvalds 			irq = IRQ_GPIO(32);
1721da177e4SLinus Torvalds 			desc = irq_desc + irq;
1731da177e4SLinus Torvalds 			do {
1741da177e4SLinus Torvalds 				if (mask & 1)
1751da177e4SLinus Torvalds 					desc->handle(irq, desc, regs);
1761da177e4SLinus Torvalds 				irq++;
1771da177e4SLinus Torvalds 				desc++;
1781da177e4SLinus Torvalds 				mask >>= 1;
1791da177e4SLinus Torvalds 			} while (mask);
1801da177e4SLinus Torvalds 			loop = 1;
1811da177e4SLinus Torvalds 		}
1821da177e4SLinus Torvalds 
1831da177e4SLinus Torvalds 		mask = GEDR2;
1841da177e4SLinus Torvalds 		if (mask) {
1851da177e4SLinus Torvalds 			GEDR2 = mask;
1861da177e4SLinus Torvalds 			irq = IRQ_GPIO(64);
1871da177e4SLinus Torvalds 			desc = irq_desc + irq;
1881da177e4SLinus Torvalds 			do {
1891da177e4SLinus Torvalds 				if (mask & 1)
1901da177e4SLinus Torvalds 					desc->handle(irq, desc, regs);
1911da177e4SLinus Torvalds 				irq++;
1921da177e4SLinus Torvalds 				desc++;
1931da177e4SLinus Torvalds 				mask >>= 1;
1941da177e4SLinus Torvalds 			} while (mask);
1951da177e4SLinus Torvalds 			loop = 1;
1961da177e4SLinus Torvalds 		}
1971da177e4SLinus Torvalds 
1981da177e4SLinus Torvalds #if PXA_LAST_GPIO >= 96
1991da177e4SLinus Torvalds 		mask = GEDR3;
2001da177e4SLinus Torvalds 		if (mask) {
2011da177e4SLinus Torvalds 			GEDR3 = mask;
2021da177e4SLinus Torvalds 			irq = IRQ_GPIO(96);
2031da177e4SLinus Torvalds 			desc = irq_desc + irq;
2041da177e4SLinus Torvalds 			do {
2051da177e4SLinus Torvalds 				if (mask & 1)
2061da177e4SLinus Torvalds 					desc->handle(irq, desc, regs);
2071da177e4SLinus Torvalds 				irq++;
2081da177e4SLinus Torvalds 				desc++;
2091da177e4SLinus Torvalds 				mask >>= 1;
2101da177e4SLinus Torvalds 			} while (mask);
2111da177e4SLinus Torvalds 			loop = 1;
2121da177e4SLinus Torvalds 		}
2131da177e4SLinus Torvalds #endif
2141da177e4SLinus Torvalds 	} while (loop);
2151da177e4SLinus Torvalds }
2161da177e4SLinus Torvalds 
2171da177e4SLinus Torvalds static void pxa_ack_muxed_gpio(unsigned int irq)
2181da177e4SLinus Torvalds {
2191da177e4SLinus Torvalds 	int gpio = irq - IRQ_GPIO(2) + 2;
2201da177e4SLinus Torvalds 	GEDR(gpio) = GPIO_bit(gpio);
2211da177e4SLinus Torvalds }
2221da177e4SLinus Torvalds 
2231da177e4SLinus Torvalds static void pxa_mask_muxed_gpio(unsigned int irq)
2241da177e4SLinus Torvalds {
2251da177e4SLinus Torvalds 	int gpio = irq - IRQ_GPIO(2) + 2;
2261da177e4SLinus Torvalds 	__clear_bit(gpio, GPIO_IRQ_mask);
2271da177e4SLinus Torvalds 	GRER(gpio) &= ~GPIO_bit(gpio);
2281da177e4SLinus Torvalds 	GFER(gpio) &= ~GPIO_bit(gpio);
2291da177e4SLinus Torvalds }
2301da177e4SLinus Torvalds 
2311da177e4SLinus Torvalds static void pxa_unmask_muxed_gpio(unsigned int irq)
2321da177e4SLinus Torvalds {
2331da177e4SLinus Torvalds 	int gpio = irq - IRQ_GPIO(2) + 2;
2341da177e4SLinus Torvalds 	int idx = gpio >> 5;
2351da177e4SLinus Torvalds 	__set_bit(gpio, GPIO_IRQ_mask);
2361da177e4SLinus Torvalds 	GRER(gpio) = GPIO_IRQ_rising_edge[idx] & GPIO_IRQ_mask[idx];
2371da177e4SLinus Torvalds 	GFER(gpio) = GPIO_IRQ_falling_edge[idx] & GPIO_IRQ_mask[idx];
2381da177e4SLinus Torvalds }
2391da177e4SLinus Torvalds 
2401da177e4SLinus Torvalds static struct irqchip pxa_muxed_gpio_chip = {
2411da177e4SLinus Torvalds 	.ack		= pxa_ack_muxed_gpio,
2421da177e4SLinus Torvalds 	.mask		= pxa_mask_muxed_gpio,
2431da177e4SLinus Torvalds 	.unmask		= pxa_unmask_muxed_gpio,
2441da177e4SLinus Torvalds 	.type		= pxa_gpio_irq_type,
2451da177e4SLinus Torvalds };
2461da177e4SLinus Torvalds 
2471da177e4SLinus Torvalds 
2481da177e4SLinus Torvalds void __init pxa_init_irq(void)
2491da177e4SLinus Torvalds {
2501da177e4SLinus Torvalds 	int irq;
2511da177e4SLinus Torvalds 
2521da177e4SLinus Torvalds 	/* disable all IRQs */
2531da177e4SLinus Torvalds 	ICMR = 0;
2541da177e4SLinus Torvalds 
2551da177e4SLinus Torvalds 	/* all IRQs are IRQ, not FIQ */
2561da177e4SLinus Torvalds 	ICLR = 0;
2571da177e4SLinus Torvalds 
2581da177e4SLinus Torvalds 	/* clear all GPIO edge detects */
2591da177e4SLinus Torvalds 	GFER0 = 0;
2601da177e4SLinus Torvalds 	GFER1 = 0;
2611da177e4SLinus Torvalds 	GFER2 = 0;
2621da177e4SLinus Torvalds 	GRER0 = 0;
2631da177e4SLinus Torvalds 	GRER1 = 0;
2641da177e4SLinus Torvalds 	GRER2 = 0;
2651da177e4SLinus Torvalds 	GEDR0 = GEDR0;
2661da177e4SLinus Torvalds 	GEDR1 = GEDR1;
2671da177e4SLinus Torvalds 	GEDR2 = GEDR2;
2681da177e4SLinus Torvalds 
2691da177e4SLinus Torvalds #ifdef CONFIG_PXA27x
2701da177e4SLinus Torvalds 	/* And similarly for the extra regs on the PXA27x */
2711da177e4SLinus Torvalds 	ICMR2 = 0;
2721da177e4SLinus Torvalds 	ICLR2 = 0;
2731da177e4SLinus Torvalds 	GFER3 = 0;
2741da177e4SLinus Torvalds 	GRER3 = 0;
2751da177e4SLinus Torvalds 	GEDR3 = GEDR3;
2761da177e4SLinus Torvalds #endif
2771da177e4SLinus Torvalds 
2781da177e4SLinus Torvalds 	/* only unmasked interrupts kick us out of idle */
2791da177e4SLinus Torvalds 	ICCR = 1;
2801da177e4SLinus Torvalds 
2811da177e4SLinus Torvalds 	/* GPIO 0 and 1 must have their mask bit always set */
2821da177e4SLinus Torvalds 	GPIO_IRQ_mask[0] = 3;
2831da177e4SLinus Torvalds 
2841da177e4SLinus Torvalds 	for (irq = PXA_IRQ(PXA_IRQ_SKIP); irq <= PXA_IRQ(31); irq++) {
2851da177e4SLinus Torvalds 		set_irq_chip(irq, &pxa_internal_chip_low);
2861da177e4SLinus Torvalds 		set_irq_handler(irq, do_level_IRQ);
2871da177e4SLinus Torvalds 		set_irq_flags(irq, IRQF_VALID);
2881da177e4SLinus Torvalds 	}
2891da177e4SLinus Torvalds 
2901da177e4SLinus Torvalds #if PXA_INTERNAL_IRQS > 32
2911da177e4SLinus Torvalds 	for (irq = PXA_IRQ(32); irq < PXA_IRQ(PXA_INTERNAL_IRQS); irq++) {
2921da177e4SLinus Torvalds 		set_irq_chip(irq, &pxa_internal_chip_high);
2931da177e4SLinus Torvalds 		set_irq_handler(irq, do_level_IRQ);
2941da177e4SLinus Torvalds 		set_irq_flags(irq, IRQF_VALID);
2951da177e4SLinus Torvalds 	}
2961da177e4SLinus Torvalds #endif
2971da177e4SLinus Torvalds 
2981da177e4SLinus Torvalds 	for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
2991da177e4SLinus Torvalds 		set_irq_chip(irq, &pxa_low_gpio_chip);
3001da177e4SLinus Torvalds 		set_irq_handler(irq, do_edge_IRQ);
3011da177e4SLinus Torvalds 		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
3021da177e4SLinus Torvalds 	}
3031da177e4SLinus Torvalds 
3041da177e4SLinus Torvalds 	for (irq = IRQ_GPIO(2); irq <= IRQ_GPIO(PXA_LAST_GPIO); irq++) {
3051da177e4SLinus Torvalds 		set_irq_chip(irq, &pxa_muxed_gpio_chip);
3061da177e4SLinus Torvalds 		set_irq_handler(irq, do_edge_IRQ);
3071da177e4SLinus Torvalds 		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
3081da177e4SLinus Torvalds 	}
3091da177e4SLinus Torvalds 
3101da177e4SLinus Torvalds 	/* Install handler for GPIO>=2 edge detect interrupts */
3111da177e4SLinus Torvalds 	set_irq_chip(IRQ_GPIO_2_x, &pxa_internal_chip_low);
3121da177e4SLinus Torvalds 	set_irq_chained_handler(IRQ_GPIO_2_x, pxa_gpio_demux_handler);
3131da177e4SLinus Torvalds }
314