aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pwm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-23 16:32:38 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-23 16:32:38 -0400
commitc70c5fb2b96dae0996fb0877d996458d3ca57eda (patch)
treefba71d0ec85e49e703b567ff43240d3aec6961cd /drivers/pwm
parent44d21c3f3a2ef2f58b18bda64c52c99e723f3f4a (diff)
parent361c1066c939a88e3bb59364f47055b2a5fb3fd4 (diff)
Merge tag 'pwm/for-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm
Pull pwm updates from Thierry Reding: "This has a couple of fixes for Atmel, Samsung and Broadcom drivers. Some preparatory patches for more upcoming Intel work is included as well" * tag 'pwm/for-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: pwm: lpss: pci: Add support for Broxton platform pwm: bcm-kona: Don't set polarity in probe pwm: Add pwmchip_add_with_polarity() API pwm: atmel: Fix incorrect CDTY value after disabling pwm: atmel: Fix incorrect CDTY value after enabling pwm: samsung: Use MODULE_DEVICE_TABLE() to include OF modalias pwm: Add support to remove registered consumer lookup tables
Diffstat (limited to 'drivers/pwm')
-rw-r--r--drivers/pwm/core.c40
-rw-r--r--drivers/pwm/pwm-atmel.c63
-rw-r--r--drivers/pwm/pwm-bcm-kona.c9
-rw-r--r--drivers/pwm/pwm-lpss-pci.c2
-rw-r--r--drivers/pwm/pwm-samsung.c1
5 files changed, 89 insertions, 26 deletions
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index ba34c7d89042..3a7769fe53de 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -223,13 +223,16 @@ void *pwm_get_chip_data(struct pwm_device *pwm)
223EXPORT_SYMBOL_GPL(pwm_get_chip_data); 223EXPORT_SYMBOL_GPL(pwm_get_chip_data);
224 224
225/** 225/**
226 * pwmchip_add() - register a new PWM chip 226 * pwmchip_add_with_polarity() - register a new PWM chip
227 * @chip: the PWM chip to add 227 * @chip: the PWM chip to add
228 * @polarity: initial polarity of PWM channels
228 * 229 *
229 * Register a new PWM chip. If chip->base < 0 then a dynamically assigned base 230 * Register a new PWM chip. If chip->base < 0 then a dynamically assigned base
230 * will be used. 231 * will be used. The initial polarity for all channels is specified by the
232 * @polarity parameter.
231 */ 233 */
232int pwmchip_add(struct pwm_chip *chip) 234int pwmchip_add_with_polarity(struct pwm_chip *chip,
235 enum pwm_polarity polarity)
233{ 236{
234 struct pwm_device *pwm; 237 struct pwm_device *pwm;
235 unsigned int i; 238 unsigned int i;
@@ -259,6 +262,7 @@ int pwmchip_add(struct pwm_chip *chip)
259 pwm->chip = chip; 262 pwm->chip = chip;
260 pwm->pwm = chip->base + i; 263 pwm->pwm = chip->base + i;
261 pwm->hwpwm = i; 264 pwm->hwpwm = i;
265 pwm->polarity = polarity;
262 266
263 radix_tree_insert(&pwm_tree, pwm->pwm, pwm); 267 radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
264 } 268 }
@@ -279,6 +283,19 @@ out:
279 mutex_unlock(&pwm_lock); 283 mutex_unlock(&pwm_lock);
280 return ret; 284 return ret;
281} 285}
286EXPORT_SYMBOL_GPL(pwmchip_add_with_polarity);
287
288/**
289 * pwmchip_add() - register a new PWM chip
290 * @chip: the PWM chip to add
291 *
292 * Register a new PWM chip. If chip->base < 0 then a dynamically assigned base
293 * will be used. The initial polarity for all channels is normal.
294 */
295int pwmchip_add(struct pwm_chip *chip)
296{
297 return pwmchip_add_with_polarity(chip, PWM_POLARITY_NORMAL);
298}
282EXPORT_SYMBOL_GPL(pwmchip_add); 299EXPORT_SYMBOL_GPL(pwmchip_add);
283 300
284/** 301/**
@@ -586,6 +603,23 @@ void pwm_add_table(struct pwm_lookup *table, size_t num)
586} 603}
587 604
588/** 605/**
606 * pwm_remove_table() - unregister PWM device consumers
607 * @table: array of consumers to unregister
608 * @num: number of consumers in table
609 */
610void pwm_remove_table(struct pwm_lookup *table, size_t num)
611{
612 mutex_lock(&pwm_lookup_lock);
613
614 while (num--) {
615 list_del(&table->list);
616 table++;
617 }
618
619 mutex_unlock(&pwm_lookup_lock);
620}
621
622/**
589 * pwm_get() - look up and request a PWM device 623 * pwm_get() - look up and request a PWM device
590 * @dev: device for PWM consumer 624 * @dev: device for PWM consumer
591 * @con_id: consumer name 625 * @con_id: consumer name
diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
index d3c22de9ee47..a947c9095d9d 100644
--- a/drivers/pwm/pwm-atmel.c
+++ b/drivers/pwm/pwm-atmel.c
@@ -8,9 +8,11 @@
8 */ 8 */
9 9
10#include <linux/clk.h> 10#include <linux/clk.h>
11#include <linux/delay.h>
11#include <linux/err.h> 12#include <linux/err.h>
12#include <linux/io.h> 13#include <linux/io.h>
13#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/mutex.h>
14#include <linux/of.h> 16#include <linux/of.h>
15#include <linux/of_device.h> 17#include <linux/of_device.h>
16#include <linux/platform_device.h> 18#include <linux/platform_device.h>
@@ -21,6 +23,7 @@
21#define PWM_ENA 0x04 23#define PWM_ENA 0x04
22#define PWM_DIS 0x08 24#define PWM_DIS 0x08
23#define PWM_SR 0x0C 25#define PWM_SR 0x0C
26#define PWM_ISR 0x1C
24/* Bit field in SR */ 27/* Bit field in SR */
25#define PWM_SR_ALL_CH_ON 0x0F 28#define PWM_SR_ALL_CH_ON 0x0F
26 29
@@ -60,6 +63,9 @@ struct atmel_pwm_chip {
60 struct clk *clk; 63 struct clk *clk;
61 void __iomem *base; 64 void __iomem *base;
62 65
66 unsigned int updated_pwms;
67 struct mutex isr_lock; /* ISR is cleared when read, ensure only one thread does that */
68
63 void (*config)(struct pwm_chip *chip, struct pwm_device *pwm, 69 void (*config)(struct pwm_chip *chip, struct pwm_device *pwm,
64 unsigned long dty, unsigned long prd); 70 unsigned long dty, unsigned long prd);
65}; 71};
@@ -144,6 +150,10 @@ static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
144 val = (val & ~PWM_CMR_CPRE_MSK) | (pres & PWM_CMR_CPRE_MSK); 150 val = (val & ~PWM_CMR_CPRE_MSK) | (pres & PWM_CMR_CPRE_MSK);
145 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val); 151 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
146 atmel_pwm->config(chip, pwm, dty, prd); 152 atmel_pwm->config(chip, pwm, dty, prd);
153 mutex_lock(&atmel_pwm->isr_lock);
154 atmel_pwm->updated_pwms |= atmel_pwm_readl(atmel_pwm, PWM_ISR);
155 atmel_pwm->updated_pwms &= ~(1 << pwm->hwpwm);
156 mutex_unlock(&atmel_pwm->isr_lock);
147 157
148 clk_disable(atmel_pwm->clk); 158 clk_disable(atmel_pwm->clk);
149 return ret; 159 return ret;
@@ -155,24 +165,25 @@ static void atmel_pwm_config_v1(struct pwm_chip *chip, struct pwm_device *pwm,
155 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip); 165 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
156 unsigned int val; 166 unsigned int val;
157 167
158 if (test_bit(PWMF_ENABLED, &pwm->flags)) {
159 /*
160 * If the PWM channel is enabled, using the update register,
161 * it needs to set bit 10 of CMR to 0
162 */
163 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV1_CUPD, dty);
164 168
165 val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR); 169 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV1_CUPD, dty);
166 val &= ~PWM_CMR_UPD_CDTY; 170
167 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val); 171 val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
168 } else { 172 val &= ~PWM_CMR_UPD_CDTY;
169 /* 173 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
170 * If the PWM channel is disabled, write value to duty and 174
171 * period registers directly. 175 /*
172 */ 176 * If the PWM channel is enabled, only update CDTY by using the update
173 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV1_CDTY, dty); 177 * register, it needs to set bit 10 of CMR to 0
174 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV1_CPRD, prd); 178 */
175 } 179 if (test_bit(PWMF_ENABLED, &pwm->flags))
180 return;
181 /*
182 * If the PWM channel is disabled, write value to duty and period
183 * registers directly.
184 */
185 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV1_CDTY, dty);
186 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV1_CPRD, prd);
176} 187}
177 188
178static void atmel_pwm_config_v2(struct pwm_chip *chip, struct pwm_device *pwm, 189static void atmel_pwm_config_v2(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -242,7 +253,22 @@ static int atmel_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
242static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) 253static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
243{ 254{
244 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip); 255 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
256 unsigned long timeout = jiffies + 2 * HZ;
257
258 /*
259 * Wait for at least a complete period to have passed before disabling a
260 * channel to be sure that CDTY has been updated
261 */
262 mutex_lock(&atmel_pwm->isr_lock);
263 atmel_pwm->updated_pwms |= atmel_pwm_readl(atmel_pwm, PWM_ISR);
264
265 while (!(atmel_pwm->updated_pwms & (1 << pwm->hwpwm)) &&
266 time_before(jiffies, timeout)) {
267 usleep_range(10, 100);
268 atmel_pwm->updated_pwms |= atmel_pwm_readl(atmel_pwm, PWM_ISR);
269 }
245 270
271 mutex_unlock(&atmel_pwm->isr_lock);
246 atmel_pwm_writel(atmel_pwm, PWM_DIS, 1 << pwm->hwpwm); 272 atmel_pwm_writel(atmel_pwm, PWM_DIS, 1 << pwm->hwpwm);
247 273
248 clk_disable(atmel_pwm->clk); 274 clk_disable(atmel_pwm->clk);
@@ -357,6 +383,8 @@ static int atmel_pwm_probe(struct platform_device *pdev)
357 atmel_pwm->chip.npwm = 4; 383 atmel_pwm->chip.npwm = 4;
358 atmel_pwm->chip.can_sleep = true; 384 atmel_pwm->chip.can_sleep = true;
359 atmel_pwm->config = data->config; 385 atmel_pwm->config = data->config;
386 atmel_pwm->updated_pwms = 0;
387 mutex_init(&atmel_pwm->isr_lock);
360 388
361 ret = pwmchip_add(&atmel_pwm->chip); 389 ret = pwmchip_add(&atmel_pwm->chip);
362 if (ret < 0) { 390 if (ret < 0) {
@@ -378,6 +406,7 @@ static int atmel_pwm_remove(struct platform_device *pdev)
378 struct atmel_pwm_chip *atmel_pwm = platform_get_drvdata(pdev); 406 struct atmel_pwm_chip *atmel_pwm = platform_get_drvdata(pdev);
379 407
380 clk_unprepare(atmel_pwm->clk); 408 clk_unprepare(atmel_pwm->clk);
409 mutex_destroy(&atmel_pwm->isr_lock);
381 410
382 return pwmchip_remove(&atmel_pwm->chip); 411 return pwmchip_remove(&atmel_pwm->chip);
383} 412}
diff --git a/drivers/pwm/pwm-bcm-kona.c b/drivers/pwm/pwm-bcm-kona.c
index 02bc048892a9..7af8fea2dc5b 100644
--- a/drivers/pwm/pwm-bcm-kona.c
+++ b/drivers/pwm/pwm-bcm-kona.c
@@ -266,18 +266,15 @@ static int kona_pwmc_probe(struct platform_device *pdev)
266 return ret; 266 return ret;
267 } 267 }
268 268
269 /* Set smooth mode, push/pull, and normal polarity for all channels */ 269 /* Set push/pull for all channels */
270 for (chan = 0; chan < kp->chip.npwm; chan++) { 270 for (chan = 0; chan < kp->chip.npwm; chan++)
271 value |= (1 << PWM_CONTROL_SMOOTH_SHIFT(chan));
272 value |= (1 << PWM_CONTROL_TYPE_SHIFT(chan)); 271 value |= (1 << PWM_CONTROL_TYPE_SHIFT(chan));
273 value |= (1 << PWM_CONTROL_POLARITY_SHIFT(chan));
274 }
275 272
276 writel(value, kp->base + PWM_CONTROL_OFFSET); 273 writel(value, kp->base + PWM_CONTROL_OFFSET);
277 274
278 clk_disable_unprepare(kp->clk); 275 clk_disable_unprepare(kp->clk);
279 276
280 ret = pwmchip_add(&kp->chip); 277 ret = pwmchip_add_with_polarity(&kp->chip, PWM_POLARITY_INVERSED);
281 if (ret < 0) 278 if (ret < 0)
282 dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret); 279 dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
283 280
diff --git a/drivers/pwm/pwm-lpss-pci.c b/drivers/pwm/pwm-lpss-pci.c
index cf20d2beacdd..45042c1b2046 100644
--- a/drivers/pwm/pwm-lpss-pci.c
+++ b/drivers/pwm/pwm-lpss-pci.c
@@ -44,8 +44,10 @@ static void pwm_lpss_remove_pci(struct pci_dev *pdev)
44} 44}
45 45
46static const struct pci_device_id pwm_lpss_pci_ids[] = { 46static const struct pci_device_id pwm_lpss_pci_ids[] = {
47 { PCI_VDEVICE(INTEL, 0x0ac8), (unsigned long)&pwm_lpss_bsw_info},
47 { PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&pwm_lpss_byt_info}, 48 { PCI_VDEVICE(INTEL, 0x0f08), (unsigned long)&pwm_lpss_byt_info},
48 { PCI_VDEVICE(INTEL, 0x0f09), (unsigned long)&pwm_lpss_byt_info}, 49 { PCI_VDEVICE(INTEL, 0x0f09), (unsigned long)&pwm_lpss_byt_info},
50 { PCI_VDEVICE(INTEL, 0x1ac8), (unsigned long)&pwm_lpss_bsw_info},
49 { PCI_VDEVICE(INTEL, 0x2288), (unsigned long)&pwm_lpss_bsw_info}, 51 { PCI_VDEVICE(INTEL, 0x2288), (unsigned long)&pwm_lpss_bsw_info},
50 { PCI_VDEVICE(INTEL, 0x2289), (unsigned long)&pwm_lpss_bsw_info}, 52 { PCI_VDEVICE(INTEL, 0x2289), (unsigned long)&pwm_lpss_bsw_info},
51 { }, 53 { },
diff --git a/drivers/pwm/pwm-samsung.c b/drivers/pwm/pwm-samsung.c
index ff201e1b9219..ada2d326dc3e 100644
--- a/drivers/pwm/pwm-samsung.c
+++ b/drivers/pwm/pwm-samsung.c
@@ -456,6 +456,7 @@ static const struct of_device_id samsung_pwm_matches[] = {
456 { .compatible = "samsung,exynos4210-pwm", .data = &s5p64x0_variant }, 456 { .compatible = "samsung,exynos4210-pwm", .data = &s5p64x0_variant },
457 {}, 457 {},
458}; 458};
459MODULE_DEVICE_TABLE(of, samsung_pwm_matches);
459 460
460static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip) 461static int pwm_samsung_parse_dt(struct samsung_pwm_chip *chip)
461{ 462{