[PATCH AUTOSEL for 4.4 066/101] power: supply: pda_power: move from timer to delayed_work
From: Michael Trimarchi[ Upstream commit 633e8799ddc09431be2744c4a1efdbda13af2b0b ] This changed is needed to avoid locking problem during boot as shown: <5>[8.824096] Registering SWP/SWPB emulation handler <6>[8.977294] clock: disabling unused clocks to save power <3>[9.108154] BUG: sleeping function called from invalid context at kernel_albert/kernel/mutex.c:269 <3>[9.122894] in_atomic(): 1, irqs_disabled(): 0, pid: 1, name: swapper/0 <4>[9.130249] 3 locks held by swapper/0/1: <4>[9.134613] #0: (&__lockdep_no_validate__){..}, at: [] __driver_attach+0x58/0xa8 <4>[9.144500] #1: (&__lockdep_no_validate__){..}, at: [] __driver_attach+0x68/0xa8 <4>[9.154357] #2: (_timer){..}, at: [] run_timer_softirq+0x108/0x3ec <4>[9.163726] Backtrace: <4>[9.166473] [] (dump_backtrace+0x0/0x114) from [] (dump_stack+0x20/0x24) <4>[9.175811] r6:00203230 r5:010d r4:d782e000 r3:6113 <4>[9.182250] [] (dump_stack+0x0/0x24) from [] (__might_sleep+0x10c/0x128) <4>[9.191650] [] (__might_sleep+0x0/0x128) from [] (mutex_lock_nested+0x34/0x36c) <4>[9.201660] r5:c02d5350 r4:d79a0c64 <4>[9.205688] [] (mutex_lock_nested+0x0/0x36c) from [] (regulator_set_current_limit+0x30/0x118) <4>[9.217071] [] (regulator_set_current_limit+0x0/0x118) from [] (update_charger+0x84/0xc4) <4>[9.228027] r7:d782fb20 r6:0101 r5:c1767e94 r4: <4>[9.234436] [] (update_charger+0x0/0xc4) from [] (psy_changed+0x20/0x48) <4>[9.243804] r5:d782e000 r4:c1767e94 <4>[9.247802] [] (psy_changed+0x0/0x48) from [] (polling_timer_func+0x84/0xb8) <4>[9.257537] r4:c1767e94 r3:0002 <4>[9.261566] [] (polling_timer_func+0x0/0xb8) from [] (run_timer_softirq+0x17c/0x3ec) <4>[9.272033] r4:c1767eb0 r3: <4>[9.276062] [] (run_timer_softirq+0x0/0x3ec) from [] (__do_softirq+0xf0/0x298) <4>[9.286010] [] (__do_softirq+0x0/0x298) from [] (irq_exit+0x98/0xa0) <4>[9.295013] [] (irq_exit+0x0/0xa0) from [] (handle_IRQ+0x60/0xc0) <4>[9.303680] r4:c1194e98 r3:c00bc778 <4>[9.307708] [] (handle_IRQ+0x0/0xc0) from [] (gic_handle_irq+0x34/0x68) <4>[9.316955] r8:000ac383 r7:d782fc3c r6:d782fc08 r5:c11936c4 r4:e0802100 <4>[9.324310] r3:c026ba48 <4>[9.327301] [] (gic_handle_irq+0x0/0x68) from [] (__irq_svc+0x40/0x74) <4>[9.336456] Exception stack(0xd782fc08 to 0xd782fc50) <4>[9.342041] fc00: d6e30e6c ac383627 ac383417 ea19c000 ea20 <4>[9.351104] fc20: beff 0667 000ac383 d6e30670 d6e3066c d782fc94 d782fbe8 d782fc50 <4>[9.360168] fc40: c026ba48 c001d1f0 0113 Fixes: b2998049cfae ("[BATTERY] pda_power platform driver") Signed-off-by: Michael Trimarchi Signed-off-by: Anthony Brandon Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin --- drivers/power/pda_power.c | 49 ++- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c index dfe1ee89f7c7..922a86787c5c 100644 --- a/drivers/power/pda_power.c +++ b/drivers/power/pda_power.c @@ -30,9 +30,9 @@ static inline unsigned int get_irq_flags(struct resource *res) static struct device *dev; static struct pda_power_pdata *pdata; static struct resource *ac_irq, *usb_irq; -static struct timer_list charger_timer; -static struct timer_list supply_timer; -static struct timer_list polling_timer; +static struct delayed_work charger_work; +static struct delayed_work polling_work; +static struct delayed_work supply_work; static int polling; static struct power_supply *pda_psy_ac, *pda_psy_usb; @@ -140,7 +140,7 @@ static void update_charger(void) } } -static void supply_timer_func(unsigned long unused) +static void supply_work_func(struct work_struct *work) { if (ac_status == PDA_PSY_TO_CHANGE) { ac_status = new_ac_status; @@ -161,11 +161,12 @@ static void psy_changed(void) * Okay, charger set. Now wait a bit before notifying supplicants, * charge power should stabilize. */ - mod_timer(_timer, - jiffies + msecs_to_jiffies(pdata->wait_for_charger)); + cancel_delayed_work(_work); + schedule_delayed_work(_work, + msecs_to_jiffies(pdata->wait_for_charger)); } -static void charger_timer_func(unsigned long unused) +static void charger_work_func(struct work_struct *work) { update_status(); psy_changed(); @@ -184,13 +185,14 @@ 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. */ - mod_timer(_timer, - jiffies +
[PATCH AUTOSEL for 4.4 066/101] power: supply: pda_power: move from timer to delayed_work
From: Michael Trimarchi [ Upstream commit 633e8799ddc09431be2744c4a1efdbda13af2b0b ] This changed is needed to avoid locking problem during boot as shown: <5>[8.824096] Registering SWP/SWPB emulation handler <6>[8.977294] clock: disabling unused clocks to save power <3>[9.108154] BUG: sleeping function called from invalid context at kernel_albert/kernel/mutex.c:269 <3>[9.122894] in_atomic(): 1, irqs_disabled(): 0, pid: 1, name: swapper/0 <4>[9.130249] 3 locks held by swapper/0/1: <4>[9.134613] #0: (&__lockdep_no_validate__){..}, at: [] __driver_attach+0x58/0xa8 <4>[9.144500] #1: (&__lockdep_no_validate__){..}, at: [] __driver_attach+0x68/0xa8 <4>[9.154357] #2: (_timer){..}, at: [] run_timer_softirq+0x108/0x3ec <4>[9.163726] Backtrace: <4>[9.166473] [] (dump_backtrace+0x0/0x114) from [] (dump_stack+0x20/0x24) <4>[9.175811] r6:00203230 r5:010d r4:d782e000 r3:6113 <4>[9.182250] [] (dump_stack+0x0/0x24) from [] (__might_sleep+0x10c/0x128) <4>[9.191650] [] (__might_sleep+0x0/0x128) from [] (mutex_lock_nested+0x34/0x36c) <4>[9.201660] r5:c02d5350 r4:d79a0c64 <4>[9.205688] [] (mutex_lock_nested+0x0/0x36c) from [] (regulator_set_current_limit+0x30/0x118) <4>[9.217071] [] (regulator_set_current_limit+0x0/0x118) from [] (update_charger+0x84/0xc4) <4>[9.228027] r7:d782fb20 r6:0101 r5:c1767e94 r4: <4>[9.234436] [] (update_charger+0x0/0xc4) from [] (psy_changed+0x20/0x48) <4>[9.243804] r5:d782e000 r4:c1767e94 <4>[9.247802] [] (psy_changed+0x0/0x48) from [] (polling_timer_func+0x84/0xb8) <4>[9.257537] r4:c1767e94 r3:0002 <4>[9.261566] [] (polling_timer_func+0x0/0xb8) from [] (run_timer_softirq+0x17c/0x3ec) <4>[9.272033] r4:c1767eb0 r3: <4>[9.276062] [] (run_timer_softirq+0x0/0x3ec) from [] (__do_softirq+0xf0/0x298) <4>[9.286010] [] (__do_softirq+0x0/0x298) from [] (irq_exit+0x98/0xa0) <4>[9.295013] [] (irq_exit+0x0/0xa0) from [] (handle_IRQ+0x60/0xc0) <4>[9.303680] r4:c1194e98 r3:c00bc778 <4>[9.307708] [] (handle_IRQ+0x0/0xc0) from [] (gic_handle_irq+0x34/0x68) <4>[9.316955] r8:000ac383 r7:d782fc3c r6:d782fc08 r5:c11936c4 r4:e0802100 <4>[9.324310] r3:c026ba48 <4>[9.327301] [] (gic_handle_irq+0x0/0x68) from [] (__irq_svc+0x40/0x74) <4>[9.336456] Exception stack(0xd782fc08 to 0xd782fc50) <4>[9.342041] fc00: d6e30e6c ac383627 ac383417 ea19c000 ea20 <4>[9.351104] fc20: beff 0667 000ac383 d6e30670 d6e3066c d782fc94 d782fbe8 d782fc50 <4>[9.360168] fc40: c026ba48 c001d1f0 0113 Fixes: b2998049cfae ("[BATTERY] pda_power platform driver") Signed-off-by: Michael Trimarchi Signed-off-by: Anthony Brandon Signed-off-by: Sebastian Reichel Signed-off-by: Sasha Levin --- drivers/power/pda_power.c | 49 ++- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/drivers/power/pda_power.c b/drivers/power/pda_power.c index dfe1ee89f7c7..922a86787c5c 100644 --- a/drivers/power/pda_power.c +++ b/drivers/power/pda_power.c @@ -30,9 +30,9 @@ static inline unsigned int get_irq_flags(struct resource *res) static struct device *dev; static struct pda_power_pdata *pdata; static struct resource *ac_irq, *usb_irq; -static struct timer_list charger_timer; -static struct timer_list supply_timer; -static struct timer_list polling_timer; +static struct delayed_work charger_work; +static struct delayed_work polling_work; +static struct delayed_work supply_work; static int polling; static struct power_supply *pda_psy_ac, *pda_psy_usb; @@ -140,7 +140,7 @@ static void update_charger(void) } } -static void supply_timer_func(unsigned long unused) +static void supply_work_func(struct work_struct *work) { if (ac_status == PDA_PSY_TO_CHANGE) { ac_status = new_ac_status; @@ -161,11 +161,12 @@ static void psy_changed(void) * Okay, charger set. Now wait a bit before notifying supplicants, * charge power should stabilize. */ - mod_timer(_timer, - jiffies + msecs_to_jiffies(pdata->wait_for_charger)); + cancel_delayed_work(_work); + schedule_delayed_work(_work, + msecs_to_jiffies(pdata->wait_for_charger)); } -static void charger_timer_func(unsigned long unused) +static void charger_work_func(struct work_struct *work) { update_status(); psy_changed(); @@ -184,13 +185,14 @@ 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. */ - mod_timer(_timer, - jiffies + msecs_to_jiffies(pdata->wait_for_status)); + cancel_delayed_work(_work); + schedule_delayed_work(_work, +