From: Cheng Ming Lin <chengminglin@mxic.com.tw>
This patch adds support for the randomizer feature.
It introduces a 'set_randomizer' callback in 'struct spinand_info' and
'struct spinand_device'.
If a driver implements this callback, the core will call it during
device initialization (spinand_init) to enable the randomizer.
Signed-off-by: Cheng Ming Lin <chengminglin@mxic.com.tw>
---
drivers/mtd/nand/spi/core.c | 23 +++++++++++++++++++++++
include/linux/mtd/spinand.h | 9 +++++++++
2 files changed, 32 insertions(+)
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index d207286572d8..4f8ff94f5ccc 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -206,6 +206,12 @@ static int spinand_cont_read_enable(struct spinand_device *spinand,
return spinand->set_cont_read(spinand, enable);
}
+static int spinand_randomizer_enable(struct spinand_device *spinand,
+ bool enable)
+{
+ return spinand->set_randomizer(spinand, enable);
+}
+
static int spinand_check_ecc_status(struct spinand_device *spinand, u8 status)
{
struct nand_device *nand = spinand_to_nand(spinand);
@@ -1218,6 +1224,19 @@ static int spinand_create_dirmaps(struct spinand_device *spinand)
return 0;
}
+static int spinand_randomizer_init(struct spinand_device *spinand)
+{
+ int ret;
+
+ if (spinand->set_randomizer) {
+ ret = spinand_randomizer_enable(spinand, true);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
static const struct nand_ops spinand_ops = {
.erase = spinand_erase,
.markbad = spinand_markbad,
@@ -1412,6 +1431,7 @@ int spinand_match_and_init(struct spinand_device *spinand,
spinand->user_otp = &table[i].user_otp;
spinand->read_retries = table[i].read_retries;
spinand->set_read_retry = table[i].set_read_retry;
+ spinand->set_randomizer = table[i].set_randomizer;
op = spinand_select_op_variant(spinand,
info->op_variants.read_cache);
@@ -1588,6 +1608,9 @@ static int spinand_init(struct spinand_device *spinand)
* ECC initialization must have happened previously.
*/
spinand_cont_read_init(spinand);
+ ret = spinand_randomizer_init(spinand);
+ if (ret)
+ goto err_cleanup_nanddev;
mtd->_read_oob = spinand_mtd_read;
mtd->_write_oob = spinand_mtd_write;
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index ce76f5c632e1..e01315a71222 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -501,6 +501,7 @@ struct spinand_user_otp {
* @user_otp: SPI NAND user OTP info.
* @read_retries: the number of read retry modes supported
* @set_read_retry: enable/disable read retry for data recovery
+ * @set_randomizer: enable/disable randomizer support
*
* Each SPI NAND manufacturer driver should have a spinand_info table
* describing all the chips supported by the driver.
@@ -527,6 +528,8 @@ struct spinand_info {
unsigned int read_retries;
int (*set_read_retry)(struct spinand_device *spinand,
unsigned int read_retry);
+ int (*set_randomizer)(struct spinand_device *spinand,
+ bool enable);
};
#define SPINAND_ID(__method, ...) \
@@ -580,6 +583,9 @@ struct spinand_info {
.read_retries = __read_retries, \
.set_read_retry = __set_read_retry
+#define SPINAND_RANDOMIZER(__set_randomizer) \
+ .set_randomizer = __set_randomizer
+
#define SPINAND_INFO(__model, __id, __memorg, __eccreq, __op_variants, \
__flags, ...) \
{ \
@@ -635,6 +641,7 @@ struct spinand_dirmap {
* @user_otp: SPI NAND user OTP info.
* @read_retries: the number of read retry modes supported
* @set_read_retry: Enable/disable the read retry feature
+ * @set_randomizer: Enable/disable the randomizer feature
*/
struct spinand_device {
struct nand_device base;
@@ -668,6 +675,8 @@ struct spinand_device {
bool cont_read_possible;
int (*set_cont_read)(struct spinand_device *spinand,
bool enable);
+ int (*set_randomizer)(struct spinand_device *spinand,
+ bool enable);
const struct spinand_fact_otp *fact_otp;
const struct spinand_user_otp *user_otp;
--
2.25.1
Hello Cheng Ming,
On 03/02/2026 at 10:13:57 +08, Cheng Ming Lin <linchengming884@gmail.com> wrote:
> From: Cheng Ming Lin <chengminglin@mxic.com.tw>
>
> This patch adds support for the randomizer feature.
>
> It introduces a 'set_randomizer' callback in 'struct spinand_info' and
> 'struct spinand_device'.
>
> If a driver implements this callback, the core will call it during
> device initialization (spinand_init) to enable the randomizer.
I recently had a request regarding the sunxi controller driver
randomizer. I would like to get back to having a nand wide randomizer DT
property, because a Macronix specific value honestly no longer makes
sense. Randomizers have been there for ages, they are not so often used
because scrambling data is not convenient for developers but they may
have a real interest depending on the NAND chip or the external
conditions.
We will need two mutually exclusive optional properties in
nand-chip.yaml:
nand-enable-randomizer;
nand-disable-randomizer;
BTW, where is the patch adding the property to the bindings? Did we
already merge it? I do not find it anymore.
Looking at the current implementation, I really don't like the core
always calling in the "init" and the manufacturer driver reading the DT
and deciding whether or not it enables it.
> Signed-off-by: Cheng Ming Lin <chengminglin@mxic.com.tw>
> ---
> drivers/mtd/nand/spi/core.c | 23 +++++++++++++++++++++++
> include/linux/mtd/spinand.h | 9 +++++++++
> 2 files changed, 32 insertions(+)
>
> diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
> index d207286572d8..4f8ff94f5ccc 100644
> --- a/drivers/mtd/nand/spi/core.c
> +++ b/drivers/mtd/nand/spi/core.c
> @@ -206,6 +206,12 @@ static int spinand_cont_read_enable(struct spinand_device *spinand,
> return spinand->set_cont_read(spinand, enable);
> }
>
> +static int spinand_randomizer_enable(struct spinand_device *spinand,
> + bool enable)
> +{
> + return spinand->set_randomizer(spinand, enable);
This helper seems mostly useless.
> +}
> +
> static int spinand_check_ecc_status(struct spinand_device *spinand, u8 status)
> {
> struct nand_device *nand = spinand_to_nand(spinand);
> @@ -1218,6 +1224,19 @@ static int spinand_create_dirmaps(struct spinand_device *spinand)
> return 0;
> }
>
> +static int spinand_randomizer_init(struct spinand_device *spinand)
> +{
> + int ret;
> +
> + if (spinand->set_randomizer) {
> + ret = spinand_randomizer_enable(spinand, true);
Please directly call the hook.
Given the previous feedback, you should change "true" to be based on the
presence of the DT property.
> + if (ret)
> + return ret;
> + }
> +
> + return 0;
> +}
Rest LGTM.
Thanks,
Miquèl
Hi Miquel,
Miquel Raynal <miquel.raynal@bootlin.com> 於 2026年2月3日週二 下午10:40寫道:
>
> Hello Cheng Ming,
>
> On 03/02/2026 at 10:13:57 +08, Cheng Ming Lin <linchengming884@gmail.com> wrote:
>
> > From: Cheng Ming Lin <chengminglin@mxic.com.tw>
> >
> > This patch adds support for the randomizer feature.
> >
> > It introduces a 'set_randomizer' callback in 'struct spinand_info' and
> > 'struct spinand_device'.
> >
> > If a driver implements this callback, the core will call it during
> > device initialization (spinand_init) to enable the randomizer.
>
> I recently had a request regarding the sunxi controller driver
> randomizer. I would like to get back to having a nand wide randomizer DT
> property, because a Macronix specific value honestly no longer makes
> sense. Randomizers have been there for ages, they are not so often used
> because scrambling data is not convenient for developers but they may
> have a real interest depending on the NAND chip or the external
> conditions.
>
> We will need two mutually exclusive optional properties in
> nand-chip.yaml:
> nand-enable-randomizer;
> nand-disable-randomizer;
Agreed. It makes sense to switch to generic device tree properties as
you suggested.
I will introduce nand-enable-randomizer and nand-disable-randomizer
in nand-chip.yaml.
In addition, I will also update the Macronix raw nand flash driver to use
these generic randomizer properties for consistency.
>
> BTW, where is the patch adding the property to the bindings? Did we
> already merge it? I do not find it anymore.
It has not been merged yet. Since the current patch series uses the
vendor-specific property "mxic,randomizer-enable", I did not include a
patch to update the generic bindings.
I will include a new patch in v5 to add these properties to
nand-chip.yaml.
>
> Looking at the current implementation, I really don't like the core
> always calling in the "init" and the manufacturer driver reading the DT
> and deciding whether or not it enables it.
I agree. I will refactor the logic in v5 so that the core parses the
generic DT properties (nand-enable-randomizer and
nand-disable-randomizer).
Then, spinand_randomizer_init will determine the state and pass a
boolean argument to the set_randomizer callback, leaving the driver
to strictly handle the hardware configuration.
>
> > Signed-off-by: Cheng Ming Lin <chengminglin@mxic.com.tw>
> > ---
> > drivers/mtd/nand/spi/core.c | 23 +++++++++++++++++++++++
> > include/linux/mtd/spinand.h | 9 +++++++++
> > 2 files changed, 32 insertions(+)
> >
> > diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
> > index d207286572d8..4f8ff94f5ccc 100644
> > --- a/drivers/mtd/nand/spi/core.c
> > +++ b/drivers/mtd/nand/spi/core.c
> > @@ -206,6 +206,12 @@ static int spinand_cont_read_enable(struct spinand_device *spinand,
> > return spinand->set_cont_read(spinand, enable);
> > }
> >
> > +static int spinand_randomizer_enable(struct spinand_device *spinand,
> > + bool enable)
> > +{
> > + return spinand->set_randomizer(spinand, enable);
>
> This helper seems mostly useless.
>
> > +}
> > +
> > static int spinand_check_ecc_status(struct spinand_device *spinand, u8 status)
> > {
> > struct nand_device *nand = spinand_to_nand(spinand);
> > @@ -1218,6 +1224,19 @@ static int spinand_create_dirmaps(struct spinand_device *spinand)
> > return 0;
> > }
> >
> > +static int spinand_randomizer_init(struct spinand_device *spinand)
> > +{
> > + int ret;
> > +
> > + if (spinand->set_randomizer) {
> > + ret = spinand_randomizer_enable(spinand, true);
>
> Please directly call the hook.
>
> Given the previous feedback, you should change "true" to be based on the
> presence of the DT property.
>
> > + if (ret)
> > + return ret;
> > + }
> > +
> > + return 0;
> > +}
>
> Rest LGTM.
>
> Thanks,
> Miquèl
Thanks,
Cheng Ming Lin
Hi Cheng Ming, >> Looking at the current implementation, I really don't like the core >> always calling in the "init" and the manufacturer driver reading the DT >> and deciding whether or not it enables it. > > I agree. I will refactor the logic in v5 so that the core parses the > generic DT properties (nand-enable-randomizer and > nand-disable-randomizer). > > Then, spinand_randomizer_init will determine the state and pass a > boolean argument to the set_randomizer callback, leaving the driver > to strictly handle the hardware configuration. Perfect. Thanks, Miquèl
© 2016 - 2026 Red Hat, Inc.