]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 28 Feb 2015 22:56:19 +0000 (14:56 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 28 Feb 2015 22:56:19 +0000 (14:56 -0800)
added patches:
arm-8284-1-sa1100-clear-rcsr_smr-on-resume.patch
tpm_tis-verify-interrupt-during-init.patch
tracing-fix-unmapping-loop-in-tracing_mark_write.patch

queue-3.10/arm-8284-1-sa1100-clear-rcsr_smr-on-resume.patch [new file with mode: 0644]
queue-3.10/series
queue-3.10/tpm_tis-verify-interrupt-during-init.patch [new file with mode: 0644]
queue-3.10/tracing-fix-unmapping-loop-in-tracing_mark_write.patch [new file with mode: 0644]

diff --git a/queue-3.10/arm-8284-1-sa1100-clear-rcsr_smr-on-resume.patch b/queue-3.10/arm-8284-1-sa1100-clear-rcsr_smr-on-resume.patch
new file mode 100644 (file)
index 0000000..045fb68
--- /dev/null
@@ -0,0 +1,33 @@
+From e461894dc2ce7778ccde1c3483c9b15a85a7fc5f Mon Sep 17 00:00:00 2001
+From: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+Date: Thu, 15 Jan 2015 03:06:22 +0100
+Subject: ARM: 8284/1: sa1100: clear RCSR_SMR on resume
+
+From: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+
+commit e461894dc2ce7778ccde1c3483c9b15a85a7fc5f upstream.
+
+StrongARM core uses RCSR SMR bit to tell to bootloader that it was reset
+by entering the sleep mode. After we have resumed, there is little point
+in having that bit enabled. Moreover, if this bit is set before reboot,
+the bootloader can become confused. Thus clear the SMR bit on resume
+just before clearing the scratchpad (resume address) register.
+
+Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arm/mach-sa1100/pm.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/arm/mach-sa1100/pm.c
++++ b/arch/arm/mach-sa1100/pm.c
+@@ -81,6 +81,7 @@ static int sa11x0_pm_enter(suspend_state
+       /*
+        * Ensure not to come back here if it wasn't intended
+        */
++      RCSR = RCSR_SMR;
+       PSPR = 0;
+       /*
index 159794579bb29af53394467aa4e8aa9fd7c47d84..ff737528f136653157c4db76763db3ab01998ab8 100644 (file)
@@ -18,3 +18,6 @@ power_supply-88pm860x-fix-leaked-power-supply-on-probe-fail.patch
 mmc-sdhci-pxav3-fix-setting-of-pdata-clk_delay_cycles.patch
 nfs-don-t-call-blocking-operations-while-task_running.patch
 mips-kvm-deliver-guest-interrupts-after-local_irq_disable.patch
+tracing-fix-unmapping-loop-in-tracing_mark_write.patch
+arm-8284-1-sa1100-clear-rcsr_smr-on-resume.patch
+tpm_tis-verify-interrupt-during-init.patch
diff --git a/queue-3.10/tpm_tis-verify-interrupt-during-init.patch b/queue-3.10/tpm_tis-verify-interrupt-during-init.patch
new file mode 100644 (file)
index 0000000..aa07a79
--- /dev/null
@@ -0,0 +1,163 @@
+From 448e9c55c12d6bd4fa90a7e31d802e045666d7c8 Mon Sep 17 00:00:00 2001
+From: Scot Doyle <lkml14@scotdoyle.com>
+Date: Wed, 24 Sep 2014 22:41:10 +0000
+Subject: tpm_tis: verify interrupt during init
+
+From: Scot Doyle <lkml14@scotdoyle.com>
+
+commit 448e9c55c12d6bd4fa90a7e31d802e045666d7c8 upstream.
+
+Some machines, such as the Acer C720 and Toshiba CB35, have TPMs that do
+not send IRQs while also having an ACPI TPM entry indicating that they
+will be sent. These machines freeze on resume while the tpm_tis module
+waits for an IRQ, eventually timing out.
+
+When in interrupt mode, the tpm_tis module should receive an IRQ during
+module init. Fall back to polling mode if none is received when expected.
+
+Signed-off-by: Scot Doyle <lkml14@scotdoyle.com>
+Tested-by: Michael Mullin <masmullin@gmail.com>
+Reviewed-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
+[phuewe: minor checkpatch fixed]
+Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/tpm/tpm_tis.c |   76 ++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 62 insertions(+), 14 deletions(-)
+
+--- a/drivers/char/tpm/tpm_tis.c
++++ b/drivers/char/tpm/tpm_tis.c
+@@ -75,6 +75,10 @@ enum tis_defaults {
+ #define       TPM_DID_VID(l)                  (0x0F00 | ((l) << 12))
+ #define       TPM_RID(l)                      (0x0F04 | ((l) << 12))
++struct priv_data {
++      bool irq_tested;
++};
++
+ static LIST_HEAD(tis_chips);
+ static DEFINE_MUTEX(tis_lock);
+@@ -338,12 +342,27 @@ out_err:
+       return rc;
+ }
++static void disable_interrupts(struct tpm_chip *chip)
++{
++      u32 intmask;
++
++      intmask =
++          ioread32(chip->vendor.iobase +
++                   TPM_INT_ENABLE(chip->vendor.locality));
++      intmask &= ~TPM_GLOBAL_INT_ENABLE;
++      iowrite32(intmask,
++                chip->vendor.iobase +
++                TPM_INT_ENABLE(chip->vendor.locality));
++      free_irq(chip->vendor.irq, chip);
++      chip->vendor.irq = 0;
++}
++
+ /*
+  * If interrupts are used (signaled by an irq set in the vendor structure)
+  * tpm.c can skip polling for the data to be available as the interrupt is
+  * waited for here
+  */
+-static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
++static int tpm_tis_send_main(struct tpm_chip *chip, u8 *buf, size_t len)
+ {
+       int rc;
+       u32 ordinal;
+@@ -373,6 +392,30 @@ out_err:
+       return rc;
+ }
++static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
++{
++      int rc, irq;
++      struct priv_data *priv = chip->vendor.priv;
++
++      if (!chip->vendor.irq || priv->irq_tested)
++              return tpm_tis_send_main(chip, buf, len);
++
++      /* Verify receipt of the expected IRQ */
++      irq = chip->vendor.irq;
++      chip->vendor.irq = 0;
++      rc = tpm_tis_send_main(chip, buf, len);
++      chip->vendor.irq = irq;
++      if (!priv->irq_tested)
++              msleep(1);
++      if (!priv->irq_tested) {
++              disable_interrupts(chip);
++              dev_err(chip->dev,
++                      FW_BUG "TPM interrupt not working, polling instead\n");
++      }
++      priv->irq_tested = true;
++      return rc;
++}
++
+ struct tis_vendor_timeout_override {
+       u32 did_vid;
+       unsigned long timeout_us[4];
+@@ -546,6 +589,7 @@ static irqreturn_t tis_int_handler(int d
+       if (interrupt == 0)
+               return IRQ_NONE;
++      ((struct priv_data *)chip->vendor.priv)->irq_tested = true;
+       if (interrupt & TPM_INTF_DATA_AVAIL_INT)
+               wake_up_interruptible(&chip->vendor.read_queue);
+       if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
+@@ -575,9 +619,14 @@ static int tpm_tis_init(struct device *d
+       u32 vendor, intfcaps, intmask;
+       int rc, i, irq_s, irq_e, probe;
+       struct tpm_chip *chip;
++      struct priv_data *priv;
++      priv = devm_kzalloc(dev, sizeof(struct priv_data), GFP_KERNEL);
++      if (priv == NULL)
++              return -ENOMEM;
+       if (!(chip = tpm_register_hardware(dev, &tpm_tis)))
+               return -ENODEV;
++      chip->vendor.priv = priv;
+       chip->vendor.iobase = ioremap(start, len);
+       if (!chip->vendor.iobase) {
+@@ -646,19 +695,6 @@ static int tpm_tis_init(struct device *d
+       if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
+               dev_dbg(dev, "\tData Avail Int Support\n");
+-      /* get the timeouts before testing for irqs */
+-      if (tpm_get_timeouts(chip)) {
+-              dev_err(dev, "Could not get TPM timeouts and durations\n");
+-              rc = -ENODEV;
+-              goto out_err;
+-      }
+-
+-      if (tpm_do_selftest(chip)) {
+-              dev_err(dev, "TPM self test failed\n");
+-              rc = -ENODEV;
+-              goto out_err;
+-      }
+-
+       /* INTERRUPT Setup */
+       init_waitqueue_head(&chip->vendor.read_queue);
+       init_waitqueue_head(&chip->vendor.int_queue);
+@@ -760,6 +796,18 @@ static int tpm_tis_init(struct device *d
+               }
+       }
++      if (tpm_get_timeouts(chip)) {
++              dev_err(dev, "Could not get TPM timeouts and durations\n");
++              rc = -ENODEV;
++              goto out_err;
++      }
++
++      if (tpm_do_selftest(chip)) {
++              dev_err(dev, "TPM self test failed\n");
++              rc = -ENODEV;
++              goto out_err;
++      }
++
+       INIT_LIST_HEAD(&chip->vendor.list);
+       mutex_lock(&tis_lock);
+       list_add(&chip->vendor.list, &tis_chips);
diff --git a/queue-3.10/tracing-fix-unmapping-loop-in-tracing_mark_write.patch b/queue-3.10/tracing-fix-unmapping-loop-in-tracing_mark_write.patch
new file mode 100644 (file)
index 0000000..580bad5
--- /dev/null
@@ -0,0 +1,41 @@
+From 7215853e985a4bef1a6c14e00e89dfec84f1e457 Mon Sep 17 00:00:00 2001
+From: Vikram Mulukutla <markivx@codeaurora.org>
+Date: Wed, 17 Dec 2014 18:50:56 -0800
+Subject: tracing: Fix unmapping loop in tracing_mark_write
+
+From: Vikram Mulukutla <markivx@codeaurora.org>
+
+commit 7215853e985a4bef1a6c14e00e89dfec84f1e457 upstream.
+
+Commit 6edb2a8a385f0cdef51dae37ff23e74d76d8a6ce introduced
+an array map_pages that contains the addresses returned by
+kmap_atomic. However, when unmapping those pages, map_pages[0]
+is unmapped before map_pages[1], breaking the nesting requirement
+as specified in the documentation for kmap_atomic/kunmap_atomic.
+
+This was caught by the highmem debug code present in kunmap_atomic.
+Fix the loop to do the unmapping properly.
+
+Link: http://lkml.kernel.org/r/1418871056-6614-1-git-send-email-markivx@codeaurora.org
+
+Reviewed-by: Stephen Boyd <sboyd@codeaurora.org>
+Reported-by: Lime Yang <limey@codeaurora.org>
+Signed-off-by: Vikram Mulukutla <markivx@codeaurora.org>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/trace.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -4588,7 +4588,7 @@ tracing_mark_write(struct file *filp, co
+       *fpos += written;
+  out_unlock:
+-      for (i = 0; i < nr_pages; i++){
++      for (i = nr_pages - 1; i >= 0; i--) {
+               kunmap_atomic(map_page[i]);
+               put_page(pages[i]);
+       }