diff options
Diffstat (limited to 'drivers')
-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); |