some Intel pwm patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 Nov 2014 00:55:49 +0000 (09:55 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 10 Nov 2014 00:55:49 +0000 (09:55 +0900)
patches.intel/pwm-add-support-for-intel-low-power-subsystem-pwm.patch [new file with mode: 0644]
patches.intel/pwm-lpss-add-acpi-and-pci-ids-for-intel-braswell.patch [new file with mode: 0644]
patches.intel/pwm-lpss-add-support-for-pci-devices.patch [new file with mode: 0644]
patches.intel/pwm-lpss-fix-build-failure-on-powerpc.patch [new file with mode: 0644]
patches.intel/pwm-lpss-fix-const-qualifier-and-sparse-warnings.patch [new file with mode: 0644]
patches.intel/pwm-lpss-properly-split-driver-to-parts.patch [new file with mode: 0644]
patches.intel/pwm-lpss-remove-dependency-on-clk-framework.patch [new file with mode: 0644]
patches.intel/pwm-lpss-use-c99-initializers-in-structures.patch [new file with mode: 0644]
series

diff --git a/patches.intel/pwm-add-support-for-intel-low-power-subsystem-pwm.patch b/patches.intel/pwm-add-support-for-intel-low-power-subsystem-pwm.patch
new file mode 100644 (file)
index 0000000..855c4c8
--- /dev/null
@@ -0,0 +1,244 @@
+From ltsi-dev-bounces@lists.linuxfoundation.org Wed Oct 29 09:53:35 2014
+From: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Date: Wed, 29 Oct 2014 08:52:51 +0800
+Subject: [LTSI-dev] [PATCH 1/8] pwm: add support for Intel Low Power Subsystem PWM
+To: LTSI Mailing List <ltsi-dev@lists.linuxfoundation.org>
+Cc: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Message-ID: <1414543978-24145-2-git-send-email-rebecca.swee.fun.chang@intel.com>
+
+
+From: Mika Westerberg <mika.westerberg@linux.intel.com>
+
+Add support for Intel Low Power I/O subsystem PWM controllers found on
+Intel BayTrail SoC.
+
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Chew, Kean Ho <kean.ho.chew@intel.com>
+Signed-off-by: Chang, Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Signed-off-by: Chew, Chiau Ee <chiau.ee.chew@intel.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+(cherry picked from commit d16a5aa9e821633a3095d7a88cd1d2cd108bf966)
+
+Signed-off-by: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+---
+ drivers/pwm/Kconfig    |   10 ++
+ drivers/pwm/Makefile   |    1 
+ drivers/pwm/pwm-lpss.c |  183 +++++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 194 insertions(+)
+ create mode 100644 drivers/pwm/pwm-lpss.c
+
+--- a/drivers/pwm/Kconfig
++++ b/drivers/pwm/Kconfig
+@@ -119,6 +119,16 @@ config PWM_LPC32XX
+         To compile this driver as a module, choose M here: the module
+         will be called pwm-lpc32xx.
++config PWM_LPSS
++      tristate "Intel LPSS PWM support"
++      depends on ACPI
++      help
++        Generic PWM framework driver for Intel Low Power Subsystem PWM
++        controller.
++
++        To compile this driver as a module, choose M here: the module
++        will be called pwm-lpss.
++
+ config PWM_MXS
+       tristate "Freescale MXS PWM support"
+       depends on ARCH_MXS && OF
+--- a/drivers/pwm/Makefile
++++ b/drivers/pwm/Makefile
+@@ -9,6 +9,7 @@ obj-$(CONFIG_PWM_IMX)          += pwm-imx.o
+ obj-$(CONFIG_PWM_JZ4740)      += pwm-jz4740.o
+ obj-$(CONFIG_PWM_LP3943)      += pwm-lp3943.o
+ obj-$(CONFIG_PWM_LPC32XX)     += pwm-lpc32xx.o
++obj-$(CONFIG_PWM_LPSS)                += pwm-lpss.o
+ obj-$(CONFIG_PWM_MXS)         += pwm-mxs.o
+ obj-$(CONFIG_PWM_PCA9685)     += pwm-pca9685.o
+ obj-$(CONFIG_PWM_PUV3)                += pwm-puv3.o
+--- /dev/null
++++ b/drivers/pwm/pwm-lpss.c
+@@ -0,0 +1,183 @@
++/*
++ * Intel Low Power Subsystem PWM controller driver
++ *
++ * Copyright (C) 2014, Intel Corporation
++ * Author: Mika Westerberg <mika.westerberg@linux.intel.com>
++ * Author: Chew Kean Ho <kean.ho.chew@intel.com>
++ * Author: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
++ * Author: Chew Chiau Ee <chiau.ee.chew@intel.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/acpi.h>
++#include <linux/clk.h>
++#include <linux/device.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/pwm.h>
++#include <linux/platform_device.h>
++
++#define PWM                           0x00000000
++#define PWM_ENABLE                    BIT(31)
++#define PWM_SW_UPDATE                 BIT(30)
++#define PWM_BASE_UNIT_SHIFT           8
++#define PWM_BASE_UNIT_MASK            0x00ffff00
++#define PWM_ON_TIME_DIV_MASK          0x000000ff
++#define PWM_DIVISION_CORRECTION               0x2
++#define PWM_LIMIT                     (0x8000 + PWM_DIVISION_CORRECTION)
++#define NSECS_PER_SEC                 1000000000UL
++
++struct pwm_lpss_chip {
++      struct pwm_chip chip;
++      void __iomem *regs;
++      struct clk *clk;
++};
++
++static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip)
++{
++      return container_of(chip, struct pwm_lpss_chip, chip);
++}
++
++static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
++                         int duty_ns, int period_ns)
++{
++      struct pwm_lpss_chip *lpwm = to_lpwm(chip);
++      u8 on_time_div;
++      unsigned long c;
++      unsigned long long base_unit, freq = NSECS_PER_SEC;
++      u32 ctrl;
++
++      do_div(freq, period_ns);
++
++      /* The equation is: base_unit = ((freq / c) * 65536) + correction */
++      base_unit = freq * 65536;
++
++      c = clk_get_rate(lpwm->clk);
++      if (!c)
++              return -EINVAL;
++
++      do_div(base_unit, c);
++      base_unit += PWM_DIVISION_CORRECTION;
++      if (base_unit > PWM_LIMIT)
++              return -EINVAL;
++
++      if (duty_ns <= 0)
++              duty_ns = 1;
++      on_time_div = 255 - (255 * duty_ns / period_ns);
++
++      ctrl = readl(lpwm->regs + PWM);
++      ctrl &= ~(PWM_BASE_UNIT_MASK | PWM_ON_TIME_DIV_MASK);
++      ctrl |= (u16) base_unit << PWM_BASE_UNIT_SHIFT;
++      ctrl |= on_time_div;
++      /* request PWM to update on next cycle */
++      ctrl |= PWM_SW_UPDATE;
++      writel(ctrl, lpwm->regs + PWM);
++
++      return 0;
++}
++
++static int pwm_lpss_enable(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++      struct pwm_lpss_chip *lpwm = to_lpwm(chip);
++      u32 ctrl;
++      int ret;
++
++      ret = clk_prepare_enable(lpwm->clk);
++      if (ret)
++              return ret;
++
++      ctrl = readl(lpwm->regs + PWM);
++      writel(ctrl | PWM_ENABLE, lpwm->regs + PWM);
++
++      return 0;
++}
++
++static void pwm_lpss_disable(struct pwm_chip *chip, struct pwm_device *pwm)
++{
++      struct pwm_lpss_chip *lpwm = to_lpwm(chip);
++      u32 ctrl;
++
++      ctrl = readl(lpwm->regs + PWM);
++      writel(ctrl & ~PWM_ENABLE, lpwm->regs + PWM);
++
++      clk_disable_unprepare(lpwm->clk);
++}
++
++static const struct pwm_ops pwm_lpss_ops = {
++      .config = pwm_lpss_config,
++      .enable = pwm_lpss_enable,
++      .disable = pwm_lpss_disable,
++      .owner = THIS_MODULE,
++};
++
++static const struct acpi_device_id pwm_lpss_acpi_match[] = {
++      { "80860F09", 0 },
++      { },
++};
++MODULE_DEVICE_TABLE(acpi, pwm_lpss_acpi_match);
++
++static int pwm_lpss_probe(struct platform_device *pdev)
++{
++      struct pwm_lpss_chip *lpwm;
++      struct resource *r;
++      int ret;
++
++      lpwm = devm_kzalloc(&pdev->dev, sizeof(*lpwm), GFP_KERNEL);
++      if (!lpwm)
++              return -ENOMEM;
++
++      r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++      lpwm->regs = devm_ioremap_resource(&pdev->dev, r);
++      if (IS_ERR(lpwm->regs))
++              return PTR_ERR(lpwm->regs);
++
++      lpwm->clk = devm_clk_get(&pdev->dev, NULL);
++      if (IS_ERR(lpwm->clk)) {
++              dev_err(&pdev->dev, "failed to get PWM clock\n");
++              return PTR_ERR(lpwm->clk);
++      }
++
++      lpwm->chip.dev = &pdev->dev;
++      lpwm->chip.ops = &pwm_lpss_ops;
++      lpwm->chip.base = -1;
++      lpwm->chip.npwm = 1;
++
++      ret = pwmchip_add(&lpwm->chip);
++      if (ret) {
++              dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
++              return ret;
++      }
++
++      platform_set_drvdata(pdev, lpwm);
++      return 0;
++}
++
++static int pwm_lpss_remove(struct platform_device *pdev)
++{
++      struct pwm_lpss_chip *lpwm = platform_get_drvdata(pdev);
++      u32 ctrl;
++
++      ctrl = readl(lpwm->regs + PWM);
++      writel(ctrl & ~PWM_ENABLE, lpwm->regs + PWM);
++
++      return pwmchip_remove(&lpwm->chip);
++}
++
++static struct platform_driver pwm_lpss_driver = {
++      .driver = {
++              .name = "pwm-lpss",
++              .acpi_match_table = pwm_lpss_acpi_match,
++      },
++      .probe = pwm_lpss_probe,
++      .remove = pwm_lpss_remove,
++};
++module_platform_driver(pwm_lpss_driver);
++
++MODULE_DESCRIPTION("PWM driver for Intel LPSS");
++MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
++MODULE_LICENSE("GPL v2");
++MODULE_ALIAS("platform:pwm-lpss");
diff --git a/patches.intel/pwm-lpss-add-acpi-and-pci-ids-for-intel-braswell.patch b/patches.intel/pwm-lpss-add-acpi-and-pci-ids-for-intel-braswell.patch
new file mode 100644 (file)
index 0000000..62d5ec0
--- /dev/null
@@ -0,0 +1,55 @@
+From ltsi-dev-bounces@lists.linuxfoundation.org Wed Oct 29 09:53:51 2014
+From: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Date: Wed, 29 Oct 2014 08:52:55 +0800
+Subject: [LTSI-dev] [PATCH 5/8] pwm: lpss: Add ACPI and PCI IDs for Intel Braswell
+To: LTSI Mailing List <ltsi-dev@lists.linuxfoundation.org>
+Cc: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Message-ID: <1414543978-24145-6-git-send-email-rebecca.swee.fun.chang@intel.com>
+
+
+From: Alan Cox <alan@linux.intel.com>
+
+This is pretty much the same as Baytrail PWM. Only difference is that the
+input clock runs on different frequency.
+
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+(cherry picked from commit 373c57829a3f9da1405b1fbd3d17e50f8e1f476e)
+
+Signed-off-by: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+---
+ drivers/pwm/pwm-lpss.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/pwm/pwm-lpss.c
++++ b/drivers/pwm/pwm-lpss.c
+@@ -48,6 +48,11 @@ static const struct pwm_lpss_boardinfo b
+       25000000
+ };
++/* Braswell */
++static const struct pwm_lpss_boardinfo bsw_info = {
++      19200000
++};
++
+ static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip)
+ {
+       return container_of(chip, struct pwm_lpss_chip, chip);
+@@ -189,6 +194,8 @@ static void pwm_lpss_remove_pci(struct p
+ static struct pci_device_id pwm_lpss_pci_ids[] = {
+       { PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&byt_info},
+       { PCI_VDEVICE(INTEL, 0x0f09), (unsigned long)&byt_info},
++      { PCI_VDEVICE(INTEL, 0x2288), (unsigned long)&bsw_info},
++      { PCI_VDEVICE(INTEL, 0x2289), (unsigned long)&bsw_info},
+       { },
+ };
+ MODULE_DEVICE_TABLE(pci, pwm_lpss_pci_ids);
+@@ -231,6 +238,7 @@ static int pwm_lpss_remove_platform(stru
+ static const struct acpi_device_id pwm_lpss_acpi_match[] = {
+       { "80860F09", (unsigned long)&byt_info },
++      { "80862288", (unsigned long)&bsw_info },
+       { },
+ };
+ MODULE_DEVICE_TABLE(acpi, pwm_lpss_acpi_match);
diff --git a/patches.intel/pwm-lpss-add-support-for-pci-devices.patch b/patches.intel/pwm-lpss-add-support-for-pci-devices.patch
new file mode 100644 (file)
index 0000000..67e9d12
--- /dev/null
@@ -0,0 +1,254 @@
+From ltsi-dev-bounces@lists.linuxfoundation.org Wed Oct 29 09:53:39 2014
+From: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Date: Wed, 29 Oct 2014 08:52:52 +0800
+Subject: [LTSI-dev]  [PATCH 2/8] pwm: lpss: Add support for PCI devices
+To: LTSI Mailing List <ltsi-dev@lists.linuxfoundation.org>
+Cc: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Message-ID: <1414543978-24145-3-git-send-email-rebecca.swee.fun.chang@intel.com>
+
+
+From: Alan Cox <alan@linux.intel.com>
+
+Not all systems enumerate the PWM devices via ACPI. They can also be
+exposed via the PCI interface.
+
+Signed-off-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Chew, Chiau Ee <chiau.ee.chew@intel.com>
+Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+(cherry picked from commit 093e00bb3f82f3c67e2d1682e316fc012bcd0d92)
+
+Signed-off-by: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+---
+ drivers/pwm/pwm-lpss.c |  159 +++++++++++++++++++++++++++++++++++++++----------
+ 1 file changed, 129 insertions(+), 30 deletions(-)
+
+--- a/drivers/pwm/pwm-lpss.c
++++ b/drivers/pwm/pwm-lpss.c
+@@ -6,6 +6,7 @@
+  * Author: Chew Kean Ho <kean.ho.chew@intel.com>
+  * Author: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+  * Author: Chew Chiau Ee <chiau.ee.chew@intel.com>
++ * Author: Alan Cox <alan@linux.intel.com>
+  *
+  * This program is free software; you can redistribute it and/or modify
+  * it under the terms of the GNU General Public License version 2 as
+@@ -19,6 +20,9 @@
+ #include <linux/module.h>
+ #include <linux/pwm.h>
+ #include <linux/platform_device.h>
++#include <linux/pci.h>
++
++static int pci_drv, plat_drv; /* So we know which drivers registered */
+ #define PWM                           0x00000000
+ #define PWM_ENABLE                    BIT(31)
+@@ -34,6 +38,16 @@ struct pwm_lpss_chip {
+       struct pwm_chip chip;
+       void __iomem *regs;
+       struct clk *clk;
++      unsigned long clk_rate;
++};
++
++struct pwm_lpss_boardinfo {
++      unsigned long clk_rate;
++};
++
++/* BayTrail */
++static const struct pwm_lpss_boardinfo byt_info = {
++      25000000
+ };
+ static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip)
+@@ -55,7 +69,7 @@ static int pwm_lpss_config(struct pwm_ch
+       /* The equation is: base_unit = ((freq / c) * 65536) + correction */
+       base_unit = freq * 65536;
+-      c = clk_get_rate(lpwm->clk);
++      c = lpwm->clk_rate;
+       if (!c)
+               return -EINVAL;
+@@ -113,52 +127,48 @@ static const struct pwm_ops pwm_lpss_ops
+       .owner = THIS_MODULE,
+ };
+-static const struct acpi_device_id pwm_lpss_acpi_match[] = {
+-      { "80860F09", 0 },
+-      { },
+-};
+-MODULE_DEVICE_TABLE(acpi, pwm_lpss_acpi_match);
+-
+-static int pwm_lpss_probe(struct platform_device *pdev)
++static struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev,
++                                          struct resource *r,
++                                          struct pwm_lpss_boardinfo *info)
+ {
+       struct pwm_lpss_chip *lpwm;
+-      struct resource *r;
+       int ret;
+-      lpwm = devm_kzalloc(&pdev->dev, sizeof(*lpwm), GFP_KERNEL);
++      lpwm = devm_kzalloc(dev, sizeof(*lpwm), GFP_KERNEL);
+       if (!lpwm)
+-              return -ENOMEM;
++              return ERR_PTR(-ENOMEM);
+-      r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-
+-      lpwm->regs = devm_ioremap_resource(&pdev->dev, r);
++      lpwm->regs = devm_ioremap_resource(dev, r);
+       if (IS_ERR(lpwm->regs))
+-              return PTR_ERR(lpwm->regs);
++              return lpwm->regs;
+-      lpwm->clk = devm_clk_get(&pdev->dev, NULL);
+-      if (IS_ERR(lpwm->clk)) {
+-              dev_err(&pdev->dev, "failed to get PWM clock\n");
+-              return PTR_ERR(lpwm->clk);
++      if (info) {
++              lpwm->clk_rate = info->clk_rate;
++      } else {
++              lpwm->clk = devm_clk_get(dev, NULL);
++              if (IS_ERR(lpwm->clk)) {
++                      dev_err(dev, "failed to get PWM clock\n");
++                      return ERR_CAST(lpwm->clk);
++              }
++              lpwm->clk_rate = clk_get_rate(lpwm->clk);
+       }
+-      lpwm->chip.dev = &pdev->dev;
++      lpwm->chip.dev = dev;
+       lpwm->chip.ops = &pwm_lpss_ops;
+       lpwm->chip.base = -1;
+       lpwm->chip.npwm = 1;
+       ret = pwmchip_add(&lpwm->chip);
+       if (ret) {
+-              dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
+-              return ret;
++              dev_err(dev, "failed to add PWM chip: %d\n", ret);
++              return ERR_PTR(ret);
+       }
+-      platform_set_drvdata(pdev, lpwm);
+-      return 0;
++      return lpwm;
+ }
+-static int pwm_lpss_remove(struct platform_device *pdev)
++static int pwm_lpss_remove(struct pwm_lpss_chip *lpwm)
+ {
+-      struct pwm_lpss_chip *lpwm = platform_get_drvdata(pdev);
+       u32 ctrl;
+       ctrl = readl(lpwm->regs + PWM);
+@@ -167,15 +177,104 @@ static int pwm_lpss_remove(struct platfo
+       return pwmchip_remove(&lpwm->chip);
+ }
+-static struct platform_driver pwm_lpss_driver = {
++static int pwm_lpss_probe_pci(struct pci_dev *pdev,
++                            const struct pci_device_id *id)
++{
++      const struct pwm_lpss_boardinfo *info;
++      struct pwm_lpss_chip *lpwm;
++      int err;
++
++      err = pci_enable_device(pdev);
++      if (err < 0)
++              return err;
++
++      info = (struct pwm_lpss_boardinfo *)id->driver_data;
++      lpwm = pwm_lpss_probe(&pdev->dev, &pdev->resource[0], info);
++      if (IS_ERR(lpwm))
++              return PTR_ERR(lpwm);
++
++      pci_set_drvdata(pdev, lpwm);
++      return 0;
++}
++
++static void pwm_lpss_remove_pci(struct pci_dev *pdev)
++{
++      struct pwm_lpss_chip *lpwm = pci_get_drvdata(pdev);
++
++      pwm_lpss_remove(lpwm);
++      pci_disable_device(pdev);
++}
++
++static struct pci_device_id pwm_lpss_pci_ids[] = {
++      { PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&byt_info},
++      { PCI_VDEVICE(INTEL, 0x0f09), (unsigned long)&byt_info},
++      { },
++};
++MODULE_DEVICE_TABLE(pci, pwm_lpss_pci_ids);
++
++static struct pci_driver pwm_lpss_driver_pci = {
++      .name = "pwm-lpss",
++      .id_table = pwm_lpss_pci_ids,
++      .probe = pwm_lpss_probe_pci,
++      .remove = pwm_lpss_remove_pci,
++};
++
++static int pwm_lpss_probe_platform(struct platform_device *pdev)
++{
++      struct pwm_lpss_chip *lpwm;
++      struct resource *r;
++
++      r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++      lpwm = pwm_lpss_probe(&pdev->dev, r, NULL);
++      if (IS_ERR(lpwm))
++              return PTR_ERR(lpwm);
++
++      platform_set_drvdata(pdev, lpwm);
++      return 0;
++}
++
++static int pwm_lpss_remove_platform(struct platform_device *pdev)
++{
++      struct pwm_lpss_chip *lpwm = platform_get_drvdata(pdev);
++
++      return pwm_lpss_remove(lpwm);
++}
++
++static const struct acpi_device_id pwm_lpss_acpi_match[] = {
++      { "80860F09", 0 },
++      { },
++};
++MODULE_DEVICE_TABLE(acpi, pwm_lpss_acpi_match);
++
++static struct platform_driver pwm_lpss_driver_platform = {
+       .driver = {
+               .name = "pwm-lpss",
+               .acpi_match_table = pwm_lpss_acpi_match,
+       },
+-      .probe = pwm_lpss_probe,
+-      .remove = pwm_lpss_remove,
++      .probe = pwm_lpss_probe_platform,
++      .remove = pwm_lpss_remove_platform,
+ };
+-module_platform_driver(pwm_lpss_driver);
++
++static int __init pwm_init(void)
++{
++      pci_drv = pci_register_driver(&pwm_lpss_driver_pci);
++      plat_drv = platform_driver_register(&pwm_lpss_driver_platform);
++      if (pci_drv && plat_drv)
++              return pci_drv;
++
++      return 0;
++}
++module_init(pwm_init);
++
++static void __exit pwm_exit(void)
++{
++      if (!pci_drv)
++              pci_unregister_driver(&pwm_lpss_driver_pci);
++      if (!plat_drv)
++              platform_driver_unregister(&pwm_lpss_driver_platform);
++}
++module_exit(pwm_exit);
+ MODULE_DESCRIPTION("PWM driver for Intel LPSS");
+ MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
diff --git a/patches.intel/pwm-lpss-fix-build-failure-on-powerpc.patch b/patches.intel/pwm-lpss-fix-build-failure-on-powerpc.patch
new file mode 100644 (file)
index 0000000..0fb414b
--- /dev/null
@@ -0,0 +1,35 @@
+From ltsi-dev-bounces@lists.linuxfoundation.org Wed Oct 29 09:53:58 2014
+From: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Date: Wed, 29 Oct 2014 08:52:57 +0800
+Subject: [LTSI-dev]  [PATCH 7/8] pwm: lpss: Fix build failure on PowerPC
+To: LTSI Mailing List <ltsi-dev@lists.linuxfoundation.org>
+Cc: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Message-ID: <1414543978-24145-8-git-send-email-rebecca.swee.fun.chang@intel.com>
+
+
+From: Thierry Reding <thierry.reding@gmail.com>
+
+An x86 build seems to pull in the linux/io.h include indirectly. On
+PowerPC that doesn't happen and the build breaks due to the readl() and
+writel() functions not being declared. Fix this by explicitly including
+linux/io.h.
+
+Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+(cherry picked from commit e0c86a3b63e948e51a47d17382c7cd8711d19750)
+
+Signed-off-by: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+---
+ drivers/pwm/pwm-lpss.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/pwm/pwm-lpss.c
++++ b/drivers/pwm/pwm-lpss.c
+@@ -13,6 +13,7 @@
+  * published by the Free Software Foundation.
+  */
++#include <linux/io.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
diff --git a/patches.intel/pwm-lpss-fix-const-qualifier-and-sparse-warnings.patch b/patches.intel/pwm-lpss-fix-const-qualifier-and-sparse-warnings.patch
new file mode 100644 (file)
index 0000000..225b391
--- /dev/null
@@ -0,0 +1,64 @@
+From ltsi-dev-bounces@lists.linuxfoundation.org Wed Oct 29 09:53:43 2014
+From: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Date: Wed, 29 Oct 2014 08:52:53 +0800
+Subject: [LTSI-dev] [PATCH 3/8] pwm: lpss: Fix const qualifier and sparse warnings
+To: LTSI Mailing List <ltsi-dev@lists.linuxfoundation.org>
+Cc: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Message-ID: <1414543978-24145-4-git-send-email-rebecca.swee.fun.chang@intel.com>
+
+
+From: Thierry Reding <thierry.reding@gmail.com>
+
+Fixes the following warnings reported by the 0-DAY kernel build testing
+backend:
+
+   drivers/pwm/pwm-lpss.c: In function 'pwm_lpss_probe_pci':
+>> drivers/pwm/pwm-lpss.c:192:2: warning: passing argument 3 of 'pwm_lpss_probe' discards 'const' qualifier from pointer target type [enabled by default]
+     lpwm = pwm_lpss_probe(&pdev->dev, &pdev->resource[0], info);
+     ^
+   drivers/pwm/pwm-lpss.c:130:30: note: expected 'struct pwm_lpss_boardinfo *' but argument is of type 'const struct pwm_lpss_boardinfo *'
+    static struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev,
+                                 ^
+>> drivers/pwm/pwm-lpss.c:143:28: sparse: incorrect type in return expression (different address spaces)
+   drivers/pwm/pwm-lpss.c:143:28:    expected struct pwm_lpss_chip *
+   drivers/pwm/pwm-lpss.c:143:28:    got void [noderef] <asn:2>*regs
+>> drivers/pwm/pwm-lpss.c:192:63: sparse: incorrect type in argument 3 (different modifiers)
+   drivers/pwm/pwm-lpss.c:192:63:    expected struct pwm_lpss_boardinfo *info
+   drivers/pwm/pwm-lpss.c:192:63:    got struct pwm_lpss_boardinfo const *[assigned] info
+   drivers/pwm/pwm-lpss.c: In function 'pwm_lpss_probe_pci':
+   drivers/pwm/pwm-lpss.c:192:2: warning: passing argument 3 of 'pwm_lpss_probe' discards 'const' qualifier from pointer target type [enabled by default]
+     lpwm = pwm_lpss_probe(&pdev->dev, &pdev->resource[0], info);
+     ^
+   drivers/pwm/pwm-lpss.c:130:30: note: expected 'struct pwm_lpss_boardinfo *' but argument is of type 'const struct pwm_lpss_boardinfo *'
+    static struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev,
+                                 ^
+
+Reported-by: kbuild test robot <fengguang.wu@intel.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+(cherry picked from commit 89c0339e0aa097384b3efed894b23820814c21d3)
+
+Signed-off-by: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+---
+ drivers/pwm/pwm-lpss.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/pwm/pwm-lpss.c
++++ b/drivers/pwm/pwm-lpss.c
+@@ -129,7 +129,7 @@ static const struct pwm_ops pwm_lpss_ops
+ static struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev,
+                                           struct resource *r,
+-                                          struct pwm_lpss_boardinfo *info)
++                                          const struct pwm_lpss_boardinfo *info)
+ {
+       struct pwm_lpss_chip *lpwm;
+       int ret;
+@@ -140,7 +140,7 @@ static struct pwm_lpss_chip *pwm_lpss_pr
+       lpwm->regs = devm_ioremap_resource(dev, r);
+       if (IS_ERR(lpwm->regs))
+-              return lpwm->regs;
++              return ERR_CAST(lpwm->regs);
+       if (info) {
+               lpwm->clk_rate = info->clk_rate;
diff --git a/patches.intel/pwm-lpss-properly-split-driver-to-parts.patch b/patches.intel/pwm-lpss-properly-split-driver-to-parts.patch
new file mode 100644 (file)
index 0000000..1d0fc80
--- /dev/null
@@ -0,0 +1,446 @@
+From ltsi-dev-bounces@lists.linuxfoundation.org Wed Oct 29 09:53:55 2014
+From: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Date: Wed, 29 Oct 2014 08:52:56 +0800
+Subject: [LTSI-dev]  [PATCH 6/8] pwm: lpss: Properly split driver to parts
+To: LTSI Mailing List <ltsi-dev@lists.linuxfoundation.org>
+Cc: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Message-ID: <1414543978-24145-7-git-send-email-rebecca.swee.fun.chang@intel.com>
+
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+The driver consists of core, PCI, and platform parts. It would be better
+to split them into separate files.
+
+The platform driver is now called pwm-lpss-platform. Thus, previously
+set CONFIG_PWM_LPSS=m is not enough to build it. But we are on the safe
+side since it seems no one from outside Intel is using it for now.
+
+While here, move to use macros module_pci_driver() and
+module_platform_driver().
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Acked-by: Alan Cox <alan@linux.intel.com>
+[thierry.reding: change select to depends on PWM_LPSS, cleanup]
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+(cherry picked from commit c558e39e14c2372394f49e07fbe94e9708b615cb)
+
+Signed-off-by: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+---
+ drivers/pwm/Kconfig             |   19 +++++
+ drivers/pwm/Makefile            |    2 
+ drivers/pwm/pwm-lpss-pci.c      |   65 +++++++++++++++++++
+ drivers/pwm/pwm-lpss-platform.c |   68 ++++++++++++++++++++
+ drivers/pwm/pwm-lpss.c          |  136 ++--------------------------------------
+ drivers/pwm/pwm-lpss.h          |   32 +++++++++
+ 6 files changed, 195 insertions(+), 127 deletions(-)
+ create mode 100644 drivers/pwm/pwm-lpss-pci.c
+ create mode 100644 drivers/pwm/pwm-lpss-platform.c
+ create mode 100644 drivers/pwm/pwm-lpss.h
+
+--- a/drivers/pwm/Kconfig
++++ b/drivers/pwm/Kconfig
+@@ -121,7 +121,6 @@ config PWM_LPC32XX
+ config PWM_LPSS
+       tristate "Intel LPSS PWM support"
+-      depends on ACPI
+       help
+         Generic PWM framework driver for Intel Low Power Subsystem PWM
+         controller.
+@@ -129,6 +128,24 @@ config PWM_LPSS
+         To compile this driver as a module, choose M here: the module
+         will be called pwm-lpss.
++config PWM_LPSS_PCI
++      tristate "Intel LPSS PWM PCI driver"
++      depends on PWM_LPSS && PCI
++      help
++        The PCI driver for Intel Low Power Subsystem PWM controller.
++
++        To compile this driver as a module, choose M here: the module
++        will be called pwm-lpss-pci.
++
++config PWM_LPSS_PLATFORM
++      tristate "Intel LPSS PWM platform driver"
++      depends on PWM_LPSS && ACPI
++      help
++        The platform driver for Intel Low Power Subsystem PWM controller.
++
++        To compile this driver as a module, choose M here: the module
++        will be called pwm-lpss-platform.
++
+ config PWM_MXS
+       tristate "Freescale MXS PWM support"
+       depends on ARCH_MXS && OF
+--- a/drivers/pwm/Makefile
++++ b/drivers/pwm/Makefile
+@@ -10,6 +10,8 @@ obj-$(CONFIG_PWM_JZ4740)     += pwm-jz4740.o
+ obj-$(CONFIG_PWM_LP3943)      += pwm-lp3943.o
+ obj-$(CONFIG_PWM_LPC32XX)     += pwm-lpc32xx.o
+ obj-$(CONFIG_PWM_LPSS)                += pwm-lpss.o
++obj-$(CONFIG_PWM_LPSS_PCI)    += pwm-lpss-pci.o
++obj-$(CONFIG_PWM_LPSS_PLATFORM)       += pwm-lpss-platform.o
+ obj-$(CONFIG_PWM_MXS)         += pwm-mxs.o
+ obj-$(CONFIG_PWM_PCA9685)     += pwm-pca9685.o
+ obj-$(CONFIG_PWM_PUV3)                += pwm-puv3.o
+--- /dev/null
++++ b/drivers/pwm/pwm-lpss-pci.c
+@@ -0,0 +1,65 @@
++/*
++ * Intel Low Power Subsystem PWM controller PCI driver
++ *
++ * Copyright (C) 2014, Intel Corporation
++ *
++ * Derived from the original pwm-lpss.c
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/pci.h>
++
++#include "pwm-lpss.h"
++
++static int pwm_lpss_probe_pci(struct pci_dev *pdev,
++                            const struct pci_device_id *id)
++{
++      const struct pwm_lpss_boardinfo *info;
++      struct pwm_lpss_chip *lpwm;
++      int err;
++
++      err = pci_enable_device(pdev);
++      if (err < 0)
++              return err;
++
++      info = (struct pwm_lpss_boardinfo *)id->driver_data;
++      lpwm = pwm_lpss_probe(&pdev->dev, &pdev->resource[0], info);
++      if (IS_ERR(lpwm))
++              return PTR_ERR(lpwm);
++
++      pci_set_drvdata(pdev, lpwm);
++      return 0;
++}
++
++static void pwm_lpss_remove_pci(struct pci_dev *pdev)
++{
++      struct pwm_lpss_chip *lpwm = pci_get_drvdata(pdev);
++
++      pwm_lpss_remove(lpwm);
++      pci_disable_device(pdev);
++}
++
++static const struct pci_device_id pwm_lpss_pci_ids[] = {
++      { PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&pwm_lpss_byt_info},
++      { PCI_VDEVICE(INTEL, 0x0f09), (unsigned long)&pwm_lpss_byt_info},
++      { PCI_VDEVICE(INTEL, 0x2288), (unsigned long)&pwm_lpss_bsw_info},
++      { PCI_VDEVICE(INTEL, 0x2289), (unsigned long)&pwm_lpss_bsw_info},
++      { },
++};
++MODULE_DEVICE_TABLE(pci, pwm_lpss_pci_ids);
++
++static struct pci_driver pwm_lpss_driver_pci = {
++      .name = "pwm-lpss",
++      .id_table = pwm_lpss_pci_ids,
++      .probe = pwm_lpss_probe_pci,
++      .remove = pwm_lpss_remove_pci,
++};
++module_pci_driver(pwm_lpss_driver_pci);
++
++MODULE_DESCRIPTION("PWM PCI driver for Intel LPSS");
++MODULE_LICENSE("GPL v2");
+--- /dev/null
++++ b/drivers/pwm/pwm-lpss-platform.c
+@@ -0,0 +1,68 @@
++/*
++ * Intel Low Power Subsystem PWM controller driver
++ *
++ * Copyright (C) 2014, Intel Corporation
++ *
++ * Derived from the original pwm-lpss.c
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/acpi.h>
++#include <linux/kernel.h>
++#include <linux/module.h>
++#include <linux/platform_device.h>
++
++#include "pwm-lpss.h"
++
++static int pwm_lpss_probe_platform(struct platform_device *pdev)
++{
++      const struct pwm_lpss_boardinfo *info;
++      const struct acpi_device_id *id;
++      struct pwm_lpss_chip *lpwm;
++      struct resource *r;
++
++      id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
++      if (!id)
++              return -ENODEV;
++
++      info = (const struct pwm_lpss_boardinfo *)id->driver_data;
++      r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++
++      lpwm = pwm_lpss_probe(&pdev->dev, r, info);
++      if (IS_ERR(lpwm))
++              return PTR_ERR(lpwm);
++
++      platform_set_drvdata(pdev, lpwm);
++      return 0;
++}
++
++static int pwm_lpss_remove_platform(struct platform_device *pdev)
++{
++      struct pwm_lpss_chip *lpwm = platform_get_drvdata(pdev);
++
++      return pwm_lpss_remove(lpwm);
++}
++
++static const struct acpi_device_id pwm_lpss_acpi_match[] = {
++      { "80860F09", (unsigned long)&pwm_lpss_byt_info },
++      { "80862288", (unsigned long)&pwm_lpss_bsw_info },
++      { },
++};
++MODULE_DEVICE_TABLE(acpi, pwm_lpss_acpi_match);
++
++static struct platform_driver pwm_lpss_driver_platform = {
++      .driver = {
++              .name = "pwm-lpss",
++              .acpi_match_table = pwm_lpss_acpi_match,
++      },
++      .probe = pwm_lpss_probe_platform,
++      .remove = pwm_lpss_remove_platform,
++};
++module_platform_driver(pwm_lpss_driver_platform);
++
++MODULE_DESCRIPTION("PWM platform driver for Intel LPSS");
++MODULE_LICENSE("GPL v2");
++MODULE_ALIAS("platform:pwm-lpss");
+--- a/drivers/pwm/pwm-lpss.c
++++ b/drivers/pwm/pwm-lpss.c
+@@ -13,15 +13,10 @@
+  * published by the Free Software Foundation.
+  */
+-#include <linux/acpi.h>
+-#include <linux/device.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+-#include <linux/pwm.h>
+-#include <linux/platform_device.h>
+-#include <linux/pci.h>
+-static int pci_drv, plat_drv; /* So we know which drivers registered */
++#include "pwm-lpss.h"
+ #define PWM                           0x00000000
+ #define PWM_ENABLE                    BIT(31)
+@@ -39,19 +34,17 @@ struct pwm_lpss_chip {
+       unsigned long clk_rate;
+ };
+-struct pwm_lpss_boardinfo {
+-      unsigned long clk_rate;
+-};
+-
+ /* BayTrail */
+-static const struct pwm_lpss_boardinfo byt_info = {
++const struct pwm_lpss_boardinfo pwm_lpss_byt_info = {
+       25000000
+ };
++EXPORT_SYMBOL_GPL(pwm_lpss_byt_info);
+ /* Braswell */
+-static const struct pwm_lpss_boardinfo bsw_info = {
++const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
+       19200000
+ };
++EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info);
+ static inline struct pwm_lpss_chip *to_lpwm(struct pwm_chip *chip)
+ {
+@@ -123,9 +116,8 @@ static const struct pwm_ops pwm_lpss_ops
+       .owner = THIS_MODULE,
+ };
+-static struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev,
+-                                          struct resource *r,
+-                                          const struct pwm_lpss_boardinfo *info)
++struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
++                                   const struct pwm_lpss_boardinfo *info)
+ {
+       struct pwm_lpss_chip *lpwm;
+       int ret;
+@@ -152,8 +144,9 @@ static struct pwm_lpss_chip *pwm_lpss_pr
+       return lpwm;
+ }
++EXPORT_SYMBOL_GPL(pwm_lpss_probe);
+-static int pwm_lpss_remove(struct pwm_lpss_chip *lpwm)
++int pwm_lpss_remove(struct pwm_lpss_chip *lpwm)
+ {
+       u32 ctrl;
+@@ -162,117 +155,8 @@ static int pwm_lpss_remove(struct pwm_lp
+       return pwmchip_remove(&lpwm->chip);
+ }
+-
+-static int pwm_lpss_probe_pci(struct pci_dev *pdev,
+-                            const struct pci_device_id *id)
+-{
+-      const struct pwm_lpss_boardinfo *info;
+-      struct pwm_lpss_chip *lpwm;
+-      int err;
+-
+-      err = pci_enable_device(pdev);
+-      if (err < 0)
+-              return err;
+-
+-      info = (struct pwm_lpss_boardinfo *)id->driver_data;
+-      lpwm = pwm_lpss_probe(&pdev->dev, &pdev->resource[0], info);
+-      if (IS_ERR(lpwm))
+-              return PTR_ERR(lpwm);
+-
+-      pci_set_drvdata(pdev, lpwm);
+-      return 0;
+-}
+-
+-static void pwm_lpss_remove_pci(struct pci_dev *pdev)
+-{
+-      struct pwm_lpss_chip *lpwm = pci_get_drvdata(pdev);
+-
+-      pwm_lpss_remove(lpwm);
+-      pci_disable_device(pdev);
+-}
+-
+-static struct pci_device_id pwm_lpss_pci_ids[] = {
+-      { PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&byt_info},
+-      { PCI_VDEVICE(INTEL, 0x0f09), (unsigned long)&byt_info},
+-      { PCI_VDEVICE(INTEL, 0x2288), (unsigned long)&bsw_info},
+-      { PCI_VDEVICE(INTEL, 0x2289), (unsigned long)&bsw_info},
+-      { },
+-};
+-MODULE_DEVICE_TABLE(pci, pwm_lpss_pci_ids);
+-
+-static struct pci_driver pwm_lpss_driver_pci = {
+-      .name = "pwm-lpss",
+-      .id_table = pwm_lpss_pci_ids,
+-      .probe = pwm_lpss_probe_pci,
+-      .remove = pwm_lpss_remove_pci,
+-};
+-
+-static int pwm_lpss_probe_platform(struct platform_device *pdev)
+-{
+-      const struct pwm_lpss_boardinfo *info;
+-      const struct acpi_device_id *id;
+-      struct pwm_lpss_chip *lpwm;
+-      struct resource *r;
+-
+-      id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
+-      if (!id)
+-              return -ENODEV;
+-
+-      r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-
+-      info = (struct pwm_lpss_boardinfo *)id->driver_data;
+-      lpwm = pwm_lpss_probe(&pdev->dev, r, info);
+-      if (IS_ERR(lpwm))
+-              return PTR_ERR(lpwm);
+-
+-      platform_set_drvdata(pdev, lpwm);
+-      return 0;
+-}
+-
+-static int pwm_lpss_remove_platform(struct platform_device *pdev)
+-{
+-      struct pwm_lpss_chip *lpwm = platform_get_drvdata(pdev);
+-
+-      return pwm_lpss_remove(lpwm);
+-}
+-
+-static const struct acpi_device_id pwm_lpss_acpi_match[] = {
+-      { "80860F09", (unsigned long)&byt_info },
+-      { "80862288", (unsigned long)&bsw_info },
+-      { },
+-};
+-MODULE_DEVICE_TABLE(acpi, pwm_lpss_acpi_match);
+-
+-static struct platform_driver pwm_lpss_driver_platform = {
+-      .driver = {
+-              .name = "pwm-lpss",
+-              .acpi_match_table = pwm_lpss_acpi_match,
+-      },
+-      .probe = pwm_lpss_probe_platform,
+-      .remove = pwm_lpss_remove_platform,
+-};
+-
+-static int __init pwm_init(void)
+-{
+-      pci_drv = pci_register_driver(&pwm_lpss_driver_pci);
+-      plat_drv = platform_driver_register(&pwm_lpss_driver_platform);
+-      if (pci_drv && plat_drv)
+-              return pci_drv;
+-
+-      return 0;
+-}
+-module_init(pwm_init);
+-
+-static void __exit pwm_exit(void)
+-{
+-      if (!pci_drv)
+-              pci_unregister_driver(&pwm_lpss_driver_pci);
+-      if (!plat_drv)
+-              platform_driver_unregister(&pwm_lpss_driver_platform);
+-}
+-module_exit(pwm_exit);
++EXPORT_SYMBOL_GPL(pwm_lpss_remove);
+ MODULE_DESCRIPTION("PWM driver for Intel LPSS");
+ MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
+ MODULE_LICENSE("GPL v2");
+-MODULE_ALIAS("platform:pwm-lpss");
+--- /dev/null
++++ b/drivers/pwm/pwm-lpss.h
+@@ -0,0 +1,32 @@
++/*
++ * Intel Low Power Subsystem PWM controller driver
++ *
++ * Copyright (C) 2014, Intel Corporation
++ *
++ * Derived from the original pwm-lpss.c
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __PWM_LPSS_H
++#define __PWM_LPSS_H
++
++#include <linux/device.h>
++#include <linux/pwm.h>
++
++struct pwm_lpss_chip;
++
++struct pwm_lpss_boardinfo {
++      unsigned long clk_rate;
++};
++
++extern const struct pwm_lpss_boardinfo pwm_lpss_byt_info;
++extern const struct pwm_lpss_boardinfo pwm_lpss_bsw_info;
++
++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);
++
++#endif        /* __PWM_LPSS_H */
diff --git a/patches.intel/pwm-lpss-remove-dependency-on-clk-framework.patch b/patches.intel/pwm-lpss-remove-dependency-on-clk-framework.patch
new file mode 100644 (file)
index 0000000..1ee2e1b
--- /dev/null
@@ -0,0 +1,116 @@
+From ltsi-dev-bounces@lists.linuxfoundation.org Wed Oct 29 09:53:47 2014
+From: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Date: Wed, 29 Oct 2014 08:52:54 +0800
+Subject: [LTSI-dev] [PATCH 4/8] pwm: lpss: remove dependency on clk framework
+To: LTSI Mailing List <ltsi-dev@lists.linuxfoundation.org>
+Cc: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Message-ID: <1414543978-24145-5-git-send-email-rebecca.swee.fun.chang@intel.com>
+
+
+From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+
+Unlike other Intel LPSS devices, the PWM does not have the
+clock dividers or the gate. All we get from the clock is the
+rate. Since PCI case uses the driver data to get the rate,
+we can drop the clk and use the same data also in case of
+ACPI. The frequency is the same.
+
+Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Reviewed-by: Chew, Chiau Ee <chiau.ee.chew@intel.com>
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+(cherry picked from commit 65accd87381ed96bf8893124b149bae08edd2740)
+
+Signed-off-by: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+---
+ drivers/pwm/pwm-lpss.c |   32 ++++++++++----------------------
+ 1 file changed, 10 insertions(+), 22 deletions(-)
+
+--- a/drivers/pwm/pwm-lpss.c
++++ b/drivers/pwm/pwm-lpss.c
+@@ -14,7 +14,6 @@
+  */
+ #include <linux/acpi.h>
+-#include <linux/clk.h>
+ #include <linux/device.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+@@ -37,7 +36,6 @@ static int pci_drv, plat_drv;        /* So we k
+ struct pwm_lpss_chip {
+       struct pwm_chip chip;
+       void __iomem *regs;
+-      struct clk *clk;
+       unsigned long clk_rate;
+ };
+@@ -97,11 +95,6 @@ static int pwm_lpss_enable(struct pwm_ch
+ {
+       struct pwm_lpss_chip *lpwm = to_lpwm(chip);
+       u32 ctrl;
+-      int ret;
+-
+-      ret = clk_prepare_enable(lpwm->clk);
+-      if (ret)
+-              return ret;
+       ctrl = readl(lpwm->regs + PWM);
+       writel(ctrl | PWM_ENABLE, lpwm->regs + PWM);
+@@ -116,8 +109,6 @@ static void pwm_lpss_disable(struct pwm_
+       ctrl = readl(lpwm->regs + PWM);
+       writel(ctrl & ~PWM_ENABLE, lpwm->regs + PWM);
+-
+-      clk_disable_unprepare(lpwm->clk);
+ }
+ static const struct pwm_ops pwm_lpss_ops = {
+@@ -142,17 +133,7 @@ static struct pwm_lpss_chip *pwm_lpss_pr
+       if (IS_ERR(lpwm->regs))
+               return ERR_CAST(lpwm->regs);
+-      if (info) {
+-              lpwm->clk_rate = info->clk_rate;
+-      } else {
+-              lpwm->clk = devm_clk_get(dev, NULL);
+-              if (IS_ERR(lpwm->clk)) {
+-                      dev_err(dev, "failed to get PWM clock\n");
+-                      return ERR_CAST(lpwm->clk);
+-              }
+-              lpwm->clk_rate = clk_get_rate(lpwm->clk);
+-      }
+-
++      lpwm->clk_rate = info->clk_rate;
+       lpwm->chip.dev = dev;
+       lpwm->chip.ops = &pwm_lpss_ops;
+       lpwm->chip.base = -1;
+@@ -221,12 +202,19 @@ static struct pci_driver pwm_lpss_driver
+ static int pwm_lpss_probe_platform(struct platform_device *pdev)
+ {
++      const struct pwm_lpss_boardinfo *info;
++      const struct acpi_device_id *id;
+       struct pwm_lpss_chip *lpwm;
+       struct resource *r;
++      id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
++      if (!id)
++              return -ENODEV;
++
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-      lpwm = pwm_lpss_probe(&pdev->dev, r, NULL);
++      info = (struct pwm_lpss_boardinfo *)id->driver_data;
++      lpwm = pwm_lpss_probe(&pdev->dev, r, info);
+       if (IS_ERR(lpwm))
+               return PTR_ERR(lpwm);
+@@ -242,7 +230,7 @@ static int pwm_lpss_remove_platform(stru
+ }
+ static const struct acpi_device_id pwm_lpss_acpi_match[] = {
+-      { "80860F09", 0 },
++      { "80860F09", (unsigned long)&byt_info },
+       { },
+ };
+ MODULE_DEVICE_TABLE(acpi, pwm_lpss_acpi_match);
diff --git a/patches.intel/pwm-lpss-use-c99-initializers-in-structures.patch b/patches.intel/pwm-lpss-use-c99-initializers-in-structures.patch
new file mode 100644 (file)
index 0000000..d9c587e
--- /dev/null
@@ -0,0 +1,68 @@
+From ltsi-dev-bounces@lists.linuxfoundation.org Wed Oct 29 09:54:01 2014
+From: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Date: Wed, 29 Oct 2014 08:52:58 +0800
+Subject: [LTSI-dev] [PATCH 8/8] pwm: lpss: use c99 initializers in structures
+To: LTSI Mailing List <ltsi-dev@lists.linuxfoundation.org>
+Cc: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+Message-ID: <1414543978-24145-9-git-send-email-rebecca.swee.fun.chang@intel.com>
+
+
+From: Julia Lawall <Julia.Lawall@lip6.fr>
+
+Use c99 initializers for structures.
+
+A simplified version of the semantic match that finds this problem is as
+follows: (http://coccinelle.lip6.fr/)
+
+// <smpl>
+@decl@
+identifier i1,fld;
+type T;
+field list[n] fs;
+@@
+
+struct i1 {
+ fs
+ T fld;
+ ...};
+
+@bad@
+identifier decl.i1,i2;
+expression e;
+initializer list[decl.n] is;
+@@
+
+struct i1 i2 = { is,
++ .fld = e
+- e
+ ,...};
+// </smpl>
+
+Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
+[thierry.reding: rebased and applied same fix for Braswell]
+Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
+(cherry picked from commit b2b7adeb21745266326d453b95e5d0b1b9cb1d4e)
+
+Signed-off-by: Chang Rebecca Swee Fun <rebecca.swee.fun.chang@intel.com>
+---
+ drivers/pwm/pwm-lpss.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/pwm/pwm-lpss.c
++++ b/drivers/pwm/pwm-lpss.c
+@@ -37,13 +37,13 @@ struct pwm_lpss_chip {
+ /* BayTrail */
+ const struct pwm_lpss_boardinfo pwm_lpss_byt_info = {
+-      25000000
++      .clk_rate = 25000000
+ };
+ EXPORT_SYMBOL_GPL(pwm_lpss_byt_info);
+ /* Braswell */
+ const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
+-      19200000
++      .clk_rate = 19200000
+ };
+ EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info);
diff --git a/series b/series
index b0e657eca2d567e34001b10f74a9fd283fead7bc..f1daeae41f7efca491acb689b9abb4beff69373b 100644 (file)
--- a/series
+++ b/series
@@ -1015,6 +1015,20 @@ patches.renesas/0973-i2c-rcar-fix-RCAR_IRQ_ACK_-RECV-SEND.patch
 patches.renesas/0001-clk-add-clock-indices-support.patch
 patches.renesas/0002-of-fdt-update-of_get_flat_dt_prop-in-prep-for-libfdt.patch
 
+
+#############################################################################
+# Intel patches
+#
+patches.intel/pwm-add-support-for-intel-low-power-subsystem-pwm.patch
+patches.intel/pwm-lpss-add-support-for-pci-devices.patch
+patches.intel/pwm-lpss-fix-const-qualifier-and-sparse-warnings.patch
+patches.intel/pwm-lpss-remove-dependency-on-clk-framework.patch
+patches.intel/pwm-lpss-add-acpi-and-pci-ids-for-intel-braswell.patch
+patches.intel/pwm-lpss-properly-split-driver-to-parts.patch
+patches.intel/pwm-lpss-fix-build-failure-on-powerpc.patch
+patches.intel/pwm-lpss-use-c99-initializers-in-structures.patch
+
+
 #############################################################################
 # fixes that go after all of the above
 #