Commit 0e47c969 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull MTD updates from Brian Norris:
 - Add me (Brian Norris) as an additional MTD maintainer (it'd be nice to get
   David's "ack" for this; I'm sure he approves, but he's been pretty silent
   lately)
 - Add Ezequiel Garcie as maintainer for the pxa3xx NAND driver
 - Last (?) round of pxa3xx improvements for supporting Armada 370/XP
 - Typical churn in driver boilerplate (OOM messages, printk()'s, devm_*, etc.)
 - Quad read mode support for SPI NOR driver (m25p80)
 - Update Davinci NAND driver to prepare for use on new platforms
 - Begin to kill off NAND_MAX_{PAGE,OOB}SIZE macros; more work is pending
 - Miscellaneous NAND device support (new IDs)
 - Add READ RETRY support for Micron MLC NAND
 - Support new GPMI NAND ECC layout device-tree binding
 - Avoid mapping stack/vmalloc() memory for GPMI NAND DMA

* tag 'for-linus-20140127' of git://git.infradead.org/linux-mtd: (151 commits)
  mtd: gpmi: add sanity check when mapping DMA for read_buf/write_buf
  mtd: gpmi: allocate a proper buffer for non ECC read/write
  mtd: m25p80: Set rx_nbits for Quad SPI transfers
  mtd: m25p80: Enable Quad SPI read transfers for s25fl512s
  mtd: s3c2410: Merge plat/regs-nand.h into s3c2410.c
  mtd: mtdram: add missing 'const'
  mtd: m25p80: assign default read command
  mtd: nuc900_nand: remove redundant return value check of platform_get_resource()
  mtd: plat_nand: remove redundant return value check of platform_get_resource()
  mtd: nand: add Intel manufacturer ID
  mtd: nand: add SanDisk manufacturer ID
  mtd: nand: add support for Samsung K9LCG08U0B
  mtd: nand: pxa3xx: Add support for 2048 bytes page size devices
  mtd: m25p80: Use OPCODE_QUAD_READ_4B for 4-byte addressing
  mtd: nand: don't use {read,write}_buf for 8-bit transfers
  mtd: nand: use __packed shorthand
  mtd: nand: support Micron READ RETRY
  mtd: nand: add generic READ RETRY support
  mtd: nand: add ONFI vendor block for Micron
  mtd: nand: localize ECC failures per page
  ...
parents 268943fb 0ff76a92
* Texas Instruments Davinci NAND
This file provides information, what the device node for the
davinci nand interface contain.
Required properties:
- compatible: "ti,davinci-nand";
- reg : contain 2 offset/length values:
- offset and length for the access window
- offset and length for accessing the aemif control registers
- ti,davinci-chipselect: Indicates on the davinci_nand driver which
chipselect is used for accessing the nand.
Recommended properties :
- ti,davinci-mask-ale: mask for ale
- ti,davinci-mask-cle: mask for cle
- ti,davinci-mask-chipsel: mask for chipselect
- ti,davinci-ecc-mode: ECC mode valid values for davinci driver:
- "none"
- "soft"
- "hw"
- ti,davinci-ecc-bits: used ECC bits, currently supported 1 or 4.
- ti,davinci-nand-buswidth: buswidth 8 or 16
- ti,davinci-nand-use-bbt: use flash based bad block table support.
nand device bindings may contain additional sub-nodes describing
partitions of the address space. See partition.txt for more detail.
Example(da850 EVM ):
nand_cs3@62000000 {
compatible = "ti,davinci-nand";
reg = <0x62000000 0x807ff
0x68000000 0x8000>;
ti,davinci-chipselect = <1>;
ti,davinci-mask-ale = <0>;
ti,davinci-mask-cle = <0>;
ti,davinci-mask-chipsel = <0>;
ti,davinci-ecc-mode = "hw";
ti,davinci-ecc-bits = <4>;
ti,davinci-nand-use-bbt;
partition@180000 {
label = "ubifs";
reg = <0x180000 0x7e80000>;
};
};
Device tree bindings for Texas instruments Davinci/Keystone NAND controller
This file provides information, what the device node for the davinci/keystone
NAND interface contains.
Documentation:
Davinci DM646x - http://www.ti.com/lit/ug/sprueq7c/sprueq7c.pdf
Kestone - http://www.ti.com/lit/ug/sprugz3a/sprugz3a.pdf
Required properties:
- compatible: "ti,davinci-nand"
"ti,keystone-nand"
- reg: Contains 2 offset/length values:
- offset and length for the access window.
- offset and length for accessing the AEMIF
control registers.
- ti,davinci-chipselect: number of chipselect. Indicates on the
davinci_nand driver which chipselect is used
for accessing the nand.
Can be in the range [0-3].
Recommended properties :
- ti,davinci-mask-ale: mask for ALE. Needed for executing address
phase. These offset will be added to the base
address for the chip select space the NAND Flash
device is connected to.
If not set equal to 0x08.
- ti,davinci-mask-cle: mask for CLE. Needed for executing command
phase. These offset will be added to the base
address for the chip select space the NAND Flash
device is connected to.
If not set equal to 0x10.
- ti,davinci-mask-chipsel: mask for chipselect address. Needed to mask
addresses for given chipselect.
- nand-ecc-mode: operation mode of the NAND ecc mode. ECC mode
valid values for davinci driver:
- "none"
- "soft"
- "hw"
- ti,davinci-ecc-bits: used ECC bits, currently supported 1 or 4.
- nand-bus-width: buswidth 8 or 16. If not present 8.
- nand-on-flash-bbt: use flash based bad block table support. OOB
identifier is saved in OOB area. If not present
false.
Deprecated properties:
- ti,davinci-ecc-mode: operation mode of the NAND ecc mode. ECC mode
valid values for davinci driver:
- "none"
- "soft"
- "hw"
- ti,davinci-nand-buswidth: buswidth 8 or 16. If not present 8.
- ti,davinci-nand-use-bbt: use flash based bad block table support. OOB
identifier is saved in OOB area. If not present
false.
Nand device bindings may contain additional sub-nodes describing partitions of
the address space. See partition.txt for more detail. The NAND Flash timing
values must be programmed in the chip select’s node of AEMIF
memory-controller (see Documentation/devicetree/bindings/memory-controllers/
davinci-aemif.txt).
Example(da850 EVM ):
nand_cs3@62000000 {
compatible = "ti,davinci-nand";
reg = <0x62000000 0x807ff
0x68000000 0x8000>;
ti,davinci-chipselect = <1>;
ti,davinci-mask-ale = <0>;
ti,davinci-mask-cle = <0>;
ti,davinci-mask-chipsel = <0>;
nand-ecc-mode = "hw";
ti,davinci-ecc-bits = <4>;
nand-on-flash-bbt;
partition@180000 {
label = "ubifs";
reg = <0x180000 0x7e80000>;
};
};
......@@ -17,6 +17,14 @@ Required properties:
Optional properties:
- nand-on-flash-bbt: boolean to enable on flash bbt option if not
present false
- fsl,use-minimum-ecc: Protect this NAND flash with the minimum ECC
strength required. The required ECC strength is
automatically discoverable for some flash
(e.g., according to the ONFI standard).
However, note that if this strength is not
discoverable or this property is not enabled,
the software may chooses an implementation-defined
ECC scheme.
The device tree may optionally contain sub-nodes describing partitions of the
address space. See partition.txt for more detail.
......
......@@ -2,7 +2,9 @@ PXA3xx NAND DT bindings
Required properties:
- compatible: Should be "marvell,pxa3xx-nand"
- compatible: Should be set to one of the following:
marvell,pxa3xx-nand
marvell,armada370-nand
- reg: The register base for the controller
- interrupts: The interrupt to map
- #address-cells: Set to <1> if the node includes partitions
......@@ -13,6 +15,8 @@ Optional properties:
- marvell,nand-keep-config: Set to keep the NAND controller config as set
by the bootloader
- num-cs: Number of chipselect lines to usw
- nand-on-flash-bbt: boolean to enable on flash bbt option if
not present false
Example:
......
About this document
===================
Some notes about Marvell's NAND controller available in PXA and Armada 370/XP
SoC (aka NFCv1 and NFCv2), with an emphasis on the latter.
NFCv2 controller background
===========================
The controller has a 2176 bytes FIFO buffer. Therefore, in order to support
larger pages, I/O operations on 4 KiB and 8 KiB pages is done with a set of
chunked transfers.
For instance, if we choose a 2048 data chunk and set "BCH" ECC (see below)
we'll have this layout in the pages:
------------------------------------------------------------------------------
| 2048B data | 32B spare | 30B ECC || 2048B data | 32B spare | 30B ECC | ... |
------------------------------------------------------------------------------
The driver reads the data and spare portions independently and builds an internal
buffer with this layout (in the 4 KiB page case):
------------------------------------------
| 4096B data | 64B spare |
------------------------------------------
Also, for the READOOB command the driver disables the ECC and reads a 'spare + ECC'
OOB, one per chunk read.
-------------------------------------------------------------------
| 4096B data | 32B spare | 30B ECC | 32B spare | 30B ECC |
-------------------------------------------------------------------
So, in order to achieve reading (for instance), we issue several READ0 commands
(with some additional controller-specific magic) and read two chunks of 2080B
(2048 data + 32 spare) each.
The driver accommodates this data to expose the NAND core a contiguous buffer
(4096 data + spare) or (4096 + spare + ECC + spare + ECC).
ECC
===
The controller has built-in hardware ECC capabilities. In addition it is
configurable between two modes: 1) Hamming, 2) BCH.
Note that the actual BCH mode: BCH-4 or BCH-8 will depend on the way
the controller is configured to transfer the data.
In the BCH mode the ECC code will be calculated for each transfered chunk
and expected to be located (when reading/programming) right after the spare
bytes as the figure above shows.
So, repeating the above scheme, a 2048B data chunk will be followed by 32B
spare, and then the ECC controller will read/write the ECC code (30B in
this case):
------------------------------------
| 2048B data | 32B spare | 30B ECC |
------------------------------------
If the ECC mode is 'BCH' then the ECC is *always* 30 bytes long.
If the ECC mode is 'Hamming' the ECC is 6 bytes long, for each 512B block.
So in Hamming mode, a 2048B page will have a 24B ECC.
Despite all of the above, the controller requires the driver to only read or
write in multiples of 8-bytes, because the data buffer is 64-bits.
OOB
===
Because of the above scheme, and because the "spare" OOB is really located in
the middle of a page, spare OOB cannot be read or write independently of the
data area. In other words, in order to read the OOB (aka READOOB), the entire
page (aka READ0) has to be read.
In the same sense, in order to write to the spare OOB the driver has to write
an *entire* page.
Factory bad blocks handling
===========================
Given the ECC BCH requires to layout the device's pages in a split
data/OOB/data/OOB way, the controller has a view of the flash page that's
different from the specified (aka the manufacturer's) view. In other words,
Factory view:
-----------------------------------------------
| Data |x OOB |
-----------------------------------------------
Driver's view:
-----------------------------------------------
| Data | OOB | Data x | OOB |
-----------------------------------------------
It can be seen from the above, that the factory bad block marker must be
searched within the 'data' region, and not in the usual OOB region.
In addition, this means under regular usage the driver will write such
position (since it belongs to the data region) and every used block is
likely to be marked as bad.
For this reason, marking the block as bad in the OOB is explicitly
disabled by using the NAND_BBT_NO_OOB_BBM option in the driver. The rationale
for this is that there's no point in marking a block as bad, because good
blocks are also 'marked as bad' (in the OOB BBM sense) under normal usage.
Instead, the driver relies on the bad block table alone, and should only perform
the bad block scan on the very first time (when the device hasn't been used).
......@@ -5622,10 +5622,11 @@ F: mm/page_cgroup.c
MEMORY TECHNOLOGY DEVICES (MTD)
M: David Woodhouse <dwmw2@infradead.org>
M: Brian Norris <computersforpeace@gmail.com>
L: linux-mtd@lists.infradead.org
W: http://www.linux-mtd.infradead.org/
Q: http://patchwork.ozlabs.org/project/linux-mtd/list/
T: git git://git.infradead.org/mtd-2.6.git
T: git git://git.infradead.org/linux-mtd.git
S: Maintained
F: drivers/mtd/
F: include/linux/mtd/
......@@ -6942,6 +6943,12 @@ F: include/sound/pxa2xx-lib.h
F: sound/arm/pxa*
F: sound/soc/pxa/
PXA3xx NAND FLASH DRIVER
M: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
L: linux-mtd@lists.infradead.org
S: Maintained
F: drivers/mtd/nand/pxa3xx-nand.c
MMP SUPPORT
M: Eric Miao <eric.y.miao@gmail.com>
M: Haojian Zhuang <haojian.zhuang@gmail.com>
......
/* arch/arm/mach-s3c2410/include/mach/regs-nand.h
*
* Copyright (c) 2004-2005 Simtec Electronics <linux@simtec.co.uk>
* http://www.simtec.co.uk/products/SWLINUX/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* S3C2410 NAND register definitions
*/
#ifndef __ASM_ARM_REGS_NAND
#define __ASM_ARM_REGS_NAND
#define S3C2410_NFREG(x) (x)
#define S3C2410_NFCONF S3C2410_NFREG(0x00)
#define S3C2410_NFCMD S3C2410_NFREG(0x04)
#define S3C2410_NFADDR S3C2410_NFREG(0x08)
#define S3C2410_NFDATA S3C2410_NFREG(0x0C)
#define S3C2410_NFSTAT S3C2410_NFREG(0x10)
#define S3C2410_NFECC S3C2410_NFREG(0x14)
#define S3C2440_NFCONT S3C2410_NFREG(0x04)
#define S3C2440_NFCMD S3C2410_NFREG(0x08)
#define S3C2440_NFADDR S3C2410_NFREG(0x0C)
#define S3C2440_NFDATA S3C2410_NFREG(0x10)
#define S3C2440_NFECCD0 S3C2410_NFREG(0x14)
#define S3C2440_NFECCD1 S3C2410_NFREG(0x18)
#define S3C2440_NFECCD S3C2410_NFREG(0x1C)
#define S3C2440_NFSTAT S3C2410_NFREG(0x20)
#define S3C2440_NFESTAT0 S3C2410_NFREG(0x24)
#define S3C2440_NFESTAT1 S3C2410_NFREG(0x28)
#define S3C2440_NFMECC0 S3C2410_NFREG(0x2C)
#define S3C2440_NFMECC1 S3C2410_NFREG(0x30)
#define S3C2440_NFSECC S3C2410_NFREG(0x34)
#define S3C2440_NFSBLK S3C2410_NFREG(0x38)
#define S3C2440_NFEBLK S3C2410_NFREG(0x3C)
#define S3C2412_NFSBLK S3C2410_NFREG(0x20)
#define S3C2412_NFEBLK S3C2410_NFREG(0x24)
#define S3C2412_NFSTAT S3C2410_NFREG(0x28)
#define S3C2412_NFMECC_ERR0 S3C2410_NFREG(0x2C)
#define S3C2412_NFMECC_ERR1 S3C2410_NFREG(0x30)
#define S3C2412_NFMECC0 S3C2410_NFREG(0x34)
#define S3C2412_NFMECC1 S3C2410_NFREG(0x38)
#define S3C2412_NFSECC S3C2410_NFREG(0x3C)
#define S3C2410_NFCONF_EN (1<<15)
#define S3C2410_NFCONF_512BYTE (1<<14)
#define S3C2410_NFCONF_4STEP (1<<13)
#define S3C2410_NFCONF_INITECC (1<<12)
#define S3C2410_NFCONF_nFCE (1<<11)
#define S3C2410_NFCONF_TACLS(x) ((x)<<8)
#define S3C2410_NFCONF_TWRPH0(x) ((x)<<4)
#define S3C2410_NFCONF_TWRPH1(x) ((x)<<0)
#define S3C2410_NFSTAT_BUSY (1<<0)
#define S3C2440_NFCONF_BUSWIDTH_8 (0<<0)
#define S3C2440_NFCONF_BUSWIDTH_16 (1<<0)
#define S3C2440_NFCONF_ADVFLASH (1<<3)
#define S3C2440_NFCONF_TACLS(x) ((x)<<12)
#define S3C2440_NFCONF_TWRPH0(x) ((x)<<8)
#define S3C2440_NFCONF_TWRPH1(x) ((x)<<4)
#define S3C2440_NFCONT_LOCKTIGHT (1<<13)
#define S3C2440_NFCONT_SOFTLOCK (1<<12)
#define S3C2440_NFCONT_ILLEGALACC_EN (1<<10)
#define S3C2440_NFCONT_RNBINT_EN (1<<9)
#define S3C2440_NFCONT_RN_FALLING (1<<8)
#define S3C2440_NFCONT_SPARE_ECCLOCK (1<<6)
#define S3C2440_NFCONT_MAIN_ECCLOCK (1<<5)
#define S3C2440_NFCONT_INITECC (1<<4)
#define S3C2440_NFCONT_nFCE (1<<1)
#define S3C2440_NFCONT_ENABLE (1<<0)
#define S3C2440_NFSTAT_READY (1<<0)
#define S3C2440_NFSTAT_nCE (1<<1)
#define S3C2440_NFSTAT_RnB_CHANGE (1<<2)
#define S3C2440_NFSTAT_ILLEGAL_ACCESS (1<<3)
#define S3C2412_NFCONF_NANDBOOT (1<<31)
#define S3C2412_NFCONF_ECCCLKCON (1<<30)
#define S3C2412_NFCONF_ECC_MLC (1<<24)
#define S3C2412_NFCONF_TACLS_MASK (7<<12) /* 1 extra bit of Tacls */
#define S3C2412_NFCONT_ECC4_DIRWR (1<<18)
#define S3C2412_NFCONT_LOCKTIGHT (1<<17)
#define S3C2412_NFCONT_SOFTLOCK (1<<16)
#define S3C2412_NFCONT_ECC4_ENCINT (1<<13)
#define S3C2412_NFCONT_ECC4_DECINT (1<<12)
#define S3C2412_NFCONT_MAIN_ECC_LOCK (1<<7)
#define S3C2412_NFCONT_INIT_MAIN_ECC (1<<5)
#define S3C2412_NFCONT_nFCE1 (1<<2)
#define S3C2412_NFCONT_nFCE0 (1<<1)
#define S3C2412_NFSTAT_ECC_ENCDONE (1<<7)
#define S3C2412_NFSTAT_ECC_DECDONE (1<<6)
#define S3C2412_NFSTAT_ILLEGAL_ACCESS (1<<5)
#define S3C2412_NFSTAT_RnB_CHANGE (1<<4)
#define S3C2412_NFSTAT_nFCE1 (1<<3)
#define S3C2412_NFSTAT_nFCE0 (1<<2)
#define S3C2412_NFSTAT_Res1 (1<<1)
#define S3C2412_NFSTAT_READY (1<<0)
#define S3C2412_NFECCERR_SERRDATA(x) (((x) >> 21) & 0xf)
#define S3C2412_NFECCERR_SERRBIT(x) (((x) >> 18) & 0x7)
#define S3C2412_NFECCERR_MERRDATA(x) (((x) >> 7) & 0x3ff)
#define S3C2412_NFECCERR_MERRBIT(x) (((x) >> 4) & 0x7)
#define S3C2412_NFECCERR_SPARE_ERR(x) (((x) >> 2) & 0x3)
#define S3C2412_NFECCERR_MAIN_ERR(x) (((x) >> 2) & 0x3)
#define S3C2412_NFECCERR_NONE (0)
#define S3C2412_NFECCERR_1BIT (1)
#define S3C2412_NFECCERR_MULTIBIT (2)
#define S3C2412_NFECCERR_ECCAREA (3)
#endif /* __ASM_ARM_REGS_NAND */
......@@ -157,10 +157,11 @@ config MTD_BCM47XX_PARTS
comment "User Modules And Translation Layers"
#
# MTD block device support is select'ed if needed
#
config MTD_BLKDEVS
tristate "Common interface to block layer for MTD 'translation layers'"
depends on BLOCK
default n
tristate
config MTD_BLOCK
tristate "Caching block device access to MTD devices"
......
......@@ -264,7 +264,8 @@ static struct mtd_part_parser afs_parser = {
static int __init afs_parser_init(void)
{
return register_mtd_parser(&afs_parser);
register_mtd_parser(&afs_parser);
return 0;
}
static void __exit afs_parser_exit(void)
......
......@@ -139,7 +139,8 @@ static struct mtd_part_parser ar7_parser = {
static int __init ar7_parser_init(void)
{
return register_mtd_parser(&ar7_parser);
register_mtd_parser(&ar7_parser);
return 0;
}
static void __exit ar7_parser_exit(void)
......
......@@ -23,10 +23,12 @@
* Amount of bytes we read when analyzing each block of flash memory.
* Set it big enough to allow detecting partition and reading important data.
*/
#define BCM47XXPART_BYTES_TO_READ 0x404
#define BCM47XXPART_BYTES_TO_READ 0x4e8
/* Magics */
#define BOARD_DATA_MAGIC 0x5246504D /* MPFR */
#define BOARD_DATA_MAGIC2 0xBD0D0BBD
#define CFE_MAGIC 0x43464531 /* 1EFC */
#define FACTORY_MAGIC 0x59544346 /* FCTY */
#define POT_MAGIC1 0x54544f50 /* POTT */
#define POT_MAGIC2 0x504f /* OP */
......@@ -102,8 +104,9 @@ static int bcm47xxpart_parse(struct mtd_info *master,
continue;
}
/* CFE has small NVRAM at 0x400 */
if (buf[0x400 / 4] == NVRAM_HEADER) {
/* Magic or small NVRAM at 0x400 */
if ((buf[0x4e0 / 4] == CFE_MAGIC && buf[0x4e4 / 4] == CFE_MAGIC) ||
(buf[0x400 / 4] == NVRAM_HEADER)) {
bcm47xxpart_add_part(&parts[curr_part++], "boot",
offset, MTD_WRITEABLE);
continue;
......@@ -190,6 +193,21 @@ static int bcm47xxpart_parse(struct mtd_info *master,
offset, 0);
continue;
}
/* Read middle of the block */
if (mtd_read(master, offset + 0x8000, 0x4,
&bytes_read, (uint8_t *)buf) < 0) {
pr_err("mtd_read error while parsing (offset: 0x%X)!\n",
offset);
continue;
}
/* Some devices (ex. WNDR3700v3) don't have a standard 'MPFR' */
if (buf[0x000 / 4] == BOARD_DATA_MAGIC2) {
bcm47xxpart_add_part(&parts[curr_part++], "board_data",
offset, MTD_WRITEABLE);
continue;
}
}
/* Look for NVRAM at the end of the last block. */
......@@ -243,7 +261,8 @@ static struct mtd_part_parser bcm47xxpart_mtd_parser = {
static int __init bcm47xxpart_init(void)
{
return register_mtd_parser(&bcm47xxpart_mtd_parser);
register_mtd_parser(&bcm47xxpart_mtd_parser);
return 0;
}
static void __exit bcm47xxpart_exit(void)
......
......@@ -221,7 +221,8 @@ static struct mtd_part_parser bcm63xx_cfe_parser = {
static int __init bcm63xx_cfe_parser_init(void)
{
return register_mtd_parser(&bcm63xx_cfe_parser);
register_mtd_parser(&bcm63xx_cfe_parser);
return 0;
}
static void __exit bcm63xx_cfe_parser_exit(void)
......
......@@ -395,7 +395,8 @@ static int __init cmdline_parser_init(void)
{
if (mtdparts)
mtdpart_setup(mtdparts);
return register_mtd_parser(&cmdline_parser);
register_mtd_parser(&cmdline_parser);
return 0;
}
static void __exit cmdline_parser_exit(void)
......
......@@ -2047,21 +2047,21 @@ static int __init docg3_probe(struct platform_device *pdev)
ress = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!ress) {
dev_err(dev, "No I/O memory resource defined\n");
goto noress;
return ret;
}
base = ioremap(ress->start, DOC_IOSPACE_SIZE);
base = devm_ioremap(dev, ress->start, DOC_IOSPACE_SIZE);
ret = -ENOMEM;
cascade = kzalloc(sizeof(*cascade) * DOC_MAX_NBFLOORS,
GFP_KERNEL);
cascade = devm_kzalloc(dev, sizeof(*cascade) * DOC_MAX_NBFLOORS,
GFP_KERNEL);
if (!cascade)
goto nomem1;
return ret;
cascade->base = base;
mutex_init(&cascade->lock);
cascade->bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T,
DOC_ECC_BCH_PRIMPOLY);
if (!cascade->bch)
goto nomem2;
return ret;
for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) {
mtd = doc_probe_device(cascade, floor, dev);
......@@ -2101,11 +2101,6 @@ static int __init docg3_probe(struct platform_device *pdev)
for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++)
if (cascade->floors[floor])
doc_release_device(cascade->floors[floor]);
nomem2:
kfree(cascade);
nomem1:
iounmap(base);
noress:
return ret;
}
......@@ -2119,7 +2114,6 @@ static int __exit docg3_release(struct platform_device *pdev)
{
struct docg3_cascade *cascade = platform_get_drvdata(pdev);
struct docg3 *docg3 = cascade->floors[0]->priv;
void __iomem *base = cascade->base;
int floor;
doc_unregister_sysfs(pdev, cascade);
......@@ -2129,8 +2123,6 @@ static int __exit docg3_release(struct platform_device *pdev)
doc_release_device(cascade->floors[floor]);
free_bch(docg3->cascade->bch);
kfree(cascade);
iounmap(base);
return 0;
}
......
This diff is collapsed.
......@@ -205,7 +205,7 @@ static int __init ms02nv_init_one(ulong addr)
mtd->type = MTD_RAM;
mtd->flags = MTD_CAP_RAM;
mtd->size = fixsize;
mtd->name = (char *)ms02nv_name;
mtd->name = ms02nv_name;
mtd->owner = THIS_MODULE;
mtd->_read = ms02nv_read;
mtd->_write = ms02nv_write;
......
......@@ -669,7 +669,6 @@ static int add_dataflash_otp(struct spi_device *spi, char *name, int nr_pages,
if (!err)
return 0;
spi_set_drvdata(spi, NULL);
kfree(priv);
return err;
}
......@@ -899,10 +898,8 @@ static int dataflash_remove(struct spi_device *spi)
pr_debug("%s: remove\n", dev_name(&spi->dev));
status = mtd_device_unregister(&flash->mtd);
if (status == 0) {
spi_set_drvdata(spi, NULL);
if (status == 0)
kfree(flash);
}
return status;
}
......
......@@ -92,7 +92,7 @@ static void __exit cleanup_mtdram(void)
}
int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
unsigned long size, char *name)
unsigned long size, const char *name)
{
memset(mtd, 0, sizeof(*mtd));
......
......@@ -388,7 +388,7 @@ static void put_chip(struct map_info *map, struct flchip *chip)
wake_up(&chip->wq);
}
int do_write_buffer(struct map_info *map, struct flchip *chip,
static int do_write_buffer(struct map_info *map, struct flchip *chip,
unsigned long adr, const struct kvec **pvec,
unsigned long *pvec_seek, int len)
{
......@@ -469,7 +469,7 @@ int do_write_buffer(struct map_info *map, struct flchip *chip,
return ret;
}
int do_erase_oneblock(struct mtd_info *mtd, loff_t adr)
static int do_erase_oneblock(struct mtd_info *mtd, loff_t adr)
{
struct map_info *map = mtd->priv;
struct lpddr_private *lpddr = map->fldrv_priv;
......@@ -748,34 +748,6 @@ static int lpddr_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len)
return do_xxlock(mtd, ofs, len, DO_XXLOCK_UNLOCK);
}
int word_program(struct map_info *map, loff_t adr, uint32_t curval)
{
int ret;
struct lpddr_private *lpddr = map->fldrv_priv;
int chipnum = adr >> lpddr->chipshift;
struct flchip *chip = &lpddr->chips[chipnum];
mutex_lock(&chip->mutex);
ret = get_chip(map, chip, FL_WRITING);
if (ret) {
mutex_unlock(&chip->mutex);
return ret;
}
send_pfow_command(map, LPDDR_WORD_PROGRAM, adr, 0x00, (map_word *)&curval);
ret = wait_for_ready(map, chip, (1<<lpddr->qinfo->SingleWordProgTime));
if (ret) {
printk(KERN_WARNING"%s word_program error at: %llx; val: %x\n",
map->name, adr, curval);
goto out;
}
out: put_chip(map, chip);
mutex_unlock(&chip->mutex);
return ret;
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Alexey Korolev <akorolev@infradead.org>");
MODULE_DESCRIPTION("MTD driver for LPDDR flash chips");
......@@ -13,6 +13,7 @@
*
*/
#include <linux/err.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/init.h>
......@@ -162,13 +163,6 @@ static int ixp4xx_flash_remove(struct platform_device *dev)
mtd_device_unregister(info->mtd);
map_destroy(info->mtd);
}
if (info->map.virt)
iounmap(info->map.virt);
if (info->res) {
release_resource(info->res);
kfree(info->res);
}
if (plat->exit)
plat->exit();
......@@ -194,7 +188,8 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
return err;
}
info = kzalloc(sizeof(struct ixp4xx_flash_info), GFP_KERNEL);
info = devm_kzalloc(&dev->dev, sizeof(struct ixp4xx_flash_info),
GFP_KERNEL);
if(!info) {
err = -ENOMEM;
goto Error;
......@@ -220,20 +215,9 @@ static int ixp4xx_flash_probe(struct platform_device *dev)
info->map.write = ixp4xx_probe_write16;
info->map.copy_from = ixp4xx_copy_from;
info->res = request_mem_region(dev->resource->start,
resource_size(dev->resource),
"IXP4XXFlash");
if (!info->res) {
printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n");
err = -ENOMEM;
goto Error;
}
info->map.virt = ioremap(dev->resource->start,
resource_size(dev->resource));
if (!info->map.virt) {
printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n");
err = -EIO;
info->map.virt = devm_ioremap_resource(&dev->dev, dev->resource);
if (IS_ERR(info->map.virt)) {
err = PTR_ERR(info->map.virt);
goto Error;
}
......
......@@ -123,24 +123,28 @@ ltq_mtd_probe(struct platform_device *pdev)
return -ENODEV;
}
ltq_mtd = kzalloc(sizeof(struct ltq_mtd), GFP_KERNEL);
ltq_mtd = devm_kzalloc(&pdev->dev, sizeof(struct ltq_mtd), GFP_KERNEL);
if (!ltq_mtd)
return -ENOMEM;
platform_set_drvdata(pdev, ltq_mtd);
ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!ltq_mtd->res) {
dev_err(&pdev->dev, "failed to get memory resource\n");
err = -ENOENT;
goto err_out;
return -ENOENT;
}
ltq_mtd->map = kzalloc(sizeof(struct map_info), GFP_KERNEL);
ltq_mtd->map = devm_kzalloc(&pdev->dev, sizeof(struct map_info),
GFP_KERNEL);
if (!ltq_mtd->map)
return -ENOMEM;
ltq_mtd->map->phys = ltq_mtd->res->start;
ltq_mtd->map->size = resource_size(ltq_mtd->res);
ltq_mtd->map->virt = devm_ioremap_resource(&pdev->dev, ltq_mtd->res);
if (IS_ERR(ltq_mtd->map->virt)) {
err = PTR_ERR(ltq_mtd->map->virt);
goto err_out;
}
if (IS_ERR(ltq_mtd->map->virt))
return PTR_ERR(ltq_mtd->map->virt);
ltq_mtd->map->name = ltq_map_name;
ltq_mtd->map->bankwidth = 2;
......@@ -155,8 +159,7 @@ ltq_mtd_probe(struct platform_device *pdev)
if (!ltq_mtd->mtd) {
dev_err(&pdev->dev, "probing failed\n");
err = -ENXIO;
goto err_free;
return -ENXIO;
}
ltq_mtd->mtd->owner = THIS_MODULE;
......@@ -177,10 +180,6 @@ ltq_mtd_probe(struct platform_device *pdev)
err_destroy:
map_destroy(ltq_mtd->mtd);
err_free:
kfree(ltq_mtd->map);
err_out:
kfree(ltq_mtd);
return err;
}
......@@ -189,13 +188,9 @@ ltq_mtd_remove(struct platform_device *pdev)
{
struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev);
if (ltq_mtd) {
if (ltq_mtd->mtd) {
mtd_device_unregister(ltq_mtd->mtd);
map_destroy(ltq_mtd->mtd);
}
kfree(ltq_mtd->map);
kfree(ltq_mtd);
if (ltq_mtd && ltq_mtd->mtd) {
mtd_device_unregister(ltq_mtd->mtd);
map_destroy(ltq_mtd->mtd);
}
return 0;
}
......
......@@ -61,7 +61,7 @@ static int pxa2xx_flash_probe(struct platform_device *pdev)
if (!info)
return -ENOMEM;
info->map.name = (char *) flash->name;
info->map.name = flash->name;
info->map.bankwidth = flash->width;
info->map.phys = res->start;
info->map.size = resource_size(res);
......
......@@ -75,7 +75,7 @@ int uflash_devinit(struct platform_device *op, struct device_node *dp)
up->name = of_get_property(dp, "model", NULL);
if (up->name && 0 < strlen(up->name))
up->map.name = (char *)up->name;
up->map.name = up->name;
up->map.phys = op->resource[0].start;
......
......@@ -313,15 +313,7 @@ static struct attribute *mtd_attrs[] = {
&dev_attr_bitflip_threshold.attr,
NULL,
};
static struct attribute_group mtd_group = {
.attrs = mtd_attrs,
};
static const struct attribute_group *mtd_groups[] = {
&mtd_group,
NULL,
};
ATTRIBUTE_GROUPS(mtd);
static struct device_type mtd_devtype = {
.name = "mtd",
......
......@@ -534,7 +534,7 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
return slave;
}
int mtd_add_partition(struct mtd_info *master, char *name,
int mtd_add_partition(struct mtd_info *master, const char *name,
long long offset, long long length)
{
struct mtd_partition part;
......@@ -672,22 +672,19 @@ static struct mtd_part_parser *get_partition_parser(const char *name)
#define put_partition_parser(p) do { module_put((p)->owner); } while (0)
int register_mtd_parser(struct mtd_part_parser *p)
void register_mtd_parser(struct mtd_part_parser *p)
{
spin_lock(&part_parser_lock);
list_add(&p->list, &part_parsers);
spin_unlock(&part_parser_lock);
return 0;
}
EXPORT_SYMBOL_GPL(register_mtd_parser);
int deregister_mtd_parser(struct mtd_part_parser *p)
void deregister_mtd_parser(struct mtd_part_parser *p)
{
spin_lock(&part_parser_lock);
list_del(&p->list);
spin_unlock(&part_parser_lock);
return 0;
}
EXPORT_SYMBOL_GPL(deregister_mtd_parser);
......
......@@ -95,7 +95,7 @@ config MTD_NAND_OMAP2
platforms.
config MTD_NAND_OMAP_BCH
depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3
depends on MTD_NAND_OMAP2
tristate "Support hardware based BCH error correction"
default n
select BCH
......@@ -326,11 +326,11 @@ config MTD_NAND_ATMEL
on Atmel AT91 and AVR32 processors.
config MTD_NAND_PXA3xx
tristate "Support for NAND flash devices on PXA3xx"
tristate "NAND support on PXA3xx and Armada 370/XP"
depends on PXA3xx || ARCH_MMP || PLAT_ORION
help
This enables the driver for the NAND flash device found on
PXA3xx processors
PXA3xx processors (NFCv1) and also on Armada 370/XP (NFCv2).
config MTD_NAND_SLC_LPC32XX
tristate "NXP LPC32xx SLC Controller"
......@@ -458,17 +458,17 @@ config MTD_NAND_MXC
config MTD_NAND_SH_FLCTL
tristate "Support for NAND on Renesas SuperH FLCTL"
depends on SUPERH || ARCH_SHMOBILE
depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST
help
Several Renesas SuperH CPU has FLCTL. This option enables support
for NAND Flash using FLCTL.
config MTD_NAND_DAVINCI
tristate "Support NAND on DaVinci SoC"
depends on ARCH_DAVINCI
tristate "Support NAND on DaVinci/Keystone SoC"
depends on ARCH_DAVINCI || (ARCH_KEYSTONE && TI_AEMIF)
help
Enable the driver for NAND flash chips on Texas Instruments
DaVinci processors.
DaVinci/Keystone processors.
config MTD_NAND_TXX9NDFMC
tristate "NAND Flash support for TXx9 SoC"
......
......@@ -1961,10 +1961,8 @@ static int atmel_nand_probe(struct platform_device *pdev)
/* Allocate memory for the device structure (and zero it) */
host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
if (!host) {
printk(KERN_ERR "atmel_nand: failed to allocate device structure.\n");
if (!host)
return -ENOMEM;
}
res = platform_driver_register(&atmel_nand_nfc_driver);
if (res)
......@@ -2062,14 +2060,14 @@ static int atmel_nand_probe(struct platform_device *pdev)
}
if (gpio_get_value(host->board.det_pin)) {
printk(KERN_INFO "No SmartMedia card inserted.\n");
dev_info(&pdev->dev, "No SmartMedia card inserted.\n");
res = -ENXIO;
goto err_no_card;
}
}
if (host->board.on_flash_bbt || on_flash_bbt) {
printk(KERN_INFO "atmel_nand: Use On Flash BBT\n");
dev_info(&pdev->dev, "Use On Flash BBT\n");
nand_chip->bbt_options |= NAND_BBT_USE_FLASH;
}
......
......@@ -418,10 +418,8 @@ static int au1550nd_probe(struct platform_device *pdev)
}
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx) {
dev_err(&pdev->dev, "no memory for NAND context\n");
if (!ctx)
return -ENOMEM;
}
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
......@@ -480,6 +478,8 @@ static int au1550nd_probe(struct platform_device *pdev)
mtd_device_register(&ctx->info, pd->parts, pd->num_parts);
platform_set_drvdata(pdev, ctx);
return 0;
out3:
......
......@@ -745,7 +745,6 @@ static int bf5xx_nand_probe(struct platform_device *pdev)
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (info == NULL) {
dev_err(&pdev->dev, "no memory for flash info\n");
err = -ENOMEM;
goto out_err_kzalloc;
}
......
......@@ -640,10 +640,8 @@ static int cafe_nand_probe(struct pci_dev *pdev,
pci_set_master(pdev);
mtd = kzalloc(sizeof(*mtd) + sizeof(struct cafe_priv), GFP_KERNEL);
if (!mtd) {
dev_warn(&pdev->dev, "failed to alloc mtd_info\n");
if (!mtd)
return -ENOMEM;
}
cafe = (void *)(&mtd[1]);
mtd->dev.parent = &pdev->dev;
......
......@@ -164,7 +164,6 @@ static int __init cmx270_init(void)
sizeof(struct nand_chip),
GFP_KERNEL);
if (!cmx270_nand_mtd) {
pr_debug("Unable to allocate CM-X270 NAND MTD device structure.\n");
ret = -ENOMEM;
goto err_kzalloc;
}
......
......@@ -199,7 +199,6 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr)
/* Allocate memory for MTD device structure and private data */
new_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
if (!new_mtd) {
printk(KERN_WARNING "Unable to allocate CS553X NAND MTD device structure.\n");
err = -ENOMEM;
goto out;
}
......
......@@ -35,6 +35,7 @@
#include <linux/slab.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/of_mtd.h>
#include <linux/platform_data/mtd-davinci.h>
#include <linux/platform_data/mtd-davinci-aemif.h>
......@@ -487,7 +488,7 @@ static int nand_davinci_dev_ready(struct mtd_info *mtd)
* ten ECC bytes plus the manufacturer's bad block marker byte, and
* and not overlapping the default BBT markers.
*/
static struct nand_ecclayout hwecc4_small __initconst = {
static struct nand_ecclayout hwecc4_small = {
.eccbytes = 10,
.eccpos = { 0, 1, 2, 3, 4,
/* offset 5 holds the badblock marker */
......@@ -503,7 +504,7 @@ static struct nand_ecclayout hwecc4_small __initconst = {
* storing ten ECC bytes plus the manufacturer's bad block marker byte,
* and not overlapping the default BBT markers.
*/
static struct nand_ecclayout hwecc4_2048 __initconst = {
static struct nand_ecclayout hwecc4_2048 = {
.eccbytes = 40,
.eccpos = {
/* at the end of spare sector */
......@@ -534,17 +535,19 @@ static struct davinci_nand_pdata
struct davinci_nand_pdata *pdata;
const char *mode;
u32 prop;
int len;
pdata = devm_kzalloc(&pdev->dev,
sizeof(struct davinci_nand_pdata),
GFP_KERNEL);
pdev->dev.platform_data = pdata;
if (!pdata)
return NULL;
return ERR_PTR(-ENOMEM);
if (!of_property_read_u32(pdev->dev.of_node,
"ti,davinci-chipselect", &prop))
pdev->id = prop;
else
return ERR_PTR(-EINVAL);
if (!of_property_read_u32(pdev->dev.of_node,
"ti,davinci-mask-ale", &prop))
pdata->mask_ale = prop;
......@@ -555,6 +558,8 @@ static struct davinci_nand_pdata
"ti,davinci-mask-chipsel", &prop))
pdata->mask_chipsel = prop;
if (!of_property_read_string(pdev->dev.of_node,
"nand-ecc-mode", &mode) ||
!of_property_read_string(pdev->dev.of_node,
"ti,davinci-ecc-mode", &mode)) {
if (!strncmp("none", mode, 4))
pdata->ecc_mode = NAND_ECC_NONE;
......@@ -566,12 +571,16 @@ static struct davinci_nand_pdata
if (!of_property_read_u32(pdev->dev.of_node,
"ti,davinci-ecc-bits", &prop))
pdata->ecc_bits = prop;
if (!of_property_read_u32(pdev->dev.of_node,
prop = of_get_nand_bus_width(pdev->dev.of_node);
if (0 < prop || !of_property_read_u32(pdev->dev.of_node,
"ti,davinci-nand-buswidth", &prop))
if (prop == 16)
pdata->options |= NAND_BUSWIDTH_16;
if (of_find_property(pdev->dev.of_node,
"ti,davinci-nand-use-bbt", &len))
if (of_property_read_bool(pdev->dev.of_node,
"nand-on-flash-bbt") ||
of_property_read_bool(pdev->dev.of_node,
"ti,davinci-nand-use-bbt"))
pdata->bbt_options = NAND_BBT_USE_FLASH;
}
......@@ -585,7 +594,7 @@ static struct davinci_nand_pdata
}
#endif
static int __init nand_davinci_probe(struct platform_device *pdev)
static int nand_davinci_probe(struct platform_device *pdev)
{
struct davinci_nand_pdata *pdata;
struct davinci_nand_info *info;
......@@ -598,6 +607,9 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
nand_ecc_modes_t ecc_mode;
pdata = nand_davinci_get_pdata(pdev);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
/* insist on board-specific configuration */
if (!pdata)
return -ENODEV;
......@@ -607,11 +619,8 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
return -ENODEV;
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (!info) {
dev_err(&pdev->dev, "unable to allocate memory\n");
ret = -ENOMEM;
goto err_nomem;
}
if (!info)
return -ENOMEM;
platform_set_drvdata(pdev, info);
......@@ -619,19 +628,23 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
if (!res1 || !res2) {
dev_err(&pdev->dev, "resource missing\n");
ret = -EINVAL;
goto err_nomem;
return -EINVAL;
}
vaddr = devm_ioremap_resource(&pdev->dev, res1);
if (IS_ERR(vaddr)) {
ret = PTR_ERR(vaddr);
goto err_ioremap;
}
base = devm_ioremap_resource(&pdev->dev, res2);
if (IS_ERR(base)) {
ret = PTR_ERR(base);
goto err_ioremap;
if (IS_ERR(vaddr))
return PTR_ERR(vaddr);
/*
* This registers range is used to setup NAND settings. In case with
* TI AEMIF driver, the same memory address range is requested already
* by AEMIF, so we cannot request it twice, just ioremap.
* The AEMIF and NAND drivers not use the same registers in this range.
*/
base = devm_ioremap(&pdev->dev, res2->start, resource_size(res2));
if (!base) {
dev_err(&pdev->dev, "ioremap failed for resource %pR\n", res2);
return -EADDRNOTAVAIL;
}
info->dev = &pdev->dev;
......@@ -699,7 +712,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
spin_unlock_irq(&davinci_nand_lock);
if (ret == -EBUSY)
goto err_ecc;
return ret;
info->chip.ecc.calculate = nand_davinci_calculate_4bit;
info->chip.ecc.correct = nand_davinci_correct_4bit;
......@@ -715,8 +728,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
info->chip.ecc.strength = pdata->ecc_bits;
break;
default:
ret = -EINVAL;
goto err_ecc;
return -EINVAL;
}
info->chip.ecc.mode = ecc_mode;
......@@ -724,7 +736,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
if (IS_ERR(info->clk)) {
ret = PTR_ERR(info->clk);
dev_dbg(&pdev->dev, "unable to get AEMIF clock, err %d\n", ret);
goto err_clk;
return ret;
}
ret = clk_prepare_enable(info->clk);
......@@ -753,7 +765,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
info->core_chipsel);
if (ret < 0) {
dev_dbg(&pdev->dev, "NAND timing values setup fail\n");
goto err_timing;
goto err;
}
spin_lock_irq(&davinci_nand_lock);
......@@ -769,7 +781,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
ret = nand_scan_ident(&info->mtd, pdata->mask_chipsel ? 2 : 1, NULL);
if (ret < 0) {
dev_dbg(&pdev->dev, "no NAND chip(s) found\n");
goto err_scan;
goto err;
}
/* Update ECC layout if needed ... for 1-bit HW ECC, the default
......@@ -783,7 +795,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
if (!chunks || info->mtd.oobsize < 16) {
dev_dbg(&pdev->dev, "too small\n");
ret = -EINVAL;
goto err_scan;
goto err;
}
/* For small page chips, preserve the manufacturer's
......@@ -814,7 +826,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
dev_warn(&pdev->dev, "no 4-bit ECC support yet "
"for 4KiB-page NAND\n");
ret = -EIO;
goto err_scan;
goto err;
syndrome_done:
info->chip.ecc.layout = &info->ecclayout;
......@@ -822,7 +834,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
ret = nand_scan_tail(&info->mtd);
if (ret < 0)
goto err_scan;
goto err;
if (pdata->parts)
ret = mtd_device_parse_register(&info->mtd, NULL, NULL,
......@@ -835,7 +847,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
NULL, 0);
}
if (ret < 0)
goto err_scan;
goto err;
val = davinci_nand_readl(info, NRCSR_OFFSET);
dev_info(&pdev->dev, "controller rev. %d.%d\n",
......@@ -843,8 +855,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
return 0;
err_scan:
err_timing:
err:
clk_disable_unprepare(info->clk);
err_clk_enable:
......@@ -852,15 +863,10 @@ static int __init nand_davinci_probe(struct platform_device *pdev)
if (ecc_mode == NAND_ECC_HW_SYNDROME)
ecc4_busy = false;
spin_unlock_irq(&davinci_nand_lock);
err_ecc:
err_clk:
err_ioremap:
err_nomem:
return ret;
}
static int __exit nand_davinci_remove(struct platform_device *pdev)
static int nand_davinci_remove(struct platform_device *pdev)
{
struct davinci_nand_info *info = platform_get_drvdata(pdev);
......@@ -877,7 +883,8 @@ static int __exit nand_davinci_remove(struct platform_device *pdev)
}
static struct platform_driver nand_davinci_driver = {
.remove = __exit_p(nand_davinci_remove),
.probe = nand_davinci_probe,
.remove = nand_davinci_remove,
.driver = {
.name = "davinci_nand",
.owner = THIS_MODULE,
......@@ -886,7 +893,7 @@ static struct platform_driver nand_davinci_driver = {
};
MODULE_ALIAS("platform:davinci_nand");
module_platform_driver_probe(nand_davinci_driver, nand_davinci_probe);
module_platform_driver(nand_davinci_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Texas Instruments");
......
......@@ -125,7 +125,6 @@ static void reset_buf(struct denali_nand_info *denali)
static void write_byte_to_buf(struct denali_nand_info *denali, uint8_t byte)
{
BUG_ON(denali->buf.tail >= sizeof(denali->buf.buf));
denali->buf.buf[denali->buf.tail++] = byte;
}
......@@ -897,7 +896,7 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t *buf, int page)
/* this function examines buffers to see if they contain data that
* indicate that the buffer is part of an erased region of flash.
*/
bool is_erased(uint8_t *buf, int len)
static bool is_erased(uint8_t *buf, int len)
{
int i = 0;
for (i = 0; i < len; i++)
......@@ -1429,20 +1428,12 @@ int denali_init(struct denali_nand_info *denali)
}
}
/* Is 32-bit DMA supported? */
ret = dma_set_mask(denali->dev, DMA_BIT_MASK(32));
if (ret) {
pr_err("Spectra: no usable DMA configuration\n");
return ret;
}
denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf,
DENALI_BUF_SIZE,
DMA_BIDIRECTIONAL);
/* allocate a temporary buffer for nand_scan_ident() */
denali->buf.buf = devm_kzalloc(denali->dev, PAGE_SIZE,
GFP_DMA | GFP_KERNEL);
if (!denali->buf.buf)
return -ENOMEM;
if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) {
dev_err(denali->dev, "Spectra: failed to map DMA buffer\n");
return -EIO;
}
denali->mtd.dev.parent = denali->dev;
denali_hw_init(denali);
denali_drv_init(denali);
......@@ -1475,12 +1466,29 @@ int denali_init(struct denali_nand_info *denali)
goto failed_req_irq;
}
/* MTD supported page sizes vary by kernel. We validate our
* kernel supports the device here.
*/
if (denali->mtd.writesize > NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) {
ret = -ENODEV;
pr_err("Spectra: device size not supported by this version of MTD.");
/* allocate the right size buffer now */
devm_kfree(denali->dev, denali->buf.buf);
denali->buf.buf = devm_kzalloc(denali->dev,
denali->mtd.writesize + denali->mtd.oobsize,
GFP_KERNEL);
if (!denali->buf.buf) {
ret = -ENOMEM;
goto failed_req_irq;
}
/* Is 32-bit DMA supported? */
ret = dma_set_mask(denali->dev, DMA_BIT_MASK(32));
if (ret) {
pr_err("Spectra: no usable DMA configuration\n");
goto failed_req_irq;
}
denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf,
denali->mtd.writesize + denali->mtd.oobsize,
DMA_BIDIRECTIONAL);
if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) {
dev_err(denali->dev, "Spectra: failed to map DMA buffer\n");
ret = -EIO;
goto failed_req_irq;
}
......@@ -1602,7 +1610,8 @@ EXPORT_SYMBOL(denali_init);
void denali_remove(struct denali_nand_info *denali)
{
denali_irq_cleanup(denali->irq, denali);
dma_unmap_single(denali->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
dma_unmap_single(denali->dev, denali->buf.dma_buf,
denali->mtd.writesize + denali->mtd.oobsize,
DMA_BIDIRECTIONAL);
}
EXPORT_SYMBOL(denali_remove);
......@@ -455,12 +455,10 @@
#define ECC_SECTOR_SIZE 512
#define DENALI_BUF_SIZE (NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE)
struct nand_buf {
int head;
int tail;
uint8_t buf[DENALI_BUF_SIZE];
uint8_t *buf;
dma_addr_t dma_buf;
};
......
......@@ -108,7 +108,7 @@ static int denali_dt_probe(struct platform_device *ofdev)
denali->dev->dma_mask = NULL;
}
dt->clk = clk_get(&ofdev->dev, NULL);
dt->clk = devm_clk_get(&ofdev->dev, NULL);
if (IS_ERR(dt->clk)) {
dev_err(&ofdev->dev, "no clk available\n");
return PTR_ERR(dt->clk);
......@@ -124,7 +124,6 @@ static int denali_dt_probe(struct platform_device *ofdev)
out_disable_clk:
clk_disable_unprepare(dt->clk);
clk_put(dt->clk);
return ret;
}
......@@ -135,7 +134,6 @@ static int denali_dt_remove(struct platform_device *ofdev)
denali_remove(&dt->denali);
clk_disable(dt->clk);
clk_put(dt->clk);
return 0;
}
......
......@@ -21,7 +21,7 @@
#define DENALI_NAND_NAME "denali-nand-pci"
/* List of platforms this NAND controller has be integrated into */
static DEFINE_PCI_DEVICE_TABLE(denali_pci_ids) = {
static const struct pci_device_id denali_pci_ids[] = {
{ PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 },
{ PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST },
{ /* end: all zeroes */ }
......@@ -131,7 +131,6 @@ static struct pci_driver denali_pci_driver = {
static int denali_init_pci(void)
{
pr_info("Spectra MTD driver built on %s @ %s\n", __DATE__, __TIME__);
return pci_register_driver(&denali_pci_driver);
}
module_init(denali_init_pci);
......
......@@ -1058,7 +1058,6 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partitio
buf = kmalloc(mtd->writesize, GFP_KERNEL);
if (!buf) {
printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n");
return 0;
}
if (!(numheaders = find_media_headers(mtd, buf, "ANAND", 1)))
......@@ -1166,7 +1165,6 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partiti
buf = kmalloc(mtd->writesize, GFP_KERNEL);
if (!buf) {
printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n");
return 0;
}
......@@ -1440,10 +1438,13 @@ static int __init doc_probe(unsigned long physadr)
int reg, len, numchips;
int ret = 0;
if (!request_mem_region(physadr, DOC_IOREMAP_LEN, NULL))
return -EBUSY;
virtadr = ioremap(physadr, DOC_IOREMAP_LEN);
if (!virtadr) {
printk(KERN_ERR "Diskonchip ioremap failed: 0x%x bytes at 0x%lx\n", DOC_IOREMAP_LEN, physadr);
return -EIO;
ret = -EIO;
goto error_ioremap;
}
/* It's not possible to cleanly detect the DiskOnChip - the
......@@ -1561,7 +1562,6 @@ static int __init doc_probe(unsigned long physadr)
sizeof(struct nand_chip) + sizeof(struct doc_priv) + (2 * sizeof(struct nand_bbt_descr));
mtd = kzalloc(len, GFP_KERNEL);
if (!mtd) {
printk(KERN_ERR "DiskOnChip kmalloc (%d bytes) failed!\n", len);
ret = -ENOMEM;
goto fail;
}
......@@ -1629,6 +1629,10 @@ static int __init doc_probe(unsigned long physadr)
WriteDOC(save_control, virtadr, DOCControl);
fail:
iounmap(virtadr);
error_ioremap:
release_mem_region(physadr, DOC_IOREMAP_LEN);
return ret;
}
......@@ -1645,6 +1649,7 @@ static void release_nanddoc(void)
nextmtd = doc->nextdoc;
nand_release(mtd);
iounmap(doc->virtadr);
release_mem_region(doc->physadr, DOC_IOREMAP_LEN);
kfree(mtd);
}
}
......
......@@ -847,7 +847,6 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev)
if (!fsl_lbc_ctrl_dev->nand) {
elbc_fcm_ctrl = kzalloc(sizeof(*elbc_fcm_ctrl), GFP_KERNEL);
if (!elbc_fcm_ctrl) {
dev_err(dev, "failed to allocate memory\n");
mutex_unlock(&fsl_elbc_nand_mutex);
ret = -ENOMEM;
goto err;
......@@ -875,7 +874,7 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev)
goto err;
}
priv->mtd.name = kasprintf(GFP_KERNEL, "%x.flash", (unsigned)res.start);
priv->mtd.name = kasprintf(GFP_KERNEL, "%llx.flash", (u64)res.start);
if (!priv->mtd.name) {
ret = -ENOMEM;
goto err;
......
......@@ -1060,7 +1060,6 @@ static int fsl_ifc_nand_probe(struct platform_device *dev)
if (!fsl_ifc_ctrl_dev->nand) {
ifc_nand_ctrl = kzalloc(sizeof(*ifc_nand_ctrl), GFP_KERNEL);
if (!ifc_nand_ctrl) {
dev_err(&dev->dev, "failed to allocate memory\n");
mutex_unlock(&fsl_ifc_nand_mutex);
return -ENOMEM;
}
......@@ -1101,7 +1100,7 @@ static int fsl_ifc_nand_probe(struct platform_device *dev)
IFC_NAND_EVTER_INTR_FTOERIR_EN |
IFC_NAND_EVTER_INTR_WPERIR_EN,
&ifc->ifc_nand.nand_evter_intr_en);
priv->mtd.name = kasprintf(GFP_KERNEL, "%x.flash", (unsigned)res.start);
priv->mtd.name = kasprintf(GFP_KERNEL, "%llx.flash", (u64)res.start);
if (!priv->mtd.name) {
ret = -ENOMEM;
goto err;
......
......@@ -889,10 +889,8 @@ static int fsmc_nand_probe_config_dt(struct platform_device *pdev,
pdata->nand_timings = devm_kzalloc(&pdev->dev,
sizeof(*pdata->nand_timings), GFP_KERNEL);
if (!pdata->nand_timings) {
dev_err(&pdev->dev, "no memory for nand_timing\n");
if (!pdata->nand_timings)
return -ENOMEM;
}
of_property_read_u8_array(np, "timings", (u8 *)pdata->nand_timings,
sizeof(*pdata->nand_timings));
......@@ -950,10 +948,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
/* Allocate memory for the device structure (and zero it) */
host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
if (!host) {
dev_err(&pdev->dev, "failed to allocate device structure\n");
if (!host)
return -ENOMEM;
}
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data");
host->data_va = devm_ioremap_resource(&pdev->dev, res);
......@@ -1108,8 +1104,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
host->ecc_place = &fsmc_ecc4_lp_place;
break;
default:
printk(KERN_WARNING "No oob scheme defined for "
"oobsize %d\n", mtd->oobsize);
dev_warn(&pdev->dev, "No oob scheme defined for oobsize %d\n",
mtd->oobsize);
BUG();
}
} else {
......@@ -1124,8 +1120,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
nand->ecc.layout = &fsmc_ecc1_128_layout;
break;
default:
printk(KERN_WARNING "No oob scheme defined for "
"oobsize %d\n", mtd->oobsize);
dev_warn(&pdev->dev, "No oob scheme defined for oobsize %d\n",
mtd->oobsize);
BUG();
}
}
......
......@@ -132,13 +132,17 @@ static int gpio_nand_get_config_of(const struct device *dev,
static struct resource *gpio_nand_get_io_sync_of(struct platform_device *pdev)
{
struct resource *r = devm_kzalloc(&pdev->dev, sizeof(*r), GFP_KERNEL);
struct resource *r;
u64 addr;
if (!r || of_property_read_u64(pdev->dev.of_node,
if (of_property_read_u64(pdev->dev.of_node,
"gpio-control-nand,io-sync-reg", &addr))
return NULL;
r = devm_kzalloc(&pdev->dev, sizeof(*r), GFP_KERNEL);
if (!r)
return NULL;
r->start = addr;
r->end = r->start + 0x3;
r->flags = IORESOURCE_MEM;
......@@ -211,10 +215,8 @@ static int gpio_nand_probe(struct platform_device *pdev)
return -EINVAL;
gpiomtd = devm_kzalloc(&pdev->dev, sizeof(*gpiomtd), GFP_KERNEL);
if (!gpiomtd) {
dev_err(&pdev->dev, "failed to create NAND MTD\n");
if (!gpiomtd)
return -ENOMEM;
}
chip = &gpiomtd->nand_chip;
......
......@@ -20,6 +20,7 @@
*/
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/slab.h>
#include "gpmi-nand.h"
#include "gpmi-regs.h"
......@@ -207,30 +208,41 @@ void gpmi_dump_info(struct gpmi_nand_data *this)
u32 reg;
int i;
pr_err("Show GPMI registers :\n");
dev_err(this->dev, "Show GPMI registers :\n");
for (i = 0; i <= HW_GPMI_DEBUG / 0x10 + 1; i++) {
reg = readl(r->gpmi_regs + i * 0x10);
pr_err("offset 0x%.3x : 0x%.8x\n", i * 0x10, reg);
dev_err(this->dev, "offset 0x%.3x : 0x%.8x\n", i * 0x10, reg);
}
/* start to print out the BCH info */
pr_err("Show BCH registers :\n");
dev_err(this->dev, "Show BCH registers :\n");
for (i = 0; i <= HW_BCH_VERSION / 0x10 + 1; i++) {
reg = readl(r->bch_regs + i * 0x10);
pr_err("offset 0x%.3x : 0x%.8x\n", i * 0x10, reg);
dev_err(this->dev, "offset 0x%.3x : 0x%.8x\n", i * 0x10, reg);
}
pr_err("BCH Geometry :\n");
pr_err("GF length : %u\n", geo->gf_len);
pr_err("ECC Strength : %u\n", geo->ecc_strength);
pr_err("Page Size in Bytes : %u\n", geo->page_size);
pr_err("Metadata Size in Bytes : %u\n", geo->metadata_size);
pr_err("ECC Chunk Size in Bytes: %u\n", geo->ecc_chunk_size);
pr_err("ECC Chunk Count : %u\n", geo->ecc_chunk_count);
pr_err("Payload Size in Bytes : %u\n", geo->payload_size);
pr_err("Auxiliary Size in Bytes: %u\n", geo->auxiliary_size);
pr_err("Auxiliary Status Offset: %u\n", geo->auxiliary_status_offset);
pr_err("Block Mark Byte Offset : %u\n", geo->block_mark_byte_offset);
pr_err("Block Mark Bit Offset : %u\n", geo->block_mark_bit_offset);
dev_err(this->dev, "BCH Geometry :\n"
"GF length : %u\n"
"ECC Strength : %u\n"
"Page Size in Bytes : %u\n"
"Metadata Size in Bytes : %u\n"
"ECC Chunk Size in Bytes: %u\n"
"ECC Chunk Count : %u\n"
"Payload Size in Bytes : %u\n"
"Auxiliary Size in Bytes: %u\n"
"Auxiliary Status Offset: %u\n"
"Block Mark Byte Offset : %u\n"
"Block Mark Bit Offset : %u\n",
geo->gf_len,
geo->ecc_strength,
geo->page_size,
geo->metadata_size,
geo->ecc_chunk_size,
geo->ecc_chunk_count,
geo->payload_size,
geo->auxiliary_size,
geo->auxiliary_status_offset,
geo->block_mark_byte_offset,
geo->block_mark_bit_offset);
}
/* Configures the geometry for BCH. */
......@@ -265,8 +277,8 @@ int bch_set_geometry(struct gpmi_nand_data *this)
* chip, otherwise it will lock up. So we skip resetting BCH on the MX23.
* On the other hand, the MX28 needs the reset, because one case has been
* seen where the BCH produced ECC errors constantly after 10000
* consecutive reboots. The latter case has not been seen on the MX23 yet,
* still we don't know if it could happen there as well.
* consecutive reboots. The latter case has not been seen on the MX23
* yet, still we don't know if it could happen there as well.
*/
ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MX23(this));
if (ret)
......@@ -353,7 +365,7 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this,
improved_timing_is_available =
(target.tREA_in_ns >= 0) &&
(target.tRLOH_in_ns >= 0) &&
(target.tRHOH_in_ns >= 0) ;
(target.tRHOH_in_ns >= 0);
/* Inspect the clock. */
nfc->clock_frequency_in_hz = clk_get_rate(r->clock[0]);
......@@ -911,10 +923,14 @@ static int enable_edo_mode(struct gpmi_nand_data *this, int mode)
struct resources *r = &this->resources;
struct nand_chip *nand = &this->nand;
struct mtd_info *mtd = &this->mtd;
uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {};
uint8_t *feature;
unsigned long rate;
int ret;
feature = kzalloc(ONFI_SUBFEATURE_PARAM_LEN, GFP_KERNEL);
if (!feature)
return -ENOMEM;
nand->select_chip(mtd, 0);
/* [1] send SET FEATURE commond to NAND */
......@@ -942,11 +958,13 @@ static int enable_edo_mode(struct gpmi_nand_data *this, int mode)
this->flags |= GPMI_ASYNC_EDO_ENABLED;
this->timing_mode = mode;
kfree(feature);
dev_info(this->dev, "enable the asynchronous EDO mode %d\n", mode);
return 0;
err_out:
nand->select_chip(mtd, -1);
kfree(feature);
dev_err(this->dev, "mode:%d ,failed in set feature.\n", mode);
return -EINVAL;
}
......@@ -986,7 +1004,7 @@ void gpmi_begin(struct gpmi_nand_data *this)
/* Enable the clock. */
ret = gpmi_enable_clk(this);
if (ret) {
pr_err("We failed in enable the clk\n");
dev_err(this->dev, "We failed in enable the clk\n");
goto err_out;
}
......@@ -1003,7 +1021,7 @@ void gpmi_begin(struct gpmi_nand_data *this)
/* [1] Set HW_GPMI_TIMING0 */
reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw.address_setup_in_cycles) |
BF_GPMI_TIMING0_DATA_HOLD(hw.data_hold_in_cycles) |
BF_GPMI_TIMING0_DATA_SETUP(hw.data_setup_in_cycles) ;
BF_GPMI_TIMING0_DATA_SETUP(hw.data_setup_in_cycles);
writel(reg, gpmi_regs + HW_GPMI_TIMING0);
......@@ -1090,7 +1108,7 @@ int gpmi_is_ready(struct gpmi_nand_data *this, unsigned chip)
mask = MX28_BF_GPMI_STAT_READY_BUSY(1 << chip);
reg = readl(r->gpmi_regs + HW_GPMI_STAT);
} else
pr_err("unknow arch.\n");
dev_err(this->dev, "unknow arch.\n");
return reg & mask;
}
......@@ -1121,10 +1139,8 @@ int gpmi_send_command(struct gpmi_nand_data *this)
desc = dmaengine_prep_slave_sg(channel,
(struct scatterlist *)pio,
ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
if (!desc) {
pr_err("step 1 error\n");
return -1;
}
if (!desc)
return -EINVAL;
/* [2] send out the COMMAND + ADDRESS string stored in @buffer */
sgl = &this->cmd_sgl;
......@@ -1134,11 +1150,8 @@ int gpmi_send_command(struct gpmi_nand_data *this)
desc = dmaengine_prep_slave_sg(channel,
sgl, 1, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
pr_err("step 2 error\n");
return -1;
}
if (!desc)
return -EINVAL;
/* [3] submit the DMA */
set_dma_type(this, DMA_FOR_COMMAND);
......@@ -1167,20 +1180,17 @@ int gpmi_send_data(struct gpmi_nand_data *this)
pio[1] = 0;
desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio,
ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
if (!desc) {
pr_err("step 1 error\n");
return -1;
}
if (!desc)
return -EINVAL;
/* [2] send DMA request */
prepare_data_dma(this, DMA_TO_DEVICE);
desc = dmaengine_prep_slave_sg(channel, &this->data_sgl,
1, DMA_MEM_TO_DEV,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
pr_err("step 2 error\n");
return -1;
}
if (!desc)
return -EINVAL;
/* [3] submit the DMA */
set_dma_type(this, DMA_FOR_WRITE_DATA);
return start_dma_without_bch_irq(this, desc);
......@@ -1204,20 +1214,16 @@ int gpmi_read_data(struct gpmi_nand_data *this)
desc = dmaengine_prep_slave_sg(channel,
(struct scatterlist *)pio,
ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
if (!desc) {
pr_err("step 1 error\n");
return -1;
}
if (!desc)
return -EINVAL;
/* [2] : send DMA request */
prepare_data_dma(this, DMA_FROM_DEVICE);
desc = dmaengine_prep_slave_sg(channel, &this->data_sgl,
1, DMA_DEV_TO_MEM,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
pr_err("step 2 error\n");
return -1;
}
if (!desc)
return -EINVAL;
/* [3] : submit the DMA */
set_dma_type(this, DMA_FOR_READ_DATA);
......@@ -1262,10 +1268,9 @@ int gpmi_send_page(struct gpmi_nand_data *this,
(struct scatterlist *)pio,
ARRAY_SIZE(pio), DMA_TRANS_NONE,
DMA_CTRL_ACK);
if (!desc) {
pr_err("step 2 error\n");
return -1;
}
if (!desc)
return -EINVAL;
set_dma_type(this, DMA_FOR_WRITE_ECC_PAGE);
return start_dma_with_bch_irq(this, desc);
}
......@@ -1297,10 +1302,8 @@ int gpmi_read_page(struct gpmi_nand_data *this,
desc = dmaengine_prep_slave_sg(channel,
(struct scatterlist *)pio, 2,
DMA_TRANS_NONE, 0);
if (!desc) {
pr_err("step 1 error\n");
return -1;
}
if (!desc)
return -EINVAL;
/* [2] Enable the BCH block and read. */
command_mode = BV_GPMI_CTRL0_COMMAND_MODE__READ;
......@@ -1327,10 +1330,8 @@ int gpmi_read_page(struct gpmi_nand_data *this,
(struct scatterlist *)pio,
ARRAY_SIZE(pio), DMA_TRANS_NONE,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
pr_err("step 2 error\n");
return -1;
}
if (!desc)
return -EINVAL;
/* [3] Disable the BCH block */
command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WAIT_FOR_READY;
......@@ -1348,10 +1349,8 @@ int gpmi_read_page(struct gpmi_nand_data *this,
(struct scatterlist *)pio, 3,
DMA_TRANS_NONE,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
pr_err("step 3 error\n");
return -1;
}
if (!desc)
return -EINVAL;
/* [4] submit the DMA */
set_dma_type(this, DMA_FOR_READ_ECC_PAGE);
......
This diff is collapsed.
......@@ -26,8 +26,6 @@
struct resources {
void __iomem *gpmi_regs;
void __iomem *bch_regs;
unsigned int bch_low_interrupt;
unsigned int bch_high_interrupt;
unsigned int dma_low_channel;
unsigned int dma_high_channel;
struct clk *clock[GPMI_CLK_MAX];
......
......@@ -416,10 +416,8 @@ static int jz_nand_probe(struct platform_device *pdev)
uint8_t nand_maf_id = 0, nand_dev_id = 0;
nand = kzalloc(sizeof(*nand), GFP_KERNEL);
if (!nand) {
dev_err(&pdev->dev, "Failed to allocate device structure.\n");
if (!nand)
return -ENOMEM;
}
ret = jz_nand_ioremap_resource(pdev, "mmio", &nand->mem, &nand->base);
if (ret)
......
......@@ -539,20 +539,6 @@ static int lpc32xx_write_page_lowlevel(struct mtd_info *mtd,
return 0;
}
static int lpc32xx_write_page(struct mtd_info *mtd, struct nand_chip *chip,
uint32_t offset, int data_len, const uint8_t *buf,
int oob_required, int page, int cached, int raw)
{
int res;
chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
res = lpc32xx_write_page_lowlevel(mtd, chip, buf, oob_required);
chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
lpc32xx_waitfunc(mtd, chip);
return res;
}
static int lpc32xx_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
int page)
{
......@@ -627,10 +613,8 @@ static struct lpc32xx_nand_cfg_mlc *lpc32xx_parse_dt(struct device *dev)
struct device_node *np = dev->of_node;
ncfg = devm_kzalloc(dev, sizeof(*ncfg), GFP_KERNEL);
if (!ncfg) {
dev_err(dev, "could not allocate memory for platform data\n");
if (!ncfg)
return NULL;
}
of_property_read_u32(np, "nxp,tcea-delay", &ncfg->tcea_delay);
of_property_read_u32(np, "nxp,busy-delay", &ncfg->busy_delay);
......@@ -666,10 +650,8 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
/* Allocate memory for the device structure (and zero it) */
host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
if (!host) {
dev_err(&pdev->dev, "failed to allocate device structure.\n");
if (!host)
return -ENOMEM;
}
rc = platform_get_resource(pdev, IORESOURCE_MEM, 0);
host->io_base = devm_ioremap_resource(&pdev->dev, rc);
......@@ -732,9 +714,9 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
nand_chip->ecc.write_oob = lpc32xx_write_oob;
nand_chip->ecc.read_oob = lpc32xx_read_oob;
nand_chip->ecc.strength = 4;
nand_chip->write_page = lpc32xx_write_page;
nand_chip->waitfunc = lpc32xx_waitfunc;
nand_chip->options = NAND_NO_SUBPAGE_WRITE;
nand_chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB;
nand_chip->bbt_td = &lpc32xx_nand_bbt;
nand_chip->bbt_md = &lpc32xx_nand_bbt_mirror;
......@@ -764,14 +746,12 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
host->dma_buf = devm_kzalloc(&pdev->dev, mtd->writesize, GFP_KERNEL);
if (!host->dma_buf) {
dev_err(&pdev->dev, "Error allocating dma_buf memory\n");
res = -ENOMEM;
goto err_exit3;
}
host->dummy_buf = devm_kzalloc(&pdev->dev, mtd->writesize, GFP_KERNEL);
if (!host->dummy_buf) {
dev_err(&pdev->dev, "Error allocating dummy_buf memory\n");
res = -ENOMEM;
goto err_exit3;
}
......
......@@ -725,10 +725,8 @@ static struct lpc32xx_nand_cfg_slc *lpc32xx_parse_dt(struct device *dev)
struct device_node *np = dev->of_node;
ncfg = devm_kzalloc(dev, sizeof(*ncfg), GFP_KERNEL);
if (!ncfg) {
dev_err(dev, "could not allocate memory for NAND config\n");
if (!ncfg)
return NULL;
}
of_property_read_u32(np, "nxp,wdr-clks", &ncfg->wdr_clks);
of_property_read_u32(np, "nxp,wwidth", &ncfg->wwidth);
......@@ -772,10 +770,8 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
/* Allocate memory for the device structure (and zero it) */
host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
if (!host) {
dev_err(&pdev->dev, "failed to allocate device structure\n");
if (!host)
return -ENOMEM;
}
host->io_base_dma = rc->start;
host->io_base = devm_ioremap_resource(&pdev->dev, rc);
......@@ -791,8 +787,8 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
}
if (host->ncfg->wp_gpio == -EPROBE_DEFER)
return -EPROBE_DEFER;
if (gpio_is_valid(host->ncfg->wp_gpio) &&
gpio_request(host->ncfg->wp_gpio, "NAND WP")) {
if (gpio_is_valid(host->ncfg->wp_gpio) && devm_gpio_request(&pdev->dev,
host->ncfg->wp_gpio, "NAND WP")) {
dev_err(&pdev->dev, "GPIO not available\n");
return -EBUSY;
}
......@@ -808,7 +804,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
mtd->dev.parent = &pdev->dev;
/* Get NAND clock */
host->clk = clk_get(&pdev->dev, NULL);
host->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(host->clk)) {
dev_err(&pdev->dev, "Clock failure\n");
res = -ENOENT;
......@@ -858,7 +854,6 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
host->data_buf = devm_kzalloc(&pdev->dev, host->dma_buf_len,
GFP_KERNEL);
if (host->data_buf == NULL) {
dev_err(&pdev->dev, "Error allocating memory\n");
res = -ENOMEM;
goto err_exit2;
}
......@@ -927,10 +922,8 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
dma_release_channel(host->dma_chan);
err_exit2:
clk_disable(host->clk);
clk_put(host->clk);
err_exit1:
lpc32xx_wp_enable(host);
gpio_free(host->ncfg->wp_gpio);
return res;
}
......@@ -953,9 +946,7 @@ static int lpc32xx_nand_remove(struct platform_device *pdev)
writel(tmp, SLC_CTRL(host->io_base));
clk_disable(host->clk);
clk_put(host->clk);
lpc32xx_wp_enable(host);
gpio_free(host->ncfg->wp_gpio);
return 0;
}
......
......@@ -653,10 +653,8 @@ static int mpc5121_nfc_probe(struct platform_device *op)
}
prv = devm_kzalloc(dev, sizeof(*prv), GFP_KERNEL);
if (!prv) {
dev_err(dev, "Memory exhausted!\n");
if (!prv)
return -ENOMEM;
}
mtd = &prv->mtd;
chip = &prv->chip;
......@@ -786,7 +784,6 @@ static int mpc5121_nfc_probe(struct platform_device *op)
/* Detect NAND chips */
if (nand_scan(mtd, be32_to_cpup(chips_no))) {
dev_err(dev, "NAND Flash not found !\n");
devm_free_irq(dev, prv->irq, mtd);
retval = -ENXIO;
goto error;
}
......@@ -811,7 +808,6 @@ static int mpc5121_nfc_probe(struct platform_device *op)
default:
dev_err(dev, "Unsupported NAND flash!\n");
devm_free_irq(dev, prv->irq, mtd);
retval = -ENXIO;
goto error;
}
......@@ -822,7 +818,6 @@ static int mpc5121_nfc_probe(struct platform_device *op)
retval = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0);
if (retval) {
dev_err(dev, "Error adding MTD device!\n");
devm_free_irq(dev, prv->irq, mtd);
goto error;
}
......@@ -836,11 +831,8 @@ static int mpc5121_nfc_remove(struct platform_device *op)
{
struct device *dev = &op->dev;
struct mtd_info *mtd = dev_get_drvdata(dev);
struct nand_chip *chip = mtd->priv;
struct mpc5121_nfc_prv *prv = chip->priv;
nand_release(mtd);
devm_free_irq(dev, prv->irq, mtd);
mpc5121_nfc_free(dev, mtd);
return 0;
......
......@@ -677,7 +677,6 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
ecc_stat >>= 4;
} while (--no_subpages);
mtd->ecc_stats.corrected += ret;
pr_debug("%d Symbol Correctable RS-ECC Error\n", ret);
return ret;
......@@ -1400,12 +1399,15 @@ static int mxcnd_probe(struct platform_device *pdev)
int err = 0;
/* Allocate memory for MTD device structure and private data */
host = devm_kzalloc(&pdev->dev, sizeof(struct mxc_nand_host) +
NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE, GFP_KERNEL);
host = devm_kzalloc(&pdev->dev, sizeof(struct mxc_nand_host),
GFP_KERNEL);
if (!host)
return -ENOMEM;
host->data_buf = (uint8_t *)(host + 1);
/* allocate a temporary buffer for the nand_scan_ident() */
host->data_buf = devm_kzalloc(&pdev->dev, PAGE_SIZE, GFP_KERNEL);
if (!host->data_buf)
return -ENOMEM;
host->dev = &pdev->dev;
/* structures must be linked */
......@@ -1512,7 +1514,9 @@ static int mxcnd_probe(struct platform_device *pdev)
if (err)
return err;
clk_prepare_enable(host->clk);
err = clk_prepare_enable(host->clk);
if (err)
return err;
host->clk_act = 1;
/*
......@@ -1531,6 +1535,15 @@ static int mxcnd_probe(struct platform_device *pdev)
goto escan;
}
/* allocate the right size buffer now */
devm_kfree(&pdev->dev, (void *)host->data_buf);
host->data_buf = devm_kzalloc(&pdev->dev, mtd->writesize + mtd->oobsize,
GFP_KERNEL);
if (!host->data_buf) {
err = -ENOMEM;
goto escan;
}
/* Call preset again, with correct writesize this time */
host->devtype_data->preset(mtd);
......@@ -1576,6 +1589,8 @@ static int mxcnd_remove(struct platform_device *pdev)
struct mxc_nand_host *host = platform_get_drvdata(pdev);
nand_release(&host->mtd);
if (host->clk_act)
clk_disable_unprepare(host->clk);
return 0;
}
......
This diff is collapsed.
......@@ -169,6 +169,8 @@ struct nand_manufacturers nand_manuf_ids[] = {
{NAND_MFR_AMD, "AMD/Spansion"},
{NAND_MFR_MACRONIX, "Macronix"},
{NAND_MFR_EON, "Eon"},
{NAND_MFR_SANDISK, "SanDisk"},
{NAND_MFR_INTEL, "Intel"},
{0x0, "Unknown"}
};
......
......@@ -241,12 +241,10 @@ static int nuc900_nand_probe(struct platform_device *pdev)
{
struct nuc900_nand *nuc900_nand;
struct nand_chip *chip;
int retval;
struct resource *res;
retval = 0;
nuc900_nand = kzalloc(sizeof(struct nuc900_nand), GFP_KERNEL);
nuc900_nand = devm_kzalloc(&pdev->dev, sizeof(struct nuc900_nand),
GFP_KERNEL);
if (!nuc900_nand)
return -ENOMEM;
chip = &(nuc900_nand->chip);
......@@ -255,11 +253,9 @@ static int nuc900_nand_probe(struct platform_device *pdev)
nuc900_nand->mtd.owner = THIS_MODULE;
spin_lock_init(&nuc900_nand->lock);
nuc900_nand->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(nuc900_nand->clk)) {
retval = -ENOENT;
goto fail1;
}
nuc900_nand->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(nuc900_nand->clk))
return -ENOENT;
clk_enable(nuc900_nand->clk);
chip->cmdfunc = nuc900_nand_command_lp;
......@@ -272,57 +268,29 @@ static int nuc900_nand_probe(struct platform_device *pdev)
chip->ecc.mode = NAND_ECC_SOFT;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
retval = -ENXIO;
goto fail1;
}
if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
retval = -EBUSY;
goto fail1;
}
nuc900_nand->reg = ioremap(res->start, resource_size(res));
if (!nuc900_nand->reg) {
retval = -ENOMEM;
goto fail2;
}
nuc900_nand->reg = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(nuc900_nand->reg))
return PTR_ERR(nuc900_nand->reg);
nuc900_nand_enable(nuc900_nand);
if (nand_scan(&(nuc900_nand->mtd), 1)) {
retval = -ENXIO;
goto fail3;
}
if (nand_scan(&(nuc900_nand->mtd), 1))
return -ENXIO;
mtd_device_register(&(nuc900_nand->mtd), partitions,
ARRAY_SIZE(partitions));
platform_set_drvdata(pdev, nuc900_nand);
return retval;
fail3: iounmap(nuc900_nand->reg);
fail2: release_mem_region(res->start, resource_size(res));
fail1: kfree(nuc900_nand);
return retval;
return 0;
}
static int nuc900_nand_remove(struct platform_device *pdev)
{
struct nuc900_nand *nuc900_nand = platform_get_drvdata(pdev);
struct resource *res;
nand_release(&nuc900_nand->mtd);
iounmap(nuc900_nand->reg);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(res->start, resource_size(res));
clk_disable(nuc900_nand->clk);
clk_put(nuc900_nand->clk);
kfree(nuc900_nand);
return 0;
}
......
......@@ -1730,13 +1730,7 @@ static int omap_nand_probe(struct platform_device *pdev)
break;
case NAND_OMAP_POLLED:
if (nand_chip->options & NAND_BUSWIDTH_16) {
nand_chip->read_buf = omap_read_buf16;
nand_chip->write_buf = omap_write_buf16;
} else {
nand_chip->read_buf = omap_read_buf8;
nand_chip->write_buf = omap_write_buf8;
}
/* Use nand_base defaults for {read,write}_buf */
break;
case NAND_OMAP_PREFETCH_DMA:
......
......@@ -87,7 +87,6 @@ static int __init orion_nand_probe(struct platform_device *pdev)
nc = kzalloc(sizeof(struct nand_chip) + sizeof(struct mtd_info), GFP_KERNEL);
if (!nc) {
printk(KERN_ERR "orion_nand: failed to allocate device structure.\n");
ret = -ENOMEM;
goto no_res;
}
......@@ -101,7 +100,7 @@ static int __init orion_nand_probe(struct platform_device *pdev)
io_base = ioremap(res->start, resource_size(res));
if (!io_base) {
printk(KERN_ERR "orion_nand: ioremap failed\n");
dev_err(&pdev->dev, "ioremap failed\n");
ret = -EIO;
goto no_res;
}
......@@ -110,7 +109,6 @@ static int __init orion_nand_probe(struct platform_device *pdev)
board = devm_kzalloc(&pdev->dev, sizeof(struct orion_nand_data),
GFP_KERNEL);
if (!board) {
printk(KERN_ERR "orion_nand: failed to allocate board structure.\n");
ret = -ENOMEM;
goto no_res;
}
......
......@@ -223,7 +223,7 @@ MODULE_DEVICE_TABLE(of, pasemi_nand_match);
static struct platform_driver pasemi_nand_driver =
{
.driver = {
.name = (char*)driver_name,
.name = driver_name,
.owner = THIS_MODULE,
.of_match_table = pasemi_nand_match,
},
......
......@@ -9,6 +9,7 @@
*
*/
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
......@@ -47,30 +48,16 @@ static int plat_nand_probe(struct platform_device *pdev)
return -EINVAL;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENXIO;
/* Allocate memory for the device structure (and zero it) */
data = kzalloc(sizeof(struct plat_nand_data), GFP_KERNEL);
if (!data) {
dev_err(&pdev->dev, "failed to allocate device structure.\n");
data = devm_kzalloc(&pdev->dev, sizeof(struct plat_nand_data),
GFP_KERNEL);
if (!data)
return -ENOMEM;
}
if (!request_mem_region(res->start, resource_size(res),
dev_name(&pdev->dev))) {
dev_err(&pdev->dev, "request_mem_region failed\n");
err = -EBUSY;
goto out_free;
}
data->io_base = ioremap(res->start, resource_size(res));
if (data->io_base == NULL) {
dev_err(&pdev->dev, "ioremap failed\n");
err = -EIO;
goto out_release_io;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
data->io_base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(data->io_base))
return PTR_ERR(data->io_base);
data->chip.priv = &data;
data->mtd.priv = &data->chip;
......@@ -122,11 +109,6 @@ static int plat_nand_probe(struct platform_device *pdev)
out:
if (pdata->ctrl.remove)
pdata->ctrl.remove(pdev);
iounmap(data->io_base);
out_release_io:
release_mem_region(res->start, resource_size(res));
out_free:
kfree(data);
return err;
}
......@@ -137,16 +119,10 @@ static int plat_nand_remove(struct platform_device *pdev)
{
struct plat_nand_data *data = platform_get_drvdata(pdev);
struct platform_nand_data *pdata = dev_get_platdata(&pdev->dev);
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
nand_release(&data->mtd);
if (pdata->ctrl.remove)
pdata->ctrl.remove(pdev);
iounmap(data->io_base);
release_mem_region(res->start, resource_size(res));
kfree(data);
return 0;
}
......
This diff is collapsed.
......@@ -46,9 +46,43 @@
#include <linux/mtd/nand_ecc.h>
#include <linux/mtd/partitions.h>
#include <plat/regs-nand.h>
#include <linux/platform_data/mtd-nand-s3c2410.h>
#define S3C2410_NFREG(x) (x)
#define S3C2410_NFCONF S3C2410_NFREG(0x00)
#define S3C2410_NFCMD S3C2410_NFREG(0x04)
#define S3C2410_NFADDR S3C2410_NFREG(0x08)
#define S3C2410_NFDATA S3C2410_NFREG(0x0C)
#define S3C2410_NFSTAT S3C2410_NFREG(0x10)
#define S3C2410_NFECC S3C2410_NFREG(0x14)
#define S3C2440_NFCONT S3C2410_NFREG(0x04)
#define S3C2440_NFCMD S3C2410_NFREG(0x08)
#define S3C2440_NFADDR S3C2410_NFREG(0x0C)
#define S3C2440_NFDATA S3C2410_NFREG(0x10)
#define S3C2440_NFSTAT S3C2410_NFREG(0x20)
#define S3C2440_NFMECC0 S3C2410_NFREG(0x2C)
#define S3C2412_NFSTAT S3C2410_NFREG(0x28)
#define S3C2412_NFMECC0 S3C2410_NFREG(0x34)
#define S3C2410_NFCONF_EN (1<<15)
#define S3C2410_NFCONF_INITECC (1<<12)
#define S3C2410_NFCONF_nFCE (1<<11)
#define S3C2410_NFCONF_TACLS(x) ((x)<<8)
#define S3C2410_NFCONF_TWRPH0(x) ((x)<<4)
#define S3C2410_NFCONF_TWRPH1(x) ((x)<<0)
#define S3C2410_NFSTAT_BUSY (1<<0)
#define S3C2440_NFCONF_TACLS(x) ((x)<<12)
#define S3C2440_NFCONF_TWRPH0(x) ((x)<<8)
#define S3C2440_NFCONF_TWRPH1(x) ((x)<<4)
#define S3C2440_NFCONT_INITECC (1<<4)
#define S3C2440_NFCONT_nFCE (1<<1)
#define S3C2440_NFCONT_ENABLE (1<<0)
#define S3C2440_NFSTAT_READY (1<<0)
#define S3C2412_NFCONF_NANDBOOT (1<<31)
#define S3C2412_NFCONT_INIT_MAIN_ECC (1<<5)
#define S3C2412_NFCONT_nFCE0 (1<<1)
#define S3C2412_NFSTAT_READY (1<<0)
/* new oob placement block for use with hardware ecc generation
*/
......@@ -919,7 +953,6 @@ static int s3c24xx_nand_probe(struct platform_device *pdev)
info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
if (info == NULL) {
dev_err(&pdev->dev, "no memory for flash info\n");
err = -ENOMEM;
goto exit_error;
}
......@@ -974,7 +1007,6 @@ static int s3c24xx_nand_probe(struct platform_device *pdev)
size = nr_sets * sizeof(*info->mtds);
info->mtds = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
if (info->mtds == NULL) {
dev_err(&pdev->dev, "failed to allocate mtd storage\n");
err = -ENOMEM;
goto exit_error;
}
......
......@@ -151,7 +151,7 @@ static void flctl_setup_dma(struct sh_flctl *flctl)
dma_cap_set(DMA_SLAVE, mask);
flctl->chan_fifo0_tx = dma_request_channel(mask, shdma_chan_filter,
(void *)pdata->slave_id_fifo0_tx);
(void *)(uintptr_t)pdata->slave_id_fifo0_tx);
dev_dbg(&pdev->dev, "%s: TX: got channel %p\n", __func__,
flctl->chan_fifo0_tx);
......@@ -168,7 +168,7 @@ static void flctl_setup_dma(struct sh_flctl *flctl)
goto err;
flctl->chan_fifo0_rx = dma_request_channel(mask, shdma_chan_filter,
(void *)pdata->slave_id_fifo0_rx);
(void *)(uintptr_t)pdata->slave_id_fifo0_rx);
dev_dbg(&pdev->dev, "%s: RX: got channel %p\n", __func__,
flctl->chan_fifo0_rx);
......@@ -1021,7 +1021,6 @@ static irqreturn_t flctl_handle_flste(int irq, void *dev_id)
return IRQ_HANDLED;
}
#ifdef CONFIG_OF
struct flctl_soc_config {
unsigned long flcmncr_val;
unsigned has_hwecc:1;
......@@ -1059,10 +1058,8 @@ static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev)
pdata = devm_kzalloc(dev, sizeof(struct sh_flctl_platform_data),
GFP_KERNEL);
if (!pdata) {
dev_err(dev, "%s: failed to allocate config data\n", __func__);
if (!pdata)
return NULL;
}
/* set SoC specific options */
pdata->flcmncr_val = config->flcmncr_val;
......@@ -1080,12 +1077,6 @@ static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev)
return pdata;
}
#else /* CONFIG_OF */
static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev)
{
return NULL;
}
#endif /* CONFIG_OF */
static int flctl_probe(struct platform_device *pdev)
{
......@@ -1094,38 +1085,30 @@ static int flctl_probe(struct platform_device *pdev)
struct mtd_info *flctl_mtd;
struct nand_chip *nand;
struct sh_flctl_platform_data *pdata;
int ret = -ENXIO;
int ret;
int irq;
struct mtd_part_parser_data ppdata = {};
flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL);
if (!flctl) {
dev_err(&pdev->dev, "failed to allocate driver data\n");
flctl = devm_kzalloc(&pdev->dev, sizeof(struct sh_flctl), GFP_KERNEL);
if (!flctl)
return -ENOMEM;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "failed to get I/O memory\n");
goto err_iomap;
}
flctl->reg = ioremap(res->start, resource_size(res));
if (flctl->reg == NULL) {
dev_err(&pdev->dev, "failed to remap I/O memory\n");
goto err_iomap;
}
flctl->reg = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(flctl->reg))
return PTR_ERR(flctl->reg);
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev, "failed to get flste irq data\n");
goto err_flste;
return -ENXIO;
}
ret = request_irq(irq, flctl_handle_flste, IRQF_SHARED, "flste", flctl);
ret = devm_request_irq(&pdev->dev, irq, flctl_handle_flste, IRQF_SHARED,
"flste", flctl);
if (ret) {
dev_err(&pdev->dev, "request interrupt failed.\n");
goto err_flste;
return ret;
}
if (pdev->dev.of_node)
......@@ -1135,8 +1118,7 @@ static int flctl_probe(struct platform_device *pdev)
if (!pdata) {
dev_err(&pdev->dev, "no setup data defined\n");
ret = -EINVAL;
goto err_pdata;
return -EINVAL;
}
platform_set_drvdata(pdev, flctl);
......@@ -1190,12 +1172,6 @@ static int flctl_probe(struct platform_device *pdev)
err_chip:
flctl_release_dma(flctl);
pm_runtime_disable(&pdev->dev);
err_pdata:
free_irq(irq, flctl);
err_flste:
iounmap(flctl->reg);
err_iomap:
kfree(flctl);
return ret;
}
......@@ -1206,9 +1182,6 @@ static int flctl_remove(struct platform_device *pdev)
flctl_release_dma(flctl);
nand_release(&flctl->mtd);
pm_runtime_disable(&pdev->dev);
free_irq(platform_get_irq(pdev, 0), flctl);
iounmap(flctl->reg);
kfree(flctl);
return 0;
}
......
......@@ -121,10 +121,8 @@ static int sharpsl_nand_probe(struct platform_device *pdev)
/* Allocate memory for MTD device structure and private data */
sharpsl = kzalloc(sizeof(struct sharpsl_nand), GFP_KERNEL);
if (!sharpsl) {
printk("Unable to allocate SharpSL NAND MTD device structure.\n");
if (!sharpsl)
return -ENOMEM;
}
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
......@@ -136,7 +134,7 @@ static int sharpsl_nand_probe(struct platform_device *pdev)
/* map physical address */
sharpsl->io = ioremap(r->start, resource_size(r));
if (!sharpsl->io) {
printk("ioremap to access Sharp SL NAND chip failed\n");
dev_err(&pdev->dev, "ioremap to access Sharp SL NAND chip failed\n");
err = -EIO;
goto err_ioremap;
}
......
......@@ -371,11 +371,9 @@ static int tmio_probe(struct platform_device *dev)
if (data == NULL)
dev_warn(&dev->dev, "NULL platform data!\n");
tmio = kzalloc(sizeof *tmio, GFP_KERNEL);
if (!tmio) {
retval = -ENOMEM;
goto err_kzalloc;
}
tmio = devm_kzalloc(&dev->dev, sizeof(*tmio), GFP_KERNEL);
if (!tmio)
return -ENOMEM;
tmio->dev = dev;
......@@ -385,22 +383,18 @@ static int tmio_probe(struct platform_device *dev)
mtd->priv = nand_chip;
mtd->name = "tmio-nand";
tmio->ccr = ioremap(ccr->start, resource_size(ccr));
if (!tmio->ccr) {
retval = -EIO;
goto err_iomap_ccr;
}
tmio->ccr = devm_ioremap(&dev->dev, ccr->start, resource_size(ccr));
if (!tmio->ccr)
return -EIO;
tmio->fcr_base = fcr->start & 0xfffff;
tmio->fcr = ioremap(fcr->start, resource_size(fcr));
if (!tmio->fcr) {
retval = -EIO;
goto err_iomap_fcr;
}
tmio->fcr = devm_ioremap(&dev->dev, fcr->start, resource_size(fcr));
if (!tmio->fcr)
return -EIO;
retval = tmio_hw_init(dev, tmio);
if (retval)
goto err_hwinit;
return retval;
/* Set address of NAND IO lines */
nand_chip->IO_ADDR_R = tmio->fcr;
......@@ -428,7 +422,8 @@ static int tmio_probe(struct platform_device *dev)
/* 15 us command delay time */
nand_chip->chip_delay = 15;
retval = request_irq(irq, &tmio_irq, 0, dev_name(&dev->dev), tmio);
retval = devm_request_irq(&dev->dev, irq, &tmio_irq, 0,
dev_name(&dev->dev), tmio);
if (retval) {
dev_err(&dev->dev, "request_irq error %d\n", retval);
goto err_irq;
......@@ -440,7 +435,7 @@ static int tmio_probe(struct platform_device *dev)
/* Scan to find existence of the device */
if (nand_scan(mtd, 1)) {
retval = -ENODEV;
goto err_scan;
goto err_irq;
}
/* Register the partitions */
retval = mtd_device_parse_register(mtd, NULL, NULL,
......@@ -451,18 +446,8 @@ static int tmio_probe(struct platform_device *dev)
nand_release(mtd);
err_scan:
if (tmio->irq)
free_irq(tmio->irq, tmio);
err_irq:
tmio_hw_stop(dev, tmio);
err_hwinit:
iounmap(tmio->fcr);
err_iomap_fcr:
iounmap(tmio->ccr);
err_iomap_ccr:
kfree(tmio);
err_kzalloc:
return retval;
}
......@@ -471,12 +456,7 @@ static int tmio_remove(struct platform_device *dev)
struct tmio_nand *tmio = platform_get_drvdata(dev);
nand_release(&tmio->mtd);
if (tmio->irq)
free_irq(tmio->irq, tmio);
tmio_hw_stop(dev, tmio);
iounmap(tmio->fcr);
iounmap(tmio->ccr);
kfree(tmio);
return 0;
}
......
......@@ -319,11 +319,8 @@ static int __init txx9ndfmc_probe(struct platform_device *dev)
continue;
txx9_priv = kzalloc(sizeof(struct txx9ndfmc_priv),
GFP_KERNEL);
if (!txx9_priv) {
dev_err(&dev->dev, "Unable to allocate "
"TXx9 NDFMC MTD device structure.\n");
if (!txx9_priv)
continue;
}
chip = &txx9_priv->chip;
mtd = &txx9_priv->mtd;
mtd->owner = THIS_MODULE;
......
......@@ -81,7 +81,7 @@ static int parse_ofpart_partitions(struct mtd_info *master,
partname = of_get_property(pp, "label", &len);
if (!partname)
partname = of_get_property(pp, "name", &len);
(*pparts)[i].name = (char *)partname;
(*pparts)[i].name = partname;
if (of_get_property(pp, "read-only", &len))
(*pparts)[i].mask_flags |= MTD_WRITEABLE;
......@@ -152,7 +152,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master,
if (names && (plen > 0)) {
int len = strlen(names) + 1;
(*pparts)[i].name = (char *)names;
(*pparts)[i].name = names;
plen -= len;
names += len;
} else {
......@@ -173,18 +173,9 @@ static struct mtd_part_parser ofoldpart_parser = {
static int __init ofpart_parser_init(void)
{
int rc;
rc = register_mtd_parser(&ofpart_parser);
if (rc)
goto out;
rc = register_mtd_parser(&ofoldpart_parser);
if (!rc)
return 0;
deregister_mtd_parser(&ofoldpart_parser);
out:
return rc;
register_mtd_parser(&ofpart_parser);
register_mtd_parser(&ofoldpart_parser);
return 0;
}
static void __exit ofpart_parser_exit(void)
......
......@@ -58,7 +58,7 @@ static int generic_onenand_probe(struct platform_device *pdev)
goto out_release_mem_region;
}
info->onenand.mmcontrol = pdata ? pdata->mmcontrol : 0;
info->onenand.mmcontrol = pdata ? pdata->mmcontrol : NULL;
info->onenand.irq = platform_get_irq(pdev, 0);
info->mtd.name = dev_name(&pdev->dev);
......
......@@ -300,7 +300,8 @@ MODULE_ALIAS("RedBoot");
static int __init redboot_parser_init(void)
{
return register_mtd_parser(&redboot_parser);
register_mtd_parser(&redboot_parser);
return 0;
}
static void __exit redboot_parser_exit(void)
......
......@@ -19,7 +19,7 @@
* or detected.
*/
#if defined(CONFIG_MTD_NAND) || defined(CONFIG_MTD_NAND_MODULE)
#if IS_ENABLED(CONFIG_MTD_NAND)
struct nand_ecc_test {
const char *name;
......
......@@ -288,6 +288,8 @@ struct jffs2_xattr_datum *jffs2_alloc_xattr_datum(void)
struct jffs2_xattr_datum *xd;
xd = kmem_cache_zalloc(xattr_datum_cache, GFP_KERNEL);
dbg_memalloc("%p\n", xd);
if (!xd)
return NULL;
xd->class = RAWNODE_CLASS_XATTR_DATUM;
xd->node = (void *)xd;
......@@ -306,6 +308,8 @@ struct jffs2_xattr_ref *jffs2_alloc_xattr_ref(void)
struct jffs2_xattr_ref *ref;
ref = kmem_cache_zalloc(xattr_ref_cache, GFP_KERNEL);
dbg_memalloc("%p\n", ref);
if (!ref)
return NULL;
ref->class = RAWNODE_CLASS_XATTR_REF;
ref->node = (void *)ref;
......
......@@ -3,6 +3,6 @@
#include <linux/mtd/mtd.h>
int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
unsigned long size, char *name);
unsigned long size, const char *name);
#endif /* __MTD_MTDRAM_H__ */
......@@ -219,6 +219,9 @@ struct nand_chip;
/* ONFI feature address */
#define ONFI_FEATURE_ADDR_TIMING_MODE 0x1
/* Vendor-specific feature address (Micron) */
#define ONFI_FEATURE_ADDR_READ_RETRY 0x89
/* ONFI subfeature parameters length */
#define ONFI_SUBFEATURE_PARAM_LEN 4
......@@ -279,16 +282,17 @@ struct nand_onfi_params {
__le16 io_pin_capacitance_typ;
__le16 input_pin_capacitance_typ;
u8 input_pin_capacitance_max;
u8 driver_strenght_support;
u8 driver_strength_support;
__le16 t_int_r;
__le16 t_ald;
u8 reserved4[7];
/* vendor */
u8 reserved5[90];
__le16 vendor_revision;
u8 vendor[88];
__le16 crc;
} __attribute__((packed));
} __packed;
#define ONFI_CRC_BASE 0x4F4E
......@@ -326,6 +330,26 @@ struct onfi_ext_param_page {
*/
} __packed;
struct nand_onfi_vendor_micron {
u8 two_plane_read;
u8 read_cache;
u8 read_unique_id;
u8 dq_imped;
u8 dq_imped_num_settings;
u8 dq_imped_feat_addr;
u8 rb_pulldown_strength;
u8 rb_pulldown_strength_feat_addr;
u8 rb_pulldown_strength_num_settings;
u8 otp_mode;
u8 otp_page_start;
u8 otp_data_prot_addr;
u8 otp_num_pages;
u8 otp_feat_addr;
u8 read_retry_options;
u8 reserved[72];
u8 param_revision;
} __packed;
/**
* struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices
* @lock: protection lock
......@@ -432,6 +456,8 @@ struct nand_buffers {
* flash device.
* @read_byte: [REPLACEABLE] read one byte from the chip
* @read_word: [REPLACEABLE] read one word from the chip
* @write_byte: [REPLACEABLE] write a single byte to the chip on the
* low 8 I/O lines
* @write_buf: [REPLACEABLE] write data from the buffer to the chip
* @read_buf: [REPLACEABLE] read data from the chip into the buffer
* @select_chip: [REPLACEABLE] select chip nr
......@@ -451,6 +477,8 @@ struct nand_buffers {
* commands to the chip.
* @waitfunc: [REPLACEABLE] hardwarespecific function for wait on
* ready.
* @setup_read_retry: [FLASHSPECIFIC] flash (vendor) specific function for
* setting the read-retry mode. Mostly needed for MLC NAND.
* @ecc: [BOARDSPECIFIC] ECC control structure
* @buffers: buffer structure for read/write
* @hwcontrol: platform-specific hardware control structure
......@@ -497,6 +525,7 @@ struct nand_buffers {
* non 0 if ONFI supported.
* @onfi_params: [INTERN] holds the ONFI page parameter when ONFI is
* supported, 0 otherwise.
* @read_retries: [INTERN] the number of read retry modes supported
* @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
* @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
* @bbt: [INTERN] bad block table pointer
......@@ -521,6 +550,7 @@ struct nand_chip {
uint8_t (*read_byte)(struct mtd_info *mtd);
u16 (*read_word)(struct mtd_info *mtd);
void (*write_byte)(struct mtd_info *mtd, uint8_t byte);
void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);
void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);
void (*select_chip)(struct mtd_info *mtd, int chip);
......@@ -544,6 +574,7 @@ struct nand_chip {
int feature_addr, uint8_t *subfeature_para);
int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip,
int feature_addr, uint8_t *subfeature_para);
int (*setup_read_retry)(struct mtd_info *mtd, int retry_mode);
int chip_delay;
unsigned int options;
......@@ -568,6 +599,8 @@ struct nand_chip {
int onfi_version;
struct nand_onfi_params onfi_params;
int read_retries;
flstate_t state;
uint8_t *oob_poi;
......@@ -600,6 +633,8 @@ struct nand_chip {
#define NAND_MFR_AMD 0x01
#define NAND_MFR_MACRONIX 0xc2
#define NAND_MFR_EON 0x92
#define NAND_MFR_SANDISK 0x45
#define NAND_MFR_INTEL 0x89
/* The maximum expected count of bytes in the NAND ID sequence */
#define NAND_MAX_ID_LEN 8
......
......@@ -37,7 +37,7 @@
*/
struct mtd_partition {
char *name; /* identifier string */
const char *name; /* identifier string */
uint64_t size; /* partition size */
uint64_t offset; /* offset within the master MTD space */
uint32_t mask_flags; /* master MTD flags to mask out for this partition */
......@@ -76,11 +76,11 @@ struct mtd_part_parser {
struct mtd_part_parser_data *);
};
extern int register_mtd_parser(struct mtd_part_parser *parser);
extern int deregister_mtd_parser(struct mtd_part_parser *parser);
extern void register_mtd_parser(struct mtd_part_parser *parser);
extern void deregister_mtd_parser(struct mtd_part_parser *parser);
int mtd_is_partition(const struct mtd_info *mtd);
int mtd_add_partition(struct mtd_info *master, char *name,
int mtd_add_partition(struct mtd_info *master, const char *name,
long long offset, long long length);
int mtd_del_partition(struct mtd_info *master, int partno);
uint64_t mtd_get_device_size(const struct mtd_info *mtd);
......
......@@ -7,7 +7,7 @@
*/
#ifndef __LINUX_OF_MTD_H
#define __LINUX_OF_NET_H
#define __LINUX_OF_MTD_H
#ifdef CONFIG_OF_MTD
......
/*
* arch/arm/plat-omap/include/mach/nand.h
*
* Copyright (C) 2006 Micron Technology Inc.
*
* This program is free software; you can redistribute it and/or modify
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment