aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-26 12:34:29 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-26 12:34:29 -0500
commit3eb05225ee8efb81fe50558f5f9d94e7477ade8f (patch)
tree40692236718c808455f1fcdfbc1c6de6a274eb36
parented5dc2372dba46e0ecd08791b1a0399d313e5cff (diff)
parent30f786170352b8264bc7b61c2482713e54accec8 (diff)
Merge tag 'for-3.9-rc1' of git://gitorious.org/linux-pwm/linux-pwm
Pull PWM changes from Thierry Reding: "A new driver has been added to support the PWM mode of the timer counter blocks found on Atmel AT91 SoCs. The VT8500 driver now supports changing the PWM signal polarity and the TI drivers (EHRPWM and ECAP) gained suspend and resume functionality. User drivers can now query the core for whether access to a PWM device will sleep (if the PWM chip is on a slow bus such as I2C or SPI). The pwm-backlight driver now handles the backlight BL_CORE_FBBLANK state in addition to the FB layer's blanking states. To round things off, a few fixes and cleanups are also included" * tag 'for-3.9-rc1' of git://gitorious.org/linux-pwm/linux-pwm: pwm: twl: Use to_twl() instead of container_of() pwm: tegra: assume CONFIG_OF pwm_backlight: Validate dft_brightness in main probe function pwm: Export pwm_{set,get}_chip_data() pwm: Make Kconfig entries more consistent pwm: Add can_sleep property to drivers pwm: Add pwm_can_sleep() as exported API to users pwm-backlight: handle BL_CORE_FBBLANK state pwm: pwm-tiecap: Low power sleep support pwm: pwm-tiehrpwm: Low power sleep support pwm: pwm-tiehrpwm: Update the clock handling of pwm-tiehrpwm driver pwm: vt8500: Add polarity support pwm: vt8500: Register write busy test performed incorrectly pwm: atmel: add Timer Counter Block PWM driver
-rw-r--r--Documentation/devicetree/bindings/pwm/atmel-tcb-pwm.txt18
-rw-r--r--Documentation/devicetree/bindings/pwm/vt8500-pwm.txt9
-rw-r--r--drivers/pwm/Kconfig18
-rw-r--r--drivers/pwm/Makefile1
-rw-r--r--drivers/pwm/core.c14
-rw-r--r--drivers/pwm/pwm-atmel-tcb.c445
-rw-r--r--drivers/pwm/pwm-tegra.c4
-rw-r--r--drivers/pwm/pwm-tiecap.c53
-rw-r--r--drivers/pwm/pwm-tiehrpwm.c93
-rw-r--r--drivers/pwm/pwm-twl-led.c1
-rw-r--r--drivers/pwm/pwm-twl.c10
-rw-r--r--drivers/pwm/pwm-vt8500.c87
-rw-r--r--drivers/video/backlight/pwm_bl.c20
-rw-r--r--include/linux/pwm.h10
14 files changed, 741 insertions, 42 deletions
diff --git a/Documentation/devicetree/bindings/pwm/atmel-tcb-pwm.txt b/Documentation/devicetree/bindings/pwm/atmel-tcb-pwm.txt
new file mode 100644
index 000000000000..de0eaed86651
--- /dev/null
+++ b/Documentation/devicetree/bindings/pwm/atmel-tcb-pwm.txt
@@ -0,0 +1,18 @@
1Atmel TCB PWM controller
2
3Required properties:
4- compatible: should be "atmel,tcb-pwm"
5- #pwm-cells: Should be 3. The first cell specifies the per-chip index
6 of the PWM to use, the second cell is the period in nanoseconds and
7 bit 0 in the third cell is used to encode the polarity of PWM output.
8 Set bit 0 of the third cell in PWM specifier to 1 for inverse polarity &
9 set to 0 for normal polarity.
10- tc-block: The Timer Counter block to use as a PWM chip.
11
12Example:
13
14pwm {
15 compatible = "atmel,tcb-pwm";
16 #pwm-cells = <3>;
17 tc-block = <1>;
18};
diff --git a/Documentation/devicetree/bindings/pwm/vt8500-pwm.txt b/Documentation/devicetree/bindings/pwm/vt8500-pwm.txt
index bcc63678a9a5..d21d82d29855 100644
--- a/Documentation/devicetree/bindings/pwm/vt8500-pwm.txt
+++ b/Documentation/devicetree/bindings/pwm/vt8500-pwm.txt
@@ -3,14 +3,17 @@ VIA/Wondermedia VT8500/WM8xxx series SoC PWM controller
3Required properties: 3Required properties:
4- compatible: should be "via,vt8500-pwm" 4- compatible: should be "via,vt8500-pwm"
5- reg: physical base address and length of the controller's registers 5- reg: physical base address and length of the controller's registers
6- #pwm-cells: should be 2. The first cell specifies the per-chip index 6- #pwm-cells: Should be 3. Number of cells being used to specify PWM property.
7 of the PWM to use and the second cell is the period in nanoseconds. 7 First cell specifies the per-chip index of the PWM to use, the second
8 cell is the period in nanoseconds and bit 0 in the third cell is used to
9 encode the polarity of PWM output. Set bit 0 of the third in PWM specifier
10 to 1 for inverse polarity & set to 0 for normal polarity.
8- clocks: phandle to the PWM source clock 11- clocks: phandle to the PWM source clock
9 12
10Example: 13Example:
11 14
12pwm1: pwm@d8220000 { 15pwm1: pwm@d8220000 {
13 #pwm-cells = <2>; 16 #pwm-cells = <3>;
14 compatible = "via,vt8500-pwm"; 17 compatible = "via,vt8500-pwm";
15 reg = <0xd8220000 0x1000>; 18 reg = <0xd8220000 0x1000>;
16 clocks = <&clkpwm>; 19 clocks = <&clkpwm>;
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index e513cd998170..0e0bfa035083 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -37,6 +37,18 @@ config PWM_AB8500
37 To compile this driver as a module, choose M here: the module 37 To compile this driver as a module, choose M here: the module
38 will be called pwm-ab8500. 38 will be called pwm-ab8500.
39 39
40config PWM_ATMEL_TCB
41 tristate "Atmel TC Block PWM support"
42 depends on ATMEL_TCLIB && OF
43 help
44 Generic PWM framework driver for Atmel Timer Counter Block.
45
46 A Timer Counter Block provides 6 PWM devices grouped by 2.
47 Devices in a given group must have the same period.
48
49 To compile this driver as a module, choose M here: the module
50 will be called pwm-atmel-tcb.
51
40config PWM_BFIN 52config PWM_BFIN
41 tristate "Blackfin PWM support" 53 tristate "Blackfin PWM support"
42 depends on BFIN_GPTIMERS 54 depends on BFIN_GPTIMERS
@@ -47,7 +59,7 @@ config PWM_BFIN
47 will be called pwm-bfin. 59 will be called pwm-bfin.
48 60
49config PWM_IMX 61config PWM_IMX
50 tristate "i.MX pwm support" 62 tristate "i.MX PWM support"
51 depends on ARCH_MXC 63 depends on ARCH_MXC
52 help 64 help
53 Generic PWM framework driver for i.MX. 65 Generic PWM framework driver for i.MX.
@@ -104,7 +116,7 @@ config PWM_PXA
104 will be called pwm-pxa. 116 will be called pwm-pxa.
105 117
106config PWM_SAMSUNG 118config PWM_SAMSUNG
107 tristate "Samsung pwm support" 119 tristate "Samsung PWM support"
108 depends on PLAT_SAMSUNG 120 depends on PLAT_SAMSUNG
109 help 121 help
110 Generic PWM framework driver for Samsung. 122 Generic PWM framework driver for Samsung.
@@ -183,7 +195,7 @@ config PWM_TWL_LED
183 will be called pwm-twl-led. 195 will be called pwm-twl-led.
184 196
185config PWM_VT8500 197config PWM_VT8500
186 tristate "vt8500 pwm support" 198 tristate "vt8500 PWM support"
187 depends on ARCH_VT8500 199 depends on ARCH_VT8500
188 help 200 help
189 Generic PWM framework driver for vt8500. 201 Generic PWM framework driver for vt8500.
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 62a2963cfe58..94ba21e24bd6 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -1,5 +1,6 @@
1obj-$(CONFIG_PWM) += core.o 1obj-$(CONFIG_PWM) += core.o
2obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o 2obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o
3obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o
3obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o 4obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o
4obj-$(CONFIG_PWM_IMX) += pwm-imx.o 5obj-$(CONFIG_PWM_IMX) += pwm-imx.o
5obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o 6obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 4a13da48fefe..32221cb0cbe7 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -211,6 +211,7 @@ int pwm_set_chip_data(struct pwm_device *pwm, void *data)
211 211
212 return 0; 212 return 0;
213} 213}
214EXPORT_SYMBOL_GPL(pwm_set_chip_data);
214 215
215/** 216/**
216 * pwm_get_chip_data() - get private chip data for a PWM 217 * pwm_get_chip_data() - get private chip data for a PWM
@@ -220,6 +221,7 @@ void *pwm_get_chip_data(struct pwm_device *pwm)
220{ 221{
221 return pwm ? pwm->chip_data : NULL; 222 return pwm ? pwm->chip_data : NULL;
222} 223}
224EXPORT_SYMBOL_GPL(pwm_get_chip_data);
223 225
224/** 226/**
225 * pwmchip_add() - register a new PWM chip 227 * pwmchip_add() - register a new PWM chip
@@ -763,6 +765,18 @@ void devm_pwm_put(struct device *dev, struct pwm_device *pwm)
763} 765}
764EXPORT_SYMBOL_GPL(devm_pwm_put); 766EXPORT_SYMBOL_GPL(devm_pwm_put);
765 767
768/**
769 * pwm_can_sleep() - report whether PWM access will sleep
770 * @pwm: PWM device
771 *
772 * It returns true if accessing the PWM can sleep, false otherwise.
773 */
774bool pwm_can_sleep(struct pwm_device *pwm)
775{
776 return pwm->chip->can_sleep;
777}
778EXPORT_SYMBOL_GPL(pwm_can_sleep);
779
766#ifdef CONFIG_DEBUG_FS 780#ifdef CONFIG_DEBUG_FS
767static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s) 781static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
768{ 782{
diff --git a/drivers/pwm/pwm-atmel-tcb.c b/drivers/pwm/pwm-atmel-tcb.c
new file mode 100644
index 000000000000..16cb53092857
--- /dev/null
+++ b/drivers/pwm/pwm-atmel-tcb.c
@@ -0,0 +1,445 @@
1/*
2 * Copyright (C) Overkiz SAS 2012
3 *
4 * Author: Boris BREZILLON <b.brezillon@overkiz.com>
5 * License terms: GNU General Public License (GPL) version 2
6 */
7
8#include <linux/module.h>
9#include <linux/init.h>
10#include <linux/clocksource.h>
11#include <linux/clockchips.h>
12#include <linux/interrupt.h>
13#include <linux/irq.h>
14
15#include <linux/clk.h>
16#include <linux/err.h>
17#include <linux/ioport.h>
18#include <linux/io.h>
19#include <linux/platform_device.h>
20#include <linux/atmel_tc.h>
21#include <linux/pwm.h>
22#include <linux/of_device.h>
23#include <linux/slab.h>
24
25#define NPWM 6
26
27#define ATMEL_TC_ACMR_MASK (ATMEL_TC_ACPA | ATMEL_TC_ACPC | \
28 ATMEL_TC_AEEVT | ATMEL_TC_ASWTRG)
29
30#define ATMEL_TC_BCMR_MASK (ATMEL_TC_BCPB | ATMEL_TC_BCPC | \
31 ATMEL_TC_BEEVT | ATMEL_TC_BSWTRG)
32
33struct atmel_tcb_pwm_device {
34 enum pwm_polarity polarity; /* PWM polarity */
35 unsigned div; /* PWM clock divider */
36 unsigned duty; /* PWM duty expressed in clk cycles */
37 unsigned period; /* PWM period expressed in clk cycles */
38};
39
40struct atmel_tcb_pwm_chip {
41 struct pwm_chip chip;
42 spinlock_t lock;
43 struct atmel_tc *tc;
44 struct atmel_tcb_pwm_device *pwms[NPWM];
45};
46
47static inline struct atmel_tcb_pwm_chip *to_tcb_chip(struct pwm_chip *chip)
48{
49 return container_of(chip, struct atmel_tcb_pwm_chip, chip);
50}
51
52static int atmel_tcb_pwm_set_polarity(struct pwm_chip *chip,
53 struct pwm_device *pwm,
54 enum pwm_polarity polarity)
55{
56 struct atmel_tcb_pwm_device *tcbpwm = pwm_get_chip_data(pwm);
57
58 tcbpwm->polarity = polarity;
59
60 return 0;
61}
62
63static int atmel_tcb_pwm_request(struct pwm_chip *chip,
64 struct pwm_device *pwm)
65{
66 struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
67 struct atmel_tcb_pwm_device *tcbpwm;
68 struct atmel_tc *tc = tcbpwmc->tc;
69 void __iomem *regs = tc->regs;
70 unsigned group = pwm->hwpwm / 2;
71 unsigned index = pwm->hwpwm % 2;
72 unsigned cmr;
73 int ret;
74
75 tcbpwm = devm_kzalloc(chip->dev, sizeof(*tcbpwm), GFP_KERNEL);
76 if (!tcbpwm)
77 return -ENOMEM;
78
79 ret = clk_enable(tc->clk[group]);
80 if (ret) {
81 devm_kfree(chip->dev, tcbpwm);
82 return ret;
83 }
84
85 pwm_set_chip_data(pwm, tcbpwm);
86 tcbpwm->polarity = PWM_POLARITY_NORMAL;
87 tcbpwm->duty = 0;
88 tcbpwm->period = 0;
89 tcbpwm->div = 0;
90
91 spin_lock(&tcbpwmc->lock);
92 cmr = __raw_readl(regs + ATMEL_TC_REG(group, CMR));
93 /*
94 * Get init config from Timer Counter registers if
95 * Timer Counter is already configured as a PWM generator.
96 */
97 if (cmr & ATMEL_TC_WAVE) {
98 if (index == 0)
99 tcbpwm->duty =
100 __raw_readl(regs + ATMEL_TC_REG(group, RA));
101 else
102 tcbpwm->duty =
103 __raw_readl(regs + ATMEL_TC_REG(group, RB));
104
105 tcbpwm->div = cmr & ATMEL_TC_TCCLKS;
106 tcbpwm->period = __raw_readl(regs + ATMEL_TC_REG(group, RC));
107 cmr &= (ATMEL_TC_TCCLKS | ATMEL_TC_ACMR_MASK |
108 ATMEL_TC_BCMR_MASK);
109 } else
110 cmr = 0;
111
112 cmr |= ATMEL_TC_WAVE | ATMEL_TC_WAVESEL_UP_AUTO | ATMEL_TC_EEVT_XC0;
113 __raw_writel(cmr, regs + ATMEL_TC_REG(group, CMR));
114 spin_unlock(&tcbpwmc->lock);
115
116 tcbpwmc->pwms[pwm->hwpwm] = tcbpwm;
117
118 return 0;
119}
120
121static void atmel_tcb_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
122{
123 struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
124 struct atmel_tcb_pwm_device *tcbpwm = pwm_get_chip_data(pwm);
125 struct atmel_tc *tc = tcbpwmc->tc;
126
127 clk_disable(tc->clk[pwm->hwpwm / 2]);
128 tcbpwmc->pwms[pwm->hwpwm] = NULL;
129 devm_kfree(chip->dev, tcbpwm);
130}
131
132static void atmel_tcb_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
133{
134 struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
135 struct atmel_tcb_pwm_device *tcbpwm = pwm_get_chip_data(pwm);
136 struct atmel_tc *tc = tcbpwmc->tc;
137 void __iomem *regs = tc->regs;
138 unsigned group = pwm->hwpwm / 2;
139 unsigned index = pwm->hwpwm % 2;
140 unsigned cmr;
141 enum pwm_polarity polarity = tcbpwm->polarity;
142
143 /*
144 * If duty is 0 the timer will be stopped and we have to
145 * configure the output correctly on software trigger:
146 * - set output to high if PWM_POLARITY_INVERSED
147 * - set output to low if PWM_POLARITY_NORMAL
148 *
149 * This is why we're reverting polarity in this case.
150 */
151 if (tcbpwm->duty == 0)
152 polarity = !polarity;
153
154 spin_lock(&tcbpwmc->lock);
155 cmr = __raw_readl(regs + ATMEL_TC_REG(group, CMR));
156
157 /* flush old setting and set the new one */
158 if (index == 0) {
159 cmr &= ~ATMEL_TC_ACMR_MASK;
160 if (polarity == PWM_POLARITY_INVERSED)
161 cmr |= ATMEL_TC_ASWTRG_CLEAR;
162 else
163 cmr |= ATMEL_TC_ASWTRG_SET;
164 } else {
165 cmr &= ~ATMEL_TC_BCMR_MASK;
166 if (polarity == PWM_POLARITY_INVERSED)
167 cmr |= ATMEL_TC_BSWTRG_CLEAR;
168 else
169 cmr |= ATMEL_TC_BSWTRG_SET;
170 }
171
172 __raw_writel(cmr, regs + ATMEL_TC_REG(group, CMR));
173
174 /*
175 * Use software trigger to apply the new setting.
176 * If both PWM devices in this group are disabled we stop the clock.
177 */
178 if (!(cmr & (ATMEL_TC_ACPC | ATMEL_TC_BCPC)))
179 __raw_writel(ATMEL_TC_SWTRG | ATMEL_TC_CLKDIS,
180 regs + ATMEL_TC_REG(group, CCR));
181 else
182 __raw_writel(ATMEL_TC_SWTRG, regs +
183 ATMEL_TC_REG(group, CCR));
184
185 spin_unlock(&tcbpwmc->lock);
186}
187
188static int atmel_tcb_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
189{
190 struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
191 struct atmel_tcb_pwm_device *tcbpwm = pwm_get_chip_data(pwm);
192 struct atmel_tc *tc = tcbpwmc->tc;
193 void __iomem *regs = tc->regs;
194 unsigned group = pwm->hwpwm / 2;
195 unsigned index = pwm->hwpwm % 2;
196 u32 cmr;
197 enum pwm_polarity polarity = tcbpwm->polarity;
198
199 /*
200 * If duty is 0 the timer will be stopped and we have to
201 * configure the output correctly on software trigger:
202 * - set output to high if PWM_POLARITY_INVERSED
203 * - set output to low if PWM_POLARITY_NORMAL
204 *
205 * This is why we're reverting polarity in this case.
206 */
207 if (tcbpwm->duty == 0)
208 polarity = !polarity;
209
210 spin_lock(&tcbpwmc->lock);
211 cmr = __raw_readl(regs + ATMEL_TC_REG(group, CMR));
212
213 /* flush old setting and set the new one */
214 cmr &= ~ATMEL_TC_TCCLKS;
215
216 if (index == 0) {
217 cmr &= ~ATMEL_TC_ACMR_MASK;
218
219 /* Set CMR flags according to given polarity */
220 if (polarity == PWM_POLARITY_INVERSED)
221 cmr |= ATMEL_TC_ASWTRG_CLEAR;
222 else
223 cmr |= ATMEL_TC_ASWTRG_SET;
224 } else {
225 cmr &= ~ATMEL_TC_BCMR_MASK;
226 if (polarity == PWM_POLARITY_INVERSED)
227 cmr |= ATMEL_TC_BSWTRG_CLEAR;
228 else
229 cmr |= ATMEL_TC_BSWTRG_SET;
230 }
231
232 /*
233 * If duty is 0 or equal to period there's no need to register
234 * a specific action on RA/RB and RC compare.
235 * The output will be configured on software trigger and keep
236 * this config till next config call.
237 */
238 if (tcbpwm->duty != tcbpwm->period && tcbpwm->duty > 0) {
239 if (index == 0) {
240 if (polarity == PWM_POLARITY_INVERSED)
241 cmr |= ATMEL_TC_ACPA_SET | ATMEL_TC_ACPC_CLEAR;
242 else
243 cmr |= ATMEL_TC_ACPA_CLEAR | ATMEL_TC_ACPC_SET;
244 } else {
245 if (polarity == PWM_POLARITY_INVERSED)
246 cmr |= ATMEL_TC_BCPB_SET | ATMEL_TC_BCPC_CLEAR;
247 else
248 cmr |= ATMEL_TC_BCPB_CLEAR | ATMEL_TC_BCPC_SET;
249 }
250 }
251
252 __raw_writel(cmr, regs + ATMEL_TC_REG(group, CMR));
253
254 if (index == 0)
255 __raw_writel(tcbpwm->duty, regs + ATMEL_TC_REG(group, RA));
256 else
257 __raw_writel(tcbpwm->duty, regs + ATMEL_TC_REG(group, RB));
258
259 __raw_writel(tcbpwm->period, regs + ATMEL_TC_REG(group, RC));
260
261 /* Use software trigger to apply the new setting */
262 __raw_writel(ATMEL_TC_CLKEN | ATMEL_TC_SWTRG,
263 regs + ATMEL_TC_REG(group, CCR));
264 spin_unlock(&tcbpwmc->lock);
265 return 0;
266}
267
268static int atmel_tcb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
269 int duty_ns, int period_ns)
270{
271 struct atmel_tcb_pwm_chip *tcbpwmc = to_tcb_chip(chip);
272 struct atmel_tcb_pwm_device *tcbpwm = pwm_get_chip_data(pwm);
273 unsigned group = pwm->hwpwm / 2;
274 unsigned index = pwm->hwpwm % 2;
275 struct atmel_tcb_pwm_device *atcbpwm = NULL;
276 struct atmel_tc *tc = tcbpwmc->tc;
277 int i;
278 int slowclk = 0;
279 unsigned period;
280 unsigned duty;
281 unsigned rate = clk_get_rate(tc->clk[group]);
282 unsigned long long min;
283 unsigned long long max;
284
285 /*
286 * Find best clk divisor:
287 * the smallest divisor which can fulfill the period_ns requirements.
288 */
289 for (i = 0; i < 5; ++i) {
290 if (atmel_tc_divisors[i] == 0) {
291 slowclk = i;
292 continue;
293 }
294 min = div_u64((u64)NSEC_PER_SEC * atmel_tc_divisors[i], rate);
295 max = min << tc->tcb_config->counter_width;
296 if (max >= period_ns)
297 break;
298 }
299
300 /*
301 * If none of the divisor are small enough to represent period_ns
302 * take slow clock (32KHz).
303 */
304 if (i == 5) {
305 i = slowclk;
306 rate = 32768;
307 min = div_u64(NSEC_PER_SEC, rate);
308 max = min << 16;
309
310 /* If period is too big return ERANGE error */
311 if (max < period_ns)
312 return -ERANGE;
313 }
314
315 duty = div_u64(duty_ns, min);
316 period = div_u64(period_ns, min);
317
318 if (index == 0)
319 atcbpwm = tcbpwmc->pwms[pwm->hwpwm + 1];
320 else
321 atcbpwm = tcbpwmc->pwms[pwm->hwpwm - 1];
322
323 /*
324 * PWM devices provided by TCB driver are grouped by 2:
325 * - group 0: PWM 0 & 1
326 * - group 1: PWM 2 & 3
327 * - group 2: PWM 4 & 5
328 *
329 * PWM devices in a given group must be configured with the
330 * same period_ns.
331 *
332 * We're checking the period value of the second PWM device
333 * in this group before applying the new config.
334 */
335 if ((atcbpwm && atcbpwm->duty > 0 &&
336 atcbpwm->duty != atcbpwm->period) &&
337 (atcbpwm->div != i || atcbpwm->period != period)) {
338 dev_err(chip->dev,
339 "failed to configure period_ns: PWM group already configured with a different value\n");
340 return -EINVAL;
341 }
342
343 tcbpwm->period = period;
344 tcbpwm->div = i;
345 tcbpwm->duty = duty;
346
347 /* If the PWM is enabled, call enable to apply the new conf */
348 if (test_bit(PWMF_ENABLED, &pwm->flags))
349 atmel_tcb_pwm_enable(chip, pwm);
350
351 return 0;
352}
353
354static const struct pwm_ops atmel_tcb_pwm_ops = {
355 .request = atmel_tcb_pwm_request,
356 .free = atmel_tcb_pwm_free,
357 .config = atmel_tcb_pwm_config,
358 .set_polarity = atmel_tcb_pwm_set_polarity,
359 .enable = atmel_tcb_pwm_enable,
360 .disable = atmel_tcb_pwm_disable,
361};
362
363static int atmel_tcb_pwm_probe(struct platform_device *pdev)
364{
365 struct atmel_tcb_pwm_chip *tcbpwm;
366 struct device_node *np = pdev->dev.of_node;
367 struct atmel_tc *tc;
368 int err;
369 int tcblock;
370
371 err = of_property_read_u32(np, "tc-block", &tcblock);
372 if (err < 0) {
373 dev_err(&pdev->dev,
374 "failed to get Timer Counter Block number from device tree (error: %d)\n",
375 err);
376 return err;
377 }
378
379 tc = atmel_tc_alloc(tcblock, "tcb-pwm");
380 if (tc == NULL) {
381 dev_err(&pdev->dev, "failed to allocate Timer Counter Block\n");
382 return -ENOMEM;
383 }
384
385 tcbpwm = devm_kzalloc(&pdev->dev, sizeof(*tcbpwm), GFP_KERNEL);
386 if (tcbpwm == NULL) {
387 atmel_tc_free(tc);
388 dev_err(&pdev->dev, "failed to allocate memory\n");
389 return -ENOMEM;
390 }
391
392 tcbpwm->chip.dev = &pdev->dev;
393 tcbpwm->chip.ops = &atmel_tcb_pwm_ops;
394 tcbpwm->chip.of_xlate = of_pwm_xlate_with_flags;
395 tcbpwm->chip.of_pwm_n_cells = 3;
396 tcbpwm->chip.base = -1;
397 tcbpwm->chip.npwm = NPWM;
398 tcbpwm->tc = tc;
399
400 spin_lock_init(&tcbpwm->lock);
401
402 err = pwmchip_add(&tcbpwm->chip);
403 if (err < 0) {
404 atmel_tc_free(tc);
405 return err;
406 }
407
408 platform_set_drvdata(pdev, tcbpwm);
409
410 return 0;
411}
412
413static int atmel_tcb_pwm_remove(struct platform_device *pdev)
414{
415 struct atmel_tcb_pwm_chip *tcbpwm = platform_get_drvdata(pdev);
416 int err;
417
418 err = pwmchip_remove(&tcbpwm->chip);
419 if (err < 0)
420 return err;
421
422 atmel_tc_free(tcbpwm->tc);
423
424 return 0;
425}
426
427static const struct of_device_id atmel_tcb_pwm_dt_ids[] = {
428 { .compatible = "atmel,tcb-pwm", },
429 { /* sentinel */ }
430};
431MODULE_DEVICE_TABLE(of, atmel_tcb_pwm_dt_ids);
432
433static struct platform_driver atmel_tcb_pwm_driver = {
434 .driver = {
435 .name = "atmel-tcb-pwm",
436 .of_match_table = atmel_tcb_pwm_dt_ids,
437 },
438 .probe = atmel_tcb_pwm_probe,
439 .remove = atmel_tcb_pwm_remove,
440};
441module_platform_driver(atmel_tcb_pwm_driver);
442
443MODULE_AUTHOR("Boris BREZILLON <b.brezillon@overkiz.com>");
444MODULE_DESCRIPTION("Atmel Timer Counter Pulse Width Modulation Driver");
445MODULE_LICENSE("GPL v2");
diff --git a/drivers/pwm/pwm-tegra.c b/drivers/pwm/pwm-tegra.c
index 71900e8cd3d1..af3ab48cb7ef 100644
--- a/drivers/pwm/pwm-tegra.c
+++ b/drivers/pwm/pwm-tegra.c
@@ -233,7 +233,6 @@ static int tegra_pwm_remove(struct platform_device *pdev)
233 return pwmchip_remove(&pc->chip); 233 return pwmchip_remove(&pc->chip);
234} 234}
235 235
236#ifdef CONFIG_OF
237static struct of_device_id tegra_pwm_of_match[] = { 236static struct of_device_id tegra_pwm_of_match[] = {
238 { .compatible = "nvidia,tegra20-pwm" }, 237 { .compatible = "nvidia,tegra20-pwm" },
239 { .compatible = "nvidia,tegra30-pwm" }, 238 { .compatible = "nvidia,tegra30-pwm" },
@@ -241,12 +240,11 @@ static struct of_device_id tegra_pwm_of_match[] = {
241}; 240};
242 241
243MODULE_DEVICE_TABLE(of, tegra_pwm_of_match); 242MODULE_DEVICE_TABLE(of, tegra_pwm_of_match);
244#endif
245 243
246static struct platform_driver tegra_pwm_driver = { 244static struct platform_driver tegra_pwm_driver = {
247 .driver = { 245 .driver = {
248 .name = "tegra-pwm", 246 .name = "tegra-pwm",
249 .of_match_table = of_match_ptr(tegra_pwm_of_match), 247 .of_match_table = tegra_pwm_of_match,
250 }, 248 },
251 .probe = tegra_pwm_probe, 249 .probe = tegra_pwm_probe,
252 .remove = tegra_pwm_remove, 250 .remove = tegra_pwm_remove,
diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c
index 27a67d6b27c1..22e96e2bffd3 100644
--- a/drivers/pwm/pwm-tiecap.c
+++ b/drivers/pwm/pwm-tiecap.c
@@ -41,10 +41,17 @@
41#define ECCTL2_SYNC_SEL_DISA (BIT(7) | BIT(6)) 41#define ECCTL2_SYNC_SEL_DISA (BIT(7) | BIT(6))
42#define ECCTL2_TSCTR_FREERUN BIT(4) 42#define ECCTL2_TSCTR_FREERUN BIT(4)
43 43
44struct ecap_context {
45 u32 cap3;
46 u32 cap4;
47 u16 ecctl2;
48};
49
44struct ecap_pwm_chip { 50struct ecap_pwm_chip {
45 struct pwm_chip chip; 51 struct pwm_chip chip;
46 unsigned int clk_rate; 52 unsigned int clk_rate;
47 void __iomem *mmio_base; 53 void __iomem *mmio_base;
54 struct ecap_context ctx;
48}; 55};
49 56
50static inline struct ecap_pwm_chip *to_ecap_pwm_chip(struct pwm_chip *chip) 57static inline struct ecap_pwm_chip *to_ecap_pwm_chip(struct pwm_chip *chip)
@@ -288,11 +295,57 @@ static int ecap_pwm_remove(struct platform_device *pdev)
288 return pwmchip_remove(&pc->chip); 295 return pwmchip_remove(&pc->chip);
289} 296}
290 297
298void ecap_pwm_save_context(struct ecap_pwm_chip *pc)
299{
300 pm_runtime_get_sync(pc->chip.dev);
301 pc->ctx.ecctl2 = readw(pc->mmio_base + ECCTL2);
302 pc->ctx.cap4 = readl(pc->mmio_base + CAP4);
303 pc->ctx.cap3 = readl(pc->mmio_base + CAP3);
304 pm_runtime_put_sync(pc->chip.dev);
305}
306
307void ecap_pwm_restore_context(struct ecap_pwm_chip *pc)
308{
309 writel(pc->ctx.cap3, pc->mmio_base + CAP3);
310 writel(pc->ctx.cap4, pc->mmio_base + CAP4);
311 writew(pc->ctx.ecctl2, pc->mmio_base + ECCTL2);
312}
313
314static int ecap_pwm_suspend(struct device *dev)
315{
316 struct ecap_pwm_chip *pc = dev_get_drvdata(dev);
317 struct pwm_device *pwm = pc->chip.pwms;
318
319 ecap_pwm_save_context(pc);
320
321 /* Disable explicitly if PWM is running */
322 if (test_bit(PWMF_ENABLED, &pwm->flags))
323 pm_runtime_put_sync(dev);
324
325 return 0;
326}
327
328static int ecap_pwm_resume(struct device *dev)
329{
330 struct ecap_pwm_chip *pc = dev_get_drvdata(dev);
331 struct pwm_device *pwm = pc->chip.pwms;
332
333 /* Enable explicitly if PWM was running */
334 if (test_bit(PWMF_ENABLED, &pwm->flags))
335 pm_runtime_get_sync(dev);
336
337 ecap_pwm_restore_context(pc);
338 return 0;
339}
340
341static SIMPLE_DEV_PM_OPS(ecap_pwm_pm_ops, ecap_pwm_suspend, ecap_pwm_resume);
342
291static struct platform_driver ecap_pwm_driver = { 343static struct platform_driver ecap_pwm_driver = {
292 .driver = { 344 .driver = {
293 .name = "ecap", 345 .name = "ecap",
294 .owner = THIS_MODULE, 346 .owner = THIS_MODULE,
295 .of_match_table = ecap_of_match, 347 .of_match_table = ecap_of_match,
348 .pm = &ecap_pwm_pm_ops,
296 }, 349 },
297 .probe = ecap_pwm_probe, 350 .probe = ecap_pwm_probe,
298 .remove = ecap_pwm_remove, 351 .remove = ecap_pwm_remove,
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index 5a1399580533..8b4c86fa99c8 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -113,6 +113,17 @@
113 113
114#define NUM_PWM_CHANNEL 2 /* EHRPWM channels */ 114#define NUM_PWM_CHANNEL 2 /* EHRPWM channels */
115 115
116struct ehrpwm_context {
117 u16 tbctl;
118 u16 tbprd;
119 u16 cmpa;
120 u16 cmpb;
121 u16 aqctla;
122 u16 aqctlb;
123 u16 aqsfrc;
124 u16 aqcsfrc;
125};
126
116struct ehrpwm_pwm_chip { 127struct ehrpwm_pwm_chip {
117 struct pwm_chip chip; 128 struct pwm_chip chip;
118 unsigned int clk_rate; 129 unsigned int clk_rate;
@@ -120,6 +131,7 @@ struct ehrpwm_pwm_chip {
120 unsigned long period_cycles[NUM_PWM_CHANNEL]; 131 unsigned long period_cycles[NUM_PWM_CHANNEL];
121 enum pwm_polarity polarity[NUM_PWM_CHANNEL]; 132 enum pwm_polarity polarity[NUM_PWM_CHANNEL];
122 struct clk *tbclk; 133 struct clk *tbclk;
134 struct ehrpwm_context ctx;
123}; 135};
124 136
125static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) 137static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip)
@@ -127,6 +139,11 @@ static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip)
127 return container_of(chip, struct ehrpwm_pwm_chip, chip); 139 return container_of(chip, struct ehrpwm_pwm_chip, chip);
128} 140}
129 141
142static u16 ehrpwm_read(void *base, int offset)
143{
144 return readw(base + offset);
145}
146
130static void ehrpwm_write(void *base, int offset, unsigned int val) 147static void ehrpwm_write(void *base, int offset, unsigned int val)
131{ 148{
132 writew(val & 0xFFFF, base + offset); 149 writew(val & 0xFFFF, base + offset);
@@ -318,6 +335,7 @@ static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
318{ 335{
319 struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip); 336 struct ehrpwm_pwm_chip *pc = to_ehrpwm_pwm_chip(chip);
320 unsigned short aqcsfrc_val, aqcsfrc_mask; 337 unsigned short aqcsfrc_val, aqcsfrc_mask;
338 int ret;
321 339
322 /* Leave clock enabled on enabling PWM */ 340 /* Leave clock enabled on enabling PWM */
323 pm_runtime_get_sync(chip->dev); 341 pm_runtime_get_sync(chip->dev);
@@ -341,7 +359,12 @@ static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
341 configure_polarity(pc, pwm->hwpwm); 359 configure_polarity(pc, pwm->hwpwm);
342 360
343 /* Enable TBCLK before enabling PWM device */ 361 /* Enable TBCLK before enabling PWM device */
344 clk_enable(pc->tbclk); 362 ret = clk_prepare_enable(pc->tbclk);
363 if (ret) {
364 pr_err("Failed to enable TBCLK for %s\n",
365 dev_name(pc->chip.dev));
366 return ret;
367 }
345 368
346 /* Enable time counter for free_run */ 369 /* Enable time counter for free_run */
347 ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_FREE_RUN); 370 ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_FREE_RUN);
@@ -372,7 +395,7 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
372 ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val); 395 ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val);
373 396
374 /* Disabling TBCLK on PWM disable */ 397 /* Disabling TBCLK on PWM disable */
375 clk_disable(pc->tbclk); 398 clk_disable_unprepare(pc->tbclk);
376 399
377 /* Stop Time base counter */ 400 /* Stop Time base counter */
378 ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_STOP_NEXT); 401 ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_STOP_NEXT);
@@ -510,11 +533,77 @@ static int ehrpwm_pwm_remove(struct platform_device *pdev)
510 return pwmchip_remove(&pc->chip); 533 return pwmchip_remove(&pc->chip);
511} 534}
512 535
536void ehrpwm_pwm_save_context(struct ehrpwm_pwm_chip *pc)
537{
538 pm_runtime_get_sync(pc->chip.dev);
539 pc->ctx.tbctl = ehrpwm_read(pc->mmio_base, TBCTL);
540 pc->ctx.tbprd = ehrpwm_read(pc->mmio_base, TBPRD);
541 pc->ctx.cmpa = ehrpwm_read(pc->mmio_base, CMPA);
542 pc->ctx.cmpb = ehrpwm_read(pc->mmio_base, CMPB);
543 pc->ctx.aqctla = ehrpwm_read(pc->mmio_base, AQCTLA);
544 pc->ctx.aqctlb = ehrpwm_read(pc->mmio_base, AQCTLB);
545 pc->ctx.aqsfrc = ehrpwm_read(pc->mmio_base, AQSFRC);
546 pc->ctx.aqcsfrc = ehrpwm_read(pc->mmio_base, AQCSFRC);
547 pm_runtime_put_sync(pc->chip.dev);
548}
549
550void ehrpwm_pwm_restore_context(struct ehrpwm_pwm_chip *pc)
551{
552 ehrpwm_write(pc->mmio_base, TBPRD, pc->ctx.tbprd);
553 ehrpwm_write(pc->mmio_base, CMPA, pc->ctx.cmpa);
554 ehrpwm_write(pc->mmio_base, CMPB, pc->ctx.cmpb);
555 ehrpwm_write(pc->mmio_base, AQCTLA, pc->ctx.aqctla);
556 ehrpwm_write(pc->mmio_base, AQCTLB, pc->ctx.aqctlb);
557 ehrpwm_write(pc->mmio_base, AQSFRC, pc->ctx.aqsfrc);
558 ehrpwm_write(pc->mmio_base, AQCSFRC, pc->ctx.aqcsfrc);
559 ehrpwm_write(pc->mmio_base, TBCTL, pc->ctx.tbctl);
560}
561
562static int ehrpwm_pwm_suspend(struct device *dev)
563{
564 struct ehrpwm_pwm_chip *pc = dev_get_drvdata(dev);
565 int i;
566
567 ehrpwm_pwm_save_context(pc);
568 for (i = 0; i < pc->chip.npwm; i++) {
569 struct pwm_device *pwm = &pc->chip.pwms[i];
570
571 if (!test_bit(PWMF_ENABLED, &pwm->flags))
572 continue;
573
574 /* Disable explicitly if PWM is running */
575 pm_runtime_put_sync(dev);
576 }
577 return 0;
578}
579
580static int ehrpwm_pwm_resume(struct device *dev)
581{
582 struct ehrpwm_pwm_chip *pc = dev_get_drvdata(dev);
583 int i;
584
585 for (i = 0; i < pc->chip.npwm; i++) {
586 struct pwm_device *pwm = &pc->chip.pwms[i];
587
588 if (!test_bit(PWMF_ENABLED, &pwm->flags))
589 continue;
590
591 /* Enable explicitly if PWM was running */
592 pm_runtime_get_sync(dev);
593 }
594 ehrpwm_pwm_restore_context(pc);
595 return 0;
596}
597
598static SIMPLE_DEV_PM_OPS(ehrpwm_pwm_pm_ops, ehrpwm_pwm_suspend,
599 ehrpwm_pwm_resume);
600
513static struct platform_driver ehrpwm_pwm_driver = { 601static struct platform_driver ehrpwm_pwm_driver = {
514 .driver = { 602 .driver = {
515 .name = "ehrpwm", 603 .name = "ehrpwm",
516 .owner = THIS_MODULE, 604 .owner = THIS_MODULE,
517 .of_match_table = ehrpwm_of_match, 605 .of_match_table = ehrpwm_of_match,
606 .pm = &ehrpwm_pwm_pm_ops,
518 }, 607 },
519 .probe = ehrpwm_pwm_probe, 608 .probe = ehrpwm_pwm_probe,
520 .remove = ehrpwm_pwm_remove, 609 .remove = ehrpwm_pwm_remove,
diff --git a/drivers/pwm/pwm-twl-led.c b/drivers/pwm/pwm-twl-led.c
index 9dfa0f3eca30..83e25d45d640 100644
--- a/drivers/pwm/pwm-twl-led.c
+++ b/drivers/pwm/pwm-twl-led.c
@@ -300,6 +300,7 @@ static int twl_pwmled_probe(struct platform_device *pdev)
300 300
301 twl->chip.dev = &pdev->dev; 301 twl->chip.dev = &pdev->dev;
302 twl->chip.base = -1; 302 twl->chip.base = -1;
303 twl->chip.can_sleep = true;
303 304
304 mutex_init(&twl->mutex); 305 mutex_init(&twl->mutex);
305 306
diff --git a/drivers/pwm/pwm-twl.c b/drivers/pwm/pwm-twl.c
index e65db95d5e59..bf3fda294223 100644
--- a/drivers/pwm/pwm-twl.c
+++ b/drivers/pwm/pwm-twl.c
@@ -200,8 +200,7 @@ out:
200 200
201static void twl4030_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) 201static void twl4030_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
202{ 202{
203 struct twl_pwm_chip *twl = container_of(chip, struct twl_pwm_chip, 203 struct twl_pwm_chip *twl = to_twl(chip);
204 chip);
205 int ret; 204 int ret;
206 u8 val, mask; 205 u8 val, mask;
207 206
@@ -231,8 +230,7 @@ out:
231 230
232static int twl6030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) 231static int twl6030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
233{ 232{
234 struct twl_pwm_chip *twl = container_of(chip, struct twl_pwm_chip, 233 struct twl_pwm_chip *twl = to_twl(chip);
235 chip);
236 int ret; 234 int ret;
237 u8 val; 235 u8 val;
238 236
@@ -255,8 +253,7 @@ out:
255 253
256static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) 254static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
257{ 255{
258 struct twl_pwm_chip *twl = container_of(chip, struct twl_pwm_chip, 256 struct twl_pwm_chip *twl = to_twl(chip);
259 chip);
260 int ret; 257 int ret;
261 u8 val; 258 u8 val;
262 259
@@ -315,6 +312,7 @@ static int twl_pwm_probe(struct platform_device *pdev)
315 twl->chip.dev = &pdev->dev; 312 twl->chip.dev = &pdev->dev;
316 twl->chip.base = -1; 313 twl->chip.base = -1;
317 twl->chip.npwm = 2; 314 twl->chip.npwm = 2;
315 twl->chip.can_sleep = true;
318 316
319 mutex_init(&twl->mutex); 317 mutex_init(&twl->mutex);
320 318
diff --git a/drivers/pwm/pwm-vt8500.c b/drivers/pwm/pwm-vt8500.c
index f9de9b28e46e..69effd19afc7 100644
--- a/drivers/pwm/pwm-vt8500.c
+++ b/drivers/pwm/pwm-vt8500.c
@@ -36,6 +36,25 @@
36 */ 36 */
37#define VT8500_NR_PWMS 2 37#define VT8500_NR_PWMS 2
38 38
39#define REG_CTRL(pwm) (((pwm) << 4) + 0x00)
40#define REG_SCALAR(pwm) (((pwm) << 4) + 0x04)
41#define REG_PERIOD(pwm) (((pwm) << 4) + 0x08)
42#define REG_DUTY(pwm) (((pwm) << 4) + 0x0C)
43#define REG_STATUS 0x40
44
45#define CTRL_ENABLE BIT(0)
46#define CTRL_INVERT BIT(1)
47#define CTRL_AUTOLOAD BIT(2)
48#define CTRL_STOP_IMM BIT(3)
49#define CTRL_LOAD_PRESCALE BIT(4)
50#define CTRL_LOAD_PERIOD BIT(5)
51
52#define STATUS_CTRL_UPDATE BIT(0)
53#define STATUS_SCALAR_UPDATE BIT(1)
54#define STATUS_PERIOD_UPDATE BIT(2)
55#define STATUS_DUTY_UPDATE BIT(3)
56#define STATUS_ALL_UPDATE 0x0F
57
39struct vt8500_chip { 58struct vt8500_chip {
40 struct pwm_chip chip; 59 struct pwm_chip chip;
41 void __iomem *base; 60 void __iomem *base;
@@ -45,15 +64,17 @@ struct vt8500_chip {
45#define to_vt8500_chip(chip) container_of(chip, struct vt8500_chip, chip) 64#define to_vt8500_chip(chip) container_of(chip, struct vt8500_chip, chip)
46 65
47#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) 66#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
48static inline void pwm_busy_wait(void __iomem *reg, u8 bitmask) 67static inline void pwm_busy_wait(struct vt8500_chip *vt8500, int nr, u8 bitmask)
49{ 68{
50 int loops = msecs_to_loops(10); 69 int loops = msecs_to_loops(10);
51 while ((readb(reg) & bitmask) && --loops) 70 u32 mask = bitmask << (nr << 8);
71
72 while ((readl(vt8500->base + REG_STATUS) & mask) && --loops)
52 cpu_relax(); 73 cpu_relax();
53 74
54 if (unlikely(!loops)) 75 if (unlikely(!loops))
55 pr_warn("Waiting for status bits 0x%x to clear timed out\n", 76 dev_warn(vt8500->chip.dev, "Waiting for status bits 0x%x to clear timed out\n",
56 bitmask); 77 mask);
57} 78}
58 79
59static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, 80static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
@@ -63,6 +84,7 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
63 unsigned long long c; 84 unsigned long long c;
64 unsigned long period_cycles, prescale, pv, dc; 85 unsigned long period_cycles, prescale, pv, dc;
65 int err; 86 int err;
87 u32 val;
66 88
67 err = clk_enable(vt8500->clk); 89 err = clk_enable(vt8500->clk);
68 if (err < 0) { 90 if (err < 0) {
@@ -91,14 +113,19 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
91 do_div(c, period_ns); 113 do_div(c, period_ns);
92 dc = c; 114 dc = c;
93 115
94 pwm_busy_wait(vt8500->base + 0x40 + pwm->hwpwm, (1 << 1)); 116 writel(prescale, vt8500->base + REG_SCALAR(pwm->hwpwm));
95 writel(prescale, vt8500->base + 0x4 + (pwm->hwpwm << 4)); 117 pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_SCALAR_UPDATE);
96 118
97 pwm_busy_wait(vt8500->base + 0x40 + pwm->hwpwm, (1 << 2)); 119 writel(pv, vt8500->base + REG_PERIOD(pwm->hwpwm));
98 writel(pv, vt8500->base + 0x8 + (pwm->hwpwm << 4)); 120 pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_PERIOD_UPDATE);
99 121
100 pwm_busy_wait(vt8500->base + 0x40 + pwm->hwpwm, (1 << 3)); 122 writel(dc, vt8500->base + REG_DUTY(pwm->hwpwm));
101 writel(dc, vt8500->base + 0xc + (pwm->hwpwm << 4)); 123 pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_DUTY_UPDATE);
124
125 val = readl(vt8500->base + REG_CTRL(pwm->hwpwm));
126 val |= CTRL_AUTOLOAD;
127 writel(val, vt8500->base + REG_CTRL(pwm->hwpwm));
128 pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE);
102 129
103 clk_disable(vt8500->clk); 130 clk_disable(vt8500->clk);
104 return 0; 131 return 0;
@@ -106,8 +133,9 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
106 133
107static int vt8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) 134static int vt8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
108{ 135{
109 int err;
110 struct vt8500_chip *vt8500 = to_vt8500_chip(chip); 136 struct vt8500_chip *vt8500 = to_vt8500_chip(chip);
137 int err;
138 u32 val;
111 139
112 err = clk_enable(vt8500->clk); 140 err = clk_enable(vt8500->clk);
113 if (err < 0) { 141 if (err < 0) {
@@ -115,25 +143,52 @@ static int vt8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
115 return err; 143 return err;
116 } 144 }
117 145
118 pwm_busy_wait(vt8500->base + 0x40 + pwm->hwpwm, (1 << 0)); 146 val = readl(vt8500->base + REG_CTRL(pwm->hwpwm));
119 writel(5, vt8500->base + (pwm->hwpwm << 4)); 147 val |= CTRL_ENABLE;
148 writel(val, vt8500->base + REG_CTRL(pwm->hwpwm));
149 pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE);
150
120 return 0; 151 return 0;
121} 152}
122 153
123static void vt8500_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) 154static void vt8500_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
124{ 155{
125 struct vt8500_chip *vt8500 = to_vt8500_chip(chip); 156 struct vt8500_chip *vt8500 = to_vt8500_chip(chip);
157 u32 val;
126 158
127 pwm_busy_wait(vt8500->base + 0x40 + pwm->hwpwm, (1 << 0)); 159 val = readl(vt8500->base + REG_CTRL(pwm->hwpwm));
128 writel(0, vt8500->base + (pwm->hwpwm << 4)); 160 val &= ~CTRL_ENABLE;
161 writel(val, vt8500->base + REG_CTRL(pwm->hwpwm));
162 pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE);
129 163
130 clk_disable(vt8500->clk); 164 clk_disable(vt8500->clk);
131} 165}
132 166
167static int vt8500_pwm_set_polarity(struct pwm_chip *chip,
168 struct pwm_device *pwm,
169 enum pwm_polarity polarity)
170{
171 struct vt8500_chip *vt8500 = to_vt8500_chip(chip);
172 u32 val;
173
174 val = readl(vt8500->base + REG_CTRL(pwm->hwpwm));
175
176 if (polarity == PWM_POLARITY_INVERSED)
177 val |= CTRL_INVERT;
178 else
179 val &= ~CTRL_INVERT;
180
181 writel(val, vt8500->base + REG_CTRL(pwm->hwpwm));
182 pwm_busy_wait(vt8500, pwm->hwpwm, STATUS_CTRL_UPDATE);
183
184 return 0;
185}
186
133static struct pwm_ops vt8500_pwm_ops = { 187static struct pwm_ops vt8500_pwm_ops = {
134 .enable = vt8500_pwm_enable, 188 .enable = vt8500_pwm_enable,
135 .disable = vt8500_pwm_disable, 189 .disable = vt8500_pwm_disable,
136 .config = vt8500_pwm_config, 190 .config = vt8500_pwm_config,
191 .set_polarity = vt8500_pwm_set_polarity,
137 .owner = THIS_MODULE, 192 .owner = THIS_MODULE,
138}; 193};
139 194
@@ -163,6 +218,8 @@ static int vt8500_pwm_probe(struct platform_device *pdev)
163 218
164 chip->chip.dev = &pdev->dev; 219 chip->chip.dev = &pdev->dev;
165 chip->chip.ops = &vt8500_pwm_ops; 220 chip->chip.ops = &vt8500_pwm_ops;
221 chip->chip.of_xlate = of_pwm_xlate_with_flags;
222 chip->chip.of_pwm_n_cells = 3;
166 chip->chip.base = -1; 223 chip->chip.base = -1;
167 chip->chip.npwm = VT8500_NR_PWMS; 224 chip->chip.npwm = VT8500_NR_PWMS;
168 225
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index f2f4c43d6e22..fa00304a63d8 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -41,10 +41,9 @@ static int pwm_backlight_update_status(struct backlight_device *bl)
41 int brightness = bl->props.brightness; 41 int brightness = bl->props.brightness;
42 int max = bl->props.max_brightness; 42 int max = bl->props.max_brightness;
43 43
44 if (bl->props.power != FB_BLANK_UNBLANK) 44 if (bl->props.power != FB_BLANK_UNBLANK ||
45 brightness = 0; 45 bl->props.fb_blank != FB_BLANK_UNBLANK ||
46 46 bl->props.state & BL_CORE_FBBLANK)
47 if (bl->props.fb_blank != FB_BLANK_UNBLANK)
48 brightness = 0; 47 brightness = 0;
49 48
50 if (pb->notify) 49 if (pb->notify)
@@ -135,12 +134,6 @@ static int pwm_backlight_parse_dt(struct device *dev,
135 if (ret < 0) 134 if (ret < 0)
136 return ret; 135 return ret;
137 136
138 if (value >= data->max_brightness) {
139 dev_warn(dev, "invalid default brightness level: %u, using %u\n",
140 value, data->max_brightness - 1);
141 value = data->max_brightness - 1;
142 }
143
144 data->dft_brightness = value; 137 data->dft_brightness = value;
145 data->max_brightness--; 138 data->max_brightness--;
146 } 139 }
@@ -249,6 +242,13 @@ static int pwm_backlight_probe(struct platform_device *pdev)
249 goto err_alloc; 242 goto err_alloc;
250 } 243 }
251 244
245 if (data->dft_brightness > data->max_brightness) {
246 dev_warn(&pdev->dev,
247 "invalid default brightness level: %u, using %u\n",
248 data->dft_brightness, data->max_brightness);
249 data->dft_brightness = data->max_brightness;
250 }
251
252 bl->props.brightness = data->dft_brightness; 252 bl->props.brightness = data->dft_brightness;
253 backlight_update_status(bl); 253 backlight_update_status(bl);
254 254
diff --git a/include/linux/pwm.h b/include/linux/pwm.h
index 70655a205b74..a4df2042b79c 100644
--- a/include/linux/pwm.h
+++ b/include/linux/pwm.h
@@ -146,6 +146,8 @@ struct pwm_ops {
146 * @base: number of first PWM controlled by this chip 146 * @base: number of first PWM controlled by this chip
147 * @npwm: number of PWMs controlled by this chip 147 * @npwm: number of PWMs controlled by this chip
148 * @pwms: array of PWM devices allocated by the framework 148 * @pwms: array of PWM devices allocated by the framework
149 * @can_sleep: must be true if the .config(), .enable() or .disable()
150 * operations may sleep
149 */ 151 */
150struct pwm_chip { 152struct pwm_chip {
151 struct device *dev; 153 struct device *dev;
@@ -159,6 +161,7 @@ struct pwm_chip {
159 struct pwm_device * (*of_xlate)(struct pwm_chip *pc, 161 struct pwm_device * (*of_xlate)(struct pwm_chip *pc,
160 const struct of_phandle_args *args); 162 const struct of_phandle_args *args);
161 unsigned int of_pwm_n_cells; 163 unsigned int of_pwm_n_cells;
164 bool can_sleep;
162}; 165};
163 166
164#if IS_ENABLED(CONFIG_PWM) 167#if IS_ENABLED(CONFIG_PWM)
@@ -182,6 +185,8 @@ struct pwm_device *devm_pwm_get(struct device *dev, const char *con_id);
182struct pwm_device *devm_of_pwm_get(struct device *dev, struct device_node *np, 185struct pwm_device *devm_of_pwm_get(struct device *dev, struct device_node *np,
183 const char *con_id); 186 const char *con_id);
184void devm_pwm_put(struct device *dev, struct pwm_device *pwm); 187void devm_pwm_put(struct device *dev, struct pwm_device *pwm);
188
189bool pwm_can_sleep(struct pwm_device *pwm);
185#else 190#else
186static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data) 191static inline int pwm_set_chip_data(struct pwm_device *pwm, void *data)
187{ 192{
@@ -242,6 +247,11 @@ static inline struct pwm_device *devm_of_pwm_get(struct device *dev,
242static inline void devm_pwm_put(struct device *dev, struct pwm_device *pwm) 247static inline void devm_pwm_put(struct device *dev, struct pwm_device *pwm)
243{ 248{
244} 249}
250
251static inline bool pwm_can_sleep(struct pwm_device *pwm)
252{
253 return false;
254}
245#endif 255#endif
246 256
247struct pwm_lookup { 257struct pwm_lookup {