[ARM] pxa: move pwm.c to common plat-pxa directory
authorEric Miao <eric.miao@marvell.com>
Mon, 13 Apr 2009 08:28:02 +0000 (16:28 +0800)
committerEric Miao <eric.y.miao@gmail.com>
Fri, 5 Jun 2009 02:32:04 +0000 (10:32 +0800)
Signed-off-by: Eric Miao <eric.miao@marvell.com>
arch/arm/mach-pxa/Makefile
arch/arm/mach-pxa/pwm.c [deleted file]
arch/arm/plat-pxa/Makefile
arch/arm/plat-pxa/pwm.c [new file with mode: 0644]

index 4bcebf72074a2110473e2155ddfa7290cc7670f8..47d01572a04d87b8e555aba287c141b71c743c10 100644 (file)
@@ -15,7 +15,6 @@ endif
 
 # Generic drivers that other drivers may depend upon
 obj-$(CONFIG_PXA_SSP)          += ssp.o
-obj-$(CONFIG_HAVE_PWM)         += pwm.o
 
 # SoC-specific code
 obj-$(CONFIG_PXA25x)           += mfp-pxa2xx.o pxa2xx.o pxa25x.o
diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/mach-pxa/pwm.c
deleted file mode 100644 (file)
index 5513c51..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-/*
- * linux/arch/arm/mach-pxa/pwm.c
- *
- * simple driver for PWM (Pulse Width Modulator) controller
- *
- * 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.
- *
- * 2008-02-13  initial version
- *             eric miao <eric.miao@marvell.com>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/pwm.h>
-
-#include <asm/div64.h>
-
-#define HAS_SECONDARY_PWM      0x10
-#define PWM_ID_BASE(d)         ((d) & 0xf)
-
-static const struct platform_device_id pwm_id_table[] = {
-       /*   PWM    has_secondary_pwm? */
-       { "pxa25x-pwm", 0 },
-       { "pxa27x-pwm", 0 | HAS_SECONDARY_PWM },
-       { },
-};
-MODULE_DEVICE_TABLE(platform, pwm_id_table);
-
-/* PWM registers and bits definitions */
-#define PWMCR          (0x00)
-#define PWMDCR         (0x04)
-#define PWMPCR         (0x08)
-
-#define PWMCR_SD       (1 << 6)
-#define PWMDCR_FD      (1 << 10)
-
-struct pwm_device {
-       struct list_head        node;
-       struct pwm_device       *secondary;
-       struct platform_device  *pdev;
-
-       const char      *label;
-       struct clk      *clk;
-       int             clk_enabled;
-       void __iomem    *mmio_base;
-
-       unsigned int    use_count;
-       unsigned int    pwm_id;
-};
-
-/*
- * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE
- * duty_ns   = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE
- */
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
-       unsigned long long c;
-       unsigned long period_cycles, prescale, pv, dc;
-
-       if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
-               return -EINVAL;
-
-       c = clk_get_rate(pwm->clk);
-       c = c * period_ns;
-       do_div(c, 1000000000);
-       period_cycles = c;
-
-       if (period_cycles < 1)
-               period_cycles = 1;
-       prescale = (period_cycles - 1) / 1024;
-       pv = period_cycles / (prescale + 1) - 1;
-
-       if (prescale > 63)
-               return -EINVAL;
-
-       if (duty_ns == period_ns)
-               dc = PWMDCR_FD;
-       else
-               dc = (pv + 1) * duty_ns / period_ns;
-
-       /* NOTE: the clock to PWM has to be enabled first
-        * before writing to the registers
-        */
-       clk_enable(pwm->clk);
-       __raw_writel(prescale, pwm->mmio_base + PWMCR);
-       __raw_writel(dc, pwm->mmio_base + PWMDCR);
-       __raw_writel(pv, pwm->mmio_base + PWMPCR);
-       clk_disable(pwm->clk);
-
-       return 0;
-}
-EXPORT_SYMBOL(pwm_config);
-
-int pwm_enable(struct pwm_device *pwm)
-{
-       int rc = 0;
-
-       if (!pwm->clk_enabled) {
-               rc = clk_enable(pwm->clk);
-               if (!rc)
-                       pwm->clk_enabled = 1;
-       }
-       return rc;
-}
-EXPORT_SYMBOL(pwm_enable);
-
-void pwm_disable(struct pwm_device *pwm)
-{
-       if (pwm->clk_enabled) {
-               clk_disable(pwm->clk);
-               pwm->clk_enabled = 0;
-       }
-}
-EXPORT_SYMBOL(pwm_disable);
-
-static DEFINE_MUTEX(pwm_lock);
-static LIST_HEAD(pwm_list);
-
-struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
-       struct pwm_device *pwm;
-       int found = 0;
-
-       mutex_lock(&pwm_lock);
-
-       list_for_each_entry(pwm, &pwm_list, node) {
-               if (pwm->pwm_id == pwm_id) {
-                       found = 1;
-                       break;
-               }
-       }
-
-       if (found) {
-               if (pwm->use_count == 0) {
-                       pwm->use_count++;
-                       pwm->label = label;
-               } else
-                       pwm = ERR_PTR(-EBUSY);
-       } else
-               pwm = ERR_PTR(-ENOENT);
-
-       mutex_unlock(&pwm_lock);
-       return pwm;
-}
-EXPORT_SYMBOL(pwm_request);
-
-void pwm_free(struct pwm_device *pwm)
-{
-       mutex_lock(&pwm_lock);
-
-       if (pwm->use_count) {
-               pwm->use_count--;
-               pwm->label = NULL;
-       } else
-               pr_warning("PWM device already freed\n");
-
-       mutex_unlock(&pwm_lock);
-}
-EXPORT_SYMBOL(pwm_free);
-
-static inline void __add_pwm(struct pwm_device *pwm)
-{
-       mutex_lock(&pwm_lock);
-       list_add_tail(&pwm->node, &pwm_list);
-       mutex_unlock(&pwm_lock);
-}
-
-static int __devinit pwm_probe(struct platform_device *pdev)
-{
-       struct platform_device_id *id = platform_get_device_id(pdev);
-       struct pwm_device *pwm, *secondary = NULL;
-       struct resource *r;
-       int ret = 0;
-
-       pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
-       if (pwm == NULL) {
-               dev_err(&pdev->dev, "failed to allocate memory\n");
-               return -ENOMEM;
-       }
-
-       pwm->clk = clk_get(&pdev->dev, NULL);
-       if (IS_ERR(pwm->clk)) {
-               ret = PTR_ERR(pwm->clk);
-               goto err_free;
-       }
-       pwm->clk_enabled = 0;
-
-       pwm->use_count = 0;
-       pwm->pwm_id = PWM_ID_BASE(id->driver_data) + pdev->id;
-       pwm->pdev = pdev;
-
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (r == NULL) {
-               dev_err(&pdev->dev, "no memory resource defined\n");
-               ret = -ENODEV;
-               goto err_free_clk;
-       }
-
-       r = request_mem_region(r->start, r->end - r->start + 1, pdev->name);
-       if (r == NULL) {
-               dev_err(&pdev->dev, "failed to request memory resource\n");
-               ret = -EBUSY;
-               goto err_free_clk;
-       }
-
-       pwm->mmio_base = ioremap(r->start, r->end - r->start + 1);
-       if (pwm->mmio_base == NULL) {
-               dev_err(&pdev->dev, "failed to ioremap() registers\n");
-               ret = -ENODEV;
-               goto err_free_mem;
-       }
-
-       if (id->driver_data & HAS_SECONDARY_PWM) {
-               secondary = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
-               if (secondary == NULL) {
-                       ret = -ENOMEM;
-                       goto err_free_mem;
-               }
-
-               *secondary = *pwm;
-               pwm->secondary = secondary;
-
-               /* registers for the second PWM has offset of 0x10 */
-               secondary->mmio_base = pwm->mmio_base + 0x10;
-               secondary->pwm_id = pdev->id + 2;
-       }
-
-       __add_pwm(pwm);
-       if (secondary)
-               __add_pwm(secondary);
-
-       platform_set_drvdata(pdev, pwm);
-       return 0;
-
-err_free_mem:
-       release_mem_region(r->start, r->end - r->start + 1);
-err_free_clk:
-       clk_put(pwm->clk);
-err_free:
-       kfree(pwm);
-       return ret;
-}
-
-static int __devexit pwm_remove(struct platform_device *pdev)
-{
-       struct pwm_device *pwm;
-       struct resource *r;
-
-       pwm = platform_get_drvdata(pdev);
-       if (pwm == NULL)
-               return -ENODEV;
-
-       mutex_lock(&pwm_lock);
-
-       if (pwm->secondary) {
-               list_del(&pwm->secondary->node);
-               kfree(pwm->secondary);
-       }
-
-       list_del(&pwm->node);
-       mutex_unlock(&pwm_lock);
-
-       iounmap(pwm->mmio_base);
-
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       release_mem_region(r->start, r->end - r->start + 1);
-
-       clk_put(pwm->clk);
-       kfree(pwm);
-       return 0;
-}
-
-static struct platform_driver pwm_driver = {
-       .driver         = {
-               .name   = "pxa25x-pwm",
-               .owner  = THIS_MODULE,
-       },
-       .probe          = pwm_probe,
-       .remove         = __devexit_p(pwm_remove),
-       .id_table       = pwm_id_table,
-};
-
-static int __init pwm_init(void)
-{
-       return platform_driver_register(&pwm_driver);
-}
-arch_initcall(pwm_init);
-
-static void __exit pwm_exit(void)
-{
-       platform_driver_unregister(&pwm_driver);
-}
-module_exit(pwm_exit);
-
-MODULE_LICENSE("GPL v2");
index 8f2c4c7fbd480ffc2318b4df7a6dc6c6cc710497..0264bfb0ca4f24254d59bc9cf5ff5e1a0f9bbdae 100644 (file)
@@ -7,3 +7,5 @@ obj-y   := dma.o
 obj-$(CONFIG_GENERIC_GPIO)     += gpio.o
 obj-$(CONFIG_PXA3xx)           += mfp.o
 obj-$(CONFIG_ARCH_MMP)         += mfp.o
+
+obj-$(CONFIG_HAVE_PWM)         += pwm.o
diff --git a/arch/arm/plat-pxa/pwm.c b/arch/arm/plat-pxa/pwm.c
new file mode 100644 (file)
index 0000000..5513c51
--- /dev/null
@@ -0,0 +1,301 @@
+/*
+ * linux/arch/arm/mach-pxa/pwm.c
+ *
+ * simple driver for PWM (Pulse Width Modulator) controller
+ *
+ * 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.
+ *
+ * 2008-02-13  initial version
+ *             eric miao <eric.miao@marvell.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/pwm.h>
+
+#include <asm/div64.h>
+
+#define HAS_SECONDARY_PWM      0x10
+#define PWM_ID_BASE(d)         ((d) & 0xf)
+
+static const struct platform_device_id pwm_id_table[] = {
+       /*   PWM    has_secondary_pwm? */
+       { "pxa25x-pwm", 0 },
+       { "pxa27x-pwm", 0 | HAS_SECONDARY_PWM },
+       { },
+};
+MODULE_DEVICE_TABLE(platform, pwm_id_table);
+
+/* PWM registers and bits definitions */
+#define PWMCR          (0x00)
+#define PWMDCR         (0x04)
+#define PWMPCR         (0x08)
+
+#define PWMCR_SD       (1 << 6)
+#define PWMDCR_FD      (1 << 10)
+
+struct pwm_device {
+       struct list_head        node;
+       struct pwm_device       *secondary;
+       struct platform_device  *pdev;
+
+       const char      *label;
+       struct clk      *clk;
+       int             clk_enabled;
+       void __iomem    *mmio_base;
+
+       unsigned int    use_count;
+       unsigned int    pwm_id;
+};
+
+/*
+ * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE
+ * duty_ns   = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE
+ */
+int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
+{
+       unsigned long long c;
+       unsigned long period_cycles, prescale, pv, dc;
+
+       if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
+               return -EINVAL;
+
+       c = clk_get_rate(pwm->clk);
+       c = c * period_ns;
+       do_div(c, 1000000000);
+       period_cycles = c;
+
+       if (period_cycles < 1)
+               period_cycles = 1;
+       prescale = (period_cycles - 1) / 1024;
+       pv = period_cycles / (prescale + 1) - 1;
+
+       if (prescale > 63)
+               return -EINVAL;
+
+       if (duty_ns == period_ns)
+               dc = PWMDCR_FD;
+       else
+               dc = (pv + 1) * duty_ns / period_ns;
+
+       /* NOTE: the clock to PWM has to be enabled first
+        * before writing to the registers
+        */
+       clk_enable(pwm->clk);
+       __raw_writel(prescale, pwm->mmio_base + PWMCR);
+       __raw_writel(dc, pwm->mmio_base + PWMDCR);
+       __raw_writel(pv, pwm->mmio_base + PWMPCR);
+       clk_disable(pwm->clk);
+
+       return 0;
+}
+EXPORT_SYMBOL(pwm_config);
+
+int pwm_enable(struct pwm_device *pwm)
+{
+       int rc = 0;
+
+       if (!pwm->clk_enabled) {
+               rc = clk_enable(pwm->clk);
+               if (!rc)
+                       pwm->clk_enabled = 1;
+       }
+       return rc;
+}
+EXPORT_SYMBOL(pwm_enable);
+
+void pwm_disable(struct pwm_device *pwm)
+{
+       if (pwm->clk_enabled) {
+               clk_disable(pwm->clk);
+               pwm->clk_enabled = 0;
+       }
+}
+EXPORT_SYMBOL(pwm_disable);
+
+static DEFINE_MUTEX(pwm_lock);
+static LIST_HEAD(pwm_list);
+
+struct pwm_device *pwm_request(int pwm_id, const char *label)
+{
+       struct pwm_device *pwm;
+       int found = 0;
+
+       mutex_lock(&pwm_lock);
+
+       list_for_each_entry(pwm, &pwm_list, node) {
+               if (pwm->pwm_id == pwm_id) {
+                       found = 1;
+                       break;
+               }
+       }
+
+       if (found) {
+               if (pwm->use_count == 0) {
+                       pwm->use_count++;
+                       pwm->label = label;
+               } else
+                       pwm = ERR_PTR(-EBUSY);
+       } else
+               pwm = ERR_PTR(-ENOENT);
+
+       mutex_unlock(&pwm_lock);
+       return pwm;
+}
+EXPORT_SYMBOL(pwm_request);
+
+void pwm_free(struct pwm_device *pwm)
+{
+       mutex_lock(&pwm_lock);
+
+       if (pwm->use_count) {
+               pwm->use_count--;
+               pwm->label = NULL;
+       } else
+               pr_warning("PWM device already freed\n");
+
+       mutex_unlock(&pwm_lock);
+}
+EXPORT_SYMBOL(pwm_free);
+
+static inline void __add_pwm(struct pwm_device *pwm)
+{
+       mutex_lock(&pwm_lock);
+       list_add_tail(&pwm->node, &pwm_list);
+       mutex_unlock(&pwm_lock);
+}
+
+static int __devinit pwm_probe(struct platform_device *pdev)
+{
+       struct platform_device_id *id = platform_get_device_id(pdev);
+       struct pwm_device *pwm, *secondary = NULL;
+       struct resource *r;
+       int ret = 0;
+
+       pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
+       if (pwm == NULL) {
+               dev_err(&pdev->dev, "failed to allocate memory\n");
+               return -ENOMEM;
+       }
+
+       pwm->clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(pwm->clk)) {
+               ret = PTR_ERR(pwm->clk);
+               goto err_free;
+       }
+       pwm->clk_enabled = 0;
+
+       pwm->use_count = 0;
+       pwm->pwm_id = PWM_ID_BASE(id->driver_data) + pdev->id;
+       pwm->pdev = pdev;
+
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (r == NULL) {
+               dev_err(&pdev->dev, "no memory resource defined\n");
+               ret = -ENODEV;
+               goto err_free_clk;
+       }
+
+       r = request_mem_region(r->start, r->end - r->start + 1, pdev->name);
+       if (r == NULL) {
+               dev_err(&pdev->dev, "failed to request memory resource\n");
+               ret = -EBUSY;
+               goto err_free_clk;
+       }
+
+       pwm->mmio_base = ioremap(r->start, r->end - r->start + 1);
+       if (pwm->mmio_base == NULL) {
+               dev_err(&pdev->dev, "failed to ioremap() registers\n");
+               ret = -ENODEV;
+               goto err_free_mem;
+       }
+
+       if (id->driver_data & HAS_SECONDARY_PWM) {
+               secondary = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
+               if (secondary == NULL) {
+                       ret = -ENOMEM;
+                       goto err_free_mem;
+               }
+
+               *secondary = *pwm;
+               pwm->secondary = secondary;
+
+               /* registers for the second PWM has offset of 0x10 */
+               secondary->mmio_base = pwm->mmio_base + 0x10;
+               secondary->pwm_id = pdev->id + 2;
+       }
+
+       __add_pwm(pwm);
+       if (secondary)
+               __add_pwm(secondary);
+
+       platform_set_drvdata(pdev, pwm);
+       return 0;
+
+err_free_mem:
+       release_mem_region(r->start, r->end - r->start + 1);
+err_free_clk:
+       clk_put(pwm->clk);
+err_free:
+       kfree(pwm);
+       return ret;
+}
+
+static int __devexit pwm_remove(struct platform_device *pdev)
+{
+       struct pwm_device *pwm;
+       struct resource *r;
+
+       pwm = platform_get_drvdata(pdev);
+       if (pwm == NULL)
+               return -ENODEV;
+
+       mutex_lock(&pwm_lock);
+
+       if (pwm->secondary) {
+               list_del(&pwm->secondary->node);
+               kfree(pwm->secondary);
+       }
+
+       list_del(&pwm->node);
+       mutex_unlock(&pwm_lock);
+
+       iounmap(pwm->mmio_base);
+
+       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       release_mem_region(r->start, r->end - r->start + 1);
+
+       clk_put(pwm->clk);
+       kfree(pwm);
+       return 0;
+}
+
+static struct platform_driver pwm_driver = {
+       .driver         = {
+               .name   = "pxa25x-pwm",
+               .owner  = THIS_MODULE,
+       },
+       .probe          = pwm_probe,
+       .remove         = __devexit_p(pwm_remove),
+       .id_table       = pwm_id_table,
+};
+
+static int __init pwm_init(void)
+{
+       return platform_driver_register(&pwm_driver);
+}
+arch_initcall(pwm_init);
+
+static void __exit pwm_exit(void)
+{
+       platform_driver_unregister(&pwm_driver);
+}
+module_exit(pwm_exit);
+
+MODULE_LICENSE("GPL v2");