Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d0eea5d8 authored by Boris Brezillon's avatar Boris Brezillon
Browse files

Merge tag 'spi-nor/for-4.19' of git://git.infradead.org/linux-mtd into mtd/next

Pull SPI NOR updates from Boris Brezillon:
"
 Core changes:
 - Apply reset hacks only when reset is explicitly marked as broken in
   the DT

 Driver changes:
 - Minor cleanup/fixes in the m25p80 driver
 - Release flash_np in the nxp-spifi driver
 - Add suspend/resume hooks to the atmel-quadspi driver
 - Include gpio/consumer.h instead of gpio.h in the atmel-quadspi driver
 - Use %pK instead of %p in the stm32-quadspi driver
 - Improve timeout handling in the cadence-quadspi driver
 - Use mtd_device_register() instead of mtd_device_parse_register() in
   the intel-spi driver
"
parents da86748b bb276262
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -69,6 +69,15 @@ Optional properties:
                   all chips and support for it can not be detected at runtime.
                   Refer to your chips' datasheet to check if this is supported
                   by your chip.
- broken-flash-reset : Some flash devices utilize stateful addressing modes
		   (e.g., for 32-bit addressing) which need to be managed
		   carefully by a system. Because these sorts of flash don't
		   have a standardized software reset command, and because some
		   systems don't toggle the flash RESET# pin upon system reset
		   (if the pin even exists at all), there are systems which
		   cannot reboot properly if the flash is left in the "wrong"
		   state. This boolean flag can be used on such systems, to
		   denote the absence of a reliable reset mechanism.

Example:

+1 −4
Original line number Diff line number Diff line
@@ -28,11 +28,9 @@
#include <linux/spi/flash.h>
#include <linux/mtd/spi-nor.h>

#define	MAX_CMD_SIZE		6
struct m25p {
	struct spi_mem		*spimem;
	struct spi_nor		spi_nor;
	u8			command[MAX_CMD_SIZE];
};

static int m25p80_read_reg(struct spi_nor *nor, u8 code, u8 *val, int len)
@@ -70,7 +68,7 @@ static ssize_t m25p80_write(struct spi_nor *nor, loff_t to, size_t len,
	struct spi_mem_op op =
			SPI_MEM_OP(SPI_MEM_OP_CMD(nor->program_opcode, 1),
				   SPI_MEM_OP_ADDR(nor->addr_width, to, 1),
				   SPI_MEM_OP_DUMMY(0, 1),
				   SPI_MEM_OP_NO_DUMMY,
				   SPI_MEM_OP_DATA_OUT(len, buf, 1));
	size_t remaining = len;
	int ret;
@@ -78,7 +76,6 @@ static ssize_t m25p80_write(struct spi_nor *nor, loff_t to, size_t len,
	/* get transfer protocols. */
	op.cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->write_proto);
	op.addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->write_proto);
	op.dummy.buswidth = op.addr.buswidth;
	op.data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto);

	if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)
+22 −1
Original line number Diff line number Diff line
@@ -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,
+8 −12
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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);

Loading