> > Kernel built with extcon and charger-manager. > > After connecting the USB cable sleeping function was called from atomic > context: > [ 63.328648] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:586 [] > [ 63.388743] Workqueue: events max14577_muic_irq_work > [ 63.393707] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) > [ 63.401422] [] (show_stack) from [] (dump_stack+0x70/0xbc) > [ 63.408625] [] (dump_stack) from [] (mutex_lock_nested+0x24/0x410) > [ 63.416525] [] (mutex_lock_nested) from [] (regmap_read+0x30/0x60) > [ 63.424424] [] (regmap_read) from [] (max14577_charger_get_property+0x1e4/0x250) > [ 63.433535] [] (max14577_charger_get_property) from [] (is_ext_pwr_online+0x30/0x6c) > [ 63.442994] [] (is_ext_pwr_online) from [] (charger_extcon_notifier+0x40/0x70) > [ 63.451934] [] (charger_extcon_notifier) from [] (_call_per_cable+0x40/0x4c) > [ 63.460704] [] (_call_per_cable) from [] (notifier_call_chain+0x64/0x128) > [ 63.469209] [] (notifier_call_chain) from [] (raw_notifier_call_chain+0x18/0x20) > [ 63.478321] [] (raw_notifier_call_chain) from [] (extcon_update_state+0xa8/0x204) > [ 63.487522] [] (extcon_update_state) from [] (max14577_muic_chg_handler+0xdc/0x180) > [ 63.496897] [] (max14577_muic_chg_handler) from [] (max14577_muic_irq_work+0x7c/0xd8) > [ 63.506445] [] (max14577_muic_irq_work) from [] (process_one_work+0x198/0x66c) > [ 63.515385] [] (process_one_work) from [] (worker_thread+0x38/0x564) > [ 63.523455] [] (worker_thread) from [] (kthread+0xcc/0xe8) > [ 63.530661] [] (kthread) from [] (ret_from_fork+0x14/0x3c) > [ 63.543926] charger_manager: Set current limit of CHARGER : 450000uA ~ 450000uA > [ 63.548870] extcon-port jack: jack event CHGDET=usb > [ 63.550592] extcon-port jack: jack event CHGDET=charger > [ 64.188607] charger-manager charger-manager@0: Failed to get battery temperature > [ 64.200684] charger-manager charger-manager@0: CHARGING > > The first sleeping function is is_ext_pwr_online() > (drivers/power/charger-manager.c). The atomic context initiating the > flow is set up in extcon_update_state() (drivers/extcon/extcon-class.c). > > The extcon_update_state() uses spin locks which are not necessary > because the function is not called from interrupt service routines. > Instead, the extcon_update_state() is called from: > 1. Threaded interrupt handlers. > 2. Work queues. > > Replace the spin lock with mutex and update the documentation of this > function. No. You've done it in the opposite way. update_state is often called in a interrupt handler that cannot sleep. For the context you've mentioned, we'd need workqueue invoked by _call_per_cable or notifier callback. Cheers, MyungJoo > > Signed-off-by: Krzysztof Kozlowski > --- > drivers/extcon/extcon-class.c | 15 ++++++++------- > include/linux/extcon.h | 3 ++- > 2 files changed, 10 insertions(+), 8 deletions(-) > [] > - spin_lock_irqsave(&edev->lock, flags); > + mutex_lock(&edev->lock); [] {.n++%ݶw{.n+{G{ayʇڙ,jfhz_(階ݢj"mG?&~iOzv^m ?I