From patchwork Tue Apr 5 13:57:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 556290 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 89247C4321E for ; Tue, 5 Apr 2022 23:26:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1452668AbiDEXGo (ORCPT ); Tue, 5 Apr 2022 19:06:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48792 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1443747AbiDEPkP (ORCPT ); Tue, 5 Apr 2022 11:40:15 -0400 Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4C4701FCC2 for ; Tue, 5 Apr 2022 06:58:56 -0700 (PDT) Received: by mail-pf1-x435.google.com with SMTP id b15so12174688pfm.5 for ; Tue, 05 Apr 2022 06:58:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Bmelj8zspcRkN5OX8DNe2PV6W/VRFRvCWxHNctPaPZA=; b=YhhSNA1OBVQonIaLXMiQYWLlVnraAbmy19de5twCLbux8x7TpHoPiH4QbCytLrIv7D 636xS6dz++z5UEt5F7Hwd41xd1/V2xdM0FtXFO2nm9JUlgpMmzNsWqdSAzoKD4uG6dmR ndAb1SPDJfiCW/yGl1QB78p2HikvDdnb93ScsXnbpw9BhNmFlHkqXuMxPDUQtSNdg1rQ /vI5Q+GIDHlpBHNnag1BvwJ6QebMq0f60Vephhf7G4VdXH0PFG8r6BcDlJiFbFVfgsZD AMaEdt5QhSpIRqOibSE2UJ13ff7JBSenDqxraJebtW4e26Byen0I+Uf4GwG/m6KQTvmR IFlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Bmelj8zspcRkN5OX8DNe2PV6W/VRFRvCWxHNctPaPZA=; b=05QyevmazvAt76koUkIgIJX1dIn4ldRblKzkmguM278Ile51qs12ta6CmOKVTcK5CQ RNMuSAgr4OnVYXB2bpuT03z4BvJPEQ4kdcojLPsN483YedJc6ZcHfOFjOgDANMNP4zB7 fFYxAJyHHYkKLy+UGiRIsjO4sySAhI/86CaDF9NB90uch6vf51Rp74AAMHDBSJu9tYtk /tlTw1bREpEr9kKv+uMgRv4sbQSIenKxkHs+YHXDdNPqa3XSx+1n9Pxm1uhuhudWT81V xJOhQdw2WdACwq5XRTTizw1QHJqyeXiY2cUDO0f+2qYMRfccnHfauX3CjZ4nd+xgIAO9 K9tQ== X-Gm-Message-State: AOAM531LMQKUg6E6OJVcznjWZYMG5FASZV0WwUHutUaw+y0Uw8W4ybxI pnBTNq6RxItP2+pl/moii7KL X-Google-Smtp-Source: ABdhPJzauq+Id391HU1LBwX25YeLxQps8qIaXH8BAQx+fRGgrGdWICOlILSGpH2os6BDmEcCCPvF7Q== X-Received: by 2002:a63:d454:0:b0:386:86:6aaa with SMTP id i20-20020a63d454000000b0038600866aaamr2999348pgj.60.1649167135756; Tue, 05 Apr 2022 06:58:55 -0700 (PDT) Received: from localhost.localdomain ([59.92.98.98]) by smtp.gmail.com with ESMTPSA id u14-20020a056a00124e00b004fab8f3245fsm16785402pfi.149.2022.04.05.06.58.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Apr 2022 06:58:55 -0700 (PDT) From: Manivannan Sadhasivam To: gregkh@linuxfoundation.org Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, elder@linaro.org, mhi@lists.linux.dev, quic_hemantk@quicinc.com, quic_bbhatt@quicinc.com, quic_jhugo@quicinc.com, bjorn.andersson@linaro.org, dmitry.baryshkov@linaro.org, Manivannan Sadhasivam Subject: [PATCH 10/18] bus: mhi: ep: Add support for powering down the MHI endpoint stack Date: Tue, 5 Apr 2022 19:27:46 +0530 Message-Id: <20220405135754.6622-11-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220405135754.6622-1-manivannan.sadhasivam@linaro.org> References: <20220405135754.6622-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add support for MHI endpoint power_down that includes stopping all available channels, destroying the channels, resetting the event and transfer rings and freeing the host cache. The stack will be powered down whenever the physical bus link goes down. Reviewed-by: Alex Elder Signed-off-by: Manivannan Sadhasivam --- drivers/bus/mhi/ep/main.c | 78 +++++++++++++++++++++++++++++++++++++++ include/linux/mhi_ep.h | 6 +++ 2 files changed, 84 insertions(+) diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 20d579733486..968025e4d3ac 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -22,6 +22,8 @@ static DEFINE_IDA(mhi_ep_cntrl_ida); +static int mhi_ep_destroy_device(struct device *dev, void *data); + static int mhi_ep_send_event(struct mhi_ep_cntrl *mhi_cntrl, u32 ring_idx, struct mhi_ring_element *el, bool bei) { @@ -400,6 +402,68 @@ static irqreturn_t mhi_ep_irq(int irq, void *data) return IRQ_HANDLED; } +static void mhi_ep_abort_transfer(struct mhi_ep_cntrl *mhi_cntrl) +{ + struct mhi_ep_ring *ch_ring, *ev_ring; + struct mhi_result result = {}; + struct mhi_ep_chan *mhi_chan; + int i; + + /* Stop all the channels */ + for (i = 0; i < mhi_cntrl->max_chan; i++) { + mhi_chan = &mhi_cntrl->mhi_chan[i]; + if (!mhi_chan->ring.started) + continue; + + mutex_lock(&mhi_chan->lock); + /* Send channel disconnect status to client drivers */ + if (mhi_chan->xfer_cb) { + result.transaction_status = -ENOTCONN; + result.bytes_xferd = 0; + mhi_chan->xfer_cb(mhi_chan->mhi_dev, &result); + } + + mhi_chan->state = MHI_CH_STATE_DISABLED; + mutex_unlock(&mhi_chan->lock); + } + + flush_workqueue(mhi_cntrl->wq); + + /* Destroy devices associated with all channels */ + device_for_each_child(&mhi_cntrl->mhi_dev->dev, NULL, mhi_ep_destroy_device); + + /* Stop and reset the transfer rings */ + for (i = 0; i < mhi_cntrl->max_chan; i++) { + mhi_chan = &mhi_cntrl->mhi_chan[i]; + if (!mhi_chan->ring.started) + continue; + + ch_ring = &mhi_cntrl->mhi_chan[i].ring; + mutex_lock(&mhi_chan->lock); + mhi_ep_ring_reset(mhi_cntrl, ch_ring); + mutex_unlock(&mhi_chan->lock); + } + + /* Stop and reset the event rings */ + for (i = 0; i < mhi_cntrl->event_rings; i++) { + ev_ring = &mhi_cntrl->mhi_event[i].ring; + if (!ev_ring->started) + continue; + + mutex_lock(&mhi_cntrl->event_lock); + mhi_ep_ring_reset(mhi_cntrl, ev_ring); + mutex_unlock(&mhi_cntrl->event_lock); + } + + /* Stop and reset the command ring */ + mhi_ep_ring_reset(mhi_cntrl, &mhi_cntrl->mhi_cmd->ring); + + mhi_ep_free_host_cfg(mhi_cntrl); + mhi_ep_mmio_mask_interrupts(mhi_cntrl); + + mhi_cntrl->enabled = false; +} + int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl) { struct device *dev = &mhi_cntrl->mhi_dev->dev; @@ -454,6 +518,16 @@ int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl) } EXPORT_SYMBOL_GPL(mhi_ep_power_up); +void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl) +{ + if (mhi_cntrl->enabled) + mhi_ep_abort_transfer(mhi_cntrl); + + kfree(mhi_cntrl->mhi_event); + disable_irq(mhi_cntrl->irq); +} +EXPORT_SYMBOL_GPL(mhi_ep_power_down); + static void mhi_ep_release_device(struct device *dev) { struct mhi_ep_device *mhi_dev = to_mhi_ep_device(dev); @@ -733,6 +807,10 @@ int mhi_ep_register_controller(struct mhi_ep_cntrl *mhi_cntrl, } EXPORT_SYMBOL_GPL(mhi_ep_register_controller); +/* + * It is expected that the controller drivers will power down the MHI EP stack + * using "mhi_ep_power_down()" before calling this function to unregister themselves. + */ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl) { struct mhi_ep_device *mhi_dev = mhi_cntrl->mhi_dev; diff --git a/include/linux/mhi_ep.h b/include/linux/mhi_ep.h index 3b065f82fbeb..9da683e8302c 100644 --- a/include/linux/mhi_ep.h +++ b/include/linux/mhi_ep.h @@ -244,4 +244,10 @@ void mhi_ep_unregister_controller(struct mhi_ep_cntrl *mhi_cntrl); */ int mhi_ep_power_up(struct mhi_ep_cntrl *mhi_cntrl); +/** + * mhi_ep_power_down - Power down the MHI endpoint stack + * @mhi_cntrl: MHI controller + */ +void mhi_ep_power_down(struct mhi_ep_cntrl *mhi_cntrl); + #endif