Received: by 2002:a25:868d:0:0:0:0:0 with SMTP id z13csp2897018ybk; Tue, 12 May 2020 10:44:41 -0700 (PDT) X-Google-Smtp-Source: APiQypJRFOPTkH9Rrs5y+jvUPkyvzfR1XUVNxbYP9jUs5cFZl9BHSk9SkLYCeeywYsdzUNDrd+zx X-Received: by 2002:a17:906:454a:: with SMTP id s10mr18939284ejq.141.1589305481082; Tue, 12 May 2020 10:44:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1589305481; cv=none; d=google.com; s=arc-20160816; b=QXRh+v8nJPwveSj5QllDmM18N6dOOeggFSgNtIwK/y8AoFl9i3I6rcxk1fFsxZT1lI okxYgxjgD5IKKlGvvuvsy7VdFv94aQFoTDfjea59YDZg3o0Xr+ycRafK31cy9STtVpY7 eVaXSrsBVGAluJNMKhpGV3kt8pFP1+ebSm9I4PZpYckzHiqfRxi9XYab6qvWi7n3E7jt RP14FhW2cZ5cuMO0YiDgE0eCYnmFkGAp3KMCJpOEYXsWDRQKocGOTDKzM0O4SilVG/+4 DKZmRJRVBBTxxLxGbFzDx34LuZktGnSOGFMuyt9UtwC+VNg1oA3u3GpxVSNO00LZOrsp Dehw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dmarc-filter:dkim-signature; bh=OGI8yDTVct0p5oMeYV6kM9AJFHplQPergOwGqrlARyE=; b=tG5lsO0hrY+rExCAPzaXtGRa3cifB2AWMwvtvE5OGJhkngcMxoniP/BRO3mu9axx6p tAwDBVBGMcfK0sOw2y9oDuLcEaQ6qYIR81JFHW5iaGd/kamQEIoURaz0LmY2abB68Hgl WYo29GtABtTaiVPLcXiqKE9dJhpfzbb7wf479WhdP4sacTXXe2ZCN2bzyrggp3B/qrUz uw1bOrVdctFXTwEW/cHSTeKchQjE1Usut721eWblHrKE+qsVK6dBsQvQNJarLwM5VCQ+ IrKUmRyFGGdjSRbO1KM0W65aWlXXw4CpTMaoycrRyFMuqVkDh959jSdnwcCpYmdSP3/j kixw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@mg.codeaurora.org header.s=smtp header.b=hv8QV990; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id by15si3141451edb.259.2020.05.12.10.44.16; Tue, 12 May 2020 10:44:41 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=fail header.i=@mg.codeaurora.org header.s=smtp header.b=hv8QV990; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730464AbgELRm1 (ORCPT + 99 others); Tue, 12 May 2020 13:42:27 -0400 Received: from mail26.static.mailgun.info ([104.130.122.26]:25561 "EHLO mail26.static.mailgun.info" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726465AbgELRmZ (ORCPT ); Tue, 12 May 2020 13:42:25 -0400 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1589305343; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=OGI8yDTVct0p5oMeYV6kM9AJFHplQPergOwGqrlARyE=; b=hv8QV9901aBV7HHLmFMi7vOipplPrr3yhv3jt3eS/43Ob3js3TtOpECdrY0YZGnXgM3yfzFB 2SnPyH4LLFJY4ZhqMT/s3Q9HBQCO+oC72uMwSAVjCY4gP1yV+8QmjMYx7cnLEpbWY6RE19sh mfqv7n4mf1fAyiqUJYjXvb18bn0= X-Mailgun-Sending-Ip: 104.130.122.26 X-Mailgun-Sid: WyI0MWYwYSIsICJsaW51eC1rZXJuZWxAdmdlci5rZXJuZWwub3JnIiwgImJlOWU0YSJd Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by mxa.mailgun.org with ESMTP id 5ebadfff.7f91dab71928-smtp-out-n04; Tue, 12 May 2020 17:42:23 -0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 1001) id 516B9C433BA; Tue, 12 May 2020 17:42:22 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=2.0 tests=ALL_TRUSTED,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.0 Received: from bbhatt-linux.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: bbhatt) by smtp.codeaurora.org (Postfix) with ESMTPSA id 8FF2EC433CB; Tue, 12 May 2020 17:42:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 8FF2EC433CB Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=bbhatt@codeaurora.org From: Bhaumik Bhatt To: manivannan.sadhasivam@linaro.org Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, hemantk@codeaurora.org, jhugo@codeaurora.org, Bhaumik Bhatt Subject: [PATCH v2 1/6] bus: mhi: core: Introduce independent voting mechanism Date: Tue, 12 May 2020 10:42:09 -0700 Message-Id: <1589305334-19466-2-git-send-email-bbhatt@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1589305334-19466-1-git-send-email-bbhatt@codeaurora.org> References: <1589305334-19466-1-git-send-email-bbhatt@codeaurora.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Allow independent votes from clients such that they can choose to vote for either the device or the bus or both. This helps in cases where the device supports autonomous low power mode wherein it can move to M2 state without the need to notify the host. Clients can also vote only to keep the underlying bus active without having the device in M0 state to support offload use cases. Signed-off-by: Bhaumik Bhatt --- drivers/bus/mhi/core/init.c | 15 +++++---- drivers/bus/mhi/core/pm.c | 75 ++++++++++++++++++++++++++++++++------------- include/linux/mhi.h | 21 ++++++++----- 3 files changed, 77 insertions(+), 34 deletions(-) diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c index 12207cc..d5bebe5 100644 --- a/drivers/bus/mhi/core/init.c +++ b/drivers/bus/mhi/core/init.c @@ -1061,7 +1061,8 @@ struct mhi_device *mhi_alloc_device(struct mhi_controller *mhi_cntrl) dev->release = mhi_release_device; dev->parent = mhi_cntrl->cntrl_dev; mhi_dev->mhi_cntrl = mhi_cntrl; - mhi_dev->dev_wake = 0; + atomic_set(&mhi_dev->dev_vote, 0); + atomic_set(&mhi_dev->bus_vote, 0); return mhi_dev; } @@ -1078,7 +1079,7 @@ static int mhi_driver_probe(struct device *dev) int ret; /* Bring device out of LPM */ - ret = mhi_device_get_sync(mhi_dev); + ret = mhi_device_get_sync(mhi_dev, MHI_VOTE_DEVICE); if (ret) return ret; @@ -1137,14 +1138,14 @@ static int mhi_driver_probe(struct device *dev) if (dl_chan && dl_chan->auto_start) mhi_prepare_channel(mhi_cntrl, dl_chan); - mhi_device_put(mhi_dev); + mhi_device_put(mhi_dev, MHI_VOTE_DEVICE); return ret; exit_probe: mhi_unprepare_from_transfer(mhi_dev); - mhi_device_put(mhi_dev); + mhi_device_put(mhi_dev, MHI_VOTE_DEVICE); return ret; } @@ -1213,8 +1214,10 @@ static int mhi_driver_remove(struct device *dev) } read_lock_bh(&mhi_cntrl->pm_lock); - while (mhi_dev->dev_wake) - mhi_device_put(mhi_dev); + while (atomic_read(&mhi_dev->dev_vote)) + mhi_device_put(mhi_dev, MHI_VOTE_DEVICE); + while (atomic_read(&mhi_dev->bus_vote)) + mhi_device_put(mhi_dev, MHI_VOTE_BUS); read_unlock_bh(&mhi_cntrl->pm_lock); return 0; diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c index de5abb2..0b68dcd 100644 --- a/drivers/bus/mhi/core/pm.c +++ b/drivers/bus/mhi/core/pm.c @@ -675,7 +675,8 @@ void mhi_pm_st_worker(struct work_struct *work) int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) { struct mhi_chan *itr, *tmp; - struct device *dev = &mhi_cntrl->mhi_dev->dev; + struct mhi_device *mhi_dev = mhi_cntrl->mhi_dev; + struct device *dev = &mhi_dev->dev; enum mhi_pm_state new_state; int ret; @@ -686,7 +687,8 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) return -EIO; /* Return busy if there are any pending resources */ - if (atomic_read(&mhi_cntrl->dev_wake)) + if (atomic_read(&mhi_cntrl->dev_wake) || + atomic_read(&mhi_dev->bus_vote)) return -EBUSY; /* Take MHI out of M2 state */ @@ -712,10 +714,9 @@ int mhi_pm_suspend(struct mhi_controller *mhi_cntrl) write_lock_irq(&mhi_cntrl->pm_lock); - if (atomic_read(&mhi_cntrl->dev_wake)) { - write_unlock_irq(&mhi_cntrl->pm_lock); + if (atomic_read(&mhi_cntrl->dev_wake) || + atomic_read(&mhi_dev->bus_vote)) return -EBUSY; - } dev_info(dev, "Allowing M3 transition\n"); new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_M3_ENTER); @@ -1080,42 +1081,74 @@ int mhi_force_rddm_mode(struct mhi_controller *mhi_cntrl) } EXPORT_SYMBOL_GPL(mhi_force_rddm_mode); -void mhi_device_get(struct mhi_device *mhi_dev) +void mhi_device_get(struct mhi_device *mhi_dev, int vote) { struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; - mhi_dev->dev_wake++; - read_lock_bh(&mhi_cntrl->pm_lock); - mhi_cntrl->wake_get(mhi_cntrl, true); - read_unlock_bh(&mhi_cntrl->pm_lock); + if (vote & MHI_VOTE_DEVICE) { + atomic_inc(&mhi_dev->dev_vote); + read_lock_bh(&mhi_cntrl->pm_lock); + mhi_cntrl->wake_get(mhi_cntrl, true); + read_unlock_bh(&mhi_cntrl->pm_lock); + } + + if (vote & MHI_VOTE_BUS) { + atomic_inc(&mhi_dev->bus_vote); + mhi_cntrl->runtime_get(mhi_cntrl); + } } EXPORT_SYMBOL_GPL(mhi_device_get); -int mhi_device_get_sync(struct mhi_device *mhi_dev) +int mhi_device_get_sync(struct mhi_device *mhi_dev, int vote) { struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; int ret; + /* bring device out of low power modes regardless of the type of vote */ ret = __mhi_device_get_sync(mhi_cntrl); - if (!ret) - mhi_dev->dev_wake++; + if (ret) + return ret; + + if (vote & MHI_VOTE_DEVICE) { + atomic_inc(&mhi_dev->dev_vote); + } else { + /* remove device vote as it was not requested */ + read_lock_bh(&mhi_cntrl->pm_lock); + mhi_cntrl->wake_put(mhi_cntrl, false); + read_unlock_bh(&mhi_cntrl->pm_lock); + } + + if (vote & MHI_VOTE_BUS) { + atomic_inc(&mhi_dev->bus_vote); + mhi_cntrl->runtime_get(mhi_cntrl); + } return ret; } EXPORT_SYMBOL_GPL(mhi_device_get_sync); -void mhi_device_put(struct mhi_device *mhi_dev) +void mhi_device_put(struct mhi_device *mhi_dev, int vote) { struct mhi_controller *mhi_cntrl = mhi_dev->mhi_cntrl; - mhi_dev->dev_wake--; - read_lock_bh(&mhi_cntrl->pm_lock); - if (MHI_PM_IN_SUSPEND_STATE(mhi_cntrl->pm_state)) { - mhi_cntrl->runtime_get(mhi_cntrl); - mhi_cntrl->runtime_put(mhi_cntrl); + if (vote & MHI_VOTE_DEVICE) { + atomic_dec(&mhi_dev->dev_vote); + read_lock_bh(&mhi_cntrl->pm_lock); + if (MHI_PM_IN_SUSPEND_STATE(mhi_cntrl->pm_state)) { + mhi_cntrl->runtime_get(mhi_cntrl); + mhi_cntrl->runtime_put(mhi_cntrl); + } + mhi_cntrl->wake_put(mhi_cntrl, false); + read_unlock_bh(&mhi_cntrl->pm_lock); } - mhi_cntrl->wake_put(mhi_cntrl, false); - read_unlock_bh(&mhi_cntrl->pm_lock); + if (vote & MHI_VOTE_BUS) { + atomic_dec(&mhi_dev->bus_vote); + mhi_cntrl->runtime_put(mhi_cntrl); + + /* notify controller that all bus votes are removed */ + if (!atomic_read(&mhi_dev->bus_vote)) + mhi_cntrl->status_cb(mhi_cntrl, MHI_CB_IDLE); + } } EXPORT_SYMBOL_GPL(mhi_device_put); diff --git a/include/linux/mhi.h b/include/linux/mhi.h index b008914..10fcb52 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -16,6 +16,9 @@ #include #include +#define MHI_VOTE_BUS BIT(0) /* do not disable the mhi bus */ +#define MHI_VOTE_DEVICE BIT(1) /* prevent mhi device from entering lpm */ + struct mhi_chan; struct mhi_event; struct mhi_ctxt; @@ -459,7 +462,8 @@ struct mhi_device { enum mhi_device_type dev_type; int ul_chan_id; int dl_chan_id; - u32 dev_wake; + atomic_t dev_vote; + atomic_t bus_vote; }; /** @@ -644,23 +648,26 @@ void mhi_set_mhi_state(struct mhi_controller *mhi_cntrl, enum mhi_state mhi_get_mhi_state(struct mhi_controller *mhi_cntrl); /** - * mhi_device_get - Disable device low power mode + * mhi_device_get - Disable device and/or bus low power mode * @mhi_dev: Device associated with the channel + * @vote: requested vote (bus, device or both) */ -void mhi_device_get(struct mhi_device *mhi_dev); +void mhi_device_get(struct mhi_device *mhi_dev, int vote); /** - * mhi_device_get_sync - Disable device low power mode. Synchronously + * mhi_device_get_sync - Disable device and/or bus low power mode. Synchronously * take the controller out of suspended state * @mhi_dev: Device associated with the channel + * @vote: requested vote (bus, device or both) */ -int mhi_device_get_sync(struct mhi_device *mhi_dev); +int mhi_device_get_sync(struct mhi_device *mhi_dev, int vote); /** - * mhi_device_put - Re-enable device low power mode + * mhi_device_put - Re-enable device and/or bus low power mode * @mhi_dev: Device associated with the channel + * @vote: vote(s) to remove (bus, device or both) */ -void mhi_device_put(struct mhi_device *mhi_dev); +void mhi_device_put(struct mhi_device *mhi_dev, int vote); /** * mhi_prepare_for_transfer - Setup channel for data transfer -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project