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

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
...@@ -47,8 +47,8 @@ struct tpm_tis_spi_phy { ...@@ -47,8 +47,8 @@ struct tpm_tis_spi_phy {
struct tpm_tis_data priv; struct tpm_tis_data priv;
struct spi_device *spi_device; struct spi_device *spi_device;
u8 tx_buf[MAX_SPI_FRAMESIZE + 4]; u8 tx_buf[4];
u8 rx_buf[MAX_SPI_FRAMESIZE + 4]; u8 rx_buf[4];
}; };
static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data *data) 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 ...@@ -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); return container_of(data, struct tpm_tis_spi_phy, priv);
} }
static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr, static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
u16 len, u8 *result) u8 *buffer, u8 direction)
{ {
struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data); struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data);
int ret, i; int ret, i;
...@@ -66,17 +66,17 @@ static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr, ...@@ -66,17 +66,17 @@ static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
.tx_buf = phy->tx_buf, .tx_buf = phy->tx_buf,
.rx_buf = phy->rx_buf, .rx_buf = phy->rx_buf,
.len = 4, .len = 4,
.cs_change = 1,
}; };
if (len > MAX_SPI_FRAMESIZE) if (len > MAX_SPI_FRAMESIZE)
return -ENOMEM; return -ENOMEM;
phy->tx_buf[0] = 0x80 | (len - 1); phy->tx_buf[0] = direction | (len - 1);
phy->tx_buf[1] = 0xd4; phy->tx_buf[1] = 0xd4;
phy->tx_buf[2] = (addr >> 8) & 0xFF; phy->tx_buf[2] = addr >> 8;
phy->tx_buf[3] = addr & 0xFF; phy->tx_buf[3] = addr;
spi_xfer.cs_change = 1;
spi_message_init(&m); spi_message_init(&m);
spi_message_add_tail(&spi_xfer, &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, ...@@ -85,7 +85,7 @@ static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
if (ret < 0) if (ret < 0)
goto exit; 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 /* 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 * 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, ...@@ -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.cs_change = 0;
spi_xfer.len = len; 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_init(&m);
spi_message_add_tail(&spi_xfer, &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, ...@@ -114,62 +121,16 @@ static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
return ret; return ret;
} }
static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
u16 len, u8 *result)
{
return tpm_tis_spi_transfer(data, addr, len, result, 0x80);
}
static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr, static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr,
u16 len, u8 *value) u16 len, u8 *value)
{ {
struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data); return tpm_tis_spi_transfer(data, addr, len, value, 0);
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;
}
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_read16(struct tpm_tis_data *data, u32 addr, u16 *result) static int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment