Export a new function, tpm_tis_spi_init(), and the associated
read/write/transfer APIs so that we can create variant drivers based on
the core functionality of this TPM SPI driver. Variant drivers can wrap
the tpm_tis_spi_phy struct with their own struct and override the
behavior of tpm_tis_spi_transfer() by supplying their own flow control
and pre-transfer hooks. This shares the most code between the core
driver and any variants that want to override certain behavior without
cluttering the core driver.

Cc: Andrey Pronin <[email protected]>
Cc: Duncan Laurie <[email protected]>
Cc: Jason Gunthorpe <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Guenter Roeck <[email protected]>
Cc: Alexander Steffen <[email protected]>
Signed-off-by: Stephen Boyd <[email protected]>
---
 drivers/char/tpm/tpm_tis_spi.c | 52 ++++++++++++++++------------------
 drivers/char/tpm/tpm_tis_spi.h | 37 ++++++++++++++++++++++++
 2 files changed, 62 insertions(+), 27 deletions(-)
 create mode 100644 drivers/char/tpm/tpm_tis_spi.h

diff --git a/drivers/char/tpm/tpm_tis_spi.c b/drivers/char/tpm/tpm_tis_spi.c
index 93f49b1941f0..fd3fb4f9f506 100644
--- a/drivers/char/tpm/tpm_tis_spi.c
+++ b/drivers/char/tpm/tpm_tis_spi.c
@@ -36,23 +36,10 @@
 #include <linux/tpm.h>
 #include "tpm.h"
 #include "tpm_tis_core.h"
+#include "tpm_tis_spi.h"
 
 #define MAX_SPI_FRAMESIZE 64
 
-struct tpm_tis_spi_phy {
-       struct tpm_tis_data priv;
-       struct spi_device *spi_device;
-       int (*flow_control)(struct tpm_tis_spi_phy *phy,
-                           struct spi_transfer *xfer);
-       void (*pre_transfer)(struct tpm_tis_spi_phy *phy);
-       u8 *iobuf;
-};
-
-static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data 
*data)
-{
-       return container_of(data, struct tpm_tis_spi_phy, priv);
-}
-
 static int tpm_tis_spi_flow_control(struct tpm_tis_spi_phy *phy,
                                    struct spi_transfer *spi_xfer)
 {
@@ -81,7 +68,7 @@ static int tpm_tis_spi_flow_control(struct tpm_tis_spi_phy 
*phy,
        return 0;
 }
 
-static int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
+int tpm_tis_spi_transfer(struct tpm_tis_data *data, u32 addr, u16 len,
                                u8 *in, const u8 *out)
 {
        struct tpm_tis_spi_phy *phy = to_tpm_tis_spi_phy(data);
@@ -148,9 +135,10 @@ static int tpm_tis_spi_transfer(struct tpm_tis_data *data, 
u32 addr, u16 len,
        spi_bus_unlock(phy->spi_device->master);
        return ret;
 }
+EXPORT_SYMBOL_GPL(tpm_tis_spi_transfer);
 
-static int tpm_tis_spi_read_bytes(struct tpm_tis_data *data, u32 addr,
-                                 u16 len, u8 *result)
+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, NULL);
 }
@@ -161,7 +149,7 @@ static int tpm_tis_spi_write_bytes(struct tpm_tis_data 
*data, u32 addr,
        return tpm_tis_spi_transfer(data, addr, len, NULL, value);
 }
 
-static int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result)
+int tpm_tis_spi_read16(struct tpm_tis_data *data, u32 addr, u16 *result)
 {
        __le16 result_le;
        int rc;
@@ -173,8 +161,9 @@ static int tpm_tis_spi_read16(struct tpm_tis_data *data, 
u32 addr, u16 *result)
 
        return rc;
 }
+EXPORT_SYMBOL_GPL(tpm_tis_spi_read16);
 
-static int tpm_tis_spi_read32(struct tpm_tis_data *data, u32 addr, u32 *result)
+int tpm_tis_spi_read32(struct tpm_tis_data *data, u32 addr, u32 *result)
 {
        __le32 result_le;
        int rc;
@@ -186,8 +175,9 @@ static int tpm_tis_spi_read32(struct tpm_tis_data *data, 
u32 addr, u32 *result)
 
        return rc;
 }
+EXPORT_SYMBOL_GPL(tpm_tis_spi_read32);
 
-static int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value)
+int tpm_tis_spi_write32(struct tpm_tis_data *data, u32 addr, u32 value)
 {
        __le32 value_le;
        int rc;
@@ -198,6 +188,20 @@ static int tpm_tis_spi_write32(struct tpm_tis_data *data, 
u32 addr, u32 value)
 
        return rc;
 }
+EXPORT_SYMBOL_GPL(tpm_tis_spi_write32);
+
+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)
+{
+       phy->iobuf = devm_kmalloc(&spi->dev, MAX_SPI_FRAMESIZE, GFP_KERNEL);
+       if (!phy->iobuf)
+               return -ENOMEM;
+
+       phy->spi_device = spi;
+
+       return tpm_tis_core_init(&spi->dev, &phy->priv, irq, phy_ops, NULL);
+}
+EXPORT_SYMBOL_GPL(tpm_tis_spi_init);
 
 static const struct tpm_tis_phy_ops tpm_spi_phy_ops = {
        .read_bytes = tpm_tis_spi_read_bytes,
@@ -217,11 +221,6 @@ static int tpm_tis_spi_probe(struct spi_device *dev)
        if (!phy)
                return -ENOMEM;
 
-       phy->spi_device = dev;
-
-       phy->iobuf = devm_kmalloc(&dev->dev, MAX_SPI_FRAMESIZE, GFP_KERNEL);
-       if (!phy->iobuf)
-               return -ENOMEM;
        phy->flow_control = tpm_tis_spi_flow_control;
 
        /* If the SPI device has an IRQ then use that */
@@ -230,8 +229,7 @@ static int tpm_tis_spi_probe(struct spi_device *dev)
        else
                irq = -1;
 
-       return tpm_tis_core_init(&dev->dev, &phy->priv, irq, &tpm_spi_phy_ops,
-                                NULL);
+       return tpm_tis_spi_init(dev, phy, irq, &tpm_spi_phy_ops);
 }
 
 static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume);
diff --git a/drivers/char/tpm/tpm_tis_spi.h b/drivers/char/tpm/tpm_tis_spi.h
new file mode 100644
index 000000000000..48be5130794a
--- /dev/null
+++ b/drivers/char/tpm/tpm_tis_spi.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2015 Infineon Technologies AG
+ * Copyright (C) 2016 STMicroelectronics SAS
+ */
+
+#ifndef TPM_TIS_SPI_H
+#define TPM_TIS_SPI_H
+
+#include "tpm_tis_core.h"
+
+struct tpm_tis_spi_phy {
+       struct tpm_tis_data priv;
+       struct spi_device *spi_device;
+       int (*flow_control)(struct tpm_tis_spi_phy *phy,
+                            struct spi_transfer *xfer);
+       void (*pre_transfer)(struct tpm_tis_spi_phy *phy);
+
+       u8 *iobuf;
+};
+
+static inline struct tpm_tis_spi_phy *to_tpm_tis_spi_phy(struct tpm_tis_data 
*data)
+{
+       return container_of(data, struct tpm_tis_spi_phy, priv);
+}
+
+extern 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);
+
+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);
+
+#endif
-- 
Sent by a computer through tubes

Reply via email to