regulator: core: fix crash in error path of regulator_register
This problem was introduced by:
commit
daad134d6649 ("regulator: core: Request GPIO before creating
sysfs entries")
The error path was not updated correctly after moving GPIO registration
code and in case regulator_ena_gpio_free failed, device_unregister() was
called even though device_register() was not yet called.
This problem breaks the boot at least on all Tegra 32-bit devices. It
will also crash each device that specifices GPIO that is unavaiable at
regulator_register call. Here's error log I've got when forced GPIO to
be invalid:
[ 1.116612] usb-otg-vbus-reg: Failed to request enable GPIO10: -22
[ 1.122794] Unable to handle kernel NULL pointer dereference at
virtual address
00000044
[ 1.130894] pgd =
c0004000
[ 1.133598] [
00000044] *pgd=
00000000
[ 1.137205] Internal error: Oops: 5 [#1] SMP ARM
and here's backtrace from KDB:
Exception stack(0xef11fbd0 to 0xef11fc18)
fbc0:
00000000 c0738a14 00000000 00000000
fbe0:
c0b2a0b0 00000000 00000000 c0738a14 c0b5fdf8 00000001 ef7f6074 ef11fc4c
fc00:
ef11fc50 ef11fc20 c02a8344 c02a7f1c 60000013 ffffffff
[<
c010cee0>] (__dabt_svc) from [<
c02a7f1c>] (kernfs_find_ns+0x18/0xf8)
[<
c02a7f1c>] (kernfs_find_ns) from [<
c02a8344>] (kernfs_find_and_get_ns+0x40/0x58)
[<
c02a8344>] (kernfs_find_and_get_ns) from [<
c02ac4a4>] (sysfs_unmerge_group+0x28/0x68)
[<
c02ac4a4>] (sysfs_unmerge_group) from [<
c044389c>] (dpm_sysfs_remove+0x30/0x5c)
[<
c044389c>] (dpm_sysfs_remove) from [<
c0436ba8>] (device_del+0x48/0x1f4)
[<
c0436ba8>] (device_del) from [<
c0436d84>] (device_unregister+0x30/0x6c)
[<
c0436d84>] (device_unregister) from [<
c0403910>] (regulator_register+0x6d0/0xdac)
[<
c0403910>] (regulator_register) from [<
c04052d4>] (devm_regulator_register+0x50/0x84)
[<
c04052d4>] (devm_regulator_register) from [<
c0406298>] (reg_fixed_voltage_probe+0x25c/0x3c0)
[<
c0406298>] (reg_fixed_voltage_probe) from [<
c043d21c>] (platform_drv_probe+0x60/0xb0)
[<
c043d21c>] (platform_drv_probe) from [<
c043b078>] (driver_probe_device+0x24c/0x440)
[<
c043b078>] (driver_probe_device) from [<
c043b5e8>] (__device_attach_driver+0xc0/0x120)
[<
c043b5e8>] (__device_attach_driver) from [<
c043901c>] (bus_for_each_drv+0x6c/0x98)
[<
c043901c>] (bus_for_each_drv) from [<
c043ad20>] (__device_attach+0xac/0x138)
[<
c043ad20>] (__device_attach) from [<
c043b664>] (device_initial_probe+0x1c/0x20)
[<
c043b664>] (device_initial_probe) from [<
c043a074>] (bus_probe_device+0x94/0x9c)
[<
c043a074>] (bus_probe_device) from [<
c043a610>] (deferred_probe_work_func+0x80/0xcc)
[<
c043a610>] (deferred_probe_work_func) from [<
c01381d0>] (process_one_work+0x158/0x454)
[<
c01381d0>] (process_one_work) from [<
c013854c>] (worker_thread+0x38/0x510)
[<
c013854c>] (worker_thread) from [<
c013e154>] (kthread+0xe8/0x104)
[<
c013e154>] (kthread) from [<
c0108638>] (ret_from_fork+0x14/0x3c)
Signed-off-by: Krzysztof Adamski <krzysztof.adamski@tieto.com>
Reported-by: Jon Hunter <jonathanh@nvidia.com>
Acked-by: Jon Hunter <jonathanh@nvidia.com>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Signed-off-by: Mark Brown <broonie@kernel.org>