aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2014-09-04 08:01:32 -0400
committerSebastian Reichel <sre@kernel.org>2014-09-16 05:01:35 -0400
commit061f3806bbe4d8e86dddf101f75f49c38d3f1669 (patch)
treebb37d1a97976d37a4297ca8b1dbeb1ff099435ed
parent1c42a389eaa0fddca6e6d9625e65ff62c9b90e80 (diff)
power-supply: Mark 'if' blocks in power_supply_changed_work() with 'likely'
The 'if' statements in power_supply_changed_work() are mostly there for taking care of races and normally they will always evaluate to true. Optimize them for fast execution with 'likely' statements. Also there is need to have better comments in code to mention about the races clearly. Get them in place. Cc: Zoran Markovic <zrn.markovic@gmail.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Sebastian Reichel <sre@kernel.org>
-rw-r--r--drivers/power/power_supply_core.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index bcff7fdf733a..26518c8218ea 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -78,7 +78,14 @@ static void power_supply_changed_work(struct work_struct *work)
78 dev_dbg(psy->dev, "%s\n", __func__); 78 dev_dbg(psy->dev, "%s\n", __func__);
79 79
80 spin_lock_irqsave(&psy->changed_lock, flags); 80 spin_lock_irqsave(&psy->changed_lock, flags);
81 if (psy->changed) { 81 /*
82 * Check 'changed' here to avoid issues due to race between
83 * power_supply_changed() and this routine. In worst case
84 * power_supply_changed() can be called again just before we take above
85 * lock. During the first call of this routine we will mark 'changed' as
86 * false and it will stay false for the next call as well.
87 */
88 if (likely(psy->changed)) {
82 psy->changed = false; 89 psy->changed = false;
83 spin_unlock_irqrestore(&psy->changed_lock, flags); 90 spin_unlock_irqrestore(&psy->changed_lock, flags);
84 class_for_each_device(power_supply_class, NULL, psy, 91 class_for_each_device(power_supply_class, NULL, psy,
@@ -89,12 +96,13 @@ static void power_supply_changed_work(struct work_struct *work)
89 kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE); 96 kobject_uevent(&psy->dev->kobj, KOBJ_CHANGE);
90 spin_lock_irqsave(&psy->changed_lock, flags); 97 spin_lock_irqsave(&psy->changed_lock, flags);
91 } 98 }
99
92 /* 100 /*
93 * Dependent power supplies (e.g. battery) may have changed state 101 * Hold the wakeup_source until all events are processed.
94 * as a result of this event, so poll again and hold the 102 * power_supply_changed() might have called again and have set 'changed'
95 * wakeup_source until all events are processed. 103 * to true.
96 */ 104 */
97 if (!psy->changed) 105 if (likely(!psy->changed))
98 pm_relax(psy->dev); 106 pm_relax(psy->dev);
99 spin_unlock_irqrestore(&psy->changed_lock, flags); 107 spin_unlock_irqrestore(&psy->changed_lock, flags);
100} 108}