OSDN Git Service

tpm: Remove read16/read32/write32 calls from tpm_tis_phy_ops
authorJohannes Holland <johannes.holland@infineon.com>
Mon, 21 Mar 2022 09:09:24 +0000 (10:09 +0100)
committerJarkko Sakkinen <jarkko@kernel.org>
Mon, 23 May 2022 15:47:49 +0000 (18:47 +0300)
Only tpm_tis and tpm_tis_synquacer have a dedicated way to access
multiple bytes at once, every other driver will just fall back to
read_bytes/write_bytes. Therefore, remove the read16/read32/write32
calls and move their logic to read_bytes/write_bytes.

Suggested-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Johannes Holland <johannes.holland@infineon.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
drivers/char/tpm/tpm_tis.c
drivers/char/tpm/tpm_tis_core.h
drivers/char/tpm/tpm_tis_spi.h
drivers/char/tpm/tpm_tis_spi_cr50.c
drivers/char/tpm/tpm_tis_spi_main.c
drivers/char/tpm/tpm_tis_synquacer.c

index d3f2e53..bcff642 100644 (file)
@@ -153,50 +153,46 @@ static int check_acpi_tpm2(struct device *dev)
 #endif
 
 static int tpm_tcg_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
-                             u8 *result)
+                             u8 *result, enum tpm_tis_io_mode io_mode)
 {
        struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
-
-       while (len--)
-               *result++ = ioread8(phy->iobase + addr);
+       __le16 result_le16;
+       __le32 result_le32;
+
+       switch (io_mode) {
+       case TPM_TIS_PHYS_8:
+               while (len--)
+                       *result++ = ioread8(phy->iobase + addr);
+               break;
+       case TPM_TIS_PHYS_16:
+               result_le16 = cpu_to_le16(ioread16(phy->iobase + addr));
+               memcpy(result, &result_le16, sizeof(u16));
+               break;
+       case TPM_TIS_PHYS_32:
+               result_le32 = cpu_to_le32(ioread32(phy->iobase + addr));
+               memcpy(result, &result_le32, sizeof(u32));
+               break;
+       }
 
        return 0;
 }
 
 static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
-                              const u8 *value)
+                              const u8 *value, enum tpm_tis_io_mode io_mode)
 {
        struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
 
-       while (len--)
-               iowrite8(*value++, phy->iobase + addr);
-
-       return 0;
-}
-
-static int tpm_tcg_read16(struct tpm_tis_data *data, u32 addr, u16 *result)
-{
-       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
-
-       *result = ioread16(phy->iobase + addr);
-
-       return 0;
-}
-
-static int tpm_tcg_read32(struct tpm_tis_data *data, u32 addr, u32 *result)
-{
-       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
-
-       *result = ioread32(phy->iobase + addr);
-
-       return 0;
-}
-
-static int tpm_tcg_write32(struct tpm_tis_data *data, u32 addr, u32 value)
-{
-       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
-
-       iowrite32(value, phy->iobase + addr);
+       switch (io_mode) {
+       case TPM_TIS_PHYS_8:
+               while (len--)
+                       iowrite8(*value++, phy->iobase + addr);
+               break;
+       case TPM_TIS_PHYS_16:
+               return -EINVAL;
+       case TPM_TIS_PHYS_32:
+               iowrite32(le32_to_cpu(*((__le32 *)value)), phy->iobase + addr);
+               break;
+       }
 
        return 0;
 }
@@ -204,9 +200,6 @@ static int tpm_tcg_write32(struct tpm_tis_data *data, u32 addr, u32 value)
 static const struct tpm_tis_phy_ops tpm_tcg = {
        .read_bytes = tpm_tcg_read_bytes,
        .write_bytes = tpm_tcg_write_bytes,
-       .read16 = tpm_tcg_read16,
-       .read32 = tpm_tcg_read32,
-       .write32 = tpm_tcg_write32,
 };
 
 static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info)
index 3be24f2..6c203f3 100644 (file)
@@ -104,54 +104,88 @@ struct tpm_tis_data {
        unsigned int timeout_max; /* usecs */
 };
 
+/*
+ * IO modes to indicate how many bytes should be read/written at once in the
+ * tpm_tis_phy_ops read_bytes/write_bytes calls. Use TPM_TIS_PHYS_8 to
+ * receive/transmit byte-wise, TPM_TIS_PHYS_16 for two bytes etc.
+ */
+enum tpm_tis_io_mode {
+       TPM_TIS_PHYS_8,
+       TPM_TIS_PHYS_16,
+       TPM_TIS_PHYS_32,
+};
+
 struct tpm_tis_phy_ops {
+       /* data is passed in little endian */
        int (*read_bytes)(struct tpm_tis_data *data, u32 addr, u16 len,
-                         u8 *result);
+                         u8 *result, enum tpm_tis_io_mode mode);
        int (*write_bytes)(struct tpm_tis_data *data, u32 addr, u16 len,
-                          const u8 *value);
-       int (*read16)(struct tpm_tis_data *data, u32 addr, u16 *result);
-       int (*read32)(struct tpm_tis_data *data, u32 addr, u32 *result);
-       int (*write32)(struct tpm_tis_data *data, u32 addr, u32 src);
+                          const u8 *value, enum tpm_tis_io_mode mode);
 };
 
 static inline int tpm_tis_read_bytes(struct tpm_tis_data *data, u32 addr,
                                     u16 len, u8 *result)
 {
-       return data->phy_ops->read_bytes(data, addr, len, result);
+       return data->phy_ops->read_bytes(data, addr, len, result,
+                                        TPM_TIS_PHYS_8);
 }
 
 static inline int tpm_tis_read8(struct tpm_tis_data *data, u32 addr, u8 *result)
 {
-       return data->phy_ops->read_bytes(data, addr, 1, result);
+       return data->phy_ops->read_bytes(data, addr, 1, result, TPM_TIS_PHYS_8);
 }
 
 static inline int tpm_tis_read16(struct tpm_tis_data *data, u32 addr,
                                 u16 *result)
 {
-       return data->phy_ops->read16(data, addr, result);
+       __le16 result_le;
+       int rc;
+
+       rc = data->phy_ops->read_bytes(data, addr, sizeof(u16),
+                                      (u8 *)&result_le, TPM_TIS_PHYS_16);
+       if (!rc)
+               *result = le16_to_cpu(result_le);
+
+       return rc;
 }
 
 static inline int tpm_tis_read32(struct tpm_tis_data *data, u32 addr,
                                 u32 *result)
 {
-       return data->phy_ops->read32(data, addr, result);
+       __le32 result_le;
+       int rc;
+
+       rc = data->phy_ops->read_bytes(data, addr, sizeof(u32),
+                                      (u8 *)&result_le, TPM_TIS_PHYS_32);
+       if (!rc)
+               *result = le32_to_cpu(result_le);
+
+       return rc;
 }
 
 static inline int tpm_tis_write_bytes(struct tpm_tis_data *data, u32 addr,
                                      u16 len, const u8 *value)
 {
-       return data->phy_ops->write_bytes(data, addr, len, value);
+       return data->phy_ops->write_bytes(data, addr, len, value,
+                                         TPM_TIS_PHYS_8);
 }
 
 static inline int tpm_tis_write8(struct tpm_tis_data *data, u32 addr, u8 value)
 {
-       return data->phy_ops->write_bytes(data, addr, 1, &value);
+       return data->phy_ops->write_bytes(data, addr, 1, &value,
+                                         TPM_TIS_PHYS_8);
 }
 
 static inline int tpm_tis_write32(struct tpm_tis_data *data, u32 addr,
                                  u32 value)
 {
-       return data->phy_ops->write32(data, addr, value);
+       __le32 value_le;
+       int rc;
+
+       value_le = cpu_to_le32(value);
+       rc =  data->phy_ops->write_bytes(data, addr, sizeof(u32),
+                                        (u8 *)&value_le, TPM_TIS_PHYS_32);
+       return rc;
 }
 
 static inline bool is_bsw(void)
index bba7397..d0f66f6 100644 (file)
@@ -31,10 +31,6 @@ extern int tpm_tis_spi_init(struct spi_device *spi, struct tpm_tis_spi_phy *phy,
 extern int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
                                u8 *in, const u8 *out);
 
-extern int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result);
-extern int tpm_tis_spi_read32(struct tpm_tis_data *data, u32 addr, u32 *result);
-extern int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value);
-
 #ifdef CONFIG_TCG_TIS_SPI_CR50
 extern int cr50_spi_probe(struct spi_device *spi);
 #else
index 7bf123d..f493728 100644 (file)
@@ -222,13 +222,13 @@ static int tpm_tis_spi_cr50_transfer(struct tpm_tis_data *data, u32 addr, u16 le
 }
 
 static int tpm_tis_spi_cr50_read_bytes(struct tpm_tis_data *data, u32 addr,
-                                      u16 len, u8 *result)
+                                      u16 len, u8 *result, enum tpm_tis_io_mode io_mode)
 {
        return tpm_tis_spi_cr50_transfer(data, addr, len, result, NULL);
 }
 
 static int tpm_tis_spi_cr50_write_bytes(struct tpm_tis_data *data, u32 addr,
-                                       u16 len, const u8 *value)
+                                       u16 len, const u8 *value, enum tpm_tis_io_mode io_mode)
 {
        return tpm_tis_spi_cr50_transfer(data, addr, len, NULL, value);
 }
@@ -236,9 +236,6 @@ static int tpm_tis_spi_cr50_write_bytes(struct tpm_tis_data *data, u32 addr,
 static const struct tpm_tis_phy_ops tpm_spi_cr50_phy_ops = {
        .read_bytes = tpm_tis_spi_cr50_read_bytes,
        .write_bytes = tpm_tis_spi_cr50_write_bytes,
-       .read16 = tpm_tis_spi_read16,
-       .read32 = tpm_tis_spi_read32,
-       .write32 = tpm_tis_spi_write32,
 };
 
 static void cr50_print_fw_version(struct tpm_tis_data *data)
index 184396b..a0963a3 100644 (file)
@@ -141,55 +141,17 @@ exit:
 }
 
 static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
-                                 u16 len, u8 *result)
+                                 u16 len, u8 *result, enum tpm_tis_io_mode io_mode)
 {
        return tpm_tis_spi_transfer(data, addr, len, result, NULL);
 }
 
 static int tpm_tis_spi_write_bytes(struct tpm_tis_data *data, u32 addr,
-                                  u16 len, const u8 *value)
+                                  u16 len, const u8 *value, enum tpm_tis_io_mode io_mode)
 {
        return tpm_tis_spi_transfer(data, addr, len, NULL, value);
 }
 
-int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result)
-{
-       __le16 result_le;
-       int rc;
-
-       rc = data->phy_ops->read_bytes(data, addr, sizeof(u16),
-                                      (u8 *)&result_le);
-       if (!rc)
-               *result = le16_to_cpu(result_le);
-
-       return rc;
-}
-
-int tpm_tis_spi_read32(struct tpm_tis_data *data, u32 addr, u32 *result)
-{
-       __le32 result_le;
-       int rc;
-
-       rc = data->phy_ops->read_bytes(data, addr, sizeof(u32),
-                                      (u8 *)&result_le);
-       if (!rc)
-               *result = le32_to_cpu(result_le);
-
-       return rc;
-}
-
-int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value)
-{
-       __le32 value_le;
-       int rc;
-
-       value_le = cpu_to_le32(value);
-       rc = data->phy_ops->write_bytes(data, addr, sizeof(u32),
-                                       (u8 *)&value_le);
-
-       return rc;
-}
-
 int tpm_tis_spi_init(struct spi_device *spi, struct tpm_tis_spi_phy *phy,
                     int irq, const struct tpm_tis_phy_ops *phy_ops)
 {
@@ -205,9 +167,6 @@ int tpm_tis_spi_init(struct spi_device *spi, struct tpm_tis_spi_phy *phy,
 static const struct tpm_tis_phy_ops tpm_spi_phy_ops = {
        .read_bytes = tpm_tis_spi_read_bytes,
        .write_bytes = tpm_tis_spi_write_bytes,
-       .read16 = tpm_tis_spi_read16,
-       .read32 = tpm_tis_spi_read32,
-       .write32 = tpm_tis_spi_write32,
 };
 
 static int tpm_tis_spi_probe(struct spi_device *dev)
index e47bdd2..679196c 100644 (file)
@@ -35,72 +35,53 @@ static inline struct tpm_tis_synquacer_phy *to_tpm_tis_tcg_phy(struct tpm_tis_da
 }
 
 static int tpm_tis_synquacer_read_bytes(struct tpm_tis_data *data, u32 addr,
-                                       u16 len, u8 *result)
+                                       u16 len, u8 *result,
+                                       enum tpm_tis_io_mode io_mode)
 {
        struct tpm_tis_synquacer_phy *phy = to_tpm_tis_tcg_phy(data);
-
-       while (len--)
-               *result++ = ioread8(phy->iobase + addr);
+       switch (io_mode) {
+       case TPM_TIS_PHYS_8:
+               while (len--)
+                       *result++ = ioread8(phy->iobase + addr);
+               break;
+       case TPM_TIS_PHYS_16:
+               result[1] = ioread8(phy->iobase + addr + 1);
+               result[0] = ioread8(phy->iobase + addr);
+               break;
+       case TPM_TIS_PHYS_32:
+               result[3] = ioread8(phy->iobase + addr + 3);
+               result[2] = ioread8(phy->iobase + addr + 2);
+               result[1] = ioread8(phy->iobase + addr + 1);
+               result[0] = ioread8(phy->iobase + addr);
+               break;
+       }
 
        return 0;
 }
 
 static int tpm_tis_synquacer_write_bytes(struct tpm_tis_data *data, u32 addr,
-                                        u16 len, const u8 *value)
+                                        u16 len, const u8 *value,
+                                        enum tpm_tis_io_mode io_mode)
 {
        struct tpm_tis_synquacer_phy *phy = to_tpm_tis_tcg_phy(data);
-
-       while (len--)
-               iowrite8(*value++, phy->iobase + addr);
-
-       return 0;
-}
-
-static int tpm_tis_synquacer_read16_bw(struct tpm_tis_data *data,
-                                      u32 addr, u16 *result)
-{
-       struct tpm_tis_synquacer_phy *phy = to_tpm_tis_tcg_phy(data);
-
-       /*
-        * Due to the limitation of SPI controller on SynQuacer,
-        * 16/32 bits access must be done in byte-wise and descending order.
-        */
-       *result = (ioread8(phy->iobase + addr + 1) << 8) |
-                 (ioread8(phy->iobase + addr));
-
-       return 0;
-}
-
-static int tpm_tis_synquacer_read32_bw(struct tpm_tis_data *data,
-                                      u32 addr, u32 *result)
-{
-       struct tpm_tis_synquacer_phy *phy = to_tpm_tis_tcg_phy(data);
-
-       /*
-        * Due to the limitation of SPI controller on SynQuacer,
-        * 16/32 bits access must be done in byte-wise and descending order.
-        */
-       *result = (ioread8(phy->iobase + addr + 3) << 24) |
-                 (ioread8(phy->iobase + addr + 2) << 16) |
-                 (ioread8(phy->iobase + addr + 1) << 8) |
-                 (ioread8(phy->iobase + addr));
-
-       return 0;
-}
-
-static int tpm_tis_synquacer_write32_bw(struct tpm_tis_data *data,
-                                       u32 addr, u32 value)
-{
-       struct tpm_tis_synquacer_phy *phy = to_tpm_tis_tcg_phy(data);
-
-       /*
-        * Due to the limitation of SPI controller on SynQuacer,
-        * 16/32 bits access must be done in byte-wise and descending order.
-        */
-       iowrite8(value >> 24, phy->iobase + addr + 3);
-       iowrite8(value >> 16, phy->iobase + addr + 2);
-       iowrite8(value >> 8, phy->iobase + addr + 1);
-       iowrite8(value, phy->iobase + addr);
+       switch (io_mode) {
+       case TPM_TIS_PHYS_8:
+               while (len--)
+                       iowrite8(*value++, phy->iobase + addr);
+               break;
+       case TPM_TIS_PHYS_16:
+               return -EINVAL;
+       case TPM_TIS_PHYS_32:
+               /*
+                * Due to the limitation of SPI controller on SynQuacer,
+                * 16/32 bits access must be done in byte-wise and descending order.
+                */
+               iowrite8(value[3], phy->iobase + addr + 3);
+               iowrite8(value[2], phy->iobase + addr + 2);
+               iowrite8(value[1], phy->iobase + addr + 1);
+               iowrite8(value[0], phy->iobase + addr);
+               break;
+       }
 
        return 0;
 }
@@ -108,9 +89,6 @@ static int tpm_tis_synquacer_write32_bw(struct tpm_tis_data *data,
 static const struct tpm_tis_phy_ops tpm_tcg_bw = {
        .read_bytes     = tpm_tis_synquacer_read_bytes,
        .write_bytes    = tpm_tis_synquacer_write_bytes,
-       .read16         = tpm_tis_synquacer_read16_bw,
-       .read32         = tpm_tis_synquacer_read32_bw,
-       .write32        = tpm_tis_synquacer_write32_bw,
 };
 
 static int tpm_tis_synquacer_init(struct device *dev,