wait_event_interruptible and wake_up_interruptible

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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");


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux