[PATCHv2,03/11] soc: ti: omap-prm: poll for reset complete during de-assert
diff mbox series

Message ID 20190828071941.32378-4-t-kristo@ti.com
State New
Headers show
Series
  • soc: ti: add OMAP PRM driver (for reset)
Related show

Commit Message

Tero Kristo Aug. 28, 2019, 7:19 a.m. UTC
Poll for reset completion status during de-assertion of reset, otherwise
the IP in question might be accessed before it has left reset properly.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 drivers/soc/ti/omap_prm.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

Comments

Philipp Zabel Aug. 29, 2019, 1:14 p.m. UTC | #1
Hi Tero,

On Wed, 2019-08-28 at 10:19 +0300, Tero Kristo wrote:
> Poll for reset completion status during de-assertion of reset, otherwise
> the IP in question might be accessed before it has left reset properly.
> 
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> ---
>  drivers/soc/ti/omap_prm.c | 20 ++++++++++++++++++++
>  1 file changed, 20 insertions(+)
> 
> diff --git a/drivers/soc/ti/omap_prm.c b/drivers/soc/ti/omap_prm.c
> index fd5c431f8736..afeb70761b27 100644
> --- a/drivers/soc/ti/omap_prm.c
> +++ b/drivers/soc/ti/omap_prm.c
> @@ -127,6 +127,7 @@ static int omap_reset_deassert(struct reset_controller_dev *rcdev,
>  	u32 v;
>  	int st_bit;
>  	bool has_rstst;
> +	int timeout = 0;
>  
>  	if (!_is_valid_reset(reset, id))
>  		return -EINVAL;
> @@ -153,6 +154,25 @@ static int omap_reset_deassert(struct reset_controller_dev *rcdev,
>  	v &= ~(1 << id);
>  	writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl);
>  
> +	if (!has_rstst)
> +		return 0;
> +
> +	/* wait for the status to be set */
> +	while (1) {
> +		v = readl_relaxed(reset->prm->base + reset->prm->data->rstst);
> +		v &= 1 << st_bit;
> +		if (v)
> +			break;
> +		timeout++;
> +		if (timeout > OMAP_RESET_MAX_WAIT) {
> +			pr_err("%s: timedout waiting for %s:%lu\n", __func__,
> +			       dev_name(rcdev->dev), id);
> +			return -EBUSY;
> +		}
> +
> +		udelay(1);
> +	}

This looks like you could use

	readl_relaxed_poll_timeout(_atomic)

regards
Philipp
Tero Kristo Aug. 30, 2019, 9:07 a.m. UTC | #2
On 29/08/2019 16:14, Philipp Zabel wrote:
> Hi Tero,
> 
> On Wed, 2019-08-28 at 10:19 +0300, Tero Kristo wrote:
>> Poll for reset completion status during de-assertion of reset, otherwise
>> the IP in question might be accessed before it has left reset properly.
>>
>> Signed-off-by: Tero Kristo <t-kristo@ti.com>
>> ---
>>   drivers/soc/ti/omap_prm.c | 20 ++++++++++++++++++++
>>   1 file changed, 20 insertions(+)
>>
>> diff --git a/drivers/soc/ti/omap_prm.c b/drivers/soc/ti/omap_prm.c
>> index fd5c431f8736..afeb70761b27 100644
>> --- a/drivers/soc/ti/omap_prm.c
>> +++ b/drivers/soc/ti/omap_prm.c
>> @@ -127,6 +127,7 @@ static int omap_reset_deassert(struct reset_controller_dev *rcdev,
>>   	u32 v;
>>   	int st_bit;
>>   	bool has_rstst;
>> +	int timeout = 0;
>>   
>>   	if (!_is_valid_reset(reset, id))
>>   		return -EINVAL;
>> @@ -153,6 +154,25 @@ static int omap_reset_deassert(struct reset_controller_dev *rcdev,
>>   	v &= ~(1 << id);
>>   	writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl);
>>   
>> +	if (!has_rstst)
>> +		return 0;
>> +
>> +	/* wait for the status to be set */
>> +	while (1) {
>> +		v = readl_relaxed(reset->prm->base + reset->prm->data->rstst);
>> +		v &= 1 << st_bit;
>> +		if (v)
>> +			break;
>> +		timeout++;
>> +		if (timeout > OMAP_RESET_MAX_WAIT) {
>> +			pr_err("%s: timedout waiting for %s:%lu\n", __func__,
>> +			       dev_name(rcdev->dev), id);
>> +			return -EBUSY;
>> +		}
>> +
>> +		udelay(1);
>> +	}
> 
> This looks like you could use
> 
> 	readl_relaxed_poll_timeout(_atomic)

Yeah true, let me change that.

-Tero
--
Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki

Patch
diff mbox series

diff --git a/drivers/soc/ti/omap_prm.c b/drivers/soc/ti/omap_prm.c
index fd5c431f8736..afeb70761b27 100644
--- a/drivers/soc/ti/omap_prm.c
+++ b/drivers/soc/ti/omap_prm.c
@@ -127,6 +127,7 @@  static int omap_reset_deassert(struct reset_controller_dev *rcdev,
 	u32 v;
 	int st_bit;
 	bool has_rstst;
+	int timeout = 0;
 
 	if (!_is_valid_reset(reset, id))
 		return -EINVAL;
@@ -153,6 +154,25 @@  static int omap_reset_deassert(struct reset_controller_dev *rcdev,
 	v &= ~(1 << id);
 	writel_relaxed(v, reset->prm->base + reset->prm->data->rstctrl);
 
+	if (!has_rstst)
+		return 0;
+
+	/* wait for the status to be set */
+	while (1) {
+		v = readl_relaxed(reset->prm->base + reset->prm->data->rstst);
+		v &= 1 << st_bit;
+		if (v)
+			break;
+		timeout++;
+		if (timeout > OMAP_RESET_MAX_WAIT) {
+			pr_err("%s: timedout waiting for %s:%lu\n", __func__,
+			       dev_name(rcdev->dev), id);
+			return -EBUSY;
+		}
+
+		udelay(1);
+	}
+
 	return 0;
 }