diff options
author | Ajit Pal Singh <ajitpal.singh@st.com> | 2014-07-14 10:33:32 -0400 |
---|---|---|
committer | Thierry Reding <thierry.reding@gmail.com> | 2014-08-08 07:12:46 -0400 |
commit | 3aacd3e1879a5359ce1483b82c9cdd31ebb348b7 (patch) | |
tree | 3815ccf96d227ce82f6beba55bc527e797925b09 | |
parent | 6ad6b838e11d8d67950716e0715b1d71bdd0769e (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.c | 64 |
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 | */ |
83 | static void sti_pwm_calc_periods(struct sti_pwm_chip *pc) | 80 | static 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 | ||
123 | static 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; |