linux-arm-msm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/2] Polling for MHI ready
@ 2021-03-31 18:34 Bhaumik Bhatt
  2021-03-31 18:34 ` [PATCH v6 1/2] bus: mhi: core: Introduce internal register poll helper function Bhaumik Bhatt
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Bhaumik Bhatt @ 2021-03-31 18:34 UTC (permalink / raw)
  To: manivannan.sadhasivam
  Cc: linux-arm-msm, hemantk, jhugo, linux-kernel, carl.yin,
	naveen.kumar, loic.poulain, Bhaumik Bhatt

v6:
-Fix return error code for mhi_poll_reg_field()
-Do not recode when returning from mhi_ready_state_transition() if polling fails

v5:
-Use fsleep in place of udelay or usleep_range to accommodate better delay use
-Drop patch for polling during RDDM panic path as new API cannot be used there

v4:
-Added reviewed-by tag
-Return appropriate error code from mhi_poll_reg_field()
-Fixed bug where mhi_poll_reg_field() returns success if polling times out
-Added an interval_us variable in mhi_ready_state_transition()

v3:
-Removed config changes that crept in in the first patch

v2:
-Addressed review comments
-Introduce new patch for to use controller defined read_reg() for polling
-Add usage in RDDM download panic path as well

Bhaumik Bhatt (2):
  bus: mhi: core: Introduce internal register poll helper function
  bus: mhi: core: Move to polling method to wait for MHI ready

 drivers/bus/mhi/core/internal.h |  3 +++
 drivers/bus/mhi/core/main.c     | 23 +++++++++++++++++++++++
 drivers/bus/mhi/core/pm.c       | 34 ++++++++++++++++------------------
 3 files changed, 42 insertions(+), 18 deletions(-)

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v6 1/2] bus: mhi: core: Introduce internal register poll helper function
  2021-03-31 18:34 [PATCH v6 0/2] Polling for MHI ready Bhaumik Bhatt
@ 2021-03-31 18:34 ` Bhaumik Bhatt
  2021-03-31 18:38   ` Manivannan Sadhasivam
  2021-03-31 18:34 ` [PATCH v6 2/2] bus: mhi: core: Move to polling method to wait for MHI ready Bhaumik Bhatt
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Bhaumik Bhatt @ 2021-03-31 18:34 UTC (permalink / raw)
  To: manivannan.sadhasivam
  Cc: linux-arm-msm, hemantk, jhugo, linux-kernel, carl.yin,
	naveen.kumar, loic.poulain, Bhaumik Bhatt

Introduce helper function to allow MHI core driver to poll for
a value in a register field. This helps reach a common path to
read and poll register values along with a retry time interval.

Signed-off-by: Bhaumik Bhatt <bbhatt@codeaurora.org>
Reviewed-by: Loic Poulain <loic.poulain@linaro.org>
---
 drivers/bus/mhi/core/internal.h |  3 +++
 drivers/bus/mhi/core/main.c     | 23 +++++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/drivers/bus/mhi/core/internal.h b/drivers/bus/mhi/core/internal.h
index 7aa5cfd..e690f15 100644
--- a/drivers/bus/mhi/core/internal.h
+++ b/drivers/bus/mhi/core/internal.h
@@ -646,6 +646,9 @@ int __must_check mhi_read_reg(struct mhi_controller *mhi_cntrl,
 int __must_check mhi_read_reg_field(struct mhi_controller *mhi_cntrl,
 				    void __iomem *base, u32 offset, u32 mask,
 				    u32 shift, u32 *out);
+int __must_check mhi_poll_reg_field(struct mhi_controller *mhi_cntrl,
+				    void __iomem *base, u32 offset, u32 mask,
+				    u32 shift, u32 val, u32 delayus);
 void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *base,
 		   u32 offset, u32 val);
 void mhi_write_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *base,
diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c
index 8b68657..58b8111 100644
--- a/drivers/bus/mhi/core/main.c
+++ b/drivers/bus/mhi/core/main.c
@@ -4,6 +4,7 @@
  *
  */
 
+#include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/dma-direction.h>
 #include <linux/dma-mapping.h>
@@ -37,6 +38,28 @@ int __must_check mhi_read_reg_field(struct mhi_controller *mhi_cntrl,
 	return 0;
 }
 
+int __must_check mhi_poll_reg_field(struct mhi_controller *mhi_cntrl,
+				    void __iomem *base, u32 offset,
+				    u32 mask, u32 shift, u32 val, u32 delayus)
+{
+	int ret;
+	u32 out, retry = (mhi_cntrl->timeout_ms * 1000) / delayus;
+
+	while (retry--) {
+		ret = mhi_read_reg_field(mhi_cntrl, base, offset, mask, shift,
+					 &out);
+		if (ret)
+			return ret;
+
+		if (out == val)
+			return 0;
+
+		fsleep(delayus);
+	}
+
+	return -ETIMEDOUT;
+}
+
 void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *base,
 		   u32 offset, u32 val)
 {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH v6 2/2] bus: mhi: core: Move to polling method to wait for MHI ready
  2021-03-31 18:34 [PATCH v6 0/2] Polling for MHI ready Bhaumik Bhatt
  2021-03-31 18:34 ` [PATCH v6 1/2] bus: mhi: core: Introduce internal register poll helper function Bhaumik Bhatt
@ 2021-03-31 18:34 ` Bhaumik Bhatt
  2021-03-31 18:39   ` Manivannan Sadhasivam
  2021-03-31 18:41 ` [PATCH v6 0/2] Polling " Manivannan Sadhasivam
  2021-05-26 19:03 ` patchwork-bot+linux-arm-msm
  3 siblings, 1 reply; 7+ messages in thread
From: Bhaumik Bhatt @ 2021-03-31 18:34 UTC (permalink / raw)
  To: manivannan.sadhasivam
  Cc: linux-arm-msm, hemantk, jhugo, linux-kernel, carl.yin,
	naveen.kumar, loic.poulain, Bhaumik Bhatt

In certain devices, it is likely that there is no incoming MHI
interrupt for a transition to MHI READY state. One such example
is the move from Pass Through to an SBL or AMSS execution
environment. In order to facilitate faster bootup times as there
is no need to wait until timeout_ms completes, MHI host can poll
every 25 milliseconds to check if device has entered MHI READY
until a maximum timeout of twice the timeout_ms is reached.

Signed-off-by: Bhaumik Bhatt <bbhatt@codeaurora.org>
Reviewed-by: Loic Poulain <loic.poulain@linaro.org>
---
 drivers/bus/mhi/core/pm.c | 34 ++++++++++++++++------------------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c
index b6920a5..e4aff77 100644
--- a/drivers/bus/mhi/core/pm.c
+++ b/drivers/bus/mhi/core/pm.c
@@ -153,35 +153,33 @@ static void mhi_toggle_dev_wake(struct mhi_controller *mhi_cntrl)
 /* Handle device ready state transition */
 int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl)
 {
-	void __iomem *base = mhi_cntrl->regs;
 	struct mhi_event *mhi_event;
 	enum mhi_pm_state cur_state;
 	struct device *dev = &mhi_cntrl->mhi_dev->dev;
-	u32 reset = 1, ready = 0;
+	u32 interval_us = 25000; /* poll register field every 25 milliseconds */
 	int ret, i;
 
-	/* Wait for RESET to be cleared and READY bit to be set by the device */
-	wait_event_timeout(mhi_cntrl->state_event,
-			   MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state) ||
-			   mhi_read_reg_field(mhi_cntrl, base, MHICTRL,
-					      MHICTRL_RESET_MASK,
-					      MHICTRL_RESET_SHIFT, &reset) ||
-			   mhi_read_reg_field(mhi_cntrl, base, MHISTATUS,
-					      MHISTATUS_READY_MASK,
-					      MHISTATUS_READY_SHIFT, &ready) ||
-			   (!reset && ready),
-			   msecs_to_jiffies(mhi_cntrl->timeout_ms));
-
 	/* Check if device entered error state */
 	if (MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state)) {
 		dev_err(dev, "Device link is not accessible\n");
 		return -EIO;
 	}
 
-	/* Timeout if device did not transition to ready state */
-	if (reset || !ready) {
-		dev_err(dev, "Device Ready timeout\n");
-		return -ETIMEDOUT;
+	/* Wait for RESET to be cleared and READY bit to be set by the device */
+	ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL,
+				 MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 0,
+				 interval_us);
+	if (ret) {
+		dev_err(dev, "Device failed to clear MHI Reset\n");
+		return ret;
+	}
+
+	ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHISTATUS,
+				 MHISTATUS_READY_MASK, MHISTATUS_READY_SHIFT, 1,
+				 interval_us);
+	if (ret) {
+		dev_err(dev, "Device failed to enter MHI Ready\n");
+		return ret;
 	}
 
 	dev_dbg(dev, "Device in READY State\n");
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v6 1/2] bus: mhi: core: Introduce internal register poll helper function
  2021-03-31 18:34 ` [PATCH v6 1/2] bus: mhi: core: Introduce internal register poll helper function Bhaumik Bhatt
@ 2021-03-31 18:38   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 7+ messages in thread
From: Manivannan Sadhasivam @ 2021-03-31 18:38 UTC (permalink / raw)
  To: Bhaumik Bhatt
  Cc: linux-arm-msm, hemantk, jhugo, linux-kernel, carl.yin,
	naveen.kumar, loic.poulain

On Wed, Mar 31, 2021 at 11:34:24AM -0700, Bhaumik Bhatt wrote:
> Introduce helper function to allow MHI core driver to poll for
> a value in a register field. This helps reach a common path to
> read and poll register values along with a retry time interval.
> 
> Signed-off-by: Bhaumik Bhatt <bbhatt@codeaurora.org>
> Reviewed-by: Loic Poulain <loic.poulain@linaro.org>

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

Thanks,
Mani

> ---
>  drivers/bus/mhi/core/internal.h |  3 +++
>  drivers/bus/mhi/core/main.c     | 23 +++++++++++++++++++++++
>  2 files changed, 26 insertions(+)
> 
> diff --git a/drivers/bus/mhi/core/internal.h b/drivers/bus/mhi/core/internal.h
> index 7aa5cfd..e690f15 100644
> --- a/drivers/bus/mhi/core/internal.h
> +++ b/drivers/bus/mhi/core/internal.h
> @@ -646,6 +646,9 @@ int __must_check mhi_read_reg(struct mhi_controller *mhi_cntrl,
>  int __must_check mhi_read_reg_field(struct mhi_controller *mhi_cntrl,
>  				    void __iomem *base, u32 offset, u32 mask,
>  				    u32 shift, u32 *out);
> +int __must_check mhi_poll_reg_field(struct mhi_controller *mhi_cntrl,
> +				    void __iomem *base, u32 offset, u32 mask,
> +				    u32 shift, u32 val, u32 delayus);
>  void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *base,
>  		   u32 offset, u32 val);
>  void mhi_write_reg_field(struct mhi_controller *mhi_cntrl, void __iomem *base,
> diff --git a/drivers/bus/mhi/core/main.c b/drivers/bus/mhi/core/main.c
> index 8b68657..58b8111 100644
> --- a/drivers/bus/mhi/core/main.c
> +++ b/drivers/bus/mhi/core/main.c
> @@ -4,6 +4,7 @@
>   *
>   */
>  
> +#include <linux/delay.h>
>  #include <linux/device.h>
>  #include <linux/dma-direction.h>
>  #include <linux/dma-mapping.h>
> @@ -37,6 +38,28 @@ int __must_check mhi_read_reg_field(struct mhi_controller *mhi_cntrl,
>  	return 0;
>  }
>  
> +int __must_check mhi_poll_reg_field(struct mhi_controller *mhi_cntrl,
> +				    void __iomem *base, u32 offset,
> +				    u32 mask, u32 shift, u32 val, u32 delayus)
> +{
> +	int ret;
> +	u32 out, retry = (mhi_cntrl->timeout_ms * 1000) / delayus;
> +
> +	while (retry--) {
> +		ret = mhi_read_reg_field(mhi_cntrl, base, offset, mask, shift,
> +					 &out);
> +		if (ret)
> +			return ret;
> +
> +		if (out == val)
> +			return 0;
> +
> +		fsleep(delayus);
> +	}
> +
> +	return -ETIMEDOUT;
> +}
> +
>  void mhi_write_reg(struct mhi_controller *mhi_cntrl, void __iomem *base,
>  		   u32 offset, u32 val)
>  {
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v6 2/2] bus: mhi: core: Move to polling method to wait for MHI ready
  2021-03-31 18:34 ` [PATCH v6 2/2] bus: mhi: core: Move to polling method to wait for MHI ready Bhaumik Bhatt
@ 2021-03-31 18:39   ` Manivannan Sadhasivam
  0 siblings, 0 replies; 7+ messages in thread
From: Manivannan Sadhasivam @ 2021-03-31 18:39 UTC (permalink / raw)
  To: Bhaumik Bhatt
  Cc: linux-arm-msm, hemantk, jhugo, linux-kernel, carl.yin,
	naveen.kumar, loic.poulain

On Wed, Mar 31, 2021 at 11:34:25AM -0700, Bhaumik Bhatt wrote:
> In certain devices, it is likely that there is no incoming MHI
> interrupt for a transition to MHI READY state. One such example
> is the move from Pass Through to an SBL or AMSS execution
> environment. In order to facilitate faster bootup times as there
> is no need to wait until timeout_ms completes, MHI host can poll
> every 25 milliseconds to check if device has entered MHI READY
> until a maximum timeout of twice the timeout_ms is reached.
> 
> Signed-off-by: Bhaumik Bhatt <bbhatt@codeaurora.org>
> Reviewed-by: Loic Poulain <loic.poulain@linaro.org>

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

Thanks,
Mani

> ---
>  drivers/bus/mhi/core/pm.c | 34 ++++++++++++++++------------------
>  1 file changed, 16 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c
> index b6920a5..e4aff77 100644
> --- a/drivers/bus/mhi/core/pm.c
> +++ b/drivers/bus/mhi/core/pm.c
> @@ -153,35 +153,33 @@ static void mhi_toggle_dev_wake(struct mhi_controller *mhi_cntrl)
>  /* Handle device ready state transition */
>  int mhi_ready_state_transition(struct mhi_controller *mhi_cntrl)
>  {
> -	void __iomem *base = mhi_cntrl->regs;
>  	struct mhi_event *mhi_event;
>  	enum mhi_pm_state cur_state;
>  	struct device *dev = &mhi_cntrl->mhi_dev->dev;
> -	u32 reset = 1, ready = 0;
> +	u32 interval_us = 25000; /* poll register field every 25 milliseconds */
>  	int ret, i;
>  
> -	/* Wait for RESET to be cleared and READY bit to be set by the device */
> -	wait_event_timeout(mhi_cntrl->state_event,
> -			   MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state) ||
> -			   mhi_read_reg_field(mhi_cntrl, base, MHICTRL,
> -					      MHICTRL_RESET_MASK,
> -					      MHICTRL_RESET_SHIFT, &reset) ||
> -			   mhi_read_reg_field(mhi_cntrl, base, MHISTATUS,
> -					      MHISTATUS_READY_MASK,
> -					      MHISTATUS_READY_SHIFT, &ready) ||
> -			   (!reset && ready),
> -			   msecs_to_jiffies(mhi_cntrl->timeout_ms));
> -
>  	/* Check if device entered error state */
>  	if (MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state)) {
>  		dev_err(dev, "Device link is not accessible\n");
>  		return -EIO;
>  	}
>  
> -	/* Timeout if device did not transition to ready state */
> -	if (reset || !ready) {
> -		dev_err(dev, "Device Ready timeout\n");
> -		return -ETIMEDOUT;
> +	/* Wait for RESET to be cleared and READY bit to be set by the device */
> +	ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL,
> +				 MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 0,
> +				 interval_us);
> +	if (ret) {
> +		dev_err(dev, "Device failed to clear MHI Reset\n");
> +		return ret;
> +	}
> +
> +	ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHISTATUS,
> +				 MHISTATUS_READY_MASK, MHISTATUS_READY_SHIFT, 1,
> +				 interval_us);
> +	if (ret) {
> +		dev_err(dev, "Device failed to enter MHI Ready\n");
> +		return ret;
>  	}
>  
>  	dev_dbg(dev, "Device in READY State\n");
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v6 0/2] Polling for MHI ready
  2021-03-31 18:34 [PATCH v6 0/2] Polling for MHI ready Bhaumik Bhatt
  2021-03-31 18:34 ` [PATCH v6 1/2] bus: mhi: core: Introduce internal register poll helper function Bhaumik Bhatt
  2021-03-31 18:34 ` [PATCH v6 2/2] bus: mhi: core: Move to polling method to wait for MHI ready Bhaumik Bhatt
@ 2021-03-31 18:41 ` Manivannan Sadhasivam
  2021-05-26 19:03 ` patchwork-bot+linux-arm-msm
  3 siblings, 0 replies; 7+ messages in thread
From: Manivannan Sadhasivam @ 2021-03-31 18:41 UTC (permalink / raw)
  To: Bhaumik Bhatt
  Cc: linux-arm-msm, hemantk, jhugo, linux-kernel, carl.yin,
	naveen.kumar, loic.poulain

On Wed, Mar 31, 2021 at 11:34:23AM -0700, Bhaumik Bhatt wrote:
> v6:
> -Fix return error code for mhi_poll_reg_field()
> -Do not recode when returning from mhi_ready_state_transition() if polling fails
> 
> v5:
> -Use fsleep in place of udelay or usleep_range to accommodate better delay use
> -Drop patch for polling during RDDM panic path as new API cannot be used there
> 
> v4:
> -Added reviewed-by tag
> -Return appropriate error code from mhi_poll_reg_field()
> -Fixed bug where mhi_poll_reg_field() returns success if polling times out
> -Added an interval_us variable in mhi_ready_state_transition()
> 
> v3:
> -Removed config changes that crept in in the first patch
> 
> v2:
> -Addressed review comments
> -Introduce new patch for to use controller defined read_reg() for polling
> -Add usage in RDDM download panic path as well
> 
> Bhaumik Bhatt (2):
>   bus: mhi: core: Introduce internal register poll helper function
>   bus: mhi: core: Move to polling method to wait for MHI ready
> 

Applied to mhi-next!

Thanks,
Mani

>  drivers/bus/mhi/core/internal.h |  3 +++
>  drivers/bus/mhi/core/main.c     | 23 +++++++++++++++++++++++
>  drivers/bus/mhi/core/pm.c       | 34 ++++++++++++++++------------------
>  3 files changed, 42 insertions(+), 18 deletions(-)
> 
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v6 0/2] Polling for MHI ready
  2021-03-31 18:34 [PATCH v6 0/2] Polling for MHI ready Bhaumik Bhatt
                   ` (2 preceding siblings ...)
  2021-03-31 18:41 ` [PATCH v6 0/2] Polling " Manivannan Sadhasivam
@ 2021-05-26 19:03 ` patchwork-bot+linux-arm-msm
  3 siblings, 0 replies; 7+ messages in thread
From: patchwork-bot+linux-arm-msm @ 2021-05-26 19:03 UTC (permalink / raw)
  To: Bhaumik Bhatt; +Cc: linux-arm-msm

Hello:

This series was applied to qcom/linux.git (refs/heads/for-next):

On Wed, 31 Mar 2021 11:34:23 -0700 you wrote:
> v6:
> -Fix return error code for mhi_poll_reg_field()
> -Do not recode when returning from mhi_ready_state_transition() if polling fails
> 
> v5:
> -Use fsleep in place of udelay or usleep_range to accommodate better delay use
> -Drop patch for polling during RDDM panic path as new API cannot be used there
> 
> [...]

Here is the summary with links:
  - [v6,1/2] bus: mhi: core: Introduce internal register poll helper function
    https://git.kernel.org/qcom/c/1a42aef25880
  - [v6,2/2] bus: mhi: core: Move to polling method to wait for MHI ready
    https://git.kernel.org/qcom/c/79d056976485

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2021-05-26 19:04 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-31 18:34 [PATCH v6 0/2] Polling for MHI ready Bhaumik Bhatt
2021-03-31 18:34 ` [PATCH v6 1/2] bus: mhi: core: Introduce internal register poll helper function Bhaumik Bhatt
2021-03-31 18:38   ` Manivannan Sadhasivam
2021-03-31 18:34 ` [PATCH v6 2/2] bus: mhi: core: Move to polling method to wait for MHI ready Bhaumik Bhatt
2021-03-31 18:39   ` Manivannan Sadhasivam
2021-03-31 18:41 ` [PATCH v6 0/2] Polling " Manivannan Sadhasivam
2021-05-26 19:03 ` patchwork-bot+linux-arm-msm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).