#include <linux/init.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/errno.h> /* error codes */
#include <asm/uaccess.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/fs.h> /* everything... */
#include <asm/semaphore.h>
#include <asm/arch/cpu_s3c2410.h>
#include <asm/hardware.h>
#include <linux/delay.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <asm/irq.h>
#include <linux/vmalloc.h>
#include <linux/config.h>
#include <linux/time.h>
#include <linux/spinlock.h>
//#include <linux/malloc.h>
#include <asm/delay.h>
#include <asm/io.h>
#include <asm-arm/arch-s3c2410/irqs.h>
#include <asm-arm/irq.h>
#include <linux/devfs_fs_kernel.h>
#define DEVICE_NAME "irq_drv"
static int major = 241; //Define device major
static void *gpfcon;
static void *gpfdat;
static void *gpfup;
devfs_handle_t irq_devfs_dir;
//static devfs_handle_t devfs_handle;
static int count=0;
static int __init irq_init(void);
void __exit demo_exit(void);
void test_ctl(unsigned long var)
{
if(var)
{
printk("this is a ioctl test:%d\n",var);
}
}
static int irq_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
switch(cmd)
{
case 0:break;
default:test_ctl(arg);break;
}
return 0;
}
static int
irq_read(struct file *filp, char *buffer, size_t count, loff_t *ppos)
{
char tmp=0xaa;
copy_to_user(buffer,(char *)&tmp,sizeof(tmp));
return 0;
}
static int
irq_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
{
int data;
copy_from_user(&data, buffer, count);
printk("Write data is:%d\n",data);
return count;
}
static int
irq_open(struct inode *inode,struct file *file)
{
MOD_INC_USE_COUNT;
return 0;
}
static int
irq_release(struct inode *inode,struct file *file)
{
MOD_DEC_USE_COUNT;
return 0;
}
static struct file_operations irq_fops =
{
.owner = THIS_MODULE,
.ioctl = irq_ioctl,
.open = irq_open,
.read = irq_read,
.write = irq_write,
.release = irq_release,
};
static int irq_func(void)
{
count ++;
printk("irq comes time is:%d\n ",count);
return 0;
}
static int __init irq_init(void)
{
int ret;
gpfcon = ioremap(0x56000050, 0x04);
gpfdat = ioremap(0x56000054, 0x04);
gpfup = ioremap(0x56000058,0x04);
writel((readl(gpfcon)&0x3fff)|0x8000,gpfcon);//set gpf7 as eint7
ret=set_external_irq(IRQ_EINT7, EXT_BOTH_EDGES, 0); /*给中断赋值操作方式 边沿操作/#define EXT_LOWLEVEL 0
#define EXT_HIGHLEVEL 1
#define EXT_FALLING_EDGE 2
#define EXT_RISING_EDGE 4
#define EXT_BOTH_EDGES 6 */
request_irq(IRQ_EINT7,irq_func, SA_INTERRUPT, DEVICE_NAME, NULL); //注册中断
ret = register_chrdev(major, DEVICE_NAME, &irq_fops); //创建设备节点
if (ret < 0)
{
printk("irq register failed\n");
return ret;
}
devfs_register(irq_devfs_dir,DEVICE_NAME,DEVFS_FL_AUTO_DEVNUM,0,0,S_IFCHR|S_IRUGO|S_IWUGO,&irq_fops,NULL); //注册设备
printk("irq driver initialized.\n");
return 0;
}
void __exit demo_exit(void)
{
//devfs_unregister(devfs_dectect);
unregister_chrdev(major, DEVICE_NAME);
}
module_init(irq_init);
module_exit(demo_exit);
MODULE_AUTHOR("shencai555 <shencai555@hotmail.com>");
MODULE_DESCRIPTION("irq Driver");
MODULE_LICENSE("GPL");