将key.c修改为:
1 #include <linux/init.h> 2 #include <linux/module.h> 3 #include <linux/miscdevice.h> 4 #include <linux/fs.h> 5 #include <linux/interrupt.h> 6 #include <linux/io.h> 7 #include <linux/wait.h> 8 #include <linux/uaccess.h> 9 #include <linux/workqueue.h> 10 11 #define GPNCON 0x7F008830 12 13 struct my_key_struct { 14 int irq; 15 int id; 16 char name[16]; 17 }; 18 19 struct my_key_struct my_key_config[6] = { 20 {S3C_EINT(0), 0, "key0"}, 21 {S3C_EINT(1), 1, "key1"}, 22 {S3C_EINT(2), 2, "key2"}, 23 {S3C_EINT(3), 3, "key3"}, 24 {S3C_EINT(4), 4, "key4"}, 25 {S3C_EINT(5), 5, "key5"}, 26 }; 27 28 static int __g_key_value; 29 30 int volatile condition = 0; 31 DECLARE_WAIT_QUEUE_HEAD(key_wqh); 32 33 //struct work_struct my_work; 34 struct delayed_work my_delayed_work; 35 struct workqueue_struct *p_my_workqueue; 36 37 void my_work_func (struct work_struct *p_work) 38 { 39 condition = 1; 40 wake_up_interruptible(&key_wqh); 41 } 42 43 irqreturn_t key_irqhandler (int irq, void *p_arg) 44 { 45 __g_key_value = *((int *)p_arg); 46 47 printk("irq\n"); 48 49 //schedule_work(&my_work); 50 //schedule_delayed_work(&my_delayed_work, 2); 51 //queue_work(p_my_workqueue, &my_work); 52 queue_delayed_work(p_my_workqueue, &my_delayed_work, 20); 53 54 return 0; 55 } 56 57 static int key_open (struct inode *p_inode, struct file *p_file) 58 { 59 int ret, i; 60 int *p_gpncon; 61 int temp; 62 63 p_gpncon = ioremap(GPNCON, 4); 64 temp = readl(p_gpncon); 65 temp &= ~(0xFFF); 66 temp |= 0xAAA; 67 writel(temp, p_gpncon); 68 69 for (i = 0; i < 6; i++) { 70 ret = request_irq(my_key_config[i].irq, 71 key_irqhandler, 72 IRQF_TRIGGER_FALLING, 73 my_key_config[i].name, 74 (void*)&my_key_config[i].id); 75 76 if (ret != 0) { 77 78 i--; 79 while (i >= 0) { 80 free_irq(my_key_config[i].irq, (void*)&my_key_config[i].id); 81 } 82 return -1; 83 } 84 } 85 86 p_my_workqueue = create_singlethread_workqueue("my_workqueue"); 87 88 //INIT_WORK(&my_work, my_work_func); 89 INIT_DELAYED_WORK(&my_delayed_work, my_work_func); 90 91 return 0; 92 } 93 94 static int key_close (struct inode *p_inode, struct file *p_file) 95 { 96 int i; 97 98 for (i = 0; i < 6; i++) { 99 free_irq(my_key_config[i].irq, (void*)&my_key_config[i].id); 100 } 101 102 destroy_workqueue(p_my_workqueue); 103 104 return 0; 105 } 106 107 static ssize_t key_read (struct file *p_file, char __user *p_dat, size_t size, loff_t *p_loff) 108 { 109 110 wait_event_interruptible(key_wqh, condition); 111 condition = 0; 112 113 copy_to_user(p_dat, &__g_key_value, 4); 114 115 return 4; 116 } 117 118 119 static struct file_operations fops = { 120 .owner = THIS_MODULE, 121 .open = key_open, 122 .release = key_close, 123 .read = key_read, 124 }; 125 126 static struct miscdevice key_dev = { 127 .minor = MISC_DYNAMIC_MINOR, 128 .name = "mykey", 129 .fops = &fops, 130 }; 131 132 static int __init key_init (void) 133 { 134 misc_register(&key_dev); 135 136 return 0; 137 } 138 139 static void __exit key_exit (void) 140 { 141 misc_deregister(&key_dev); 142 } 143 144 module_init(key_init); 145 module_exit(key_exit); 146 147 MODULE_LICENSE("GPL");
第52行的延时时间与按键质量有关系,按键抖动厉害的话就适当增加时间。