diff options
author | Lei Wen <leiwen@marvell.com> | 2011-07-14 23:44:30 -0400 |
---|---|---|
committer | Artem Bityutskiy <artem.bityutskiy@intel.com> | 2011-09-11 08:02:15 -0400 |
commit | 051fc41c2e578e10950bf34dc84878e489e0679f (patch) | |
tree | 8fb03f5ea60ca132ffe9b1e12e2a82098ad2f24d /drivers/mtd/nand | |
parent | 52a474de0a830bdf4305ef19c3321064ce5da438 (diff) |
mtd: pxa3xx_nand: enhance suspend and resume routine
This patch add protection on the suspend&resume path to prevent
some unexpected behavior, like interrupt occur at the very second
of resume back and it don't follow normal command path, which lead
to bug.
Signed-off-by: Lei Wen <leiwen@marvell.com>
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r-- | drivers/mtd/nand/pxa3xx_nand.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index b7db1b2021f..61e1ff5a9ad 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -1158,23 +1158,36 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) | |||
1158 | static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state) | 1158 | static int pxa3xx_nand_suspend(struct platform_device *pdev, pm_message_t state) |
1159 | { | 1159 | { |
1160 | struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); | 1160 | struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); |
1161 | struct mtd_info *mtd = info->mtd; | ||
1161 | 1162 | ||
1162 | if (info->state) { | 1163 | if (info->state) { |
1163 | dev_err(&pdev->dev, "driver busy, state = %d\n", info->state); | 1164 | dev_err(&pdev->dev, "driver busy, state = %d\n", info->state); |
1164 | return -EAGAIN; | 1165 | return -EAGAIN; |
1165 | } | 1166 | } |
1166 | 1167 | ||
1168 | mtd->suspend(mtd); | ||
1167 | return 0; | 1169 | return 0; |
1168 | } | 1170 | } |
1169 | 1171 | ||
1170 | static int pxa3xx_nand_resume(struct platform_device *pdev) | 1172 | static int pxa3xx_nand_resume(struct platform_device *pdev) |
1171 | { | 1173 | { |
1172 | struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); | 1174 | struct pxa3xx_nand_info *info = platform_get_drvdata(pdev); |
1175 | struct mtd_info *mtd = info->mtd; | ||
1176 | |||
1177 | /* We don't want to handle interrupt without calling mtd routine */ | ||
1178 | disable_int(info, NDCR_INT_MASK); | ||
1173 | 1179 | ||
1174 | nand_writel(info, NDTR0CS0, info->ndtr0cs0); | 1180 | nand_writel(info, NDTR0CS0, info->ndtr0cs0); |
1175 | nand_writel(info, NDTR1CS0, info->ndtr1cs0); | 1181 | nand_writel(info, NDTR1CS0, info->ndtr1cs0); |
1176 | clk_enable(info->clk); | ||
1177 | 1182 | ||
1183 | /* | ||
1184 | * As the spec says, the NDSR would be updated to 0x1800 when | ||
1185 | * doing the nand_clk disable/enable. | ||
1186 | * To prevent it damaging state machine of the driver, clear | ||
1187 | * all status before resume | ||
1188 | */ | ||
1189 | nand_writel(info, NDSR, NDSR_MASK); | ||
1190 | mtd->resume(mtd); | ||
1178 | return 0; | 1191 | return 0; |
1179 | } | 1192 | } |
1180 | #else | 1193 | #else |