aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-27 11:15:51 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-27 11:15:51 -0500
commit398b60a8de46adfbd43aa4c01753acf0161ec764 (patch)
tree7d3a1673f4c764782cec34523967b386bf085fc6 /drivers
parent028e219eff45ce8ba962c59e3dbc622499e88d50 (diff)
parent6691a19966f04dd81e60505f9630c1a7cf148507 (diff)
Merge tag 'pwm/for-3.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm
Pull pwm changes from Thierry Reding: "The patches for this release cycle include various enhancements (device tree support, better compile coverage, ...) for existing drivers. There is a new driver for Atmel SoCs. Various drivers as well as the sysfs support received minor fixes and cleanups" * tag 'pwm/for-3.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: pwm: tiecap: Remove duplicate put_sync call pwm: tiehrpwm: use dev_err() instead of pr_err() pwm: pxa: remove unnecessary space before tabs pwm: ep93xx: split module author names pwm: use seq_puts() instead of seq_printf() pwm: atmel-pwm: Do not unprepare clock after successful registration of: Add Atmel PWM controller device tree binding pwm: atmel-pwm: Add Atmel PWM controller driver backlight: pwm_bl: Remove error message upon devm_kzalloc() failure pwm: pca9685: depends on I2C rather than REGMAP_I2C pwm: renesas-tpu: Enable driver compilation with COMPILE_TEST pwm: jz4740: Use devm_clk_get() pwm: jz4740: Pass device to clk_get() pwm: sysfs: Convert to use ATTRIBUTE_GROUPS macro pwm: pxa: Add device tree support
Diffstat (limited to 'drivers')
-rw-r--r--drivers/pwm/Kconfig14
-rw-r--r--drivers/pwm/Makefile1
-rw-r--r--drivers/pwm/core.c6
-rw-r--r--drivers/pwm/pwm-atmel.c395
-rw-r--r--drivers/pwm/pwm-ep93xx.c4
-rw-r--r--drivers/pwm/pwm-jz4740.c20
-rw-r--r--drivers/pwm/pwm-pxa.c55
-rw-r--r--drivers/pwm/pwm-tiecap.c1
-rw-r--r--drivers/pwm/pwm-tiehrpwm.c4
-rw-r--r--drivers/pwm/sysfs.c12
-rw-r--r--drivers/video/backlight/pwm_bl.c1
11 files changed, 474 insertions, 39 deletions
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 7acab93d5a47..22f2f2857b82 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -41,6 +41,15 @@ config PWM_AB8500
41 To compile this driver as a module, choose M here: the module 41 To compile this driver as a module, choose M here: the module
42 will be called pwm-ab8500. 42 will be called pwm-ab8500.
43 43
44config PWM_ATMEL
45 tristate "Atmel PWM support"
46 depends on ARCH_AT91
47 help
48 Generic PWM framework driver for Atmel SoC.
49
50 To compile this driver as a module, choose M here: the module
51 will be called pwm-atmel.
52
44config PWM_ATMEL_TCB 53config PWM_ATMEL_TCB
45 tristate "Atmel TC Block PWM support" 54 tristate "Atmel TC Block PWM support"
46 depends on ATMEL_TCLIB && OF 55 depends on ATMEL_TCLIB && OF
@@ -122,7 +131,8 @@ config PWM_MXS
122 131
123config PWM_PCA9685 132config PWM_PCA9685
124 tristate "NXP PCA9685 PWM driver" 133 tristate "NXP PCA9685 PWM driver"
125 depends on OF && REGMAP_I2C 134 depends on OF && I2C
135 select REGMAP_I2C
126 help 136 help
127 Generic PWM framework driver for NXP PCA9685 LED controller. 137 Generic PWM framework driver for NXP PCA9685 LED controller.
128 138
@@ -149,7 +159,7 @@ config PWM_PXA
149 159
150config PWM_RENESAS_TPU 160config PWM_RENESAS_TPU
151 tristate "Renesas TPU PWM support" 161 tristate "Renesas TPU PWM support"
152 depends on ARCH_SHMOBILE 162 depends on ARCH_SHMOBILE || COMPILE_TEST
153 help 163 help
154 This driver exposes the Timer Pulse Unit (TPU) PWM controller found 164 This driver exposes the Timer Pulse Unit (TPU) PWM controller found
155 in Renesas chips through the PWM API. 165 in Renesas chips through the PWM API.
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index 4abf337dcd02..d8906ec69976 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -1,6 +1,7 @@
1obj-$(CONFIG_PWM) += core.o 1obj-$(CONFIG_PWM) += core.o
2obj-$(CONFIG_PWM_SYSFS) += sysfs.o 2obj-$(CONFIG_PWM_SYSFS) += sysfs.o
3obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o 3obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o
4obj-$(CONFIG_PWM_ATMEL) += pwm-atmel.o
4obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o 5obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o
5obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o 6obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o
6obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o 7obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
index 2ca95042a0b9..a80471399c20 100644
--- a/drivers/pwm/core.c
+++ b/drivers/pwm/core.c
@@ -808,12 +808,12 @@ static void pwm_dbg_show(struct pwm_chip *chip, struct seq_file *s)
808 seq_printf(s, " pwm-%-3d (%-20.20s):", i, pwm->label); 808 seq_printf(s, " pwm-%-3d (%-20.20s):", i, pwm->label);
809 809
810 if (test_bit(PWMF_REQUESTED, &pwm->flags)) 810 if (test_bit(PWMF_REQUESTED, &pwm->flags))
811 seq_printf(s, " requested"); 811 seq_puts(s, " requested");
812 812
813 if (test_bit(PWMF_ENABLED, &pwm->flags)) 813 if (test_bit(PWMF_ENABLED, &pwm->flags))
814 seq_printf(s, " enabled"); 814 seq_puts(s, " enabled");
815 815
816 seq_printf(s, "\n"); 816 seq_puts(s, "\n");
817 } 817 }
818} 818}
819 819
diff --git a/drivers/pwm/pwm-atmel.c b/drivers/pwm/pwm-atmel.c
new file mode 100644
index 000000000000..bf4144a14661
--- /dev/null
+++ b/drivers/pwm/pwm-atmel.c
@@ -0,0 +1,395 @@
1/*
2 * Driver for Atmel Pulse Width Modulation Controller
3 *
4 * Copyright (C) 2013 Atmel Corporation
5 * Bo Shen <voice.shen@atmel.com>
6 *
7 * Licensed under GPLv2.
8 */
9
10#include <linux/clk.h>
11#include <linux/err.h>
12#include <linux/io.h>
13#include <linux/module.h>
14#include <linux/of.h>
15#include <linux/of_device.h>
16#include <linux/platform_device.h>
17#include <linux/pwm.h>
18#include <linux/slab.h>
19
20/* The following is global registers for PWM controller */
21#define PWM_ENA 0x04
22#define PWM_DIS 0x08
23#define PWM_SR 0x0C
24/* Bit field in SR */
25#define PWM_SR_ALL_CH_ON 0x0F
26
27/* The following register is PWM channel related registers */
28#define PWM_CH_REG_OFFSET 0x200
29#define PWM_CH_REG_SIZE 0x20
30
31#define PWM_CMR 0x0
32/* Bit field in CMR */
33#define PWM_CMR_CPOL (1 << 9)
34#define PWM_CMR_UPD_CDTY (1 << 10)
35
36/* The following registers for PWM v1 */
37#define PWMV1_CDTY 0x04
38#define PWMV1_CPRD 0x08
39#define PWMV1_CUPD 0x10
40
41/* The following registers for PWM v2 */
42#define PWMV2_CDTY 0x04
43#define PWMV2_CDTYUPD 0x08
44#define PWMV2_CPRD 0x0C
45#define PWMV2_CPRDUPD 0x10
46
47/*
48 * Max value for duty and period
49 *
50 * Although the duty and period register is 32 bit,
51 * however only the LSB 16 bits are significant.
52 */
53#define PWM_MAX_DTY 0xFFFF
54#define PWM_MAX_PRD 0xFFFF
55#define PRD_MAX_PRES 10
56
57struct atmel_pwm_chip {
58 struct pwm_chip chip;
59 struct clk *clk;
60 void __iomem *base;
61
62 void (*config)(struct pwm_chip *chip, struct pwm_device *pwm,
63 unsigned long dty, unsigned long prd);
64};
65
66static inline struct atmel_pwm_chip *to_atmel_pwm_chip(struct pwm_chip *chip)
67{
68 return container_of(chip, struct atmel_pwm_chip, chip);
69}
70
71static inline u32 atmel_pwm_readl(struct atmel_pwm_chip *chip,
72 unsigned long offset)
73{
74 return readl_relaxed(chip->base + offset);
75}
76
77static inline void atmel_pwm_writel(struct atmel_pwm_chip *chip,
78 unsigned long offset, unsigned long val)
79{
80 writel_relaxed(val, chip->base + offset);
81}
82
83static inline u32 atmel_pwm_ch_readl(struct atmel_pwm_chip *chip,
84 unsigned int ch, unsigned long offset)
85{
86 unsigned long base = PWM_CH_REG_OFFSET + ch * PWM_CH_REG_SIZE;
87
88 return readl_relaxed(chip->base + base + offset);
89}
90
91static inline void atmel_pwm_ch_writel(struct atmel_pwm_chip *chip,
92 unsigned int ch, unsigned long offset,
93 unsigned long val)
94{
95 unsigned long base = PWM_CH_REG_OFFSET + ch * PWM_CH_REG_SIZE;
96
97 writel_relaxed(val, chip->base + base + offset);
98}
99
100static int atmel_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
101 int duty_ns, int period_ns)
102{
103 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
104 unsigned long clk_rate, prd, dty;
105 unsigned long long div;
106 unsigned int pres = 0;
107 int ret;
108
109 if (test_bit(PWMF_ENABLED, &pwm->flags) && (period_ns != pwm->period)) {
110 dev_err(chip->dev, "cannot change PWM period while enabled\n");
111 return -EBUSY;
112 }
113
114 clk_rate = clk_get_rate(atmel_pwm->clk);
115 div = clk_rate;
116
117 /* Calculate the period cycles */
118 while (div > PWM_MAX_PRD) {
119 div = clk_rate / (1 << pres);
120 div = div * period_ns;
121 /* 1/Hz = 100000000 ns */
122 do_div(div, 1000000000);
123
124 if (pres++ > PRD_MAX_PRES) {
125 dev_err(chip->dev, "pres exceeds the maximum value\n");
126 return -EINVAL;
127 }
128 }
129
130 /* Calculate the duty cycles */
131 prd = div;
132 div *= duty_ns;
133 do_div(div, period_ns);
134 dty = div;
135
136 ret = clk_enable(atmel_pwm->clk);
137 if (ret) {
138 dev_err(chip->dev, "failed to enable PWM clock\n");
139 return ret;
140 }
141
142 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, pres);
143 atmel_pwm->config(chip, pwm, dty, prd);
144
145 clk_disable(atmel_pwm->clk);
146 return ret;
147}
148
149static void atmel_pwm_config_v1(struct pwm_chip *chip, struct pwm_device *pwm,
150 unsigned long dty, unsigned long prd)
151{
152 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
153 unsigned int val;
154
155 if (test_bit(PWMF_ENABLED, &pwm->flags)) {
156 /*
157 * If the PWM channel is enabled, using the update register,
158 * it needs to set bit 10 of CMR to 0
159 */
160 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV1_CUPD, dty);
161
162 val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
163 val &= ~PWM_CMR_UPD_CDTY;
164 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
165 } else {
166 /*
167 * If the PWM channel is disabled, write value to duty and
168 * period registers directly.
169 */
170 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV1_CDTY, dty);
171 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV1_CPRD, prd);
172 }
173}
174
175static void atmel_pwm_config_v2(struct pwm_chip *chip, struct pwm_device *pwm,
176 unsigned long dty, unsigned long prd)
177{
178 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
179
180 if (test_bit(PWMF_ENABLED, &pwm->flags)) {
181 /*
182 * If the PWM channel is enabled, using the duty update register
183 * to update the value.
184 */
185 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV2_CDTYUPD, dty);
186 } else {
187 /*
188 * If the PWM channel is disabled, write value to duty and
189 * period registers directly.
190 */
191 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV2_CDTY, dty);
192 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWMV2_CPRD, prd);
193 }
194}
195
196static int atmel_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
197 enum pwm_polarity polarity)
198{
199 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
200 u32 val;
201 int ret;
202
203 val = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
204
205 if (polarity == PWM_POLARITY_NORMAL)
206 val &= ~PWM_CMR_CPOL;
207 else
208 val |= PWM_CMR_CPOL;
209
210 ret = clk_enable(atmel_pwm->clk);
211 if (ret) {
212 dev_err(chip->dev, "failed to enable PWM clock\n");
213 return ret;
214 }
215
216 atmel_pwm_ch_writel(atmel_pwm, pwm->hwpwm, PWM_CMR, val);
217
218 clk_disable(atmel_pwm->clk);
219
220 return 0;
221}
222
223static int atmel_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
224{
225 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
226 int ret;
227
228 ret = clk_enable(atmel_pwm->clk);
229 if (ret) {
230 dev_err(chip->dev, "failed to enable PWM clock\n");
231 return ret;
232 }
233
234 atmel_pwm_writel(atmel_pwm, PWM_ENA, 1 << pwm->hwpwm);
235
236 return 0;
237}
238
239static void atmel_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
240{
241 struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
242
243 atmel_pwm_writel(atmel_pwm, PWM_DIS, 1 << pwm->hwpwm);
244
245 clk_disable(atmel_pwm->clk);
246}
247
248static const struct pwm_ops atmel_pwm_ops = {
249 .config = atmel_pwm_config,
250 .set_polarity = atmel_pwm_set_polarity,
251 .enable = atmel_pwm_enable,
252 .disable = atmel_pwm_disable,
253 .owner = THIS_MODULE,
254};
255
256struct atmel_pwm_data {
257 void (*config)(struct pwm_chip *chip, struct pwm_device *pwm,
258 unsigned long dty, unsigned long prd);
259};
260
261static const struct atmel_pwm_data atmel_pwm_data_v1 = {
262 .config = atmel_pwm_config_v1,
263};
264
265static const struct atmel_pwm_data atmel_pwm_data_v2 = {
266 .config = atmel_pwm_config_v2,
267};
268
269static const struct platform_device_id atmel_pwm_devtypes[] = {
270 {
271 .name = "at91sam9rl-pwm",
272 .driver_data = (kernel_ulong_t)&atmel_pwm_data_v1,
273 }, {
274 .name = "sama5d3-pwm",
275 .driver_data = (kernel_ulong_t)&atmel_pwm_data_v2,
276 }, {
277 /* sentinel */
278 },
279};
280MODULE_DEVICE_TABLE(platform, atmel_pwm_devtypes);
281
282static const struct of_device_id atmel_pwm_dt_ids[] = {
283 {
284 .compatible = "atmel,at91sam9rl-pwm",
285 .data = &atmel_pwm_data_v1,
286 }, {
287 .compatible = "atmel,sama5d3-pwm",
288 .data = &atmel_pwm_data_v2,
289 }, {
290 /* sentinel */
291 },
292};
293MODULE_DEVICE_TABLE(of, atmel_pwm_dt_ids);
294
295static inline const struct atmel_pwm_data *
296atmel_pwm_get_driver_data(struct platform_device *pdev)
297{
298 if (pdev->dev.of_node) {
299 const struct of_device_id *match;
300
301 match = of_match_device(atmel_pwm_dt_ids, &pdev->dev);
302 if (!match)
303 return NULL;
304
305 return match->data;
306 } else {
307 const struct platform_device_id *id;
308
309 id = platform_get_device_id(pdev);
310
311 return (struct atmel_pwm_data *)id->driver_data;
312 }
313}
314
315static int atmel_pwm_probe(struct platform_device *pdev)
316{
317 const struct atmel_pwm_data *data;
318 struct atmel_pwm_chip *atmel_pwm;
319 struct resource *res;
320 int ret;
321
322 data = atmel_pwm_get_driver_data(pdev);
323 if (!data)
324 return -ENODEV;
325
326 atmel_pwm = devm_kzalloc(&pdev->dev, sizeof(*atmel_pwm), GFP_KERNEL);
327 if (!atmel_pwm)
328 return -ENOMEM;
329
330 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
331 atmel_pwm->base = devm_ioremap_resource(&pdev->dev, res);
332 if (IS_ERR(atmel_pwm->base))
333 return PTR_ERR(atmel_pwm->base);
334
335 atmel_pwm->clk = devm_clk_get(&pdev->dev, NULL);
336 if (IS_ERR(atmel_pwm->clk))
337 return PTR_ERR(atmel_pwm->clk);
338
339 ret = clk_prepare(atmel_pwm->clk);
340 if (ret) {
341 dev_err(&pdev->dev, "failed to prepare PWM clock\n");
342 return ret;
343 }
344
345 atmel_pwm->chip.dev = &pdev->dev;
346 atmel_pwm->chip.ops = &atmel_pwm_ops;
347
348 if (pdev->dev.of_node) {
349 atmel_pwm->chip.of_xlate = of_pwm_xlate_with_flags;
350 atmel_pwm->chip.of_pwm_n_cells = 3;
351 }
352
353 atmel_pwm->chip.base = -1;
354 atmel_pwm->chip.npwm = 4;
355 atmel_pwm->config = data->config;
356
357 ret = pwmchip_add(&atmel_pwm->chip);
358 if (ret < 0) {
359 dev_err(&pdev->dev, "failed to add PWM chip %d\n", ret);
360 goto unprepare_clk;
361 }
362
363 platform_set_drvdata(pdev, atmel_pwm);
364
365 return ret;
366
367unprepare_clk:
368 clk_unprepare(atmel_pwm->clk);
369 return ret;
370}
371
372static int atmel_pwm_remove(struct platform_device *pdev)
373{
374 struct atmel_pwm_chip *atmel_pwm = platform_get_drvdata(pdev);
375
376 clk_unprepare(atmel_pwm->clk);
377
378 return pwmchip_remove(&atmel_pwm->chip);
379}
380
381static struct platform_driver atmel_pwm_driver = {
382 .driver = {
383 .name = "atmel-pwm",
384 .of_match_table = of_match_ptr(atmel_pwm_dt_ids),
385 },
386 .id_table = atmel_pwm_devtypes,
387 .probe = atmel_pwm_probe,
388 .remove = atmel_pwm_remove,
389};
390module_platform_driver(atmel_pwm_driver);
391
392MODULE_ALIAS("platform:atmel-pwm");
393MODULE_AUTHOR("Bo Shen <voice.shen@atmel.com>");
394MODULE_DESCRIPTION("Atmel PWM driver");
395MODULE_LICENSE("GPL v2");
diff --git a/drivers/pwm/pwm-ep93xx.c b/drivers/pwm/pwm-ep93xx.c
index 33aa4461e1ce..e593e9c45c51 100644
--- a/drivers/pwm/pwm-ep93xx.c
+++ b/drivers/pwm/pwm-ep93xx.c
@@ -224,7 +224,7 @@ static struct platform_driver ep93xx_pwm_driver = {
224module_platform_driver(ep93xx_pwm_driver); 224module_platform_driver(ep93xx_pwm_driver);
225 225
226MODULE_DESCRIPTION("Cirrus Logic EP93xx PWM driver"); 226MODULE_DESCRIPTION("Cirrus Logic EP93xx PWM driver");
227MODULE_AUTHOR("Matthieu Crapet <mcrapet@gmail.com>, " 227MODULE_AUTHOR("Matthieu Crapet <mcrapet@gmail.com>");
228 "H Hartley Sweeten <hsweeten@visionengravers.com>"); 228MODULE_AUTHOR("H Hartley Sweeten <hsweeten@visionengravers.com>");
229MODULE_ALIAS("platform:ep93xx-pwm"); 229MODULE_ALIAS("platform:ep93xx-pwm");
230MODULE_LICENSE("GPL"); 230MODULE_LICENSE("GPL");
diff --git a/drivers/pwm/pwm-jz4740.c b/drivers/pwm/pwm-jz4740.c
index 0a2ede3c3932..9c46209e1d02 100644
--- a/drivers/pwm/pwm-jz4740.c
+++ b/drivers/pwm/pwm-jz4740.c
@@ -165,13 +165,12 @@ static const struct pwm_ops jz4740_pwm_ops = {
165static int jz4740_pwm_probe(struct platform_device *pdev) 165static int jz4740_pwm_probe(struct platform_device *pdev)
166{ 166{
167 struct jz4740_pwm_chip *jz4740; 167 struct jz4740_pwm_chip *jz4740;
168 int ret;
169 168
170 jz4740 = devm_kzalloc(&pdev->dev, sizeof(*jz4740), GFP_KERNEL); 169 jz4740 = devm_kzalloc(&pdev->dev, sizeof(*jz4740), GFP_KERNEL);
171 if (!jz4740) 170 if (!jz4740)
172 return -ENOMEM; 171 return -ENOMEM;
173 172
174 jz4740->clk = clk_get(NULL, "ext"); 173 jz4740->clk = devm_clk_get(&pdev->dev, "ext");
175 if (IS_ERR(jz4740->clk)) 174 if (IS_ERR(jz4740->clk))
176 return PTR_ERR(jz4740->clk); 175 return PTR_ERR(jz4740->clk);
177 176
@@ -180,29 +179,16 @@ static int jz4740_pwm_probe(struct platform_device *pdev)
180 jz4740->chip.npwm = NUM_PWM; 179 jz4740->chip.npwm = NUM_PWM;
181 jz4740->chip.base = -1; 180 jz4740->chip.base = -1;
182 181
183 ret = pwmchip_add(&jz4740->chip);
184 if (ret < 0) {
185 clk_put(jz4740->clk);
186 return ret;
187 }
188
189 platform_set_drvdata(pdev, jz4740); 182 platform_set_drvdata(pdev, jz4740);
190 183
191 return 0; 184 return pwmchip_add(&jz4740->chip);
192} 185}
193 186
194static int jz4740_pwm_remove(struct platform_device *pdev) 187static int jz4740_pwm_remove(struct platform_device *pdev)
195{ 188{
196 struct jz4740_pwm_chip *jz4740 = platform_get_drvdata(pdev); 189 struct jz4740_pwm_chip *jz4740 = platform_get_drvdata(pdev);
197 int ret;
198
199 ret = pwmchip_remove(&jz4740->chip);
200 if (ret < 0)
201 return ret;
202 190
203 clk_put(jz4740->clk); 191 return pwmchip_remove(&jz4740->chip);
204
205 return 0;
206} 192}
207 193
208static struct platform_driver jz4740_pwm_driver = { 194static struct platform_driver jz4740_pwm_driver = {
diff --git a/drivers/pwm/pwm-pxa.c b/drivers/pwm/pwm-pxa.c
index a4d2164aaf55..8d995731cef8 100644
--- a/drivers/pwm/pwm-pxa.c
+++ b/drivers/pwm/pwm-pxa.c
@@ -8,7 +8,7 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 * 9 *
10 * 2008-02-13 initial version 10 * 2008-02-13 initial version
11 * eric miao <eric.miao@marvell.com> 11 * eric miao <eric.miao@marvell.com>
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
@@ -19,6 +19,7 @@
19#include <linux/clk.h> 19#include <linux/clk.h>
20#include <linux/io.h> 20#include <linux/io.h>
21#include <linux/pwm.h> 21#include <linux/pwm.h>
22#include <linux/of_device.h>
22 23
23#include <asm/div64.h> 24#include <asm/div64.h>
24 25
@@ -124,6 +125,46 @@ static struct pwm_ops pxa_pwm_ops = {
124 .owner = THIS_MODULE, 125 .owner = THIS_MODULE,
125}; 126};
126 127
128#ifdef CONFIG_OF
129/*
130 * Device tree users must create one device instance for each pwm channel.
131 * Hence we dispense with the HAS_SECONDARY_PWM and "tell" the original driver
132 * code that this is a single channel pxa25x-pwm. Currently all devices are
133 * supported identically.
134 */
135static struct of_device_id pwm_of_match[] = {
136 { .compatible = "marvell,pxa250-pwm", .data = &pwm_id_table[0]},
137 { .compatible = "marvell,pxa270-pwm", .data = &pwm_id_table[0]},
138 { .compatible = "marvell,pxa168-pwm", .data = &pwm_id_table[0]},
139 { .compatible = "marvell,pxa910-pwm", .data = &pwm_id_table[0]},
140 { }
141};
142MODULE_DEVICE_TABLE(of, pwm_of_match);
143#else
144#define pwm_of_match NULL
145#endif
146
147static const struct platform_device_id *pxa_pwm_get_id_dt(struct device *dev)
148{
149 const struct of_device_id *id = of_match_device(pwm_of_match, dev);
150
151 return id ? id->data : NULL;
152}
153
154static struct pwm_device *
155pxa_pwm_of_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
156{
157 struct pwm_device *pwm;
158
159 pwm = pwm_request_from_chip(pc, 0, NULL);
160 if (IS_ERR(pwm))
161 return pwm;
162
163 pwm_set_period(pwm, args->args[0]);
164
165 return pwm;
166}
167
127static int pwm_probe(struct platform_device *pdev) 168static int pwm_probe(struct platform_device *pdev)
128{ 169{
129 const struct platform_device_id *id = platform_get_device_id(pdev); 170 const struct platform_device_id *id = platform_get_device_id(pdev);
@@ -131,6 +172,12 @@ static int pwm_probe(struct platform_device *pdev)
131 struct resource *r; 172 struct resource *r;
132 int ret = 0; 173 int ret = 0;
133 174
175 if (IS_ENABLED(CONFIG_OF) && id == NULL)
176 id = pxa_pwm_get_id_dt(&pdev->dev);
177
178 if (id == NULL)
179 return -EINVAL;
180
134 pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL); 181 pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
135 if (pwm == NULL) { 182 if (pwm == NULL) {
136 dev_err(&pdev->dev, "failed to allocate memory\n"); 183 dev_err(&pdev->dev, "failed to allocate memory\n");
@@ -146,6 +193,11 @@ static int pwm_probe(struct platform_device *pdev)
146 pwm->chip.base = -1; 193 pwm->chip.base = -1;
147 pwm->chip.npwm = (id->driver_data & HAS_SECONDARY_PWM) ? 2 : 1; 194 pwm->chip.npwm = (id->driver_data & HAS_SECONDARY_PWM) ? 2 : 1;
148 195
196 if (IS_ENABLED(CONFIG_OF)) {
197 pwm->chip.of_xlate = pxa_pwm_of_xlate;
198 pwm->chip.of_pwm_n_cells = 1;
199 }
200
149 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 201 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
150 pwm->mmio_base = devm_ioremap_resource(&pdev->dev, r); 202 pwm->mmio_base = devm_ioremap_resource(&pdev->dev, r);
151 if (IS_ERR(pwm->mmio_base)) 203 if (IS_ERR(pwm->mmio_base))
@@ -176,6 +228,7 @@ static struct platform_driver pwm_driver = {
176 .driver = { 228 .driver = {
177 .name = "pxa25x-pwm", 229 .name = "pxa25x-pwm",
178 .owner = THIS_MODULE, 230 .owner = THIS_MODULE,
231 .of_match_table = pwm_of_match,
179 }, 232 },
180 .probe = pwm_probe, 233 .probe = pwm_probe,
181 .remove = pwm_remove, 234 .remove = pwm_remove,
diff --git a/drivers/pwm/pwm-tiecap.c b/drivers/pwm/pwm-tiecap.c
index 4e5c3d13d4f8..032092c7a6ae 100644
--- a/drivers/pwm/pwm-tiecap.c
+++ b/drivers/pwm/pwm-tiecap.c
@@ -279,7 +279,6 @@ static int ecap_pwm_remove(struct platform_device *pdev)
279 pwmss_submodule_state_change(pdev->dev.parent, PWMSS_ECAPCLK_STOP_REQ); 279 pwmss_submodule_state_change(pdev->dev.parent, PWMSS_ECAPCLK_STOP_REQ);
280 pm_runtime_put_sync(&pdev->dev); 280 pm_runtime_put_sync(&pdev->dev);
281 281
282 pm_runtime_put_sync(&pdev->dev);
283 pm_runtime_disable(&pdev->dev); 282 pm_runtime_disable(&pdev->dev);
284 return pwmchip_remove(&pc->chip); 283 return pwmchip_remove(&pc->chip);
285} 284}
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c
index a4d8f519d965..aee4471424d1 100644
--- a/drivers/pwm/pwm-tiehrpwm.c
+++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -360,8 +360,8 @@ static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
360 /* Enable TBCLK before enabling PWM device */ 360 /* Enable TBCLK before enabling PWM device */
361 ret = clk_enable(pc->tbclk); 361 ret = clk_enable(pc->tbclk);
362 if (ret) { 362 if (ret) {
363 pr_err("Failed to enable TBCLK for %s\n", 363 dev_err(chip->dev, "Failed to enable TBCLK for %s\n",
364 dev_name(pc->chip.dev)); 364 dev_name(pc->chip.dev));
365 return ret; 365 return ret;
366 } 366 }
367 367
diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
index 8c20332d4825..4bd0c639e16d 100644
--- a/drivers/pwm/sysfs.c
+++ b/drivers/pwm/sysfs.c
@@ -169,15 +169,7 @@ static struct attribute *pwm_attrs[] = {
169 &dev_attr_polarity.attr, 169 &dev_attr_polarity.attr,
170 NULL 170 NULL
171}; 171};
172 172ATTRIBUTE_GROUPS(pwm);
173static const struct attribute_group pwm_attr_group = {
174 .attrs = pwm_attrs,
175};
176
177static const struct attribute_group *pwm_attr_groups[] = {
178 &pwm_attr_group,
179 NULL,
180};
181 173
182static void pwm_export_release(struct device *child) 174static void pwm_export_release(struct device *child)
183{ 175{
@@ -205,7 +197,7 @@ static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
205 export->child.release = pwm_export_release; 197 export->child.release = pwm_export_release;
206 export->child.parent = parent; 198 export->child.parent = parent;
207 export->child.devt = MKDEV(0, 0); 199 export->child.devt = MKDEV(0, 0);
208 export->child.groups = pwm_attr_groups; 200 export->child.groups = pwm_groups;
209 dev_set_name(&export->child, "pwm%u", pwm->hwpwm); 201 dev_set_name(&export->child, "pwm%u", pwm->hwpwm);
210 202
211 ret = device_register(&export->child); 203 ret = device_register(&export->child);
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index fb80d68f4d33..b75201ff46f6 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -241,7 +241,6 @@ static int pwm_backlight_probe(struct platform_device *pdev)
241 241
242 pb = devm_kzalloc(&pdev->dev, sizeof(*pb), GFP_KERNEL); 242 pb = devm_kzalloc(&pdev->dev, sizeof(*pb), GFP_KERNEL);
243 if (!pb) { 243 if (!pb) {
244 dev_err(&pdev->dev, "no memory for state\n");
245 ret = -ENOMEM; 244 ret = -ENOMEM;
246 goto err_alloc; 245 goto err_alloc;
247 } 246 }