Skip to content

Commit

Permalink
Merge tag 'for-linus-20160523' of git://git.infradead.org/linux-mtd
Browse files Browse the repository at this point in the history
Pull MTD updates from Brian Norris:
 "First cycle with Boris as NAND maintainer! Many (most) bullets stolen
  from him.

  Generic:
   - Migrated NAND LED trigger to be a generic MTD trigger

  NAND:
   - Introduction of the "ECC algorithm" concept, to avoid overloading
     the ECC mode field too much more
   - Replaced the nand_ecclayout infrastructure with something a little
     more flexible (finally!) and future proof
   - Rework of the OMAP GPMC and NAND drivers; the TI folks pulled some
     of this into their own tree as well
   - Prepare the sunxi NAND driver to receive DMA support
   - Handle bitflips in erased pages on GPMI revisions that do not
     support this in hardware.

  SPI NOR:
   - Start using the spi_flash_read() API for SPI drivers that support
     it (i.e., SPI drivers with special memory-mapped flash modes)

  And other small scattered improvments"

* tag 'for-linus-20160523' of git://git.infradead.org/linux-mtd: (155 commits)
  mtd: spi-nor: support GigaDevice gd25lq64c
  mtd: nand_bch: fix spelling of "probably"
  mtd: brcmnand: respect ECC algorithm set by NAND subsystem
  gpmi-nand: Handle ECC Errors in erased pages
  Documentation: devicetree: deprecate "soft_bch" nand-ecc-mode value
  mtd: nand: add support for "nand-ecc-algo" DT property
  mtd: mtd: drop NAND_ECC_SOFT_BCH enum value
  mtd: drop support for NAND_ECC_SOFT_BCH as "soft_bch" mapping
  mtd: nand: read ECC algorithm from the new field
  mtd: nand: fsmc: validate ECC setup by checking algorithm directly
  mtd: nand: set ECC algorithm to Hamming on fallback
  staging: mt29f_spinand: set ECC algorithm explicitly
  CRIS v32: nand: set ECC algorithm explicitly
  mtd: nand: atmel: set ECC algorithm explicitly
  mtd: nand: davinci: set ECC algorithm explicitly
  mtd: nand: bf5xx: set ECC algorithm explicitly
  mtd: nand: omap2: Fix high memory dma prefetch transfer
  mtd: nand: omap2: Start dma request before enabling prefetch
  mtd: nandsim: add __init attribute
  mtd: nand: move of_get_nand_xxx() helpers into nand_base.c
  ...
  • Loading branch information
torvalds committed May 24, 2016
2 parents 2956729 + e5366a2 commit 8bc4d5f
Show file tree
Hide file tree
Showing 89 changed files with 4,338 additions and 2,908 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,19 @@ Required properties:
bootloader) are used for the physical address decoding.
As this will change in the future, filling correct
values here is a requirement.
- interrupt-controller: The GPMC driver implements and interrupt controller for
the NAND events "fifoevent" and "termcount" plus the
rising/falling edges on the GPMC_WAIT pins.
The interrupt number mapping is as follows
0 - NAND_fifoevent
1 - NAND_termcount
2 - GPMC_WAIT0 pin edge
3 - GPMC_WAIT1 pin edge, and so on.
- interrupt-cells: Must be set to 2
- gpio-controller: The GPMC driver implements a GPIO controller for the
GPMC WAIT pins that can be used as general purpose inputs.
0 maps to GPMC_WAIT0 pin.
- gpio-cells: Must be set to 2

Timing properties for child nodes. All are optional and default to 0.

Expand Down Expand Up @@ -130,6 +143,10 @@ Example for an AM33xx board:
#address-cells = <2>;
#size-cells = <1>;
ranges = <0 0 0x08000000 0x10000000>; /* CS0 @addr 0x8000000, size 0x10000000 */
interrupt-controller;
#interrupt-cells = <2>;
gpio-controller;
#gpio-cells = <2>;

/* child nodes go here */
};
1 change: 1 addition & 0 deletions Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Required properties:
brcm,brcmnand-v5.0
brcm,brcmnand-v6.0
brcm,brcmnand-v6.1
brcm,brcmnand-v6.2
brcm,brcmnand-v7.0
brcm,brcmnand-v7.1
brcm,brcmnand
Expand Down
19 changes: 15 additions & 4 deletions Documentation/devicetree/bindings/mtd/gpmc-nand.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ Documentation/devicetree/bindings/mtd/nand.txt

Required properties:

- reg: The CS line the peripheral is connected to
- compatible: "ti,omap2-nand"
- reg: range id (CS number), base offset and length of the
NAND I/O space
- interrupt-parent: must point to gpmc node
- interrupts: Two interrupt specifiers, one for fifoevent, one for termcount.

Optional properties:

Expand Down Expand Up @@ -44,6 +48,7 @@ Optional properties:
locating ECC errors for BCHx algorithms. SoC devices which have
ELM hardware engines should specify this device node in .dtsi
Using ELM for ECC error correction frees some CPU cycles.
- rb-gpios: GPIO specifier for the ready/busy# pin.

For inline partition table parsing (optional):

Expand All @@ -55,20 +60,26 @@ Example for an AM33xx board:
gpmc: gpmc@50000000 {
compatible = "ti,am3352-gpmc";
ti,hwmods = "gpmc";
reg = <0x50000000 0x1000000>;
reg = <0x50000000 0x36c>;
interrupts = <100>;
gpmc,num-cs = <8>;
gpmc,num-waitpins = <2>;
#address-cells = <2>;
#size-cells = <1>;
ranges = <0 0 0x08000000 0x2000>; /* CS0: NAND */
ranges = <0 0 0x08000000 0x1000000>; /* CS0 space, 16MB */
elm_id = <&elm>;
interrupt-controller;
#interrupt-cells = <2>;

nand@0,0 {
reg = <0 0 0>; /* CS0, offset 0 */
compatible = "ti,omap2-nand";
reg = <0 0 4>; /* CS0, offset 0, NAND I/O window 4 */
interrupt-parent = <&gpmc>;
interrupts = <0 IRQ_TYPE_NONE>, <1 IRQ_TYPE NONE>;
nand-bus-width = <16>;
ti,nand-ecc-opt = "bch8";
ti,nand-xfer-type = "polled";
rb-gpios = <&gpmc 0 GPIO_ACTIVE_HIGH>; /* gpmc_wait0 */

gpmc,sync-clk-ps = <0>;
gpmc,cs-on-ns = <0>;
Expand Down
45 changes: 42 additions & 3 deletions Documentation/devicetree/bindings/mtd/nand.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,31 @@
* MTD generic binding
* NAND chip and NAND controller generic binding

NAND controller/NAND chip representation:

The NAND controller should be represented with its own DT node, and all
NAND chips attached to this controller should be defined as children nodes
of the NAND controller. This representation should be enforced even for
simple controllers supporting only one chip.

Mandatory NAND controller properties:
- #address-cells: depends on your controller. Should at least be 1 to
encode the CS line id.
- #size-cells: depends on your controller. Put zero unless you need a
mapping between CS lines and dedicated memory regions

Optional NAND controller properties
- ranges: only needed if you need to define a mapping between CS lines and
memory regions

Optional NAND chip properties:

- nand-ecc-mode : String, operation mode of the NAND ecc mode.
Supported values are: "none", "soft", "hw", "hw_syndrome", "hw_oob_first",
"soft_bch".
Supported values are: "none", "soft", "hw", "hw_syndrome",
"hw_oob_first".
Deprecated values:
"soft_bch": use "soft" and nand-ecc-algo instead
- nand-ecc-algo: string, algorithm of NAND ECC.
Supported values are: "hamming", "bch".
- nand-bus-width : 8 or 16 bus width if not present 8
- nand-on-flash-bbt: boolean to enable on flash bbt option if not present false

Expand All @@ -19,3 +42,19 @@ errors per {size} bytes".
The interpretation of these parameters is implementation-defined, so not all
implementations must support all possible combinations. However, implementations
are encouraged to further specify the value(s) they support.

Example:

nand-controller {
#address-cells = <1>;
#size-cells = <0>;

/* controller specific properties */

nand@0 {
reg = <0>;
nand-ecc-mode = "soft_bch";

/* controller specific properties */
};
};
7 changes: 1 addition & 6 deletions arch/arm/mach-omap2/gpmc-nand.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,7 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
gpmc_nand_res[2].start = gpmc_get_client_irq(GPMC_IRQ_COUNT_EVENT);

memset(&s, 0, sizeof(struct gpmc_settings));
if (gpmc_nand_data->of_node)
gpmc_read_settings_dt(gpmc_nand_data->of_node, &s);
else
gpmc_set_legacy(gpmc_nand_data, &s);
gpmc_set_legacy(gpmc_nand_data, &s);

s.device_nand = true;

Expand All @@ -121,8 +118,6 @@ int gpmc_nand_init(struct omap_nand_platform_data *gpmc_nand_data,
if (err < 0)
goto out_free_cs;

gpmc_update_nand_reg(&gpmc_nand_data->reg, gpmc_nand_data->cs);

if (!gpmc_hwecc_bch_capable(gpmc_nand_data->ecc_opt)) {
pr_err("omap2-nand: Unsupported NAND ECC scheme selected\n");
err = -EINVAL;
Expand Down
55 changes: 45 additions & 10 deletions arch/arm/mach-pxa/spitz.c
Original file line number Diff line number Diff line change
Expand Up @@ -763,14 +763,49 @@ static struct nand_bbt_descr spitz_nand_bbt = {
.pattern = scan_ff_pattern
};

static struct nand_ecclayout akita_oobinfo = {
.oobfree = { {0x08, 0x09} },
.eccbytes = 24,
.eccpos = {
0x05, 0x01, 0x02, 0x03, 0x06, 0x07, 0x15, 0x11,
0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37,
},
static int akita_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
{
if (section > 12)
return -ERANGE;

switch (section % 3) {
case 0:
oobregion->offset = 5;
oobregion->length = 1;
break;

case 1:
oobregion->offset = 1;
oobregion->length = 3;
break;

case 2:
oobregion->offset = 6;
oobregion->length = 2;
break;
}

oobregion->offset += (section / 3) * 0x10;

return 0;
}

static int akita_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
{
if (section)
return -ERANGE;

oobregion->offset = 8;
oobregion->length = 9;

return 0;
}

static const struct mtd_ooblayout_ops akita_ooblayout_ops = {
.ecc = akita_ooblayout_ecc,
.free = akita_ooblayout_free,
};

static struct sharpsl_nand_platform_data spitz_nand_pdata = {
Expand Down Expand Up @@ -804,11 +839,11 @@ static void __init spitz_nand_init(void)
} else if (machine_is_akita()) {
spitz_nand_partitions[1].size = 58 * 1024 * 1024;
spitz_nand_bbt.len = 1;
spitz_nand_pdata.ecc_layout = &akita_oobinfo;
spitz_nand_pdata.ecc_layout = &akita_ooblayout_ops;
} else if (machine_is_borzoi()) {
spitz_nand_partitions[1].size = 32 * 1024 * 1024;
spitz_nand_bbt.len = 1;
spitz_nand_pdata.ecc_layout = &akita_oobinfo;
spitz_nand_pdata.ecc_layout = &akita_ooblayout_ops;
}

platform_device_register(&spitz_nand_device);
Expand Down
1 change: 1 addition & 0 deletions arch/cris/arch-v32/drivers/mach-a3/nandflash.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ struct mtd_info *__init crisv32_nand_flash_probe(void)
/* 20 us command delay time */
this->chip_delay = 20;
this->ecc.mode = NAND_ECC_SOFT;
this->ecc.algo = NAND_ECC_HAMMING;

/* Enable the following for a flash based bad block table */
/* this->bbt_options = NAND_BBT_USE_FLASH; */
Expand Down
1 change: 1 addition & 0 deletions arch/cris/arch-v32/drivers/mach-fs/nandflash.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ struct mtd_info *__init crisv32_nand_flash_probe(void)
/* 20 us command delay time */
this->chip_delay = 20;
this->ecc.mode = NAND_ECC_SOFT;
this->ecc.algo = NAND_ECC_HAMMING;

/* Enable the following for a flash based bad block table */
/* this->bbt_options = NAND_BBT_USE_FLASH; */
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/include/asm/mach-jz4740/jz4740_nand.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ struct jz_nand_platform_data {

unsigned char banks[JZ_NAND_NUM_BANKS];

void (*ident_callback)(struct platform_device *, struct nand_chip *,
void (*ident_callback)(struct platform_device *, struct mtd_info *,
struct mtd_partition **, int *num_partitions);
};

Expand Down
87 changes: 51 additions & 36 deletions arch/mips/jz4740/board-qi_lb60.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,6 @@
#define QI_LB60_GPIO_KEYIN8 JZ_GPIO_PORTD(26)

/* NAND */
static struct nand_ecclayout qi_lb60_ecclayout_1gb = {
.eccbytes = 36,
.eccpos = {
6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33, 34, 35, 36, 37,
38, 39, 40, 41
},
.oobfree = {
{ .offset = 2, .length = 4 },
{ .offset = 42, .length = 22 }
},
};

/* Early prototypes of the QI LB60 had only 1GB of NAND.
* In order to support these devices as well the partition and ecc layout is
Expand All @@ -84,25 +70,6 @@ static struct mtd_partition qi_lb60_partitions_1gb[] = {
},
};

static struct nand_ecclayout qi_lb60_ecclayout_2gb = {
.eccbytes = 72,
.eccpos = {
12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27,
28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43,
44, 45, 46, 47, 48, 49, 50, 51,
52, 53, 54, 55, 56, 57, 58, 59,
60, 61, 62, 63, 64, 65, 66, 67,
68, 69, 70, 71, 72, 73, 74, 75,
76, 77, 78, 79, 80, 81, 82, 83
},
.oobfree = {
{ .offset = 2, .length = 10 },
{ .offset = 84, .length = 44 },
},
};

static struct mtd_partition qi_lb60_partitions_2gb[] = {
{
.name = "NAND BOOT partition",
Expand All @@ -121,19 +88,67 @@ static struct mtd_partition qi_lb60_partitions_2gb[] = {
},
};

static int qi_lb60_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
{
if (section)
return -ERANGE;

oobregion->length = 36;
oobregion->offset = 6;

if (mtd->oobsize == 128) {
oobregion->length *= 2;
oobregion->offset *= 2;
}

return 0;
}

static int qi_lb60_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobregion)
{
int eccbytes = 36, eccoff = 6;

if (section > 1)
return -ERANGE;

if (mtd->oobsize == 128) {
eccbytes *= 2;
eccoff *= 2;
}

if (!section) {
oobregion->offset = 2;
oobregion->length = eccoff - 2;
} else {
oobregion->offset = eccoff + eccbytes;
oobregion->length = mtd->oobsize - oobregion->offset;
}

return 0;
}

static const struct mtd_ooblayout_ops qi_lb60_ooblayout_ops = {
.ecc = qi_lb60_ooblayout_ecc,
.free = qi_lb60_ooblayout_free,
};

static void qi_lb60_nand_ident(struct platform_device *pdev,
struct nand_chip *chip, struct mtd_partition **partitions,
struct mtd_info *mtd, struct mtd_partition **partitions,
int *num_partitions)
{
struct nand_chip *chip = mtd_to_nand(mtd);

if (chip->page_shift == 12) {
chip->ecc.layout = &qi_lb60_ecclayout_2gb;
*partitions = qi_lb60_partitions_2gb;
*num_partitions = ARRAY_SIZE(qi_lb60_partitions_2gb);
} else {
chip->ecc.layout = &qi_lb60_ecclayout_1gb;
*partitions = qi_lb60_partitions_1gb;
*num_partitions = ARRAY_SIZE(qi_lb60_partitions_1gb);
}

mtd_set_ooblayout(mtd, &qi_lb60_ooblayout_ops);
}

static struct jz_nand_platform_data qi_lb60_nand_pdata = {
Expand Down
1 change: 0 additions & 1 deletion drivers/bcma/driver_chipcommon_sflash.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,6 @@ int bcma_sflash_init(struct bcma_drv_cc *cc)
return -ENOTSUPP;
}

sflash->window = BCMA_SOC_FLASH2;
sflash->blocksize = e->blocksize;
sflash->numblocks = e->numblocks;
sflash->size = sflash->blocksize * sflash->numblocks;
Expand Down
1 change: 1 addition & 0 deletions drivers/memory/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ config TI_EMIF

config OMAP_GPMC
bool
select GPIOLIB
help
This driver is for the General Purpose Memory Controller (GPMC)
present on Texas Instruments SoCs (e.g. OMAP2+). GPMC allows
Expand Down
Loading

0 comments on commit 8bc4d5f

Please sign in to comment.