ACPI material for v4.10-rc1
- 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). -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJYTx6WAAoJEILEb/54YlRxFksP/0oZUm4dxHJFT6ED1ogBLid6 o+T7PA46i7VpyyT64tq3YcBqccFAYq9jHvK0FasK6WA3GKF+fj8cc5FsFM0lfdlw pMFfkdVTVajzFAM1QcxxeNr+TNuAGhx1ENf3us4xOP1Nt++kESBMwA112emoqEJL kzb2M3sCWyHNUxLtbis5CpYXLNFifFf8PP+LgmfRk0u2EYYW2nOShd6A7w5USmDh cYsfKcrBHs+nmNh6uZrQbGg+6zTcQT7XORyqcIsgT2JoWooVfwOrBjgLymFvuLUc ShZ1dHqR+RwIu1ZTIWImpDcBz/dALGIDuGAxad1YRhx7N7Eg4jmmht3hASYKWabG lqU4PWMBERonIW0MCFJ7Pg8+Ny7+kAF/rZjDyw09P2DGGQjsG4aJGAdoG5Dtjidc 1W+OAJC6SY494U+r/kHnsR0/JWTX24H7sVP5IBCFxHkByhe5daSngtknrYzIV4kE dV4h8JJATrSyvdgwAEHmVSpTCR0tmFvsc5J87Mg/g/b6NM3tPVxb70eE9tRr4xw1 oW0X9YI9M8NFnRP6RbCVg6uO06xDD2SMfb0e8fiiAp+/eGGyjp1PVR9SreuUdqaJ XJwntAWxKOXBPXMRuCeOuXBUNe5mT+WkMF6AuQyfBoM7rIhkqJb328buVAsyAKBx 74gsPkkeA6/Z1n7HWUFn =Nzrb -----END PGP SIGNATURE----- Merge tag 'acpi-4.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm 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 ..
This commit is contained in:
commit
a67485d4bf
|
@ -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
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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", },
|
||||
|
|
|
@ -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 @@ exit:
|
|||
|
||||
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;
|
||||
|
||||
|
|
|
@ -43,17 +43,6 @@
|
|||
|
||||
#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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 (\
|
||||
u8 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
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -240,6 +240,7 @@
|
|||
#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
|
||||
|
|
|
@ -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"));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
/*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,6 +170,15 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer *buffer)
|
|||
return (status);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wants the single segment ACPI name.
|
||||
* Validate handle and convert to a namespace Node
|
||||
*/
|
||||
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return (status);
|
||||
}
|
||||
|
||||
if (name_type == ACPI_FULL_PATHNAME ||
|
||||
name_type == ACPI_FULL_PATHNAME_NO_TRAILING) {
|
||||
|
||||
|
@ -181,40 +188,12 @@ acpi_get_name(acpi_handle handle, u32 name_type, struct acpi_buffer *buffer)
|
|||
name_type ==
|
||||
ACPI_FULL_PATHNAME ? FALSE :
|
||||
TRUE);
|
||||
return (status);
|
||||
} else {
|
||||
/* Get the single name */
|
||||
|
||||
status = acpi_ns_handle_to_name(handle, buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wants the single segment ACPI name.
|
||||
* Validate handle and convert to a namespace Node
|
||||
*/
|
||||
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
status = AE_OK;
|
||||
|
||||
unlock_and_exit:
|
||||
|
||||
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
||||
return (status);
|
||||
}
|
||||
|
|
|
@ -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,41 +862,8 @@ 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_ns_load_table(i, acpi_gbl_root_node);
|
||||
|
||||
/* Execute any module-level code that was found in the table */
|
||||
|
||||
if (!acpi_gbl_parse_table_as_term_list
|
||||
&& acpi_gbl_group_module_level_code) {
|
||||
acpi_ns_exec_module_code_list();
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
/* 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_tb_load_table(i, acpi_gbl_root_node);
|
||||
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
|
||||
|
||||
unlock_and_exit:
|
||||
|
@ -906,3 +871,51 @@ unlock_and_exit:
|
|||
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_tb_unload_table
|
||||
*
|
||||
* PARAMETERS: table_index - Table index
|
||||
*
|
||||
* RETURN: Status
|
||||
*
|
||||
* DESCRIPTION: Unload an ACPI table
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
acpi_status acpi_tb_unload_table(u32 table_index)
|
||||
{
|
||||
acpi_status status = AE_OK;
|
||||
struct acpi_table_header *table;
|
||||
|
||||
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) {
|
||||
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)) {
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
/*******************************************************************************
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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))
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
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, buf.pointer, &dn->data))
|
||||
dn->handle = handle;
|
||||
|
||||
if (dn->handle) {
|
||||
dn->data.pointer = buf.pointer;
|
||||
dn->data.pointer = desc;
|
||||
list_add_tail(&dn->sibling, list);
|
||||
return true;
|
||||
}
|
||||
|
||||
acpi_handle_debug(handle, "Invalid properties/subnodes data, skipping\n");
|
||||
|
||||
fail:
|
||||
ACPI_FREE(buf.pointer);
|
||||
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;
|
||||
|
||||
ACPI_FREE(buf.pointer);
|
||||
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;
|
||||
|
|
|
@ -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"),
|
||||
},
|
||||
},
|
||||
|
||||
{ },
|
||||
};
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@
|
|||
|
||||
/* Maximum number of While() loops before abort */
|
||||
|
||||
#define ACPI_MAX_LOOP_COUNT 0xFFFF
|
||||
#define ACPI_MAX_LOOP_COUNT 0x000FFFFF
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue