diff mbox series

[v10,07/17] pwm: lpss: Remove suspend/resume handlers

Message ID 20200903112337.4113-8-hdegoede@redhat.com (mailing list archive)
State New, archived
Headers show
Series acpi/pwm/i915: Convert pwm-crc and i915 driver's PWM code to use the atomic PWM API | expand

Commit Message

Hans de Goede Sept. 3, 2020, 11:23 a.m. UTC
PWM controller drivers should not restore the PWM state on resume. The
convention is that PWM consumers do this by calling pwm_apply_state(),
so that it can be done at the exact moment when the consumer needs
the state to be stored, avoiding e.g. backlight flickering.

The only in kernel consumers of the pwm-lpss code, the i915 driver
and the pwm-class sysfs interface code both correctly restore the
state on resume, so there is no need to do this in the pwm-lpss code.

More-over the removed resume handler is buggy, since it blindly
restores the ctrl-register contents without setting the update
bit, which is necessary to get the controller to actually use/apply
the restored base-unit and on-time-div values.

Acked-by: Thierry Reding <thierry.reding@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
Changes in v9:
- This is a new patch in v9 of this series
---
 drivers/pwm/pwm-lpss-platform.c |  1 -
 drivers/pwm/pwm-lpss.c          | 24 ------------------------
 drivers/pwm/pwm-lpss.h          |  3 ---
 3 files changed, 28 deletions(-)

Comments

Andy Shevchenko Sept. 3, 2020, 12:48 p.m. UTC | #1
On Thu, Sep 03, 2020 at 01:23:27PM +0200, Hans de Goede wrote:
> PWM controller drivers should not restore the PWM state on resume. The
> convention is that PWM consumers do this by calling pwm_apply_state(),
> so that it can be done at the exact moment when the consumer needs
> the state to be stored, avoiding e.g. backlight flickering.
> 
> The only in kernel consumers of the pwm-lpss code, the i915 driver
> and the pwm-class sysfs interface code both correctly restore the
> state on resume, so there is no need to do this in the pwm-lpss code.
> 
> More-over the removed resume handler is buggy, since it blindly
> restores the ctrl-register contents without setting the update
> bit, which is necessary to get the controller to actually use/apply
> the restored base-unit and on-time-div values.

While this is okay

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>

the question is do we need to have similar in acpi_lpss.c?
For example,
	static const struct lpss_device_desc byt_pwm_dev_desc = {
		.flags = LPSS_SAVE_CTX,
		^^^^^^^^^^^^^^
		.prv_offset = 0x800,
		.setup = byt_pwm_setup,
	};

	static const struct lpss_device_desc bsw_pwm_dev_desc = {
		.flags = LPSS_SAVE_CTX | LPSS_NO_D3_DELAY,
		^^^^^^^^^^^^^^
		.prv_offset = 0x800,
		.setup = bsw_pwm_setup,
	};


> Acked-by: Thierry Reding <thierry.reding@gmail.com>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
> Changes in v9:
> - This is a new patch in v9 of this series
> ---
>  drivers/pwm/pwm-lpss-platform.c |  1 -
>  drivers/pwm/pwm-lpss.c          | 24 ------------------------
>  drivers/pwm/pwm-lpss.h          |  3 ---
>  3 files changed, 28 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-lpss-platform.c b/drivers/pwm/pwm-lpss-platform.c
> index 48f34d20aecd..c6502cf7a7af 100644
> --- a/drivers/pwm/pwm-lpss-platform.c
> +++ b/drivers/pwm/pwm-lpss-platform.c
> @@ -89,7 +89,6 @@ static int pwm_lpss_prepare(struct device *dev)
>  
>  static const struct dev_pm_ops pwm_lpss_platform_pm_ops = {
>  	.prepare = pwm_lpss_prepare,
> -	SET_SYSTEM_SLEEP_PM_OPS(pwm_lpss_suspend, pwm_lpss_resume)
>  };
>  
>  static const struct acpi_device_id pwm_lpss_acpi_match[] = {
> diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c
> index 9c5c7217c9b6..3444c56b4bed 100644
> --- a/drivers/pwm/pwm-lpss.c
> +++ b/drivers/pwm/pwm-lpss.c
> @@ -260,30 +260,6 @@ int pwm_lpss_remove(struct pwm_lpss_chip *lpwm)
>  }
>  EXPORT_SYMBOL_GPL(pwm_lpss_remove);
>  
> -int pwm_lpss_suspend(struct device *dev)
> -{
> -	struct pwm_lpss_chip *lpwm = dev_get_drvdata(dev);
> -	int i;
> -
> -	for (i = 0; i < lpwm->info->npwm; i++)
> -		lpwm->saved_ctrl[i] = readl(lpwm->regs + i * PWM_SIZE + PWM);
> -
> -	return 0;
> -}
> -EXPORT_SYMBOL_GPL(pwm_lpss_suspend);
> -
> -int pwm_lpss_resume(struct device *dev)
> -{
> -	struct pwm_lpss_chip *lpwm = dev_get_drvdata(dev);
> -	int i;
> -
> -	for (i = 0; i < lpwm->info->npwm; i++)
> -		writel(lpwm->saved_ctrl[i], lpwm->regs + i * PWM_SIZE + PWM);
> -
> -	return 0;
> -}
> -EXPORT_SYMBOL_GPL(pwm_lpss_resume);
> -
>  MODULE_DESCRIPTION("PWM driver for Intel LPSS");
>  MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
>  MODULE_LICENSE("GPL v2");
> diff --git a/drivers/pwm/pwm-lpss.h b/drivers/pwm/pwm-lpss.h
> index 7909fa12fca2..70db7e389d66 100644
> --- a/drivers/pwm/pwm-lpss.h
> +++ b/drivers/pwm/pwm-lpss.h
> @@ -19,7 +19,6 @@ struct pwm_lpss_chip {
>  	struct pwm_chip chip;
>  	void __iomem *regs;
>  	const struct pwm_lpss_boardinfo *info;
> -	u32 saved_ctrl[MAX_PWMS];
>  };
>  
>  struct pwm_lpss_boardinfo {
> @@ -37,7 +36,5 @@ struct pwm_lpss_boardinfo {
>  struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
>  				     const struct pwm_lpss_boardinfo *info);
>  int pwm_lpss_remove(struct pwm_lpss_chip *lpwm);
> -int pwm_lpss_suspend(struct device *dev);
> -int pwm_lpss_resume(struct device *dev);
>  
>  #endif	/* __PWM_LPSS_H */
> -- 
> 2.28.0
>
Andy Shevchenko Sept. 3, 2020, 12:56 p.m. UTC | #2
On Thu, Sep 03, 2020 at 03:48:16PM +0300, Andy Shevchenko wrote:
> On Thu, Sep 03, 2020 at 01:23:27PM +0200, Hans de Goede wrote:

> the question is do we need to have similar in acpi_lpss.c?
> For example,
> 	static const struct lpss_device_desc byt_pwm_dev_desc = {
> 		.flags = LPSS_SAVE_CTX,
> 		^^^^^^^^^^^^^^
> 		.prv_offset = 0x800,
> 		.setup = byt_pwm_setup,
> 	};
> 
> 	static const struct lpss_device_desc bsw_pwm_dev_desc = {
> 		.flags = LPSS_SAVE_CTX | LPSS_NO_D3_DELAY,
> 		^^^^^^^^^^^^^^
> 		.prv_offset = 0x800,
> 		.setup = bsw_pwm_setup,
> 	};

Okay, it's a private space which has clock and reset gating, so means we still
need to handle it.
Hans de Goede Sept. 3, 2020, 1:09 p.m. UTC | #3
Hi,

On 9/3/20 2:56 PM, Andy Shevchenko wrote:
> On Thu, Sep 03, 2020 at 03:48:16PM +0300, Andy Shevchenko wrote:
>> On Thu, Sep 03, 2020 at 01:23:27PM +0200, Hans de Goede wrote:
> 
>> the question is do we need to have similar in acpi_lpss.c?
>> For example,
>> 	static const struct lpss_device_desc byt_pwm_dev_desc = {
>> 		.flags = LPSS_SAVE_CTX,
>> 		^^^^^^^^^^^^^^
>> 		.prv_offset = 0x800,
>> 		.setup = byt_pwm_setup,
>> 	};
>>
>> 	static const struct lpss_device_desc bsw_pwm_dev_desc = {
>> 		.flags = LPSS_SAVE_CTX | LPSS_NO_D3_DELAY,
>> 		^^^^^^^^^^^^^^
>> 		.prv_offset = 0x800,
>> 		.setup = bsw_pwm_setup,
>> 	};
> 
> Okay, it's a private space which has clock and reset gating, so means we still
> need to handle it.

Right I was about to say the same.

As always, thank you for your reviews.

Regards,

Hans
diff mbox series

Patch

diff --git a/drivers/pwm/pwm-lpss-platform.c b/drivers/pwm/pwm-lpss-platform.c
index 48f34d20aecd..c6502cf7a7af 100644
--- a/drivers/pwm/pwm-lpss-platform.c
+++ b/drivers/pwm/pwm-lpss-platform.c
@@ -89,7 +89,6 @@  static int pwm_lpss_prepare(struct device *dev)
 
 static const struct dev_pm_ops pwm_lpss_platform_pm_ops = {
 	.prepare = pwm_lpss_prepare,
-	SET_SYSTEM_SLEEP_PM_OPS(pwm_lpss_suspend, pwm_lpss_resume)
 };
 
 static const struct acpi_device_id pwm_lpss_acpi_match[] = {
diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c
index 9c5c7217c9b6..3444c56b4bed 100644
--- a/drivers/pwm/pwm-lpss.c
+++ b/drivers/pwm/pwm-lpss.c
@@ -260,30 +260,6 @@  int pwm_lpss_remove(struct pwm_lpss_chip *lpwm)
 }
 EXPORT_SYMBOL_GPL(pwm_lpss_remove);
 
-int pwm_lpss_suspend(struct device *dev)
-{
-	struct pwm_lpss_chip *lpwm = dev_get_drvdata(dev);
-	int i;
-
-	for (i = 0; i < lpwm->info->npwm; i++)
-		lpwm->saved_ctrl[i] = readl(lpwm->regs + i * PWM_SIZE + PWM);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(pwm_lpss_suspend);
-
-int pwm_lpss_resume(struct device *dev)
-{
-	struct pwm_lpss_chip *lpwm = dev_get_drvdata(dev);
-	int i;
-
-	for (i = 0; i < lpwm->info->npwm; i++)
-		writel(lpwm->saved_ctrl[i], lpwm->regs + i * PWM_SIZE + PWM);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(pwm_lpss_resume);
-
 MODULE_DESCRIPTION("PWM driver for Intel LPSS");
 MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/pwm/pwm-lpss.h b/drivers/pwm/pwm-lpss.h
index 7909fa12fca2..70db7e389d66 100644
--- a/drivers/pwm/pwm-lpss.h
+++ b/drivers/pwm/pwm-lpss.h
@@ -19,7 +19,6 @@  struct pwm_lpss_chip {
 	struct pwm_chip chip;
 	void __iomem *regs;
 	const struct pwm_lpss_boardinfo *info;
-	u32 saved_ctrl[MAX_PWMS];
 };
 
 struct pwm_lpss_boardinfo {
@@ -37,7 +36,5 @@  struct pwm_lpss_boardinfo {
 struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
 				     const struct pwm_lpss_boardinfo *info);
 int pwm_lpss_remove(struct pwm_lpss_chip *lpwm);
-int pwm_lpss_suspend(struct device *dev);
-int pwm_lpss_resume(struct device *dev);
 
 #endif	/* __PWM_LPSS_H */