diff options
| -rw-r--r-- | drivers/power/wm97xx_battery.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c index 14ebd960ebe5..cad1ba283bfd 100644 --- a/drivers/power/wm97xx_battery.c +++ b/drivers/power/wm97xx_battery.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
| 23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
| 24 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
| 25 | #include <linux/irq.h> | ||
| 25 | 26 | ||
| 26 | static DEFINE_MUTEX(bat_lock); | 27 | static DEFINE_MUTEX(bat_lock); |
| 27 | static struct work_struct bat_work; | 28 | static struct work_struct bat_work; |
| @@ -137,6 +138,12 @@ static void wm97xx_bat_work(struct work_struct *work) | |||
| 137 | wm97xx_bat_update(&bat_ps); | 138 | wm97xx_bat_update(&bat_ps); |
| 138 | } | 139 | } |
| 139 | 140 | ||
| 141 | static irqreturn_t wm97xx_chrg_irq(int irq, void *data) | ||
| 142 | { | ||
| 143 | schedule_work(&bat_work); | ||
| 144 | return IRQ_HANDLED; | ||
| 145 | } | ||
| 146 | |||
| 140 | #ifdef CONFIG_PM | 147 | #ifdef CONFIG_PM |
| 141 | static int wm97xx_bat_suspend(struct platform_device *dev, pm_message_t state) | 148 | static int wm97xx_bat_suspend(struct platform_device *dev, pm_message_t state) |
| 142 | { | 149 | { |
| @@ -179,13 +186,18 @@ static int __devinit wm97xx_bat_probe(struct platform_device *dev) | |||
| 179 | return -EINVAL; | 186 | return -EINVAL; |
| 180 | } | 187 | } |
| 181 | 188 | ||
| 182 | if (pdata->charge_gpio >= 0 && gpio_is_valid(pdata->charge_gpio)) { | 189 | if (gpio_is_valid(pdata->charge_gpio)) { |
| 183 | ret = gpio_request(pdata->charge_gpio, "BATT CHRG"); | 190 | ret = gpio_request(pdata->charge_gpio, "BATT CHRG"); |
| 184 | if (ret) | 191 | if (ret) |
| 185 | goto err; | 192 | goto err; |
| 186 | ret = gpio_direction_input(pdata->charge_gpio); | 193 | ret = gpio_direction_input(pdata->charge_gpio); |
| 187 | if (ret) | 194 | if (ret) |
| 188 | goto err2; | 195 | goto err2; |
| 196 | ret = request_irq(gpio_to_irq(pdata->charge_gpio), | ||
| 197 | wm97xx_chrg_irq, IRQF_DISABLED, | ||
| 198 | "AC Detect", 0); | ||
| 199 | if (ret) | ||
| 200 | goto err2; | ||
| 189 | props++; /* POWER_SUPPLY_PROP_STATUS */ | 201 | props++; /* POWER_SUPPLY_PROP_STATUS */ |
| 190 | } | 202 | } |
| 191 | 203 | ||
| @@ -202,7 +214,7 @@ static int __devinit wm97xx_bat_probe(struct platform_device *dev) | |||
| 202 | 214 | ||
| 203 | prop = kzalloc(props * sizeof(*prop), GFP_KERNEL); | 215 | prop = kzalloc(props * sizeof(*prop), GFP_KERNEL); |
| 204 | if (!prop) | 216 | if (!prop) |
| 205 | goto err2; | 217 | goto err3; |
| 206 | 218 | ||
| 207 | prop[i++] = POWER_SUPPLY_PROP_PRESENT; | 219 | prop[i++] = POWER_SUPPLY_PROP_PRESENT; |
| 208 | if (pdata->charge_gpio >= 0) | 220 | if (pdata->charge_gpio >= 0) |
| @@ -235,13 +247,17 @@ static int __devinit wm97xx_bat_probe(struct platform_device *dev) | |||
| 235 | if (!ret) | 247 | if (!ret) |
| 236 | schedule_work(&bat_work); | 248 | schedule_work(&bat_work); |
| 237 | else | 249 | else |
| 238 | goto err3; | 250 | goto err4; |
| 239 | 251 | ||
| 240 | return 0; | 252 | return 0; |
| 241 | err3: | 253 | err4: |
| 242 | kfree(prop); | 254 | kfree(prop); |
| 255 | err3: | ||
| 256 | if (gpio_is_valid(pdata->charge_gpio)) | ||
| 257 | free_irq(gpio_to_irq(pdata->charge_gpio), dev); | ||
| 243 | err2: | 258 | err2: |
| 244 | gpio_free(pdata->charge_gpio); | 259 | if (gpio_is_valid(pdata->charge_gpio)) |
| 260 | gpio_free(pdata->charge_gpio); | ||
| 245 | err: | 261 | err: |
| 246 | return ret; | 262 | return ret; |
| 247 | } | 263 | } |
| @@ -251,8 +267,10 @@ static int __devexit wm97xx_bat_remove(struct platform_device *dev) | |||
| 251 | struct wm97xx_pdata *wmdata = dev->dev.platform_data; | 267 | struct wm97xx_pdata *wmdata = dev->dev.platform_data; |
| 252 | struct wm97xx_batt_pdata *pdata = wmdata->batt_pdata; | 268 | struct wm97xx_batt_pdata *pdata = wmdata->batt_pdata; |
| 253 | 269 | ||
| 254 | if (pdata && pdata->charge_gpio && pdata->charge_gpio >= 0) | 270 | if (pdata && gpio_is_valid(pdata->charge_gpio)) { |
| 271 | free_irq(gpio_to_irq(pdata->charge_gpio), dev); | ||
| 255 | gpio_free(pdata->charge_gpio); | 272 | gpio_free(pdata->charge_gpio); |
| 273 | } | ||
| 256 | flush_scheduled_work(); | 274 | flush_scheduled_work(); |
| 257 | power_supply_unregister(&bat_ps); | 275 | power_supply_unregister(&bat_ps); |
| 258 | kfree(prop); | 276 | kfree(prop); |
