]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
Merge tag 'acpi-4.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 13 Dec 2016 19:06:21 +0000 (11:06 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 13 Dec 2016 19:06:21 +0000 (11:06 -0800)
Pull ACPI updates from Rafael Wysocki:
 "The ACPICA code in the kernel gets updated as usual (included is
  upstream revision 20160930 and a few commits from the next one, with
  the rest waiting for an issue discovered in linux-next to be
  addressed) which brings in a couple of fixes and cleanups

  On top of that initial support for APEI on ARM64 is added, two new
  pieces of documentation are introduced, the properties-parsing code is
  updated to follow changes in the (external) documentation it is based
  on and there are a few updates of SoC drivers, some new blacklist
  entries, plus some assorted fixes and cleanups

  Specifics:

   - ACPICA update including upstream revision 20160930 and several
     commits beyond it (Bob Moore, Lv Zheng)

   - Initial support for ACPI APEI on ARM64 (Tomasz Nowicki)

   - New document describing the handling of _OSI and _REV in Linux (Len
     Brown)

   - New document describing the usage rules for _DSD properties (Rafael
     Wysocki)

   - Update of the ACPI properties-parsing code to reflect recent
     changes in the (external) documentation it is based on (Rafael
     Wysocki)

   - Updates of the ACPI LPSS and ACPI APD SoC drivers for additional
     hardware support (Andy Shevchenko, Nehal Shah)

   - New blacklist entries for _REV and video handling (Alex Hung, Hans
     de Goede, Michael Pobega)

   - ACPI battery driver fix to fall back to _BIF if _BIX fails (Dave
     Lambley)

   - NMI notifications handling fix for APEI (Prarit Bhargava)

   - Error code path fix for the ACPI CPPC library (Dan Carpenter)

   - Assorted cleanups (Andy Shevchenko, Longpeng Mike)"

* tag 'acpi-4.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (31 commits)
  ACPICA: Utilities: Add new decode function for parser values
  ACPI / osl: Refactor acpi_os_get_root_pointer() to drop 'else':s
  ACPI / osl: Propagate actual error code for kstrtoul()
  ACPI / property: Document usage rules for _DSD properties
  ACPI: Document _OSI and _REV for Linux BIOS writers
  ACPI / APEI / ARM64: APEI initial support for ARM64
  ACPI / APEI: Fix NMI notification handling
  ACPICA: Tables: Add an error message complaining driver bugs
  ACPICA: Tables: Add acpi_tb_unload_table()
  ACPICA: Tables: Cleanup acpi_tb_install_and_load_table()
  ACPICA: Events: Fix acpi_ev_initialize_region() return value
  ACPICA: Back port of "ACPICA: Dispatcher: Tune interpreter lock around AcpiEvInitializeRegion()"
  ACPICA: Namespace: Add acpi_ns_handle_to_name()
  ACPI / CPPC: set an error code on probe error path
  ACPI / video: Add force_native quirk for HP Pavilion dv6
  ACPI / video: Add force_native quirk for Dell XPS 17 L702X
  ACPI / property: Hierarchical properties support update
  ACPI / LPSS: enable hard LLP for DMA
  ACPI / battery: If _BIX fails, retry with _BIF
  ACPI / video: Move ACPI_VIDEO_NOTIFY_* defines to acpi/video.h
  ..

41 files changed:
Documentation/acpi/DSD-properties-rules.txt [new file with mode: 0644]
Documentation/acpi/enumeration.txt
Documentation/acpi/osi.txt [new file with mode: 0644]
arch/arm64/Kconfig
arch/arm64/include/asm/acpi.h
arch/x86/kernel/acpi/apei.c
drivers/acpi/acpi_apd.c
drivers/acpi/acpi_lpss.c
drivers/acpi/acpi_video.c
drivers/acpi/acpica/acevents.h
drivers/acpi/acpica/acglobal.h
drivers/acpi/acpica/aclocal.h
drivers/acpi/acpica/acnamesp.h
drivers/acpi/acpica/actables.h
drivers/acpi/acpica/acutils.h
drivers/acpi/acpica/amlcode.h
drivers/acpi/acpica/dsinit.c
drivers/acpi/acpica/dsopcode.c
drivers/acpi/acpica/dswload2.c
drivers/acpi/acpica/evrgnini.c
drivers/acpi/acpica/exconfig.c
drivers/acpi/acpica/nsnames.c
drivers/acpi/acpica/nsxfname.c
drivers/acpi/acpica/tbdata.c
drivers/acpi/acpica/tbxface.c
drivers/acpi/acpica/tbxfload.c
drivers/acpi/acpica/utdecode.c
drivers/acpi/apei/ghes.c
drivers/acpi/apei/hest.c
drivers/acpi/battery.c
drivers/acpi/blacklist.c
drivers/acpi/cppc_acpi.c
drivers/acpi/device_sysfs.c
drivers/acpi/osl.c
drivers/acpi/property.c
drivers/acpi/video_detect.c
include/acpi/acconfig.h
include/acpi/acpixf.h
include/acpi/video.h
include/linux/acpi.h
tools/power/acpi/os_specific/service_layers/osunixxf.c

diff --git a/Documentation/acpi/DSD-properties-rules.txt b/Documentation/acpi/DSD-properties-rules.txt
new file mode 100644 (file)
index 0000000..3e4862b
--- /dev/null
@@ -0,0 +1,97 @@
+_DSD Device Properties Usage Rules
+----------------------------------
+
+Properties, Property Sets and Property Subsets
+----------------------------------------------
+
+The _DSD (Device Specific Data) configuration object, introduced in ACPI 5.1,
+allows any type of device configuration data to be provided via the ACPI
+namespace.  In principle, the format of the data may be arbitrary, but it has to
+be identified by a UUID which must be recognized by the driver processing the
+_DSD output.  However, there are generic UUIDs defined for _DSD recognized by
+the ACPI subsystem in the Linux kernel which automatically processes the data
+packages associated with them and makes those data available to device drivers
+as "device properties".
+
+A device property is a data item consisting of a string key and a value (of a
+specific type) associated with it.
+
+In the ACPI _DSD context it is an element of the sub-package following the
+generic Device Properties UUID in the _DSD return package as specified in the
+Device Properties UUID definition document [1].
+
+It also may be regarded as the definition of a key and the associated data type
+that can be returned by _DSD in the Device Properties UUID sub-package for a
+given device.
+
+A property set is a collection of properties applicable to a hardware entity
+like a device.  In the ACPI _DSD context it is the set of all properties that
+can be returned in the Device Properties UUID sub-package for the device in
+question.
+
+Property subsets are nested collections of properties.  Each of them is
+associated with an additional key (name) allowing the subset to be referred
+to as a whole (and to be treated as a separate entity).  The canonical
+representation of property subsets is via the mechanism specified in the
+Hierarchical Properties Extension UUID definition document [2].
+
+Property sets may be hierarchical.  That is, a property set may contain
+multiple property subsets that each may contain property subsets of its
+own and so on.
+
+General Validity Rule for Property Sets
+---------------------------------------
+
+Valid property sets must follow the guidance given by the Device Properties UUID
+definition document [1].
+
+_DSD properties are intended to be used in addition to, and not instead of, the
+existing mechanisms defined by the ACPI specification.  Therefore, as a rule,
+they should only be used if the ACPI specification does not make direct
+provisions for handling the underlying use case.  It generally is invalid to
+return property sets which do not follow that rule from _DSD in data packages
+associated with the Device Properties UUID.
+
+Additional Considerations
+-------------------------
+
+There are cases in which, even if the general rule given above is followed in
+principle, the property set may still not be regarded as a valid one.
+
+For example, that applies to device properties which may cause kernel code
+(either a device driver or a library/subsystem) to access hardware in a way
+possibly leading to a conflict with AML methods in the ACPI namespace.  In
+particular, that may happen if the kernel code uses device properties to
+manipulate hardware normally controlled by ACPI methods related to power
+management, like _PSx and _DSW (for device objects) or _ON and _OFF (for power
+resource objects), or by ACPI device disabling/enabling methods, like _DIS and
+_SRS.
+
+In all cases in which kernel code may do something that will confuse AML as a
+result of using device properties, the device properties in question are not
+suitable for the ACPI environment and consequently they cannot belong to a valid
+property set.
+
+Property Sets and Device Tree Bindings
+--------------------------------------
+
+It often is useful to make _DSD return property sets that follow Device Tree
+bindings.
+
+In those cases, however, the above validity considerations must be taken into
+account in the first place and returning invalid property sets from _DSD must be
+avoided.  For this reason, it may not be possible to make _DSD return a property
+set following the given DT binding literally and completely.  Still, for the
+sake of code re-use, it may make sense to provide as much of the configuration
+data as possible in the form of device properties and complement that with an
+ACPI-specific mechanism suitable for the use case at hand.
+
+In any case, property sets following DT bindings literally should not be
+expected to automatically work in the ACPI environment regardless of their
+contents.
+
+References
+----------
+
+[1] http://www.uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
+[2] http://www.uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.1.pdf
index a91ec5af52df28cf3ff3c2ae03b163272caae0e6..209a5eba6b8711e34000b102f68814e76bfcded8 100644 (file)
@@ -415,3 +415,12 @@ the "compatible" property in the _DSD or a _CID as long as one of their
 ancestors provides a _DSD with a valid "compatible" property.  Such device
 objects are then simply regarded as additional "blocks" providing hierarchical
 configuration information to the driver of the composite ancestor device.
+
+However, PRP0001 can only be returned from either _HID or _CID of a device
+object if all of the properties returned by the _DSD associated with it (either
+the _DSD of the device object itself or the _DSD of its ancestor in the
+"composite device" case described above) can be used in the ACPI environment.
+Otherwise, the _DSD itself is regarded as invalid and therefore the "compatible"
+property returned by it is meaningless.
+
+Refer to DSD-properties-rules.txt for more information.
diff --git a/Documentation/acpi/osi.txt b/Documentation/acpi/osi.txt
new file mode 100644 (file)
index 0000000..50cde0c
--- /dev/null
@@ -0,0 +1,187 @@
+ACPI _OSI and _REV methods
+--------------------------
+
+An ACPI BIOS can use the "Operating System Interfaces" method (_OSI)
+to find out what the operating system supports. Eg. If BIOS
+AML code includes _OSI("XYZ"), the kernel's AML interpreter
+can evaluate that method, look to see if it supports 'XYZ'
+and answer YES or NO to the BIOS.
+
+The ACPI _REV method returns the "Revision of the ACPI specification
+that OSPM supports"
+
+This document explains how and why the BIOS and Linux should use these methods.
+It also explains how and why they are widely misused.
+
+How to use _OSI
+---------------
+
+Linux runs on two groups of machines -- those that are tested by the OEM
+to be compatible with Linux, and those that were never tested with Linux,
+but where Linux was installed to replace the original OS (Windows or OSX).
+
+The larger group is the systems tested to run only Windows.  Not only that,
+but many were tested to run with just one specific version of Windows.
+So even though the BIOS may use _OSI to query what version of Windows is running,
+only a single path through the BIOS has actually been tested.
+Experience shows that taking untested paths through the BIOS
+exposes Linux to an entire category of BIOS bugs.
+For this reason, Linux _OSI defaults must continue to claim compatibility
+with all versions of Windows.
+
+But Linux isn't actually compatible with Windows, and the Linux community
+has also been hurt with regressions when Linux adds the latest version of
+Windows to its list of _OSI strings.  So it is possible that additional strings
+will be more thoroughly vetted before shipping upstream in the future.
+But it is likely that they will all eventually be added.
+
+What should an OEM do if they want to support Linux and Windows
+using the same BIOS image?  Often they need to do something different
+for Linux to deal with how Linux is different from Windows.
+Here the BIOS should ask exactly what it wants to know:
+
+_OSI("Linux-OEM-my_interface_name")
+where 'OEM' is needed if this is an OEM-specific hook,
+and 'my_interface_name' describes the hook, which could be a
+quirk, a bug, or a bug-fix.
+
+In addition, the OEM should send a patch to upstream Linux
+via the linux-acpi@vger.kernel.org mailing list.  When that patch
+is checked into Linux, the OS will answer "YES" when the BIOS
+on the OEM's system uses _OSI to ask if the interface is supported
+by the OS.  Linux distributors can back-port that patch for Linux
+pre-installs, and it will be included by all distributions that
+re-base to upstream.  If the distribution can not update the kernel binary,
+they can also add an acpi_osi=Linux-OEM-my_interface_name
+cmdline parameter to the boot loader, as needed.
+
+If the string refers to a feature where the upstream kernel
+eventually grows support, a patch should be sent to remove
+the string when that support is added to the kernel.
+
+That was easy.  Read on, to find out how to do it wrong.
+
+Before _OSI, there was _OS
+--------------------------
+
+ACPI 1.0 specified "_OS" as an
+"object that evaluates to a string that identifies the operating system."
+
+The ACPI BIOS flow would include an evaluation of _OS, and the AML
+interpreter in the kernel would return to it a string identifying the OS:
+
+Windows 98, SE: "Microsoft Windows"
+Windows ME: "Microsoft WindowsME:Millenium Edition"
+Windows NT: "Microsoft Windows NT"
+
+The idea was on a platform tasked with running multiple OS's,
+the BIOS could use _OS to enable devices that an OS
+might support, or enable quirks or bug workarounds
+necessary to make the platform compatible with that pre-existing OS.
+
+But _OS had fundamental problems.  First, the BIOS needed to know the name
+of every possible version of the OS that would run on it, and needed to know
+all the quirks of those OS's.  Certainly it would make more sense
+for the BIOS to ask *specific* things of the OS, such
+"do you support a specific interface", and thus in ACPI 3.0,
+_OSI was born to replace _OS.
+
+_OS was abandoned, though even today, many BIOS look for
+_OS "Microsoft Windows NT", though it seems somewhat far-fetched
+that anybody would install those old operating systems
+over what came with the machine.
+
+Linux answers "Microsoft Windows NT" to please that BIOS idiom.
+That is the *only* viable strategy, as that is what modern Windows does,
+and so doing otherwise could steer the BIOS down an untested path.
+
+_OSI is born, and immediately misused
+--------------------------------------
+
+With _OSI, the *BIOS* provides the string describing an interface,
+and asks the OS: "YES/NO, are you compatible with this interface?"
+
+eg. _OSI("3.0 Thermal Model") would return TRUE if the OS knows how
+to deal with the thermal extensions made to the ACPI 3.0 specification.
+An old OS that doesn't know about those extensions would answer FALSE,
+and a new OS may be able to return TRUE.
+
+For an OS-specific interface, the ACPI spec said that the BIOS and the OS
+were to agree on a string of the form such as "Windows-interface_name".
+
+But two bad things happened.  First, the Windows ecosystem used _OSI
+not as designed, but as a direct replacement for _OS -- identifying
+the OS version, rather than an OS supported interface.  Indeed, right
+from the start, the ACPI 3.0 spec itself codified this misuse
+in example code using _OSI("Windows 2001").
+
+This misuse was adopted and continues today.
+
+Linux had no choice but to also return TRUE to _OSI("Windows 2001")
+and its successors.  To do otherwise would virtually guarantee breaking
+a BIOS that has been tested only with that _OSI returning TRUE.
+
+This strategy is problematic, as Linux is never completely compatible with
+the latest version of Windows, and sometimes it takes more than a year
+to iron out incompatibilities.
+
+Not to be out-done, the Linux community made things worse by returning TRUE
+to _OSI("Linux").  Doing so is even worse than the Windows misuse
+of _OSI, as "Linux" does not even contain any version information.
+_OSI("Linux") led to some BIOS' malfunctioning due to BIOS writer's
+using it in untested BIOS flows.  But some OEM's used _OSI("Linux")
+in tested flows to support real Linux features.  In 2009, Linux
+removed _OSI("Linux"), and added a cmdline parameter to restore it
+for legacy systems still needed it.  Further a BIOS_BUG warning prints
+for all BIOS's that invoke it.
+
+No BIOS should use _OSI("Linux").
+
+The result is a strategy for Linux to maximize compatibility with
+ACPI BIOS that are tested on Windows machines.  There is a real risk
+of over-stating that compatibility; but the alternative has often been
+catastrophic failure resulting from the BIOS taking paths that
+were never validated under *any* OS.
+
+Do not use _REV
+---------------
+
+Since _OSI("Linux") went away, some BIOS writers used _REV
+to support Linux and Windows differences in the same BIOS.
+
+_REV was defined in ACPI 1.0 to return the version of ACPI
+supported by the OS and the OS AML interpreter.
+
+Modern Windows returns _REV = 2.  Linux used ACPI_CA_SUPPORT_LEVEL,
+which would increment, based on the version of the spec supported.
+
+Unfortunately, _REV was also misused.  eg. some BIOS would check
+for _REV = 3, and do something for Linux, but when Linux returned
+_REV = 4, that support broke.
+
+In response to this problem, Linux returns _REV = 2 always,
+from mid-2015 onward.  The ACPI specification will also be updated
+to reflect that _REV is deprecated, and always returns 2.
+
+Apple Mac and _OSI("Darwin")
+----------------------------
+
+On Apple's Mac platforms, the ACPI BIOS invokes _OSI("Darwin")
+to determine if the machine is running Apple OSX.
+
+Like Linux's _OSI("*Windows*") strategy, Linux defaults to
+answering YES to _OSI("Darwin") to enable full access
+to the hardware and validated BIOS paths seen by OSX.
+Just like on Windows-tested platforms, this strategy has risks.
+
+Starting in Linux-3.18, the kernel answered YES to _OSI("Darwin")
+for the purpose of enabling Mac Thunderbolt support.  Further,
+if the kernel noticed _OSI("Darwin") being invoked, it additionally
+disabled all _OSI("*Windows*") to keep poorly written Mac BIOS
+from going down untested combinations of paths.
+
+The Linux-3.18 change in default caused power regressions on Mac
+laptops, and the 3.18 implementation did not allow changing
+the default via cmdline "acpi_osi=!Darwin".  Linux-4.7 fixed
+the ability to use acpi_osi=!Darwin as a workaround, and
+we hope to see Mac Thunderbolt power management support in Linux-4.11.
index 969ef880d234e3b340713948eb2e9aec8ba0b3a3..657be7f5014e31e50da1ee86979d32332bcefe54 100644 (file)
@@ -52,6 +52,7 @@ config ARM64
        select GENERIC_TIME_VSYSCALL
        select HANDLE_DOMAIN_IRQ
        select HARDIRQS_SW_RESEND
+       select HAVE_ACPI_APEI if (ACPI && EFI)
        select HAVE_ALIGNED_STRUCT_PAGE if SLUB
        select HAVE_ARCH_AUDITSYSCALL
        select HAVE_ARCH_BITREVERSE
index e517088d635fcc0c0f698418cf850b0541c8eb32..d0de0e032bc2c689f849ee679754f7b18d9451c3 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <asm/cputype.h>
 #include <asm/smp_plat.h>
+#include <asm/tlbflush.h>
 
 /* Macros for consistency checks of the GICC subtable of MADT */
 #define ACPI_MADT_GICC_LENGTH  \
@@ -114,8 +115,28 @@ static inline const char *acpi_get_enable_method(int cpu)
 }
 
 #ifdef CONFIG_ACPI_APEI
+/*
+ * acpi_disable_cmcff is used in drivers/acpi/apei/hest.c for disabling
+ * IA-32 Architecture Corrected Machine Check (CMC) Firmware-First mode
+ * with a kernel command line parameter "acpi=nocmcoff". But we don't
+ * have this IA-32 specific feature on ARM64, this definition is only
+ * for compatibility.
+ */
+#define acpi_disable_cmcff 1
 pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr);
-#endif
+
+/*
+ * Despite its name, this function must still broadcast the TLB
+ * invalidation in order to ensure other CPUs don't end up with junk
+ * entries as a result of speculation. Unusually, its also called in
+ * IRQ context (ghes_iounmap_irq) so if we ever need to use IPIs for
+ * TLB broadcasting, then we're in trouble here.
+ */
+static inline void arch_apei_flush_tlb_one(unsigned long addr)
+{
+       flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
+}
+#endif /* CONFIG_ACPI_APEI */
 
 #ifdef CONFIG_ACPI_NUMA
 int arm64_acpi_numa_init(void);
index c280df6b2aa28304b1c18832267a1a3966a71ae9..ea3046e0b0cf53c44417eed99ae8f76b6fec08d9 100644 (file)
@@ -24,9 +24,6 @@ int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data)
        struct acpi_hest_ia_corrected *cmc;
        struct acpi_hest_ia_error_bank *mc_bank;
 
-       if (hest_hdr->type != ACPI_HEST_TYPE_IA32_CORRECTED_CHECK)
-               return 0;
-
        cmc = (struct acpi_hest_ia_corrected *)hest_hdr;
        if (!cmc->enabled)
                return 0;
index 7dd70927991e7e9e0de14a3af89db442eca8d175..26696b693e634e665d4972bb1226c64fa1ab3acd 100644 (file)
@@ -77,6 +77,11 @@ static const struct apd_device_desc cz_i2c_desc = {
        .fixed_clk_rate = 133000000,
 };
 
+static const struct apd_device_desc wt_i2c_desc = {
+       .setup = acpi_apd_setup,
+       .fixed_clk_rate = 150000000,
+};
+
 static struct property_entry uart_properties[] = {
        PROPERTY_ENTRY_U32("reg-io-width", 4),
        PROPERTY_ENTRY_U32("reg-shift", 2),
@@ -156,7 +161,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = {
        /* Generic apd devices */
 #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE
        { "AMD0010", APD_ADDR(cz_i2c_desc) },
-       { "AMDI0010", APD_ADDR(cz_i2c_desc) },
+       { "AMDI0010", APD_ADDR(wt_i2c_desc) },
        { "AMD0020", APD_ADDR(cz_uart_desc) },
        { "AMDI0020", APD_ADDR(cz_uart_desc) },
        { "AMD0030", },
index 373657f7e35a9cac3a2a951cd030c00ef6fbd06d..8ea836c046f8be056623f109fedb6494d23dc586 100644 (file)
@@ -718,13 +718,14 @@ static int acpi_lpss_resume_early(struct device *dev)
 #define LPSS_GPIODEF0_DMA1_D3          BIT(2)
 #define LPSS_GPIODEF0_DMA2_D3          BIT(3)
 #define LPSS_GPIODEF0_DMA_D3_MASK      GENMASK(3, 2)
+#define LPSS_GPIODEF0_DMA_LLP          BIT(13)
 
 static DEFINE_MUTEX(lpss_iosf_mutex);
 
 static void lpss_iosf_enter_d3_state(void)
 {
        u32 value1 = 0;
-       u32 mask1 = LPSS_GPIODEF0_DMA_D3_MASK;
+       u32 mask1 = LPSS_GPIODEF0_DMA_D3_MASK | LPSS_GPIODEF0_DMA_LLP;
        u32 value2 = LPSS_PMCSR_D3hot;
        u32 mask2 = LPSS_PMCSR_Dx_MASK;
        /*
@@ -768,8 +769,9 @@ static void lpss_iosf_enter_d3_state(void)
 
 static void lpss_iosf_exit_d3_state(void)
 {
-       u32 value1 = LPSS_GPIODEF0_DMA1_D3 | LPSS_GPIODEF0_DMA2_D3;
-       u32 mask1 = LPSS_GPIODEF0_DMA_D3_MASK;
+       u32 value1 = LPSS_GPIODEF0_DMA1_D3 | LPSS_GPIODEF0_DMA2_D3 |
+                    LPSS_GPIODEF0_DMA_LLP;
+       u32 mask1 = LPSS_GPIODEF0_DMA_D3_MASK | LPSS_GPIODEF0_DMA_LLP;
        u32 value2 = LPSS_PMCSR_D0;
        u32 mask2 = LPSS_PMCSR_Dx_MASK;
 
index c5557d070954c6a7bbf8799b0f2cc4ee593a14d4..201292e67ee8a130cf67bb4d10d81eac707716c4 100644 (file)
 
 #define ACPI_VIDEO_BUS_NAME            "Video Bus"
 #define ACPI_VIDEO_DEVICE_NAME         "Video Device"
-#define ACPI_VIDEO_NOTIFY_SWITCH       0x80
-#define ACPI_VIDEO_NOTIFY_PROBE                0x81
-#define ACPI_VIDEO_NOTIFY_CYCLE                0x82
-#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT  0x83
-#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT  0x84
-
-#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS     0x85
-#define        ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS        0x86
-#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS       0x87
-#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS      0x88
-#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF          0x89
 
 #define MAX_NAME_LEN   20
 
index 92fa47c6498cdf50d07319ef282fc4b2bf5f4ada..8a0049d5cdf31b0b7655cb43b6400261d4ae727b 100644 (file)
@@ -243,9 +243,7 @@ acpi_ev_default_region_setup(acpi_handle handle,
                             u32 function,
                             void *handler_context, void **region_context);
 
-acpi_status
-acpi_ev_initialize_region(union acpi_operand_object *region_obj,
-                         u8 acpi_ns_locked);
+acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj);
 
 /*
  * evsci - SCI (System Control Interrupt) handling/dispatch
index 750fa824d42c4b6d38fc07a566cca8ea2300982c..edbb42e251a65334140203003fa0f0e6e4610808 100644 (file)
@@ -240,10 +240,6 @@ ACPI_INIT_GLOBAL(u32, acpi_gbl_nesting_level, 0);
 
 ACPI_GLOBAL(struct acpi_thread_state *, acpi_gbl_current_walk_list);
 
-/* Maximum number of While() loop iterations before forced abort */
-
-ACPI_GLOBAL(u16, acpi_gbl_max_loop_iterations);
-
 /* Control method single step flag */
 
 ACPI_GLOBAL(u8, acpi_gbl_cm_single_step);
@@ -318,6 +314,7 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_cstyle_disassembly, TRUE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_force_aml_disassembly, FALSE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_dm_opt_verbose, TRUE);
 ACPI_INIT_GLOBAL(u8, acpi_gbl_dm_emit_external_opcodes, FALSE);
+ACPI_INIT_GLOBAL(u8, acpi_gbl_do_disassembler_optimizations, TRUE);
 
 ACPI_GLOBAL(u8, acpi_gbl_dm_opt_disasm);
 ACPI_GLOBAL(u8, acpi_gbl_dm_opt_listing);
index dff1207a60788ad2a5b93b64ba1cc9d90945f52a..7926600549925873ca8a40d45588ddd17ee74b0d 100644 (file)
@@ -765,7 +765,7 @@ union acpi_parse_value {
        union acpi_parse_value          value;          /* Value or args associated with the opcode */\
        u8                              arg_list_length; /* Number of elements in the arg list */\
        ACPI_DISASM_ONLY_MEMBERS (\
-       u                             disasm_flags;   /* Used during AML disassembly */\
+       u16                             disasm_flags;   /* Used during AML disassembly */\
        u8                              disasm_opcode;  /* Subtype used for disassembly */\
        char                            *operator_symbol;/* Used for C-style operator name strings */\
        char                            aml_op_name[16])        /* Op name (debug only) */
@@ -868,14 +868,15 @@ struct acpi_parse_state {
 
 /* Parse object disasm_flags */
 
-#define ACPI_PARSEOP_IGNORE                 0x01
-#define ACPI_PARSEOP_PARAMETER_LIST         0x02
-#define ACPI_PARSEOP_EMPTY_TERMLIST         0x04
-#define ACPI_PARSEOP_PREDEFINED_CHECKED     0x08
-#define ACPI_PARSEOP_CLOSING_PAREN          0x10
-#define ACPI_PARSEOP_COMPOUND_ASSIGNMENT    0x20
-#define ACPI_PARSEOP_ASSIGNMENT             0x40
-#define ACPI_PARSEOP_ELSEIF                 0x80
+#define ACPI_PARSEOP_IGNORE                 0x0001
+#define ACPI_PARSEOP_PARAMETER_LIST         0x0002
+#define ACPI_PARSEOP_EMPTY_TERMLIST         0x0004
+#define ACPI_PARSEOP_PREDEFINED_CHECKED     0x0008
+#define ACPI_PARSEOP_CLOSING_PAREN          0x0010
+#define ACPI_PARSEOP_COMPOUND_ASSIGNMENT    0x0020
+#define ACPI_PARSEOP_ASSIGNMENT             0x0040
+#define ACPI_PARSEOP_ELSEIF                 0x0080
+#define ACPI_PARSEOP_LEGACY_ASL_ONLY        0x0100
 
 /*****************************************************************************
  *
index bb7fca1c8ba307add15b588cd38a64084275d037..7affdcdfcc816e827651f83c82979fd398c74a14 100644 (file)
@@ -291,6 +291,9 @@ char *acpi_ns_get_normalized_pathname(struct acpi_namespace_node *node,
 
 char *acpi_ns_name_of_current_scope(struct acpi_walk_state *walk_state);
 
+acpi_status
+acpi_ns_handle_to_name(acpi_handle target_handle, struct acpi_buffer *buffer);
+
 acpi_status
 acpi_ns_handle_to_pathname(acpi_handle target_handle,
                           struct acpi_buffer *buffer, u8 no_trailing);
index e85953b6fa0edcac98631c006b09ea16fb2353fe..7dd527f8ca1d24b10915c865dc3f24e4a8e34b92 100644 (file)
@@ -127,10 +127,11 @@ acpi_status
 acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node);
 
 acpi_status
-acpi_tb_install_and_load_table(struct acpi_table_header *table,
-                              acpi_physical_address address,
+acpi_tb_install_and_load_table(acpi_physical_address address,
                               u8 flags, u8 override, u32 *table_index);
 
+acpi_status acpi_tb_unload_table(u32 table_index);
+
 void acpi_tb_terminate(void);
 
 acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index);
index 0a1b53c9ee0e04709d1a582b2e0713a870a10646..845afb180a7e94ca67a92d0d554bea820ff678a3 100644 (file)
@@ -232,6 +232,8 @@ const char *acpi_ut_get_region_name(u8 space_id);
 
 const char *acpi_ut_get_event_name(u32 event_id);
 
+const char *acpi_ut_get_argument_type_name(u32 arg_type);
+
 char acpi_ut_hex_to_ascii_char(u64 integer, u32 position);
 
 acpi_status acpi_ut_ascii_to_hex_byte(char *two_ascii_chars, u8 *return_byte);
index ceb4f7365f7f6c50ad76c8d405a2d698cc05e507..6bd8d4bcff6540b6bed02382f47136261d529ca2 100644 (file)
 #define ARGP_QWORDDATA              0x11
 #define ARGP_SIMPLENAME             0x12       /* name_string | local_term | arg_term */
 #define ARGP_NAME_OR_REF            0x13       /* For object_type only */
+#define ARGP_MAX                    0x13
 
 /*
  * Resolved argument types for the AML Interpreter
index 54d48b90de2cd025710a71c03bcc88ea1ca75f32..5de3f10cab03bd315ad02d0f129e5ebed9bda524 100644 (file)
@@ -221,8 +221,8 @@ acpi_ds_initialize_objects(u32 table_index,
         */
        status =
            acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
-                                  0, acpi_ds_init_one_object, NULL, &info,
-                                  NULL);
+                                  ACPI_NS_WALK_NO_UNLOCK,
+                                  acpi_ds_init_one_object, NULL, &info, NULL);
        if (ACPI_FAILURE(status)) {
                ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
        }
index 4cc9d989a114f5fffa0e734d014fad2a44a1d407..77fd7c84ec39ce8da79d5b1b7345d9b6e4bf62a1 100644 (file)
@@ -84,7 +84,7 @@ acpi_status acpi_ds_initialize_region(acpi_handle obj_handle)
 
        /* Namespace is NOT locked */
 
-       status = acpi_ev_initialize_region(obj_desc, FALSE);
+       status = acpi_ev_initialize_region(obj_desc);
        return (status);
 }
 
index e36218206bb013d030fc3d75487834403ecf5458..651f35a66cc287c1f0f30852972a11ed2b784fc9 100644 (file)
@@ -609,18 +609,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
 
                        status =
                            acpi_ev_initialize_region
-                           (acpi_ns_get_attached_object(node), FALSE);
-
-                       if (ACPI_FAILURE(status)) {
-                               /*
-                                *  If AE_NOT_EXIST is returned, it is not fatal
-                                *  because many regions get created before a handler
-                                *  is installed for said region.
-                                */
-                               if (AE_NOT_EXIST == status) {
-                                       status = AE_OK;
-                               }
-                       }
+                           (acpi_ns_get_attached_object(node));
                        break;
 
                case AML_NAME_OP:
index 75ddd160a716faaa10c81ac92ddca37d1a73dcbf..a9092251ce80ad05d4afba422ced31ab706bc05f 100644 (file)
@@ -479,7 +479,6 @@ acpi_ev_default_region_setup(acpi_handle handle,
  * FUNCTION:    acpi_ev_initialize_region
  *
  * PARAMETERS:  region_obj      - Region we are initializing
- *              acpi_ns_locked  - Is namespace locked?
  *
  * RETURN:      Status
  *
@@ -497,19 +496,28 @@ acpi_ev_default_region_setup(acpi_handle handle,
  * MUTEX:       Interpreter should be unlocked, because we may run the _REG
  *              method for this region.
  *
+ * NOTE:        Possible incompliance:
+ *              There is a behavior conflict in automatic _REG execution:
+ *              1. When the interpreter is evaluating a method, we can only
+ *                 automatically run _REG for the following case:
+ *                   operation_region (OPR1, 0x80, 0x1000010, 0x4)
+ *              2. When the interpreter is loading a table, we can also
+ *                 automatically run _REG for the following case:
+ *                   operation_region (OPR1, 0x80, 0x1000010, 0x4)
+ *              Though this may not be compliant to the de-facto standard, the
+ *              logic is kept in order not to trigger regressions. And keeping
+ *              this logic should be taken care by the caller of this function.
+ *
  ******************************************************************************/
 
-acpi_status
-acpi_ev_initialize_region(union acpi_operand_object *region_obj,
-                         u8 acpi_ns_locked)
+acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj)
 {
        union acpi_operand_object *handler_obj;
        union acpi_operand_object *obj_desc;
        acpi_adr_space_type space_id;
        struct acpi_namespace_node *node;
-       acpi_status status;
 
-       ACPI_FUNCTION_TRACE_U32(ev_initialize_region, acpi_ns_locked);
+       ACPI_FUNCTION_TRACE(ev_initialize_region);
 
        if (!region_obj) {
                return_ACPI_STATUS(AE_BAD_PARAMETER);
@@ -580,39 +588,17 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
                                                  handler_obj, region_obj,
                                                  obj_desc));
 
-                               status =
-                                   acpi_ev_attach_region(handler_obj,
-                                                         region_obj,
-                                                         acpi_ns_locked);
+                               (void)acpi_ev_attach_region(handler_obj,
+                                                           region_obj, FALSE);
 
                                /*
                                 * Tell all users that this region is usable by
                                 * running the _REG method
                                 */
-                               if (acpi_ns_locked) {
-                                       status =
-                                           acpi_ut_release_mutex
-                                           (ACPI_MTX_NAMESPACE);
-                                       if (ACPI_FAILURE(status)) {
-                                               return_ACPI_STATUS(status);
-                                       }
-                               }
-
                                acpi_ex_exit_interpreter();
-                               status =
-                                   acpi_ev_execute_reg_method(region_obj,
-                                                              ACPI_REG_CONNECT);
+                               (void)acpi_ev_execute_reg_method(region_obj,
+                                                                ACPI_REG_CONNECT);
                                acpi_ex_enter_interpreter();
-
-                               if (acpi_ns_locked) {
-                                       status =
-                                           acpi_ut_acquire_mutex
-                                           (ACPI_MTX_NAMESPACE);
-                                       if (ACPI_FAILURE(status)) {
-                                               return_ACPI_STATUS(status);
-                                       }
-                               }
-
                                return_ACPI_STATUS(AE_OK);
                        }
                }
@@ -622,12 +608,15 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
                node = node->parent;
        }
 
-       /* If we get here, there is no handler for this region */
-
+       /*
+        * If we get here, there is no handler for this region. This is not
+        * fatal because many regions get created before a handler is installed
+        * for said region.
+        */
        ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
                          "No handler for RegionType %s(%X) (RegionObj %p)\n",
                          acpi_ut_get_region_name(space_id), space_id,
                          region_obj));
 
-       return_ACPI_STATUS(AE_NOT_EXIST);
+       return_ACPI_STATUS(AE_OK);
 }
index 718428ba0b89ee8ed52e6ffc74f6ce32ab6221d7..c32c7829878a86719181ec025292c1f97f5a8621 100644 (file)
@@ -437,10 +437,9 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
 
        ACPI_INFO(("Dynamic OEM Table Load:"));
        acpi_ex_exit_interpreter();
-       status =
-           acpi_tb_install_and_load_table(table, ACPI_PTR_TO_PHYSADDR(table),
-                                          ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
-                                          TRUE, &table_index);
+       status = acpi_tb_install_and_load_table(ACPI_PTR_TO_PHYSADDR(table),
+                                               ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
+                                               TRUE, &table_index);
        acpi_ex_enter_interpreter();
        if (ACPI_FAILURE(status)) {
 
@@ -500,7 +499,6 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
        acpi_status status = AE_OK;
        union acpi_operand_object *table_desc = ddb_handle;
        u32 table_index;
-       struct acpi_table_header *table;
 
        ACPI_FUNCTION_TRACE(ex_unload_table);
 
@@ -537,39 +535,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
         * strict order requirement against it.
         */
        acpi_ex_exit_interpreter();
-
-       /* Ensure the table is still loaded */
-
-       if (!acpi_tb_is_table_loaded(table_index)) {
-               status = AE_NOT_EXIST;
-               goto lock_and_exit;
-       }
-
-       /* Invoke table handler if present */
-
-       if (acpi_gbl_table_handler) {
-               status = acpi_get_table_by_index(table_index, &table);
-               if (ACPI_SUCCESS(status)) {
-                       (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
-                                                    table,
-                                                    acpi_gbl_table_handler_context);
-               }
-       }
-
-       /* Delete the portion of the namespace owned by this table */
-
-       status = acpi_tb_delete_namespace_by_owner(table_index);
-       if (ACPI_FAILURE(status)) {
-               goto lock_and_exit;
-       }
-
-       (void)acpi_tb_release_owner_id(table_index);
-       acpi_tb_set_table_loaded_flag(table_index, FALSE);
-
-lock_and_exit:
-
-       /* Re-acquire the interpreter lock */
-
+       status = acpi_tb_unload_table(table_index);
        acpi_ex_enter_interpreter();
 
        /*
index f03dd41e86d023b521e90fe4aa6cd1ef635ff3be..94d5d3339845f954110c5214305c775117c3d231 100644 (file)
@@ -95,6 +95,51 @@ acpi_size acpi_ns_get_pathname_length(struct acpi_namespace_node *node)
        return (size);
 }
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_handle_to_name
+ *
+ * PARAMETERS:  target_handle           - Handle of named object whose name is
+ *                                        to be found
+ *              buffer                  - Where the name is returned
+ *
+ * RETURN:      Status, Buffer is filled with name if status is AE_OK
+ *
+ * DESCRIPTION: Build and return a full namespace name
+ *
+ ******************************************************************************/
+
+acpi_status
+acpi_ns_handle_to_name(acpi_handle target_handle, struct acpi_buffer *buffer)
+{
+       acpi_status status;
+       struct acpi_namespace_node *node;
+       const char *node_name;
+
+       ACPI_FUNCTION_TRACE_PTR(ns_handle_to_name, target_handle);
+
+       node = acpi_ns_validate_handle(target_handle);
+       if (!node) {
+               return_ACPI_STATUS(AE_BAD_PARAMETER);
+       }
+
+       /* Validate/Allocate/Clear caller buffer */
+
+       status = acpi_ut_initialize_buffer(buffer, ACPI_PATH_SEGMENT_LENGTH);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       /* Just copy the ACPI name from the Node and zero terminate it */
+
+       node_name = acpi_ut_get_node_name(node);
+       ACPI_MOVE_NAME(buffer->pointer, node_name);
+       ((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0;
+
+       ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%4.4s\n", (char *)buffer->pointer));
+       return_ACPI_STATUS(AE_OK);
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_handle_to_pathname
index 76a1bd4bb0700aa6ff6b129b399ed3ebdd729ba8..e525cbe7d83b63966e9050ebd6d8bbfb36c3fa9f 100644 (file)
@@ -158,8 +158,6 @@ acpi_status
 acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer *buffer)
 {
        acpi_status status;
-       struct acpi_namespace_node *node;
-       const char *node_name;
 
        /* Parameter validation */
 
@@ -172,18 +170,6 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer *buffer)
                return (status);
        }
 
-       if (name_type == ACPI_FULL_PATHNAME ||
-           name_type == ACPI_FULL_PATHNAME_NO_TRAILING) {
-
-               /* Get the full pathname (From the namespace root) */
-
-               status = acpi_ns_handle_to_pathname(handle, buffer,
-                                                   name_type ==
-                                                   ACPI_FULL_PATHNAME ? FALSE :
-                                                   TRUE);
-               return (status);
-       }
-
        /*
         * Wants the single segment ACPI name.
         * Validate handle and convert to a namespace Node
@@ -193,27 +179,20 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer *buffer)
                return (status);
        }
 
-       node = acpi_ns_validate_handle(handle);
-       if (!node) {
-               status = AE_BAD_PARAMETER;
-               goto unlock_and_exit;
-       }
-
-       /* Validate/Allocate/Clear caller buffer */
-
-       status = acpi_ut_initialize_buffer(buffer, ACPI_PATH_SEGMENT_LENGTH);
-       if (ACPI_FAILURE(status)) {
-               goto unlock_and_exit;
-       }
+       if (name_type == ACPI_FULL_PATHNAME ||
+           name_type == ACPI_FULL_PATHNAME_NO_TRAILING) {
 
-       /* Just copy the ACPI name from the Node and zero terminate it */
+               /* Get the full pathname (From the namespace root) */
 
-       node_name = acpi_ut_get_node_name(node);
-       ACPI_MOVE_NAME(buffer->pointer, node_name);
-       ((char *)buffer->pointer)[ACPI_NAME_SIZE] = 0;
-       status = AE_OK;
+               status = acpi_ns_handle_to_pathname(handle, buffer,
+                                                   name_type ==
+                                                   ACPI_FULL_PATHNAME ? FALSE :
+                                                   TRUE);
+       } else {
+               /* Get the single name */
 
-unlock_and_exit:
+               status = acpi_ns_handle_to_name(handle, buffer);
+       }
 
        (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
        return (status);
index d9ca8c2aa2d3cc5a28ec55987c5f90eab513e46a..82b0b571097960919ce6ed36a703402422ac3cc7 100644 (file)
@@ -832,9 +832,9 @@ acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node)
  *
  * FUNCTION:    acpi_tb_install_and_load_table
  *
- * PARAMETERS:  table                   - Pointer to the table
- *              address                 - Physical address of the table
+ * PARAMETERS:  address                 - Physical address of the table
  *              flags                   - Allocation flags of the table
+ *              override                - Whether override should be performed
  *              table_index             - Where table index is returned
  *
  * RETURN:      Status
@@ -844,15 +844,13 @@ acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node)
  ******************************************************************************/
 
 acpi_status
-acpi_tb_install_and_load_table(struct acpi_table_header *table,
-                              acpi_physical_address address,
+acpi_tb_install_and_load_table(acpi_physical_address address,
                               u8 flags, u8 override, u32 *table_index)
 {
        acpi_status status;
        u32 i;
-       acpi_owner_id owner_id;
 
-       ACPI_FUNCTION_TRACE(acpi_load_table);
+       ACPI_FUNCTION_TRACE(tb_install_and_load_table);
 
        (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
@@ -864,45 +862,60 @@ acpi_tb_install_and_load_table(struct acpi_table_header *table,
                goto unlock_and_exit;
        }
 
-       /*
-        * Note: Now table is "INSTALLED", it must be validated before
-        * using.
-        */
-       status = acpi_tb_validate_table(&acpi_gbl_root_table_list.tables[i]);
-       if (ACPI_FAILURE(status)) {
-               goto unlock_and_exit;
-       }
+       (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+       status = acpi_tb_load_table(i, acpi_gbl_root_node);
+       (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
+unlock_and_exit:
+       *table_index = i;
        (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
-       status = acpi_ns_load_table(i, acpi_gbl_root_node);
+       return_ACPI_STATUS(status);
+}
 
-       /* Execute any module-level code that was found in the table */
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_unload_table
+ *
+ * PARAMETERS:  table_index             - Table index
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Unload an ACPI table
+ *
+ ******************************************************************************/
 
-       if (!acpi_gbl_parse_table_as_term_list
-           && acpi_gbl_group_module_level_code) {
-               acpi_ns_exec_module_code_list();
-       }
+acpi_status acpi_tb_unload_table(u32 table_index)
+{
+       acpi_status status = AE_OK;
+       struct acpi_table_header *table;
 
-       /*
-        * Update GPEs for any new _Lxx/_Exx methods. Ignore errors. The host is
-        * responsible for discovering any new wake GPEs by running _PRW methods
-        * that may have been loaded by this table.
-        */
-       status = acpi_tb_get_owner_id(i, &owner_id);
-       if (ACPI_SUCCESS(status)) {
-               acpi_ev_update_gpes(owner_id);
+       ACPI_FUNCTION_TRACE(tb_unload_table);
+
+       /* Ensure the table is still loaded */
+
+       if (!acpi_tb_is_table_loaded(table_index)) {
+               return_ACPI_STATUS(AE_NOT_EXIST);
        }
 
        /* Invoke table handler if present */
 
        if (acpi_gbl_table_handler) {
-               (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_LOAD, table,
-                                            acpi_gbl_table_handler_context);
+               status = acpi_get_table_by_index(table_index, &table);
+               if (ACPI_SUCCESS(status)) {
+                       (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
+                                                    table,
+                                                    acpi_gbl_table_handler_context);
+               }
        }
-       (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 
-unlock_and_exit:
-       *table_index = i;
-       (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+       /* Delete the portion of the namespace owned by this table */
+
+       status = acpi_tb_delete_namespace_by_owner(table_index);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
+
+       (void)acpi_tb_release_owner_id(table_index);
+       acpi_tb_set_table_loaded_flag(table_index, FALSE);
        return_ACPI_STATUS(status);
 }
index 4ab6b9cd0aec0e28f8d701f803f066b25c1c2402..d5adb7ac468430c82c4c1d7a1d7c75be6be40c5e 100644 (file)
@@ -167,6 +167,7 @@ ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_tables)
 acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
 {
        acpi_status status;
+       u32 i;
 
        ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);
 
@@ -178,6 +179,21 @@ acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
                return_ACPI_STATUS(AE_SUPPORT);
        }
 
+       /*
+        * Ensure OS early boot logic, which is required by some hosts. If the
+        * table state is reported to be wrong, developers should fix the
+        * issue by invoking acpi_put_table() for the reported table during the
+        * early stage.
+        */
+       for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
+               if (acpi_gbl_root_table_list.tables[i].pointer) {
+                       ACPI_ERROR((AE_INFO,
+                                   "Table [%4.4s] is not invalidated during early boot stage",
+                                   acpi_gbl_root_table_list.tables[i].
+                                   signature.ascii));
+               }
+       }
+
        acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE;
 
        status = acpi_tb_resize_root_table_list();
index 5569f637f6696dd28947ca71f319f6005a6d31cd..82019c01a0e58edd7c8382fb9bcf7fadddf4f67b 100644 (file)
@@ -239,7 +239,7 @@ acpi_status acpi_tb_load_namespace(void)
        }
 
        if (!tables_failed) {
-               ACPI_INFO(("%u ACPI AML tables successfully acquired and loaded\n", tables_loaded));
+               ACPI_INFO(("%u ACPI AML tables successfully acquired and loaded", tables_loaded));
        } else {
                ACPI_ERROR((AE_INFO,
                            "%u table load failures, %u successful",
@@ -250,6 +250,10 @@ acpi_status acpi_tb_load_namespace(void)
                status = AE_CTRL_TERMINATE;
        }
 
+#ifdef ACPI_APPLICATION
+       ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT, "\n"));
+#endif
+
 unlock_and_exit:
        (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
        return_ACPI_STATUS(status);
@@ -326,10 +330,9 @@ acpi_status acpi_load_table(struct acpi_table_header *table)
        /* Install the table and load it into the namespace */
 
        ACPI_INFO(("Host-directed Dynamic ACPI Table Load:"));
-       status =
-           acpi_tb_install_and_load_table(table, ACPI_PTR_TO_PHYSADDR(table),
-                                          ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
-                                          FALSE, &table_index);
+       status = acpi_tb_install_and_load_table(ACPI_PTR_TO_PHYSADDR(table),
+                                               ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
+                                               FALSE, &table_index);
        return_ACPI_STATUS(status);
 }
 
@@ -405,37 +408,8 @@ acpi_status acpi_unload_parent_table(acpi_handle object)
                        break;
                }
 
-               /* Ensure the table is actually loaded */
-
                (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
-               if (!acpi_tb_is_table_loaded(i)) {
-                       status = AE_NOT_EXIST;
-                       (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
-                       break;
-               }
-
-               /* Invoke table handler if present */
-
-               if (acpi_gbl_table_handler) {
-                       (void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
-                                                    acpi_gbl_root_table_list.
-                                                    tables[i].pointer,
-                                                    acpi_gbl_table_handler_context);
-               }
-
-               /*
-                * Delete all namespace objects owned by this table. Note that
-                * these objects can appear anywhere in the namespace by virtue
-                * of the AML "Scope" operator. Thus, we need to track ownership
-                * by an ID, not simply a position within the hierarchy.
-                */
-               status = acpi_tb_delete_namespace_by_owner(i);
-               if (ACPI_FAILURE(status)) {
-                       break;
-               }
-
-               status = acpi_tb_release_owner_id(i);
-               acpi_tb_set_table_loaded_flag(i, FALSE);
+               status = acpi_tb_unload_table(i);
                (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
                break;
        }
index 15728ad8356b18363411b278874db837b3fcd0e0..b3d8421cfb8079b1f3b78b71f43cc4d2bbb63402 100644 (file)
@@ -44,6 +44,7 @@
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acnamesp.h"
+#include "amlcode.h"
 
 #define _COMPONENT          ACPI_UTILITIES
 ACPI_MODULE_NAME("utdecode")
@@ -532,6 +533,54 @@ const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type)
 
        return ("Hardware-Specific");
 }
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_get_argument_type_name
+ *
+ * PARAMETERS:  arg_type            - an ARGP_* parser argument type
+ *
+ * RETURN:      Decoded ARGP_* type
+ *
+ * DESCRIPTION: Decode an ARGP_* parser type, as defined in the amlcode.h file,
+ *              and used in the acopcode.h file. For example, ARGP_TERMARG.
+ *              Used for debug only.
+ *
+ ******************************************************************************/
+
+static const char *acpi_gbl_argument_type[20] = {
+       /* 00 */ "Unknown ARGP",
+       /* 01 */ "ByteData",
+       /* 02 */ "ByteList",
+       /* 03 */ "CharList",
+       /* 04 */ "DataObject",
+       /* 05 */ "DataObjectList",
+       /* 06 */ "DWordData",
+       /* 07 */ "FieldList",
+       /* 08 */ "Name",
+       /* 09 */ "NameString",
+       /* 0A */ "ObjectList",
+       /* 0B */ "PackageLength",
+       /* 0C */ "SuperName",
+       /* 0D */ "Target",
+       /* 0E */ "TermArg",
+       /* 0F */ "TermList",
+       /* 10 */ "WordData",
+       /* 11 */ "QWordData",
+       /* 12 */ "SimpleName",
+       /* 13 */ "NameOrRef"
+};
+
+const char *acpi_ut_get_argument_type_name(u32 arg_type)
+{
+
+       if (arg_type > ARGP_MAX) {
+               return ("Unknown ARGP");
+       }
+
+       return (acpi_gbl_argument_type[arg_type]);
+}
+
 #endif
 
 /*******************************************************************************
index 0d099a24f776ac9bd665f3aab8006793031aef48..e53bef6cf53c627d7c9a6a566d75fbe1805d1138 100644 (file)
@@ -852,6 +852,8 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
                if (ghes_read_estatus(ghes, 1)) {
                        ghes_clear_estatus(ghes);
                        continue;
+               } else {
+                       ret = NMI_HANDLED;
                }
 
                sev = ghes_severity(ghes->estatus->error_severity);
@@ -863,12 +865,11 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
 
                __process_error(ghes);
                ghes_clear_estatus(ghes);
-
-               ret = NMI_HANDLED;
        }
 
 #ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
-       irq_work_queue(&ghes_proc_irq_work);
+       if (ret == NMI_HANDLED)
+               irq_work_queue(&ghes_proc_irq_work);
 #endif
        atomic_dec(&ghes_in_nmi);
        return ret;
index 20b3fcf4007caf8a95e22d8bac320aea3a317667..8f2a98e23bbae906fcf78421b3b48722fd9f67c0 100644 (file)
@@ -123,7 +123,13 @@ EXPORT_SYMBOL_GPL(apei_hest_parse);
  */
 static int __init hest_parse_cmc(struct acpi_hest_header *hest_hdr, void *data)
 {
-       return arch_apei_enable_cmcff(hest_hdr, data);
+       if (hest_hdr->type != ACPI_HEST_TYPE_IA32_CORRECTED_CHECK)
+               return 0;
+
+       if (!acpi_disable_cmcff)
+               return !arch_apei_enable_cmcff(hest_hdr, data);
+
+       return 0;
 }
 
 struct ghes_arr {
@@ -232,8 +238,9 @@ void __init acpi_hest_init(void)
                goto err;
        }
 
-       if (!acpi_disable_cmcff)
-               apei_hest_parse(hest_parse_cmc, NULL);
+       rc = apei_hest_parse(hest_parse_cmc, NULL);
+       if (rc)
+               goto err;
 
        if (!ghes_disable) {
                rc = apei_hest_parse(hest_parse_ghes_count, &ghes_count);
index 93ecae55fe6a02452a8e7974c0d290f46ccae836..05fe9ebfb9b5d8acd5625b3bb16e34f2c03b6a4b 100644 (file)
@@ -430,39 +430,24 @@ static int acpi_battery_get_status(struct acpi_battery *battery)
        return 0;
 }
 
-static int acpi_battery_get_info(struct acpi_battery *battery)
+
+static int extract_battery_info(const int use_bix,
+                        struct acpi_battery *battery,
+                        const struct acpi_buffer *buffer)
 {
        int result = -EFAULT;
-       acpi_status status = 0;
-       char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags) ?
-                       "_BIX" : "_BIF";
-
-       struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
 
-       if (!acpi_battery_present(battery))
-               return 0;
-       mutex_lock(&battery->lock);
-       status = acpi_evaluate_object(battery->device->handle, name,
-                                               NULL, &buffer);
-       mutex_unlock(&battery->lock);
-
-       if (ACPI_FAILURE(status)) {
-               ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s", name));
-               return -ENODEV;
-       }
-
-       if (battery_bix_broken_package)
-               result = extract_package(battery, buffer.pointer,
+       if (use_bix && battery_bix_broken_package)
+               result = extract_package(battery, buffer->pointer,
                                extended_info_offsets + 1,
                                ARRAY_SIZE(extended_info_offsets) - 1);
-       else if (test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags))
-               result = extract_package(battery, buffer.pointer,
+       else if (use_bix)
+               result = extract_package(battery, buffer->pointer,
                                extended_info_offsets,
                                ARRAY_SIZE(extended_info_offsets));
        else
-               result = extract_package(battery, buffer.pointer,
+               result = extract_package(battery, buffer->pointer,
                                info_offsets, ARRAY_SIZE(info_offsets));
-       kfree(buffer.pointer);
        if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
                battery->full_charge_capacity = battery->design_capacity;
        if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) &&
@@ -483,6 +468,45 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
        return result;
 }
 
+static int acpi_battery_get_info(struct acpi_battery *battery)
+{
+       const int xinfo = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags);
+       int use_bix;
+       int result = -ENODEV;
+
+       if (!acpi_battery_present(battery))
+               return 0;
+
+
+       for (use_bix = xinfo ? 1 : 0; use_bix >= 0; use_bix--) {
+               struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+               acpi_status status = AE_ERROR;
+
+               mutex_lock(&battery->lock);
+               status = acpi_evaluate_object(battery->device->handle,
+                                             use_bix ? "_BIX":"_BIF",
+                                             NULL, &buffer);
+               mutex_unlock(&battery->lock);
+
+               if (ACPI_FAILURE(status)) {
+                       ACPI_EXCEPTION((AE_INFO, status, "Evaluating %s",
+                                       use_bix ? "_BIX":"_BIF"));
+               } else {
+                       result = extract_battery_info(use_bix,
+                                                     battery,
+                                                     &buffer);
+
+                       kfree(buffer.pointer);
+                       break;
+               }
+       }
+
+       if (!result && !use_bix && xinfo)
+               pr_warn(FW_BUG "The _BIX method is broken, using _BIF.\n");
+
+       return result;
+}
+
 static int acpi_battery_get_state(struct acpi_battery *battery)
 {
        int result = 0;
index bdc67bad61a75b8c823973ea822b7c9feafed28c..4421f7c9981c7c5aa950893273a9d93dfc353bb4 100644 (file)
@@ -160,6 +160,34 @@ static struct dmi_system_id acpi_rev_dmi_table[] __initdata = {
                      DMI_MATCH(DMI_PRODUCT_NAME, "XPS 13 9343"),
                },
        },
+       {
+        .callback = dmi_enable_rev_override,
+        .ident = "DELL Precision 5520",
+        .matches = {
+                     DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                     DMI_MATCH(DMI_PRODUCT_NAME, "Precision 5520"),
+               },
+       },
+       {
+        .callback = dmi_enable_rev_override,
+        .ident = "DELL Precision 3520",
+        .matches = {
+                     DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                     DMI_MATCH(DMI_PRODUCT_NAME, "Precision 3520"),
+               },
+       },
+       /*
+        * Resolves a quirk with the Dell Latitude 3350 that
+        * causes the ethernet adapter to not function.
+        */
+       {
+        .callback = dmi_enable_rev_override,
+        .ident = "DELL Latitude 3350",
+        .matches = {
+                     DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+                     DMI_MATCH(DMI_PRODUCT_NAME, "Latitude 3350"),
+               },
+       },
 #endif
        {}
 };
index d0d0504b7c895b47bc29f8c50c20c50b3ce98f13..e0ea8f56d2bfd9ceb19fa63eda3544195e4c1e56 100644 (file)
@@ -784,8 +784,10 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr)
 
        /* Add per logical CPU nodes for reading its feedback counters. */
        cpu_dev = get_cpu_device(pr->id);
-       if (!cpu_dev)
+       if (!cpu_dev) {
+               ret = -EINVAL;
                goto out_free;
+       }
 
        ret = kobject_init_and_add(&cpc_ptr->kobj, &cppc_ktype, &cpu_dev->kobj,
                        "acpi_cppc");
index 7b2c48fde4e2b19f7134c1900931ff0695469ad9..24418932612eeabc62d72185df50980ed55ee5bd 100644 (file)
@@ -52,7 +52,7 @@ struct acpi_data_node_attr {
 
 static ssize_t data_node_show_path(struct acpi_data_node *dn, char *buf)
 {
-       return acpi_object_path(dn->handle, buf);
+       return dn->handle ? acpi_object_path(dn->handle, buf) : 0;
 }
 
 DATA_NODE_ATTR(path);
@@ -105,10 +105,10 @@ static void acpi_expose_nondev_subnodes(struct kobject *kobj,
                init_completion(&dn->kobj_done);
                ret = kobject_init_and_add(&dn->kobj, &acpi_data_node_ktype,
                                           kobj, "%s", dn->name);
-               if (ret)
-                       acpi_handle_err(dn->handle, "Failed to expose (%d)\n", ret);
-               else
+               if (!ret)
                        acpi_expose_nondev_subnodes(&dn->kobj, &dn->data);
+               else if (dn->handle)
+                       acpi_handle_err(dn->handle, "Failed to expose (%d)\n", ret);
        }
 }
 
index 416953a4251094ce2066d724c1d88583b8e89705..9a4c6abee63e0e86a6941d19665a409d3931b301 100644 (file)
@@ -181,15 +181,15 @@ void acpi_os_vprintf(const char *fmt, va_list args)
 static unsigned long acpi_rsdp;
 static int __init setup_acpi_rsdp(char *arg)
 {
-       if (kstrtoul(arg, 16, &acpi_rsdp))
-               return -EINVAL;
-       return 0;
+       return kstrtoul(arg, 16, &acpi_rsdp);
 }
 early_param("acpi_rsdp", setup_acpi_rsdp);
 #endif
 
 acpi_physical_address __init acpi_os_get_root_pointer(void)
 {
+       acpi_physical_address pa = 0;
+
 #ifdef CONFIG_KEXEC
        if (acpi_rsdp)
                return acpi_rsdp;
@@ -198,21 +198,14 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
        if (efi_enabled(EFI_CONFIG_TABLES)) {
                if (efi.acpi20 != EFI_INVALID_TABLE_ADDR)
                        return efi.acpi20;
-               else if (efi.acpi != EFI_INVALID_TABLE_ADDR)
+               if (efi.acpi != EFI_INVALID_TABLE_ADDR)
                        return efi.acpi;
-               else {
-                       printk(KERN_ERR PREFIX
-                              "System description tables not found\n");
-                       return 0;
-               }
+               pr_err(PREFIX "System description tables not found\n");
        } else if (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
-               acpi_physical_address pa = 0;
-
                acpi_find_root_pointer(&pa);
-               return pa;
        }
 
-       return 0;
+       return pa;
 }
 
 /* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
index 03f5ec11ab3197de66ced4e7f09d39dbab6b8232..3afddcd834efdb407f8b5dec1bebf42ce704c0c5 100644 (file)
@@ -41,14 +41,13 @@ static bool acpi_enumerate_nondev_subnodes(acpi_handle scope,
 static bool acpi_extract_properties(const union acpi_object *desc,
                                    struct acpi_device_data *data);
 
-static bool acpi_nondev_subnode_ok(acpi_handle scope,
-                                  const union acpi_object *link,
-                                  struct list_head *list)
+static bool acpi_nondev_subnode_extract(const union acpi_object *desc,
+                                       acpi_handle handle,
+                                       const union acpi_object *link,
+                                       struct list_head *list)
 {
-       struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
        struct acpi_data_node *dn;
-       acpi_handle handle;
-       acpi_status status;
+       bool result;
 
        dn = kzalloc(sizeof(*dn), GFP_KERNEL);
        if (!dn)
@@ -58,43 +57,75 @@ static bool acpi_nondev_subnode_ok(acpi_handle scope,
        dn->fwnode.type = FWNODE_ACPI_DATA;
        INIT_LIST_HEAD(&dn->data.subnodes);
 
-       status = acpi_get_handle(scope, link->package.elements[1].string.pointer,
-                                &handle);
-       if (ACPI_FAILURE(status))
-               goto fail;
+       result = acpi_extract_properties(desc, &dn->data);
 
-       status = acpi_evaluate_object_typed(handle, NULL, NULL, &buf,
-                                           ACPI_TYPE_PACKAGE);
-       if (ACPI_FAILURE(status))
-               goto fail;
+       if (handle) {
+               acpi_handle scope;
+               acpi_status status;
 
-       if (acpi_extract_properties(buf.pointer, &dn->data))
-               dn->handle = handle;
+               /*
+                * The scope for the subnode object lookup is the one of the
+                * namespace node (device) containing the object that has
+                * returned the package.  That is, it's the scope of that
+                * object's parent.
+                */
+               status = acpi_get_parent(handle, &scope);
+               if (ACPI_SUCCESS(status)
+                   && acpi_enumerate_nondev_subnodes(scope, desc, &dn->data))
+                       result = true;
+       } else if (acpi_enumerate_nondev_subnodes(NULL, desc, &dn->data)) {
+               result = true;
+       }
 
-       /*
-        * The scope for the subnode object lookup is the one of the namespace
-        * node (device) containing the object that has returned the package.
-        * That is, it's the scope of that object's parent.
-        */
-       status = acpi_get_parent(handle, &scope);
-       if (ACPI_SUCCESS(status)
-           && acpi_enumerate_nondev_subnodes(scope, buf.pointer, &dn->data))
+       if (result) {
                dn->handle = handle;
-
-       if (dn->handle) {
-               dn->data.pointer = buf.pointer;
+               dn->data.pointer = desc;
                list_add_tail(&dn->sibling, list);
                return true;
        }
 
+       kfree(dn);
        acpi_handle_debug(handle, "Invalid properties/subnodes data, skipping\n");
+       return false;
+}
+
+static bool acpi_nondev_subnode_data_ok(acpi_handle handle,
+                                       const union acpi_object *link,
+                                       struct list_head *list)
+{
+       struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
+       acpi_status status;
+
+       status = acpi_evaluate_object_typed(handle, NULL, NULL, &buf,
+                                           ACPI_TYPE_PACKAGE);
+       if (ACPI_FAILURE(status))
+               return false;
+
+       if (acpi_nondev_subnode_extract(buf.pointer, handle, link, list))
+               return true;
 
- fail:
        ACPI_FREE(buf.pointer);
-       kfree(dn);
        return false;
 }
 
+static bool acpi_nondev_subnode_ok(acpi_handle scope,
+                                  const union acpi_object *link,
+                                  struct list_head *list)
+{
+       acpi_handle handle;
+       acpi_status status;
+
+       if (!scope)
+               return false;
+
+       status = acpi_get_handle(scope, link->package.elements[1].string.pointer,
+                                &handle);
+       if (ACPI_FAILURE(status))
+               return false;
+
+       return acpi_nondev_subnode_data_ok(handle, link, list);
+}
+
 static int acpi_add_nondev_subnodes(acpi_handle scope,
                                    const union acpi_object *links,
                                    struct list_head *list)
@@ -103,15 +134,37 @@ static int acpi_add_nondev_subnodes(acpi_handle scope,
        int i;
 
        for (i = 0; i < links->package.count; i++) {
-               const union acpi_object *link;
+               const union acpi_object *link, *desc;
+               acpi_handle handle;
+               bool result;
 
                link = &links->package.elements[i];
-               /* Only two elements allowed, both must be strings. */
-               if (link->package.count == 2
-                   && link->package.elements[0].type == ACPI_TYPE_STRING
-                   && link->package.elements[1].type == ACPI_TYPE_STRING
-                   && acpi_nondev_subnode_ok(scope, link, list))
-                       ret = true;
+               /* Only two elements allowed. */
+               if (link->package.count != 2)
+                       continue;
+
+               /* The first one must be a string. */
+               if (link->package.elements[0].type != ACPI_TYPE_STRING)
+                       continue;
+
+               /* The second one may be a string, a reference or a package. */
+               switch (link->package.elements[1].type) {
+               case ACPI_TYPE_STRING:
+                       result = acpi_nondev_subnode_ok(scope, link, list);
+                       break;
+               case ACPI_TYPE_LOCAL_REFERENCE:
+                       handle = link->package.elements[1].reference.handle;
+                       result = acpi_nondev_subnode_data_ok(handle, link, list);
+                       break;
+               case ACPI_TYPE_PACKAGE:
+                       desc = &link->package.elements[1];
+                       result = acpi_nondev_subnode_extract(desc, NULL, link, list);
+                       break;
+               default:
+                       result = false;
+                       break;
+               }
+               ret = ret || result;
        }
 
        return ret;
index a6b36fc53aec54dfc642dd260aa25cfbbec037b5..02ded25c82e4a06e1e79bf2f0a4855aa933b3df1 100644 (file)
@@ -296,6 +296,26 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
                DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"),
                },
        },
+       {
+        /* https://bugzilla.redhat.com/show_bug.cgi?id=1123661 */
+        .callback = video_detect_force_native,
+        .ident = "Dell XPS 17 L702X",
+        .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+               DMI_MATCH(DMI_PRODUCT_NAME, "Dell System XPS L702X"),
+               },
+       },
+       {
+       /* https://bugzilla.redhat.com/show_bug.cgi?id=1204476 */
+       /* https://bugs.launchpad.net/ubuntu/+source/linux-lts-trusty/+bug/1416940 */
+       .callback = video_detect_force_native,
+       .ident = "HP Pavilion dv6",
+       .matches = {
+               DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+               DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv6 Notebook PC"),
+               },
+       },
+
        { },
 };
 
index 12c2882bf6472bf0d9a3f90678742074ee1a4862..d25da936750e7df39af2c07605b313d636346b91 100644 (file)
 
 /* Maximum number of While() loops before abort */
 
-#define ACPI_MAX_LOOP_COUNT             0xFFFF
+#define ACPI_MAX_LOOP_COUNT             0x000FFFFF
 
 /******************************************************************************
  *
index c7b3a132dbe771956fabfedf69faf3088ef52bf1..5c7356adc10b5f96f0fc39f430ae4741fbda8ea1 100644 (file)
@@ -46,7 +46,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20160831
+#define ACPI_CA_VERSION                 0x20160930
 
 #include <acpi/acconfig.h>
 #include <acpi/actypes.h>
@@ -258,6 +258,13 @@ ACPI_INIT_GLOBAL(u8, acpi_gbl_osi_data, 0);
  */
 ACPI_INIT_GLOBAL(u8, acpi_gbl_reduced_hardware, FALSE);
 
+/*
+ * Maximum number of While() loop iterations before forced method abort.
+ * This mechanism is intended to prevent infinite loops during interpreter
+ * execution within a host kernel.
+ */
+ACPI_INIT_GLOBAL(u32, acpi_gbl_max_loop_iterations, ACPI_MAX_LOOP_COUNT);
+
 /*
  * This mechanism is used to trace a specified AML method. The method is
  * traced each time it is executed.
index 4536bd345ab462db5137be14a06d776cd5f6f85c..bfe484da55d2c98506106321501fa74a7551ecd1 100644 (file)
@@ -30,6 +30,17 @@ struct acpi_device;
 #define ACPI_VIDEO_DISPLAY_LEGACY_PANEL   0x0110
 #define ACPI_VIDEO_DISPLAY_LEGACY_TV      0x0200
 
+#define ACPI_VIDEO_NOTIFY_SWITCH               0x80
+#define ACPI_VIDEO_NOTIFY_PROBE                        0x81
+#define ACPI_VIDEO_NOTIFY_CYCLE                        0x82
+#define ACPI_VIDEO_NOTIFY_NEXT_OUTPUT          0x83
+#define ACPI_VIDEO_NOTIFY_PREV_OUTPUT          0x84
+#define ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS     0x85
+#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS       0x86
+#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS       0x87
+#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS      0x88
+#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF          0x89
+
 enum acpi_backlight_type {
        acpi_backlight_undef = -1,
        acpi_backlight_none = 0,
index 0510237565203e96b7466bd7f3b6617f2ee0044c..43b28f04a1f5b30146375d801a350e6771987afb 100644 (file)
@@ -220,10 +220,6 @@ int __init acpi_table_parse_entries(char *id, unsigned long table_size,
                              int entry_id,
                              acpi_tbl_entry_handler handler,
                              unsigned int max_entries);
-int __init acpi_table_parse_entries(char *id, unsigned long table_size,
-                             int entry_id,
-                             acpi_tbl_entry_handler handler,
-                             unsigned int max_entries);
 int __init acpi_table_parse_entries_array(char *id, unsigned long table_size,
                              struct acpi_subtable_proc *proc, int proc_num,
                              unsigned int max_entries);
index 8d8003c919d4425b940788aed97de11e8b82402b..10648aaf616476aa24577a1820f0a8ff4150b513 100644 (file)
@@ -646,8 +646,12 @@ acpi_os_create_semaphore(u32 max_units,
        }
 #ifdef __APPLE__
        {
-               char *semaphore_name = tmpnam(NULL);
+               static int semaphore_count = 0;
+               char semaphore_name[32];
 
+               snprintf(semaphore_name, sizeof(semaphore_name), "acpi_sem_%d",
+                        semaphore_count++);
+               printf("%s\n", semaphore_name);
                sem =
                    sem_open(semaphore_name, O_EXCL | O_CREAT, 0755,
                             initial_units);
@@ -692,10 +696,15 @@ acpi_status acpi_os_delete_semaphore(acpi_handle handle)
        if (!sem) {
                return (AE_BAD_PARAMETER);
        }
-
+#ifdef __APPLE__
+       if (sem_close(sem) == -1) {
+               return (AE_BAD_PARAMETER);
+       }
+#else
        if (sem_destroy(sem) == -1) {
                return (AE_BAD_PARAMETER);
        }
+#endif
 
        return (AE_OK);
 }