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

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

Merge remote-tracking branches 'spi/fix/fsl-cpm', 'spi/fix/fsl-dspi' and...

Merge remote-tracking branches 'spi/fix/fsl-cpm', 'spi/fix/fsl-dspi' and 'spi/fix/fsl-espi' into spi-linus
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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.
+6 −1
Original line number Diff line number Diff line
@@ -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);

+31 −14
Original line number Diff line number Diff line
@@ -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;