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

Commit df9633a7 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branch 'spi/topic/core' into spi-next

parents bad0ae3f 62826970
Loading
Loading
Loading
Loading
+48 −0
Original line number Diff line number Diff line
@@ -1152,6 +1152,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread)
		}
	}

	mutex_lock(&master->bus_lock_mutex);
	trace_spi_message_start(master->cur_msg);

	if (master->prepare_message) {
@@ -1161,6 +1162,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread)
				"failed to prepare message: %d\n", ret);
			master->cur_msg->status = ret;
			spi_finalize_current_message(master);
			mutex_unlock(&master->bus_lock_mutex);
			return;
		}
		master->cur_msg_prepared = true;
@@ -1170,6 +1172,7 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread)
	if (ret) {
		master->cur_msg->status = ret;
		spi_finalize_current_message(master);
		mutex_unlock(&master->bus_lock_mutex);
		return;
	}

@@ -1177,8 +1180,13 @@ static void __spi_pump_messages(struct spi_master *master, bool in_kthread)
	if (ret) {
		dev_err(&master->dev,
			"failed to transfer one message from queue\n");
		mutex_unlock(&master->bus_lock_mutex);
		return;
	}
	mutex_unlock(&master->bus_lock_mutex);

	/* Prod the scheduler in case transfer_one() was busy waiting */
	cond_resched();
}

/**
@@ -2351,6 +2359,46 @@ int spi_async_locked(struct spi_device *spi, struct spi_message *message)
EXPORT_SYMBOL_GPL(spi_async_locked);


int spi_flash_read(struct spi_device *spi,
		   struct spi_flash_read_message *msg)

{
	struct spi_master *master = spi->master;
	int ret;

	if ((msg->opcode_nbits == SPI_NBITS_DUAL ||
	     msg->addr_nbits == SPI_NBITS_DUAL) &&
	    !(spi->mode & (SPI_TX_DUAL | SPI_TX_QUAD)))
		return -EINVAL;
	if ((msg->opcode_nbits == SPI_NBITS_QUAD ||
	     msg->addr_nbits == SPI_NBITS_QUAD) &&
	    !(spi->mode & SPI_TX_QUAD))
		return -EINVAL;
	if (msg->data_nbits == SPI_NBITS_DUAL &&
	    !(spi->mode & (SPI_RX_DUAL | SPI_RX_QUAD)))
		return -EINVAL;
	if (msg->data_nbits == SPI_NBITS_QUAD &&
	    !(spi->mode &  SPI_RX_QUAD))
		return -EINVAL;

	if (master->auto_runtime_pm) {
		ret = pm_runtime_get_sync(master->dev.parent);
		if (ret < 0) {
			dev_err(&master->dev, "Failed to power device: %d\n",
				ret);
			return ret;
		}
	}
	mutex_lock(&master->bus_lock_mutex);
	ret = master->spi_flash_read(spi, msg);
	mutex_unlock(&master->bus_lock_mutex);
	if (master->auto_runtime_pm)
		pm_runtime_put(master->dev.parent);

	return ret;
}
EXPORT_SYMBOL_GPL(spi_flash_read);

/*-------------------------------------------------------------------------*/

/* Utility methods for SPI master protocol drivers, layered on
+41 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
struct dma_chan;
struct spi_master;
struct spi_transfer;
struct spi_flash_read_message;

/*
 * INTERFACES between SPI master-side drivers and SPI infrastructure.
@@ -361,6 +362,8 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
 * @handle_err: the subsystem calls the driver to handle an error that occurs
 *		in the generic implementation of transfer_one_message().
 * @unprepare_message: undo any work done by prepare_message().
 * @spi_flash_read: to support spi-controller hardwares that provide
 *                  accelerated interface to read from flash devices.
 * @cs_gpios: Array of GPIOs to use as chip select lines; one per CS
 *	number. Any individual value may be -ENOENT for CS lines that
 *	are not GPIOs (driven by the SPI controller itself).
@@ -513,6 +516,8 @@ struct spi_master {
			       struct spi_message *message);
	int (*unprepare_message)(struct spi_master *master,
				 struct spi_message *message);
	int (*spi_flash_read)(struct  spi_device *spi,
			      struct spi_flash_read_message *msg);

	/*
	 * These hooks are for drivers that use a generic implementation
@@ -1019,6 +1024,42 @@ static inline ssize_t spi_w8r16be(struct spi_device *spi, u8 cmd)
	return be16_to_cpu(result);
}

/**
 * struct spi_flash_read_message - flash specific information for
 * spi-masters that provide accelerated flash read interfaces
 * @buf: buffer to read data
 * @from: offset within the flash from where data is to be read
 * @len: length of data to be read
 * @retlen: actual length of data read
 * @read_opcode: read_opcode to be used to communicate with flash
 * @addr_width: number of address bytes
 * @dummy_bytes: number of dummy bytes
 * @opcode_nbits: number of lines to send opcode
 * @addr_nbits: number of lines to send address
 * @data_nbits: number of lines for data
 */
struct spi_flash_read_message {
	void *buf;
	loff_t from;
	size_t len;
	size_t retlen;
	u8 read_opcode;
	u8 addr_width;
	u8 dummy_bytes;
	u8 opcode_nbits;
	u8 addr_nbits;
	u8 data_nbits;
};

/* SPI core interface for flash read support */
static inline bool spi_flash_read_supported(struct spi_device *spi)
{
	return spi->master->spi_flash_read ? true : false;
}

int spi_flash_read(struct spi_device *spi,
		   struct spi_flash_read_message *msg);

/*---------------------------------------------------------------------------*/

/*