mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	tpm: separate cmd_ready/go_idle from runtime_pm
Fix tpm ptt initialization error: tpm tpm0: A TPM error (378) occurred get tpm pcr allocation. We cannot use go_idle cmd_ready commands via runtime_pm handles as with the introduction of localities this is no longer an optional feature, while runtime pm can be not enabled. Though cmd_ready/go_idle provides a power saving, it's also a part of TPM2 protocol and should be called explicitly. This patch exposes cmd_read/go_idle via tpm class ops and removes runtime pm support as it is not used by any driver. When calling from nested context always use both flags: TPM_TRANSMIT_UNLOCKED and TPM_TRANSMIT_RAW. Both are needed to resolve tpm spaces and locality request recursive calls to tpm_transmit(). TPM_TRANSMIT_RAW should never be used standalone as it will fail on double locking. While TPM_TRANSMIT_UNLOCKED standalone should be called from non-recursive locked contexts. New wrappers are added tpm_cmd_ready() and tpm_go_idle() to streamline tpm_try_transmit code. tpm_crb no longer needs own power saving functions and can drop using tpm_pm_suspend/resume. This patch cannot be really separated from the locality fix. Fixes:888d867df4(tpm: cmd_ready command can be issued only after granting locality) Cc: stable@vger.kernel.org Fixes:888d867df4(tpm: cmd_ready command can be issued only after granting locality) Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
This commit is contained in:
		
							parent
							
								
									79e2472f99
								
							
						
					
					
						commit
						627448e85c
					
				
					 5 changed files with 90 additions and 92 deletions
				
			
		| 
						 | 
					@ -29,7 +29,6 @@
 | 
				
			||||||
#include <linux/mutex.h>
 | 
					#include <linux/mutex.h>
 | 
				
			||||||
#include <linux/spinlock.h>
 | 
					#include <linux/spinlock.h>
 | 
				
			||||||
#include <linux/freezer.h>
 | 
					#include <linux/freezer.h>
 | 
				
			||||||
#include <linux/pm_runtime.h>
 | 
					 | 
				
			||||||
#include <linux/tpm_eventlog.h>
 | 
					#include <linux/tpm_eventlog.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "tpm.h"
 | 
					#include "tpm.h"
 | 
				
			||||||
| 
						 | 
					@ -369,10 +368,13 @@ static int tpm_validate_command(struct tpm_chip *chip,
 | 
				
			||||||
	return -EINVAL;
 | 
						return -EINVAL;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int tpm_request_locality(struct tpm_chip *chip)
 | 
					static int tpm_request_locality(struct tpm_chip *chip, unsigned int flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc;
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (flags & TPM_TRANSMIT_RAW)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!chip->ops->request_locality)
 | 
						if (!chip->ops->request_locality)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -385,10 +387,13 @@ static int tpm_request_locality(struct tpm_chip *chip)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void tpm_relinquish_locality(struct tpm_chip *chip)
 | 
					static void tpm_relinquish_locality(struct tpm_chip *chip, unsigned int flags)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int rc;
 | 
						int rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (flags & TPM_TRANSMIT_RAW)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!chip->ops->relinquish_locality)
 | 
						if (!chip->ops->relinquish_locality)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -399,6 +404,28 @@ static void tpm_relinquish_locality(struct tpm_chip *chip)
 | 
				
			||||||
	chip->locality = -1;
 | 
						chip->locality = -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int tpm_cmd_ready(struct tpm_chip *chip, unsigned int flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (flags & TPM_TRANSMIT_RAW)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!chip->ops->cmd_ready)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return chip->ops->cmd_ready(chip);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int tpm_go_idle(struct tpm_chip *chip, unsigned int flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (flags & TPM_TRANSMIT_RAW)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!chip->ops->go_idle)
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return chip->ops->go_idle(chip);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ssize_t tpm_try_transmit(struct tpm_chip *chip,
 | 
					static ssize_t tpm_try_transmit(struct tpm_chip *chip,
 | 
				
			||||||
				struct tpm_space *space,
 | 
									struct tpm_space *space,
 | 
				
			||||||
				u8 *buf, size_t bufsiz,
 | 
									u8 *buf, size_t bufsiz,
 | 
				
			||||||
| 
						 | 
					@ -449,14 +476,15 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip,
 | 
				
			||||||
	/* Store the decision as chip->locality will be changed. */
 | 
						/* Store the decision as chip->locality will be changed. */
 | 
				
			||||||
	need_locality = chip->locality == -1;
 | 
						need_locality = chip->locality == -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!(flags & TPM_TRANSMIT_RAW) && need_locality) {
 | 
						if (need_locality) {
 | 
				
			||||||
		rc = tpm_request_locality(chip);
 | 
							rc = tpm_request_locality(chip, flags);
 | 
				
			||||||
		if (rc < 0)
 | 
							if (rc < 0)
 | 
				
			||||||
			goto out_no_locality;
 | 
								goto out_no_locality;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (chip->dev.parent)
 | 
						rc = tpm_cmd_ready(chip, flags);
 | 
				
			||||||
		pm_runtime_get_sync(chip->dev.parent);
 | 
						if (rc)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc = tpm2_prepare_space(chip, space, ordinal, buf);
 | 
						rc = tpm2_prepare_space(chip, space, ordinal, buf);
 | 
				
			||||||
	if (rc)
 | 
						if (rc)
 | 
				
			||||||
| 
						 | 
					@ -516,13 +544,16 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc = tpm2_commit_space(chip, space, ordinal, buf, &len);
 | 
						rc = tpm2_commit_space(chip, space, ordinal, buf, &len);
 | 
				
			||||||
 | 
						if (rc)
 | 
				
			||||||
 | 
							dev_err(&chip->dev, "tpm2_commit_space: error %d\n", rc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	if (chip->dev.parent)
 | 
						rc = tpm_go_idle(chip, flags);
 | 
				
			||||||
		pm_runtime_put_sync(chip->dev.parent);
 | 
						if (rc)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (need_locality)
 | 
						if (need_locality)
 | 
				
			||||||
		tpm_relinquish_locality(chip);
 | 
							tpm_relinquish_locality(chip, flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out_no_locality:
 | 
					out_no_locality:
 | 
				
			||||||
	if (chip->ops->clk_enable != NULL)
 | 
						if (chip->ops->clk_enable != NULL)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -512,9 +512,17 @@ extern const struct file_operations tpm_fops;
 | 
				
			||||||
extern const struct file_operations tpmrm_fops;
 | 
					extern const struct file_operations tpmrm_fops;
 | 
				
			||||||
extern struct idr dev_nums_idr;
 | 
					extern struct idr dev_nums_idr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * enum tpm_transmit_flags
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @TPM_TRANSMIT_UNLOCKED: used to lock sequence of tpm_transmit calls.
 | 
				
			||||||
 | 
					 * @TPM_TRANSMIT_RAW: prevent recursive calls into setup steps
 | 
				
			||||||
 | 
					 *                    (go idle, locality,..). Always use with UNLOCKED
 | 
				
			||||||
 | 
					 *                    as it will fail on double locking.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
enum tpm_transmit_flags {
 | 
					enum tpm_transmit_flags {
 | 
				
			||||||
	TPM_TRANSMIT_UNLOCKED	= BIT(0),
 | 
						TPM_TRANSMIT_UNLOCKED = BIT(0),
 | 
				
			||||||
	TPM_TRANSMIT_RAW	= BIT(1),
 | 
						TPM_TRANSMIT_RAW      = BIT(1),
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space,
 | 
					ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,8 @@ static void tpm2_flush_sessions(struct tpm_chip *chip, struct tpm_space *space)
 | 
				
			||||||
	for (i = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
 | 
						for (i = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
 | 
				
			||||||
		if (space->session_tbl[i])
 | 
							if (space->session_tbl[i])
 | 
				
			||||||
			tpm2_flush_context_cmd(chip, space->session_tbl[i],
 | 
								tpm2_flush_context_cmd(chip, space->session_tbl[i],
 | 
				
			||||||
					       TPM_TRANSMIT_UNLOCKED);
 | 
										       TPM_TRANSMIT_UNLOCKED |
 | 
				
			||||||
 | 
										       TPM_TRANSMIT_RAW);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,7 +85,7 @@ static int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
 | 
				
			||||||
	tpm_buf_append(&tbuf, &buf[*offset], body_size);
 | 
						tpm_buf_append(&tbuf, &buf[*offset], body_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc = tpm_transmit_cmd(chip, NULL, tbuf.data, PAGE_SIZE, 4,
 | 
						rc = tpm_transmit_cmd(chip, NULL, tbuf.data, PAGE_SIZE, 4,
 | 
				
			||||||
			      TPM_TRANSMIT_UNLOCKED, NULL);
 | 
								      TPM_TRANSMIT_UNLOCKED | TPM_TRANSMIT_RAW, NULL);
 | 
				
			||||||
	if (rc < 0) {
 | 
						if (rc < 0) {
 | 
				
			||||||
		dev_warn(&chip->dev, "%s: failed with a system error %d\n",
 | 
							dev_warn(&chip->dev, "%s: failed with a system error %d\n",
 | 
				
			||||||
			 __func__, rc);
 | 
								 __func__, rc);
 | 
				
			||||||
| 
						 | 
					@ -133,7 +134,7 @@ static int tpm2_save_context(struct tpm_chip *chip, u32 handle, u8 *buf,
 | 
				
			||||||
	tpm_buf_append_u32(&tbuf, handle);
 | 
						tpm_buf_append_u32(&tbuf, handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc = tpm_transmit_cmd(chip, NULL, tbuf.data, PAGE_SIZE, 0,
 | 
						rc = tpm_transmit_cmd(chip, NULL, tbuf.data, PAGE_SIZE, 0,
 | 
				
			||||||
			      TPM_TRANSMIT_UNLOCKED, NULL);
 | 
								      TPM_TRANSMIT_UNLOCKED | TPM_TRANSMIT_RAW, NULL);
 | 
				
			||||||
	if (rc < 0) {
 | 
						if (rc < 0) {
 | 
				
			||||||
		dev_warn(&chip->dev, "%s: failed with a system error %d\n",
 | 
							dev_warn(&chip->dev, "%s: failed with a system error %d\n",
 | 
				
			||||||
			 __func__, rc);
 | 
								 __func__, rc);
 | 
				
			||||||
| 
						 | 
					@ -170,7 +171,8 @@ static void tpm2_flush_space(struct tpm_chip *chip)
 | 
				
			||||||
	for (i = 0; i < ARRAY_SIZE(space->context_tbl); i++)
 | 
						for (i = 0; i < ARRAY_SIZE(space->context_tbl); i++)
 | 
				
			||||||
		if (space->context_tbl[i] && ~space->context_tbl[i])
 | 
							if (space->context_tbl[i] && ~space->context_tbl[i])
 | 
				
			||||||
			tpm2_flush_context_cmd(chip, space->context_tbl[i],
 | 
								tpm2_flush_context_cmd(chip, space->context_tbl[i],
 | 
				
			||||||
					       TPM_TRANSMIT_UNLOCKED);
 | 
										       TPM_TRANSMIT_UNLOCKED |
 | 
				
			||||||
 | 
										       TPM_TRANSMIT_RAW);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tpm2_flush_sessions(chip, space);
 | 
						tpm2_flush_sessions(chip, space);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -377,7 +379,8 @@ static int tpm2_map_response_header(struct tpm_chip *chip, u32 cc, u8 *rsp,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
out_no_slots:
 | 
					out_no_slots:
 | 
				
			||||||
	tpm2_flush_context_cmd(chip, phandle, TPM_TRANSMIT_UNLOCKED);
 | 
						tpm2_flush_context_cmd(chip, phandle,
 | 
				
			||||||
 | 
								       TPM_TRANSMIT_UNLOCKED | TPM_TRANSMIT_RAW);
 | 
				
			||||||
	dev_warn(&chip->dev, "%s: out of slots for 0x%08X\n", __func__,
 | 
						dev_warn(&chip->dev, "%s: out of slots for 0x%08X\n", __func__,
 | 
				
			||||||
		 phandle);
 | 
							 phandle);
 | 
				
			||||||
	return -ENOMEM;
 | 
						return -ENOMEM;
 | 
				
			||||||
| 
						 | 
					@ -465,7 +468,8 @@ static int tpm2_save_space(struct tpm_chip *chip)
 | 
				
			||||||
			return rc;
 | 
								return rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		tpm2_flush_context_cmd(chip, space->context_tbl[i],
 | 
							tpm2_flush_context_cmd(chip, space->context_tbl[i],
 | 
				
			||||||
				       TPM_TRANSMIT_UNLOCKED);
 | 
									       TPM_TRANSMIT_UNLOCKED |
 | 
				
			||||||
 | 
									       TPM_TRANSMIT_RAW);
 | 
				
			||||||
		space->context_tbl[i] = ~0;
 | 
							space->context_tbl[i] = ~0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -132,7 +132,7 @@ static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * crb_go_idle - request tpm crb device to go the idle state
 | 
					 * __crb_go_idle - request tpm crb device to go the idle state
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @dev:  crb device
 | 
					 * @dev:  crb device
 | 
				
			||||||
 * @priv: crb private data
 | 
					 * @priv: crb private data
 | 
				
			||||||
| 
						 | 
					@ -147,7 +147,7 @@ static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value,
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Return: 0 always
 | 
					 * Return: 0 always
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int crb_go_idle(struct device *dev, struct crb_priv *priv)
 | 
					static int __crb_go_idle(struct device *dev, struct crb_priv *priv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ((priv->sm == ACPI_TPM2_START_METHOD) ||
 | 
						if ((priv->sm == ACPI_TPM2_START_METHOD) ||
 | 
				
			||||||
	    (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) ||
 | 
						    (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) ||
 | 
				
			||||||
| 
						 | 
					@ -163,11 +163,20 @@ static int crb_go_idle(struct device *dev, struct crb_priv *priv)
 | 
				
			||||||
		dev_warn(dev, "goIdle timed out\n");
 | 
							dev_warn(dev, "goIdle timed out\n");
 | 
				
			||||||
		return -ETIME;
 | 
							return -ETIME;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int crb_go_idle(struct tpm_chip *chip)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct device *dev = &chip->dev;
 | 
				
			||||||
 | 
						struct crb_priv *priv = dev_get_drvdata(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return __crb_go_idle(dev, priv);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * crb_cmd_ready - request tpm crb device to enter ready state
 | 
					 * __crb_cmd_ready - request tpm crb device to enter ready state
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @dev:  crb device
 | 
					 * @dev:  crb device
 | 
				
			||||||
 * @priv: crb private data
 | 
					 * @priv: crb private data
 | 
				
			||||||
| 
						 | 
					@ -181,7 +190,7 @@ static int crb_go_idle(struct device *dev, struct crb_priv *priv)
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Return: 0 on success -ETIME on timeout;
 | 
					 * Return: 0 on success -ETIME on timeout;
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int crb_cmd_ready(struct device *dev, struct crb_priv *priv)
 | 
					static int __crb_cmd_ready(struct device *dev, struct crb_priv *priv)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if ((priv->sm == ACPI_TPM2_START_METHOD) ||
 | 
						if ((priv->sm == ACPI_TPM2_START_METHOD) ||
 | 
				
			||||||
	    (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) ||
 | 
						    (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) ||
 | 
				
			||||||
| 
						 | 
					@ -200,6 +209,14 @@ static int crb_cmd_ready(struct device *dev, struct crb_priv *priv)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int crb_cmd_ready(struct tpm_chip *chip)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct device *dev = &chip->dev;
 | 
				
			||||||
 | 
						struct crb_priv *priv = dev_get_drvdata(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return __crb_cmd_ready(dev, priv);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __crb_request_locality(struct device *dev,
 | 
					static int __crb_request_locality(struct device *dev,
 | 
				
			||||||
				  struct crb_priv *priv, int loc)
 | 
									  struct crb_priv *priv, int loc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -401,6 +418,8 @@ static const struct tpm_class_ops tpm_crb = {
 | 
				
			||||||
	.send = crb_send,
 | 
						.send = crb_send,
 | 
				
			||||||
	.cancel = crb_cancel,
 | 
						.cancel = crb_cancel,
 | 
				
			||||||
	.req_canceled = crb_req_canceled,
 | 
						.req_canceled = crb_req_canceled,
 | 
				
			||||||
 | 
						.go_idle  = crb_go_idle,
 | 
				
			||||||
 | 
						.cmd_ready = crb_cmd_ready,
 | 
				
			||||||
	.request_locality = crb_request_locality,
 | 
						.request_locality = crb_request_locality,
 | 
				
			||||||
	.relinquish_locality = crb_relinquish_locality,
 | 
						.relinquish_locality = crb_relinquish_locality,
 | 
				
			||||||
	.req_complete_mask = CRB_DRV_STS_COMPLETE,
 | 
						.req_complete_mask = CRB_DRV_STS_COMPLETE,
 | 
				
			||||||
| 
						 | 
					@ -520,7 +539,7 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
 | 
				
			||||||
	 * PTT HW bug w/a: wake up the device to access
 | 
						 * PTT HW bug w/a: wake up the device to access
 | 
				
			||||||
	 * possibly not retained registers.
 | 
						 * possibly not retained registers.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	ret = crb_cmd_ready(dev, priv);
 | 
						ret = __crb_cmd_ready(dev, priv);
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		goto out_relinquish_locality;
 | 
							goto out_relinquish_locality;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -565,7 +584,7 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv,
 | 
				
			||||||
	if (!ret)
 | 
						if (!ret)
 | 
				
			||||||
		priv->cmd_size = cmd_size;
 | 
							priv->cmd_size = cmd_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	crb_go_idle(dev, priv);
 | 
						__crb_go_idle(dev, priv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
out_relinquish_locality:
 | 
					out_relinquish_locality:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -628,32 +647,7 @@ static int crb_acpi_add(struct acpi_device *device)
 | 
				
			||||||
	chip->acpi_dev_handle = device->handle;
 | 
						chip->acpi_dev_handle = device->handle;
 | 
				
			||||||
	chip->flags = TPM_CHIP_FLAG_TPM2;
 | 
						chip->flags = TPM_CHIP_FLAG_TPM2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc = __crb_request_locality(dev, priv, 0);
 | 
						return tpm_chip_register(chip);
 | 
				
			||||||
	if (rc)
 | 
					 | 
				
			||||||
		return rc;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rc  = crb_cmd_ready(dev, priv);
 | 
					 | 
				
			||||||
	if (rc)
 | 
					 | 
				
			||||||
		goto out;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pm_runtime_get_noresume(dev);
 | 
					 | 
				
			||||||
	pm_runtime_set_active(dev);
 | 
					 | 
				
			||||||
	pm_runtime_enable(dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	rc = tpm_chip_register(chip);
 | 
					 | 
				
			||||||
	if (rc) {
 | 
					 | 
				
			||||||
		crb_go_idle(dev, priv);
 | 
					 | 
				
			||||||
		pm_runtime_put_noidle(dev);
 | 
					 | 
				
			||||||
		pm_runtime_disable(dev);
 | 
					 | 
				
			||||||
		goto out;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pm_runtime_put_sync(dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
out:
 | 
					 | 
				
			||||||
	__crb_relinquish_locality(dev, priv, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return rc;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int crb_acpi_remove(struct acpi_device *device)
 | 
					static int crb_acpi_remove(struct acpi_device *device)
 | 
				
			||||||
| 
						 | 
					@ -663,52 +657,11 @@ static int crb_acpi_remove(struct acpi_device *device)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tpm_chip_unregister(chip);
 | 
						tpm_chip_unregister(chip);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pm_runtime_disable(dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __maybe_unused crb_pm_runtime_suspend(struct device *dev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct tpm_chip *chip = dev_get_drvdata(dev);
 | 
					 | 
				
			||||||
	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return crb_go_idle(dev, priv);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int __maybe_unused crb_pm_runtime_resume(struct device *dev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	struct tpm_chip *chip = dev_get_drvdata(dev);
 | 
					 | 
				
			||||||
	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return crb_cmd_ready(dev, priv);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int __maybe_unused crb_pm_suspend(struct device *dev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int ret;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret = tpm_pm_suspend(dev);
 | 
					 | 
				
			||||||
	if (ret)
 | 
					 | 
				
			||||||
		return ret;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return crb_pm_runtime_suspend(dev);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int __maybe_unused crb_pm_resume(struct device *dev)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	int ret;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret = crb_pm_runtime_resume(dev);
 | 
					 | 
				
			||||||
	if (ret)
 | 
					 | 
				
			||||||
		return ret;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return tpm_pm_resume(dev);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const struct dev_pm_ops crb_pm = {
 | 
					static const struct dev_pm_ops crb_pm = {
 | 
				
			||||||
	SET_SYSTEM_SLEEP_PM_OPS(crb_pm_suspend, crb_pm_resume)
 | 
						SET_SYSTEM_SLEEP_PM_OPS(tpm_pm_suspend, tpm_pm_resume)
 | 
				
			||||||
	SET_RUNTIME_PM_OPS(crb_pm_runtime_suspend, crb_pm_runtime_resume, NULL)
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct acpi_device_id crb_device_ids[] = {
 | 
					static const struct acpi_device_id crb_device_ids[] = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,6 +43,8 @@ struct tpm_class_ops {
 | 
				
			||||||
	u8 (*status) (struct tpm_chip *chip);
 | 
						u8 (*status) (struct tpm_chip *chip);
 | 
				
			||||||
	bool (*update_timeouts)(struct tpm_chip *chip,
 | 
						bool (*update_timeouts)(struct tpm_chip *chip,
 | 
				
			||||||
				unsigned long *timeout_cap);
 | 
									unsigned long *timeout_cap);
 | 
				
			||||||
 | 
						int (*go_idle)(struct tpm_chip *chip);
 | 
				
			||||||
 | 
						int (*cmd_ready)(struct tpm_chip *chip);
 | 
				
			||||||
	int (*request_locality)(struct tpm_chip *chip, int loc);
 | 
						int (*request_locality)(struct tpm_chip *chip, int loc);
 | 
				
			||||||
	int (*relinquish_locality)(struct tpm_chip *chip, int loc);
 | 
						int (*relinquish_locality)(struct tpm_chip *chip, int loc);
 | 
				
			||||||
	void (*clk_enable)(struct tpm_chip *chip, bool value);
 | 
						void (*clk_enable)(struct tpm_chip *chip, bool value);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue