aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pwm/pwm-omap-dmtimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pwm/pwm-omap-dmtimer.c')
-rw-r--r--drivers/pwm/pwm-omap-dmtimer.c68
1 files changed, 42 insertions, 26 deletions
diff --git a/drivers/pwm/pwm-omap-dmtimer.c b/drivers/pwm/pwm-omap-dmtimer.c
index 5ad42f33e70c..665da3c8fbce 100644
--- a/drivers/pwm/pwm-omap-dmtimer.c
+++ b/drivers/pwm/pwm-omap-dmtimer.c
@@ -23,6 +23,7 @@
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/of.h> 24#include <linux/of.h>
25#include <linux/of_platform.h> 25#include <linux/of_platform.h>
26#include <linux/platform_data/dmtimer-omap.h>
26#include <linux/platform_data/pwm_omap_dmtimer.h> 27#include <linux/platform_data/pwm_omap_dmtimer.h>
27#include <linux/platform_device.h> 28#include <linux/platform_device.h>
28#include <linux/pm_runtime.h> 29#include <linux/pm_runtime.h>
@@ -37,7 +38,7 @@ struct pwm_omap_dmtimer_chip {
37 struct pwm_chip chip; 38 struct pwm_chip chip;
38 struct mutex mutex; 39 struct mutex mutex;
39 pwm_omap_dmtimer *dm_timer; 40 pwm_omap_dmtimer *dm_timer;
40 struct pwm_omap_dmtimer_pdata *pdata; 41 const struct omap_dm_timer_ops *pdata;
41 struct platform_device *dm_timer_pdev; 42 struct platform_device *dm_timer_pdev;
42}; 43};
43 44
@@ -242,19 +243,35 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
242{ 243{
243 struct device_node *np = pdev->dev.of_node; 244 struct device_node *np = pdev->dev.of_node;
244 struct device_node *timer; 245 struct device_node *timer;
246 struct platform_device *timer_pdev;
245 struct pwm_omap_dmtimer_chip *omap; 247 struct pwm_omap_dmtimer_chip *omap;
246 struct pwm_omap_dmtimer_pdata *pdata; 248 struct dmtimer_platform_data *timer_pdata;
249 const struct omap_dm_timer_ops *pdata;
247 pwm_omap_dmtimer *dm_timer; 250 pwm_omap_dmtimer *dm_timer;
248 u32 v; 251 u32 v;
249 int status; 252 int ret = 0;
250 253
251 pdata = dev_get_platdata(&pdev->dev); 254 timer = of_parse_phandle(np, "ti,timers", 0);
252 if (!pdata) { 255 if (!timer)
253 dev_err(&pdev->dev, "Missing dmtimer platform data\n"); 256 return -ENODEV;
254 return -EINVAL; 257
258 timer_pdev = of_find_device_by_node(timer);
259 if (!timer_pdev) {
260 dev_err(&pdev->dev, "Unable to find Timer pdev\n");
261 ret = -ENODEV;
262 goto put;
255 } 263 }
256 264
257 if (!pdata->request_by_node || 265 timer_pdata = dev_get_platdata(&timer_pdev->dev);
266 if (!timer_pdata) {
267 dev_err(&pdev->dev, "dmtimer pdata structure NULL\n");
268 ret = -EINVAL;
269 goto put;
270 }
271
272 pdata = timer_pdata->timer_ops;
273
274 if (!pdata || !pdata->request_by_node ||
258 !pdata->free || 275 !pdata->free ||
259 !pdata->enable || 276 !pdata->enable ||
260 !pdata->disable || 277 !pdata->disable ||
@@ -267,21 +284,26 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
267 !pdata->set_prescaler || 284 !pdata->set_prescaler ||
268 !pdata->write_counter) { 285 !pdata->write_counter) {
269 dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n"); 286 dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n");
270 return -EINVAL; 287 ret = -EINVAL;
288 goto put;
271 } 289 }
272 290
273 timer = of_parse_phandle(np, "ti,timers", 0);
274 if (!timer)
275 return -ENODEV;
276
277 if (!of_get_property(timer, "ti,timer-pwm", NULL)) { 291 if (!of_get_property(timer, "ti,timer-pwm", NULL)) {
278 dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n"); 292 dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n");
279 return -ENODEV; 293 ret = -ENODEV;
294 goto put;
280 } 295 }
281 296
282 dm_timer = pdata->request_by_node(timer); 297 dm_timer = pdata->request_by_node(timer);
283 if (!dm_timer) 298 if (!dm_timer) {
284 return -EPROBE_DEFER; 299 ret = -EPROBE_DEFER;
300 goto put;
301 }
302
303put:
304 of_node_put(timer);
305 if (ret < 0)
306 return ret;
285 307
286 omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL); 308 omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL);
287 if (!omap) { 309 if (!omap) {
@@ -291,13 +313,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
291 313
292 omap->pdata = pdata; 314 omap->pdata = pdata;
293 omap->dm_timer = dm_timer; 315 omap->dm_timer = dm_timer;
294 316 omap->dm_timer_pdev = timer_pdev;
295 omap->dm_timer_pdev = of_find_device_by_node(timer);
296 if (!omap->dm_timer_pdev) {
297 dev_err(&pdev->dev, "Unable to find timer pdev\n");
298 omap->pdata->free(dm_timer);
299 return -EINVAL;
300 }
301 317
302 /* 318 /*
303 * Ensure that the timer is stopped before we allow PWM core to call 319 * Ensure that the timer is stopped before we allow PWM core to call
@@ -322,11 +338,11 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
322 338
323 mutex_init(&omap->mutex); 339 mutex_init(&omap->mutex);
324 340
325 status = pwmchip_add(&omap->chip); 341 ret = pwmchip_add(&omap->chip);
326 if (status < 0) { 342 if (ret < 0) {
327 dev_err(&pdev->dev, "failed to register PWM\n"); 343 dev_err(&pdev->dev, "failed to register PWM\n");
328 omap->pdata->free(omap->dm_timer); 344 omap->pdata->free(omap->dm_timer);
329 return status; 345 return ret;
330 } 346 }
331 347
332 platform_set_drvdata(pdev, omap); 348 platform_set_drvdata(pdev, omap);