1
0
Fork 0

Merge remote-tracking branches 'spi/fix/fsl-cpm', 'spi/fix/fsl-dspi' and 'spi/fix/fsl-espi' into spi-linus

hifive-unleashed-5.1
Mark Brown 2015-05-11 17:29:49 +01:00
commit c8b350424d
3 changed files with 38 additions and 16 deletions

View File

@ -303,7 +303,7 @@ config SPI_FSL_SPI
config SPI_FSL_DSPI
tristate "Freescale DSPI controller"
select REGMAP_MMIO
depends on SOC_VF610 || COMPILE_TEST
depends on SOC_VF610 || SOC_LS1021A || COMPILE_TEST
help
This enables support for the Freescale DSPI controller in master
mode. VF610 platform uses the controller.

View File

@ -310,10 +310,15 @@ int fsl_spi_cpm_init(struct mpc8xxx_spi *mspi)
if (mspi->flags & SPI_CPM1) {
struct resource *res;
void *pram;
res = platform_get_resource(to_platform_device(dev),
IORESOURCE_MEM, 1);
mspi->pram = devm_ioremap_resource(dev, res);
pram = devm_ioremap_resource(dev, res);
if (IS_ERR(pram))
mspi->pram = NULL;
else
mspi->pram = pram;
} else {
unsigned long pram_ofs = fsl_spi_cpm_get_pram(mspi);

View File

@ -359,14 +359,16 @@ 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 n_tx = espi_trans->n_tx;
unsigned int n_rx = espi_trans->n_rx;
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;
int i, pos, loop;
unsigned int tx_only;
unsigned int rx_pos = 0;
unsigned int pos;
int i, loop;
local_buf = kzalloc(SPCOM_TRANLEN_MAX, GFP_KERNEL);
if (!local_buf) {
@ -374,36 +376,48 @@ static void fsl_espi_rw_trans(struct spi_message *m,
return;
}
for (pos = 0, loop = 0; pos < n_rx; pos += trans_len, loop++) {
trans_len = n_rx - pos;
if (trans_len > SPCOM_TRANLEN_MAX - n_tx)
trans_len = SPCOM_TRANLEN_MAX - n_tx;
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);
i += t->len;
if (!t->rx_buf)
tx_only += t->len;
}
}
/* 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 += pos;
addr += rx_pos;
fsl_espi_addr2cmd(addr, local_buf);
}
espi_trans->n_tx = n_tx;
espi_trans->n_rx = trans_len;
espi_trans->len = trans_len + n_tx;
espi_trans->len = trans_len;
espi_trans->tx_buf = local_buf;
espi_trans->rx_buf = local_buf;
fsl_espi_do_trans(m, espi_trans);
memcpy(rx_buf + pos, espi_trans->rx_buf + n_tx, trans_len);
/* 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 - n_tx;
espi_trans->actual_length += espi_trans->len - tx_only;
else
espi_trans->actual_length += espi_trans->len;
}
@ -418,6 +432,7 @@ static int fsl_espi_do_one_msg(struct spi_master *master,
u8 *rx_buf = NULL;
unsigned int n_tx = 0;
unsigned int n_rx = 0;
unsigned int xfer_len = 0;
struct fsl_espi_transfer espi_trans;
list_for_each_entry(t, &m->transfers, transfer_list) {
@ -427,11 +442,13 @@ static int fsl_espi_do_one_msg(struct spi_master *master,
n_rx += t->len;
rx_buf = t->rx_buf;
}
if ((t->tx_buf) || (t->rx_buf))
xfer_len += t->len;
}
espi_trans.n_tx = n_tx;
espi_trans.n_rx = n_rx;
espi_trans.len = n_tx + n_rx;
espi_trans.len = xfer_len;
espi_trans.actual_length = 0;
espi_trans.status = 0;