Commit 7e928263 authored by Miquel Raynal's avatar Miquel Raynal
Browse files

mtd: rawnand: onfi: Avoid doing a copy of the parameter page



There is no need for copying the parameter page, playing with
pointers does the trick.

There is not functional change.

Signed-off-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: default avatarBoris Brezillon <boris.brezillon@collabora.com>
Link: https://lore.kernel.org/linux-mtd/20200428094302.14624-7-miquel.raynal@bootlin.com
parent dacd1a12
Loading
Loading
Loading
Loading
+15 −15
Original line number Diff line number Diff line
@@ -143,7 +143,7 @@ int nand_onfi_detect(struct nand_chip *chip)
{
	struct mtd_info *mtd = nand_to_mtd(chip);
	struct nand_memory_organization *memorg;
	struct nand_onfi_params *p;
	struct nand_onfi_params *p = NULL, *pbuf;
	struct onfi_params *onfi;
	int onfi_version = 0;
	char id[4];
@@ -158,8 +158,8 @@ int nand_onfi_detect(struct nand_chip *chip)
		return 0;

	/* ONFI chip: allocate a buffer to hold its parameter page */
	p = kzalloc((sizeof(*p) * ONFI_PARAM_PAGES), GFP_KERNEL);
	if (!p)
	pbuf = kzalloc((sizeof(*pbuf) * ONFI_PARAM_PAGES), GFP_KERNEL);
	if (!pbuf)
		return -ENOMEM;

	ret = nand_read_param_page_op(chip, 0, NULL, 0);
@@ -169,16 +169,15 @@ int nand_onfi_detect(struct nand_chip *chip)
	}

	for (i = 0; i < ONFI_PARAM_PAGES; i++) {
		ret = nand_read_data_op(chip, &p[i], sizeof(*p), true);
		ret = nand_read_data_op(chip, &pbuf[i], sizeof(*pbuf), true);
		if (ret) {
			ret = 0;
			goto free_onfi_param_page;
		}

		crc = onfi_crc16(ONFI_CRC_BASE, (u8 *)&p[i], 254);
		if (crc == le16_to_cpu(p[i].crc)) {
			if (i)
				memcpy(p, &p[i], sizeof(*p));
		crc = onfi_crc16(ONFI_CRC_BASE, (u8 *)&pbuf[i], 254);
		if (crc == le16_to_cpu(pbuf[i].crc)) {
			p = &pbuf[i];
			break;
		}
	}
@@ -188,17 +187,18 @@ int nand_onfi_detect(struct nand_chip *chip)
		unsigned int j;

		for (j = 0; j < ONFI_PARAM_PAGES; j++)
			srcbufs[j] = p + j;
			srcbufs[j] = pbuf + j;

		pr_warn("Could not find a valid ONFI parameter page, trying bit-wise majority to recover it\n");
		nand_bit_wise_majority(srcbufs, ONFI_PARAM_PAGES, p,
				       sizeof(*p));
		nand_bit_wise_majority(srcbufs, ONFI_PARAM_PAGES, pbuf,
				       sizeof(*pbuf));

		crc = onfi_crc16(ONFI_CRC_BASE, (u8 *)p, 254);
		if (crc != le16_to_cpu(p->crc)) {
		crc = onfi_crc16(ONFI_CRC_BASE, (u8 *)pbuf, 254);
		if (crc != le16_to_cpu(pbuf->crc)) {
			pr_err("ONFI parameter recovery failed, aborting\n");
			goto free_onfi_param_page;
		}
		p = pbuf;
	}

	if (chip->manufacturer.desc && chip->manufacturer.desc->ops &&
@@ -306,14 +306,14 @@ int nand_onfi_detect(struct nand_chip *chip)
	chip->parameters.onfi = onfi;

	/* Identification done, free the full ONFI parameter page and exit */
	kfree(p);
	kfree(pbuf);

	return 1;

free_model:
	kfree(chip->parameters.model);
free_onfi_param_page:
	kfree(p);
	kfree(pbuf);

	return ret;
}