全志_外部中断


平台:全志A64

源码:Android 7.1  Linux3.1

  1 #include <linux/init.h>
  2 #include <linux/module.h>
  3 #include <linux/fs.h>
  4 #include <linux/device.h>
  5 #include <linux/slab.h>
  6 #include <linux/gpio.h>
  7 #include <linux/cdev.h>
  8 #include <linux/interrupt.h>
  9 #include <linux/input.h>
 10 #include <asm/io.h>
 11 #include <asm/string.h>
 12 #include <asm/uaccess.h>
 13 #include <asm-generic/ioctl.h>
 14 #include <linux/kernel.h>
 15 #include <linux/interrupt.h>
 16 #include <linux/input.h>
 17 #include <linux/platform_device.h>
 18 #include <linux/list.h>
 19 #include <linux/spinlock.h>
 20 #include <linux/rwsem.h>
 21 #include <linux/timer.h>
 22 #include <linux/module.h>
 23 #include <linux/err.h>
 24 #include <linux/ctype.h>
 25 #include <linux/sysfs.h>
 26 #include <linux/of.h>
 27 #include <linux/of_gpio.h>
 28 #include <linux/miscdevice.h>
 29 #include <linux/delay.h>
 30 #include <linux/sys_config.h>
 31
 32 // 串口3     RX      PH5   PH_EINT5
 33
 34 #define IR_GPIO GPIOH(8)               //外部中断引脚
 35
 36
 37 //定义个数据包
 38 struct fsp_event{
 39     int code;
 40     int value;
 41 };
 42
 43
 44 //面向对象-设备的类型
 45 struct fsp{
 46     //unsigned int major;
 47     dev_t  devno;
 48     struct class * cls;
 49     struct device * dev;
 50     struct cdev  *cdev;
 51     unsigned int irqno;
 52     struct fsp_event event;
 53     int data;
 54 };
 55 struct fsp *fsp_dev;
 56
 57
 58 //中断服务函数
 59 irqreturn_t fsp_irq_svc(int irqno, void *dev)
 60 {
 61     printk("irq success !\n");    //for text 
 62
 63
 64     return IRQ_HANDLED;
 65 }
 66
 67
 68 //设备操作接口
 69 int fsp_open(struct inode *inode, struct file *filp)
 70 {
 71
 72
 73     return 0;
 74 }
 75
 76
 77 ssize_t fsp_read(struct file *filp , char __user *buf , size_t size, loff_t *flags)
 78 {
 79
 80
 81
 82     return size;
 83 }
 84
 85 ssize_t fsp_write(struct file *filp, const char __user *buf, size_t size, loff_t *flags)
 86 {
 87
 88
 89     return size;
 90 }
 91
 92
 93 long fsp_ioctl(struct file *filp, unsigned int cmd , unsigned long args)
 94 {
 95
 96
 97     return 0;
 98 }
 99
100
101 int fsp_close(struct inode *inode, struct file *filp)
102 {
103
104
105     return 0;
106 }
107
108
109 static struct file_operations fops = {
110     .open = fsp_open,
111     .read = fsp_read,
112     .write = fsp_write,
113     .unlocked_ioctl = fsp_ioctl,
114     .release = fsp_close,
115 };
116
117 static int __init fsp_init(void)
118 {
119
120     printk("fsp_init  success !\n");
121
122     int ret;
123     fsp_dev = kzalloc(sizeof(struct fsp),GFP_KERNEL);
124     if(IS_ERR(fsp_dev)){
125         printk("kzalloc error!\n");
126         ret = PTR_ERR(fsp_dev);
127         return -ENOMEM;
128     }
129
130
131     //动态申请设备号
132     ret = alloc_chrdev_region(&fsp_dev->devno,0,1,"button_drv");
133     if(ret < 0){
134         printk("register_chrdev_region error!\n");
135         ret =  -EINVAL;
136         goto err_kfree;
137     }
138
139
140     //申请cdev的空间
141     fsp_dev->cdev = cdev_alloc();
142     if(IS_ERR(fsp_dev->cdev)){
143         printk("fsp_dev->cdev error!\n");
144         ret = PTR_ERR(fsp_dev->cdev);
145         goto err_unregister;
146     }
147
148     //初始化cdev的成员
149     cdev_init(fsp_dev->cdev,&fops);
150
151     //将cdev加入到内核中----链表
152     ret = cdev_add(fsp_dev->cdev,fsp_dev->devno,1);
153
154     //创建设备文件
155     fsp_dev->cls = class_create(THIS_MODULE,"fsp_dev");
156     if(IS_ERR(fsp_dev->cls)){
157         printk("class_create error!\n");
158         ret = PTR_ERR(fsp_dev->cls);
159         goto err_cdev_del;
160     }
161
162     fsp_dev->dev = device_create(fsp_dev->cls,NULL,fsp_dev->devno,NULL,"fsp_EINT");
163     if(IS_ERR(fsp_dev->dev)){
164         printk("device_create error!\n");
165         ret = PTR_ERR(fsp_dev->dev);
166         goto err_class;
167     }
168
169
170     fsp_dev->irqno = gpio_to_irq(IR_GPIO);   //中断号
171     ret = request_irq(fsp_dev->irqno,fsp_irq_svc,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,"eint-keydown",NULL);
172     if(ret != 0){
173         printk("request_irq error!\n");
174         ret = -EBUSY;
175         goto err_device;
176     }
177
178     return 0;
179
180 err_device:
181     device_destroy(fsp_dev->cls,fsp_dev->devno);
182 err_class:
183     class_destroy(fsp_dev->cls);
184
185 err_cdev_del:
186     cdev_del(fsp_dev->cdev);
187
188 err_unregister:
189     unregister_chrdev_region(fsp_dev->devno,1);
190
191 err_kfree:
192     kfree(fsp_dev);
193     return ret;
194
195 }
196
197 static void __exit fsp_exit(void)
198 {
199     printk("fsp_init  success !\n");
200
201     free_irq(fsp_dev->irqno,NULL);
202     device_destroy(fsp_dev->cls,fsp_dev->devno);
203     class_destroy(fsp_dev->cls);
204     cdev_del(fsp_dev->cdev);
205     unregister_chrdev_region(fsp_dev->devno,1);
206     kfree(fsp_dev);
207 }
208
209 module_init(fsp_init);
210 module_exit(fsp_exit);
211 MODULE_LICENSE("GPL");

 测试:

success

笔记


01-21 14:58