• Tony Lindgren's avatar
    dmaengine: cppi41: Fix oops in cppi41_runtime_resume · 362f4562
    Tony Lindgren authored
    Commit fdea2d09 ("dmaengine: cppi41: Add basic PM runtime support")
    together with recent MUSB changes allowed USB and DMA on BeagleBone to idle
    when no cable is connected. But looks like few corner case issues still
    remain.
    
    Looks like just by re-plugging USB cable about ten or so times on BeagleBone
    when configured in USB peripheral mode we can get warnings and eventually
    trigger an oops in cppi41 DMA:
    
    WARNING: CPU: 0 PID: 14 at drivers/dma/cppi41.c:1154 cppi41_runtime_suspend+
    x28/0x38 [cppi41]
    ...
    
    WARNING: CPU: 0 PID: 14 at drivers/dma/cppi41.c:452
    push_desc_queue+0x94/0x9c [cppi41]
    ...
    
    Unable to handle kernel NULL pointer dereference at virtual
    address 00000104
    pgd = c0004000
    [00000104] *pgd=00000000
    Internal error: Oops: 805 [#1] SMP ARM
    ...
    [<bf0d92cc>] (cppi41_runtime_resume [cppi41]) from [<c0589838>]
    (__rpm_callback+0xc0/0x214)
    [<c0589838>] (__rpm_callback) from [<c05899ac>] (rpm_callback+0x20/0x80)
    [<c05899ac>] (rpm_callback) from [<c0589460>] (rpm_resume+0x504/0x78c)
    [<c0589460>] (rpm_resume) from [<c058a1a0>] (pm_runtime_work+0x60/0xa8)
    [<c058a1a0>] (pm_runtime_work) from [<c0156120>] (process_one_work+0x2b4/0x808)
    
    This is because of a race with runtime PM and cppi41_dma_issue_pending()
    as reported by Alexandre Bailon <abailon@baylibre.com> in earlier
    set of patches. Based on mailing list discussions we however came to the
    conclusion that a different fix from Alexandre's fix is needed in order
    to guarantee that DMA is really active when we try to use it.
    
    To fix the issue, we need to add a driver specific flag as we otherwise
    can have -EINPROGRESS state set by runtime PM and can't rely on
    pm_runtime_active() to tell us when we can use the DMA.
    
    And we need to make sure the DMA transfers get triggered in the queued
    order. So let's always queue the transfers, then flush the queue
    from both cppi41_dma_issue_pending() and cppi41_runtime_resume()
    as suggested by Grygorii Strashko <grygorii.strashko@ti.com> in an
    earlier example patch.
    
    For reference, this is also documented in Documentation/power/runtime_pm.txt
    in the example at the end of the file as pointed out by Grygorii Strashko
    <grygorii.strashko@ti.com>.
    
    Based on earlier patches from Alexandre Bailon <abailon@baylibre.com>
    and Grygorii Strashko <grygorii.strashko@ti.com> modified based on
    testing and what was discussed on the mailing lists.
    
    Fixes: fdea2d09 ("dmaengine: cppi41: Add basic PM runtime support")
    Cc: Andy Shevchenko <andy.shevchenko@gmail.com>
    Cc: Bin Liu <b-liu@ti.com>
    Cc: Grygorii Strashko <grygorii.strashko@ti.com>
    Cc: Kevin Hilman <khilman@baylibre.com>
    Cc: Patrick Titiano <ptitiano@baylibre.com>
    Cc: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
    Reported-by: default avatarAlexandre Bailon <abailon@baylibre.com>
    Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
    Tested-by: default avatarBin Liu <b-liu@ti.com>
    Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
    362f4562
cppi41.c 28.7 KB