PageRenderTime 41ms CodeModel.GetById 22ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 0ms

/arch/arm/mach-sa1100/irq.c

https://bitbucket.org/evzijst/gittest
C | 332 lines | 214 code | 59 blank | 59 comment | 15 complexity | 8570a919cfbf49a13f8caf9c5ee8d522 MD5 | raw file
  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/ioport.h>
 15#include <linux/ptrace.h>
 16#include <linux/sysdev.h>
 17
 18#include <asm/hardware.h>
 19#include <asm/irq.h>
 20#include <asm/mach/irq.h>
 21
 22#include "generic.h"
 23
 24
 25/*
 26 * SA1100 GPIO edge detection for IRQs:
 27 * IRQs are generated on Falling-Edge, Rising-Edge, or both.
 28 * Use this instead of directly setting GRER/GFER.
 29 */
 30static int GPIO_IRQ_rising_edge;
 31static int GPIO_IRQ_falling_edge;
 32static int GPIO_IRQ_mask = (1 << 11) - 1;
 33
 34/*
 35 * To get the GPIO number from an IRQ number
 36 */
 37#define GPIO_11_27_IRQ(i)	((i) - 21)
 38#define GPIO11_27_MASK(irq)	(1 << GPIO_11_27_IRQ(irq))
 39
 40static int sa1100_gpio_type(unsigned int irq, unsigned int type)
 41{
 42	unsigned int mask;
 43
 44	if (irq <= 10)
 45		mask = 1 << irq;
 46	else
 47		mask = GPIO11_27_MASK(irq);
 48
 49	if (type == IRQT_PROBE) {
 50		if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
 51			return 0;
 52		type = __IRQT_RISEDGE | __IRQT_FALEDGE;
 53	}
 54
 55	if (type & __IRQT_RISEDGE) {
 56		GPIO_IRQ_rising_edge |= mask;
 57	} else
 58		GPIO_IRQ_rising_edge &= ~mask;
 59	if (type & __IRQT_FALEDGE) {
 60		GPIO_IRQ_falling_edge |= mask;
 61	} else
 62		GPIO_IRQ_falling_edge &= ~mask;
 63
 64	GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
 65	GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
 66
 67	return 0;
 68}
 69
 70/*
 71 * GPIO IRQs must be acknowledged.  This is for IRQs from 0 to 10.
 72 */
 73static void sa1100_low_gpio_ack(unsigned int irq)
 74{
 75	GEDR = (1 << irq);
 76}
 77
 78static void sa1100_low_gpio_mask(unsigned int irq)
 79{
 80	ICMR &= ~(1 << irq);
 81}
 82
 83static void sa1100_low_gpio_unmask(unsigned int irq)
 84{
 85	ICMR |= 1 << irq;
 86}
 87
 88static int sa1100_low_gpio_wake(unsigned int irq, unsigned int on)
 89{
 90	if (on)
 91		PWER |= 1 << irq;
 92	else
 93		PWER &= ~(1 << irq);
 94	return 0;
 95}
 96
 97static struct irqchip sa1100_low_gpio_chip = {
 98	.ack		= sa1100_low_gpio_ack,
 99	.mask		= sa1100_low_gpio_mask,
100	.unmask		= sa1100_low_gpio_unmask,
101	.type		= sa1100_gpio_type,
102	.wake		= sa1100_low_gpio_wake,
103};
104
105/*
106 * IRQ11 (GPIO11 through 27) handler.  We enter here with the
107 * irq_controller_lock held, and IRQs disabled.  Decode the IRQ
108 * and call the handler.
109 */
110static void
111sa1100_high_gpio_handler(unsigned int irq, struct irqdesc *desc,
112			 struct pt_regs *regs)
113{
114	unsigned int mask;
115
116	mask = GEDR & 0xfffff800;
117	do {
118		/*
119		 * clear down all currently active IRQ sources.
120		 * We will be processing them all.
121		 */
122		GEDR = mask;
123
124		irq = IRQ_GPIO11;
125		desc = irq_desc + irq;
126		mask >>= 11;
127		do {
128			if (mask & 1)
129				desc->handle(irq, desc, regs);
130			mask >>= 1;
131			irq++;
132			desc++;
133		} while (mask);
134
135		mask = GEDR & 0xfffff800;
136	} while (mask);
137}
138
139/*
140 * Like GPIO0 to 10, GPIO11-27 IRQs need to be handled specially.
141 * In addition, the IRQs are all collected up into one bit in the
142 * interrupt controller registers.
143 */
144static void sa1100_high_gpio_ack(unsigned int irq)
145{
146	unsigned int mask = GPIO11_27_MASK(irq);
147
148	GEDR = mask;
149}
150
151static void sa1100_high_gpio_mask(unsigned int irq)
152{
153	unsigned int mask = GPIO11_27_MASK(irq);
154
155	GPIO_IRQ_mask &= ~mask;
156
157	GRER &= ~mask;
158	GFER &= ~mask;
159}
160
161static void sa1100_high_gpio_unmask(unsigned int irq)
162{
163	unsigned int mask = GPIO11_27_MASK(irq);
164
165	GPIO_IRQ_mask |= mask;
166
167	GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
168	GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
169}
170
171static int sa1100_high_gpio_wake(unsigned int irq, unsigned int on)
172{
173	if (on)
174		PWER |= GPIO11_27_MASK(irq);
175	else
176		PWER &= ~GPIO11_27_MASK(irq);
177	return 0;
178}
179
180static struct irqchip sa1100_high_gpio_chip = {
181	.ack		= sa1100_high_gpio_ack,
182	.mask		= sa1100_high_gpio_mask,
183	.unmask		= sa1100_high_gpio_unmask,
184	.type		= sa1100_gpio_type,
185	.wake		= sa1100_high_gpio_wake,
186};
187
188/*
189 * We don't need to ACK IRQs on the SA1100 unless they're GPIOs
190 * this is for internal IRQs i.e. from 11 to 31.
191 */
192static void sa1100_mask_irq(unsigned int irq)
193{
194	ICMR &= ~(1 << irq);
195}
196
197static void sa1100_unmask_irq(unsigned int irq)
198{
199	ICMR |= (1 << irq);
200}
201
202static struct irqchip sa1100_normal_chip = {
203	.ack		= sa1100_mask_irq,
204	.mask		= sa1100_mask_irq,
205	.unmask		= sa1100_unmask_irq,
206};
207
208static struct resource irq_resource = {
209	.name	= "irqs",
210	.start	= 0x90050000,
211	.end	= 0x9005ffff,
212};
213
214static struct sa1100irq_state {
215	unsigned int	saved;
216	unsigned int	icmr;
217	unsigned int	iclr;
218	unsigned int	iccr;
219} sa1100irq_state;
220
221static int sa1100irq_suspend(struct sys_device *dev, pm_message_t state)
222{
223	struct sa1100irq_state *st = &sa1100irq_state;
224
225	st->saved = 1;
226	st->icmr = ICMR;
227	st->iclr = ICLR;
228	st->iccr = ICCR;
229
230	/*
231	 * Disable all GPIO-based interrupts.
232	 */
233	ICMR &= ~(IC_GPIO11_27|IC_GPIO10|IC_GPIO9|IC_GPIO8|IC_GPIO7|
234		  IC_GPIO6|IC_GPIO5|IC_GPIO4|IC_GPIO3|IC_GPIO2|
235		  IC_GPIO1|IC_GPIO0);
236
237	/*
238	 * Set the appropriate edges for wakeup.
239	 */
240	GRER = PWER & GPIO_IRQ_rising_edge;
241	GFER = PWER & GPIO_IRQ_falling_edge;
242	
243	/*
244	 * Clear any pending GPIO interrupts.
245	 */
246	GEDR = GEDR;
247
248	return 0;
249}
250
251static int sa1100irq_resume(struct sys_device *dev)
252{
253	struct sa1100irq_state *st = &sa1100irq_state;
254
255	if (st->saved) {
256		ICCR = st->iccr;
257		ICLR = st->iclr;
258
259		GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
260		GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
261
262		ICMR = st->icmr;
263	}
264	return 0;
265}
266
267static struct sysdev_class sa1100irq_sysclass = {
268	set_kset_name("sa11x0-irq"),
269	.suspend	= sa1100irq_suspend,
270	.resume		= sa1100irq_resume,
271};
272
273static struct sys_device sa1100irq_device = {
274	.id		= 0,
275	.cls		= &sa1100irq_sysclass,
276};
277
278static int __init sa1100irq_init_devicefs(void)
279{
280	sysdev_class_register(&sa1100irq_sysclass);
281	return sysdev_register(&sa1100irq_device);
282}
283
284device_initcall(sa1100irq_init_devicefs);
285
286void __init sa1100_init_irq(void)
287{
288	unsigned int irq;
289
290	request_resource(&iomem_resource, &irq_resource);
291
292	/* disable all IRQs */
293	ICMR = 0;
294
295	/* all IRQs are IRQ, not FIQ */
296	ICLR = 0;
297
298	/* clear all GPIO edge detects */
299	GFER = 0;
300	GRER = 0;
301	GEDR = -1;
302
303	/*
304	 * Whatever the doc says, this has to be set for the wait-on-irq
305	 * instruction to work... on a SA1100 rev 9 at least.
306	 */
307	ICCR = 1;
308
309	for (irq = 0; irq <= 10; irq++) {
310		set_irq_chip(irq, &sa1100_low_gpio_chip);
311		set_irq_handler(irq, do_edge_IRQ);
312		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
313	}
314
315	for (irq = 12; irq <= 31; irq++) {
316		set_irq_chip(irq, &sa1100_normal_chip);
317		set_irq_handler(irq, do_level_IRQ);
318		set_irq_flags(irq, IRQF_VALID);
319	}
320
321	for (irq = 32; irq <= 48; irq++) {
322		set_irq_chip(irq, &sa1100_high_gpio_chip);
323		set_irq_handler(irq, do_edge_IRQ);
324		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
325	}
326
327	/*
328	 * Install handler for GPIO 11-27 edge detect interrupts
329	 */
330	set_irq_chip(IRQ_GPIO11_27, &sa1100_normal_chip);
331	set_irq_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler);
332}