diff --git a/linux/drivers/mtd/nand/raw/pl35x-nand-controller.c b/linux/drivers/mtd/nand/raw/pl35x-nand-controller.c index 1d3f0261a7..a2e8ba9dc4 100644 --- a/linux/drivers/mtd/nand/raw/pl35x-nand-controller.c +++ b/linux/drivers/mtd/nand/raw/pl35x-nand-controller.c @@ -755,6 +755,33 @@ static int pl35x_nand_exec_op(struct nand_chip *chip, return 0; } + +static int pl35x_nand_exec_data_out_op(struct nand_chip *chip, + const struct nand_subop *subop) +{ + struct pl35x_nandc *nfc = to_pl35x_nandc(chip->controller); + const struct nand_op_instr *instr; + unsigned int len, offset; + + if (subop->ninstrs != 1 || subop->instrs[0].type != NAND_OP_DATA_OUT_INSTR) { + dev_err(nfc->dev, "Invalid data out operation\n"); + return -EINVAL; + } + + instr = &subop->instrs[0]; + offset = nand_subop_get_data_start_off(subop, 0); + len = nand_subop_get_data_len(subop, 0); + + dev_dbg(nfc->dev, "Executing data out op: len=%u, offset=%u\n", len, offset); + + pl35x_nand_write_data_op(chip, instr->ctx.data.buf.out + offset, + len, instr->ctx.data.force_8bit, + 0, PL35X_SMC_DATA_PHASE_CLEAR_CS); + + return 0; +} + + static const struct nand_op_parser pl35x_nandc_op_parser = NAND_OP_PARSER( NAND_OP_PARSER_PATTERN(pl35x_nand_exec_op, NAND_OP_PARSER_PAT_CMD_ELEM(true), @@ -774,6 +801,9 @@ static const struct nand_op_parser pl35x_nandc_op_parser = NAND_OP_PARSER( NAND_OP_PARSER_PAT_DATA_OUT_ELEM(false, 2112), NAND_OP_PARSER_PAT_CMD_ELEM(true), NAND_OP_PARSER_PAT_WAITRDY_ELEM(true)), + /* Pure data out operation (for BBT writes) */ + NAND_OP_PARSER_PATTERN(pl35x_nand_exec_data_out_op, + NAND_OP_PARSER_PAT_DATA_OUT_ELEM(false, 2112)), );