aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/onenand/omap2.c
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@nokia.com>2010-02-19 09:39:53 -0500
committerDavid Woodhouse <David.Woodhouse@intel.com>2011-01-06 10:34:34 -0500
commit9ac4e613a88d7f6a7a9651d863e9c8f63b582718 (patch)
treec8ca917466c14e8c73ea5518a9da1cae5815817d /drivers/mtd/onenand/omap2.c
parentcf24dc85ff29a41abd8e73730e5feb22b2666bd3 (diff)
mtd: OneNAND: OMAP2/3: prevent regulator sleeping while OneNAND is in use
Prevent OneNAND's voltage regulator from going to sleep while OneNAND is in use, by explicitly enabling and disabling the regulator as appropriate. Signed-off-by: Adrian Hunter <adrian.hunter@nokia.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/onenand/omap2.c')
-rw-r--r--drivers/mtd/onenand/omap2.c41
1 files changed, 40 insertions, 1 deletions
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 324402fcdedc..1a07bfcc70d4 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -35,6 +35,7 @@
35#include <linux/dma-mapping.h> 35#include <linux/dma-mapping.h>
36#include <linux/io.h> 36#include <linux/io.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/regulator/consumer.h>
38 39
39#include <asm/mach/flash.h> 40#include <asm/mach/flash.h>
40#include <plat/gpmc.h> 41#include <plat/gpmc.h>
@@ -63,6 +64,7 @@ struct omap2_onenand {
63 int dma_channel; 64 int dma_channel;
64 int freq; 65 int freq;
65 int (*setup)(void __iomem *base, int freq); 66 int (*setup)(void __iomem *base, int freq);
67 struct regulator *regulator;
66}; 68};
67 69
68#ifdef CONFIG_MTD_PARTITIONS 70#ifdef CONFIG_MTD_PARTITIONS
@@ -601,6 +603,30 @@ static void omap2_onenand_shutdown(struct platform_device *pdev)
601 memset((__force void *)c->onenand.base, 0, ONENAND_BUFRAM_SIZE); 603 memset((__force void *)c->onenand.base, 0, ONENAND_BUFRAM_SIZE);
602} 604}
603 605
606static int omap2_onenand_enable(struct mtd_info *mtd)
607{
608 int ret;
609 struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
610
611 ret = regulator_enable(c->regulator);
612 if (ret != 0)
613 dev_err(&c->pdev->dev, "cant enable regulator\n");
614
615 return ret;
616}
617
618static int omap2_onenand_disable(struct mtd_info *mtd)
619{
620 int ret;
621 struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd);
622
623 ret = regulator_disable(c->regulator);
624 if (ret != 0)
625 dev_err(&c->pdev->dev, "cant disable regulator\n");
626
627 return ret;
628}
629
604static int __devinit omap2_onenand_probe(struct platform_device *pdev) 630static int __devinit omap2_onenand_probe(struct platform_device *pdev)
605{ 631{
606 struct omap_onenand_platform_data *pdata; 632 struct omap_onenand_platform_data *pdata;
@@ -715,8 +741,18 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
715 } 741 }
716 } 742 }
717 743
744 if (pdata->regulator_can_sleep) {
745 c->regulator = regulator_get(&pdev->dev, "vonenand");
746 if (IS_ERR(c->regulator)) {
747 dev_err(&pdev->dev, "Failed to get regulator\n");
748 goto err_release_dma;
749 }
750 c->onenand.enable = omap2_onenand_enable;
751 c->onenand.disable = omap2_onenand_disable;
752 }
753
718 if ((r = onenand_scan(&c->mtd, 1)) < 0) 754 if ((r = onenand_scan(&c->mtd, 1)) < 0)
719 goto err_release_dma; 755 goto err_release_regulator;
720 756
721 switch ((c->onenand.version_id >> 4) & 0xf) { 757 switch ((c->onenand.version_id >> 4) & 0xf) {
722 case 0: 758 case 0:
@@ -751,6 +787,8 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
751 787
752err_release_onenand: 788err_release_onenand:
753 onenand_release(&c->mtd); 789 onenand_release(&c->mtd);
790err_release_regulator:
791 regulator_put(c->regulator);
754err_release_dma: 792err_release_dma:
755 if (c->dma_channel != -1) 793 if (c->dma_channel != -1)
756 omap_free_dma(c->dma_channel); 794 omap_free_dma(c->dma_channel);
@@ -777,6 +815,7 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev)
777 struct omap2_onenand *c = dev_get_drvdata(&pdev->dev); 815 struct omap2_onenand *c = dev_get_drvdata(&pdev->dev);
778 816
779 onenand_release(&c->mtd); 817 onenand_release(&c->mtd);
818 regulator_put(c->regulator);
780 if (c->dma_channel != -1) 819 if (c->dma_channel != -1)
781 omap_free_dma(c->dma_channel); 820 omap_free_dma(c->dma_channel);
782 omap2_onenand_shutdown(pdev); 821 omap2_onenand_shutdown(pdev);