From b445692ae1f7f615e501632baf8e5babb28a7497 Mon Sep 17 00:00:00 2001 From: "Philip, Avinash" Date: Thu, 6 Sep 2012 10:44:25 +0530 Subject: [PATCH] --- yaml --- r: 322923 b: refs/heads/master c: 01b2d4536f0215c6d97d77e157afee04300ffc90 h: refs/heads/master i: 322921: 9ce8551a28fb89a2ce73ef9be49c582552cd9d9f 322919: 8016617063e0c7e3428ad7555985b6f6bc49bcda v: v3 --- [refs] | 2 +- trunk/drivers/pwm/pwm-tiehrpwm.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 1cc80f5ac257..ff5ba8688a51 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c06fad9d28c95b024ea10455cf1397432b12848d +refs/heads/master: 01b2d4536f0215c6d97d77e157afee04300ffc90 diff --git a/trunk/drivers/pwm/pwm-tiehrpwm.c b/trunk/drivers/pwm/pwm-tiehrpwm.c index c3756d1be194..b1996bcd5b78 100644 --- a/trunk/drivers/pwm/pwm-tiehrpwm.c +++ b/trunk/drivers/pwm/pwm-tiehrpwm.c @@ -104,6 +104,7 @@ struct ehrpwm_pwm_chip { struct pwm_chip chip; unsigned int clk_rate; void __iomem *mmio_base; + unsigned long period_cycles[NUM_PWM_CHANNEL]; }; static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) @@ -210,6 +211,7 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, unsigned long long c; unsigned long period_cycles, duty_cycles; unsigned short ps_divval, tb_divval; + int i; if (period_ns < 0 || duty_ns < 0 || period_ns > NSEC_PER_SEC) return -ERANGE; @@ -229,6 +231,28 @@ static int ehrpwm_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, duty_cycles = (unsigned long)c; } + /* + * Period values should be same for multiple PWM channels as IP uses + * same period register for multiple channels. + */ + for (i = 0; i < NUM_PWM_CHANNEL; i++) { + if (pc->period_cycles[i] && + (pc->period_cycles[i] != period_cycles)) { + /* + * Allow channel to reconfigure period if no other + * channels being configured. + */ + if (i == pwm->hwpwm) + continue; + + dev_err(chip->dev, "Period value conflicts with channel %d\n", + i); + return -EINVAL; + } + } + + pc->period_cycles[pwm->hwpwm] = period_cycles; + /* Configure clock prescaler to support Low frequency PWM wave */ if (set_prescale_div(period_cycles/PERIOD_MAX, &ps_divval, &tb_divval)) { @@ -320,10 +344,15 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) { + struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); + if (test_bit(PWMF_ENABLED, &pwm->flags)) { dev_warn(chip->dev, "Removing PWM device without disabling\n"); pm_runtime_put_sync(chip->dev); } + + /* set period value to zero on free */ + pc->period_cycles[pwm->hwpwm] = 0; } static const struct pwm_ops ehrpwm_pwm_ops = {