summaryrefslogtreecommitdiff
path: root/drivers/spi/spi-qpic-snand.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-qpic-snand.c')
-rw-r--r--drivers/spi/spi-qpic-snand.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c
index 3f747fd61d19..f2e1a27b410d 100644
--- a/drivers/spi/spi-qpic-snand.c
+++ b/drivers/spi/spi-qpic-snand.c
@@ -315,6 +315,22 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand)
mtd_set_ooblayout(mtd, &qcom_spi_ooblayout);
+ /*
+ * Free the temporary BAM transaction allocated initially by
+ * qcom_nandc_alloc(), and allocate a new one based on the
+ * updated max_cwperpage value.
+ */
+ qcom_free_bam_transaction(snandc);
+
+ snandc->max_cwperpage = cwperpage;
+
+ snandc->bam_txn = qcom_alloc_bam_transaction(snandc);
+ if (!snandc->bam_txn) {
+ dev_err(snandc->dev, "failed to allocate BAM transaction\n");
+ ret = -ENOMEM;
+ goto err_free_ecc_cfg;
+ }
+
ecc_cfg->cfg0 = FIELD_PREP(CW_PER_PAGE_MASK, (cwperpage - 1)) |
FIELD_PREP(UD_SIZE_BYTES_MASK, ecc_cfg->cw_data) |
FIELD_PREP(DISABLE_STATUS_AFTER_WRITE, 1) |
@@ -639,6 +655,20 @@ static int qcom_spi_check_error(struct qcom_nand_controller *snandc)
unsigned int stat;
stat = buffer & BS_CORRECTABLE_ERR_MSK;
+
+ /*
+ * The exact number of the corrected bits is
+ * unknown because the hardware only reports the
+ * number of the corrected bytes.
+ *
+ * Since we have no better solution at the moment,
+ * report that value as the number of bit errors
+ * despite that it is inaccurate in most cases.
+ */
+ if (stat && stat != ecc_cfg->strength)
+ dev_warn_once(snandc->dev,
+ "Warning: due to hw limitation, the reported number of the corrected bits may be inaccurate\n");
+
snandc->qspi->ecc_stats.corrected += stat;
max_bitflips = max(max_bitflips, stat);
}