* [PATCH] da9030_battery: fix race between event handler and monitor
@ 2009-05-12 7:20 Mike Rapoport
2009-05-13 18:40 ` Andrew Morton
0 siblings, 1 reply; 3+ messages in thread
From: Mike Rapoport @ 2009-05-12 7:20 UTC (permalink / raw)
To: cbou; +Cc: linux-kernel, Mike Rapoport
Signed-off-by: Mike Rapoport <mike@compulab.co.il>
---
drivers/power/da9030_battery.c | 19 ++++++++++++-------
1 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/power/da9030_battery.c b/drivers/power/da9030_battery.c
index 1662bb0..3364198 100644
--- a/drivers/power/da9030_battery.c
+++ b/drivers/power/da9030_battery.c
@@ -22,8 +22,6 @@
#include <linux/debugfs.h>
#include <linux/seq_file.h>
-#define DA9030_STATUS_CHDET (1 << 3)
-
#define DA9030_FAULT_LOG 0x0a
#define DA9030_FAULT_LOG_OVER_TEMP (1 << 7)
#define DA9030_FAULT_LOG_VBAT_OVER (1 << 4)
@@ -244,6 +242,8 @@ static void da9030_set_charge(struct da9030_charger *charger, int on)
}
da903x_write(charger->master, DA9030_CHARGE_CONTROL, val);
+
+ power_supply_changed(&charger->psy);
}
static void da9030_charger_check_state(struct da9030_charger *charger)
@@ -258,6 +258,12 @@ static void da9030_charger_check_state(struct da9030_charger *charger)
da9030_set_charge(charger, 1);
}
} else {
+ /* Charger has been pulled out */
+ if (!charger->chdet) {
+ da9030_set_charge(charger, 0);
+ return;
+ }
+
if (charger->adc.vbat_res >=
charger->thresholds.vbat_charge_stop) {
da9030_set_charge(charger, 0);
@@ -395,13 +401,11 @@ static int da9030_battery_event(struct notifier_block *nb, unsigned long event,
{
struct da9030_charger *charger =
container_of(nb, struct da9030_charger, nb);
- int status;
switch (event) {
case DA9030_EVENT_CHDET:
- status = da903x_query_status(charger->master,
- DA9030_STATUS_CHDET);
- da9030_set_charge(charger, status);
+ cancel_delayed_work_sync(&charger->work);
+ schedule_work(&charger->work.work);
break;
case DA9030_EVENT_VBATMON:
da9030_battery_vbat_event(charger);
@@ -565,7 +569,8 @@ static int da9030_battery_remove(struct platform_device *dev)
da903x_unregister_notifier(charger->master, &charger->nb,
DA9030_EVENT_CHDET | DA9030_EVENT_VBATMON |
DA9030_EVENT_CHIOVER | DA9030_EVENT_TBAT);
- cancel_delayed_work(&charger->work);
+ cancel_delayed_work_sync(&charger->work);
+ da9030_set_charge(charger, 0);
power_supply_unregister(&charger->psy);
kfree(charger);
--
1.6.0.6
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] da9030_battery: fix race between event handler and monitor
2009-05-12 7:20 [PATCH] da9030_battery: fix race between event handler and monitor Mike Rapoport
@ 2009-05-13 18:40 ` Andrew Morton
2009-05-14 5:39 ` Mike Rapoport
0 siblings, 1 reply; 3+ messages in thread
From: Andrew Morton @ 2009-05-13 18:40 UTC (permalink / raw)
To: Mike Rapoport; +Cc: cbou, linux-kernel, mike
On Tue, 12 May 2009 10:20:09 +0300
Mike Rapoport <mike@compulab.co.il> wrote:
> Signed-off-by: Mike Rapoport <mike@compulab.co.il>
We seem to be missing a changelog.
>
> diff --git a/drivers/power/da9030_battery.c b/drivers/power/da9030_battery.c
> index 1662bb0..3364198 100644
> --- a/drivers/power/da9030_battery.c
> +++ b/drivers/power/da9030_battery.c
> @@ -22,8 +22,6 @@
> #include <linux/debugfs.h>
> #include <linux/seq_file.h>
>
> -#define DA9030_STATUS_CHDET (1 << 3)
> -
> #define DA9030_FAULT_LOG 0x0a
> #define DA9030_FAULT_LOG_OVER_TEMP (1 << 7)
> #define DA9030_FAULT_LOG_VBAT_OVER (1 << 4)
> @@ -244,6 +242,8 @@ static void da9030_set_charge(struct da9030_charger *charger, int on)
> }
>
> da903x_write(charger->master, DA9030_CHARGE_CONTROL, val);
> +
> + power_supply_changed(&charger->psy);
> }
>
> static void da9030_charger_check_state(struct da9030_charger *charger)
> @@ -258,6 +258,12 @@ static void da9030_charger_check_state(struct da9030_charger *charger)
> da9030_set_charge(charger, 1);
> }
> } else {
> + /* Charger has been pulled out */
> + if (!charger->chdet) {
> + da9030_set_charge(charger, 0);
> + return;
> + }
> +
> if (charger->adc.vbat_res >=
> charger->thresholds.vbat_charge_stop) {
> da9030_set_charge(charger, 0);
> @@ -395,13 +401,11 @@ static int da9030_battery_event(struct notifier_block *nb, unsigned long event,
> {
> struct da9030_charger *charger =
> container_of(nb, struct da9030_charger, nb);
> - int status;
>
> switch (event) {
> case DA9030_EVENT_CHDET:
> - status = da903x_query_status(charger->master,
> - DA9030_STATUS_CHDET);
> - da9030_set_charge(charger, status);
> + cancel_delayed_work_sync(&charger->work);
> + schedule_work(&charger->work.work);
> break;
> case DA9030_EVENT_VBATMON:
> da9030_battery_vbat_event(charger);
> @@ -565,7 +569,8 @@ static int da9030_battery_remove(struct platform_device *dev)
> da903x_unregister_notifier(charger->master, &charger->nb,
> DA9030_EVENT_CHDET | DA9030_EVENT_VBATMON |
> DA9030_EVENT_CHIOVER | DA9030_EVENT_TBAT);
> - cancel_delayed_work(&charger->work);
> + cancel_delayed_work_sync(&charger->work);
> + da9030_set_charge(charger, 0);
> power_supply_unregister(&charger->psy);
>
> kfree(charger);
What is this race? What are the user-visible effects when it occurs?
How does the patch fix the race?
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] da9030_battery: fix race between event handler and monitor
2009-05-13 18:40 ` Andrew Morton
@ 2009-05-14 5:39 ` Mike Rapoport
0 siblings, 0 replies; 3+ messages in thread
From: Mike Rapoport @ 2009-05-14 5:39 UTC (permalink / raw)
To: Andrew Morton; +Cc: cbou, linux-kernel
Andrew Morton wrote:
> On Tue, 12 May 2009 10:20:09 +0300
> Mike Rapoport <mike@compulab.co.il> wrote:
>
>> Signed-off-by: Mike Rapoport <mike@compulab.co.il>
>
> We seem to be missing a changelog.
My bad...
>> diff --git a/drivers/power/da9030_battery.c b/drivers/power/da9030_battery.c
>> index 1662bb0..3364198 100644
>> --- a/drivers/power/da9030_battery.c
>> +++ b/drivers/power/da9030_battery.c
>> @@ -22,8 +22,6 @@
>> #include <linux/debugfs.h>
>> #include <linux/seq_file.h>
[ snip ]
> What is this race? What are the user-visible effects when it occurs?
There are cases when charging monitor and the event handler try to change the
charger state simultaneously. For instance, a charger is connected to the
system, there's the detection event and the event handler tries to enable
charging. It is possible that the periodic charging monitor runs at the same
time and it still thinks there's no external charger. So it tries to disable the
charging. As the result, even if the conditions necessary to charge the battery
hold, there will be no actual charging.
> How does the patch fix the race?
The patch changes the event handler so that instead of enabling/disabling the
charger immediately it would rather make the monitor run. The monitor code then
decides what should be the charger state.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
--
Sincerely yours,
Mike.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2009-05-14 5:39 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-05-12 7:20 [PATCH] da9030_battery: fix race between event handler and monitor Mike Rapoport
2009-05-13 18:40 ` Andrew Morton
2009-05-14 5:39 ` Mike Rapoport
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox