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

Commit f848f214 authored by Peter Huewe's avatar Peter Huewe Committed by Jarkko Sakkinen
Browse files

tpm_tis_spi: Use single function to transfer data



The algorithm for sending data to the TPM is mostly identical to the
algorithm for receiving data from the TPM, so a single function is
sufficient to handle both cases.

This is a prequisite for all the other fixes, so we don't have to fix
everything twice (send/receive)

v2: u16 instead of u8 for the length.
Cc: <stable@vger.kernel.org>
Fixes: 0edbfea5 ("tpm/tpm_tis_spi: Add support for spi phy")
Signed-off-by: default avatarAlexander Steffen <Alexander.Steffen@infineon.com>
Signed-off-by: default avatarPeter Huewe <peter.huewe@infineon.com>
Reviewed-by: default avatarJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: default avatarBenoit Houyere <benoit.houyere@st.com>
Signed-off-by: default avatarJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
parent 095fc30c
Loading
Loading
Loading
Loading
+24 −63
Original line number Diff line number Diff line
@@ -47,8 +47,8 @@ struct tpm_tis_spi_phy {
	struct tpm_tis_data priv;
	struct spi_device *spi_device;

	u8 tx_buf[MAX_SPI_FRAMESIZE + 4];
	u8 rx_buf[MAX_SPI_FRAMESIZE + 4];
	u8 tx_buf[4];
	u8 rx_buf[4];
};

static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *data)
@@ -56,8 +56,8 @@ static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *da
	return container_of(data, struct tpm_tis_spi_phy, priv);
}

static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
				  u16 len, u8 *result)
static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
				u8 *buffer, u8 direction)
{
	struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data);
	int ret, i;
@@ -66,17 +66,17 @@ static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
		.tx_buf = phy->tx_buf,
		.rx_buf = phy->rx_buf,
		.len = 4,
		.cs_change = 1,
	};

	if (len > MAX_SPI_FRAMESIZE)
		return -ENOMEM;

	phy->tx_buf[0] = 0x80 | (len - 1);
	phy->tx_buf[0] = direction | (len - 1);
	phy->tx_buf[1] = 0xd4;
	phy->tx_buf[2] = (addr >> 8)  & 0xFF;
	phy->tx_buf[3] = addr	      & 0xFF;
	phy->tx_buf[2] = addr >> 8;
	phy->tx_buf[3] = addr;

	spi_xfer.cs_change = 1;
	spi_message_init(&m);
	spi_message_add_tail(&spi_xfer, &m);

@@ -85,7 +85,7 @@ static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
	if (ret < 0)
		goto exit;

	memset(phy->tx_buf, 0, len);
	phy->tx_buf[0] = 0;

	/* According to TCG PTP specification, if there is no TPM present at
	 * all, then the design has a weak pull-up on MISO. If a TPM is not
@@ -103,7 +103,14 @@ static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,

	spi_xfer.cs_change = 0;
	spi_xfer.len = len;
	spi_xfer.rx_buf = result;

	if (direction) {
		spi_xfer.tx_buf = NULL;
		spi_xfer.rx_buf = buffer;
	} else {
		spi_xfer.tx_buf = buffer;
		spi_xfer.rx_buf = NULL;
	}

	spi_message_init(&m);
	spi_message_add_tail(&spi_xfer, &m);
@@ -114,62 +121,16 @@ static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
	return ret;
}

static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr,
				   u16 len, u8 *value)
static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
				  u16 len, u8 *result)
{
	struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data);
	int ret, i;
	struct spi_message m;
	struct spi_transfer spi_xfer = {
		.tx_buf = phy->tx_buf,
		.rx_buf = phy->rx_buf,
		.len = 4,
	};

	if (len > MAX_SPI_FRAMESIZE)
		return -ENOMEM;

	phy->tx_buf[0] = len - 1;
	phy->tx_buf[1] = 0xd4;
	phy->tx_buf[2] = (addr >> 8)  & 0xFF;
	phy->tx_buf[3] = addr         & 0xFF;

	spi_xfer.cs_change = 1;
	spi_message_init(&m);
	spi_message_add_tail(&spi_xfer, &m);

	spi_bus_lock(phy->spi_device->master);
	ret = spi_sync_locked(phy->spi_device, &m);
	if (ret < 0)
		goto exit;

	memset(phy->tx_buf, 0, len);

	/* According to TCG PTP specification, if there is no TPM present at
	 * all, then the design has a weak pull-up on MISO. If a TPM is not
	 * present, a pull-up on MISO means that the SB controller sees a 1,
	 * and will latch in 0xFF on the read.
	 */
	for (i = 0; (phy->rx_buf[0] & 0x01) == 0 && i < TPM_RETRY; i++) {
		spi_xfer.len = 1;
		spi_message_init(&m);
		spi_message_add_tail(&spi_xfer, &m);
		ret = spi_sync_locked(phy->spi_device, &m);
		if (ret < 0)
			goto exit;
	return tpm_tis_spi_transfer(data, addr, len, result, 0x80);
}

	spi_xfer.len = len;
	spi_xfer.tx_buf = value;
	spi_xfer.cs_change = 0;
	spi_xfer.tx_buf = value;
	spi_message_init(&m);
	spi_message_add_tail(&spi_xfer, &m);
	ret = spi_sync_locked(phy->spi_device, &m);

exit:
	spi_bus_unlock(phy->spi_device->master);
	return ret;
static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr,
				   u16 len, u8 *value)
{
	return tpm_tis_spi_transfer(data, addr, len, value, 0);
}

static int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result)