Commit 5e3ca2b349b1 ("regulator: Try to resolve regulators supplies on registration") added a call to regulator_resolve_supply() within regulator_register() where the regulator_list_mutex is held. This causes the following deadlock to occur on the Tegra114 Dalmore board when the palmas PMIC is registered because regulator_register_resolve_supply() calls regulator_dev_lookup() which may try to acquire the regulator_list_mutex again. INFO: task swapper/0:1 blocked for more than 120 seconds. Not tainted 4.6.0-rc1-00001-g5e3ca2b-dirty #290 "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. swapper/0 D c07daeac 0 1 0 0x00000000 [<c07daeac>] (__schedule) from [<c07db454>] (schedule+0x50/0xc0) [<c07db454>] (schedule) from [<c07db6b0>] (schedule_preempt_disabled+0x24/0x40) [<c07db6b0>] (schedule_preempt_disabled) from [<c07ddd48>] (__mutex_lock_slowpath+0x17c/0x3e4) [<c07ddd48>] (__mutex_lock_slowpath) from [<c07ddfbc>] (mutex_lock+0xc/0x24) [<c07ddfbc>] (mutex_lock) from [<c03ab5f0>] (regulator_dev_lookup+0x130/0x208) [<c03ab5f0>] (regulator_dev_lookup) from [<c03aedd0>] (regulator_resolve_supply+0x94/0x2bc) [<c03aedd0>] (regulator_resolve_supply) from [<c04364e4>] (class_for_each_device+0x54/0xa8) [<c04364e4>] (class_for_each_device) from [<c03ae0a4>] (regulator_register+0x8cc/0xd10) [<c03ae0a4>] (regulator_register) from [<c03b0000>] (devm_regulator_register+0x40/0x74) [<c03b0000>] (devm_regulator_register) from [<c03b2ef0>] (palmas_smps_registration+0x254/0x3fc) [<c03b2ef0>] (palmas_smps_registration) from [<c03b3400>] (palmas_regulators_probe+0x368/0x424) [<c03b3400>] (palmas_regulators_probe) from [<c0436b1c>] (platform_drv_probe+0x50/0xb0) [<c0436b1c>] (platform_drv_probe) from [<c0435548>] (driver_probe_device+0x1f4/0x2b0) [<c0435548>] (driver_probe_device) from [<c0433ad0>] (bus_for_each_drv+0x44/0x8c) [<c0433ad0>] (bus_for_each_drv) from [<c04352cc>] (__device_attach+0x9c/0x100) [<c04352cc>] (__device_attach) from [<c0434958>] (bus_probe_device+0x84/0x8c) [<c0434958>] (bus_probe_device) from [<c0432e88>] (device_add+0x33c/0x524) [<c0432e88>] (device_add) from [<c05b1e48>] (of_platform_device_create_pdata+0x80/0xc4) [<c05b1e48>] (of_platform_device_create_pdata) from [<c05b1f5c>] (of_platform_bus_create+0xd0/0x2dc) [<c05b1f5c>] (of_platform_bus_create) from [<c05b21c4>] (of_platform_populate+0x5c/0xac) [<c05b21c4>] (of_platform_populate) from [<c04596fc>] (palmas_i2c_probe+0x324/0x580) [<c04596fc>] (palmas_i2c_probe) from [<c054ae1c>] (i2c_device_probe+0x140/0x1d0) [<c054ae1c>] (i2c_device_probe) from [<c0435548>] (driver_probe_device+0x1f4/0x2b0) [<c0435548>] (driver_probe_device) from [<c0433ad0>] (bus_for_each_drv+0x44/0x8c) [<c0433ad0>] (bus_for_each_drv) from [<c04352cc>] (__device_attach+0x9c/0x100) [<c04352cc>] (__device_attach) from [<c0434958>] (bus_probe_device+0x84/0x8c) [<c0434958>] (bus_probe_device) from [<c0432e88>] (device_add+0x33c/0x524) [<c0432e88>] (device_add) from [<c054b814>] (i2c_new_device+0x14c/0x184) [<c054b814>] (i2c_new_device) from [<c054bd0c>] (i2c_register_adapter+0x248/0x46c) [<c054bd0c>] (i2c_register_adapter) from [<c054fca0>] (tegra_i2c_probe+0x2d8/0x3bc) [<c054fca0>] (tegra_i2c_probe) from [<c0436b1c>] (platform_drv_probe+0x50/0xb0) [<c0436b1c>] (platform_drv_probe) from [<c0435548>] (driver_probe_device+0x1f4/0x2b0) [<c0435548>] (driver_probe_device) from [<c04356b0>] (__driver_attach+0xac/0xb0) [<c04356b0>] (__driver_attach) from [<c0433b6c>] (bus_for_each_dev+0x54/0x88) [<c0433b6c>] (bus_for_each_dev) from [<c0434b3c>] (bus_add_driver+0xe8/0x1f4) [<c0434b3c>] (bus_add_driver) from [<c0435eac>] (driver_register+0x78/0xf4) [<c0435eac>] (driver_register) from [<c0101768>] (do_one_initcall+0x84/0x1d4) [<c0101768>] (do_one_initcall) from [<c0b00d90>] (kernel_init_freeable+0x11c/0x1e8) [<c0b00d90>] (kernel_init_freeable) from [<c07d9350>] (kernel_init+0x8/0x118) [<c07d9350>] (kernel_init) from [<c0107938>] (ret_from_fork+0x14/0x3c) Fix this by releasing the mutex before calling regulator_register_resolve_supply() and update the error exit path to ensure the mutex is released on an error. Signed-off-by: Jon Hunter <jonathanh@xxxxxxxxxx> --- Mark, please confirm if it is ok to move the call to release the mutex before calling regulator_register_resolve_supply(). drivers/regulator/core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 74e8a7a3b3e8..2786d251b1cc 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -4000,12 +4000,11 @@ regulator_register(const struct regulator_desc *regulator_desc, } rdev_init_debugfs(rdev); + mutex_unlock(®ulator_list_mutex); /* try to resolve regulators supply since a new one was registered */ class_for_each_device(®ulator_class, NULL, NULL, regulator_register_resolve_supply); -out: - mutex_unlock(®ulator_list_mutex); kfree(config); return rdev; @@ -4016,15 +4015,16 @@ scrub: regulator_ena_gpio_free(rdev); device_unregister(&rdev->dev); /* device core frees rdev */ - rdev = ERR_PTR(ret); goto out; wash: regulator_ena_gpio_free(rdev); clean: kfree(rdev); - rdev = ERR_PTR(ret); - goto out; +out: + mutex_unlock(®ulator_list_mutex); + kfree(config); + return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(regulator_register); -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-tegra" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html