summaryrefslogtreecommitdiffstats
path: root/drivers/pwm/pwm-tiehrpwm.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-09-24 18:07:48 +0200
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-09-24 18:17:12 +0200
commit398b7a1b882a655ee84bd985f6c2ba89082404ae (patch)
tree5eb9284a87ee2a45a10809cfbe3a66fea6ea53ae /drivers/pwm/pwm-tiehrpwm.c
parent57df2ae9df6e335a98969cac5aafb09c4de10bb2 (diff)
parent979570e02981d4a8fc20b3cc8fd651856c98ee9d (diff)
Merge tag 'v3.6-rc7' into drm-intel-next-queued
Manual backmerge of -rc7 to resolve a silent conflict leading to compile failure in drivers/gpu/drm/i915/intel_hdmi.c. This is due to the bugfix in -rc7: commit b98b60167279df3acac9422c3c9820d9ebbcf9fb Author: Wang Xingchao <xingchao.wang@intel.com> Date: Thu Sep 13 07:43:22 2012 +0800 drm/i915: HDMI - Clear Audio Enable bit for Hot Plug Since this code moved around a lot in -next git put that snippet at the wrong spot. I've tried to fix this by making the conflict explicit by merging a version for next with: commit 3cce574f0190dd149472059fb69267cf83d290f9 Author: Wang Xingchao <xingchao.wang@intel.com> Date: Thu Sep 13 11:19:00 2012 +0800 drm/i915: HDMI - Clear Audio Enable bit for Hot Plug unconditionally But that failed to solve the entire problem. To avoid pushing out further -nightly branch to our QA where this is broken, do the backmerge and manually add the stuff git adds to -next from the patch in -fixes. Note that this doesn't show up in git's merge diff (and hence is also not handled by git rerere), which adds to the reasons why I'd like to fix this with a verbose backmerge. The git merge diff only shows a bunch of trivial conflicts of the "code changed in lines next to each another" kind. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/pwm/pwm-tiehrpwm.c')
-rw-r--r--drivers/pwm/pwm-tiehrpwm.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index c3756d1be19..b1996bcd5b7 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/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 = {