aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAjit Pal Singh <ajitpal.singh@st.com>2014-07-14 10:33:32 -0400
committerThierry Reding <thierry.reding@gmail.com>2014-08-08 07:12:46 -0400
commit3aacd3e1879a5359ce1483b82c9cdd31ebb348b7 (patch)
tree3815ccf96d227ce82f6beba55bc527e797925b09
parent6ad6b838e11d8d67950716e0715b1d71bdd0769e (diff)
pwm: sti: Remove PWM period table
Removes the PWM period table. Instead the prescaler is computed from the period value passed in the config() function. Signed-off-by: Ajit Pal Singh <ajitpal.singh@st.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
-rw-r--r--drivers/pwm/pwm-sti.c64
1 files changed, 16 insertions, 48 deletions
diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c
index f98afe4906fb..b95115cdaea7 100644
--- a/drivers/pwm/pwm-sti.c
+++ b/drivers/pwm/pwm-sti.c
@@ -10,7 +10,6 @@
10 * (at your option) any later version. 10 * (at your option) any later version.
11 */ 11 */
12 12
13#include <linux/bsearch.h>
14#include <linux/clk.h> 13#include <linux/clk.h>
15#include <linux/math64.h> 14#include <linux/math64.h>
16#include <linux/mfd/syscon.h> 15#include <linux/mfd/syscon.h>
@@ -56,7 +55,6 @@ struct sti_pwm_chip {
56 struct regmap_field *prescale_high; 55 struct regmap_field *prescale_high;
57 struct regmap_field *pwm_en; 56 struct regmap_field *pwm_en;
58 struct regmap_field *pwm_int_en; 57 struct regmap_field *pwm_int_en;
59 unsigned long *pwm_periods;
60 struct pwm_chip chip; 58 struct pwm_chip chip;
61 struct pwm_device *cur; 59 struct pwm_device *cur;
62 unsigned int en_count; 60 unsigned int en_count;
@@ -77,29 +75,31 @@ static inline struct sti_pwm_chip *to_sti_pwmchip(struct pwm_chip *chip)
77} 75}
78 76
79/* 77/*
80 * Calculate the period values supported by the PWM for the 78 * Calculate the prescaler value corresponding to the period.
81 * current clock rate.
82 */ 79 */
83static void sti_pwm_calc_periods(struct sti_pwm_chip *pc) 80static int sti_pwm_get_prescale(struct sti_pwm_chip *pc, unsigned long period,
81 unsigned int *prescale)
84{ 82{
85 struct sti_pwm_compat_data *cdata = pc->cdata; 83 struct sti_pwm_compat_data *cdata = pc->cdata;
86 struct device *dev = pc->dev;
87 unsigned long val; 84 unsigned long val;
88 int i; 85 unsigned int ps;
89 86
90 /* 87 /*
91 * period_ns = (10^9 * (prescaler + 1) * (MAX_PWM_COUNT + 1)) / CLK_RATE 88 * prescale = ((period_ns * clk_rate) / (10^9 * (max_pwm_count + 1)) - 1
92 */ 89 */
93 val = NSEC_PER_SEC / pc->clk_rate; 90 val = NSEC_PER_SEC / pc->clk_rate;
94 val *= cdata->max_pwm_cnt + 1; 91 val *= cdata->max_pwm_cnt + 1;
95 92
96 dev_dbg(dev, "possible periods for clkrate[HZ]:%lu\n", pc->clk_rate); 93 if (period % val) {
97 94 return -EINVAL;
98 for (i = 0; i <= cdata->max_prescale; i++) { 95 } else {
99 pc->pwm_periods[i] = val * (i + 1); 96 ps = period / val - 1;
100 dev_dbg(dev, "prescale:%d, period[ns]:%lu\n", 97 if (ps > cdata->max_prescale)
101 i, pc->pwm_periods[i]); 98 return -EINVAL;
102 } 99 }
100 *prescale = ps;
101
102 return 0;
103} 103}
104 104
105/* Calculate the number of PWM devices configured with a period. */ 105/* Calculate the number of PWM devices configured with a period. */
@@ -120,17 +120,6 @@ static unsigned int sti_pwm_count_configured(struct pwm_chip *chip)
120 return ncfg; 120 return ncfg;
121} 121}
122 122
123static int sti_pwm_cmp_periods(const void *key, const void *elt)
124{
125 unsigned long i = *(unsigned long *)key;
126 unsigned long j = *(unsigned long *)elt;
127
128 if (i < j)
129 return -1;
130 else
131 return i == j ? 0 : 1;
132}
133
134/* 123/*
135 * For STiH4xx PWM IP, the PWM period is fixed to 256 local clock cycles. 124 * For STiH4xx PWM IP, the PWM period is fixed to 256 local clock cycles.
136 * The only way to change the period (apart from changing the PWM input clock) 125 * The only way to change the period (apart from changing the PWM input clock)
@@ -148,7 +137,6 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
148 struct pwm_device *cur = pc->cur; 137 struct pwm_device *cur = pc->cur;
149 struct device *dev = pc->dev; 138 struct device *dev = pc->dev;
150 unsigned int prescale = 0, pwmvalx; 139 unsigned int prescale = 0, pwmvalx;
151 unsigned long *found;
152 int ret; 140 int ret;
153 unsigned int ncfg; 141 unsigned int ncfg;
154 bool period_same = false; 142 bool period_same = false;
@@ -178,21 +166,9 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
178 return ret; 166 return ret;
179 167
180 if (!period_same) { 168 if (!period_same) {
181 /* 169 ret = sti_pwm_get_prescale(pc, period_ns, &prescale);
182 * Search for matching period value. 170 if (ret)
183 * The corresponding index is our prescale value.
184 */
185 found = bsearch(&period_ns, &pc->pwm_periods[0],
186 cdata->max_prescale + 1,
187 sizeof(unsigned long),
188 sti_pwm_cmp_periods);
189 if (!found) {
190 dev_err(dev,
191 "failed to find matching period\n");
192 ret = -EINVAL;
193 goto clk_dis; 171 goto clk_dis;
194 }
195 prescale = found - &pc->pwm_periods[0];
196 172
197 ret = 173 ret =
198 regmap_field_write(pc->prescale_low, 174 regmap_field_write(pc->prescale_low,
@@ -373,12 +349,6 @@ static int sti_pwm_probe(struct platform_device *pdev)
373 if (ret) 349 if (ret)
374 return ret; 350 return ret;
375 351
376 pc->pwm_periods = devm_kzalloc(dev,
377 sizeof(unsigned long) * (pc->cdata->max_prescale + 1),
378 GFP_KERNEL);
379 if (!pc->pwm_periods)
380 return -ENOMEM;
381
382 pc->clk = of_clk_get_by_name(dev->of_node, "pwm"); 352 pc->clk = of_clk_get_by_name(dev->of_node, "pwm");
383 if (IS_ERR(pc->clk)) { 353 if (IS_ERR(pc->clk)) {
384 dev_err(dev, "failed to get PWM clock\n"); 354 dev_err(dev, "failed to get PWM clock\n");
@@ -397,8 +367,6 @@ static int sti_pwm_probe(struct platform_device *pdev)
397 return ret; 367 return ret;
398 } 368 }
399 369
400 sti_pwm_calc_periods(pc);
401
402 pc->chip.dev = dev; 370 pc->chip.dev = dev;
403 pc->chip.ops = &sti_pwm_ops; 371 pc->chip.ops = &sti_pwm_ops;
404 pc->chip.base = -1; 372 pc->chip.base = -1;