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: Boris Brezillon <boris.brezillon@free-electrons.com> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
This commit is contained in:
parent
a723bf6a58
commit
442f201b93
|
@ -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,
|
||||||
* 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,
|
||||||
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,
|
||||||
{
|
{
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
{
|
{
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
/* 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)
|
||||||
* 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)
|
||||||
/* 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
* 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)
|
||||||
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)
|
||||||
* 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)
|
||||||
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);
|
||||||
/* 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 {
|
||||||
#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;
|
||||||
|
|
Loading…
Reference in New Issue