aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/power
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/power')
-rw-r--r--drivers/power/wm97xx_battery.c30
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
26static DEFINE_MUTEX(bat_lock); 27static DEFINE_MUTEX(bat_lock);
27static struct work_struct bat_work; 28static 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
141static 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
141static int wm97xx_bat_suspend(struct platform_device *dev, pm_message_t state) 148static 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;
241err3: 253err4:
242 kfree(prop); 254 kfree(prop);
255err3:
256 if (gpio_is_valid(pdata->charge_gpio))
257 free_irq(gpio_to_irq(pdata->charge_gpio), dev);
243err2: 258err2:
244 gpio_free(pdata->charge_gpio); 259 if (gpio_is_valid(pdata->charge_gpio))
260 gpio_free(pdata->charge_gpio);
245err: 261err:
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);