⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irq.c

📁 是关于linux2.5.1的完全源码
💻 C
字号:
/* * linux/arch/arm/mach-sa1100/irq.c * * Copyright (C) 1999-2001 Nicolas Pitre * * Generic IRQ handling for the SA11x0, GPIO 11-27 IRQ demultiplexing. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */#include <linux/init.h>#include <linux/module.h>#include <linux/sched.h>#include <linux/interrupt.h>#include <linux/ioport.h>#include <linux/ptrace.h>#include <asm/hardware.h>#include <asm/irq.h>#include <asm/mach/irq.h>#include "generic.h"/* * SA1100 GPIO edge detection for IRQs: * IRQs are generated on Falling-Edge, Rising-Edge, or both. * This must be called *before* the appropriate IRQ is registered. * Use this instead of directly setting GRER/GFER. */static int GPIO_IRQ_rising_edge;static int GPIO_IRQ_falling_edge;static int GPIO_IRQ_mask = (1 << 11) - 1;static void sa1100_manual_rerun(unsigned int irq){	struct pt_regs regs;	memset(&regs, 0, sizeof(regs));	irq_desc[irq].handle(irq, &irq_desc[irq], &regs);}#define GPIO11_27_MASK(irq)	(1 << GPIO_11_27_IRQ(irq))static int sa1100_gpio_type(unsigned int irq, unsigned int type){	unsigned int mask;	printk(KERN_DEBUG "IRQ%d: ", irq);	if (irq <= 10)		mask = 1 << irq;	else		mask = GPIO11_27_MASK(irq);	if (type & __IRQT_RISEDGE) {		printk("rising ");		GPIO_IRQ_rising_edge |= mask;	} else		GPIO_IRQ_rising_edge &= ~mask;	if (type & __IRQT_FALEDGE) {		printk("falling ");		GPIO_IRQ_falling_edge |= mask;	} else		GPIO_IRQ_falling_edge &= ~mask;	printk("edges\n");	GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;	GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;	return 0;}/* * GPIO IRQs must be acknoledged.  This is for IRQs from 0 to 10. */static void sa1100_low_gpio_ack(unsigned int irq){	GEDR = (1 << irq);}static void sa1100_low_gpio_mask(unsigned int irq){	ICMR &= ~(1 << irq);}static void sa1100_low_gpio_unmask(unsigned int irq){	ICMR |= 1 << irq;}static struct irqchip sa1100_low_gpio_chip = {	ack:		sa1100_low_gpio_ack,	mask:		sa1100_low_gpio_mask,	unmask:		sa1100_low_gpio_unmask,	rerun:		sa1100_manual_rerun,	type:		sa1100_gpio_type,};/* * IRQ11 (GPIO11 through 27) handler.  We enter here with the * irq_controller_lock held, and IRQs disabled.  Decode the IRQ * and call the handler. */static voidsa1100_high_gpio_handler(unsigned int irq, struct irqdesc *desc,			 struct pt_regs *regs){	unsigned int mask;	mask = GEDR & 0xfffff800;	do {		/*		 * clear down all currently active IRQ sources.		 * We will be processing them all.		 */		GEDR = mask;		irq = IRQ_GPIO11;		desc = irq_desc + irq;		mask >>= 11;		do {			if (mask & 1)				desc->handle(irq, desc, regs);			mask >>= 1;			irq++;			desc++;		} while (mask);		mask = GEDR & 0xfffff800;	} while (mask);}/* * Like GPIO0 to 10, GPIO11-27 IRQs need to be handled specially. * In addition, the IRQs are all collected up into one bit in the * interrupt controller registers. */static void sa1100_high_gpio_ack(unsigned int irq){	unsigned int mask = GPIO11_27_MASK(irq);	GEDR = mask;}static void sa1100_high_gpio_mask(unsigned int irq){	unsigned int mask = GPIO11_27_MASK(irq);	GPIO_IRQ_mask &= ~mask;	GRER &= ~mask;	GFER &= ~mask;}static void sa1100_high_gpio_unmask(unsigned int irq){	unsigned int mask = GPIO11_27_MASK(irq);	GPIO_IRQ_mask |= mask;	GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;	GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;}static struct irqchip sa1100_high_gpio_chip = {	ack:		sa1100_high_gpio_ack,	mask:		sa1100_high_gpio_mask,	unmask:		sa1100_high_gpio_unmask,	rerun:		sa1100_manual_rerun,	type:		sa1100_gpio_type,};/* * We don't need to ACK IRQs on the SA1100 unless they're GPIOs * this is for internal IRQs i.e. from 11 to 31. */static void sa1100_mask_irq(unsigned int irq){	ICMR &= ~(1 << irq);}static void sa1100_unmask_irq(unsigned int irq){	ICMR |= (1 << irq);}static struct irqchip sa1100_normal_chip = {	ack:		sa1100_mask_irq,	mask:		sa1100_mask_irq,	unmask:		sa1100_unmask_irq,	/* rerun should never be called */};static struct resource irq_resource = {	name:	"irqs",	start:	0x90050000,	end:	0x9005ffff,};void __init sa1100_init_irq(void){	unsigned int irq;	request_resource(&iomem_resource, &irq_resource);	/* disable all IRQs */	ICMR = 0;	/* all IRQs are IRQ, not FIQ */	ICLR = 0;	/* clear all GPIO edge detects */	GFER = 0;	GRER = 0;	GEDR = -1;	/*	 * Whatever the doc says, this has to be set for the wait-on-irq	 * instruction to work... on a SA1100 rev 9 at least.	 */	ICCR = 1;	for (irq = 0; irq <= 10; irq++) {		set_irq_chip(irq, &sa1100_low_gpio_chip);		set_irq_handler(irq, do_edge_IRQ);		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);	}	for (irq = 12; irq <= 31; irq++) {		set_irq_chip(irq, &sa1100_normal_chip);		set_irq_handler(irq, do_level_IRQ);		set_irq_flags(irq, IRQF_VALID);	}	for (irq = 32; irq <= 48; irq++) {		set_irq_chip(irq, &sa1100_high_gpio_chip);		set_irq_handler(irq, do_edge_IRQ);		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);	}	/*	 * Install handler for GPIO 11-27 edge detect interrupts	 */	set_irq_chip(IRQ_GPIO11_27, &sa1100_normal_chip);	set_irq_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler);	/*	 * We generally don't want the LCD IRQ being	 * enabled as soon as we request it.	 */	set_irq_flags(IRQ_LCD, IRQF_VALID | IRQF_NOAUTOEN);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -