From: Stefano Radaelli <[email protected]>

The common TPM Device Tree binding already documents resets and
reset-gpios, but the TIS I2C driver never requests a reset control.
As a result, an I2C TPM held in reset by board wiring remains
inaccessible and the first register access during probe fails.

Request the optional reset control and deassert it before
communicating with the TPM. This keeps existing boards without a reset
line unchanged while allowing platforms using resets or reset-gpios to
release the TPM before probe continues.

Tested on a Variscite DART-MX95 with an ST33KTPM2XI2C TPM using
reset-gpios.

Signed-off-by: Stefano Radaelli <[email protected]>
---
 drivers/char/tpm/tpm_tis_i2c.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/char/tpm/tpm_tis_i2c.c b/drivers/char/tpm/tpm_tis_i2c.c
index d55f30fef00a..cde0b093ed58 100644
--- a/drivers/char/tpm/tpm_tis_i2c.c
+++ b/drivers/char/tpm/tpm_tis_i2c.c
@@ -12,6 +12,7 @@
 
 #include <linux/i2c.h>
 #include <linux/crc-ccitt.h>
+#include <linux/reset.h>
 #include "tpm_tis_core.h"
 
 /* TPM registers */
@@ -330,6 +331,7 @@ static const struct tpm_tis_phy_ops tpm_i2c_phy_ops = {
 static int tpm_tis_i2c_probe(struct i2c_client *dev)
 {
        struct tpm_tis_i2c_phy *phy;
+       struct reset_control *reset;
        const u8 crc_enable = 1;
        const u8 locality = 0;
        int ret;
@@ -346,6 +348,16 @@ static int tpm_tis_i2c_probe(struct i2c_client *dev)
        set_bit(TPM_TIS_DEFAULT_CANCELLATION, &phy->priv.flags);
        phy->i2c_client = dev;
 
+       reset = devm_reset_control_get_optional_exclusive(&dev->dev, NULL);
+       if (IS_ERR(reset))
+               return dev_err_probe(&dev->dev, PTR_ERR(reset),
+                                    "failed to get reset control\n");
+
+       ret = reset_control_deassert(reset);
+       if (ret)
+               return dev_err_probe(&dev->dev, ret,
+                                    "failed to deassert reset\n");
+
        /* must precede all communication with the tpm */
        ret = tpm_tis_i2c_init_guard_time(phy);
        if (ret)
-- 
2.47.3


Reply via email to