Commit 442f201b authored by Boris BREZILLON's avatar Boris BREZILLON Committed by Brian Norris

mtd: nand: denali: use the mtd instance embedded in struct nand_chip

struct nand_chip now embeds an mtd device. Make use of this mtd instance.
Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
parent a723bf6a
...@@ -75,7 +75,10 @@ MODULE_PARM_DESC(onfi_timing_mode, ...@@ -75,7 +75,10 @@ MODULE_PARM_DESC(onfi_timing_mode,
* this macro allows us to convert from an MTD structure to our own * this macro allows us to convert from an MTD structure to our own
* device context (denali) structure. * device context (denali) structure.
*/ */
#define mtd_to_denali(m) container_of(m, struct denali_nand_info, mtd) static inline struct denali_nand_info *mtd_to_denali(struct mtd_info *mtd)
{
return container_of(mtd_to_nand(mtd), struct denali_nand_info, nand);
}
/* /*
* These constants are defined by the driver to enable common driver * These constants are defined by the driver to enable common driver
...@@ -986,6 +989,8 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, ...@@ -986,6 +989,8 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf,
* than one NAND connected. * than one NAND connected.
*/ */
if (err_byte < ECC_SECTOR_SIZE) { if (err_byte < ECC_SECTOR_SIZE) {
struct mtd_info *mtd =
nand_to_mtd(&denali->nand);
int offset; int offset;
offset = (err_sector * offset = (err_sector *
...@@ -995,7 +1000,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, ...@@ -995,7 +1000,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf,
err_device; err_device;
/* correct the ECC error */ /* correct the ECC error */
buf[offset] ^= err_correction_value; buf[offset] ^= err_correction_value;
denali->mtd.ecc_stats.corrected++; mtd->ecc_stats.corrected++;
bitflips++; bitflips++;
} }
} else { } else {
...@@ -1062,7 +1067,7 @@ static int write_page(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -1062,7 +1067,7 @@ static int write_page(struct mtd_info *mtd, struct nand_chip *chip,
{ {
struct denali_nand_info *denali = mtd_to_denali(mtd); struct denali_nand_info *denali = mtd_to_denali(mtd);
dma_addr_t addr = denali->buf.dma_buf; dma_addr_t addr = denali->buf.dma_buf;
size_t size = denali->mtd.writesize + denali->mtd.oobsize; size_t size = mtd->writesize + mtd->oobsize;
uint32_t irq_status; uint32_t irq_status;
uint32_t irq_mask = INTR_STATUS__DMA_CMD_COMP | uint32_t irq_mask = INTR_STATUS__DMA_CMD_COMP |
INTR_STATUS__PROGRAM_FAIL; INTR_STATUS__PROGRAM_FAIL;
...@@ -1160,7 +1165,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -1160,7 +1165,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
struct denali_nand_info *denali = mtd_to_denali(mtd); struct denali_nand_info *denali = mtd_to_denali(mtd);
dma_addr_t addr = denali->buf.dma_buf; dma_addr_t addr = denali->buf.dma_buf;
size_t size = denali->mtd.writesize + denali->mtd.oobsize; size_t size = mtd->writesize + mtd->oobsize;
uint32_t irq_status; uint32_t irq_status;
uint32_t irq_mask = INTR_STATUS__ECC_TRANSACTION_DONE | uint32_t irq_mask = INTR_STATUS__ECC_TRANSACTION_DONE |
...@@ -1193,14 +1198,14 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -1193,14 +1198,14 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip,
denali_enable_dma(denali, false); denali_enable_dma(denali, false);
if (check_erased_page) { if (check_erased_page) {
read_oob_data(&denali->mtd, chip->oob_poi, denali->page); read_oob_data(mtd, chip->oob_poi, denali->page);
/* check ECC failures that may have occurred on erased pages */ /* check ECC failures that may have occurred on erased pages */
if (check_erased_page) { if (check_erased_page) {
if (!is_erased(buf, denali->mtd.writesize)) if (!is_erased(buf, mtd->writesize))
denali->mtd.ecc_stats.failed++; mtd->ecc_stats.failed++;
if (!is_erased(buf, denali->mtd.oobsize)) if (!is_erased(buf, mtd->oobsize))
denali->mtd.ecc_stats.failed++; mtd->ecc_stats.failed++;
} }
} }
return max_bitflips; return max_bitflips;
...@@ -1211,7 +1216,7 @@ static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, ...@@ -1211,7 +1216,7 @@ static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
{ {
struct denali_nand_info *denali = mtd_to_denali(mtd); struct denali_nand_info *denali = mtd_to_denali(mtd);
dma_addr_t addr = denali->buf.dma_buf; dma_addr_t addr = denali->buf.dma_buf;
size_t size = denali->mtd.writesize + denali->mtd.oobsize; size_t size = mtd->writesize + mtd->oobsize;
uint32_t irq_mask = INTR_STATUS__DMA_CMD_COMP; uint32_t irq_mask = INTR_STATUS__DMA_CMD_COMP;
if (page != denali->page) { if (page != denali->page) {
...@@ -1428,6 +1433,7 @@ static void denali_drv_init(struct denali_nand_info *denali) ...@@ -1428,6 +1433,7 @@ static void denali_drv_init(struct denali_nand_info *denali)
int denali_init(struct denali_nand_info *denali) int denali_init(struct denali_nand_info *denali)
{ {
struct mtd_info *mtd = nand_to_mtd(&denali->nand);
int ret; int ret;
if (denali->platform == INTEL_CE4100) { if (denali->platform == INTEL_CE4100) {
...@@ -1447,7 +1453,7 @@ int denali_init(struct denali_nand_info *denali) ...@@ -1447,7 +1453,7 @@ int denali_init(struct denali_nand_info *denali)
if (!denali->buf.buf) if (!denali->buf.buf)
return -ENOMEM; return -ENOMEM;
denali->mtd.dev.parent = denali->dev; mtd->dev.parent = denali->dev;
denali_hw_init(denali); denali_hw_init(denali);
denali_drv_init(denali); denali_drv_init(denali);
...@@ -1463,8 +1469,8 @@ int denali_init(struct denali_nand_info *denali) ...@@ -1463,8 +1469,8 @@ int denali_init(struct denali_nand_info *denali)
/* now that our ISR is registered, we can enable interrupts */ /* now that our ISR is registered, we can enable interrupts */
denali_set_intr_modes(denali, true); denali_set_intr_modes(denali, true);
denali->mtd.name = "denali-nand"; mtd->name = "denali-nand";
denali->mtd.priv = &denali->nand; mtd->priv = &denali->nand;
/* register the driver with the NAND core subsystem */ /* register the driver with the NAND core subsystem */
denali->nand.select_chip = denali_select_chip; denali->nand.select_chip = denali_select_chip;
...@@ -1477,7 +1483,7 @@ int denali_init(struct denali_nand_info *denali) ...@@ -1477,7 +1483,7 @@ int denali_init(struct denali_nand_info *denali)
* this is the first stage in a two step process to register * this is the first stage in a two step process to register
* with the nand subsystem * with the nand subsystem
*/ */
if (nand_scan_ident(&denali->mtd, denali->max_banks, NULL)) { if (nand_scan_ident(mtd, denali->max_banks, NULL)) {
ret = -ENXIO; ret = -ENXIO;
goto failed_req_irq; goto failed_req_irq;
} }
...@@ -1485,7 +1491,7 @@ int denali_init(struct denali_nand_info *denali) ...@@ -1485,7 +1491,7 @@ int denali_init(struct denali_nand_info *denali)
/* allocate the right size buffer now */ /* allocate the right size buffer now */
devm_kfree(denali->dev, denali->buf.buf); devm_kfree(denali->dev, denali->buf.buf);
denali->buf.buf = devm_kzalloc(denali->dev, denali->buf.buf = devm_kzalloc(denali->dev,
denali->mtd.writesize + denali->mtd.oobsize, mtd->writesize + mtd->oobsize,
GFP_KERNEL); GFP_KERNEL);
if (!denali->buf.buf) { if (!denali->buf.buf) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -1500,7 +1506,7 @@ int denali_init(struct denali_nand_info *denali) ...@@ -1500,7 +1506,7 @@ int denali_init(struct denali_nand_info *denali)
} }
denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf, denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf,
denali->mtd.writesize + denali->mtd.oobsize, mtd->writesize + mtd->oobsize,
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) { if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) {
dev_err(denali->dev, "Spectra: failed to map DMA buffer\n"); dev_err(denali->dev, "Spectra: failed to map DMA buffer\n");
...@@ -1521,10 +1527,10 @@ int denali_init(struct denali_nand_info *denali) ...@@ -1521,10 +1527,10 @@ int denali_init(struct denali_nand_info *denali)
denali->nand.bbt_erase_shift += (denali->devnum - 1); denali->nand.bbt_erase_shift += (denali->devnum - 1);
denali->nand.phys_erase_shift = denali->nand.bbt_erase_shift; denali->nand.phys_erase_shift = denali->nand.bbt_erase_shift;
denali->nand.chip_shift += (denali->devnum - 1); denali->nand.chip_shift += (denali->devnum - 1);
denali->mtd.writesize <<= (denali->devnum - 1); mtd->writesize <<= (denali->devnum - 1);
denali->mtd.oobsize <<= (denali->devnum - 1); mtd->oobsize <<= (denali->devnum - 1);
denali->mtd.erasesize <<= (denali->devnum - 1); mtd->erasesize <<= (denali->devnum - 1);
denali->mtd.size = denali->nand.numchips * denali->nand.chipsize; mtd->size = denali->nand.numchips * denali->nand.chipsize;
denali->bbtskipbytes *= denali->devnum; denali->bbtskipbytes *= denali->devnum;
/* /*
...@@ -1551,16 +1557,16 @@ int denali_init(struct denali_nand_info *denali) ...@@ -1551,16 +1557,16 @@ int denali_init(struct denali_nand_info *denali)
* SLC if possible. * SLC if possible.
* */ * */
if (!nand_is_slc(&denali->nand) && if (!nand_is_slc(&denali->nand) &&
(denali->mtd.oobsize > (denali->bbtskipbytes + (mtd->oobsize > (denali->bbtskipbytes +
ECC_15BITS * (denali->mtd.writesize / ECC_15BITS * (mtd->writesize /
ECC_SECTOR_SIZE)))) { ECC_SECTOR_SIZE)))) {
/* if MLC OOB size is large enough, use 15bit ECC*/ /* if MLC OOB size is large enough, use 15bit ECC*/
denali->nand.ecc.strength = 15; denali->nand.ecc.strength = 15;
denali->nand.ecc.layout = &nand_15bit_oob; denali->nand.ecc.layout = &nand_15bit_oob;
denali->nand.ecc.bytes = ECC_15BITS; denali->nand.ecc.bytes = ECC_15BITS;
iowrite32(15, denali->flash_reg + ECC_CORRECTION); iowrite32(15, denali->flash_reg + ECC_CORRECTION);
} else if (denali->mtd.oobsize < (denali->bbtskipbytes + } else if (mtd->oobsize < (denali->bbtskipbytes +
ECC_8BITS * (denali->mtd.writesize / ECC_8BITS * (mtd->writesize /
ECC_SECTOR_SIZE))) { ECC_SECTOR_SIZE))) {
pr_err("Your NAND chip OOB is not large enough to contain 8bit ECC correction codes"); pr_err("Your NAND chip OOB is not large enough to contain 8bit ECC correction codes");
goto failed_req_irq; goto failed_req_irq;
...@@ -1574,11 +1580,11 @@ int denali_init(struct denali_nand_info *denali) ...@@ -1574,11 +1580,11 @@ int denali_init(struct denali_nand_info *denali)
denali->nand.ecc.bytes *= denali->devnum; denali->nand.ecc.bytes *= denali->devnum;
denali->nand.ecc.strength *= denali->devnum; denali->nand.ecc.strength *= denali->devnum;
denali->nand.ecc.layout->eccbytes *= denali->nand.ecc.layout->eccbytes *=
denali->mtd.writesize / ECC_SECTOR_SIZE; mtd->writesize / ECC_SECTOR_SIZE;
denali->nand.ecc.layout->oobfree[0].offset = denali->nand.ecc.layout->oobfree[0].offset =
denali->bbtskipbytes + denali->nand.ecc.layout->eccbytes; denali->bbtskipbytes + denali->nand.ecc.layout->eccbytes;
denali->nand.ecc.layout->oobfree[0].length = denali->nand.ecc.layout->oobfree[0].length =
denali->mtd.oobsize - denali->nand.ecc.layout->eccbytes - mtd->oobsize - denali->nand.ecc.layout->eccbytes -
denali->bbtskipbytes; denali->bbtskipbytes;
/* /*
...@@ -1586,7 +1592,7 @@ int denali_init(struct denali_nand_info *denali) ...@@ -1586,7 +1592,7 @@ int denali_init(struct denali_nand_info *denali)
* contained by each nand chip. blksperchip will help driver to * contained by each nand chip. blksperchip will help driver to
* know how many blocks is taken by FW. * know how many blocks is taken by FW.
*/ */
denali->totalblks = denali->mtd.size >> denali->nand.phys_erase_shift; denali->totalblks = mtd->size >> denali->nand.phys_erase_shift;
denali->blksperchip = denali->totalblks / denali->nand.numchips; denali->blksperchip = denali->totalblks / denali->nand.numchips;
/* override the default read operations */ /* override the default read operations */
...@@ -1599,12 +1605,12 @@ int denali_init(struct denali_nand_info *denali) ...@@ -1599,12 +1605,12 @@ int denali_init(struct denali_nand_info *denali)
denali->nand.ecc.write_oob = denali_write_oob; denali->nand.ecc.write_oob = denali_write_oob;
denali->nand.erase = denali_erase; denali->nand.erase = denali_erase;
if (nand_scan_tail(&denali->mtd)) { if (nand_scan_tail(mtd)) {
ret = -ENXIO; ret = -ENXIO;
goto failed_req_irq; goto failed_req_irq;
} }
ret = mtd_device_register(&denali->mtd, NULL, 0); ret = mtd_device_register(mtd, NULL, 0);
if (ret) { if (ret) {
dev_err(denali->dev, "Spectra: Failed to register MTD: %d\n", dev_err(denali->dev, "Spectra: Failed to register MTD: %d\n",
ret); ret);
...@@ -1622,14 +1628,15 @@ EXPORT_SYMBOL(denali_init); ...@@ -1622,14 +1628,15 @@ EXPORT_SYMBOL(denali_init);
/* driver exit point */ /* driver exit point */
void denali_remove(struct denali_nand_info *denali) void denali_remove(struct denali_nand_info *denali)
{ {
struct mtd_info *mtd = nand_to_mtd(&denali->nand);
/* /*
* Pre-compute DMA buffer size to avoid any problems in case * Pre-compute DMA buffer size to avoid any problems in case
* nand_release() ever changes in a way that mtd->writesize and * nand_release() ever changes in a way that mtd->writesize and
* mtd->oobsize are not reliable after this call. * mtd->oobsize are not reliable after this call.
*/ */
int bufsize = denali->mtd.writesize + denali->mtd.oobsize; int bufsize = mtd->writesize + mtd->oobsize;
nand_release(&denali->mtd); nand_release(mtd);
denali_irq_cleanup(denali->irq, denali); denali_irq_cleanup(denali->irq, denali);
dma_unmap_single(denali->dev, denali->buf.dma_buf, bufsize, dma_unmap_single(denali->dev, denali->buf.dma_buf, bufsize,
DMA_BIDIRECTIONAL); DMA_BIDIRECTIONAL);
......
...@@ -450,7 +450,6 @@ struct nand_buf { ...@@ -450,7 +450,6 @@ struct nand_buf {
#define DT 3 #define DT 3
struct denali_nand_info { struct denali_nand_info {
struct mtd_info mtd;
struct nand_chip nand; struct nand_chip nand;
int flash_bank; /* currently selected chip */ int flash_bank; /* currently selected chip */
int status; int status;
......
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