Commit 1b88176b authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull MTD updates from Miquel Raynal:
 "MTD core:
   - drop inactive maintainers, update the repositories and add IRC
     channel
   - debugfs functions improvements
   - initialize more structure parameters
   - misc fixes reported by robots

  MTD devices:
   - spear_smi: Fixed Write Burst mode
   - new Intel IXP4xx flash probing hook

  Raw NAND core:
   - useless extra checks dropped
   - update the detection of the bad block markers position

  Raw NAND controller drivers:
   - Cadence: new driver
   - Brcmnand: support for flash-dma v0 + fixes
   - Denali: drop support for the legacy controller/chip DT representation
   - superfluous dev_err() calls removed

  SPI NOR core changes:
   - introduce 'struct spi_nor_controller_ops'
   - clean the Register Operations methods
   - use dev_dbg insted of dev_err for low level info
   - fix retlen handling in sst_write()
   - fix silent truncations in spi_nor_read and spi_nor_read_raw()
   - fix the clearing of QE bit on lock()/unlock()
   - rework the disabling of the block write protection
   - rework the Quad Enable methods
   - make sure nor->spimem and nor->controller_ops are mutually exclusive
   - set default Quad Enable method for ISSI flashes
   - add support for few flashes

  SPI NOR controller drivers changes:
   - intel-spi:
      - support chips without software sequencer
      - add support for Intel Cannon Lake and Intel Comet Lake-H flashes

  CFI core changes:
   - code cleanups related useless initializers and coding style issues
   - fix for a possible double free problem in cfi_cmdset_0002
   - improved HyperFlash error reporting and handling in cfi_cmdset_0002 core"

* tag 'mtd/for-5.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: (73 commits)
  mtd: devices: fix mchp23k256 read and write
  mtd: no need to check return value of debugfs_create functions
  mtd: spi-nor: Set default Quad Enable method for ISSI flashes
  mtd: spi-nor: Add support for is25wp256
  mtd: spi-nor: Add support for w25q256jw
  mtd: spi-nor: Move condition to avoid a NULL check
  mtd: spi-nor: Make sure nor->spimem and nor->controller_ops are mutually exclusive
  mtd: spi-nor: Rename Quad Enable methods
  mtd: spi-nor: Merge spansion Quad Enable methods
  mtd: spi-nor: Rename CR_QUAD_EN_SPAN to SR2_QUAD_EN_BIT1
  mtd: spi-nor: Extend the SR Read Back test
  mtd: spi-nor: Rework the disabling of block write protection
  mtd: spi-nor: Fix clearing of QE bit on lock()/unlock()
  mtd: cfi_cmdset_0002: fix delayed error detection on HyperFlash
  mtd: cfi_cmdset_0002: only check errors when ready in cfi_check_err_status()
  mtd: cfi_cmdset_0002: don't free cfi->cfiq in error path of cfi_amdstd_setup()
  mtd: cfi_cmdset_*: kill useless 'ret' variable initializers
  mtd: cfi_util: use DIV_ROUND_UP() in cfi_udelay()
  mtd: spi-nor: Print debug message when the read back test fails
  mtd: spi-nor: Check all the bits written, not just the BP ones
  ...
parents eeee2827 589e1b6c
Loading
Loading
Loading
Loading
+53 −0
Original line number Diff line number Diff line
* Cadence NAND controller

Required properties:
  - compatible : "cdns,hp-nfc"
  - reg : Contains two entries, each of which is a tuple consisting of a
	  physical address and length. The first entry is the address and
	  length of the controller register set. The second entry is the
	  address and length of the Slave DMA data port.
  - reg-names: should contain "reg" and "sdma"
  - #address-cells: should be 1. The cell encodes the chip select connection.
  - #size-cells : should be 0.
  - interrupts : The interrupt number.
  - clocks: phandle of the controller core clock (nf_clk).

Optional properties:
  - dmas: shall reference DMA channel associated to the NAND controller
  - cdns,board-delay-ps : Estimated Board delay. The value includes the total
    round trip delay for the signals and is used for deciding on values
    associated with data read capture. The example formula for SDR mode is
    the following:
    board delay = RE#PAD delay + PCB trace to device + PCB trace from device
    + DQ PAD delay

Child nodes represent the available NAND chips.

Required properties of NAND chips:
  - reg: shall contain the native Chip Select ids from 0 to max supported by
    the cadence nand flash controller

See Documentation/devicetree/bindings/mtd/nand.txt for more details on
generic bindings.

Example:

nand_controller: nand-controller@60000000 {
	  compatible = "cdns,hp-nfc";
	  #address-cells = <1>;
	  #size-cells = <0>;
	  reg = <0x60000000 0x10000>, <0x80000000 0x10000>;
	  reg-names = "reg", "sdma";
	  clocks = <&nf_clk>;
	  cdns,board-delay-ps = <4830>;
	  interrupts = <2 0>;
	  nand@0 {
	      reg = <0>;
	      label = "nand-1";
	  };
	  nand@1 {
	      reg = <1>;
	      label = "nand-2";
	  };

};
+22 −0
Original line number Diff line number Diff line
Flash device on Intel IXP4xx SoC

This flash is regular CFI compatible (Intel or AMD extended) flash chips with
specific big-endian or mixed-endian memory access pattern.

Required properties:
- compatible : must be "intel,ixp4xx-flash", "cfi-flash";
- reg : memory address for the flash chip
- bank-width : width in bytes of flash interface, should be <2>

For the rest of the properties, see mtd-physmap.txt.

The device tree may optionally contain sub-nodes describing partitions of the
address space. See partition.txt for more detail.

Example:

flash@50000000 {
	compatible = "intel,ixp4xx-flash", "cfi-flash";
	reg = <0x50000000 0x01000000>;
	bank-width = <2>;
};
+12 −9
Original line number Diff line number Diff line
@@ -3595,6 +3595,13 @@ S: Maintained
F:	Documentation/devicetree/bindings/media/cdns,*.txt
F:	drivers/media/platform/cadence/cdns-csi2*
CADENCE NAND DRIVER
M:	Piotr Sroka <piotrs@cadence.com>
L:	linux-mtd@lists.infradead.org
S:	Maintained
F:	drivers/mtd/nand/raw/cadence-nand-controller.c
F:	Documentation/devicetree/bindings/mtd/cadence-nand-controller.txt
CADET FM/AM RADIO RECEIVER DRIVER
M:	Hans Verkuil <hverkuil@xs4all.nl>
L:	linux-media@vger.kernel.org
@@ -10537,15 +10544,13 @@ F: include/linux/vmalloc.h
F:	mm/
MEMORY TECHNOLOGY DEVICES (MTD)
M:	David Woodhouse <dwmw2@infradead.org>
M:	Brian Norris <computersforpeace@gmail.com>
M:	Marek Vasut <marek.vasut@gmail.com>
M:	Miquel Raynal <miquel.raynal@bootlin.com>
M:	Richard Weinberger <richard@nod.at>
M:	Vignesh Raghavendra <vigneshr@ti.com>
L:	linux-mtd@lists.infradead.org
W:	http://www.linux-mtd.infradead.org/
Q:	http://patchwork.ozlabs.org/project/linux-mtd/list/
C:	irc://irc.oftc.net/mtd
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git mtd/fixes
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git mtd/next
S:	Maintained
@@ -15296,7 +15301,6 @@ F: arch/arm/boot/dts/spear*
F:	arch/arm/mach-spear/
SPI NOR SUBSYSTEM
M:	Marek Vasut <marek.vasut@gmail.com>
M:	Tudor Ambarus <tudor.ambarus@microchip.com>
L:	linux-mtd@lists.infradead.org
W:	http://www.linux-mtd.infradead.org/
@@ -16593,10 +16597,9 @@ F: drivers/media/pci/tw686x/
UBI FILE SYSTEM (UBIFS)
M:	Richard Weinberger <richard@nod.at>
M:	Artem Bityutskiy <dedekind1@gmail.com>
M:	Adrian Hunter <adrian.hunter@intel.com>
L:	linux-mtd@lists.infradead.org
T:	git git://git.infradead.org/ubifs-2.6.git
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs.git next
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs.git fixes
W:	http://www.linux-mtd.infradead.org/doc/ubifs.html
S:	Supported
F:	Documentation/filesystems/ubifs.txt
@@ -16711,11 +16714,11 @@ S: Maintained
F:	drivers/scsi/ufs/ufs-mediatek*
UNSORTED BLOCK IMAGES (UBI)
M:	Artem Bityutskiy <dedekind1@gmail.com>
M:	Richard Weinberger <richard@nod.at>
W:	http://www.linux-mtd.infradead.org/
L:	linux-mtd@lists.infradead.org
T:	git git://git.infradead.org/ubifs-2.6.git
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs.git next
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/rw/ubifs.git fixes
S:	Supported
F:	drivers/mtd/ubi/
F:	include/linux/mtd/ubi.h
+5 −5
Original line number Diff line number Diff line
@@ -1353,7 +1353,7 @@ static int do_point_onechip (struct map_info *map, struct flchip *chip, loff_t a
{
	unsigned long cmd_addr;
	struct cfi_private *cfi = map->fldrv_priv;
	int ret = 0;
	int ret;

	adr += chip->start;

@@ -1383,7 +1383,7 @@ static int cfi_intelext_point(struct mtd_info *mtd, loff_t from, size_t len,
	struct cfi_private *cfi = map->fldrv_priv;
	unsigned long ofs, last_end = 0;
	int chipnum;
	int ret = 0;
	int ret;

	if (!map->virt)
		return -EINVAL;
@@ -1550,7 +1550,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
{
	struct cfi_private *cfi = map->fldrv_priv;
	map_word status, write_cmd;
	int ret=0;
	int ret;

	adr += chip->start;

@@ -1624,7 +1624,7 @@ static int cfi_intelext_write_words (struct mtd_info *mtd, loff_t to , size_t le
{
	struct map_info *map = mtd->priv;
	struct cfi_private *cfi = map->fldrv_priv;
	int ret = 0;
	int ret;
	int chipnum;
	unsigned long ofs;

@@ -1871,7 +1871,7 @@ static int cfi_intelext_writev (struct mtd_info *mtd, const struct kvec *vecs,
	struct map_info *map = mtd->priv;
	struct cfi_private *cfi = map->fldrv_priv;
	int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
	int ret = 0;
	int ret;
	int chipnum;
	unsigned long ofs, vec_seek, i;
	size_t len = 0;
+45 −34
Original line number Diff line number Diff line
@@ -123,19 +123,23 @@ static int cfi_use_status_reg(struct cfi_private *cfi)
		(extp->SoftwareFeatures & poll_mask) == CFI_POLL_STATUS_REG;
}

static void cfi_check_err_status(struct map_info *map, struct flchip *chip,
static int cfi_check_err_status(struct map_info *map, struct flchip *chip,
				unsigned long adr)
{
	struct cfi_private *cfi = map->fldrv_priv;
	map_word status;

	if (!cfi_use_status_reg(cfi))
		return;
		return 0;

	cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi,
			 cfi->device_type, NULL);
	status = map_read(map, adr);

	/* The error bits are invalid while the chip's busy */
	if (!map_word_bitsset(map, status, CMD(CFI_SR_DRB)))
		return 0;

	if (map_word_bitsset(map, status, CMD(0x3a))) {
		unsigned long chipstatus = MERGESTATUS(status);

@@ -151,7 +155,12 @@ static void cfi_check_err_status(struct map_info *map, struct flchip *chip,
		if (chipstatus & CFI_SR_SLSB)
			pr_err("%s sector write protected, status %lx\n",
			       map->name, chipstatus);

		/* Erase/Program status bits are set on the operation failure */
		if (chipstatus & (CFI_SR_ESB | CFI_SR_PSB))
			return 1;
	}
	return 0;
}

/* #define DEBUG_CFI_FEATURES */
@@ -785,7 +794,6 @@ static struct mtd_info *cfi_amdstd_setup(struct mtd_info *mtd)
	kfree(mtd->eraseregions);
	kfree(mtd);
	kfree(cfi->cmdset_priv);
	kfree(cfi->cfiq);
	return NULL;
}

@@ -848,20 +856,16 @@ static int __xipram chip_good(struct map_info *map, struct flchip *chip,

	if (cfi_use_status_reg(cfi)) {
		map_word ready = CMD(CFI_SR_DRB);
		map_word err = CMD(CFI_SR_PSB | CFI_SR_ESB);

		/*
		 * For chips that support status register, check device
		 * ready bit and Erase/Program status bit to know if
		 * operation succeeded.
		 * ready bit
		 */
		cfi_send_gen_cmd(0x70, cfi->addr_unlock1, chip->start, map, cfi,
				 cfi->device_type, NULL);
		curd = map_read(map, addr);

		if (map_word_andequal(map, curd, ready, ready))
			return !map_word_bitsset(map, curd, err);

		return 0;
		return map_word_andequal(map, curd, ready, ready);
	}

	oldd = map_read(map, addr);
@@ -1699,8 +1703,11 @@ static int __xipram do_write_oneword_once(struct map_info *map,
			break;
		}

		if (chip_good(map, chip, adr, datum))
		if (chip_good(map, chip, adr, datum)) {
			if (cfi_check_err_status(map, chip, adr))
				ret = -EIO;
			break;
		}

		/* Latency issues. Drop the lock, wait a while and retry */
		UDELAY(map, chip, adr, 1);
@@ -1713,7 +1720,7 @@ static int __xipram do_write_oneword_start(struct map_info *map,
					   struct flchip *chip,
					   unsigned long adr, int mode)
{
	int ret = 0;
	int ret;

	mutex_lock(&chip->mutex);

@@ -1773,7 +1780,6 @@ static int __xipram do_write_oneword_retry(struct map_info *map,
	ret = do_write_oneword_once(map, chip, adr, datum, mode, cfi);
	if (ret) {
		/* reset on all failures. */
		cfi_check_err_status(map, chip, adr);
		map_write(map, CMD(0xF0), chip->start);
		/* FIXME - should have reset delay before continuing */

@@ -1791,7 +1797,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip,
				     unsigned long adr, map_word datum,
				     int mode)
{
	int ret = 0;
	int ret;

	adr += chip->start;

@@ -1815,7 +1821,7 @@ static int cfi_amdstd_write_words(struct mtd_info *mtd, loff_t to, size_t len,
{
	struct map_info *map = mtd->priv;
	struct cfi_private *cfi = map->fldrv_priv;
	int ret = 0;
	int ret;
	int chipnum;
	unsigned long ofs, chipstart;
	DECLARE_WAITQUEUE(wait, current);
@@ -1970,12 +1976,17 @@ static int __xipram do_write_buffer_wait(struct map_info *map,
		 */
		if (time_after(jiffies, timeo) &&
		    !chip_good(map, chip, adr, datum)) {
			pr_err("MTD %s(): software timeout, address:0x%.8lx.\n",
			       __func__, adr);
			ret = -EIO;
			break;
		}

		if (chip_good(map, chip, adr, datum))
		if (chip_good(map, chip, adr, datum)) {
			if (cfi_check_err_status(map, chip, adr))
				ret = -EIO;
			break;
		}

		/* Latency issues. Drop the lock, wait a while and retry */
		UDELAY(map, chip, adr, 1);
@@ -2014,7 +2025,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
				    int len)
{
	struct cfi_private *cfi = map->fldrv_priv;
	int ret = -EIO;
	int ret;
	unsigned long cmd_adr;
	int z, words;
	map_word datum;
@@ -2071,12 +2082,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
				chip->word_write_time);

	ret = do_write_buffer_wait(map, chip, adr, datum);
	if (ret) {
		cfi_check_err_status(map, chip, adr);
	if (ret)
		do_write_buffer_reset(map, chip, cfi);
		pr_err("MTD %s(): software timeout, address:0x%.8lx.\n",
		       __func__, adr);
	}

	xip_enable(map, chip, adr);

@@ -2095,7 +2102,7 @@ static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
	struct map_info *map = mtd->priv;
	struct cfi_private *cfi = map->fldrv_priv;
	int wbufsize = cfi_interleave(cfi) << cfi->cfiq->MaxBufWriteSize;
	int ret = 0;
	int ret;
	int chipnum;
	unsigned long ofs;

@@ -2232,7 +2239,7 @@ static int do_panic_write_oneword(struct map_info *map, struct flchip *chip,
	struct cfi_private *cfi = map->fldrv_priv;
	int retry_cnt = 0;
	map_word oldd;
	int ret = 0;
	int ret;
	int i;

	adr += chip->start;
@@ -2271,9 +2278,9 @@ retry:
		udelay(1);
	}

	if (!chip_good(map, chip, adr, datum)) {
	if (!chip_good(map, chip, adr, datum) ||
	    cfi_check_err_status(map, chip, adr)) {
		/* reset on all failures. */
		cfi_check_err_status(map, chip, adr);
		map_write(map, CMD(0xF0), chip->start);
		/* FIXME - should have reset delay before continuing */

@@ -2307,7 +2314,7 @@ static int cfi_amdstd_panic_write(struct mtd_info *mtd, loff_t to, size_t len,
	struct map_info *map = mtd->priv;
	struct cfi_private *cfi = map->fldrv_priv;
	unsigned long ofs, chipstart;
	int ret = 0;
	int ret;
	int chipnum;

	chipnum = to >> cfi->chipshift;
@@ -2411,7 +2418,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
	unsigned long timeo = jiffies + HZ;
	unsigned long int adr;
	DECLARE_WAITQUEUE(wait, current);
	int ret = 0;
	int ret;
	int retry_cnt = 0;

	adr = cfi->addr_unlock1;
@@ -2467,8 +2474,11 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
			chip->erase_suspended = 0;
		}

		if (chip_good(map, chip, adr, map_word_ff(map)))
		if (chip_good(map, chip, adr, map_word_ff(map))) {
			if (cfi_check_err_status(map, chip, adr))
				ret = -EIO;
			break;
		}

		if (time_after(jiffies, timeo)) {
			printk(KERN_WARNING "MTD %s(): software timeout\n",
@@ -2483,7 +2493,6 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip)
	/* Did we succeed? */
	if (ret) {
		/* reset on all failures. */
		cfi_check_err_status(map, chip, adr);
		map_write(map, CMD(0xF0), chip->start);
		/* FIXME - should have reset delay before continuing */

@@ -2508,7 +2517,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
	struct cfi_private *cfi = map->fldrv_priv;
	unsigned long timeo = jiffies + HZ;
	DECLARE_WAITQUEUE(wait, current);
	int ret = 0;
	int ret;
	int retry_cnt = 0;

	adr += chip->start;
@@ -2564,8 +2573,11 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
			chip->erase_suspended = 0;
		}

		if (chip_good(map, chip, adr, map_word_ff(map)))
		if (chip_good(map, chip, adr, map_word_ff(map))) {
			if (cfi_check_err_status(map, chip, adr))
				ret = -EIO;
			break;
		}

		if (time_after(jiffies, timeo)) {
			printk(KERN_WARNING "MTD %s(): software timeout\n",
@@ -2580,7 +2592,6 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
	/* Did we succeed? */
	if (ret) {
		/* reset on all failures. */
		cfi_check_err_status(map, chip, adr);
		map_write(map, CMD(0xF0), chip->start);
		/* FIXME - should have reset delay before continuing */

Loading