]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 13 Mar 2018 13:03:01 +0000 (14:03 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 13 Mar 2018 13:03:01 +0000 (14:03 +0100)
added patches:
tpm-delete-the-tpm_tis_clk_enable-flag.patch
tpm-keep-clkrun-enabled-throughout-the-duration-of-transmit_cmd.patch
tpm-only-attempt-to-disable-the-lpc-clkrun-if-is-already-enabled.patch
tpm-remove-unused-variables.patch
tpm_tis-move-ilb_base_addr-to-tpm_tis_data.patch

queue-4.15/series
queue-4.15/tpm-delete-the-tpm_tis_clk_enable-flag.patch [new file with mode: 0644]
queue-4.15/tpm-keep-clkrun-enabled-throughout-the-duration-of-transmit_cmd.patch [new file with mode: 0644]
queue-4.15/tpm-only-attempt-to-disable-the-lpc-clkrun-if-is-already-enabled.patch [new file with mode: 0644]
queue-4.15/tpm-remove-unused-variables.patch [new file with mode: 0644]
queue-4.15/tpm_tis-move-ilb_base_addr-to-tpm_tis_data.patch [new file with mode: 0644]

index fdb8fe83c613f6584a9b0b67f6504449c71d1758..e6860aa852b10c6b1b0a1ba123177ba510458e4d 100644 (file)
@@ -115,3 +115,8 @@ netfilter-ebtables-config_compat-don-t-trust-userland-offsets.patch
 netfilter-bridge-ebt_among-add-missing-match-size-checks.patch
 netfilter-ipv6-fix-use-after-free-write-in-nf_nat_ipv6_manip_pkt.patch
 netfilter-use-skb_to_full_sk-in-ip6_route_me_harder.patch
+tpm_tis-move-ilb_base_addr-to-tpm_tis_data.patch
+tpm-keep-clkrun-enabled-throughout-the-duration-of-transmit_cmd.patch
+tpm-delete-the-tpm_tis_clk_enable-flag.patch
+tpm-remove-unused-variables.patch
+tpm-only-attempt-to-disable-the-lpc-clkrun-if-is-already-enabled.patch
diff --git a/queue-4.15/tpm-delete-the-tpm_tis_clk_enable-flag.patch b/queue-4.15/tpm-delete-the-tpm_tis_clk_enable-flag.patch
new file mode 100644 (file)
index 0000000..79b989c
--- /dev/null
@@ -0,0 +1,107 @@
+From 764325add6c2ad1641199edde7b2995495fc2d7c Mon Sep 17 00:00:00 2001
+From: Javier Martinez Canillas <javierm@redhat.com>
+Date: Mon, 25 Dec 2017 03:22:49 +0100
+Subject: tpm: delete the TPM_TIS_CLK_ENABLE flag
+
+From: Javier Martinez Canillas <javierm@redhat.com>
+
+commit 764325add6c2ad1641199edde7b2995495fc2d7c upstream.
+
+This flag is only used to warn if CLKRUN_EN wasn't disabled on Braswell
+systems, but the only way this can happen is if the code is not correct.
+
+So it's an unnecessary check that just makes the code harder to read.
+
+Suggested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm_tis.c      |   15 ---------------
+ drivers/char/tpm/tpm_tis_core.c |    2 --
+ drivers/char/tpm/tpm_tis_core.h |    1 -
+ 3 files changed, 18 deletions(-)
+
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -138,9 +138,6 @@ static int tpm_tcg_read_bytes(struct tpm
+ {
+       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
+-      if (is_bsw() && !(data->flags & TPM_TIS_CLK_ENABLE))
+-              WARN(1, "CLKRUN not enabled!\n");
+-
+       while (len--)
+               *result++ = ioread8(phy->iobase + addr);
+@@ -152,9 +149,6 @@ static int tpm_tcg_write_bytes(struct tp
+ {
+       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
+-      if (is_bsw() && !(data->flags & TPM_TIS_CLK_ENABLE))
+-              WARN(1, "CLKRUN not enabled!\n");
+-
+       while (len--)
+               iowrite8(*value++, phy->iobase + addr);
+@@ -165,9 +159,6 @@ static int tpm_tcg_read16(struct tpm_tis
+ {
+       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
+-      if (is_bsw() && !(data->flags & TPM_TIS_CLK_ENABLE))
+-              WARN(1, "CLKRUN not enabled!\n");
+-
+       *result = ioread16(phy->iobase + addr);
+       return 0;
+@@ -177,9 +168,6 @@ static int tpm_tcg_read32(struct tpm_tis
+ {
+       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
+-      if (is_bsw() && !(data->flags & TPM_TIS_CLK_ENABLE))
+-              WARN(1, "CLKRUN not enabled!\n");
+-
+       *result = ioread32(phy->iobase + addr);
+       return 0;
+@@ -189,9 +177,6 @@ static int tpm_tcg_write32(struct tpm_ti
+ {
+       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
+-      if (is_bsw() && !(data->flags & TPM_TIS_CLK_ENABLE))
+-              WARN(1, "CLKRUN not enabled!\n");
+-
+       iowrite32(value, phy->iobase + addr);
+       return 0;
+--- a/drivers/char/tpm/tpm_tis_core.c
++++ b/drivers/char/tpm/tpm_tis_core.c
+@@ -698,7 +698,6 @@ static void tpm_tis_clkrun_enable(struct
+               return;
+       if (value) {
+-              data->flags |= TPM_TIS_CLK_ENABLE;
+               data->clkrun_enabled++;
+               if (data->clkrun_enabled > 1)
+                       return;
+@@ -729,7 +728,6 @@ static void tpm_tis_clkrun_enable(struct
+                * sure LPC clock is running before sending any TPM command.
+                */
+               outb(0xCC, 0x80);
+-              data->flags &= ~TPM_TIS_CLK_ENABLE;
+       }
+ }
+--- a/drivers/char/tpm/tpm_tis_core.h
++++ b/drivers/char/tpm/tpm_tis_core.h
+@@ -86,7 +86,6 @@ enum tis_defaults {
+ enum tpm_tis_flags {
+       TPM_TIS_ITPM_WORKAROUND         = BIT(0),
+-      TPM_TIS_CLK_ENABLE              = BIT(1),
+ };
+ struct tpm_tis_data {
diff --git a/queue-4.15/tpm-keep-clkrun-enabled-throughout-the-duration-of-transmit_cmd.patch b/queue-4.15/tpm-keep-clkrun-enabled-throughout-the-duration-of-transmit_cmd.patch
new file mode 100644 (file)
index 0000000..478ae28
--- /dev/null
@@ -0,0 +1,451 @@
+From b3e958ce4c585bf666de249dc794971ebc62d2d3 Mon Sep 17 00:00:00 2001
+From: Azhar Shaikh <azhar.shaikh@intel.com>
+Date: Fri, 22 Dec 2017 12:13:44 -0800
+Subject: tpm: Keep CLKRUN enabled throughout the duration of transmit_cmd()
+
+From: Azhar Shaikh <azhar.shaikh@intel.com>
+
+commit b3e958ce4c585bf666de249dc794971ebc62d2d3 upstream.
+
+Commit 5e572cab92f0bb5 ("tpm: Enable CLKRUN protocol for Braswell
+systems") disabled CLKRUN protocol during TPM transactions and re-enabled
+once the transaction is completed. But there were still some corner cases
+observed where, reading of TPM header failed for savestate command
+while going to suspend, which resulted in suspend failure.
+To fix this issue keep the CLKRUN protocol disabled for the entire
+duration of a single TPM command and not disabling and re-enabling
+again for every TPM transaction. For the other TPM accesses outside
+TPM command flow, add a higher level of disabling and re-enabling
+the CLKRUN protocol, instead of doing for every TPM transaction.
+
+Fixes: 5e572cab92f0bb5 ("tpm: Enable CLKRUN protocol for Braswell systems")
+Signed-off-by: Azhar Shaikh <azhar.shaikh@intel.com>
+Reviewed-by: Jarkko Sakkinen  <jarkko.sakkinen@linux.intel.com>
+Tested-by: Jarkko Sakkinen  <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen  <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm-interface.c |    6 ++
+ drivers/char/tpm/tpm_tis.c       |   92 +++------------------------------
+ drivers/char/tpm/tpm_tis_core.c  |  108 +++++++++++++++++++++++++++++++++++----
+ drivers/char/tpm/tpm_tis_core.h  |    4 +
+ include/linux/tpm.h              |    1 
+ 5 files changed, 119 insertions(+), 92 deletions(-)
+
+--- a/drivers/char/tpm/tpm-interface.c
++++ b/drivers/char/tpm/tpm-interface.c
+@@ -413,6 +413,9 @@ ssize_t tpm_transmit(struct tpm_chip *ch
+       if (chip->dev.parent)
+               pm_runtime_get_sync(chip->dev.parent);
++      if (chip->ops->clk_enable != NULL)
++              chip->ops->clk_enable(chip, true);
++
+       /* Store the decision as chip->locality will be changed. */
+       need_locality = chip->locality == -1;
+@@ -489,6 +492,9 @@ out:
+               chip->locality = -1;
+       }
+ 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);
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -133,79 +133,17 @@ static int check_acpi_tpm2(struct device
+ }
+ #endif
+-#ifdef CONFIG_X86
+-#define LPC_CNTRL_OFFSET              0x84
+-#define LPC_CLKRUN_EN                 (1 << 2)
+-
+-/**
+- * tpm_platform_begin_xfer() - clear LPC CLKRUN_EN i.e. clocks will be running
+- */
+-static void tpm_platform_begin_xfer(struct tpm_tis_data *data)
+-{
+-      u32 clkrun_val;
+-
+-      if (!is_bsw())
+-              return;
+-
+-      clkrun_val = ioread32(data->ilb_base_addr + LPC_CNTRL_OFFSET);
+-
+-      /* Disable LPC CLKRUN# */
+-      clkrun_val &= ~LPC_CLKRUN_EN;
+-      iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET);
+-
+-      /*
+-       * Write any random value on port 0x80 which is on LPC, to make
+-       * sure LPC clock is running before sending any TPM command.
+-       */
+-      outb(0xCC, 0x80);
+-
+-}
+-
+-/**
+- * tpm_platform_end_xfer() - set LPC CLKRUN_EN i.e. clocks can be turned off
+- */
+-static void tpm_platform_end_xfer(struct tpm_tis_data *data)
+-{
+-      u32 clkrun_val;
+-
+-      if (!is_bsw())
+-              return;
+-
+-      clkrun_val = ioread32(data->ilb_base_addr + LPC_CNTRL_OFFSET);
+-
+-      /* Enable LPC CLKRUN# */
+-      clkrun_val |= LPC_CLKRUN_EN;
+-      iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET);
+-
+-      /*
+-       * Write any random value on port 0x80 which is on LPC, to make
+-       * sure LPC clock is running before sending any TPM command.
+-       */
+-      outb(0xCC, 0x80);
+-
+-}
+-#else
+-static void tpm_platform_begin_xfer(struct tpm_tis_data *data)
+-{
+-}
+-
+-static void tpm_platform_end_xfer(struct tpm_tis_data *data)
+-{
+-}
+-#endif
+-
+ static int tpm_tcg_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len,
+                             u8 *result)
+ {
+       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
+-      tpm_platform_begin_xfer(data);
++      if (is_bsw() && !(data->flags & TPM_TIS_CLK_ENABLE))
++              WARN(1, "CLKRUN not enabled!\n");
+       while (len--)
+               *result++ = ioread8(phy->iobase + addr);
+-      tpm_platform_end_xfer(data);
+-
+       return 0;
+ }
+@@ -214,13 +152,12 @@ static int tpm_tcg_write_bytes(struct tp
+ {
+       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
+-      tpm_platform_begin_xfer(data);
++      if (is_bsw() && !(data->flags & TPM_TIS_CLK_ENABLE))
++              WARN(1, "CLKRUN not enabled!\n");
+       while (len--)
+               iowrite8(*value++, phy->iobase + addr);
+-      tpm_platform_end_xfer(data);
+-
+       return 0;
+ }
+@@ -228,12 +165,11 @@ static int tpm_tcg_read16(struct tpm_tis
+ {
+       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
+-      tpm_platform_begin_xfer(data);
++      if (is_bsw() && !(data->flags & TPM_TIS_CLK_ENABLE))
++              WARN(1, "CLKRUN not enabled!\n");
+       *result = ioread16(phy->iobase + addr);
+-      tpm_platform_end_xfer(data);
+-
+       return 0;
+ }
+@@ -241,12 +177,11 @@ static int tpm_tcg_read32(struct tpm_tis
+ {
+       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
+-      tpm_platform_begin_xfer(data);
++      if (is_bsw() && !(data->flags & TPM_TIS_CLK_ENABLE))
++              WARN(1, "CLKRUN not enabled!\n");
+       *result = ioread32(phy->iobase + addr);
+-      tpm_platform_end_xfer(data);
+-
+       return 0;
+ }
+@@ -254,12 +189,11 @@ static int tpm_tcg_write32(struct tpm_ti
+ {
+       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
+-      tpm_platform_begin_xfer(data);
++      if (is_bsw() && !(data->flags & TPM_TIS_CLK_ENABLE))
++              WARN(1, "CLKRUN not enabled!\n");
+       iowrite32(value, phy->iobase + addr);
+-      tpm_platform_end_xfer(data);
+-
+       return 0;
+ }
+@@ -341,9 +275,6 @@ static void tpm_tis_pnp_remove(struct pn
+       tpm_chip_unregister(chip);
+       tpm_tis_remove(chip);
+-      if (is_bsw())
+-              iounmap(priv->ilb_base_addr);
+-
+ }
+ static struct pnp_driver tis_pnp_driver = {
+@@ -395,9 +326,6 @@ static int tpm_tis_plat_remove(struct pl
+       tpm_chip_unregister(chip);
+       tpm_tis_remove(chip);
+-      if (is_bsw())
+-              iounmap(priv->ilb_base_addr);
+-
+       return 0;
+ }
+--- a/drivers/char/tpm/tpm_tis_core.c
++++ b/drivers/char/tpm/tpm_tis_core.c
+@@ -31,6 +31,8 @@
+ #include "tpm.h"
+ #include "tpm_tis_core.h"
++static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value);
++
+ /* Before we attempt to access the TPM we must see that the valid bit is set.
+  * The specification says that this bit is 0 at reset and remains 0 until the
+  * 'TPM has gone through its self test and initialization and has established
+@@ -422,19 +424,28 @@ static bool tpm_tis_update_timeouts(stru
+       int i, rc;
+       u32 did_vid;
++      if (chip->ops->clk_enable != NULL)
++              chip->ops->clk_enable(chip, true);
++
+       rc = tpm_tis_read32(priv, TPM_DID_VID(0), &did_vid);
+       if (rc < 0)
+-              return rc;
++              goto out;
+       for (i = 0; i != ARRAY_SIZE(vendor_timeout_overrides); i++) {
+               if (vendor_timeout_overrides[i].did_vid != did_vid)
+                       continue;
+               memcpy(timeout_cap, vendor_timeout_overrides[i].timeout_us,
+                      sizeof(vendor_timeout_overrides[i].timeout_us));
+-              return true;
++              rc = true;
+       }
+-      return false;
++      rc = false;
++
++out:
++      if (chip->ops->clk_enable != NULL)
++              chip->ops->clk_enable(chip, false);
++
++      return rc;
+ }
+ /*
+@@ -654,14 +665,74 @@ void tpm_tis_remove(struct tpm_chip *chi
+       u32 interrupt;
+       int rc;
++      tpm_tis_clkrun_enable(chip, true);
++
+       rc = tpm_tis_read32(priv, reg, &interrupt);
+       if (rc < 0)
+               interrupt = 0;
+       tpm_tis_write32(priv, reg, ~TPM_GLOBAL_INT_ENABLE & interrupt);
++
++      tpm_tis_clkrun_enable(chip, false);
++
++      if (priv->ilb_base_addr)
++              iounmap(priv->ilb_base_addr);
+ }
+ EXPORT_SYMBOL_GPL(tpm_tis_remove);
++/**
++ * tpm_tis_clkrun_enable() - Keep clkrun protocol disabled for entire duration
++ *                           of a single TPM command
++ * @chip:     TPM chip to use
++ * @value:    1 - Disable CLKRUN protocol, so that clocks are free running
++ *            0 - Enable CLKRUN protocol
++ * Call this function directly in tpm_tis_remove() in error or driver removal
++ * path, since the chip->ops is set to NULL in tpm_chip_unregister().
++ */
++static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value)
++{
++      struct tpm_tis_data *data = dev_get_drvdata(&chip->dev);
++      u32 clkrun_val;
++
++      if (!IS_ENABLED(CONFIG_X86) || !is_bsw())
++              return;
++
++      if (value) {
++              data->flags |= TPM_TIS_CLK_ENABLE;
++              data->clkrun_enabled++;
++              if (data->clkrun_enabled > 1)
++                      return;
++              clkrun_val = ioread32(data->ilb_base_addr + LPC_CNTRL_OFFSET);
++
++              /* Disable LPC CLKRUN# */
++              clkrun_val &= ~LPC_CLKRUN_EN;
++              iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET);
++
++              /*
++               * Write any random value on port 0x80 which is on LPC, to make
++               * sure LPC clock is running before sending any TPM command.
++               */
++              outb(0xCC, 0x80);
++      } else {
++              data->clkrun_enabled--;
++              if (data->clkrun_enabled)
++                      return;
++
++              clkrun_val = ioread32(data->ilb_base_addr + LPC_CNTRL_OFFSET);
++
++              /* Enable LPC CLKRUN# */
++              clkrun_val |= LPC_CLKRUN_EN;
++              iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET);
++
++              /*
++               * Write any random value on port 0x80 which is on LPC, to make
++               * sure LPC clock is running before sending any TPM command.
++               */
++              outb(0xCC, 0x80);
++              data->flags &= ~TPM_TIS_CLK_ENABLE;
++      }
++}
++
+ static const struct tpm_class_ops tpm_tis = {
+       .flags = TPM_OPS_AUTO_STARTUP,
+       .status = tpm_tis_status,
+@@ -674,6 +745,7 @@ static const struct tpm_class_ops tpm_ti
+       .req_canceled = tpm_tis_req_canceled,
+       .request_locality = request_locality,
+       .relinquish_locality = release_locality,
++      .clk_enable = tpm_tis_clkrun_enable,
+ };
+ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
+@@ -708,6 +780,9 @@ int tpm_tis_core_init(struct device *dev
+                       return -ENOMEM;
+       }
++      if (chip->ops->clk_enable != NULL)
++              chip->ops->clk_enable(chip, true);
++
+       if (wait_startup(chip, 0) != 0) {
+               rc = -ENODEV;
+               goto out_err;
+@@ -799,14 +874,18 @@ int tpm_tis_core_init(struct device *dev
+       }
+       rc = tpm_chip_register(chip);
+-      if (rc && is_bsw())
+-              iounmap(priv->ilb_base_addr);
++      if (rc)
++              goto out_err;
+-      return rc;
++      if (chip->ops->clk_enable != NULL)
++              chip->ops->clk_enable(chip, false);
++
++      return 0;
+ out_err:
++      if ((chip->ops != NULL) && (chip->ops->clk_enable != NULL))
++              chip->ops->clk_enable(chip, false);
++
+       tpm_tis_remove(chip);
+-      if (is_bsw())
+-              iounmap(priv->ilb_base_addr);
+       return rc;
+ }
+@@ -819,22 +898,31 @@ static void tpm_tis_reenable_interrupts(
+       u32 intmask;
+       int rc;
++      if (chip->ops->clk_enable != NULL)
++              chip->ops->clk_enable(chip, true);
++
+       /* reenable interrupts that device may have lost or
+        * BIOS/firmware may have disabled
+        */
+       rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), priv->irq);
+       if (rc < 0)
+-              return;
++              goto out;
+       rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask);
+       if (rc < 0)
+-              return;
++              goto out;
+       intmask |= TPM_INTF_CMD_READY_INT
+           | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
+           | TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE;
+       tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask);
++
++out:
++      if (chip->ops->clk_enable != NULL)
++              chip->ops->clk_enable(chip, false);
++
++      return;
+ }
+ int tpm_tis_resume(struct device *dev)
+--- a/drivers/char/tpm/tpm_tis_core.h
++++ b/drivers/char/tpm/tpm_tis_core.h
+@@ -79,11 +79,14 @@ enum tis_defaults {
+ #define       TPM_DID_VID(l)                  (0x0F00 | ((l) << 12))
+ #define       TPM_RID(l)                      (0x0F04 | ((l) << 12))
++#define LPC_CNTRL_OFFSET              0x84
++#define LPC_CLKRUN_EN                 (1 << 2)
+ #define INTEL_LEGACY_BLK_BASE_ADDR    0xFED08000
+ #define ILB_REMAP_SIZE                        0x100
+ enum tpm_tis_flags {
+       TPM_TIS_ITPM_WORKAROUND         = BIT(0),
++      TPM_TIS_CLK_ENABLE              = BIT(1),
+ };
+ struct tpm_tis_data {
+@@ -93,6 +96,7 @@ struct tpm_tis_data {
+       bool irq_tested;
+       unsigned int flags;
+       void __iomem *ilb_base_addr;
++      u16 clkrun_enabled;
+       wait_queue_head_t int_queue;
+       wait_queue_head_t read_queue;
+       const struct tpm_tis_phy_ops *phy_ops;
+--- a/include/linux/tpm.h
++++ b/include/linux/tpm.h
+@@ -50,6 +50,7 @@ struct tpm_class_ops {
+                               unsigned long *timeout_cap);
+       int (*request_locality)(struct tpm_chip *chip, int loc);
+       void (*relinquish_locality)(struct tpm_chip *chip, int loc);
++      void (*clk_enable)(struct tpm_chip *chip, bool value);
+ };
+ #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
diff --git a/queue-4.15/tpm-only-attempt-to-disable-the-lpc-clkrun-if-is-already-enabled.patch b/queue-4.15/tpm-only-attempt-to-disable-the-lpc-clkrun-if-is-already-enabled.patch
new file mode 100644 (file)
index 0000000..e1c1dfb
--- /dev/null
@@ -0,0 +1,71 @@
+From 6c9f0ce0dffe64da2204f38b0fd90f3ae2a8903c Mon Sep 17 00:00:00 2001
+From: Javier Martinez Canillas <javierm@redhat.com>
+Date: Mon, 25 Dec 2017 03:22:51 +0100
+Subject: tpm: only attempt to disable the LPC CLKRUN if is already enabled
+
+From: Javier Martinez Canillas <javierm@redhat.com>
+
+commit 6c9f0ce0dffe64da2204f38b0fd90f3ae2a8903c upstream.
+
+Commit 5e572cab92f0 ("tpm: Enable CLKRUN protocol for Braswell systems")
+added logic in the TPM TIS driver to disable the Low Pin Count CLKRUN
+signal during TPM transactions.
+
+Unfortunately this breaks other devices that are attached to the LPC bus
+like for example PS/2 mouse and keyboards.
+
+One flaw with the logic is that it assumes that the CLKRUN is always
+enabled, and so it unconditionally enables it after a TPM transaction.
+
+But it could be that the CLKRUN# signal was already disabled in the LPC
+bus and so after the driver probes, CLKRUN_EN will remain enabled which
+may break other devices that are attached to the LPC bus but don't have
+support for the CLKRUN protocol.
+
+Fixes: 5e572cab92f0 ("tpm: Enable CLKRUN protocol for Braswell systems")
+Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
+Tested-by: James Ettle <james@ettle.org.uk>
+Tested-by: Jeffery Miller <jmiller@neverware.com>
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm_tis_core.c |   11 ++++++++++-
+ 1 file changed, 10 insertions(+), 1 deletion(-)
+
+--- a/drivers/char/tpm/tpm_tis_core.c
++++ b/drivers/char/tpm/tpm_tis_core.c
+@@ -694,7 +694,8 @@ static void tpm_tis_clkrun_enable(struct
+       struct tpm_tis_data *data = dev_get_drvdata(&chip->dev);
+       u32 clkrun_val;
+-      if (!IS_ENABLED(CONFIG_X86) || !is_bsw())
++      if (!IS_ENABLED(CONFIG_X86) || !is_bsw() ||
++          !data->ilb_base_addr)
+               return;
+       if (value) {
+@@ -751,6 +752,7 @@ int tpm_tis_core_init(struct device *dev
+                     acpi_handle acpi_dev_handle)
+ {
+       u32 vendor, intfcaps, intmask;
++      u32 clkrun_val;
+       u8 rid;
+       int rc, probe;
+       struct tpm_chip *chip;
+@@ -776,6 +778,13 @@ int tpm_tis_core_init(struct device *dev
+                                       ILB_REMAP_SIZE);
+               if (!priv->ilb_base_addr)
+                       return -ENOMEM;
++
++              clkrun_val = ioread32(priv->ilb_base_addr + LPC_CNTRL_OFFSET);
++              /* Check if CLKRUN# is already not enabled in the LPC bus */
++              if (!(clkrun_val & LPC_CLKRUN_EN)) {
++                      iounmap(priv->ilb_base_addr);
++                      priv->ilb_base_addr = NULL;
++              }
+       }
+       if (chip->ops->clk_enable != NULL)
diff --git a/queue-4.15/tpm-remove-unused-variables.patch b/queue-4.15/tpm-remove-unused-variables.patch
new file mode 100644 (file)
index 0000000..a38a80e
--- /dev/null
@@ -0,0 +1,47 @@
+From 68021bf4734d15c9a9ed1c1072b9ebcfda3e39cc Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Tue, 2 Jan 2018 11:38:54 +0100
+Subject: tpm: remove unused variables
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+commit 68021bf4734d15c9a9ed1c1072b9ebcfda3e39cc upstream.
+
+The CLKRUN fix caused a few harmless compile-time warnings:
+
+drivers/char/tpm/tpm_tis.c: In function 'tpm_tis_pnp_remove':
+drivers/char/tpm/tpm_tis.c:274:23: error: unused variable 'priv' [-Werror=unused-variable]
+drivers/char/tpm/tpm_tis.c: In function 'tpm_tis_plat_remove':
+drivers/char/tpm/tpm_tis.c:324:23: error: unused variable 'priv' [-Werror=unused-variable]
+
+This removes the variables that have now become unused.
+
+Fixes: 6d0866cbc2d3 ("tpm: Keep CLKRUN enabled throughout the duration of transmit_cmd()")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Reviewed-by: James Morris <jmorris@namei.org>
+Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm_tis.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -256,7 +256,6 @@ MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
+ static void tpm_tis_pnp_remove(struct pnp_dev *dev)
+ {
+       struct tpm_chip *chip = pnp_get_drvdata(dev);
+-      struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+       tpm_chip_unregister(chip);
+       tpm_tis_remove(chip);
+@@ -306,7 +305,6 @@ static int tpm_tis_plat_probe(struct pla
+ static int tpm_tis_plat_remove(struct platform_device *pdev)
+ {
+       struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
+-      struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+       tpm_chip_unregister(chip);
+       tpm_tis_remove(chip);
diff --git a/queue-4.15/tpm_tis-move-ilb_base_addr-to-tpm_tis_data.patch b/queue-4.15/tpm_tis-move-ilb_base_addr-to-tpm_tis_data.patch
new file mode 100644 (file)
index 0000000..1ce0927
--- /dev/null
@@ -0,0 +1,311 @@
+From c382babccba2c82fe57f9e647f290fb7bf4d130d Mon Sep 17 00:00:00 2001
+From: Azhar Shaikh <azhar.shaikh@intel.com>
+Date: Fri, 22 Dec 2017 12:13:43 -0800
+Subject: tpm_tis: Move ilb_base_addr to tpm_tis_data
+
+From: Azhar Shaikh <azhar.shaikh@intel.com>
+
+commit c382babccba2c82fe57f9e647f290fb7bf4d130d upstream.
+
+Move static variable ilb_base_addr to tpm_tis_data.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Azhar Shaikh <azhar.shaikh@intel.com>
+Reviewed-by: Jarkko Sakkinen  <jarkko.sakkinen@linux.intel.com>
+Tested-by: Jarkko Sakkinen  <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Jarkko Sakkinen  <jarkko.sakkinen@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm_tis.c      |   75 ++++++++++++++--------------------------
+ drivers/char/tpm/tpm_tis_core.c |   16 ++++++++
+ drivers/char/tpm/tpm_tis_core.h |   13 ++++++
+ 3 files changed, 56 insertions(+), 48 deletions(-)
+
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -134,33 +134,24 @@ static int check_acpi_tpm2(struct device
+ #endif
+ #ifdef CONFIG_X86
+-#define INTEL_LEGACY_BLK_BASE_ADDR      0xFED08000
+-#define ILB_REMAP_SIZE                        0x100
+-#define LPC_CNTRL_REG_OFFSET            0x84
+-#define LPC_CLKRUN_EN                   (1 << 2)
+-
+-static void __iomem *ilb_base_addr;
+-
+-static inline bool is_bsw(void)
+-{
+-      return ((boot_cpu_data.x86_model == INTEL_FAM6_ATOM_AIRMONT) ? 1 : 0);
+-}
++#define LPC_CNTRL_OFFSET              0x84
++#define LPC_CLKRUN_EN                 (1 << 2)
+ /**
+  * tpm_platform_begin_xfer() - clear LPC CLKRUN_EN i.e. clocks will be running
+  */
+-static void tpm_platform_begin_xfer(void)
++static void tpm_platform_begin_xfer(struct tpm_tis_data *data)
+ {
+       u32 clkrun_val;
+       if (!is_bsw())
+               return;
+-      clkrun_val = ioread32(ilb_base_addr + LPC_CNTRL_REG_OFFSET);
++      clkrun_val = ioread32(data->ilb_base_addr + LPC_CNTRL_OFFSET);
+       /* Disable LPC CLKRUN# */
+       clkrun_val &= ~LPC_CLKRUN_EN;
+-      iowrite32(clkrun_val, ilb_base_addr + LPC_CNTRL_REG_OFFSET);
++      iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET);
+       /*
+        * Write any random value on port 0x80 which is on LPC, to make
+@@ -173,18 +164,18 @@ static void tpm_platform_begin_xfer(void
+ /**
+  * tpm_platform_end_xfer() - set LPC CLKRUN_EN i.e. clocks can be turned off
+  */
+-static void tpm_platform_end_xfer(void)
++static void tpm_platform_end_xfer(struct tpm_tis_data *data)
+ {
+       u32 clkrun_val;
+       if (!is_bsw())
+               return;
+-      clkrun_val = ioread32(ilb_base_addr + LPC_CNTRL_REG_OFFSET);
++      clkrun_val = ioread32(data->ilb_base_addr + LPC_CNTRL_OFFSET);
+       /* Enable LPC CLKRUN# */
+       clkrun_val |= LPC_CLKRUN_EN;
+-      iowrite32(clkrun_val, ilb_base_addr + LPC_CNTRL_REG_OFFSET);
++      iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET);
+       /*
+        * Write any random value on port 0x80 which is on LPC, to make
+@@ -194,16 +185,11 @@ static void tpm_platform_end_xfer(void)
+ }
+ #else
+-static inline bool is_bsw(void)
+-{
+-      return false;
+-}
+-
+-static void tpm_platform_begin_xfer(void)
++static void tpm_platform_begin_xfer(struct tpm_tis_data *data)
+ {
+ }
+-static void tpm_platform_end_xfer(void)
++static void tpm_platform_end_xfer(struct tpm_tis_data *data)
+ {
+ }
+ #endif
+@@ -213,12 +199,12 @@ static int tpm_tcg_read_bytes(struct tpm
+ {
+       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
+-      tpm_platform_begin_xfer();
++      tpm_platform_begin_xfer(data);
+       while (len--)
+               *result++ = ioread8(phy->iobase + addr);
+-      tpm_platform_end_xfer();
++      tpm_platform_end_xfer(data);
+       return 0;
+ }
+@@ -228,12 +214,12 @@ static int tpm_tcg_write_bytes(struct tp
+ {
+       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
+-      tpm_platform_begin_xfer();
++      tpm_platform_begin_xfer(data);
+       while (len--)
+               iowrite8(*value++, phy->iobase + addr);
+-      tpm_platform_end_xfer();
++      tpm_platform_end_xfer(data);
+       return 0;
+ }
+@@ -242,11 +228,11 @@ static int tpm_tcg_read16(struct tpm_tis
+ {
+       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
+-      tpm_platform_begin_xfer();
++      tpm_platform_begin_xfer(data);
+       *result = ioread16(phy->iobase + addr);
+-      tpm_platform_end_xfer();
++      tpm_platform_end_xfer(data);
+       return 0;
+ }
+@@ -255,11 +241,11 @@ static int tpm_tcg_read32(struct tpm_tis
+ {
+       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
+-      tpm_platform_begin_xfer();
++      tpm_platform_begin_xfer(data);
+       *result = ioread32(phy->iobase + addr);
+-      tpm_platform_end_xfer();
++      tpm_platform_end_xfer(data);
+       return 0;
+ }
+@@ -268,11 +254,11 @@ static int tpm_tcg_write32(struct tpm_ti
+ {
+       struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data);
+-      tpm_platform_begin_xfer();
++      tpm_platform_begin_xfer(data);
+       iowrite32(value, phy->iobase + addr);
+-      tpm_platform_end_xfer();
++      tpm_platform_end_xfer(data);
+       return 0;
+ }
+@@ -351,9 +337,13 @@ MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
+ static void tpm_tis_pnp_remove(struct pnp_dev *dev)
+ {
+       struct tpm_chip *chip = pnp_get_drvdata(dev);
++      struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+       tpm_chip_unregister(chip);
+       tpm_tis_remove(chip);
++      if (is_bsw())
++              iounmap(priv->ilb_base_addr);
++
+ }
+ static struct pnp_driver tis_pnp_driver = {
+@@ -400,10 +390,14 @@ static int tpm_tis_plat_probe(struct pla
+ static int tpm_tis_plat_remove(struct platform_device *pdev)
+ {
+       struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
++      struct tpm_tis_data *priv = dev_get_drvdata(&chip->dev);
+       tpm_chip_unregister(chip);
+       tpm_tis_remove(chip);
++      if (is_bsw())
++              iounmap(priv->ilb_base_addr);
++
+       return 0;
+ }
+@@ -461,11 +455,6 @@ static int __init init_tis(void)
+       if (rc)
+               goto err_force;
+-#ifdef CONFIG_X86
+-      if (is_bsw())
+-              ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR,
+-                                      ILB_REMAP_SIZE);
+-#endif
+       rc = platform_driver_register(&tis_drv);
+       if (rc)
+               goto err_platform;
+@@ -484,10 +473,6 @@ err_pnp:
+ err_platform:
+       if (force_pdev)
+               platform_device_unregister(force_pdev);
+-#ifdef CONFIG_X86
+-      if (is_bsw())
+-              iounmap(ilb_base_addr);
+-#endif
+ err_force:
+       return rc;
+ }
+@@ -497,10 +482,6 @@ static void __exit cleanup_tis(void)
+       pnp_unregister_driver(&tis_pnp_driver);
+       platform_driver_unregister(&tis_drv);
+-#ifdef CONFIG_X86
+-      if (is_bsw())
+-              iounmap(ilb_base_addr);
+-#endif
+       if (force_pdev)
+               platform_device_unregister(force_pdev);
+ }
+--- a/drivers/char/tpm/tpm_tis_core.c
++++ b/drivers/char/tpm/tpm_tis_core.c
+@@ -701,6 +701,13 @@ int tpm_tis_core_init(struct device *dev
+       priv->phy_ops = phy_ops;
+       dev_set_drvdata(&chip->dev, priv);
++      if (is_bsw()) {
++              priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR,
++                                      ILB_REMAP_SIZE);
++              if (!priv->ilb_base_addr)
++                      return -ENOMEM;
++      }
++
+       if (wait_startup(chip, 0) != 0) {
+               rc = -ENODEV;
+               goto out_err;
+@@ -791,9 +798,16 @@ int tpm_tis_core_init(struct device *dev
+               }
+       }
+-      return tpm_chip_register(chip);
++      rc = tpm_chip_register(chip);
++      if (rc && is_bsw())
++              iounmap(priv->ilb_base_addr);
++
++      return rc;
+ out_err:
+       tpm_tis_remove(chip);
++      if (is_bsw())
++              iounmap(priv->ilb_base_addr);
++
+       return rc;
+ }
+ EXPORT_SYMBOL_GPL(tpm_tis_core_init);
+--- a/drivers/char/tpm/tpm_tis_core.h
++++ b/drivers/char/tpm/tpm_tis_core.h
+@@ -79,6 +79,9 @@ enum tis_defaults {
+ #define       TPM_DID_VID(l)                  (0x0F00 | ((l) << 12))
+ #define       TPM_RID(l)                      (0x0F04 | ((l) << 12))
++#define INTEL_LEGACY_BLK_BASE_ADDR    0xFED08000
++#define ILB_REMAP_SIZE                        0x100
++
+ enum tpm_tis_flags {
+       TPM_TIS_ITPM_WORKAROUND         = BIT(0),
+ };
+@@ -89,6 +92,7 @@ struct tpm_tis_data {
+       int irq;
+       bool irq_tested;
+       unsigned int flags;
++      void __iomem *ilb_base_addr;
+       wait_queue_head_t int_queue;
+       wait_queue_head_t read_queue;
+       const struct tpm_tis_phy_ops *phy_ops;
+@@ -144,6 +148,15 @@ static inline int tpm_tis_write32(struct
+       return data->phy_ops->write32(data, addr, value);
+ }
++static inline bool is_bsw(void)
++{
++#ifdef CONFIG_X86
++      return ((boot_cpu_data.x86_model == INTEL_FAM6_ATOM_AIRMONT) ? 1 : 0);
++#else
++      return false;
++#endif
++}
++
+ void tpm_tis_remove(struct tpm_chip *chip);
+ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq,
+                     const struct tpm_tis_phy_ops *phy_ops,