特殊按键--休眠键驱动(五)

2014-11-24 07:27:14 · 作者: · 浏览: 5
irq();
ret = wait_handshake_sleep(SLEEP_EVENT);
ppwk->checkforsleep = NONEEDCHECKSLEEP;
wakeup_init();
wakeup_ack_irq();
}
}
//schedule_timeout();
ret = wait_event_interruptible_timeout(ppwk->keywaitq, ppwk->checkforsleep == NEEDCHECKSLEEP, (2*HZ));
}
printk("%s exit!\n",__FUNCTION__);
return 0;
}
static int create_powerkey_thread(void)
{
struct powerkey_t *ppwk = &pwk;
//printk("%s\n",__FUNCTION__);
ppwk->p_thread = kthread_run(&powerkey_thread,NULL,"powerkey_thread");
if(ppwk->p_thread == NULL)
{
printk("%s failed\n",__FUNCTION__);
return -1;
}
return 0;
}
static void delete_powerkey_thread(void)
{
struct powerkey_t *ppwk = &pwk;
//printk("%s\n",__FUNCTION__);
if(ppwk->p_thread)
{
kthread_stop(ppwk->p_thread);
}
ppwk->p_thread = NULL;
}
/*
struct task_struct *kthread_create(int (*threadfn)(void *data),void *data,const char *namefmt, ...);
线程创建后,不会马上运行,而是需要将kthread_create() 返回的task_struct指针传给wake_up_process(),然后通过此函数运行线程。
struct task_struct *kthread_run(int (*threadfn)(void *data),void *data,const char *namefmt, ...); 创建并启动线程
int kthread_stop(struct task_struct *thread);
线程一旦启动起来后,会一直运行,除非该线程主动调用do_exit函数,或者其他的进程调用kthread_stop函数,结束线程的运行
kthread_should_stop()函数,我们需要在开启的线程中嵌入该函数并检查此函数的返回值,否则kthread_stop是不起作用的
类似,我们也可以创建其他几条线程。
*/
static int pb_fasync(int fd,struct file* filp,int mode)
{
struct powerkey_t *ppwk = &pwk;
//printk("%s\n",__FUNCTION__);
ppwk->ifhandshake = REQUESTHANDSHAKE;
ppwk->ifreleasehandshakecnt++;
return fasync_helper(fd,filp,mode,&ppwk->pwrkey_async_queue);
}
static int pb_handshake(int sig,int mode)
{
struct powerkey_t *ppwk = &pwk;
//printk("%s\n",__FUNCTION__);
if(ppwk->pwrkey_async_queue)
{
kill_fasync(&ppwk->pwrkey_async_queue,sig,mode);
return 0;
}
//printk("%s failed.no async_queue\n",__FUNCTION__);
return -1;
}
static void release_fasync(struct file *file)
{
int ret;
struct powerkey_t *p = &pwk;
//printk("%s\n",__FUNCTION__);
if(p->ifreleasehandshakecnt != 0)
p->ifreleasehandshakecnt--;
if(p->ifhandshake == REQUESTHANDSHAKE) //have
{
if(p->ifreleasehandshakecnt == 0)
{
ret = fasync_helper(-1,file,0,&p->pwrkey_async_queue);
printk("%s fasync_helper ret=%d\n",__FUNCTION__,ret);
if(p->pwrkey_async_queue)
{
p->pwrkey_async_queue = NULL;
}
p->ifhandshake = FREEHANDSHAKE;
}
}
}
/*
异步通知:一旦设备就绪,则主动通知应用程序,不需要查询。
设备驱动中异步通知比较简单,主要用到fasync_struct结构体,还有下面两个函数。
int fasync_helper(int fd, struct file *filp, int mode, struct fasync_struct **fa); 处理FASYNC标志变更的函数。记得要释放
void kill_fasync(struct fasync_struct **fa, int sig, int band); 释放信号用的函数
sig信号用的最多的是SIGIO,可读时band设置为POLL_IN,可写时band设置为POLL_OUT。
*/
int pb_open(struct inode *