lkml.org 
[lkml]   [2021]   [Jul]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.13 069/800] bus: mhi: core: Fix power down latency
    Date
    From: Loic Poulain <loic.poulain@linaro.org>

    commit 44b1eba44dc537edf076f131f1eeee7544d0e04f upstream.

    On graceful power-down/disable transition, when an MHI reset is
    performed, the MHI device loses its context, including interrupt
    configuration. However, the current implementation is waiting for
    event(irq) driven state change to confirm reset has been completed,
    which never happens, and causes reset timeout, leading to unexpected
    high latency of the mhi_power_down procedure (up to 45 seconds).

    Fix that by moving to the recently introduced poll_reg_field method,
    waiting for the reset bit to be cleared, in the same way as the
    power_on procedure.

    Cc: stable@vger.kernel.org
    Fixes: a6e2e3522f29 ("bus: mhi: core: Add support for PM state transitions")
    Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
    Reviewed-by: Bhaumik Bhatt <bbhatt@codeaurora.org>
    Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
    Reviewed-by: Hemant Kumar <hemantk@codeaurora.org>
    Link: https://lore.kernel.org/r/1620029090-8975-1-git-send-email-loic.poulain@linaro.org
    Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
    Link: https://lore.kernel.org/r/20210621161616.77524-3-manivannan.sadhasivam@linaro.org
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/bus/mhi/core/pm.c | 18 +++++-------------
    1 file changed, 5 insertions(+), 13 deletions(-)

    --- a/drivers/bus/mhi/core/pm.c
    +++ b/drivers/bus/mhi/core/pm.c
    @@ -465,23 +465,15 @@ static void mhi_pm_disable_transition(st

    /* Trigger MHI RESET so that the device will not access host memory */
    if (!MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state)) {
    - u32 in_reset = -1;
    - unsigned long timeout = msecs_to_jiffies(mhi_cntrl->timeout_ms);
    -
    dev_dbg(dev, "Triggering MHI Reset in device\n");
    mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET);

    /* Wait for the reset bit to be cleared by the device */
    - ret = wait_event_timeout(mhi_cntrl->state_event,
    - mhi_read_reg_field(mhi_cntrl,
    - mhi_cntrl->regs,
    - MHICTRL,
    - MHICTRL_RESET_MASK,
    - MHICTRL_RESET_SHIFT,
    - &in_reset) ||
    - !in_reset, timeout);
    - if (!ret || in_reset)
    - dev_err(dev, "Device failed to exit MHI Reset state\n");
    + ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL,
    + MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 0,
    + 25000);
    + if (ret)
    + dev_err(dev, "Device failed to clear MHI Reset\n");

    /*
    * Device will clear BHI_INTVEC as a part of RESET processing,

    \
     
     \ /
      Last update: 2021-07-12 10:40    [W:2.079 / U:0.396 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site