diff options
author | Anton Vorontsov <cbouatmailru@gmail.com> | 2008-01-12 18:44:20 -0500 |
---|---|---|
committer | Anton Vorontsov <cbouatmailru@gmail.com> | 2008-02-01 18:44:34 -0500 |
commit | c3caebad7427f62fe77621bae1bd1da0e56a130d (patch) | |
tree | b5da1069e1c2161a4b7af5a907126968c308a5a3 | |
parent | bfde2662ae8c7f0054990e59456718761a352651 (diff) |
pda_power: implement polling
Signed-off-by: Anton Vorontsov <cbou@mail.ru>
-rw-r--r-- | drivers/power/pda_power.c | 46 | ||||
-rw-r--r-- | include/linux/pda_power.h | 1 |
2 files changed, 46 insertions, 1 deletions
diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c index d6c6dbc20e2a..c8aa55b81fd8 100644 --- a/drivers/power/pda_power.c +++ b/drivers/power/pda_power.c | |||
@@ -32,6 +32,8 @@ static struct pda_power_pdata *pdata; | |||
32 | static struct resource *ac_irq, *usb_irq; | 32 | static struct resource *ac_irq, *usb_irq; |
33 | static struct timer_list charger_timer; | 33 | static struct timer_list charger_timer; |
34 | static struct timer_list supply_timer; | 34 | static struct timer_list supply_timer; |
35 | static struct timer_list polling_timer; | ||
36 | static int polling; | ||
35 | 37 | ||
36 | enum { | 38 | enum { |
37 | PDA_PSY_OFFLINE = 0, | 39 | PDA_PSY_OFFLINE = 0, |
@@ -167,6 +169,31 @@ static irqreturn_t power_changed_isr(int irq, void *power_supply) | |||
167 | return IRQ_HANDLED; | 169 | return IRQ_HANDLED; |
168 | } | 170 | } |
169 | 171 | ||
172 | static void polling_timer_func(unsigned long unused) | ||
173 | { | ||
174 | int changed = 0; | ||
175 | |||
176 | dev_dbg(dev, "polling...\n"); | ||
177 | |||
178 | update_status(); | ||
179 | |||
180 | if (!ac_irq && new_ac_status != ac_status) { | ||
181 | ac_status = PDA_PSY_TO_CHANGE; | ||
182 | changed = 1; | ||
183 | } | ||
184 | |||
185 | if (!usb_irq && new_usb_status != usb_status) { | ||
186 | usb_status = PDA_PSY_TO_CHANGE; | ||
187 | changed = 1; | ||
188 | } | ||
189 | |||
190 | if (changed) | ||
191 | psy_changed(); | ||
192 | |||
193 | mod_timer(&polling_timer, | ||
194 | jiffies + msecs_to_jiffies(pdata->polling_interval)); | ||
195 | } | ||
196 | |||
170 | static int pda_power_probe(struct platform_device *pdev) | 197 | static int pda_power_probe(struct platform_device *pdev) |
171 | { | 198 | { |
172 | int ret = 0; | 199 | int ret = 0; |
@@ -191,6 +218,9 @@ static int pda_power_probe(struct platform_device *pdev) | |||
191 | if (!pdata->wait_for_charger) | 218 | if (!pdata->wait_for_charger) |
192 | pdata->wait_for_charger = 500; | 219 | pdata->wait_for_charger = 500; |
193 | 220 | ||
221 | if (!pdata->polling_interval) | ||
222 | pdata->polling_interval = 2000; | ||
223 | |||
194 | setup_timer(&charger_timer, charger_timer_func, 0); | 224 | setup_timer(&charger_timer, charger_timer_func, 0); |
195 | setup_timer(&supply_timer, supply_timer_func, 0); | 225 | setup_timer(&supply_timer, supply_timer_func, 0); |
196 | 226 | ||
@@ -220,6 +250,8 @@ static int pda_power_probe(struct platform_device *pdev) | |||
220 | dev_err(dev, "request ac irq failed\n"); | 250 | dev_err(dev, "request ac irq failed\n"); |
221 | goto ac_irq_failed; | 251 | goto ac_irq_failed; |
222 | } | 252 | } |
253 | } else { | ||
254 | polling = 1; | ||
223 | } | 255 | } |
224 | } | 256 | } |
225 | 257 | ||
@@ -239,10 +271,20 @@ static int pda_power_probe(struct platform_device *pdev) | |||
239 | dev_err(dev, "request usb irq failed\n"); | 271 | dev_err(dev, "request usb irq failed\n"); |
240 | goto usb_irq_failed; | 272 | goto usb_irq_failed; |
241 | } | 273 | } |
274 | } else { | ||
275 | polling = 1; | ||
242 | } | 276 | } |
243 | } | 277 | } |
244 | 278 | ||
245 | device_init_wakeup(&pdev->dev, 1); | 279 | if (polling) { |
280 | dev_dbg(dev, "will poll for status\n"); | ||
281 | setup_timer(&polling_timer, polling_timer_func, 0); | ||
282 | mod_timer(&polling_timer, | ||
283 | jiffies + msecs_to_jiffies(pdata->polling_interval)); | ||
284 | } | ||
285 | |||
286 | if (ac_irq || usb_irq) | ||
287 | device_init_wakeup(&pdev->dev, 1); | ||
246 | 288 | ||
247 | return 0; | 289 | return 0; |
248 | 290 | ||
@@ -267,6 +309,8 @@ static int pda_power_remove(struct platform_device *pdev) | |||
267 | if (pdata->is_ac_online && ac_irq) | 309 | if (pdata->is_ac_online && ac_irq) |
268 | free_irq(ac_irq->start, &pda_psy_ac); | 310 | free_irq(ac_irq->start, &pda_psy_ac); |
269 | 311 | ||
312 | if (polling) | ||
313 | del_timer_sync(&polling_timer); | ||
270 | del_timer_sync(&charger_timer); | 314 | del_timer_sync(&charger_timer); |
271 | del_timer_sync(&supply_timer); | 315 | del_timer_sync(&supply_timer); |
272 | 316 | ||
diff --git a/include/linux/pda_power.h b/include/linux/pda_power.h index 1375f15797e7..225beb136807 100644 --- a/include/linux/pda_power.h +++ b/include/linux/pda_power.h | |||
@@ -26,6 +26,7 @@ struct pda_power_pdata { | |||
26 | 26 | ||
27 | unsigned int wait_for_status; /* msecs, default is 500 */ | 27 | unsigned int wait_for_status; /* msecs, default is 500 */ |
28 | unsigned int wait_for_charger; /* msecs, default is 500 */ | 28 | unsigned int wait_for_charger; /* msecs, default is 500 */ |
29 | unsigned int polling_interval; /* msecs, default is 2000 */ | ||
29 | }; | 30 | }; |
30 | 31 | ||
31 | #endif /* __PDA_POWER_H__ */ | 32 | #endif /* __PDA_POWER_H__ */ |