Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 54245ed8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'for-linus-20150623' of git://git.infradead.org/linux-mtd

Pull MTD updates from Brian Norris:
 "JFFS2:
   - fix a theoretical unbalanced locking issue; the lock handling was a
     bit unclean, but AFAICT, it didn't actually lead to real deadlocks

  NAND:
   - brcmnand driver: new driver supporting NAND controller found
     originally on Broadcom STB SoCs (BCM7xxx), but now also found on
     BCM63xxx, iProc (e.g., Cygnus, BCM5301x), BCM3xxx, and more

   - begin factoring out BBT code so it can be shared between
     traditional (parallel) NAND drivers and upcoming SPI NAND drivers
     (WIP)

   - add common DT-based init support, so nand_base can pick up some
     flash properties automatically, using established common NAND DT
     properties

   - mxc_nand: support 8-bit ECC

   - pxa3xx_nand:
     * fix build for ARM64
     * use a jiffies-based timeout

  SPI NOR:
   - add a few new IDs

   - clear out some unnecessary entries

   - make sure SECT_4K flags are correct for all (?) entries

  Core:
   - fix mtd->usecount race conditions (BUG_ON())

   - switch to modern PM ops

  Other:
   - CFI: save code space by de-inlining large functions

   - clean up some partition parser selection code across several
     drivers

   - various miscellaneous changes, mostly minor"

* tag 'for-linus-20150623' of git://git.infradead.org/linux-mtd: (57 commits)
  mtd: docg3: Fix kasprintf() usage
  mtd: docg3: Don't leak docg3->bbt in error path
  mtd: nandsim: Fix kasprintf() usage
  mtd: cs553x_nand: Fix kasprintf() usage
  mtd: r852: Fix device_create_file() usage
  mtd: brcmnand: drop unnecessary initialization
  mtd: propagate error codes from add_mtd_device()
  mtd: diskonchip: remove two-phase partitioning / registration
  mtd: dc21285: use raw spinlock functions for nw_gpio_lock
  mtd: chips: fixup dependencies, to prevent build error
  mtd: cfi_cmdset_0002: Initialize datum before calling map_word_load_partial
  mtd: cfi: deinline large functions
  mtd: lantiq-flash: use default partition parsers
  mtd: plat_nand: use default partition probe
  mtd: nand: correct indentation within conditional
  mtd: remove incorrect file name
  mtd: blktrans: use better error code for unimplemented ioctl()
  mtd: maps: Spelling s/reseved/reserved/
  mtd: blktrans: change blktrans_getgeo return value
  mtd: mxc_nand: generate nand_ecclayout for 8 bit ECC
  ...
parents 84e9c87e 0eb8618b
Loading
Loading
Loading
Loading
+150 −0
Original line number Diff line number Diff line
* Broadcom STB NAND Controller

The Broadcom Set-Top Box NAND controller supports low-level access to raw NAND
flash chips. It has a memory-mapped register interface for both control
registers and for its data input/output buffer. On some SoCs, this controller is
paired with a custom DMA engine (inventively named "Flash DMA") which supports
basic PROGRAM and READ functions, among other features.

This controller was originally designed for STB SoCs (BCM7xxx) but is now
available on a variety of Broadcom SoCs, including some BCM3xxx, BCM63xx, and
iProc/Cygnus. Its history includes several similar (but not fully register
compatible) versions.

Required properties:
- compatible       : May contain an SoC-specific compatibility string (see below)
                     to account for any SoC-specific hardware bits that may be
                     added on top of the base core controller.
                     In addition, must contain compatibility information about
                     the core NAND controller, of the following form:
                     "brcm,brcmnand" and an appropriate version compatibility
                     string, like "brcm,brcmnand-v7.0"
                     Possible values:
                         brcm,brcmnand-v4.0
                         brcm,brcmnand-v5.0
                         brcm,brcmnand-v6.0
                         brcm,brcmnand-v6.1
                         brcm,brcmnand-v7.0
                         brcm,brcmnand-v7.1
                         brcm,brcmnand
- reg              : the register start and length for NAND register region.
                     (optional) Flash DMA register range (if present)
                     (optional) NAND flash cache range (if at non-standard offset)
- reg-names        : a list of the names corresponding to the previous register
                     ranges. Should contain "nand" and (optionally)
                     "flash-dma" and/or "nand-cache".
- interrupts       : The NAND CTLRDY interrupt and (if Flash DMA is available)
                     FLASH_DMA_DONE
- interrupt-names  : May be "nand_ctlrdy" or "flash_dma_done", if broken out as
                     individual interrupts.
                     May be "nand", if the SoC has the individual NAND
                     interrupts multiplexed behind another custom piece of
                     hardware
- interrupt-parent : See standard interrupt bindings
- #address-cells   : <1> - subnodes give the chip-select number
- #size-cells      : <0>

Optional properties:
- brcm,nand-has-wp          : Some versions of this IP include a write-protect
                              (WP) control bit. It is always available on >=
                              v7.0. Use this property to describe the rare
                              earlier versions of this core that include WP

 -- Additonal SoC-specific NAND controller properties --

The NAND controller is integrated differently on the variety of SoCs on which it
is found. Part of this integration involves providing status and enable bits
with which to control the 8 exposed NAND interrupts, as well as hardware for
configuring the endianness of the data bus. On some SoCs, these features are
handled via standard, modular components (e.g., their interrupts look like a
normal IRQ chip), but on others, they are controlled in unique and interesting
ways, sometimes with registers that lump multiple NAND-related functions
together. The former case can be described simply by the standard interrupts
properties in the main controller node. But for the latter exceptional cases,
we define additional 'compatible' properties and associated register resources within the NAND controller node above.

 - compatible: Can be one of several SoC-specific strings. Each SoC may have
   different requirements for its additional properties, as described below each
   bullet point below.

   * "brcm,nand-bcm63138"
     - reg: (required) the 'NAND_INT_BASE' register range, with separate status
       and enable registers
     - reg-names: (required) "nand-int-base"

   * "brcm,nand-iproc"
     - reg: (required) the "IDM" register range, for interrupt enable and APB
       bus access endianness configuration, and the "EXT" register range,
       for interrupt status/ack.
     - reg-names: (required) a list of the names corresponding to the previous
       register ranges. Should contain "iproc-idm" and "iproc-ext".


* NAND chip-select

Each controller (compatible: "brcm,brcmnand") may contain one or more subnodes
to represent enabled chip-selects which (may) contain NAND flash chips. Their
properties are as follows.

Required properties:
- compatible                : should contain "brcm,nandcs"
- reg                       : a single integer representing the chip-select
                              number (e.g., 0, 1, 2, etc.)
- #address-cells            : see partition.txt
- #size-cells               : see partition.txt
- nand-ecc-strength         : see nand.txt
- nand-ecc-step-size        : must be 512 or 1024. See nand.txt

Optional properties:
- nand-on-flash-bbt         : boolean, to enable the on-flash BBT for this
                              chip-select. See nand.txt
- brcm,nand-oob-sector-size : integer, to denote the spare area sector size
                              expected for the ECC layout in use. This size, in
                              addition to the strength and step-size,
                              determines how the hardware BCH engine will lay
                              out the parity bytes it stores on the flash.
                              This property can be automatically determined by
                              the flash geometry (particularly the NAND page
                              and OOB size) in many cases, but when booting
                              from NAND, the boot controller has only a limited
                              number of available options for its default ECC
                              layout.

Each nandcs device node may optionally contain sub-nodes describing the flash
partition mapping. See partition.txt for more detail.


Example:

nand@f0442800 {
	compatible = "brcm,brcmnand-v7.0", "brcm,brcmnand";
	reg = <0xF0442800 0x600>,
	      <0xF0443000 0x100>;
	reg-names = "nand", "flash-dma";
	interrupt-parent = <&hif_intr2_intc>;
	interrupts = <24>, <4>;

	#address-cells = <1>;
	#size-cells = <0>;

	nandcs@1 {
		compatible = "brcm,nandcs";
		reg = <1>; // Chip select 1
		nand-on-flash-bbt;
		nand-ecc-strength = <12>;
		nand-ecc-step-size = <512>;

		// Partitions
		#address-cells = <1>;  // <2>, for 64-bit offset
		#size-cells = <1>;     // <2>, for 64-bit length
		flash0.rootfs@0 {
			reg = <0 0x10000000>;
		};
		flash0@0 {
			reg = <0 0>; // MTDPART_SIZ_FULL
		};
		flash0.kernel@10000000 {
			reg = <0x10000000 0x400000>;
		};
	};
};
+6 −0
Original line number Diff line number Diff line
@@ -2267,6 +2267,12 @@ S: Supported
F:	drivers/gpio/gpio-bcm-kona.c
F:	Documentation/devicetree/bindings/gpio/gpio-bcm-kona.txt

BROADCOM STB NAND FLASH DRIVER
M:	Brian Norris <computersforpeace@gmail.com>
L:	linux-mtd@lists.infradead.org
S:	Maintained
F:	drivers/mtd/nand/brcmnand/

BROADCOM SPECIFIC AMBA DRIVER (BCMA)
M:	Rafał Miłecki <zajec5@gmail.com>
L:	linux-wireless@vger.kernel.org
+1 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ config MTD_CFI
config MTD_JEDECPROBE
	tristate "Detect non-CFI AMD/JEDEC-compatible flash chips"
	select MTD_GEN_PROBE
	select MTD_CFI_UTIL
	help
	  This option enables JEDEC-style probing of flash chips which are not
	  compatible with the Common Flash Interface, but will use the common
+1 −1
Original line number Diff line number Diff line
@@ -1295,7 +1295,7 @@ static int do_otp_write(struct map_info *map, struct flchip *chip, loff_t adr,
		unsigned long bus_ofs = adr & ~(map_bankwidth(map)-1);
		int gap = adr - bus_ofs;
		int n = min_t(int, len, map_bankwidth(map) - gap);
		map_word datum;
		map_word datum = map_word_ff(map);

		if (n != map_bankwidth(map)) {
			/* partial write of a word, load old contents */
+188 −0
Original line number Diff line number Diff line
@@ -23,6 +23,194 @@
#include <linux/mtd/map.h>
#include <linux/mtd/cfi.h>

void cfi_udelay(int us)
{
	if (us >= 1000) {
		msleep((us+999)/1000);
	} else {
		udelay(us);
		cond_resched();
	}
}
EXPORT_SYMBOL(cfi_udelay);

/*
 * Returns the command address according to the given geometry.
 */
uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs,
				struct map_info *map, struct cfi_private *cfi)
{
	unsigned bankwidth = map_bankwidth(map);
	unsigned interleave = cfi_interleave(cfi);
	unsigned type = cfi->device_type;
	uint32_t addr;

	addr = (cmd_ofs * type) * interleave;

	/* Modify the unlock address if we are in compatibility mode.
	 * For 16bit devices on 8 bit busses
	 * and 32bit devices on 16 bit busses
	 * set the low bit of the alternating bit sequence of the address.
	 */
	if (((type * interleave) > bankwidth) && ((cmd_ofs & 0xff) == 0xaa))
		addr |= (type >> 1)*interleave;

	return  addr;
}
EXPORT_SYMBOL(cfi_build_cmd_addr);

/*
 * Transforms the CFI command for the given geometry (bus width & interleave).
 * It looks too long to be inline, but in the common case it should almost all
 * get optimised away.
 */
map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cfi_private *cfi)
{
	map_word val = { {0} };
	int wordwidth, words_per_bus, chip_mode, chips_per_word;
	unsigned long onecmd;
	int i;

	/* We do it this way to give the compiler a fighting chance
	   of optimising away all the crap for 'bankwidth' larger than
	   an unsigned long, in the common case where that support is
	   disabled */
	if (map_bankwidth_is_large(map)) {
		wordwidth = sizeof(unsigned long);
		words_per_bus = (map_bankwidth(map)) / wordwidth; // i.e. normally 1
	} else {
		wordwidth = map_bankwidth(map);
		words_per_bus = 1;
	}

	chip_mode = map_bankwidth(map) / cfi_interleave(cfi);
	chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map);

	/* First, determine what the bit-pattern should be for a single
	   device, according to chip mode and endianness... */
	switch (chip_mode) {
	default: BUG();
	case 1:
		onecmd = cmd;
		break;
	case 2:
		onecmd = cpu_to_cfi16(map, cmd);
		break;
	case 4:
		onecmd = cpu_to_cfi32(map, cmd);
		break;
	}

	/* Now replicate it across the size of an unsigned long, or
	   just to the bus width as appropriate */
	switch (chips_per_word) {
	default: BUG();
#if BITS_PER_LONG >= 64
	case 8:
		onecmd |= (onecmd << (chip_mode * 32));
#endif
	case 4:
		onecmd |= (onecmd << (chip_mode * 16));
	case 2:
		onecmd |= (onecmd << (chip_mode * 8));
	case 1:
		;
	}

	/* And finally, for the multi-word case, replicate it
	   in all words in the structure */
	for (i=0; i < words_per_bus; i++) {
		val.x[i] = onecmd;
	}

	return val;
}
EXPORT_SYMBOL(cfi_build_cmd);

unsigned long cfi_merge_status(map_word val, struct map_info *map,
					   struct cfi_private *cfi)
{
	int wordwidth, words_per_bus, chip_mode, chips_per_word;
	unsigned long onestat, res = 0;
	int i;

	/* We do it this way to give the compiler a fighting chance
	   of optimising away all the crap for 'bankwidth' larger than
	   an unsigned long, in the common case where that support is
	   disabled */
	if (map_bankwidth_is_large(map)) {
		wordwidth = sizeof(unsigned long);
		words_per_bus = (map_bankwidth(map)) / wordwidth; // i.e. normally 1
	} else {
		wordwidth = map_bankwidth(map);
		words_per_bus = 1;
	}

	chip_mode = map_bankwidth(map) / cfi_interleave(cfi);
	chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map);

	onestat = val.x[0];
	/* Or all status words together */
	for (i=1; i < words_per_bus; i++) {
		onestat |= val.x[i];
	}

	res = onestat;
	switch(chips_per_word) {
	default: BUG();
#if BITS_PER_LONG >= 64
	case 8:
		res |= (onestat >> (chip_mode * 32));
#endif
	case 4:
		res |= (onestat >> (chip_mode * 16));
	case 2:
		res |= (onestat >> (chip_mode * 8));
	case 1:
		;
	}

	/* Last, determine what the bit-pattern should be for a single
	   device, according to chip mode and endianness... */
	switch (chip_mode) {
	case 1:
		break;
	case 2:
		res = cfi16_to_cpu(map, res);
		break;
	case 4:
		res = cfi32_to_cpu(map, res);
		break;
	default: BUG();
	}
	return res;
}
EXPORT_SYMBOL(cfi_merge_status);

/*
 * Sends a CFI command to a bank of flash for the given geometry.
 *
 * Returns the offset in flash where the command was written.
 * If prev_val is non-null, it will be set to the value at the command address,
 * before the command was written.
 */
uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t base,
				struct map_info *map, struct cfi_private *cfi,
				int type, map_word *prev_val)
{
	map_word val;
	uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, map, cfi);
	val = cfi_build_cmd(cmd, map, cfi);

	if (prev_val)
		*prev_val = map_read(map, addr);

	map_write(map, val, addr);

	return addr - base;
}
EXPORT_SYMBOL(cfi_send_gen_cmd);

int __xipram cfi_qry_present(struct map_info *map, __u32 base,
			     struct cfi_private *cfi)
{
Loading