]> git.karo-electronics.de Git - linux-beck.git/commitdiff
pwm: lpss: Add support for runtime PM
authorQipeng Zha <qipeng.zha@intel.com>
Mon, 26 Oct 2015 10:58:27 +0000 (12:58 +0200)
committerThierry Reding <thierry.reding@gmail.com>
Fri, 6 Nov 2015 13:34:13 +0000 (14:34 +0100)
To be able to save some power when PWM is not in use, add support for
runtime PM for this driver. This also allows the platform to transition to
low power S0ix states when the system is idle.

Signed-off-by: Huiquan Zhong <huiquan.zhong@intel.com>
Signed-off-by: Qipeng Zha <qipeng.zha@intel.com>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
drivers/pwm/pwm-lpss-pci.c
drivers/pwm/pwm-lpss-platform.c
drivers/pwm/pwm-lpss.c

index c15bc6d00f1aef323375584dd8f75ac0f0dbc57e..7160e8ab38a4ea83f7cd01b21f58b6309b0859fc 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/pm_runtime.h>
 
 #include "pwm-lpss.h"
 
@@ -33,6 +34,10 @@ static int pwm_lpss_probe_pci(struct pci_dev *pdev,
                return PTR_ERR(lpwm);
 
        pci_set_drvdata(pdev, lpwm);
+
+       pm_runtime_put(&pdev->dev);
+       pm_runtime_allow(&pdev->dev);
+
        return 0;
 }
 
@@ -40,9 +45,33 @@ static void pwm_lpss_remove_pci(struct pci_dev *pdev)
 {
        struct pwm_lpss_chip *lpwm = pci_get_drvdata(pdev);
 
+       pm_runtime_forbid(&pdev->dev);
+       pm_runtime_get_sync(&pdev->dev);
+
        pwm_lpss_remove(lpwm);
 }
 
+#ifdef CONFIG_PM
+static int pwm_lpss_runtime_suspend_pci(struct device *dev)
+{
+       /*
+        * The PCI core will handle transition to D3 automatically. We only
+        * need to provide runtime PM hooks for that to happen.
+        */
+       return 0;
+}
+
+static int pwm_lpss_runtime_resume_pci(struct device *dev)
+{
+       return 0;
+}
+#endif
+
+static const struct dev_pm_ops pwm_lpss_pci_pm = {
+       SET_RUNTIME_PM_OPS(pwm_lpss_runtime_suspend_pci,
+                          pwm_lpss_runtime_resume_pci, NULL)
+};
+
 static const struct pci_device_id pwm_lpss_pci_ids[] = {
        { PCI_VDEVICE(INTEL, 0x0ac8), (unsigned long)&pwm_lpss_bxt_info},
        { PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&pwm_lpss_byt_info},
@@ -60,6 +89,9 @@ static struct pci_driver pwm_lpss_driver_pci = {
        .id_table = pwm_lpss_pci_ids,
        .probe = pwm_lpss_probe_pci,
        .remove = pwm_lpss_remove_pci,
+       .driver = {
+               .pm = &pwm_lpss_pci_pm,
+       },
 };
 module_pci_driver(pwm_lpss_driver_pci);
 
index a914aacf6757d071df0887c093c7a56458ec0fb1..54433fc6d1a4e491e9e046b20558e093d7c5c4de 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 
 #include "pwm-lpss.h"
 
@@ -36,6 +37,10 @@ static int pwm_lpss_probe_platform(struct platform_device *pdev)
                return PTR_ERR(lpwm);
 
        platform_set_drvdata(pdev, lpwm);
+
+       pm_runtime_set_active(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+
        return 0;
 }
 
@@ -43,6 +48,7 @@ static int pwm_lpss_remove_platform(struct platform_device *pdev)
 {
        struct pwm_lpss_chip *lpwm = platform_get_drvdata(pdev);
 
+       pm_runtime_disable(&pdev->dev);
        return pwm_lpss_remove(lpwm);
 }
 
index df03b50f20dd15e1712c3d38a2de04f1bfd976b4..25044104003b01a7e3879fe6b94e7e5e7d477681 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/pm_runtime.h>
 
 #include "pwm-lpss.h"
 
@@ -105,6 +106,8 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
                duty_ns = 1;
        on_time_div = 255 - (255 * duty_ns / period_ns);
 
+       pm_runtime_get_sync(chip->dev);
+
        ctrl = pwm_lpss_read(pwm);
        ctrl &= ~(PWM_BASE_UNIT_MASK | PWM_ON_TIME_DIV_MASK);
        ctrl |= (u16) base_unit << PWM_BASE_UNIT_SHIFT;
@@ -113,11 +116,14 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
        ctrl |= PWM_SW_UPDATE;
        pwm_lpss_write(pwm, ctrl);
 
+       pm_runtime_put(chip->dev);
+
        return 0;
 }
 
 static int pwm_lpss_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
+       pm_runtime_get_sync(chip->dev);
        pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE);
        return 0;
 }
@@ -125,6 +131,7 @@ static int pwm_lpss_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 static void pwm_lpss_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 {
        pwm_lpss_write(pwm, pwm_lpss_read(pwm) & ~PWM_ENABLE);
+       pm_runtime_put(chip->dev);
 }
 
 static const struct pwm_ops pwm_lpss_ops = {