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

📄 locomo.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * linux/arch/arm/common/locomo.c * * Sharp LoCoMo support * * 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. * * This file contains all generic LoCoMo support. * * All initialization functions provided here are intended to be called * from machine specific code with proper arguments when required. * * Based on sa1111.c */#include <linux/config.h>#include <linux/module.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/delay.h>#include <linux/errno.h>#include <linux/ioport.h>#include <linux/device.h>#include <linux/slab.h>#include <linux/spinlock.h>#include <asm/hardware.h>#include <asm/mach-types.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/mach/irq.h>#include <asm/hardware/locomo.h>/* the following is the overall data for the locomo chip */struct locomo {	struct device *dev;	unsigned long phys;	unsigned int irq;	void *base;};struct locomo_dev_info {	unsigned long	offset;	unsigned long	length;	unsigned int	devid;	unsigned int	irq[1];	const char *	name;};static struct locomo_dev_info locomo_devices[] = {};/** LoCoMo interrupt handling stuff. * NOTE: LoCoMo has a 1 to many mapping on all of its IRQs. * that is, there is only one real hardware interrupt * we determine which interrupt it is by reading some IO memory. * We have two levels of expansion, first in the handler for the * hardware interrupt we generate an interrupt * IRQ_LOCOMO_*_BASE and those handlers generate more interrupts * * hardware irq reads LOCOMO_ICR & 0x0f00 *   IRQ_LOCOMO_KEY_BASE *   IRQ_LOCOMO_GPIO_BASE *   IRQ_LOCOMO_LT_BASE *   IRQ_LOCOMO_SPI_BASE * IRQ_LOCOMO_KEY_BASE reads LOCOMO_KIC & 0x0001 *   IRQ_LOCOMO_KEY * IRQ_LOCOMO_GPIO_BASE reads LOCOMO_GIR & LOCOMO_GPD & 0xffff *   IRQ_LOCOMO_GPIO[0-15] * IRQ_LOCOMO_LT_BASE reads LOCOMO_LTINT & 0x0001 *   IRQ_LOCOMO_LT * IRQ_LOCOMO_SPI_BASE reads LOCOMO_SPIIR & 0x000F *   IRQ_LOCOMO_SPI_RFR *   IRQ_LOCOMO_SPI_RFW *   IRQ_LOCOMO_SPI_OVRN *   IRQ_LOCOMO_SPI_TEND */#define LOCOMO_IRQ_START	(IRQ_LOCOMO_KEY_BASE)#define LOCOMO_IRQ_KEY_START	(IRQ_LOCOMO_KEY)#define	LOCOMO_IRQ_GPIO_START	(IRQ_LOCOMO_GPIO0)#define	LOCOMO_IRQ_LT_START	(IRQ_LOCOMO_LT)#define	LOCOMO_IRQ_SPI_START	(IRQ_LOCOMO_SPI_RFR)static void locomo_handler(unsigned int irq, struct irqdesc *desc,			struct pt_regs *regs){	int req, i;	struct irqdesc *d;	void *mapbase = get_irq_chipdata(irq);	/* Acknowledge the parent IRQ */	desc->chip->ack(irq);	/* check why this interrupt was generated */	req = locomo_readl(mapbase + LOCOMO_ICR) & 0x0f00;	if (req) {		/* generate the next interrupt(s) */		irq = LOCOMO_IRQ_START;		d = irq_desc + irq;		for (i = 0; i <= 3; i++, d++, irq++) {			if (req & (0x0100 << i)) {				d->handle(irq, d, regs);			}		}	}}static void locomo_ack_irq(unsigned int irq){}static void locomo_mask_irq(unsigned int irq){	void *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_ICR);	r &= ~(0x0010 << (irq - LOCOMO_IRQ_START));	locomo_writel(r, mapbase + LOCOMO_ICR);}static void locomo_unmask_irq(unsigned int irq){	void *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_ICR);	r |= (0x0010 << (irq - LOCOMO_IRQ_START));	locomo_writel(r, mapbase + LOCOMO_ICR);}static struct irqchip locomo_chip = {	.ack	= locomo_ack_irq,	.mask	= locomo_mask_irq,	.unmask	= locomo_unmask_irq,};static void locomo_key_handler(unsigned int irq, struct irqdesc *desc,			    struct pt_regs *regs){	struct irqdesc *d;	void *mapbase = get_irq_chipdata(irq);	if (locomo_readl(mapbase + LOCOMO_KIC) & 0x0001) {		d = irq_desc + LOCOMO_IRQ_KEY_START;		d->handle(LOCOMO_IRQ_KEY_START, d, regs);	}}static void locomo_key_ack_irq(unsigned int irq){	void *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_KIC);	r &= ~(0x0100 << (irq - LOCOMO_IRQ_KEY_START));	locomo_writel(r, mapbase + LOCOMO_KIC);}static void locomo_key_mask_irq(unsigned int irq){	void *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_KIC);	r &= ~(0x0010 << (irq - LOCOMO_IRQ_KEY_START));	locomo_writel(r, mapbase + LOCOMO_KIC);}static void locomo_key_unmask_irq(unsigned int irq){	void *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_KIC);	r |= (0x0010 << (irq - LOCOMO_IRQ_KEY_START));	locomo_writel(r, mapbase + LOCOMO_KIC);}static struct irqchip locomo_key_chip = {	.ack	= locomo_key_ack_irq,	.mask	= locomo_key_mask_irq,	.unmask	= locomo_key_unmask_irq,};static void locomo_gpio_handler(unsigned int irq, struct irqdesc *desc,			     struct pt_regs *regs){	int req, i;	struct irqdesc *d;	void *mapbase = get_irq_chipdata(irq);	req = 	locomo_readl(mapbase + LOCOMO_GIR) &		locomo_readl(mapbase + LOCOMO_GPD) &		0xffff;	if (req) {		irq = LOCOMO_IRQ_GPIO_START;		d = irq_desc + LOCOMO_IRQ_GPIO_START;		for (i = 0; i <= 15; i++, irq++, d++) {			if (req & (0x0001 << i)) {				d->handle(irq, d, regs);			}		}	}}static void locomo_gpio_ack_irq(unsigned int irq){	void *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_GWE);	r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START));	locomo_writel(r, mapbase + LOCOMO_GWE);	r = locomo_readl(mapbase + LOCOMO_GIS);	r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));	locomo_writel(r, mapbase + LOCOMO_GIS);	r = locomo_readl(mapbase + LOCOMO_GWE);	r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));	locomo_writel(r, mapbase + LOCOMO_GWE);}static void locomo_gpio_mask_irq(unsigned int irq){	void *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_GIE);	r &= ~(0x0001 << (irq - LOCOMO_IRQ_GPIO_START));	locomo_writel(r, mapbase + LOCOMO_GIE);}static void locomo_gpio_unmask_irq(unsigned int irq){	void *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_GIE);	r |= (0x0001 << (irq - LOCOMO_IRQ_GPIO_START));	locomo_writel(r, mapbase + LOCOMO_GIE);}static struct irqchip locomo_gpio_chip = {	.ack	= locomo_gpio_ack_irq,	.mask	= locomo_gpio_mask_irq,	.unmask	= locomo_gpio_unmask_irq,};static void locomo_lt_handler(unsigned int irq, struct irqdesc *desc,			   struct pt_regs *regs){	struct irqdesc *d;	void *mapbase = get_irq_chipdata(irq);	if (locomo_readl(mapbase + LOCOMO_LTINT) & 0x0001) {		d = irq_desc + LOCOMO_IRQ_LT_START;		d->handle(LOCOMO_IRQ_LT_START, d, regs);	}}static void locomo_lt_ack_irq(unsigned int irq){	void *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_LTINT);	r &= ~(0x0100 << (irq - LOCOMO_IRQ_LT_START));	locomo_writel(r, mapbase + LOCOMO_LTINT);}static void locomo_lt_mask_irq(unsigned int irq){	void *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_LTINT);	r &= ~(0x0010 << (irq - LOCOMO_IRQ_LT_START));	locomo_writel(r, mapbase + LOCOMO_LTINT);}static void locomo_lt_unmask_irq(unsigned int irq){	void *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_LTINT);	r |= (0x0010 << (irq - LOCOMO_IRQ_LT_START));	locomo_writel(r, mapbase + LOCOMO_LTINT);}static struct irqchip locomo_lt_chip = {	.ack	= locomo_lt_ack_irq,	.mask	= locomo_lt_mask_irq,	.unmask	= locomo_lt_unmask_irq,};static void locomo_spi_handler(unsigned int irq, struct irqdesc *desc,			    struct pt_regs *regs){	int req, i;	struct irqdesc *d;	void *mapbase = get_irq_chipdata(irq);	req = locomo_readl(mapbase + LOCOMO_SPIIR) & 0x000F;	if (req) {		irq = LOCOMO_IRQ_SPI_START;		d = irq_desc + irq;		for (i = 0; i <= 3; i++, irq++, d++) {			if (req & (0x0001 << i)) {				d->handle(irq, d, regs);			}		}	}}static void locomo_spi_ack_irq(unsigned int irq){	void *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_SPIWE);	r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START));	locomo_writel(r, mapbase + LOCOMO_SPIWE);	r = locomo_readl(mapbase + LOCOMO_SPIIS);	r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));	locomo_writel(r, mapbase + LOCOMO_SPIIS);	r = locomo_readl(mapbase + LOCOMO_SPIWE);	r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));	locomo_writel(r, mapbase + LOCOMO_SPIWE);}static void locomo_spi_mask_irq(unsigned int irq){	void *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_SPIIE);	r &= ~(0x0001 << (irq - LOCOMO_IRQ_SPI_START));	locomo_writel(r, mapbase + LOCOMO_SPIIE);}static void locomo_spi_unmask_irq(unsigned int irq){	void *mapbase = get_irq_chipdata(irq);	unsigned int r;	r = locomo_readl(mapbase + LOCOMO_SPIIE);	r |= (0x0001 << (irq - LOCOMO_IRQ_SPI_START));	locomo_writel(r, mapbase + LOCOMO_SPIIE);}static struct irqchip locomo_spi_chip = {	.ack	= locomo_spi_ack_irq,	.mask	= locomo_spi_mask_irq,	.unmask	= locomo_spi_unmask_irq,};static void locomo_setup_irq(struct locomo *lchip){	int irq;	void *irqbase = lchip->base;	/*	 * Install handler for IRQ_LOCOMO_HW.	 */	set_irq_type(lchip->irq, IRQT_FALLING);	set_irq_chipdata(lchip->irq, irqbase);	set_irq_chained_handler(lchip->irq, locomo_handler);	/* Install handlers for IRQ_LOCOMO_*_BASE */	set_irq_chip(IRQ_LOCOMO_KEY_BASE, &locomo_chip);	set_irq_chipdata(IRQ_LOCOMO_KEY_BASE, irqbase);	set_irq_chained_handler(IRQ_LOCOMO_KEY_BASE, locomo_key_handler);	set_irq_flags(IRQ_LOCOMO_KEY_BASE, IRQF_VALID | IRQF_PROBE);	set_irq_chip(IRQ_LOCOMO_GPIO_BASE, &locomo_chip);	set_irq_chipdata(IRQ_LOCOMO_GPIO_BASE, irqbase);	set_irq_chained_handler(IRQ_LOCOMO_GPIO_BASE, locomo_gpio_handler);	set_irq_flags(IRQ_LOCOMO_GPIO_BASE, IRQF_VALID | IRQF_PROBE);	set_irq_chip(IRQ_LOCOMO_LT_BASE, &locomo_chip);	set_irq_chipdata(IRQ_LOCOMO_LT_BASE, irqbase);	set_irq_chained_handler(IRQ_LOCOMO_LT_BASE, locomo_lt_handler);

⌨️ 快捷键说明

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