Skip to content

Commit

Permalink
pwm: lpss: Add support for runtime PM
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Qipeng Zha authored and Thierry Reding committed Nov 6, 2015
1 parent 03f00e5 commit f080be2
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
32 changes: 32 additions & 0 deletions drivers/pwm/pwm-lpss-pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -33,16 +34,44 @@ 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;
}

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},
Expand All @@ -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);

Expand Down
6 changes: 6 additions & 0 deletions drivers/pwm/pwm-lpss-platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -36,13 +37,18 @@ 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;
}

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);
}

Expand Down
7 changes: 7 additions & 0 deletions drivers/pwm/pwm-lpss.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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;
Expand All @@ -113,18 +116,22 @@ 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;
}

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 = {
Expand Down

0 comments on commit f080be2

Please sign in to comment.