1edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara/* 2edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara * arch/arm/mach-dove/irq.c 3edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara * 4edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara * Dove IRQ handling. 5edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara * 6edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara * This file is licensed under the terms of the GNU General Public 7edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara * License version 2. This program is licensed "as is" without any 8edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara * warranty of any kind, whether express or implied. 9edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara */ 10edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 11edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara#include <linux/kernel.h> 12edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara#include <linux/init.h> 13edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara#include <linux/irq.h> 14edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara#include <linux/gpio.h> 15edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara#include <linux/io.h> 16edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara#include <asm/mach/arch.h> 17edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara#include <plat/irq.h> 18edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara#include <asm/mach/irq.h> 19edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara#include <mach/pm.h> 20edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara#include <mach/bridge-regs.h> 21edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara#include "common.h" 22edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 23edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bisharastatic void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) 24edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara{ 25edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara int irqoff; 26edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara BUG_ON(irq < IRQ_DOVE_GPIO_0_7 || irq > IRQ_DOVE_HIGH_GPIO); 27edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 28edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara irqoff = irq <= IRQ_DOVE_GPIO_16_23 ? irq - IRQ_DOVE_GPIO_0_7 : 29edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 3 + irq - IRQ_DOVE_GPIO_24_31; 30edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 31edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara orion_gpio_irq_handler(irqoff << 3); 32edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara if (irq == IRQ_DOVE_HIGH_GPIO) { 33edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara orion_gpio_irq_handler(40); 34edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara orion_gpio_irq_handler(48); 35edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara orion_gpio_irq_handler(56); 36edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara } 37edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara} 38edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 39aa456a6eba197f0774d68531342ba7f85ccf2971Lennert Buytenhekstatic void pmu_irq_mask(struct irq_data *d) 40edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara{ 41aa456a6eba197f0774d68531342ba7f85ccf2971Lennert Buytenhek int pin = irq_to_pmu(d->irq); 42edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara u32 u; 43edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 44edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara u = readl(PMU_INTERRUPT_MASK); 45edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara u &= ~(1 << (pin & 31)); 46edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara writel(u, PMU_INTERRUPT_MASK); 47edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara} 48edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 49aa456a6eba197f0774d68531342ba7f85ccf2971Lennert Buytenhekstatic void pmu_irq_unmask(struct irq_data *d) 50edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara{ 51aa456a6eba197f0774d68531342ba7f85ccf2971Lennert Buytenhek int pin = irq_to_pmu(d->irq); 52edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara u32 u; 53edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 54edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara u = readl(PMU_INTERRUPT_MASK); 55edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara u |= 1 << (pin & 31); 56edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara writel(u, PMU_INTERRUPT_MASK); 57edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara} 58edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 59aa456a6eba197f0774d68531342ba7f85ccf2971Lennert Buytenhekstatic void pmu_irq_ack(struct irq_data *d) 60edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara{ 61aa456a6eba197f0774d68531342ba7f85ccf2971Lennert Buytenhek int pin = irq_to_pmu(d->irq); 62edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara u32 u; 63edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 64edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara u = ~(1 << (pin & 31)); 65edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara writel(u, PMU_INTERRUPT_CAUSE); 66edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara} 67edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 68edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bisharastatic struct irq_chip pmu_irq_chip = { 69edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara .name = "pmu_irq", 70aa456a6eba197f0774d68531342ba7f85ccf2971Lennert Buytenhek .irq_mask = pmu_irq_mask, 71aa456a6eba197f0774d68531342ba7f85ccf2971Lennert Buytenhek .irq_unmask = pmu_irq_unmask, 72aa456a6eba197f0774d68531342ba7f85ccf2971Lennert Buytenhek .irq_ack = pmu_irq_ack, 73edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara}; 74edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 75edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bisharastatic void pmu_irq_handler(unsigned int irq, struct irq_desc *desc) 76edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara{ 77edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara unsigned long cause = readl(PMU_INTERRUPT_CAUSE); 78edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 79edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara cause &= readl(PMU_INTERRUPT_MASK); 80edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara if (cause == 0) { 81edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara do_bad_IRQ(irq, desc); 82edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara return; 83edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara } 84edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 85edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara for (irq = 0; irq < NR_PMU_IRQS; irq++) { 86edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara if (!(cause & (1 << irq))) 87edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara continue; 88edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara irq = pmu_to_irq(irq); 89cf0d6b76c11b565f8d8b7d527d17b9f82eb3b3a5Thomas Gleixner generic_handle_irq(irq); 90edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara } 91edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara} 92edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 93edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bisharavoid __init dove_init_irq(void) 94edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara{ 95edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara int i; 96edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 97edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara orion_irq_init(0, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF)); 98edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara orion_irq_init(32, (void __iomem *)(IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF)); 99edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 100edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara /* 1019eac6d0a4e7e5149a7f86575b46d710ad2e05fe2Lennert Buytenhek * Initialize gpiolib for GPIOs 0-71. 102edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara */ 1039eac6d0a4e7e5149a7f86575b46d710ad2e05fe2Lennert Buytenhek orion_gpio_init(0, 32, DOVE_GPIO_LO_VIRT_BASE, 0, 1049eac6d0a4e7e5149a7f86575b46d710ad2e05fe2Lennert Buytenhek IRQ_DOVE_GPIO_START); 1056845664a6a7d443f03883db59d10749d38d98b8eThomas Gleixner irq_set_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler); 1066845664a6a7d443f03883db59d10749d38d98b8eThomas Gleixner irq_set_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler); 1076845664a6a7d443f03883db59d10749d38d98b8eThomas Gleixner irq_set_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler); 1086845664a6a7d443f03883db59d10749d38d98b8eThomas Gleixner irq_set_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler); 1099eac6d0a4e7e5149a7f86575b46d710ad2e05fe2Lennert Buytenhek 1109eac6d0a4e7e5149a7f86575b46d710ad2e05fe2Lennert Buytenhek orion_gpio_init(32, 32, DOVE_GPIO_HI_VIRT_BASE, 0, 1119eac6d0a4e7e5149a7f86575b46d710ad2e05fe2Lennert Buytenhek IRQ_DOVE_GPIO_START + 32); 1126845664a6a7d443f03883db59d10749d38d98b8eThomas Gleixner irq_set_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler); 1139eac6d0a4e7e5149a7f86575b46d710ad2e05fe2Lennert Buytenhek 1149eac6d0a4e7e5149a7f86575b46d710ad2e05fe2Lennert Buytenhek orion_gpio_init(64, 8, DOVE_GPIO2_VIRT_BASE, 0, 1159eac6d0a4e7e5149a7f86575b46d710ad2e05fe2Lennert Buytenhek IRQ_DOVE_GPIO_START + 64); 116edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 117edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara /* 118edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara * Mask and clear PMU interrupts 119edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara */ 120edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara writel(0, PMU_INTERRUPT_MASK); 121edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara writel(0, PMU_INTERRUPT_CAUSE); 122edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara 123edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara for (i = IRQ_DOVE_PMU_START; i < NR_IRQS; i++) { 124f38c02f3b338651e145aac2889ba976baf6b28b3Thomas Gleixner irq_set_chip_and_handler(i, &pmu_irq_chip, handle_level_irq); 125cf0d6b76c11b565f8d8b7d527d17b9f82eb3b3a5Thomas Gleixner irq_set_status_flags(i, IRQ_LEVEL); 126edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara set_irq_flags(i, IRQF_VALID); 127edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara } 1286845664a6a7d443f03883db59d10749d38d98b8eThomas Gleixner irq_set_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler); 129edabd38e1a017e922e3e3b485ee3ddb4df433aa4Saeed Bishara} 130