- 論壇徽章:
- 0
|
打開驅(qū)動的時候,按下按鍵后出現(xiàn)如下
Occured key board Inetrrupt,irq=11
buttonEvent_1
irq55: nobody cared
PC is at 0x8430
LR is at 0x3c00
pc : [<00008430>] lr : [<00003c00>] Not tainted
sp : befffd24 ip : 00000000 fp : befffd54
r10: 4013d180 r9 : 000083d8 r8 : 4013f430
r7 : 00000001 r6 : 00008444 r5 : 4001bd80 r4 : befffd84
r3 : 00000003 r2 : befffd8c r1 : 00000002 r0 : 00000003
Flags: nzcv IRQs on FIQs on Mode USER_32 Segment user
Control: C000717F Table: 3260C000 DAC: 00000015
handlers:
[<bf030074>] (isr_button+0x0/0x8c [button])
/*************驅(qū)動程序如下******************************/
/*gpio_mod.c*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/sched.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/console.h>
#include <linux/parport.h>
#include <linux/lp.h>
#include <asm/io.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#define GPECON (0x56000040)
#define GPFCON (0x56000050)
#define GPGCON (0x56000060)
#define GPEDAT (0x56000044)
#define GPGDAT (0x56000064)
#define SRCPND (0x4A000000)
#define EINTMASK (0x560000A4)
#define INTMASK (0x4A00000
static void *gpecon;
static void *gpfcon;
static void *gpgcon;
static void *gpedat;
static void *gpgdat;
static void *srcpnd;
static void *eintmask;
static void *intmask;
#define keyirq_MAJOR 242
#define NAME "button16"
#define NOKEY '0'
#define KEY1 '1'
#define KEY2 '2'
#define KEY3 '3'
#define KEY4 '4'
static struct semaphore key_sem;
static char key=NOKEY;
static void inline clearIrq(void)
{
writel(readl(srcpnd)|0x25,srcpnd);//clear srcpnd 0 2 11 19
}
static irqreturn_t key1_irq_isr(int irq, void *dev_id, struct pt_regs *regs)
{
clearIrq();
key = KEY1;
up(&key_sem);
return 0;
}
static irqreturn_t key2_irq_isr(int irq, void *dev_id, struct pt_regs *regs)
{
clearIrq();
key = KEY2;
up(&key_sem);
return 0;
}
static irqreturn_t key3_irq_isr(int irq, void *dev_id, struct pt_regs *regs)
{
clearIrq();
key = KEY3;
up(&key_sem);
return 0;
}
static irqreturn_t key4_irq_isr(int irq, void *dev_id, struct pt_regs *regs)
{
clearIrq();
key = KEY4;
up(&key_sem);
return 0;
}
static ssize_t keyirq_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
down_interruptible(&key_sem);
put_user(key, buf);
key = NOKEY;
return 1;
}
int keyirq_open(struct inode *inode, struct file *file)
{
clearIrq();
#if 1
enable_irq(IRQ_EINT0);
enable_irq(IRQ_EINT2);
enable_irq(IRQ_EINT11);
enable_irq(IRQ_EINT19);
#endif
sema_init(&key_sem, 0);
return 0;
}
int keyirq_release(struct inode *inode, struct file *filp)
{
#if 1
disable_irq(IRQ_EINT0);
disable_irq(IRQ_EINT2);
disable_irq(IRQ_EINT11);
disable_irq(IRQ_EINT19);
#endif
return 0;
}
static int keyirq_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
return 0;
}
struct file_operations keyirq_fops = {
.owner= THIS_MODULE,
.read = keyirq_read,
.open = keyirq_open,
.release = keyirq_release,
.ioctl = keyirq_ioctl,
};
int __init keyirq_init(void)
{
int rc;
gpecon=ioremap_nocache(GPECON,0x0000004);
gpfcon=ioremap_nocache(GPFCON,0x0000004);
gpgcon=ioremap_nocache(GPGCON,0x0000004);
srcpnd=ioremap_nocache(SRCPND,0x0000004);
intmask=ioremap_nocache(INTMASK,0x0000004);
eintmask=ioremap_nocache(EINTMASK,0x0000004);
gpedat=ioremap_nocache(GPEDAT,0x0000004);//remap, ready for follow step
gpgdat=ioremap_nocache(GPGDAT,0x0000004);
writel(readl(gpecon)& (~((3<<26)|(3<<22))),gpecon);//set gpe11 13 to output
writel(readl(gpecon) | ((1<<26)|(1<<22)),gpecon);
writel(readl(gpedat)&(~((1<<13)|(1<<11))) ,gpedat); //set GPE11 13 to 00
writel(readl(gpgcon) & (~((3<<12)|(3<<4))),gpgcon);//set gpe2 6 to output
writel(readl(gpgcon) | ((1<<12)|(1<<4)),gpgcon);
writel(readl(gpgdat)&(~((1<<6)|(1<<2))) ,gpgdat); //set GPG2 6 to 00 :
writel(readl(gpgcon) & (~((3<<22)|(3<<6))),gpgcon); //set GPG3/EINT11,GPG11/EINT19
writel(readl(gpgcon) | ((2<<22)|(2<<6)),gpgcon);
writel(readl(gpfcon) & (~((3<<4)|(3<<0))),gpfcon);//set GPF0/EINT0,GPF2/EINT2
writel(readl(gpfcon) | ((2<<4)|(2<<0)),gpfcon);
set_irq_type(IRQ_EINT0, IRQT_FALLING);
set_irq_type(IRQ_EINT2, IRQT_FALLING);
set_irq_type(IRQ_EINT11, IRQT_FALLING);
set_irq_type(IRQ_EINT19, IRQT_FALLING);
writel(readl(intmask) | (~(0xffffffda)),intmask);
writel(readl(intmask)&0xffffffda,intmask);//中斷屏蔽寄存器 0 2
writel(readl(eintmask)| (~(0xfff7f7ff)),eintmask);
writel(readl(eintmask)&0xfff7f7ff,eintmask);//外部中斷屏蔽寄存器 11 19
rc = request_irq(IRQ_EINT0, key1_irq_isr, SA_INTERRUPT, NAME, NULL);
if (rc) {
printk ("<1>keyirq 1 irq not registered. Error:%d\n", rc);
}
rc = request_irq(IRQ_EINT2, key2_irq_isr, SA_INTERRUPT, NAME, NULL);
if (rc) {
printk ("<1>keyirq 2 irq not registered. Error:%d\n", rc);
}
rc = request_irq(IRQ_EINT11, key3_irq_isr, SA_INTERRUPT, NAME, NULL);
if (rc) {
printk ("<1>keyirq 3 irq not registered. Error:%d\n", rc);
}
rc = request_irq(IRQ_EINT19, key4_irq_isr, SA_INTERRUPT, NAME, NULL);
if (rc) {
printk ("<1>keyirq 4 irq not registered. Error:%d\n", rc);
}
#if 1
disable_irq(IRQ_EINT0);
disable_irq(IRQ_EINT2);
disable_irq(IRQ_EINT11);
disable_irq(IRQ_EINT19);
#endif
/*Register myirq as character device*/
if ((rc = register_chrdev(keyirq_MAJOR, NAME, &keyirq_fops)) < 0){
printk("keyirq: can't get major %d\n", keyirq_MAJOR);
return 1;
}
return 0;
}
void keyirq_exit(void)
{
#if 1
disable_irq(IRQ_EINT0);
disable_irq(IRQ_EINT2);
disable_irq(IRQ_EINT11);
disable_irq(IRQ_EINT19);
#endif
free_irq(IRQ_EINT0, NULL);
free_irq(IRQ_EINT2, NULL);
free_irq(IRQ_EINT11, NULL);
free_irq(IRQ_EINT19, NULL);
unregister_chrdev(keyirq_MAJOR, NAME);
}
module_init(keyirq_init);
module_exit(keyirq_exit);
[ 本帖最后由 andylao 于 2008-5-13 09:10 編輯 ] |
|