📄 spioc.c
字号:
/* spioc.c, 2006-06-02 * GS0521117 秦广 */#ifndef __KERNEL__# define __KERNEL__#endif#ifndef MODULE# define MODULE#endif#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/errno.h>#include <linux/slab.h>#include <linux/mm.h>#include <linux/init.h>#include <asm/uaccess.h>#include <linux/interrupt.h>#include <linux/irq.h>#include <asm/hardware.h>#include <linux/delay.h>#include "spioc.h"#include <linux/miscdevice.h>#include <linux/sched.h>#include <linux/poll.h>#include <linux/spinlock.h>#include <asm/hardware.h>#undef DEBUG#define DEBUG#ifdef DEBUG#define DPRINTK( x... ) printk("s3c2410-kbd: " ##x)#else#define DPRINTK( x... )#endif#define DEVICE_NAME "spioc"#define KBDRAW_MINOR 1static int spioc_major = 0;#ifdef CONFIG_DEVFS_FSstatic devfs_handle_t devfs_spioc;#endif /**********************************************************************/DECLARE_WAIT_QUEUE_HEAD(spioc_queue);static void spioc_do_tasklet(unsigned long);DECLARE_TASKLET(spioc_tasklet,spioc_do_tasklet,0);/*do tasklet*/static void spioc_do_tasklet(unsigned long temp){ int i; char p; printk("tasklet is here.qinguang"); for(i=0; i<count/2; i++) { p=wbuff[i]; wbuff[i]= wbuff[count-i-1]; wbuff[count-i-1]=p; } //唤醒中断 wake_up_interruptible(&spioc_queue); return;}/*中断响应函数*/static void spioc_interrupt(int irq, void *dev_id, struct pt_regs *regs){ printk("kbd interrupt received.\n"); printk("here is call talklet_schedule,spioc_tasklet .jw\n"); tasklet_schedule(&spioc_tasklet); return;}/* open and close */static int spioc_open(struct inode *inode, struct file *filp){ enable_irq(IRQ_EINT4); memset(wbuff, 0, BUFFSIZE); memset(rbuff, 0, BUFFSIZE); count = 0; //初始化中断 init_waitqueue_head(&spioc_queue); MOD_INC_USE_COUNT; DPRINTK( "opened\n"); return 0; }static int spioc_close(struct inode *inode, struct file *filp){ MOD_DEC_USE_COUNT; //禁止中断 disable_irq(IRQ_EINT4); DPRINTK("closed\n"); return 0;}/* read and write */static ssize_t spioc_read(struct file *filp, char *buf, size_t cnt, loff_t *off){ int i; printk("calling spioc_read(),interruptible_sleep_on.\n"); interruptible_sleep_on(&spioc_queue); if(signal_pending(current)) return -ERESTARTSYS; if(!count) return 0; for(i=0; i<count; i++) rbuff[i] = wbuff[i]; if(cnt > count) cnt = count; copy_to_user(buf, rbuff, cnt); return cnt;}static ssize_t spioc_write(struct file *filp, const char *buf, size_t cnt, loff_t *off){ printk("Write to wbuff,Copy_from_user().\n"); if(cnt > BUFFSIZE) cnt = BUFFSIZE; copy_from_user(wbuff, buf, cnt); count = cnt; return cnt;}/* ioctl */static int spioc_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){ switch(cmd) { default: break; } return 0;}/* the device fops */static struct file_operations spioc_fops = { owner: THIS_MODULE, read: spioc_read, write: spioc_write, ioctl: spioc_ioctl, open: spioc_open, release: spioc_close,};/* init and exit */static int __init spioc_init(void){ int ret; int flags; int result; int result_irq; wbuff = kmalloc(BUFFSIZE, GFP_KERNEL); rbuff = kmalloc(BUFFSIZE, GFP_KERNEL); ret = set_external_irq(IRQ_EINT4, EXT_FALLING_EDGE, GPIO_PULLUP_EN); local_irq_save(flags); DPRINTK("system register=0x%x\n", ret); result = register_chrdev(SPIOC_MAJOR, "spioc", &spioc_fops); if(result < 0) { printk(KERN_ERR "Cannot register spioc device.\n"); kfree(wbuff); kfree(rbuff); return -EIO; } result_irq = request_irq(IRQ_EINT4, spioc_interrupt,SA_INTERRUPT, "spioc",spioc_interrupt); if(result_irq) { printk("spioc: irq request failed.\n"); }#ifdef CONFIG_DEVFS_FS result = devfs_register_chrdev(0,DEVICE_NAME, &spioc_fops); if(result < 0) return result; spioc_major = result; devfs_spioc = devfs_register(NULL, "spioc", DEVFS_FL_DEFAULT, spioc_major, KBDRAW_MINOR, S_IFCHR | S_IRUSR | S_IWUSR, &spioc_fops, NULL);#endif printk (DEVICE_NAME"\tinitialized\n"); return 0;}static void __exit spioc_exit(void){ int result;#ifdef CONFIG_DEVFS_FS devfs_unregister(devfs_spioc);#endif unregister_chrdev(spioc_major, DEVICE_NAME); result = unregister_chrdev(SPIOC_MAJOR, "spioc"); if(result < 0) { printk(KERN_ERR "Cannot remove spioc device.\n"); return; } free_irq(IRQ_EINT4,NULL); if(wbuff) kfree(wbuff); if(rbuff) kfree(rbuff); return;}module_init(spioc_init);module_exit(spioc_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -