Skip to contentSkip to conversation

dm: Convert TPM drivers to driver model

PATCH New Simon Glass 2 participants 64 messages Aug 11, 2015 – Aug 20, 2015

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

cover dm: Convert TPM drivers to driver model

This series adds driver model support for Trusted Platform Modules (TPMs). These have a very simple interface and are configured via the device tree.

Two bus types are supported at present: I2C and LPC (Intel Low-Pin-Count).

Most drivers and users are converted over to driver model. The exception is the Atmel TPM and its users.

The I2C driver has been cleaned up and simplified. It was ported from Linux and was pretty hard to follow. This series includes patches to unify the code, remove duplicated data structures and drop unnecessary indirection.

Also this series enables the TPM on all Chromebooks (snow, spring, nyan-big, pit, pi, link) since some did not have it fully enabled.

As before, the 'tpm' command can be used to implement TPM functionality.

Simon Glass (25):
tpm: Remove old pre-driver-model I2C code
tpm: Drop two unused options
tpm: Add Kconfig options for TPMs
tpm: Convert board config TPM options to Kconfig
tpm: Convert drivers to use SPDX
tpm: Move the I2C TPM code into one file
tpm: tpm_tis_i2c: Drop unnecessary methods
tpm: tpm_tis_i2c: Drop struct tpm_vendor_specific
tpm: tpm_tis_i2c: Merge struct tpm_dev into tpm_chip
tpm: tpm_tis_i2c: Merge struct tpm into tpm_chip
tpm: tpm_tis_i2c: Move definitions into the header file
tpm: tpm_tis_i2c: Simplify init code
tpm: tpm_tis_i2c: Use a consistent tpm_tis_i2c_ prefix
tpm: tpm_tis_i2c: Tidy up delays
dm: tpm: Add a uclass for Trusted Platform Modules
dm: tpm: Convert the TPM command and library to driver model
dm: i2c: Add a command to adjust the offset length
tpm: Report tpm errors on the command line
dm: tpm: sandbox: Convert TPM driver to driver model
tpm: Check that parse_byte_string() has data to parse
exynos: x86: dts: Add tpm nodes to the device tree for Chrome OS
devices
dm: tpm: Convert I2C driver to driver model
dm: tpm: Convert LPC driver to driver model
tpm: Add a 'tpm info' command
tegra: nyan: Enable TPM command and driver

 README                                             |   6 -
 arch/arm/dts/exynos5250-snow.dts                   |   9 +
 arch/arm/dts/exynos5250-spring.dts                 |   8 +
 arch/arm/dts/exynos5420-peach-pit.dts              |   6 +-
 arch/arm/dts/exynos5800-peach-pi.dts               |   6 +-
 arch/sandbox/dts/sandbox.dts                       |   4 +
 arch/x86/dts/chromebook_link.dts                   |   5 +
 common/Kconfig                                     |  12 +
 common/cmd_i2c.c                                   |  33 +
 common/cmd_tpm.c                                   | 100 ++-
 configs/chromebook_link_defconfig                  |   4 +
 configs/chromebox_panther_defconfig                |   4 +
 .../controlcenterd_36BIT_SDCARD_DEVELOP_defconfig  |   4 +
 configs/controlcenterd_36BIT_SDCARD_defconfig      |   4 +
 .../controlcenterd_TRAILBLAZER_DEVELOP_defconfig   |   4 +
 configs/controlcenterd_TRAILBLAZER_defconfig       |   4 +
 configs/coreboot-x86_defconfig                     |   4 +
 configs/nyan-big_defconfig                         |   4 +
 configs/peach-pi_defconfig                         |   4 +
 configs/peach-pit_defconfig                        |   4 +
 configs/sandbox_defconfig                          |   3 +
 configs/snow_defconfig                             |   4 +
 configs/spring_defconfig                           |   4 +
 drivers/tpm/Kconfig                                |  61 ++
 drivers/tpm/Makefile                               |   4 +-
 drivers/tpm/tpm-uclass.c                           |  57 ++
 drivers/tpm/tpm.c                                  | 694 ---------------------
 drivers/tpm/tpm_atmel_twi.c                        |  15 +-
 drivers/tpm/tpm_private.h                          | 140 -----
 drivers/tpm/tpm_tis_i2c.c                          | 594 ++++++++++--------
 drivers/tpm/tpm_tis_i2c.h                          | 446 +++++++++++++
 drivers/tpm/tpm_tis_lpc.c                          | 291 +++++----
 drivers/tpm/tpm_tis_sandbox.c                      |  48 +-
 include/configs/controlcenterd.h                   |   7 -
 include/configs/efi-x86.h                          |   2 -
 include/configs/exynos5-common.h                   |   7 -
 include/configs/x86-common.h                       |   2 -
 include/dm/uclass-id.h                             |   1 +
 include/fdtdec.h                                   |   2 -
 include/tis.h                                      |  97 +++
 include/tpm.h                                      |   2 +-
 lib/Kconfig                                        |  10 +
 lib/fdtdec.c                                       |   2 -
 lib/tpm.c                                          |  29 +-
 44 files changed, 1404 insertions(+), 1347 deletions(-)
 create mode 100644 drivers/tpm/tpm-uclass.c
 delete mode 100644 drivers/tpm/tpm.c
 delete mode 100644 drivers/tpm/tpm_private.h
 create mode 100644 drivers/tpm/tpm_tis_i2c.h
Signature · 1 line
2.5.0.rc2.392.g76e840b
#1 lore raw

PATCH 1/25 tpm: Remove old pre-driver-model I2C code

This is not used anymore by any board so drop it.

---

 drivers/tpm/tpm.c         | 108 ++--------------------------------------------
 drivers/tpm/tpm_private.h |   4 +-
 drivers/tpm/tpm_tis_i2c.c |  74 +------------------------------
 3 files changed, 7 insertions(+), 179 deletions(-)
drivers/tpm/tpm.c +4 -104
index a650892..24997f6 100644
@@ -49,13 +49,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
 /* TPM configuration */
 struct tpm {
-#ifdef CONFIG_DM_I2C
 	struct udevice *dev;
-#else
-	int i2c_bus;
-	int slave_addr;
-	int old_bus;
-#endif
 	char inited;
 } tpm;
 
@@ -441,7 +435,6 @@ out:
 	return rc;
 }
 
-#ifdef CONFIG_DM_I2C
 static int tpm_open_dev(struct udevice *dev)
 {
 	int rc;
@@ -449,24 +442,12 @@ static int tpm_open_dev(struct udevice *dev)
 	debug("%s: start\n", __func__);
 	if (g_chip.is_open)
 		return -EBUSY;
-	rc = tpm_vendor_init_dev(dev);
+	rc = tpm_vendor_init(dev);
 	if (rc < 0)
 		g_chip.is_open = 0;
 	return rc;
 }
-#else
-static int tpm_open(uint32_t dev_addr)
-{
-	int rc;
 
-	if (g_chip.is_open)
-		return -EBUSY;
-	rc = tpm_vendor_init(dev_addr);
-	if (rc < 0)
-		g_chip.is_open = 0;
-	return rc;
-}
-#endif
 static void tpm_close(void)
 {
 	if (g_chip.is_open) {
@@ -475,42 +456,6 @@ static void tpm_close(void)
 	}
 }
 
-static int tpm_select(void)
-{
-#ifndef CONFIG_DM_I2C
-	int ret;
-
-	tpm.old_bus = i2c_get_bus_num();
-	if (tpm.old_bus != tpm.i2c_bus) {
-		ret = i2c_set_bus_num(tpm.i2c_bus);
-		if (ret) {
-			debug("%s: Fail to set i2c bus %d\n", __func__,
-			      tpm.i2c_bus);
-			return -1;
-		}
-	}
-#endif
-	return 0;
-}
-
-static int tpm_deselect(void)
-{
-#ifndef CONFIG_DM_I2C
-	int ret;
-
-	if (tpm.old_bus != i2c_get_bus_num()) {
-		ret = i2c_set_bus_num(tpm.old_bus);
-		if (ret) {
-			debug("%s: Fail to restore i2c bus %d\n",
-			      __func__, tpm.old_bus);
-			return -1;
-		}
-	}
-	tpm.old_bus = -1;
-#endif
-	return 0;
-}
-
 /**
  * Decode TPM configuration.
  *
@@ -520,8 +465,11 @@ static int tpm_deselect(void)
 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) {
@@ -537,10 +485,6 @@ static int tpm_decode_config(struct tpm *dev)
 		debug("%s: Cannot find node parent\n", __func__);
 		return -1;
 	}
-#ifdef CONFIG_DM_I2C
-	struct udevice *bus;
-	int chip_addr;
-	int ret;
 
 	/*
 	 * TODO([email protected]): Remove this when driver model supports
@@ -569,15 +513,6 @@ static int tpm_decode_config(struct tpm *dev)
 		      fdt_get_name(blob, node, NULL), ret);
 		return ret;
 	}
-#else
-	int i2c_bus;
-
-	i2c_bus = i2c_get_bus_num_fdt(parent);
-	if (i2c_bus < 0)
-		return -1;
-	dev->i2c_bus = i2c_bus;
-	dev->slave_addr = fdtdec_get_addr(blob, node, "reg");
-#endif
 
 	return 0;
 }
@@ -602,22 +537,6 @@ int tis_init(void)
 	if (tpm_decode_config(&tpm))
 		return -1;
 
-	if (tpm_select())
-		return -1;
-
-#ifndef CONFIG_DM_I2C
-	/*
-	 * Probe TPM twice; the first probing might fail because TPM is asleep,
-	 * and the probing can wake up TPM.
-	 */
-	if (i2c_probe(tpm.slave_addr) && i2c_probe(tpm.slave_addr)) {
-		debug("%s: fail to probe i2c addr 0x%x\n", __func__,
-		      tpm.slave_addr);
-		return -1;
-	}
-#endif
-
-	tpm_deselect();
 	debug("%s: done\n", __func__);
 
 	tpm.inited = 1;
@@ -632,16 +551,7 @@ int tis_open(void)
 	if (!tpm.inited)
 		return -1;
 
-	if (tpm_select())
-		return -1;
-
-#ifdef CONFIG_DM_I2C
 	rc = tpm_open_dev(tpm.dev);
-#else
-	rc = tpm_open(tpm.slave_addr);
-#endif
-
-	tpm_deselect();
 
 	return rc;
 }
@@ -651,13 +561,8 @@ int tis_close(void)
 	if (!tpm.inited)
 		return -1;
 
-	if (tpm_select())
-		return -1;
-
 	tpm_close();
 
-	tpm_deselect();
-
 	return 0;
 }
 
@@ -675,13 +580,8 @@ int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
 
 	memcpy(buf, sendbuf, sbuf_size);
 
-	if (tpm_select())
-		return -1;
-
 	len = tpm_transmit(buf, sbuf_size);
 
-	tpm_deselect();
-
 	if (len < 10) {
 		*rbuf_len = 0;
 		return -1;
drivers/tpm/tpm_private.h +1 -3
index 8894c98..daaf8b8 100644
@@ -129,10 +129,8 @@ struct tpm_cmd_t {
 
 struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *);
 
-int tpm_vendor_init(uint32_t dev_addr);
-
 struct udevice;
-int tpm_vendor_init_dev(struct udevice *dev);
+int tpm_vendor_init(struct udevice *dev);
 
 void tpm_vendor_cleanup(struct tpm_chip *chip);
 
drivers/tpm/tpm_tis_i2c.c +2 -72

143 lines not on this page · raw message

Signature · 1 line
2.5.0.rc2.392.g76e840b
#2 lore raw

PATCH 1/25 tpm: Remove old pre-driver-model I2C code

Hi Simon,

In here you are removing usage of i2c_read/i2c_write for dm_i2c_read/dm_i2c_write.
This require boards to support DM_I2C which is not the case with example beagleboard or boards using omap.

Will you drop all drivers not supporting DM in the future ?

Other than that i have proposed about the same change here:
http://lists.denx.de/pipermail/u-boot/2015-August/222598.html

Best Regards
Christophe

Quoted 384 lines · Simon Glass

This is not used anymore by any board so drop it.

---

  drivers/tpm/tpm.c         | 108 ++--------------------------------------------
  drivers/tpm/tpm_private.h |   4 +-
  drivers/tpm/tpm_tis_i2c.c |  74 +------------------------------
  3 files changed, 7 insertions(+), 179 deletions(-)
drivers/tpm/tpm.c +4 -104
index a650892..24997f6 100644
@@ -49,13 +49,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
  /* TPM configuration */
  struct tpm {
-#ifdef CONFIG_DM_I2C
  	struct udevice *dev;
-#else
-	int i2c_bus;
-	int slave_addr;
-	int old_bus;
-#endif
  	char inited;
  } tpm;
 
@@ -441,7 +435,6 @@ out:
  	return rc;
  }
 
-#ifdef CONFIG_DM_I2C
  static int tpm_open_dev(struct udevice *dev)
  {
  	int rc;
@@ -449,24 +442,12 @@ static int tpm_open_dev(struct udevice *dev)
  	debug("%s: start\n", __func__);
  	if (g_chip.is_open)
  		return -EBUSY;
-	rc = tpm_vendor_init_dev(dev);
+	rc = tpm_vendor_init(dev);
  	if (rc < 0)
  		g_chip.is_open = 0;
  	return rc;
  }
-#else
-static int tpm_open(uint32_t dev_addr)
-{
-	int rc;
 
-	if (g_chip.is_open)
-		return -EBUSY;
-	rc = tpm_vendor_init(dev_addr);
-	if (rc < 0)
-		g_chip.is_open = 0;
-	return rc;
-}
-#endif
  static void tpm_close(void)
  {
  	if (g_chip.is_open) {
@@ -475,42 +456,6 @@ static void tpm_close(void)
  	}
  }
 
-static int tpm_select(void)
-{
-#ifndef CONFIG_DM_I2C
-	int ret;
-
-	tpm.old_bus = i2c_get_bus_num();
-	if (tpm.old_bus != tpm.i2c_bus) {
-		ret = i2c_set_bus_num(tpm.i2c_bus);
-		if (ret) {
-			debug("%s: Fail to set i2c bus %d\n", __func__,
-			      tpm.i2c_bus);
-			return -1;
-		}
-	}
-#endif
-	return 0;
-}
-
-static int tpm_deselect(void)
-{
-#ifndef CONFIG_DM_I2C
-	int ret;
-
-	if (tpm.old_bus != i2c_get_bus_num()) {
-		ret = i2c_set_bus_num(tpm.old_bus);
-		if (ret) {
-			debug("%s: Fail to restore i2c bus %d\n",
-			      __func__, tpm.old_bus);
-			return -1;
-		}
-	}
-	tpm.old_bus = -1;
-#endif
-	return 0;
-}
-
  /**
   * Decode TPM configuration.
   *
@@ -520,8 +465,11 @@ static int tpm_deselect(void)
  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) {
@@ -537,10 +485,6 @@ static int tpm_decode_config(struct tpm *dev)
  		debug("%s: Cannot find node parent\n", __func__);
  		return -1;
  	}
-#ifdef CONFIG_DM_I2C
-	struct udevice *bus;
-	int chip_addr;
-	int ret;
 
  	/*
  	 * TODO(sjg at chromium.org): Remove this when driver model supports
@@ -569,15 +513,6 @@ static int tpm_decode_config(struct tpm *dev)
  		      fdt_get_name(blob, node, NULL), ret);
  		return ret;
  	}
-#else
-	int i2c_bus;
-
-	i2c_bus = i2c_get_bus_num_fdt(parent);
-	if (i2c_bus < 0)
-		return -1;
-	dev->i2c_bus = i2c_bus;
-	dev->slave_addr = fdtdec_get_addr(blob, node, "reg");
-#endif
 
  	return 0;
  }
@@ -602,22 +537,6 @@ int tis_init(void)
  	if (tpm_decode_config(&tpm))
  		return -1;
 
-	if (tpm_select())
-		return -1;
-
-#ifndef CONFIG_DM_I2C
-	/*
-	 * Probe TPM twice; the first probing might fail because TPM is asleep,
-	 * and the probing can wake up TPM.
-	 */
-	if (i2c_probe(tpm.slave_addr) && i2c_probe(tpm.slave_addr)) {
-		debug("%s: fail to probe i2c addr 0x%x\n", __func__,
-		      tpm.slave_addr);
-		return -1;
-	}
-#endif
-
-	tpm_deselect();
  	debug("%s: done\n", __func__);
 
  	tpm.inited = 1;
@@ -632,16 +551,7 @@ int tis_open(void)
  	if (!tpm.inited)
  		return -1;
 
-	if (tpm_select())
-		return -1;
-
-#ifdef CONFIG_DM_I2C
  	rc = tpm_open_dev(tpm.dev);
-#else
-	rc = tpm_open(tpm.slave_addr);
-#endif
-
-	tpm_deselect();
 
  	return rc;
  }
@@ -651,13 +561,8 @@ int tis_close(void)
  	if (!tpm.inited)
  		return -1;
 
-	if (tpm_select())
-		return -1;
-
  	tpm_close();
 
-	tpm_deselect();
-
  	return 0;
  }
 
@@ -675,13 +580,8 @@ int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
 
  	memcpy(buf, sendbuf, sbuf_size);
 
-	if (tpm_select())
-		return -1;
-
  	len = tpm_transmit(buf, sbuf_size);
 
-	tpm_deselect();
-
  	if (len < 10) {
  		*rbuf_len = 0;
  		return -1;
drivers/tpm/tpm_private.h +1 -3
index 8894c98..daaf8b8 100644
@@ -129,10 +129,8 @@ struct tpm_cmd_t {
 
  struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *);
 
-int tpm_vendor_init(uint32_t dev_addr);
-
  struct udevice;
-int tpm_vendor_init_dev(struct udevice *dev);
+int tpm_vendor_init(struct udevice *dev);
 
  void tpm_vendor_cleanup(struct tpm_chip *chip);
 
drivers/tpm/tpm_tis_i2c.c +2 -72
index ee4dfea..a7082e6 100644
@@ -50,9 +50,6 @@
 
  DECLARE_GLOBAL_DATA_PTR;
 
-/* Address of the TPM on the I2C bus */
-#define TPM_I2C_ADDR		0x20
-
  /* Max buffer size supported by our tpm */
  #define TPM_DEV_BUFSIZE		1260
 
@@ -73,13 +70,6 @@ DECLARE_GLOBAL_DATA_PTR;
 
  #define TPM_HEADER_SIZE		10
 
-/*
- * Expected value for DIDVID register
- *
- * The only device the system knows about at this moment is Infineon slb9635.
- */
-#define TPM_TIS_I2C_DID_VID	0x000b15d1L
-
  enum tis_access {
  	TPM_ACCESS_VALID		= 0x80,
  	TPM_ACCESS_ACTIVE_LOCALITY	= 0x20,
@@ -123,21 +113,11 @@ static const char * const chip_name[] = {
 
  /* Structure to store I2C TPM specific stuff */
  struct tpm_dev {
-#ifdef CONFIG_DM_I2C
  	struct udevice *dev;
-#else
-	uint addr;
-#endif
  	u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)];  /* Max buffer size + addr */
  	enum i2c_chip_type chip_type;
  };
 
-static struct tpm_dev tpm_dev = {
-#ifndef CONFIG_DM_I2C
-	.addr = TPM_I2C_ADDR
-#endif
-};
-
  static struct tpm_dev tpm_dev;
 
  /*
@@ -163,12 +143,7 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
  	if ((tpm_dev.chip_type == SLB9635) || (tpm_dev.chip_type == UNKNOWN)) {
  		/* slb9635 protocol should work in both cases */
  		for (count = 0; count < MAX_COUNT; count++) {
-#ifdef CONFIG_DM_I2C
  			rc = dm_i2c_write(tpm_dev.dev, 0, (uchar *)&addrbuf, 1);
-#else
-			rc = i2c_write(tpm_dev.addr, 0, 0,
-				       (uchar *)&addrbuf, 1);
-#endif
  			if (rc == 0)
  				break;  /* Success, break to skip sleep */
  			udelay(SLEEP_DURATION);
@@ -182,11 +157,7 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
  		 */
  		for (count = 0; count < MAX_COUNT; count++) {
  			udelay(SLEEP_DURATION);
-#ifdef CONFIG_DM_I2C
  			rc = dm_i2c_read(tpm_dev.dev, 0, buffer, len);
-#else
-			rc = i2c_read(tpm_dev.addr, 0, 0, buffer, len);
-#endif
  			if (rc == 0)
  				break;  /* success, break to skip sleep */
  		}
@@ -199,11 +170,7 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
  		 * be safe on the safe side.
  		 */
  		for (count = 0; count < MAX_COUNT; count++) {
-#ifdef CONFIG_DM_I2C
  			rc = dm_i2c_read(tpm_dev.dev, addr, buffer, len);
-#else
-			rc = i2c_read(tpm_dev.addr, addr, 1, buffer, len);
-#endif
  			if (rc == 0)
  				break;  /* break here to skip sleep */
  			udelay(SLEEP_DURATION);
@@ -224,20 +191,8 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
  	int rc = 0;
  	int count;
 
-	/* Prepare send buffer */
-#ifndef CONFIG_DM_I2C
-	tpm_dev.buf[0] = addr;
-	memcpy(&(tpm_dev.buf[1]), buffer, len);
-	buffer = tpm_dev.buf;
-	len++;
-#endif
-
  	for (count = 0; count < max_count; count++) {
-#ifdef CONFIG_DM_I2C
  		rc = dm_i2c_write(tpm_dev.dev, addr, buffer, len);
-#else
-		rc = i2c_write(tpm_dev.addr, 0, 0, buffer, len);
-#endif
  		if (rc == 0)
  			break;  /* Success, break to skip sleep */
  		udelay(sleep_time);
@@ -597,12 +552,13 @@ static enum i2c_chip_type tpm_vendor_chip_type(void)
  	return UNKNOWN;
  }
 
-static int tpm_vendor_init_common(void)
+int tpm_vendor_init(struct udevice *dev)
  {
  	struct tpm_chip *chip;
  	u32 vendor;
  	u32 expected_did_vid;
 
+	tpm_dev.dev = dev;
  	tpm_dev.chip_type = tpm_vendor_chip_type();
 
  	chip = tpm_register_hardware(&tpm_tis_i2c);
@@ -651,32 +607,6 @@ static int tpm_vendor_init_common(void)
  	return 0;
  }
 
-#ifdef CONFIG_DM_I2C
-/* Initialisation of i2c tpm */
-int tpm_vendor_init_dev(struct udevice *dev)
-{
-	tpm_dev.dev = dev;
-	return tpm_vendor_init_common();
-}
-#else
-/* Initialisation of i2c tpm */
-int tpm_vendor_init(uint32_t dev_addr)
-{
-	uint old_addr;
-	int rc = 0;
-
-	old_addr = tpm_dev.addr;
-	if (dev_addr != 0)
-		tpm_dev.addr = dev_addr;
-
-	rc = tpm_vendor_init_common();
-	if (rc)
-		tpm_dev.addr = old_addr;
-
-	return rc;
-}
-#endif
-
  void tpm_vendor_cleanup(struct tpm_chip *chip)
  {
  	release_locality(chip, chip->vendor.locality, 1);
#3 lore raw

PATCH 1/25 tpm: Remove old pre-driver-model I2C code

Hi Christophe,

Quoted 6 lines · christophe.ricard

Hi Simon,

In here you are removing usage of i2c_read/i2c_write for dm_i2c_read/dm_i2c_write.
This require boards to support DM_I2C which is not the case with example beagleboard or boards using omap.

As far as I know those boards don't use a TPM. We can really only deal with source code which is present in mainline.

Quoted 2 lines

Will you drop all drivers not supporting DM in the future ?

At some point, but I suspect it might be quite a while before we even start that. In any case this is not what I am doing here.

Quoted 4 lines

Other than that i have proposed about the same change here:
http://lists.denx.de/pipermail/u-boot/2015-August/222598.html

Quoted 18 lines

Best Regards
Christophe

Quoted 12 lines · Simon Glass

This is not used anymore by any board so drop it.

---

  drivers/tpm/tpm.c         | 108
++--------------------------------------------
  drivers/tpm/tpm_private.h |   4 +-
  drivers/tpm/tpm_tis_i2c.c |  74 +------------------------------
  3 files changed, 7 insertions(+), 179 deletions(-)

[snip]

Regards,
Simon

#4 lore raw

PATCH 2/25 tpm: Drop two unused options

In reply to Simon Glass

The address of the I2C TPM is now defined in the device tree so there is no need for the CONFIG options.

Remove them from the README and board config to avoid confusion.

---

 README                           | 6 ------
 include/configs/exynos5-common.h | 2 --
 2 files changed, 8 deletions(-)
README +0 -6
index 1bcb63c..b55175a 100644
@@ -1496,12 +1496,6 @@ The following options need to be configured:
 		Support for i2c bus TPM devices. Only one device
 		per system is supported at this time.
 
-			CONFIG_TPM_TIS_I2C_BUS_NUMBER
-			Define the the i2c bus number for the TPM device
-
-			CONFIG_TPM_TIS_I2C_SLAVE_ADDRESS
-			Define the TPM's address on the i2c bus
-
 			CONFIG_TPM_TIS_I2C_BURST_LIMITATION
 			Define the burst count bytes upper limit
 
include/configs/exynos5-common.h +0 -2
index e710f41..fb5ee0d 100644
@@ -58,8 +58,6 @@
 #define CONFIG_TPM
 #define CONFIG_CMD_TPM
 #define CONFIG_TPM_TIS_I2C
-#define CONFIG_TPM_TIS_I2C_BUS_NUMBER	3
-#define CONFIG_TPM_TIS_I2C_SLAVE_ADDR	0x20
 
 /* MMC SPL */
 #define COPY_BL2_FNPTR_ADDR	0x02020030
Signature · 1 line
2.5.0.rc2.392.g76e840b
#5 lore raw

PATCH 2/25 tpm: Drop two unused options

Hi Simon,

I am ok with this one. I proposed about the same changed in here:
http://lists.denx.de/pipermail/u-boot/2015-August/222598.html

Best Regards
Christophe

Quoted 42 lines · Simon Glass

The address of the I2C TPM is now defined in the device tree so there is no need for the CONFIG options.

Remove them from the README and board config to avoid confusion.

---

  README                           | 6 ------
  include/configs/exynos5-common.h | 2 --
  2 files changed, 8 deletions(-)
README +0 -6
index 1bcb63c..b55175a 100644
@@ -1496,12 +1496,6 @@ The following options need to be configured:
  		Support for i2c bus TPM devices. Only one device
  		per system is supported at this time.
 
-			CONFIG_TPM_TIS_I2C_BUS_NUMBER
-			Define the the i2c bus number for the TPM device
-
-			CONFIG_TPM_TIS_I2C_SLAVE_ADDRESS
-			Define the TPM's address on the i2c bus
-
  			CONFIG_TPM_TIS_I2C_BURST_LIMITATION
  			Define the burst count bytes upper limit
 
include/configs/exynos5-common.h +0 -2
index e710f41..fb5ee0d 100644
@@ -58,8 +58,6 @@
  #define CONFIG_TPM
  #define CONFIG_CMD_TPM
  #define CONFIG_TPM_TIS_I2C
-#define CONFIG_TPM_TIS_I2C_BUS_NUMBER	3
-#define CONFIG_TPM_TIS_I2C_SLAVE_ADDR	0x20
 
  /* MMC SPL */
  #define COPY_BL2_FNPTR_ADDR	0x02020030
#6 lore raw

PATCH 3/25 tpm: Add Kconfig options for TPMs

In reply to Simon Glass

Add new Kconfig options for TPMs in preparation for moving boards to use Kconfig for TPM configuration.

---

 common/Kconfig      | 12 ++++++++++++
 drivers/tpm/Kconfig | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/Kconfig         | 10 ++++++++++
 3 files changed, 74 insertions(+)
common/Kconfig +12 -0
index 40cd69e..05faae9 100644
@@ -618,4 +618,16 @@ config CMD_REGULATOR
 
 endmenu
 
+menu "Security commands"
+config CMD_TPM
+	bool "Enable the 'tpm' command"
+	depends on TPM
+	help
+	  This provides a means to talk to a TPM from the command line. A wide
+	  range of commands if provided - see 'tpm help' for details. The
+	  command requires a suitable TPM on your board and the correct driver
+	  must be enabled.
+
+endmenu
+
 endmenu
drivers/tpm/Kconfig +52 -0

59 lines not on this page · raw message

lib/Kconfig +10 -0
index 884218a..0673072 100644
@@ -54,6 +54,16 @@ source lib/dhry/Kconfig
 
 source lib/rsa/Kconfig
 
+config TPM
+	bool "Trusted Platform Module (TPM) Support"
+	help
+	  This enables support for TPMs which can be used to provide security
+	  features for your board. The TPM can be connected via LPC or I2C
+	  and a sandbox TPM is provided for testing purposes. Use the 'tpm'
+	  command to interactive the TPM. Driver model support is provided
+	  for the low-level TPM interface, but only one TPM is supported at
+	  a time by the TPM library.
+
 menu "Hashing Support"
 
 config SHA1
Signature · 1 line
2.5.0.rc2.392.g76e840b
#7 lore raw

PATCH 3/25 tpm: Add Kconfig options for TPMs

Hi Simon,

Quoted 86 lines · Simon Glass

Add new Kconfig options for TPMs in preparation for moving boards to use Kconfig for TPM configuration.

---

  common/Kconfig      | 12 ++++++++++++
  drivers/tpm/Kconfig | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
  lib/Kconfig         | 10 ++++++++++
  3 files changed, 74 insertions(+)
common/Kconfig +12 -0
index 40cd69e..05faae9 100644
@@ -618,4 +618,16 @@ config CMD_REGULATOR
 
  endmenu
 
+menu "Security commands"
+config CMD_TPM
+	bool "Enable the 'tpm' command"
+	depends on TPM
+	help
+	  This provides a means to talk to a TPM from the command line. A wide
+	  range of commands if provided - see 'tpm help' for details. The
+	  command requires a suitable TPM on your board and the correct driver
+	  must be enabled.
+
+endmenu
+
  endmenu
drivers/tpm/Kconfig +42 -0
index f408b8a..993d2d7 100644
@@ -1,7 +1,59 @@
  config TPM_TIS_SANDBOX
  	bool "Enable sandbox TPM driver"
+	depends on SANDBOX
  	help
  	  This driver emulates a TPM, providing access to base functions
  	  such as reading and writing TPM private data. This is enough to
  	  support Chrome OS verified boot. Extend functionality is not
  	  implemented.
+
+config TPM_ATMEL_TWI
+	bool "Enable Atmel TWI TPM device driver"
+	depends on TPM
+	help
+	  This driver supports an Atmel TPM device connected on the I2C bus.
+	  The usual tpm operations and the 'tpm' command can be used to talk
+	  to the device using the standard TPM Interface Specification (TIS)
+	  protocol
+
+config TPM_TIS_I2C
+	bool "Enable support for Infineon SLB9635/45 TPMs on I2C"
+	depends on TPM && DM_I2C
+	help
+	  This driver supports Infineon TPM devices connected on the I2C bus.
+	  The usual tpm operations and the 'tpm' command can be used to talk
+	  to the device using the standard TPM Interface Specification (TIS)
+	  protocol
+
+config TPM_TIS_I2C_BURST_LIMITATION
+	bool "Enable I2C burst length limitation"
+	depends on TPM_TIS_I2C
+	help
+	  Some broken TPMs have a limitation on the number of bytes they can
+	  receive in one message. Enable this option to allow you to set this
+	  option. The can allow a broken TPM to be used by splitting messages
+	  into separate pieces.
+
+config TPM_TIS_I2C_BURST_LIMITATION_LEN
+	int "Length"
+	depends on TPM_TIS_I2C_BURST_LIMITATION
+	help
+	  Use this to set the burst limitation length
+
+config TPM_TIS_LPC
+	bool "Enable support for Infineon SLB9635/45 TPMs on LPC"
+	depends on TPM && X86
+	help
+	  This driver supports Infineon TPM devices connected on the I2C bus.
+	  The usual tpm operations and the 'tpm' command can be used to talk
+	  to the device using the standard TPM Interface Specification (TIS)

drivers/tpm/Kconfig line 59

Quoted 10 lines
drivers/tpm/Kconfig +10 -0
+	  protocol
+
+config TPM_AUTH_SESSIONS
+	bool "Enable TPM authentication session support"
+	depends on TPM
+	help
+	  Enable support for authorised (AUTH1) commands as specified in the
+	  TCG Main Specification 1.2. OIAP-authorised versions of the commands
+	  TPM_LoadKey2 and TPM_GetPubKey are provided. Both features are
+	  available using the 'tpm' command, too.

Won't you put all TPM drivers in a "TPM support" menu showing "Device Drivers" parent ?

Quoted 11 lines
lib/Kconfig +3 -0
index 884218a..0673072 100644
@@ -54,6 +54,16 @@ source lib/dhry/Kconfig
 
  source lib/rsa/Kconfig
 
+config TPM
+	bool "Trusted Platform Module (TPM) Support"
+	help

lib/Kconfig source lib/dhry/Kconfig · line 69

Quoted 10 lines
lib/Kconfig +7 -0
+	  This enables support for TPMs which can be used to provide security
+	  features for your board. The TPM can be connected via LPC or I2C
+	  and a sandbox TPM is provided for testing purposes. Use the 'tpm'
+	  command to interactive the TPM. Driver model support is provided
+	  for the low-level TPM interface, but only one TPM is supported at
+	  a time by the TPM library.
+
  menu "Hashing Support"
 
  config SHA1

Best Regards
Christophe

#8 lore raw

PATCH 3/25 tpm: Add Kconfig options for TPMs

Quoted 111 lines · christophe.ricard

Hi Simon,

Quoted 107 lines · Simon Glass

Add new Kconfig options for TPMs in preparation for moving boards to use Kconfig for TPM configuration.

---

  common/Kconfig      | 12 ++++++++++++
  drivers/tpm/Kconfig | 52
++++++++++++++++++++++++++++++++++++++++++++++++++++
  lib/Kconfig         | 10 ++++++++++
  3 files changed, 74 insertions(+)
common/Kconfig +5 -0
index 40cd69e..05faae9 100644
@@ -618,4 +618,16 @@ config CMD_REGULATOR
    endmenu
  +menu "Security commands"
+config CMD_TPM
+       bool "Enable the 'tpm' command"
+       depends on TPM
+       help
+         This provides a means to talk to a TPM from the command line. A

wide

common/Kconfig +2 -0
+         range of commands if provided - see 'tpm help' for details. The
+         command requires a suitable TPM on your board and the correct

driver

common/Kconfig +4 -0
+         must be enabled.
+
+endmenu
+
  endmenu
drivers/tpm/Kconfig +7 -0
index f408b8a..993d2d7 100644
@@ -1,7 +1,59 @@
  config TPM_TIS_SANDBOX
        bool "Enable sandbox TPM driver"
+       depends on SANDBOX
        help
          This driver emulates a TPM, providing access to base functions
          such as reading and writing TPM private data. This is enough to
          support Chrome OS verified boot. Extend functionality is not
          implemented.
+
+config TPM_ATMEL_TWI
+       bool "Enable Atmel TWI TPM device driver"
+       depends on TPM
+       help
+         This driver supports an Atmel TPM device connected on the I2C

bus.
+ The usual tpm operations and the 'tpm' command can be used to
talk
+ to the device using the standard TPM Interface Specification
(TIS)

drivers/tpm/Kconfig +7 -0
+         protocol
+
+config TPM_TIS_I2C
+       bool "Enable support for Infineon SLB9635/45 TPMs on I2C"
+       depends on TPM && DM_I2C
+       help
+         This driver supports Infineon TPM devices connected on the I2C

bus.
+ The usual tpm operations and the 'tpm' command can be used to
talk
+ to the device using the standard TPM Interface Specification
(TIS)

drivers/tpm/Kconfig +7 -0
+         protocol
+
+config TPM_TIS_I2C_BURST_LIMITATION
+       bool "Enable I2C burst length limitation"
+       depends on TPM_TIS_I2C
+       help
+         Some broken TPMs have a limitation on the number of bytes they

can
+ receive in one message. Enable this option to allow you to set
this
+ option. The can allow a broken TPM to be used by splitting
messages

drivers/tpm/Kconfig +13 -0
+         into separate pieces.
+
+config TPM_TIS_I2C_BURST_LIMITATION_LEN
+       int "Length"
+       depends on TPM_TIS_I2C_BURST_LIMITATION
+       help
+         Use this to set the burst limitation length
+
+config TPM_TIS_LPC
+       bool "Enable support for Infineon SLB9635/45 TPMs on LPC"
+       depends on TPM && X86
+       help
+         This driver supports Infineon TPM devices connected on the I2C

bus.
+ The usual tpm operations and the 'tpm' command can be used to
talk
+ to the device using the standard TPM Interface Specification
(TIS)

drivers/tpm/Kconfig +7 -0
+         protocol
+
+config TPM_AUTH_SESSIONS
+       bool "Enable TPM authentication session support"
+       depends on TPM
+       help
+         Enable support for authorised (AUTH1) commands as specified in
Quoted 8 lines

drivers/tpm/Kconfig line 59

Quoted 5 lines

the
+ TCG Main Specification 1.2. OIAP-authorised versions of the
commands

drivers/tpm/Kconfig +2 -0
+         TPM_LoadKey2 and TPM_GetPubKey are provided. Both features are
+         available using the 'tpm' command, too.

Won't you put all TPM drivers in a "TPM support" menu showing "Device Drivers" parent ?

Yes that's a good idea, I'll do that.

Quoted 17 lines
Quoted 17 lines
lib/Kconfig +3 -0
index 884218a..0673072 100644
@@ -54,6 +54,16 @@ source lib/dhry/Kconfig
    source lib/rsa/Kconfig
  +config TPM
+       bool "Trusted Platform Module (TPM) Support"
+       help
+         This enables support for TPMs which can be used to provide

security

lib/Kconfig +2 -0
+         features for your board. The TPM can be connected via LPC or I2C
+         and a sandbox TPM is provided for testing purposes. Use the

'tpm'

lib/Kconfig +2 -0
+         command to interactive the TPM. Driver model support is provided
+         for the low-level TPM interface, but only one TPM is supported
Quoted 8 lines

lib/Kconfig source lib/dhry/Kconfig · line 69

Quoted 5 lines

at

lib/Kconfig +2 -0
+         a time by the TPM library.
+
  menu "Hashing Support"
    config SHA1

Best Regards
Christophe

Regards,
Simon

#9 lore raw

PATCH 4/25 tpm: Convert board config TPM options to Kconfig

In reply to Simon Glass

Convert all TPM options to Kconfig and tidy up.

---

 configs/chromebook_link_defconfig                     | 2 ++
 configs/chromebox_panther_defconfig                   | 2 ++
 configs/controlcenterd_36BIT_SDCARD_DEVELOP_defconfig | 4 ++++
 configs/controlcenterd_36BIT_SDCARD_defconfig         | 4 ++++
 configs/controlcenterd_TRAILBLAZER_DEVELOP_defconfig  | 4 ++++
 configs/controlcenterd_TRAILBLAZER_defconfig          | 4 ++++
 configs/coreboot-x86_defconfig                        | 2 ++
 configs/peach-pi_defconfig                            | 3 +++
 configs/peach-pit_defconfig                           | 3 +++
 configs/sandbox_defconfig                             | 2 ++
 configs/snow_defconfig                                | 3 +++
 configs/spring_defconfig                              | 3 +++
 include/configs/controlcenterd.h                      | 7 -------
 include/configs/efi-x86.h                             | 2 --
 include/configs/exynos5-common.h                      | 5 -----
 include/configs/x86-common.h                          | 2 --
 16 files changed, 36 insertions(+), 16 deletions(-)
configs/chromebook_link_defconfig +2 -0
index b987f3f..b0fc5ca 100644
@@ -17,9 +17,11 @@ CONFIG_SPI_FLASH=y
 CONFIG_CMD_CROS_EC=y
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_LPC=y
+CONFIG_TPM_TIS_LPC=y
 CONFIG_VIDEO_VESA=y
 CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
 CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
 CONFIG_DM_RTC=y
 CONFIG_USE_PRIVATE_LIBGCC=y
 CONFIG_SYS_VSNPRINTF=y
+CONFIG_TPM=y
configs/chromebox_panther_defconfig +2 -0
index e82c8ec..e7ef8fe 100644
@@ -17,9 +17,11 @@ CONFIG_SPI_FLASH=y
 CONFIG_CMD_CROS_EC=y
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_LPC=y
+CONFIG_TPM_TIS_LPC=y
 CONFIG_VIDEO_VESA=y
 CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
 CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
 CONFIG_DM_RTC=y
 CONFIG_USE_PRIVATE_LIBGCC=y
 CONFIG_SYS_VSNPRINTF=y
+CONFIG_TPM=y
configs/controlcenterd_36BIT_SDCARD_DEVELOP_defconfig +4 -0
index 37ead03..c8ab862 100644
@@ -4,4 +4,8 @@ CONFIG_TARGET_CONTROLCENTERD=y
 CONFIG_SYS_EXTRA_OPTIONS="36BIT,SDCARD,DEVELOP"
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
+CONFIG_CMD_TPM=y
 CONFIG_SPI_FLASH=y
+CONFIG_TPM_ATMEL_TWI=y
+CONFIG_TPM_AUTH_SESSIONS=y
+CONFIG_TPM=y
configs/controlcenterd_36BIT_SDCARD_defconfig +4 -0
index 7166edb..21c0eab 100644
@@ -4,4 +4,8 @@ CONFIG_TARGET_CONTROLCENTERD=y
 CONFIG_SYS_EXTRA_OPTIONS="36BIT,SDCARD"
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
+CONFIG_CMD_TPM=y
 CONFIG_SPI_FLASH=y
+CONFIG_TPM_ATMEL_TWI=y
+CONFIG_TPM_AUTH_SESSIONS=y
+CONFIG_TPM=y
configs/controlcenterd_TRAILBLAZER_DEVELOP_defconfig +4 -0
index d99fcd4..c3a0920 100644
@@ -6,3 +6,7 @@ CONFIG_SYS_EXTRA_OPTIONS="TRAILBLAZER,SPIFLASH,DEVELOP"
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TPM=y
+CONFIG_TPM_ATMEL_TWI=y
+CONFIG_TPM_AUTH_SESSIONS=y
+CONFIG_TPM=y
configs/controlcenterd_TRAILBLAZER_defconfig +4 -0
index 3557aea..08aae9a 100644
@@ -6,3 +6,7 @@ CONFIG_SYS_EXTRA_OPTIONS="TRAILBLAZER,SPIFLASH"
 # CONFIG_CMD_IMLS is not set
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TPM=y
+CONFIG_TPM_ATMEL_TWI=y
+CONFIG_TPM_AUTH_SESSIONS=y
+CONFIG_TPM=y
configs/coreboot-x86_defconfig +2 -0
index 581df0a..fc6410b 100644
@@ -12,5 +12,7 @@ CONFIG_CMD_BOOTSTAGE=y
 CONFIG_OF_CONTROL=y
 CONFIG_DM_PCI=y
 CONFIG_SPI_FLASH=y
+CONFIG_TPM_TIS_LPC=y
 CONFIG_USE_PRIVATE_LIBGCC=y
 CONFIG_SYS_VSNPRINTF=y
+CONFIG_TPM=y
configs/peach-pi_defconfig +3 -0
index 94ba3f8..5df93b9 100644
@@ -7,11 +7,13 @@ CONFIG_SPL=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_PMIC=y
 CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_TPM=y
 CONFIG_SPI_FLASH=y
 CONFIG_CMD_CROS_EC=y
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_SPI=y
 CONFIG_CROS_EC_KEYB=y
+CONFIG_TPM_TIS_I2C=y
 CONFIG_DM_I2C=y
 CONFIG_DM_I2C_COMPAT=y
 CONFIG_I2C_CROS_EC_TUNNEL=y
@@ -30,4 +32,5 @@ CONFIG_SOUND_MAX98095=y
 CONFIG_SOUND_WM8994=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_TPM=y
 CONFIG_ERRNO_STR=y
configs/peach-pit_defconfig +3 -0
index 229b712..e5921ff 100644
@@ -7,11 +7,13 @@ CONFIG_SPL=y
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_CMD_PMIC=y
 CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_TPM=y
 CONFIG_SPI_FLASH=y
 CONFIG_CMD_CROS_EC=y
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_SPI=y
 CONFIG_CROS_EC_KEYB=y
+CONFIG_TPM_TIS_I2C=y
 CONFIG_DM_I2C=y
 CONFIG_DM_I2C_COMPAT=y
 CONFIG_I2C_CROS_EC_TUNNEL=y
@@ -30,4 +32,5 @@ CONFIG_SOUND_MAX98095=y
 CONFIG_SOUND_WM8994=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_TPM=y
 CONFIG_ERRNO_STR=y
configs/sandbox_defconfig +2 -0
index 85ff95d..b68d688 100644
@@ -11,6 +11,7 @@ CONFIG_BOOTSTAGE=y
 CONFIG_BOOTSTAGE_REPORT=y
 CONFIG_CMD_PMIC=y
 CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_TPM=y
 CONFIG_OF_CONTROL=y
 CONFIG_OF_HOSTFILE=y
 CONFIG_CLK=y
@@ -49,6 +50,7 @@ CONFIG_DM_MMC=y
 CONFIG_DM_RTC=y
 CONFIG_SYS_VSNPRINTF=y
 CONFIG_CMD_DHRYSTONE=y
+CONFIG_TPM=y
 CONFIG_ERRNO_STR=y
 CONFIG_UNIT_TEST=y
 CONFIG_UT_TIME=y
configs/snow_defconfig +3 -0
index 3466d96..0f7a764 100644
@@ -8,6 +8,7 @@ CONFIG_SPL=y
 CONFIG_CMD_SOUND=y
 CONFIG_CMD_PMIC=y
 CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_TPM=y
 CONFIG_SPI_FLASH=y
 CONFIG_CMD_CROS_EC=y
 CONFIG_CROS_EC=y
@@ -17,6 +18,7 @@ CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART_S5P=y
 CONFIG_DEBUG_UART_BASE=0x12c30000
 CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_TPM_TIS_I2C=y
 CONFIG_DM_I2C=y
 CONFIG_DM_I2C_COMPAT=y
 CONFIG_I2C_CROS_EC_LDO=y
@@ -40,4 +42,5 @@ CONFIG_SOUND_MAX98095=y
 CONFIG_SOUND_WM8994=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_TPM=y
 CONFIG_ERRNO_STR=y
configs/spring_defconfig +3 -0
index 8e8ec44..1b3daa4 100644
@@ -8,6 +8,7 @@ CONFIG_SPL=y
 CONFIG_CMD_SOUND=y
 CONFIG_CMD_PMIC=y
 CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_TPM=y
 CONFIG_SPI_FLASH=y
 CONFIG_CMD_CROS_EC=y
 CONFIG_CROS_EC=y
@@ -17,6 +18,7 @@ CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART_S5P=y
 CONFIG_DEBUG_UART_BASE=0x12c30000
 CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_TPM_TIS_I2C=y
 CONFIG_DM_I2C=y
 CONFIG_DM_I2C_COMPAT=y
 CONFIG_I2C_CROS_EC_LDO=y
@@ -39,4 +41,5 @@ CONFIG_SOUND_MAX98095=y
 CONFIG_SOUND_WM8994=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_TPM=y
 CONFIG_ERRNO_STR=y
include/configs/controlcenterd.h +0 -7
index 8f829ed..9a1f6d0 100644
@@ -226,14 +226,7 @@
 #define CONFIG_SF_DEFAULT_MODE		0
 #endif
 
-/*
- * TPM
- */
-#define CONFIG_TPM_ATMEL_TWI
-#define CONFIG_TPM
-#define CONFIG_TPM_AUTH_SESSIONS
 #define CONFIG_SHA1
-#define CONFIG_CMD_TPM
 
 /*
  * MMC
include/configs/efi-x86.h +0 -2
index 5779cfd..1c955d9 100644
@@ -11,8 +11,6 @@
 
 #undef CONFIG_CMD_SF_TEST
 
-#undef CONFIG_TPM
-#undef CONFIG_TPM_TIS_LPC
 #undef CONFIG_TPM_TIS_BASE_ADDRESS
 
 #undef CONFIG_CMD_IMLS
include/configs/exynos5-common.h +0 -5
index fb5ee0d..4866836 100644
@@ -54,11 +54,6 @@
 #define CONFIG_CMD_DTT
 #define CONFIG_TMU_CMD_DTT
 
-/* TPM */
-#define CONFIG_TPM
-#define CONFIG_CMD_TPM
-#define CONFIG_TPM_TIS_I2C
-
 /* MMC SPL */
 #define COPY_BL2_FNPTR_ADDR	0x02020030
 #define CONFIG_SUPPORT_EMMC_BOOT
include/configs/x86-common.h +0 -2
index 349b06c..27d3043 100644
@@ -47,8 +47,6 @@
 #endif
 
 /* Generic TPM interfaced through LPC bus */
-#define CONFIG_TPM
-#define CONFIG_TPM_TIS_LPC
 #define CONFIG_TPM_TIS_BASE_ADDRESS        0xfed40000
 
 /*-----------------------------------------------------------------------
Signature · 1 line
2.5.0.rc2.392.g76e840b
#10 lore raw

PATCH 4/25 tpm: Convert board config TPM options to Kconfig

Hi Simon,

Best Regards
Christophe

Quoted 298 lines · Simon Glass

Convert all TPM options to Kconfig and tidy up.

---

  configs/chromebook_link_defconfig                     | 2 ++
  configs/chromebox_panther_defconfig                   | 2 ++
  configs/controlcenterd_36BIT_SDCARD_DEVELOP_defconfig | 4 ++++
  configs/controlcenterd_36BIT_SDCARD_defconfig         | 4 ++++
  configs/controlcenterd_TRAILBLAZER_DEVELOP_defconfig  | 4 ++++
  configs/controlcenterd_TRAILBLAZER_defconfig          | 4 ++++
  configs/coreboot-x86_defconfig                        | 2 ++
  configs/peach-pi_defconfig                            | 3 +++
  configs/peach-pit_defconfig                           | 3 +++
  configs/sandbox_defconfig                             | 2 ++
  configs/snow_defconfig                                | 3 +++
  configs/spring_defconfig                              | 3 +++
  include/configs/controlcenterd.h                      | 7 -------
  include/configs/efi-x86.h                             | 2 --
  include/configs/exynos5-common.h                      | 5 -----
  include/configs/x86-common.h                          | 2 --
  16 files changed, 36 insertions(+), 16 deletions(-)
configs/chromebook_link_defconfig +2 -0
index b987f3f..b0fc5ca 100644
@@ -17,9 +17,11 @@ CONFIG_SPI_FLASH=y
  CONFIG_CMD_CROS_EC=y
  CONFIG_CROS_EC=y
  CONFIG_CROS_EC_LPC=y
+CONFIG_TPM_TIS_LPC=y
  CONFIG_VIDEO_VESA=y
  CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
  CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
  CONFIG_DM_RTC=y
  CONFIG_USE_PRIVATE_LIBGCC=y
  CONFIG_SYS_VSNPRINTF=y
+CONFIG_TPM=y
configs/chromebox_panther_defconfig +2 -0
index e82c8ec..e7ef8fe 100644
@@ -17,9 +17,11 @@ CONFIG_SPI_FLASH=y
  CONFIG_CMD_CROS_EC=y
  CONFIG_CROS_EC=y
  CONFIG_CROS_EC_LPC=y
+CONFIG_TPM_TIS_LPC=y
  CONFIG_VIDEO_VESA=y
  CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
  CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
  CONFIG_DM_RTC=y
  CONFIG_USE_PRIVATE_LIBGCC=y
  CONFIG_SYS_VSNPRINTF=y
+CONFIG_TPM=y
configs/controlcenterd_36BIT_SDCARD_DEVELOP_defconfig +4 -0
index 37ead03..c8ab862 100644
@@ -4,4 +4,8 @@ CONFIG_TARGET_CONTROLCENTERD=y
  CONFIG_SYS_EXTRA_OPTIONS="36BIT,SDCARD,DEVELOP"
  # CONFIG_CMD_IMLS is not set
  # CONFIG_CMD_FLASH is not set
+CONFIG_CMD_TPM=y
  CONFIG_SPI_FLASH=y
+CONFIG_TPM_ATMEL_TWI=y
+CONFIG_TPM_AUTH_SESSIONS=y
+CONFIG_TPM=y
configs/controlcenterd_36BIT_SDCARD_defconfig +4 -0
index 7166edb..21c0eab 100644
@@ -4,4 +4,8 @@ CONFIG_TARGET_CONTROLCENTERD=y
  CONFIG_SYS_EXTRA_OPTIONS="36BIT,SDCARD"
  # CONFIG_CMD_IMLS is not set
  # CONFIG_CMD_FLASH is not set
+CONFIG_CMD_TPM=y
  CONFIG_SPI_FLASH=y
+CONFIG_TPM_ATMEL_TWI=y
+CONFIG_TPM_AUTH_SESSIONS=y
+CONFIG_TPM=y
configs/controlcenterd_TRAILBLAZER_DEVELOP_defconfig +4 -0
index d99fcd4..c3a0920 100644
@@ -6,3 +6,7 @@ CONFIG_SYS_EXTRA_OPTIONS="TRAILBLAZER,SPIFLASH,DEVELOP"
  # CONFIG_CMD_IMLS is not set
  # CONFIG_CMD_FLASH is not set
  # CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TPM=y
+CONFIG_TPM_ATMEL_TWI=y
+CONFIG_TPM_AUTH_SESSIONS=y
+CONFIG_TPM=y
configs/controlcenterd_TRAILBLAZER_defconfig +4 -0
index 3557aea..08aae9a 100644
@@ -6,3 +6,7 @@ CONFIG_SYS_EXTRA_OPTIONS="TRAILBLAZER,SPIFLASH"
  # CONFIG_CMD_IMLS is not set
  # CONFIG_CMD_FLASH is not set
  # CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TPM=y
+CONFIG_TPM_ATMEL_TWI=y
+CONFIG_TPM_AUTH_SESSIONS=y
+CONFIG_TPM=y
configs/coreboot-x86_defconfig +2 -0
index 581df0a..fc6410b 100644
@@ -12,5 +12,7 @@ CONFIG_CMD_BOOTSTAGE=y
  CONFIG_OF_CONTROL=y
  CONFIG_DM_PCI=y
  CONFIG_SPI_FLASH=y
+CONFIG_TPM_TIS_LPC=y
  CONFIG_USE_PRIVATE_LIBGCC=y
  CONFIG_SYS_VSNPRINTF=y
+CONFIG_TPM=y
configs/peach-pi_defconfig +3 -0
index 94ba3f8..5df93b9 100644
@@ -7,11 +7,13 @@ CONFIG_SPL=y
  # CONFIG_CMD_SETEXPR is not set
  CONFIG_CMD_PMIC=y
  CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_TPM=y
  CONFIG_SPI_FLASH=y
  CONFIG_CMD_CROS_EC=y
  CONFIG_CROS_EC=y
  CONFIG_CROS_EC_SPI=y
  CONFIG_CROS_EC_KEYB=y
+CONFIG_TPM_TIS_I2C=y
  CONFIG_DM_I2C=y
  CONFIG_DM_I2C_COMPAT=y
  CONFIG_I2C_CROS_EC_TUNNEL=y
@@ -30,4 +32,5 @@ CONFIG_SOUND_MAX98095=y
  CONFIG_SOUND_WM8994=y
  CONFIG_USB=y
  CONFIG_DM_USB=y
+CONFIG_TPM=y
  CONFIG_ERRNO_STR=y
configs/peach-pit_defconfig +3 -0
index 229b712..e5921ff 100644
@@ -7,11 +7,13 @@ CONFIG_SPL=y
  # CONFIG_CMD_SETEXPR is not set
  CONFIG_CMD_PMIC=y
  CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_TPM=y
  CONFIG_SPI_FLASH=y
  CONFIG_CMD_CROS_EC=y
  CONFIG_CROS_EC=y
  CONFIG_CROS_EC_SPI=y
  CONFIG_CROS_EC_KEYB=y
+CONFIG_TPM_TIS_I2C=y
  CONFIG_DM_I2C=y
  CONFIG_DM_I2C_COMPAT=y
  CONFIG_I2C_CROS_EC_TUNNEL=y
@@ -30,4 +32,5 @@ CONFIG_SOUND_MAX98095=y
  CONFIG_SOUND_WM8994=y
  CONFIG_USB=y
  CONFIG_DM_USB=y
+CONFIG_TPM=y
  CONFIG_ERRNO_STR=y
configs/sandbox_defconfig +2 -0
index 85ff95d..b68d688 100644
@@ -11,6 +11,7 @@ CONFIG_BOOTSTAGE=y
  CONFIG_BOOTSTAGE_REPORT=y
  CONFIG_CMD_PMIC=y
  CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_TPM=y
  CONFIG_OF_CONTROL=y
  CONFIG_OF_HOSTFILE=y
  CONFIG_CLK=y
@@ -49,6 +50,7 @@ CONFIG_DM_MMC=y
  CONFIG_DM_RTC=y
  CONFIG_SYS_VSNPRINTF=y
  CONFIG_CMD_DHRYSTONE=y
+CONFIG_TPM=y
  CONFIG_ERRNO_STR=y
  CONFIG_UNIT_TEST=y
  CONFIG_UT_TIME=y
configs/snow_defconfig +3 -0
index 3466d96..0f7a764 100644
@@ -8,6 +8,7 @@ CONFIG_SPL=y
  CONFIG_CMD_SOUND=y
  CONFIG_CMD_PMIC=y
  CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_TPM=y
  CONFIG_SPI_FLASH=y
  CONFIG_CMD_CROS_EC=y
  CONFIG_CROS_EC=y
@@ -17,6 +18,7 @@ CONFIG_DEBUG_UART=y
  CONFIG_DEBUG_UART_S5P=y
  CONFIG_DEBUG_UART_BASE=0x12c30000
  CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_TPM_TIS_I2C=y
  CONFIG_DM_I2C=y
  CONFIG_DM_I2C_COMPAT=y
  CONFIG_I2C_CROS_EC_LDO=y
@@ -40,4 +42,5 @@ CONFIG_SOUND_MAX98095=y
  CONFIG_SOUND_WM8994=y
  CONFIG_USB=y
  CONFIG_DM_USB=y
+CONFIG_TPM=y
  CONFIG_ERRNO_STR=y
configs/spring_defconfig +3 -0
index 8e8ec44..1b3daa4 100644
@@ -8,6 +8,7 @@ CONFIG_SPL=y
  CONFIG_CMD_SOUND=y
  CONFIG_CMD_PMIC=y
  CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_TPM=y
  CONFIG_SPI_FLASH=y
  CONFIG_CMD_CROS_EC=y
  CONFIG_CROS_EC=y
@@ -17,6 +18,7 @@ CONFIG_DEBUG_UART=y
  CONFIG_DEBUG_UART_S5P=y
  CONFIG_DEBUG_UART_BASE=0x12c30000
  CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_TPM_TIS_I2C=y
  CONFIG_DM_I2C=y
  CONFIG_DM_I2C_COMPAT=y
  CONFIG_I2C_CROS_EC_LDO=y
@@ -39,4 +41,5 @@ CONFIG_SOUND_MAX98095=y
  CONFIG_SOUND_WM8994=y
  CONFIG_USB=y
  CONFIG_DM_USB=y
+CONFIG_TPM=y
  CONFIG_ERRNO_STR=y
include/configs/controlcenterd.h +0 -7
index 8f829ed..9a1f6d0 100644
@@ -226,14 +226,7 @@
  #define CONFIG_SF_DEFAULT_MODE		0
  #endif
 
-/*
- * TPM
- */
-#define CONFIG_TPM_ATMEL_TWI
-#define CONFIG_TPM
-#define CONFIG_TPM_AUTH_SESSIONS
  #define CONFIG_SHA1
-#define CONFIG_CMD_TPM
 
  /*
   * MMC
include/configs/efi-x86.h +0 -2
index 5779cfd..1c955d9 100644
@@ -11,8 +11,6 @@
 
  #undef CONFIG_CMD_SF_TEST
 
-#undef CONFIG_TPM
-#undef CONFIG_TPM_TIS_LPC
  #undef CONFIG_TPM_TIS_BASE_ADDRESS
 
  #undef CONFIG_CMD_IMLS
include/configs/exynos5-common.h +0 -5
index fb5ee0d..4866836 100644
@@ -54,11 +54,6 @@
  #define CONFIG_CMD_DTT
  #define CONFIG_TMU_CMD_DTT
 
-/* TPM */
-#define CONFIG_TPM
-#define CONFIG_CMD_TPM
-#define CONFIG_TPM_TIS_I2C
-
  /* MMC SPL */
  #define COPY_BL2_FNPTR_ADDR	0x02020030
  #define CONFIG_SUPPORT_EMMC_BOOT
include/configs/x86-common.h +0 -2
index 349b06c..27d3043 100644
@@ -47,8 +47,6 @@
  #endif
 
  /* Generic TPM interfaced through LPC bus */
-#define CONFIG_TPM
-#define CONFIG_TPM_TIS_LPC
  #define CONFIG_TPM_TIS_BASE_ADDRESS        0xfed40000
 
  /*-----------------------------------------------------------------------
#11 lore raw

PATCH 5/25 tpm: Convert drivers to use SPDX

In reply to Simon Glass

Add an SPDX header to two drivers that don't have it.

---

 drivers/tpm/tpm_atmel_twi.c | 15 +++------------
 drivers/tpm/tpm_tis_i2c.c   | 18 +-----------------
 2 files changed, 4 insertions(+), 29 deletions(-)
drivers/tpm/tpm_atmel_twi.c +3 -12
index 361a772..205d7a5 100644
@@ -1,18 +1,9 @@
 /*
- * 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; either version 2 of
- * the License, or (at your option) any later version.
+ * Copyright (C) 2013 Guntermann & Drunck, GmbH
  *
- * 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.
+ * Written by Dirk Eibach <[email protected]>
  *
- * 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+
  */
 
 #include <common.h>
drivers/tpm/tpm_tis_i2c.c +1 -17
index a7082e6..a43e80d 100644
@@ -17,23 +17,7 @@
  *
  * 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
+ * SPDX-License-Identifier:	GPL-2.0
  */
 
 #include <common.h>
Signature · 1 line
2.5.0.rc2.392.g76e840b
#12 lore raw

PATCH 5/25 tpm: Convert drivers to use SPDX

Hi Simon,

Just to mention i have seen this one as well.

Best Regards
Christophe

Quoted 64 lines · Simon Glass

Add an SPDX header to two drivers that don't have it.

---

  drivers/tpm/tpm_atmel_twi.c | 15 +++------------
  drivers/tpm/tpm_tis_i2c.c   | 18 +-----------------
  2 files changed, 4 insertions(+), 29 deletions(-)
drivers/tpm/tpm_atmel_twi.c +3 -12
index 361a772..205d7a5 100644
@@ -1,18 +1,9 @@
  /*
- * 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; either version 2 of
- * the License, or (at your option) any later version.
+ * Copyright (C) 2013 Guntermann & Drunck, GmbH
   *
- * 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.
+ * Written by Dirk Eibach <[email protected]>
   *
- * 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+
   */
 
  #include <common.h>
drivers/tpm/tpm_tis_i2c.c +1 -17
index a7082e6..a43e80d 100644
@@ -17,23 +17,7 @@
   *
   * 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
+ * SPDX-License-Identifier:	GPL-2.0
   */
 
  #include <common.h>
#13 lore raw

PATCH 6/25 tpm: Move the I2C TPM code into one file

In reply to Simon Glass

The current Infineon I2C TPM driver is written in two parts, intended to support use with other I2C devices. However we don't have any users and the Atmel I2C TPM device does not use this file.

We should simplify this and remove the unused abstration. As a first step, move the code into one file.

Also the name tpm_private.h suggests that the header file is generic to all TPMs but it is not. Rename it indicate that it relates only to this driver

---

 drivers/tpm/Makefile                         |   2 -
 drivers/tpm/tpm.c                            | 594 ---------------------------
 drivers/tpm/tpm_tis_i2c.c                    | 548 +++++++++++++++++++++++-
 drivers/tpm/{tpm_private.h => tpm_tis_i2c.h} |  24 +-
 4 files changed, 550 insertions(+), 618 deletions(-)
 delete mode 100644 drivers/tpm/tpm.c
 rename drivers/tpm/{tpm_private.h => tpm_tis_i2c.h} (73%)
drivers/tpm/Makefile +0 -2
index 150570e..597966c 100644
@@ -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
drivers/tpm/tpm.c deleted +0 -594

594 lines not on this page · raw message

drivers/tpm/tpm_tis_i2c.c +547 -1

563 lines not on this page · raw message

drivers/tpm/tpm_tis_i2c.h renamed from drivers/tpm/tpm_private.h +3 -21
similarity index 73%
rename from drivers/tpm/tpm_private.h
rename to drivers/tpm/tpm_tis_i2c.h
index daaf8b8..75fa829 100644
@@ -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
Signature · 1 line
2.5.0.rc2.392.g76e840b
#14 lore raw

PATCH 6/25 tpm: Move the I2C TPM code into one file

Hi Simon,

I would basically disagree with this one.
The code from tpm.c you are merging into tpm_tis_i2c may not only be used by tpm_tis_i2c as it is using data from TPM standards (e.g: Trusted computing group) that should be used by other TPM drivers. You can find in chapter 17 how the table tpm_protected_ordinal_duration, tpm_ordinal_duration were build.
(https://www.trustedcomputinggroup.org/files/resource_files/E14876A3-1A4B-B294-D086297A1ED38F96/mainP2Structrev103.pdf).

This come from a Linux port.

As a result, we can imagine tis_sendrecv as a generic function where tpm_transmit manage the way tpm commands are sent following specification giving the hand to drivers thanks to the tpm_vendor_specific field {send,recv} for handling the communication over a specified or proprietary transport protocol.
As an example in tpm_tis_lpc, a 1s command duration might be too short or too long for some commands and might be really hard to debug in case someone decide to had a new TPM command support in u-boot. Also 1s might be enought for the current commands or for evaluated TPM but it may require a longer duration for some other.
By reading the duration TPM capability, that will be just generic.

Also tpm_tis_i2c is Infineon specific and does not fit to any TCG standard for TPM1.2, i would recommand to rename this driver tpm_i2c_infineon to be inline with Linux naming and not confuse a future user on what it support.

At the end from my delivery tentative, a Linux port as well, you may see that i also rely on those functions. However I am not doing any check on the command duration. This is to be improved...

May you prefer an approach that would not lead to duplicated code ?

Best Regards
Christophe

Quoted 1,250 lines · Simon Glass

The current Infineon I2C TPM driver is written in two parts, intended to support use with other I2C devices. However we don't have any users and the Atmel I2C TPM device does not use this file.

We should simplify this and remove the unused abstration. As a first step, move the code into one file.

Also the name tpm_private.h suggests that the header file is generic to all TPMs but it is not. Rename it indicate that it relates only to this driver

---

  drivers/tpm/Makefile                         |   2 -
  drivers/tpm/tpm.c                            | 594 ---------------------------
  drivers/tpm/tpm_tis_i2c.c                    | 548 +++++++++++++++++++++++-
  drivers/tpm/{tpm_private.h => tpm_tis_i2c.h} |  24 +-
  4 files changed, 550 insertions(+), 618 deletions(-)

delete mode 100644 drivers/tpm/tpm.c
rename drivers/tpm/{tpm_private.h => tpm_tis_i2c.h} (73%)

drivers/tpm/Makefile +0 -2
index 150570e..597966c 100644
@@ -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
drivers/tpm/tpm.c deleted +0 -594
deleted file mode 100644
index 24997f6..0000000
@@ -1,594 +0,0 @@
-/*
- * Copyright (C) 2011 Infineon Technologies
- *
- * Authors:
- * Peter Huewe <[email protected]>
- *
- * 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 at 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 at 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;
-}
drivers/tpm/tpm_tis_i2c.c +547 -1
index a43e80d..2b3ce8c 100644
@@ -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 at 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 at 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;
+}
drivers/tpm/tpm_tis_i2c.h renamed from drivers/tpm/tpm_private.h +3 -21
similarity index 73%
rename from drivers/tpm/tpm_private.h
rename to drivers/tpm/tpm_tis_i2c.h
index daaf8b8..75fa829 100644
@@ -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
#15 lore raw

PATCH 6/25 tpm: Move the I2C TPM code into one file

Hi Christophe,

Quoted 12 lines · christophe.ricard

Hi Simon,

I would basically disagree with this one.
The code from tpm.c you are merging into tpm_tis_i2c may not only be used by tpm_tis_i2c as it is using data from TPM standards (e.g: Trusted computing group) that should be used by other TPM drivers.
You can find in chapter 17 how the table tpm_protected_ordinal_duration, tpm_ordinal_duration were build.
(https://www.trustedcomputinggroup.org/files/resource_files/E14876A3-1A4B-B294-D086297A1ED38F96/mainP2Structrev103.pdf).

This come from a Linux port.

Quoted 11 lines

As a result, we can imagine tis_sendrecv as a generic function where tpm_transmit manage the way tpm commands are sent following specification giving the hand to drivers thanks to the tpm_vendor_specific field {send,recv} for handling the communication over a specified or proprietary transport protocol.
As an example in tpm_tis_lpc, a 1s command duration might be too short or too long for some commands and might be really hard to debug in case someone decide to had a new TPM command support in u-boot.
Also 1s might be enought for the current commands or for evaluated TPM but it may require a longer duration for some other.
By reading the duration TPM capability, that will be just generic.

But this code is only used by the Infineon driver.

Quoted 4 lines

Also tpm_tis_i2c is Infineon specific and does not fit to any TCG standard for TPM1.2, i would recommand to rename this driver tpm_i2c_infineon to be inline with Linux naming and not confuse a future user on what it support.

Yes we should do that.

Quoted 6 lines

At the end from my delivery tentative, a Linux port as well, you may see that i also rely on those functions. However I am not doing any check on the command duration. This is to be improved...

May you prefer an approach that would not lead to duplicated code ?

I wonder if the timing of each command can be attached to the uclass and handled there. We might have a function like:

tpm_xfer()

which sends data to the TPM and receives a rseponse. This can be implemented by the uclass.

Then the driver interface (which I currently have as xfer()) could be send() and receive(). The time delay measurement could happen in the uclass.

So in summary:

tpm-uclass.c:
tpm_xfer()
- calls driver->send()
- checks timeout based on data supplied by the driver

    -calls driver->receive()

- checks timeout based on data supplied by the driver
- returns result

Then the drivers only need to implement simple send and receive functions.

Quoted 31 lines

Best Regards
Christophe

Quoted 26 lines · Simon Glass

The current Infineon I2C TPM driver is written in two parts, intended to support use with other I2C devices. However we don't have any users and the
Atmel I2C TPM device does not use this file.

We should simplify this and remove the unused abstration. As a first step, move the code into one file.

Also the name tpm_private.h suggests that the header file is generic to all
TPMs but it is not. Rename it indicate that it relates only to this driver

---

  drivers/tpm/Makefile                         |   2 -
  drivers/tpm/tpm.c                            | 594
---------------------------
  drivers/tpm/tpm_tis_i2c.c                    | 548
+++++++++++++++++++++++-
  drivers/tpm/{tpm_private.h => tpm_tis_i2c.h} |  24 +-
  4 files changed, 550 insertions(+), 618 deletions(-)

delete mode 100644 drivers/tpm/tpm.c
rename drivers/tpm/{tpm_private.h => tpm_tis_i2c.h} (73%)

[snip]

Regards,
Simon

#16 lore raw

PATCH 6/25 tpm: Move the I2C TPM code into one file

Hi Simon,

Quoted 27 lines · Simon Glass

Hi Christophe,

Quoted 12 lines · christophe.ricard

Hi Simon,

I would basically disagree with this one.
The code from tpm.c you are merging into tpm_tis_i2c may not only be used by tpm_tis_i2c as it is using data from TPM standards (e.g: Trusted computing group) that should be used by other TPM drivers.
You can find in chapter 17 how the table tpm_protected_ordinal_duration, tpm_ordinal_duration were build.
(https://www.trustedcomputinggroup.org/files/resource_files/E14876A3-1A4B-B294-D086297A1ED38F96/mainP2Structrev103.pdf).

This come from a Linux port.

Quoted 11 lines

As a result, we can imagine tis_sendrecv as a generic function where tpm_transmit manage the way tpm commands are sent following specification giving the hand to drivers thanks to the tpm_vendor_specific field {send,recv} for handling the communication over a specified or proprietary transport protocol.
As an example in tpm_tis_lpc, a 1s command duration might be too short or too long for some commands and might be really hard to debug in case someone decide to had a new TPM command support in u-boot.
Also 1s might be enought for the current commands or for evaluated TPM but it may require a longer duration for some other.
By reading the duration TPM capability, that will be just generic.

Quoted 1 line

But this code is only used by the Infineon driver.

My idea is to standardize the way a tpm does a command transfer in u-boot. The approach is applicable to all the existing u-boot tpm drivers.

Quoted 33 lines
Quoted 4 lines

Also tpm_tis_i2c is Infineon specific and does not fit to any TCG standard for TPM1.2, i would recommand to rename this driver tpm_i2c_infineon to be inline with Linux naming and not confuse a future user on what it support.

Yes we should do that.

Quoted 5 lines

At the end from my delivery tentative, a Linux port as well, you may see that i also rely on those functions. However I am not doing any check on the command duration. This is to be improved...

May you prefer an approach that would not lead to duplicated code ?

I wonder if the timing of each command can be attached to the uclass and handled there. We might have a function like:

tpm_xfer()

which sends data to the TPM and receives a rseponse. This can be implemented by the uclass.

Then the driver interface (which I currently have as xfer()) could be send() and receive(). The time delay measurement could happen in the uclass.

So in summary:

tpm-uclass.c:
tpm_xfer()
- calls driver->send()
- checks timeout based on data supplied by the driver -calls driver->receive()
- checks timeout based on data supplied by the driver
- returns result

Quoted 1 line

Then the drivers only need to implement simple send and receive functions.

I agree with this approach.

[...]

Best REgards
Christophe

#17 lore raw

PATCH 7/25 tpm: tpm_tis_i2c: Drop unnecessary methods

In reply to Simon Glass

The function methods in struct tpm_vendor_specific just call local functions. Change the code to use a direct call.

---

 drivers/tpm/tpm_tis_i2c.c | 12 ++++--------
 drivers/tpm/tpm_tis_i2c.h |  4 ----
 2 files changed, 4 insertions(+), 12 deletions(-)
drivers/tpm/tpm_tis_i2c.c +4 -8
index 2b3ce8c..5615ffc 100644
@@ -810,10 +810,6 @@ out_err:
 }
 
 static struct tpm_vendor_specific tpm_tis_i2c = {
-	.status = tpm_tis_i2c_status,
-	.recv = tpm_tis_i2c_recv,
-	.send = tpm_tis_i2c_send,
-	.cancel = tpm_tis_i2c_ready,
 	.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 	.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
 	.req_canceled = TPM_STS_COMMAND_READY,
@@ -940,7 +936,7 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
 	}
 
 	debug("Calling send\n");
-	rc = chip->vendor.send(chip, (u8 *)buf, count);
+	rc = tpm_tis_i2c_send(chip, (u8 *)buf, count);
 	debug("   ... done calling send\n");
 	if (rc < 0) {
 		error("tpm_transmit: tpm_send: error %d\n", rc);
@@ -954,7 +950,7 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
 	stop = tpm_calc_ordinal_duration(chip, ordinal);
 	do {
 		debug("waiting for status... %ld %ld\n", start, stop);
-		u8 status = chip->vendor.status(chip);
+		u8 status = tpm_tis_i2c_status(chip);
 		if ((status & chip->vendor.req_complete_mask) ==
 		    chip->vendor.req_complete_val) {
 			debug("...got it;\n");
@@ -969,14 +965,14 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
 		udelay(TPM_TIMEOUT * 1000);
 	} while (get_timer(start) < stop);
 
-	chip->vendor.cancel(chip);
+	tpm_tis_i2c_ready(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);
+	rc = tpm_tis_i2c_recv(chip, (u8 *)buf, TPM_BUFSIZE);
 	if (rc < 0)
 		error("tpm_transmit: tpm_recv: error %d\n", rc);
 
drivers/tpm/tpm_tis_i2c.h +0 -4
index 75fa829..426c519 100644
@@ -40,10 +40,6 @@ struct tpm_vendor_specific {
 	const u8 req_complete_val;
 	const u8 req_canceled;
 	int irq;
-	int (*recv) (struct tpm_chip *, u8 *, size_t);
-	int (*send) (struct tpm_chip *, u8 *, size_t);
-	void (*cancel) (struct tpm_chip *);
-	u8(*status) (struct tpm_chip *);
 	int locality;
 	unsigned long timeout_a, timeout_b, timeout_c, timeout_d;  /* msec */
 	unsigned long duration[3];  /* msec */
Signature · 1 line
2.5.0.rc2.392.g76e840b
#18 lore raw

PATCH 7/25 tpm: tpm_tis_i2c: Drop unnecessary methods

Hi Simon,

As per my comment on patch 6, i would disagree as well on this one. It tpm_vendor_specific structure is convenient for ST33ZP24 for example.

Best Regards
Christophe

Quoted 75 lines · Simon Glass

The function methods in struct tpm_vendor_specific just call local functions. Change the code to use a direct call.

---

  drivers/tpm/tpm_tis_i2c.c | 12 ++++--------
  drivers/tpm/tpm_tis_i2c.h |  4 ----
  2 files changed, 4 insertions(+), 12 deletions(-)
drivers/tpm/tpm_tis_i2c.c +4 -8
index 2b3ce8c..5615ffc 100644
@@ -810,10 +810,6 @@ out_err:
  }
 
  static struct tpm_vendor_specific tpm_tis_i2c = {
-	.status = tpm_tis_i2c_status,
-	.recv = tpm_tis_i2c_recv,
-	.send = tpm_tis_i2c_send,
-	.cancel = tpm_tis_i2c_ready,
  	.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
  	.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
  	.req_canceled = TPM_STS_COMMAND_READY,
@@ -940,7 +936,7 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
  	}
 
  	debug("Calling send\n");
-	rc = chip->vendor.send(chip, (u8 *)buf, count);
+	rc = tpm_tis_i2c_send(chip, (u8 *)buf, count);
  	debug("   ... done calling send\n");
  	if (rc < 0) {
  		error("tpm_transmit: tpm_send: error %d\n", rc);
@@ -954,7 +950,7 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
  	stop = tpm_calc_ordinal_duration(chip, ordinal);
  	do {
  		debug("waiting for status... %ld %ld\n", start, stop);
-		u8 status = chip->vendor.status(chip);
+		u8 status = tpm_tis_i2c_status(chip);
  		if ((status & chip->vendor.req_complete_mask) ==
  		    chip->vendor.req_complete_val) {
  			debug("...got it;\n");
@@ -969,14 +965,14 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
  		udelay(TPM_TIMEOUT * 1000);
  	} while (get_timer(start) < stop);
 
-	chip->vendor.cancel(chip);
+	tpm_tis_i2c_ready(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);
+	rc = tpm_tis_i2c_recv(chip, (u8 *)buf, TPM_BUFSIZE);
  	if (rc < 0)
  		error("tpm_transmit: tpm_recv: error %d\n", rc);
 
drivers/tpm/tpm_tis_i2c.h +0 -4
index 75fa829..426c519 100644
@@ -40,10 +40,6 @@ struct tpm_vendor_specific {
  	const u8 req_complete_val;
  	const u8 req_canceled;
  	int irq;
-	int (*recv) (struct tpm_chip *, u8 *, size_t);
-	int (*send) (struct tpm_chip *, u8 *, size_t);
-	void (*cancel) (struct tpm_chip *);
-	u8(*status) (struct tpm_chip *);
  	int locality;
  	unsigned long timeout_a, timeout_b, timeout_c, timeout_d;  /* msec */
  	unsigned long duration[3];  /* msec */
#19 lore raw

PATCH 7/25 tpm: tpm_tis_i2c: Drop unnecessary methods

Hi Christophe,

Quoted 8 lines · christophe.ricard

Hi Simon,

As per my comment on patch 6, i would disagree as well on this one. It tpm_vendor_specific structure is convenient for ST33ZP24 for example.

Best Regards
Christophe

As things stand they are only used in one place. I think we should work out the best uclass API for the TPM and then go with that.

[snip]

Regards,
Simon

#20 lore raw

PATCH 7/25 tpm: tpm_tis_i2c: Drop unnecessary methods

Hi Simon,

Quoted 6 lines · Simon Glass

Hi Christophe,

Quoted 2 lines · christophe.ricard

Hi Simon,

Quoted 8 lines
Quoted 6 lines

As per my comment on patch 6, i would disagree as well on this one. It tpm_vendor_specific structure is convenient for ST33ZP24 for example.

Best Regards
Christophe

As things stand they are only used in one place. I think we should work out the best uclass API for the TPM and then go with that.

I agree with that.
How do you want to proceed ? Do you agree to integrate the results of our exchanges for a new round ?

[...]

Best Regards
Christophe

#21 lore raw

PATCH 7/25 tpm: tpm_tis_i2c: Drop unnecessary methods

Hi Christophe,

Quoted 17 lines · Christophe Ricard

Hi Simon,

Quoted 14 lines · Simon Glass

Hi Christophe,

Quoted 9 lines · christophe.ricard

Hi Simon,

As per my comment on patch 6, i would disagree as well on this one. It tpm_vendor_specific structure is convenient for ST33ZP24 for example.

Best Regards
Christophe

Quoted 6 lines
Quoted 2 lines

As things stand they are only used in one place. I think we should work out the best uclass API for the TPM and then go with that.

I agree with that.
How do you want to proceed ? Do you agree to integrate the results of our exchanges for a new round ?

Yes OK, I'll have a crack at this.

Regards,
Simon

#22 lore raw

PATCH 8/25 tpm: tpm_tis_i2c: Drop struct tpm_vendor_specific

In reply to Simon Glass

This function is misnamed since it only applies to a single driver. Merge its fields into its parent.

---

 drivers/tpm/tpm_tis_i2c.c | 79 ++++++++++++++++++-----------------------------
 drivers/tpm/tpm_tis_i2c.h | 16 +++-------
 2 files changed, 35 insertions(+), 60 deletions(-)
drivers/tpm/tpm_tis_i2c.c +30 -49
index 5615ffc..3c4e6c5 100644
@@ -531,7 +531,7 @@ static int check_locality(struct tpm_chip *chip, int loc)
 		return rc;
 
 	if ((buf & mask) == mask) {
-		chip->vendor.locality = loc;
+		chip->locality = loc;
 		return loc;
 	}
 
@@ -567,7 +567,7 @@ static int request_locality(struct tpm_chip *chip, int loc)
 
 	/* Wait for burstcount */
 	start = get_timer(0);
-	stop = chip->vendor.timeout_a;
+	stop = chip->timeout_a;
 	do {
 		if (check_locality(chip, loc) >= 0)
 			return loc;
@@ -582,7 +582,7 @@ static u8 tpm_tis_i2c_status(struct tpm_chip *chip)
 	/* NOTE: Since i2c read may fail, return 0 in this case --> time-out */
 	u8 buf;
 
-	if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0)
+	if (iic_tpm_read(TPM_STS(chip->locality), &buf, 1) < 0)
 		return 0;
 	else
 		return buf;
@@ -596,7 +596,7 @@ static void tpm_tis_i2c_ready(struct tpm_chip *chip)
 	u8 buf = TPM_STS_COMMAND_READY;
 
 	debug("%s\n", __func__);
-	rc = iic_tpm_write_long(TPM_STS(chip->vendor.locality), &buf, 1);
+	rc = iic_tpm_write_long(TPM_STS(chip->locality), &buf, 1);
 	if (rc)
 		debug("%s: rc=%d\n", __func__, rc);
 }
@@ -610,10 +610,10 @@ static ssize_t get_burstcount(struct tpm_chip *chip)
 	/* Wait for burstcount */
 	/* XXX: Which timeout value? Spec has 2 answers (c & d) */
 	start = get_timer(0);
-	stop = chip->vendor.timeout_d;
+	stop = chip->timeout_d;
 	do {
 		/* Note: STS is little endian */
-		addr = TPM_STS(chip->vendor.locality) + 1;
+		addr = TPM_STS(chip->locality) + 1;
 		if (iic_tpm_read(addr, buf, 3) < 0)
 			burstcnt = 0;
 		else
@@ -666,7 +666,7 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
 		if (burstcnt > (count - size))
 			burstcnt = count - size;
 
-		rc = iic_tpm_read(TPM_DATA_FIFO(chip->vendor.locality),
+		rc = iic_tpm_read(TPM_DATA_FIFO(chip->locality),
 				&(buf[size]), burstcnt);
 		if (rc == 0)
 			size += burstcnt;
@@ -708,7 +708,7 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 		goto out;
 	}
 
-	wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
+	wait_for_stat(chip, TPM_STS_VALID, chip->timeout_c, &status);
 	if (status & TPM_STS_DATA_AVAIL) {  /* Retry? */
 		error("Error left over data\n");
 		size = -EIO;
@@ -722,7 +722,7 @@ out:
 	 * so we sleep rather than keeping the bus busy
 	 */
 	udelay(2000);
-	release_locality(chip, chip->vendor.locality, 0);
+	release_locality(chip, chip->locality, 0);
 
 	return size;
 }
@@ -746,7 +746,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
 	if ((status & TPM_STS_COMMAND_READY) == 0) {
 		tpm_tis_i2c_ready(chip);
 		if (wait_for_stat(chip, TPM_STS_COMMAND_READY,
-				  chip->vendor.timeout_b, &status) < 0) {
+				  chip->timeout_b, &status) < 0) {
 			rc = -ETIME;
 			goto out_err;
 		}
@@ -768,7 +768,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
 			burstcnt = CONFIG_TPM_TIS_I2C_BURST_LIMITATION;
 #endif /* CONFIG_TPM_TIS_I2C_BURST_LIMITATION */
 
-		rc = iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality),
+		rc = iic_tpm_write(TPM_DATA_FIFO(chip->locality),
 				&(buf[count]), burstcnt);
 		if (rc == 0)
 			count += burstcnt;
@@ -779,7 +779,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
 				goto out_err;
 			}
 			rc = wait_for_stat(chip, TPM_STS_VALID,
-					   chip->vendor.timeout_c, &status);
+					   chip->timeout_c, &status);
 			if (rc)
 				goto out_err;
 
@@ -791,7 +791,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
 	}
 
 	/* Go and do it */
-	iic_tpm_write(TPM_STS(chip->vendor.locality), &sts, 1);
+	iic_tpm_write(TPM_STS(chip->locality), &sts, 1);
 	debug("done\n");
 
 	return len;
@@ -804,18 +804,11 @@ out_err:
 	 * so we sleep rather than keeping the bus busy
 	 */
 	udelay(2000);
-	release_locality(chip, chip->vendor.locality, 0);
+	release_locality(chip, chip->locality, 0);
 
 	return rc;
 }
 
-static struct tpm_vendor_specific tpm_tis_i2c = {
-	.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
-	.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
-	.req_canceled = TPM_STS_COMMAND_READY,
-};
-
-
 static enum i2c_chip_type tpm_vendor_chip_type(void)
 {
 #ifdef CONFIG_OF_CONTROL
@@ -832,25 +825,25 @@ static enum i2c_chip_type tpm_vendor_chip_type(void)
 
 int tpm_vendor_init(struct udevice *dev)
 {
-	struct tpm_chip *chip;
+	struct tpm_chip *chip = &g_chip;
 	u32 vendor;
 	u32 expected_did_vid;
 
 	tpm_dev.dev = dev;
 	tpm_dev.chip_type = tpm_vendor_chip_type();
-
-	chip = tpm_register_hardware(&tpm_tis_i2c);
-	if (chip < 0)
-		return -ENODEV;
+	chip->is_open = 1;
 
 	/* Disable interrupts (not supported) */
-	chip->vendor.irq = 0;
+	chip->irq = 0;
 
 	/* Default timeouts */
-	chip->vendor.timeout_a = TIS_SHORT_TIMEOUT;
-	chip->vendor.timeout_b = TIS_LONG_TIMEOUT;
-	chip->vendor.timeout_c = TIS_SHORT_TIMEOUT;
-	chip->vendor.timeout_d = TIS_SHORT_TIMEOUT;
+	chip->timeout_a = TIS_SHORT_TIMEOUT;
+	chip->timeout_b = TIS_LONG_TIMEOUT;
+	chip->timeout_c = TIS_SHORT_TIMEOUT;
+	chip->timeout_d = TIS_SHORT_TIMEOUT;
+	chip->req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID;
+	chip->req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID;
+	chip->req_canceled = TPM_STS_COMMAND_READY;
 
 	if (request_locality(chip, 0) < 0)
 		return  -ENODEV;
@@ -887,7 +880,7 @@ int tpm_vendor_init(struct udevice *dev)
 
 void tpm_vendor_cleanup(struct tpm_chip *chip)
 {
-	release_locality(chip, chip->vendor.locality, 1);
+	release_locality(chip, chip->locality, 1);
 }
 
 /* Returns max number of milliseconds to wait */
@@ -906,7 +899,7 @@ static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
 	}
 
 	if (duration_idx != TPM_UNDEFINED)
-		duration = chip->vendor.duration[duration_idx];
+		duration = chip->duration[duration_idx];
 
 	if (duration <= 0)
 		return 2 * 60 * HZ; /* Two minutes timeout */
@@ -943,7 +936,7 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
 		goto out;
 	}
 
-	if (chip->vendor.irq)
+	if (chip->irq)
 		goto out_recv;
 
 	start = get_timer(0);
@@ -951,13 +944,13 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
 	do {
 		debug("waiting for status... %ld %ld\n", start, stop);
 		u8 status = tpm_tis_i2c_status(chip);
-		if ((status & chip->vendor.req_complete_mask) ==
-		    chip->vendor.req_complete_val) {
+		if ((status & chip->req_complete_mask) ==
+		    chip->req_complete_val) {
 			debug("...got it;\n");
 			goto out_recv;
 		}
 
-		if (status == chip->vendor.req_canceled) {
+		if (status == chip->req_canceled) {
 			error("Operation Canceled\n");
 			rc = -ECANCELED;
 			goto out;
@@ -1062,18 +1055,6 @@ static int tpm_decode_config(struct tpm *dev)
 	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)
drivers/tpm/tpm_tis_i2c.h +5 -11
index 426c519..2a4ad77 100644
@@ -35,21 +35,17 @@ enum tpm_timeout {
 
 struct tpm_chip;
 
-struct tpm_vendor_specific {
-	const u8 req_complete_mask;
-	const u8 req_complete_val;
-	const u8 req_canceled;
+struct tpm_chip {
+	int is_open;
+	u8 req_complete_mask;
+	u8 req_complete_val;
+	u8 req_canceled;
 	int irq;
 	int locality;
 	unsigned long timeout_a, timeout_b, timeout_c, timeout_d;  /* msec */
 	unsigned long duration[3];  /* msec */
 };
 
-struct tpm_chip {
-	int is_open;
-	struct tpm_vendor_specific vendor;
-};
-
 struct tpm_input_header {
 	__be16 tag;
 	__be32 length;
@@ -106,8 +102,6 @@ struct tpm_cmd_t {
 	union tpm_cmd_params params;
 } __packed;
 
-struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *);
-
 struct udevice;
 int tpm_vendor_init(struct udevice *dev);
 
Signature · 1 line
2.5.0.rc2.392.g76e840b
#23 lore raw

PATCH 8/25 tpm: tpm_tis_i2c: Drop struct tpm_vendor_specific

Hi Simon,

Locality concept are valid almost on any chip assuming if no locality are supported the default one is locality 0.
I would leave this change open for discussion.

However, as per patch 06 & 07, i would keep req_complete_mask, req_complete_val, req_canceled, timeout_a, timeout_b, timeout_c, timeout_d in tpm_vendor_specific structure as this is chip specific.

I really think tpm_vendor_specific is usefull for managing different kind of TPM "the same way"/following standards.

Best Regards
Christophe

Quoted 285 lines · Simon Glass

This function is misnamed since it only applies to a single driver. Merge its fields into its parent.

---

  drivers/tpm/tpm_tis_i2c.c | 79 ++++++++++++++++++-----------------------------
  drivers/tpm/tpm_tis_i2c.h | 16 +++-------
  2 files changed, 35 insertions(+), 60 deletions(-)
drivers/tpm/tpm_tis_i2c.c +30 -49
index 5615ffc..3c4e6c5 100644
@@ -531,7 +531,7 @@ static int check_locality(struct tpm_chip *chip, int loc)
  		return rc;
 
  	if ((buf & mask) == mask) {
-		chip->vendor.locality = loc;
+		chip->locality = loc;
  		return loc;
  	}
 
@@ -567,7 +567,7 @@ static int request_locality(struct tpm_chip *chip, int loc)
 
  	/* Wait for burstcount */
  	start = get_timer(0);
-	stop = chip->vendor.timeout_a;
+	stop = chip->timeout_a;
  	do {
  		if (check_locality(chip, loc) >= 0)
  			return loc;
@@ -582,7 +582,7 @@ static u8 tpm_tis_i2c_status(struct tpm_chip *chip)
  	/* NOTE: Since i2c read may fail, return 0 in this case --> time-out */
  	u8 buf;
 
-	if (iic_tpm_read(TPM_STS(chip->vendor.locality), &buf, 1) < 0)
+	if (iic_tpm_read(TPM_STS(chip->locality), &buf, 1) < 0)
  		return 0;
  	else
  		return buf;
@@ -596,7 +596,7 @@ static void tpm_tis_i2c_ready(struct tpm_chip *chip)
  	u8 buf = TPM_STS_COMMAND_READY;
 
  	debug("%s\n", __func__);
-	rc = iic_tpm_write_long(TPM_STS(chip->vendor.locality), &buf, 1);
+	rc = iic_tpm_write_long(TPM_STS(chip->locality), &buf, 1);
  	if (rc)
  		debug("%s: rc=%d\n", __func__, rc);
  }
@@ -610,10 +610,10 @@ static ssize_t get_burstcount(struct tpm_chip *chip)
  	/* Wait for burstcount */
  	/* XXX: Which timeout value? Spec has 2 answers (c & d) */
  	start = get_timer(0);
-	stop = chip->vendor.timeout_d;
+	stop = chip->timeout_d;
  	do {
  		/* Note: STS is little endian */
-		addr = TPM_STS(chip->vendor.locality) + 1;
+		addr = TPM_STS(chip->locality) + 1;
  		if (iic_tpm_read(addr, buf, 3) < 0)
  			burstcnt = 0;
  		else
@@ -666,7 +666,7 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
  		if (burstcnt > (count - size))
  			burstcnt = count - size;
 
-		rc = iic_tpm_read(TPM_DATA_FIFO(chip->vendor.locality),
+		rc = iic_tpm_read(TPM_DATA_FIFO(chip->locality),
  				&(buf[size]), burstcnt);
  		if (rc == 0)
  			size += burstcnt;
@@ -708,7 +708,7 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
  		goto out;
  	}
 
-	wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, &status);
+	wait_for_stat(chip, TPM_STS_VALID, chip->timeout_c, &status);
  	if (status & TPM_STS_DATA_AVAIL) {  /* Retry? */
  		error("Error left over data\n");
  		size = -EIO;
@@ -722,7 +722,7 @@ out:
  	 * so we sleep rather than keeping the bus busy
  	 */
  	udelay(2000);
-	release_locality(chip, chip->vendor.locality, 0);
+	release_locality(chip, chip->locality, 0);
 
  	return size;
  }
@@ -746,7 +746,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
  	if ((status & TPM_STS_COMMAND_READY) == 0) {
  		tpm_tis_i2c_ready(chip);
  		if (wait_for_stat(chip, TPM_STS_COMMAND_READY,
-				  chip->vendor.timeout_b, &status) < 0) {
+				  chip->timeout_b, &status) < 0) {
  			rc = -ETIME;
  			goto out_err;
  		}
@@ -768,7 +768,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
  			burstcnt = CONFIG_TPM_TIS_I2C_BURST_LIMITATION;
  #endif /* CONFIG_TPM_TIS_I2C_BURST_LIMITATION */
 
-		rc = iic_tpm_write(TPM_DATA_FIFO(chip->vendor.locality),
+		rc = iic_tpm_write(TPM_DATA_FIFO(chip->locality),
  				&(buf[count]), burstcnt);
  		if (rc == 0)
  			count += burstcnt;
@@ -779,7 +779,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
  				goto out_err;
  			}
  			rc = wait_for_stat(chip, TPM_STS_VALID,
-					   chip->vendor.timeout_c, &status);
+					   chip->timeout_c, &status);
  			if (rc)
  				goto out_err;
 
@@ -791,7 +791,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
  	}
 
  	/* Go and do it */
-	iic_tpm_write(TPM_STS(chip->vendor.locality), &sts, 1);
+	iic_tpm_write(TPM_STS(chip->locality), &sts, 1);
  	debug("done\n");
 
  	return len;
@@ -804,18 +804,11 @@ out_err:
  	 * so we sleep rather than keeping the bus busy
  	 */
  	udelay(2000);
-	release_locality(chip, chip->vendor.locality, 0);
+	release_locality(chip, chip->locality, 0);
 
  	return rc;
  }
 
-static struct tpm_vendor_specific tpm_tis_i2c = {
-	.req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
-	.req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
-	.req_canceled = TPM_STS_COMMAND_READY,
-};
-
-
  static enum i2c_chip_type tpm_vendor_chip_type(void)
  {
  #ifdef CONFIG_OF_CONTROL
@@ -832,25 +825,25 @@ static enum i2c_chip_type tpm_vendor_chip_type(void)
 
  int tpm_vendor_init(struct udevice *dev)
  {
-	struct tpm_chip *chip;
+	struct tpm_chip *chip = &g_chip;
  	u32 vendor;
  	u32 expected_did_vid;
 
  	tpm_dev.dev = dev;
  	tpm_dev.chip_type = tpm_vendor_chip_type();
-
-	chip = tpm_register_hardware(&tpm_tis_i2c);
-	if (chip < 0)
-		return -ENODEV;
+	chip->is_open = 1;
 
  	/* Disable interrupts (not supported) */
-	chip->vendor.irq = 0;
+	chip->irq = 0;
 
  	/* Default timeouts */
-	chip->vendor.timeout_a = TIS_SHORT_TIMEOUT;
-	chip->vendor.timeout_b = TIS_LONG_TIMEOUT;
-	chip->vendor.timeout_c = TIS_SHORT_TIMEOUT;
-	chip->vendor.timeout_d = TIS_SHORT_TIMEOUT;
+	chip->timeout_a = TIS_SHORT_TIMEOUT;
+	chip->timeout_b = TIS_LONG_TIMEOUT;
+	chip->timeout_c = TIS_SHORT_TIMEOUT;
+	chip->timeout_d = TIS_SHORT_TIMEOUT;
+	chip->req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID;
+	chip->req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID;
+	chip->req_canceled = TPM_STS_COMMAND_READY;
 
  	if (request_locality(chip, 0) < 0)
  		return  -ENODEV;
@@ -887,7 +880,7 @@ int tpm_vendor_init(struct udevice *dev)
 
  void tpm_vendor_cleanup(struct tpm_chip *chip)
  {
-	release_locality(chip, chip->vendor.locality, 1);
+	release_locality(chip, chip->locality, 1);
  }
 
  /* Returns max number of milliseconds to wait */
@@ -906,7 +899,7 @@ static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
  	}
 
  	if (duration_idx != TPM_UNDEFINED)
-		duration = chip->vendor.duration[duration_idx];
+		duration = chip->duration[duration_idx];
 
  	if (duration <= 0)
  		return 2 * 60 * HZ; /* Two minutes timeout */
@@ -943,7 +936,7 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
  		goto out;
  	}
 
-	if (chip->vendor.irq)
+	if (chip->irq)
  		goto out_recv;
 
  	start = get_timer(0);
@@ -951,13 +944,13 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
  	do {
  		debug("waiting for status... %ld %ld\n", start, stop);
  		u8 status = tpm_tis_i2c_status(chip);
-		if ((status & chip->vendor.req_complete_mask) ==
-		    chip->vendor.req_complete_val) {
+		if ((status & chip->req_complete_mask) ==
+		    chip->req_complete_val) {
  			debug("...got it;\n");
  			goto out_recv;
  		}
 
-		if (status == chip->vendor.req_canceled) {
+		if (status == chip->req_canceled) {
  			error("Operation Canceled\n");
  			rc = -ECANCELED;
  			goto out;
@@ -1062,18 +1055,6 @@ static int tpm_decode_config(struct tpm *dev)
  	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)
drivers/tpm/tpm_tis_i2c.h +5 -11
index 426c519..2a4ad77 100644
@@ -35,21 +35,17 @@ enum tpm_timeout {
 
  struct tpm_chip;
 
-struct tpm_vendor_specific {
-	const u8 req_complete_mask;
-	const u8 req_complete_val;
-	const u8 req_canceled;
+struct tpm_chip {
+	int is_open;
+	u8 req_complete_mask;
+	u8 req_complete_val;
+	u8 req_canceled;
  	int irq;
  	int locality;
  	unsigned long timeout_a, timeout_b, timeout_c, timeout_d;  /* msec */
  	unsigned long duration[3];  /* msec */
  };
 
-struct tpm_chip {
-	int is_open;
-	struct tpm_vendor_specific vendor;
-};
-
  struct tpm_input_header {
  	__be16 tag;
  	__be32 length;
@@ -106,8 +102,6 @@ struct tpm_cmd_t {
  	union tpm_cmd_params params;
  } __packed;
 
-struct tpm_chip *tpm_register_hardware(const struct tpm_vendor_specific *);
-
  struct udevice;
  int tpm_vendor_init(struct udevice *dev);
 
#24 lore raw

PATCH 8/25 tpm: tpm_tis_i2c: Drop struct tpm_vendor_specific

Hi Christophe,

Quoted 6 lines · christophe.ricard

Hi Simon,

Locality concept are valid almost on any chip assuming if no locality are supported the default one is locality 0.
I would leave this change open for discussion.

Quoted 6 lines

However, as per patch 06 & 07, i would keep req_complete_mask, req_complete_val, req_canceled, timeout_a, timeout_b, timeout_c, timeout_d in tpm_vendor_specific structure as this is chip specific.

I really think tpm_vendor_specific is usefull for managing different kind of TPM "the same way"/following standards.

That code belongs in the uclass I think. If there really are generic settings that are needed for all TPMs then it should sit there. We don't want to have an additional layer of stuff that doesn't relate to driver model.

I'll refrain from commenting further until we can work out what the TPM uclass should look like.

Quoted 3 lines

Best Regards
Christophe

[snip]

Regards,
Simon

#25 lore raw

PATCH 8/25 tpm: tpm_tis_i2c: Drop struct tpm_vendor_specific

Hi Simon,

Quoted 14 lines · Simon Glass

Hi Christophe,

Quoted 10 lines · christophe.ricard

Hi Simon,

Locality concept are valid almost on any chip assuming if no locality are supported the default one is locality 0.
I would leave this change open for discussion.

However, as per patch 06 & 07, i would keep req_complete_mask, req_complete_val, req_canceled, timeout_a, timeout_b, timeout_c, timeout_d in tpm_vendor_specific structure as this is chip specific.

Quoted 6 lines
Quoted 2 lines

I really think tpm_vendor_specific is usefull for managing different kind of TPM "the same way"/following standards.

That code belongs in the uclass I think. If there really are generic settings that are needed for all TPMs then it should sit there. We don't want to have an additional layer of stuff that doesn't relate to driver model.

After reviewing your previous comments, i think we can drop this tpm_vendor_specific structure to simplify the code a bit. However, the work we are doing may stick only to TPM1.2. I think it will be fine as we have only drivers for those kind of TPMs.
I believe a new uclass may be necessary when going to provide support TPM 2.0.

In short, may be we can anticipate that and make it explicit in the uclass name ? (UCLASS_TPM12 ?)

[...]

Best Regards
Christophe

#26 lore raw

PATCH 8/25 tpm: tpm_tis_i2c: Drop struct tpm_vendor_specific

Hi Christophe,

Quoted 36 lines · Christophe Ricard

Hi Simon,

Quoted 17 lines · Simon Glass

Hi Christophe,

Quoted 12 lines · christophe.ricard

Hi Simon,

Locality concept are valid almost on any chip assuming if no locality are supported the default one is locality 0.
I would leave this change open for discussion.

However, as per patch 06 & 07, i would keep req_complete_mask, req_complete_val, req_canceled, timeout_a, timeout_b, timeout_c, timeout_d
in tpm_vendor_specific structure as this is chip specific.

Quoted 8 lines
Quoted 3 lines

I really think tpm_vendor_specific is usefull for managing different kind of
TPM "the same way"/following standards.

That code belongs in the uclass I think. If there really are generic settings that are needed for all TPMs then it should sit there. We don't want to have an additional layer of stuff that doesn't relate to driver model.

After reviewing your previous comments, i think we can drop this tpm_vendor_specific structure to simplify the code a bit. However, the work we are doing may stick only to TPM1.2. I think it will be fine as we have only drivers for those kind of TPMs.
I believe a new uclass may be necessary when going to provide support TPM 2.0.

Quoted 2 lines

In short, may be we can anticipate that and make it explicit in the uclass name ? (UCLASS_TPM12 ?)

Ick, I'd rather worry about this when we have a problem.

Regardsimon

#27 lore raw

PATCH 9/25 tpm: tpm_tis_i2c: Merge struct tpm_dev into tpm_chip

In reply to Simon Glass

There are too many structures storing the same sort of information. Move the fields from struct tpm_dev into struct tpm_chip and remove the former struct.

---

 drivers/tpm/tpm_tis_i2c.c | 52 +++++++++++++----------------------------------
 drivers/tpm/tpm_tis_i2c.h | 17 ++++++++++------
 2 files changed, 25 insertions(+), 44 deletions(-)
drivers/tpm/tpm_tis_i2c.c +14 -38
index 3c4e6c5..70d21ca 100644
@@ -34,9 +34,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Max buffer size supported by our tpm */
-#define TPM_DEV_BUFSIZE		1260
-
 /* Max number of iterations after i2c NAK */
 #define MAX_COUNT		3
 
@@ -78,12 +75,6 @@ enum tis_defaults {
 #define TPM_TIS_I2C_DID_VID_9635 0x000b15d1L
 #define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L
 
-enum i2c_chip_type {
-	SLB9635,
-	SLB9645,
-	UNKNOWN,
-};
-
 static const char * const chip_name[] = {
 	[SLB9635] = "slb9635tt",
 	[SLB9645] = "slb9645tt",
@@ -390,18 +381,8 @@ struct tpm {
 	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;
-	u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)];  /* Max buffer size + addr */
-	enum i2c_chip_type chip_type;
-};
-
-static struct tpm_dev tpm_dev;
-
 /*
  * iic_tpm_read() - read from TPM register
  * @addr: register address to read from
@@ -422,10 +403,10 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
 	int count;
 	uint32_t addrbuf = addr;
 
-	if ((tpm_dev.chip_type == SLB9635) || (tpm_dev.chip_type == UNKNOWN)) {
+	if ((g_chip.chip_type == SLB9635) || (g_chip.chip_type == UNKNOWN)) {
 		/* slb9635 protocol should work in both cases */
 		for (count = 0; count < MAX_COUNT; count++) {
-			rc = dm_i2c_write(tpm_dev.dev, 0, (uchar *)&addrbuf, 1);
+			rc = dm_i2c_write(g_chip.dev, 0, (uchar *)&addrbuf, 1);
 			if (rc == 0)
 				break;  /* Success, break to skip sleep */
 			udelay(SLEEP_DURATION);
@@ -439,7 +420,7 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
 		 */
 		for (count = 0; count < MAX_COUNT; count++) {
 			udelay(SLEEP_DURATION);
-			rc = dm_i2c_read(tpm_dev.dev, 0, buffer, len);
+			rc = dm_i2c_read(g_chip.dev, 0, buffer, len);
 			if (rc == 0)
 				break;  /* success, break to skip sleep */
 		}
@@ -452,7 +433,7 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
 		 * be safe on the safe side.
 		 */
 		for (count = 0; count < MAX_COUNT; count++) {
-			rc = dm_i2c_read(tpm_dev.dev, addr, buffer, len);
+			rc = dm_i2c_read(g_chip.dev, addr, buffer, len);
 			if (rc == 0)
 				break;  /* break here to skip sleep */
 			udelay(SLEEP_DURATION);
@@ -474,7 +455,7 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
 	int count;
 
 	for (count = 0; count < max_count; count++) {
-		rc = dm_i2c_write(tpm_dev.dev, addr, buffer, len);
+		rc = dm_i2c_write(g_chip.dev, addr, buffer, len);
 		if (rc == 0)
 			break;  /* Success, break to skip sleep */
 		udelay(sleep_time);
@@ -809,7 +790,7 @@ out_err:
 	return rc;
 }
 
-static enum i2c_chip_type tpm_vendor_chip_type(void)
+static enum i2c_chip_type tpm_tis_i2c_chip_type(void)
 {
 #ifdef CONFIG_OF_CONTROL
 	const void *blob = gd->fdt_blob;
@@ -823,14 +804,14 @@ static enum i2c_chip_type tpm_vendor_chip_type(void)
 	return UNKNOWN;
 }
 
-int tpm_vendor_init(struct udevice *dev)
+static int tpm_tis_i2c_init(struct udevice *dev)
 {
 	struct tpm_chip *chip = &g_chip;
 	u32 vendor;
 	u32 expected_did_vid;
 
-	tpm_dev.dev = dev;
-	tpm_dev.chip_type = tpm_vendor_chip_type();
+	g_chip.dev = dev;
+	g_chip.chip_type = tpm_tis_i2c_chip_type();
 	chip->is_open = 1;
 
 	/* Disable interrupts (not supported) */
@@ -854,7 +835,7 @@ int tpm_vendor_init(struct udevice *dev)
 		return -EIO;
 	}
 
-	if (tpm_dev.chip_type == SLB9635) {
+	if (g_chip.chip_type == SLB9635) {
 		vendor = be32_to_cpu(vendor);
 		expected_did_vid = TPM_TIS_I2C_DID_VID_9635;
 	} else {
@@ -862,13 +843,13 @@ int tpm_vendor_init(struct udevice *dev)
 		expected_did_vid = TPM_TIS_I2C_DID_VID_9645;
 	}
 
-	if (tpm_dev.chip_type != UNKNOWN && vendor != expected_did_vid) {
+	if (g_chip.chip_type != UNKNOWN && vendor != expected_did_vid) {
 		error("Vendor id did not match! ID was %08x\n", vendor);
 		return -ENODEV;
 	}
 
 	debug("1.2 TPM (chip type %s device-id 0x%X)\n",
-	      chip_name[tpm_dev.chip_type], vendor >> 16);
+	      chip_name[g_chip.chip_type], vendor >> 16);
 
 	/*
 	 * A timeout query to TPM can be placed here.
@@ -878,11 +859,6 @@ int tpm_vendor_init(struct udevice *dev)
 	return 0;
 }
 
-void tpm_vendor_cleanup(struct tpm_chip *chip)
-{
-	release_locality(chip, chip->locality, 1);
-}
-
 /* Returns max number of milliseconds to wait */
 static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
 		u32 ordinal)
@@ -980,7 +956,7 @@ static int tpm_open_dev(struct udevice *dev)
 	debug("%s: start\n", __func__);
 	if (g_chip.is_open)
 		return -EBUSY;
-	rc = tpm_vendor_init(dev);
+	rc = tpm_tis_i2c_init(dev);
 	if (rc < 0)
 		g_chip.is_open = 0;
 	return rc;
@@ -989,7 +965,7 @@ static int tpm_open_dev(struct udevice *dev)
 static void tpm_close(void)
 {
 	if (g_chip.is_open) {
-		tpm_vendor_cleanup(&g_chip);
+		release_locality(&g_chip, g_chip.locality, 1);
 		g_chip.is_open = 0;
 	}
 }
drivers/tpm/tpm_tis_i2c.h +11 -6
index 2a4ad77..0fec464 100644
@@ -33,7 +33,14 @@ enum tpm_timeout {
 #define TPM_RSP_SIZE_BYTE	2
 #define TPM_RSP_RC_BYTE		6
 
-struct tpm_chip;
+/* Max buffer size supported by our tpm */
+#define TPM_DEV_BUFSIZE		1260
+
+enum i2c_chip_type {
+	SLB9635,
+	SLB9645,
+	UNKNOWN,
+};
 
 struct tpm_chip {
 	int is_open;
@@ -44,6 +51,9 @@ struct tpm_chip {
 	int locality;
 	unsigned long timeout_a, timeout_b, timeout_c, timeout_d;  /* msec */
 	unsigned long duration[3];  /* msec */
+	struct udevice *dev;
+	u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)];  /* Max buffer size + addr */
+	enum i2c_chip_type chip_type;
 };
 
 struct tpm_input_header {
@@ -102,9 +112,4 @@ struct tpm_cmd_t {
 	union tpm_cmd_params params;
 } __packed;
 
-struct udevice;
-int tpm_vendor_init(struct udevice *dev);
-
-void tpm_vendor_cleanup(struct tpm_chip *chip);
-
 #endif
Signature · 1 line
2.5.0.rc2.392.g76e840b
#28 lore raw

PATCH 9/25 tpm: tpm_tis_i2c: Merge struct tpm_dev into tpm_chip

Hi Simon,

As per my delivery tentative, don't you think driver specific data could be stored in a void *priv field in struct tpm_vendor_specific ? This how we manage such information in Linux drivers.

Please have a look in tpm_private.h changes:
http://lists.denx.de/pipermail/u-boot/2015-August/222598.html

Best Regards
Christophe

Quoted 219 lines · Simon Glass

There are too many structures storing the same sort of information. Move the fields from struct tpm_dev into struct tpm_chip and remove the former struct.

---

  drivers/tpm/tpm_tis_i2c.c | 52 +++++++++++++----------------------------------
  drivers/tpm/tpm_tis_i2c.h | 17 ++++++++++------
  2 files changed, 25 insertions(+), 44 deletions(-)
drivers/tpm/tpm_tis_i2c.c +14 -38
index 3c4e6c5..70d21ca 100644
@@ -34,9 +34,6 @@
 
  DECLARE_GLOBAL_DATA_PTR;
 
-/* Max buffer size supported by our tpm */
-#define TPM_DEV_BUFSIZE		1260
-
  /* Max number of iterations after i2c NAK */
  #define MAX_COUNT		3
 
@@ -78,12 +75,6 @@ enum tis_defaults {
  #define TPM_TIS_I2C_DID_VID_9635 0x000b15d1L
  #define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L
 
-enum i2c_chip_type {
-	SLB9635,
-	SLB9645,
-	UNKNOWN,
-};
-
  static const char * const chip_name[] = {
  	[SLB9635] = "slb9635tt",
  	[SLB9645] = "slb9645tt",
@@ -390,18 +381,8 @@ struct tpm {
  	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;
-	u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)];  /* Max buffer size + addr */
-	enum i2c_chip_type chip_type;
-};
-
-static struct tpm_dev tpm_dev;
-
  /*
   * iic_tpm_read() - read from TPM register
   * @addr: register address to read from
@@ -422,10 +403,10 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
  	int count;
  	uint32_t addrbuf = addr;
 
-	if ((tpm_dev.chip_type == SLB9635) || (tpm_dev.chip_type == UNKNOWN)) {
+	if ((g_chip.chip_type == SLB9635) || (g_chip.chip_type == UNKNOWN)) {
  		/* slb9635 protocol should work in both cases */
  		for (count = 0; count < MAX_COUNT; count++) {
-			rc = dm_i2c_write(tpm_dev.dev, 0, (uchar *)&addrbuf, 1);
+			rc = dm_i2c_write(g_chip.dev, 0, (uchar *)&addrbuf, 1);
  			if (rc == 0)
  				break;  /* Success, break to skip sleep */
  			udelay(SLEEP_DURATION);
@@ -439,7 +420,7 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
  		 */
  		for (count = 0; count < MAX_COUNT; count++) {
  			udelay(SLEEP_DURATION);
-			rc = dm_i2c_read(tpm_dev.dev, 0, buffer, len);
+			rc = dm_i2c_read(g_chip.dev, 0, buffer, len);
  			if (rc == 0)
  				break;  /* success, break to skip sleep */
  		}
@@ -452,7 +433,7 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
  		 * be safe on the safe side.
  		 */
  		for (count = 0; count < MAX_COUNT; count++) {
-			rc = dm_i2c_read(tpm_dev.dev, addr, buffer, len);
+			rc = dm_i2c_read(g_chip.dev, addr, buffer, len);
  			if (rc == 0)
  				break;  /* break here to skip sleep */
  			udelay(SLEEP_DURATION);
@@ -474,7 +455,7 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
  	int count;
 
  	for (count = 0; count < max_count; count++) {
-		rc = dm_i2c_write(tpm_dev.dev, addr, buffer, len);
+		rc = dm_i2c_write(g_chip.dev, addr, buffer, len);
  		if (rc == 0)
  			break;  /* Success, break to skip sleep */
  		udelay(sleep_time);
@@ -809,7 +790,7 @@ out_err:
  	return rc;
  }
 
-static enum i2c_chip_type tpm_vendor_chip_type(void)
+static enum i2c_chip_type tpm_tis_i2c_chip_type(void)
  {
  #ifdef CONFIG_OF_CONTROL
  	const void *blob = gd->fdt_blob;
@@ -823,14 +804,14 @@ static enum i2c_chip_type tpm_vendor_chip_type(void)
  	return UNKNOWN;
  }
 
-int tpm_vendor_init(struct udevice *dev)
+static int tpm_tis_i2c_init(struct udevice *dev)
  {
  	struct tpm_chip *chip = &g_chip;
  	u32 vendor;
  	u32 expected_did_vid;
 
-	tpm_dev.dev = dev;
-	tpm_dev.chip_type = tpm_vendor_chip_type();
+	g_chip.dev = dev;
+	g_chip.chip_type = tpm_tis_i2c_chip_type();
  	chip->is_open = 1;
 
  	/* Disable interrupts (not supported) */
@@ -854,7 +835,7 @@ int tpm_vendor_init(struct udevice *dev)
  		return -EIO;
  	}
 
-	if (tpm_dev.chip_type == SLB9635) {
+	if (g_chip.chip_type == SLB9635) {
  		vendor = be32_to_cpu(vendor);
  		expected_did_vid = TPM_TIS_I2C_DID_VID_9635;
  	} else {
@@ -862,13 +843,13 @@ int tpm_vendor_init(struct udevice *dev)
  		expected_did_vid = TPM_TIS_I2C_DID_VID_9645;
  	}
 
-	if (tpm_dev.chip_type != UNKNOWN && vendor != expected_did_vid) {
+	if (g_chip.chip_type != UNKNOWN && vendor != expected_did_vid) {
  		error("Vendor id did not match! ID was %08x\n", vendor);
  		return -ENODEV;
  	}
 
  	debug("1.2 TPM (chip type %s device-id 0x%X)\n",
-	      chip_name[tpm_dev.chip_type], vendor >> 16);
+	      chip_name[g_chip.chip_type], vendor >> 16);
 
  	/*
  	 * A timeout query to TPM can be placed here.
@@ -878,11 +859,6 @@ int tpm_vendor_init(struct udevice *dev)
  	return 0;
  }
 
-void tpm_vendor_cleanup(struct tpm_chip *chip)
-{
-	release_locality(chip, chip->locality, 1);
-}
-
  /* Returns max number of milliseconds to wait */
  static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
  		u32 ordinal)
@@ -980,7 +956,7 @@ static int tpm_open_dev(struct udevice *dev)
  	debug("%s: start\n", __func__);
  	if (g_chip.is_open)
  		return -EBUSY;
-	rc = tpm_vendor_init(dev);
+	rc = tpm_tis_i2c_init(dev);
  	if (rc < 0)
  		g_chip.is_open = 0;
  	return rc;
@@ -989,7 +965,7 @@ static int tpm_open_dev(struct udevice *dev)
  static void tpm_close(void)
  {
  	if (g_chip.is_open) {
-		tpm_vendor_cleanup(&g_chip);
+		release_locality(&g_chip, g_chip.locality, 1);
  		g_chip.is_open = 0;
  	}
  }
drivers/tpm/tpm_tis_i2c.h +11 -6
index 2a4ad77..0fec464 100644
@@ -33,7 +33,14 @@ enum tpm_timeout {
  #define TPM_RSP_SIZE_BYTE	2
  #define TPM_RSP_RC_BYTE		6
 
-struct tpm_chip;
+/* Max buffer size supported by our tpm */
+#define TPM_DEV_BUFSIZE		1260
+
+enum i2c_chip_type {
+	SLB9635,
+	SLB9645,
+	UNKNOWN,
+};
 
  struct tpm_chip {
  	int is_open;
@@ -44,6 +51,9 @@ struct tpm_chip {
  	int locality;
  	unsigned long timeout_a, timeout_b, timeout_c, timeout_d;  /* msec */
  	unsigned long duration[3];  /* msec */
+	struct udevice *dev;
+	u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)];  /* Max buffer size + addr */
+	enum i2c_chip_type chip_type;
  };
 
  struct tpm_input_header {
@@ -102,9 +112,4 @@ struct tpm_cmd_t {
  	union tpm_cmd_params params;
  } __packed;
 
-struct udevice;
-int tpm_vendor_init(struct udevice *dev);
-
-void tpm_vendor_cleanup(struct tpm_chip *chip);
-
  #endif
#29 lore raw

PATCH 10/25 tpm: tpm_tis_i2c: Merge struct tpm into tpm_chip

In reply to Simon Glass

There are too many structures storing the same sort of information. Move the fields from struct tpm into struct tpm_chip and remove the former struct.

---

 drivers/tpm/tpm_tis_i2c.c | 24 +++++++++---------------
 drivers/tpm/tpm_tis_i2c.h |  1 +
 2 files changed, 10 insertions(+), 15 deletions(-)
drivers/tpm/tpm_tis_i2c.c +9 -15
index 70d21ca..07150ec 100644
@@ -375,12 +375,6 @@ static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
 	TPM_MEDIUM,
 };
 
-/* TPM configuration */
-struct tpm {
-	struct udevice *dev;
-	char inited;
-} tpm;
-
 static struct tpm_chip g_chip;
 
 /*
@@ -976,7 +970,7 @@ static void tpm_close(void)
  * @param dev	Returns a configuration of TPM device
  * @return 0 if ok, -1 on error
  */
-static int tpm_decode_config(struct tpm *dev)
+static int tpm_decode_config(struct tpm_chip *chip)
 {
 	const void *blob = gd->fdt_blob;
 	struct udevice *bus;
@@ -1021,7 +1015,7 @@ static int tpm_decode_config(struct tpm *dev)
 	 * TODO(sjg at 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);
+	ret = i2c_get_chip(bus, chip_addr, 1, &chip->dev);
 	if (ret) {
 		debug("Cannot find device for node '%s: ret=%d'\n",
 		      fdt_get_name(blob, node, NULL), ret);
@@ -1033,15 +1027,15 @@ static int tpm_decode_config(struct tpm *dev)
 
 int tis_init(void)
 {
-	if (tpm.inited)
+	if (g_chip.inited)
 		return 0;
 
-	if (tpm_decode_config(&tpm))
+	if (tpm_decode_config(&g_chip))
 		return -1;
 
 	debug("%s: done\n", __func__);
 
-	tpm.inited = 1;
+	g_chip.inited = 1;
 
 	return 0;
 }
@@ -1050,17 +1044,17 @@ int tis_open(void)
 {
 	int rc;
 
-	if (!tpm.inited)
+	if (!g_chip.inited)
 		return -1;
 
-	rc = tpm_open_dev(tpm.dev);
+	rc = tpm_open_dev(g_chip.dev);
 
 	return rc;
 }
 
 int tis_close(void)
 {
-	if (!tpm.inited)
+	if (!g_chip.inited)
 		return -1;
 
 	tpm_close();
@@ -1074,7 +1068,7 @@ int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
 	int len;
 	uint8_t buf[4096];
 
-	if (!tpm.inited)
+	if (!g_chip.inited)
 		return -1;
 
 	if (sizeof(buf) < sbuf_size)
drivers/tpm/tpm_tis_i2c.h +1 -0
index 0fec464..161e63b 100644
@@ -43,6 +43,7 @@ enum i2c_chip_type {
 };
 
 struct tpm_chip {
+	bool inited;
 	int is_open;
 	u8 req_complete_mask;
 	u8 req_complete_val;
Signature · 1 line
2.5.0.rc2.392.g76e840b
#30 lore raw

PATCH 10/25 tpm: tpm_tis_i2c: Merge struct tpm into tpm_chip

Hi Simon,

I almost agree with this one. Except that here tis_init, tis_open... are already merged into tpm_tis_i2c...

Best Regards
Christophe

Quoted 106 lines · Simon Glass

There are too many structures storing the same sort of information. Move the fields from struct tpm into struct tpm_chip and remove the former struct.

---

  drivers/tpm/tpm_tis_i2c.c | 24 +++++++++---------------
  drivers/tpm/tpm_tis_i2c.h |  1 +
  2 files changed, 10 insertions(+), 15 deletions(-)
drivers/tpm/tpm_tis_i2c.c +9 -15
index 70d21ca..07150ec 100644
@@ -375,12 +375,6 @@ static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
  	TPM_MEDIUM,
  };
 
-/* TPM configuration */
-struct tpm {
-	struct udevice *dev;
-	char inited;
-} tpm;
-
  static struct tpm_chip g_chip;
 
  /*
@@ -976,7 +970,7 @@ static void tpm_close(void)
   * @param dev	Returns a configuration of TPM device
   * @return 0 if ok, -1 on error
   */
-static int tpm_decode_config(struct tpm *dev)
+static int tpm_decode_config(struct tpm_chip *chip)
  {
  	const void *blob = gd->fdt_blob;
  	struct udevice *bus;
@@ -1021,7 +1015,7 @@ static int tpm_decode_config(struct tpm *dev)
  	 * TODO(sjg at 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);
+	ret = i2c_get_chip(bus, chip_addr, 1, &chip->dev);
  	if (ret) {
  		debug("Cannot find device for node '%s: ret=%d'\n",
  		      fdt_get_name(blob, node, NULL), ret);
@@ -1033,15 +1027,15 @@ static int tpm_decode_config(struct tpm *dev)
 
  int tis_init(void)
  {
-	if (tpm.inited)
+	if (g_chip.inited)
  		return 0;
 
-	if (tpm_decode_config(&tpm))
+	if (tpm_decode_config(&g_chip))
  		return -1;
 
  	debug("%s: done\n", __func__);
 
-	tpm.inited = 1;
+	g_chip.inited = 1;
 
  	return 0;
  }
@@ -1050,17 +1044,17 @@ int tis_open(void)
  {
  	int rc;
 
-	if (!tpm.inited)
+	if (!g_chip.inited)
  		return -1;
 
-	rc = tpm_open_dev(tpm.dev);
+	rc = tpm_open_dev(g_chip.dev);
 
  	return rc;
  }
 
  int tis_close(void)
  {
-	if (!tpm.inited)
+	if (!g_chip.inited)
  		return -1;
 
  	tpm_close();
@@ -1074,7 +1068,7 @@ int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
  	int len;
  	uint8_t buf[4096];
 
-	if (!tpm.inited)
+	if (!g_chip.inited)
  		return -1;
 
  	if (sizeof(buf) < sbuf_size)
drivers/tpm/tpm_tis_i2c.h +1 -0
index 0fec464..161e63b 100644
@@ -43,6 +43,7 @@ enum i2c_chip_type {
  };
 
  struct tpm_chip {
+	bool inited;
  	int is_open;
  	u8 req_complete_mask;
  	u8 req_complete_val;
#31 lore raw

PATCH 11/25 tpm: tpm_tis_i2c: Move definitions into the header file

In reply to Simon Glass

Some definitions are in the C file and some are in the header file. Move everything into the header file for consistency and to reduce clutter.

---

 drivers/tpm/tpm_tis_i2c.c | 335 ----------------------------------------------
 drivers/tpm/tpm_tis_i2c.h | 335 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 335 insertions(+), 335 deletions(-)
drivers/tpm/tpm_tis_i2c.c +0 -335
index 07150ec..60d97d3 100644
@@ -34,347 +34,12 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* Max number of iterations after i2c NAK */
-#define MAX_COUNT		3
-
-/*
- * Max number of iterations after i2c NAK for 'long' commands
- *
- * We need this especially for sending TPM_READY, since the cleanup after the
- * transtion to the ready state may take some time, but it is unpredictable
- * how long it will take.
- */
-#define MAX_COUNT_LONG		50
-
-#define SLEEP_DURATION		60	/* in usec */
-#define SLEEP_DURATION_LONG	210	/* in usec */
-
-#define TPM_HEADER_SIZE		10
-
-enum tis_access {
-	TPM_ACCESS_VALID		= 0x80,
-	TPM_ACCESS_ACTIVE_LOCALITY	= 0x20,
-	TPM_ACCESS_REQUEST_PENDING	= 0x04,
-	TPM_ACCESS_REQUEST_USE		= 0x02,
-};
-
-enum tis_status {
-	TPM_STS_VALID			= 0x80,
-	TPM_STS_COMMAND_READY		= 0x40,
-	TPM_STS_GO			= 0x20,
-	TPM_STS_DATA_AVAIL		= 0x10,
-	TPM_STS_DATA_EXPECT		= 0x08,
-};
-
-enum tis_defaults {
-	TIS_SHORT_TIMEOUT		= 750,	/* ms */
-	TIS_LONG_TIMEOUT		= 2000,	/* ms */
-};
-
-/* expected value for DIDVID register */
-#define TPM_TIS_I2C_DID_VID_9635 0x000b15d1L
-#define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L
-
 static const char * const chip_name[] = {
 	[SLB9635] = "slb9635tt",
 	[SLB9645] = "slb9645tt",
 	[UNKNOWN] = "unknown/fallback to slb9635",
 };
 
-#define	TPM_ACCESS(l)			(0x0000 | ((l) << 4))
-#define	TPM_STS(l)			(0x0001 | ((l) << 4))
-#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,
-};
-
 static struct tpm_chip g_chip;
 
 /*
drivers/tpm/tpm_tis_i2c.h +335 -0

339 lines not on this page · raw message

Signature · 1 line
2.5.0.rc2.392.g76e840b
#32 lore raw

PATCH 11/25 tpm: tpm_tis_i2c: Move definitions into the header file

Hi Simon,

As per my previous comment, this file may be kept common to may other drivers (lpc or from ST...).
I would renamed tpm_tis_i2c.h into something more generic like tpm.h.

Below please find data specific to Infineon (tpm_tis_i2c) driver.

Quoted 15 lines · Simon Glass

Some definitions are in the C file and some are in the header file. Move everything into the header file for consistency and to reduce clutter.

---

  drivers/tpm/tpm_tis_i2c.c | 335 ----------------------------------------------
  drivers/tpm/tpm_tis_i2c.h | 335 ++++++++++++++++++++++++++++++++++++++++++++++
  2 files changed, 335 insertions(+), 335 deletions(-)
drivers/tpm/tpm_tis_i2c.c +0 -0
index 07150ec..60d97d3 100644

drivers/tpm/tpm_tis_i2c.c line 38

Quoted 5 lines
drivers/tpm/tpm_tis_i2c.c +0 -2
@@ -34,347 +34,12 @@
 
  DECLARE_GLOBAL_DATA_PTR;
 
-/* Max number of iterations after i2c NAK */
-#define MAX_COUNT		3

Specific to tpm_tis_i2c

drivers/tpm/tpm_tis_i2c.c line 49

Quoted 11 lines
drivers/tpm/tpm_tis_i2c.c +0 -11
-
-/*
- * Max number of iterations after i2c NAK for 'long' commands
- *
- * We need this especially for sending TPM_READY, since the cleanup after the
- * transtion to the ready state may take some time, but it is unpredictable
- * how long it will take.
- */
-#define MAX_COUNT_LONG		50
-
-#define SLEEP_DURATION		60	/* in usec */

Specific to tpm_tis_i2c

drivers/tpm/tpm_tis_i2c.c line 50

Quoted 1 line
drivers/tpm/tpm_tis_i2c.c +0 -1
-#define SLEEP_DURATION_LONG	210	/* in usec */

Specific to tpm_tis_i2c

Quoted 15 lines
drivers/tpm/tpm_tis_i2c.c +0 -15
-
-#define TPM_HEADER_SIZE		10
-
-enum tis_access {
-	TPM_ACCESS_VALID		= 0x80,
-	TPM_ACCESS_ACTIVE_LOCALITY	= 0x20,
-	TPM_ACCESS_REQUEST_PENDING	= 0x04,
-	TPM_ACCESS_REQUEST_USE		= 0x02,
-};
-
-enum tis_status {
-	TPM_STS_VALID			= 0x80,
-	TPM_STS_COMMAND_READY		= 0x40,
-	TPM_STS_GO			= 0x20,
-	TPM_STS_DATA_AVAIL		= 0x10,

drivers/tpm/tpm_tis_i2c.c line 75

Quoted 10 lines
drivers/tpm/tpm_tis_i2c.c +0 -10
-	TPM_STS_DATA_EXPECT		= 0x08,
-};
-
-enum tis_defaults {
-	TIS_SHORT_TIMEOUT		= 750,	/* ms */
-	TIS_LONG_TIMEOUT		= 2000,	/* ms */
-};
-
-/* expected value for DIDVID register */
-#define TPM_TIS_I2C_DID_VID_9635 0x000b15d1L

Specific to tpm_tis_i2c

drivers/tpm/tpm_tis_i2c.c line 77

Quoted 2 lines
drivers/tpm/tpm_tis_i2c.c +0 -2
-#define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L
-

Specific to tpm_tis_i2c

drivers/tpm/tpm_tis_i2c.c line 41

Quoted 5 lines
drivers/tpm/tpm_tis_i2c.c +0 -0
  static const char * const chip_name[] = {
  	[SLB9635] = "slb9635tt",
  	[SLB9645] = "slb9645tt",
  	[UNKNOWN] = "unknown/fallback to slb9635",
  };

Specific to tpm_tis_i2c

Quoted 631 lines
drivers/tpm/tpm_tis_i2c.c +0 -294
-#define	TPM_ACCESS(l)			(0x0000 | ((l) << 4))
-#define	TPM_STS(l)			(0x0001 | ((l) << 4))
-#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,
-};
-
  static struct tpm_chip g_chip;
 
  /*
drivers/tpm/tpm_tis_i2c.h +326 -0
index 161e63b..db99200 100644
@@ -113,4 +113,339 @@ struct tpm_cmd_t {
  	union tpm_cmd_params params;
  } __packed;
 
+/* Max number of iterations after i2c NAK */
+#define MAX_COUNT		3
+
+/*
+ * Max number of iterations after i2c NAK for 'long' commands
+ *
+ * We need this especially for sending TPM_READY, since the cleanup after the
+ * transtion to the ready state may take some time, but it is unpredictable
+ * how long it will take.
+ */
+#define MAX_COUNT_LONG		50
+
+#define SLEEP_DURATION		60	/* in usec */
+#define SLEEP_DURATION_LONG	210	/* in usec */
+
+#define TPM_HEADER_SIZE		10
+
+enum tis_access {
+	TPM_ACCESS_VALID		= 0x80,
+	TPM_ACCESS_ACTIVE_LOCALITY	= 0x20,
+	TPM_ACCESS_REQUEST_PENDING	= 0x04,
+	TPM_ACCESS_REQUEST_USE		= 0x02,
+};
+
+enum tis_status {
+	TPM_STS_VALID			= 0x80,
+	TPM_STS_COMMAND_READY		= 0x40,
+	TPM_STS_GO			= 0x20,
+	TPM_STS_DATA_AVAIL		= 0x10,
+	TPM_STS_DATA_EXPECT		= 0x08,
+};
+
+enum tis_defaults {
+	TIS_SHORT_TIMEOUT		= 750,	/* ms */
+	TIS_LONG_TIMEOUT		= 2000,	/* ms */
+};
+
+/* expected value for DIDVID register */
+#define TPM_TIS_I2C_DID_VID_9635 0x000b15d1L
+#define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L
+
+#define	TPM_ACCESS(l)			(0x0000 | ((l) << 4))
+#define	TPM_STS(l)			(0x0001 | ((l) << 4))
+#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 */

drivers/tpm/tpm_tis_i2c.h struct tpm_cmd_t { · line 451

Quoted 10 lines
drivers/tpm/tpm_tis_i2c.h +9 -0
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_UNDEFINED,
+	TPM_SHORT,		/* 240 */
+	TPM_UNDEFINED,
+	TPM_MEDIUM,
+};
+
  #endif

Best Regards
Christophe

#33 lore raw

PATCH 12/25 tpm: tpm_tis_i2c: Simplify init code

In reply to Simon Glass

Move all the init and uninit code into one place.

---

 drivers/tpm/tpm_tis_i2c.c | 33 ++++++++++-----------------------
 1 file changed, 10 insertions(+), 23 deletions(-)
drivers/tpm/tpm_tis_i2c.c +10 -23
index 60d97d3..329e8fc 100644
@@ -608,27 +608,6 @@ 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_tis_i2c_init(dev);
-	if (rc < 0)
-		g_chip.is_open = 0;
-	return rc;
-}
-
-static void tpm_close(void)
-{
-	if (g_chip.is_open) {
-		release_locality(&g_chip, g_chip.locality, 1);
-		g_chip.is_open = 0;
-	}
-}
-
 /**
  * Decode TPM configuration.
  *
@@ -712,7 +691,12 @@ int tis_open(void)
 	if (!g_chip.inited)
 		return -1;
 
-	rc = tpm_open_dev(g_chip.dev);
+	debug("%s: start\n", __func__);
+	if (g_chip.is_open)
+		return -EBUSY;
+	rc = tpm_tis_i2c_init(g_chip.dev);
+	if (rc < 0)
+		g_chip.is_open = 0;
 
 	return rc;
 }
@@ -722,7 +706,10 @@ int tis_close(void)
 	if (!g_chip.inited)
 		return -1;
 
-	tpm_close();
+	if (g_chip.is_open) {
+		release_locality(&g_chip, g_chip.locality, 1);
+		g_chip.is_open = 0;
+	}
 
 	return 0;
 }
Signature · 1 line
2.5.0.rc2.392.g76e840b
#34 lore raw

PATCH 12/25 tpm: tpm_tis_i2c: Simplify init code

Hi Simon,

Nothing much to say on tpm_tis_i2c, however this could be even more generic if providing init ops to be specified by TPM driver developers. For example:

+struct dm_tpm_ops {
+ int (*init)(struct udevice *);
+ int (*open)(struct udevice *);
+ int (*close)(struct udevice *);
+ int (*sendrecv)(struct udevice *,
+ const uint8_t *, size_t,
+ uint8_t *, size_t *);
+};

I tried to propose a structure like this one in
http://lists.denx.de/pipermail/u-boot/2015-August/222598.html very closed to yours when moving to DM.
I would just add the init handler.

Best Regards
Christophe

Quoted 66 lines · Simon Glass

Move all the init and uninit code into one place.

---

  drivers/tpm/tpm_tis_i2c.c | 33 ++++++++++-----------------------
  1 file changed, 10 insertions(+), 23 deletions(-)
drivers/tpm/tpm_tis_i2c.c +10 -23
index 60d97d3..329e8fc 100644
@@ -608,27 +608,6 @@ 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_tis_i2c_init(dev);
-	if (rc < 0)
-		g_chip.is_open = 0;
-	return rc;
-}
-
-static void tpm_close(void)
-{
-	if (g_chip.is_open) {
-		release_locality(&g_chip, g_chip.locality, 1);
-		g_chip.is_open = 0;
-	}
-}
-
  /**
   * Decode TPM configuration.
   *
@@ -712,7 +691,12 @@ int tis_open(void)
  	if (!g_chip.inited)
  		return -1;
 
-	rc = tpm_open_dev(g_chip.dev);
+	debug("%s: start\n", __func__);
+	if (g_chip.is_open)
+		return -EBUSY;
+	rc = tpm_tis_i2c_init(g_chip.dev);
+	if (rc < 0)
+		g_chip.is_open = 0;
 
  	return rc;
  }
@@ -722,7 +706,10 @@ int tis_close(void)
  	if (!g_chip.inited)
  		return -1;
 
-	tpm_close();
+	if (g_chip.is_open) {
+		release_locality(&g_chip, g_chip.locality, 1);
+		g_chip.is_open = 0;
+	}
 
  	return 0;
  }
#35 lore raw

PATCH 13/25 tpm: tpm_tis_i2c: Use a consistent tpm_tis_i2c_ prefix

In reply to Simon Glass

Use the same prefix on each function for consistency.

---

 drivers/tpm/tpm_tis_i2c.c | 113 ++++++++++++++++++++++++----------------------
 1 file changed, 58 insertions(+), 55 deletions(-)
drivers/tpm/tpm_tis_i2c.c +58 -55
index 329e8fc..f3d615c 100644
@@ -43,7 +43,7 @@ static const char * const chip_name[] = {
 static struct tpm_chip g_chip;
 
 /*
- * iic_tpm_read() - read from TPM register
+ * tpm_tis_i2c_read() - read from TPM register
  * @addr: register address to read from
  * @buffer: provided by caller
  * @len: number of bytes to read
@@ -56,7 +56,7 @@ static struct tpm_chip g_chip;
  *
  * Return -EIO on error, 0 on success.
  */
-static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
+static int tpm_tis_i2c_read(u8 addr, u8 *buffer, size_t len)
 {
 	int rc;
 	int count;
@@ -107,8 +107,8 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
 	return 0;
 }
 
-static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
-		unsigned int sleep_time, u8 max_count)
+static int tpm_tis_i2c_write_generic(u8 addr, u8 *buffer, size_t len,
+				     unsigned int sleep_time, u8 max_count)
 {
 	int rc = 0;
 	int count;
@@ -129,7 +129,7 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
 }
 
 /*
- * iic_tpm_write() - write to TPM register
+ * tpm_tis_i2c_write() - write to TPM register
  * @addr: register address to write to
  * @buffer: containing data to be written
  * @len: number of bytes to write
@@ -140,13 +140,13 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
  * NOTE: TPM is big-endian for multi-byte values. Multi-byte
  * values have to be swapped.
  *
- * NOTE: use this function instead of the iic_tpm_write_generic function.
+ * NOTE: use this function instead of the tpm_tis_i2c_write_generic function.
  *
  * Return -EIO on error, 0 on success
  */
-static int iic_tpm_write(u8 addr, u8 *buffer, size_t len)
+static int tpm_tis_i2c_write(u8 addr, u8 *buffer, size_t len)
 {
-	return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION,
+	return tpm_tis_i2c_write_generic(addr, buffer, len, SLEEP_DURATION,
 			MAX_COUNT);
 }
 
@@ -154,19 +154,19 @@ static int iic_tpm_write(u8 addr, u8 *buffer, size_t len)
  * This function is needed especially for the cleanup situation after
  * sending TPM_READY
  */
-static int iic_tpm_write_long(u8 addr, u8 *buffer, size_t len)
+static int tpm_tis_i2c_write_long(u8 addr, u8 *buffer, size_t len)
 {
-	return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LONG,
+	return tpm_tis_i2c_write_generic(addr, buffer, len, SLEEP_DURATION_LONG,
 			MAX_COUNT_LONG);
 }
 
-static int check_locality(struct tpm_chip *chip, int loc)
+static int tpm_tis_i2c_check_locality(struct tpm_chip *chip, int loc)
 {
 	const u8 mask = TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID;
 	u8 buf;
 	int rc;
 
-	rc = iic_tpm_read(TPM_ACCESS(loc), &buf, 1);
+	rc = tpm_tis_i2c_read(TPM_ACCESS(loc), &buf, 1);
 	if (rc < 0)
 		return rc;
 
@@ -178,30 +178,31 @@ static int check_locality(struct tpm_chip *chip, int loc)
 	return -1;
 }
 
-static void release_locality(struct tpm_chip *chip, int loc, int force)
+static void tpm_tis_i2c_release_locality(struct tpm_chip *chip, int loc,
+					 int force)
 {
 	const u8 mask = TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID;
 	u8 buf;
 
-	if (iic_tpm_read(TPM_ACCESS(loc), &buf, 1) < 0)
+	if (tpm_tis_i2c_read(TPM_ACCESS(loc), &buf, 1) < 0)
 		return;
 
 	if (force || (buf & mask) == mask) {
 		buf = TPM_ACCESS_ACTIVE_LOCALITY;
-		iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
+		tpm_tis_i2c_write(TPM_ACCESS(loc), &buf, 1);
 	}
 }
 
-static int request_locality(struct tpm_chip *chip, int loc)
+static int tpm_tis_i2c_request_locality(struct tpm_chip *chip, int loc)
 {
 	unsigned long start, stop;
 	u8 buf = TPM_ACCESS_REQUEST_USE;
 	int rc;
 
-	if (check_locality(chip, loc) >= 0)
+	if (tpm_tis_i2c_check_locality(chip, loc) >= 0)
 		return loc;  /* We already have the locality */
 
-	rc = iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
+	rc = tpm_tis_i2c_write(TPM_ACCESS(loc), &buf, 1);
 	if (rc)
 		return rc;
 
@@ -209,7 +210,7 @@ static int request_locality(struct tpm_chip *chip, int loc)
 	start = get_timer(0);
 	stop = chip->timeout_a;
 	do {
-		if (check_locality(chip, loc) >= 0)
+		if (tpm_tis_i2c_check_locality(chip, loc) >= 0)
 			return loc;
 		udelay(TPM_TIMEOUT * 1000);
 	} while (get_timer(start) < stop);
@@ -222,7 +223,7 @@ static u8 tpm_tis_i2c_status(struct tpm_chip *chip)
 	/* NOTE: Since i2c read may fail, return 0 in this case --> time-out */
 	u8 buf;
 
-	if (iic_tpm_read(TPM_STS(chip->locality), &buf, 1) < 0)
+	if (tpm_tis_i2c_read(TPM_STS(chip->locality), &buf, 1) < 0)
 		return 0;
 	else
 		return buf;
@@ -236,12 +237,12 @@ static void tpm_tis_i2c_ready(struct tpm_chip *chip)
 	u8 buf = TPM_STS_COMMAND_READY;
 
 	debug("%s\n", __func__);
-	rc = iic_tpm_write_long(TPM_STS(chip->locality), &buf, 1);
+	rc = tpm_tis_i2c_write_long(TPM_STS(chip->locality), &buf, 1);
 	if (rc)
 		debug("%s: rc=%d\n", __func__, rc);
 }
 
-static ssize_t get_burstcount(struct tpm_chip *chip)
+static ssize_t tpm_tis_i2c_get_burstcount(struct tpm_chip *chip)
 {
 	unsigned long start, stop;
 	ssize_t burstcnt;
@@ -254,7 +255,7 @@ static ssize_t get_burstcount(struct tpm_chip *chip)
 	do {
 		/* Note: STS is little endian */
 		addr = TPM_STS(chip->locality) + 1;
-		if (iic_tpm_read(addr, buf, 3) < 0)
+		if (tpm_tis_i2c_read(addr, buf, 3) < 0)
 			burstcnt = 0;
 		else
 			burstcnt = (buf[2] << 16) + (buf[1] << 8) + buf[0];
@@ -267,8 +268,8 @@ static ssize_t get_burstcount(struct tpm_chip *chip)
 	return -EBUSY;
 }
 
-static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
-		int *status)
+static int tpm_tis_i2c_wait_for_stat(struct tpm_chip *chip, u8 mask,
+				     unsigned long timeout, int *status)
 {
 	unsigned long start, stop;
 
@@ -289,14 +290,14 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
 	return -ETIME;
 }
 
-static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
+static int tpm_tis_i2c_recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
 {
 	size_t size = 0;
 	ssize_t burstcnt;
 	int rc;
 
 	while (size < count) {
-		burstcnt = get_burstcount(chip);
+		burstcnt = tpm_tis_i2c_get_burstcount(chip);
 
 		/* burstcount < 0 -> tpm is busy */
 		if (burstcnt < 0)
@@ -306,7 +307,7 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
 		if (burstcnt > (count - size))
 			burstcnt = count - size;
 
-		rc = iic_tpm_read(TPM_DATA_FIFO(chip->locality),
+		rc = tpm_tis_i2c_read(TPM_DATA_FIFO(chip->locality),
 				&(buf[size]), burstcnt);
 		if (rc == 0)
 			size += burstcnt;
@@ -326,7 +327,7 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 	}
 
 	/* Read first 10 bytes, including tag, paramsize, and result */
-	size = recv_data(chip, buf, TPM_HEADER_SIZE);
+	size = tpm_tis_i2c_recv_data(chip, buf, TPM_HEADER_SIZE);
 	if (size < TPM_HEADER_SIZE) {
 		error("Unable to read header\n");
 		goto out;
@@ -340,15 +341,16 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 		goto out;
 	}
 
-	size += recv_data(chip, &buf[TPM_HEADER_SIZE],
-			expected - TPM_HEADER_SIZE);
+	size += tpm_tis_i2c_recv_data(chip, &buf[TPM_HEADER_SIZE],
+				      expected - TPM_HEADER_SIZE);
 	if (size < expected) {
 		error("Unable to read remainder of result\n");
 		size = -ETIME;
 		goto out;
 	}
 
-	wait_for_stat(chip, TPM_STS_VALID, chip->timeout_c, &status);
+	tpm_tis_i2c_wait_for_stat(chip, TPM_STS_VALID, chip->timeout_c,
+				  &status);
 	if (status & TPM_STS_DATA_AVAIL) {  /* Retry? */
 		error("Error left over data\n");
 		size = -EIO;
@@ -362,7 +364,7 @@ out:
 	 * so we sleep rather than keeping the bus busy
 	 */
 	udelay(2000);
-	release_locality(chip, chip->locality, 0);
+	tpm_tis_i2c_release_locality(chip, chip->locality, 0);
 
 	return size;
 }
@@ -379,20 +381,20 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
 	if (len > TPM_DEV_BUFSIZE)
 		return -E2BIG;  /* Command is too long for our tpm, sorry */
 
-	if (request_locality(chip, 0) < 0)
+	if (tpm_tis_i2c_request_locality(chip, 0) < 0)
 		return -EBUSY;
 
 	status = tpm_tis_i2c_status(chip);
 	if ((status & TPM_STS_COMMAND_READY) == 0) {
 		tpm_tis_i2c_ready(chip);
-		if (wait_for_stat(chip, TPM_STS_COMMAND_READY,
-				  chip->timeout_b, &status) < 0) {
+		if (tpm_tis_i2c_wait_for_stat(chip, TPM_STS_COMMAND_READY,
+					      chip->timeout_b, &status) < 0) {
 			rc = -ETIME;
 			goto out_err;
 		}
 	}
 
-	burstcnt = get_burstcount(chip);
+	burstcnt = tpm_tis_i2c_get_burstcount(chip);
 
 	/* burstcount < 0 -> tpm is busy */
 	if (burstcnt < 0)
@@ -408,7 +410,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
 			burstcnt = CONFIG_TPM_TIS_I2C_BURST_LIMITATION;
 #endif /* CONFIG_TPM_TIS_I2C_BURST_LIMITATION */
 
-		rc = iic_tpm_write(TPM_DATA_FIFO(chip->locality),
+		rc = tpm_tis_i2c_write(TPM_DATA_FIFO(chip->locality),
 				&(buf[count]), burstcnt);
 		if (rc == 0)
 			count += burstcnt;
@@ -418,8 +420,9 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
 				rc = -EIO;
 				goto out_err;
 			}
-			rc = wait_for_stat(chip, TPM_STS_VALID,
-					   chip->timeout_c, &status);
+			rc = tpm_tis_i2c_wait_for_stat(chip, TPM_STS_VALID,
+						       chip->timeout_c,
+						       &status);
 			if (rc)
 				goto out_err;
 
@@ -431,7 +434,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
 	}
 
 	/* Go and do it */
-	iic_tpm_write(TPM_STS(chip->locality), &sts, 1);
+	tpm_tis_i2c_write(TPM_STS(chip->locality), &sts, 1);
 	debug("done\n");
 
 	return len;
@@ -444,7 +447,7 @@ out_err:
 	 * so we sleep rather than keeping the bus busy
 	 */
 	udelay(2000);
-	release_locality(chip, chip->locality, 0);
+	tpm_tis_i2c_release_locality(chip, chip->locality, 0);
 
 	return rc;
 }
@@ -476,7 +479,7 @@ static int tpm_tis_i2c_init(struct udevice *dev)
 	/* Disable interrupts (not supported) */
 	chip->irq = 0;
 
-	/* Default timeouts */
+	/* Default timeouts - these could move to the device tree */
 	chip->timeout_a = TIS_SHORT_TIMEOUT;
 	chip->timeout_b = TIS_LONG_TIMEOUT;
 	chip->timeout_c = TIS_SHORT_TIMEOUT;
@@ -485,12 +488,12 @@ static int tpm_tis_i2c_init(struct udevice *dev)
 	chip->req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID;
 	chip->req_canceled = TPM_STS_COMMAND_READY;
 
-	if (request_locality(chip, 0) < 0)
+	if (tpm_tis_i2c_request_locality(chip, 0) < 0)
 		return  -ENODEV;
 
 	/* Read four bytes from DID_VID register */
-	if (iic_tpm_read(TPM_DID_VID(0), (uchar *)&vendor, 4) < 0) {
-		release_locality(chip, 0, 1);
+	if (tpm_tis_i2c_read(TPM_DID_VID(0), (uchar *)&vendor, 4) < 0) {
+		tpm_tis_i2c_release_locality(chip, 0, 1);
 		return -EIO;
 	}
 
@@ -519,8 +522,8 @@ static int tpm_tis_i2c_init(struct udevice *dev)
 }
 
 /* Returns max number of milliseconds to wait */
-static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
-		u32 ordinal)
+static unsigned long tpm_tis_i2c_calc_ordinal_duration(struct tpm_chip *chip,
+						       u32 ordinal)
 {
 	int duration_idx = TPM_UNDEFINED;
 	int duration = 0;
@@ -542,7 +545,7 @@ static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
 		return duration;
 }
 
-static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
+static ssize_t tpm_tis_i2c_transmit(const unsigned char *buf, size_t bufsiz)
 {
 	int rc;
 	u32 count, ordinal;
@@ -575,7 +578,7 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
 		goto out_recv;
 
 	start = get_timer(0);
-	stop = tpm_calc_ordinal_duration(chip, ordinal);
+	stop = tpm_tis_i2c_calc_ordinal_duration(chip, ordinal);
 	do {
 		debug("waiting for status... %ld %ld\n", start, stop);
 		u8 status = tpm_tis_i2c_status(chip);
@@ -614,7 +617,7 @@ out:
  * @param dev	Returns a configuration of TPM device
  * @return 0 if ok, -1 on error
  */
-static int tpm_decode_config(struct tpm_chip *chip)
+static int tpm_tis_i2c_decode_config(struct tpm_chip *chip)
 {
 	const void *blob = gd->fdt_blob;
 	struct udevice *bus;
@@ -657,7 +660,7 @@ static int tpm_decode_config(struct tpm_chip *chip)
 	}
 	/*
 	 * TODO(sjg at chromium.org): Older TPMs will need to use the older method
-	 * in iic_tpm_read() so the offset length needs to be 0 here.
+	 * in tpm_tis_i2c_read() so the offset length needs to be 0 here.
 	 */
 	ret = i2c_get_chip(bus, chip_addr, 1, &chip->dev);
 	if (ret) {
@@ -674,7 +677,7 @@ int tis_init(void)
 	if (g_chip.inited)
 		return 0;
 
-	if (tpm_decode_config(&g_chip))
+	if (tpm_tis_i2c_decode_config(&g_chip))
 		return -1;
 
 	debug("%s: done\n", __func__);
@@ -707,7 +710,7 @@ int tis_close(void)
 		return -1;
 
 	if (g_chip.is_open) {
-		release_locality(&g_chip, g_chip.locality, 1);
+		tpm_tis_i2c_release_locality(&g_chip, g_chip.locality, 1);
 		g_chip.is_open = 0;
 	}
 
@@ -728,7 +731,7 @@ int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
 
 	memcpy(buf, sendbuf, sbuf_size);
 
-	len = tpm_transmit(buf, sbuf_size);
+	len = tpm_tis_i2c_transmit(buf, sbuf_size);
 
 	if (len < 10) {
 		*rbuf_len = 0;
Signature · 1 line
2.5.0.rc2.392.g76e840b
#36 lore raw

PATCH 13/25 tpm: tpm_tis_i2c: Use a consistent tpm_tis_i2c_ prefix

Hi Simon,

Best Regards
Christophe

Quoted 409 lines · Simon Glass

Use the same prefix on each function for consistency.

---

  drivers/tpm/tpm_tis_i2c.c | 113 ++++++++++++++++++++++++----------------------
  1 file changed, 58 insertions(+), 55 deletions(-)
drivers/tpm/tpm_tis_i2c.c +58 -55
index 329e8fc..f3d615c 100644
@@ -43,7 +43,7 @@ static const char * const chip_name[] = {
  static struct tpm_chip g_chip;
 
  /*
- * iic_tpm_read() - read from TPM register
+ * tpm_tis_i2c_read() - read from TPM register
   * @addr: register address to read from
   * @buffer: provided by caller
   * @len: number of bytes to read
@@ -56,7 +56,7 @@ static struct tpm_chip g_chip;
   *
   * Return -EIO on error, 0 on success.
   */
-static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
+static int tpm_tis_i2c_read(u8 addr, u8 *buffer, size_t len)
  {
  	int rc;
  	int count;
@@ -107,8 +107,8 @@ static int iic_tpm_read(u8 addr, u8 *buffer, size_t len)
  	return 0;
  }
 
-static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
-		unsigned int sleep_time, u8 max_count)
+static int tpm_tis_i2c_write_generic(u8 addr, u8 *buffer, size_t len,
+				     unsigned int sleep_time, u8 max_count)
  {
  	int rc = 0;
  	int count;
@@ -129,7 +129,7 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
  }
 
  /*
- * iic_tpm_write() - write to TPM register
+ * tpm_tis_i2c_write() - write to TPM register
   * @addr: register address to write to
   * @buffer: containing data to be written
   * @len: number of bytes to write
@@ -140,13 +140,13 @@ static int iic_tpm_write_generic(u8 addr, u8 *buffer, size_t len,
   * NOTE: TPM is big-endian for multi-byte values. Multi-byte
   * values have to be swapped.
   *
- * NOTE: use this function instead of the iic_tpm_write_generic function.
+ * NOTE: use this function instead of the tpm_tis_i2c_write_generic function.
   *
   * Return -EIO on error, 0 on success
   */
-static int iic_tpm_write(u8 addr, u8 *buffer, size_t len)
+static int tpm_tis_i2c_write(u8 addr, u8 *buffer, size_t len)
  {
-	return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION,
+	return tpm_tis_i2c_write_generic(addr, buffer, len, SLEEP_DURATION,
  			MAX_COUNT);
  }
 
@@ -154,19 +154,19 @@ static int iic_tpm_write(u8 addr, u8 *buffer, size_t len)
   * This function is needed especially for the cleanup situation after
   * sending TPM_READY
   */
-static int iic_tpm_write_long(u8 addr, u8 *buffer, size_t len)
+static int tpm_tis_i2c_write_long(u8 addr, u8 *buffer, size_t len)
  {
-	return iic_tpm_write_generic(addr, buffer, len, SLEEP_DURATION_LONG,
+	return tpm_tis_i2c_write_generic(addr, buffer, len, SLEEP_DURATION_LONG,
  			MAX_COUNT_LONG);
  }
 
-static int check_locality(struct tpm_chip *chip, int loc)
+static int tpm_tis_i2c_check_locality(struct tpm_chip *chip, int loc)
  {
  	const u8 mask = TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID;
  	u8 buf;
  	int rc;
 
-	rc = iic_tpm_read(TPM_ACCESS(loc), &buf, 1);
+	rc = tpm_tis_i2c_read(TPM_ACCESS(loc), &buf, 1);
  	if (rc < 0)
  		return rc;
 
@@ -178,30 +178,31 @@ static int check_locality(struct tpm_chip *chip, int loc)
  	return -1;
  }
 
-static void release_locality(struct tpm_chip *chip, int loc, int force)
+static void tpm_tis_i2c_release_locality(struct tpm_chip *chip, int loc,
+					 int force)
  {
  	const u8 mask = TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID;
  	u8 buf;
 
-	if (iic_tpm_read(TPM_ACCESS(loc), &buf, 1) < 0)
+	if (tpm_tis_i2c_read(TPM_ACCESS(loc), &buf, 1) < 0)
  		return;
 
  	if (force || (buf & mask) == mask) {
  		buf = TPM_ACCESS_ACTIVE_LOCALITY;
-		iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
+		tpm_tis_i2c_write(TPM_ACCESS(loc), &buf, 1);
  	}
  }
 
-static int request_locality(struct tpm_chip *chip, int loc)
+static int tpm_tis_i2c_request_locality(struct tpm_chip *chip, int loc)
  {
  	unsigned long start, stop;
  	u8 buf = TPM_ACCESS_REQUEST_USE;
  	int rc;
 
-	if (check_locality(chip, loc) >= 0)
+	if (tpm_tis_i2c_check_locality(chip, loc) >= 0)
  		return loc;  /* We already have the locality */
 
-	rc = iic_tpm_write(TPM_ACCESS(loc), &buf, 1);
+	rc = tpm_tis_i2c_write(TPM_ACCESS(loc), &buf, 1);
  	if (rc)
  		return rc;
 
@@ -209,7 +210,7 @@ static int request_locality(struct tpm_chip *chip, int loc)
  	start = get_timer(0);
  	stop = chip->timeout_a;
  	do {
-		if (check_locality(chip, loc) >= 0)
+		if (tpm_tis_i2c_check_locality(chip, loc) >= 0)
  			return loc;
  		udelay(TPM_TIMEOUT * 1000);
  	} while (get_timer(start) < stop);
@@ -222,7 +223,7 @@ static u8 tpm_tis_i2c_status(struct tpm_chip *chip)
  	/* NOTE: Since i2c read may fail, return 0 in this case --> time-out */
  	u8 buf;
 
-	if (iic_tpm_read(TPM_STS(chip->locality), &buf, 1) < 0)
+	if (tpm_tis_i2c_read(TPM_STS(chip->locality), &buf, 1) < 0)
  		return 0;
  	else
  		return buf;
@@ -236,12 +237,12 @@ static void tpm_tis_i2c_ready(struct tpm_chip *chip)
  	u8 buf = TPM_STS_COMMAND_READY;
 
  	debug("%s\n", __func__);
-	rc = iic_tpm_write_long(TPM_STS(chip->locality), &buf, 1);
+	rc = tpm_tis_i2c_write_long(TPM_STS(chip->locality), &buf, 1);
  	if (rc)
  		debug("%s: rc=%d\n", __func__, rc);
  }
 
-static ssize_t get_burstcount(struct tpm_chip *chip)
+static ssize_t tpm_tis_i2c_get_burstcount(struct tpm_chip *chip)
  {
  	unsigned long start, stop;
  	ssize_t burstcnt;
@@ -254,7 +255,7 @@ static ssize_t get_burstcount(struct tpm_chip *chip)
  	do {
  		/* Note: STS is little endian */
  		addr = TPM_STS(chip->locality) + 1;
-		if (iic_tpm_read(addr, buf, 3) < 0)
+		if (tpm_tis_i2c_read(addr, buf, 3) < 0)
  			burstcnt = 0;
  		else
  			burstcnt = (buf[2] << 16) + (buf[1] << 8) + buf[0];
@@ -267,8 +268,8 @@ static ssize_t get_burstcount(struct tpm_chip *chip)
  	return -EBUSY;
  }
 
-static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
-		int *status)
+static int tpm_tis_i2c_wait_for_stat(struct tpm_chip *chip, u8 mask,
+				     unsigned long timeout, int *status)
  {
  	unsigned long start, stop;
 
@@ -289,14 +290,14 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
  	return -ETIME;
  }
 
-static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
+static int tpm_tis_i2c_recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
  {
  	size_t size = 0;
  	ssize_t burstcnt;
  	int rc;
 
  	while (size < count) {
-		burstcnt = get_burstcount(chip);
+		burstcnt = tpm_tis_i2c_get_burstcount(chip);
 
  		/* burstcount < 0 -> tpm is busy */
  		if (burstcnt < 0)
@@ -306,7 +307,7 @@ static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
  		if (burstcnt > (count - size))
  			burstcnt = count - size;
 
-		rc = iic_tpm_read(TPM_DATA_FIFO(chip->locality),
+		rc = tpm_tis_i2c_read(TPM_DATA_FIFO(chip->locality),
  				&(buf[size]), burstcnt);
  		if (rc == 0)
  			size += burstcnt;
@@ -326,7 +327,7 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
  	}
 
  	/* Read first 10 bytes, including tag, paramsize, and result */
-	size = recv_data(chip, buf, TPM_HEADER_SIZE);
+	size = tpm_tis_i2c_recv_data(chip, buf, TPM_HEADER_SIZE);
  	if (size < TPM_HEADER_SIZE) {
  		error("Unable to read header\n");
  		goto out;
@@ -340,15 +341,16 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
  		goto out;
  	}
 
-	size += recv_data(chip, &buf[TPM_HEADER_SIZE],
-			expected - TPM_HEADER_SIZE);
+	size += tpm_tis_i2c_recv_data(chip, &buf[TPM_HEADER_SIZE],
+				      expected - TPM_HEADER_SIZE);
  	if (size < expected) {
  		error("Unable to read remainder of result\n");
  		size = -ETIME;
  		goto out;
  	}
 
-	wait_for_stat(chip, TPM_STS_VALID, chip->timeout_c, &status);
+	tpm_tis_i2c_wait_for_stat(chip, TPM_STS_VALID, chip->timeout_c,
+				  &status);
  	if (status & TPM_STS_DATA_AVAIL) {  /* Retry? */
  		error("Error left over data\n");
  		size = -EIO;
@@ -362,7 +364,7 @@ out:
  	 * so we sleep rather than keeping the bus busy
  	 */
  	udelay(2000);
-	release_locality(chip, chip->locality, 0);
+	tpm_tis_i2c_release_locality(chip, chip->locality, 0);
 
  	return size;
  }
@@ -379,20 +381,20 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
  	if (len > TPM_DEV_BUFSIZE)
  		return -E2BIG;  /* Command is too long for our tpm, sorry */
 
-	if (request_locality(chip, 0) < 0)
+	if (tpm_tis_i2c_request_locality(chip, 0) < 0)
  		return -EBUSY;
 
  	status = tpm_tis_i2c_status(chip);
  	if ((status & TPM_STS_COMMAND_READY) == 0) {
  		tpm_tis_i2c_ready(chip);
-		if (wait_for_stat(chip, TPM_STS_COMMAND_READY,
-				  chip->timeout_b, &status) < 0) {
+		if (tpm_tis_i2c_wait_for_stat(chip, TPM_STS_COMMAND_READY,
+					      chip->timeout_b, &status) < 0) {
  			rc = -ETIME;
  			goto out_err;
  		}
  	}
 
-	burstcnt = get_burstcount(chip);
+	burstcnt = tpm_tis_i2c_get_burstcount(chip);
 
  	/* burstcount < 0 -> tpm is busy */
  	if (burstcnt < 0)
@@ -408,7 +410,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
  			burstcnt = CONFIG_TPM_TIS_I2C_BURST_LIMITATION;
  #endif /* CONFIG_TPM_TIS_I2C_BURST_LIMITATION */
 
-		rc = iic_tpm_write(TPM_DATA_FIFO(chip->locality),
+		rc = tpm_tis_i2c_write(TPM_DATA_FIFO(chip->locality),
  				&(buf[count]), burstcnt);
  		if (rc == 0)
  			count += burstcnt;
@@ -418,8 +420,9 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
  				rc = -EIO;
  				goto out_err;
  			}
-			rc = wait_for_stat(chip, TPM_STS_VALID,
-					   chip->timeout_c, &status);
+			rc = tpm_tis_i2c_wait_for_stat(chip, TPM_STS_VALID,
+						       chip->timeout_c,
+						       &status);
  			if (rc)
  				goto out_err;
 
@@ -431,7 +434,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
  	}
 
  	/* Go and do it */
-	iic_tpm_write(TPM_STS(chip->locality), &sts, 1);
+	tpm_tis_i2c_write(TPM_STS(chip->locality), &sts, 1);
  	debug("done\n");
 
  	return len;
@@ -444,7 +447,7 @@ out_err:
  	 * so we sleep rather than keeping the bus busy
  	 */
  	udelay(2000);
-	release_locality(chip, chip->locality, 0);
+	tpm_tis_i2c_release_locality(chip, chip->locality, 0);
 
  	return rc;
  }
@@ -476,7 +479,7 @@ static int tpm_tis_i2c_init(struct udevice *dev)
  	/* Disable interrupts (not supported) */
  	chip->irq = 0;
 
-	/* Default timeouts */
+	/* Default timeouts - these could move to the device tree */
  	chip->timeout_a = TIS_SHORT_TIMEOUT;
  	chip->timeout_b = TIS_LONG_TIMEOUT;
  	chip->timeout_c = TIS_SHORT_TIMEOUT;
@@ -485,12 +488,12 @@ static int tpm_tis_i2c_init(struct udevice *dev)
  	chip->req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID;
  	chip->req_canceled = TPM_STS_COMMAND_READY;
 
-	if (request_locality(chip, 0) < 0)
+	if (tpm_tis_i2c_request_locality(chip, 0) < 0)
  		return  -ENODEV;
 
  	/* Read four bytes from DID_VID register */
-	if (iic_tpm_read(TPM_DID_VID(0), (uchar *)&vendor, 4) < 0) {
-		release_locality(chip, 0, 1);
+	if (tpm_tis_i2c_read(TPM_DID_VID(0), (uchar *)&vendor, 4) < 0) {
+		tpm_tis_i2c_release_locality(chip, 0, 1);
  		return -EIO;
  	}
 
@@ -519,8 +522,8 @@ static int tpm_tis_i2c_init(struct udevice *dev)
  }
 
  /* Returns max number of milliseconds to wait */
-static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
-		u32 ordinal)
+static unsigned long tpm_tis_i2c_calc_ordinal_duration(struct tpm_chip *chip,
+						       u32 ordinal)
  {
  	int duration_idx = TPM_UNDEFINED;
  	int duration = 0;
@@ -542,7 +545,7 @@ static unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
  		return duration;
  }
 
-static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
+static ssize_t tpm_tis_i2c_transmit(const unsigned char *buf, size_t bufsiz)
  {
  	int rc;
  	u32 count, ordinal;
@@ -575,7 +578,7 @@ static ssize_t tpm_transmit(const unsigned char *buf, size_t bufsiz)
  		goto out_recv;
 
  	start = get_timer(0);
-	stop = tpm_calc_ordinal_duration(chip, ordinal);
+	stop = tpm_tis_i2c_calc_ordinal_duration(chip, ordinal);
  	do {
  		debug("waiting for status... %ld %ld\n", start, stop);
  		u8 status = tpm_tis_i2c_status(chip);
@@ -614,7 +617,7 @@ out:
   * @param dev	Returns a configuration of TPM device
   * @return 0 if ok, -1 on error
   */
-static int tpm_decode_config(struct tpm_chip *chip)
+static int tpm_tis_i2c_decode_config(struct tpm_chip *chip)
  {
  	const void *blob = gd->fdt_blob;
  	struct udevice *bus;
@@ -657,7 +660,7 @@ static int tpm_decode_config(struct tpm_chip *chip)
  	}
  	/*
  	 * TODO(sjg at chromium.org): Older TPMs will need to use the older method
-	 * in iic_tpm_read() so the offset length needs to be 0 here.
+	 * in tpm_tis_i2c_read() so the offset length needs to be 0 here.
  	 */
  	ret = i2c_get_chip(bus, chip_addr, 1, &chip->dev);
  	if (ret) {
@@ -674,7 +677,7 @@ int tis_init(void)
  	if (g_chip.inited)
  		return 0;
 
-	if (tpm_decode_config(&g_chip))
+	if (tpm_tis_i2c_decode_config(&g_chip))
  		return -1;
 
  	debug("%s: done\n", __func__);
@@ -707,7 +710,7 @@ int tis_close(void)
  		return -1;
 
  	if (g_chip.is_open) {
-		release_locality(&g_chip, g_chip.locality, 1);
+		tpm_tis_i2c_release_locality(&g_chip, g_chip.locality, 1);
  		g_chip.is_open = 0;
  	}
 
@@ -728,7 +731,7 @@ int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
 
  	memcpy(buf, sendbuf, sbuf_size);
 
-	len = tpm_transmit(buf, sbuf_size);
+	len = tpm_tis_i2c_transmit(buf, sbuf_size);
 
  	if (len < 10) {
  		*rbuf_len = 0;
#37 lore raw

PATCH 14/25 tpm: tpm_tis_i2c: Tidy up delays

In reply to Simon Glass

Use a _US suffix for microseconds and a _MS suffic for milliseconds. Move all timeouts and delays into one place. Use mdelay() instead of udelay() where appropriate.

---

 drivers/tpm/tpm_tis_i2c.c | 43 ++++++++++++++++++++++---------------------
 drivers/tpm/tpm_tis_i2c.h | 16 ++++++----------
 2 files changed, 28 insertions(+), 31 deletions(-)
drivers/tpm/tpm_tis_i2c.c +22 -21
index f3d615c..f1ad596 100644
@@ -68,7 +68,7 @@ static int tpm_tis_i2c_read(u8 addr, u8 *buffer, size_t len)
 			rc = dm_i2c_write(g_chip.dev, 0, (uchar *)&addrbuf, 1);
 			if (rc == 0)
 				break;  /* Success, break to skip sleep */
-			udelay(SLEEP_DURATION);
+			udelay(SLEEP_DURATION_US);
 		}
 		if (rc)
 			return -rc;
@@ -78,7 +78,7 @@ static int tpm_tis_i2c_read(u8 addr, u8 *buffer, size_t len)
 		 * retrieving the data
 		 */
 		for (count = 0; count < MAX_COUNT; count++) {
-			udelay(SLEEP_DURATION);
+			udelay(SLEEP_DURATION_US);
 			rc = dm_i2c_read(g_chip.dev, 0, buffer, len);
 			if (rc == 0)
 				break;  /* success, break to skip sleep */
@@ -95,12 +95,12 @@ static int tpm_tis_i2c_read(u8 addr, u8 *buffer, size_t len)
 			rc = dm_i2c_read(g_chip.dev, addr, buffer, len);
 			if (rc == 0)
 				break;  /* break here to skip sleep */
-			udelay(SLEEP_DURATION);
+			udelay(SLEEP_DURATION_US);
 		}
 	}
 
 	/* Take care of 'guard time' */
-	udelay(SLEEP_DURATION);
+	udelay(SLEEP_DURATION_US);
 	if (rc)
 		return -rc;
 
@@ -108,7 +108,7 @@ static int tpm_tis_i2c_read(u8 addr, u8 *buffer, size_t len)
 }
 
 static int tpm_tis_i2c_write_generic(u8 addr, u8 *buffer, size_t len,
-				     unsigned int sleep_time, u8 max_count)
+				     unsigned int sleep_time_us, u8 max_count)
 {
 	int rc = 0;
 	int count;
@@ -117,11 +117,11 @@ static int tpm_tis_i2c_write_generic(u8 addr, u8 *buffer, size_t len,
 		rc = dm_i2c_write(g_chip.dev, addr, buffer, len);
 		if (rc == 0)
 			break;  /* Success, break to skip sleep */
-		udelay(sleep_time);
+		udelay(sleep_time_us);
 	}
 
 	/* take care of 'guard time' */
-	udelay(sleep_time);
+	udelay(sleep_time_us);
 	if (rc)
 		return -rc;
 
@@ -146,8 +146,8 @@ static int tpm_tis_i2c_write_generic(u8 addr, u8 *buffer, size_t len,
  */
 static int tpm_tis_i2c_write(u8 addr, u8 *buffer, size_t len)
 {
-	return tpm_tis_i2c_write_generic(addr, buffer, len, SLEEP_DURATION,
-			MAX_COUNT);
+	return tpm_tis_i2c_write_generic(addr, buffer, len, SLEEP_DURATION_US,
+					 MAX_COUNT);
 }
 
 /*
@@ -156,8 +156,9 @@ static int tpm_tis_i2c_write(u8 addr, u8 *buffer, size_t len)
  */
 static int tpm_tis_i2c_write_long(u8 addr, u8 *buffer, size_t len)
 {
-	return tpm_tis_i2c_write_generic(addr, buffer, len, SLEEP_DURATION_LONG,
-			MAX_COUNT_LONG);
+	return tpm_tis_i2c_write_generic(addr, buffer, len,
+					 SLEEP_DURATION_LONG_US,
+					 MAX_COUNT_LONG);
 }
 
 static int tpm_tis_i2c_check_locality(struct tpm_chip *chip, int loc)
@@ -212,7 +213,7 @@ static int tpm_tis_i2c_request_locality(struct tpm_chip *chip, int loc)
 	do {
 		if (tpm_tis_i2c_check_locality(chip, loc) >= 0)
 			return loc;
-		udelay(TPM_TIMEOUT * 1000);
+		mdelay(TPM_TIMEOUT_MS);
 	} while (get_timer(start) < stop);
 
 	return -1;
@@ -262,7 +263,7 @@ static ssize_t tpm_tis_i2c_get_burstcount(struct tpm_chip *chip)
 
 		if (burstcnt)
 			return burstcnt;
-		udelay(TPM_TIMEOUT * 1000);
+		mdelay(TPM_TIMEOUT_MS);
 	} while (get_timer(start) < stop);
 
 	return -EBUSY;
@@ -281,7 +282,7 @@ static int tpm_tis_i2c_wait_for_stat(struct tpm_chip *chip, u8 mask,
 	start = get_timer(0);
 	stop = timeout;
 	do {
-		udelay(TPM_TIMEOUT * 1000);
+		mdelay(TPM_TIMEOUT_MS);
 		*status = tpm_tis_i2c_status(chip);
 		if ((*status & mask) == mask)
 			return 0;
@@ -363,7 +364,7 @@ out:
 	 * The TPM needs some time to clean up here,
 	 * so we sleep rather than keeping the bus busy
 	 */
-	udelay(2000);
+	mdelay(2);
 	tpm_tis_i2c_release_locality(chip, chip->locality, 0);
 
 	return size;
@@ -446,7 +447,7 @@ out_err:
 	 * The TPM needs some time to clean up here,
 	 * so we sleep rather than keeping the bus busy
 	 */
-	udelay(2000);
+	mdelay(2);
 	tpm_tis_i2c_release_locality(chip, chip->locality, 0);
 
 	return rc;
@@ -480,10 +481,10 @@ static int tpm_tis_i2c_init(struct udevice *dev)
 	chip->irq = 0;
 
 	/* Default timeouts - these could move to the device tree */
-	chip->timeout_a = TIS_SHORT_TIMEOUT;
-	chip->timeout_b = TIS_LONG_TIMEOUT;
-	chip->timeout_c = TIS_SHORT_TIMEOUT;
-	chip->timeout_d = TIS_SHORT_TIMEOUT;
+	chip->timeout_a = TIS_SHORT_TIMEOUT_MS;
+	chip->timeout_b = TIS_LONG_TIMEOUT_MS;
+	chip->timeout_c = TIS_SHORT_TIMEOUT_MS;
+	chip->timeout_d = TIS_SHORT_TIMEOUT_MS;
 	chip->req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID;
 	chip->req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID;
 	chip->req_canceled = TPM_STS_COMMAND_READY;
@@ -593,7 +594,7 @@ static ssize_t tpm_tis_i2c_transmit(const unsigned char *buf, size_t bufsiz)
 			rc = -ECANCELED;
 			goto out;
 		}
-		udelay(TPM_TIMEOUT * 1000);
+		mdelay(TPM_TIMEOUT_MS);
 	} while (get_timer(start) < stop);
 
 	tpm_tis_i2c_ready(chip);
drivers/tpm/tpm_tis_i2c.h +6 -10
index db99200..ecdaf0c 100644
@@ -23,7 +23,11 @@
 #include <linux/types.h>
 
 enum tpm_timeout {
-	TPM_TIMEOUT = 5,	/* msecs */
+	TPM_TIMEOUT_MS			= 5,
+	TIS_SHORT_TIMEOUT_MS		= 750,
+	TIS_LONG_TIMEOUT_MS		= 2000,
+	SLEEP_DURATION_US		= 60,
+	SLEEP_DURATION_LONG_US		= 210,
 };
 
 /* Size of external transmit buffer (used in tpm_transmit)*/
@@ -125,9 +129,6 @@ struct tpm_cmd_t {
  */
 #define MAX_COUNT_LONG		50
 
-#define SLEEP_DURATION		60	/* in usec */
-#define SLEEP_DURATION_LONG	210	/* in usec */
-
 #define TPM_HEADER_SIZE		10
 
 enum tis_access {
@@ -145,11 +146,6 @@ enum tis_status {
 	TPM_STS_DATA_EXPECT		= 0x08,
 };
 
-enum tis_defaults {
-	TIS_SHORT_TIMEOUT		= 750,	/* ms */
-	TIS_LONG_TIMEOUT		= 2000,	/* ms */
-};
-
 /* expected value for DIDVID register */
 #define TPM_TIS_I2C_DID_VID_9635 0x000b15d1L
 #define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L
@@ -169,7 +165,7 @@ enum tpm_duration {
 /* Extended error numbers from linux (see errno.h) */
 #define ECANCELED	125	/* Operation Canceled */
 
-/* Timer frequency. Corresponds to msec timer resolution*/
+/* Timer frequency. Corresponds to msec timer resolution */
 #define HZ		1000
 
 #define TPM_MAX_ORDINAL			243
Signature · 1 line
2.5.0.rc2.392.g76e840b
#38 lore raw

PATCH 14/25 tpm: tpm_tis_i2c: Tidy up delays

Hi Simon,

Best Regards
Christophe

Quoted 211 lines · Simon Glass

Use a _US suffix for microseconds and a _MS suffic for milliseconds. Move all timeouts and delays into one place. Use mdelay() instead of udelay() where appropriate.

---

  drivers/tpm/tpm_tis_i2c.c | 43 ++++++++++++++++++++++---------------------
  drivers/tpm/tpm_tis_i2c.h | 16 ++++++----------
  2 files changed, 28 insertions(+), 31 deletions(-)
drivers/tpm/tpm_tis_i2c.c +22 -21
index f3d615c..f1ad596 100644
@@ -68,7 +68,7 @@ static int tpm_tis_i2c_read(u8 addr, u8 *buffer, size_t len)
  			rc = dm_i2c_write(g_chip.dev, 0, (uchar *)&addrbuf, 1);
  			if (rc == 0)
  				break;  /* Success, break to skip sleep */
-			udelay(SLEEP_DURATION);
+			udelay(SLEEP_DURATION_US);
  		}
  		if (rc)
  			return -rc;
@@ -78,7 +78,7 @@ static int tpm_tis_i2c_read(u8 addr, u8 *buffer, size_t len)
  		 * retrieving the data
  		 */
  		for (count = 0; count < MAX_COUNT; count++) {
-			udelay(SLEEP_DURATION);
+			udelay(SLEEP_DURATION_US);
  			rc = dm_i2c_read(g_chip.dev, 0, buffer, len);
  			if (rc == 0)
  				break;  /* success, break to skip sleep */
@@ -95,12 +95,12 @@ static int tpm_tis_i2c_read(u8 addr, u8 *buffer, size_t len)
  			rc = dm_i2c_read(g_chip.dev, addr, buffer, len);
  			if (rc == 0)
  				break;  /* break here to skip sleep */
-			udelay(SLEEP_DURATION);
+			udelay(SLEEP_DURATION_US);
  		}
  	}
 
  	/* Take care of 'guard time' */
-	udelay(SLEEP_DURATION);
+	udelay(SLEEP_DURATION_US);
  	if (rc)
  		return -rc;
 
@@ -108,7 +108,7 @@ static int tpm_tis_i2c_read(u8 addr, u8 *buffer, size_t len)
  }
 
  static int tpm_tis_i2c_write_generic(u8 addr, u8 *buffer, size_t len,
-				     unsigned int sleep_time, u8 max_count)
+				     unsigned int sleep_time_us, u8 max_count)
  {
  	int rc = 0;
  	int count;
@@ -117,11 +117,11 @@ static int tpm_tis_i2c_write_generic(u8 addr, u8 *buffer, size_t len,
  		rc = dm_i2c_write(g_chip.dev, addr, buffer, len);
  		if (rc == 0)
  			break;  /* Success, break to skip sleep */
-		udelay(sleep_time);
+		udelay(sleep_time_us);
  	}
 
  	/* take care of 'guard time' */
-	udelay(sleep_time);
+	udelay(sleep_time_us);
  	if (rc)
  		return -rc;
 
@@ -146,8 +146,8 @@ static int tpm_tis_i2c_write_generic(u8 addr, u8 *buffer, size_t len,
   */
  static int tpm_tis_i2c_write(u8 addr, u8 *buffer, size_t len)
  {
-	return tpm_tis_i2c_write_generic(addr, buffer, len, SLEEP_DURATION,
-			MAX_COUNT);
+	return tpm_tis_i2c_write_generic(addr, buffer, len, SLEEP_DURATION_US,
+					 MAX_COUNT);
  }
 
  /*
@@ -156,8 +156,9 @@ static int tpm_tis_i2c_write(u8 addr, u8 *buffer, size_t len)
   */
  static int tpm_tis_i2c_write_long(u8 addr, u8 *buffer, size_t len)
  {
-	return tpm_tis_i2c_write_generic(addr, buffer, len, SLEEP_DURATION_LONG,
-			MAX_COUNT_LONG);
+	return tpm_tis_i2c_write_generic(addr, buffer, len,
+					 SLEEP_DURATION_LONG_US,
+					 MAX_COUNT_LONG);
  }
 
  static int tpm_tis_i2c_check_locality(struct tpm_chip *chip, int loc)
@@ -212,7 +213,7 @@ static int tpm_tis_i2c_request_locality(struct tpm_chip *chip, int loc)
  	do {
  		if (tpm_tis_i2c_check_locality(chip, loc) >= 0)
  			return loc;
-		udelay(TPM_TIMEOUT * 1000);
+		mdelay(TPM_TIMEOUT_MS);
  	} while (get_timer(start) < stop);
 
  	return -1;
@@ -262,7 +263,7 @@ static ssize_t tpm_tis_i2c_get_burstcount(struct tpm_chip *chip)
 
  		if (burstcnt)
  			return burstcnt;
-		udelay(TPM_TIMEOUT * 1000);
+		mdelay(TPM_TIMEOUT_MS);
  	} while (get_timer(start) < stop);
 
  	return -EBUSY;
@@ -281,7 +282,7 @@ static int tpm_tis_i2c_wait_for_stat(struct tpm_chip *chip, u8 mask,
  	start = get_timer(0);
  	stop = timeout;
  	do {
-		udelay(TPM_TIMEOUT * 1000);
+		mdelay(TPM_TIMEOUT_MS);
  		*status = tpm_tis_i2c_status(chip);
  		if ((*status & mask) == mask)
  			return 0;
@@ -363,7 +364,7 @@ out:
  	 * The TPM needs some time to clean up here,
  	 * so we sleep rather than keeping the bus busy
  	 */
-	udelay(2000);
+	mdelay(2);
  	tpm_tis_i2c_release_locality(chip, chip->locality, 0);
 
  	return size;
@@ -446,7 +447,7 @@ out_err:
  	 * The TPM needs some time to clean up here,
  	 * so we sleep rather than keeping the bus busy
  	 */
-	udelay(2000);
+	mdelay(2);
  	tpm_tis_i2c_release_locality(chip, chip->locality, 0);
 
  	return rc;
@@ -480,10 +481,10 @@ static int tpm_tis_i2c_init(struct udevice *dev)
  	chip->irq = 0;
 
  	/* Default timeouts - these could move to the device tree */
-	chip->timeout_a = TIS_SHORT_TIMEOUT;
-	chip->timeout_b = TIS_LONG_TIMEOUT;
-	chip->timeout_c = TIS_SHORT_TIMEOUT;
-	chip->timeout_d = TIS_SHORT_TIMEOUT;
+	chip->timeout_a = TIS_SHORT_TIMEOUT_MS;
+	chip->timeout_b = TIS_LONG_TIMEOUT_MS;
+	chip->timeout_c = TIS_SHORT_TIMEOUT_MS;
+	chip->timeout_d = TIS_SHORT_TIMEOUT_MS;
  	chip->req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID;
  	chip->req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID;
  	chip->req_canceled = TPM_STS_COMMAND_READY;
@@ -593,7 +594,7 @@ static ssize_t tpm_tis_i2c_transmit(const unsigned char *buf, size_t bufsiz)
  			rc = -ECANCELED;
  			goto out;
  		}
-		udelay(TPM_TIMEOUT * 1000);
+		mdelay(TPM_TIMEOUT_MS);
  	} while (get_timer(start) < stop);
 
  	tpm_tis_i2c_ready(chip);
drivers/tpm/tpm_tis_i2c.h +6 -10
index db99200..ecdaf0c 100644
@@ -23,7 +23,11 @@
  #include <linux/types.h>
 
  enum tpm_timeout {
-	TPM_TIMEOUT = 5,	/* msecs */
+	TPM_TIMEOUT_MS			= 5,
+	TIS_SHORT_TIMEOUT_MS		= 750,
+	TIS_LONG_TIMEOUT_MS		= 2000,
+	SLEEP_DURATION_US		= 60,
+	SLEEP_DURATION_LONG_US		= 210,
  };
 
  /* Size of external transmit buffer (used in tpm_transmit)*/
@@ -125,9 +129,6 @@ struct tpm_cmd_t {
   */
  #define MAX_COUNT_LONG		50
 
-#define SLEEP_DURATION		60	/* in usec */
-#define SLEEP_DURATION_LONG	210	/* in usec */
-
  #define TPM_HEADER_SIZE		10
 
  enum tis_access {
@@ -145,11 +146,6 @@ enum tis_status {
  	TPM_STS_DATA_EXPECT		= 0x08,
  };
 
-enum tis_defaults {
-	TIS_SHORT_TIMEOUT		= 750,	/* ms */
-	TIS_LONG_TIMEOUT		= 2000,	/* ms */
-};
-
  /* expected value for DIDVID register */
  #define TPM_TIS_I2C_DID_VID_9635 0x000b15d1L
  #define TPM_TIS_I2C_DID_VID_9645 0x001a15d1L
@@ -169,7 +165,7 @@ enum tpm_duration {
  /* Extended error numbers from linux (see errno.h) */
  #define ECANCELED	125	/* Operation Canceled */
 
-/* Timer frequency. Corresponds to msec timer resolution*/
+/* Timer frequency. Corresponds to msec timer resolution */
  #define HZ		1000
 
  #define TPM_MAX_ORDINAL			243
#39 lore raw

PATCH 15/25 dm: tpm: Add a uclass for Trusted Platform Modules

In reply to Simon Glass

Add a new uclass for TPMs which uses almost the same TIS (TPM Interface Specification) as is currently implemented. Since init() is handled by the normal driver model probe() method, we don't need to implement that. Also rename the transfer method to xfer() which is a less clumbsy name.

Once all drivers and users are converted to driver model we can remove the old code.

---

 drivers/tpm/Kconfig      |  9 +++++
 drivers/tpm/Makefile     |  2 +
 drivers/tpm/tpm-uclass.c | 57 ++++++++++++++++++++++++++++
 include/dm/uclass-id.h   |  1 +
 include/tis.h            | 97 ++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 166 insertions(+)
 create mode 100644 drivers/tpm/tpm-uclass.c
drivers/tpm/Kconfig +9 -0
index 993d2d7..800239e 100644
@@ -1,3 +1,12 @@
+config DM_TPM
+	bool "Enable driver model for Trusted Platform Module drivers"
+	depends on DM && TPM
+	help
+          Enable driver model for TPMs. The TIS interface (tis_open(),
+	  tis_sendrecv(), etc.) is then implemented by the TPM uclass. Note
+	  that even with driver model only a single TPM is currently
+	  supported, since the tpm library assumes this.
+
 config TPM_TIS_SANDBOX
 	bool "Enable sandbox TPM driver"
 	depends on SANDBOX
drivers/tpm/Makefile +2 -0
index 597966c..0d328f8 100644
@@ -3,6 +3,8 @@
 # SPDX-License-Identifier:	GPL-2.0+
 #
 
+obj-$(CONFIG_DM_TPM) += tpm-uclass.o
+
 obj-$(CONFIG_TPM_ATMEL_TWI) += tpm_atmel_twi.o
 obj-$(CONFIG_TPM_TIS_I2C) += tpm_tis_i2c.o
 obj-$(CONFIG_TPM_TIS_LPC) += tpm_tis_lpc.o
drivers/tpm/tpm-uclass.c new file +57 -0

57 lines not on this page · raw message

include/dm/uclass-id.h +1 -0
index c744044..3eff895 100644
@@ -54,6 +54,7 @@ enum uclass_id {
 	UCLASS_SPI_GENERIC,	/* Generic SPI flash target */
 	UCLASS_SYSCON,		/* System configuration device */
 	UCLASS_THERMAL,		/* Thermal sensor */
+	UCLASS_TPM,		/* Trusted Platform Module TIS interface */
 	UCLASS_USB,		/* USB bus */
 	UCLASS_USB_DEV_GENERIC,	/* USB generic device */
 	UCLASS_USB_HUB,		/* USB hub */
include/tis.h +97 -0

108 lines not on this page · raw message

Signature · 1 line
2.5.0.rc2.392.g76e840b
#40 lore raw

PATCH 15/25 dm: tpm: Add a uclass for Trusted Platform Modules

Hi Simon,

I think we are pretty inline for the uclass.
Please find below some few remarks.

Quoted 96 lines · Simon Glass

Add a new uclass for TPMs which uses almost the same TIS (TPM Interface Specification) as is currently implemented. Since init() is handled by the normal driver model probe() method, we don't need to implement that. Also rename the transfer method to xfer() which is a less clumbsy name.

Once all drivers and users are converted to driver model we can remove the old code.

---

  drivers/tpm/Kconfig      |  9 +++++
  drivers/tpm/Makefile     |  2 +
  drivers/tpm/tpm-uclass.c | 57 ++++++++++++++++++++++++++++
  include/dm/uclass-id.h   |  1 +
  include/tis.h            | 97 ++++++++++++++++++++++++++++++++++++++++++++++++
  5 files changed, 166 insertions(+)

create mode 100644 drivers/tpm/tpm-uclass.c

drivers/tpm/Kconfig +9 -0
index 993d2d7..800239e 100644
@@ -1,3 +1,12 @@
+config DM_TPM
+	bool "Enable driver model for Trusted Platform Module drivers"
+	depends on DM && TPM
+	help
+          Enable driver model for TPMs. The TIS interface (tis_open(),
+	  tis_sendrecv(), etc.) is then implemented by the TPM uclass. Note
+	  that even with driver model only a single TPM is currently
+	  supported, since the tpm library assumes this.
+
  config TPM_TIS_SANDBOX
  	bool "Enable sandbox TPM driver"
  	depends on SANDBOX
drivers/tpm/Makefile +2 -0
index 597966c..0d328f8 100644
@@ -3,6 +3,8 @@
  # SPDX-License-Identifier:	GPL-2.0+
  #
 
+obj-$(CONFIG_DM_TPM) += tpm-uclass.o
+
  obj-$(CONFIG_TPM_ATMEL_TWI) += tpm_atmel_twi.o
  obj-$(CONFIG_TPM_TIS_I2C) += tpm_tis_i2c.o
  obj-$(CONFIG_TPM_TIS_LPC) += tpm_tis_lpc.o
drivers/tpm/tpm-uclass.c new file +41 -0
new file mode 100644
index 0000000..ccade5b
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <tis.h>
+
+int tis_open(struct udevice *dev)
+{
+	struct tpm_ops *ops = tpm_get_ops(dev);
+
+	if (!ops->open)
+		return -ENOSYS;
+
+	return ops->open(dev);
+}
+
+int tis_close(struct udevice *dev)
+{
+	struct tpm_ops *ops = tpm_get_ops(dev);
+
+	if (!ops->close)
+		return -ENOSYS;
+
+	return ops->close(dev);
+}
+
+int tis_get_desc(struct udevice *dev, char *buf, int size)
+{
+	struct tpm_ops *ops = tpm_get_ops(dev);
+
+	if (!ops->get_desc)
+		return -ENOSYS;
+
+	return ops->get_desc(dev, buf, size);
+}
+

drivers/tpm/tpm-uclass.c line 51

Quoted 10 lines
drivers/tpm/tpm-uclass.c new file +10 -0
+int tis_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size,
+	uint8_t *recvbuf, size_t *recv_size)
+{
+	struct tpm_ops *ops = tpm_get_ops(dev);
+
+	if (!ops->xfer)
+		return -ENOSYS;
+
+	return ops->xfer(dev, sendbuf, send_size, recvbuf, recv_size);
+}

tis_xfer could be more generic and rely on tpm_transmit from original tpm.c. The command duration could be calculated at probe time during driver initialisation running one single getcapability command.

Quoted 23 lines
drivers/tpm/tpm-uclass.c new file +6 -0
+
+UCLASS_DRIVER(tpm) = {
+	.id             = UCLASS_TPM,
+	.name           = "tpm",
+	.flags          = DM_UC_FLAG_SEQ_ALIAS,
+};
include/dm/uclass-id.h +1 -0
index c744044..3eff895 100644
@@ -54,6 +54,7 @@ enum uclass_id {
  	UCLASS_SPI_GENERIC,	/* Generic SPI flash target */
  	UCLASS_SYSCON,		/* System configuration device */
  	UCLASS_THERMAL,		/* Thermal sensor */
+	UCLASS_TPM,		/* Trusted Platform Module TIS interface */
  	UCLASS_USB,		/* USB bus */
  	UCLASS_USB_DEV_GENERIC,	/* USB generic device */
  	UCLASS_USB_HUB,		/* USB hub */
include/tis.h +0 -0
index 40a1f86..6620554 100644

include/tis.h line 11

Quoted 5 lines
include/tis.h +2 -0
@@ -7,6 +7,102 @@
  #ifndef __TIS_H
  #define __TIS_H
 
+#ifdef CONFIG_DM_TPM
+struct tpm_ops {

As per a previous comment, an init handler could be usefull.

Quoted 39 lines
include/tis.h +39 -0
+	/**
+	 * open() - Request access to locality 0 for the caller
+	 *
+	 * After all commands have been completed the caller should call
+	 * tis_close().
+	 *
+	 * @dev:	Device to close
+	 * @return 0 ok OK, -ve on error
+	 */
+	int (*open)(struct udevice *dev);
+
+	/**
+	 * tis_close() - Close the current session
+	 *
+	 * Releasing the locked locality. Returns 0 on success, -ve 1 on
+	 * failure (in case lock removal did not succeed).
+	 *
+	 * @dev:	Device to close
+	 * @return 0 ok OK, -ve on error
+	 */
+	int (*close)(struct udevice *dev);
+
+	/**
+	 * get_desc() - Get a text description of the TPM
+	 *
+	 * @dev:	Device to check
+	 * @buf:	Buffer to put the string
+	 * @size:	Maximum size of buffer
+	 * @return length of string, or -ENOSPC it no space
+	 */
+	int (*get_desc)(struct udevice *dev, char *buf, int size);
+
+	/**
+	 * xfer() - send data to the TPM and get response
+	 *
+	 * @dev:	Device to talk to
+	 * @sendbuf:	Buffer of the data to send
+	 * @send_size:	Size of the data to send
+	 * @recvbuf:	Buffer to save the response to

include/tis.h line 60

Quoted 10 lines
include/tis.h +10 -0
+	 * @recv_size:	Pointer to the size of the response buffer
+	 *
+	 * Returns 0 on success (and places the number of response bytes at
+	 * recv_size) or -ve on failure.
+	 */
+	int (*xfer)(struct udevice *dev, const uint8_t *sendbuf,
+		    size_t send_size, uint8_t *recvbuf, size_t *recv_size);
+};
+
+#define tpm_get_ops(dev)        ((struct tpm_ops *)(dev)->driver->ops)

why not device_get_ops(dev) ?

Quoted 33 lines
include/tis.h +33 -0
+
+/*
+ * open() - Request access to locality 0 for the caller
+ *
+ * After all commands have been completed the caller is supposed to
+ * call tis_close().
+ *
+ * Returns 0 on success, -ve on failure.
+ */
+int tis_open(struct udevice *dev);
+
+/*
+ * tis_close() - Close the current session
+ *
+ * Releasing the locked locality. Returns 0 on success, -ve 1 on
+ * failure (in case lock removal did not succeed).
+ */
+int tis_close(struct udevice *dev);
+
+/**
+ * tis_get_desc() - Get a text description of the TPM
+ *
+ * @dev:	Device to check
+ * @buf:	Buffer to put the string
+ * @size:	Maximum size of buffer
+ * @return length of string, or -ENOSPC it no space
+ */
+int tis_get_desc(struct udevice *dev, char *buf, int size);
+
+/*
+ * tis_sendrecv() - send data to the TPM and get response
+ *
+ * @sendbuf - buffer of the data to send

include/tis.h line 103

Quoted 10 lines
include/tis.h +10 -0
+ * @send_size size of the data to send
+ * @recvbuf - memory to save the response to
+ * @recv_len - pointer to the size of the response buffer
+ *
+ * Returns 0 on success (and places the number of response bytes at
+ * recv_len) or -ve on failure.
+ */
+int tis_xfer(struct udevice *dev, const uint8_t *sendbuf, size_t send_size,
+	     uint8_t *recvbuf, size_t *recv_size);
+

As at the moment there is a 1 - 1 link with TPM and a platform, are you sure udevice should be a parameter ?

include/tis.h int tis_close(void); · line 154

Quoted 12 lines
include/tis.h +3 -0
+#else
+
  #include <common.h>
 
  /* Low-level interface to access TPM */
@@ -53,5 +149,6 @@ int tis_close(void);
   */
  int tis_sendrecv(const uint8_t *sendbuf, size_t send_size, uint8_t *recvbuf,
  			size_t *recv_len);
+#endif
 
  #endif /* __TIS_H */

Best Regards
Christophe

#41 lore raw

PATCH 16/25 dm: tpm: Convert the TPM command and library to driver model

In reply to Simon Glass

Add driver model support to the TPM command and the TPM library. Both support only a single TPM at present.

---

 common/cmd_tpm.c | 26 ++++++++++++++++++++++++++
 include/tpm.h    |  2 +-
 lib/tpm.c        | 29 +++++++++++++++++++++++++----
 3 files changed, 52 insertions(+), 5 deletions(-)
common/cmd_tpm.c +26 -0
index 0294952..274e3cd 100644
@@ -6,6 +6,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <dm.h>
 #include <malloc.h>
 #include <tpm.h>
 #include <asm/unaligned.h>
@@ -438,6 +439,21 @@ TPM_COMMAND_NO_ARG(tpm_force_clear)
 TPM_COMMAND_NO_ARG(tpm_physical_enable)
 TPM_COMMAND_NO_ARG(tpm_physical_disable)
 
+#ifdef CONFIG_DM_TPM
+static int get_tpm(struct udevice **devp)
+{
+	int rc;
+
+	rc = uclass_first_device(UCLASS_TPM, devp);
+	if (rc) {
+		printf("Could not find TPM (ret=%d)\n", rc);
+		return CMD_RET_FAILURE;
+	}
+
+	return 0;
+}
+#endif
+
 static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag,
 		int argc, char * const argv[])
 {
@@ -452,7 +468,17 @@ static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag,
 		return CMD_RET_FAILURE;
 	}
 
+#ifdef CONFIG_DM_TPM
+	struct udevice *dev;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
+
+	rc = tis_xfer(dev, command, count, response, &response_length);
+#else
 	rc = tis_sendrecv(command, count, response, &response_length);
+#endif
 	free(command);
 	if (!rc) {
 		puts("tpm response:\n");
include/tpm.h +1 -1
index 88aeba2..9a0f87c 100644
@@ -157,7 +157,7 @@ enum tpm_return_code {
  *
  * @return 0 on success, non-0 on error.
  */
-uint32_t tpm_init(void);
+int tpm_init(void);
 
 /**
  * Issue a TPM_Startup command.
lib/tpm.c +25 -4
index d9789b0..9e2cc77 100644
@@ -6,10 +6,11 @@
  */
 
 #include <common.h>
-#include <stdarg.h>
-#include <u-boot/sha1.h>
+#include <dm.h>
+#include <tis.h>
 #include <tpm.h>
 #include <asm/unaligned.h>
+#include <u-boot/sha1.h>
 
 /* Internal error of TPM command library */
 #define TPM_LIB_ERROR	((uint32_t)~0u)
@@ -240,8 +241,19 @@ static uint32_t tpm_sendrecv_command(const void *command,
 		response = response_buffer;
 		response_length = sizeof(response_buffer);
 	}
+#ifdef CONFIG_DM_TPM
+	struct udevice *dev;
+	int ret;
+
+	ret = uclass_first_device(UCLASS_TPM, &dev);
+	if (ret)
+		return ret;
+	err = tis_xfer(dev, command, tpm_command_size(command),
+		       response, &response_length);
+#else
 	err = tis_sendrecv(command, tpm_command_size(command),
 			response, &response_length);
+#endif
 	if (err)
 		return TPM_LIB_ERROR;
 	if (size_ptr)
@@ -250,15 +262,24 @@ static uint32_t tpm_sendrecv_command(const void *command,
 	return tpm_return_code(response);
 }
 
-uint32_t tpm_init(void)
+int tpm_init(void)
 {
-	uint32_t err;
+	int err;
 
+#ifdef CONFIG_DM_TPM
+	struct udevice *dev;
+
+	err = uclass_first_device(UCLASS_TPM, &dev);
+	if (err)
+		return err;
+	return tis_open(dev);
+#else
 	err = tis_init();
 	if (err)
 		return err;
 
 	return tis_open();
+#endif
 }
 
 uint32_t tpm_startup(enum tpm_startup_type mode)
Signature · 1 line
2.5.0.rc2.392.g76e840b
#42 lore raw

PATCH 16/25 dm: tpm: Convert the TPM command and library to driver model

Hi Simon

Quoted 50 lines · Simon Glass

Add driver model support to the TPM command and the TPM library. Both support only a single TPM at present.

---

  common/cmd_tpm.c | 26 ++++++++++++++++++++++++++
  include/tpm.h    |  2 +-
  lib/tpm.c        | 29 +++++++++++++++++++++++++----
  3 files changed, 52 insertions(+), 5 deletions(-)
common/cmd_tpm.c +17 -0
index 0294952..274e3cd 100644
@@ -6,6 +6,7 @@
 
  #include <common.h>
  #include <command.h>
+#include <dm.h>
  #include <malloc.h>
  #include <tpm.h>
  #include <asm/unaligned.h>
@@ -438,6 +439,21 @@ TPM_COMMAND_NO_ARG(tpm_force_clear)
  TPM_COMMAND_NO_ARG(tpm_physical_enable)
  TPM_COMMAND_NO_ARG(tpm_physical_disable)
 
+#ifdef CONFIG_DM_TPM
+static int get_tpm(struct udevice **devp)
+{
+	int rc;
+
+	rc = uclass_first_device(UCLASS_TPM, devp);
+	if (rc) {
+		printf("Could not find TPM (ret=%d)\n", rc);
+		return CMD_RET_FAILURE;
+	}
+
+	return 0;
+}
+#endif
+
  static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag,
  		int argc, char * const argv[])
  {
@@ -452,7 +468,17 @@ static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag,
  		return CMD_RET_FAILURE;
  	}
 
+#ifdef CONFIG_DM_TPM

common/cmd_tpm.c static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag, · line 481

Quoted 10 lines
common/cmd_tpm.c +9 -0
+	struct udevice *dev;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
+
+	rc = tis_xfer(dev, command, count, response, &response_length);
+#else
  	rc = tis_sendrecv(command, count, response, &response_length);
+#endif

Why don't you retrieve the TPM dev inside a tis_sendrecv function defined only if DM_TPM is enabled ?
As we manage only 1 TPM per platform, it may simplify changes for now ?

Quoted 41 lines
common/cmd_tpm.c +0 -0
  	free(command);
  	if (!rc) {
  		puts("tpm response:\n");
include/tpm.h +1 -1
index 88aeba2..9a0f87c 100644
@@ -157,7 +157,7 @@ enum tpm_return_code {
   *
   * @return 0 on success, non-0 on error.
   */
-uint32_t tpm_init(void);
+int tpm_init(void);
 
  /**
   * Issue a TPM_Startup command.
lib/tpm.c +6 -2
index d9789b0..9e2cc77 100644
@@ -6,10 +6,11 @@
   */
 
  #include <common.h>
-#include <stdarg.h>
-#include <u-boot/sha1.h>
+#include <dm.h>
+#include <tis.h>
  #include <tpm.h>
  #include <asm/unaligned.h>
+#include <u-boot/sha1.h>
 
  /* Internal error of TPM command library */
  #define TPM_LIB_ERROR	((uint32_t)~0u)
@@ -240,8 +241,19 @@ static uint32_t tpm_sendrecv_command(const void *command,
  		response = response_buffer;
  		response_length = sizeof(response_buffer);
  	}
+#ifdef CONFIG_DM_TPM
+	struct udevice *dev;
+	int ret;

lib/tpm.c static uint32_t tpm_sendrecv_command(const void *command, · line 256

Quoted 10 lines
lib/tpm.c +8 -0
+
+	ret = uclass_first_device(UCLASS_TPM, &dev);
+	if (ret)
+		return ret;
+	err = tis_xfer(dev, command, tpm_command_size(command),
+		       response, &response_length);
+#else
  	err = tis_sendrecv(command, tpm_command_size(command),
  			response, &response_length);
+#endif

Same remark than above.

Quoted 17 lines
lib/tpm.c +6 -2
  	if (err)
  		return TPM_LIB_ERROR;
  	if (size_ptr)
@@ -250,15 +262,24 @@ static uint32_t tpm_sendrecv_command(const void *command,
  	return tpm_return_code(response);
  }
 
-uint32_t tpm_init(void)
+int tpm_init(void)
  {
-	uint32_t err;
+	int err;
 
+#ifdef CONFIG_DM_TPM
+	struct udevice *dev;
+
+	err = uclass_first_device(UCLASS_TPM, &dev);

lib/tpm.c static uint32_t tpm_sendrecv_command(const void *command, · line 282

Quoted 10 lines
lib/tpm.c +5 -0
+	if (err)
+		return err;
+	return tis_open(dev);
+#else
  	err = tis_init();
  	if (err)
  		return err;
 
  	return tis_open();
+#endif

Same

lib/tpm.c static uint32_t tpm_sendrecv_command(const void *command, · line 285

Quoted 3 lines
lib/tpm.c +0 -0
  }
 
  uint32_t tpm_startup(enum tpm_startup_type mode)

Best Regards
Christophe

#43 lore raw

PATCH 17/25 dm: i2c: Add a command to adjust the offset length

In reply to Simon Glass

I2C chips can support a register offset, with registers accessible by sending this offset as the first part of any read or write transaction. Most I2C chips have a single byte offset, thus the offset length is 1. This provides access for up 256 registers.

However other offset lengths are supported, including 0.

Add a command to provide access to the offset length from the command line. This allows the offset length to be read or written.

---

 common/cmd_i2c.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)
common/cmd_i2c.c +33 -0
index 1bc0db8..864b259 100644
@@ -453,6 +453,37 @@ static int do_i2c_flags(cmd_tbl_t *cmdtp, int flag, int argc,
 
 	return 0;
 }
+
+static int do_i2c_olen(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+	struct udevice *dev;
+	uint olen;
+	int chip;
+	int ret;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	chip = simple_strtoul(argv[1], NULL, 16);
+	ret = i2c_get_cur_bus_chip(chip, &dev);
+	if (ret)
+		return i2c_report_err(ret, I2C_ERR_READ);
+
+	if (argc > 2) {
+		olen = simple_strtoul(argv[2], NULL, 16);
+		ret = i2c_set_chip_offset_len(dev, olen);
+	} else  {
+		ret = i2c_get_chip_offset_len(dev);
+		if (ret >= 0) {
+			printf("%x\n", ret);
+			ret = 0;
+		}
+	}
+	if (ret)
+		return i2c_report_err(ret, I2C_ERR_READ);
+
+	return 0;
+}
 #endif
 
 /**
@@ -1903,6 +1934,7 @@ static cmd_tbl_t cmd_i2c_sub[] = {
 	U_BOOT_CMD_MKENT(write, 6, 0, do_i2c_write, "", ""),
 #ifdef CONFIG_DM_I2C
 	U_BOOT_CMD_MKENT(flags, 2, 1, do_i2c_flags, "", ""),
+	U_BOOT_CMD_MKENT(olen, 2, 1, do_i2c_olen, "", ""),
 #endif
 	U_BOOT_CMD_MKENT(reset, 0, 1, do_i2c_reset, "", ""),
 #if defined(CONFIG_CMD_SDRAM)
@@ -1971,6 +2003,7 @@ static char i2c_help_text[] =
 	"          to I2C; the -s option selects bulk write in a single transaction\n"
 #ifdef CONFIG_DM_I2C
 	"i2c flags chip [flags] - set or get chip flags\n"
+	"i2c olen chip [offset_length] - set or get chip offset length\n"
 #endif
 	"i2c reset - re-init the I2C Controller\n"
 #if defined(CONFIG_CMD_SDRAM)
Signature · 1 line
2.5.0.rc2.392.g76e840b
#44 lore raw

PATCH 18/25 tpm: Report tpm errors on the command line

In reply to Simon Glass

When a 'tpm' command fails, we set the return code but give no indication of failure. This can be confusing.

Add an error message when any tpm command fails.

---

 common/cmd_tpm.c | 46 ++++++++++++++++++++++++----------------------
 1 file changed, 24 insertions(+), 22 deletions(-)
common/cmd_tpm.c +24 -22
index 274e3cd..f48ab04 100644
@@ -80,17 +80,19 @@ static void *parse_byte_string(char *bytes, uint8_t *data, size_t *count_ptr)
 }
 
 /**
- * Convert TPM command return code to U-Boot command error codes.
+ * report_return_code() - Report any error and return failure or success
  *
  * @param return_code	TPM command return code
  * @return value of enum command_ret_t
  */
-static int convert_return_code(uint32_t return_code)
+static int report_return_code(int return_code)
 {
-	if (return_code)
+	if (return_code < 0) {
+		printf("Error: %d\n", return_code);
 		return CMD_RET_FAILURE;
-	else
+	} else {
 		return CMD_RET_SUCCESS;
+	}
 }
 
 /**
@@ -252,7 +254,7 @@ static int do_tpm_startup(cmd_tbl_t *cmdtp, int flag,
 		return CMD_RET_FAILURE;
 	}
 
-	return convert_return_code(tpm_startup(mode));
+	return report_return_code(tpm_startup(mode));
 }
 
 static int do_tpm_nv_define_space(cmd_tbl_t *cmdtp, int flag,
@@ -266,7 +268,7 @@ static int do_tpm_nv_define_space(cmd_tbl_t *cmdtp, int flag,
 	perm = simple_strtoul(argv[2], NULL, 0);
 	size = simple_strtoul(argv[3], NULL, 0);
 
-	return convert_return_code(tpm_nv_define_space(index, perm, size));
+	return report_return_code(tpm_nv_define_space(index, perm, size));
 }
 
 static int do_tpm_nv_read_value(cmd_tbl_t *cmdtp, int flag,
@@ -287,7 +289,7 @@ static int do_tpm_nv_read_value(cmd_tbl_t *cmdtp, int flag,
 		print_byte_string(data, count);
 	}
 
-	return convert_return_code(rc);
+	return report_return_code(rc);
 }
 
 static int do_tpm_nv_write_value(cmd_tbl_t *cmdtp, int flag,
@@ -309,7 +311,7 @@ static int do_tpm_nv_write_value(cmd_tbl_t *cmdtp, int flag,
 	rc = tpm_nv_write_value(index, data, count);
 	free(data);
 
-	return convert_return_code(rc);
+	return report_return_code(rc);
 }
 
 static int do_tpm_extend(cmd_tbl_t *cmdtp, int flag,
@@ -332,7 +334,7 @@ static int do_tpm_extend(cmd_tbl_t *cmdtp, int flag,
 		print_byte_string(out_digest, sizeof(out_digest));
 	}
 
-	return convert_return_code(rc);
+	return report_return_code(rc);
 }
 
 static int do_tpm_pcr_read(cmd_tbl_t *cmdtp, int flag,
@@ -353,7 +355,7 @@ static int do_tpm_pcr_read(cmd_tbl_t *cmdtp, int flag,
 		print_byte_string(data, count);
 	}
 
-	return convert_return_code(rc);
+	return report_return_code(rc);
 }
 
 static int do_tpm_tsc_physical_presence(cmd_tbl_t *cmdtp, int flag,
@@ -365,7 +367,7 @@ static int do_tpm_tsc_physical_presence(cmd_tbl_t *cmdtp, int flag,
 		return CMD_RET_USAGE;
 	presence = (uint16_t)simple_strtoul(argv[1], NULL, 0);
 
-	return convert_return_code(tpm_tsc_physical_presence(presence));
+	return report_return_code(tpm_tsc_physical_presence(presence));
 }
 
 static int do_tpm_read_pubek(cmd_tbl_t *cmdtp, int flag,
@@ -385,7 +387,7 @@ static int do_tpm_read_pubek(cmd_tbl_t *cmdtp, int flag,
 		print_byte_string(data, count);
 	}
 
-	return convert_return_code(rc);
+	return report_return_code(rc);
 }
 
 static int do_tpm_physical_set_deactivated(cmd_tbl_t *cmdtp, int flag,
@@ -397,7 +399,7 @@ static int do_tpm_physical_set_deactivated(cmd_tbl_t *cmdtp, int flag,
 		return CMD_RET_USAGE;
 	state = (uint8_t)simple_strtoul(argv[1], NULL, 0);
 
-	return convert_return_code(tpm_physical_set_deactivated(state));
+	return report_return_code(tpm_physical_set_deactivated(state));
 }
 
 static int do_tpm_get_capability(cmd_tbl_t *cmdtp, int flag,
@@ -420,7 +422,7 @@ static int do_tpm_get_capability(cmd_tbl_t *cmdtp, int flag,
 		print_byte_string(cap, count);
 	}
 
-	return convert_return_code(rc);
+	return report_return_code(rc);
 }
 
 #define TPM_COMMAND_NO_ARG(cmd)				\
@@ -429,7 +431,7 @@ static int do_##cmd(cmd_tbl_t *cmdtp, int flag,		\
 {							\
 	if (argc != 1)					\
 		return CMD_RET_USAGE;			\
-	return convert_return_code(cmd());		\
+	return report_return_code(cmd());		\
 }
 
 TPM_COMMAND_NO_ARG(tpm_init)
@@ -485,7 +487,7 @@ static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag,
 		print_byte_string(response, response_length);
 	}
 
-	return convert_return_code(rc);
+	return report_return_code(rc);
 }
 
 static int do_tpm_nv_define(cmd_tbl_t *cmdtp, int flag,
@@ -503,7 +505,7 @@ static int do_tpm_nv_define(cmd_tbl_t *cmdtp, int flag,
 	index = simple_strtoul(argv[2], NULL, 0);
 	perm = simple_strtoul(argv[3], NULL, 0);
 
-	return convert_return_code(tpm_nv_define_space(index, perm, size));
+	return report_return_code(tpm_nv_define_space(index, perm, size));
 }
 
 static int do_tpm_nv_read(cmd_tbl_t *cmdtp, int flag,
@@ -532,7 +534,7 @@ static int do_tpm_nv_read(cmd_tbl_t *cmdtp, int flag,
 	}
 	free(data);
 
-	return convert_return_code(err);
+	return report_return_code(err);
 }
 
 static int do_tpm_nv_write(cmd_tbl_t *cmdtp, int flag,
@@ -560,7 +562,7 @@ static int do_tpm_nv_write(cmd_tbl_t *cmdtp, int flag,
 	err = tpm_nv_write_value(index, data, count);
 	free(data);
 
-	return convert_return_code(err);
+	return report_return_code(err);
 }
 
 #ifdef CONFIG_TPM_AUTH_SESSIONS
@@ -572,7 +574,7 @@ static int do_tpm_oiap(cmd_tbl_t *cmdtp, int flag,
 
 	err = tpm_oiap(&auth_handle);
 
-	return convert_return_code(err);
+	return report_return_code(err);
 }
 
 static int do_tpm_load_key2_oiap(cmd_tbl_t *cmdtp, int flag,
@@ -597,7 +599,7 @@ static int do_tpm_load_key2_oiap(cmd_tbl_t *cmdtp, int flag,
 	if (!err)
 		printf("Key handle is 0x%x\n", key_handle);
 
-	return convert_return_code(err);
+	return report_return_code(err);
 }
 
 static int do_tpm_get_pub_key_oiap(cmd_tbl_t *cmdtp, int flag,
@@ -622,7 +624,7 @@ static int do_tpm_get_pub_key_oiap(cmd_tbl_t *cmdtp, int flag,
 		printf("dump of received pub key structure:\n");
 		print_byte_string(pub_key_buffer, pub_key_len);
 	}
-	return convert_return_code(err);
+	return report_return_code(err);
 }
 
 TPM_COMMAND_NO_ARG(tpm_end_oiap)
Signature · 1 line
2.5.0.rc2.392.g76e840b
#45 lore raw

PATCH 18/25 tpm: Report tpm errors on the command line

Hi Simon,

Good one !

Best Regards
Christophe

Quoted 201 lines · Simon Glass

When a 'tpm' command fails, we set the return code but give no indication of failure. This can be confusing.

Add an error message when any tpm command fails.

---

  common/cmd_tpm.c | 46 ++++++++++++++++++++++++----------------------
  1 file changed, 24 insertions(+), 22 deletions(-)
common/cmd_tpm.c +24 -22
index 274e3cd..f48ab04 100644
@@ -80,17 +80,19 @@ static void *parse_byte_string(char *bytes, uint8_t *data, size_t *count_ptr)
  }
 
  /**
- * Convert TPM command return code to U-Boot command error codes.
+ * report_return_code() - Report any error and return failure or success
   *
   * @param return_code	TPM command return code
   * @return value of enum command_ret_t
   */
-static int convert_return_code(uint32_t return_code)
+static int report_return_code(int return_code)
  {
-	if (return_code)
+	if (return_code < 0) {
+		printf("Error: %d\n", return_code);
  		return CMD_RET_FAILURE;
-	else
+	} else {
  		return CMD_RET_SUCCESS;
+	}
  }
 
  /**
@@ -252,7 +254,7 @@ static int do_tpm_startup(cmd_tbl_t *cmdtp, int flag,
  		return CMD_RET_FAILURE;
  	}
 
-	return convert_return_code(tpm_startup(mode));
+	return report_return_code(tpm_startup(mode));
  }
 
  static int do_tpm_nv_define_space(cmd_tbl_t *cmdtp, int flag,
@@ -266,7 +268,7 @@ static int do_tpm_nv_define_space(cmd_tbl_t *cmdtp, int flag,
  	perm = simple_strtoul(argv[2], NULL, 0);
  	size = simple_strtoul(argv[3], NULL, 0);
 
-	return convert_return_code(tpm_nv_define_space(index, perm, size));
+	return report_return_code(tpm_nv_define_space(index, perm, size));
  }
 
  static int do_tpm_nv_read_value(cmd_tbl_t *cmdtp, int flag,
@@ -287,7 +289,7 @@ static int do_tpm_nv_read_value(cmd_tbl_t *cmdtp, int flag,
  		print_byte_string(data, count);
  	}
 
-	return convert_return_code(rc);
+	return report_return_code(rc);
  }
 
  static int do_tpm_nv_write_value(cmd_tbl_t *cmdtp, int flag,
@@ -309,7 +311,7 @@ static int do_tpm_nv_write_value(cmd_tbl_t *cmdtp, int flag,
  	rc = tpm_nv_write_value(index, data, count);
  	free(data);
 
-	return convert_return_code(rc);
+	return report_return_code(rc);
  }
 
  static int do_tpm_extend(cmd_tbl_t *cmdtp, int flag,
@@ -332,7 +334,7 @@ static int do_tpm_extend(cmd_tbl_t *cmdtp, int flag,
  		print_byte_string(out_digest, sizeof(out_digest));
  	}
 
-	return convert_return_code(rc);
+	return report_return_code(rc);
  }
 
  static int do_tpm_pcr_read(cmd_tbl_t *cmdtp, int flag,
@@ -353,7 +355,7 @@ static int do_tpm_pcr_read(cmd_tbl_t *cmdtp, int flag,
  		print_byte_string(data, count);
  	}
 
-	return convert_return_code(rc);
+	return report_return_code(rc);
  }
 
  static int do_tpm_tsc_physical_presence(cmd_tbl_t *cmdtp, int flag,
@@ -365,7 +367,7 @@ static int do_tpm_tsc_physical_presence(cmd_tbl_t *cmdtp, int flag,
  		return CMD_RET_USAGE;
  	presence = (uint16_t)simple_strtoul(argv[1], NULL, 0);
 
-	return convert_return_code(tpm_tsc_physical_presence(presence));
+	return report_return_code(tpm_tsc_physical_presence(presence));
  }
 
  static int do_tpm_read_pubek(cmd_tbl_t *cmdtp, int flag,
@@ -385,7 +387,7 @@ static int do_tpm_read_pubek(cmd_tbl_t *cmdtp, int flag,
  		print_byte_string(data, count);
  	}
 
-	return convert_return_code(rc);
+	return report_return_code(rc);
  }
 
  static int do_tpm_physical_set_deactivated(cmd_tbl_t *cmdtp, int flag,
@@ -397,7 +399,7 @@ static int do_tpm_physical_set_deactivated(cmd_tbl_t *cmdtp, int flag,
  		return CMD_RET_USAGE;
  	state = (uint8_t)simple_strtoul(argv[1], NULL, 0);
 
-	return convert_return_code(tpm_physical_set_deactivated(state));
+	return report_return_code(tpm_physical_set_deactivated(state));
  }
 
  static int do_tpm_get_capability(cmd_tbl_t *cmdtp, int flag,
@@ -420,7 +422,7 @@ static int do_tpm_get_capability(cmd_tbl_t *cmdtp, int flag,
  		print_byte_string(cap, count);
  	}
 
-	return convert_return_code(rc);
+	return report_return_code(rc);
  }
 
  #define TPM_COMMAND_NO_ARG(cmd)				\
@@ -429,7 +431,7 @@ static int do_##cmd(cmd_tbl_t *cmdtp, int flag,		\
  {							\
  	if (argc != 1)					\
  		return CMD_RET_USAGE;			\
-	return convert_return_code(cmd());		\
+	return report_return_code(cmd());		\
  }
 
  TPM_COMMAND_NO_ARG(tpm_init)
@@ -485,7 +487,7 @@ static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag,
  		print_byte_string(response, response_length);
  	}
 
-	return convert_return_code(rc);
+	return report_return_code(rc);
  }
 
  static int do_tpm_nv_define(cmd_tbl_t *cmdtp, int flag,
@@ -503,7 +505,7 @@ static int do_tpm_nv_define(cmd_tbl_t *cmdtp, int flag,
  	index = simple_strtoul(argv[2], NULL, 0);
  	perm = simple_strtoul(argv[3], NULL, 0);
 
-	return convert_return_code(tpm_nv_define_space(index, perm, size));
+	return report_return_code(tpm_nv_define_space(index, perm, size));
  }
 
  static int do_tpm_nv_read(cmd_tbl_t *cmdtp, int flag,
@@ -532,7 +534,7 @@ static int do_tpm_nv_read(cmd_tbl_t *cmdtp, int flag,
  	}
  	free(data);
 
-	return convert_return_code(err);
+	return report_return_code(err);
  }
 
  static int do_tpm_nv_write(cmd_tbl_t *cmdtp, int flag,
@@ -560,7 +562,7 @@ static int do_tpm_nv_write(cmd_tbl_t *cmdtp, int flag,
  	err = tpm_nv_write_value(index, data, count);
  	free(data);
 
-	return convert_return_code(err);
+	return report_return_code(err);
  }
 
  #ifdef CONFIG_TPM_AUTH_SESSIONS
@@ -572,7 +574,7 @@ static int do_tpm_oiap(cmd_tbl_t *cmdtp, int flag,
 
  	err = tpm_oiap(&auth_handle);
 
-	return convert_return_code(err);
+	return report_return_code(err);
  }
 
  static int do_tpm_load_key2_oiap(cmd_tbl_t *cmdtp, int flag,
@@ -597,7 +599,7 @@ static int do_tpm_load_key2_oiap(cmd_tbl_t *cmdtp, int flag,
  	if (!err)
  		printf("Key handle is 0x%x\n", key_handle);
 
-	return convert_return_code(err);
+	return report_return_code(err);
  }
 
  static int do_tpm_get_pub_key_oiap(cmd_tbl_t *cmdtp, int flag,
@@ -622,7 +624,7 @@ static int do_tpm_get_pub_key_oiap(cmd_tbl_t *cmdtp, int flag,
  		printf("dump of received pub key structure:\n");
  		print_byte_string(pub_key_buffer, pub_key_len);
  	}
-	return convert_return_code(err);
+	return report_return_code(err);
  }
 
  TPM_COMMAND_NO_ARG(tpm_end_oiap)
#46 lore raw

PATCH 19/25 dm: tpm: sandbox: Convert TPM driver to driver model

In reply to Simon Glass

Convert the sandbox TPM driver to use driver model. Add it to the device tree so that it can be found on start-up.

---

 arch/sandbox/dts/sandbox.dts  |  4 ++++
 configs/sandbox_defconfig     |  1 +
 drivers/tpm/tpm_tis_sandbox.c | 48 ++++++++++++++++++++++++++++++++-----------
 3 files changed, 41 insertions(+), 12 deletions(-)
arch/sandbox/dts/sandbox.dts +4 -0
index 8927527..758c4a5 100644
@@ -156,6 +156,10 @@
 		sides = <4>;
 	};
 
+	tpm {
+		compatible = "google,sandbox-tpm";
+	};
+
 	triangle {
 		compatible = "demo-shape";
 		colour = "cyan";
configs/sandbox_defconfig +1 -0
index b68d688..2600bf7 100644
@@ -31,6 +31,7 @@ CONFIG_CROS_EC_KEYB=y
 CONFIG_LED=y
 CONFIG_LED_GPIO=y
 CONFIG_SANDBOX_SERIAL=y
+CONFIG_DM_TPM=y
 CONFIG_TPM_TIS_SANDBOX=y
 CONFIG_SYS_I2C_SANDBOX=y
 CONFIG_SANDBOX_SPI=y
drivers/tpm/tpm_tis_sandbox.c +36 -12

93 lines not on this page · raw message

Signature · 1 line
2.5.0.rc2.392.g76e840b
#47 lore raw

PATCH 19/25 dm: tpm: sandbox: Convert TPM driver to driver model

Quoted 141 lines · Simon Glass

Convert the sandbox TPM driver to use driver model. Add it to the device tree so that it can be found on start-up.

---

  arch/sandbox/dts/sandbox.dts  |  4 ++++
  configs/sandbox_defconfig     |  1 +
  drivers/tpm/tpm_tis_sandbox.c | 48 ++++++++++++++++++++++++++++++++-----------
  3 files changed, 41 insertions(+), 12 deletions(-)
arch/sandbox/dts/sandbox.dts +4 -0
index 8927527..758c4a5 100644
@@ -156,6 +156,10 @@
  		sides = <4>;
  	};
 
+	tpm {
+		compatible = "google,sandbox-tpm";
+	};
+
  	triangle {
  		compatible = "demo-shape";
  		colour = "cyan";
configs/sandbox_defconfig +1 -0
index b68d688..2600bf7 100644
@@ -31,6 +31,7 @@ CONFIG_CROS_EC_KEYB=y
  CONFIG_LED=y
  CONFIG_LED_GPIO=y
  CONFIG_SANDBOX_SERIAL=y
+CONFIG_DM_TPM=y
  CONFIG_TPM_TIS_SANDBOX=y
  CONFIG_SYS_I2C_SANDBOX=y
  CONFIG_SANDBOX_SPI=y
drivers/tpm/tpm_tis_sandbox.c +36 -12
index ed4b039..7a481dd 100644
@@ -5,6 +5,8 @@
   */
 
  #include <common.h>
+#include <dm.h>
+#include <tis.h>
  #include <asm/state.h>
  #include <asm/unaligned.h>
  #include <linux/crc8.h>
@@ -56,7 +58,7 @@ enum {
   */
  static struct tpm_state {
  	uint8_t nvdata[NV_SEQ_COUNT][NV_DATA_SIZE];
-} state;
+} g_state;
 
  /**
   * sandbox_tpm_read_state() - read the sandbox EC state from the state file
@@ -82,7 +84,7 @@ static int sandbox_tpm_read_state(const void *blob, int node)
  		sprintf(prop_name, "nvdata%d", i);
  		prop = fdt_getprop(blob, node, prop_name, &len);
  		if (prop && len == NV_DATA_SIZE)
-			memcpy(state.nvdata[i], prop, NV_DATA_SIZE);
+			memcpy(g_state.nvdata[i], prop, NV_DATA_SIZE);
  	}
 
  	return 0;
@@ -110,7 +112,7 @@ static int sandbox_tpm_write_state(void *blob, int node)
  		char prop_name[20];
 
  		sprintf(prop_name, "nvdata%d", i);
-		fdt_setprop(blob, node, prop_name, state.nvdata[i],
+		fdt_setprop(blob, node, prop_name, g_state.nvdata[i],
  			    NV_DATA_SIZE);
  	}
 
@@ -135,10 +137,11 @@ static int index_to_seq(uint32_t index)
  	return -1;
  }
 
-int tis_sendrecv(const u8 *sendbuf, size_t send_size,
-		 u8 *recvbuf, size_t *recv_len)
+static int sandbox_tpm_xfer(struct udevice *dev, const uint8_t *sendbuf,
+			    size_t send_size, uint8_t *recvbuf,
+			    size_t *recv_len)
  {
-	struct tpm_state *tpm = &state;
+	struct tpm_state *tpm = dev_get_priv(dev);
  	uint32_t code, index, length, type;
  	uint8_t *data;
  	int seq;
@@ -241,20 +244,41 @@ int tis_sendrecv(const u8 *sendbuf, size_t send_size,
  	return 0;
  }
 
-int tis_open(void)
+static int sandbox_tpm_probe(struct udevice *dev)
  {
-	printf("%s\n", __func__);
+	struct tpm_state *tpm = dev_get_priv(dev);
+
+	memcpy(tpm, &g_state, sizeof(*tpm));
+
  	return 0;
  }
 
-int tis_close(void)
+static int sandbox_tpm_open(struct udevice *dev)
  {
-	printf("%s\n", __func__);
  	return 0;
  }
 
-int tis_init(void)
+static int sandbox_tpm_close(struct udevice *dev)
  {
-	printf("%s\n", __func__);
  	return 0;
  }
+
+static const struct tpm_ops sandbox_tpm_ops = {
+	.open		= sandbox_tpm_open,
+	.close		= sandbox_tpm_close,
+	.xfer		= sandbox_tpm_xfer,
+};
+
+static const struct udevice_id sandbox_tpm_ids[] = {
+	{ .compatible = "google,sandbox-tpm" },
+	{ }
+};
+
+U_BOOT_DRIVER(sandbox_tpm) = {
+	.name   = "sandbox_tpm",
+	.id     = UCLASS_TPM,
+	.of_match = sandbox_tpm_ids,
+	.ops    = &sandbox_tpm_ops,
+	.probe	= sandbox_tpm_probe,
+	.priv_auto_alloc_size = sizeof(struct tpm_state),
+};
#48 lore raw

PATCH 20/25 tpm: Check that parse_byte_string() has data to parse

In reply to Simon Glass

Rather then crashing when there is no data, print an error.

---

 common/cmd_tpm.c | 2 ++
 1 file changed, 2 insertions(+)
common/cmd_tpm.c +2 -0
index f48ab04..2783895 100644
@@ -58,6 +58,8 @@ static void *parse_byte_string(char *bytes, uint8_t *data, size_t *count_ptr)
 	size_t count, length;
 	int i;
 
+	if (!bytes)
+		return NULL;
 	length = strlen(bytes);
 	count = length / 2;
 
Signature · 1 line
2.5.0.rc2.392.g76e840b
#49 lore raw

PATCH 20/25 tpm: Check that parse_byte_string() has data to parse

Hi Simon,

Best Regards
Christophe

Quoted 21 lines · Simon Glass

Rather then crashing when there is no data, print an error.

---

  common/cmd_tpm.c | 2 ++
  1 file changed, 2 insertions(+)
common/cmd_tpm.c +2 -0
index f48ab04..2783895 100644
@@ -58,6 +58,8 @@ static void *parse_byte_string(char *bytes, uint8_t *data, size_t *count_ptr)
  	size_t count, length;
  	int i;
 
+	if (!bytes)
+		return NULL;
  	length = strlen(bytes);
  	count = length / 2;
 
#50 lore raw

PATCH 21/25 exynos: x86: dts: Add tpm nodes to the device tree for Chrome OS devices

In reply to Simon Glass

Add a TPM node to the various Chromebooks so that driver can be converted to driver model.

---

 arch/arm/dts/exynos5250-snow.dts      | 9 +++++++++
 arch/arm/dts/exynos5250-spring.dts    | 8 ++++++++
 arch/arm/dts/exynos5420-peach-pit.dts | 6 +++---
 arch/arm/dts/exynos5800-peach-pi.dts  | 6 +++---
 arch/x86/dts/chromebook_link.dts      | 5 +++++
 5 files changed, 28 insertions(+), 6 deletions(-)
arch/arm/dts/exynos5250-snow.dts +9 -0
index 32c0098..bda5499 100644
@@ -206,6 +206,15 @@
 		};
 	};
 
+	i2c at 12C90000 {
+		clock-frequency = <100000>;
+		tpm at 20 {
+			reg = <0x20>;
+			u-boot,i2c-offset-len = <0>;
+			compatible = "infineon,slb9635tt";
+		};
+	};
+
 	spi at 12d30000 {
 		spi-max-frequency = <50000000>;
 		firmware_storage_spi: flash at 0 {
arch/arm/dts/exynos5250-spring.dts +8 -0
index 76d5323..81b3d29 100644
@@ -59,6 +59,14 @@
 					 <&gpy4 2 0>;
 	};
 
+	i2c at 12C90000 {
+		clock-frequency = <100000>;
+		tpm at 20 {
+			reg = <0x20>;
+			compatible = "infineon,slb9645tt";
+		};
+	};
+
 	mmc at 12200000 {
 		samsung,bus-width = <8>;
 		samsung,timing = <1 3 3>;
arch/arm/dts/exynos5420-peach-pit.dts +3 -3
index 2d2b7c9..16d52f4 100644
@@ -197,9 +197,9 @@
 
 	i2c at 12E10000 { /* i2c9 */
 		clock-frequency = <400000>;
-                tpm at 20 {
-                        compatible = "infineon,slb9645tt";
-                        reg = <0x20>;
+		tpm at 20 {
+			compatible = "infineon,slb9645tt";
+			reg = <0x20>;
 		};
 	};
 
arch/arm/dts/exynos5800-peach-pi.dts +3 -3
index 600c294..1d7ff23 100644
@@ -72,9 +72,9 @@
 
 	i2c at 12E10000 { /* i2c9 */
 		clock-frequency = <400000>;
-                tpm at 20 {
-                        compatible = "infineon,slb9645tt";
-                        reg = <0x20>;
+		tpm at 20 {
+			compatible = "infineon,slb9645tt";
+			reg = <0x20>;
 		};
 	};
 
arch/x86/dts/chromebook_link.dts +5 -0
index ad390bf..4291141 100644
@@ -237,6 +237,11 @@
 		};
 	};
 
+	tpm {
+		reg = <0xfed40000 0x5000>;
+		compatible = "infineon,slb9635lpc";
+	};
+
 	microcode {
 		update at 0 {
 #include "microcode/m12306a9_0000001b.dtsi"
Signature · 1 line
2.5.0.rc2.392.g76e840b
#51 lore raw

PATCH 22/25 dm: tpm: Convert I2C driver to driver model

In reply to Simon Glass

Convert the tpm_tis_i2c driver to use driver model and update boards which use it.

---

 configs/peach-pi_defconfig  |   1 +
 configs/peach-pit_defconfig |   1 +
 configs/snow_defconfig      |   1 +
 configs/spring_defconfig    |   1 +
 drivers/tpm/tpm_tis_i2c.c   | 361 +++++++++++++++++++++-----------------------
 drivers/tpm/tpm_tis_i2c.h   |   3 +-
 include/fdtdec.h            |   2 -
 lib/fdtdec.c                |   2 -
 8 files changed, 175 insertions(+), 197 deletions(-)
configs/peach-pi_defconfig +1 -0
index 5df93b9..215f9ba 100644
@@ -13,6 +13,7 @@ CONFIG_CMD_CROS_EC=y
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_SPI=y
 CONFIG_CROS_EC_KEYB=y
+CONFIG_DM_TPM=y
 CONFIG_TPM_TIS_I2C=y
 CONFIG_DM_I2C=y
 CONFIG_DM_I2C_COMPAT=y
configs/peach-pit_defconfig +1 -0
index e5921ff..40fefc3 100644
@@ -13,6 +13,7 @@ CONFIG_CMD_CROS_EC=y
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_SPI=y
 CONFIG_CROS_EC_KEYB=y
+CONFIG_DM_TPM=y
 CONFIG_TPM_TIS_I2C=y
 CONFIG_DM_I2C=y
 CONFIG_DM_I2C_COMPAT=y
configs/snow_defconfig +1 -0
index 0f7a764..e731608 100644
@@ -18,6 +18,7 @@ CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART_S5P=y
 CONFIG_DEBUG_UART_BASE=0x12c30000
 CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_DM_TPM=y
 CONFIG_TPM_TIS_I2C=y
 CONFIG_DM_I2C=y
 CONFIG_DM_I2C_COMPAT=y
configs/spring_defconfig +1 -0
index 1b3daa4..bb4c0ef 100644
@@ -18,6 +18,7 @@ CONFIG_DEBUG_UART=y
 CONFIG_DEBUG_UART_S5P=y
 CONFIG_DEBUG_UART_BASE=0x12c30000
 CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_DM_TPM=y
 CONFIG_TPM_TIS_I2C=y
 CONFIG_DM_I2C=y
 CONFIG_DM_I2C_COMPAT=y
drivers/tpm/tpm_tis_i2c.c +170 -191

741 lines not on this page · raw message

drivers/tpm/tpm_tis_i2c.h +1 -2
index ecdaf0c..324a3e5 100644
@@ -47,16 +47,15 @@ enum i2c_chip_type {
 };
 
 struct tpm_chip {
-	bool inited;
 	int is_open;
 	u8 req_complete_mask;
 	u8 req_complete_val;
 	u8 req_canceled;
 	int irq;
 	int locality;
+	u32 vend_dev;
 	unsigned long timeout_a, timeout_b, timeout_c, timeout_d;  /* msec */
 	unsigned long duration[3];  /* msec */
-	struct udevice *dev;
 	u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)];  /* Max buffer size + addr */
 	enum i2c_chip_type chip_type;
 };
include/fdtdec.h +0 -2
index eac679e..3062635 100644
@@ -164,8 +164,6 @@ enum fdt_compat_id {
 	COMPAT_MAXIM_MAX77686_PMIC,	/* MAX77686 PMIC */
 	COMPAT_GENERIC_SPI_FLASH,	/* Generic SPI Flash chip */
 	COMPAT_MAXIM_98095_CODEC,	/* MAX98095 Codec */
-	COMPAT_INFINEON_SLB9635_TPM,	/* Infineon SLB9635 TPM */
-	COMPAT_INFINEON_SLB9645_TPM,	/* Infineon SLB9645 TPM */
 	COMPAT_SAMSUNG_EXYNOS5_I2C,	/* Exynos5 High Speed I2C Controller */
 	COMPAT_SANDBOX_LCD_SDL,		/* Sandbox LCD emulation with SDL */
 	COMPAT_SAMSUNG_EXYNOS_SYSMMU,	/* Exynos sysmmu */
lib/fdtdec.c +0 -2
index b201787..6b67670 100644
@@ -58,8 +58,6 @@ static const char * const compat_names[COMPAT_COUNT] = {
 	COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686"),
 	COMPAT(GENERIC_SPI_FLASH, "spi-flash"),
 	COMPAT(MAXIM_98095_CODEC, "maxim,max98095-codec"),
-	COMPAT(INFINEON_SLB9635_TPM, "infineon,slb9635-tpm"),
-	COMPAT(INFINEON_SLB9645_TPM, "infineon,slb9645tt"),
 	COMPAT(SAMSUNG_EXYNOS5_I2C, "samsung,exynos5-hsi2c"),
 	COMPAT(SANDBOX_LCD_SDL, "sandbox,lcd-sdl"),
 	COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"),
Signature · 1 line
2.5.0.rc2.392.g76e840b
#52 lore raw

PATCH 22/25 dm: tpm: Convert I2C driver to driver model

Hi Simon,

I would be ok if we can get to a common agreement on my previous comments.

Best Regards
Christophe

Quoted 889 lines · Simon Glass

Convert the tpm_tis_i2c driver to use driver model and update boards which use it.

---

  configs/peach-pi_defconfig  |   1 +
  configs/peach-pit_defconfig |   1 +
  configs/snow_defconfig      |   1 +
  configs/spring_defconfig    |   1 +
  drivers/tpm/tpm_tis_i2c.c   | 361 +++++++++++++++++++++-----------------------
  drivers/tpm/tpm_tis_i2c.h   |   3 +-
  include/fdtdec.h            |   2 -
  lib/fdtdec.c                |   2 -
  8 files changed, 175 insertions(+), 197 deletions(-)
configs/peach-pi_defconfig +1 -0
index 5df93b9..215f9ba 100644
@@ -13,6 +13,7 @@ CONFIG_CMD_CROS_EC=y
  CONFIG_CROS_EC=y
  CONFIG_CROS_EC_SPI=y
  CONFIG_CROS_EC_KEYB=y
+CONFIG_DM_TPM=y
  CONFIG_TPM_TIS_I2C=y
  CONFIG_DM_I2C=y
  CONFIG_DM_I2C_COMPAT=y
configs/peach-pit_defconfig +1 -0
index e5921ff..40fefc3 100644
@@ -13,6 +13,7 @@ CONFIG_CMD_CROS_EC=y
  CONFIG_CROS_EC=y
  CONFIG_CROS_EC_SPI=y
  CONFIG_CROS_EC_KEYB=y
+CONFIG_DM_TPM=y
  CONFIG_TPM_TIS_I2C=y
  CONFIG_DM_I2C=y
  CONFIG_DM_I2C_COMPAT=y
configs/snow_defconfig +1 -0
index 0f7a764..e731608 100644
@@ -18,6 +18,7 @@ CONFIG_DEBUG_UART=y
  CONFIG_DEBUG_UART_S5P=y
  CONFIG_DEBUG_UART_BASE=0x12c30000
  CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_DM_TPM=y
  CONFIG_TPM_TIS_I2C=y
  CONFIG_DM_I2C=y
  CONFIG_DM_I2C_COMPAT=y
configs/spring_defconfig +1 -0
index 1b3daa4..bb4c0ef 100644
@@ -18,6 +18,7 @@ CONFIG_DEBUG_UART=y
  CONFIG_DEBUG_UART_S5P=y
  CONFIG_DEBUG_UART_BASE=0x12c30000
  CONFIG_DEBUG_UART_CLOCK=100000000
+CONFIG_DM_TPM=y
  CONFIG_TPM_TIS_I2C=y
  CONFIG_DM_I2C=y
  CONFIG_DM_I2C_COMPAT=y
drivers/tpm/tpm_tis_i2c.c +170 -191
index f1ad596..14ed8f4 100644
@@ -23,10 +23,11 @@
  #include <common.h>
  #include <dm.h>
  #include <fdtdec.h>
-#include <linux/compiler.h>
  #include <i2c.h>
+#include <tis.h>
  #include <tpm.h>
  #include <asm-generic/errno.h>
+#include <linux/compiler.h>
  #include <linux/types.h>
  #include <linux/unaligned/be_byteshift.h>
 
@@ -40,8 +41,6 @@ static const char * const chip_name[] = {
  	[UNKNOWN] = "unknown/fallback to slb9635",
  };
 
-static struct tpm_chip g_chip;
-
  /*
   * tpm_tis_i2c_read() - read from TPM register
   * @addr: register address to read from
@@ -56,22 +55,24 @@ static struct tpm_chip g_chip;
   *
   * Return -EIO on error, 0 on success.
   */
-static int tpm_tis_i2c_read(u8 addr, u8 *buffer, size_t len)
+static int tpm_tis_i2c_read(struct udevice *dev, u8 addr, u8 *buffer,
+			    size_t len)
  {
+	struct tpm_chip *chip = dev_get_priv(dev);
  	int rc;
  	int count;
  	uint32_t addrbuf = addr;
 
-	if ((g_chip.chip_type == SLB9635) || (g_chip.chip_type == UNKNOWN)) {
+	if ((chip->chip_type == SLB9635) || (chip->chip_type == UNKNOWN)) {
  		/* slb9635 protocol should work in both cases */
  		for (count = 0; count < MAX_COUNT; count++) {
-			rc = dm_i2c_write(g_chip.dev, 0, (uchar *)&addrbuf, 1);
+			rc = dm_i2c_write(dev, 0, (uchar *)&addrbuf, 1);
  			if (rc == 0)
  				break;  /* Success, break to skip sleep */
  			udelay(SLEEP_DURATION_US);
  		}
  		if (rc)
-			return -rc;
+			return rc;
 
  		/* After the TPM has successfully received the register address
  		 * it needs some time, thus we're sleeping here again, before
@@ -79,7 +80,7 @@ static int tpm_tis_i2c_read(u8 addr, u8 *buffer, size_t len)
  		 */
  		for (count = 0; count < MAX_COUNT; count++) {
  			udelay(SLEEP_DURATION_US);
-			rc = dm_i2c_read(g_chip.dev, 0, buffer, len);
+			rc = dm_i2c_read(dev, 0, buffer, len);
  			if (rc == 0)
  				break;  /* success, break to skip sleep */
  		}
@@ -92,7 +93,7 @@ static int tpm_tis_i2c_read(u8 addr, u8 *buffer, size_t len)
  		 * be safe on the safe side.
  		 */
  		for (count = 0; count < MAX_COUNT; count++) {
-			rc = dm_i2c_read(g_chip.dev, addr, buffer, len);
+			rc = dm_i2c_read(dev, addr, buffer, len);
  			if (rc == 0)
  				break;  /* break here to skip sleep */
  			udelay(SLEEP_DURATION_US);
@@ -102,19 +103,30 @@ static int tpm_tis_i2c_read(u8 addr, u8 *buffer, size_t len)
  	/* Take care of 'guard time' */
  	udelay(SLEEP_DURATION_US);
  	if (rc)
-		return -rc;
+		return rc;
 
  	return 0;
  }
 
-static int tpm_tis_i2c_write_generic(u8 addr, u8 *buffer, size_t len,
-				     unsigned int sleep_time_us, u8 max_count)
+static int tpm_tis_i2c_write_generic(struct udevice *dev, u8 addr, u8 *buffer,
+				     size_t len, unsigned int sleep_time_us,
+				     u8 max_count)
  {
+	struct tpm_chip *chip = dev_get_priv(dev);
  	int rc = 0;
  	int count;
 
+	if (chip->chip_type == SLB9635) {
+		/* Prepare send buffer to include the address */
+		chip->buf[0] = addr;
+		memcpy(&(chip->buf[1]), buffer, len);
+		buffer = chip->buf;
+		len++;
+		addr = 0;
+	}
+
  	for (count = 0; count < max_count; count++) {
-		rc = dm_i2c_write(g_chip.dev, addr, buffer, len);
+		rc = dm_i2c_write(dev, addr, buffer, len);
  		if (rc == 0)
  			break;  /* Success, break to skip sleep */
  		udelay(sleep_time_us);
@@ -123,7 +135,7 @@ static int tpm_tis_i2c_write_generic(u8 addr, u8 *buffer, size_t len,
  	/* take care of 'guard time' */
  	udelay(sleep_time_us);
  	if (rc)
-		return -rc;
+		return rc;
 
  	return 0;
  }
@@ -144,30 +156,33 @@ static int tpm_tis_i2c_write_generic(u8 addr, u8 *buffer, size_t len,
   *
   * Return -EIO on error, 0 on success
   */
-static int tpm_tis_i2c_write(u8 addr, u8 *buffer, size_t len)
+static int tpm_tis_i2c_write(struct udevice *dev, u8 addr, u8 *buffer,
+			     size_t len)
  {
-	return tpm_tis_i2c_write_generic(addr, buffer, len, SLEEP_DURATION_US,
-					 MAX_COUNT);
+	return tpm_tis_i2c_write_generic(dev, addr, buffer, len,
+					 SLEEP_DURATION_US, MAX_COUNT);
  }
 
  /*
   * This function is needed especially for the cleanup situation after
   * sending TPM_READY
   */
-static int tpm_tis_i2c_write_long(u8 addr, u8 *buffer, size_t len)
+static int tpm_tis_i2c_write_long(struct udevice *dev, u8 addr, u8 *buffer,
+				  size_t len)
  {
-	return tpm_tis_i2c_write_generic(addr, buffer, len,
+	return tpm_tis_i2c_write_generic(dev, addr, buffer, len,
  					 SLEEP_DURATION_LONG_US,
  					 MAX_COUNT_LONG);
  }
 
-static int tpm_tis_i2c_check_locality(struct tpm_chip *chip, int loc)
+static int tpm_tis_i2c_check_locality(struct udevice *dev, int loc)
  {
  	const u8 mask = TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID;
+	struct tpm_chip *chip = dev_get_priv(dev);
  	u8 buf;
  	int rc;
 
-	rc = tpm_tis_i2c_read(TPM_ACCESS(loc), &buf, 1);
+	rc = tpm_tis_i2c_read(dev, TPM_ACCESS(loc), &buf, 1);
  	if (rc < 0)
  		return rc;
 
@@ -176,34 +191,38 @@ static int tpm_tis_i2c_check_locality(struct tpm_chip *chip, int loc)
  		return loc;
  	}
 
-	return -1;
+	return -ENOENT;
  }
 
-static void tpm_tis_i2c_release_locality(struct tpm_chip *chip, int loc,
+static void tpm_tis_i2c_release_locality(struct udevice *dev, int loc,
  					 int force)
  {
  	const u8 mask = TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID;
  	u8 buf;
 
-	if (tpm_tis_i2c_read(TPM_ACCESS(loc), &buf, 1) < 0)
+	if (tpm_tis_i2c_read(dev, TPM_ACCESS(loc), &buf, 1) < 0)
  		return;
 
  	if (force || (buf & mask) == mask) {
  		buf = TPM_ACCESS_ACTIVE_LOCALITY;
-		tpm_tis_i2c_write(TPM_ACCESS(loc), &buf, 1);
+		tpm_tis_i2c_write(dev, TPM_ACCESS(loc), &buf, 1);
  	}
  }
 
-static int tpm_tis_i2c_request_locality(struct tpm_chip *chip, int loc)
+static int tpm_tis_i2c_request_locality(struct udevice *dev, int loc)
  {
+	struct tpm_chip *chip = dev_get_priv(dev);
  	unsigned long start, stop;
  	u8 buf = TPM_ACCESS_REQUEST_USE;
  	int rc;
 
-	if (tpm_tis_i2c_check_locality(chip, loc) >= 0)
+	rc = tpm_tis_i2c_check_locality(dev, loc);
+	if (rc >= 0)
  		return loc;  /* We already have the locality */
+	else if (rc != -ENOENT)
+		return rc;
 
-	rc = tpm_tis_i2c_write(TPM_ACCESS(loc), &buf, 1);
+	rc = tpm_tis_i2c_write(dev, TPM_ACCESS(loc), &buf, 1);
  	if (rc)
  		return rc;
 
@@ -211,40 +230,46 @@ static int tpm_tis_i2c_request_locality(struct tpm_chip *chip, int loc)
  	start = get_timer(0);
  	stop = chip->timeout_a;
  	do {
-		if (tpm_tis_i2c_check_locality(chip, loc) >= 0)
+		rc = tpm_tis_i2c_check_locality(dev, loc);
+		if (rc >= 0)
  			return loc;
+		else if (rc != -ENOENT)
+			return rc;
  		mdelay(TPM_TIMEOUT_MS);
  	} while (get_timer(start) < stop);
 
-	return -1;
+	return rc;
  }
 
-static u8 tpm_tis_i2c_status(struct tpm_chip *chip)
+static u8 tpm_tis_i2c_status(struct udevice *dev)
  {
+	struct tpm_chip *chip = dev_get_priv(dev);
  	/* NOTE: Since i2c read may fail, return 0 in this case --> time-out */
  	u8 buf;
 
-	if (tpm_tis_i2c_read(TPM_STS(chip->locality), &buf, 1) < 0)
+	if (tpm_tis_i2c_read(dev, TPM_STS(chip->locality), &buf, 1) < 0)
  		return 0;
  	else
  		return buf;
  }
 
-static void tpm_tis_i2c_ready(struct tpm_chip *chip)
+static void tpm_tis_i2c_ready(struct udevice *dev)
  {
+	struct tpm_chip *chip = dev_get_priv(dev);
  	int rc;
 
  	/* This causes the current command to be aborted */
  	u8 buf = TPM_STS_COMMAND_READY;
 
  	debug("%s\n", __func__);
-	rc = tpm_tis_i2c_write_long(TPM_STS(chip->locality), &buf, 1);
+	rc = tpm_tis_i2c_write_long(dev, TPM_STS(chip->locality), &buf, 1);
  	if (rc)
  		debug("%s: rc=%d\n", __func__, rc);
  }
 
-static ssize_t tpm_tis_i2c_get_burstcount(struct tpm_chip *chip)
+static ssize_t tpm_tis_i2c_get_burstcount(struct udevice *dev)
  {
+	struct tpm_chip *chip = dev_get_priv(dev);
  	unsigned long start, stop;
  	ssize_t burstcnt;
  	u8 addr, buf[3];
@@ -256,7 +281,7 @@ static ssize_t tpm_tis_i2c_get_burstcount(struct tpm_chip *chip)
  	do {
  		/* Note: STS is little endian */
  		addr = TPM_STS(chip->locality) + 1;
-		if (tpm_tis_i2c_read(addr, buf, 3) < 0)
+		if (tpm_tis_i2c_read(dev, addr, buf, 3) < 0)
  			burstcnt = 0;
  		else
  			burstcnt = (buf[2] << 16) + (buf[1] << 8) + buf[0];
@@ -269,13 +294,13 @@ static ssize_t tpm_tis_i2c_get_burstcount(struct tpm_chip *chip)
  	return -EBUSY;
  }
 
-static int tpm_tis_i2c_wait_for_stat(struct tpm_chip *chip, u8 mask,
+static int tpm_tis_i2c_wait_for_stat(struct udevice *dev, u8 mask,
  				     unsigned long timeout, int *status)
  {
  	unsigned long start, stop;
 
  	/* Check current status */
-	*status = tpm_tis_i2c_status(chip);
+	*status = tpm_tis_i2c_status(dev);
  	if ((*status & mask) == mask)
  		return 0;
 
@@ -283,7 +308,7 @@ static int tpm_tis_i2c_wait_for_stat(struct tpm_chip *chip, u8 mask,
  	stop = timeout;
  	do {
  		mdelay(TPM_TIMEOUT_MS);
-		*status = tpm_tis_i2c_status(chip);
+		*status = tpm_tis_i2c_status(dev);
  		if ((*status & mask) == mask)
  			return 0;
  	} while (get_timer(start) < stop);
@@ -291,14 +316,15 @@ static int tpm_tis_i2c_wait_for_stat(struct tpm_chip *chip, u8 mask,
  	return -ETIME;
  }
 
-static int tpm_tis_i2c_recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
+static int tpm_tis_i2c_recv_data(struct udevice *dev, u8 *buf, size_t count)
  {
+	struct tpm_chip *chip = dev_get_priv(dev);
  	size_t size = 0;
  	ssize_t burstcnt;
  	int rc;
 
  	while (size < count) {
-		burstcnt = tpm_tis_i2c_get_burstcount(chip);
+		burstcnt = tpm_tis_i2c_get_burstcount(dev);
 
  		/* burstcount < 0 -> tpm is busy */
  		if (burstcnt < 0)
@@ -308,8 +334,8 @@ static int tpm_tis_i2c_recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
  		if (burstcnt > (count - size))
  			burstcnt = count - size;
 
-		rc = tpm_tis_i2c_read(TPM_DATA_FIFO(chip->locality),
-				&(buf[size]), burstcnt);
+		rc = tpm_tis_i2c_read(dev, TPM_DATA_FIFO(chip->locality),
+				      &(buf[size]), burstcnt);
  		if (rc == 0)
  			size += burstcnt;
  	}
@@ -317,8 +343,9 @@ static int tpm_tis_i2c_recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
  	return size;
  }
 
-static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
+static int tpm_tis_i2c_recv(struct udevice *dev, u8 *buf, size_t count)
  {
+	struct tpm_chip *chip = dev_get_priv(dev);
  	int size = 0;
  	int expected, status;
 
@@ -328,7 +355,7 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
  	}
 
  	/* Read first 10 bytes, including tag, paramsize, and result */
-	size = tpm_tis_i2c_recv_data(chip, buf, TPM_HEADER_SIZE);
+	size = tpm_tis_i2c_recv_data(dev, buf, TPM_HEADER_SIZE);
  	if (size < TPM_HEADER_SIZE) {
  		error("Unable to read header\n");
  		goto out;
@@ -342,7 +369,7 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
  		goto out;
  	}
 
-	size += tpm_tis_i2c_recv_data(chip, &buf[TPM_HEADER_SIZE],
+	size += tpm_tis_i2c_recv_data(dev, &buf[TPM_HEADER_SIZE],
  				      expected - TPM_HEADER_SIZE);
  	if (size < expected) {
  		error("Unable to read remainder of result\n");
@@ -350,7 +377,7 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
  		goto out;
  	}
 
-	tpm_tis_i2c_wait_for_stat(chip, TPM_STS_VALID, chip->timeout_c,
+	tpm_tis_i2c_wait_for_stat(dev, TPM_STS_VALID, chip->timeout_c,
  				  &status);
  	if (status & TPM_STS_DATA_AVAIL) {  /* Retry? */
  		error("Error left over data\n");
@@ -359,19 +386,20 @@ static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
  	}
 
  out:
-	tpm_tis_i2c_ready(chip);
+	tpm_tis_i2c_ready(dev);
  	/*
  	 * The TPM needs some time to clean up here,
  	 * so we sleep rather than keeping the bus busy
  	 */
  	mdelay(2);
-	tpm_tis_i2c_release_locality(chip, chip->locality, 0);
+	tpm_tis_i2c_release_locality(dev, chip->locality, 0);
 
  	return size;
  }
 
-static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
+static int tpm_tis_i2c_send(struct udevice *dev, u8 *buf, size_t len)
  {
+	struct tpm_chip *chip = dev_get_priv(dev);
  	int rc, status;
  	size_t burstcnt;
  	size_t count = 0;
@@ -382,20 +410,20 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
  	if (len > TPM_DEV_BUFSIZE)
  		return -E2BIG;  /* Command is too long for our tpm, sorry */
 
-	if (tpm_tis_i2c_request_locality(chip, 0) < 0)
+	if (tpm_tis_i2c_request_locality(dev, 0) < 0)
  		return -EBUSY;
 
-	status = tpm_tis_i2c_status(chip);
+	status = tpm_tis_i2c_status(dev);
  	if ((status & TPM_STS_COMMAND_READY) == 0) {
-		tpm_tis_i2c_ready(chip);
-		if (tpm_tis_i2c_wait_for_stat(chip, TPM_STS_COMMAND_READY,
+		tpm_tis_i2c_ready(dev);
+		if (tpm_tis_i2c_wait_for_stat(dev, TPM_STS_COMMAND_READY,
  					      chip->timeout_b, &status) < 0) {
  			rc = -ETIME;
  			goto out_err;
  		}
  	}
 
-	burstcnt = tpm_tis_i2c_get_burstcount(chip);
+	burstcnt = tpm_tis_i2c_get_burstcount(dev);
 
  	/* burstcount < 0 -> tpm is busy */
  	if (burstcnt < 0)
@@ -407,12 +435,12 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
  			burstcnt = len - count;
 
  #ifdef CONFIG_TPM_TIS_I2C_BURST_LIMITATION
-		if (retry && burstcnt > CONFIG_TPM_TIS_I2C_BURST_LIMITATION)
-			burstcnt = CONFIG_TPM_TIS_I2C_BURST_LIMITATION;
+		if (retry && burstcnt > CONFIG_TPM_TIS_I2C_BURST_LIMITATION_LEN)
+			burstcnt = CONFIG_TPM_TIS_I2C_BURST_LIMITATION_LEN;
  #endif /* CONFIG_TPM_TIS_I2C_BURST_LIMITATION */
 
-		rc = tpm_tis_i2c_write(TPM_DATA_FIFO(chip->locality),
-				&(buf[count]), burstcnt);
+		rc = tpm_tis_i2c_write(dev, TPM_DATA_FIFO(chip->locality),
+				       &(buf[count]), burstcnt);
  		if (rc == 0)
  			count += burstcnt;
  		else {
@@ -421,7 +449,7 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
  				rc = -EIO;
  				goto out_err;
  			}
-			rc = tpm_tis_i2c_wait_for_stat(chip, TPM_STS_VALID,
+			rc = tpm_tis_i2c_wait_for_stat(dev, TPM_STS_VALID,
  						       chip->timeout_c,
  						       &status);
  			if (rc)
@@ -435,46 +463,31 @@ static int tpm_tis_i2c_send(struct tpm_chip *chip, u8 *buf, size_t len)
  	}
 
  	/* Go and do it */
-	tpm_tis_i2c_write(TPM_STS(chip->locality), &sts, 1);
+	tpm_tis_i2c_write(dev, TPM_STS(chip->locality), &sts, 1);
  	debug("done\n");
 
  	return len;
 
  out_err:
  	debug("%s: out_err\n", __func__);
-	tpm_tis_i2c_ready(chip);
+	tpm_tis_i2c_ready(dev);
  	/*
  	 * The TPM needs some time to clean up here,
  	 * so we sleep rather than keeping the bus busy
  	 */
  	mdelay(2);
-	tpm_tis_i2c_release_locality(chip, chip->locality, 0);
+	tpm_tis_i2c_release_locality(dev, chip->locality, 0);
 
  	return rc;
  }
 
-static enum i2c_chip_type tpm_tis_i2c_chip_type(void)
-{
-#ifdef CONFIG_OF_CONTROL
-	const void *blob = gd->fdt_blob;
-
-	if (fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9645_TPM) >= 0)
-		return SLB9645;
-
-	if (fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM) >= 0)
-		return SLB9635;
-#endif
-	return UNKNOWN;
-}
-
  static int tpm_tis_i2c_init(struct udevice *dev)
  {
-	struct tpm_chip *chip = &g_chip;
+	struct tpm_chip *chip = dev_get_priv(dev);
  	u32 vendor;
  	u32 expected_did_vid;
+	int rc;
 
-	g_chip.dev = dev;
-	g_chip.chip_type = tpm_tis_i2c_chip_type();
  	chip->is_open = 1;
 
  	/* Disable interrupts (not supported) */
@@ -489,16 +502,17 @@ static int tpm_tis_i2c_init(struct udevice *dev)
  	chip->req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID;
  	chip->req_canceled = TPM_STS_COMMAND_READY;
 
-	if (tpm_tis_i2c_request_locality(chip, 0) < 0)
-		return  -ENODEV;
+	rc = tpm_tis_i2c_request_locality(dev, 0);
+	if (rc < 0)
+		return rc;
 
  	/* Read four bytes from DID_VID register */
-	if (tpm_tis_i2c_read(TPM_DID_VID(0), (uchar *)&vendor, 4) < 0) {
-		tpm_tis_i2c_release_locality(chip, 0, 1);
+	if (tpm_tis_i2c_read(dev, TPM_DID_VID(0), (uchar *)&vendor, 4) < 0) {
+		tpm_tis_i2c_release_locality(dev, 0, 1);
  		return -EIO;
  	}
 
-	if (g_chip.chip_type == SLB9635) {
+	if (chip->chip_type == SLB9635) {
  		vendor = be32_to_cpu(vendor);
  		expected_did_vid = TPM_TIS_I2C_DID_VID_9635;
  	} else {
@@ -506,13 +520,14 @@ static int tpm_tis_i2c_init(struct udevice *dev)
  		expected_did_vid = TPM_TIS_I2C_DID_VID_9645;
  	}
 
-	if (g_chip.chip_type != UNKNOWN && vendor != expected_did_vid) {
+	if (chip->chip_type != UNKNOWN && vendor != expected_did_vid) {
  		error("Vendor id did not match! ID was %08x\n", vendor);
  		return -ENODEV;
  	}
 
+	chip->vend_dev = vendor;
  	debug("1.2 TPM (chip type %s device-id 0x%X)\n",
-	      chip_name[g_chip.chip_type], vendor >> 16);
+	      chip_name[chip->chip_type], vendor >> 16);
 
  	/*
  	 * A timeout query to TPM can be placed here.
@@ -546,14 +561,14 @@ static unsigned long tpm_tis_i2c_calc_ordinal_duration(struct tpm_chip *chip,
  		return duration;
  }
 
-static ssize_t tpm_tis_i2c_transmit(const unsigned char *buf, size_t bufsiz)
+static ssize_t tpm_tis_i2c_transmit(struct udevice *dev,
+				    const unsigned char *buf, size_t bufsiz)
  {
+	struct tpm_chip *chip = dev_get_priv(dev);
  	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);
@@ -568,7 +583,7 @@ static ssize_t tpm_tis_i2c_transmit(const unsigned char *buf, size_t bufsiz)
  	}
 
  	debug("Calling send\n");
-	rc = tpm_tis_i2c_send(chip, (u8 *)buf, count);
+	rc = tpm_tis_i2c_send(dev, (u8 *)buf, count);
  	debug("   ... done calling send\n");
  	if (rc < 0) {
  		error("tpm_transmit: tpm_send: error %d\n", rc);
@@ -582,7 +597,7 @@ static ssize_t tpm_tis_i2c_transmit(const unsigned char *buf, size_t bufsiz)
  	stop = tpm_tis_i2c_calc_ordinal_duration(chip, ordinal);
  	do {
  		debug("waiting for status... %ld %ld\n", start, stop);
-		u8 status = tpm_tis_i2c_status(chip);
+		u8 status = tpm_tis_i2c_status(dev);
  		if ((status & chip->req_complete_mask) ==
  		    chip->req_complete_val) {
  			debug("...got it;\n");
@@ -597,14 +612,14 @@ static ssize_t tpm_tis_i2c_transmit(const unsigned char *buf, size_t bufsiz)
  		mdelay(TPM_TIMEOUT_MS);
  	} while (get_timer(start) < stop);
 
-	tpm_tis_i2c_ready(chip);
+	tpm_tis_i2c_ready(dev);
  	error("Operation Timed out\n");
  	rc = -ETIME;
  	goto out;
 
  out_recv:
  	debug("out_recv: reading response...\n");
-	rc = tpm_tis_i2c_recv(chip, (u8 *)buf, TPM_BUFSIZE);
+	rc = tpm_tis_i2c_recv(dev, (u8 *)buf, TPM_BUFSIZE);
  	if (rc < 0)
  		error("tpm_transmit: tpm_recv: error %d\n", rc);
 
@@ -612,131 +627,51 @@ out:
  	return rc;
  }
 
-/**
- * Decode TPM configuration.
- *
- * @param dev	Returns a configuration of TPM device
- * @return 0 if ok, -1 on error
- */
-static int tpm_tis_i2c_decode_config(struct tpm_chip *chip)
-{
-	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 at 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 at chromium.org): Older TPMs will need to use the older method
-	 * in tpm_tis_i2c_read() so the offset length needs to be 0 here.
-	 */
-	ret = i2c_get_chip(bus, chip_addr, 1, &chip->dev);
-	if (ret) {
-		debug("Cannot find device for node '%s: ret=%d'\n",
-		      fdt_get_name(blob, node, NULL), ret);
-		return ret;
-	}
-
-	return 0;
-}
-
-int tis_init(void)
-{
-	if (g_chip.inited)
-		return 0;
-
-	if (tpm_tis_i2c_decode_config(&g_chip))
-		return -1;
-
-	debug("%s: done\n", __func__);
-
-	g_chip.inited = 1;
-
-	return 0;
-}
-
-int tis_open(void)
+static int tpm_tis_i2c_open(struct udevice *dev)
  {
+	struct tpm_chip *chip = dev_get_priv(dev);
  	int rc;
 
-	if (!g_chip.inited)
-		return -1;
-
  	debug("%s: start\n", __func__);
-	if (g_chip.is_open)
+	if (chip->is_open)
  		return -EBUSY;
-	rc = tpm_tis_i2c_init(g_chip.dev);
+	rc = tpm_tis_i2c_init(dev);
  	if (rc < 0)
-		g_chip.is_open = 0;
+		chip->is_open = 0;
 
  	return rc;
  }
 
-int tis_close(void)
+static int tpm_tis_i2c_close(struct udevice *dev)
  {
-	if (!g_chip.inited)
-		return -1;
+	struct tpm_chip *chip = dev_get_priv(dev);
 
-	if (g_chip.is_open) {
-		tpm_tis_i2c_release_locality(&g_chip, g_chip.locality, 1);
-		g_chip.is_open = 0;
+	if (chip->is_open) {
+		tpm_tis_i2c_release_locality(dev, chip->locality, 1);
+		chip->is_open = 0;
+		chip->vend_dev = 0;
  	}
 
  	return 0;
  }
 
-int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
-		uint8_t *recvbuf, size_t *rbuf_len)
+static int tpm_tis_i2c_xfer(struct udevice *dev, const uint8_t *sendbuf,
+			    size_t sbuf_size, uint8_t *recvbuf,
+			    size_t *rbuf_len)
  {
  	int len;
  	uint8_t buf[4096];
 
-	if (!g_chip.inited)
-		return -1;
-
  	if (sizeof(buf) < sbuf_size)
-		return -1;
+		return -ENOSPC;
 
  	memcpy(buf, sendbuf, sbuf_size);
 
-	len = tpm_tis_i2c_transmit(buf, sbuf_size);
+	len = tpm_tis_i2c_transmit(dev, buf, sbuf_size);
 
  	if (len < 10) {
  		*rbuf_len = 0;
-		return -1;
+		return -EBADMSG;
  	}
 
  	memcpy(recvbuf, buf, len);
@@ -744,3 +679,47 @@ int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size,
 
  	return 0;
  }
+
+static int tpm_tis_get_desc(struct udevice *dev, char *buf, int size)
+{
+	struct tpm_chip *chip = dev_get_priv(dev);
+
+	if (size < 50)
+		return -ENOSPC;
+
+	return snprintf(buf, size, "1.2 TPM (%s, chip type %s device-id 0x%x)",
+			chip->is_open ? "open" : "closed",
+			chip_name[chip->chip_type],
+			chip->vend_dev >> 16);
+}
+
+static int tpm_tis_i2c_probe(struct udevice *dev)
+{
+	struct tpm_chip *chip = dev_get_priv(dev);
+
+	chip->chip_type = dev_get_driver_data(dev);
+
+	return 0;
+}
+
+static const struct tpm_ops tpm_tis_i2c_ops = {
+	.open		= tpm_tis_i2c_open,
+	.close		= tpm_tis_i2c_close,
+	.get_desc	= tpm_tis_get_desc,
+	.xfer		= tpm_tis_i2c_xfer,
+};
+
+static const struct udevice_id tpm_tis_i2c_ids[] = {
+	{ .compatible = "infineon,slb9635tt", .data = SLB9635 },
+	{ .compatible = "infineon,slb9645tt", .data = SLB9645 },
+	{ }
+};
+
+U_BOOT_DRIVER(tpm_tis_i2c) = {
+	.name   = "tpm_tis_i2c",
+	.id     = UCLASS_TPM,
+	.of_match = tpm_tis_i2c_ids,
+	.ops    = &tpm_tis_i2c_ops,
+	.probe	= tpm_tis_i2c_probe,
+	.priv_auto_alloc_size = sizeof(struct tpm_chip),
+};
drivers/tpm/tpm_tis_i2c.h +1 -2
index ecdaf0c..324a3e5 100644
@@ -47,16 +47,15 @@ enum i2c_chip_type {
  };
 
  struct tpm_chip {
-	bool inited;
  	int is_open;
  	u8 req_complete_mask;
  	u8 req_complete_val;
  	u8 req_canceled;
  	int irq;
  	int locality;
+	u32 vend_dev;
  	unsigned long timeout_a, timeout_b, timeout_c, timeout_d;  /* msec */
  	unsigned long duration[3];  /* msec */
-	struct udevice *dev;
  	u8 buf[TPM_DEV_BUFSIZE + sizeof(u8)];  /* Max buffer size + addr */
  	enum i2c_chip_type chip_type;
  };
include/fdtdec.h +0 -2
index eac679e..3062635 100644
@@ -164,8 +164,6 @@ enum fdt_compat_id {
  	COMPAT_MAXIM_MAX77686_PMIC,	/* MAX77686 PMIC */
  	COMPAT_GENERIC_SPI_FLASH,	/* Generic SPI Flash chip */
  	COMPAT_MAXIM_98095_CODEC,	/* MAX98095 Codec */
-	COMPAT_INFINEON_SLB9635_TPM,	/* Infineon SLB9635 TPM */
-	COMPAT_INFINEON_SLB9645_TPM,	/* Infineon SLB9645 TPM */
  	COMPAT_SAMSUNG_EXYNOS5_I2C,	/* Exynos5 High Speed I2C Controller */
  	COMPAT_SANDBOX_LCD_SDL,		/* Sandbox LCD emulation with SDL */
  	COMPAT_SAMSUNG_EXYNOS_SYSMMU,	/* Exynos sysmmu */
lib/fdtdec.c +0 -2
index b201787..6b67670 100644
@@ -58,8 +58,6 @@ static const char * const compat_names[COMPAT_COUNT] = {
  	COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686"),
  	COMPAT(GENERIC_SPI_FLASH, "spi-flash"),
  	COMPAT(MAXIM_98095_CODEC, "maxim,max98095-codec"),
-	COMPAT(INFINEON_SLB9635_TPM, "infineon,slb9635-tpm"),
-	COMPAT(INFINEON_SLB9645_TPM, "infineon,slb9645tt"),
  	COMPAT(SAMSUNG_EXYNOS5_I2C, "samsung,exynos5-hsi2c"),
  	COMPAT(SANDBOX_LCD_SDL, "sandbox,lcd-sdl"),
  	COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"),
#53 lore raw

PATCH 23/25 dm: tpm: Convert LPC driver to driver model

In reply to Simon Glass

Convert the tpm_tis_lpc driver to use driver model and update boards which use it.

---

 configs/chromebook_link_defconfig   |   2 +
 configs/chromebox_panther_defconfig |   2 +
 configs/coreboot-x86_defconfig      |   2 +
 drivers/tpm/tpm_tis_lpc.c           | 291 +++++++++++++++++-------------------
 4 files changed, 147 insertions(+), 150 deletions(-)
configs/chromebook_link_defconfig +2 -0
index b0fc5ca..85752e4 100644
@@ -11,12 +11,14 @@ CONFIG_HAVE_VGA_BIOS=y
 CONFIG_BOOTSTAGE=y
 CONFIG_BOOTSTAGE_REPORT=y
 CONFIG_CMD_BOOTSTAGE=y
+CONFIG_CMD_TPM=y
 CONFIG_OF_CONTROL=y
 CONFIG_DM_PCI=y
 CONFIG_SPI_FLASH=y
 CONFIG_CMD_CROS_EC=y
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_LPC=y
+CONFIG_DM_TPM=y
 CONFIG_TPM_TIS_LPC=y
 CONFIG_VIDEO_VESA=y
 CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
configs/chromebox_panther_defconfig +2 -0
index e7ef8fe..a6bafe3 100644
@@ -11,12 +11,14 @@ CONFIG_HAVE_VGA_BIOS=y
 CONFIG_BOOTSTAGE=y
 CONFIG_BOOTSTAGE_REPORT=y
 CONFIG_CMD_BOOTSTAGE=y
+CONFIG_CMD_TPM=y
 CONFIG_OF_CONTROL=y
 CONFIG_DM_PCI=y
 CONFIG_SPI_FLASH=y
 CONFIG_CMD_CROS_EC=y
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_LPC=y
+CONFIG_DM_TPM=y
 CONFIG_TPM_TIS_LPC=y
 CONFIG_VIDEO_VESA=y
 CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
configs/coreboot-x86_defconfig +2 -0
index fc6410b..6d47a58 100644
@@ -9,9 +9,11 @@ CONFIG_TSC_CALIBRATION_BYPASS=y
 CONFIG_BOOTSTAGE=y
 CONFIG_BOOTSTAGE_REPORT=y
 CONFIG_CMD_BOOTSTAGE=y
+CONFIG_CMD_TPM=y
 CONFIG_OF_CONTROL=y
 CONFIG_DM_PCI=y
 CONFIG_SPI_FLASH=y
+CONFIG_DM_TPM=y
 CONFIG_TPM_TIS_LPC=y
 CONFIG_USE_PRIVATE_LIBGCC=y
 CONFIG_SYS_VSNPRINTF=y
drivers/tpm/tpm_tis_lpc.c +141 -150

511 lines not on this page · raw message

Signature · 1 line
2.5.0.rc2.392.g76e840b
#54 lore raw

PATCH 23/25 dm: tpm: Convert LPC driver to driver model

Hi Simon,

Ok for now, except with the xfer handler.

Best Regards
Christophe

Quoted 594 lines · Simon Glass

Convert the tpm_tis_lpc driver to use driver model and update boards which use it.

---

  configs/chromebook_link_defconfig   |   2 +
  configs/chromebox_panther_defconfig |   2 +
  configs/coreboot-x86_defconfig      |   2 +
  drivers/tpm/tpm_tis_lpc.c           | 291 +++++++++++++++++-------------------
  4 files changed, 147 insertions(+), 150 deletions(-)
configs/chromebook_link_defconfig +2 -0
index b0fc5ca..85752e4 100644
@@ -11,12 +11,14 @@ CONFIG_HAVE_VGA_BIOS=y
  CONFIG_BOOTSTAGE=y
  CONFIG_BOOTSTAGE_REPORT=y
  CONFIG_CMD_BOOTSTAGE=y
+CONFIG_CMD_TPM=y
  CONFIG_OF_CONTROL=y
  CONFIG_DM_PCI=y
  CONFIG_SPI_FLASH=y
  CONFIG_CMD_CROS_EC=y
  CONFIG_CROS_EC=y
  CONFIG_CROS_EC_LPC=y
+CONFIG_DM_TPM=y
  CONFIG_TPM_TIS_LPC=y
  CONFIG_VIDEO_VESA=y
  CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
configs/chromebox_panther_defconfig +2 -0
index e7ef8fe..a6bafe3 100644
@@ -11,12 +11,14 @@ CONFIG_HAVE_VGA_BIOS=y
  CONFIG_BOOTSTAGE=y
  CONFIG_BOOTSTAGE_REPORT=y
  CONFIG_CMD_BOOTSTAGE=y
+CONFIG_CMD_TPM=y
  CONFIG_OF_CONTROL=y
  CONFIG_DM_PCI=y
  CONFIG_SPI_FLASH=y
  CONFIG_CMD_CROS_EC=y
  CONFIG_CROS_EC=y
  CONFIG_CROS_EC_LPC=y
+CONFIG_DM_TPM=y
  CONFIG_TPM_TIS_LPC=y
  CONFIG_VIDEO_VESA=y
  CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
configs/coreboot-x86_defconfig +2 -0
index fc6410b..6d47a58 100644
@@ -9,9 +9,11 @@ CONFIG_TSC_CALIBRATION_BYPASS=y
  CONFIG_BOOTSTAGE=y
  CONFIG_BOOTSTAGE_REPORT=y
  CONFIG_CMD_BOOTSTAGE=y
+CONFIG_CMD_TPM=y
  CONFIG_OF_CONTROL=y
  CONFIG_DM_PCI=y
  CONFIG_SPI_FLASH=y
+CONFIG_DM_TPM=y
  CONFIG_TPM_TIS_LPC=y
  CONFIG_USE_PRIVATE_LIBGCC=y
  CONFIG_SYS_VSNPRINTF=y
drivers/tpm/tpm_tis_lpc.c +141 -150
index d09f8ce..13c1534 100644
@@ -14,8 +14,11 @@
   */
 
  #include <common.h>
-#include <asm/io.h>
+#include <dm.h>
+#include <mapmem.h>
+#include <tis.h>
  #include <tpm.h>
+#include <asm/io.h>
 
  #define PREFIX "lpc_tpm: "
 
@@ -36,13 +39,15 @@ struct tpm_locality {
  	u8 padding4[251];
  };
 
+struct tpm_tis_lpc_priv {
+	struct tpm_locality *regs;
+};
+
  /*
   * This pointer refers to the TPM chip, 5 of its localities are mapped as an
   * array.
   */
  #define TPM_TOTAL_LOCALITIES	5
-static struct tpm_locality *lpc_tpm_dev =
-	(struct tpm_locality *)CONFIG_TPM_TIS_BASE_ADDRESS;
 
  /* Some registers' bit field definitions */
  #define TIS_STS_VALID                  (1 << 7) /* 0x80 */
@@ -63,85 +68,45 @@ static struct tpm_locality *lpc_tpm_dev =
  #define TIS_STS_BURST_COUNT_MASK       (0xffff)
  #define TIS_STS_BURST_COUNT_SHIFT      (8)
 
-/*
- * Error value returned if a tpm register does not enter the expected state
- * after continuous polling. No actual TPM register reading ever returns -1,
- * so this value is a safe error indication to be mixed with possible status
- * register values.
- */
-#define TPM_TIMEOUT_ERR			(-1)
-
-/* Error value returned on various TPM driver errors. */
-#define TPM_DRIVER_ERR		(1)
-
   /* 1 second is plenty for anything TPM does. */
  #define MAX_DELAY_US	(1000 * 1000)
 
  /* Retrieve burst count value out of the status register contents. */
  static u16 burst_count(u32 status)
  {
-	return (status >> TIS_STS_BURST_COUNT_SHIFT) & TIS_STS_BURST_COUNT_MASK;
+	return (status >> TIS_STS_BURST_COUNT_SHIFT) &
+			TIS_STS_BURST_COUNT_MASK;
  }
 
-/*
- * Structures defined below allow creating descriptions of TPM vendor/device
- * ID information for run time discovery. The only device the system knows
- * about at this time is Infineon slb9635.
- */
-struct device_name {
-	u16 dev_id;
-	const char * const dev_name;
-};
-
-struct vendor_name {
-	u16 vendor_id;
-	const char *vendor_name;
-	const struct device_name *dev_names;
-};
-
-static const struct device_name infineon_devices[] = {
-	{0xb, "SLB9635 TT 1.2"},
-	{0}
-};
-
-static const struct vendor_name vendor_names[] = {
-	{0x15d1, "Infineon", infineon_devices},
-};
-
-/*
- * Cached vendor/device ID pair to indicate that the device has been already
- * discovered.
- */
-static u32 vendor_dev_id;
-
  /* TPM access wrappers to support tracing */
-static u8 tpm_read_byte(const u8 *ptr)
+static u8 tpm_read_byte(struct tpm_tis_lpc_priv *priv, const u8 *ptr)
  {
  	u8  ret = readb(ptr);
  	debug(PREFIX "Read reg 0x%4.4x returns 0x%2.2x\n",
-	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)lpc_tpm_dev, ret);
+	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, ret);
  	return ret;
  }
 
-static u32 tpm_read_word(const u32 *ptr)
+static u32 tpm_read_word(struct tpm_tis_lpc_priv *priv, const u32 *ptr)
  {
  	u32  ret = readl(ptr);
  	debug(PREFIX "Read reg 0x%4.4x returns 0x%8.8x\n",
-	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)lpc_tpm_dev, ret);
+	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, ret);
  	return ret;
  }
 
-static void tpm_write_byte(u8 value, u8 *ptr)
+static void tpm_write_byte(struct tpm_tis_lpc_priv *priv, u8 value, u8 *ptr)
  {
  	debug(PREFIX "Write reg 0x%4.4x with 0x%2.2x\n",
-	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)lpc_tpm_dev, value);
+	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, value);
  	writeb(value, ptr);
  }
 
-static void tpm_write_word(u32 value, u32 *ptr)
+static void tpm_write_word(struct tpm_tis_lpc_priv *priv, u32 value,
+			   u32 *ptr)
  {
  	debug(PREFIX "Write reg 0x%4.4x with 0x%8.8x\n",
-	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)lpc_tpm_dev, value);
+	      (u32)(uintptr_t)ptr - (u32)(uintptr_t)priv->regs, value);
  	writel(value, ptr);
  }
 
@@ -156,67 +121,51 @@ static void tpm_write_word(u32 value, u32 *ptr)
   * @expected - value the field(s) are supposed to be set to
   *
   * Returns the register contents in case the expected value was found in the
- * appropriate register bits, or TPM_TIMEOUT_ERR on timeout.
+ * appropriate register bits, or -ETIMEDOUT on timeout.
   */
-static u32 tis_wait_reg(u32 *reg, u8 mask, u8 expected)
+static int tis_wait_reg(struct tpm_tis_lpc_priv *priv, u32 *reg, u8 mask,
+			u8 expected)
  {
  	u32 time_us = MAX_DELAY_US;
 
  	while (time_us > 0) {
-		u32 value = tpm_read_word(reg);
+		u32 value = tpm_read_word(priv, reg);
  		if ((value & mask) == expected)
  			return value;
  		udelay(1); /* 1 us */
  		time_us--;
  	}
-	return TPM_TIMEOUT_ERR;
+
+	return -ETIMEDOUT;
  }
 
  /*
   * Probe the TPM device and try determining its manufacturer/device name.
   *
- * Returns 0 on success (the device is found or was found during an earlier
- * invocation) or TPM_DRIVER_ERR if the device is not found.
+ * Returns 0 on success, -ve on error
   */
-int tis_init(void)
+static int tpm_tis_lpc_probe(struct udevice *dev)
  {
-	u32 didvid = tpm_read_word(&lpc_tpm_dev[0].did_vid);
-	int i;
-	const char *device_name = "unknown";
-	const char *vendor_name = device_name;
-	u16 vid, did;
-
-	if (vendor_dev_id)
-		return 0;  /* Already probed. */
-
-	if (!didvid || (didvid == 0xffffffff)) {
-		printf("%s: No TPM device found\n", __func__);
-		return TPM_DRIVER_ERR;
-	}
+	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
+	u32 vid, did;
+	fdt_addr_t addr;
+	u32 didvid;
 
-	vendor_dev_id = didvid;
+	addr = dev_get_addr(dev);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+	priv->regs = map_sysmem(addr, 0);
+	didvid = tpm_read_word(priv, &priv->regs[0].did_vid);
 
  	vid = didvid & 0xffff;
  	did = (didvid >> 16) & 0xffff;
-	for (i = 0; i < ARRAY_SIZE(vendor_names); i++) {
-		int j = 0;
-		u16 known_did;
-
-		if (vid == vendor_names[i].vendor_id)
-			vendor_name = vendor_names[i].vendor_name;
-
-		while ((known_did = vendor_names[i].dev_names[j].dev_id) != 0) {
-			if (known_did == did) {
-				device_name =
-					vendor_names[i].dev_names[j].dev_name;
-				break;
-			}
-			j++;
-		}
-		break;
+	if (vid != 0x15d1 || did != 0xb) {
+		debug("Invalid vendor/device ID %04x/%04x\n", vid, did);
+		return -ENOSYS;
  	}
 
-	printf("Found TPM %s by %s\n", device_name, vendor_name);
+	debug("Found TPM %s by %s\n", "SLB9635 TT 1.2", "Infineon");
+
  	return 0;
  }
 
@@ -228,23 +177,25 @@ int tis_init(void)
   * @data - address of the data to send, byte by byte
   * @len - length of the data to send
   *
- * Returns 0 on success, TPM_DRIVER_ERR on error (in case the device does
- * not accept the entire command).
+ * Returns 0 on success, -ve on error (in case the device does not accept
+ * the entire command).
   */
-static u32 tis_senddata(const u8 * const data, u32 len)
+static u32 tis_senddata(struct tpm_tis_lpc_priv *priv, const u8 * const data,
+			u32 len)
  {
+	struct tpm_locality *regs = priv->regs;
  	u32 offset = 0;
  	u16 burst = 0;
  	u32 max_cycles = 0;
  	u8 locality = 0;
  	u32 value;
 
-	value = tis_wait_reg(&lpc_tpm_dev[locality].tpm_status,
+	value = tis_wait_reg(priv, &regs[locality].tpm_status,
  			     TIS_STS_COMMAND_READY, TIS_STS_COMMAND_READY);
-	if (value == TPM_TIMEOUT_ERR) {
+	if (value == -ETIMEDOUT) {
  		printf("%s:%d - failed to get 'command_ready' status\n",
  		       __FILE__, __LINE__);
-		return TPM_DRIVER_ERR;
+		return value;
  	}
  	burst = burst_count(value);
 
@@ -256,11 +207,11 @@ static u32 tis_senddata(const u8 * const data, u32 len)
  			if (max_cycles++ == MAX_DELAY_US) {
  				printf("%s:%d failed to feed %d bytes of %d\n",
  				       __FILE__, __LINE__, len - offset, len);
-				return TPM_DRIVER_ERR;
+				return -ETIMEDOUT;
  			}
  			udelay(1);
-			burst = burst_count(tpm_read_word(&lpc_tpm_dev
-						     [locality].tpm_status));
+			burst = burst_count(tpm_read_word(priv,
+					&regs[locality].tpm_status));
  		}
 
  		max_cycles = 0;
@@ -276,16 +227,16 @@ static u32 tis_senddata(const u8 * const data, u32 len)
  		 */
  		count = min((u32)burst, len - offset - 1);
  		while (count--)
-			tpm_write_byte(data[offset++],
-				  &lpc_tpm_dev[locality].data);
+			tpm_write_byte(priv, data[offset++],
+				       &regs[locality].data);
 
-		value = tis_wait_reg(&lpc_tpm_dev[locality].tpm_status,
+		value = tis_wait_reg(priv, &regs[locality].tpm_status,
  				     TIS_STS_VALID, TIS_STS_VALID);
 
-		if ((value == TPM_TIMEOUT_ERR) || !(value & TIS_STS_EXPECT)) {
+		if ((value == -ETIMEDOUT) || !(value & TIS_STS_EXPECT)) {
  			printf("%s:%d TPM command feed overflow\n",
  			       __FILE__, __LINE__);
-			return TPM_DRIVER_ERR;
+			return value == -ETIMEDOUT ? value : -EIO;
  		}
 
  		burst = burst_count(value);
@@ -300,21 +251,21 @@ static u32 tis_senddata(const u8 * const data, u32 len)
  	}
 
  	/* Send the last byte. */
-	tpm_write_byte(data[offset++], &lpc_tpm_dev[locality].data);
+	tpm_write_byte(priv, data[offset++], &regs[locality].data);
  	/*
  	 * Verify that TPM does not expect any more data as part of this
  	 * command.
  	 */
-	value = tis_wait_reg(&lpc_tpm_dev[locality].tpm_status,
+	value = tis_wait_reg(priv, &regs[locality].tpm_status,
  			     TIS_STS_VALID, TIS_STS_VALID);
-	if ((value == TPM_TIMEOUT_ERR) || (value & TIS_STS_EXPECT)) {
+	if ((value == -ETIMEDOUT) || (value & TIS_STS_EXPECT)) {
  		printf("%s:%d unexpected TPM status 0x%x\n",
  		       __FILE__, __LINE__, value);
-		return TPM_DRIVER_ERR;
+		return value == -ETIMEDOUT ? value : -EIO;
  	}
 
  	/* OK, sitting pretty, let's start the command execution. */
-	tpm_write_word(TIS_STS_TPM_GO, &lpc_tpm_dev[locality].tpm_status);
+	tpm_write_word(priv, TIS_STS_TPM_GO, &regs[locality].tpm_status);
  	return 0;
  }
 
@@ -328,10 +279,12 @@ static u32 tis_senddata(const u8 * const data, u32 len)
   *
   * On success stores the number of received bytes to len and returns 0. On
   * errors (misformatted TPM data or synchronization problems) returns
- * TPM_DRIVER_ERR.
+ * -ve value.
   */
-static u32 tis_readresponse(u8 *buffer, u32 *len)
+static u32 tis_readresponse(struct tpm_tis_lpc_priv *priv, u8 *buffer,
+			    u32 *len)
  {
+	struct tpm_locality *regs = priv->regs;
  	u16 burst;
  	u32 value;
  	u32 offset = 0;
@@ -341,12 +294,12 @@ static u32 tis_readresponse(u8 *buffer, u32 *len)
  	int max_cycles = 0;
 
  	/* Wait for the TPM to process the command. */
-	value = tis_wait_reg(&lpc_tpm_dev[locality].tpm_status,
+	value = tis_wait_reg(priv, &regs[locality].tpm_status,
  			      has_data, has_data);
-	if (value == TPM_TIMEOUT_ERR) {
+	if (value == -ETIMEDOUT) {
  		printf("%s:%d failed processing command\n",
  		       __FILE__, __LINE__);
-		return TPM_DRIVER_ERR;
+		return value;
  	}
 
  	do {
@@ -354,18 +307,18 @@ static u32 tis_readresponse(u8 *buffer, u32 *len)
  			if (max_cycles++ == MAX_DELAY_US) {
  				printf("%s:%d TPM stuck on read\n",
  				       __FILE__, __LINE__);
-				return TPM_DRIVER_ERR;
+				return -EIO;
  			}
  			udelay(1);
-			value = tpm_read_word(&lpc_tpm_dev
-					      [locality].tpm_status);
+			value = tpm_read_word(priv,
+					      &regs[locality].tpm_status);
  		}
 
  		max_cycles = 0;
 
  		while (burst-- && (offset < expected_count)) {
-			buffer[offset++] = tpm_read_byte(&lpc_tpm_dev
-							 [locality].data);
+			buffer[offset++] = tpm_read_byte(priv,
+						&regs[locality].data);
 
  			if (offset == 6) {
  				/*
@@ -386,18 +339,18 @@ static u32 tis_readresponse(u8 *buffer, u32 *len)
  					printf("%s:%d bad response size %d\n",
  					       __FILE__, __LINE__,
  					       expected_count);
-					return TPM_DRIVER_ERR;
+					return -ENOSPC;
  				}
  			}
  		}
 
  		/* Wait for the next portion. */
-		value = tis_wait_reg(&lpc_tpm_dev[locality].tpm_status,
+		value = tis_wait_reg(priv, &regs[locality].tpm_status,
  				     TIS_STS_VALID, TIS_STS_VALID);
-		if (value == TPM_TIMEOUT_ERR) {
+		if (value == -ETIMEDOUT) {
  			printf("%s:%d failed to read response\n",
  			       __FILE__, __LINE__);
-			return TPM_DRIVER_ERR;
+			return value;
  		}
 
  		if (offset == expected_count)
@@ -412,68 +365,106 @@ static u32 tis_readresponse(u8 *buffer, u32 *len)
  	if (value & TIS_STS_DATA_AVAILABLE) {
  		printf("%s:%d wrong receive status %x\n",
  		       __FILE__, __LINE__, value);
-		return TPM_DRIVER_ERR;
+		return -EBADMSG;
  	}
 
  	/* Tell the TPM that we are done. */
-	tpm_write_word(TIS_STS_COMMAND_READY, &lpc_tpm_dev
-		  [locality].tpm_status);
+	tpm_write_word(priv, TIS_STS_COMMAND_READY,
+		       &regs[locality].tpm_status);
  	*len = offset;
  	return 0;
  }
 
-int tis_open(void)
+static int tpm_tis_lpc_open(struct udevice *dev)
  {
+	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
+	struct tpm_locality *regs = priv->regs;
  	u8 locality = 0; /* we use locality zero for everything. */
-
-	if (tis_close())
-		return TPM_DRIVER_ERR;
+	int ret;
 
  	/* now request access to locality. */
-	tpm_write_word(TIS_ACCESS_REQUEST_USE, &lpc_tpm_dev[locality].access);
+	tpm_write_word(priv, TIS_ACCESS_REQUEST_USE, &regs[locality].access);
 
  	/* did we get a lock? */
-	if (tis_wait_reg(&lpc_tpm_dev[locality].access,
+	ret = tis_wait_reg(priv, &regs[locality].access,
  			 TIS_ACCESS_ACTIVE_LOCALITY,
-			 TIS_ACCESS_ACTIVE_LOCALITY) == TPM_TIMEOUT_ERR) {
+			 TIS_ACCESS_ACTIVE_LOCALITY);
+	if (ret == -ETIMEDOUT) {
  		printf("%s:%d - failed to lock locality %d\n",
  		       __FILE__, __LINE__, locality);
-		return TPM_DRIVER_ERR;
+		return ret;
  	}
 
-	tpm_write_word(TIS_STS_COMMAND_READY,
-		       &lpc_tpm_dev[locality].tpm_status);
+	tpm_write_word(priv, TIS_STS_COMMAND_READY,
+		       &regs[locality].tpm_status);
  	return 0;
  }
 
-int tis_close(void)
+static int tpm_tis_lpc_close(struct udevice *dev)
  {
+	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
+	struct tpm_locality *regs = priv->regs;
  	u8 locality = 0;
 
-	if (tpm_read_word(&lpc_tpm_dev[locality].access) &
+	if (tpm_read_word(priv, &regs[locality].access) &
  	    TIS_ACCESS_ACTIVE_LOCALITY) {
-		tpm_write_word(TIS_ACCESS_ACTIVE_LOCALITY,
-			       &lpc_tpm_dev[locality].access);
+		tpm_write_word(priv, TIS_ACCESS_ACTIVE_LOCALITY,
+			       &regs[locality].access);
 
-		if (tis_wait_reg(&lpc_tpm_dev[locality].access,
+		if (tis_wait_reg(priv, &regs[locality].access,
  				 TIS_ACCESS_ACTIVE_LOCALITY, 0) ==
-		    TPM_TIMEOUT_ERR) {
+		    -ETIMEDOUT) {
  			printf("%s:%d - failed to release locality %d\n",
  			       __FILE__, __LINE__, locality);
-			return TPM_DRIVER_ERR;
+			return -ETIMEDOUT;
  		}
  	}
  	return 0;
  }
 
-int tis_sendrecv(const u8 *sendbuf, size_t send_size,
-		 u8 *recvbuf, size_t *recv_len)
+static int tpm_tis_lpc_xfer(struct udevice *dev, const u8 *sendbuf,
+			    size_t send_size, u8 *recvbuf, size_t *recv_len)
  {
-	if (tis_senddata(sendbuf, send_size)) {
+	struct tpm_tis_lpc_priv *priv = dev_get_priv(dev);
+	int ret;
+
+	ret = tis_senddata(priv, sendbuf, send_size);
+	if (ret) {
  		printf("%s:%d failed sending data to TPM\n",
  		       __FILE__, __LINE__);
-		return TPM_DRIVER_ERR;
+		return ret;
  	}
 
-	return tis_readresponse(recvbuf, (u32 *)recv_len);
+	return tis_readresponse(priv, recvbuf, (u32 *)recv_len);
+}
+
+static int tpm_tis_get_desc(struct udevice *dev, char *buf, int size)
+{
+	if (size < 50)
+		return -ENOSPC;
+
+	return snprintf(buf, size, "1.2 TPM (vendor %s, chip %s)",
+			"Infineon", "SLB9635 TT 1.2");
  }
+
+
+static const struct tpm_ops tpm_tis_lpc_ops = {
+	.open		= tpm_tis_lpc_open,
+	.close		= tpm_tis_lpc_close,
+	.get_desc	= tpm_tis_get_desc,
+	.xfer		= tpm_tis_lpc_xfer,
+};
+
+static const struct udevice_id tpm_tis_lpc_ids[] = {
+	{ .compatible = "infineon,slb9635lpc" },
+	{ }
+};
+
+U_BOOT_DRIVER(tpm_tis_lpc) = {
+	.name   = "tpm_tis_lpc",
+	.id     = UCLASS_TPM,
+	.of_match = tpm_tis_lpc_ids,
+	.ops    = &tpm_tis_lpc_ops,
+	.probe	= tpm_tis_lpc_probe,
+	.priv_auto_alloc_size = sizeof(struct tpm_tis_lpc_priv),
+};
#55 lore raw

PATCH 24/25 tpm: Add a 'tpm info' command

In reply to Simon Glass

Add a command to display basic information about a TPM such as the model and open/close state. This can be useful for debugging.

---

 common/cmd_tpm.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)
common/cmd_tpm.c +26 -0
index 2783895..3d0adf8 100644
@@ -456,6 +456,26 @@ static int get_tpm(struct udevice **devp)
 
 	return 0;
 }
+
+static int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc,
+		       char *const argv[])
+{
+	struct udevice *dev;
+	char buf[80];
+	int rc;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
+	rc = tis_get_desc(dev, buf, sizeof(buf));
+	if (rc < 0) {
+		printf("Couldn't get TPM info (%d)\n", rc);
+		return CMD_RET_FAILURE;
+	}
+	printf("%s\n", buf);
+
+	return 0;
+}
 #endif
 
 static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag,
@@ -637,6 +657,9 @@ TPM_COMMAND_NO_ARG(tpm_end_oiap)
 	U_BOOT_CMD_MKENT(cmd, 0, 1, do_tpm_ ## cmd, "", "")
 
 static cmd_tbl_t tpm_commands[] = {
+#ifdef CONFIG_DM_TPM
+	U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
+#endif
 	U_BOOT_CMD_MKENT(init, 0, 1,
 			do_tpm_init, "", ""),
 	U_BOOT_CMD_MKENT(startup, 0, 1,
@@ -707,6 +730,9 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
 "cmd args...\n"
 "    - Issue TPM command <cmd> with arguments <args...>.\n"
 "Admin Startup and State Commands:\n"
+#ifdef CONFIG_DM_TPM
+"  info - Show information about the TPM\n"
+#endif
 "  init\n"
 "    - Put TPM into a state where it waits for 'startup' command.\n"
 "  startup mode\n"
Signature · 1 line
2.5.0.rc2.392.g76e840b
#56 lore raw

PATCH 24/25 tpm: Add a 'tpm info' command

Hi Simon,

Best Regards
Christophe

Quoted 60 lines · Simon Glass

Add a command to display basic information about a TPM such as the model and open/close state. This can be useful for debugging.

---

  common/cmd_tpm.c | 26 ++++++++++++++++++++++++++
  1 file changed, 26 insertions(+)
common/cmd_tpm.c +26 -0
index 2783895..3d0adf8 100644
@@ -456,6 +456,26 @@ static int get_tpm(struct udevice **devp)
 
  	return 0;
  }
+
+static int do_tpm_info(cmd_tbl_t *cmdtp, int flag, int argc,
+		       char *const argv[])
+{
+	struct udevice *dev;
+	char buf[80];
+	int rc;
+
+	rc = get_tpm(&dev);
+	if (rc)
+		return rc;
+	rc = tis_get_desc(dev, buf, sizeof(buf));
+	if (rc < 0) {
+		printf("Couldn't get TPM info (%d)\n", rc);
+		return CMD_RET_FAILURE;
+	}
+	printf("%s\n", buf);
+
+	return 0;
+}
  #endif
 
  static int do_tpm_raw_transfer(cmd_tbl_t *cmdtp, int flag,
@@ -637,6 +657,9 @@ TPM_COMMAND_NO_ARG(tpm_end_oiap)
  	U_BOOT_CMD_MKENT(cmd, 0, 1, do_tpm_ ## cmd, "", "")
 
  static cmd_tbl_t tpm_commands[] = {
+#ifdef CONFIG_DM_TPM
+	U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""),
+#endif
  	U_BOOT_CMD_MKENT(init, 0, 1,
  			do_tpm_init, "", ""),
  	U_BOOT_CMD_MKENT(startup, 0, 1,
@@ -707,6 +730,9 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
  "cmd args...\n"
  "    - Issue TPM command <cmd> with arguments <args...>.\n"
  "Admin Startup and State Commands:\n"
+#ifdef CONFIG_DM_TPM
+"  info - Show information about the TPM\n"
+#endif
  "  init\n"
  "    - Put TPM into a state where it waits for 'startup' command.\n"
  "  startup mode\n"
#57 lore raw

PATCH 25/25 tegra: nyan: Enable TPM command and driver

In reply to Simon Glass

The TPM is listed in the device tree. Enable the driver and 'tpm' command so that it can be used.

---

 configs/nyan-big_defconfig | 4 ++++
 1 file changed, 4 insertions(+)
configs/nyan-big_defconfig +4 -0
index 2b26841..4be6e4f 100644
@@ -9,15 +9,19 @@ CONFIG_DEFAULT_DEVICE_TREE="tegra124-nyan-big"
 # CONFIG_CMD_FPGA is not set
 # CONFIG_CMD_SETEXPR is not set
 # CONFIG_CMD_NFS is not set
+CONFIG_CMD_TPM=y
 CONFIG_SPL_DM=y
 CONFIG_SPI_FLASH=y
 CONFIG_CMD_CROS_EC=y
 CONFIG_CROS_EC=y
 CONFIG_CROS_EC_SPI=y
 CONFIG_CROS_EC_KEYB=y
+CONFIG_DM_TPM=y
+CONFIG_TPM_TIS_I2C=y
 CONFIG_TEGRA114_SPI=y
 CONFIG_DISPLAY_PORT=y
 CONFIG_VIDEO_TEGRA124=y
 CONFIG_USB=y
 CONFIG_DM_USB=y
+CONFIG_TPM=y
 CONFIG_USE_PRIVATE_LIBGCC=y
Signature · 1 line
2.5.0.rc2.392.g76e840b
#58 lore raw

PATCH 25/25 tegra: nyan: Enable TPM command and driver

Hi Simon,

Best Regards
Christophe

Quoted 33 lines · Simon Glass

The TPM is listed in the device tree. Enable the driver and 'tpm' command so that it can be used.

---

  configs/nyan-big_defconfig | 4 ++++
  1 file changed, 4 insertions(+)
configs/nyan-big_defconfig +4 -0
index 2b26841..4be6e4f 100644
@@ -9,15 +9,19 @@ CONFIG_DEFAULT_DEVICE_TREE="tegra124-nyan-big"
  # CONFIG_CMD_FPGA is not set
  # CONFIG_CMD_SETEXPR is not set
  # CONFIG_CMD_NFS is not set
+CONFIG_CMD_TPM=y
  CONFIG_SPL_DM=y
  CONFIG_SPI_FLASH=y
  CONFIG_CMD_CROS_EC=y
  CONFIG_CROS_EC=y
  CONFIG_CROS_EC_SPI=y
  CONFIG_CROS_EC_KEYB=y
+CONFIG_DM_TPM=y
+CONFIG_TPM_TIS_I2C=y
  CONFIG_TEGRA114_SPI=y
  CONFIG_DISPLAY_PORT=y
  CONFIG_VIDEO_TEGRA124=y
  CONFIG_USB=y
  CONFIG_DM_USB=y
+CONFIG_TPM=y
  CONFIG_USE_PRIVATE_LIBGCC=y
#59 lore raw

cover dm: Convert TPM drivers to driver model

In reply to Simon Glass

Hi Simon,

I pretty much like the move to driver model for TPM. However, i have some few remarks:

The current i2c driver stick to Infineon TPMs and will not support any other vendors like ST(in my case).
The main reason for this is that there is no transport protocol over I2C specification defined by the Trusted Computing Group for TPM1.2. You can take a look at my release tentative here:
http://lists.denx.de/pipermail/u-boot/2015-August/222596.html

The tpm.c file was delivering a way to ajust best the waiting time for command duration to receive a command answer from a TPM command. It was ported from Linux to u-boot.
You can find in chapter 17 how the table tpm_protected_ordinal_duration, tpm_ordinal_duration were build.
(https://www.trustedcomputinggroup.org/files/resource_files/E14876A3-1A4B-B294-D086297A1ED38F96/mainP2Structrev103.pdf)
This is defined by the TCG and followed by TPM vendors. In u-boot, this is used only by Infineon i2c driver but it could/should(?) be used by all other drivers (i2c and lpc).

In short, the idea is to keep the way TPM commands are transfered giving the hands to drivers for handling the communication over a specified or proprietary transport protocol.

I fear the current approach would lead to duplicated codes on may TPM drivers and 2 very differents kind of drivers (Linux/u-boot) very far from each other.

Would it be possible to have your comments on my proposal ?
http://lists.denx.de/pipermail/u-boot/2015-August/222596.html

Best Regards
Christophe

Quoted 96 lines · Simon Glass

This series adds driver model support for Trusted Platform Modules (TPMs). These have a very simple interface and are configured via the device tree.

Two bus types are supported at present: I2C and LPC (Intel Low-Pin-Count).

Most drivers and users are converted over to driver model. The exception is the Atmel TPM and its users.

The I2C driver has been cleaned up and simplified. It was ported from Linux and was pretty hard to follow. This series includes patches to unify the code, remove duplicated data structures and drop unnecessary indirection.

Also this series enables the TPM on all Chromebooks (snow, spring, nyan-big, pit, pi, link) since some did not have it fully enabled.

As before, the 'tpm' command can be used to implement TPM functionality.

Simon Glass (25):
tpm: Remove old pre-driver-model I2C code
tpm: Drop two unused options
tpm: Add Kconfig options for TPMs
tpm: Convert board config TPM options to Kconfig
tpm: Convert drivers to use SPDX
tpm: Move the I2C TPM code into one file
tpm: tpm_tis_i2c: Drop unnecessary methods
tpm: tpm_tis_i2c: Drop struct tpm_vendor_specific
tpm: tpm_tis_i2c: Merge struct tpm_dev into tpm_chip
tpm: tpm_tis_i2c: Merge struct tpm into tpm_chip
tpm: tpm_tis_i2c: Move definitions into the header file
tpm: tpm_tis_i2c: Simplify init code
tpm: tpm_tis_i2c: Use a consistent tpm_tis_i2c_ prefix
tpm: tpm_tis_i2c: Tidy up delays
dm: tpm: Add a uclass for Trusted Platform Modules
dm: tpm: Convert the TPM command and library to driver model
dm: i2c: Add a command to adjust the offset length
tpm: Report tpm errors on the command line
dm: tpm: sandbox: Convert TPM driver to driver model
tpm: Check that parse_byte_string() has data to parse
exynos: x86: dts: Add tpm nodes to the device tree for Chrome OS
devices
dm: tpm: Convert I2C driver to driver model
dm: tpm: Convert LPC driver to driver model
tpm: Add a 'tpm info' command
tegra: nyan: Enable TPM command and driver

  README                                             |   6 -
  arch/arm/dts/exynos5250-snow.dts                   |   9 +
  arch/arm/dts/exynos5250-spring.dts                 |   8 +
  arch/arm/dts/exynos5420-peach-pit.dts              |   6 +-
  arch/arm/dts/exynos5800-peach-pi.dts               |   6 +-
  arch/sandbox/dts/sandbox.dts                       |   4 +
  arch/x86/dts/chromebook_link.dts                   |   5 +
  common/Kconfig                                     |  12 +
  common/cmd_i2c.c                                   |  33 +
  common/cmd_tpm.c                                   | 100 ++-
  configs/chromebook_link_defconfig                  |   4 +
  configs/chromebox_panther_defconfig                |   4 +
  .../controlcenterd_36BIT_SDCARD_DEVELOP_defconfig  |   4 +
  configs/controlcenterd_36BIT_SDCARD_defconfig      |   4 +
  .../controlcenterd_TRAILBLAZER_DEVELOP_defconfig   |   4 +
  configs/controlcenterd_TRAILBLAZER_defconfig       |   4 +
  configs/coreboot-x86_defconfig                     |   4 +
  configs/nyan-big_defconfig                         |   4 +
  configs/peach-pi_defconfig                         |   4 +
  configs/peach-pit_defconfig                        |   4 +
  configs/sandbox_defconfig                          |   3 +
  configs/snow_defconfig                             |   4 +
  configs/spring_defconfig                           |   4 +
  drivers/tpm/Kconfig                                |  61 ++
  drivers/tpm/Makefile                               |   4 +-
  drivers/tpm/tpm-uclass.c                           |  57 ++
  drivers/tpm/tpm.c                                  | 694 ---------------------
  drivers/tpm/tpm_atmel_twi.c                        |  15 +-
  drivers/tpm/tpm_private.h                          | 140 -----
  drivers/tpm/tpm_tis_i2c.c                          | 594 ++++++++++--------
  drivers/tpm/tpm_tis_i2c.h                          | 446 +++++++++++++
  drivers/tpm/tpm_tis_lpc.c                          | 291 +++++----
  drivers/tpm/tpm_tis_sandbox.c                      |  48 +-
  include/configs/controlcenterd.h                   |   7 -
  include/configs/efi-x86.h                          |   2 -
  include/configs/exynos5-common.h                   |   7 -
  include/configs/x86-common.h                       |   2 -
  include/dm/uclass-id.h                             |   1 +
  include/fdtdec.h                                   |   2 -
  include/tis.h                                      |  97 +++
  include/tpm.h                                      |   2 +-
  lib/Kconfig                                        |  10 +
  lib/fdtdec.c                                       |   2 -
  lib/tpm.c                                          |  29 +-
  44 files changed, 1404 insertions(+), 1347 deletions(-)

create mode 100644 drivers/tpm/tpm-uclass.c
delete mode 100644 drivers/tpm/tpm.c
delete mode 100644 drivers/tpm/tpm_private.h
create mode 100644 drivers/tpm/tpm_tis_i2c.h

#60 lore raw

cover dm: Convert TPM drivers to driver model

Hi Christophe,

Quoted 11 lines · christophe.ricard

Hi Simon,

I pretty much like the move to driver model for TPM. However, i have some few remarks:

The current i2c driver stick to Infineon TPMs and will not support any other vendors like ST(in my case).
The main reason for this is that there is no transport protocol over I2C specification defined by the Trusted Computing Group for TPM1.2. You can take a look at my release tentative here:
http://lists.denx.de/pipermail/u-boot/2015-August/222596.html

Yes I agree it's probably better to rename it. One more patch...

Quoted 11 lines

The tpm.c file was delivering a way to ajust best the waiting time for command duration to receive a command answer from a TPM command. It was ported from Linux to u-boot.
You can find in chapter 17 how the table tpm_protected_ordinal_duration, tpm_ordinal_duration were build.
(https://www.trustedcomputinggroup.org/files/resource_files/E14876A3-1A4B-B294-D086297A1ED38F96/mainP2Structrev103.pdf)
This is defined by the TCG and followed by TPM vendors. In u-boot, this is used only by Infineon i2c driver but it could/should(?) be used by all other drivers (i2c and lpc).

Quoted 7 lines

In short, the idea is to keep the way TPM commands are transfered giving the hands to drivers for handling the communication over a specified or proprietary transport protocol.

I fear the current approach would lead to duplicated codes on may TPM drivers and 2 very differents kind of drivers (Linux/u-boot) very far from each other.

In that case we should define what the interface is for the TPM. My approach is to provide a low-level interface which takes care of open/close, and sending and receiving bytes.

Since that interface doesn't understand the actual commands it can't attach different timeouts to each. On the other hand as you say only one driver uses it.

But since tpm_transmit() currently looks inside the packet, I don't see why the new xfer() method could not do that also. It removes one layer of itnerfaces.

Do all TPMs use the same commands and timeouts?

In general Linux has ad-hoc interfaces for different things, but in U-Boot we are trying to standardise on driver model, so normally function pointers would end up implemented there.

Quoted 3 lines

Would it be possible to have your comments on my proposal ?
http://lists.denx.de/pipermail/u-boot/2015-August/222596.html

OK I'll take a look.

Quoted 109 lines

Best Regards
Christophe

Quoted 102 lines · Simon Glass

This series adds driver model support for Trusted Platform Modules (TPMs). These have a very simple interface and are configured via the device tree.

Two bus types are supported at present: I2C and LPC (Intel Low-Pin-Count).

Most drivers and users are converted over to driver model. The exception is
the Atmel TPM and its users.

The I2C driver has been cleaned up and simplified. It was ported from Linux
and was pretty hard to follow. This series includes patches to unify the code, remove duplicated data structures and drop unnecessary indirection.

Also this series enables the TPM on all Chromebooks (snow, spring, nyan-big,
pit, pi, link) since some did not have it fully enabled.

As before, the 'tpm' command can be used to implement TPM functionality.

Simon Glass (25):
tpm: Remove old pre-driver-model I2C code
tpm: Drop two unused options
tpm: Add Kconfig options for TPMs
tpm: Convert board config TPM options to Kconfig
tpm: Convert drivers to use SPDX
tpm: Move the I2C TPM code into one file
tpm: tpm_tis_i2c: Drop unnecessary methods
tpm: tpm_tis_i2c: Drop struct tpm_vendor_specific
tpm: tpm_tis_i2c: Merge struct tpm_dev into tpm_chip
tpm: tpm_tis_i2c: Merge struct tpm into tpm_chip
tpm: tpm_tis_i2c: Move definitions into the header file
tpm: tpm_tis_i2c: Simplify init code
tpm: tpm_tis_i2c: Use a consistent tpm_tis_i2c_ prefix
tpm: tpm_tis_i2c: Tidy up delays
dm: tpm: Add a uclass for Trusted Platform Modules
dm: tpm: Convert the TPM command and library to driver model
dm: i2c: Add a command to adjust the offset length
tpm: Report tpm errors on the command line
dm: tpm: sandbox: Convert TPM driver to driver model
tpm: Check that parse_byte_string() has data to parse
exynos: x86: dts: Add tpm nodes to the device tree for Chrome OS
devices
dm: tpm: Convert I2C driver to driver model
dm: tpm: Convert LPC driver to driver model
tpm: Add a 'tpm info' command
tegra: nyan: Enable TPM command and driver

  README                                             |   6 -
  arch/arm/dts/exynos5250-snow.dts                   |   9 +
  arch/arm/dts/exynos5250-spring.dts                 |   8 +
  arch/arm/dts/exynos5420-peach-pit.dts              |   6 +-
  arch/arm/dts/exynos5800-peach-pi.dts               |   6 +-
  arch/sandbox/dts/sandbox.dts                       |   4 +
  arch/x86/dts/chromebook_link.dts                   |   5 +
  common/Kconfig                                     |  12 +
  common/cmd_i2c.c                                   |  33 +
  common/cmd_tpm.c                                   | 100 ++-
  configs/chromebook_link_defconfig                  |   4 +
  configs/chromebox_panther_defconfig                |   4 +
  .../controlcenterd_36BIT_SDCARD_DEVELOP_defconfig  |   4 +
  configs/controlcenterd_36BIT_SDCARD_defconfig      |   4 +
  .../controlcenterd_TRAILBLAZER_DEVELOP_defconfig   |   4 +
  configs/controlcenterd_TRAILBLAZER_defconfig       |   4 +
  configs/coreboot-x86_defconfig                     |   4 +
  configs/nyan-big_defconfig                         |   4 +
  configs/peach-pi_defconfig                         |   4 +
  configs/peach-pit_defconfig                        |   4 +
  configs/sandbox_defconfig                          |   3 +
  configs/snow_defconfig                             |   4 +
  configs/spring_defconfig                           |   4 +
  drivers/tpm/Kconfig                                |  61 ++
  drivers/tpm/Makefile                               |   4 +-
  drivers/tpm/tpm-uclass.c                           |  57 ++
  drivers/tpm/tpm.c                                  | 694
---------------------
  drivers/tpm/tpm_atmel_twi.c                        |  15 +-
  drivers/tpm/tpm_private.h                          | 140 -----
  drivers/tpm/tpm_tis_i2c.c                          | 594
++++++++++--------
  drivers/tpm/tpm_tis_i2c.h                          | 446 +++++++++++++
  drivers/tpm/tpm_tis_lpc.c                          | 291 +++++----
  drivers/tpm/tpm_tis_sandbox.c                      |  48 +-
  include/configs/controlcenterd.h                   |   7 -
  include/configs/efi-x86.h                          |   2 -
  include/configs/exynos5-common.h                   |   7 -
  include/configs/x86-common.h                       |   2 -
  include/dm/uclass-id.h                             |   1 +
  include/fdtdec.h                                   |   2 -
  include/tis.h                                      |  97 +++
  include/tpm.h                                      |   2 +-
  lib/Kconfig                                        |  10 +
  lib/fdtdec.c                                       |   2 -
  lib/tpm.c                                          |  29 +-
  44 files changed, 1404 insertions(+), 1347 deletions(-)

create mode 100644 drivers/tpm/tpm-uclass.c
delete mode 100644 drivers/tpm/tpm.c
delete mode 100644 drivers/tpm/tpm_private.h
create mode 100644 drivers/tpm/tpm_tis_i2c.h

#61 lore raw

cover dm: Convert TPM drivers to driver model

Hi Simon,

Thanks for the review and your comments.
Please see mine below:

Quoted 38 lines · Simon Glass

Hi Christophe,

Quoted 11 lines · christophe.ricard

Hi Simon,

I pretty much like the move to driver model for TPM. However, i have some few remarks:

The current i2c driver stick to Infineon TPMs and will not support any other vendors like ST(in my case).
The main reason for this is that there is no transport protocol over I2C specification defined by the Trusted Computing Group for TPM1.2. You can take a look at my release tentative here:
http://lists.denx.de/pipermail/u-boot/2015-August/222596.html

Yes I agree it's probably better to rename it. One more patch...

Quoted 10 lines

The tpm.c file was delivering a way to ajust best the waiting time for command duration to receive a command answer from a TPM command. It was ported from Linux to u-boot.
You can find in chapter 17 how the table tpm_protected_ordinal_duration, tpm_ordinal_duration were build.
(https://www.trustedcomputinggroup.org/files/resource_files/E14876A3-1A4B-B294-D086297A1ED38F96/mainP2Structrev103.pdf)
This is defined by the TCG and followed by TPM vendors. In u-boot, this is used only by Infineon i2c driver but it could/should(?) be used by all other drivers (i2c and lpc).

Quoted 7 lines

In short, the idea is to keep the way TPM commands are transfered giving the hands to drivers for handling the communication over a specified or proprietary transport protocol.

I fear the current approach would lead to duplicated codes on may TPM drivers and 2 very differents kind of drivers (Linux/u-boot) very far from each other.

In that case we should define what the interface is for the TPM. My approach is to provide a low-level interface which takes care of open/close, and sending and receiving bytes.

Quoted 7 lines

Since that interface doesn't understand the actual commands it can't attach different timeouts to each. On the other hand as you say only one driver uses it.

But since tpm_transmit() currently looks inside the packet, I don't see why the new xfer() method could not do that also. It removes one layer of itnerfaces.

I think your approach is acceptable and simplifies the code as well. I would use the send/recv low level interfaces in tis_xfer reproducing the tpm_transmit behavior.

Quoted 2 lines

Do all TPMs use the same commands and timeouts?

My answer is yes with some few informations or highlights.

When it goes with TPM commands, the litteratures is using term "duration". Term "timeout" is used for a lower level layer that may not be used by all TPMs (TIS).

Durations are classified into 3 categories: short, medium and long. Undefined is for non used Ordinals.
Each categories have a predefined value in the standard but TPM vendors are free to modified(greater or lower) them according to their implementation.
Those values can/may be updated using a tpm_getcapability command requiring at least a prior TPM_Startup.
I believe TPM_Startup and the tpm_getcapability(duration) could be executed in tis_open.

Just a nitpick, i believe prefix tis_ for the main TPM class functions may not be appropriate.
What about tcg_ or tpm_ ?

Also, we will have TPM 2.0 would it be acceptable to build a second TPM class to support additional features ?

Quoted 4 lines

In general Linux has ad-hoc interfaces for different things, but in U-Boot we are trying to standardise on driver model, so normally function pointers would end up implemented there.

[...]

Regards
Christophe

#62 lore raw

cover dm: Convert TPM drivers to driver model

Hi Christophe,

Quoted 83 lines · Christophe Ricard

Hi Simon,

Thanks for the review and your comments.
Please see mine below:

Quoted 46 lines · Simon Glass

Hi Christophe,

Quoted 6 lines · christophe.ricard

Hi Simon,

I pretty much like the move to driver model for TPM. However, i have some few remarks:

Quoted 7 lines

The current i2c driver stick to Infineon TPMs and will not support any other
vendors like ST(in my case).
The main reason for this is that there is no transport protocol over I2C specification defined by the Trusted Computing Group for TPM1.2. You can take a look at my release tentative here:
http://lists.denx.de/pipermail/u-boot/2015-August/222596.html

Yes I agree it's probably better to rename it. One more patch...

Quoted 12 lines

The tpm.c file was delivering a way to ajust best the waiting time for command duration to receive a command answer from a TPM command. It was ported from Linux to u-boot.
You can find in chapter 17 how the table tpm_protected_ordinal_duration, tpm_ordinal_duration were build.

(https://www.trustedcomputinggroup.org/files/resource_files/E14876A3-1A4B-B294-D086297A1ED38F96/mainP2Structrev103.pdf)
This is defined by the TCG and followed by TPM vendors. In u-boot, this is
used only by Infineon i2c driver but it could/should(?) be used by all other drivers (i2c and lpc).

Quoted 8 lines

In short, the idea is to keep the way TPM commands are transfered giving the hands to drivers for handling the communication over a specified or proprietary transport protocol.

I fear the current approach would lead to duplicated codes on may TPM drivers and 2 very differents kind of drivers (Linux/u-boot) very far from
each other.

In that case we should define what the interface is for the TPM. My approach is to provide a low-level interface which takes care of open/close, and sending and receiving bytes.

Quoted 7 lines

Since that interface doesn't understand the actual commands it can't attach different timeouts to each. On the other hand as you say only one driver uses it.

But since tpm_transmit() currently looks inside the packet, I don't see why the new xfer() method could not do that also. It removes one layer of itnerfaces.

I think your approach is acceptable and simplifies the code as well. I would use the send/recv low level interfaces in tis_xfer reproducing the tpm_transmit behavior.

Quoted 3 lines

Do all TPMs use the same commands and timeouts?

My answer is yes with some few informations or highlights.

When it goes with TPM commands, the litteratures is using term "duration". Term "timeout" is used for a lower level layer that may not be used by all TPMs (TIS).

Durations are classified into 3 categories: short, medium and long. Undefined is for non used Ordinals.
Each categories have a predefined value in the standard but TPM vendors are free to modified(greater or lower) them according to their implementation. Those values can/may be updated using a tpm_getcapability command requiring at least a prior TPM_Startup.
I believe TPM_Startup and the tpm_getcapability(duration) could be executed in tis_open.

Quoted 3 lines

Just a nitpick, i believe prefix tis_ for the main TPM class functions may not be appropriate.
What about tcg_ or tpm_ ?

Let's go with tpm then, at least it is clear.

Quoted 3 lines

Also, we will have TPM 2.0 would it be acceptable to build a second TPM class to support additional features ?

Is it incompatible with the driver API we are talking about (open, close, send, recv)?

Quoted 8 lines
Quoted 5 lines

In general Linux has ad-hoc interfaces for different things, but in U-Boot we are trying to standardise on driver model, so normally function pointers would end up implemented there.

[...]

Regards,
Simon

#63 lore raw

cover dm: Convert TPM drivers to driver model

Hi Christophe,

Quoted 91 lines · Simon Glass

Hi Christophe,

Quoted 83 lines · Christophe Ricard

Hi Simon,

Thanks for the review and your comments.
Please see mine below:

Quoted 46 lines · Simon Glass

Hi Christophe,

Quoted 6 lines · christophe.ricard

Hi Simon,

I pretty much like the move to driver model for TPM. However, i have some few remarks:

Quoted 7 lines

The current i2c driver stick to Infineon TPMs and will not support any other
vendors like ST(in my case).
The main reason for this is that there is no transport protocol over I2C specification defined by the Trusted Computing Group for TPM1.2. You can take a look at my release tentative here:
http://lists.denx.de/pipermail/u-boot/2015-August/222596.html

Yes I agree it's probably better to rename it. One more patch...

Quoted 12 lines

The tpm.c file was delivering a way to ajust best the waiting time for command duration to receive a command answer from a TPM command. It was ported from Linux to u-boot.
You can find in chapter 17 how the table tpm_protected_ordinal_duration, tpm_ordinal_duration were build.

(https://www.trustedcomputinggroup.org/files/resource_files/E14876A3-1A4B-B294-D086297A1ED38F96/mainP2Structrev103.pdf)
This is defined by the TCG and followed by TPM vendors. In u-boot, this is
used only by Infineon i2c driver but it could/should(?) be used by all other drivers (i2c and lpc).

Quoted 8 lines

In short, the idea is to keep the way TPM commands are transfered giving the hands to drivers for handling the communication over a specified or proprietary transport protocol.

I fear the current approach would lead to duplicated codes on may TPM drivers and 2 very differents kind of drivers (Linux/u-boot) very far from
each other.

In that case we should define what the interface is for the TPM. My approach is to provide a low-level interface which takes care of open/close, and sending and receiving bytes.

Quoted 7 lines

Since that interface doesn't understand the actual commands it can't attach different timeouts to each. On the other hand as you say only one driver uses it.

But since tpm_transmit() currently looks inside the packet, I don't see why the new xfer() method could not do that also. It removes one layer of itnerfaces.

I think your approach is acceptable and simplifies the code as well. I would use the send/recv low level interfaces in tis_xfer reproducing the tpm_transmit behavior.

Quoted 3 lines

Do all TPMs use the same commands and timeouts?

My answer is yes with some few informations or highlights.

When it goes with TPM commands, the litteratures is using term "duration". Term "timeout" is used for a lower level layer that may not be used by all TPMs (TIS).

Durations are classified into 3 categories: short, medium and long. Undefined is for non used Ordinals.
Each categories have a predefined value in the standard but TPM vendors are free to modified(greater or lower) them according to their implementation. Those values can/may be updated using a tpm_getcapability command requiring at least a prior TPM_Startup.
I believe TPM_Startup and the tpm_getcapability(duration) could be executed in tis_open.

Quoted 3 lines

Just a nitpick, i believe prefix tis_ for the main TPM class functions may not be appropriate.
What about tcg_ or tpm_ ?

Quoted 16 lines

Let's go with tpm then, at least it is clear.

Quoted 3 lines

Also, we will have TPM 2.0 would it be acceptable to build a second TPM class to support additional features ?

Is it incompatible with the driver API we are talking about (open, close, send, recv)?

Quoted 7 lines
Quoted 5 lines

In general Linux has ad-hoc interfaces for different things, but in U-Boot we are trying to standardise on driver model, so normally function pointers would end up implemented there.

[...]

I have a rough crack at this (at u-boot-dm/tpm-working) but have not had a lot of time for this. It will likely be next week before I tidy up and resend the patches.

Regards,
Simon