• Krzysztof Adamski's avatar
    regulator: core: fix crash in error path of regulator_register · 32165230
    Krzysztof Adamski authored
    This problem was introduced by:
    commit daad134d ("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: default avatarKrzysztof Adamski <krzysztof.adamski@tieto.com>
    Reported-by: default avatarJon Hunter <jonathanh@nvidia.com>
    Acked-by: default avatarJon Hunter <jonathanh@nvidia.com>
    Tested-by: default avatarJon Hunter <jonathanh@nvidia.com>
    Signed-off-by: default avatarMark Brown <broonie@kernel.org>
    32165230
core.c 114 KB