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 10 #define GPNCON 0x7F008830 11 12 struct my_key_struct { 13 int irq; 14 int id; 15 char name[16]; 16 }; 17 18 struct my_key_struct my_key_config[6] = { 19 {S3C_EINT(0), 0, "key0"}, 20 {S3C_EINT(1), 1, "key1"}, 21 {S3C_EINT(2), 2, "key2"}, 22 {S3C_EINT(3), 3, "key3"}, 23 {S3C_EINT(4), 4, "key4"}, 24 {S3C_EINT(5), 5, "key5"}, 25 }; 26 27 static int __g_key_value; 28 29 int volatile condition = 0; 30 DECLARE_WAIT_QUEUE_HEAD(key_wqh); 31 32 irqreturn_t key_irqhandler (int irq, void *p_arg) 33 { 34 //printk("eint %d\n", *((int *)p_arg)); 35 36 __g_key_value = *((int *)p_arg); 37 38 condition = 1; 39 wake_up_interruptible(&key_wqh); 40 41 return 0; 42 } 43 44 static int key_open (struct inode *p_inode, struct file *p_file) 45 { 46 int ret, i; 47 int *p_gpncon; 48 int temp; 49 50 p_gpncon = ioremap(GPNCON, 4); 51 temp = readl(p_gpncon); 52 temp &= ~(0xFFF); 53 temp |= 0xAAA; 54 writel(temp, p_gpncon); 55 56 for (i = 0; i < 6; i++) { 57 ret = request_irq(my_key_config[i].irq, 58 key_irqhandler, 59 IRQF_TRIGGER_FALLING, 60 my_key_config[i].name, 61 (void*)&my_key_config[i].id); 62 63 if (ret != 0) { 64 65 i--; 66 while (i >= 0) { 67 free_irq(my_key_config[i].irq, (void*)&my_key_config[i].id); 68 } 69 return -1; 70 } 71 } 72 return 0; 73 } 74 75 static int key_close (struct inode *p_inode, struct file *p_file) 76 { 77 int i; 78 79 for (i = 0; i < 6; i++) { 80 free_irq(my_key_config[i].irq, (void*)&my_key_config[i].id); 81 } 82 83 return 0; 84 } 85 86 static ssize_t key_read (struct file *p_file, char __user *p_dat, size_t size, loff_t *p_loff) 87 { 88 89 wait_event_interruptible(key_wqh, condition); 90 condition = 0; 91 92 copy_to_user(p_dat, &__g_key_value, 4); 93 94 //printk("**************\n"); 95 96 return 4; 97 } 98 99 100 static struct file_operations fops = { 101 .owner = THIS_MODULE, 102 .open = key_open, 103 .release = key_close, 104 .read = key_read, 105 }; 106 107 static struct miscdevice key_dev = { 108 .minor = MISC_DYNAMIC_MINOR, 109 .name = "mykey", 110 .fops = &fops, 111 }; 112 113 static int __init key_init (void) 114 { 115 misc_register(&key_dev); 116 117 return 0; 118 } 119 120 static void __exit key_exit (void) 121 { 122 misc_deregister(&key_dev); 123 } 124 125 module_init(key_init); 126 module_exit(key_exit); 127 128 MODULE_LICENSE("GPL");
key_app.c
1 #include <stdio.h> 2 #include <sys/types.h> 3 #include <sys/stat.h> 4 #include <fcntl.h> 5 6 int main(int argc, const char *argv[]) 7 { 8 int fd; 9 int key_val; 10 11 fd = open("/dev/mykey", O_RDWR); 12 13 while (1) { 14 if (4 == read(fd, &key_val, 4)) { 15 printf("key_val = %d\n", key_val); 16 } else { 17 printf("fail to read\n"); 18 } 19 } 20 21 return 0; 22 }
这样调用read的时候回阻塞,直到中断发生