• Semen Protsenko's avatar
    serial: omap: Fix error handling in probe · 66cf1d84
    Semen Protsenko authored
    There is pm_qos_add_request() being executed on serial_omap_probe(),
    which stores "&up->pm_qos_request" from omap-serial driver to
    "pm_qos_array[PM_QOS_CPU_DMA_LATENCY]->constraints". If
    serial_omap_probe() fails after pm_qos_add_request() (e.g. on
    uart_add_one_port() call), pm_qos_array still keeping pm_qos_request
    struct from omap-serial driver, which is not valid anymore (since driver
    failed). This leads further to kernel crash on pm_qos_update_target(),
    executing from some completely different driver.
    
    We were observing this while trying to run audio playback while having
    one of omap-serial driver instances failed on uart_add_one_port() call:
        Unable to handle kernel paging request at virtual address fffffffc
        Backtrace:
        (plist_add) from (pm_qos_update_target)
        (pm_qos_update_target) from (pm_qos_add_request)
        (pm_qos_add_request) from (snd_pcm_hw_params)
        (snd_pcm_hw_params) from (snd_pcm_common_ioctl1)
        (snd_pcm_common_ioctl1) from (snd_pcm_playback_ioctl1)
        (snd_pcm_playback_ioctl1) from (snd_pcm_playback_ioctl)
        (snd_pcm_playback_ioctl) from (do_vfs_ioctl)
        (do_vfs_ioctl) from (SyS_ioctl)
        (SyS_ioctl) from (ret_fast_syscall)
    
    This patch adds pm_qos_remove_request() on fail path in
    serial_omap_probe() in order to fix this issue. While at it, free the
    wakeup settings on fail path as well, just like it's done in
    serial_omap_remove().
    Signed-off-by: default avatarSemen Protsenko <semen.protsenko@globallogic.com>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    66cf1d84
omap-serial.c 48.8 KB