diff options
Diffstat (limited to 'arch/arm/plat-samsung/adc.c')
-rw-r--r-- | arch/arm/plat-samsung/adc.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/arch/arm/plat-samsung/adc.c b/arch/arm/plat-samsung/adc.c index e8f2be2d67f2..2224128cc603 100644 --- a/arch/arm/plat-samsung/adc.c +++ b/arch/arm/plat-samsung/adc.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
22 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <linux/regulator/consumer.h> | ||
24 | 25 | ||
25 | #include <plat/regs-adc.h> | 26 | #include <plat/regs-adc.h> |
26 | #include <plat/adc.h> | 27 | #include <plat/adc.h> |
@@ -71,6 +72,7 @@ struct adc_device { | |||
71 | unsigned int prescale; | 72 | unsigned int prescale; |
72 | 73 | ||
73 | int irq; | 74 | int irq; |
75 | struct regulator *vdd; | ||
74 | }; | 76 | }; |
75 | 77 | ||
76 | static struct adc_device *adc_dev; | 78 | static struct adc_device *adc_dev; |
@@ -338,17 +340,24 @@ static int s3c_adc_probe(struct platform_device *pdev) | |||
338 | adc->pdev = pdev; | 340 | adc->pdev = pdev; |
339 | adc->prescale = S3C2410_ADCCON_PRSCVL(49); | 341 | adc->prescale = S3C2410_ADCCON_PRSCVL(49); |
340 | 342 | ||
343 | adc->vdd = regulator_get(dev, "vdd"); | ||
344 | if (IS_ERR(adc->vdd)) { | ||
345 | dev_err(dev, "operating without regulator \"vdd\" .\n"); | ||
346 | ret = PTR_ERR(adc->vdd); | ||
347 | goto err_alloc; | ||
348 | } | ||
349 | |||
341 | adc->irq = platform_get_irq(pdev, 1); | 350 | adc->irq = platform_get_irq(pdev, 1); |
342 | if (adc->irq <= 0) { | 351 | if (adc->irq <= 0) { |
343 | dev_err(dev, "failed to get adc irq\n"); | 352 | dev_err(dev, "failed to get adc irq\n"); |
344 | ret = -ENOENT; | 353 | ret = -ENOENT; |
345 | goto err_alloc; | 354 | goto err_reg; |
346 | } | 355 | } |
347 | 356 | ||
348 | ret = request_irq(adc->irq, s3c_adc_irq, 0, dev_name(dev), adc); | 357 | ret = request_irq(adc->irq, s3c_adc_irq, 0, dev_name(dev), adc); |
349 | if (ret < 0) { | 358 | if (ret < 0) { |
350 | dev_err(dev, "failed to attach adc irq\n"); | 359 | dev_err(dev, "failed to attach adc irq\n"); |
351 | goto err_alloc; | 360 | goto err_reg; |
352 | } | 361 | } |
353 | 362 | ||
354 | adc->clk = clk_get(dev, "adc"); | 363 | adc->clk = clk_get(dev, "adc"); |
@@ -372,6 +381,10 @@ static int s3c_adc_probe(struct platform_device *pdev) | |||
372 | goto err_clk; | 381 | goto err_clk; |
373 | } | 382 | } |
374 | 383 | ||
384 | ret = regulator_enable(adc->vdd); | ||
385 | if (ret) | ||
386 | goto err_ioremap; | ||
387 | |||
375 | clk_enable(adc->clk); | 388 | clk_enable(adc->clk); |
376 | 389 | ||
377 | tmp = adc->prescale | S3C2410_ADCCON_PRSCEN; | 390 | tmp = adc->prescale | S3C2410_ADCCON_PRSCEN; |
@@ -388,12 +401,15 @@ static int s3c_adc_probe(struct platform_device *pdev) | |||
388 | 401 | ||
389 | return 0; | 402 | return 0; |
390 | 403 | ||
404 | err_ioremap: | ||
405 | iounmap(adc->regs); | ||
391 | err_clk: | 406 | err_clk: |
392 | clk_put(adc->clk); | 407 | clk_put(adc->clk); |
393 | 408 | ||
394 | err_irq: | 409 | err_irq: |
395 | free_irq(adc->irq, adc); | 410 | free_irq(adc->irq, adc); |
396 | 411 | err_reg: | |
412 | regulator_put(adc->vdd); | ||
397 | err_alloc: | 413 | err_alloc: |
398 | kfree(adc); | 414 | kfree(adc); |
399 | return ret; | 415 | return ret; |
@@ -406,6 +422,8 @@ static int __devexit s3c_adc_remove(struct platform_device *pdev) | |||
406 | iounmap(adc->regs); | 422 | iounmap(adc->regs); |
407 | free_irq(adc->irq, adc); | 423 | free_irq(adc->irq, adc); |
408 | clk_disable(adc->clk); | 424 | clk_disable(adc->clk); |
425 | regulator_disable(adc->vdd); | ||
426 | regulator_put(adc->vdd); | ||
409 | clk_put(adc->clk); | 427 | clk_put(adc->clk); |
410 | kfree(adc); | 428 | kfree(adc); |
411 | 429 | ||
@@ -428,6 +446,7 @@ static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state) | |||
428 | disable_irq(adc->irq); | 446 | disable_irq(adc->irq); |
429 | spin_unlock_irqrestore(&adc->lock, flags); | 447 | spin_unlock_irqrestore(&adc->lock, flags); |
430 | clk_disable(adc->clk); | 448 | clk_disable(adc->clk); |
449 | regulator_disable(adc->vdd); | ||
431 | 450 | ||
432 | return 0; | 451 | return 0; |
433 | } | 452 | } |
@@ -435,7 +454,11 @@ static int s3c_adc_suspend(struct platform_device *pdev, pm_message_t state) | |||
435 | static int s3c_adc_resume(struct platform_device *pdev) | 454 | static int s3c_adc_resume(struct platform_device *pdev) |
436 | { | 455 | { |
437 | struct adc_device *adc = platform_get_drvdata(pdev); | 456 | struct adc_device *adc = platform_get_drvdata(pdev); |
457 | int ret; | ||
438 | 458 | ||
459 | ret = regulator_enable(adc->vdd); | ||
460 | if (ret) | ||
461 | return ret; | ||
439 | clk_enable(adc->clk); | 462 | clk_enable(adc->clk); |
440 | enable_irq(adc->irq); | 463 | enable_irq(adc->irq); |
441 | 464 | ||
@@ -485,4 +508,4 @@ static int __init adc_init(void) | |||
485 | return ret; | 508 | return ret; |
486 | } | 509 | } |
487 | 510 | ||
488 | arch_initcall(adc_init); | 511 | module_init(adc_init); |