linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V1] i2c: busses: tegra: Add suspend-resume support
@ 2019-05-30  5:55 Bitan Biswas
  2019-05-30 11:27 ` Dmitry Osipenko
  0 siblings, 1 reply; 7+ messages in thread
From: Bitan Biswas @ 2019-05-30  5:55 UTC (permalink / raw)
  To: Laxman Dewangan, Thierry Reding, Jonathan Hunter, linux-i2c,
	linux-tegra, linux-kernel
  Cc: Shardar Mohammed, Sowjanya Komatineni, Mantravadi Karthik, Bitan Biswas

Post suspend I2C registers have power on reset values. Before any
transfer initialize I2C registers to prevent I2C transfer timeout
and implement suspend and resume callbacks needed. Fix below errors
post suspend:

1) Tegra I2C transfer timeout during jetson tx2 resume:

[   27.520613] pca953x 1-0074: calling pca953x_resume+0x0/0x1b0 @ 2939, parent: i2c-1
[   27.633623] tegra-i2c 3160000.i2c: i2c transfer timed out
[   27.639162] pca953x 1-0074: Unable to sync registers 0x3-0x5. -110
[   27.645336] pca953x 1-0074: Failed to sync GPIO dir registers: -110
[   27.651596] PM: dpm_run_callback(): pca953x_resume+0x0/0x1b0 returns -110
[   27.658375] pca953x 1-0074: pca953x_resume+0x0/0x1b0 returned -110 after 127152 usecs
[   27.666194] PM: Device 1-0074 failed to resume: error -110

2) Tegra I2C transfer timeout error on jetson Xavier post resume.

Signed-off-by: Bitan Biswas <bbiswas@nvidia.com>
---
 drivers/i2c/busses/i2c-tegra.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index ebaa78d..f6a377f 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -1687,9 +1687,33 @@ static int tegra_i2c_remove(struct platform_device *pdev)
 }
 
 #ifdef CONFIG_PM_SLEEP
+static int tegra_i2c_suspend(struct device *dev)
+{
+	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
+
+	i2c_mark_adapter_suspended(&i2c_dev->adapter);
+
+	return 0;
+}
+
+static int tegra_i2c_resume(struct device *dev)
+{
+	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
+	int ret;
+
+	i2c_lock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
+	ret = tegra_i2c_init(i2c_dev, false);
+	i2c_unlock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
+	if (!ret)
+		i2c_mark_adapter_resumed(&i2c_dev->adapter);
+
+       return ret;
+}
+
 static const struct dev_pm_ops tegra_i2c_pm = {
 	SET_RUNTIME_PM_OPS(tegra_i2c_runtime_suspend, tegra_i2c_runtime_resume,
 			   NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(tegra_i2c_suspend, tegra_i2c_resume)
 };
 #define TEGRA_I2C_PM	(&tegra_i2c_pm)
 #else
-- 
2.7.4


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

* Re: [PATCH V1] i2c: busses: tegra: Add suspend-resume support
  2019-05-30  5:55 [PATCH V1] i2c: busses: tegra: Add suspend-resume support Bitan Biswas
@ 2019-05-30 11:27 ` Dmitry Osipenko
  2019-05-31  8:50   ` Bitan Biswas
  0 siblings, 1 reply; 7+ messages in thread
From: Dmitry Osipenko @ 2019-05-30 11:27 UTC (permalink / raw)
  To: Bitan Biswas, Laxman Dewangan, Thierry Reding, Jonathan Hunter,
	linux-i2c, linux-tegra, linux-kernel
  Cc: Shardar Mohammed, Sowjanya Komatineni, Mantravadi Karthik

30.05.2019 8:55, Bitan Biswas пишет:
> Post suspend I2C registers have power on reset values. Before any
> transfer initialize I2C registers to prevent I2C transfer timeout
> and implement suspend and resume callbacks needed. Fix below errors
> post suspend:
> 
> 1) Tegra I2C transfer timeout during jetson tx2 resume:
> 
> [   27.520613] pca953x 1-0074: calling pca953x_resume+0x0/0x1b0 @ 2939, parent: i2c-1
> [   27.633623] tegra-i2c 3160000.i2c: i2c transfer timed out
> [   27.639162] pca953x 1-0074: Unable to sync registers 0x3-0x5. -110
> [   27.645336] pca953x 1-0074: Failed to sync GPIO dir registers: -110
> [   27.651596] PM: dpm_run_callback(): pca953x_resume+0x0/0x1b0 returns -110
> [   27.658375] pca953x 1-0074: pca953x_resume+0x0/0x1b0 returned -110 after 127152 usecs
> [   27.666194] PM: Device 1-0074 failed to resume: error -110
> 
> 2) Tegra I2C transfer timeout error on jetson Xavier post resume.
> 
> Signed-off-by: Bitan Biswas <bbiswas@nvidia.com>
> ---
>  drivers/i2c/busses/i2c-tegra.c | 24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
> index ebaa78d..f6a377f 100644
> --- a/drivers/i2c/busses/i2c-tegra.c
> +++ b/drivers/i2c/busses/i2c-tegra.c
> @@ -1687,9 +1687,33 @@ static int tegra_i2c_remove(struct platform_device *pdev)
>  }
>  
>  #ifdef CONFIG_PM_SLEEP
> +static int tegra_i2c_suspend(struct device *dev)
> +{
> +	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
> +
> +	i2c_mark_adapter_suspended(&i2c_dev->adapter);
> +
> +	return 0;
> +}
> +
> +static int tegra_i2c_resume(struct device *dev)
> +{
> +	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
> +	int ret;
> +
> +	i2c_lock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
> +	ret = tegra_i2c_init(i2c_dev, false);
> +	i2c_unlock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);

Why the locking is needed here?

> +	if (!ret)
> +		i2c_mark_adapter_resumed(&i2c_dev->adapter);
> +
> +       return ret;

A very minor nit.. will be a bit more straightforward to write this as:

	int err;

	err = tegra_i2c_init(i2c_dev, false);
	if (err)
		return err;

	i2c_mark_adapter_resumed(&i2c_dev->adapter);

	return 0;

It is always cleaner to return 0 on success.

--
Dmitry

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

* Re: [PATCH V1] i2c: busses: tegra: Add suspend-resume support
  2019-05-30 11:27 ` Dmitry Osipenko
@ 2019-05-31  8:50   ` Bitan Biswas
  2019-05-31 12:43     ` Dmitry Osipenko
  0 siblings, 1 reply; 7+ messages in thread
From: Bitan Biswas @ 2019-05-31  8:50 UTC (permalink / raw)
  To: Dmitry Osipenko, Laxman Dewangan, Thierry Reding,
	Jonathan Hunter, linux-i2c, linux-tegra, linux-kernel
  Cc: Shardar Mohammed, Sowjanya Komatineni, Mantravadi Karthik



On 5/30/19 4:27 AM, Dmitry Osipenko wrote:
> 30.05.2019 8:55, Bitan Biswas пишет:
>> Post suspend I2C registers have power on reset values. Before any
>> transfer initialize I2C registers to prevent I2C transfer timeout
>> and implement suspend and resume callbacks needed. Fix below errors
>> post suspend:
>>
>> 1) Tegra I2C transfer timeout during jetson tx2 resume:
>>
>> [   27.520613] pca953x 1-0074: calling pca953x_resume+0x0/0x1b0 @ 2939, parent: i2c-1
>> [   27.633623] tegra-i2c 3160000.i2c: i2c transfer timed out
>> [   27.639162] pca953x 1-0074: Unable to sync registers 0x3-0x5. -110
>> [   27.645336] pca953x 1-0074: Failed to sync GPIO dir registers: -110
>> [   27.651596] PM: dpm_run_callback(): pca953x_resume+0x0/0x1b0 returns -110
>> [   27.658375] pca953x 1-0074: pca953x_resume+0x0/0x1b0 returned -110 after 127152 usecs
>> [   27.666194] PM: Device 1-0074 failed to resume: error -110
>>
>> 2) Tegra I2C transfer timeout error on jetson Xavier post resume.
>>
>> Signed-off-by: Bitan Biswas <bbiswas@nvidia.com>
>> ---
>>   drivers/i2c/busses/i2c-tegra.c | 24 ++++++++++++++++++++++++
>>   1 file changed, 24 insertions(+)
>>
>> diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
>> index ebaa78d..f6a377f 100644
>> --- a/drivers/i2c/busses/i2c-tegra.c
>> +++ b/drivers/i2c/busses/i2c-tegra.c
>> @@ -1687,9 +1687,33 @@ static int tegra_i2c_remove(struct platform_device *pdev)
>>   }
>>   
>>   #ifdef CONFIG_PM_SLEEP
>> +static int tegra_i2c_suspend(struct device *dev)
>> +{
>> +	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
>> +
>> +	i2c_mark_adapter_suspended(&i2c_dev->adapter);
>> +
>> +	return 0;
>> +}
>> +
>> +static int tegra_i2c_resume(struct device *dev)
>> +{
>> +	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
>> +	int ret;
>> +
>> +	i2c_lock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
>> +	ret = tegra_i2c_init(i2c_dev, false);
>> +	i2c_unlock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
> 
> Why the locking is needed here?

async resume could result in stress test issues if some client accesses 
the i2c instance. This ensures the i2c instance is locked till the 
initialization is complete.

> 
>> +	if (!ret)
>> +		i2c_mark_adapter_resumed(&i2c_dev->adapter);
>> +
>> +       return ret;
> 
> A very minor nit.. will be a bit more straightforward to write this as:
> 
> 	int err;
> 
> 	err = tegra_i2c_init(i2c_dev, false);
> 	if (err)
> 		return err;
> 
> 	i2c_mark_adapter_resumed(&i2c_dev->adapter);
> 
> 	return 0;
> 
> It is always cleaner to return 0 on success.
Thanks. I shall update the section in patch as per this suggestion.

-regards,
  Bitan


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

* Re: [PATCH V1] i2c: busses: tegra: Add suspend-resume support
  2019-05-31  8:50   ` Bitan Biswas
@ 2019-05-31 12:43     ` Dmitry Osipenko
  2019-06-06  5:43       ` Bitan Biswas
  0 siblings, 1 reply; 7+ messages in thread
From: Dmitry Osipenko @ 2019-05-31 12:43 UTC (permalink / raw)
  To: Bitan Biswas, Laxman Dewangan, Thierry Reding, Jonathan Hunter,
	linux-i2c, linux-tegra, linux-kernel
  Cc: Shardar Mohammed, Sowjanya Komatineni, Mantravadi Karthik

31.05.2019 11:50, Bitan Biswas пишет:
> 
> 
> On 5/30/19 4:27 AM, Dmitry Osipenko wrote:
>> 30.05.2019 8:55, Bitan Biswas пишет:
>>> Post suspend I2C registers have power on reset values. Before any
>>> transfer initialize I2C registers to prevent I2C transfer timeout
>>> and implement suspend and resume callbacks needed. Fix below errors
>>> post suspend:
>>>
>>> 1) Tegra I2C transfer timeout during jetson tx2 resume:
>>>
>>> [   27.520613] pca953x 1-0074: calling pca953x_resume+0x0/0x1b0 @
>>> 2939, parent: i2c-1
>>> [   27.633623] tegra-i2c 3160000.i2c: i2c transfer timed out
>>> [   27.639162] pca953x 1-0074: Unable to sync registers 0x3-0x5. -110
>>> [   27.645336] pca953x 1-0074: Failed to sync GPIO dir registers: -110
>>> [   27.651596] PM: dpm_run_callback(): pca953x_resume+0x0/0x1b0
>>> returns -110
>>> [   27.658375] pca953x 1-0074: pca953x_resume+0x0/0x1b0 returned -110
>>> after 127152 usecs
>>> [   27.666194] PM: Device 1-0074 failed to resume: error -110
>>>
>>> 2) Tegra I2C transfer timeout error on jetson Xavier post resume.
>>>
>>> Signed-off-by: Bitan Biswas <bbiswas@nvidia.com>
>>> ---
>>>   drivers/i2c/busses/i2c-tegra.c | 24 ++++++++++++++++++++++++
>>>   1 file changed, 24 insertions(+)
>>>
>>> diff --git a/drivers/i2c/busses/i2c-tegra.c
>>> b/drivers/i2c/busses/i2c-tegra.c
>>> index ebaa78d..f6a377f 100644
>>> --- a/drivers/i2c/busses/i2c-tegra.c
>>> +++ b/drivers/i2c/busses/i2c-tegra.c
>>> @@ -1687,9 +1687,33 @@ static int tegra_i2c_remove(struct
>>> platform_device *pdev)
>>>   }
>>>     #ifdef CONFIG_PM_SLEEP
>>> +static int tegra_i2c_suspend(struct device *dev)
>>> +{
>>> +    struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
>>> +
>>> +    i2c_mark_adapter_suspended(&i2c_dev->adapter);
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static int tegra_i2c_resume(struct device *dev)
>>> +{
>>> +    struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
>>> +    int ret;
>>> +
>>> +    i2c_lock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
>>> +    ret = tegra_i2c_init(i2c_dev, false);
>>> +    i2c_unlock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
>>
>> Why the locking is needed here?
> 
> async resume could result in stress test issues if some client accesses
> the i2c instance. This ensures the i2c instance is locked till the
> initialization is complete.

1) This doesn't make much sense.. if client could access I2C during of
tegra_i2c_init execution, then what stops it to perform the access
before the lock is taken?

2) The whole point of the i2c_mark_adapter_* API is to catch those
faulty clients that have a broken suspend-resume sequence. Client will
get a -ESHUTDOWN on trying to issue I2C transfer while controller is
marked as suspended.

3) Please don't use async suspend-resume where it doesn't make sense.

Corollary: you should drop the locking because it doesn't do anything
useful.

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

* Re: [PATCH V1] i2c: busses: tegra: Add suspend-resume support
  2019-05-31 12:43     ` Dmitry Osipenko
@ 2019-06-06  5:43       ` Bitan Biswas
  2019-06-06 11:52         ` Dmitry Osipenko
  0 siblings, 1 reply; 7+ messages in thread
From: Bitan Biswas @ 2019-06-06  5:43 UTC (permalink / raw)
  To: Dmitry Osipenko, Laxman Dewangan, Thierry Reding,
	Jonathan Hunter, linux-i2c, linux-tegra, linux-kernel
  Cc: Shardar Mohammed, Sowjanya Komatineni, Mantravadi Karthik



On 5/31/19 5:43 AM, Dmitry Osipenko wrote:
> 31.05.2019 11:50, Bitan Biswas пишет:
>>
>>
>> On 5/30/19 4:27 AM, Dmitry Osipenko wrote:
>>> 30.05.2019 8:55, Bitan Biswas пишет:
>>>> Post suspend I2C registers have power on reset values. Before any
>>>> transfer initialize I2C registers to prevent I2C transfer timeout
>>>> and implement suspend and resume callbacks needed. Fix below errors
>>>> post suspend:
>>>>
>>>> 1) Tegra I2C transfer timeout during jetson tx2 resume:
>>>>
>>>> [   27.520613] pca953x 1-0074: calling pca953x_resume+0x0/0x1b0 @
>>>> 2939, parent: i2c-1
>>>> [   27.633623] tegra-i2c 3160000.i2c: i2c transfer timed out
>>>> [   27.639162] pca953x 1-0074: Unable to sync registers 0x3-0x5. -110
>>>> [   27.645336] pca953x 1-0074: Failed to sync GPIO dir registers: -110
>>>> [   27.651596] PM: dpm_run_callback(): pca953x_resume+0x0/0x1b0
>>>> returns -110
>>>> [   27.658375] pca953x 1-0074: pca953x_resume+0x0/0x1b0 returned -110
>>>> after 127152 usecs
>>>> [   27.666194] PM: Device 1-0074 failed to resume: error -110
>>>>
>>>> 2) Tegra I2C transfer timeout error on jetson Xavier post resume.
>>>>
>>>> Signed-off-by: Bitan Biswas <bbiswas@nvidia.com>
>>>> ---
>>>>    drivers/i2c/busses/i2c-tegra.c | 24 ++++++++++++++++++++++++
>>>>    1 file changed, 24 insertions(+)
>>>>
>>>> diff --git a/drivers/i2c/busses/i2c-tegra.c
>>>> b/drivers/i2c/busses/i2c-tegra.c
>>>> index ebaa78d..f6a377f 100644
>>>> --- a/drivers/i2c/busses/i2c-tegra.c
>>>> +++ b/drivers/i2c/busses/i2c-tegra.c
>>>> @@ -1687,9 +1687,33 @@ static int tegra_i2c_remove(struct
>>>> platform_device *pdev)
>>>>    }
>>>>      #ifdef CONFIG_PM_SLEEP
>>>> +static int tegra_i2c_suspend(struct device *dev)
>>>> +{
>>>> +    struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
>>>> +
>>>> +    i2c_mark_adapter_suspended(&i2c_dev->adapter);
>>>> +
>>>> +    return 0;
>>>> +}
>>>> +
>>>> +static int tegra_i2c_resume(struct device *dev)
>>>> +{
>>>> +    struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
>>>> +    int ret;
>>>> +
>>>> +    i2c_lock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
>>>> +    ret = tegra_i2c_init(i2c_dev, false);
>>>> +    i2c_unlock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
>>>
>>> Why the locking is needed here?
>>
>> async resume could result in stress test issues if some client accesses
>> the i2c instance. This ensures the i2c instance is locked till the
>> initialization is complete.
> 
> 1) This doesn't make much sense.. if client could access I2C during of
> tegra_i2c_init execution, then what stops it to perform the access
> before the lock is taken?
Client resumes will start after I2C instance resume because of driver 
dependency. Since lock is the first call in i2c-tegra I believe I2C 
calls of client will not start.

> 
> 2) The whole point of the i2c_mark_adapter_* API is to catch those
> faulty clients that have a broken suspend-resume sequence. Client will
> get a -ESHUTDOWN on trying to issue I2C transfer while controller is
> marked as suspended.
i2c lock bus calls were used in the resume callback implementation that 
was reverted few months back. Hence, these were added in this patch 
which should be more like a revert-of-revert .

But I feel probably your point also makes sense. Old resume callback did 
not have i2c_mark_adapter_* calls. Based on the i2c_adapter_mark_* API 
documentation it should be taking care that core i2c calls from client 
are not started. I plan to update the patch and remove the lock-unlock 
guards in resume callback.


> 
> 3) Please don't use async suspend-resume where it doesn't make sense.
This is a system wide setting. /sys/power/pm_async by default is 1 and 
there is no driver specific change in this patch to choose async 
suspend-resume.

> 
> Corollary: you should drop the locking because it doesn't do anything
> useful.
> 
I did some basic suspend resume tests and do not see any problems 
removing the i2c_lock_bus call you pointed out.

-Thanks,
  Bitan


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

* Re: [PATCH V1] i2c: busses: tegra: Add suspend-resume support
  2019-06-06  5:43       ` Bitan Biswas
@ 2019-06-06 11:52         ` Dmitry Osipenko
  2019-06-06 13:55           ` Bitan Biswas
  0 siblings, 1 reply; 7+ messages in thread
From: Dmitry Osipenko @ 2019-06-06 11:52 UTC (permalink / raw)
  To: Bitan Biswas, Laxman Dewangan, Thierry Reding, Jonathan Hunter,
	linux-i2c, linux-tegra, linux-kernel
  Cc: Shardar Mohammed, Sowjanya Komatineni, Mantravadi Karthik

06.06.2019 8:43, Bitan Biswas пишет:
> 
> 
> On 5/31/19 5:43 AM, Dmitry Osipenko wrote:
>> 31.05.2019 11:50, Bitan Biswas пишет:
>>>
>>>
>>> On 5/30/19 4:27 AM, Dmitry Osipenko wrote:
>>>> 30.05.2019 8:55, Bitan Biswas пишет:
>>>>> Post suspend I2C registers have power on reset values. Before any
>>>>> transfer initialize I2C registers to prevent I2C transfer timeout
>>>>> and implement suspend and resume callbacks needed. Fix below errors
>>>>> post suspend:
>>>>>
>>>>> 1) Tegra I2C transfer timeout during jetson tx2 resume:
>>>>>
>>>>> [   27.520613] pca953x 1-0074: calling pca953x_resume+0x0/0x1b0 @
>>>>> 2939, parent: i2c-1
>>>>> [   27.633623] tegra-i2c 3160000.i2c: i2c transfer timed out
>>>>> [   27.639162] pca953x 1-0074: Unable to sync registers 0x3-0x5. -110
>>>>> [   27.645336] pca953x 1-0074: Failed to sync GPIO dir registers: -110
>>>>> [   27.651596] PM: dpm_run_callback(): pca953x_resume+0x0/0x1b0
>>>>> returns -110
>>>>> [   27.658375] pca953x 1-0074: pca953x_resume+0x0/0x1b0 returned -110
>>>>> after 127152 usecs
>>>>> [   27.666194] PM: Device 1-0074 failed to resume: error -110
>>>>>
>>>>> 2) Tegra I2C transfer timeout error on jetson Xavier post resume.
>>>>>
>>>>> Signed-off-by: Bitan Biswas <bbiswas@nvidia.com>
>>>>> ---
>>>>>    drivers/i2c/busses/i2c-tegra.c | 24 ++++++++++++++++++++++++
>>>>>    1 file changed, 24 insertions(+)
>>>>>
>>>>> diff --git a/drivers/i2c/busses/i2c-tegra.c
>>>>> b/drivers/i2c/busses/i2c-tegra.c
>>>>> index ebaa78d..f6a377f 100644
>>>>> --- a/drivers/i2c/busses/i2c-tegra.c
>>>>> +++ b/drivers/i2c/busses/i2c-tegra.c
>>>>> @@ -1687,9 +1687,33 @@ static int tegra_i2c_remove(struct
>>>>> platform_device *pdev)
>>>>>    }
>>>>>      #ifdef CONFIG_PM_SLEEP
>>>>> +static int tegra_i2c_suspend(struct device *dev)
>>>>> +{
>>>>> +    struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
>>>>> +
>>>>> +    i2c_mark_adapter_suspended(&i2c_dev->adapter);
>>>>> +
>>>>> +    return 0;
>>>>> +}
>>>>> +
>>>>> +static int tegra_i2c_resume(struct device *dev)
>>>>> +{
>>>>> +    struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
>>>>> +    int ret;
>>>>> +
>>>>> +    i2c_lock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
>>>>> +    ret = tegra_i2c_init(i2c_dev, false);
>>>>> +    i2c_unlock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
>>>>
>>>> Why the locking is needed here?
>>>
>>> async resume could result in stress test issues if some client accesses
>>> the i2c instance. This ensures the i2c instance is locked till the
>>> initialization is complete.
>>
>> 1) This doesn't make much sense.. if client could access I2C during of
>> tegra_i2c_init execution, then what stops it to perform the access
>> before the lock is taken?
> Client resumes will start after I2C instance resume because of driver
> dependency. Since lock is the first call in i2c-tegra I believe I2C
> calls of client will not start.

You're incorrectly assuming that client can start resuming in the middle
of the controller's resume process. I2C client's resume won't start
until tegra_i2c_resume() is finished completely. That is because child
drivers are resumed only after theirs parent is ready and this is
guaranteed by the drivers core.

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

* Re: [PATCH V1] i2c: busses: tegra: Add suspend-resume support
  2019-06-06 11:52         ` Dmitry Osipenko
@ 2019-06-06 13:55           ` Bitan Biswas
  0 siblings, 0 replies; 7+ messages in thread
From: Bitan Biswas @ 2019-06-06 13:55 UTC (permalink / raw)
  To: Dmitry Osipenko, Laxman Dewangan, Thierry Reding,
	Jonathan Hunter, linux-i2c, linux-tegra, linux-kernel
  Cc: Shardar Mohammed, Sowjanya Komatineni, Mantravadi Karthik



On 6/6/19 4:52 AM, Dmitry Osipenko wrote:
> 06.06.2019 8:43, Bitan Biswas пишет:
>>
>>
>> On 5/31/19 5:43 AM, Dmitry Osipenko wrote:
>>> 31.05.2019 11:50, Bitan Biswas пишет:
>>>>
>>>>
>>>> On 5/30/19 4:27 AM, Dmitry Osipenko wrote:
>>>>> 30.05.2019 8:55, Bitan Biswas пишет:
>>>>>> Post suspend I2C registers have power on reset values. Before any
>>>>>> transfer initialize I2C registers to prevent I2C transfer timeout
>>>>>> and implement suspend and resume callbacks needed. Fix below errors
>>>>>> post suspend:
>>>>>>
>>>>>> 1) Tegra I2C transfer timeout during jetson tx2 resume:
>>>>>>
>>>>>> [   27.520613] pca953x 1-0074: calling pca953x_resume+0x0/0x1b0 @
>>>>>> 2939, parent: i2c-1
>>>>>> [   27.633623] tegra-i2c 3160000.i2c: i2c transfer timed out
>>>>>> [   27.639162] pca953x 1-0074: Unable to sync registers 0x3-0x5. -110
>>>>>> [   27.645336] pca953x 1-0074: Failed to sync GPIO dir registers: -110
>>>>>> [   27.651596] PM: dpm_run_callback(): pca953x_resume+0x0/0x1b0
>>>>>> returns -110
>>>>>> [   27.658375] pca953x 1-0074: pca953x_resume+0x0/0x1b0 returned -110
>>>>>> after 127152 usecs
>>>>>> [   27.666194] PM: Device 1-0074 failed to resume: error -110
>>>>>>
>>>>>> 2) Tegra I2C transfer timeout error on jetson Xavier post resume.
>>>>>>
>>>>>> Signed-off-by: Bitan Biswas <bbiswas@nvidia.com>
>>>>>> ---
>>>>>>     drivers/i2c/busses/i2c-tegra.c | 24 ++++++++++++++++++++++++
>>>>>>     1 file changed, 24 insertions(+)
>>>>>>
>>>>>> diff --git a/drivers/i2c/busses/i2c-tegra.c
>>>>>> b/drivers/i2c/busses/i2c-tegra.c
>>>>>> index ebaa78d..f6a377f 100644
>>>>>> --- a/drivers/i2c/busses/i2c-tegra.c
>>>>>> +++ b/drivers/i2c/busses/i2c-tegra.c
>>>>>> @@ -1687,9 +1687,33 @@ static int tegra_i2c_remove(struct
>>>>>> platform_device *pdev)
>>>>>>     }
>>>>>>       #ifdef CONFIG_PM_SLEEP
>>>>>> +static int tegra_i2c_suspend(struct device *dev)
>>>>>> +{
>>>>>> +    struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
>>>>>> +
>>>>>> +    i2c_mark_adapter_suspended(&i2c_dev->adapter);
>>>>>> +
>>>>>> +    return 0;
>>>>>> +}
>>>>>> +
>>>>>> +static int tegra_i2c_resume(struct device *dev)
>>>>>> +{
>>>>>> +    struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
>>>>>> +    int ret;
>>>>>> +
>>>>>> +    i2c_lock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
>>>>>> +    ret = tegra_i2c_init(i2c_dev, false);
>>>>>> +    i2c_unlock_bus(&i2c_dev->adapter, I2C_LOCK_ROOT_ADAPTER);
>>>>>
>>>>> Why the locking is needed here?
>>>>
>>>> async resume could result in stress test issues if some client accesses
>>>> the i2c instance. This ensures the i2c instance is locked till the
>>>> initialization is complete.
>>>
>>> 1) This doesn't make much sense.. if client could access I2C during of
>>> tegra_i2c_init execution, then what stops it to perform the access
>>> before the lock is taken?
>> Client resumes will start after I2C instance resume because of driver
>> dependency. Since lock is the first call in i2c-tegra I believe I2C
>> calls of client will not start.
> 
> You're incorrectly assuming that client can start resuming in the middle
> of the controller's resume process. I2C client's resume won't start
> until tegra_i2c_resume() is finished completely. That is because child
> drivers are resumed only after theirs parent is ready and this is
> guaranteed by the drivers core.
> 
Agreed.

-regards,
  Bitan

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

end of thread, other threads:[~2019-06-06 13:55 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-30  5:55 [PATCH V1] i2c: busses: tegra: Add suspend-resume support Bitan Biswas
2019-05-30 11:27 ` Dmitry Osipenko
2019-05-31  8:50   ` Bitan Biswas
2019-05-31 12:43     ` Dmitry Osipenko
2019-06-06  5:43       ` Bitan Biswas
2019-06-06 11:52         ` Dmitry Osipenko
2019-06-06 13:55           ` Bitan Biswas

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).