struct powerkey_t *p = &pwk;
if(sleepevent == DEEPSLEEP_EVENT)
{
if(p->ifopen > NOOPENED)
ret = wait_event_interruptible_timeout(p->keywaitq, p->pressed == KEYRELEASE, (3*HZ));
disable_wakeup();
wakeup_ack_irq();
}
if(p->ifopen > NOOPENED)
{
p->handshake = NONEEDHANDSHAKE;
ret = wait_event_interruptible_timeout(p->keywaitq, p->handshake == HANDSHAKE_EVENT_OK, (20*HZ));
if( ret == 0)
{
printk("Handshake timeout\n");
}
p->handshake = NONEEDHANDSHAKE;
}
if(sleepevent == DEEPSLEEP_EVENT)
{
wakeup_init();
wakeup_ack_irq();
}
pb_sleep_exe(sleepevent);
wait_wakeup_handshake();
return 0;
}
static int wait_handshake_sleep(int sleepevent)
{
int ret;
struct powerkey_t *p = &pwk;
p->event = sleepevent;
if(p->ifhandshake == REQUESTHANDSHAKE)
{ //for signal mode
if(pb_handshake(SIGIO,POLL_IN))
{
printk("Posting Handshake fail\n");
return -1;
}
ret = preevent_sleep(sleepevent);
}
else //for polling mode
{
ret = preevent_sleep(sleepevent);
}
return 0;
}
/*
wait_event_interruptible_timeout(queue, condition, timeout)
使用例如:
(1)初始化等待队列
int flags = 0;
wait_queue_head_t select_wait;
init_waitqueue_head(&select_wait);
(2)等待事件的发生(条件满足)
{
...
wait_event_interruptible_timeout(select_wait, flags != 0, HZ/10);
...
}
(3)唤醒等待队列
{
...
if(waitqueue_active(&select_wait))
{
flags = 1;
wake_up_interruptible( &nd->select_in_wait );
}
...
}
*/
static int driver_data_init(void)
{
struct powerkey_t *ppwk = &pwk;
if(PECR & PECR_IVE0)
{
ppwk->pressed = KEYPRESSED;
}
else
{
ppwk->pressed = KEYRELEASE;
}
ppwk->ifopen = NOOPENED;
ppwk->event = NORMAL_EVENT;
ppwk->handshake = NONEEDHANDSHAKE;
ppwk->checkforsleep = NONEEDCHECKSLEEP;
ppwk->ifhandshake = FREEHANDSHAKE;
ppwk->ifreleasehandshakecnt = 0;
init_waitqueue_head(&ppwk->keywaitq);
return 0;
}
static int powerkey_thread(void *data)
{
struct powerkey_t *ppwk = &pwk;
long ret;
// unsigned long flags;
//printk("%s\n",__FUNCTION__);
while(!kthread_should_stop())
{
set_current_state(TASK_INTERRUPTIBLE);
//if(kthread_should_stop()) break;
while(ppwk->checkforsleep == NEEDCHECKSLEEP)
{
ret = wait_event_interruptible_timeout(ppwk->keywaitq, ppwk->pressed == KEYRELEASE, (2*HZ));
if(ret == 0)
{ //time out
//disable_wakeup0_int();
//wakeup0_ack_irq();
ret = wait_handshake_sleep(DEEPSLEEP_EVENT);
ppwk->checkforsleep = NONEEDCHECKSLEEP;
//wakeup0_init();
//wakeup0_ack_irq();
}
else
{
disable_wakeup();
wakeup_ack_