/******************************************************************** * I.MX6 bq27441 GPOUT interrupt * 说明: * 由于目前的bq27441驱动中没有GPOUT中断驱动,所以需要另外加上,其 * 中有参考TI的驱动,但是内核版本不一致,所以处理方式也不一致。 * * 2016-7-15 深圳 南山平山村 曾剑锋 *******************************************************************/ 一、参考文档: a reasonable example of a work queue? http://www.spinics.net/lists/newbies/msg27303.html 二、修改drivers/power/bq27x00_battery.c ...... #include <linux/interrupt.h> #include <linux/gpio.h> #define SABRESD_UAUGE_PIN IMX_GPIO_NR(1, 29) ...... static void battery_irq(struct work_struct *unused); static DECLARE_DELAYED_WORK(battery_irq_work, battery_irq); struct bq27x00_device_info *battery_irq_work_di = NULL; static void battery_irq(struct work_struct *unused) { if (battery_irq_work_di != NULL) bq27x00_update(battery_irq_work_di); } static irqreturn_t bq27xxx_battery_irq_handler_thread(int irq, void *data) { struct bq27x00_device_info *di = data; battery_irq_work_di = di; schedule_delayed_work(&battery_irq_work, 0); return IRQ_HANDLED; } ...... static int __init bq27x00_battery_probe(struct i2c_client *client, const struct i2c_device_id *id) { ...... gpio_request(SABRESD_UAUGE_PIN, "sabresd_uauge_pin"); gpio_direction_input(SABRESD_UAUGE_PIN); unsigned int irq = gpio_to_irq(SABRESD_UAUGE_PIN); int ret = request_irq(irq, bq27xxx_battery_irq_handler_thread, IRQF_TRIGGER_RISING, "sabresd_uauge_pin", di); enable_irq_wake(irq); ...... }