Linux的device wakeup
设备可以将系统从suspend状态唤醒,比如gpio,power key,tp,wifi/bt wakeup等,这些都可以将系统从suspend状态唤醒。
1)相关函数
device_init_wakeup(struct device *dev, bool val); // 初始化设备能不能唤醒系统,通常在设备初始化时使能,在remove时禁用
device_may_wakeup // 判断设备是否注册了唤醒
device_wakeup_enable(struct device *dev); // Enable given device to be a wakeup source
device_wakeup_disable(struct device *dev);
device_set_wakeup_capable(struct device *dev, bool capable);
device_set_wakeup_enable(struct device *dev, bool enable); //Enable or disable a device to wake up the system.
2)唤醒必须有中断源,以下是常使用的中断函数
int gpiod_to_irq(const struct gpio_desc *desc) //gpio转中断
void disable_irq(unsigned int irq);//禁用中断
void enable_irq(unsigned int irq);//使能中断
int request_threaded_irq(unsigned int irq, irq_handler_t handler,
irq_handler_t thread_fn,
unsigned long flags, const char *name, void *dev);
//其中参数thread_fn 是中断线程处理函数,类似中断的下半部,只是系统帮你做了,你只需要实现业务处理
int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
const char *name, void *dev)
//和上面request_threaded_irq的区别,中断处理函数handler作为上半部,不能耗时,把耗时操作放到tasklet或者workqueue
int request_any_context_irq(unsigned int irq, irq_handler_t handler,
unsigned long flags, const char *name, void *dev_id);
3)命令查看硬件中断命令:
cat /proc/interrupts
查看软件中断:
cat /proc/softirqs
4)有这样一种情况,中断触发后,中断处理函数一开始disable了中断,然后在下半部执行一个比较耗时的操作,而此时如果系统休眠了,因为上面已经禁用了中断,那将永远唤醒不了设备了,所以此时我们可以首先调用pm_stay_awake,来增加休眠计数,这样可以阻止系统进入休眠,同样,在中断下半部,处理完以后,调用pm_relax减少计数
pm_stay_awake(struct device *dev);
pm_relax(struct device *dev);
pm_wakeup_event(struct device *dev, unsigned int msec);