|
@@ -143,13 +143,58 @@ static bool check_locality(struct tpm_chip *chip, int l)
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+static bool locality_inactive(struct tpm_chip *chip, int l)
|
|
|
+{
|
|
|
+ struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
|
|
|
+ int rc;
|
|
|
+ u8 access;
|
|
|
+
|
|
|
+ rc = tpm_tis_read8(priv, TPM_ACCESS(l), &access);
|
|
|
+ if (rc < 0)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if ((access & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY))
|
|
|
+ == TPM_ACCESS_VALID)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
static int release_locality(struct tpm_chip *chip, int l)
|
|
|
{
|
|
|
struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
|
|
|
+ unsigned long stop, timeout;
|
|
|
+ long rc;
|
|
|
|
|
|
tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY);
|
|
|
|
|
|
- return 0;
|
|
|
+ stop = jiffies + chip->timeout_a;
|
|
|
+
|
|
|
+ if (chip->flags & TPM_CHIP_FLAG_IRQ) {
|
|
|
+again:
|
|
|
+ timeout = stop - jiffies;
|
|
|
+ if ((long)timeout <= 0)
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ rc = wait_event_interruptible_timeout(priv->int_queue,
|
|
|
+ (locality_inactive(chip, l)),
|
|
|
+ timeout);
|
|
|
+
|
|
|
+ if (rc > 0)
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ if (rc == -ERESTARTSYS && freezing(current)) {
|
|
|
+ clear_thread_flag(TIF_SIGPENDING);
|
|
|
+ goto again;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ do {
|
|
|
+ if (locality_inactive(chip, l))
|
|
|
+ return 0;
|
|
|
+ tpm_msleep(TPM_TIMEOUT);
|
|
|
+ } while (time_before(jiffies, stop));
|
|
|
+ }
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
static int request_locality(struct tpm_chip *chip, int l)
|