Message ID | 1370860014-1770-5-git-send-email-josh.wu@atmel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 18:26 Mon 10 Jun , Josh Wu wrote: > NFC has embedded sram which can use to transfer data. This patch enable reading > nand flash via NFC SRAM. It will minimize the CPU overhead. > > This driver has been tested on SAMA5D3X-EK with JFFS2, YAFFS2, UBIFS and > mtd-utils. > > Here puts the part of mtd_speedtest (read test) result as following: > Compare with non-NFC mtd_speedtest result, reading will reduce %45 cpu load > with increase %80 speed. > > - commands use to test: > # insmod /mnt/mtd_speedtest.ko dev=2 & > # top -n 30 -d 1 | grep speedtest > Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> Best Regards, J. > - test result: > ================================================= > mtd_speedtest: MTD device: 2 > mtd_speedtest: MTD device size 41943040, eraseblock size 131072, page size 2048, count of eraseblocks 320, pages per eraseblock 64, OOB size 64 > mtd_speedtest: testing eraseblock read speed > 509 495 root D 1164 0% 28% insmod /mnt/mtd_speedtest.ko dev=2 > 509 495 root D 1164 0% 25% insmod /mnt/mtd_speedtest.ko dev=2 > 509 495 root D 1164 0% 26% insmod /mnt/mtd_speedtest.ko dev=2 > mtd_speedtest: eraseblock read speed is 9403 KiB/s > mtd_speedtest: testing page read speed > 509 495 root R 1164 0% 31% insmod /mnt/mtd_speedtest.ko dev=2 > 509 495 root D 1164 0% 57% insmod /mnt/mtd_speedtest.ko dev=2 > 509 495 root D 1164 0% 53% insmod /mnt/mtd_speedtest.ko dev=2 > 509 495 root D 1164 0% 71% insmod /mnt/mtd_speedtest.ko dev=2 > mtd_speedtest: page read speed is 9258 KiB/s > > Signed-off-by: Josh Wu <josh.wu@atmel.com> > --- > v2 --> v3: > - if NFC sram address and size is specified then enable NFC sram read. > Otherwise disable NFC sram read. > > drivers/mtd/nand/atmel_nand.c | 163 +++++++++++++++++++++++++++++++++++++++-- > 1 file changed, 157 insertions(+), 6 deletions(-) > > diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c > index bf3370b..c2ec740 100644 > --- a/drivers/mtd/nand/atmel_nand.c > +++ b/drivers/mtd/nand/atmel_nand.c > @@ -96,9 +96,13 @@ struct atmel_nfc { > void __iomem *hsmc_regs; > void __iomem *sram_bank0; > dma_addr_t sram_bank0_phys; > + bool use_nfc_sram; > > bool is_initialized; > struct completion comp_nfc; > + > + /* Point to the sram bank which include readed data via NFC */ > + void __iomem *data_in_sram; > }; > static struct atmel_nfc nand_nfc; > > @@ -251,24 +255,47 @@ static int atmel_nand_set_enable_ready_pins(struct mtd_info *mtd) > return res; > } > } > + > return res; > } > > +static void memcpy32_fromio(void *trg, const void __iomem *src, size_t size) > +{ > + int i; > + u32 *t = trg; > + const __iomem u32 *s = src; > + > + for (i = 0; i < (size >> 2); i++) > + *t++ = readl_relaxed(s++); > +} > + > /* > * Minimal-overhead PIO for data access. > */ > static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len) > { > struct nand_chip *nand_chip = mtd->priv; > + struct atmel_nand_host *host = nand_chip->priv; > > - __raw_readsb(nand_chip->IO_ADDR_R, buf, len); > + if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { > + memcpy32_fromio(buf, host->nfc->data_in_sram, len); > + host->nfc->data_in_sram += len; > + } else { > + __raw_readsb(nand_chip->IO_ADDR_R, buf, len); > + } > } > > static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len) > { > struct nand_chip *nand_chip = mtd->priv; > + struct atmel_nand_host *host = nand_chip->priv; > > - __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2); > + if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { > + memcpy32_fromio(buf, host->nfc->data_in_sram, len); > + host->nfc->data_in_sram += len; > + } else { > + __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2); > + } > } > > static void atmel_write_buf8(struct mtd_info *mtd, const u8 *buf, int len) > @@ -290,6 +317,40 @@ static void dma_complete_func(void *completion) > complete(completion); > } > > +static int nfc_set_sram_bank(struct atmel_nand_host *host, unsigned int bank) > +{ > + /* NFC only has two banks. Must be 0 or 1 */ > + if (bank > 1) > + return -EINVAL; > + > + if (bank) { > + /* Only for a 2k-page or lower flash, NFC can handle 2 banks */ > + if (host->mtd.writesize > 2048) > + return -EINVAL; > + nfc_writel(host->nfc->hsmc_regs, BANK, ATMEL_HSMC_NFC_BANK1); > + } else { > + nfc_writel(host->nfc->hsmc_regs, BANK, ATMEL_HSMC_NFC_BANK0); > + } > + > + return 0; > +} > + > +static uint nfc_get_sram_off(struct atmel_nand_host *host) > +{ > + if (nfc_readl(host->nfc->hsmc_regs, BANK) & ATMEL_HSMC_NFC_BANK1) > + return NFC_SRAM_BANK1_OFFSET; > + else > + return 0; > +} > + > +static dma_addr_t nfc_sram_phys(struct atmel_nand_host *host) > +{ > + if (nfc_readl(host->nfc->hsmc_regs, BANK) & ATMEL_HSMC_NFC_BANK1) > + return host->nfc->sram_bank0_phys + NFC_SRAM_BANK1_OFFSET; > + else > + return host->nfc->sram_bank0_phys; > +} > + > static int atmel_nand_dma_op(struct mtd_info *mtd, void *buf, int len, > int is_read) > { > @@ -303,6 +364,7 @@ static int atmel_nand_dma_op(struct mtd_info *mtd, void *buf, int len, > void *p = buf; > int err = -EIO; > enum dma_data_direction dir = is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; > + struct atmel_nfc *nfc = host->nfc; > > if (buf >= high_memory) > goto err_buf; > @@ -319,7 +381,12 @@ static int atmel_nand_dma_op(struct mtd_info *mtd, void *buf, int len, > } > > if (is_read) { > - dma_src_addr = host->io_phys; > + if (nfc && nfc->data_in_sram) > + dma_src_addr = nfc_sram_phys(host) + (nfc->data_in_sram > + - (nfc->sram_bank0 + nfc_get_sram_off(host))); > + else > + dma_src_addr = host->io_phys; > + > dma_dst_addr = phys_addr; > } else { > dma_src_addr = phys_addr; > @@ -346,6 +413,10 @@ static int atmel_nand_dma_op(struct mtd_info *mtd, void *buf, int len, > dma_async_issue_pending(host->dma_chan); > wait_for_completion(&host->comp); > > + if (is_read && nfc && nfc->data_in_sram) > + /* After read data from SRAM, need to increase the position */ > + nfc->data_in_sram += len; > + > err = 0; > > err_dma: > @@ -856,7 +927,8 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, > unsigned long end_time; > int bitflips = 0; > > - pmecc_enable(host, NAND_ECC_READ); > + if (!host->nfc || !host->nfc->use_nfc_sram) > + pmecc_enable(host, NAND_ECC_READ); > > chip->read_buf(mtd, buf, eccsize); > chip->read_buf(mtd, oob, mtd->oobsize); > @@ -1669,6 +1741,7 @@ static void nfc_nand_command(struct mtd_info *mtd, unsigned int command, > unsigned int addr1234 = 0; > unsigned int cycle0 = 0; > bool do_addr = true; > + host->nfc->data_in_sram = NULL; > > dev_dbg(host->dev, "%s: cmd = 0x%02x, col = 0x%08x, page = 0x%08x\n", > __func__, command, column, page_addr); > @@ -1710,6 +1783,16 @@ static void nfc_nand_command(struct mtd_info *mtd, unsigned int command, > command = NAND_CMD_READ0; /* only READ0 is valid */ > cmd1 = command << 2; > } > + if (host->nfc->use_nfc_sram) { > + /* Enable Data transfer to sram */ > + dataen = NFCADDR_CMD_DATAEN; > + > + /* Need enable PMECC now, since NFC will transfer > + * data in bus after sending nfc read command. > + */ > + if (chip->ecc.mode == NAND_ECC_HW && host->has_pmecc) > + pmecc_enable(host, NAND_ECC_READ); > + } > > cmd2 = NAND_CMD_READSTART << 10; > vcmd2 = NFCADDR_CMD_VCMD2; > @@ -1731,6 +1814,10 @@ static void nfc_nand_command(struct mtd_info *mtd, unsigned int command, > nfc_addr_cmd = cmd1 | cmd2 | vcmd2 | acycle | csid | dataen | nfcwr; > nfc_send_command(host, nfc_addr_cmd, addr1234, cycle0); > > + if (dataen == NFCADDR_CMD_DATAEN) > + if (nfc_wait_interrupt(host, NFC_SR_XFR_DONE)) > + dev_err(host->dev, "something wrong, No XFR_DONE interrupt comes.\n"); > + > /* > * Program and erase have their own busy handlers status, sequential > * in, and deplete1 need no delay. > @@ -1748,12 +1835,65 @@ static void nfc_nand_command(struct mtd_info *mtd, unsigned int command, > return; > > case NAND_CMD_READ0: > + if (dataen == NFCADDR_CMD_DATAEN) { > + host->nfc->data_in_sram = host->nfc->sram_bank0 + > + nfc_get_sram_off(host); > + return; > + } > /* fall through */ > default: > nfc_wait_interrupt(host, NFC_SR_RB_EDGE); > } > } > > +static int nfc_sram_init(struct mtd_info *mtd) > +{ > + struct nand_chip *chip = mtd->priv; > + struct atmel_nand_host *host = chip->priv; > + int res = 0; > + > + /* Initialize the NFC CFG register */ > + unsigned int cfg_nfc = 0; > + > + /* set page size and oob layout */ > + switch (mtd->writesize) { > + case 512: > + cfg_nfc = NFC_CFG_PAGESIZE_512; > + break; > + case 1024: > + cfg_nfc = NFC_CFG_PAGESIZE_1024; > + break; > + case 2048: > + cfg_nfc = NFC_CFG_PAGESIZE_2048; > + break; > + case 4096: > + cfg_nfc = NFC_CFG_PAGESIZE_4096; > + break; > + case 8192: > + cfg_nfc = NFC_CFG_PAGESIZE_8192; > + break; > + default: > + dev_err(host->dev, "Unsupported page size for NFC.\n"); > + res = -ENXIO; > + return res; > + } > + > + /* oob bytes size = (NFCSPARESIZE + 1) * 4 > + * Max support spare size is 512 bytes. */ > + cfg_nfc |= (((mtd->oobsize / 4) - 1) << 24 & NFC_CFG_NFC_SPARESIZE); > + /* default set a max timeout */ > + cfg_nfc |= NFC_CFG_RSPARE | > + NFC_CFG_NFC_DTOCYC | NFC_CFG_NFC_DTOMUL; > + > + nfc_writel(host->nfc->hsmc_regs, CFG, cfg_nfc); > + > + nfc_set_sram_bank(host, 0); > + > + dev_info(host->dev, "Using NFC Sram read\n"); > + > + return 0; > +} > + > static struct platform_driver atmel_nand_nfc_driver; > /* > * Probe for the NAND device. > @@ -1928,6 +2068,15 @@ static int __init atmel_nand_probe(struct platform_device *pdev) > goto err_hw_ecc; > } > > + /* initialize the nfc configuration register */ > + if (host->nfc && host->nfc->use_nfc_sram) { > + res = nfc_sram_init(mtd); > + if (res) { > + host->nfc->use_nfc_sram = false; > + dev_err(host->dev, "Disable use nfc sram for data transfer.\n"); > + } > + } > + > /* second phase scan */ > if (nand_scan_tail(mtd)) { > res = -ENXIO; > @@ -2009,11 +2158,13 @@ static int atmel_nand_nfc_probe(struct platform_device *pdev) > nfc_sram = platform_get_resource(pdev, IORESOURCE_MEM, 2); > if (nfc_sram) { > nfc->sram_bank0 = devm_ioremap_resource(&pdev->dev, nfc_sram); > - if (IS_ERR(nfc->sram_bank0)) > + if (IS_ERR(nfc->sram_bank0)) { > dev_warn(&pdev->dev, "Fail to ioremap the NFC sram with error: %ld. So disable NFC sram.\n", > PTR_ERR(nfc->sram_bank0)); > - else > + } else { > + nfc->use_nfc_sram = true; > nfc->sram_bank0_phys = (dma_addr_t)nfc_sram->start; > + } > } > > nfc->is_initialized = true; > -- > 1.7.9.5 >
================================================= mtd_speedtest: MTD device: 2 mtd_speedtest: MTD device size 41943040, eraseblock size 131072, page size 2048, count of eraseblocks 320, pages per eraseblock 64, OOB size 64 mtd_speedtest: testing eraseblock read speed 509 495 root D 1164 0% 28% insmod /mnt/mtd_speedtest.ko dev=2 509 495 root D 1164 0% 25% insmod /mnt/mtd_speedtest.ko dev=2 509 495 root D 1164 0% 26% insmod /mnt/mtd_speedtest.ko dev=2 mtd_speedtest: eraseblock read speed is 9403 KiB/s mtd_speedtest: testing page read speed 509 495 root R 1164 0% 31% insmod /mnt/mtd_speedtest.ko dev=2 509 495 root D 1164 0% 57% insmod /mnt/mtd_speedtest.ko dev=2 509 495 root D 1164 0% 53% insmod /mnt/mtd_speedtest.ko dev=2 509 495 root D 1164 0% 71% insmod /mnt/mtd_speedtest.ko dev=2 mtd_speedtest: page read speed is 9258 KiB/s Signed-off-by: Josh Wu <josh.wu@atmel.com> --- v2 --> v3: - if NFC sram address and size is specified then enable NFC sram read. Otherwise disable NFC sram read. drivers/mtd/nand/atmel_nand.c | 163 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 157 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index bf3370b..c2ec740 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c @@ -96,9 +96,13 @@ struct atmel_nfc { void __iomem *hsmc_regs; void __iomem *sram_bank0; dma_addr_t sram_bank0_phys; + bool use_nfc_sram; bool is_initialized; struct completion comp_nfc; + + /* Point to the sram bank which include readed data via NFC */ + void __iomem *data_in_sram; }; static struct atmel_nfc nand_nfc; @@ -251,24 +255,47 @@ static int atmel_nand_set_enable_ready_pins(struct mtd_info *mtd) return res; } } + return res; } +static void memcpy32_fromio(void *trg, const void __iomem *src, size_t size) +{ + int i; + u32 *t = trg; + const __iomem u32 *s = src; + + for (i = 0; i < (size >> 2); i++) + *t++ = readl_relaxed(s++); +} + /* * Minimal-overhead PIO for data access. */ static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len) { struct nand_chip *nand_chip = mtd->priv; + struct atmel_nand_host *host = nand_chip->priv; - __raw_readsb(nand_chip->IO_ADDR_R, buf, len); + if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { + memcpy32_fromio(buf, host->nfc->data_in_sram, len); + host->nfc->data_in_sram += len; + } else { + __raw_readsb(nand_chip->IO_ADDR_R, buf, len); + } } static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len) { struct nand_chip *nand_chip = mtd->priv; + struct atmel_nand_host *host = nand_chip->priv; - __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2); + if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { + memcpy32_fromio(buf, host->nfc->data_in_sram, len); + host->nfc->data_in_sram += len; + } else { + __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2); + } } static void atmel_write_buf8(struct mtd_info *mtd, const u8 *buf, int len) @@ -290,6 +317,40 @@ static void dma_complete_func(void *completion) complete(completion); } +static int nfc_set_sram_bank(struct atmel_nand_host *host, unsigned int bank) +{ + /* NFC only has two banks. Must be 0 or 1 */ + if (bank > 1) + return -EINVAL; + + if (bank) { + /* Only for a 2k-page or lower flash, NFC can handle 2 banks */ + if (host->mtd.writesize > 2048) + return -EINVAL; + nfc_writel(host->nfc->hsmc_regs, BANK, ATMEL_HSMC_NFC_BANK1); + } else { + nfc_writel(host->nfc->hsmc_regs, BANK, ATMEL_HSMC_NFC_BANK0); + } + + return 0; +} + +static uint nfc_get_sram_off(struct atmel_nand_host *host) +{ + if (nfc_readl(host->nfc->hsmc_regs, BANK) & ATMEL_HSMC_NFC_BANK1) + return NFC_SRAM_BANK1_OFFSET; + else + return 0; +} + +static dma_addr_t nfc_sram_phys(struct atmel_nand_host *host) +{ + if (nfc_readl(host->nfc->hsmc_regs, BANK) & ATMEL_HSMC_NFC_BANK1) + return host->nfc->sram_bank0_phys + NFC_SRAM_BANK1_OFFSET; + else + return host->nfc->sram_bank0_phys; +} + static int atmel_nand_dma_op(struct mtd_info *mtd, void *buf, int len, int is_read) { @@ -303,6 +364,7 @@ static int atmel_nand_dma_op(struct mtd_info *mtd, void *buf, int len, void *p = buf; int err = -EIO; enum dma_data_direction dir = is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + struct atmel_nfc *nfc = host->nfc; if (buf >= high_memory) goto err_buf; @@ -319,7 +381,12 @@ static int atmel_nand_dma_op(struct mtd_info *mtd, void *buf, int len, } if (is_read) { - dma_src_addr = host->io_phys; + if (nfc && nfc->data_in_sram) + dma_src_addr = nfc_sram_phys(host) + (nfc->data_in_sram + - (nfc->sram_bank0 + nfc_get_sram_off(host))); + else + dma_src_addr = host->io_phys; + dma_dst_addr = phys_addr; } else { dma_src_addr = phys_addr; @@ -346,6 +413,10 @@ static int atmel_nand_dma_op(struct mtd_info *mtd, void *buf, int len, dma_async_issue_pending(host->dma_chan); wait_for_completion(&host->comp); + if (is_read && nfc && nfc->data_in_sram) + /* After read data from SRAM, need to increase the position */ + nfc->data_in_sram += len; + err = 0; err_dma: @@ -856,7 +927,8 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, unsigned long end_time; int bitflips = 0; - pmecc_enable(host, NAND_ECC_READ); + if (!host->nfc || !host->nfc->use_nfc_sram) + pmecc_enable(host, NAND_ECC_READ); chip->read_buf(mtd, buf, eccsize); chip->read_buf(mtd, oob, mtd->oobsize); @@ -1669,6 +1741,7 @@ static void nfc_nand_command(struct mtd_info *mtd, unsigned int command, unsigned int addr1234 = 0; unsigned int cycle0 = 0; bool do_addr = true; + host->nfc->data_in_sram = NULL; dev_dbg(host->dev, "%s: cmd = 0x%02x, col = 0x%08x, page = 0x%08x\n", __func__, command, column, page_addr); @@ -1710,6 +1783,16 @@ static void nfc_nand_command(struct mtd_info *mtd, unsigned int command, command = NAND_CMD_READ0; /* only READ0 is valid */ cmd1 = command << 2; } + if (host->nfc->use_nfc_sram) { + /* Enable Data transfer to sram */ + dataen = NFCADDR_CMD_DATAEN; + + /* Need enable PMECC now, since NFC will transfer + * data in bus after sending nfc read command. + */ + if (chip->ecc.mode == NAND_ECC_HW && host->has_pmecc) + pmecc_enable(host, NAND_ECC_READ); + } cmd2 = NAND_CMD_READSTART << 10; vcmd2 = NFCADDR_CMD_VCMD2; @@ -1731,6 +1814,10 @@ static void nfc_nand_command(struct mtd_info *mtd, unsigned int command, nfc_addr_cmd = cmd1 | cmd2 | vcmd2 | acycle | csid | dataen | nfcwr; nfc_send_command(host, nfc_addr_cmd, addr1234, cycle0); + if (dataen == NFCADDR_CMD_DATAEN) + if (nfc_wait_interrupt(host, NFC_SR_XFR_DONE)) + dev_err(host->dev, "something wrong, No XFR_DONE interrupt comes.\n"); + /* * Program and erase have their own busy handlers status, sequential * in, and deplete1 need no delay. @@ -1748,12 +1835,65 @@ static void nfc_nand_command(struct mtd_info *mtd, unsigned int command, return; case NAND_CMD_READ0: + if (dataen == NFCADDR_CMD_DATAEN) { + host->nfc->data_in_sram = host->nfc->sram_bank0 + + nfc_get_sram_off(host); + return; + } /* fall through */ default: nfc_wait_interrupt(host, NFC_SR_RB_EDGE); } } +static int nfc_sram_init(struct mtd_info *mtd) +{ + struct nand_chip *chip = mtd->priv; + struct atmel_nand_host *host = chip->priv; + int res = 0; + + /* Initialize the NFC CFG register */ + unsigned int cfg_nfc = 0; + + /* set page size and oob layout */ + switch (mtd->writesize) { + case 512: + cfg_nfc = NFC_CFG_PAGESIZE_512; + break; + case 1024: + cfg_nfc = NFC_CFG_PAGESIZE_1024; + break; + case 2048: + cfg_nfc = NFC_CFG_PAGESIZE_2048; + break; + case 4096: + cfg_nfc = NFC_CFG_PAGESIZE_4096; + break; + case 8192: + cfg_nfc = NFC_CFG_PAGESIZE_8192; + break; + default: + dev_err(host->dev, "Unsupported page size for NFC.\n"); + res = -ENXIO; + return res; + } + + /* oob bytes size = (NFCSPARESIZE + 1) * 4 + * Max support spare size is 512 bytes. */ + cfg_nfc |= (((mtd->oobsize / 4) - 1) << 24 & NFC_CFG_NFC_SPARESIZE); + /* default set a max timeout */ + cfg_nfc |= NFC_CFG_RSPARE | + NFC_CFG_NFC_DTOCYC | NFC_CFG_NFC_DTOMUL; + + nfc_writel(host->nfc->hsmc_regs, CFG, cfg_nfc); + + nfc_set_sram_bank(host, 0); + + dev_info(host->dev, "Using NFC Sram read\n"); + + return 0; +} + static struct platform_driver atmel_nand_nfc_driver; /* * Probe for the NAND device. @@ -1928,6 +2068,15 @@ static int __init atmel_nand_probe(struct platform_device *pdev) goto err_hw_ecc; } + /* initialize the nfc configuration register */ + if (host->nfc && host->nfc->use_nfc_sram) { + res = nfc_sram_init(mtd); + if (res) { + host->nfc->use_nfc_sram = false; + dev_err(host->dev, "Disable use nfc sram for data transfer.\n"); + } + } + /* second phase scan */ if (nand_scan_tail(mtd)) { res = -ENXIO; @@ -2009,11 +2158,13 @@ static int atmel_nand_nfc_probe(struct platform_device *pdev) nfc_sram = platform_get_resource(pdev, IORESOURCE_MEM, 2); if (nfc_sram) { nfc->sram_bank0 = devm_ioremap_resource(&pdev->dev, nfc_sram); - if (IS_ERR(nfc->sram_bank0)) + if (IS_ERR(nfc->sram_bank0)) { dev_warn(&pdev->dev, "Fail to ioremap the NFC sram with error: %ld. So disable NFC sram.\n", PTR_ERR(nfc->sram_bank0)); - else + } else { + nfc->use_nfc_sram = true; nfc->sram_bank0_phys = (dma_addr_t)nfc_sram->start; + } } nfc->is_initialized = true;