@@ -377,7 +377,8 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
&priv->int_queue, false);
status = tpm_tis_status(chip);
- if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) {
+ if ((status & priv->data_expect_mask) !=
+ priv->data_expect_val) {
rc = -EIO;
goto out_err;
}
@@ -391,7 +392,8 @@ static int tpm_tis_send_data(struct tpm_chip *chip, u8 *buf, size_t len)
wait_for_tpm_stat(chip, TPM_STS_VALID, chip->timeout_c,
&priv->int_queue, false);
status = tpm_tis_status(chip);
- if ((status & TPM_STS_DATA_EXPECT) != 0) {
+ if ((status & priv->data_expect_mask) ==
+ priv->data_expect_mask) {
rc = -EIO;
goto out_err;
}
@@ -529,6 +531,8 @@ static bool tpm_tis_update_timeouts(struct tpm_chip *chip,
static int probe_itpm(struct tpm_chip *chip)
{
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+ u8 data_expect_mask = priv->data_expect_mask;
+ u8 data_expect_val = priv->data_expect_val;
int rc = 0;
u8 cmd_getticks[] = {
0x00, 0xc1, 0x00, 0x00, 0x00, 0x0a,
@@ -556,13 +560,18 @@ static int probe_itpm(struct tpm_chip *chip)
release_locality(chip, priv->locality, 0);
itpm = true;
+ priv->data_expect_mask = 0;
+ priv->data_expect_val = 0;
rc = tpm_tis_send_data(chip, cmd_getticks, len);
if (rc == 0) {
dev_info(&chip->dev, "Detected an iTPM.\n");
rc = 1;
- } else
+ } else {
+ priv->data_expect_mask = data_expect_mask;
+ priv->data_expect_val = data_expect_val;
rc = -EFAULT;
+ }
out:
itpm = rem_itpm;
@@ -598,6 +607,11 @@ static const struct tpm_class_ops tpm_tis = {
.req_canceled = tpm_tis_req_canceled,
};
+static struct tpm_tis_phy_ops tis_phy_ops = {
+ .data_expect_mask = TPM_STS_DATA_EXPECT,
+ .data_expect_val = TPM_STS_DATA_EXPECT,
+};
+
static int tpm_mem_read_bytes(struct tpm_chip *chip, u32 addr, u16 len,
u8 *result)
{
@@ -852,6 +866,8 @@ static int tpm_tis_init(struct device *dev, struct tpm_info *tpm_info,
chip->timeout_b = TIS_TIMEOUT_B_MAX;
chip->timeout_c = TIS_TIMEOUT_C_MAX;
chip->timeout_d = TIS_TIMEOUT_D_MAX;
+ priv->data_expect_req = TPM_STS_DATA_EXPECT;
+ priv->data_expect_mask = TPM_STS_DATA_EXPECT;
priv->phy_id = phy;
dev_set_drvdata(&chip->dev, priv);
@@ -36,14 +36,21 @@ struct tpm_tis_class_lowlevel {
int (*write32)(struct tpm_chip *chip, u32 addr, u32 src);
};
+struct tpm_tis_phy_ops {
+ int (*post_probe)(struct tpm_chip *chip);
+};
+
struct tpm_tis_data {
u16 manufacturer_id;
+ u8 data_expect_mask;
+ u8 data_expect_val;
int locality;
int irq;
bool irq_tested;
wait_queue_head_t int_queue;
wait_queue_head_t read_queue;
const struct tpm_tis_class_lowlevel *lowlevel;
+ const struct tpm_tis_phy_ops *phy_ops;
void *phy_id;
};
In order to keep this itpm workaround available after the tpm_tis rework, we are changing the way it is managed by using a tpm_tis_phy_ops structure allowing to manage TPM_STS_EXPECT_DATA bit behavior according to different TPM vendor. Those 2 fields might be used only for tpm_tis (lpc) phy in the future. Signed-off-by: Christophe Ricard <christophe-h.ricard@st.com> --- drivers/char/tpm/tpm_tis.c | 22 +++++++++++++++++++--- drivers/char/tpm/tpm_tis_core.h | 7 +++++++ 2 files changed, 26 insertions(+), 3 deletions(-)