bq24296: fix reboot warning
author黄涛 <huangtao@rock-chips.com>
Tue, 1 Apr 2014 10:29:36 +0000 (18:29 +0800)
committer黄涛 <huangtao@rock-chips.com>
Tue, 1 Apr 2014 10:31:09 +0000 (18:31 +0800)
WARNING: at kernel/irq/manage.c:1249 __free_irq+0x88/0x184()
Trying to free already-free IRQ 200
Modules linked in:
CPU: 0 PID: 1 Comm: init Not tainted 3.10.0 #296
[<c0013dc4>] (unwind_backtrace+0x0/0xe0) from [<c00116e0>] (show_stack+0x10/0x14)
[<c00116e0>] (show_stack+0x10/0x14) from [<c002a424>] (warn_slowpath_common+0x4c/0x68)
[<c002a424>] (warn_slowpath_common+0x4c/0x68) from [<c002a4c0>] (warn_slowpath_fmt+0x2c/0x3c)
[<c002a4c0>] (warn_slowpath_fmt+0x2c/0x3c) from [<c0091668>] (__free_irq+0x88/0x184)
[<c0091668>] (__free_irq+0x88/0x184) from [<c00917d8>] (free_irq+0x74/0x98)
[<c00917d8>] (free_irq+0x74/0x98) from [<c0412898>] (i2c_device_shutdown+0x3c/0x44)
[<c0412898>] (i2c_device_shutdown+0x3c/0x44) from [<c02cd184>] (device_shutdown+0x110/0x170)
[<c02cd184>] (device_shutdown+0x110/0x170) from [<c003e948>] (kernel_restart+0xc/0x50)
[<c003e948>] (kernel_restart+0xc/0x50) from [<c003eae4>] (SyS_reboot+0x150/0x1b0)
[<c003eae4>] (SyS_reboot+0x150/0x1b0) from [<c000da00>] (ret_fast_syscall+0x0/0x30)

drivers/power/bq24296_charger.c
include/linux/power/bq24296_charger.h

index d5a2cfa1adc0f590dfefae7af2d986cfac36a896..7312c87c06f933f1fccefffc3bf131bea4572a39 100755 (executable)
@@ -523,7 +523,7 @@ static int bq24296_battery_probe(struct i2c_client *client,const struct i2c_devi
        u8 retval = 0;
        struct bq24296_board *pdev;
        struct device_node *bq24296_node;
-       int ret=0,irq=0;
+       int ret=0;
        
         DBG("%s,line=%d\n", __func__,__LINE__);
         
@@ -578,8 +578,8 @@ static int bq24296_battery_probe(struct i2c_client *client,const struct i2c_devi
 
 
        if (gpio_is_valid(pdev->chg_irq_pin)){
-               irq = gpio_to_irq(pdev->chg_irq_pin);
-               ret = request_threaded_irq(irq, NULL,chg_irq_func, IRQF_TRIGGER_FALLING| IRQF_ONESHOT, "bq24296_chg_irq", di);
+               pdev->chg_irq = gpio_to_irq(pdev->chg_irq_pin);
+               ret = request_threaded_irq(pdev->chg_irq, NULL, chg_irq_func, IRQF_TRIGGER_FALLING| IRQF_ONESHOT, "bq24296_chg_irq", di);
                if (ret) {
                        ret = -EINVAL;
                        printk("failed to request bq24296_chg_irq\n");
@@ -600,12 +600,12 @@ batt_failed_2:
 
 static void bq24296_battery_shutdown(struct i2c_client *client)
 {
+       struct bq24296_device_info *di = i2c_get_clientdata(client);
 
-       if (gpio_is_valid(bq24296_pdata->chg_irq_pin)){
-       free_irq(gpio_to_irq(bq24296_pdata->chg_irq_pin), NULL);
-       }
-       
+       if (bq24296_pdata->chg_irq)
+               free_irq(bq24296_pdata->chg_irq, di);
 }
+
 static int bq24296_battery_remove(struct i2c_client *client)
 {
        struct bq24296_device_info *di = i2c_get_clientdata(client);
index 12358ed048c3dd95e0b3837e6f8af841d23bd5ef..24a53626e6ce21ebdf5c670b9ad78b04eeab3217 100755 (executable)
@@ -153,6 +153,7 @@ struct bq24296_platform_data {
 struct bq24296_board {
        unsigned int otg_usb_pin;
        unsigned int chg_irq_pin;
+       unsigned int chg_irq;
        unsigned int dc_det_pin;
        unsigned int psel_pin;
        struct device_node *of_node;