Added two new callbacks to struct tpm_class_ops:

- request_locality
- relinquish_locality

These are called before sending and receiving data from the TPM.

Signed-off-by: Jarkko Sakkinen <[email protected]>
---
 drivers/char/tpm/tpm-interface.c |  9 +++++++++
 drivers/char/tpm/tpm_crb.c       | 41 +++++++++++++++++++++++++++++++++++++++-
 include/linux/tpm.h              |  3 ++-
 3 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index bd2128e..ae6aafa 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -369,6 +369,12 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, 
size_t bufsiz,
        if (chip->dev.parent)
                pm_runtime_get_sync(chip->dev.parent);
 
+       if (chip->ops->request_locality)  {
+               rc = chip->ops->request_locality(chip);
+               if (rc)
+                       goto out;
+       }
+
        rc = chip->ops->send(chip, (u8 *) buf, count);
        if (rc < 0) {
                dev_err(&chip->dev,
@@ -410,6 +416,9 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, 
size_t bufsiz,
                dev_err(&chip->dev,
                        "tpm_transmit: tpm_recv: error %zd\n", rc);
 out:
+       if (chip->ops->relinquish_locality)
+               chip->ops->relinquish_locality(chip);
+
        if (chip->dev.parent)
                pm_runtime_put_sync(chip->dev.parent);
 
diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
index 3245618..89dc8a176 100644
--- a/drivers/char/tpm/tpm_crb.c
+++ b/drivers/char/tpm/tpm_crb.c
@@ -34,6 +34,15 @@ enum crb_defaults {
        CRB_ACPI_START_INDEX = 1,
 };
 
+enum crb_loc_ctrl {
+       CRB_LOC_CTRL_REQUEST_ACCESS     = BIT(0),
+       CRB_LOC_CTRL_RELINQUISH         = BIT(1),
+};
+
+enum crb_loc_state {
+       CRB_LOC_STATE_LOC_ASSIGNED      = BIT(1),
+};
+
 enum crb_ctrl_req {
        CRB_CTRL_REQ_CMD_READY  = BIT(0),
        CRB_CTRL_REQ_GO_IDLE    = BIT(1),
@@ -172,6 +181,35 @@ static int __maybe_unused crb_cmd_ready(struct device *dev,
        return 0;
 }
 
+static int crb_request_locality(struct tpm_chip *chip)
+{
+       struct crb_priv *priv = dev_get_drvdata(&chip->dev);
+
+       if (!priv->regs_h)
+               return 0;
+
+       iowrite32(CRB_LOC_CTRL_REQUEST_ACCESS, &priv->regs_h->loc_ctrl);
+       if (!crb_wait_for_reg_32(&priv->regs_h->loc_state,
+                                CRB_LOC_STATE_LOC_ASSIGNED, /* mask */
+                                CRB_LOC_STATE_LOC_ASSIGNED, /* value */
+                                TPM2_TIMEOUT_C)) {
+               dev_warn(&chip->dev, "TPM_LOC_STATE_x.requestAccess timed 
out\n");
+               return -ETIME;
+       }
+
+       return 0;
+}
+
+static void crb_relinquish_locality(struct tpm_chip *chip)
+{
+       struct crb_priv *priv = dev_get_drvdata(&chip->dev);
+
+       if (!priv->regs_h)
+               return;
+
+       iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl);
+}
+
 static u8 crb_status(struct tpm_chip *chip)
 {
        struct crb_priv *priv = dev_get_drvdata(&chip->dev);
@@ -198,7 +236,6 @@ static int crb_recv(struct tpm_chip *chip, u8 *buf, size_t 
count)
 
        memcpy_fromio(buf, priv->rsp, 6);
        expected = be32_to_cpup((__be32 *) &buf[2]);
-
        if (expected > count)
                return -EIO;
 
@@ -279,6 +316,8 @@ static const struct tpm_class_ops tpm_crb = {
        .send = crb_send,
        .cancel = crb_cancel,
        .req_canceled = crb_req_canceled,
+       .request_locality = crb_request_locality,
+       .relinquish_locality = crb_relinquish_locality,
        .req_complete_mask = CRB_DRV_STS_COMPLETE,
        .req_complete_val = CRB_DRV_STS_COMPLETE,
 };
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index da158f0..0ac6ea6 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -48,7 +48,8 @@ struct tpm_class_ops {
        u8 (*status) (struct tpm_chip *chip);
        bool (*update_timeouts)(struct tpm_chip *chip,
                                unsigned long *timeout_cap);
-
+       int (*request_locality)(struct tpm_chip *chip);
+       void (*relinquish_locality)(struct tpm_chip *chip);
 };
 
 #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
-- 
2.9.3


------------------------------------------------------------------------------
Announcing the Oxford Dictionaries API! The API offers world-renowned
dictionary content that is easy and intuitive to access. Sign up for an
account today to start using our lexical data to power your apps and
projects. Get started today and enter our developer competition.
http://sdm.link/oxford
_______________________________________________
tpmdd-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

Reply via email to