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: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Heiner Kallweit 2016-08-17 21:11:01 +02:00 committed by Mark Brown
parent 5090cc6ae2
commit 02a595d5d6

View File

@ -258,23 +258,6 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t)
return mpc8xxx_spi->count; 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, static void fsl_espi_do_trans(struct spi_message *m,
struct fsl_espi_transfer *tr) struct fsl_espi_transfer *tr)
{ {
@ -366,68 +349,36 @@ static void fsl_espi_cmd_trans(struct spi_message *m,
static void fsl_espi_rw_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 *trans, u8 *rx_buff)
{ {
struct fsl_espi_transfer *espi_trans = trans;
unsigned int total_len = espi_trans->len;
struct spi_transfer *t; struct spi_transfer *t;
u8 *local_buf; u8 *local_buf;
u8 *rx_buf = rx_buff; unsigned int tx_only = 0;
unsigned int trans_len; int i = 0;
unsigned int addr;
unsigned int tx_only;
unsigned int rx_pos = 0;
unsigned int pos;
int i, loop;
local_buf = kzalloc(SPCOM_TRANLEN_MAX, GFP_KERNEL); local_buf = kzalloc(SPCOM_TRANLEN_MAX, GFP_KERNEL);
if (!local_buf) { if (!local_buf) {
espi_trans->status = -ENOMEM; trans->status = -ENOMEM;
return; return;
} }
for (pos = 0, loop = 0; pos < total_len; pos += trans_len, loop++) { list_for_each_entry(t, &m->transfers, transfer_list) {
trans_len = total_len - pos; if (t->tx_buf) {
memcpy(local_buf + i, t->tx_buf, t->len);
i = 0; i += t->len;
tx_only = 0; if (!t->rx_buf)
list_for_each_entry(t, &m->transfers, transfer_list) { tx_only += t->len;
if (t->tx_buf) {
memcpy(local_buf + i, t->tx_buf, t->len);
i += t->len;
if (!t->rx_buf)
tx_only += t->len;
}
} }
}
/* Add additional TX bytes to compensate SPCOM_TRANLEN_MAX */ trans->tx_buf = local_buf;
if (loop > 0) trans->rx_buf = local_buf;
trans_len += tx_only; fsl_espi_do_trans(m, trans);
if (trans_len > SPCOM_TRANLEN_MAX) if (!trans->status) {
trans_len = SPCOM_TRANLEN_MAX; /* If there is at least one RX byte then copy it to rx_buff */
if (trans->len > tx_only)
/* Update device offset */ memcpy(rx_buff, trans->rx_buf + tx_only,
if (pos > 0) { trans->len - tx_only);
addr = fsl_espi_cmd2addr(local_buf); trans->actual_length += trans->len;
addr += rx_pos;
fsl_espi_addr2cmd(addr, local_buf);
}
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;
} }
kfree(local_buf); kfree(local_buf);
@ -663,7 +614,7 @@ static int fsl_espi_runtime_resume(struct device *dev)
} }
#endif #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; return SPCOM_TRANLEN_MAX;
} }
@ -695,7 +646,7 @@ static struct spi_master * fsl_espi_probe(struct device *dev,
master->cleanup = fsl_espi_cleanup; master->cleanup = fsl_espi_cleanup;
master->transfer_one_message = fsl_espi_do_one_msg; master->transfer_one_message = fsl_espi_do_one_msg;
master->auto_runtime_pm = true; 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); mpc8xxx_spi = spi_master_get_devdata(master);