Loading drivers/power/pda_power.c +92 −55 Original line number Diff line number Diff line Loading @@ -33,6 +33,16 @@ static struct resource *ac_irq, *usb_irq; static struct timer_list charger_timer; static struct timer_list supply_timer; enum { PDA_PSY_OFFLINE = 0, PDA_PSY_ONLINE = 1, PDA_PSY_TO_CHANGE, }; static int new_ac_status = -1; static int new_usb_status = -1; static int ac_status = -1; static int usb_status = -1; static int pda_power_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) Loading Loading @@ -61,8 +71,7 @@ static char *pda_power_supplied_to[] = { "backup-battery", }; static struct power_supply pda_power_supplies[] = { { static struct power_supply pda_psy_ac = { .name = "ac", .type = POWER_SUPPLY_TYPE_MAINS, .supplied_to = pda_power_supplied_to, Loading @@ -70,8 +79,9 @@ static struct power_supply pda_power_supplies[] = { .properties = pda_power_props, .num_properties = ARRAY_SIZE(pda_power_props), .get_property = pda_power_get_property, }, { }; static struct power_supply pda_psy_usb = { .name = "usb", .type = POWER_SUPPLY_TYPE_USB, .supplied_to = pda_power_supplied_to, Loading @@ -79,18 +89,26 @@ static struct power_supply pda_power_supplies[] = { .properties = pda_power_props, .num_properties = ARRAY_SIZE(pda_power_props), .get_property = pda_power_get_property, }, }; static void update_status(void) { if (pdata->is_ac_online) new_ac_status = !!pdata->is_ac_online(); if (pdata->is_usb_online) new_usb_status = !!pdata->is_usb_online(); } static void update_charger(void) { if (!pdata->set_charge) return; if (pdata->is_ac_online && pdata->is_ac_online()) { if (new_ac_status > 0) { dev_dbg(dev, "charger on (AC)\n"); pdata->set_charge(PDA_POWER_CHARGE_AC); } else if (pdata->is_usb_online && pdata->is_usb_online()) { } else if (new_usb_status > 0) { dev_dbg(dev, "charger on (USB)\n"); pdata->set_charge(PDA_POWER_CHARGE_USB); } else { Loading @@ -99,31 +117,53 @@ static void update_charger(void) } } static void supply_timer_func(unsigned long power_supply_ptr) static void supply_timer_func(unsigned long unused) { void *power_supply = (void *)power_supply_ptr; if (ac_status == PDA_PSY_TO_CHANGE) { ac_status = new_ac_status; power_supply_changed(&pda_psy_ac); } power_supply_changed(power_supply); if (usb_status == PDA_PSY_TO_CHANGE) { usb_status = new_usb_status; power_supply_changed(&pda_psy_usb); } } static void charger_timer_func(unsigned long power_supply_ptr) static void psy_changed(void) { update_charger(); /* Okay, charger set. Now wait a bit before notifying supplicants, * charge power should stabilize. */ supply_timer.data = power_supply_ptr; /* * Okay, charger set. Now wait a bit before notifying supplicants, * charge power should stabilize. */ mod_timer(&supply_timer, jiffies + msecs_to_jiffies(pdata->wait_for_charger)); } static void charger_timer_func(unsigned long unused) { update_status(); psy_changed(); } 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 = (unsigned long)power_supply; if (power_supply == &pda_psy_ac) ac_status = PDA_PSY_TO_CHANGE; else if (power_supply == &pda_psy_usb) usb_status = PDA_PSY_TO_CHANGE; else return IRQ_NONE; /* * Wait a bit before reading ac/usb line status and setting charger, * because ac/usb status readings may lag from irq. */ mod_timer(&charger_timer, jiffies + msecs_to_jiffies(pdata->wait_for_status)); return IRQ_HANDLED; } Loading @@ -142,6 +182,7 @@ static int pda_power_probe(struct platform_device *pdev) pdata = pdev->dev.platform_data; update_status(); update_charger(); if (!pdata->wait_for_status) Loading @@ -155,31 +196,26 @@ static int pda_power_probe(struct platform_device *pdev) ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac"); usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb"); if (!ac_irq && !usb_irq) { dev_err(dev, "no ac/usb irq specified\n"); ret = -ENODEV; goto noirqs; } if (pdata->supplied_to) { pda_power_supplies[0].supplied_to = pdata->supplied_to; pda_power_supplies[1].supplied_to = pdata->supplied_to; pda_power_supplies[0].num_supplicants = pdata->num_supplicants; pda_power_supplies[1].num_supplicants = pdata->num_supplicants; pda_psy_ac.supplied_to = pdata->supplied_to; pda_psy_ac.num_supplicants = pdata->num_supplicants; pda_psy_usb.supplied_to = pdata->supplied_to; pda_psy_usb.num_supplicants = pdata->num_supplicants; } if (pdata->is_ac_online) { ret = power_supply_register(&pdev->dev, &pda_power_supplies[0]); ret = power_supply_register(&pdev->dev, &pda_psy_ac); if (ret) { dev_err(dev, "failed to register %s power supply\n", pda_power_supplies[0].name); pda_psy_ac.name); goto ac_supply_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]); &pda_psy_ac); if (ret) { dev_err(dev, "request ac irq failed\n"); goto ac_irq_failed; Loading @@ -188,18 +224,17 @@ static int pda_power_probe(struct platform_device *pdev) } if (pdata->is_usb_online) { ret = power_supply_register(&pdev->dev, &pda_power_supplies[1]); ret = power_supply_register(&pdev->dev, &pda_psy_usb); if (ret) { dev_err(dev, "failed to register %s power supply\n", pda_power_supplies[1].name); pda_psy_usb.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]); usb_irq->name, &pda_psy_usb); if (ret) { dev_err(dev, "request usb irq failed\n"); goto usb_irq_failed; Loading @@ -213,15 +248,14 @@ static int pda_power_probe(struct platform_device *pdev) usb_irq_failed: if (pdata->is_usb_online) power_supply_unregister(&pda_power_supplies[1]); power_supply_unregister(&pda_psy_usb); usb_supply_failed: if (pdata->is_ac_online && ac_irq) free_irq(ac_irq->start, &pda_power_supplies[0]); free_irq(ac_irq->start, &pda_psy_ac); ac_irq_failed: if (pdata->is_ac_online) power_supply_unregister(&pda_power_supplies[0]); power_supply_unregister(&pda_psy_ac); ac_supply_failed: noirqs: wrongid: return ret; } Loading @@ -229,15 +263,18 @@ static int pda_power_probe(struct platform_device *pdev) static int pda_power_remove(struct platform_device *pdev) { if (pdata->is_usb_online && usb_irq) free_irq(usb_irq->start, &pda_power_supplies[1]); free_irq(usb_irq->start, &pda_psy_usb); if (pdata->is_ac_online && ac_irq) free_irq(ac_irq->start, &pda_power_supplies[0]); free_irq(ac_irq->start, &pda_psy_ac); del_timer_sync(&charger_timer); del_timer_sync(&supply_timer); if (pdata->is_usb_online) power_supply_unregister(&pda_power_supplies[1]); power_supply_unregister(&pda_psy_usb); if (pdata->is_ac_online) power_supply_unregister(&pda_power_supplies[0]); power_supply_unregister(&pda_psy_ac); return 0; } Loading Loading
drivers/power/pda_power.c +92 −55 Original line number Diff line number Diff line Loading @@ -33,6 +33,16 @@ static struct resource *ac_irq, *usb_irq; static struct timer_list charger_timer; static struct timer_list supply_timer; enum { PDA_PSY_OFFLINE = 0, PDA_PSY_ONLINE = 1, PDA_PSY_TO_CHANGE, }; static int new_ac_status = -1; static int new_usb_status = -1; static int ac_status = -1; static int usb_status = -1; static int pda_power_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) Loading Loading @@ -61,8 +71,7 @@ static char *pda_power_supplied_to[] = { "backup-battery", }; static struct power_supply pda_power_supplies[] = { { static struct power_supply pda_psy_ac = { .name = "ac", .type = POWER_SUPPLY_TYPE_MAINS, .supplied_to = pda_power_supplied_to, Loading @@ -70,8 +79,9 @@ static struct power_supply pda_power_supplies[] = { .properties = pda_power_props, .num_properties = ARRAY_SIZE(pda_power_props), .get_property = pda_power_get_property, }, { }; static struct power_supply pda_psy_usb = { .name = "usb", .type = POWER_SUPPLY_TYPE_USB, .supplied_to = pda_power_supplied_to, Loading @@ -79,18 +89,26 @@ static struct power_supply pda_power_supplies[] = { .properties = pda_power_props, .num_properties = ARRAY_SIZE(pda_power_props), .get_property = pda_power_get_property, }, }; static void update_status(void) { if (pdata->is_ac_online) new_ac_status = !!pdata->is_ac_online(); if (pdata->is_usb_online) new_usb_status = !!pdata->is_usb_online(); } static void update_charger(void) { if (!pdata->set_charge) return; if (pdata->is_ac_online && pdata->is_ac_online()) { if (new_ac_status > 0) { dev_dbg(dev, "charger on (AC)\n"); pdata->set_charge(PDA_POWER_CHARGE_AC); } else if (pdata->is_usb_online && pdata->is_usb_online()) { } else if (new_usb_status > 0) { dev_dbg(dev, "charger on (USB)\n"); pdata->set_charge(PDA_POWER_CHARGE_USB); } else { Loading @@ -99,31 +117,53 @@ static void update_charger(void) } } static void supply_timer_func(unsigned long power_supply_ptr) static void supply_timer_func(unsigned long unused) { void *power_supply = (void *)power_supply_ptr; if (ac_status == PDA_PSY_TO_CHANGE) { ac_status = new_ac_status; power_supply_changed(&pda_psy_ac); } power_supply_changed(power_supply); if (usb_status == PDA_PSY_TO_CHANGE) { usb_status = new_usb_status; power_supply_changed(&pda_psy_usb); } } static void charger_timer_func(unsigned long power_supply_ptr) static void psy_changed(void) { update_charger(); /* Okay, charger set. Now wait a bit before notifying supplicants, * charge power should stabilize. */ supply_timer.data = power_supply_ptr; /* * Okay, charger set. Now wait a bit before notifying supplicants, * charge power should stabilize. */ mod_timer(&supply_timer, jiffies + msecs_to_jiffies(pdata->wait_for_charger)); } static void charger_timer_func(unsigned long unused) { update_status(); psy_changed(); } 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 = (unsigned long)power_supply; if (power_supply == &pda_psy_ac) ac_status = PDA_PSY_TO_CHANGE; else if (power_supply == &pda_psy_usb) usb_status = PDA_PSY_TO_CHANGE; else return IRQ_NONE; /* * Wait a bit before reading ac/usb line status and setting charger, * because ac/usb status readings may lag from irq. */ mod_timer(&charger_timer, jiffies + msecs_to_jiffies(pdata->wait_for_status)); return IRQ_HANDLED; } Loading @@ -142,6 +182,7 @@ static int pda_power_probe(struct platform_device *pdev) pdata = pdev->dev.platform_data; update_status(); update_charger(); if (!pdata->wait_for_status) Loading @@ -155,31 +196,26 @@ static int pda_power_probe(struct platform_device *pdev) ac_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "ac"); usb_irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "usb"); if (!ac_irq && !usb_irq) { dev_err(dev, "no ac/usb irq specified\n"); ret = -ENODEV; goto noirqs; } if (pdata->supplied_to) { pda_power_supplies[0].supplied_to = pdata->supplied_to; pda_power_supplies[1].supplied_to = pdata->supplied_to; pda_power_supplies[0].num_supplicants = pdata->num_supplicants; pda_power_supplies[1].num_supplicants = pdata->num_supplicants; pda_psy_ac.supplied_to = pdata->supplied_to; pda_psy_ac.num_supplicants = pdata->num_supplicants; pda_psy_usb.supplied_to = pdata->supplied_to; pda_psy_usb.num_supplicants = pdata->num_supplicants; } if (pdata->is_ac_online) { ret = power_supply_register(&pdev->dev, &pda_power_supplies[0]); ret = power_supply_register(&pdev->dev, &pda_psy_ac); if (ret) { dev_err(dev, "failed to register %s power supply\n", pda_power_supplies[0].name); pda_psy_ac.name); goto ac_supply_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]); &pda_psy_ac); if (ret) { dev_err(dev, "request ac irq failed\n"); goto ac_irq_failed; Loading @@ -188,18 +224,17 @@ static int pda_power_probe(struct platform_device *pdev) } if (pdata->is_usb_online) { ret = power_supply_register(&pdev->dev, &pda_power_supplies[1]); ret = power_supply_register(&pdev->dev, &pda_psy_usb); if (ret) { dev_err(dev, "failed to register %s power supply\n", pda_power_supplies[1].name); pda_psy_usb.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]); usb_irq->name, &pda_psy_usb); if (ret) { dev_err(dev, "request usb irq failed\n"); goto usb_irq_failed; Loading @@ -213,15 +248,14 @@ static int pda_power_probe(struct platform_device *pdev) usb_irq_failed: if (pdata->is_usb_online) power_supply_unregister(&pda_power_supplies[1]); power_supply_unregister(&pda_psy_usb); usb_supply_failed: if (pdata->is_ac_online && ac_irq) free_irq(ac_irq->start, &pda_power_supplies[0]); free_irq(ac_irq->start, &pda_psy_ac); ac_irq_failed: if (pdata->is_ac_online) power_supply_unregister(&pda_power_supplies[0]); power_supply_unregister(&pda_psy_ac); ac_supply_failed: noirqs: wrongid: return ret; } Loading @@ -229,15 +263,18 @@ static int pda_power_probe(struct platform_device *pdev) static int pda_power_remove(struct platform_device *pdev) { if (pdata->is_usb_online && usb_irq) free_irq(usb_irq->start, &pda_power_supplies[1]); free_irq(usb_irq->start, &pda_psy_usb); if (pdata->is_ac_online && ac_irq) free_irq(ac_irq->start, &pda_power_supplies[0]); free_irq(ac_irq->start, &pda_psy_ac); del_timer_sync(&charger_timer); del_timer_sync(&supply_timer); if (pdata->is_usb_online) power_supply_unregister(&pda_power_supplies[1]); power_supply_unregister(&pda_psy_usb); if (pdata->is_ac_online) power_supply_unregister(&pda_power_supplies[0]); power_supply_unregister(&pda_psy_ac); return 0; } Loading