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); |
