summaryrefslogtreecommitdiff
path: root/drivers/mtd/nand
diff options
context:
space:
mode:
authorJason Liu <r64343@freescale.com>2010-08-12 19:07:53 +0800
committerJustin Waters <justin.waters@timesys.com>2010-12-13 16:09:42 -0500
commite6589014d951a2e083f7516b3426c541ac68a456 (patch)
tree0a31bfefe9d7389ab0d8baff41ca48d3b9ea6c3a /drivers/mtd/nand
parent79358473a42a3204fa9c2acece512936c5a6ef4a (diff)
ENGR00126278 NAND:nfc_clk count not zero after multi-cs NAND scan
In fact, NAND driver always do clk_enable when use NAND and clk_disable when not use. But there is one open issue in nand_base.c community code for multiple NAND scan, it call multiple chip->select_chip(mtd, i); but only call one time for chip->select_chip(mtd, -1); which will cause the nfc clock count not equal to zero after multiple cs NAND scan Signed-off-by:Jason Liu <r64343@freescale.com>
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r--drivers/mtd/nand/mxc_nd2.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/mtd/nand/mxc_nd2.c b/drivers/mtd/nand/mxc_nd2.c
index 07eb120d0c24..18213448abf8 100644
--- a/drivers/mtd/nand/mxc_nd2.c
+++ b/drivers/mtd/nand/mxc_nd2.c
@@ -40,6 +40,7 @@ struct mxc_mtd_s {
struct mtd_partition *parts;
struct device *dev;
int disable_bi_swap; /* disable bi swap */
+ int clk_active;
};
static struct mxc_mtd_s *mxc_nand_data;
@@ -791,6 +792,30 @@ static int mxc_nand_verify_buf(struct mtd_info *mtd, const u_char * buf,
}
/*!
+ * This function will enable NFC clock
+ *
+ */
+static inline void mxc_nand_clk_enable(void)
+{
+ if (!mxc_nand_data->clk_active) {
+ clk_enable(nfc_clk);
+ mxc_nand_data->clk_active = 1;
+ }
+}
+
+/*!
+ * This function will disable NFC clock
+ *
+ */
+static inline void mxc_nand_clk_disable(void)
+{
+ if (mxc_nand_data->clk_active) {
+ clk_disable(nfc_clk);
+ mxc_nand_data->clk_active = 0;
+ }
+}
+
+/*!
* This function is used by upper layer for select and deselect of the NAND
* chip
*
@@ -803,13 +828,14 @@ static void mxc_nand_select_chip(struct mtd_info *mtd, int chip)
switch (chip) {
case -1:
/* Disable the NFC clock */
- clk_disable(nfc_clk);
+ mxc_nand_clk_disable();
+
break;
- case 0 ... 7:
+ case 0 ... NFC_GET_MAXCHIP_SP():
/* Enable the NFC clock */
- clk_enable(nfc_clk);
-
+ mxc_nand_clk_enable();
NFC_SET_NFC_ACTIVE_CS(chip);
+
break;
default:
@@ -1438,6 +1464,7 @@ static int __devinit mxcnd_probe(struct platform_device *pdev)
nfc_clk = clk_get(&pdev->dev, "nfc_clk");
clk_enable(nfc_clk);
+ mxc_nand_data->clk_active = 1;
if (hardware_ecc) {
this->ecc.read_page = mxc_nand_read_page;
@@ -1523,7 +1550,7 @@ static int __exit mxcnd_remove(struct platform_device *pdev)
manage_sysfs_files(false);
mxc_free_buf();
- clk_disable(nfc_clk);
+ mxc_nand_clk_disable();
clk_put(nfc_clk);
platform_set_drvdata(pdev, NULL);
@@ -1554,7 +1581,7 @@ static int mxcnd_suspend(struct platform_device *pdev, pm_message_t state)
DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND2 : NAND suspend\n");
/* Disable the NFC clock */
- clk_disable(nfc_clk);
+ mxc_nand_clk_disable();
return 0;
}
@@ -1573,7 +1600,7 @@ static int mxcnd_resume(struct platform_device *pdev)
DEBUG(MTD_DEBUG_LEVEL0, "MXC_ND2 : NAND resume\n");
/* Enable the NFC clock */
- clk_enable(nfc_clk);
+ mxc_nand_clk_enable();
return 0;
}