diff options
author | Ramalingam C <ramalingamc@nvidia.com> | 2012-03-19 11:48:27 +0530 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-03-19 17:25:20 -0700 |
commit | b09dbbdf0e0089a37bdbe4627fcdde8c1d9d5451 (patch) | |
tree | 9846583c68f37292b016de7a248d92252273a169 /drivers/mtd | |
parent | ac209d00bd9e8925b90b66770930e710d196e85e (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/mtd')
-rw-r--r-- | drivers/mtd/devices/tegra_nand.c | 88 |
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; |