Commit b9c90f15 authored by Hans de Goede's avatar Hans de Goede Committed by Thierry Reding
Browse files

pwm: lpss: Use DPM_FLAG_NO_DIRECT_COMPLETE instead of declaring a prepare handler



ACPI LPSS devices use direct-complete style suspend/resume handling by
default. We set the DPM_FLAG_SMART_PREPARE and define a prepare handler
to disable this on Cherry Trail devices.

Clean this up a bit by setting the DPM_FLAG_NO_DIRECT_COMPLETE flag for
Cherry Trail devices, instead of defining a prepare handler.

While at it also improve the comment explaining why this is necessary.

Reviewed-by: default avatarAndy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarThierry Reding <thierry.reding@gmail.com>
parent d58560e6
Loading
Loading
Loading
Loading
+15 −20
Original line number Diff line number Diff line
@@ -58,7 +58,21 @@ static int pwm_lpss_probe_platform(struct platform_device *pdev)

	platform_set_drvdata(pdev, lpwm);

	dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_SMART_PREPARE);
	/*
	 * On Cherry Trail devices the GFX0._PS0 AML checks if the controller
	 * is on and if it is not on it turns it on and restores what it
	 * believes is the correct state to the PWM controller.
	 * Because of this we must disallow direct-complete, which keeps the
	 * controller (runtime)suspended on resume, to avoid 2 issues:
	 * 1. The controller getting turned on without the linux-pm code
	 *    knowing about this. On devices where the controller is unused
	 *    this causes it to stay on during the next suspend causing high
	 *    battery drain (because S0i3 is not reached)
	 * 2. The state restoring code unexpectedly messing with the controller
	 */
	if (info->other_devices_aml_touches_pwm_regs)
		dev_pm_set_driver_flags(&pdev->dev, DPM_FLAG_NO_DIRECT_COMPLETE);

	pm_runtime_set_active(&pdev->dev);
	pm_runtime_enable(&pdev->dev);

@@ -73,24 +87,6 @@ static int pwm_lpss_remove_platform(struct platform_device *pdev)
	return pwm_lpss_remove(lpwm);
}

static int pwm_lpss_prepare(struct device *dev)
{
	struct pwm_lpss_chip *lpwm = dev_get_drvdata(dev);

	/*
	 * If other device's AML code touches the PWM regs on suspend/resume
	 * force runtime-resume the PWM controller to allow this.
	 */
	if (lpwm->info->other_devices_aml_touches_pwm_regs)
		return 0; /* Force runtime-resume */

	return 1; /* If runtime-suspended leave as is */
}

static const struct dev_pm_ops pwm_lpss_platform_pm_ops = {
	.prepare = pwm_lpss_prepare,
};

static const struct acpi_device_id pwm_lpss_acpi_match[] = {
	{ "80860F09", (unsigned long)&pwm_lpss_byt_info },
	{ "80862288", (unsigned long)&pwm_lpss_bsw_info },
@@ -104,7 +100,6 @@ static struct platform_driver pwm_lpss_driver_platform = {
	.driver = {
		.name = "pwm-lpss",
		.acpi_match_table = pwm_lpss_acpi_match,
		.pm = &pwm_lpss_platform_pm_ops,
	},
	.probe = pwm_lpss_probe_platform,
	.remove = pwm_lpss_remove_platform,