tpm_tis_spi: Use single function to transfer data
authorPeter Huewe <peter.huewe@infineon.com>
Thu, 2 Mar 2017 13:03:11 +0000 (13:03 +0000)
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Mon, 3 Apr 2017 19:46:00 +0000 (22:46 +0300)
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: 0edbfea537d1 ("tpm/tpm_tis_spi: Add support for spi phy")
Signed-off-by: Alexander Steffen <Alexander.Steffen@infineon.com>
Signed-off-by: Peter Huewe <peter.huewe@infineon.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: Benoit Houyere <benoit.houyere@st.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
drivers/char/tpm/tpm_tis_spi.c

index 5292e57..062799e 100644 (file)
@@ -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 @@ exit:
        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,
                                   u16 len, u8 *value)
 {
-       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;
-       }
-
-       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;
+       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)