1/* 2 * linux/arch/arm/mach-sa1100/irq.c 3 * 4 * Copyright (C) 1999-2001 Nicolas Pitre 5 * 6 * Generic IRQ handling for the SA11x0, GPIO 11-27 IRQ demultiplexing. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12#include <linux/init.h> 13#include <linux/module.h> 14#include <linux/interrupt.h> 15#include <linux/io.h> 16#include <linux/irq.h> 17#include <linux/irqdomain.h> 18#include <linux/ioport.h> 19#include <linux/syscore_ops.h> 20 21#include <mach/hardware.h> 22#include <mach/irqs.h> 23#include <asm/mach/irq.h> 24#include <asm/exception.h> 25 26#include "generic.h" 27 28 29/* 30 * We don't need to ACK IRQs on the SA1100 unless they're GPIOs 31 * this is for internal IRQs i.e. from IRQ LCD to RTCAlrm. 32 */ 33static void sa1100_mask_irq(struct irq_data *d) 34{ 35 ICMR &= ~BIT(d->hwirq); 36} 37 38static void sa1100_unmask_irq(struct irq_data *d) 39{ 40 ICMR |= BIT(d->hwirq); 41} 42 43/* 44 * Apart form GPIOs, only the RTC alarm can be a wakeup event. 45 */ 46static int sa1100_set_wake(struct irq_data *d, unsigned int on) 47{ 48 if (BIT(d->hwirq) == IC_RTCAlrm) { 49 if (on) 50 PWER |= PWER_RTC; 51 else 52 PWER &= ~PWER_RTC; 53 return 0; 54 } 55 return -EINVAL; 56} 57 58static struct irq_chip sa1100_normal_chip = { 59 .name = "SC", 60 .irq_ack = sa1100_mask_irq, 61 .irq_mask = sa1100_mask_irq, 62 .irq_unmask = sa1100_unmask_irq, 63 .irq_set_wake = sa1100_set_wake, 64}; 65 66static int sa1100_normal_irqdomain_map(struct irq_domain *d, 67 unsigned int irq, irq_hw_number_t hwirq) 68{ 69 irq_set_chip_and_handler(irq, &sa1100_normal_chip, 70 handle_level_irq); 71 set_irq_flags(irq, IRQF_VALID); 72 73 return 0; 74} 75 76static struct irq_domain_ops sa1100_normal_irqdomain_ops = { 77 .map = sa1100_normal_irqdomain_map, 78 .xlate = irq_domain_xlate_onetwocell, 79}; 80 81static struct irq_domain *sa1100_normal_irqdomain; 82 83static struct resource irq_resource = 84 DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs"); 85 86static struct sa1100irq_state { 87 unsigned int saved; 88 unsigned int icmr; 89 unsigned int iclr; 90 unsigned int iccr; 91} sa1100irq_state; 92 93static int sa1100irq_suspend(void) 94{ 95 struct sa1100irq_state *st = &sa1100irq_state; 96 97 st->saved = 1; 98 st->icmr = ICMR; 99 st->iclr = ICLR; 100 st->iccr = ICCR; 101 102 /* 103 * Disable all GPIO-based interrupts. 104 */ 105 ICMR &= ~(IC_GPIO11_27|IC_GPIO10|IC_GPIO9|IC_GPIO8|IC_GPIO7| 106 IC_GPIO6|IC_GPIO5|IC_GPIO4|IC_GPIO3|IC_GPIO2| 107 IC_GPIO1|IC_GPIO0); 108 109 return 0; 110} 111 112static void sa1100irq_resume(void) 113{ 114 struct sa1100irq_state *st = &sa1100irq_state; 115 116 if (st->saved) { 117 ICCR = st->iccr; 118 ICLR = st->iclr; 119 120 ICMR = st->icmr; 121 } 122} 123 124static struct syscore_ops sa1100irq_syscore_ops = { 125 .suspend = sa1100irq_suspend, 126 .resume = sa1100irq_resume, 127}; 128 129static int __init sa1100irq_init_devicefs(void) 130{ 131 register_syscore_ops(&sa1100irq_syscore_ops); 132 return 0; 133} 134 135device_initcall(sa1100irq_init_devicefs); 136 137static asmlinkage void __exception_irq_entry 138sa1100_handle_irq(struct pt_regs *regs) 139{ 140 uint32_t icip, icmr, mask; 141 142 do { 143 icip = (ICIP); 144 icmr = (ICMR); 145 mask = icip & icmr; 146 147 if (mask == 0) 148 break; 149 150 handle_domain_irq(sa1100_normal_irqdomain, 151 ffs(mask) - 1, regs); 152 } while (1); 153} 154 155void __init sa1100_init_irq(void) 156{ 157 request_resource(&iomem_resource, &irq_resource); 158 159 /* disable all IRQs */ 160 ICMR = 0; 161 162 /* all IRQs are IRQ, not FIQ */ 163 ICLR = 0; 164 165 /* 166 * Whatever the doc says, this has to be set for the wait-on-irq 167 * instruction to work... on a SA1100 rev 9 at least. 168 */ 169 ICCR = 1; 170 171 sa1100_normal_irqdomain = irq_domain_add_simple(NULL, 172 32, IRQ_GPIO0_SC, 173 &sa1100_normal_irqdomain_ops, NULL); 174 175 set_handle_irq(sa1100_handle_irq); 176 177 sa1100_init_gpio(); 178} 179