From 0ee9c21cf3560ea6062cbfbc8ec55cd0e3b8ebb4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 26 Apr 2018 19:55:27 +0200 Subject: [PATCH] 4.16-stable patches added patches: drm-bridge-dw-hdmi-fix-overflow-workaround-for-amlogic-meson-gx-socs.patch i40e-fix-attach-vf-to-vm-issue.patch tpm-add-retry-logic.patch tpm-cmd_ready-command-can-be-issued-only-after-granting-locality.patch tpm-tpm-interface-fix-tpm_transmit-_cmd-kdoc.patch --- ...workaround-for-amlogic-meson-gx-socs.patch | 45 +++ .../i40e-fix-attach-vf-to-vm-issue.patch | 56 +++ queue-4.16/series | 5 + queue-4.16/tpm-add-retry-logic.patch | 144 +++++++ ...-issued-only-after-granting-locality.patch | 361 ++++++++++++++++++ ...interface-fix-tpm_transmit-_cmd-kdoc.patch | 48 +++ 6 files changed, 659 insertions(+) create mode 100644 queue-4.16/drm-bridge-dw-hdmi-fix-overflow-workaround-for-amlogic-meson-gx-socs.patch create mode 100644 queue-4.16/i40e-fix-attach-vf-to-vm-issue.patch create mode 100644 queue-4.16/tpm-add-retry-logic.patch create mode 100644 queue-4.16/tpm-cmd_ready-command-can-be-issued-only-after-granting-locality.patch create mode 100644 queue-4.16/tpm-tpm-interface-fix-tpm_transmit-_cmd-kdoc.patch diff --git a/queue-4.16/drm-bridge-dw-hdmi-fix-overflow-workaround-for-amlogic-meson-gx-socs.patch b/queue-4.16/drm-bridge-dw-hdmi-fix-overflow-workaround-for-amlogic-meson-gx-socs.patch new file mode 100644 index 00000000000..46ef46d55d0 --- /dev/null +++ b/queue-4.16/drm-bridge-dw-hdmi-fix-overflow-workaround-for-amlogic-meson-gx-socs.patch @@ -0,0 +1,45 @@ +From 9c305eb442f3b371fc722ade827bbf673514123e Mon Sep 17 00:00:00 2001 +From: Neil Armstrong +Date: Fri, 23 Feb 2018 12:44:37 +0100 +Subject: drm: bridge: dw-hdmi: Fix overflow workaround for Amlogic Meson GX SoCs + +From: Neil Armstrong + +commit 9c305eb442f3b371fc722ade827bbf673514123e upstream. + +The Amlogic Meson GX SoCs, embedded the v2.01a controller, has been also +identified needing this workaround. +This patch adds the corresponding version to enable a single iteration for +this specific version. + +Fixes: be41fc55f1aa ("drm: bridge: dw-hdmi: Handle overflow workaround based on device version") +Acked-by: Archit Taneja +[narmstrong: s/identifies/identified and rebased against Jernej's change] +Signed-off-by: Neil Armstrong +Link: https://patchwork.freedesktop.org/patch/msgid/1519386277-25902-1-git-send-email-narmstrong@baylibre.com +[narmstrong: v4.14 to v4.16 backport] +Cc: # 4.14.x +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c ++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c +@@ -1637,6 +1637,8 @@ static void dw_hdmi_clear_overflow(struc + * (and possibly on the platform). So far only i.MX6Q (v1.30a) and + * i.MX6DL (v1.31a) have been identified as needing the workaround, with + * 4 and 1 iterations respectively. ++ * The Amlogic Meson GX SoCs (v2.01a) have been identified as needing ++ * the workaround with a single iteration. + */ + + switch (hdmi->version) { +@@ -1644,6 +1646,7 @@ static void dw_hdmi_clear_overflow(struc + count = 4; + break; + case 0x131a: ++ case 0x201a: + count = 1; + break; + default: diff --git a/queue-4.16/i40e-fix-attach-vf-to-vm-issue.patch b/queue-4.16/i40e-fix-attach-vf-to-vm-issue.patch new file mode 100644 index 00000000000..c3a74a49fa8 --- /dev/null +++ b/queue-4.16/i40e-fix-attach-vf-to-vm-issue.patch @@ -0,0 +1,56 @@ +From 028daf80117376b22909becd9720daaefdfceff4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pawe=C5=82=20Jab=C5=82o=C5=84ski?= +Date: Thu, 8 Mar 2018 14:52:05 -0800 +Subject: i40e: Fix attach VF to VM issue +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Paweł Jabłoński + +commit 028daf80117376b22909becd9720daaefdfceff4 upstream. + +Fix for "Resource temporarily unavailable" problem when virsh is +trying to attach a device to VM. When the VF driver is loaded on +host and virsh is trying to attach it to the VM and set a MAC +address, it ends with a race condition between i40e_reset_vf and +i40e_ndo_set_vf_mac functions. The bug is fixed by adding polling +in i40e_ndo_set_vf_mac function For when the VF is in Reset mode. + +Signed-off-by: Paweł Jabłoński +Tested-by: Andrew Bowers +Signed-off-by: Jeff Kirsher +Cc: Sinan Kaya +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c ++++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +@@ -2889,6 +2889,7 @@ int i40e_ndo_set_vf_mac(struct net_devic + int ret = 0; + struct hlist_node *h; + int bkt; ++ u8 i; + + /* validate the request */ + if (vf_id >= pf->num_alloc_vfs) { +@@ -2900,6 +2901,16 @@ int i40e_ndo_set_vf_mac(struct net_devic + + vf = &(pf->vf[vf_id]); + vsi = pf->vsi[vf->lan_vsi_idx]; ++ ++ /* When the VF is resetting wait until it is done. ++ * It can take up to 200 milliseconds, ++ * but wait for up to 300 milliseconds to be safe. ++ */ ++ for (i = 0; i < 15; i++) { ++ if (test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) ++ break; ++ msleep(20); ++ } + if (!test_bit(I40E_VF_STATE_INIT, &vf->vf_states)) { + dev_err(&pf->pdev->dev, "VF %d still in reset. Try again.\n", + vf_id); diff --git a/queue-4.16/series b/queue-4.16/series index 74f0ca5f7b7..e398aedcf33 100644 --- a/queue-4.16/series +++ b/queue-4.16/series @@ -1 +1,6 @@ revert-pinctrl-intel-initialize-gpio-properly-when-used-through-irqchip.patch +drm-bridge-dw-hdmi-fix-overflow-workaround-for-amlogic-meson-gx-socs.patch +i40e-fix-attach-vf-to-vm-issue.patch +tpm-cmd_ready-command-can-be-issued-only-after-granting-locality.patch +tpm-tpm-interface-fix-tpm_transmit-_cmd-kdoc.patch +tpm-add-retry-logic.patch diff --git a/queue-4.16/tpm-add-retry-logic.patch b/queue-4.16/tpm-add-retry-logic.patch new file mode 100644 index 00000000000..18fa29fc054 --- /dev/null +++ b/queue-4.16/tpm-add-retry-logic.patch @@ -0,0 +1,144 @@ +From e2fb992d82c626c43ed0566e07c410e56a087af3 Mon Sep 17 00:00:00 2001 +From: James Bottomley +Date: Wed, 21 Mar 2018 11:43:48 -0700 +Subject: tpm: add retry logic +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: James Bottomley + +commit e2fb992d82c626c43ed0566e07c410e56a087af3 upstream. + +TPM2 can return TPM2_RC_RETRY to any command and when it does we get +unexpected failures inside the kernel that surprise users (this is +mostly observed in the trusted key handling code). The UEFI 2.6 spec +has advice on how to handle this: + + The firmware SHALL not return TPM2_RC_RETRY prior to the completion + of the call to ExitBootServices(). + + Implementer’s Note: the implementation of this function should check + the return value in the TPM response and, if it is TPM2_RC_RETRY, + resend the command. The implementation may abort if a sufficient + number of retries has been done. + +So we follow that advice in our tpm_transmit() code using +TPM2_DURATION_SHORT as the initial wait duration and +TPM2_DURATION_LONG as the maximum wait time. This should fix all the +in-kernel use cases and also means that user space TSS implementations +don't have to have their own retry handling. + +Signed-off-by: James Bottomley +Cc: stable@vger.kernel.org +Reviewed-by: Jarkko Sakkinen +Tested-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm-interface.c | 75 +++++++++++++++++++++++++++++++-------- + drivers/char/tpm/tpm.h | 1 + 2 files changed, 61 insertions(+), 15 deletions(-) + +--- a/drivers/char/tpm/tpm-interface.c ++++ b/drivers/char/tpm/tpm-interface.c +@@ -399,21 +399,10 @@ static void tpm_relinquish_locality(stru + chip->locality = -1; + } + +-/** +- * tpm_transmit - Internal kernel interface to transmit TPM commands. +- * +- * @chip: TPM chip to use +- * @space: tpm space +- * @buf: TPM command buffer +- * @bufsiz: length of the TPM command buffer +- * @flags: tpm transmit flags - bitmap +- * +- * Return: +- * 0 when the operation is successful. +- * A negative number for system errors (errno). +- */ +-ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, +- u8 *buf, size_t bufsiz, unsigned int flags) ++static ssize_t tpm_try_transmit(struct tpm_chip *chip, ++ struct tpm_space *space, ++ u8 *buf, size_t bufsiz, ++ unsigned int flags) + { + struct tpm_output_header *header = (void *)buf; + int rc; +@@ -545,6 +534,62 @@ out_no_locality: + } + + /** ++ * tpm_transmit - Internal kernel interface to transmit TPM commands. ++ * ++ * @chip: TPM chip to use ++ * @space: tpm space ++ * @buf: TPM command buffer ++ * @bufsiz: length of the TPM command buffer ++ * @flags: tpm transmit flags - bitmap ++ * ++ * A wrapper around tpm_try_transmit that handles TPM2_RC_RETRY ++ * returns from the TPM and retransmits the command after a delay up ++ * to a maximum wait of TPM2_DURATION_LONG. ++ * ++ * Note: TPM1 never returns TPM2_RC_RETRY so the retry logic is TPM2 ++ * only ++ * ++ * Return: ++ * the length of the return when the operation is successful. ++ * A negative number for system errors (errno). ++ */ ++ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, ++ u8 *buf, size_t bufsiz, unsigned int flags) ++{ ++ struct tpm_output_header *header = (struct tpm_output_header *)buf; ++ /* space for header and handles */ ++ u8 save[TPM_HEADER_SIZE + 3*sizeof(u32)]; ++ unsigned int delay_msec = TPM2_DURATION_SHORT; ++ u32 rc = 0; ++ ssize_t ret; ++ const size_t save_size = min(space ? sizeof(save) : TPM_HEADER_SIZE, ++ bufsiz); ++ ++ /* ++ * Subtlety here: if we have a space, the handles will be ++ * transformed, so when we restore the header we also have to ++ * restore the handles. ++ */ ++ memcpy(save, buf, save_size); ++ ++ for (;;) { ++ ret = tpm_try_transmit(chip, space, buf, bufsiz, flags); ++ if (ret < 0) ++ break; ++ rc = be32_to_cpu(header->return_code); ++ if (rc != TPM2_RC_RETRY) ++ break; ++ delay_msec *= 2; ++ if (delay_msec > TPM2_DURATION_LONG) { ++ dev_err(&chip->dev, "TPM is in retry loop\n"); ++ break; ++ } ++ tpm_msleep(delay_msec); ++ memcpy(buf, save, save_size); ++ } ++ return ret; ++} ++/** + * tpm_transmit_cmd - send a tpm command to the device + * The function extracts tpm out header return code + * +--- a/drivers/char/tpm/tpm.h ++++ b/drivers/char/tpm/tpm.h +@@ -108,6 +108,7 @@ enum tpm2_return_codes { + TPM2_RC_COMMAND_CODE = 0x0143, + TPM2_RC_TESTING = 0x090A, /* RC_WARN */ + TPM2_RC_REFERENCE_H0 = 0x0910, ++ TPM2_RC_RETRY = 0x0922, + }; + + enum tpm2_algorithms { diff --git a/queue-4.16/tpm-cmd_ready-command-can-be-issued-only-after-granting-locality.patch b/queue-4.16/tpm-cmd_ready-command-can-be-issued-only-after-granting-locality.patch new file mode 100644 index 00000000000..90bee42cfdd --- /dev/null +++ b/queue-4.16/tpm-cmd_ready-command-can-be-issued-only-after-granting-locality.patch @@ -0,0 +1,361 @@ +From 888d867df4417deffc33927e6fc2c6925736fe92 Mon Sep 17 00:00:00 2001 +From: Tomas Winkler +Date: Mon, 5 Mar 2018 13:34:49 +0200 +Subject: tpm: cmd_ready command can be issued only after granting locality + +From: Tomas Winkler + +commit 888d867df4417deffc33927e6fc2c6925736fe92 upstream. + +The correct sequence is to first request locality and only after +that perform cmd_ready handshake, otherwise the hardware will drop +the subsequent message as from the device point of view the cmd_ready +handshake wasn't performed. Symmetrically locality has to be relinquished +only after going idle handshake has completed, this requires that +go_idle has to poll for the completion and as well locality +relinquish has to poll for completion so it is not overridden +in back to back commands flow. + +Two wrapper functions are added (request_locality relinquish_locality) +to simplify the error handling. + +The issue is only visible on devices that support multiple localities. + +Fixes: 877c57d0d0ca ("tpm_crb: request and relinquish locality 0") +Signed-off-by: Tomas Winkler +Reviewed-by: Jarkko Sakkinen +Tested-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm-interface.c | 54 ++++++++++++++----- + drivers/char/tpm/tpm_crb.c | 108 +++++++++++++++++++++++++++------------ + drivers/char/tpm/tpm_tis_core.c | 4 + + include/linux/tpm.h | 2 + 4 files changed, 120 insertions(+), 48 deletions(-) + +--- a/drivers/char/tpm/tpm-interface.c ++++ b/drivers/char/tpm/tpm-interface.c +@@ -369,6 +369,36 @@ err_len: + return -EINVAL; + } + ++static int tpm_request_locality(struct tpm_chip *chip) ++{ ++ int rc; ++ ++ if (!chip->ops->request_locality) ++ return 0; ++ ++ rc = chip->ops->request_locality(chip, 0); ++ if (rc < 0) ++ return rc; ++ ++ chip->locality = rc; ++ ++ return 0; ++} ++ ++static void tpm_relinquish_locality(struct tpm_chip *chip) ++{ ++ int rc; ++ ++ if (!chip->ops->relinquish_locality) ++ return; ++ ++ rc = chip->ops->relinquish_locality(chip, chip->locality); ++ if (rc) ++ dev_err(&chip->dev, "%s: : error %d\n", __func__, rc); ++ ++ chip->locality = -1; ++} ++ + /** + * tmp_transmit - Internal kernel interface to transmit TPM commands. + * +@@ -422,8 +452,6 @@ ssize_t tpm_transmit(struct tpm_chip *ch + if (!(flags & TPM_TRANSMIT_UNLOCKED)) + mutex_lock(&chip->tpm_mutex); + +- if (chip->dev.parent) +- pm_runtime_get_sync(chip->dev.parent); + + if (chip->ops->clk_enable != NULL) + chip->ops->clk_enable(chip, true); +@@ -431,14 +459,15 @@ ssize_t tpm_transmit(struct tpm_chip *ch + /* Store the decision as chip->locality will be changed. */ + need_locality = chip->locality == -1; + +- if (!(flags & TPM_TRANSMIT_RAW) && +- need_locality && chip->ops->request_locality) { +- rc = chip->ops->request_locality(chip, 0); ++ if (!(flags & TPM_TRANSMIT_RAW) && need_locality) { ++ rc = tpm_request_locality(chip); + if (rc < 0) + goto out_no_locality; +- chip->locality = rc; + } + ++ if (chip->dev.parent) ++ pm_runtime_get_sync(chip->dev.parent); ++ + rc = tpm2_prepare_space(chip, space, ordinal, buf); + if (rc) + goto out; +@@ -499,17 +528,16 @@ out_recv: + rc = tpm2_commit_space(chip, space, ordinal, buf, &len); + + out: +- if (need_locality && chip->ops->relinquish_locality) { +- chip->ops->relinquish_locality(chip, chip->locality); +- chip->locality = -1; +- } ++ if (chip->dev.parent) ++ pm_runtime_put_sync(chip->dev.parent); ++ ++ if (need_locality) ++ tpm_relinquish_locality(chip); ++ + out_no_locality: + if (chip->ops->clk_enable != NULL) + chip->ops->clk_enable(chip, false); + +- if (chip->dev.parent) +- pm_runtime_put_sync(chip->dev.parent); +- + if (!(flags & TPM_TRANSMIT_UNLOCKED)) + mutex_unlock(&chip->tpm_mutex); + return rc ? rc : len; +--- a/drivers/char/tpm/tpm_crb.c ++++ b/drivers/char/tpm/tpm_crb.c +@@ -112,6 +112,25 @@ struct tpm2_crb_smc { + u32 smc_func_id; + }; + ++static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value, ++ unsigned long timeout) ++{ ++ ktime_t start; ++ ktime_t stop; ++ ++ start = ktime_get(); ++ stop = ktime_add(start, ms_to_ktime(timeout)); ++ ++ do { ++ if ((ioread32(reg) & mask) == value) ++ return true; ++ ++ usleep_range(50, 100); ++ } while (ktime_before(ktime_get(), stop)); ++ ++ return ((ioread32(reg) & mask) == value); ++} ++ + /** + * crb_go_idle - request tpm crb device to go the idle state + * +@@ -128,7 +147,7 @@ struct tpm2_crb_smc { + * + * Return: 0 always + */ +-static int __maybe_unused 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) || + (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || +@@ -136,30 +155,17 @@ static int __maybe_unused crb_go_idle(st + return 0; + + iowrite32(CRB_CTRL_REQ_GO_IDLE, &priv->regs_t->ctrl_req); +- /* we don't really care when this settles */ + ++ if (!crb_wait_for_reg_32(&priv->regs_t->ctrl_req, ++ CRB_CTRL_REQ_GO_IDLE/* mask */, ++ 0, /* value */ ++ TPM2_TIMEOUT_C)) { ++ dev_warn(dev, "goIdle timed out\n"); ++ return -ETIME; ++ } + return 0; + } + +-static bool crb_wait_for_reg_32(u32 __iomem *reg, u32 mask, u32 value, +- unsigned long timeout) +-{ +- ktime_t start; +- ktime_t stop; +- +- start = ktime_get(); +- stop = ktime_add(start, ms_to_ktime(timeout)); +- +- do { +- if ((ioread32(reg) & mask) == value) +- return true; +- +- usleep_range(50, 100); +- } while (ktime_before(ktime_get(), stop)); +- +- return false; +-} +- + /** + * crb_cmd_ready - request tpm crb device to enter ready state + * +@@ -175,8 +181,7 @@ static bool crb_wait_for_reg_32(u32 __io + * + * Return: 0 on success -ETIME on timeout; + */ +-static int __maybe_unused 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) || + (priv->sm == ACPI_TPM2_COMMAND_BUFFER_WITH_START_METHOD) || +@@ -195,11 +200,11 @@ static int __maybe_unused crb_cmd_ready( + return 0; + } + +-static int crb_request_locality(struct tpm_chip *chip, int loc) ++static int __crb_request_locality(struct device *dev, ++ struct crb_priv *priv, int loc) + { +- struct crb_priv *priv = dev_get_drvdata(&chip->dev); + u32 value = CRB_LOC_STATE_LOC_ASSIGNED | +- CRB_LOC_STATE_TPM_REG_VALID_STS; ++ CRB_LOC_STATE_TPM_REG_VALID_STS; + + if (!priv->regs_h) + return 0; +@@ -207,21 +212,45 @@ static int crb_request_locality(struct t + iowrite32(CRB_LOC_CTRL_REQUEST_ACCESS, &priv->regs_h->loc_ctrl); + if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, value, value, + TPM2_TIMEOUT_C)) { +- dev_warn(&chip->dev, "TPM_LOC_STATE_x.requestAccess timed out\n"); ++ dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed out\n"); + return -ETIME; + } + + return 0; + } + +-static void crb_relinquish_locality(struct tpm_chip *chip, int loc) ++static int crb_request_locality(struct tpm_chip *chip, int loc) + { + struct crb_priv *priv = dev_get_drvdata(&chip->dev); + ++ return __crb_request_locality(&chip->dev, priv, loc); ++} ++ ++static int __crb_relinquish_locality(struct device *dev, ++ struct crb_priv *priv, int loc) ++{ ++ u32 mask = CRB_LOC_STATE_LOC_ASSIGNED | ++ CRB_LOC_STATE_TPM_REG_VALID_STS; ++ u32 value = CRB_LOC_STATE_TPM_REG_VALID_STS; ++ + if (!priv->regs_h) +- return; ++ return 0; + + iowrite32(CRB_LOC_CTRL_RELINQUISH, &priv->regs_h->loc_ctrl); ++ if (!crb_wait_for_reg_32(&priv->regs_h->loc_state, mask, value, ++ TPM2_TIMEOUT_C)) { ++ dev_warn(dev, "TPM_LOC_STATE_x.requestAccess timed out\n"); ++ return -ETIME; ++ } ++ ++ return 0; ++} ++ ++static int crb_relinquish_locality(struct tpm_chip *chip, int loc) ++{ ++ struct crb_priv *priv = dev_get_drvdata(&chip->dev); ++ ++ return __crb_relinquish_locality(&chip->dev, priv, loc); + } + + static u8 crb_status(struct tpm_chip *chip) +@@ -475,6 +504,10 @@ static int crb_map_io(struct acpi_device + dev_warn(dev, FW_BUG "Bad ACPI memory layout"); + } + ++ ret = __crb_request_locality(dev, priv, 0); ++ if (ret) ++ return ret; ++ + priv->regs_t = crb_map_res(dev, priv, &io_res, buf->control_address, + sizeof(struct crb_regs_tail)); + if (IS_ERR(priv->regs_t)) +@@ -531,6 +564,8 @@ out: + + crb_go_idle(dev, priv); + ++ __crb_relinquish_locality(dev, priv, 0); ++ + return ret; + } + +@@ -588,10 +623,14 @@ static int crb_acpi_add(struct acpi_devi + chip->acpi_dev_handle = device->handle; + chip->flags = TPM_CHIP_FLAG_TPM2; + +- rc = crb_cmd_ready(dev, priv); ++ rc = __crb_request_locality(dev, priv, 0); + 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); +@@ -601,12 +640,15 @@ static int crb_acpi_add(struct acpi_devi + crb_go_idle(dev, priv); + pm_runtime_put_noidle(dev); + pm_runtime_disable(dev); +- return rc; ++ goto out; + } + +- pm_runtime_put(dev); ++ pm_runtime_put_sync(dev); + +- return 0; ++out: ++ __crb_relinquish_locality(dev, priv, 0); ++ ++ return rc; + } + + static int crb_acpi_remove(struct acpi_device *device) +--- a/drivers/char/tpm/tpm_tis_core.c ++++ b/drivers/char/tpm/tpm_tis_core.c +@@ -143,11 +143,13 @@ static bool check_locality(struct tpm_ch + return false; + } + +-static void release_locality(struct tpm_chip *chip, int l) ++static int release_locality(struct tpm_chip *chip, int l) + { + struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev); + + tpm_tis_write8(priv, TPM_ACCESS(l), TPM_ACCESS_ACTIVE_LOCALITY); ++ ++ return 0; + } + + static int request_locality(struct tpm_chip *chip, int l) +--- a/include/linux/tpm.h ++++ b/include/linux/tpm.h +@@ -44,7 +44,7 @@ struct tpm_class_ops { + bool (*update_timeouts)(struct tpm_chip *chip, + unsigned long *timeout_cap); + int (*request_locality)(struct tpm_chip *chip, int loc); +- void (*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); + }; + diff --git a/queue-4.16/tpm-tpm-interface-fix-tpm_transmit-_cmd-kdoc.patch b/queue-4.16/tpm-tpm-interface-fix-tpm_transmit-_cmd-kdoc.patch new file mode 100644 index 00000000000..72ff03c0420 --- /dev/null +++ b/queue-4.16/tpm-tpm-interface-fix-tpm_transmit-_cmd-kdoc.patch @@ -0,0 +1,48 @@ +From 65520d46a4adbf7f23bbb6d9b1773513f7bc7821 Mon Sep 17 00:00:00 2001 +From: "Winkler, Tomas" +Date: Mon, 5 Mar 2018 14:48:25 +0200 +Subject: tpm: tpm-interface: fix tpm_transmit/_cmd kdoc + +From: Winkler, Tomas + +commit 65520d46a4adbf7f23bbb6d9b1773513f7bc7821 upstream. + +Fix tmp_ -> tpm_ typo and add reference to 'space' parameter +in kdoc for tpm_transmit and tpm_transmit_cmd functions. + +Signed-off-by: Tomas Winkler +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm-interface.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/char/tpm/tpm-interface.c ++++ b/drivers/char/tpm/tpm-interface.c +@@ -400,9 +400,10 @@ static void tpm_relinquish_locality(stru + } + + /** +- * tmp_transmit - Internal kernel interface to transmit TPM commands. ++ * tpm_transmit - Internal kernel interface to transmit TPM commands. + * + * @chip: TPM chip to use ++ * @space: tpm space + * @buf: TPM command buffer + * @bufsiz: length of the TPM command buffer + * @flags: tpm transmit flags - bitmap +@@ -544,10 +545,11 @@ out_no_locality: + } + + /** +- * tmp_transmit_cmd - send a tpm command to the device ++ * tpm_transmit_cmd - send a tpm command to the device + * The function extracts tpm out header return code + * + * @chip: TPM chip to use ++ * @space: tpm space + * @buf: TPM command buffer + * @bufsiz: length of the buffer + * @min_rsp_body_length: minimum expected length of response body -- 2.47.3