diff options
Diffstat (limited to 'drivers/mtd/spi-nor')
-rw-r--r-- | drivers/mtd/spi-nor/atmel-quadspi.c | 23 | ||||
-rw-r--r-- | drivers/mtd/spi-nor/cadence-quadspi.c | 20 | ||||
-rw-r--r-- | drivers/mtd/spi-nor/intel-spi.c | 2 | ||||
-rw-r--r-- | drivers/mtd/spi-nor/nxp-spifi.c | 1 | ||||
-rw-r--r-- | drivers/mtd/spi-nor/spi-nor.c | 18 | ||||
-rw-r--r-- | drivers/mtd/spi-nor/stm32-quadspi.c | 6 |
6 files changed, 51 insertions, 19 deletions
diff --git a/drivers/mtd/spi-nor/atmel-quadspi.c b/drivers/mtd/spi-nor/atmel-quadspi.c index 6c5708bacad8..820048726b4f 100644 --- a/drivers/mtd/spi-nor/atmel-quadspi.c +++ b/drivers/mtd/spi-nor/atmel-quadspi.c @@ -34,7 +34,7 @@ #include <linux/of.h> #include <linux/io.h> -#include <linux/gpio.h> +#include <linux/gpio/consumer.h> /* QSPI register offsets */ #define QSPI_CR 0x0000 /* Control Register */ @@ -737,6 +737,26 @@ static int atmel_qspi_remove(struct platform_device *pdev) return 0; } +static int __maybe_unused atmel_qspi_suspend(struct device *dev) +{ + struct atmel_qspi *aq = dev_get_drvdata(dev); + + clk_disable_unprepare(aq->clk); + + return 0; +} + +static int __maybe_unused atmel_qspi_resume(struct device *dev) +{ + struct atmel_qspi *aq = dev_get_drvdata(dev); + + clk_prepare_enable(aq->clk); + + return atmel_qspi_init(aq); +} + +static SIMPLE_DEV_PM_OPS(atmel_qspi_pm_ops, atmel_qspi_suspend, + atmel_qspi_resume); static const struct of_device_id atmel_qspi_dt_ids[] = { { .compatible = "atmel,sama5d2-qspi" }, @@ -749,6 +769,7 @@ static struct platform_driver atmel_qspi_driver = { .driver = { .name = "atmel_qspi", .of_match_table = atmel_qspi_dt_ids, + .pm = &atmel_qspi_pm_ops, }, .probe = atmel_qspi_probe, .remove = atmel_qspi_remove, diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c index c3f7aaa5d18f..7a19dae717fa 100644 --- a/drivers/mtd/spi-nor/cadence-quadspi.c +++ b/drivers/mtd/spi-nor/cadence-quadspi.c @@ -525,15 +525,14 @@ static int cqspi_indirect_read_execute(struct spi_nor *nor, u8 *rxbuf, reg_base + CQSPI_REG_INDIRECTRD); while (remaining > 0) { - ret = wait_for_completion_timeout(&cqspi->transfer_complete, - msecs_to_jiffies - (CQSPI_READ_TIMEOUT_MS)); + if (!wait_for_completion_timeout(&cqspi->transfer_complete, + msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS))) + ret = -ETIMEDOUT; bytes_to_read = cqspi_get_rd_sram_level(cqspi); - if (!ret && bytes_to_read == 0) { + if (ret && bytes_to_read == 0) { dev_err(nor->dev, "Indirect read timeout, no bytes\n"); - ret = -ETIMEDOUT; goto failrd; } @@ -649,10 +648,8 @@ static int cqspi_indirect_write_execute(struct spi_nor *nor, loff_t to_addr, iowrite32_rep(cqspi->ahb_base, txbuf, DIV_ROUND_UP(write_bytes, 4)); - ret = wait_for_completion_timeout(&cqspi->transfer_complete, - msecs_to_jiffies - (CQSPI_TIMEOUT_MS)); - if (!ret) { + if (!wait_for_completion_timeout(&cqspi->transfer_complete, + msecs_to_jiffies(CQSPI_TIMEOUT_MS))) { dev_err(nor->dev, "Indirect write timeout\n"); ret = -ETIMEDOUT; goto failwr; @@ -986,9 +983,8 @@ static int cqspi_direct_read_execute(struct spi_nor *nor, u_char *buf, } dma_async_issue_pending(cqspi->rx_chan); - ret = wait_for_completion_timeout(&cqspi->rx_dma_complete, - msecs_to_jiffies(len)); - if (ret <= 0) { + if (!wait_for_completion_timeout(&cqspi->rx_dma_complete, + msecs_to_jiffies(len))) { dmaengine_terminate_sync(cqspi->rx_chan); dev_err(nor->dev, "DMA wait_for_completion_timeout\n"); ret = -ETIMEDOUT; diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/intel-spi.c index d2cbfc27826e..af0a22019516 100644 --- a/drivers/mtd/spi-nor/intel-spi.c +++ b/drivers/mtd/spi-nor/intel-spi.c @@ -908,7 +908,7 @@ struct intel_spi *intel_spi_probe(struct device *dev, if (!ispi->writeable || !writeable) ispi->nor.mtd.flags &= ~MTD_WRITEABLE; - ret = mtd_device_parse_register(&ispi->nor.mtd, NULL, NULL, &part, 1); + ret = mtd_device_register(&ispi->nor.mtd, &part, 1); if (ret) return ERR_PTR(ret); diff --git a/drivers/mtd/spi-nor/nxp-spifi.c b/drivers/mtd/spi-nor/nxp-spifi.c index 15374216d4d9..0c9094ec5966 100644 --- a/drivers/mtd/spi-nor/nxp-spifi.c +++ b/drivers/mtd/spi-nor/nxp-spifi.c @@ -436,6 +436,7 @@ static int nxp_spifi_probe(struct platform_device *pdev) } ret = nxp_spifi_setup_flash(spifi, flash_np); + of_node_put(flash_np); if (ret) { dev_err(&pdev->dev, "unable to setup flash chip\n"); goto dis_clks; diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index d9c368c44194..f028277fb1ce 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -2757,8 +2757,18 @@ static int spi_nor_init(struct spi_nor *nor) if ((nor->addr_width == 4) && (JEDEC_MFR(nor->info) != SNOR_MFR_SPANSION) && - !(nor->info->flags & SPI_NOR_4B_OPCODES)) + !(nor->info->flags & SPI_NOR_4B_OPCODES)) { + /* + * If the RESET# pin isn't hooked up properly, or the system + * otherwise doesn't perform a reset command in the boot + * sequence, it's impossible to 100% protect against unexpected + * reboots (e.g., crashes). Warn the user (or hopefully, system + * designer) that this is bad. + */ + WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET, + "enabling reset hack; may not recover from unexpected reboots\n"); set_4byte(nor, nor->info, 1); + } return 0; } @@ -2781,7 +2791,8 @@ void spi_nor_restore(struct spi_nor *nor) /* restore the addressing mode */ if ((nor->addr_width == 4) && (JEDEC_MFR(nor->info) != SNOR_MFR_SPANSION) && - !(nor->info->flags & SPI_NOR_4B_OPCODES)) + !(nor->info->flags & SPI_NOR_4B_OPCODES) && + (nor->flags & SNOR_F_BROKEN_RESET)) set_4byte(nor, nor->info, 0); } EXPORT_SYMBOL_GPL(spi_nor_restore); @@ -2911,6 +2922,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, params.hwcaps.mask |= SNOR_HWCAPS_READ_FAST; } + if (of_property_read_bool(np, "broken-flash-reset")) + nor->flags |= SNOR_F_BROKEN_RESET; + /* Some devices cannot do fast-read, no matter what DT tells us */ if (info->flags & SPI_NOR_NO_FR) params.hwcaps.mask &= ~SNOR_HWCAPS_READ_FAST; diff --git a/drivers/mtd/spi-nor/stm32-quadspi.c b/drivers/mtd/spi-nor/stm32-quadspi.c index 72553506a00b..13e9fc961d3b 100644 --- a/drivers/mtd/spi-nor/stm32-quadspi.c +++ b/drivers/mtd/spi-nor/stm32-quadspi.c @@ -355,7 +355,7 @@ static int stm32_qspi_read_reg(struct spi_nor *nor, struct device *dev = flash->qspi->dev; struct stm32_qspi_cmd cmd; - dev_dbg(dev, "read_reg: cmd:%#.2x buf:%p len:%#x\n", opcode, buf, len); + dev_dbg(dev, "read_reg: cmd:%#.2x buf:%pK len:%#x\n", opcode, buf, len); memset(&cmd, 0, sizeof(cmd)); cmd.opcode = opcode; @@ -376,7 +376,7 @@ static int stm32_qspi_write_reg(struct spi_nor *nor, u8 opcode, struct device *dev = flash->qspi->dev; struct stm32_qspi_cmd cmd; - dev_dbg(dev, "write_reg: cmd:%#.2x buf:%p len:%#x\n", opcode, buf, len); + dev_dbg(dev, "write_reg: cmd:%#.2x buf:%pK len:%#x\n", opcode, buf, len); memset(&cmd, 0, sizeof(cmd)); cmd.opcode = opcode; @@ -398,7 +398,7 @@ static ssize_t stm32_qspi_read(struct spi_nor *nor, loff_t from, size_t len, struct stm32_qspi_cmd cmd; int err; - dev_dbg(qspi->dev, "read(%#.2x): buf:%p from:%#.8x len:%#zx\n", + dev_dbg(qspi->dev, "read(%#.2x): buf:%pK from:%#.8x len:%#zx\n", nor->read_opcode, buf, (u32)from, len); memset(&cmd, 0, sizeof(cmd)); |