aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQipeng Zha <qipeng.zha@intel.com>2015-10-26 06:58:27 -0400
committerThierry Reding <thierry.reding@gmail.com>2015-11-06 08:34:13 -0500
commitf080be27d7d9333e4815655a2cedab91c3aa7acc (patch)
tree102b1929216c09c2e26e7ecc9dc93e023c549635
parent03f00e5311d5d0d3ac716121865cb967259980ca (diff)
pwm: lpss: Add support for runtime PM
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>
-rw-r--r--drivers/pwm/pwm-lpss-pci.c32
-rw-r--r--drivers/pwm/pwm-lpss-platform.c6
-rw-r--r--drivers/pwm/pwm-lpss.c7
3 files changed, 45 insertions, 0 deletions
diff --git a/drivers/pwm/pwm-lpss-pci.c b/drivers/pwm/pwm-lpss-pci.c
index c15bc6d00f1a..7160e8ab38a4 100644
--- a/drivers/pwm/pwm-lpss-pci.c
+++ b/drivers/pwm/pwm-lpss-pci.c
@@ -13,6 +13,7 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/pci.h> 15#include <linux/pci.h>
16#include <linux/pm_runtime.h>
16 17
17#include "pwm-lpss.h" 18#include "pwm-lpss.h"
18 19
@@ -33,6 +34,10 @@ static int pwm_lpss_probe_pci(struct pci_dev *pdev,
33 return PTR_ERR(lpwm); 34 return PTR_ERR(lpwm);
34 35
35 pci_set_drvdata(pdev, lpwm); 36 pci_set_drvdata(pdev, lpwm);
37
38 pm_runtime_put(&pdev->dev);
39 pm_runtime_allow(&pdev->dev);
40
36 return 0; 41 return 0;
37} 42}
38 43
@@ -40,9 +45,33 @@ static void pwm_lpss_remove_pci(struct pci_dev *pdev)
40{ 45{
41 struct pwm_lpss_chip *lpwm = pci_get_drvdata(pdev); 46 struct pwm_lpss_chip *lpwm = pci_get_drvdata(pdev);
42 47
48 pm_runtime_forbid(&pdev->dev);
49 pm_runtime_get_sync(&pdev->dev);
50
43 pwm_lpss_remove(lpwm); 51 pwm_lpss_remove(lpwm);
44} 52}
45 53
54#ifdef CONFIG_PM
55static int pwm_lpss_runtime_suspend_pci(struct device *dev)
56{
57 /*
58 * The PCI core will handle transition to D3 automatically. We only
59 * need to provide runtime PM hooks for that to happen.
60 */
61 return 0;
62}
63
64static int pwm_lpss_runtime_resume_pci(struct device *dev)
65{
66 return 0;
67}
68#endif
69
70static const struct dev_pm_ops pwm_lpss_pci_pm = {
71 SET_RUNTIME_PM_OPS(pwm_lpss_runtime_suspend_pci,
72 pwm_lpss_runtime_resume_pci, NULL)
73};
74
46static const struct pci_device_id pwm_lpss_pci_ids[] = { 75static const struct pci_device_id pwm_lpss_pci_ids[] = {
47 { PCI_VDEVICE(INTEL, 0x0ac8), (unsigned long)&pwm_lpss_bxt_info}, 76 { PCI_VDEVICE(INTEL, 0x0ac8), (unsigned long)&pwm_lpss_bxt_info},
48 { PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&pwm_lpss_byt_info}, 77 { PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&pwm_lpss_byt_info},
@@ -60,6 +89,9 @@ static struct pci_driver pwm_lpss_driver_pci = {
60 .id_table = pwm_lpss_pci_ids, 89 .id_table = pwm_lpss_pci_ids,
61 .probe = pwm_lpss_probe_pci, 90 .probe = pwm_lpss_probe_pci,
62 .remove = pwm_lpss_remove_pci, 91 .remove = pwm_lpss_remove_pci,
92 .driver = {
93 .pm = &pwm_lpss_pci_pm,
94 },
63}; 95};
64module_pci_driver(pwm_lpss_driver_pci); 96module_pci_driver(pwm_lpss_driver_pci);
65 97
diff --git a/drivers/pwm/pwm-lpss-platform.c b/drivers/pwm/pwm-lpss-platform.c
index a914aacf6757..54433fc6d1a4 100644
--- a/drivers/pwm/pwm-lpss-platform.c
+++ b/drivers/pwm/pwm-lpss-platform.c
@@ -14,6 +14,7 @@
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/pm_runtime.h>
17 18
18#include "pwm-lpss.h" 19#include "pwm-lpss.h"
19 20
@@ -36,6 +37,10 @@ static int pwm_lpss_probe_platform(struct platform_device *pdev)
36 return PTR_ERR(lpwm); 37 return PTR_ERR(lpwm);
37 38
38 platform_set_drvdata(pdev, lpwm); 39 platform_set_drvdata(pdev, lpwm);
40
41 pm_runtime_set_active(&pdev->dev);
42 pm_runtime_enable(&pdev->dev);
43
39 return 0; 44 return 0;
40} 45}
41 46
@@ -43,6 +48,7 @@ static int pwm_lpss_remove_platform(struct platform_device *pdev)
43{ 48{
44 struct pwm_lpss_chip *lpwm = platform_get_drvdata(pdev); 49 struct pwm_lpss_chip *lpwm = platform_get_drvdata(pdev);
45 50
51 pm_runtime_disable(&pdev->dev);
46 return pwm_lpss_remove(lpwm); 52 return pwm_lpss_remove(lpwm);
47} 53}
48 54
diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c
index df03b50f20dd..25044104003b 100644
--- a/drivers/pwm/pwm-lpss.c
+++ b/drivers/pwm/pwm-lpss.c
@@ -16,6 +16,7 @@
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/pm_runtime.h>
19 20
20#include "pwm-lpss.h" 21#include "pwm-lpss.h"
21 22
@@ -105,6 +106,8 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
105 duty_ns = 1; 106 duty_ns = 1;
106 on_time_div = 255 - (255 * duty_ns / period_ns); 107 on_time_div = 255 - (255 * duty_ns / period_ns);
107 108
109 pm_runtime_get_sync(chip->dev);
110
108 ctrl = pwm_lpss_read(pwm); 111 ctrl = pwm_lpss_read(pwm);
109 ctrl &= ~(PWM_BASE_UNIT_MASK | PWM_ON_TIME_DIV_MASK); 112 ctrl &= ~(PWM_BASE_UNIT_MASK | PWM_ON_TIME_DIV_MASK);
110 ctrl |= (u16) base_unit << PWM_BASE_UNIT_SHIFT; 113 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,
113 ctrl |= PWM_SW_UPDATE; 116 ctrl |= PWM_SW_UPDATE;
114 pwm_lpss_write(pwm, ctrl); 117 pwm_lpss_write(pwm, ctrl);
115 118
119 pm_runtime_put(chip->dev);
120
116 return 0; 121 return 0;
117} 122}
118 123
119static int pwm_lpss_enable(struct pwm_chip *chip, struct pwm_device *pwm) 124static int pwm_lpss_enable(struct pwm_chip *chip, struct pwm_device *pwm)
120{ 125{
126 pm_runtime_get_sync(chip->dev);
121 pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE); 127 pwm_lpss_write(pwm, pwm_lpss_read(pwm) | PWM_ENABLE);
122 return 0; 128 return 0;
123} 129}
@@ -125,6 +131,7 @@ static int pwm_lpss_enable(struct pwm_chip *chip, struct pwm_device *pwm)
125static void pwm_lpss_disable(struct pwm_chip *chip, struct pwm_device *pwm) 131static void pwm_lpss_disable(struct pwm_chip *chip, struct pwm_device *pwm)
126{ 132{
127 pwm_lpss_write(pwm, pwm_lpss_read(pwm) & ~PWM_ENABLE); 133 pwm_lpss_write(pwm, pwm_lpss_read(pwm) & ~PWM_ENABLE);
134 pm_runtime_put(chip->dev);
128} 135}
129 136
130static const struct pwm_ops pwm_lpss_ops = { 137static const struct pwm_ops pwm_lpss_ops = {