All of lore.kernel.org
 help / color / mirror / Atom feed
From: christophe.ricard <christophe.ricard@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 22/25] dm: tpm: Convert I2C driver to driver model
Date: Tue, 11 Aug 2015 23:41:22 +0200	[thread overview]
Message-ID: <55CA6C02.9020509@gmail.com> (raw)
In-Reply-To: <1439304497-10081-23-git-send-email-sjg@chromium.org>

Hi Simon,

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

Best Regards
Christophe

On 11/08/2015 16:48, Simon Glass wrote:
> Convert the tpm_tis_i2c driver to use driver model and update boards which
> use it.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>   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(-)
>
> diff --git a/configs/peach-pi_defconfig b/configs/peach-pi_defconfig
> index 5df93b9..215f9ba 100644
> --- a/configs/peach-pi_defconfig
> +++ b/configs/peach-pi_defconfig
> @@ -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
> diff --git a/configs/peach-pit_defconfig b/configs/peach-pit_defconfig
> index e5921ff..40fefc3 100644
> --- a/configs/peach-pit_defconfig
> +++ b/configs/peach-pit_defconfig
> @@ -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
> diff --git a/configs/snow_defconfig b/configs/snow_defconfig
> index 0f7a764..e731608 100644
> --- a/configs/snow_defconfig
> +++ b/configs/snow_defconfig
> @@ -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
> diff --git a/configs/spring_defconfig b/configs/spring_defconfig
> index 1b3daa4..bb4c0ef 100644
> --- a/configs/spring_defconfig
> +++ b/configs/spring_defconfig
> @@ -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
> diff --git a/drivers/tpm/tpm_tis_i2c.c b/drivers/tpm/tpm_tis_i2c.c
> index f1ad596..14ed8f4 100644
> --- a/drivers/tpm/tpm_tis_i2c.c
> +++ b/drivers/tpm/tpm_tis_i2c.c
> @@ -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),
> +};
> diff --git a/drivers/tpm/tpm_tis_i2c.h b/drivers/tpm/tpm_tis_i2c.h
> index ecdaf0c..324a3e5 100644
> --- a/drivers/tpm/tpm_tis_i2c.h
> +++ b/drivers/tpm/tpm_tis_i2c.h
> @@ -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;
>   };
> diff --git a/include/fdtdec.h b/include/fdtdec.h
> index eac679e..3062635 100644
> --- a/include/fdtdec.h
> +++ b/include/fdtdec.h
> @@ -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 */
> diff --git a/lib/fdtdec.c b/lib/fdtdec.c
> index b201787..6b67670 100644
> --- a/lib/fdtdec.c
> +++ b/lib/fdtdec.c
> @@ -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"),

  reply	other threads:[~2015-08-11 21:41 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-11 14:47 [U-Boot] [PATCH 00/25] dm: Convert TPM drivers to driver model Simon Glass
2015-08-11 14:47 ` [U-Boot] [PATCH 01/25] tpm: Remove old pre-driver-model I2C code Simon Glass
2015-08-11 21:41   ` christophe.ricard
2015-08-13  1:30     ` Simon Glass
2015-08-11 14:47 ` [U-Boot] [PATCH 02/25] tpm: Drop two unused options Simon Glass
2015-08-11 21:44   ` christophe.ricard
2015-08-11 14:47 ` [U-Boot] [PATCH 03/25] tpm: Add Kconfig options for TPMs Simon Glass
2015-08-11 21:45   ` christophe.ricard
2015-08-13  1:30     ` Simon Glass
2015-08-11 14:47 ` [U-Boot] [PATCH 04/25] tpm: Convert board config TPM options to Kconfig Simon Glass
2015-08-11 21:45   ` christophe.ricard
2015-08-11 14:47 ` [U-Boot] [PATCH 05/25] tpm: Convert drivers to use SPDX Simon Glass
2015-08-11 21:41   ` christophe.ricard
2015-08-11 14:47 ` [U-Boot] [PATCH 06/25] tpm: Move the I2C TPM code into one file Simon Glass
2015-08-11 21:42   ` christophe.ricard
2015-08-13  1:30     ` Simon Glass
2015-08-13 20:26       ` Christophe Ricard
2015-08-11 14:47 ` [U-Boot] [PATCH 07/25] tpm: tpm_tis_i2c: Drop unnecessary methods Simon Glass
2015-08-11 21:47   ` christophe.ricard
2015-08-13  1:30     ` Simon Glass
2015-08-13 20:28       ` Christophe Ricard
2015-08-13 22:53         ` Simon Glass
2015-08-11 14:48 ` [U-Boot] [PATCH 08/25] tpm: tpm_tis_i2c: Drop struct tpm_vendor_specific Simon Glass
2015-08-11 21:47   ` christophe.ricard
2015-08-13  1:30     ` Simon Glass
2015-08-13 20:32       ` Christophe Ricard
2015-08-13 22:53         ` Simon Glass
2015-08-11 14:48 ` [U-Boot] [PATCH 09/25] tpm: tpm_tis_i2c: Merge struct tpm_dev into tpm_chip Simon Glass
2015-08-11 21:46   ` christophe.ricard
2015-08-11 14:48 ` [U-Boot] [PATCH 10/25] tpm: tpm_tis_i2c: Merge struct tpm " Simon Glass
2015-08-11 21:46   ` christophe.ricard
2015-08-11 14:48 ` [U-Boot] [PATCH 11/25] tpm: tpm_tis_i2c: Move definitions into the header file Simon Glass
2015-08-11 21:45   ` christophe.ricard
2015-08-11 14:48 ` [U-Boot] [PATCH 12/25] tpm: tpm_tis_i2c: Simplify init code Simon Glass
2015-08-11 21:45   ` christophe.ricard
2015-08-11 14:48 ` [U-Boot] [PATCH 13/25] tpm: tpm_tis_i2c: Use a consistent tpm_tis_i2c_ prefix Simon Glass
2015-08-11 21:44   ` christophe.ricard
2015-08-11 14:48 ` [U-Boot] [PATCH 14/25] tpm: tpm_tis_i2c: Tidy up delays Simon Glass
2015-08-11 21:44   ` christophe.ricard
2015-08-11 14:48 ` [U-Boot] [PATCH 15/25] dm: tpm: Add a uclass for Trusted Platform Modules Simon Glass
2015-08-11 21:44   ` christophe.ricard
2015-08-11 14:48 ` [U-Boot] [PATCH 16/25] dm: tpm: Convert the TPM command and library to driver model Simon Glass
2015-08-11 21:43   ` christophe.ricard
2015-08-11 14:48 ` [U-Boot] [PATCH 17/25] dm: i2c: Add a command to adjust the offset length Simon Glass
2015-08-11 14:48 ` [U-Boot] [PATCH 18/25] tpm: Report tpm errors on the command line Simon Glass
2015-08-11 21:43   ` christophe.ricard
2015-08-11 14:48 ` [U-Boot] [PATCH 19/25] dm: tpm: sandbox: Convert TPM driver to driver model Simon Glass
2015-08-11 21:42   ` christophe.ricard
2015-08-11 14:48 ` [U-Boot] [PATCH 20/25] tpm: Check that parse_byte_string() has data to parse Simon Glass
2015-08-11 21:42   ` christophe.ricard
2015-08-11 14:48 ` [U-Boot] [PATCH 21/25] exynos: x86: dts: Add tpm nodes to the device tree for Chrome OS devices Simon Glass
2015-08-11 14:48 ` [U-Boot] [PATCH 22/25] dm: tpm: Convert I2C driver to driver model Simon Glass
2015-08-11 21:41   ` christophe.ricard [this message]
2015-08-11 14:48 ` [U-Boot] [PATCH 23/25] dm: tpm: Convert LPC " Simon Glass
2015-08-11 21:41   ` christophe.ricard
2015-08-11 14:48 ` [U-Boot] [PATCH 24/25] tpm: Add a 'tpm info' command Simon Glass
2015-08-11 21:40   ` christophe.ricard
2015-08-11 14:48 ` [U-Boot] [PATCH 25/25] tegra: nyan: Enable TPM command and driver Simon Glass
2015-08-11 21:40   ` christophe.ricard
2015-08-11 21:50 ` [U-Boot] [PATCH 00/25] dm: Convert TPM drivers to driver model christophe.ricard
2015-08-13  1:30   ` Simon Glass
2015-08-13 20:22     ` Christophe Ricard
2015-08-13 22:52       ` Simon Glass
2015-08-20 21:39         ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=55CA6C02.9020509@gmail.com \
    --to=christophe.ricard@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.