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

Commit 02a595d5 authored by Heiner Kallweit's avatar Heiner Kallweit Committed by Mark Brown
Browse files

spi: fsl-espi: eliminate spi nor flash read loop



The fsl-espi driver contains a read loop that implicitely assumes that
the device to read from is a m25p80 SPI NOR flash (bytes 2 - 4 of the
first write transfer are interpreted as 3 byte flash address).

Now that we have such a read loop in the spi-nor driver and are able
to correctly indicate the message size limit of the controller,
the read loop can be removed from the fsl-espi driver.

Signed-off-by: default avatarHeiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 5090cc6a
Loading
Loading
Loading
Loading
+21 −70
Original line number Diff line number Diff line
@@ -258,23 +258,6 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
	return mpc8xxx_spi->count;
}

static inline void fsl_espi_addr2cmd(unsigned int addr, u8 *cmd)
{
	if (cmd) {
		cmd[1] = (u8)(addr >> 16);
		cmd[2] = (u8)(addr >> 8);
		cmd[3] = (u8)(addr >> 0);
	}
}

static inline unsigned int fsl_espi_cmd2addr(u8 *cmd)
{
	if (cmd)
		return cmd[1] << 16 | cmd[2] << 8 | cmd[3] << 0;

	return 0;
}

static void fsl_espi_do_trans(struct spi_message *m,
				struct fsl_espi_transfer *tr)
{
@@ -366,29 +349,17 @@ static void fsl_espi_cmd_trans(struct spi_message *m,
static void fsl_espi_rw_trans(struct spi_message *m,
				struct fsl_espi_transfer *trans, u8 *rx_buff)
{
	struct fsl_espi_transfer *espi_trans = trans;
	unsigned int total_len = espi_trans->len;
	struct spi_transfer *t;
	u8 *local_buf;
	u8 *rx_buf = rx_buff;
	unsigned int trans_len;
	unsigned int addr;
	unsigned int tx_only;
	unsigned int rx_pos = 0;
	unsigned int pos;
	int i, loop;
	unsigned int tx_only = 0;
	int i = 0;

	local_buf = kzalloc(SPCOM_TRANLEN_MAX, GFP_KERNEL);
	if (!local_buf) {
		espi_trans->status = -ENOMEM;
		trans->status = -ENOMEM;
		return;
	}

	for (pos = 0, loop = 0; pos < total_len; pos += trans_len, loop++) {
		trans_len = total_len - pos;

		i = 0;
		tx_only = 0;
	list_for_each_entry(t, &m->transfers, transfer_list) {
		if (t->tx_buf) {
			memcpy(local_buf + i, t->tx_buf, t->len);
@@ -398,36 +369,16 @@ static void fsl_espi_rw_trans(struct spi_message *m,
		}
	}

		/* Add additional TX bytes to compensate SPCOM_TRANLEN_MAX */
		if (loop > 0)
			trans_len += tx_only;

		if (trans_len > SPCOM_TRANLEN_MAX)
			trans_len = SPCOM_TRANLEN_MAX;

		/* Update device offset */
		if (pos > 0) {
			addr = fsl_espi_cmd2addr(local_buf);
			addr += rx_pos;
			fsl_espi_addr2cmd(addr, local_buf);
		}
	trans->tx_buf = local_buf;
	trans->rx_buf = local_buf;
	fsl_espi_do_trans(m, trans);

		espi_trans->len = trans_len;
		espi_trans->tx_buf = local_buf;
		espi_trans->rx_buf = local_buf;
		fsl_espi_do_trans(m, espi_trans);

		/* If there is at least one RX byte then copy it to rx_buf */
		if (tx_only < SPCOM_TRANLEN_MAX)
			memcpy(rx_buf + rx_pos, espi_trans->rx_buf + tx_only,
					trans_len - tx_only);

		rx_pos += trans_len - tx_only;

		if (loop > 0)
			espi_trans->actual_length += espi_trans->len - tx_only;
		else
			espi_trans->actual_length += espi_trans->len;
	if (!trans->status) {
		/* If there is at least one RX byte then copy it to rx_buff */
		if (trans->len > tx_only)
			memcpy(rx_buff, trans->rx_buf + tx_only,
			       trans->len - tx_only);
		trans->actual_length += trans->len;
	}

	kfree(local_buf);
@@ -663,7 +614,7 @@ static int fsl_espi_runtime_resume(struct device *dev)
}
#endif

static size_t fsl_espi_max_transfer_size(struct spi_device *spi)
static size_t fsl_espi_max_message_size(struct spi_device *spi)
{
	return SPCOM_TRANLEN_MAX;
}
@@ -695,7 +646,7 @@ static struct spi_master * fsl_espi_probe(struct device *dev,
	master->cleanup = fsl_espi_cleanup;
	master->transfer_one_message = fsl_espi_do_one_msg;
	master->auto_runtime_pm = true;
	master->max_transfer_size = fsl_espi_max_transfer_size;
	master->max_message_size = fsl_espi_max_message_size;

	mpc8xxx_spi = spi_master_get_devdata(master);