diff --git a/drivers/tpm/Makefile b/drivers/tpm/Makefile
index 150570ee7e4d94c096ad2b2340cfef13c043fc51..597966ce1fad02382055abecf6194249a4c9bcaa 100644
--- a/drivers/tpm/Makefile
+++ b/drivers/tpm/Makefile
@@ -3,9 +3,7 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
-# TODO: Merge tpm_tis_lpc.c with tpm.c
 obj-$(CONFIG_TPM_ATMEL_TWI) += tpm_atmel_twi.o
-obj-$(CONFIG_TPM_TIS_I2C) += tpm.o
 obj-$(CONFIG_TPM_TIS_I2C) += tpm_tis_i2c.o
 obj-$(CONFIG_TPM_TIS_LPC) += tpm_tis_lpc.o
 obj-$(CONFIG_TPM_TIS_SANDBOX) += tpm_tis_sandbox.o
diff --git a/drivers/tpm/tpm.c b/drivers/tpm/tpm.c
deleted file mode 100644
index 24997f6702d7b9796d4e3ba8a5d8d660b819046b..0000000000000000000000000000000000000000
--- a/drivers/tpm/tpm.c
+++ /dev/null
@@ -1,594 +0,0 @@
-/*
- * Copyright (C) 2011 Infineon Technologies
- *
- * Authors:
- * Peter Huewe <huewe.external@infineon.com>
- *
- * Description:
- * Device driver for TCG/TCPA TPM (trusted platform module).
- * Specifications at www.trustedcomputinggroup.org
- *
- * It is based on the Linux kernel driver tpm.c from Leendert van
- * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
- *
- * Version: 2.1.1
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2 of the
- * License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <config.h>
-#include <common.h>
-#include <dm.h>
-#include <linux/compiler.h>
-#include <fdtdec.h>
-#include <i2c.h>
-#include <tpm.h>
-#include <asm-generic/errno.h>
-#include <linux/types.h>
-#include <linux/unaligned/be_byteshift.h>
-
-#include "tpm_private.h"
-
-DECLARE_GLOBAL_DATA_PTR;
-
-/* TPM configuration */
-struct tpm {
-	struct udevice *dev;
-	char inited;
-} tpm;
-
-/* Global structure for tpm chip data */
-static struct tpm_chip g_chip;
-
-enum tpm_duration {
-	TPM_SHORT = 0,
-	TPM_MEDIUM = 1,
-	TPM_LONG = 2,
-	TPM_UNDEFINED,
-};
-
-/* Extended error numbers from linux (see errno.h) */
-#define ECANCELED	125	/* Operation Canceled */
-
-/* Timer frequency. Corresponds to msec timer resolution*/
-#define HZ		1000
-
-#define TPM_MAX_ORDINAL			243
-#define TPM_MAX_PROTECTED_ORDINAL	12
-#define TPM_PROTECTED_ORDINAL_MASK	0xFF
-
-#define TPM_CMD_COUNT_BYTE	2
-#define TPM_CMD_ORDINAL_BYTE	6
-
-/*
- * Array with one entry per ordinal defining the maximum amount
- * of time the chip could take to return the result.  The ordinal
- * designation of short, medium or long is defined in a table in
- * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
- * values of the SHORT, MEDIUM, and LONG durations are retrieved
- * from the chip during initialization with a call to tpm_get_timeouts.
- */
-static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
-	TPM_UNDEFINED,		/* 0 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,		/* 5 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_SHORT,		/* 10 */
-	TPM_SHORT,
-};
-
-static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
-	TPM_UNDEFINED,		/* 0 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,		/* 5 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_SHORT,		/* 10 */
-	TPM_SHORT,
-	TPM_MEDIUM,
-	TPM_LONG,
-	TPM_LONG,
-	TPM_MEDIUM,		/* 15 */
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_MEDIUM,
-	TPM_LONG,
-	TPM_SHORT,		/* 20 */
-	TPM_SHORT,
-	TPM_MEDIUM,
-	TPM_MEDIUM,
-	TPM_MEDIUM,
-	TPM_SHORT,		/* 25 */
-	TPM_SHORT,
-	TPM_MEDIUM,
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_MEDIUM,		/* 30 */
-	TPM_LONG,
-	TPM_MEDIUM,
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_SHORT,		/* 35 */
-	TPM_MEDIUM,
-	TPM_MEDIUM,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_MEDIUM,		/* 40 */
-	TPM_LONG,
-	TPM_MEDIUM,
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_SHORT,		/* 45 */
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_LONG,
-	TPM_MEDIUM,		/* 50 */
-	TPM_MEDIUM,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,		/* 55 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_MEDIUM,		/* 60 */
-	TPM_MEDIUM,
-	TPM_MEDIUM,
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_MEDIUM,		/* 65 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_SHORT,		/* 70 */
-	TPM_SHORT,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,		/* 75 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_LONG,		/* 80 */
-	TPM_UNDEFINED,
-	TPM_MEDIUM,
-	TPM_LONG,
-	TPM_SHORT,
-	TPM_UNDEFINED,		/* 85 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_SHORT,		/* 90 */
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_UNDEFINED,		/* 95 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_MEDIUM,		/* 100 */
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,		/* 105 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_SHORT,		/* 110 */
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_SHORT,		/* 115 */
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_LONG,		/* 120 */
-	TPM_LONG,
-	TPM_MEDIUM,
-	TPM_UNDEFINED,
-	TPM_SHORT,
-	TPM_SHORT,		/* 125 */
-	TPM_SHORT,
-	TPM_LONG,
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_SHORT,		/* 130 */
-	TPM_MEDIUM,
-	TPM_UNDEFINED,
-	TPM_SHORT,
-	TPM_MEDIUM,
-	TPM_UNDEFINED,		/* 135 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_SHORT,		/* 140 */
-	TPM_SHORT,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,		/* 145 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_SHORT,		/* 150 */
-	TPM_MEDIUM,
-	TPM_MEDIUM,
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_UNDEFINED,		/* 155 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_SHORT,		/* 160 */
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,		/* 165 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_LONG,		/* 170 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,		/* 175 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_MEDIUM,		/* 180 */
-	TPM_SHORT,
-	TPM_MEDIUM,
-	TPM_MEDIUM,
-	TPM_MEDIUM,
-	TPM_MEDIUM,		/* 185 */
-	TPM_SHORT,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,		/* 190 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,		/* 195 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_SHORT,		/* 200 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_SHORT,
-	TPM_SHORT,		/* 205 */
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_MEDIUM,		/* 210 */
-	TPM_UNDEFINED,
-	TPM_MEDIUM,
-	TPM_MEDIUM,
-	TPM_MEDIUM,
-	TPM_UNDEFINED,		/* 215 */
-	TPM_MEDIUM,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_SHORT,
-	TPM_SHORT,		/* 220 */
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_SHORT,
-	TPM_UNDEFINED,		/* 225 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_SHORT,		/* 230 */
-	TPM_LONG,
-	TPM_MEDIUM,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,		/* 235 */
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_UNDEFINED,
-	TPM_SHORT,		/* 240 */
-	TPM_UNDEFINED,
-	TPM_MEDIUM,
-};
-
-/* Returns max number of milliseconds to wait */
-static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
-		u32 ordinal)
-{
-	int duration_idx = TPM_UNDEFINED;
-	int duration = 0;
-
-	if (ordinal < TPM_MAX_ORDINAL) {
-		duration_idx = tpm_ordinal_duration[ordinal];
-	} else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
-			TPM_MAX_PROTECTED_ORDINAL) {
-		duration_idx = tpm_protected_ordinal_duration[
-				ordinal & TPM_PROTECTED_ORDINAL_MASK];
-	}
-
-	if (duration_idx != TPM_UNDEFINED)
-		duration = chip->vendor.duration[duration_idx];
-
-	if (duration <= 0)
-		return 2 * 60 * HZ; /* Two minutes timeout */
-	else
-		return duration;
-}
-
-static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
-{
-	int rc;
-	u32 count, ordinal;
-	unsigned long start, stop;
-
-	struct tpm_chip *chip = &g_chip;
-
-	/* switch endianess: big->little */
-	count = get_unaligned_be32(buf + TPM_CMD_COUNT_BYTE);
-	ordinal = get_unaligned_be32(buf + TPM_CMD_ORDINAL_BYTE);
-
-	if (count == 0) {
-		error("no data\n");
-		return -ENODATA;
-	}
-	if (count > bufsiz) {
-		error("invalid count value %x %zx\n", count, bufsiz);
-		return -E2BIG;
-	}
-
-	debug("Calling send\n");
-	rc = chip->vendor.send(chip, (u8 *)buf, count);
-	debug("   ... done calling send\n");
-	if (rc < 0) {
-		error("tpm_transmit: tpm_send: error %d\n", rc);
-		goto out;
-	}
-
-	if (chip->vendor.irq)
-		goto out_recv;
-
-	start = get_timer(0);
-	stop = tpm_calc_ordinal_duration(chip, ordinal);
-	do {
-		debug("waiting for status... %ld %ld\n", start, stop);
-		u8 status = chip->vendor.status(chip);
-		if ((status & chip->vendor.req_complete_mask) ==
-		    chip->vendor.req_complete_val) {
-			debug("...got it;\n");
-			goto out_recv;
-		}
-
-		if (status == chip->vendor.req_canceled) {
-			error("Operation Canceled\n");
-			rc = -ECANCELED;
-			goto out;
-		}
-		udelay(TPM_TIMEOUT * 1000);
-	} while (get_timer(start) < stop);
-
-	chip->vendor.cancel(chip);
-	error("Operation Timed out\n");
-	rc = -ETIME;
-	goto out;
-
-out_recv:
-	debug("out_recv: reading response...\n");
-	rc = chip->vendor.recv(chip, (u8 *)buf, TPM_BUFSIZE);
-	if (rc < 0)
-		error("tpm_transmit: tpm_recv: error %d\n", rc);
-
-out:
-	return rc;
-}
-
-static int tpm_open_dev(struct udevice *dev)
-{
-	int rc;
-
-	debug("%s: start\n", __func__);
-	if (g_chip.is_open)
-		return -EBUSY;
-	rc = tpm_vendor_init(dev);
-	if (rc < 0)
-		g_chip.is_open = 0;
-	return rc;
-}
-
-static void tpm_close(void)
-{
-	if (g_chip.is_open) {
-		tpm_vendor_cleanup(&g_chip);
-		g_chip.is_open = 0;
-	}
-}
-
-/**
- * Decode TPM configuration.
- *
- * @param dev	Returns a configuration of TPM device
- * @return 0 if ok, -1 on error
- */
-static int tpm_decode_config(struct tpm *dev)
-{
-	const void *blob = gd->fdt_blob;
-	struct udevice *bus;
-	int chip_addr;
-	int parent;
-	int node;
-	int ret;
-
-	node = fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM);
-	if (node < 0) {
-		node = fdtdec_next_compatible(blob, 0,
-				COMPAT_INFINEON_SLB9645_TPM);
-	}
-	if (node < 0) {
-		debug("%s: Node not found\n", __func__);
-		return -1;
-	}
-	parent = fdt_parent_offset(blob, node);
-	if (parent < 0) {
-		debug("%s: Cannot find node parent\n", __func__);
-		return -1;
-	}
-
-	/*
-	 * TODO(sjg@chromium.org): Remove this when driver model supports
-	 * TPMs
-	 */
-	ret = uclass_get_device_by_of_offset(UCLASS_I2C, parent, &bus);
-	if (ret) {
-		debug("Cannot find bus for node '%s: ret=%d'\n",
-		      fdt_get_name(blob, parent, NULL), ret);
-		return ret;
-	}
-
-	chip_addr = fdtdec_get_int(blob, node, "reg", -1);
-	if (chip_addr == -1) {
-		debug("Cannot find reg property for node '%s: ret=%d'\n",
-		      fdt_get_name(blob, node, NULL), ret);
-		return ret;
-	}
-	/*
-	 * TODO(sjg@chromium.org): Older TPMs will need to use the older method
-	 * in iic_tpm_read() so the offset length needs to be 0 here.
-	 */
-	ret = i2c_get_chip(bus, chip_addr, 1, &dev->dev);
-	if (ret) {
-		debug("Cannot find device for node '%s: ret=%d'\n",
-		      fdt_get_name(blob, node, NULL), ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *entry)
-{
-	struct tpm_chip *chip;
-
-	/* Driver specific per-device data */
-	chip = &g_chip;
-	memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
-	chip->is_open = 1;
-
-	return chip;
-}
-
-int tis_init(void)
-{
-	if (tpm.inited)
-		return 0;
-
-	if (tpm_decode_config(&tpm))
-		return -1;
-
-	debug("%s: done\n", __func__);
-
-	tpm.inited = 1;
-
-	return 0;
-}
-
-int tis_open(void)
-{
-	int rc;
-
-	if (!tpm.inited)
-		return -1;
-
-	rc = tpm_open_dev(tpm.dev);
-
-	return rc;
-}
-
-int tis_close(void)
-{
-	if (!tpm.inited)
-		return -1;
-
-	tpm_close();
-
-	return 0;
-}
-
-int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
-		uint8_t *recvbuf, size_t *rbuf_len)
-{
-	int len;
-	uint8_t buf[4096];
-
-	if (!tpm.inited)
-		return -1;
-
-	if (sizeof(buf) < sbuf_size)
-		return -1;
-
-	memcpy(buf, sendbuf, sbuf_size);
-
-	len = tpm_transmit(buf, sbuf_size);
-
-	if (len < 10) {
-		*rbuf_len = 0;
-		return -1;
-	}
-
-	memcpy(recvbuf, buf, len);
-	*rbuf_len = len;
-
-	return 0;
-}
diff --git a/drivers/tpm/tpm_tis_i2c.c b/drivers/tpm/tpm_tis_i2c.c
index 438a22160747ee4414384a5d404b0a2223c4ad34..e547f0ad9f311db9074e16b145244ee242562bbb 100644
--- a/drivers/tpm/tpm_tis_i2c.c
+++ b/drivers/tpm/tpm_tis_i2c.c
@@ -30,7 +30,7 @@
 #include <linux/types.h>
 #include <linux/unaligned/be_byteshift.h>
 
-#include "tpm_private.h"
+#include "tpm_tis_i2c.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -95,6 +95,304 @@ static const char * const chip_name[] = {
 #define	TPM_DATA_FIFO(l)		(0x0005 | ((l) << 4))
 #define	TPM_DID_VID(l)			(0x0006 | ((l) << 4))
 
+enum tpm_duration {
+	TPM_SHORT = 0,
+	TPM_MEDIUM = 1,
+	TPM_LONG = 2,
+	TPM_UNDEFINED,
+};
+
+/* Extended error numbers from linux (see errno.h) */
+#define ECANCELED	125	/* Operation Canceled */
+
+/* Timer frequency. Corresponds to msec timer resolution*/
+#define HZ		1000
+
+#define TPM_MAX_ORDINAL			243
+#define TPM_MAX_PROTECTED_ORDINAL	12
+#define TPM_PROTECTED_ORDINAL_MASK	0xFF
+
+#define TPM_CMD_COUNT_BYTE	2
+#define TPM_CMD_ORDINAL_BYTE	6
+
+/*
+ * Array with one entry per ordinal defining the maximum amount
+ * of time the chip could take to return the result.  The ordinal
+ * designation of short, medium or long is defined in a table in
+ * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
+ * values of the SHORT, MEDIUM, and LONG durations are retrieved
+ * from the chip during initialization with a call to tpm_get_timeouts.
+ */
+static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
+	TPM_UNDEFINED,		/* 0 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,		/* 5 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_SHORT,		/* 10 */
+	TPM_SHORT,
+};
+
+static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
+	TPM_UNDEFINED,		/* 0 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,		/* 5 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_SHORT,		/* 10 */
+	TPM_SHORT,
+	TPM_MEDIUM,
+	TPM_LONG,
+	TPM_LONG,
+	TPM_MEDIUM,		/* 15 */
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_MEDIUM,
+	TPM_LONG,
+	TPM_SHORT,		/* 20 */
+	TPM_SHORT,
+	TPM_MEDIUM,
+	TPM_MEDIUM,
+	TPM_MEDIUM,
+	TPM_SHORT,		/* 25 */
+	TPM_SHORT,
+	TPM_MEDIUM,
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_MEDIUM,		/* 30 */
+	TPM_LONG,
+	TPM_MEDIUM,
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_SHORT,		/* 35 */
+	TPM_MEDIUM,
+	TPM_MEDIUM,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_MEDIUM,		/* 40 */
+	TPM_LONG,
+	TPM_MEDIUM,
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_SHORT,		/* 45 */
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_LONG,
+	TPM_MEDIUM,		/* 50 */
+	TPM_MEDIUM,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,		/* 55 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_MEDIUM,		/* 60 */
+	TPM_MEDIUM,
+	TPM_MEDIUM,
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_MEDIUM,		/* 65 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_SHORT,		/* 70 */
+	TPM_SHORT,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,		/* 75 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_LONG,		/* 80 */
+	TPM_UNDEFINED,
+	TPM_MEDIUM,
+	TPM_LONG,
+	TPM_SHORT,
+	TPM_UNDEFINED,		/* 85 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_SHORT,		/* 90 */
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_UNDEFINED,		/* 95 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_MEDIUM,		/* 100 */
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,		/* 105 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_SHORT,		/* 110 */
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_SHORT,		/* 115 */
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_LONG,		/* 120 */
+	TPM_LONG,
+	TPM_MEDIUM,
+	TPM_UNDEFINED,
+	TPM_SHORT,
+	TPM_SHORT,		/* 125 */
+	TPM_SHORT,
+	TPM_LONG,
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_SHORT,		/* 130 */
+	TPM_MEDIUM,
+	TPM_UNDEFINED,
+	TPM_SHORT,
+	TPM_MEDIUM,
+	TPM_UNDEFINED,		/* 135 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_SHORT,		/* 140 */
+	TPM_SHORT,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,		/* 145 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_SHORT,		/* 150 */
+	TPM_MEDIUM,
+	TPM_MEDIUM,
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_UNDEFINED,		/* 155 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_SHORT,		/* 160 */
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,		/* 165 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_LONG,		/* 170 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,		/* 175 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_MEDIUM,		/* 180 */
+	TPM_SHORT,
+	TPM_MEDIUM,
+	TPM_MEDIUM,
+	TPM_MEDIUM,
+	TPM_MEDIUM,		/* 185 */
+	TPM_SHORT,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,		/* 190 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,		/* 195 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_SHORT,		/* 200 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_SHORT,
+	TPM_SHORT,		/* 205 */
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_MEDIUM,		/* 210 */
+	TPM_UNDEFINED,
+	TPM_MEDIUM,
+	TPM_MEDIUM,
+	TPM_MEDIUM,
+	TPM_UNDEFINED,		/* 215 */
+	TPM_MEDIUM,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_SHORT,
+	TPM_SHORT,		/* 220 */
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_SHORT,
+	TPM_UNDEFINED,		/* 225 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_SHORT,		/* 230 */
+	TPM_LONG,
+	TPM_MEDIUM,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,		/* 235 */
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_SHORT,		/* 240 */
+	TPM_UNDEFINED,
+	TPM_MEDIUM,
+};
+
+/* TPM configuration */
+struct tpm {
+	struct udevice *dev;
+	char inited;
+} tpm;
+
+/* Global structure for tpm chip data */
+static struct tpm_chip g_chip;
+
 /* Structure to store I2C TPM specific stuff */
 struct tpm_dev {
 	struct udevice *dev;
@@ -595,3 +893,251 @@ void tpm_vendor_cleanup(struct tpm_chip *chip)
 {
 	release_locality(chip, chip->vendor.locality, 1);
 }
+
+/* Returns max number of milliseconds to wait */
+static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
+		u32 ordinal)
+{
+	int duration_idx = TPM_UNDEFINED;
+	int duration = 0;
+
+	if (ordinal < TPM_MAX_ORDINAL) {
+		duration_idx = tpm_ordinal_duration[ordinal];
+	} else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
+			TPM_MAX_PROTECTED_ORDINAL) {
+		duration_idx = tpm_protected_ordinal_duration[
+				ordinal & TPM_PROTECTED_ORDINAL_MASK];
+	}
+
+	if (duration_idx != TPM_UNDEFINED)
+		duration = chip->vendor.duration[duration_idx];
+
+	if (duration <= 0)
+		return 2 * 60 * HZ; /* Two minutes timeout */
+	else
+		return duration;
+}
+
+static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
+{
+	int rc;
+	u32 count, ordinal;
+	unsigned long start, stop;
+
+	struct tpm_chip *chip = &g_chip;
+
+	/* switch endianess: big->little */
+	count = get_unaligned_be32(buf + TPM_CMD_COUNT_BYTE);
+	ordinal = get_unaligned_be32(buf + TPM_CMD_ORDINAL_BYTE);
+
+	if (count == 0) {
+		error("no data\n");
+		return -ENODATA;
+	}
+	if (count > bufsiz) {
+		error("invalid count value %x %zx\n", count, bufsiz);
+		return -E2BIG;
+	}
+
+	debug("Calling send\n");
+	rc = chip->vendor.send(chip, (u8 *)buf, count);
+	debug("   ... done calling send\n");
+	if (rc < 0) {
+		error("tpm_transmit: tpm_send: error %d\n", rc);
+		goto out;
+	}
+
+	if (chip->vendor.irq)
+		goto out_recv;
+
+	start = get_timer(0);
+	stop = tpm_calc_ordinal_duration(chip, ordinal);
+	do {
+		debug("waiting for status... %ld %ld\n", start, stop);
+		u8 status = chip->vendor.status(chip);
+		if ((status & chip->vendor.req_complete_mask) ==
+		    chip->vendor.req_complete_val) {
+			debug("...got it;\n");
+			goto out_recv;
+		}
+
+		if (status == chip->vendor.req_canceled) {
+			error("Operation Canceled\n");
+			rc = -ECANCELED;
+			goto out;
+		}
+		udelay(TPM_TIMEOUT * 1000);
+	} while (get_timer(start) < stop);
+
+	chip->vendor.cancel(chip);
+	error("Operation Timed out\n");
+	rc = -ETIME;
+	goto out;
+
+out_recv:
+	debug("out_recv: reading response...\n");
+	rc = chip->vendor.recv(chip, (u8 *)buf, TPM_BUFSIZE);
+	if (rc < 0)
+		error("tpm_transmit: tpm_recv: error %d\n", rc);
+
+out:
+	return rc;
+}
+
+static int tpm_open_dev(struct udevice *dev)
+{
+	int rc;
+
+	debug("%s: start\n", __func__);
+	if (g_chip.is_open)
+		return -EBUSY;
+	rc = tpm_vendor_init(dev);
+	if (rc < 0)
+		g_chip.is_open = 0;
+	return rc;
+}
+
+static void tpm_close(void)
+{
+	if (g_chip.is_open) {
+		tpm_vendor_cleanup(&g_chip);
+		g_chip.is_open = 0;
+	}
+}
+
+/**
+ * Decode TPM configuration.
+ *
+ * @param dev	Returns a configuration of TPM device
+ * @return 0 if ok, -1 on error
+ */
+static int tpm_decode_config(struct tpm *dev)
+{
+	const void *blob = gd->fdt_blob;
+	struct udevice *bus;
+	int chip_addr;
+	int parent;
+	int node;
+	int ret;
+
+	node = fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM);
+	if (node < 0) {
+		node = fdtdec_next_compatible(blob, 0,
+				COMPAT_INFINEON_SLB9645_TPM);
+	}
+	if (node < 0) {
+		debug("%s: Node not found\n", __func__);
+		return -1;
+	}
+	parent = fdt_parent_offset(blob, node);
+	if (parent < 0) {
+		debug("%s: Cannot find node parent\n", __func__);
+		return -1;
+	}
+
+	/*
+	 * TODO(sjg@chromium.org): Remove this when driver model supports
+	 * TPMs
+	 */
+	ret = uclass_get_device_by_of_offset(UCLASS_I2C, parent, &bus);
+	if (ret) {
+		debug("Cannot find bus for node '%s: ret=%d'\n",
+		      fdt_get_name(blob, parent, NULL), ret);
+		return ret;
+	}
+
+	chip_addr = fdtdec_get_int(blob, node, "reg", -1);
+	if (chip_addr == -1) {
+		debug("Cannot find reg property for node '%s: ret=%d'\n",
+		      fdt_get_name(blob, node, NULL), ret);
+		return ret;
+	}
+	/*
+	 * TODO(sjg@chromium.org): Older TPMs will need to use the older method
+	 * in iic_tpm_read() so the offset length needs to be 0 here.
+	 */
+	ret = i2c_get_chip(bus, chip_addr, 1, &dev->dev);
+	if (ret) {
+		debug("Cannot find device for node '%s: ret=%d'\n",
+		      fdt_get_name(blob, node, NULL), ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *entry)
+{
+	struct tpm_chip *chip;
+
+	/* Driver specific per-device data */
+	chip = &g_chip;
+	memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
+	chip->is_open = 1;
+
+	return chip;
+}
+
+int tis_init(void)
+{
+	if (tpm.inited)
+		return 0;
+
+	if (tpm_decode_config(&tpm))
+		return -1;
+
+	debug("%s: done\n", __func__);
+
+	tpm.inited = 1;
+
+	return 0;
+}
+
+int tis_open(void)
+{
+	int rc;
+
+	if (!tpm.inited)
+		return -1;
+
+	rc = tpm_open_dev(tpm.dev);
+
+	return rc;
+}
+
+int tis_close(void)
+{
+	if (!tpm.inited)
+		return -1;
+
+	tpm_close();
+
+	return 0;
+}
+
+int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
+		uint8_t *recvbuf, size_t *rbuf_len)
+{
+	int len;
+	uint8_t buf[4096];
+
+	if (!tpm.inited)
+		return -1;
+
+	if (sizeof(buf) < sbuf_size)
+		return -1;
+
+	memcpy(buf, sendbuf, sbuf_size);
+
+	len = tpm_transmit(buf, sbuf_size);
+
+	if (len < 10) {
+		*rbuf_len = 0;
+		return -1;
+	}
+
+	memcpy(recvbuf, buf, len);
+	*rbuf_len = len;
+
+	return 0;
+}
diff --git a/drivers/tpm/tpm_private.h b/drivers/tpm/tpm_tis_i2c.h
similarity index 73%
rename from drivers/tpm/tpm_private.h
rename to drivers/tpm/tpm_tis_i2c.h
index daaf8b80291165a688acce395deda37c7b452760..75fa829e3d98b6134895d0951a15444038a6f7c3 100644
--- a/drivers/tpm/tpm_private.h
+++ b/drivers/tpm/tpm_tis_i2c.h
@@ -13,28 +13,11 @@
  * It is based on the Linux kernel driver tpm.c from Leendert van
  * Dorn, Dave Safford, Reiner Sailer, and Kyleen Hall.
  *
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2 of the
- * License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier:	GPL-2.0
  */
 
-#ifndef _TPM_PRIVATE_H_
-#define _TPM_PRIVATE_H_
+#ifndef _TPM_TIS_I2C_H
+#define _TPM_TIS_I2C_H
 
 #include <linux/compiler.h>
 #include <linux/types.h>
@@ -134,5 +117,4 @@ int tpm_vendor_init(struct udevice *dev);
 
 void tpm_vendor_cleanup(struct tpm_chip *chip);
 
-
 #endif