diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-13 22:25:54 +0300 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-13 22:25:54 +0300 | 
| commit | ac53b2e053fffc74372da94e734b92f37e70d32c (patch) | |
| tree | cda82af0fcded5d230e9f56104d3988b7a75c8aa /drivers/mtd/nand/omap2.c | |
| parent | cf09112d160e6db21ff8427ce696f819b957423b (diff) | |
| parent | 9146cbd52b11d4ade62dba8f238ec5e421c3fa2b (diff) | |
| download | linux-ac53b2e053fffc74372da94e734b92f37e70d32c.tar.xz | |
Merge tag 'for-linus-20160112' of git://git.infradead.org/linux-mtd
Pull MTD updates from Brian Norris:
 "Generic MTD:
   - populate the MTD device 'of_node' field (and get a proper 'of_node'
     symlink in sysfs)
     This yielded some new helper functions, and changes across a
     variety of drivers
   - partitioning cleanups, to prepare for better device-tree based
     partitioning in the future
     Eliminate a lot of boilerplate for drivers that want to use
     OF-based partition parsing
     The DT bindings for this didn't settle yet, so most non-cleanup
     portions are deferred for a future release
  NAND:
   - embed a struct mtd_info inside struct nand_chip
     This is really long overdue; too many drivers have to do the same
     silly boilerplate to allocate and link up two "independent"
     structs, when in fact, everyone is assuming there is an exact 1:1
     relationship between a NAND chips struct and its underlying MTD.
     This aids improved helpers and should make certain abstractions
     easier in the future.
     Also causes a lot of churn, helped along by some automated code
     transformations
   - add more core support for detecting (and "correcting") bitflips in
     erased pages; requires opt-in by drivers, but at least we kill a
     few bad implementations and hopefully stave off future ones
   - pxa3xx_nand: cleanups, a few fixes, and PM improvements
   - new JZ4780 NAND driver
  SPI NOR:
   - provide default erase function, for controllers that just want to
     send the SECTOR_ERASE command directly
   - fix some module auto-loading issues with device tree
     ("jedec,spi-nor")
   - error handling fixes
   - new Mediatek QSPI flash driver
  Other:
   - cfi: force valid geometry Kconfig (finally!)
     This one used to trip up randconfigs occasionally, since bots
     aren't deterred by big scary "advanced configuration" menus
  More? Probably. See the commit logs"
* tag 'for-linus-20160112' of git://git.infradead.org/linux-mtd: (168 commits)
  mtd: jz4780_nand: replace if/else blocks with switch/case
  mtd: nand: jz4780: Update ecc correction error codes
  mtd: nandsim: use nand_get_controller_data()
  mtd: jz4780_nand: remove useless mtd->priv = chip assignment
  staging: mt29f_spinand: make use of nand_set/get_controller_data() helpers
  mtd: nand: make use of nand_set/get_controller_data() helpers
  ARM: make use of nand_set/get_controller_data() helpers
  mtd: nand: add helpers to access ->priv
  mtd: nand: jz4780: driver for NAND devices on JZ4780 SoCs
  mtd: nand: jz4740: remove custom 'erased check' implementation
  mtd: nand: diskonchip: remove custom 'erased check' implementation
  mtd: nand: davinci: remove custom 'erased check' implementation
  mtd: nand: use nand_check_erased_ecc_chunk in default ECC read functions
  mtd: nand: return consistent error codes in ecc.correct() implementations
  doc: dt: mtd: new binding for jz4780-{nand,bch}
  mtd: cfi_cmdset_0001: fixing memory leak and handling failed kmalloc
  mtd: spi-nor: wait until lock/unlock operations are ready
  mtd: tests: consolidate kmalloc/memset 0 call to kzalloc
  jffs2: use to_delayed_work
  mtd: nand: assign reasonable default name for NAND drivers
  ...
Diffstat (limited to 'drivers/mtd/nand/omap2.c')
| -rw-r--r-- | drivers/mtd/nand/omap2.c | 92 | 
1 files changed, 38 insertions, 54 deletions
| diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 93f664cd1c90..c553f78ab83f 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c @@ -152,7 +152,6 @@ static struct nand_hw_control omap_gpmc_controller = {  struct omap_nand_info {  	struct omap_nand_platform_data	*pdata; -	struct mtd_info			mtd;  	struct nand_chip		nand;  	struct platform_device		*pdev; @@ -177,6 +176,11 @@ struct omap_nand_info {  	struct device_node		*of_node;  }; +static inline struct omap_nand_info *mtd_to_omap(struct mtd_info *mtd) +{ +	return container_of(mtd_to_nand(mtd), struct omap_nand_info, nand); +} +  /**   * omap_prefetch_enable - configures and starts prefetch transfer   * @cs: cs (chip select) number @@ -247,8 +251,7 @@ static int omap_prefetch_reset(int cs, struct omap_nand_info *info)   */  static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)  { -	struct omap_nand_info *info = container_of(mtd, -					struct omap_nand_info, mtd); +	struct omap_nand_info *info = mtd_to_omap(mtd);  	if (cmd != NAND_CMD_NONE) {  		if (ctrl & NAND_CLE) @@ -270,7 +273,7 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)   */  static void omap_read_buf8(struct mtd_info *mtd, u_char *buf, int len)  { -	struct nand_chip *nand = mtd->priv; +	struct nand_chip *nand = mtd_to_nand(mtd);  	ioread8_rep(nand->IO_ADDR_R, buf, len);  } @@ -283,8 +286,7 @@ static void omap_read_buf8(struct mtd_info *mtd, u_char *buf, int len)   */  static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len)  { -	struct omap_nand_info *info = container_of(mtd, -						struct omap_nand_info, mtd); +	struct omap_nand_info *info = mtd_to_omap(mtd);  	u_char *p = (u_char *)buf;  	u32	status = 0; @@ -306,7 +308,7 @@ static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len)   */  static void omap_read_buf16(struct mtd_info *mtd, u_char *buf, int len)  { -	struct nand_chip *nand = mtd->priv; +	struct nand_chip *nand = mtd_to_nand(mtd);  	ioread16_rep(nand->IO_ADDR_R, buf, len / 2);  } @@ -319,8 +321,7 @@ static void omap_read_buf16(struct mtd_info *mtd, u_char *buf, int len)   */  static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len)  { -	struct omap_nand_info *info = container_of(mtd, -						struct omap_nand_info, mtd); +	struct omap_nand_info *info = mtd_to_omap(mtd);  	u16 *p = (u16 *) buf;  	u32	status = 0;  	/* FIXME try bursts of writesw() or DMA ... */ @@ -344,8 +345,7 @@ static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len)   */  static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len)  { -	struct omap_nand_info *info = container_of(mtd, -						struct omap_nand_info, mtd); +	struct omap_nand_info *info = mtd_to_omap(mtd);  	uint32_t r_count = 0;  	int ret = 0;  	u32 *p = (u32 *)buf; @@ -392,8 +392,7 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len)  static void omap_write_buf_pref(struct mtd_info *mtd,  					const u_char *buf, int len)  { -	struct omap_nand_info *info = container_of(mtd, -						struct omap_nand_info, mtd); +	struct omap_nand_info *info = mtd_to_omap(mtd);  	uint32_t w_count = 0;  	int i = 0, ret = 0;  	u16 *p = (u16 *)buf; @@ -458,8 +457,7 @@ static void omap_nand_dma_callback(void *data)  static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr,  					unsigned int len, int is_write)  { -	struct omap_nand_info *info = container_of(mtd, -					struct omap_nand_info, mtd); +	struct omap_nand_info *info = mtd_to_omap(mtd);  	struct dma_async_tx_descriptor *tx;  	enum dma_data_direction dir = is_write ? DMA_TO_DEVICE :  							DMA_FROM_DEVICE; @@ -623,8 +621,7 @@ done:   */  static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len)  { -	struct omap_nand_info *info = container_of(mtd, -						struct omap_nand_info, mtd); +	struct omap_nand_info *info = mtd_to_omap(mtd);  	int ret = 0;  	if (len <= mtd->oobsize) { @@ -671,8 +668,7 @@ out_copy:  static void omap_write_buf_irq_pref(struct mtd_info *mtd,  					const u_char *buf, int len)  { -	struct omap_nand_info *info = container_of(mtd, -						struct omap_nand_info, mtd); +	struct omap_nand_info *info = mtd_to_omap(mtd);  	int ret = 0;  	unsigned long tim, limit;  	u32 val; @@ -830,12 +826,12 @@ static int omap_compare_ecc(u8 *ecc_data1,	/* read from NAND memory */  	case 1:  		/* Uncorrectable error */  		pr_debug("ECC UNCORRECTED_ERROR 1\n"); -		return -1; +		return -EBADMSG;  	case 11:  		/* UN-Correctable error */  		pr_debug("ECC UNCORRECTED_ERROR B\n"); -		return -1; +		return -EBADMSG;  	case 12:  		/* Correctable error */ @@ -865,7 +861,7 @@ static int omap_compare_ecc(u8 *ecc_data1,	/* read from NAND memory */  				return 0;  		}  		pr_debug("UNCORRECTED_ERROR default\n"); -		return -1; +		return -EBADMSG;  	}  } @@ -886,8 +882,7 @@ static int omap_compare_ecc(u8 *ecc_data1,	/* read from NAND memory */  static int omap_correct_data(struct mtd_info *mtd, u_char *dat,  				u_char *read_ecc, u_char *calc_ecc)  { -	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, -							mtd); +	struct omap_nand_info *info = mtd_to_omap(mtd);  	int blockCnt = 0, i = 0, ret = 0;  	int stat = 0; @@ -928,8 +923,7 @@ static int omap_correct_data(struct mtd_info *mtd, u_char *dat,  static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat,  				u_char *ecc_code)  { -	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, -							mtd); +	struct omap_nand_info *info = mtd_to_omap(mtd);  	u32 val;  	val = readl(info->reg.gpmc_ecc_config); @@ -953,9 +947,8 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat,   */  static void omap_enable_hwecc(struct mtd_info *mtd, int mode)  { -	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, -							mtd); -	struct nand_chip *chip = mtd->priv; +	struct omap_nand_info *info = mtd_to_omap(mtd); +	struct nand_chip *chip = mtd_to_nand(mtd);  	unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0;  	u32 val; @@ -1001,9 +994,8 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode)   */  static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)  { -	struct nand_chip *this = mtd->priv; -	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, -							mtd); +	struct nand_chip *this = mtd_to_nand(mtd); +	struct omap_nand_info *info = mtd_to_omap(mtd);  	unsigned long timeo = jiffies;  	int status, state = this->state; @@ -1031,8 +1023,7 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip)  static int omap_dev_ready(struct mtd_info *mtd)  {  	unsigned int val = 0; -	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, -							mtd); +	struct omap_nand_info *info = mtd_to_omap(mtd);  	val = readl(info->reg.gpmc_status); @@ -1058,10 +1049,9 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info *mtd, int mode)  {  	unsigned int bch_type;  	unsigned int dev_width, nsectors; -	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, -						   mtd); +	struct omap_nand_info *info = mtd_to_omap(mtd);  	enum omap_ecc ecc_opt = info->ecc_opt; -	struct nand_chip *chip = mtd->priv; +	struct nand_chip *chip = mtd_to_nand(mtd);  	u32 val, wr_mode;  	unsigned int ecc_size1, ecc_size0; @@ -1162,8 +1152,7 @@ static u8  bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2,  static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,  					const u_char *dat, u_char *ecc_calc)  { -	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, -						   mtd); +	struct omap_nand_info *info = mtd_to_omap(mtd);  	int eccbytes	= info->nand.ecc.bytes;  	struct gpmc_nand_regs	*gpmc_regs = &info->reg;  	u8 *ecc_code; @@ -1334,8 +1323,7 @@ static int erased_sector_bitflips(u_char *data, u_char *oob,  static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data,  				u_char *read_ecc, u_char *calc_ecc)  { -	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, -			mtd); +	struct omap_nand_info *info = mtd_to_omap(mtd);  	struct nand_ecc_ctrl *ecc = &info->nand.ecc;  	int eccsteps = info->nand.ecc.steps;  	int i , j, stat = 0; @@ -1663,7 +1651,6 @@ static int omap_nand_probe(struct platform_device *pdev)  	unsigned			sig;  	unsigned			oob_index;  	struct resource			*res; -	struct mtd_part_parser_data	ppdata = {};  	pdata = dev_get_platdata(&pdev->dev);  	if (pdata == NULL) { @@ -1683,11 +1670,11 @@ static int omap_nand_probe(struct platform_device *pdev)  	info->reg		= pdata->reg;  	info->of_node		= pdata->of_node;  	info->ecc_opt		= pdata->ecc_opt; -	mtd			= &info->mtd; -	mtd->priv		= &info->nand; -	mtd->dev.parent		= &pdev->dev;  	nand_chip		= &info->nand; +	mtd			= nand_to_mtd(nand_chip); +	mtd->dev.parent		= &pdev->dev;  	nand_chip->ecc.priv	= NULL; +	nand_set_flash_node(nand_chip, pdata->of_node);  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	nand_chip->IO_ADDR_R = devm_ioremap_resource(&pdev->dev, res); @@ -1909,7 +1896,7 @@ static int omap_nand_probe(struct platform_device *pdev)  				ecclayout->eccpos[ecclayout->eccbytes - 1] + 1;  		err = elm_config(info->elm_dev, BCH4_ECC, -				 info->mtd.writesize / nand_chip->ecc.size, +				 mtd->writesize / nand_chip->ecc.size,  				 nand_chip->ecc.size, nand_chip->ecc.bytes);  		if (err < 0)  			goto return_error; @@ -1963,7 +1950,7 @@ static int omap_nand_probe(struct platform_device *pdev)  		nand_chip->ecc.write_page	= omap_write_page_bch;  		err = elm_config(info->elm_dev, BCH8_ECC, -				 info->mtd.writesize / nand_chip->ecc.size, +				 mtd->writesize / nand_chip->ecc.size,  				 nand_chip->ecc.size, nand_chip->ecc.bytes);  		if (err < 0)  			goto return_error; @@ -1993,7 +1980,7 @@ static int omap_nand_probe(struct platform_device *pdev)  		nand_chip->ecc.write_page	= omap_write_page_bch;  		err = elm_config(info->elm_dev, BCH16_ECC, -				 info->mtd.writesize / nand_chip->ecc.size, +				 mtd->writesize / nand_chip->ecc.size,  				 nand_chip->ecc.size, nand_chip->ecc.bytes);  		if (err < 0)  			goto return_error; @@ -2037,9 +2024,7 @@ scan_tail:  		goto return_error;  	} -	ppdata.of_node = pdata->of_node; -	mtd_device_parse_register(mtd, NULL, &ppdata, pdata->parts, -				  pdata->nr_parts); +	mtd_device_register(mtd, pdata->parts, pdata->nr_parts);  	platform_set_drvdata(pdev, mtd); @@ -2058,9 +2043,8 @@ return_error:  static int omap_nand_remove(struct platform_device *pdev)  {  	struct mtd_info *mtd = platform_get_drvdata(pdev); -	struct nand_chip *nand_chip = mtd->priv; -	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, -							mtd); +	struct nand_chip *nand_chip = mtd_to_nand(mtd); +	struct omap_nand_info *info = mtd_to_omap(mtd);  	if (nand_chip->ecc.priv) {  		nand_bch_free(nand_chip->ecc.priv);  		nand_chip->ecc.priv = NULL; | 
