]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Jul 2014 17:41:38 +0000 (10:41 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Jul 2014 17:41:38 +0000 (10:41 -0700)
added patches:
acpi-ec-add-asynchronous-command-byte-write-support.patch
acpi-ec-avoid-race-condition-related-to-advance_transaction.patch
acpi-ec-fix-race-condition-in-ec_transaction_completed.patch
acpi-ec-remove-duplicated-ec_wait_ibf0-waiter.patch
acpi-resources-only-reject-zero-length-resources-based-at-address-zero.patch
hwmon-adc128d818-drop-write-support-on-inx_input-attributes.patch
hwmon-adm1021-fix-cache-problem-when-writing-temperature-limits.patch
hwmon-adm1029-ensure-the-fan_div-cache-is-updated-in-set_fan_div.patch
hwmon-adm1031-fix-writes-to-limit-registers.patch
hwmon-amc6821-fix-permissions-for-temp2_input.patch
hwmon-emc2103-clamp-limits-instead-of-bailing-out.patch
powerpc-kvm-remove-redundant-save-of-sier-and-mmcr2.patch
powerpc-perf-add-ppmu_arch_207s-define.patch
powerpc-perf-clear-mmcr2-when-enabling-pmu.patch
powerpc-perf-never-program-book3s-pmcs-with-values-0x80000000.patch
revert-acpi-ac-remove-ac-s-proc-directory.patch
thermal-hwmon-make-the-check-for-critical-temp-valid-consistent.patch

18 files changed:
queue-3.15/acpi-ec-add-asynchronous-command-byte-write-support.patch [new file with mode: 0644]
queue-3.15/acpi-ec-avoid-race-condition-related-to-advance_transaction.patch [new file with mode: 0644]
queue-3.15/acpi-ec-fix-race-condition-in-ec_transaction_completed.patch [new file with mode: 0644]
queue-3.15/acpi-ec-remove-duplicated-ec_wait_ibf0-waiter.patch [new file with mode: 0644]
queue-3.15/acpi-resources-only-reject-zero-length-resources-based-at-address-zero.patch [new file with mode: 0644]
queue-3.15/hwmon-adc128d818-drop-write-support-on-inx_input-attributes.patch [new file with mode: 0644]
queue-3.15/hwmon-adm1021-fix-cache-problem-when-writing-temperature-limits.patch [new file with mode: 0644]
queue-3.15/hwmon-adm1029-ensure-the-fan_div-cache-is-updated-in-set_fan_div.patch [new file with mode: 0644]
queue-3.15/hwmon-adm1031-fix-writes-to-limit-registers.patch [new file with mode: 0644]
queue-3.15/hwmon-amc6821-fix-permissions-for-temp2_input.patch [new file with mode: 0644]
queue-3.15/hwmon-emc2103-clamp-limits-instead-of-bailing-out.patch [new file with mode: 0644]
queue-3.15/powerpc-kvm-remove-redundant-save-of-sier-and-mmcr2.patch [new file with mode: 0644]
queue-3.15/powerpc-perf-add-ppmu_arch_207s-define.patch [new file with mode: 0644]
queue-3.15/powerpc-perf-clear-mmcr2-when-enabling-pmu.patch [new file with mode: 0644]
queue-3.15/powerpc-perf-never-program-book3s-pmcs-with-values-0x80000000.patch [new file with mode: 0644]
queue-3.15/revert-acpi-ac-remove-ac-s-proc-directory.patch [new file with mode: 0644]
queue-3.15/series
queue-3.15/thermal-hwmon-make-the-check-for-critical-temp-valid-consistent.patch [new file with mode: 0644]

diff --git a/queue-3.15/acpi-ec-add-asynchronous-command-byte-write-support.patch b/queue-3.15/acpi-ec-add-asynchronous-command-byte-write-support.patch
new file mode 100644 (file)
index 0000000..b6fca81
--- /dev/null
@@ -0,0 +1,217 @@
+From f92fca0060fc4dc9227342d0072d75df98c1e5a5 Mon Sep 17 00:00:00 2001
+From: Lv Zheng <lv.zheng@intel.com>
+Date: Sun, 15 Jun 2014 08:41:35 +0800
+Subject: ACPI / EC: Add asynchronous command byte write support
+
+From: Lv Zheng <lv.zheng@intel.com>
+
+commit f92fca0060fc4dc9227342d0072d75df98c1e5a5 upstream.
+
+Move the first command byte write into advance_transaction() so that all
+EC register accesses that can affect the command processing state machine
+can happen in this asynchronous state machine advancement function.
+
+The advance_transaction() function then can be a complete implementation
+of an asyncrhonous transaction for a single command so that:
+ 1. The first command byte can be written in the interrupt context;
+ 2. The command completion waiter can also be used to wait the first command
+    byte's timeout;
+ 3. In BURST mode, the follow-up command bytes can be written in the
+    interrupt context directly, so that it doesn't need to return to the
+    task context. Returning to the task context reduces the throughput of
+    the BURST mode and in the worst cases where the system workload is very
+    high, this leads to the hardware driven automatic BURST mode exit.
+
+In order not to increase memory consumption, convert 'done' into 'flags'
+to contain multiple indications:
+ 1. ACPI_EC_COMMAND_COMPLETE: converting from original 'done' condition,
+    indicating the completion of the command transaction.
+ 2. ACPI_EC_COMMAND_POLL: indicating the availability of writing the first
+    command byte. A new command can utilize this flag to compete for the
+    right of accessing the underlying hardware. There is a follow-up bug
+    fix that has utilized this new flag.
+
+The 2 flags are important because it also reflects a key concept of IO
+programs' design used in the system softwares. Normally an IO program
+running in the kernel should first be implemented in the asynchronous way.
+And the 2 flags are the most common way to implement its synchronous
+operations on top of the asynchronous operations:
+1. POLL: This flag can be used to block until the asynchronous operations
+         can happen.
+2. COMPLETE: This flag can be used to block until the asynchronous
+             operations have completed.
+By constructing code cleanly in this way, many difficult problems can be
+solved smoothly.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911
+Reported-and-tested-by: Gareth Williams <gareth@garethwilliams.me.uk>
+Reported-and-tested-by: Hans de Goede <jwrdegoede@fedoraproject.org>
+Reported-by: Barton Xu <tank.xuhan@gmail.com>
+Tested-by: Steffen Weber <steffen.weber@gmail.com>
+Tested-by: Arthur Chen <axchen@nvidia.com>
+Signed-off-by: Lv Zheng <lv.zheng@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/ec.c |   83 +++++++++++++++++++++++++++++++-----------------------
+ 1 file changed, 48 insertions(+), 35 deletions(-)
+
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -78,6 +78,9 @@ enum {
+       EC_FLAGS_BLOCKED,               /* Transactions are blocked */
+ };
++#define ACPI_EC_COMMAND_POLL          0x01 /* Available for command byte */
++#define ACPI_EC_COMMAND_COMPLETE      0x02 /* Completed last byte */
++
+ /* ec.c is compiled in acpi namespace so this shows up as acpi.ec_delay param */
+ static unsigned int ec_delay __read_mostly = ACPI_EC_DELAY;
+ module_param(ec_delay, uint, 0644);
+@@ -109,7 +112,7 @@ struct transaction {
+       u8 ri;
+       u8 wlen;
+       u8 rlen;
+-      bool done;
++      u8 flags;
+ };
+ struct acpi_ec *boot_ec, *first_ec;
+@@ -150,63 +153,68 @@ static inline void acpi_ec_write_data(st
+       outb(data, ec->data_addr);
+ }
+-static int ec_transaction_done(struct acpi_ec *ec)
++static int ec_transaction_completed(struct acpi_ec *ec)
+ {
+       unsigned long flags;
+       int ret = 0;
+       spin_lock_irqsave(&ec->lock, flags);
+-      if (!ec->curr || ec->curr->done)
++      if (!ec->curr || (ec->curr->flags & ACPI_EC_COMMAND_COMPLETE))
+               ret = 1;
+       spin_unlock_irqrestore(&ec->lock, flags);
+       return ret;
+ }
+-static void start_transaction(struct acpi_ec *ec)
+-{
+-      ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0;
+-      ec->curr->done = false;
+-      acpi_ec_write_cmd(ec, ec->curr->command);
+-}
+-
+ static void advance_transaction(struct acpi_ec *ec)
+ {
+-      unsigned long flags;
+       struct transaction *t;
+       u8 status;
+-      spin_lock_irqsave(&ec->lock, flags);
+       pr_debug("===== %s =====\n", in_interrupt() ? "IRQ" : "TASK");
+       status = acpi_ec_read_status(ec);
+       t = ec->curr;
+       if (!t)
+-              goto unlock;
+-      if (t->wlen > t->wi) {
+-              if ((status & ACPI_EC_FLAG_IBF) == 0)
+-                      acpi_ec_write_data(ec,
+-                              t->wdata[t->wi++]);
+-              else
+-                      goto err;
+-      } else if (t->rlen > t->ri) {
+-              if ((status & ACPI_EC_FLAG_OBF) == 1) {
+-                      t->rdata[t->ri++] = acpi_ec_read_data(ec);
+-                      if (t->rlen == t->ri)
+-                              t->done = true;
++              goto err;
++      if (t->flags & ACPI_EC_COMMAND_POLL) {
++              if (t->wlen > t->wi) {
++                      if ((status & ACPI_EC_FLAG_IBF) == 0)
++                              acpi_ec_write_data(ec, t->wdata[t->wi++]);
++                      else
++                              goto err;
++              } else if (t->rlen > t->ri) {
++                      if ((status & ACPI_EC_FLAG_OBF) == 1) {
++                              t->rdata[t->ri++] = acpi_ec_read_data(ec);
++                              if (t->rlen == t->ri)
++                                      t->flags |= ACPI_EC_COMMAND_COMPLETE;
++                      } else
++                              goto err;
++              } else if (t->wlen == t->wi &&
++                         (status & ACPI_EC_FLAG_IBF) == 0)
++                      t->flags |= ACPI_EC_COMMAND_COMPLETE;
++              return;
++      } else {
++              if ((status & ACPI_EC_FLAG_IBF) == 0) {
++                      acpi_ec_write_cmd(ec, t->command);
++                      t->flags |= ACPI_EC_COMMAND_POLL;
+               } else
+                       goto err;
+-      } else if (t->wlen == t->wi &&
+-                 (status & ACPI_EC_FLAG_IBF) == 0)
+-              t->done = true;
+-      goto unlock;
++              return;
++      }
+ err:
+       /*
+        * If SCI bit is set, then don't think it's a false IRQ
+        * otherwise will take a not handled IRQ as a false one.
+        */
+-      if (in_interrupt() && !(status & ACPI_EC_FLAG_SCI))
+-              ++t->irq_count;
++      if (!(status & ACPI_EC_FLAG_SCI)) {
++              if (in_interrupt() && t)
++                      ++t->irq_count;
++      }
++}
+-unlock:
+-      spin_unlock_irqrestore(&ec->lock, flags);
++static void start_transaction(struct acpi_ec *ec)
++{
++      ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0;
++      ec->curr->flags = 0;
++      advance_transaction(ec);
+ }
+ static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data);
+@@ -231,15 +239,17 @@ static int ec_poll(struct acpi_ec *ec)
+                       /* don't sleep with disabled interrupts */
+                       if (EC_FLAGS_MSI || irqs_disabled()) {
+                               udelay(ACPI_EC_MSI_UDELAY);
+-                              if (ec_transaction_done(ec))
++                              if (ec_transaction_completed(ec))
+                                       return 0;
+                       } else {
+                               if (wait_event_timeout(ec->wait,
+-                                              ec_transaction_done(ec),
++                                              ec_transaction_completed(ec),
+                                               msecs_to_jiffies(1)))
+                                       return 0;
+                       }
++                      spin_lock_irqsave(&ec->lock, flags);
+                       advance_transaction(ec);
++                      spin_unlock_irqrestore(&ec->lock, flags);
+               } while (time_before(jiffies, delay));
+               pr_debug("controller reset, restart transaction\n");
+               spin_lock_irqsave(&ec->lock, flags);
+@@ -637,10 +647,13 @@ static int ec_check_sci(struct acpi_ec *
+ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device,
+       u32 gpe_number, void *data)
+ {
++      unsigned long flags;
+       struct acpi_ec *ec = data;
++      spin_lock_irqsave(&ec->lock, flags);
+       advance_transaction(ec);
+-      if (ec_transaction_done(ec) &&
++      spin_unlock_irqrestore(&ec->lock, flags);
++      if (ec_transaction_completed(ec) &&
+           (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) {
+               wake_up(&ec->wait);
+               ec_check_sci(ec, acpi_ec_read_status(ec));
diff --git a/queue-3.15/acpi-ec-avoid-race-condition-related-to-advance_transaction.patch b/queue-3.15/acpi-ec-avoid-race-condition-related-to-advance_transaction.patch
new file mode 100644 (file)
index 0000000..6808897
--- /dev/null
@@ -0,0 +1,92 @@
+From 66b42b78bc1e816f92b662e8888c89195e4199e1 Mon Sep 17 00:00:00 2001
+From: Lv Zheng <lv.zheng@intel.com>
+Date: Sun, 15 Jun 2014 08:41:17 +0800
+Subject: ACPI / EC: Avoid race condition related to advance_transaction()
+
+From: Lv Zheng <lv.zheng@intel.com>
+
+commit 66b42b78bc1e816f92b662e8888c89195e4199e1 upstream.
+
+The advance_transaction() will be invoked from the IRQ context GPE handler
+and the task context ec_poll(). The handling of this function is locked so
+that the EC state machine are ensured to be advanced sequentially.
+
+But there is a problem. Before invoking advance_transaction(), EC_SC(R) is
+read. Then for advance_transaction(), there could be race condition around
+the lock from both contexts. The first one reading the register could fail
+this race and when it passes the stale register value to the state machine
+advancement code, the hardware condition is totally different from when
+the register is read. And the hardware accesses determined from the wrong
+hardware status can break the EC state machine. And there could be cases
+that the functionalities of the platform firmware are seriously affected.
+For example:
+ 1. When 2 EC_DATA(W) writes compete the IBF=0, the 2nd EC_DATA(W) write may
+    be invalid due to IBF=1 after the 1st EC_DATA(W) write. Then the
+    hardware will either refuse to respond a next EC_SC(W) write of the next
+    command or discard the current WR_EC command when it receives a EC_SC(W)
+    write of the next command.
+ 2. When 1 EC_SC(W) write and 1 EC_DATA(W) write compete the IBF=0, the
+    EC_DATA(W) write may be invalid due to IBF=1 after the EC_SC(W) write.
+    The next EC_DATA(R) could never be responded by the hardware. This is
+    the root cause of the reported issue.
+
+Fix this issue by moving the EC_SC(R) access into the lock so that we can
+ensure that the state machine is advanced consistently.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911
+Reported-and-tested-by: Gareth Williams <gareth@garethwilliams.me.uk>
+Reported-and-tested-by: Hans de Goede <jwrdegoede@fedoraproject.org>
+Reported-by: Barton Xu <tank.xuhan@gmail.com>
+Tested-by: Steffen Weber <steffen.weber@gmail.com>
+Tested-by: Arthur Chen <axchen@nvidia.com>
+Signed-off-by: Lv Zheng <lv.zheng@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/ec.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -168,12 +168,15 @@ static void start_transaction(struct acp
+       acpi_ec_write_cmd(ec, ec->curr->command);
+ }
+-static void advance_transaction(struct acpi_ec *ec, u8 status)
++static void advance_transaction(struct acpi_ec *ec)
+ {
+       unsigned long flags;
+       struct transaction *t;
++      u8 status;
+       spin_lock_irqsave(&ec->lock, flags);
++      pr_debug("===== %s =====\n", in_interrupt() ? "IRQ" : "TASK");
++      status = acpi_ec_read_status(ec);
+       t = ec->curr;
+       if (!t)
+               goto unlock;
+@@ -236,7 +239,7 @@ static int ec_poll(struct acpi_ec *ec)
+                                               msecs_to_jiffies(1)))
+                                       return 0;
+                       }
+-                      advance_transaction(ec, acpi_ec_read_status(ec));
++                      advance_transaction(ec);
+               } while (time_before(jiffies, delay));
+               pr_debug("controller reset, restart transaction\n");
+               spin_lock_irqsave(&ec->lock, flags);
+@@ -635,11 +638,8 @@ static u32 acpi_ec_gpe_handler(acpi_hand
+       u32 gpe_number, void *data)
+ {
+       struct acpi_ec *ec = data;
+-      u8 status = acpi_ec_read_status(ec);
+-
+-      pr_debug("~~~> interrupt, status:0x%02x\n", status);
+-      advance_transaction(ec, status);
++      advance_transaction(ec);
+       if (ec_transaction_done(ec) &&
+           (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) {
+               wake_up(&ec->wait);
diff --git a/queue-3.15/acpi-ec-fix-race-condition-in-ec_transaction_completed.patch b/queue-3.15/acpi-ec-fix-race-condition-in-ec_transaction_completed.patch
new file mode 100644 (file)
index 0000000..24f5019
--- /dev/null
@@ -0,0 +1,135 @@
+From c0d653412fc8450370167a3268b78fc772ff9c87 Mon Sep 17 00:00:00 2001
+From: Lv Zheng <lv.zheng@intel.com>
+Date: Sun, 15 Jun 2014 08:42:07 +0800
+Subject: ACPI / EC: Fix race condition in ec_transaction_completed()
+
+From: Lv Zheng <lv.zheng@intel.com>
+
+commit c0d653412fc8450370167a3268b78fc772ff9c87 upstream.
+
+There is a race condition in ec_transaction_completed().
+
+When ec_transaction_completed() is called in the GPE handler, it could
+return true because of (ec->curr == NULL). Then the wake_up() invocation
+could complete the next command unexpectedly since there is no lock between
+the 2 invocations. With the previous cleanup, the IBF=0 waiter race need
+not be handled any more. It's now safe to return a flag from
+advance_condition() to indicate the requirement of wakeup, the flag is
+returned from a locked context.
+
+The ec_transaction_completed() is now only invoked by the ec_poll() where
+the ec->curr is ensured to be different from NULL.
+
+After cleaning up, the EVT_SCI=1 check should be moved out of the wakeup
+condition so that an EVT_SCI raised with (ec->curr == NULL) can trigger a
+QR_SC command.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911
+Reported-and-tested-by: Gareth Williams <gareth@garethwilliams.me.uk>
+Reported-and-tested-by: Hans de Goede <jwrdegoede@fedoraproject.org>
+Reported-by: Barton Xu <tank.xuhan@gmail.com>
+Tested-by: Steffen Weber <steffen.weber@gmail.com>
+Tested-by: Arthur Chen <axchen@nvidia.com>
+Signed-off-by: Lv Zheng <lv.zheng@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/ec.c |   30 +++++++++++++++++-------------
+ 1 file changed, 17 insertions(+), 13 deletions(-)
+
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -158,16 +158,17 @@ static int ec_transaction_completed(stru
+       unsigned long flags;
+       int ret = 0;
+       spin_lock_irqsave(&ec->lock, flags);
+-      if (!ec->curr || (ec->curr->flags & ACPI_EC_COMMAND_COMPLETE))
++      if (ec->curr && (ec->curr->flags & ACPI_EC_COMMAND_COMPLETE))
+               ret = 1;
+       spin_unlock_irqrestore(&ec->lock, flags);
+       return ret;
+ }
+-static void advance_transaction(struct acpi_ec *ec)
++static bool advance_transaction(struct acpi_ec *ec)
+ {
+       struct transaction *t;
+       u8 status;
++      bool wakeup = false;
+       pr_debug("===== %s =====\n", in_interrupt() ? "IRQ" : "TASK");
+       status = acpi_ec_read_status(ec);
+@@ -183,21 +184,25 @@ static void advance_transaction(struct a
+               } else if (t->rlen > t->ri) {
+                       if ((status & ACPI_EC_FLAG_OBF) == 1) {
+                               t->rdata[t->ri++] = acpi_ec_read_data(ec);
+-                              if (t->rlen == t->ri)
++                              if (t->rlen == t->ri) {
+                                       t->flags |= ACPI_EC_COMMAND_COMPLETE;
++                                      wakeup = true;
++                              }
+                       } else
+                               goto err;
+               } else if (t->wlen == t->wi &&
+-                         (status & ACPI_EC_FLAG_IBF) == 0)
++                         (status & ACPI_EC_FLAG_IBF) == 0) {
+                       t->flags |= ACPI_EC_COMMAND_COMPLETE;
+-              return;
++                      wakeup = true;
++              }
++              return wakeup;
+       } else {
+               if ((status & ACPI_EC_FLAG_IBF) == 0) {
+                       acpi_ec_write_cmd(ec, t->command);
+                       t->flags |= ACPI_EC_COMMAND_POLL;
+               } else
+                       goto err;
+-              return;
++              return wakeup;
+       }
+ err:
+       /*
+@@ -208,13 +213,14 @@ err:
+               if (in_interrupt() && t)
+                       ++t->irq_count;
+       }
++      return wakeup;
+ }
+ static void start_transaction(struct acpi_ec *ec)
+ {
+       ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0;
+       ec->curr->flags = 0;
+-      advance_transaction(ec);
++      (void)advance_transaction(ec);
+ }
+ static int acpi_ec_sync_query(struct acpi_ec *ec, u8 *data);
+@@ -248,7 +254,7 @@ static int ec_poll(struct acpi_ec *ec)
+                                       return 0;
+                       }
+                       spin_lock_irqsave(&ec->lock, flags);
+-                      advance_transaction(ec);
++                      (void)advance_transaction(ec);
+                       spin_unlock_irqrestore(&ec->lock, flags);
+               } while (time_before(jiffies, delay));
+               pr_debug("controller reset, restart transaction\n");
+@@ -627,12 +633,10 @@ static u32 acpi_ec_gpe_handler(acpi_hand
+       struct acpi_ec *ec = data;
+       spin_lock_irqsave(&ec->lock, flags);
+-      advance_transaction(ec);
+-      spin_unlock_irqrestore(&ec->lock, flags);
+-      if (ec_transaction_completed(ec)) {
++      if (advance_transaction(ec))
+               wake_up(&ec->wait);
+-              ec_check_sci(ec, acpi_ec_read_status(ec));
+-      }
++      spin_unlock_irqrestore(&ec->lock, flags);
++      ec_check_sci(ec, acpi_ec_read_status(ec));
+       return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE;
+ }
diff --git a/queue-3.15/acpi-ec-remove-duplicated-ec_wait_ibf0-waiter.patch b/queue-3.15/acpi-ec-remove-duplicated-ec_wait_ibf0-waiter.patch
new file mode 100644 (file)
index 0000000..66db0da
--- /dev/null
@@ -0,0 +1,93 @@
+From 9b80f0f73ae1583c22325ede341c74195847618c Mon Sep 17 00:00:00 2001
+From: Lv Zheng <lv.zheng@intel.com>
+Date: Sun, 15 Jun 2014 08:41:48 +0800
+Subject: ACPI / EC: Remove duplicated ec_wait_ibf0() waiter
+
+From: Lv Zheng <lv.zheng@intel.com>
+
+commit 9b80f0f73ae1583c22325ede341c74195847618c upstream.
+
+After we've added the first command byte write into advance_transaction(),
+the IBF=0 waiter is duplicated with the command completion waiter
+implemented in the ec_poll() because:
+   If IBF=1 blocked the first command byte write invoked in the task
+   context ec_poll(), it would be kicked off upon IBF=0 interrupt or timed
+   out and retried again in the task context.
+
+Remove this seperate and duplicate IBF=0 waiter.  By doing so we can
+reduce the overall number of times to access the EC_SC(R) status
+register.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=70891
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=63931
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=59911
+Reported-and-tested-by: Gareth Williams <gareth@garethwilliams.me.uk>
+Reported-and-tested-by: Hans de Goede <jwrdegoede@fedoraproject.org>
+Reported-by: Barton Xu <tank.xuhan@gmail.com>
+Tested-by: Steffen Weber <steffen.weber@gmail.com>
+Tested-by: Arthur Chen <axchen@nvidia.com>
+Signed-off-by: Lv Zheng <lv.zheng@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/ec.c |   27 +--------------------------
+ 1 file changed, 1 insertion(+), 26 deletions(-)
+
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -281,23 +281,6 @@ static int acpi_ec_transaction_unlocked(
+       return ret;
+ }
+-static int ec_check_ibf0(struct acpi_ec *ec)
+-{
+-      u8 status = acpi_ec_read_status(ec);
+-      return (status & ACPI_EC_FLAG_IBF) == 0;
+-}
+-
+-static int ec_wait_ibf0(struct acpi_ec *ec)
+-{
+-      unsigned long delay = jiffies + msecs_to_jiffies(ec_delay);
+-      /* interrupt wait manually if GPE mode is not active */
+-      while (time_before(jiffies, delay))
+-              if (wait_event_timeout(ec->wait, ec_check_ibf0(ec),
+-                                      msecs_to_jiffies(1)))
+-                      return 0;
+-      return -ETIME;
+-}
+-
+ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t)
+ {
+       int status;
+@@ -318,12 +301,6 @@ static int acpi_ec_transaction(struct ac
+                       goto unlock;
+               }
+       }
+-      if (ec_wait_ibf0(ec)) {
+-              pr_err("input buffer is not empty, "
+-                              "aborting transaction\n");
+-              status = -ETIME;
+-              goto end;
+-      }
+       pr_debug("transaction start (cmd=0x%02x, addr=0x%02x)\n",
+                       t->command, t->wdata ? t->wdata[0] : 0);
+       /* disable GPE during transaction if storm is detected */
+@@ -347,7 +324,6 @@ static int acpi_ec_transaction(struct ac
+               set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
+       }
+       pr_debug("transaction end\n");
+-end:
+       if (ec->global_lock)
+               acpi_release_global_lock(glk);
+ unlock:
+@@ -653,8 +629,7 @@ static u32 acpi_ec_gpe_handler(acpi_hand
+       spin_lock_irqsave(&ec->lock, flags);
+       advance_transaction(ec);
+       spin_unlock_irqrestore(&ec->lock, flags);
+-      if (ec_transaction_completed(ec) &&
+-          (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) {
++      if (ec_transaction_completed(ec)) {
+               wake_up(&ec->wait);
+               ec_check_sci(ec, acpi_ec_read_status(ec));
+       }
diff --git a/queue-3.15/acpi-resources-only-reject-zero-length-resources-based-at-address-zero.patch b/queue-3.15/acpi-resources-only-reject-zero-length-resources-based-at-address-zero.patch
new file mode 100644 (file)
index 0000000..1536f4a
--- /dev/null
@@ -0,0 +1,83 @@
+From 867f9d463b82462793ea4610e748be0b04b37fc7 Mon Sep 17 00:00:00 2001
+From: Andy Whitcroft <apw@canonical.com>
+Date: Thu, 19 Jun 2014 11:19:16 +0100
+Subject: ACPI / resources: only reject zero length resources based at address zero
+
+From: Andy Whitcroft <apw@canonical.com>
+
+commit 867f9d463b82462793ea4610e748be0b04b37fc7 upstream.
+
+The recently merged change (in v3.14-rc6) to ACPI resource detection
+(below) causes all zero length ACPI resources to be elided from the
+table:
+
+  commit b355cee88e3b1a193f0e9a81db810f6f83ad728b
+  Author: Zhang Rui <rui.zhang@intel.com>
+  Date:   Thu Feb 27 11:37:15 2014 +0800
+
+    ACPI / resources: ignore invalid ACPI device resources
+
+This change has caused a regression in (at least) serial port detection
+for a number of machines (see LP#1313981 [1]).  These seem to represent
+their IO regions (presumably incorrectly) as a zero length region.
+Reverting the above commit restores these serial devices.
+
+Only elide zero length resources which lie at address 0.
+
+Fixes: b355cee88e3b (ACPI / resources: ignore invalid ACPI device resources)
+Signed-off-by: Andy Whitcroft <apw@canonical.com>
+Acked-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/resource.c |   10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/acpi/resource.c
++++ b/drivers/acpi/resource.c
+@@ -77,7 +77,7 @@ bool acpi_dev_resource_memory(struct acp
+       switch (ares->type) {
+       case ACPI_RESOURCE_TYPE_MEMORY24:
+               memory24 = &ares->data.memory24;
+-              if (!memory24->address_length)
++              if (!memory24->minimum && !memory24->address_length)
+                       return false;
+               acpi_dev_get_memresource(res, memory24->minimum,
+                                        memory24->address_length,
+@@ -85,7 +85,7 @@ bool acpi_dev_resource_memory(struct acp
+               break;
+       case ACPI_RESOURCE_TYPE_MEMORY32:
+               memory32 = &ares->data.memory32;
+-              if (!memory32->address_length)
++              if (!memory32->minimum && !memory32->address_length)
+                       return false;
+               acpi_dev_get_memresource(res, memory32->minimum,
+                                        memory32->address_length,
+@@ -93,7 +93,7 @@ bool acpi_dev_resource_memory(struct acp
+               break;
+       case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
+               fixed_memory32 = &ares->data.fixed_memory32;
+-              if (!fixed_memory32->address_length)
++              if (!fixed_memory32->address && !fixed_memory32->address_length)
+                       return false;
+               acpi_dev_get_memresource(res, fixed_memory32->address,
+                                        fixed_memory32->address_length,
+@@ -150,7 +150,7 @@ bool acpi_dev_resource_io(struct acpi_re
+       switch (ares->type) {
+       case ACPI_RESOURCE_TYPE_IO:
+               io = &ares->data.io;
+-              if (!io->address_length)
++              if (!io->minimum && !io->address_length)
+                       return false;
+               acpi_dev_get_ioresource(res, io->minimum,
+                                       io->address_length,
+@@ -158,7 +158,7 @@ bool acpi_dev_resource_io(struct acpi_re
+               break;
+       case ACPI_RESOURCE_TYPE_FIXED_IO:
+               fixed_io = &ares->data.fixed_io;
+-              if (!fixed_io->address_length)
++              if (!fixed_io->address && !fixed_io->address_length)
+                       return false;
+               acpi_dev_get_ioresource(res, fixed_io->address,
+                                       fixed_io->address_length,
diff --git a/queue-3.15/hwmon-adc128d818-drop-write-support-on-inx_input-attributes.patch b/queue-3.15/hwmon-adc128d818-drop-write-support-on-inx_input-attributes.patch
new file mode 100644 (file)
index 0000000..b2bf615
--- /dev/null
@@ -0,0 +1,88 @@
+From 7fe7381cbdadf16792e733789983690b3fa82880 Mon Sep 17 00:00:00 2001
+From: Guenter Roeck <linux@roeck-us.net>
+Date: Mon, 7 Jul 2014 07:10:10 -0700
+Subject: hwmon: (adc128d818) Drop write support on inX_input attributes
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+commit 7fe7381cbdadf16792e733789983690b3fa82880 upstream.
+
+Writes into input registers doesn't make sense, even more so since
+the writes actually ended up writing into the maximum limit registers.
+Drop it.
+
+Reviewed-by: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwmon/adc128d818.c |   28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+--- a/drivers/hwmon/adc128d818.c
++++ b/drivers/hwmon/adc128d818.c
+@@ -239,50 +239,50 @@ static ssize_t adc128_show_alarm(struct
+       return sprintf(buf, "%u\n", !!(alarms & mask));
+ }
+-static SENSOR_DEVICE_ATTR_2(in0_input, S_IWUSR | S_IRUGO,
+-                          adc128_show_in, adc128_set_in, 0, 0);
++static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO,
++                          adc128_show_in, NULL, 0, 0);
+ static SENSOR_DEVICE_ATTR_2(in0_min, S_IWUSR | S_IRUGO,
+                           adc128_show_in, adc128_set_in, 0, 1);
+ static SENSOR_DEVICE_ATTR_2(in0_max, S_IWUSR | S_IRUGO,
+                           adc128_show_in, adc128_set_in, 0, 2);
+-static SENSOR_DEVICE_ATTR_2(in1_input, S_IWUSR | S_IRUGO,
+-                          adc128_show_in, adc128_set_in, 1, 0);
++static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO,
++                          adc128_show_in, NULL, 1, 0);
+ static SENSOR_DEVICE_ATTR_2(in1_min, S_IWUSR | S_IRUGO,
+                           adc128_show_in, adc128_set_in, 1, 1);
+ static SENSOR_DEVICE_ATTR_2(in1_max, S_IWUSR | S_IRUGO,
+                           adc128_show_in, adc128_set_in, 1, 2);
+-static SENSOR_DEVICE_ATTR_2(in2_input, S_IWUSR | S_IRUGO,
+-                          adc128_show_in, adc128_set_in, 2, 0);
++static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO,
++                          adc128_show_in, NULL, 2, 0);
+ static SENSOR_DEVICE_ATTR_2(in2_min, S_IWUSR | S_IRUGO,
+                           adc128_show_in, adc128_set_in, 2, 1);
+ static SENSOR_DEVICE_ATTR_2(in2_max, S_IWUSR | S_IRUGO,
+                           adc128_show_in, adc128_set_in, 2, 2);
+-static SENSOR_DEVICE_ATTR_2(in3_input, S_IWUSR | S_IRUGO,
+-                          adc128_show_in, adc128_set_in, 3, 0);
++static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO,
++                          adc128_show_in, NULL, 3, 0);
+ static SENSOR_DEVICE_ATTR_2(in3_min, S_IWUSR | S_IRUGO,
+                           adc128_show_in, adc128_set_in, 3, 1);
+ static SENSOR_DEVICE_ATTR_2(in3_max, S_IWUSR | S_IRUGO,
+                           adc128_show_in, adc128_set_in, 3, 2);
+-static SENSOR_DEVICE_ATTR_2(in4_input, S_IWUSR | S_IRUGO,
+-                          adc128_show_in, adc128_set_in, 4, 0);
++static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO,
++                          adc128_show_in, NULL, 4, 0);
+ static SENSOR_DEVICE_ATTR_2(in4_min, S_IWUSR | S_IRUGO,
+                           adc128_show_in, adc128_set_in, 4, 1);
+ static SENSOR_DEVICE_ATTR_2(in4_max, S_IWUSR | S_IRUGO,
+                           adc128_show_in, adc128_set_in, 4, 2);
+-static SENSOR_DEVICE_ATTR_2(in5_input, S_IWUSR | S_IRUGO,
+-                          adc128_show_in, adc128_set_in, 5, 0);
++static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO,
++                          adc128_show_in, NULL, 5, 0);
+ static SENSOR_DEVICE_ATTR_2(in5_min, S_IWUSR | S_IRUGO,
+                           adc128_show_in, adc128_set_in, 5, 1);
+ static SENSOR_DEVICE_ATTR_2(in5_max, S_IWUSR | S_IRUGO,
+                           adc128_show_in, adc128_set_in, 5, 2);
+-static SENSOR_DEVICE_ATTR_2(in6_input, S_IWUSR | S_IRUGO,
+-                          adc128_show_in, adc128_set_in, 6, 0);
++static SENSOR_DEVICE_ATTR_2(in6_input, S_IRUGO,
++                          adc128_show_in, NULL, 6, 0);
+ static SENSOR_DEVICE_ATTR_2(in6_min, S_IWUSR | S_IRUGO,
+                           adc128_show_in, adc128_set_in, 6, 1);
+ static SENSOR_DEVICE_ATTR_2(in6_max, S_IWUSR | S_IRUGO,
diff --git a/queue-3.15/hwmon-adm1021-fix-cache-problem-when-writing-temperature-limits.patch b/queue-3.15/hwmon-adm1021-fix-cache-problem-when-writing-temperature-limits.patch
new file mode 100644 (file)
index 0000000..20be3d9
--- /dev/null
@@ -0,0 +1,70 @@
+From c024044d4da2c9c3b32933b4235df1e409293b84 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@ingics.com>
+Date: Thu, 3 Jul 2014 22:45:45 +0800
+Subject: hwmon: (adm1021) Fix cache problem when writing temperature limits
+
+From: Axel Lin <axel.lin@ingics.com>
+
+commit c024044d4da2c9c3b32933b4235df1e409293b84 upstream.
+
+The module test script for the adm1021 driver exposes a cache problem
+when writing temperature limits. temp_min and temp_max are expected
+to be stored in milli-degrees C but are stored in degrees C.
+
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Axel Lin <axel.lin@ingics.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwmon/adm1021.c |   14 ++++++++------
+ 1 file changed, 8 insertions(+), 6 deletions(-)
+
+--- a/drivers/hwmon/adm1021.c
++++ b/drivers/hwmon/adm1021.c
+@@ -185,7 +185,7 @@ static ssize_t set_temp_max(struct devic
+       struct adm1021_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
+       long temp;
+-      int err;
++      int reg_val, err;
+       err = kstrtol(buf, 10, &temp);
+       if (err)
+@@ -193,10 +193,11 @@ static ssize_t set_temp_max(struct devic
+       temp /= 1000;
+       mutex_lock(&data->update_lock);
+-      data->temp_max[index] = clamp_val(temp, -128, 127);
++      reg_val = clamp_val(temp, -128, 127);
++      data->temp_max[index] = reg_val * 1000;
+       if (!read_only)
+               i2c_smbus_write_byte_data(client, ADM1021_REG_TOS_W(index),
+-                                        data->temp_max[index]);
++                                        reg_val);
+       mutex_unlock(&data->update_lock);
+       return count;
+@@ -210,7 +211,7 @@ static ssize_t set_temp_min(struct devic
+       struct adm1021_data *data = dev_get_drvdata(dev);
+       struct i2c_client *client = data->client;
+       long temp;
+-      int err;
++      int reg_val, err;
+       err = kstrtol(buf, 10, &temp);
+       if (err)
+@@ -218,10 +219,11 @@ static ssize_t set_temp_min(struct devic
+       temp /= 1000;
+       mutex_lock(&data->update_lock);
+-      data->temp_min[index] = clamp_val(temp, -128, 127);
++      reg_val = clamp_val(temp, -128, 127);
++      data->temp_min[index] = reg_val * 1000;
+       if (!read_only)
+               i2c_smbus_write_byte_data(client, ADM1021_REG_THYST_W(index),
+-                                        data->temp_min[index]);
++                                        reg_val);
+       mutex_unlock(&data->update_lock);
+       return count;
diff --git a/queue-3.15/hwmon-adm1029-ensure-the-fan_div-cache-is-updated-in-set_fan_div.patch b/queue-3.15/hwmon-adm1029-ensure-the-fan_div-cache-is-updated-in-set_fan_div.patch
new file mode 100644 (file)
index 0000000..d4e19f6
--- /dev/null
@@ -0,0 +1,36 @@
+From 1035a9e3e9c76b64a860a774f5b867d28d34acc2 Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@ingics.com>
+Date: Wed, 2 Jul 2014 08:29:55 +0800
+Subject: hwmon: (adm1029) Ensure the fan_div cache is updated in set_fan_div
+
+From: Axel Lin <axel.lin@ingics.com>
+
+commit 1035a9e3e9c76b64a860a774f5b867d28d34acc2 upstream.
+
+Writing to fanX_div does not clear the cache. As a result, reading
+from fanX_div may return the old value for up to two seconds
+after writing a new value.
+
+This patch ensures the fan_div cache is updated in set_fan_div().
+
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Axel Lin <axel.lin@ingics.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwmon/adm1029.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/hwmon/adm1029.c
++++ b/drivers/hwmon/adm1029.c
+@@ -232,6 +232,9 @@ static ssize_t set_fan_div(struct device
+       /* Update the value */
+       reg = (reg & 0x3F) | (val << 6);
++      /* Update the cache */
++      data->fan_div[attr->index] = reg;
++
+       /* Write value */
+       i2c_smbus_write_byte_data(client,
+                                 ADM1029_REG_FAN_DIV[attr->index], reg);
diff --git a/queue-3.15/hwmon-adm1031-fix-writes-to-limit-registers.patch b/queue-3.15/hwmon-adm1031-fix-writes-to-limit-registers.patch
new file mode 100644 (file)
index 0000000..116c000
--- /dev/null
@@ -0,0 +1,75 @@
+From 145e74a4e5022225adb84f4e5d4fff7938475c35 Mon Sep 17 00:00:00 2001
+From: Guenter Roeck <linux@roeck-us.net>
+Date: Thu, 3 Jul 2014 13:44:23 -0700
+Subject: hwmon: (adm1031) Fix writes to limit registers
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+commit 145e74a4e5022225adb84f4e5d4fff7938475c35 upstream.
+
+Upper limit for write operations to temperature limit registers
+was clamped to a fractional value. However, limit registers do
+not support fractional values. As a result, upper limits of 127.5
+degrees C or higher resulted in a rounded limit of 128 degrees C.
+Since limit registers are signed, this was stored as -128 degrees C.
+Clamp limits to (-55, +127) degrees C to solve the problem.
+
+Value on writes to auto_temp[12]_min and auto_temp[12]_max were not
+clamped at all, but masked. As a result, out-of-range writes resulted
+in a more or less arbitrary limit. Clamp those attributes to (0, 127)
+degrees C for more predictable results.
+
+Cc: Axel Lin <axel.lin@ingics.com>
+Reviewed-by: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwmon/adm1031.c |    8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/hwmon/adm1031.c
++++ b/drivers/hwmon/adm1031.c
+@@ -365,6 +365,7 @@ set_auto_temp_min(struct device *dev, st
+       if (ret)
+               return ret;
++      val = clamp_val(val, 0, 127000);
+       mutex_lock(&data->update_lock);
+       data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]);
+       adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
+@@ -394,6 +395,7 @@ set_auto_temp_max(struct device *dev, st
+       if (ret)
+               return ret;
++      val = clamp_val(val, 0, 127000);
+       mutex_lock(&data->update_lock);
+       data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr],
+                                                 data->pwm[nr]);
+@@ -696,7 +698,7 @@ static ssize_t set_temp_min(struct devic
+       if (ret)
+               return ret;
+-      val = clamp_val(val, -55000, nr == 0 ? 127750 : 127875);
++      val = clamp_val(val, -55000, 127000);
+       mutex_lock(&data->update_lock);
+       data->temp_min[nr] = TEMP_TO_REG(val);
+       adm1031_write_value(client, ADM1031_REG_TEMP_MIN(nr),
+@@ -717,7 +719,7 @@ static ssize_t set_temp_max(struct devic
+       if (ret)
+               return ret;
+-      val = clamp_val(val, -55000, nr == 0 ? 127750 : 127875);
++      val = clamp_val(val, -55000, 127000);
+       mutex_lock(&data->update_lock);
+       data->temp_max[nr] = TEMP_TO_REG(val);
+       adm1031_write_value(client, ADM1031_REG_TEMP_MAX(nr),
+@@ -738,7 +740,7 @@ static ssize_t set_temp_crit(struct devi
+       if (ret)
+               return ret;
+-      val = clamp_val(val, -55000, nr == 0 ? 127750 : 127875);
++      val = clamp_val(val, -55000, 127000);
+       mutex_lock(&data->update_lock);
+       data->temp_crit[nr] = TEMP_TO_REG(val);
+       adm1031_write_value(client, ADM1031_REG_TEMP_CRIT(nr),
diff --git a/queue-3.15/hwmon-amc6821-fix-permissions-for-temp2_input.patch b/queue-3.15/hwmon-amc6821-fix-permissions-for-temp2_input.patch
new file mode 100644 (file)
index 0000000..0d0f83c
--- /dev/null
@@ -0,0 +1,31 @@
+From df86754b746e9a0ff6f863f690b1c01d408e3cdc Mon Sep 17 00:00:00 2001
+From: Axel Lin <axel.lin@ingics.com>
+Date: Wed, 2 Jul 2014 07:44:44 +0800
+Subject: hwmon: (amc6821) Fix permissions for temp2_input
+
+From: Axel Lin <axel.lin@ingics.com>
+
+commit df86754b746e9a0ff6f863f690b1c01d408e3cdc upstream.
+
+temp2_input should not be writable, fix it.
+
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Axel Lin <axel.lin@ingics.com>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwmon/amc6821.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/hwmon/amc6821.c
++++ b/drivers/hwmon/amc6821.c
+@@ -704,7 +704,7 @@ static SENSOR_DEVICE_ATTR(temp1_max_alar
+       get_temp_alarm, NULL, IDX_TEMP1_MAX);
+ static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO,
+       get_temp_alarm, NULL, IDX_TEMP1_CRIT);
+-static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO | S_IWUSR,
++static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
+       get_temp, NULL, IDX_TEMP2_INPUT);
+ static SENSOR_DEVICE_ATTR(temp2_min, S_IRUGO | S_IWUSR, get_temp,
+       set_temp, IDX_TEMP2_MIN);
diff --git a/queue-3.15/hwmon-emc2103-clamp-limits-instead-of-bailing-out.patch b/queue-3.15/hwmon-emc2103-clamp-limits-instead-of-bailing-out.patch
new file mode 100644 (file)
index 0000000..6979786
--- /dev/null
@@ -0,0 +1,65 @@
+From f6c2dd20108c35e30e2c1f3c6142d189451a626b Mon Sep 17 00:00:00 2001
+From: Guenter Roeck <linux@roeck-us.net>
+Date: Sun, 6 Jul 2014 11:39:24 -0700
+Subject: hwmon: (emc2103) Clamp limits instead of bailing out
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+commit f6c2dd20108c35e30e2c1f3c6142d189451a626b upstream.
+
+It is customary to clamp limits instead of bailing out with an error
+if a configured limit is out of the range supported by the driver.
+This simplifies limit configuration, since the user will not typically
+know chip and/or driver specific limits.
+
+Reviewed-by: Jean Delvare <jdelvare@suse.de>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hwmon/emc2103.c |   15 +++++----------
+ 1 file changed, 5 insertions(+), 10 deletions(-)
+
+--- a/drivers/hwmon/emc2103.c
++++ b/drivers/hwmon/emc2103.c
+@@ -250,9 +250,7 @@ static ssize_t set_temp_min(struct devic
+       if (result < 0)
+               return result;
+-      val = DIV_ROUND_CLOSEST(val, 1000);
+-      if ((val < -63) || (val > 127))
+-              return -EINVAL;
++      val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -63, 127);
+       mutex_lock(&data->update_lock);
+       data->temp_min[nr] = val;
+@@ -274,9 +272,7 @@ static ssize_t set_temp_max(struct devic
+       if (result < 0)
+               return result;
+-      val = DIV_ROUND_CLOSEST(val, 1000);
+-      if ((val < -63) || (val > 127))
+-              return -EINVAL;
++      val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -63, 127);
+       mutex_lock(&data->update_lock);
+       data->temp_max[nr] = val;
+@@ -390,15 +386,14 @@ static ssize_t set_fan_target(struct dev
+ {
+       struct emc2103_data *data = emc2103_update_device(dev);
+       struct i2c_client *client = to_i2c_client(dev);
+-      long rpm_target;
++      unsigned long rpm_target;
+-      int result = kstrtol(buf, 10, &rpm_target);
++      int result = kstrtoul(buf, 10, &rpm_target);
+       if (result < 0)
+               return result;
+       /* Datasheet states 16384 as maximum RPM target (table 3.2) */
+-      if ((rpm_target < 0) || (rpm_target > 16384))
+-              return -EINVAL;
++      rpm_target = clamp_val(rpm_target, 0, 16384);
+       mutex_lock(&data->update_lock);
diff --git a/queue-3.15/powerpc-kvm-remove-redundant-save-of-sier-and-mmcr2.patch b/queue-3.15/powerpc-kvm-remove-redundant-save-of-sier-and-mmcr2.patch
new file mode 100644 (file)
index 0000000..5fea752
--- /dev/null
@@ -0,0 +1,44 @@
+From f73128f4f680e8be68cda831f2710214559583cb Mon Sep 17 00:00:00 2001
+From: Joel Stanley <joel@jms.id.au>
+Date: Tue, 8 Jul 2014 16:08:20 +0930
+Subject: powerpc/kvm: Remove redundant save of SIER AND MMCR2
+
+From: Joel Stanley <joel@jms.id.au>
+
+commit f73128f4f680e8be68cda831f2710214559583cb upstream.
+
+These two registers are already saved in the block above. Aside from
+being unnecessary, by the time we get down to the second save location
+r8 no longer contains MMCR2, so we are clobbering the saved value with
+PMC5.
+
+MMCR2 primarily consists of counter freeze bits. So restoring the value
+of PMC5 into MMCR2 will most likely have the effect of freezing
+counters.
+
+Fixes: 72cde5a88d37 ("KVM: PPC: Book3S HV: Save/restore host PMU registers that are new in POWER8")
+Signed-off-by: Joel Stanley <joel@jms.id.au>
+Acked-by: Michael Ellerman <mpe@ellerman.id.au>
+Acked-by: Paul Mackerras <paulus@samba.org>
+Reviewed-by: Alexander Graf <agraf@suse.de>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kvm/book3s_hv_interrupts.S |    5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/arch/powerpc/kvm/book3s_hv_interrupts.S
++++ b/arch/powerpc/kvm/book3s_hv_interrupts.S
+@@ -127,11 +127,6 @@ BEGIN_FTR_SECTION
+       stw     r10, HSTATE_PMC + 24(r13)
+       stw     r11, HSTATE_PMC + 28(r13)
+ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_201)
+-BEGIN_FTR_SECTION
+-      mfspr   r9, SPRN_SIER
+-      std     r8, HSTATE_MMCR + 40(r13)
+-      std     r9, HSTATE_MMCR + 48(r13)
+-END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S)
+ 31:
+       /*
diff --git a/queue-3.15/powerpc-perf-add-ppmu_arch_207s-define.patch b/queue-3.15/powerpc-perf-add-ppmu_arch_207s-define.patch
new file mode 100644 (file)
index 0000000..01660d7
--- /dev/null
@@ -0,0 +1,77 @@
+From 4d9690dd56b0d18f2af8a9d4a279cb205aae3345 Mon Sep 17 00:00:00 2001
+From: Joel Stanley <joel@jms.id.au>
+Date: Tue, 8 Jul 2014 16:08:21 +0930
+Subject: powerpc/perf: Add PPMU_ARCH_207S define
+
+From: Joel Stanley <joel@jms.id.au>
+
+commit 4d9690dd56b0d18f2af8a9d4a279cb205aae3345 upstream.
+
+Instead of separate bits for every POWER8 PMU feature, have a single one
+for v2.07 of the architecture.
+
+This saves us adding a MMCR2 define for a future patch.
+
+Signed-off-by: Joel Stanley <joel@jms.id.au>
+Acked-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/include/asm/perf_event_server.h |    3 +--
+ arch/powerpc/perf/core-book3s.c              |    6 +++---
+ arch/powerpc/perf/power8-pmu.c               |    2 +-
+ 3 files changed, 5 insertions(+), 6 deletions(-)
+
+--- a/arch/powerpc/include/asm/perf_event_server.h
++++ b/arch/powerpc/include/asm/perf_event_server.h
+@@ -61,8 +61,7 @@ struct power_pmu {
+ #define PPMU_SIAR_VALID               0x00000010 /* Processor has SIAR Valid bit */
+ #define PPMU_HAS_SSLOT                0x00000020 /* Has sampled slot in MMCRA */
+ #define PPMU_HAS_SIER         0x00000040 /* Has SIER */
+-#define PPMU_BHRB             0x00000080 /* has BHRB feature enabled */
+-#define PPMU_EBB              0x00000100 /* supports event based branch */
++#define PPMU_ARCH_207S                0x00000080 /* PMC is architecture v2.07S */
+ /*
+  * Values for flags to get_alternatives()
+--- a/arch/powerpc/perf/core-book3s.c
++++ b/arch/powerpc/perf/core-book3s.c
+@@ -485,7 +485,7 @@ static bool is_ebb_event(struct perf_eve
+        * check that the PMU supports EBB, meaning those that don't can still
+        * use bit 63 of the event code for something else if they wish.
+        */
+-      return (ppmu->flags & PPMU_EBB) &&
++      return (ppmu->flags & PPMU_ARCH_207S) &&
+              ((event->attr.config >> PERF_EVENT_CONFIG_EBB_SHIFT) & 1);
+ }
+@@ -777,7 +777,7 @@ void perf_event_print_debug(void)
+       if (ppmu->flags & PPMU_HAS_SIER)
+               sier = mfspr(SPRN_SIER);
+-      if (ppmu->flags & PPMU_EBB) {
++      if (ppmu->flags & PPMU_ARCH_207S) {
+               pr_info("MMCR2: %016lx EBBHR: %016lx\n",
+                       mfspr(SPRN_MMCR2), mfspr(SPRN_EBBHR));
+               pr_info("EBBRR: %016lx BESCR: %016lx\n",
+@@ -1711,7 +1711,7 @@ static int power_pmu_event_init(struct p
+       if (has_branch_stack(event)) {
+               /* PMU has BHRB enabled */
+-              if (!(ppmu->flags & PPMU_BHRB))
++              if (!(ppmu->flags & PPMU_ARCH_207S))
+                       return -EOPNOTSUPP;
+       }
+--- a/arch/powerpc/perf/power8-pmu.c
++++ b/arch/powerpc/perf/power8-pmu.c
+@@ -792,7 +792,7 @@ static struct power_pmu power8_pmu = {
+       .get_constraint         = power8_get_constraint,
+       .get_alternatives       = power8_get_alternatives,
+       .disable_pmc            = power8_disable_pmc,
+-      .flags                  = PPMU_HAS_SSLOT | PPMU_HAS_SIER | PPMU_BHRB | PPMU_EBB,
++      .flags                  = PPMU_HAS_SSLOT | PPMU_HAS_SIER | PPMU_ARCH_207S,
+       .n_generic              = ARRAY_SIZE(power8_generic_events),
+       .generic_events         = power8_generic_events,
+       .cache_events           = &power8_cache_events,
diff --git a/queue-3.15/powerpc-perf-clear-mmcr2-when-enabling-pmu.patch b/queue-3.15/powerpc-perf-clear-mmcr2-when-enabling-pmu.patch
new file mode 100644 (file)
index 0000000..8cff031
--- /dev/null
@@ -0,0 +1,74 @@
+From b50a6c584bb47b370f84bfd746770c0bbe7129b7 Mon Sep 17 00:00:00 2001
+From: Joel Stanley <joel@jms.id.au>
+Date: Tue, 8 Jul 2014 16:08:22 +0930
+Subject: powerpc/perf: Clear MMCR2 when enabling PMU
+
+From: Joel Stanley <joel@jms.id.au>
+
+commit b50a6c584bb47b370f84bfd746770c0bbe7129b7 upstream.
+
+On POWER8 when switching to a KVM guest we set bits in MMCR2 to freeze
+the PMU counters. Aside from on boot they are then never reset,
+resulting in stuck perf counters for any user in the guest or host.
+
+We now set MMCR2 to 0 whenever enabling the PMU, which provides a sane
+state for perf to use the PMU counters under either the guest or the
+host.
+
+This was manifesting as a bug with ppc64_cpu --frequency:
+
+    $ sudo ppc64_cpu --frequency
+    WARNING: couldn't run on cpu 0
+    WARNING: couldn't run on cpu 8
+      ...
+    WARNING: couldn't run on cpu 144
+    WARNING: couldn't run on cpu 152
+    min:    18446744073.710 GHz (cpu -1)
+    max:    0.000 GHz (cpu -1)
+    avg:    0.000 GHz
+
+The command uses a perf counter to measure CPU cycles over a fixed
+amount of time, in order to approximate the frequency of the machine.
+The counters were returning zero once a guest was started, regardless of
+weather it was still running or had been shut down.
+
+By dumping the value of MMCR2, it was observed that once a guest is
+running MMCR2 is set to 1s - which stops counters from running:
+
+    $ sudo sh -c 'echo p > /proc/sysrq-trigger'
+    CPU: 0 PMU registers, ppmu = POWER8 n_counters = 6
+    PMC1:  5b635e38 PMC2: 00000000 PMC3: 00000000 PMC4: 00000000
+    PMC5:  1bf5a646 PMC6: 5793d378 PMC7: deadbeef PMC8: deadbeef
+    MMCR0: 0000000080000000 MMCR1: 000000001e000000 MMCRA: 0000040000000000
+    MMCR2: fffffffffffffc00 EBBHR: 0000000000000000
+    EBBRR: 0000000000000000 BESCR: 0000000000000000
+    SIAR:  00000000000a51cc SDAR:  c00000000fc40000 SIER:  0000000001000000
+
+This is done unconditionally in book3s_hv_interrupts.S upon entering the
+guest, and the original value is only save/restored if the host has
+indicated it was using the PMU. This is okay, however the user of the
+PMU needs to ensure that it is in a defined state when it starts using
+it.
+
+Fixes: e05b9b9e5c10 ("powerpc/perf: Power8 PMU support")
+Signed-off-by: Joel Stanley <joel@jms.id.au>
+Acked-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/perf/core-book3s.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/arch/powerpc/perf/core-book3s.c
++++ b/arch/powerpc/perf/core-book3s.c
+@@ -1315,6 +1315,9 @@ static void power_pmu_enable(struct pmu
+       write_mmcr0(cpuhw, mmcr0);
++      if (ppmu->flags & PPMU_ARCH_207S)
++              mtspr(SPRN_MMCR2, 0);
++
+       /*
+        * Enable instruction sampling if necessary
+        */
diff --git a/queue-3.15/powerpc-perf-never-program-book3s-pmcs-with-values-0x80000000.patch b/queue-3.15/powerpc-perf-never-program-book3s-pmcs-with-values-0x80000000.patch
new file mode 100644 (file)
index 0000000..6408d48
--- /dev/null
@@ -0,0 +1,57 @@
+From f56029410a13cae3652d1f34788045c40a13ffc7 Mon Sep 17 00:00:00 2001
+From: Anton Blanchard <anton@samba.org>
+Date: Thu, 29 May 2014 08:15:38 +1000
+Subject: powerpc/perf: Never program book3s PMCs with values >= 0x80000000
+
+From: Anton Blanchard <anton@samba.org>
+
+commit f56029410a13cae3652d1f34788045c40a13ffc7 upstream.
+
+We are seeing a lot of PMU warnings on POWER8:
+
+    Can't find PMC that caused IRQ
+
+Looking closer, the active PMC is 0 at this point and we took a PMU
+exception on the transition from negative to 0. Some versions of POWER8
+have an issue where they edge detect and not level detect PMC overflows.
+
+A number of places program the PMC with (0x80000000 - period_left),
+where period_left can be negative. We can either fix all of these or
+just ensure that period_left is always >= 1.
+
+This patch takes the second option.
+
+Signed-off-by: Anton Blanchard <anton@samba.org>
+Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/perf/core-book3s.c |   17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+--- a/arch/powerpc/perf/core-book3s.c
++++ b/arch/powerpc/perf/core-book3s.c
+@@ -996,7 +996,22 @@ static void power_pmu_read(struct perf_e
+       } while (local64_cmpxchg(&event->hw.prev_count, prev, val) != prev);
+       local64_add(delta, &event->count);
+-      local64_sub(delta, &event->hw.period_left);
++
++      /*
++       * A number of places program the PMC with (0x80000000 - period_left).
++       * We never want period_left to be less than 1 because we will program
++       * the PMC with a value >= 0x800000000 and an edge detected PMC will
++       * roll around to 0 before taking an exception. We have seen this
++       * on POWER8.
++       *
++       * To fix this, clamp the minimum value of period_left to 1.
++       */
++      do {
++              prev = local64_read(&event->hw.period_left);
++              val = prev - delta;
++              if (val < 1)
++                      val = 1;
++      } while (local64_cmpxchg(&event->hw.period_left, prev, val) != prev);
+ }
+ /*
diff --git a/queue-3.15/revert-acpi-ac-remove-ac-s-proc-directory.patch b/queue-3.15/revert-acpi-ac-remove-ac-s-proc-directory.patch
new file mode 100644 (file)
index 0000000..55f7960
--- /dev/null
@@ -0,0 +1,228 @@
+From e63f6e28dda6de3de2392ddca321e211fd860925 Mon Sep 17 00:00:00 2001
+From: Lan Tianyu <tianyu.lan@intel.com>
+Date: Mon, 7 Jul 2014 01:13:46 +0200
+Subject: Revert "ACPI / AC: Remove AC's proc directory."
+
+From: Lan Tianyu <tianyu.lan@intel.com>
+
+commit e63f6e28dda6de3de2392ddca321e211fd860925 upstream.
+
+Revert commit ab0fd674d6ce (ACPI / AC: Remove AC's proc directory.),
+because some old tools (e.g. kpowersave from kde 3.5.10) are still
+using /proc/acpi/ac_adapter.
+
+Fixes: ab0fd674d6ce (ACPI / AC: Remove AC's proc directory.)
+Reported-and-tested-by: Sorin Manolache <sorinm@gmail.com>
+Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/ac.c |  130 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 128 insertions(+), 2 deletions(-)
+
+--- a/drivers/acpi/ac.c
++++ b/drivers/acpi/ac.c
+@@ -30,6 +30,10 @@
+ #include <linux/types.h>
+ #include <linux/dmi.h>
+ #include <linux/delay.h>
++#ifdef CONFIG_ACPI_PROCFS_POWER
++#include <linux/proc_fs.h>
++#include <linux/seq_file.h>
++#endif
+ #include <linux/platform_device.h>
+ #include <linux/power_supply.h>
+ #include <linux/acpi.h>
+@@ -52,6 +56,7 @@ MODULE_AUTHOR("Paul Diefenbaugh");
+ MODULE_DESCRIPTION("ACPI AC Adapter Driver");
+ MODULE_LICENSE("GPL");
++
+ static int acpi_ac_add(struct acpi_device *device);
+ static int acpi_ac_remove(struct acpi_device *device);
+ static void acpi_ac_notify(struct acpi_device *device, u32 event);
+@@ -67,6 +72,13 @@ static int acpi_ac_resume(struct device
+ #endif
+ static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume);
++#ifdef CONFIG_ACPI_PROCFS_POWER
++extern struct proc_dir_entry *acpi_lock_ac_dir(void);
++extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir);
++static int acpi_ac_open_fs(struct inode *inode, struct file *file);
++#endif
++
++
+ static int ac_sleep_before_get_state_ms;
+ static struct acpi_driver acpi_ac_driver = {
+@@ -91,6 +103,16 @@ struct acpi_ac {
+ #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger)
++#ifdef CONFIG_ACPI_PROCFS_POWER
++static const struct file_operations acpi_ac_fops = {
++      .owner = THIS_MODULE,
++      .open = acpi_ac_open_fs,
++      .read = seq_read,
++      .llseek = seq_lseek,
++      .release = single_release,
++};
++#endif
++
+ /* --------------------------------------------------------------------------
+                                AC Adapter Management
+    -------------------------------------------------------------------------- */
+@@ -143,6 +165,83 @@ static enum power_supply_property ac_pro
+       POWER_SUPPLY_PROP_ONLINE,
+ };
++#ifdef CONFIG_ACPI_PROCFS_POWER
++/* --------------------------------------------------------------------------
++                              FS Interface (/proc)
++   -------------------------------------------------------------------------- */
++
++static struct proc_dir_entry *acpi_ac_dir;
++
++static int acpi_ac_seq_show(struct seq_file *seq, void *offset)
++{
++      struct acpi_ac *ac = seq->private;
++
++
++      if (!ac)
++              return 0;
++
++      if (acpi_ac_get_state(ac)) {
++              seq_puts(seq, "ERROR: Unable to read AC Adapter state\n");
++              return 0;
++      }
++
++      seq_puts(seq, "state:                   ");
++      switch (ac->state) {
++      case ACPI_AC_STATUS_OFFLINE:
++              seq_puts(seq, "off-line\n");
++              break;
++      case ACPI_AC_STATUS_ONLINE:
++              seq_puts(seq, "on-line\n");
++              break;
++      default:
++              seq_puts(seq, "unknown\n");
++              break;
++      }
++
++      return 0;
++}
++
++static int acpi_ac_open_fs(struct inode *inode, struct file *file)
++{
++      return single_open(file, acpi_ac_seq_show, PDE_DATA(inode));
++}
++
++static int acpi_ac_add_fs(struct acpi_ac *ac)
++{
++      struct proc_dir_entry *entry = NULL;
++
++      printk(KERN_WARNING PREFIX "Deprecated procfs I/F for AC is loaded,"
++                      " please retry with CONFIG_ACPI_PROCFS_POWER cleared\n");
++      if (!acpi_device_dir(ac->device)) {
++              acpi_device_dir(ac->device) =
++                      proc_mkdir(acpi_device_bid(ac->device), acpi_ac_dir);
++              if (!acpi_device_dir(ac->device))
++                      return -ENODEV;
++      }
++
++      /* 'state' [R] */
++      entry = proc_create_data(ACPI_AC_FILE_STATE,
++                               S_IRUGO, acpi_device_dir(ac->device),
++                               &acpi_ac_fops, ac);
++      if (!entry)
++              return -ENODEV;
++      return 0;
++}
++
++static int acpi_ac_remove_fs(struct acpi_ac *ac)
++{
++
++      if (acpi_device_dir(ac->device)) {
++              remove_proc_entry(ACPI_AC_FILE_STATE,
++                                acpi_device_dir(ac->device));
++              remove_proc_entry(acpi_device_bid(ac->device), acpi_ac_dir);
++              acpi_device_dir(ac->device) = NULL;
++      }
++
++      return 0;
++}
++#endif
++
+ /* --------------------------------------------------------------------------
+                                    Driver Model
+    -------------------------------------------------------------------------- */
+@@ -243,6 +342,11 @@ static int acpi_ac_add(struct acpi_devic
+               goto end;
+       ac->charger.name = acpi_device_bid(device);
++#ifdef CONFIG_ACPI_PROCFS_POWER
++      result = acpi_ac_add_fs(ac);
++      if (result)
++              goto end;
++#endif
+       ac->charger.type = POWER_SUPPLY_TYPE_MAINS;
+       ac->charger.properties = ac_props;
+       ac->charger.num_properties = ARRAY_SIZE(ac_props);
+@@ -258,8 +362,12 @@ static int acpi_ac_add(struct acpi_devic
+       ac->battery_nb.notifier_call = acpi_ac_battery_notify;
+       register_acpi_notifier(&ac->battery_nb);
+ end:
+-      if (result)
++      if (result) {
++#ifdef CONFIG_ACPI_PROCFS_POWER
++              acpi_ac_remove_fs(ac);
++#endif
+               kfree(ac);
++      }
+       dmi_check_system(ac_dmi_table);
+       return result;
+@@ -303,6 +411,10 @@ static int acpi_ac_remove(struct acpi_de
+               power_supply_unregister(&ac->charger);
+       unregister_acpi_notifier(&ac->battery_nb);
++#ifdef CONFIG_ACPI_PROCFS_POWER
++      acpi_ac_remove_fs(ac);
++#endif
++
+       kfree(ac);
+       return 0;
+@@ -315,9 +427,20 @@ static int __init acpi_ac_init(void)
+       if (acpi_disabled)
+               return -ENODEV;
++#ifdef CONFIG_ACPI_PROCFS_POWER
++      acpi_ac_dir = acpi_lock_ac_dir();
++      if (!acpi_ac_dir)
++              return -ENODEV;
++#endif
++
++
+       result = acpi_bus_register_driver(&acpi_ac_driver);
+-      if (result < 0)
++      if (result < 0) {
++#ifdef CONFIG_ACPI_PROCFS_POWER
++              acpi_unlock_ac_dir(acpi_ac_dir);
++#endif
+               return -ENODEV;
++      }
+       return 0;
+ }
+@@ -325,6 +448,9 @@ static int __init acpi_ac_init(void)
+ static void __exit acpi_ac_exit(void)
+ {
+       acpi_bus_unregister_driver(&acpi_ac_driver);
++#ifdef CONFIG_ACPI_PROCFS_POWER
++      acpi_unlock_ac_dir(acpi_ac_dir);
++#endif
+ }
+ module_init(acpi_ac_init);
+ module_exit(acpi_ac_exit);
index a1405459e7f152714a8980b3482d4f56819ad4ce..28775fc2b5073b23b67895ba0746fe3303ebb94c 100644 (file)
@@ -12,3 +12,20 @@ workqueue-zero-cpumask-of-wq_numa_possible_cpumask-on-init.patch
 ahci-imx-manage-only-sata_ref_clk-in-imx_sata_enable.patch
 i8k-fix-non-smp-operation.patch
 serial-imx-fix-build-breakage.patch
+thermal-hwmon-make-the-check-for-critical-temp-valid-consistent.patch
+hwmon-adc128d818-drop-write-support-on-inx_input-attributes.patch
+hwmon-amc6821-fix-permissions-for-temp2_input.patch
+hwmon-emc2103-clamp-limits-instead-of-bailing-out.patch
+hwmon-adm1031-fix-writes-to-limit-registers.patch
+hwmon-adm1029-ensure-the-fan_div-cache-is-updated-in-set_fan_div.patch
+hwmon-adm1021-fix-cache-problem-when-writing-temperature-limits.patch
+revert-acpi-ac-remove-ac-s-proc-directory.patch
+acpi-resources-only-reject-zero-length-resources-based-at-address-zero.patch
+acpi-ec-avoid-race-condition-related-to-advance_transaction.patch
+acpi-ec-add-asynchronous-command-byte-write-support.patch
+acpi-ec-remove-duplicated-ec_wait_ibf0-waiter.patch
+acpi-ec-fix-race-condition-in-ec_transaction_completed.patch
+powerpc-kvm-remove-redundant-save-of-sier-and-mmcr2.patch
+powerpc-perf-never-program-book3s-pmcs-with-values-0x80000000.patch
+powerpc-perf-add-ppmu_arch_207s-define.patch
+powerpc-perf-clear-mmcr2-when-enabling-pmu.patch
diff --git a/queue-3.15/thermal-hwmon-make-the-check-for-critical-temp-valid-consistent.patch b/queue-3.15/thermal-hwmon-make-the-check-for-critical-temp-valid-consistent.patch
new file mode 100644 (file)
index 0000000..219669d
--- /dev/null
@@ -0,0 +1,97 @@
+From e8db5d6736a712a3e2280c0e31f4b301d85172d8 Mon Sep 17 00:00:00 2001
+From: Aaron Lu <aaron.lu@intel.com>
+Date: Wed, 21 May 2014 16:33:27 +0800
+Subject: thermal: hwmon: Make the check for critical temp valid consistent
+
+From: Aaron Lu <aaron.lu@intel.com>
+
+commit e8db5d6736a712a3e2280c0e31f4b301d85172d8 upstream.
+
+On 05/21/2014 04:22 PM, Aaron Lu wrote:
+> On 05/21/2014 01:57 PM, Kui Zhang wrote:
+>> Hello,
+>>
+>> I get following error when rmmod thermal.
+>>
+>> rmmod  thermal
+>> Killed
+
+While dealing with this problem, I found another problem that also
+results in a kernel crash on thermal module removal:
+
+From: Aaron Lu <aaron.lu@intel.com>
+Date: Wed, 21 May 2014 16:05:38 +0800
+Subject: thermal: hwmon: Make the check for critical temp valid consistent
+
+We used the tz->ops->get_crit_temp && !tz->ops->get_crit_temp(tz, temp)
+to decide if we need to create the temp_crit attribute file but we just
+check if tz->ops->get_crit_temp exists to decide if we need to remove
+that attribute file. Some ACPI thermal zone doesn't have a valid critical
+trip point and that would result in removing a non-existent device file
+on thermal module unload.
+
+Signed-off-by: Aaron Lu <aaron.lu@intel.com>
+Signed-off-by: Zhang Rui <rui.zhang@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/thermal/thermal_hwmon.c |   33 ++++++++++++++++++---------------
+ 1 file changed, 18 insertions(+), 15 deletions(-)
+
+--- a/drivers/thermal/thermal_hwmon.c
++++ b/drivers/thermal/thermal_hwmon.c
+@@ -140,6 +140,12 @@ thermal_hwmon_lookup_temp(const struct t
+       return NULL;
+ }
++static bool thermal_zone_crit_temp_valid(struct thermal_zone_device *tz)
++{
++      unsigned long temp;
++      return tz->ops->get_crit_temp && !tz->ops->get_crit_temp(tz, &temp);
++}
++
+ int thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
+ {
+       struct thermal_hwmon_device *hwmon;
+@@ -189,21 +195,18 @@ int thermal_add_hwmon_sysfs(struct therm
+       if (result)
+               goto free_temp_mem;
+-      if (tz->ops->get_crit_temp) {
+-              unsigned long temperature;
+-              if (!tz->ops->get_crit_temp(tz, &temperature)) {
+-                      snprintf(temp->temp_crit.name,
+-                               sizeof(temp->temp_crit.name),
++      if (thermal_zone_crit_temp_valid(tz)) {
++              snprintf(temp->temp_crit.name,
++                              sizeof(temp->temp_crit.name),
+                               "temp%d_crit", hwmon->count);
+-                      temp->temp_crit.attr.attr.name = temp->temp_crit.name;
+-                      temp->temp_crit.attr.attr.mode = 0444;
+-                      temp->temp_crit.attr.show = temp_crit_show;
+-                      sysfs_attr_init(&temp->temp_crit.attr.attr);
+-                      result = device_create_file(hwmon->device,
+-                                                  &temp->temp_crit.attr);
+-                      if (result)
+-                              goto unregister_input;
+-              }
++              temp->temp_crit.attr.attr.name = temp->temp_crit.name;
++              temp->temp_crit.attr.attr.mode = 0444;
++              temp->temp_crit.attr.show = temp_crit_show;
++              sysfs_attr_init(&temp->temp_crit.attr.attr);
++              result = device_create_file(hwmon->device,
++                                          &temp->temp_crit.attr);
++              if (result)
++                      goto unregister_input;
+       }
+       mutex_lock(&thermal_hwmon_list_lock);
+@@ -250,7 +253,7 @@ void thermal_remove_hwmon_sysfs(struct t
+       }
+       device_remove_file(hwmon->device, &temp->temp_input.attr);
+-      if (tz->ops->get_crit_temp)
++      if (thermal_zone_crit_temp_valid(tz))
+               device_remove_file(hwmon->device, &temp->temp_crit.attr);
+       mutex_lock(&thermal_hwmon_list_lock);