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
--- /dev/null
+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 {
--- /dev/null
+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)
--- /dev/null
+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)
--- /dev/null
+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);
--- /dev/null
+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,