dev_dbg(dev, "charger off\n");
pdata->set_charge(0);
}
-
- return;
}
-static void supply_timer_func(unsigned long irq)
+static void supply_timer_func(unsigned long power_supply_ptr)
{
- if (ac_irq && irq == ac_irq->start)
- power_supply_changed(&pda_power_supplies[0]);
- else if (usb_irq && irq == usb_irq->start)
- power_supply_changed(&pda_power_supplies[1]);
- return;
+ void *power_supply = (void *)power_supply_ptr;
+
+ power_supply_changed(power_supply);
}
-static void charger_timer_func(unsigned long irq)
+static void charger_timer_func(unsigned long power_supply_ptr)
{
update_charger();
/* Okay, charger set. Now wait a bit before notifying supplicants,
* charge power should stabilize. */
- supply_timer.data = irq;
+ supply_timer.data = power_supply_ptr;
mod_timer(&supply_timer,
jiffies + msecs_to_jiffies(pdata->wait_for_charger));
- return;
}
-static irqreturn_t power_changed_isr(int irq, void *unused)
+static irqreturn_t power_changed_isr(int irq, void *power_supply)
{
/* Wait a bit before reading ac/usb line status and setting charger,
* because ac/usb status readings may lag from irq. */
- charger_timer.data = irq;
+ charger_timer.data = (unsigned long)power_supply;
mod_timer(&charger_timer,
jiffies + msecs_to_jiffies(pdata->wait_for_status));
return IRQ_HANDLED;
pda_power_supplies[1].num_supplicants = pdata->num_supplicants;
}
- ret = power_supply_register(&pdev->dev, &pda_power_supplies[0]);
- if (ret) {
- dev_err(dev, "failed to register %s power supply\n",
- pda_power_supplies[0].name);
- goto supply0_failed;
- }
+ if (pdata->is_ac_online) {
+ ret = power_supply_register(&pdev->dev, &pda_power_supplies[0]);
+ if (ret) {
+ dev_err(dev, "failed to register %s power supply\n",
+ pda_power_supplies[0].name);
+ goto ac_supply_failed;
+ }
- ret = power_supply_register(&pdev->dev, &pda_power_supplies[1]);
- if (ret) {
- dev_err(dev, "failed to register %s power supply\n",
- pda_power_supplies[1].name);
- goto supply1_failed;
+ if (ac_irq) {
+ ret = request_irq(ac_irq->start, power_changed_isr,
+ get_irq_flags(ac_irq), ac_irq->name,
+ &pda_power_supplies[0]);
+ if (ret) {
+ dev_err(dev, "request ac irq failed\n");
+ goto ac_irq_failed;
+ }
+ }
}
- if (ac_irq) {
- ret = request_irq(ac_irq->start, power_changed_isr,
- get_irq_flags(ac_irq), ac_irq->name,
- &pda_power_supplies[0]);
+ if (pdata->is_usb_online) {
+ ret = power_supply_register(&pdev->dev, &pda_power_supplies[1]);
if (ret) {
- dev_err(dev, "request ac irq failed\n");
- goto ac_irq_failed;
+ dev_err(dev, "failed to register %s power supply\n",
+ pda_power_supplies[1].name);
+ goto usb_supply_failed;
}
- }
- if (usb_irq) {
- ret = request_irq(usb_irq->start, power_changed_isr,
- get_irq_flags(usb_irq), usb_irq->name,
- &pda_power_supplies[1]);
- if (ret) {
- dev_err(dev, "request usb irq failed\n");
- goto usb_irq_failed;
+ if (usb_irq) {
+ ret = request_irq(usb_irq->start, power_changed_isr,
+ get_irq_flags(usb_irq),
+ usb_irq->name,
+ &pda_power_supplies[1]);
+ if (ret) {
+ dev_err(dev, "request usb irq failed\n");
+ goto usb_irq_failed;
+ }
}
}
- goto success;
+ device_init_wakeup(&pdev->dev, 1);
+
+ return 0;
usb_irq_failed:
- if (ac_irq)
+ if (pdata->is_usb_online)
+ power_supply_unregister(&pda_power_supplies[1]);
+usb_supply_failed:
+ if (pdata->is_ac_online && ac_irq)
free_irq(ac_irq->start, &pda_power_supplies[0]);
ac_irq_failed:
- power_supply_unregister(&pda_power_supplies[1]);
-supply1_failed:
- power_supply_unregister(&pda_power_supplies[0]);
-supply0_failed:
+ if (pdata->is_ac_online)
+ power_supply_unregister(&pda_power_supplies[0]);
+ac_supply_failed:
noirqs:
wrongid:
-success:
return ret;
}
static int pda_power_remove(struct platform_device *pdev)
{
- if (usb_irq)
+ if (pdata->is_usb_online && usb_irq)
free_irq(usb_irq->start, &pda_power_supplies[1]);
- if (ac_irq)
+ if (pdata->is_ac_online && ac_irq)
free_irq(ac_irq->start, &pda_power_supplies[0]);
del_timer_sync(&charger_timer);
del_timer_sync(&supply_timer);
- power_supply_unregister(&pda_power_supplies[1]);
- power_supply_unregister(&pda_power_supplies[0]);
+ if (pdata->is_usb_online)
+ power_supply_unregister(&pda_power_supplies[1]);
+ if (pdata->is_ac_online)
+ power_supply_unregister(&pda_power_supplies[0]);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int pda_power_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ if (device_may_wakeup(&pdev->dev)) {
+ if (ac_irq)
+ enable_irq_wake(ac_irq->start);
+ if (usb_irq)
+ enable_irq_wake(usb_irq->start);
+ }
+
+ return 0;
+}
+
+static int pda_power_resume(struct platform_device *pdev)
+{
+ if (device_may_wakeup(&pdev->dev)) {
+ if (usb_irq)
+ disable_irq_wake(usb_irq->start);
+ if (ac_irq)
+ disable_irq_wake(ac_irq->start);
+ }
+
return 0;
}
+#else
+#define pda_power_suspend NULL
+#define pda_power_resume NULL
+#endif /* CONFIG_PM */
static struct platform_driver pda_power_pdrv = {
.driver = {
},
.probe = pda_power_probe,
.remove = pda_power_remove,
+ .suspend = pda_power_suspend,
+ .resume = pda_power_resume,
};
static int __init pda_power_init(void)
static void __exit pda_power_exit(void)
{
platform_driver_unregister(&pda_power_pdrv);
- return;
}
module_init(pda_power_init);