浅析linux的pmic单元使用实例
micco_thread()这个micco电源管理线程会先#define MICCO_LOOP_TIMEOUT 50
prepare_to_wait_exclusive(&micco_d->micco_wait_queue,
&micco_wait, TASK_INTERRUPTIBLE);
使thread进入pending状态,直到micco发生了irq中断或其他事件,然后irq或其他事件将调用 wake_up(&micco_d->micco_wait_queue);来唤醒thread或者经过 MICCO_LOOP_TIMEOUT超时后,唤醒该thread,所以当没有wake_up发生时,micco_thread就会以 MICCO_LOOP_TIMEOUT为周期,进行schedule_timeout(micco_d->micco_timeout);来定时检查micco状态.
如果出现电源键或者usb线插入,触发micco_irq_handler()中断,执行 wake_up(&micco_d->micco_wait_queue);唤醒micco_thread,紧接着将执行 pmic_event_handle()函数,这个函数是原子操作,他会遍历pxa3xx_pmic_ops->list链表上的所有对象,然后一一摘下,然后执行pmic_cb->func(event);操作,所以pmic_cb->func函数不能睡眠,同时必须尽可能快的执行完成,否则会影响kernel的实时性能表现.
对于micco_thread是在micco_probe的时候调用kernel_thread(&micco_thread, micco_d, 0);当即创建的.
有一下模块注册了pmic电源管理处理函数,也就是micco发生电源事件之后,有下面几个单元可以在micco返回的状态信息中,找到自己的事件状态.
pmic_callback_register(PMIC_EVENT_VBATMON, battery_low_interrupt);
pmic_callback_register(PMIC_EVENT_ONKEY, onkey_interrupt);
pmic_callback_register(PMIC_EVENT_HEADSET | PMIC_EVENT_HOOKSWITCH, headset_interrupt);
pmic_callback_register((PMIC_EVENT_CHARGER | PMIC_EVENT_VBUS),micco_charger_interrupt);
pmic_callback_register(PMIC_EVENT_USB, pxa3xx_usb_event_change);
|