diff options
Diffstat (limited to 'drivers/mtd/nand/denali.c')
| -rw-r--r-- | drivers/mtd/nand/denali.c | 64 | 
1 files changed, 36 insertions, 28 deletions
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 2ed2bb33a6e..9f2012a3e76 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -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++) @@ -1234,7 +1233,7 @@ static int denali_waitfunc(struct mtd_info *mtd, struct nand_chip *chip)  	return status;  } -static void denali_erase(struct mtd_info *mtd, int page) +static int denali_erase(struct mtd_info *mtd, int page)  {  	struct denali_nand_info *denali = mtd_to_denali(mtd); @@ -1251,8 +1250,7 @@ static void denali_erase(struct mtd_info *mtd, int page)  	irq_status = wait_for_irq(denali, INTR_STATUS__ERASE_COMP |  					INTR_STATUS__ERASE_FAIL); -	denali->status = (irq_status & INTR_STATUS__ERASE_FAIL) ? -						NAND_STATUS_FAIL : PASS; +	return (irq_status & INTR_STATUS__ERASE_FAIL) ? NAND_STATUS_FAIL : PASS;  }  static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col, @@ -1394,7 +1392,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {  };  /* initialize driver data structures */ -void denali_drv_init(struct denali_nand_info *denali) +static void denali_drv_init(struct denali_nand_info *denali)  {  	denali->idx = 0; @@ -1429,20 +1427,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 +1465,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;  	} @@ -1520,7 +1527,7 @@ int denali_init(struct denali_nand_info *denali)  	 * so just let controller do 15bit ECC for MLC and 8bit ECC for  	 * SLC if possible.  	 * */ -	if (denali->nand.cellinfo & NAND_CI_CELLTYPE_MSK && +	if (!nand_is_slc(&denali->nand) &&  			(denali->mtd.oobsize > (denali->bbtskipbytes +  			ECC_15BITS * (denali->mtd.writesize /  			ECC_SECTOR_SIZE)))) { @@ -1576,7 +1583,7 @@ int denali_init(struct denali_nand_info *denali)  	denali->nand.ecc.write_page_raw = denali_write_page_raw;  	denali->nand.ecc.read_oob = denali_read_oob;  	denali->nand.ecc.write_oob = denali_write_oob; -	denali->nand.erase_cmd = denali_erase; +	denali->nand.erase = denali_erase;  	if (nand_scan_tail(&denali->mtd)) {  		ret = -ENXIO; @@ -1602,7 +1609,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);  | 
