aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-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);