diff mbox series

[v5,2/4] soc: samsung: usi: add a routine for unconfiguring the ip

Message ID 20250109090325.595475-3-ivo.ivanov.ivanov1@gmail.com (mailing list archive)
State New
Headers show
Series soc: samsung: usi: implement support for USIv1 | expand

Commit Message

Ivaylo Ivanov Jan. 9, 2025, 9:03 a.m. UTC
Add a devm_add_action_or_reset() routine for unconfiguring the USI IP
block whenever the device gets removed.

Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
---
 drivers/soc/samsung/exynos-usi.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

Comments

Krzysztof Kozlowski Jan. 14, 2025, 5:59 p.m. UTC | #1
On 09/01/2025 10:03, Ivaylo Ivanov wrote:
>  static int exynos_usi_parse_dt(struct device_node *np, struct exynos_usi *usi)
>  {
>  	int ret;
> @@ -251,6 +268,10 @@ static int exynos_usi_probe(struct platform_device *pdev)
>  			return PTR_ERR(usi->regs);
>  	}
>  
> +	ret = devm_add_action_or_reset(&pdev->dev, exynos_usi_unconfigure, usi);
> +	if (ret)
> +		return ret;

You should not reverse the action before the action actually takes place.

> +
>  	ret = exynos_usi_configure(usi);
>  	if (ret)
>  		return ret;

Registering cleanup should therefore happen here.


Best regards,
Krzysztof
Krzysztof Kozlowski Jan. 14, 2025, 6:03 p.m. UTC | #2
On 09/01/2025 10:03, Ivaylo Ivanov wrote:
> +static void exynos_usi_unconfigure(void *data)
> +{
> +	struct exynos_usi *usi = data;
> +	u32 val;
> +
> +	/* Make sure that we've stopped providing the clock to USI IP */
> +	val = readl(usi->regs + USI_OPTION);
> +	val &= ~USI_OPTION_CLKREQ_ON;
> +	val |= ~USI_OPTION_CLKSTOP_ON;
> +	writel(val, usi->regs + USI_OPTION);
> +
> +	/* Set USI block state to reset */
> +	val = readl(usi->regs + USI_CON);
> +	val |= USI_CON_RESET;
> +	writel(val, usi->regs + USI_CON);
Also shouldn't you enable clocks for accessing these? They are being
disabled at the end of exynos_usi_enable().

Best regards,
Krzysztof
Ivaylo Ivanov Jan. 14, 2025, 9:57 p.m. UTC | #3
On 1/14/25 20:03, Krzysztof Kozlowski wrote:
> On 09/01/2025 10:03, Ivaylo Ivanov wrote:
>> +static void exynos_usi_unconfigure(void *data)
>> +{
>> +	struct exynos_usi *usi = data;
>> +	u32 val;
>> +
>> +	/* Make sure that we've stopped providing the clock to USI IP */
>> +	val = readl(usi->regs + USI_OPTION);
>> +	val &= ~USI_OPTION_CLKREQ_ON;
>> +	val |= ~USI_OPTION_CLKSTOP_ON;
>> +	writel(val, usi->regs + USI_OPTION);
>> +
>> +	/* Set USI block state to reset */
>> +	val = readl(usi->regs + USI_CON);
>> +	val |= USI_CON_RESET;
>> +	writel(val, usi->regs + USI_CON);
> Also shouldn't you enable clocks for accessing these? They are being
> disabled at the end of exynos_usi_enable().

Hm, perhaps. But I find that weird, since I haven't seen it in the downstream
driver implementation.

Best regards,
Ivaylo

>
> Best regards,
> Krzysztof
Ivaylo Ivanov Jan. 14, 2025, 9:59 p.m. UTC | #4
On 1/14/25 19:59, Krzysztof Kozlowski wrote:
> On 09/01/2025 10:03, Ivaylo Ivanov wrote:
>>  static int exynos_usi_parse_dt(struct device_node *np, struct exynos_usi *usi)
>>  {
>>  	int ret;
>> @@ -251,6 +268,10 @@ static int exynos_usi_probe(struct platform_device *pdev)
>>  			return PTR_ERR(usi->regs);
>>  	}
>>  
>> +	ret = devm_add_action_or_reset(&pdev->dev, exynos_usi_unconfigure, usi);
>> +	if (ret)
>> +		return ret;
> You should not reverse the action before the action actually takes place.
>
>> +
>>  	ret = exynos_usi_configure(usi);
>>  	if (ret)
>>  		return ret;
> Registering cleanup should therefore happen here.

Alright, will fix. I'll try to submit the next (and hopefully final, if that's
all the critique you have) version in the following days, but I'm currently
focused on working on exynos2200.

Best regards,
Ivaylo

>
>
> Best regards,
> Krzysztof
Krzysztof Kozlowski Jan. 15, 2025, 8:24 a.m. UTC | #5
On 14/01/2025 22:57, Ivaylo Ivanov wrote:
> On 1/14/25 20:03, Krzysztof Kozlowski wrote:
>> On 09/01/2025 10:03, Ivaylo Ivanov wrote:
>>> +static void exynos_usi_unconfigure(void *data)
>>> +{
>>> +	struct exynos_usi *usi = data;
>>> +	u32 val;
>>> +
>>> +	/* Make sure that we've stopped providing the clock to USI IP */
>>> +	val = readl(usi->regs + USI_OPTION);
>>> +	val &= ~USI_OPTION_CLKREQ_ON;
>>> +	val |= ~USI_OPTION_CLKSTOP_ON;
>>> +	writel(val, usi->regs + USI_OPTION);
>>> +
>>> +	/* Set USI block state to reset */
>>> +	val = readl(usi->regs + USI_CON);
>>> +	val |= USI_CON_RESET;
>>> +	writel(val, usi->regs + USI_CON);
>> Also shouldn't you enable clocks for accessing these? They are being
>> disabled at the end of exynos_usi_enable().
> 
> Hm, perhaps. But I find that weird, since I haven't seen it in the downstream
> driver implementation.

So the downstream enables clocks when configured usi, but never when
unconfiguring? I could believe that no one cared about remove/error
paths, thus never tested.

Best regards,
Krzysztof
Krzysztof Kozlowski Jan. 15, 2025, 8:25 a.m. UTC | #6
On 14/01/2025 22:59, Ivaylo Ivanov wrote:
> On 1/14/25 19:59, Krzysztof Kozlowski wrote:
>> On 09/01/2025 10:03, Ivaylo Ivanov wrote:
>>>  static int exynos_usi_parse_dt(struct device_node *np, struct exynos_usi *usi)
>>>  {
>>>  	int ret;
>>> @@ -251,6 +268,10 @@ static int exynos_usi_probe(struct platform_device *pdev)
>>>  			return PTR_ERR(usi->regs);
>>>  	}
>>>  
>>> +	ret = devm_add_action_or_reset(&pdev->dev, exynos_usi_unconfigure, usi);
>>> +	if (ret)
>>> +		return ret;
>> You should not reverse the action before the action actually takes place.
>>
>>> +
>>>  	ret = exynos_usi_configure(usi);
>>>  	if (ret)
>>>  		return ret;
>> Registering cleanup should therefore happen here.
> 
> Alright, will fix. I'll try to submit the next (and hopefully final, if that's
> all the critique you have) version in the following days, but I'm currently
> focused on working on exynos2200.

Yeah, rest looks good. Anyway it is too late for this cycle, so I will
pick this (and everything else not picked up) after the merge window.

Best regards,
Krzysztof
diff mbox series

Patch

diff --git a/drivers/soc/samsung/exynos-usi.c b/drivers/soc/samsung/exynos-usi.c
index 114352695..4b84f481b 100644
--- a/drivers/soc/samsung/exynos-usi.c
+++ b/drivers/soc/samsung/exynos-usi.c
@@ -174,6 +174,23 @@  static int exynos_usi_configure(struct exynos_usi *usi)
 	return 0;
 }
 
+static void exynos_usi_unconfigure(void *data)
+{
+	struct exynos_usi *usi = data;
+	u32 val;
+
+	/* Make sure that we've stopped providing the clock to USI IP */
+	val = readl(usi->regs + USI_OPTION);
+	val &= ~USI_OPTION_CLKREQ_ON;
+	val |= ~USI_OPTION_CLKSTOP_ON;
+	writel(val, usi->regs + USI_OPTION);
+
+	/* Set USI block state to reset */
+	val = readl(usi->regs + USI_CON);
+	val |= USI_CON_RESET;
+	writel(val, usi->regs + USI_CON);
+}
+
 static int exynos_usi_parse_dt(struct device_node *np, struct exynos_usi *usi)
 {
 	int ret;
@@ -251,6 +268,10 @@  static int exynos_usi_probe(struct platform_device *pdev)
 			return PTR_ERR(usi->regs);
 	}
 
+	ret = devm_add_action_or_reset(&pdev->dev, exynos_usi_unconfigure, usi);
+	if (ret)
+		return ret;
+
 	ret = exynos_usi_configure(usi);
 	if (ret)
 		return ret;