diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index cc1e5bc..91332dd 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -507,7 +507,8 @@ int tpm_get_timeouts(struct tpm_chip *chip)
 	struct tpm_cmd_t tpm_cmd;
 	unsigned long new_timeout[4];
 	unsigned long old_timeout[4];
-	struct duration_t *duration_cap;
+	unsigned long new_duration[3];
+	unsigned long old_duration[3];
 	ssize_t rc;
 
 	tpm_cmd.header.in = tpm_getcap_header;
@@ -599,26 +600,34 @@ duration:
 	    != sizeof(tpm_cmd.header.out) + sizeof(u32) + 3 * sizeof(u32))
 		return -EINVAL;
 
-	duration_cap = &tpm_cmd.params.getcap_out.cap.duration;
+	old_duration[TPM_SHORT] =
+		be32_to_cpu(tpm_cmd.params.getcap_out.cap.duration.tpm_short);
+	old_duration[TPM_MEDIUM] =
+		be32_to_cpu(tpm_cmd.params.getcap_out.cap.duration.tpm_medium);
+	old_duration[TPM_LONG] =
+		be32_to_cpu(tpm_cmd.params.getcap_out.cap.duration.tpm_long);
+	memcpy(new_duration, old_duration, sizeof(new_duration));
+
+	if (chip->ops->update_durations != NULL)
+		chip->vendor.duration_adjusted =
+			chip->ops->update_durations(chip, new_duration);
+
+	/* Report adjusted durations */
+	if (chip->vendor.duration_adjusted) {
+		dev_info(chip->pdev,
+			 HW_ERR "Adjusting reported durations: short %lu->%luus medium %lu->%luus long %lu->%luus\n",
+			 old_duration[TPM_SHORT], new_duration[TPM_SHORT],
+			 old_duration[TPM_MEDIUM], new_duration[TPM_MEDIUM],
+			 old_duration[TPM_LONG], new_duration[TPM_LONG]);
+	}
+
 	chip->vendor.duration[TPM_SHORT] =
-	    usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_short));
+		usecs_to_jiffies(new_duration[TPM_SHORT]);
 	chip->vendor.duration[TPM_MEDIUM] =
-	    usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_medium));
+		usecs_to_jiffies(new_duration[TPM_MEDIUM]);
 	chip->vendor.duration[TPM_LONG] =
-	    usecs_to_jiffies(be32_to_cpu(duration_cap->tpm_long));
+		usecs_to_jiffies(new_duration[TPM_LONG]);
 
-	/* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above
-	 * value wrong and apparently reports msecs rather than usecs. So we
-	 * fix up the resulting too-small TPM_SHORT value to make things work.
-	 * We also scale the TPM_MEDIUM and -_LONG values by 1000.
-	 */
-	if (chip->vendor.duration[TPM_SHORT] < (HZ / 100)) {
-		chip->vendor.duration[TPM_SHORT] = HZ;
-		chip->vendor.duration[TPM_MEDIUM] *= 1000;
-		chip->vendor.duration[TPM_LONG] *= 1000;
-		chip->vendor.duration_adjusted = true;
-		dev_info(chip->pdev, "Adjusting TPM timeout parameters.");
-	}
 	return 0;
 }
 EXPORT_SYMBOL_GPL(tpm_get_timeouts);
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 088fa86..3baba73 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -505,6 +505,45 @@ static bool tpm_tis_update_timeouts(struct tpm_chip *chip,
 	return false;
 }
 
+struct tis_vendor_duration_override {
+	u32 did_vid;
+	unsigned long duration_us[3];
+};
+
+static const struct tis_vendor_duration_override vendor_duration_overrides[] = {
+};
+
+static bool tpm_tis_update_durations(struct tpm_chip *chip,
+				     unsigned long *duration_cap)
+{
+	int i;
+	u32 did_vid;
+
+	did_vid = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
+
+	for (i = 0; i != ARRAY_SIZE(vendor_duration_overrides); i++) {
+		if (vendor_duration_overrides[i].did_vid != did_vid)
+			continue;
+		memcpy(duration_cap, vendor_duration_overrides[i].duration_us,
+		       sizeof(vendor_duration_overrides[i].duration_us));
+		return true;
+	}
+
+	/* The Broadcom BCM0102 chipset in a Dell Latitude D820 gets the above
+	 * value wrong and apparently reports msecs rather than usecs. So we
+	 * fix up the resulting too-small TPM_SHORT value to make things work.
+	 * We also scale the TPM_MEDIUM and -_LONG values by 1000.
+	 */
+	if (duration_cap[TPM_SHORT] < (HZ / 100)) {
+		duration_cap[TPM_SHORT] = HZ;
+		duration_cap[TPM_MEDIUM] *= 1000;
+		duration_cap[TPM_LONG] *= 1000;
+		return true;
+	}
+
+	return false;
+}
+
 /*
  * Early probing for iTPM with STS_DATA_EXPECT flaw.
  * Try sending command without itpm flag set and if that
@@ -570,6 +609,7 @@ static const struct tpm_class_ops tpm_tis = {
 	.send = tpm_tis_send,
 	.cancel = tpm_tis_ready,
 	.update_timeouts = tpm_tis_update_timeouts,
+	.update_durations = tpm_tis_update_durations,
 	.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 	.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 	.req_canceled = tpm_tis_req_canceled,
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 706e63e..862d0a1 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -43,6 +43,8 @@ struct tpm_class_ops {
 	u8 (*status) (struct tpm_chip *chip);
 	bool (*update_timeouts)(struct tpm_chip *chip,
 				unsigned long *timeout_cap);
+	bool (*update_durations)(struct tpm_chip *chip,
+				unsigned long *duration_cap);
 
 };
 
