Hi,
Changelog
v4:
Patch nand_suspend() return error code to the upper layer,
removed _ prefix of suspend/resme hooks and kbuildtest robot tag.
v3:
patch nand_lock_area/nand_unlock_area.
fixed kbuidtest robot warnings and reviewer's comments as below:
- Patched the Kdoc for both lock_area/unlock_area and _suspend/_resume
- Created a helper to read default protected value (after device power on)
for protection function detection.
- patched the prefix for Macronix deep power down command, 0xB9
- Patched the description of mxic_nand_resume() and add a small sleeping
delay.
- Created a helper for deep power down device part number detection.
v2:
Patch nand_lock() & nand_unlock() for MTD->_lock/_unlock default call-back
function replacement.
Patch nand_suspend() & nand_resume() with manufacturer specific operation.
v1:
Patch manufacturer post_init for MTD->_lock/_unlock & MTD->_suspend/_resume
replacement.
thanks for your time & review.
Mason
Mason Yang (2):
mtd: rawnand: Add support for manufacturer specific suspend/resume
operation
mtd: rawnand: macronix: Add support for deep power down mode
drivers/mtd/nand/raw/nand_base.c | 17 +++++++--
drivers/mtd/nand/raw/nand_macronix.c | 74 ++++++++++++++++++++++++++++++++++++
include/linux/mtd/rawnand.h | 4 ++
3 files changed, 91 insertions(+), 4 deletions(-)
--
1.9.1
Macronix AD series support deep power down mode for a minimum
power consumption state.
Overload nand_suspend() & nand_resume() in Macronix specific code to
support deep power down mode.
Signed-off-by: Mason Yang <[email protected]>
---
drivers/mtd/nand/raw/nand_macronix.c | 74 ++++++++++++++++++++++++++++++++++++
1 file changed, 74 insertions(+)
diff --git a/drivers/mtd/nand/raw/nand_macronix.c b/drivers/mtd/nand/raw/nand_macronix.c
index 3ff7ce0..756c175 100644
--- a/drivers/mtd/nand/raw/nand_macronix.c
+++ b/drivers/mtd/nand/raw/nand_macronix.c
@@ -6,11 +6,14 @@
* Author: Boris Brezillon <[email protected]>
*/
+#include "linux/delay.h"
#include "internals.h"
#define MACRONIX_READ_RETRY_BIT BIT(0)
#define MACRONIX_NUM_READ_RETRY_MODES 6
+#define MXIC_CMD_POWER_DOWN 0xB9
+
struct nand_onfi_vendor_macronix {
u8 reserved;
u8 reliability_func;
@@ -91,6 +94,76 @@ static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip)
ONFI_FEATURE_ADDR_TIMING_MODE, 1);
}
+static int nand_power_down_op(struct nand_chip *chip)
+{
+ int ret;
+
+ if (nand_has_exec_op(chip)) {
+ struct nand_op_instr instrs[] = {
+ NAND_OP_CMD(MXIC_CMD_POWER_DOWN, 0),
+ };
+
+ struct nand_operation op = NAND_OPERATION(chip->cur_cs, instrs);
+
+ ret = nand_exec_op(chip, &op);
+ if (ret)
+ return ret;
+
+ } else {
+ chip->legacy.cmdfunc(chip, MXIC_CMD_POWER_DOWN, -1, -1);
+ }
+
+ return 0;
+}
+
+static int mxic_nand_suspend(struct nand_chip *chip)
+{
+ int ret;
+
+ nand_select_target(chip, 0);
+ ret = nand_power_down_op(chip);
+ if (ret < 0)
+ pr_err("Suspending MXIC NAND chip failed (%d)\n", ret);
+ nand_deselect_target(chip);
+
+ return ret;
+}
+
+static void mxic_nand_resume(struct nand_chip *chip)
+{
+ /*
+ * Toggle #CS pin to resume NAND device and don't care
+ * of the others CLE, #WE, #RE pins status.
+ * A NAND controller ensure it is able to assert/de-assert #CS
+ * by sending any byte over the NAND bus.
+ * i.e.,
+ * NAND power down command or reset command w/o R/B# status checking.
+ */
+ nand_select_target(chip, 0);
+ nand_power_down_op(chip);
+ /* The minimum of a recovery time tRDP is 35 us */
+ usleep_range(35, 100);
+ nand_deselect_target(chip);
+}
+
+static void macronix_nand_deep_power_down_support(struct nand_chip *chip)
+{
+ int i;
+ static const char * const deep_power_down_dev[] = {
+ "MX30UF1G28AD",
+ "MX30UF2G28AD",
+ "MX30UF4G28AD",
+ };
+
+ i = match_string(deep_power_down_dev, ARRAY_SIZE(deep_power_down_dev),
+ chip->parameters.model);
+ if (i < 0)
+ return;
+
+ chip->suspend = mxic_nand_suspend;
+ chip->resume = mxic_nand_resume;
+}
+
static int macronix_nand_init(struct nand_chip *chip)
{
if (nand_is_slc(chip))
@@ -98,6 +171,7 @@ static int macronix_nand_init(struct nand_chip *chip)
macronix_nand_fix_broken_get_timings(chip);
macronix_nand_onfi_init(chip);
+ macronix_nand_deep_power_down_support(chip);
return 0;
}
--
1.9.1
Patch nand_suspend() & nand_resume() to let manufacturers overwrite
suspend/resume operations.
Signed-off-by: Mason Yang <[email protected]>
Reviewed-by: Miquel Raynal <[email protected]>
---
drivers/mtd/nand/raw/nand_base.c | 17 +++++++++++++----
include/linux/mtd/rawnand.h | 4 ++++
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index f64e3b6..bde17a3 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -4321,16 +4321,22 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
/**
* nand_suspend - [MTD Interface] Suspend the NAND flash
* @mtd: MTD device structure
+ *
+ * Returns 0 for success or negative error code otherwise.
*/
static int nand_suspend(struct mtd_info *mtd)
{
struct nand_chip *chip = mtd_to_nand(mtd);
+ int ret = 0;
mutex_lock(&chip->lock);
- chip->suspended = 1;
+ if (chip->suspend)
+ ret = chip->suspend(chip);
+ if (!ret)
+ chip->suspended = 1;
mutex_unlock(&chip->lock);
- return 0;
+ return ret;
}
/**
@@ -4342,11 +4348,14 @@ static void nand_resume(struct mtd_info *mtd)
struct nand_chip *chip = mtd_to_nand(mtd);
mutex_lock(&chip->lock);
- if (chip->suspended)
+ if (chip->suspended) {
+ if (chip->resume)
+ chip->resume(chip);
chip->suspended = 0;
- else
+ } else {
pr_err("%s called for a chip which is not in suspended state\n",
__func__);
+ }
mutex_unlock(&chip->lock);
}
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 4ab9bcc..b3dccb9 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1064,6 +1064,8 @@ struct nand_legacy {
* @lock: lock protecting the suspended field. Also used to
* serialize accesses to the NAND device.
* @suspended: set to 1 when the device is suspended, 0 when it's not.
+ * @suspend: [REPLACEABLE] specific NAND device suspend operation
+ * @resume: [REPLACEABLE] specific NAND device resume operation
* @bbt: [INTERN] bad block table pointer
* @bbt_td: [REPLACEABLE] bad block table descriptor for flash
* lookup.
@@ -1117,6 +1119,8 @@ struct nand_chip {
struct mutex lock;
unsigned int suspended : 1;
+ int (*suspend)(struct nand_chip *chip);
+ void (*resume)(struct nand_chip *chip);
uint8_t *oob_poi;
struct nand_controller *controller;
--
1.9.1
On Wed, 2020-03-18 at 07:42:27 UTC, Mason Yang wrote:
> Patch nand_suspend() & nand_resume() to let manufacturers overwrite
> suspend/resume operations.
>
> Signed-off-by: Mason Yang <[email protected]>
> Reviewed-by: Miquel Raynal <[email protected]>
Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks.
Miquel
Hi Mason,
Mason Yang <[email protected]> wrote on Wed, 18 Mar 2020 15:42:28
+0800:
> Macronix AD series support deep power down mode for a minimum
> power consumption state.
>
> Overload nand_suspend() & nand_resume() in Macronix specific code to
> support deep power down mode.
>
> Signed-off-by: Mason Yang <[email protected]>
This was not based on nand/next so as I applied changes in this files
(patches 1 and 2 of the original series) this patch did not apply. I
manually merged it.
Thanks,
Miquèl
Hi Miquel,
> Mason Yang <[email protected]> wrote on Wed, 18 Mar 2020 15:42:28
> +0800:
>
> > Macronix AD series support deep power down mode for a minimum
> > power consumption state.
> >
> > Overload nand_suspend() & nand_resume() in Macronix specific code to
> > support deep power down mode.
> >
> > Signed-off-by: Mason Yang <[email protected]>
>
> This was not based on nand/next so as I applied changes in this files
> (patches 1 and 2 of the original series) this patch did not apply. I
> manually merged it.
Got it and thanks a lot for your help.
>
>
> Thanks,
> Miqu?l
best regards,
Mason
CONFIDENTIALITY NOTE:
This e-mail and any attachments may contain confidential information
and/or personal data, which is protected by applicable laws. Please be
reminded that duplication, disclosure, distribution, or use of this e-mail
(and/or its attachments) or any part thereof is prohibited. If you receive
this e-mail in error, please notify us immediately and delete this mail as
well as its attachment(s) from your system. In addition, please be
informed that collection, processing, and/or use of personal data is
prohibited unless expressly permitted by personal data protection laws.
Thank you for your attention and cooperation.
Macronix International Co., Ltd.
=====================================================================
============================================================================
CONFIDENTIALITY NOTE:
This e-mail and any attachments may contain confidential information and/or personal data, which is protected by applicable laws. Please be reminded that duplication, disclosure, distribution, or use of this e-mail (and/or its attachments) or any part thereof is prohibited. If you receive this e-mail in error, please notify us immediately and delete this mail as well as its attachment(s) from your system. In addition, please be informed that collection, processing, and/or use of personal data is prohibited unless expressly permitted by personal data protection laws. Thank you for your attention and cooperation.
Macronix International Co., Ltd.
=====================================================================