]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 Jul 2015 22:23:39 +0000 (15:23 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 Jul 2015 22:23:39 +0000 (15:23 -0700)
added patches:
acpi-init-switch-over-platform-to-the-acpi-mode-later.patch
acpi-pm-add-missing-pm_generic_complete-invocation.patch
acpi-pnp-avoid-conflicting-resource-reservations.patch
iio-accel-kxcjk-1013-add-the-kxcj9000-acpi-id.patch

queue-4.1/acpi-init-switch-over-platform-to-the-acpi-mode-later.patch [new file with mode: 0644]
queue-4.1/acpi-pm-add-missing-pm_generic_complete-invocation.patch [new file with mode: 0644]
queue-4.1/acpi-pnp-avoid-conflicting-resource-reservations.patch [new file with mode: 0644]
queue-4.1/iio-accel-kxcjk-1013-add-the-kxcj9000-acpi-id.patch [new file with mode: 0644]
queue-4.1/series

diff --git a/queue-4.1/acpi-init-switch-over-platform-to-the-acpi-mode-later.patch b/queue-4.1/acpi-init-switch-over-platform-to-the-acpi-mode-later.patch
new file mode 100644 (file)
index 0000000..e767242
--- /dev/null
@@ -0,0 +1,151 @@
+From b064a8fa77dfead647564c46ac8fc5b13bd1ab73 Mon Sep 17 00:00:00 2001
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+Date: Wed, 10 Jun 2015 01:33:36 +0200
+Subject: ACPI / init: Switch over platform to the ACPI mode later
+
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+
+commit b064a8fa77dfead647564c46ac8fc5b13bd1ab73 upstream.
+
+Commit 73f7d1ca3263 "ACPI / init: Run acpi_early_init() before
+timekeeping_init()" moved the ACPI subsystem initialization,
+including the ACPI mode enabling, to an earlier point in the
+initialization sequence, to allow the timekeeping subsystem
+use ACPI early.  Unfortunately, that resulted in boot regressions
+on some systems and the early ACPI initialization was moved toward
+its original position in the kernel initialization code by commit
+c4e1acbb35e4 "ACPI / init: Invoke early ACPI initialization later".
+
+However, that turns out to be insufficient, as boot is still broken
+on the Tyan S8812 mainboard.
+
+To fix that issue, split the ACPI early initialization code into
+two pieces so the majority of it still located in acpi_early_init()
+and the part switching over the platform into the ACPI mode goes into
+a new function, acpi_subsystem_init(), executed at the original early
+ACPI initialization spot.
+
+That fixes the Tyan S8812 boot problem, but still allows ACPI
+tables to be loaded earlier which is useful to the EFI code in
+efi_enter_virtual_mode().
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=97141
+Fixes: 73f7d1ca3263 "ACPI / init: Run acpi_early_init() before timekeeping_init()"
+Reported-and-tested-by: Marius Tolzmann <tolzmann@molgen.mpg.de>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Acked-by: Toshi Kani <toshi.kani@hp.com>
+Reviewed-by: Hanjun Guo <hanjun.guo@linaro.org>
+Reviewed-by: Lee, Chun-Yi <jlee@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/bus.c   |   56 +++++++++++++++++++++++++++++++++++++--------------
+ include/linux/acpi.h |    2 +
+ init/main.c          |    1 
+ 3 files changed, 44 insertions(+), 15 deletions(-)
+
+--- a/drivers/acpi/bus.c
++++ b/drivers/acpi/bus.c
+@@ -470,6 +470,16 @@ static int __init acpi_bus_init_irq(void
+       return 0;
+ }
++/**
++ * acpi_early_init - Initialize ACPICA and populate the ACPI namespace.
++ *
++ * The ACPI tables are accessible after this, but the handling of events has not
++ * been initialized and the global lock is not available yet, so AML should not
++ * be executed at this point.
++ *
++ * Doing this before switching the EFI runtime services to virtual mode allows
++ * the EfiBootServices memory to be freed slightly earlier on boot.
++ */
+ void __init acpi_early_init(void)
+ {
+       acpi_status status;
+@@ -533,26 +543,42 @@ void __init acpi_early_init(void)
+               acpi_gbl_FADT.sci_interrupt = acpi_sci_override_gsi;
+       }
+ #endif
++      return;
++
++ error0:
++      disable_acpi();
++}
++
++/**
++ * acpi_subsystem_init - Finalize the early initialization of ACPI.
++ *
++ * Switch over the platform to the ACPI mode (if possible), initialize the
++ * handling of ACPI events, install the interrupt and global lock handlers.
++ *
++ * Doing this too early is generally unsafe, but at the same time it needs to be
++ * done before all things that really depend on ACPI.  The right spot appears to
++ * be before finalizing the EFI initialization.
++ */
++void __init acpi_subsystem_init(void)
++{
++      acpi_status status;
++
++      if (acpi_disabled)
++              return;
+       status = acpi_enable_subsystem(~ACPI_NO_ACPI_ENABLE);
+       if (ACPI_FAILURE(status)) {
+               printk(KERN_ERR PREFIX "Unable to enable ACPI\n");
+-              goto error0;
++              disable_acpi();
++      } else {
++              /*
++               * If the system is using ACPI then we can be reasonably
++               * confident that any regulators are managed by the firmware
++               * so tell the regulator core it has everything it needs to
++               * know.
++               */
++              regulator_has_full_constraints();
+       }
+-
+-      /*
+-       * If the system is using ACPI then we can be reasonably
+-       * confident that any regulators are managed by the firmware
+-       * so tell the regulator core it has everything it needs to
+-       * know.
+-       */
+-      regulator_has_full_constraints();
+-
+-      return;
+-
+-      error0:
+-      disable_acpi();
+-      return;
+ }
+ static int __init acpi_bus_init(void)
+--- a/include/linux/acpi.h
++++ b/include/linux/acpi.h
+@@ -440,6 +440,7 @@ extern acpi_status acpi_pci_osc_control_
+ #define ACPI_OST_SC_INSERT_NOT_SUPPORTED      0x82
+ extern void acpi_early_init(void);
++extern void acpi_subsystem_init(void);
+ extern int acpi_nvs_register(__u64 start, __u64 size);
+@@ -494,6 +495,7 @@ static inline const char *acpi_dev_name(
+ }
+ static inline void acpi_early_init(void) { }
++static inline void acpi_subsystem_init(void) { }
+ static inline int early_acpi_boot_init(void)
+ {
+--- a/init/main.c
++++ b/init/main.c
+@@ -664,6 +664,7 @@ asmlinkage __visible void __init start_k
+       check_bugs();
++      acpi_subsystem_init();
+       sfi_init_late();
+       if (efi_enabled(EFI_RUNTIME_SERVICES)) {
diff --git a/queue-4.1/acpi-pm-add-missing-pm_generic_complete-invocation.patch b/queue-4.1/acpi-pm-add-missing-pm_generic_complete-invocation.patch
new file mode 100644 (file)
index 0000000..1362efd
--- /dev/null
@@ -0,0 +1,32 @@
+From 3d56402d3fa8d10749eeb36293dd1992bd5ad0c3 Mon Sep 17 00:00:00 2001
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+Date: Wed, 10 Jun 2015 01:32:38 +0200
+Subject: ACPI / PM: Add missing pm_generic_complete() invocation
+
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+
+commit 3d56402d3fa8d10749eeb36293dd1992bd5ad0c3 upstream.
+
+Add missing invocation of pm_generic_complete() to
+acpi_subsys_complete() to allow ->complete callbacks provided
+by the drivers of devices using the ACPI PM domain to be executed
+during system resume.
+
+Fixes: f25c0ae2b4c4 (ACPI / PM: Avoid resuming devices in ACPI PM domain during system suspend)
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/device_pm.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/acpi/device_pm.c
++++ b/drivers/acpi/device_pm.c
+@@ -953,6 +953,7 @@ EXPORT_SYMBOL_GPL(acpi_subsys_prepare);
+  */
+ void acpi_subsys_complete(struct device *dev)
+ {
++      pm_generic_complete(dev);
+       /*
+        * If the device had been runtime-suspended before the system went into
+        * the sleep state it is going out of and it has never been resumed till
diff --git a/queue-4.1/acpi-pnp-avoid-conflicting-resource-reservations.patch b/queue-4.1/acpi-pnp-avoid-conflicting-resource-reservations.patch
new file mode 100644 (file)
index 0000000..334be98
--- /dev/null
@@ -0,0 +1,324 @@
+From 0f1b414d190724617eb1cdd615592fa8cd9d0b50 Mon Sep 17 00:00:00 2001
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+Date: Thu, 18 Jun 2015 18:32:02 +0200
+Subject: ACPI / PNP: Avoid conflicting resource reservations
+
+From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
+
+commit 0f1b414d190724617eb1cdd615592fa8cd9d0b50 upstream.
+
+Commit b9a5e5e18fbf "ACPI / init: Fix the ordering of
+acpi_reserve_resources()" overlooked the fact that the memory
+and/or I/O regions reserved by acpi_reserve_resources() may
+conflict with those reserved by the PNP "system" driver.
+
+If that conflict actually takes place, it causes the reservations
+made by the "system" driver to fail while before commit b9a5e5e18fbf
+all reservations made by it and by acpi_reserve_resources() would be
+successful.  In turn, that allows the resources that haven't been
+reserved by the "system" driver to be used by others (e.g. PCI) which
+sometimes leads to functional problems (up to and including boot
+failures).
+
+To fix that issue, introduce a common resource reservation routine,
+acpi_reserve_region(), to be used by both acpi_reserve_resources()
+and the "system" driver, that will track all resources reserved by
+it and avoid making conflicting requests.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=99831
+Link: http://marc.info/?t=143389402600001&r=1&w=2
+Fixes: b9a5e5e18fbf "ACPI / init: Fix the ordering of acpi_reserve_resources()"
+Reported-by: Roland Dreier <roland@purestorage.com>
+Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/acpi/osl.c      |    6 -
+ drivers/acpi/resource.c |  160 ++++++++++++++++++++++++++++++++++++++++++++++++
+ drivers/pnp/system.c    |   35 +++++++---
+ include/linux/acpi.h    |   10 +++
+ 4 files changed, 197 insertions(+), 14 deletions(-)
+
+--- a/drivers/acpi/osl.c
++++ b/drivers/acpi/osl.c
+@@ -175,11 +175,7 @@ static void __init acpi_request_region (
+       if (!addr || !length)
+               return;
+-      /* Resources are never freed */
+-      if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO)
+-              request_region(addr, length, desc);
+-      else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
+-              request_mem_region(addr, length, desc);
++      acpi_reserve_region(addr, length, gas->space_id, 0, desc);
+ }
+ static void __init acpi_reserve_resources(void)
+--- a/drivers/acpi/resource.c
++++ b/drivers/acpi/resource.c
+@@ -26,6 +26,7 @@
+ #include <linux/device.h>
+ #include <linux/export.h>
+ #include <linux/ioport.h>
++#include <linux/list.h>
+ #include <linux/slab.h>
+ #ifdef CONFIG_X86
+@@ -621,3 +622,162 @@ int acpi_dev_filter_resource_type(struct
+       return (type & types) ? 0 : 1;
+ }
+ EXPORT_SYMBOL_GPL(acpi_dev_filter_resource_type);
++
++struct reserved_region {
++      struct list_head node;
++      u64 start;
++      u64 end;
++};
++
++static LIST_HEAD(reserved_io_regions);
++static LIST_HEAD(reserved_mem_regions);
++
++static int request_range(u64 start, u64 end, u8 space_id, unsigned long flags,
++                       char *desc)
++{
++      unsigned int length = end - start + 1;
++      struct resource *res;
++
++      res = space_id == ACPI_ADR_SPACE_SYSTEM_IO ?
++              request_region(start, length, desc) :
++              request_mem_region(start, length, desc);
++      if (!res)
++              return -EIO;
++
++      res->flags &= ~flags;
++      return 0;
++}
++
++static int add_region_before(u64 start, u64 end, u8 space_id,
++                           unsigned long flags, char *desc,
++                           struct list_head *head)
++{
++      struct reserved_region *reg;
++      int error;
++
++      reg = kmalloc(sizeof(*reg), GFP_KERNEL);
++      if (!reg)
++              return -ENOMEM;
++
++      error = request_range(start, end, space_id, flags, desc);
++      if (error)
++              return error;
++
++      reg->start = start;
++      reg->end = end;
++      list_add_tail(&reg->node, head);
++      return 0;
++}
++
++/**
++ * acpi_reserve_region - Reserve an I/O or memory region as a system resource.
++ * @start: Starting address of the region.
++ * @length: Length of the region.
++ * @space_id: Identifier of address space to reserve the region from.
++ * @flags: Resource flags to clear for the region after requesting it.
++ * @desc: Region description (for messages).
++ *
++ * Reserve an I/O or memory region as a system resource to prevent others from
++ * using it.  If the new region overlaps with one of the regions (in the given
++ * address space) already reserved by this routine, only the non-overlapping
++ * parts of it will be reserved.
++ *
++ * Returned is either 0 (success) or a negative error code indicating a resource
++ * reservation problem.  It is the code of the first encountered error, but the
++ * routine doesn't abort until it has attempted to request all of the parts of
++ * the new region that don't overlap with other regions reserved previously.
++ *
++ * The resources requested by this routine are never released.
++ */
++int acpi_reserve_region(u64 start, unsigned int length, u8 space_id,
++                      unsigned long flags, char *desc)
++{
++      struct list_head *regions;
++      struct reserved_region *reg;
++      u64 end = start + length - 1;
++      int ret = 0, error = 0;
++
++      if (space_id == ACPI_ADR_SPACE_SYSTEM_IO)
++              regions = &reserved_io_regions;
++      else if (space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
++              regions = &reserved_mem_regions;
++      else
++              return -EINVAL;
++
++      if (list_empty(regions))
++              return add_region_before(start, end, space_id, flags, desc, regions);
++
++      list_for_each_entry(reg, regions, node)
++              if (reg->start == end + 1) {
++                      /* The new region can be prepended to this one. */
++                      ret = request_range(start, end, space_id, flags, desc);
++                      if (!ret)
++                              reg->start = start;
++
++                      return ret;
++              } else if (reg->start > end) {
++                      /* No overlap.  Add the new region here and get out. */
++                      return add_region_before(start, end, space_id, flags,
++                                               desc, &reg->node);
++              } else if (reg->end == start - 1) {
++                      goto combine;
++              } else if (reg->end >= start) {
++                      goto overlap;
++              }
++
++      /* The new region goes after the last existing one. */
++      return add_region_before(start, end, space_id, flags, desc, regions);
++
++ overlap:
++      /*
++       * The new region overlaps an existing one.
++       *
++       * The head part of the new region immediately preceding the existing
++       * overlapping one can be combined with it right away.
++       */
++      if (reg->start > start) {
++              error = request_range(start, reg->start - 1, space_id, flags, desc);
++              if (error)
++                      ret = error;
++              else
++                      reg->start = start;
++      }
++
++ combine:
++      /*
++       * The new region is adjacent to an existing one.  If it extends beyond
++       * that region all the way to the next one, it is possible to combine
++       * all three of them.
++       */
++      while (reg->end < end) {
++              struct reserved_region *next = NULL;
++              u64 a = reg->end + 1, b = end;
++
++              if (!list_is_last(&reg->node, regions)) {
++                      next = list_next_entry(reg, node);
++                      if (next->start <= end)
++                              b = next->start - 1;
++              }
++              error = request_range(a, b, space_id, flags, desc);
++              if (!error) {
++                      if (next && next->start == b + 1) {
++                              reg->end = next->end;
++                              list_del(&next->node);
++                              kfree(next);
++                      } else {
++                              reg->end = end;
++                              break;
++                      }
++              } else if (next) {
++                      if (!ret)
++                              ret = error;
++
++                      reg = next;
++              } else {
++                      break;
++              }
++      }
++
++      return ret ? ret : error;
++}
++EXPORT_SYMBOL_GPL(acpi_reserve_region);
+--- a/drivers/pnp/system.c
++++ b/drivers/pnp/system.c
+@@ -7,6 +7,7 @@
+  *    Bjorn Helgaas <bjorn.helgaas@hp.com>
+  */
++#include <linux/acpi.h>
+ #include <linux/pnp.h>
+ #include <linux/device.h>
+ #include <linux/init.h>
+@@ -22,25 +23,41 @@ static const struct pnp_device_id pnp_de
+       {"", 0}
+ };
++#ifdef CONFIG_ACPI
++static bool __reserve_range(u64 start, unsigned int length, bool io, char *desc)
++{
++      u8 space_id = io ? ACPI_ADR_SPACE_SYSTEM_IO : ACPI_ADR_SPACE_SYSTEM_MEMORY;
++      return !acpi_reserve_region(start, length, space_id, IORESOURCE_BUSY, desc);
++}
++#else
++static bool __reserve_range(u64 start, unsigned int length, bool io, char *desc)
++{
++      struct resource *res;
++
++      res = io ? request_region(start, length, desc) :
++              request_mem_region(start, length, desc);
++      if (res) {
++              res->flags &= ~IORESOURCE_BUSY;
++              return true;
++      }
++      return false;
++}
++#endif
++
+ static void reserve_range(struct pnp_dev *dev, struct resource *r, int port)
+ {
+       char *regionid;
+       const char *pnpid = dev_name(&dev->dev);
+       resource_size_t start = r->start, end = r->end;
+-      struct resource *res;
++      bool reserved;
+       regionid = kmalloc(16, GFP_KERNEL);
+       if (!regionid)
+               return;
+       snprintf(regionid, 16, "pnp %s", pnpid);
+-      if (port)
+-              res = request_region(start, end - start + 1, regionid);
+-      else
+-              res = request_mem_region(start, end - start + 1, regionid);
+-      if (res)
+-              res->flags &= ~IORESOURCE_BUSY;
+-      else
++      reserved = __reserve_range(start, end - start + 1, !!port, regionid);
++      if (!reserved)
+               kfree(regionid);
+       /*
+@@ -49,7 +66,7 @@ static void reserve_range(struct pnp_dev
+        * have double reservations.
+        */
+       dev_info(&dev->dev, "%pR %s reserved\n", r,
+-               res ? "has been" : "could not be");
++               reserved ? "has been" : "could not be");
+ }
+ static void reserve_resources_of_dev(struct pnp_dev *dev)
+--- a/include/linux/acpi.h
++++ b/include/linux/acpi.h
+@@ -332,6 +332,9 @@ int acpi_check_region(resource_size_t st
+ int acpi_resources_are_enforced(void);
++int acpi_reserve_region(u64 start, unsigned int length, u8 space_id,
++                      unsigned long flags, char *desc);
++
+ #ifdef CONFIG_HIBERNATION
+ void __init acpi_no_s4_hw_signature(void);
+ #endif
+@@ -527,6 +530,13 @@ static inline int acpi_check_region(reso
+       return 0;
+ }
++static inline int acpi_reserve_region(u64 start, unsigned int length,
++                                    u8 space_id, unsigned long flags,
++                                    char *desc)
++{
++      return -ENXIO;
++}
++
+ struct acpi_table_header;
+ static inline int acpi_table_parse(char *id,
+                               int (*handler)(struct acpi_table_header *))
diff --git a/queue-4.1/iio-accel-kxcjk-1013-add-the-kxcj9000-acpi-id.patch b/queue-4.1/iio-accel-kxcjk-1013-add-the-kxcj9000-acpi-id.patch
new file mode 100644 (file)
index 0000000..0a389ce
--- /dev/null
@@ -0,0 +1,32 @@
+From 61e2c70da9cfc79e8485eafa0f98b5919b04bbe1 Mon Sep 17 00:00:00 2001
+From: Antonio Ospite <ao2@ao2.it>
+Date: Mon, 4 May 2015 11:13:03 +0200
+Subject: iio: accel: kxcjk-1013: add the "KXCJ9000" ACPI id
+
+From: Antonio Ospite <ao2@ao2.it>
+
+commit 61e2c70da9cfc79e8485eafa0f98b5919b04bbe1 upstream.
+
+This id has been seen in the DSDT of the Teclast X98 Air 3G tablet based
+on Intel Bay Trail.
+
+Signed-off-by: Antonio Ospite <ao2@ao2.it>
+Cc: Bastien Nocera <hadess@hadess.net>
+Reviewed-by: Daniel Baluta <daniel.baluta@intel.com>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/iio/accel/kxcjk-1013.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/iio/accel/kxcjk-1013.c
++++ b/drivers/iio/accel/kxcjk-1013.c
+@@ -1418,6 +1418,7 @@ static const struct dev_pm_ops kxcjk1013
+ static const struct acpi_device_id kx_acpi_match[] = {
+       {"KXCJ1013", KXCJK1013},
+       {"KXCJ1008", KXCJ91008},
++      {"KXCJ9000", KXCJ91008},
+       {"KXTJ1009", KXTJ21009},
+       {"SMO8500",  KXCJ91008},
+       { },
index 9b85f0c16e991c9cb174aa1ddde325cfea1feb6b..190b863c5e2707a4d6a5fcca125681e6a13cfe0e 100644 (file)
@@ -20,3 +20,7 @@ alsa-hda-restore-the-mic-fixup-for-some-dell-machines.patch
 alsa-hda-add-headset-support-to-acer-aspire-v5.patch
 alsa-hda-fix-the-dock-headphone-output-on-fujitsu-lifebook-e780.patch
 alsa-hda-add-a-fixup-for-dell-e7450.patch
+acpi-init-switch-over-platform-to-the-acpi-mode-later.patch
+acpi-pm-add-missing-pm_generic_complete-invocation.patch
+acpi-pnp-avoid-conflicting-resource-reservations.patch
+iio-accel-kxcjk-1013-add-the-kxcj9000-acpi-id.patch