I want to use wait_event_interruptible and wake_up_interruptible to some jobs,but some error ouccor when wake_up_interruptible. Attach is the code.please help me.
#include <linux/config.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/fs.h> #include <linux/init.h> #include <linux/sched.h> #include <linux/delay.h> #include <linux/string.h> #include <linux/poll.h> #include <linux/interrupt.h> #include <linux/miscdevice.h> #include <linux/time.h> #include <asm/hardware.h> #include <asm/irq.h> #include <asm/uaccess.h> #include <asm/io.h> #include "ir.h" #include "hi_gpio.h" #define IR_PORT GPIO_1_BASE #define Irq_1 7 DECLARE_WAIT_QUEUE_HEAD(ir_wait_q); struct semaphore ir_sem; unsigned char sleep_flag=0; void gpio_init(void); /**************************receive*******************************/ void gpio_init(void) { unsigned int tmp; /*set gpio1 dir:out 3 in 2 */ gpio_dirgetbyte(1,&tmp); tmp=tmp&0xfb; tmp=tmp|0x08; gpio_dirsetbyte(1,tmp); /*set gpio1 interrupt:raise edge interrpt 2bit*/ gpio_interruptsenseset(1,2,SENSE_EDGE); gpio_interruptsenseboth(1,2,SENSE_SINGLE); gpio_interruptevenset(1,2,EVENT_RISING_EDGE); /*disable gpio1_2 interrupt*/ tmp=0x04; gpio_interruptdisable_byte(1,tmp); /*clear data gpio1_3*/ gpio_writebit(1,3,0); /*clear interrupt:gpio1_2*/ gpio_interruptclear(1,2); /*enable interrupt gpio1_2*/ /*tmp=0x04; gpio_interruptenable_byte(1,tmp);*/ } int ir_save_stream(void) { unsigned char current_irq; unsigned char flag; unsigned int tmp; unsigned int count; unsigned int i; i=1; flag=1; current_irq=readw(IR_PORT+GPIO_RIS); if(!(current_irq&0x4)) { printk("this is not ir_in_irq\n"); return -1; } udelay(250); gpio_readbit(1,2,&tmp); if (tmp!=1) // false irq; { printk("false ir_irq\n") ; return -1; } else { count=5; } while(count<250&&i<128) { udelay(50); gpio_readbit(1,2,&tmp); if(tmp==1) //high level { if(flag==1) //1 rising;0 falling { count=count+1; } else { ir_receive_stream[i].high_low=0; ir_receive_stream[i].counter_time=count; i++; count=1; flag=1; } } else //low level { if(flag==0) { count=count+1; } else { ir_receive_stream[i].high_low=1; ir_receive_stream[i].counter_time=count; i++; count=1; flag=0; } } if(i>127) { printk("ir_receive_stream buffer full!\n"); } if(count>=250) { printk("count biger than count!\n"); } } printk("ir save stream finished\n"); sleep_flag=1; printk("wake up ir_wait_q\n"); wake_up_interruptible(&ir_wait_q); return 0; } int ir_send_stream(void) { unsigned char i; unsigned char level; unsigned char count_delay; for(i=1;i<128;i++) { level=ir_temp_stream[i].high_low; count_delay=ir_temp_stream[i].counter_time; gpio_writebit(1,3,level); further_delay_n50us(count_delay); } return 0; } static irqreturn_t ir_in_irq(int irq,void *dev_id,struct pt_regs *reg) { unsigned int tmp; int handled=0; tmp=0x04; gpio_interruptdisable_byte(1,tmp); ir_save_stream(); //gpio_interruptenable_byte(1,0x04); return IRQ_RETVAL(handled); } /*************************************************************************** **************************************************************************/ static int ir_open(struct inode *inode,struct file *file) { int i; for(i=0;i<128;i++) { ir_receive_stream[i].high_low=0; ir_receive_stream[i].counter_time=0; } gpio_interruptenable_byte(1,0x04); printk("ir_irq enable\n"); sleep_flag=0; return 0; } static int ir_close(struct inode *inode,struct file *file) { gpio_interruptdisable_byte(1,0x04); printk("ir_irq disable\n"); return 0; } static int ir_read(struct file *file,char __user *buffer,size_t count,loff_t *ppos) { struct ir_stream *user_buf; int ret; user_buf=(struct ir_stream *)buffer; printk("process %i(%s) going to sleep\n",current->pid,current->comm); wait_event_interruptible(ir_wait_q,sleep_flag!=0); printk("process %i(%s) awoken\n",current->pid,current->comm); ret=copy_to_user(user_buf,(struct ir_stream *)ir_receive_stream,128*sizeof(struct ir_stream)); if(ret) { printk("IR_error:error_val is %lu\n",ret); } else { printk("get ir stream success\n"); printk("copy_return val is %lu\n",ret); } sleep_flag=0; return 0; } static int ir_write(struct file *file,char __user *buffer,size_t count,loff_t *ppos) { struct ir_stream *user_buf; int ret; user_buf=(struct ir_stream *)buffer; ret=copy_from_user((struct ir_stream *)ir_temp_stream,user_buf,128*sizeof(struct ir_stream)); if(ret) { printk("IR_error:cpy_error_val is %lu\n",ret); } else { printk("get stream from user success\n"); printk("copy_return val is %lu\n",ret); } ir_send_stream(); return 0; } static int ir_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg) { void __user *argp=(void __user *)arg; switch(cmd) { case IR_GET_STREAM: { break; } default: return -EINVAL; } } static struct file_operations ir_fops= { .owner=THIS_MODULE, .open =ir_open, .release=ir_close, .ioctl=ir_ioctl, .read=ir_read, .write=ir_write, }; static struct miscdevice ir_dev= { MISC_DYNAMIC_MINOR, "irdev", &ir_fops, }; static int __init ir_init(void) { int ret; ret=misc_register(&ir_dev); if(ret) { printk("could not register ir devices.\n"); return ret; } gpio_remap(); ret=request_irq(Irq_1,&ir_in_irq,0,"irdev",NULL); if(ret) { misc_deregister(&ir_dev); printk("can't request irq 7\n"); return ret; } gpio_init(); return 0; } static void __exit ir_exit(void) { misc_deregister(&ir_dev); free_irq(Irq_1,NULL); gpio_unmap(); } module_init(ir_init); module_exit(ir_exit); MODULE_LICENSE("GPL");