From ba9c91825d4a3bb49532d4a59c72e98b529b7eff Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 7 Oct 2014 17:47:37 +0200 Subject: [PATCH] power: charger-manager: Avoid recursive thermal get_temp call The charger manager supports POWER_SUPPLY_PROP_TEMP property and acts as a thermal zone if any of these conditions match: 1. Fuel gauge used by charger manager supports POWER_SUPPLY_PROP_TEMP. 2. 'cm-thermal-zone' property is present in DTS (then it will supersede the fuel gauge temperature property). However in case 1 (fuel gauge reports temperature and 'cm-thermal-zone' is not set) the charger manager forwards its get_temp calls to fuel gauge thermal zone. This leads to reporting by lockdep a false positive deadlock for thermal zone's mutex because of nested calls to thermal_zone_get_temp(). This is false positive because these are different mutexes: one for charger manager thermal zone and second for fuel gauge thermal zone. Get rid of false lockdep alert and recursive call by setting 'no_thermal' property for this power supply class. The thermal zone for charger manager won't be created (user space does not use it anyway). The lockdep report: [ 2.540339] charger-manager charger-manager@0: Ignoring full-battery voltage threshold as it is not supplied [ 2.540351] charger-manager charger-manager@0: Ignoring full-battery full capacity threshold as it is not supplied [ 2.546296] [ 2.546302] ============================================= [ 2.546305] [ INFO: possible recursive locking detected ] [ 2.546312] 3.17.0-rc6-next-20140926-00012-gbb13895e46af-dirty #39 Not tainted [ 2.546316] --------------------------------------------- [ 2.546321] swapper/0/1 is trying to acquire lock: [ 2.546348] (&tz->lock){+.+...}, at: [] thermal_zone_get_temp+0x38/0x68 [ 2.546352] [ 2.546352] but task is already holding lock: [ 2.546369] (&tz->lock){+.+...}, at: [] thermal_zone_get_temp+0x38/0x68 [ 2.546373] [ 2.546373] other info that might help us debug this: [ 2.546376] Possible unsafe locking scenario: [ 2.546376] [ 2.546378] CPU0 [ 2.546380] ---- [ 2.546386] lock(&tz->lock); [ 2.546392] lock(&tz->lock); [ 2.546394] [ 2.546394] *** DEADLOCK *** [ 2.546394] [ 2.546397] May be due to missing lock nesting notation [ 2.546397] [ 2.546401] 2 locks held by swapper/0/1: [ 2.546430] #0: (&dev->mutex){......}, at: [] __driver_attach+0x58/0x98 [ 2.546448] #1: (&tz->lock){+.+...}, at: [] thermal_zone_get_temp+0x38/0x68 [ 2.546451] [ 2.546451] stack backtrace: [ 2.546460] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 3.17.0-rc6-next-20140926-00012-gbb13895e46af-dirty #39 [ 2.546497] [] (unwind_backtrace) from [] (show_stack+0x10/0x14) [ 2.546526] [] (show_stack) from [] (dump_stack+0x70/0xbc) [ 2.546554] [] (dump_stack) from [] (validate_chain.isra.24+0x718/0x890) [ 2.546569] [] (validate_chain.isra.24) from [] (__lock_acquire+0x498/0xa78) [ 2.546581] [] (__lock_acquire) from [] (lock_acquire+0x78/0xb8) [ 2.546594] [] (lock_acquire) from [] (mutex_lock_nested+0x64/0x458) [ 2.546605] [] (mutex_lock_nested) from [] (thermal_zone_get_temp+0x38/0x68) [ 2.546634] [] (thermal_zone_get_temp) from [] (charger_get_property+0x10c/0x348) [ 2.546649] [] (charger_get_property) from [] (power_supply_read_temp+0x28/0x58) [ 2.546662] [] (power_supply_read_temp) from [] (thermal_zone_get_temp+0x4c/0x68) [ 2.546676] [] (thermal_zone_get_temp) from [] (thermal_zone_device_update+0x24/0x9c) [ 2.546687] [] (thermal_zone_device_update) from [] (thermal_zone_device_register+0x424/0x550) [ 2.546701] [] (thermal_zone_device_register) from [] (__power_supply_register+0x2a4/0x348) [ 2.546714] [] (__power_supply_register) from [] (charger_manager_probe+0x600/0xe5c) [ 2.546727] [] (charger_manager_probe) from [] (platform_drv_probe+0x48/0xa4) [ 2.546746] [] (platform_drv_probe) from [] (driver_probe_device+0x10c/0x224) [ 2.546760] [] (driver_probe_device) from [] (__driver_attach+0x94/0x98) [ 2.546772] [] (__driver_attach) from [] (bus_for_each_dev+0x54/0x88) [ 2.546784] [] (bus_for_each_dev) from [] (bus_add_driver+0xd4/0x1d0) [ 2.546797] [] (bus_add_driver) from [] (driver_register+0x78/0xf4) [ 2.546809] [] (driver_register) from [] (do_one_initcall+0x80/0x1d4) [ 2.546829] [] (do_one_initcall) from [] (kernel_init_freeable+0x10c/0x1d8) [ 2.546847] [] (kernel_init_freeable) from [] (kernel_init+0x8/0xec) [ 2.546863] [] (kernel_init) from [] (ret_from_fork+0x14/0x2c) [ 2.551396] charger-manager charger-manager@0: 'chg-reg' regulator's externally_control is 0 Signed-off-by: Krzysztof Kozlowski Signed-off-by: Sebastian Reichel --- drivers/power/charger-manager.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c index 7098a1ce2d3c..7a1177ea238d 100644 --- a/drivers/power/charger-manager.c +++ b/drivers/power/charger-manager.c @@ -970,6 +970,7 @@ static struct power_supply psy_default = { .properties = default_charger_props, .num_properties = ARRAY_SIZE(default_charger_props), .get_property = charger_get_property, + .no_thermal = true, }; /** -- 2.11.4.GIT