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, 1367801907bSRussell King .set_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, 2447801907bSRussell King .set_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