diff options
-rw-r--r-- | drivers/char/tpm/tpm-interface.c | 5 | ||||
-rw-r--r-- | drivers/char/tpm/tpm_crb.c | 173 |
2 files changed, 24 insertions, 154 deletions
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 77d83c98d67f..8de61876f633 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -29,7 +29,6 @@ #include <linux/mutex.h> #include <linux/spinlock.h> #include <linux/freezer.h> -#include <linux/pm_runtime.h> #include "tpm.h" #include "tpm_eventlog.h" @@ -357,8 +356,6 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz, if (!(flags & TPM_TRANSMIT_UNLOCKED)) mutex_lock(&chip->tpm_mutex); - pm_runtime_get_sync(chip->dev.parent); - rc = chip->ops->send(chip, (u8 *) buf, count); if (rc < 0) { dev_err(&chip->dev, @@ -400,8 +397,6 @@ out_recv: dev_err(&chip->dev, "tpm_transmit: tpm_recv: error %zd\n", rc); out: - pm_runtime_put(chip->dev.parent); - if (!(flags & TPM_TRANSMIT_UNLOCKED)) mutex_unlock(&chip->tpm_mutex); return rc; diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c index aa0ef742ac03..a7c870af916c 100644 --- a/drivers/char/tpm/tpm_crb.c +++ b/drivers/char/tpm/tpm_crb.c @@ -19,7 +19,6 @@ #include <linux/highmem.h> #include <linux/rculist.h> #include <linux/module.h> -#include <linux/pm_runtime.h> #include "tpm.h" #define ACPI_SIG_TPM2 "TPM2" @@ -84,74 +83,7 @@ struct crb_priv { u32 cmd_size; }; -/** - * crb_go_idle - request tpm crb device to go the idle state - * - * @dev: crb device - * @priv: crb private data - * - * Write CRB_CTRL_REQ_GO_IDLE to TPM_CRB_CTRL_REQ - * The device should respond within TIMEOUT_C by clearing the bit. - * Anyhow, we do not wait here as a consequent CMD_READY request - * will be handled correctly even if idle was not completed. - * - * The function does nothing for devices with ACPI-start method. - * - * Return: 0 always - */ -static int __maybe_unused crb_go_idle(struct device *dev, struct crb_priv *priv) -{ - if (priv->flags & CRB_FL_ACPI_START) - return 0; - - iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->cca->req); - /* we don't really care when this settles */ - - return 0; -} - -/** - * crb_cmd_ready - request tpm crb device to enter ready state - * - * @dev: crb device - * @priv: crb private data - * - * Write CRB_CTRL_REQ_CMD_READY to TPM_CRB_CTRL_REQ - * and poll till the device acknowledge it by clearing the bit. - * The device should respond within TIMEOUT_C. - * - * The function does nothing for devices with ACPI-start method - * - * Return: 0 on success -ETIME on timeout; - */ -static int __maybe_unused crb_cmd_ready(struct device *dev, - struct crb_priv *priv) -{ - ktime_t stop, start; - - if (priv->flags & CRB_FL_ACPI_START) - return 0; - - iowrite32(CRB_CTRL_REQ_CMD_READY, &priv->cca->req); - - start = ktime_get(); - stop = ktime_add(start, ms_to_ktime(TPM2_TIMEOUT_C)); - do { - if (!(ioread32(&priv->cca->req) & CRB_CTRL_REQ_CMD_READY)) { - dev_dbg(dev, "cmdReady in %lld usecs\n", - ktime_to_us(ktime_sub(ktime_get(), start))); - return 0; - } - usleep_range(50, 100); - } while (ktime_before(ktime_get(), stop)); - - if (ioread32(&priv->cca->req) & CRB_CTRL_REQ_CMD_READY) { - dev_warn(dev, "cmdReady timed out\n"); - return -ETIME; - } - - return 0; -} +static SIMPLE_DEV_PM_OPS(crb_pm, tpm_pm_suspend, tpm_pm_resume); static u8 crb_status(struct tpm_chip *chip) { @@ -264,6 +196,21 @@ static const struct tpm_class_ops tpm_crb = { .req_complete_val = CRB_DRV_STS_COMPLETE, }; +static int crb_init(struct acpi_device *device, struct crb_priv *priv) +{ + struct tpm_chip *chip; + + chip = tpmm_chip_alloc(&device->dev, &tpm_crb); + if (IS_ERR(chip)) + return PTR_ERR(chip); + + dev_set_drvdata(&chip->dev, priv); + chip->acpi_dev_handle = device->handle; + chip->flags = TPM_CHIP_FLAG_TPM2; + + return tpm_chip_register(chip); +} + static int crb_check_resource(struct acpi_resource *ares, void *data) { struct resource *io_res = data; @@ -302,7 +249,6 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, struct list_head resources; struct resource io_res; struct device *dev = &device->dev; - u32 pa_high, pa_low; u64 cmd_pa; u32 cmd_size; u64 rsp_pa; @@ -330,27 +276,12 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, if (IS_ERR(priv->cca)) return PTR_ERR(priv->cca); - /* - * PTT HW bug w/a: wake up the device to access - * possibly not retained registers. - */ - ret = crb_cmd_ready(dev, priv); - if (ret) - return ret; - - pa_high = ioread32(&priv->cca->cmd_pa_high); - pa_low = ioread32(&priv->cca->cmd_pa_low); - cmd_pa = ((u64)pa_high << 32) | pa_low; + cmd_pa = ((u64) ioread32(&priv->cca->cmd_pa_high) << 32) | + (u64) ioread32(&priv->cca->cmd_pa_low); cmd_size = ioread32(&priv->cca->cmd_size); - - dev_dbg(dev, "cmd_hi = %X cmd_low = %X cmd_size %X\n", - pa_high, pa_low, cmd_size); - priv->cmd = crb_map_res(dev, priv, &io_res, cmd_pa, cmd_size); - if (IS_ERR(priv->cmd)) { - ret = PTR_ERR(priv->cmd); - goto out; - } + if (IS_ERR(priv->cmd)) + return PTR_ERR(priv->cmd); memcpy_fromio(&rsp_pa, &priv->cca->rsp_pa, 8); rsp_pa = le64_to_cpu(rsp_pa); @@ -358,8 +289,7 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, if (cmd_pa != rsp_pa) { priv->rsp = crb_map_res(dev, priv, &io_res, rsp_pa, rsp_size); - ret = PTR_ERR_OR_ZERO(priv->rsp); - goto out; + return PTR_ERR_OR_ZERO(priv->rsp); } /* According to the PTP specification, overlapping command and response @@ -367,25 +297,18 @@ static int crb_map_io(struct acpi_device *device, struct crb_priv *priv, */ if (cmd_size != rsp_size) { dev_err(dev, FW_BUG "overlapping command and response buffer sizes are not identical"); - ret = -EINVAL; - goto out; + return -EINVAL; } - priv->cmd_size = cmd_size; priv->rsp = priv->cmd; - -out: - crb_go_idle(dev, priv); - - return ret; + return 0; } static int crb_acpi_add(struct acpi_device *device) { struct acpi_table_tpm2 *buf; struct crb_priv *priv; - struct tpm_chip *chip; struct device *dev = &device->dev; acpi_status status; u32 sm; @@ -423,30 +346,7 @@ static int crb_acpi_add(struct acpi_device *device) if (rc) return rc; - chip = tpmm_chip_alloc(dev, &tpm_crb); - if (IS_ERR(chip)) - return PTR_ERR(chip); - - dev_set_drvdata(&chip->dev, priv); - chip->acpi_dev_handle = device->handle; - chip->flags = TPM_CHIP_FLAG_TPM2; - - rc = crb_cmd_ready(dev, priv); - if (rc) - return rc; - - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - - rc = tpm_chip_register(chip); - if (rc) { - crb_go_idle(dev, priv); - pm_runtime_disable(dev); - } - - pm_runtime_put(dev); - - return rc; + return crb_init(device, priv); } static int crb_acpi_remove(struct acpi_device *device) @@ -456,34 +356,9 @@ static int crb_acpi_remove(struct acpi_device *device) tpm_chip_unregister(chip); - pm_runtime_disable(dev); - return 0; } -#ifdef CONFIG_PM -static int 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 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); -} -#endif /* CONFIG_PM */ - -static const struct dev_pm_ops crb_pm = { - 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 struct acpi_device_id crb_device_ids[] = { {"MSFT0101", 0}, {"", 0}, |