Commit d4cb37e7 authored by Boris Brezillon's avatar Boris Brezillon
Browse files

mtd: nand: Remove support for block locking/unlocking



Commit 7d70f334 ("mtd: nand: add lock/unlock routines") introduced
support for the Micron LOCK/UNLOCK commands but no one ever used the
nand_lock/unlock() functions.

Remove support for these vendor-specific operations from the core. If
one ever wants to add them back they should be put in nand_micron.c and
mtd->_lock/_unlock should be directly assigned from there instead of
exporting the functions.

Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
parent 5771a8c0
Loading
Loading
Loading
Loading
+0 −173
Original line number Diff line number Diff line
@@ -1239,179 +1239,6 @@ int nand_reset(struct nand_chip *chip, int chipnr)
	return 0;
}

/**
 * __nand_unlock - [REPLACEABLE] unlocks specified locked blocks
 * @mtd: mtd info
 * @ofs: offset to start unlock from
 * @len: length to unlock
 * @invert:
 *        - when = 0, unlock the range of blocks within the lower and
 *                    upper boundary address
 *        - when = 1, unlock the range of blocks outside the boundaries
 *                    of the lower and upper boundary address
 *
 * Returs unlock status.
 */
static int __nand_unlock(struct mtd_info *mtd, loff_t ofs,
					uint64_t len, int invert)
{
	int ret = 0;
	int status, page;
	struct nand_chip *chip = mtd_to_nand(mtd);

	/* Submit address of first page to unlock */
	page = ofs >> chip->page_shift;
	chip->cmdfunc(mtd, NAND_CMD_UNLOCK1, -1, page & chip->pagemask);

	/* Submit address of last page to unlock */
	page = (ofs + len) >> chip->page_shift;
	chip->cmdfunc(mtd, NAND_CMD_UNLOCK2, -1,
				(page | invert) & chip->pagemask);

	/* Call wait ready function */
	status = chip->waitfunc(mtd, chip);
	/* See if device thinks it succeeded */
	if (status & NAND_STATUS_FAIL) {
		pr_debug("%s: error status = 0x%08x\n",
					__func__, status);
		ret = -EIO;
	}

	return ret;
}

/**
 * nand_unlock - [REPLACEABLE] unlocks specified locked blocks
 * @mtd: mtd info
 * @ofs: offset to start unlock from
 * @len: length to unlock
 *
 * Returns unlock status.
 */
int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
	int ret = 0;
	int chipnr;
	struct nand_chip *chip = mtd_to_nand(mtd);

	pr_debug("%s: start = 0x%012llx, len = %llu\n",
			__func__, (unsigned long long)ofs, len);

	if (check_offs_len(mtd, ofs, len))
		return -EINVAL;

	/* Align to last block address if size addresses end of the device */
	if (ofs + len == mtd->size)
		len -= mtd->erasesize;

	nand_get_device(mtd, FL_UNLOCKING);

	/* Shift to get chip number */
	chipnr = ofs >> chip->chip_shift;

	/*
	 * Reset the chip.
	 * If we want to check the WP through READ STATUS and check the bit 7
	 * we must reset the chip
	 * some operation can also clear the bit 7 of status register
	 * eg. erase/program a locked block
	 */
	nand_reset(chip, chipnr);

	chip->select_chip(mtd, chipnr);

	/* Check, if it is write protected */
	if (nand_check_wp(mtd)) {
		pr_debug("%s: device is write protected!\n",
					__func__);
		ret = -EIO;
		goto out;
	}

	ret = __nand_unlock(mtd, ofs, len, 0);

out:
	chip->select_chip(mtd, -1);
	nand_release_device(mtd);

	return ret;
}
EXPORT_SYMBOL(nand_unlock);

/**
 * nand_lock - [REPLACEABLE] locks all blocks present in the device
 * @mtd: mtd info
 * @ofs: offset to start unlock from
 * @len: length to unlock
 *
 * This feature is not supported in many NAND parts. 'Micron' NAND parts do
 * have this feature, but it allows only to lock all blocks, not for specified
 * range for block. Implementing 'lock' feature by making use of 'unlock', for
 * now.
 *
 * Returns lock status.
 */
int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
{
	int ret = 0;
	int chipnr, status, page;
	struct nand_chip *chip = mtd_to_nand(mtd);

	pr_debug("%s: start = 0x%012llx, len = %llu\n",
			__func__, (unsigned long long)ofs, len);

	if (check_offs_len(mtd, ofs, len))
		return -EINVAL;

	nand_get_device(mtd, FL_LOCKING);

	/* Shift to get chip number */
	chipnr = ofs >> chip->chip_shift;

	/*
	 * Reset the chip.
	 * If we want to check the WP through READ STATUS and check the bit 7
	 * we must reset the chip
	 * some operation can also clear the bit 7 of status register
	 * eg. erase/program a locked block
	 */
	nand_reset(chip, chipnr);

	chip->select_chip(mtd, chipnr);

	/* Check, if it is write protected */
	if (nand_check_wp(mtd)) {
		pr_debug("%s: device is write protected!\n",
					__func__);
		status = MTD_ERASE_FAILED;
		ret = -EIO;
		goto out;
	}

	/* Submit address of first page to lock */
	page = ofs >> chip->page_shift;
	chip->cmdfunc(mtd, NAND_CMD_LOCK, -1, page & chip->pagemask);

	/* Call wait ready function */
	status = chip->waitfunc(mtd, chip);
	/* See if device thinks it succeeded */
	if (status & NAND_STATUS_FAIL) {
		pr_debug("%s: error status = 0x%08x\n",
					__func__, status);
		ret = -EIO;
		goto out;
	}

	ret = __nand_unlock(mtd, ofs, len, 0x1);

out:
	chip->select_chip(mtd, -1);
	nand_release_device(mtd);

	return ret;
}
EXPORT_SYMBOL(nand_lock);

/**
 * nand_check_erased_buf - check if a buffer contains (almost) only 0xff data
 * @buf: buffer to test
+0 −10
Original line number Diff line number Diff line
@@ -44,12 +44,6 @@ void nand_release(struct mtd_info *mtd);
/* Internal helper for board drivers which need to override command function */
void nand_wait_ready(struct mtd_info *mtd);

/* locks all blocks present in the device */
int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);

/* unlocks specified locked blocks */
int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);

/* The maximum number of NAND chips in an array */
#define NAND_MAX_CHIPS		8

@@ -89,10 +83,6 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
#define NAND_CMD_SET_FEATURES	0xef
#define NAND_CMD_RESET		0xff

#define NAND_CMD_LOCK		0x2a
#define NAND_CMD_UNLOCK1	0x23
#define NAND_CMD_UNLOCK2	0x24

/* Extended commands for large page devices */
#define NAND_CMD_READSTART	0x30
#define NAND_CMD_RNDOUTSTART	0xE0