• Tomi Valkeinen's avatar
    drm/bridge: sii902x: Fix probing race issue · dffdfb8f
    Tomi Valkeinen authored
    A null pointer dereference crash has been observed rarely on TI
    platforms using sii9022 bridge:
    
    [   53.271356]  sii902x_get_edid+0x34/0x70 [sii902x]
    [   53.276066]  sii902x_bridge_get_edid+0x14/0x20 [sii902x]
    [   53.281381]  drm_bridge_get_edid+0x20/0x34 [drm]
    [   53.286305]  drm_bridge_connector_get_modes+0x8c/0xcc [drm_kms_helper]
    [   53.292955]  drm_helper_probe_single_connector_modes+0x190/0x538 [drm_kms_helper]
    [   53.300510]  drm_client_modeset_probe+0x1f0/0xbd4 [drm]
    [   53.305958]  __drm_fb_helper_initial_config_and_unlock+0x50/0x510 [drm_kms_helper]
    [   53.313611]  drm_fb_helper_initial_config+0x48/0x58 [drm_kms_helper]
    [   53.320039]  drm_fbdev_dma_client_hotplug+0x84/0xd4 [drm_dma_helper]
    [   53.326401]  drm_client_register+0x5c/0xa0 [drm]
    [   53.331216]  drm_fbdev_dma_setup+0xc8/0x13c [drm_dma_helper]
    [   53.336881]  tidss_probe+0x128/0x264 [tidss]
    [   53.341174]  platform_probe+0x68/0xc4
    [   53.344841]  really_probe+0x188/0x3c4
    [   53.348501]  __driver_probe_device+0x7c/0x16c
    [   53.352854]  driver_probe_device+0x3c/0x10c
    [   53.357033]  __device_attach_driver+0xbc/0x158
    [   53.361472]  bus_for_each_drv+0x88/0xe8
    [   53.365303]  __device_attach+0xa0/0x1b4
    [   53.369135]  device_initial_probe+0x14/0x20
    [   53.373314]  bus_probe_device+0xb0/0xb4
    [   53.377145]  deferred_probe_work_func+0xcc/0x124
    [   53.381757]  process_one_work+0x1f0/0x518
    [   53.385770]  worker_thread+0x1e8/0x3dc
    [   53.389519]  kthread+0x11c/0x120
    [   53.392750]  ret_from_fork+0x10/0x20
    
    The issue here is as follows:
    
    - tidss probes, but is deferred as sii902x is still missing.
    - sii902x starts probing and enters sii902x_init().
    - sii902x calls drm_bridge_add(). Now the sii902x bridge is ready from
      DRM's perspective.
    - sii902x calls sii902x_audio_codec_init() and
      platform_device_register_data()
    - The registration of the audio platform device causes probing of the
      deferred devices.
    - tidss probes, which eventually causes sii902x_bridge_get_edid() to be
      called.
    - sii902x_bridge_get_edid() tries to use the i2c to read the edid.
      However, the sii902x driver has not set up the i2c part yet, leading
      to the crash.
    
    Fix this by moving the drm_bridge_add() to the end of the
    sii902x_init(), which is also at the very end of sii902x_probe().
    Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ideasonboard.com>
    Fixes: 21d80840 ("drm/bridge/sii902x: Fix EDID readback")
    Reviewed-by: default avatarAradhya Bhatia <a-bhatia1@ti.com>
    Acked-by: default avatarLinus Walleij <linus.walleij@linaro.org>
    Signed-off-by: default avatarRobert Foss <rfoss@kernel.org>
    Link: https://patchwork.freedesktop.org/patch/msgid/20240103-si902x-fixes-v1-1-b9fd3e448411@ideasonboard.com
    dffdfb8f
sii902x.c 33.4 KB