|
@@ -34,6 +34,16 @@ 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),
|
|
|
+ CRB_LOC_STATE_TPM_REG_VALID_STS = BIT(7),
|
|
|
+};
|
|
|
+
|
|
|
enum crb_ctrl_req {
|
|
|
CRB_CTRL_REQ_CMD_READY = BIT(0),
|
|
|
CRB_CTRL_REQ_GO_IDLE = BIT(1),
|
|
@@ -172,6 +182,35 @@ static int __maybe_unused crb_cmd_ready(struct device *dev,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int crb_request_locality(struct tpm_chip *chip, int loc)
|
|
|
+{
|
|
|
+ struct crb_priv *priv = dev_get_drvdata(&chip->dev);
|
|
|
+ u32 value = CRB_LOC_STATE_LOC_ASSIGNED |
|
|
|
+ CRB_LOC_STATE_TPM_REG_VALID_STS;
|
|
|
+
|
|
|
+ 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, value, 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, int loc)
|
|
|
+{
|
|
|
+ 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);
|
|
@@ -278,6 +317,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,
|
|
|
};
|