arm:omap:pwm - eCAP & ePWM driver in AM335X
authorPhilip, Avinash <avinashphilip@ti.com>
Mon, 20 Jun 2011 12:21:49 +0000 (17:51 +0530)
committerVaibhav Hiremath <hvaibhav@ti.com>
Mon, 23 Jan 2012 19:14:52 +0000 (00:44 +0530)
Unline with DA850, where each PWM module has individual clock,
AM335x SOC will be having common clock for ePWM, eCAP & eQEP which comes
under PWMSS instances. Clock gating is happening at configuration space
in PWMSS.
This patch modified eCAP & ePWM driver to support AM335X SOC as follows
1. Updated the clk_get() arguments to access common functional clock in
accordance with platform device id.
2. In AM335X SOC, PWMSS has a common config space for eCAP, ePWM & eQEP.
The clock gating to individual module has done from common config
space.So each module drivers should be able to access the common
configuration space independently. This patch provides a method to
access this common configuration space across each modules
independently. This method involves remapping the common config space
only on the first module in PWMSS. All the other modules in PWMSS uses
this remapped address to access the common configuration space. Clock
gating can be controlled on this common configuration space from
respective module. Protection mechanism is provided by
semaphore. Configuratin space unmapping is happening when the last
module is removed.
3. Config file support added for AM33XX_SOC

Signed-off-by: Philip, Avinash <avinashphilip@ti.com>
arch/arm/plat-omap/include/plat/config_pwm.h [new file with mode: 0644]
drivers/pwm/Kconfig
drivers/pwm/ecap.c
drivers/pwm/ehrpwm.c
include/linux/pwm/ehrpwm.h
include/linux/pwm/pwm.h

diff --git a/arch/arm/plat-omap/include/plat/config_pwm.h b/arch/arm/plat-omap/include/plat/config_pwm.h
new file mode 100644 (file)
index 0000000..a0c568a
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef __CONFIG_CONFIG_PWM
+#define __CONFIG_CONFIG_PWM
+
+#define AM33XX_CONFIG_BASE      (0x0)
+#define AM33XX_CONFIG_SIZE      (AM33XX_CONFIG_BASE + 0x10)
+#define AM33XX_ECAP_BASE        (0x0100)
+#define AM33XX_ECAP_SIZE        (AM33XX_ECAP_BASE + 0x080)
+#define AM33XX_EQEP_BASE        (0x0180)
+#define AM33XX_EQeP_SIZE        (AM33XX_EQEP_BASE + 0x080)
+#define AM33XX_EPWM_BASE        (0x0200)
+#define AM33XX_EPWM_SIZE        (AM33XX_EPWM_BASE + 0x0100)
+
+#define PWMSS_CLKCONFIG          (0x08)
+#define ECAP_CLK_EN              (0x0)
+#define ECAP_CLK_STOP_REQ        (0x1)
+#define EQEP_CLK_EN              (0x4)
+#define EQEP_CLK_STOP_REQ        (0x5)
+#define EPWM_CLK_EN              (0x8)
+#define EPWM_CLK_STOP_REQ        (0x9)
+
+#define SET                      (1)
+#define CLEAR                    (0)
+
+#define PWM_CON_ID_STRING_LENGTH (12)
+
+#endif
index c2205e36cfbfbaa365f08ff9578bb7b459b0a435..73c0db04a53573b98fec74980c4081f018d6c7de 100644 (file)
@@ -12,7 +12,7 @@ menuconfig GENERIC_PWM
 config DAVINCI_EHRPWM
        bool "Davinci eHRPWM support"
        select HAVE_PWM
-       depends on GENERIC_PWM && ARCH_DAVINCI_DA850
+       depends on GENERIC_PWM && (ARCH_DAVINCI_DA850 || SOC_OMAPAM33XX)
        help
          This option enables support for eHRPWM driver. If
          unsure, say N.
@@ -20,10 +20,10 @@ config DAVINCI_EHRPWM
 config ECAP_PWM
        tristate "eCAP PWM support"
        select HAVE_PWM
-       depends on GENERIC_PWM && ARCH_DAVINCI_DA850
+       depends on GENERIC_PWM && (ARCH_DAVINCI_DA850 || SOC_OMAPAM33XX)
        help
          This option enables device driver support for eCAP module found
-         on DA8xx Processors. eCAP module is used to geenrate wide range
-         of PWM waveforms. Maximum frequency generated is equal to half
-         the system clock frequency.
+         on DA8xx Processors & AM335x processor. eCAP module is used to
+         generate wide range of PWM waveforms. Maximum frequency generated
+         is equal to half the system clock frequency.
          Say Y to enable the eCAP support. If unsure, say N.
index 351d88dc812b59455d6f65bac06e16549f0295b2..3dd6f6da62058308c3163d1557d24a63a190944b 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 
 #include <plat/clock.h>
+#include <plat/config_pwm.h>
 
 #define TIMER_CTR_REG                  0x0
 #define CAPTURE_2_REG                  0x0c
@@ -43,6 +44,7 @@ struct ecap_pwm {
        struct clk      *clk;
        int     clk_enabled;
        void __iomem    *mmio_base;
+       u8 version;
 };
 
 static inline struct ecap_pwm *to_ecap_pwm(const struct pwm_device *p)
@@ -212,48 +214,110 @@ static int ecap_frequency_transition_cb(struct pwm_device *p)
                return 0;
 }
 
-static int __init ecap_probe(struct platform_device *pdev)
+static int ecap_probe(struct platform_device *pdev)
 {
        struct ecap_pwm *ep = NULL;
        struct resource *r;
        int ret = 0;
+       int val;
+       char con_id[PWM_CON_ID_STRING_LENGTH] = "epwmss";
+       struct pwmss_platform_data *pdata = (&pdev->dev)->platform_data;
 
        ep = kzalloc(sizeof(*ep), GFP_KERNEL);
+
        if (!ep) {
                dev_err(&pdev->dev, "failed to allocate memory\n");
                ret = -ENOMEM;
-               goto err_ecap_pwm_alloc;
+               goto err_mem_failure;
        }
 
-       ep->clk = clk_get(&pdev->dev, "ecap");
+       ep->version = pdata->version;
+
+       if (ep->version == PWM_VERSION_1) {
+               sprintf(con_id, "%s%d_%s", con_id, pdev->id, "fck");
+               ep->clk = clk_get(&pdev->dev, con_id);
+       } else
+               ep->clk = clk_get(&pdev->dev, "ecap");
+
        if (IS_ERR(ep->clk)) {
                ret = PTR_ERR(ep->clk);
-               goto err_free;
+               goto err_clock_failure;
+       }
+
+       if (ep->version == PWM_VERSION_1) {
+               down(&pdata->config_semaphore);
+               r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+               if (!r) {
+                       dev_err(&pdev->dev, "no memory resource defined\n");
+                       ret = -ENOMEM;
+                       up(&pdata->config_semaphore);
+                       goto err_resource_mem_failure;
+               }
+
+               r = request_mem_region(r->start, resource_size(r), pdev->name);
+
+               if (!r) {
+
+                       if (pdata->config_mem_base) {
+                               goto set_bit;
+                       } else {
+                               dev_err(&pdev->dev,
+                                       "failed to request memory resource\n");
+                               ret = -EBUSY;
+                               up(&pdata->config_semaphore);
+                               goto err_request_mem_failure;
+                       }
+               }
+
+               pdata->config_mem_base = ioremap(r->start, resource_size(r));
+
+               if (!pdata->config_mem_base) {
+
+                       dev_err(&pdev->dev, "failed to ioremap() registers\n");
+                       ret = -ENODEV;
+                       up(&pdata->config_semaphore);
+                       goto err_free_mem_config;
+               }
+
+set_bit:
+               pdata->pwmss_module_usage_count++;
+               clk_enable(ep->clk);
+               val = __raw_readw(pdata->config_mem_base + PWMSS_CLKCONFIG);
+               val |= BIT(ECAP_CLK_EN);
+               __raw_writew(val, pdata->config_mem_base + PWMSS_CLKCONFIG);
+               clk_disable(ep->clk);
+               up(&pdata->config_semaphore);
        }
 
        spin_lock_init(&ep->lock);
        ep->ops.config = ecap_pwm_config;
        ep->ops.request = ecap_pwm_request;
        ep->ops.freq_transition_notifier_cb = ecap_frequency_transition_cb;
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       if (ep->version == PWM_VERSION_1)
+               r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       else
+               r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
        if (!r) {
                dev_err(&pdev->dev, "no memory resource defined\n");
                ret = -ENODEV;
-               goto err_free_clk;
+               goto err_resource_mem2_failiure;
        }
 
        r = request_mem_region(r->start, resource_size(r), pdev->name);
        if (!r) {
                dev_err(&pdev->dev, "failed to request memory resource\n");
                ret = -EBUSY;
-               goto err_free_clk;
+               goto err_request_mem2_failure;
        }
 
        ep->mmio_base = ioremap(r->start, resource_size(r));
        if (!ep->mmio_base) {
                dev_err(&pdev->dev, "failed to ioremap() registers\n");
                ret = -ENODEV;
-               goto err_free_mem;
+               goto err_free_mem2;
        }
 
        ep->pwm.ops = &ep->ops;
@@ -262,13 +326,31 @@ static int __init ecap_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, ep);
        return 0;
 
-err_free_mem:
+err_free_mem2:
        release_mem_region(r->start, resource_size(r));
-err_free_clk:
+err_request_mem2_failure:
+err_resource_mem2_failiure:
+       if (ep->version == PWM_VERSION_1) {
+               down(&pdata->config_semaphore);
+               pdata->pwmss_module_usage_count--;
+
+               if (!pdata->pwmss_module_usage_count) {
+                       iounmap(pdata->config_mem_base);
+                       pdata->config_mem_base = NULL;
+               }
+               up(&pdata->config_semaphore);
+       }
+err_free_mem_config:
+       if (ep->version == PWM_VERSION_1) {
+               r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+               release_mem_region(r->start, resource_size(r));
+       }
+err_request_mem_failure:
+err_resource_mem_failure:
        clk_put(ep->clk);
-err_free:
+err_clock_failure:
        kfree(ep);
-err_ecap_pwm_alloc:
+err_mem_failure:
        return ret;
 }
 
@@ -301,10 +383,33 @@ static int __devexit ecap_remove(struct platform_device *pdev)
 {
        struct ecap_pwm *ep = platform_get_drvdata(pdev);
        struct resource *r;
+       struct pwmss_platform_data *pdata;
+       int val;
+
+       if (ep->version == PWM_VERSION_1) {
+               pdata = (&pdev->dev)->platform_data;
+               down(&pdata->config_semaphore);
+               pdata->pwmss_module_usage_count--;
+               val = __raw_readw(pdata->config_mem_base + PWMSS_CLKCONFIG);
+               val &= ~BIT(ECAP_CLK_EN);
+               __raw_writew(val, pdata->config_mem_base + PWMSS_CLKCONFIG);
+
+               if (!pdata->pwmss_module_usage_count) {
+                       iounmap(pdata->config_mem_base);
+                       pdata->config_mem_base = NULL;
+                       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+                       release_mem_region(r->start, resource_size(r));
+               }
+               up(&pdata->config_semaphore);
+       }
 
        pwm_unregister(&ep->pwm);
        iounmap(ep->mmio_base);
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       if (ep->version == PWM_VERSION_1)
+               r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       else
+               r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        release_mem_region(r->start, resource_size(r));
        platform_set_drvdata(pdev, NULL);
        clk_put(ep->clk);
index 879abf59200413ba77726b00bee7f3e1093fc8ad..d5600073c2b23dce1c4db0d90467dd76c1a94b33 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/pwm/ehrpwm.h>
 
 #include <plat/clock.h>
+#include <plat/config_pwm.h>
 
 #ifdef DEBUG
 #define debug(format, args...) printk(format, ##args)
 #define CMPAHR                         0x10
 #define HRCNFG                         0x1040
 
+#define AM335X_HRCNFG                  0x40
+
 #define HRCNFG_EDGEMD_MASK             (BIT(1) | BIT(0))
 #define HRCNFG_LDMD_POS                        0x3
 #define HRCNFG_CTLMD_POS               0x2
@@ -841,9 +844,21 @@ int ehrpwm_hr_config(struct pwm_device *p, unsigned char loadmode,
        if (loadmode > 1 || ctlmode > 1 || edgemode > 3)
                return -EINVAL;
 
-       ehrpwm_reg_config(ehrpwm, HRCNFG, loadmode << HRCNFG_LDMD_POS, BIT(3));
-       ehrpwm_reg_config(ehrpwm, HRCNFG, ctlmode << HRCNFG_CTLMD_POS, BIT(2));
-       ehrpwm_reg_config(ehrpwm, HRCNFG, edgemode, HRCNFG_EDGEMD_MASK);
+       if (ehrpwm->version == PWM_VERSION_1) {
+               ehrpwm_reg_config(ehrpwm, AM335X_HRCNFG,
+                               loadmode << HRCNFG_LDMD_POS, BIT(3));
+               ehrpwm_reg_config(ehrpwm, AM335X_HRCNFG,
+                               ctlmode << HRCNFG_CTLMD_POS, BIT(2));
+               ehrpwm_reg_config(ehrpwm, AM335X_HRCNFG,
+                               edgemode, HRCNFG_EDGEMD_MASK);
+       } else {
+               ehrpwm_reg_config(ehrpwm, HRCNFG,
+                               loadmode << HRCNFG_LDMD_POS, BIT(3));
+               ehrpwm_reg_config(ehrpwm, HRCNFG,
+                               ctlmode << HRCNFG_CTLMD_POS, BIT(2));
+               ehrpwm_reg_config(ehrpwm, HRCNFG,
+                               edgemode, HRCNFG_EDGEMD_MASK);
+       }
 
        return 0;
 }
@@ -854,8 +869,10 @@ inline int ehrpwm_reg_read(struct pwm_device *p, unsigned int reg,
 {
        struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);
 
-       if (reg > HRCNFG)
-               return -EINVAL;
+       if (!(ehrpwm->version == PWM_VERSION_1)) {
+               if (reg > HRCNFG)
+                       return -EINVAL;
+       }
 
        *val = ehrpwm_read(ehrpwm, reg);
 
@@ -868,8 +885,10 @@ inline int ehrpwm_reg_write(struct pwm_device *p, unsigned int reg,
 {
        struct ehrpwm_pwm *ehrpwm = to_ehrpwm_pwm(p);
 
-       if (reg > HRCNFG)
-               return -EINVAL;
+       if (!(ehrpwm->version == PWM_VERSION_1)) {
+               if (reg > HRCNFG)
+                       return -EINVAL;
+       }
 
        ehrpwm_write(ehrpwm, reg, val);
 
@@ -1065,7 +1084,11 @@ static int ehrpwm_hr_duty_config(struct pwm_device *p)
        cmphr_val = (cmphr_val * no_of_mepsteps) / 1000;
        cmphr_val = (cmphr_val << 8) + 0x180;
        ehrpwm_write(ehrpwm, CMPAHR, cmphr_val);
-       ehrpwm_write(ehrpwm, HRCNFG, 0x2);
+
+       if (ehrpwm->version == PWM_VERSION_1)
+               ehrpwm_write(ehrpwm, AM335X_HRCNFG, 0x2);
+       else
+               ehrpwm_write(ehrpwm, HRCNFG, 0x2);
 
        return 0;
 }
@@ -1090,7 +1113,10 @@ static int ehrpwm_pwm_set_dty(struct pwm_device *p)
        /* High resolution module */
        if (chan && ehrpwm->prescale_val <= 1) {
                ret = ehrpwm_hr_duty_config(p);
-               ehrpwm_write(ehrpwm, HRCNFG, 0x2);
+               if (ehrpwm->version == PWM_VERSION_1)
+                       ehrpwm_write(ehrpwm, AM335X_HRCNFG, 0x2);
+               else
+                       ehrpwm_write(ehrpwm, HRCNFG, 0x2);
        }
 
        ehrpwm_pwm_set_pol(p);
@@ -1293,46 +1319,107 @@ static int ehrpwm_probe(struct platform_device *pdev)
        int ret = 0;
        int chan = 0;
        struct pwmss_platform_data *pdata = (&pdev->dev)->platform_data;
-       int ch_mask;
+       int ch_mask = 0;
+       int val;
+       char con_id[PWM_CON_ID_STRING_LENGTH] = "epwmss";
 
-       ch_mask = pdata->channel_mask;
        ehrpwm = kzalloc(sizeof(*ehrpwm), GFP_KERNEL);
        if (!ehrpwm) {
                dev_err(&pdev->dev, "failed to allocate memory\n");
                ret = -ENOMEM;
-               return ret;
+               goto err_mem_failure;
        }
 
-       ehrpwm->clk = clk_get(&pdev->dev, "ehrpwm");
+       ehrpwm->version = pdata->version;
+
+       if (ehrpwm->version == PWM_VERSION_1) {
+               sprintf(con_id, "%s%d_%s", con_id, pdev->id, "fck");
+               ehrpwm->clk = clk_get(&pdev->dev, con_id);
+       } else
+               ehrpwm->clk = clk_get(&pdev->dev, "ehrpwm");
+
        if (IS_ERR(ehrpwm->clk)) {
                ret = PTR_ERR(ehrpwm->clk);
-               goto err_free_device;
+               goto err_clock_failure;
        }
 
+       if (ehrpwm->version == PWM_VERSION_1) {
+               down(&pdata->config_semaphore);
+               r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+               if (!r) {
+                       dev_err(&pdev->dev, "no memory resource defined\n");
+                       ret = -ENOMEM;
+                       up(&pdata->config_semaphore);
+                       goto err_resource_mem_failure;
+               }
+
+               r = request_mem_region(r->start, resource_size(r), pdev->name);
+
+               if (!r) {
+
+                       if (pdata->config_mem_base) {
+                               goto set_bit;
+                       } else {
+                               dev_err(&pdev->dev,
+                                       "failed to request memory resource\n");
+                               ret = -EBUSY;
+                               up(&pdata->config_semaphore);
+                               goto err_request_mem_failure;
+                       }
+               }
+
+               pdata->config_mem_base = ioremap(r->start, resource_size(r));
+
+               if (!pdata->config_mem_base) {
+
+                       dev_err(&pdev->dev, "failed to ioremap() registers\n");
+                       ret = -ENODEV;
+                       up(&pdata->config_semaphore);
+                       goto err_free_mem_config;
+               }
+
+set_bit:
+               pdata->pwmss_module_usage_count++;
+               clk_enable(ehrpwm->clk);
+               val = __raw_readw(pdata->config_mem_base + PWMSS_CLKCONFIG);
+               val |= BIT(EPWM_CLK_EN);
+               __raw_writew(val, pdata->config_mem_base + PWMSS_CLKCONFIG);
+               clk_disable(ehrpwm->clk);
+               up(&pdata->config_semaphore);
+
+       } else
+               ch_mask = pdata->channel_mask;
+
        spin_lock_init(&ehrpwm->lock);
        ehrpwm->ops.config = ehrpwm_pwm_config;
        ehrpwm->ops.request = ehrpwm_pwm_request;
        ehrpwm->ops.freq_transition_notifier_cb = ehrpwm_freq_transition_cb;
        ehrpwm->prescale_val = 1;
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       if (ehrpwm->version == PWM_VERSION_1)
+               r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       else
+               r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
        if (!r) {
                dev_err(&pdev->dev, "no memory resource defined\n");
                ret = -ENODEV;
-               goto err_free_clk;
+               goto err_resource_mem2_failiure;
        }
 
        r = request_mem_region(r->start, resource_size(r), pdev->name);
        if (!r) {
                dev_err(&pdev->dev, "failed to request memory resource\n");
                ret = -EBUSY;
-               goto err_free_clk;
+               goto err_request_mem2_failure;
        }
 
        ehrpwm->mmio_base = ioremap(r->start, resource_size(r));
        if (!ehrpwm->mmio_base) {
                dev_err(&pdev->dev, "failed to ioremap() registers\n");
                ret = -ENODEV;
-               goto err_free_mem;
+               goto err_free_mem2;
        }
 
        ehrpwm->irq[0] = platform_get_irq(pdev, 0);
@@ -1362,15 +1449,18 @@ static int ehrpwm_probe(struct platform_device *pdev)
        for (chan = 0; chan < NCHAN; chan++) {
                ehrpwm->pwm[chan].ops = &ehrpwm->ops;
                pwm_set_drvdata(&ehrpwm->pwm[chan], ehrpwm);
-               if (!(ch_mask & (0x1 << chan)))
-                       continue;
+
+               if (!(ehrpwm->version == PWM_VERSION_1)) {
+                       if (!(ch_mask & (0x1 << chan)))
+                               continue;
+               }
+
                ret =  pwm_register(&ehrpwm->pwm[chan], &pdev->dev, chan);
                if (ret)
                        goto err_pwm_register;
        }
 
                platform_set_drvdata(pdev, ehrpwm);
-
        return 0;
 
 err_pwm_register:
@@ -1384,12 +1474,31 @@ err_request_irq:
                free_irq(ehrpwm->irq[0], ehrpwm);
 err_free_io:
        iounmap(ehrpwm->mmio_base);
-err_free_mem:
+err_free_mem2:
        release_mem_region(r->start, resource_size(r));
-err_free_clk:
+err_request_mem2_failure:
+err_resource_mem2_failiure:
+       if (ehrpwm->version == PWM_VERSION_1) {
+               down(&pdata->config_semaphore);
+               pdata->pwmss_module_usage_count--;
+
+               if (!pdata->pwmss_module_usage_count) {
+                       iounmap(pdata->config_mem_base);
+                       pdata->config_mem_base = NULL;
+               }
+               up(&pdata->config_semaphore);
+       }
+err_free_mem_config:
+       if (ehrpwm->version == PWM_VERSION_1) {
+               r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+               release_mem_region(r->start, resource_size(r));
+       }
+err_request_mem_failure:
+err_resource_mem_failure:
        clk_put(ehrpwm->clk);
-err_free_device:
+err_clock_failure:
        kfree(ehrpwm);
+err_mem_failure:
        return ret;
 }
 
@@ -1423,6 +1532,25 @@ static int __devexit ehrpwm_remove(struct platform_device *pdev)
        struct ehrpwm_pwm *ehrpwm = platform_get_drvdata(pdev);
        struct resource *r;
        unsigned char i;
+       int val;
+       struct pwmss_platform_data *pdata;
+
+       if (ehrpwm->version == PWM_VERSION_1) {
+               pdata = (&pdev->dev)->platform_data;
+               down(&pdata->config_semaphore);
+               pdata->pwmss_module_usage_count--;
+               val = __raw_readw(pdata->config_mem_base + PWMSS_CLKCONFIG);
+               val &= ~BIT(EPWM_CLK_EN);
+               __raw_writew(val, pdata->config_mem_base + PWMSS_CLKCONFIG);
+
+               if (!pdata->pwmss_module_usage_count) {
+                       iounmap(pdata->config_mem_base);
+                       pdata->config_mem_base = NULL;
+                       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+                       release_mem_region(r->start, resource_size(r));
+               }
+               up(&pdata->config_semaphore);
+       }
 
        for (i = 0; i < NCHAN; i++) {
                if (pwm_is_registered(&ehrpwm->pwm[i]))
@@ -1433,7 +1561,12 @@ static int __devexit ehrpwm_remove(struct platform_device *pdev)
                if (ehrpwm->irq[i] != -ENXIO)
                        free_irq(ehrpwm->irq[i], ehrpwm);
        iounmap(ehrpwm->mmio_base);
-       r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       if (ehrpwm->version == PWM_VERSION_1)
+               r = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+       else
+               r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
        release_mem_region(r->start, resource_size(r));
        platform_set_drvdata(pdev, NULL);
        clk_put(ehrpwm->clk);
index d41e6f21ec4e8f52b96420c4da23dfc39ec74535..60d1e0c515a322a5d98d558f6f1172f1a0050662 100644 (file)
@@ -29,6 +29,7 @@ struct ehrpwm_pwm {
        int irq[2];
        struct et_int st_etint;
        struct tz_int st_tzint;
+       u8 version;
 };
 
 enum tz_event {
index cebea993616d981a6f8ea0b45c37293c2e84dbb9..76b57a3d983aea876a93eb9529694203bbcf28b2 100644 (file)
@@ -105,8 +105,19 @@ struct pwm_device {
        spinlock_t pwm_lock;
 };
 
+#include <linux/semaphore.h>
+
+enum {
+       PWM_VERSION_0,
+       PWM_VERSION_1,
+};
+
 struct pwmss_platform_data {
        int channel_mask;
+       struct semaphore config_semaphore;
+       int pwmss_module_usage_count;
+       void *config_mem_base;
+       u8 version;
 };
 
 struct pwm_device *pwm_request_byname(const char *name, const char *label);