summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRamalingam C <ramalingamc@nvidia.com>2012-03-19 11:48:27 +0530
committerSimone Willett <swillett@nvidia.com>2012-03-19 17:25:20 -0700
commitb09dbbdf0e0089a37bdbe4627fcdde8c1d9d5451 (patch)
tree9846583c68f37292b016de7a248d92252273a169 /drivers
parentac209d00bd9e8925b90b66770930e710d196e85e (diff)
Drivers: MTD: NAND: restore to the NAND controller
On entering the power saving mode NAND controller registers are getting reset. With this change resume will restore the controller registers' values. Bug 933291 Change-Id: Ia1a43827b4b4a91ab1383bf07c3c0fe3068b666b Signed-off-by: Ramalingam C <ramalingamc@nvidia.com> Reviewed-on: http://git-master/r/90883 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Venu Byravarasu <vbyravarasu@nvidia.com> Reviewed-by: Preetham Chandru <pchandru@nvidia.com> Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mtd/devices/tegra_nand.c88
1 files changed, 56 insertions, 32 deletions
diff --git a/drivers/mtd/devices/tegra_nand.c b/drivers/mtd/devices/tegra_nand.c
index ba90925285e4..c8a3e7090b90 100644
--- a/drivers/mtd/devices/tegra_nand.c
+++ b/drivers/mtd/devices/tegra_nand.c
@@ -132,6 +132,7 @@ struct tegra_nand_info {
uint32_t is_data_bus_width_16;
uint32_t device_id;
uint32_t vendor_id;
+ uint32_t dev_parms;
uint32_t num_bad_blocks;
};
#define MTD_TO_INFO(mtd) container_of((mtd), struct tegra_nand_info, mtd)
@@ -1288,38 +1289,6 @@ static int tegra_nand_suspend(struct mtd_info *mtd)
return 0;
}
-static void tegra_nand_resume(struct mtd_info *mtd)
-{
-}
-
-static int scan_bad_blocks(struct tegra_nand_info *info)
-{
- struct mtd_info *mtd = &info->mtd;
- int num_blocks = mtd->size >> info->chip.block_shift;
- uint32_t block;
- int is_bad = 0;
- info->num_bad_blocks = 0;
-
- for (block = 0; block < num_blocks; ++block) {
- /* make sure the bit is cleared, meaning it's bad/unknown before
- * we check. */
- clear_bit(block, info->bb_bitmap);
- is_bad = mtd->block_isbad(mtd, block << info->chip.block_shift);
-
- if (is_bad == 0)
- set_bit(block, info->bb_bitmap);
- else if (is_bad > 0) {
- info->num_bad_blocks++;
- pr_debug("block 0x%08x is bad.\n", block);
- } else {
- pr_err("Fatal error (%d) while scanning for "
- "bad blocks\n", is_bad);
- return is_bad;
- }
- }
- return 0;
-}
-
static void
set_chip_timing(struct tegra_nand_info *info, uint32_t vendor_id,
uint32_t dev_id, uint32_t fourth_id_field)
@@ -1357,6 +1326,60 @@ set_chip_timing(struct tegra_nand_info *info, uint32_t vendor_id,
#undef CNT
}
+static void tegra_nand_resume(struct mtd_info *mtd)
+{
+ struct tegra_nand_info *info = MTD_TO_INFO(mtd);
+
+ cfg_hwstatus_mon(info);
+
+ /* clear all pending interrupts */
+ writel(readl(ISR_REG), ISR_REG);
+
+ /* clear dma interrupt */
+ writel(DMA_CTRL_IS_DMA_DONE, DMA_MST_CTRL_REG);
+
+ /* enable interrupts */
+ disable_ints(info, 0xffffffff);
+ enable_ints(info,
+ IER_ERR_TRIG_VAL(4) | IER_UND | IER_OVR | IER_CMD_DONE |
+ IER_ECC_ERR | IER_GIE);
+
+ writel(0, CONFIG_REG);
+
+ set_chip_timing(info, info->vendor_id,
+ info->device_id, info->dev_parms);
+
+ return;
+}
+
+static int scan_bad_blocks(struct tegra_nand_info *info)
+{
+ struct mtd_info *mtd = &info->mtd;
+ int num_blocks = mtd->size >> info->chip.block_shift;
+ uint32_t block;
+ int is_bad = 0;
+ info->num_bad_blocks = 0;
+
+ for (block = 0; block < num_blocks; ++block) {
+ /* make sure the bit is cleared, meaning it's bad/unknown before
+ * we check. */
+ clear_bit(block, info->bb_bitmap);
+ is_bad = mtd->block_isbad(mtd, block << info->chip.block_shift);
+
+ if (is_bad == 0)
+ set_bit(block, info->bb_bitmap);
+ else if (is_bad > 0) {
+ info->num_bad_blocks++;
+ pr_debug("block 0x%08x is bad.\n", block);
+ } else {
+ pr_err("Fatal error (%d) while scanning for "
+ "bad blocks\n", is_bad);
+ return is_bad;
+ }
+ }
+ return 0;
+}
+
/* Scans for nand flash devices, identifies them, and fills in the
* device info. */
static int tegra_nand_scan(struct mtd_info *mtd, int maxchips)
@@ -1419,6 +1442,7 @@ static int tegra_nand_scan(struct mtd_info *mtd, int maxchips)
dev_info->name);
info->vendor_id = vendor_id;
info->device_id = dev_id;
+ info->dev_parms = dev_parms;
info->chip.num_chips = cnt;
info->chip.chipsize = dev_info->chipsize << 20;
mtd->size = info->chip.num_chips * info->chip.chipsize;