Power management and ACPI updates for 3.11-rc1
- Hotplug changes allowing device hot-removal operations to fail gracefully (instead of crashing the kernel) if they cannot be carried out completely. From Rafael J Wysocki and Toshi Kani. - Freezer update from Colin Cross and Mandeep Singh Baines targeted at making the freezing of tasks a bit less heavy weight operation. - cpufreq resume fix from Srivatsa S Bhat for a regression introduced during the 3.10 cycle causing some cpufreq sysfs attributes to return wrong values to user space after resume. - New freqdomain_cpus sysfs attribute for the acpi-cpufreq driver to provide information previously available via related_cpus from Lan Tianyu. - cpufreq fixes and cleanups from Viresh Kumar, Jacob Shin, Heiko Stübner, Xiaoguang Chen, Ezequiel Garcia, Arnd Bergmann, and Tang Yuantian. - Fix for an ACPICA regression causing suspend/resume issues to appear on some systems introduced during the 3.4 development cycle from Lv Zheng. - ACPICA fixes and cleanups from Bob Moore, Tomasz Nowicki, Lv Zheng, Chao Guan, and Zhang Rui. - New cupidle driver for Xilinx Zynq processors from Michal Simek. - cpuidle fixes and cleanups from Daniel Lezcano. - Changes to make suspend/resume work correctly in Xen guests from Konrad Rzeszutek Wilk. - ACPI device power management fixes and cleanups from Fengguang Wu and Rafael J Wysocki. - ACPI documentation updates from Lv Zheng, Aaron Lu and Hanjun Guo. - Fix for the IA-64 issue that was the reason for reverting commit9f29ab1
and updates of the ACPI scan code from Rafael J Wysocki. - Mechanism for adding CMOS RTC address space handlers from Lan Tianyu (to allow some EC-related breakage to be fixed on some systems). - Spec-compliant implementation of acpi_os_get_timer() from Mika Westerberg. - Modification of do_acpi_find_child() to execute _STA in order to to avoid situations in which a pointer to a disabled device object is returned instead of an enabled one with the same _ADR value. From Jeff Wu. - Intel BayTrail PCH (Platform Controller Hub) support for the ACPI Intel Low-Power Subsystems (LPSS) driver and modificaions of that driver to work around a couple of known BIOS issues from Mika Westerberg and Heikki Krogerus. - EC driver fix from Vasiliy Kulikov to make it use get_user() and put_user() instead of dereferencing user space pointers blindly. - Assorted ACPI code cleanups from Bjorn Helgaas, Nicholas Mazzuca and Toshi Kani. - Modification of the "runtime idle" helper routine to take the return values of the callbacks executed by it into account and to call rpm_suspend() if they return 0, which allows some code bloat reduction to be done, from Rafael J Wysocki and Alan Stern. - New trace points for PM QoS from Sahara <keun-o.park@windriver.com>. - PM QoS documentation update from Lan Tianyu. - Assorted core PM code cleanups and changes from Bernie Thompson, Bjorn Helgaas, Julius Werner, and Shuah Khan. - New devfreq driver for the Exynos5-bus device from Abhilash Kesavan. - Minor devfreq cleanups, fixes and MAINTAINERS update from MyungJoo Ham, Abhilash Kesavan, Paul Bolle, Rajagopal Venkat, and Wei Yongjun. - OMAP Adaptive Voltage Scaling (AVS) SmartReflex voltage control driver updates from Andrii Tseglytskyi and Nishanth Menon. / -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iQIcBAABAgAGBQJR0ZNOAAoJEKhOf7ml8uNsDLYP/0EU4rmvw0TWTITfp6RS1KDE 9GwBn96ZR4Q5bJd9gBCTPSqhHOYMqxWEUp99sn/M2wehG1pk/jw5LO56+2IhM3UZ g1HDcJ7te2nVT/iXsKiAGTVhU9Rk0aYwoVSknwk27qpIBGxW9w/s5tLX8pY3Q3Zq wL/7aTPjyL+PFFFEaxgH7qLqsl3DhbtYW5AriUBTkXout/tJ4eO1b7MNBncLDh8X VQ/0DNCKE95VEJfkO4rk9RKUyVp9GDn0i+HXCD/FS4IA5oYzePdVdNDmXf7g+swe CGlTZq8pB+oBpDiHl4lxzbNrKQjRNbGnDUkoRcWqn0nAw56xK+vmYnWJhW99gQ/I fKnvxeLca5po1aiqmC4VSJxZIatFZqLrZAI4dzoCLWY+bGeTnCKmj0/F8ytFnZA2 8IuLLs7/dFOaHXV/pKmpg6FAlFa9CPxoqRFoyqb4M0GjEarADyalXUWsPtG+6xCp R/p0CISpwk+guKZR/qPhL7M654S7SHrPwd2DPF0KgGsvk+G2GhoB8EzvD8BVp98Z 9siCGCdgKQfJQVI6R0k9aFmn/4gRQIAgyPhkhv9tqULUUkiaXki+/t8kPfnb8O/d zep+CA57E2G8MYLkDJfpFeKS7GpPD6TIdgFdGmOUC0Y6sl9iTdiw4yTx8O2JM37z rHBZfYGkJBrbGRu+Q1gs =VBBq -----END PGP SIGNATURE----- Merge tag 'pm+acpi-3.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm Pull power management and ACPI updates from Rafael Wysocki: "This time the total number of ACPI commits is slightly greater than the number of cpufreq commits, but Viresh Kumar (who works on cpufreq) remains the most active patch submitter. To me, the most significant change is the addition of offline/online device operations to the driver core (with the Greg's blessing) and the related modifications of the ACPI core hotplug code. Next are the freezer updates from Colin Cross that should make the freezing of tasks a bit less heavy weight. We also have a couple of regression fixes, a number of fixes for issues that have not been identified as regressions, two new drivers and a bunch of cleanups all over. Highlights: - Hotplug changes to support graceful hot-removal failures. It sometimes is necessary to fail device hot-removal operations gracefully if they cannot be carried out completely. For example, if memory from a memory module being hot-removed has been allocated for the kernel's own use and cannot be moved elsewhere, it's desirable to fail the hot-removal operation in a graceful way rather than to crash the kernel, but currenty a success or a kernel crash are the only possible outcomes of an attempted memory hot-removal. Needless to say, that is not a very attractive alternative and it had to be addressed. However, in order to make it work for memory, I first had to make it work for CPUs and for this purpose I needed to modify the ACPI processor driver. It's been split into two parts, a resident one handling the low-level initialization/cleanup and a modular one playing the actual driver's role (but it binds to the CPU system device objects rather than to the ACPI device objects representing processors). That's been sort of like a live brain surgery on a patient who's riding a bike. So this is a little scary, but since we found and fixed a couple of regressions it caused to happen during the early linux-next testing (a month ago), nobody has complained. As a bonus we remove some duplicated ACPI hotplug code, because the ACPI-based CPU hotplug is now going to use the common ACPI hotplug code. - Lighter weight freezing of tasks. These changes from Colin Cross and Mandeep Singh Baines are targeted at making the freezing of tasks a bit less heavy weight operation. They reduce the number of tasks woken up every time during the freezing, by using the observation that the freezer simply doesn't need to wake up some of them and wait for them all to call refrigerator(). The time needed for the freezer to decide to report a failure is reduced too. Also reintroduced is the check causing a lockdep warining to trigger when try_to_freeze() is called with locks held (which is generally unsafe and shouldn't happen). - cpufreq updates First off, a commit from Srivatsa S Bhat fixes a resume regression introduced during the 3.10 cycle causing some cpufreq sysfs attributes to return wrong values to user space after resume. The fix is kind of fresh, but also it's pretty obvious once Srivatsa has identified the root cause. Second, we have a new freqdomain_cpus sysfs attribute for the acpi-cpufreq driver to provide information previously available via related_cpus. From Lan Tianyu. Finally, we fix a number of issues, mostly related to the CPUFREQ_POSTCHANGE notifier and cpufreq Kconfig options and clean up some code. The majority of changes from Viresh Kumar with bits from Jacob Shin, Heiko Stübner, Xiaoguang Chen, Ezequiel Garcia, Arnd Bergmann, and Tang Yuantian. - ACPICA update A usual bunch of updates from the ACPICA upstream. During the 3.4 cycle we introduced support for ACPI 5 extended sleep registers, but they are only supposed to be used if the HW-reduced mode bit is set in the FADT flags and the code attempted to use them without checking that bit. That caused suspend/resume regressions to happen on some systems. Fix from Lv Zheng causes those registers to be used only if the HW-reduced mode bit is set. Apart from this some other ACPICA bugs are fixed and code cleanups are made by Bob Moore, Tomasz Nowicki, Lv Zheng, Chao Guan, and Zhang Rui. - cpuidle updates New driver for Xilinx Zynq processors is added by Michal Simek. Multidriver support simplification, addition of some missing kerneldoc comments and Kconfig-related fixes come from Daniel Lezcano. - ACPI power management updates Changes to make suspend/resume work correctly in Xen guests from Konrad Rzeszutek Wilk, sparse warning fix from Fengguang Wu and cleanups and fixes of the ACPI device power state selection routine. - ACPI documentation updates Some previously missing pieces of ACPI documentation are added by Lv Zheng and Aaron Lu (hopefully, that will help people to uderstand how the ACPI subsystem works) and one outdated doc is updated by Hanjun Guo. - Assorted ACPI updates We finally nailed down the IA-64 issue that was the reason for reverting commit9f29ab11dd
("ACPI / scan: do not match drivers against objects having scan handlers"), so we can fix it and move the ACPI scan handler check added to the ACPI video driver back to the core. A mechanism for adding CMOS RTC address space handlers is introduced by Lan Tianyu to allow some EC-related breakage to be fixed on some systems. A spec-compliant implementation of acpi_os_get_timer() is added by Mika Westerberg. The evaluation of _STA is added to do_acpi_find_child() to avoid situations in which a pointer to a disabled device object is returned instead of an enabled one with the same _ADR value. From Jeff Wu. Intel BayTrail PCH (Platform Controller Hub) support is added to the ACPI driver for Intel Low-Power Subsystems (LPSS) and that driver is modified to work around a couple of known BIOS issues. Changes from Mika Westerberg and Heikki Krogerus. The EC driver is fixed by Vasiliy Kulikov to use get_user() and put_user() instead of dereferencing user space pointers blindly. Code cleanups are made by Bjorn Helgaas, Nicholas Mazzuca and Toshi Kani. - Assorted power management updates The "runtime idle" helper routine is changed to take the return values of the callbacks executed by it into account and to call rpm_suspend() if they return 0, which allows us to reduce the overall code bloat a bit (by dropping some code that's not necessary any more after that modification). The runtime PM documentation is updated by Alan Stern (to reflect the "runtime idle" behavior change). New trace points for PM QoS are added by Sahara (<keun-o.park@windriver.com>). PM QoS documentation is updated by Lan Tianyu. Code cleanups are made and minor issues are addressed by Bernie Thompson, Bjorn Helgaas, Julius Werner, and Shuah Khan. - devfreq updates New driver for the Exynos5-bus device from Abhilash Kesavan. Minor cleanups, fixes and MAINTAINERS update from MyungJoo Ham, Abhilash Kesavan, Paul Bolle, Rajagopal Venkat, and Wei Yongjun. - OMAP power management updates Adaptive Voltage Scaling (AVS) SmartReflex voltage control driver updates from Andrii Tseglytskyi and Nishanth Menon." * tag 'pm+acpi-3.11-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (162 commits) cpufreq: Fix cpufreq regression after suspend/resume ACPI / PM: Fix possible NULL pointer deref in acpi_pm_device_sleep_state() PM / Sleep: Warn about system time after resume with pm_trace cpufreq: don't leave stale policy pointer in cdbs->cur_policy acpi-cpufreq: Add new sysfs attribute freqdomain_cpus cpufreq: make sure frequency transitions are serialized ACPI: implement acpi_os_get_timer() according the spec ACPI / EC: Add HP Folio 13 to ec_dmi_table in order to skip DSDT scan ACPI: Add CMOS RTC Operation Region handler support ACPI / processor: Drop unused variable from processor_perflib.c cpufreq: tegra: call CPUFREQ_POSTCHANGE notfier in error cases cpufreq: s3c64xx: call CPUFREQ_POSTCHANGE notfier in error cases cpufreq: omap: call CPUFREQ_POSTCHANGE notfier in error cases cpufreq: imx6q: call CPUFREQ_POSTCHANGE notfier in error cases cpufreq: exynos: call CPUFREQ_POSTCHANGE notfier in error cases cpufreq: dbx500: call CPUFREQ_POSTCHANGE notfier in error cases cpufreq: davinci: call CPUFREQ_POSTCHANGE notfier in error cases cpufreq: arm-big-little: call CPUFREQ_POSTCHANGE notfier in error cases cpufreq: powernow-k8: call CPUFREQ_POSTCHANGE notfier in error cases cpufreq: pcc: call CPUFREQ_POSTCHANGE notfier in error cases ...
This commit is contained in:
commit
f991fae5c6
58
Documentation/ABI/testing/sysfs-bus-acpi
Normal file
58
Documentation/ABI/testing/sysfs-bus-acpi
Normal file
@ -0,0 +1,58 @@
|
||||
What: /sys/bus/acpi/devices/.../path
|
||||
Date: December 2006
|
||||
Contact: Rafael J. Wysocki <rjw@rjwysocki.net>
|
||||
Description:
|
||||
This attribute indicates the full path of ACPI namespace
|
||||
object associated with the device object. For example,
|
||||
\_SB_.PCI0.
|
||||
This file is not present for device objects representing
|
||||
fixed ACPI hardware features (like power and sleep
|
||||
buttons).
|
||||
|
||||
What: /sys/bus/acpi/devices/.../modalias
|
||||
Date: July 2007
|
||||
Contact: Rafael J. Wysocki <rjw@rjwysocki.net>
|
||||
Description:
|
||||
This attribute indicates the PNP IDs of the device object.
|
||||
That is acpi:HHHHHHHH:[CCCCCCC:]. Where each HHHHHHHH or
|
||||
CCCCCCCC contains device object's PNPID (_HID or _CID).
|
||||
|
||||
What: /sys/bus/acpi/devices/.../hid
|
||||
Date: April 2005
|
||||
Contact: Rafael J. Wysocki <rjw@rjwysocki.net>
|
||||
Description:
|
||||
This attribute indicates the hardware ID (_HID) of the
|
||||
device object. For example, PNP0103.
|
||||
This file is present for device objects having the _HID
|
||||
control method.
|
||||
|
||||
What: /sys/bus/acpi/devices/.../description
|
||||
Date: October 2012
|
||||
Contact: Rafael J. Wysocki <rjw@rjwysocki.net>
|
||||
Description:
|
||||
This attribute contains the output of the device object's
|
||||
_STR control method, if present.
|
||||
|
||||
What: /sys/bus/acpi/devices/.../adr
|
||||
Date: October 2012
|
||||
Contact: Rafael J. Wysocki <rjw@rjwysocki.net>
|
||||
Description:
|
||||
This attribute contains the output of the device object's
|
||||
_ADR control method, which is present for ACPI device
|
||||
objects representing devices having standard enumeration
|
||||
algorithms, such as PCI.
|
||||
|
||||
What: /sys/bus/acpi/devices/.../uid
|
||||
Date: October 2012
|
||||
Contact: Rafael J. Wysocki <rjw@rjwysocki.net>
|
||||
Description:
|
||||
This attribute contains the output of the device object's
|
||||
_UID control method, if present.
|
||||
|
||||
What: /sys/bus/acpi/devices/.../eject
|
||||
Date: December 2006
|
||||
Contact: Rafael J. Wysocki <rjw@rjwysocki.net>
|
||||
Description:
|
||||
Writing 1 to this attribute will trigger hot removal of
|
||||
this device object. This file exists for every device
|
||||
object that has _EJ0 method.
|
@ -78,3 +78,23 @@ Contact: Nishanth Menon <nm@ti.com>
|
||||
Description:
|
||||
The /sys/class/devfreq/.../available_governors shows
|
||||
currently available governors in the system.
|
||||
|
||||
What: /sys/class/devfreq/.../min_freq
|
||||
Date: January 2013
|
||||
Contact: MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||
Description:
|
||||
The /sys/class/devfreq/.../min_freq shows and stores
|
||||
the minimum frequency requested by users. It is 0 if
|
||||
the user does not care. min_freq overrides the
|
||||
frequency requested by governors.
|
||||
|
||||
What: /sys/class/devfreq/.../max_freq
|
||||
Date: January 2013
|
||||
Contact: MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||
Description:
|
||||
The /sys/class/devfreq/.../max_freq shows and stores
|
||||
the maximum frequency requested by users. It is 0 if
|
||||
the user does not care. max_freq overrides the
|
||||
frequency requested by governors and min_freq.
|
||||
The max_freq overrides min_freq because max_freq may be
|
||||
used to throttle devices to avoid overheating.
|
||||
|
20
Documentation/ABI/testing/sysfs-devices-online
Normal file
20
Documentation/ABI/testing/sysfs-devices-online
Normal file
@ -0,0 +1,20 @@
|
||||
What: /sys/devices/.../online
|
||||
Date: April 2013
|
||||
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Description:
|
||||
The /sys/devices/.../online attribute is only present for
|
||||
devices whose bus types provide .online() and .offline()
|
||||
callbacks. The number read from it (0 or 1) reflects the value
|
||||
of the device's 'offline' field. If that number is 1 and '0'
|
||||
(or 'n', or 'N') is written to this file, the device bus type's
|
||||
.offline() callback is executed for the device and (if
|
||||
successful) its 'offline' field is updated accordingly. In
|
||||
turn, if that number is 0 and '1' (or 'y', or 'Y') is written to
|
||||
this file, the device bus type's .online() callback is executed
|
||||
for the device and (if successful) its 'offline' field is
|
||||
updated as appropriate.
|
||||
|
||||
After a successful execution of the bus type's .offline()
|
||||
callback the device cannot be used for any purpose until either
|
||||
it is removed (i.e. device_del() is called for it), or its bus
|
||||
type's .online() is exeucted successfully.
|
@ -1,4 +1,4 @@
|
||||
Whatt: /sys/devices/.../sun
|
||||
What: /sys/devices/.../sun
|
||||
Date: October 2012
|
||||
Contact: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
|
||||
Description:
|
||||
|
@ -144,6 +144,21 @@ Description: Discover and change clock speed of CPUs
|
||||
to learn how to control the knobs.
|
||||
|
||||
|
||||
What: /sys/devices/system/cpu/cpu#/cpufreq/freqdomain_cpus
|
||||
Date: June 2013
|
||||
Contact: cpufreq@vger.kernel.org
|
||||
Description: Discover CPUs in the same CPU frequency coordination domain
|
||||
|
||||
freqdomain_cpus is the list of CPUs (online+offline) that share
|
||||
the same clock/freq domain (possibly at the hardware level).
|
||||
That information may be hidden from the cpufreq core and the
|
||||
value of related_cpus may be different from freqdomain_cpus. This
|
||||
attribute is useful for user space DVFS controllers to get better
|
||||
power/performance results for platforms using acpi-cpufreq.
|
||||
|
||||
This file is only present if the acpi-cpufreq driver is in use.
|
||||
|
||||
|
||||
What: /sys/devices/system/cpu/cpu*/cache/index3/cache_disable_{0,1}
|
||||
Date: August 2008
|
||||
KernelVersion: 2.6.27
|
||||
|
@ -44,6 +44,16 @@ Description:
|
||||
or 0 (unset). Attempts to write any other values to it will
|
||||
cause -EINVAL to be returned.
|
||||
|
||||
What: /sys/firmware/acpi/hotplug/force_remove
|
||||
Date: May 2013
|
||||
Contact: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
Description:
|
||||
The number in this file (0 or 1) determines whether (1) or not
|
||||
(0) the ACPI subsystem will allow devices to be hot-removed even
|
||||
if they cannot be put offline gracefully (from the kernel's
|
||||
viewpoint). That number can be changed by writing a boolean
|
||||
value to this file.
|
||||
|
||||
What: /sys/firmware/acpi/interrupts/
|
||||
Date: February 2008
|
||||
Contact: Len Brown <lenb@kernel.org>
|
||||
|
395
Documentation/acpi/namespace.txt
Normal file
395
Documentation/acpi/namespace.txt
Normal file
@ -0,0 +1,395 @@
|
||||
ACPI Device Tree - Representation of ACPI Namespace
|
||||
|
||||
Copyright (C) 2013, Intel Corporation
|
||||
Author: Lv Zheng <lv.zheng@intel.com>
|
||||
|
||||
|
||||
Abstract:
|
||||
|
||||
The Linux ACPI subsystem converts ACPI namespace objects into a Linux
|
||||
device tree under the /sys/devices/LNXSYSTEM:00 and updates it upon
|
||||
receiving ACPI hotplug notification events. For each device object in this
|
||||
hierarchy there is a corresponding symbolic link in the
|
||||
/sys/bus/acpi/devices.
|
||||
This document illustrates the structure of the ACPI device tree.
|
||||
|
||||
|
||||
Credit:
|
||||
|
||||
Thanks for the help from Zhang Rui <rui.zhang@intel.com> and Rafael J.
|
||||
Wysocki <rafael.j.wysocki@intel.com>.
|
||||
|
||||
|
||||
1. ACPI Definition Blocks
|
||||
|
||||
The ACPI firmware sets up RSDP (Root System Description Pointer) in the
|
||||
system memory address space pointing to the XSDT (Extended System
|
||||
Description Table). The XSDT always points to the FADT (Fixed ACPI
|
||||
Description Table) using its first entry, the data within the FADT
|
||||
includes various fixed-length entries that describe fixed ACPI features
|
||||
of the hardware. The FADT contains a pointer to the DSDT
|
||||
(Differentiated System Descripition Table). The XSDT also contains
|
||||
entries pointing to possibly multiple SSDTs (Secondary System
|
||||
Description Table).
|
||||
|
||||
The DSDT and SSDT data is organized in data structures called definition
|
||||
blocks that contain definitions of various objects, including ACPI
|
||||
control methods, encoded in AML (ACPI Machine Language). The data block
|
||||
of the DSDT along with the contents of SSDTs represents a hierarchical
|
||||
data structure called the ACPI namespace whose topology reflects the
|
||||
structure of the underlying hardware platform.
|
||||
|
||||
The relationships between ACPI System Definition Tables described above
|
||||
are illustrated in the following diagram.
|
||||
|
||||
+---------+ +-------+ +--------+ +------------------------+
|
||||
| RSDP | +->| XSDT | +->| FADT | | +-------------------+ |
|
||||
+---------+ | +-------+ | +--------+ +-|->| DSDT | |
|
||||
| Pointer | | | Entry |-+ | ...... | | | +-------------------+ |
|
||||
+---------+ | +-------+ | X_DSDT |--+ | | Definition Blocks | |
|
||||
| Pointer |-+ | ..... | | ...... | | +-------------------+ |
|
||||
+---------+ +-------+ +--------+ | +-------------------+ |
|
||||
| Entry |------------------|->| SSDT | |
|
||||
+- - - -+ | +-------------------| |
|
||||
| Entry | - - - - - - - -+ | | Definition Blocks | |
|
||||
+- - - -+ | | +-------------------+ |
|
||||
| | +- - - - - - - - - -+ |
|
||||
+-|->| SSDT | |
|
||||
| +-------------------+ |
|
||||
| | Definition Blocks | |
|
||||
| +- - - - - - - - - -+ |
|
||||
+------------------------+
|
||||
|
|
||||
OSPM Loading |
|
||||
\|/
|
||||
+----------------+
|
||||
| ACPI Namespace |
|
||||
+----------------+
|
||||
|
||||
Figure 1. ACPI Definition Blocks
|
||||
|
||||
NOTE: RSDP can also contain a pointer to the RSDT (Root System
|
||||
Description Table). Platforms provide RSDT to enable
|
||||
compatibility with ACPI 1.0 operating systems. The OS is expected
|
||||
to use XSDT, if present.
|
||||
|
||||
|
||||
2. Example ACPI Namespace
|
||||
|
||||
All definition blocks are loaded into a single namespace. The namespace
|
||||
is a hierarchy of objects identified by names and paths.
|
||||
The following naming conventions apply to object names in the ACPI
|
||||
namespace:
|
||||
1. All names are 32 bits long.
|
||||
2. The first byte of a name must be one of 'A' - 'Z', '_'.
|
||||
3. Each of the remaining bytes of a name must be one of 'A' - 'Z', '0'
|
||||
- '9', '_'.
|
||||
4. Names starting with '_' are reserved by the ACPI specification.
|
||||
5. The '\' symbol represents the root of the namespace (i.e. names
|
||||
prepended with '\' are relative to the namespace root).
|
||||
6. The '^' symbol represents the parent of the current namespace node
|
||||
(i.e. names prepended with '^' are relative to the parent of the
|
||||
current namespace node).
|
||||
|
||||
The figure below shows an example ACPI namespace.
|
||||
|
||||
+------+
|
||||
| \ | Root
|
||||
+------+
|
||||
|
|
||||
| +------+
|
||||
+-| _PR | Scope(_PR): the processor namespace
|
||||
| +------+
|
||||
| |
|
||||
| | +------+
|
||||
| +-| CPU0 | Processor(CPU0): the first processor
|
||||
| +------+
|
||||
|
|
||||
| +------+
|
||||
+-| _SB | Scope(_SB): the system bus namespace
|
||||
| +------+
|
||||
| |
|
||||
| | +------+
|
||||
| +-| LID0 | Device(LID0); the lid device
|
||||
| | +------+
|
||||
| | |
|
||||
| | | +------+
|
||||
| | +-| _HID | Name(_HID, "PNP0C0D"): the hardware ID
|
||||
| | | +------+
|
||||
| | |
|
||||
| | | +------+
|
||||
| | +-| _STA | Method(_STA): the status control method
|
||||
| | +------+
|
||||
| |
|
||||
| | +------+
|
||||
| +-| PCI0 | Device(PCI0); the PCI root bridge
|
||||
| +------+
|
||||
| |
|
||||
| | +------+
|
||||
| +-| _HID | Name(_HID, "PNP0A08"): the hardware ID
|
||||
| | +------+
|
||||
| |
|
||||
| | +------+
|
||||
| +-| _CID | Name(_CID, "PNP0A03"): the compatible ID
|
||||
| | +------+
|
||||
| |
|
||||
| | +------+
|
||||
| +-| RP03 | Scope(RP03): the PCI0 power scope
|
||||
| | +------+
|
||||
| | |
|
||||
| | | +------+
|
||||
| | +-| PXP3 | PowerResource(PXP3): the PCI0 power resource
|
||||
| | +------+
|
||||
| |
|
||||
| | +------+
|
||||
| +-| GFX0 | Device(GFX0): the graphics adapter
|
||||
| +------+
|
||||
| |
|
||||
| | +------+
|
||||
| +-| _ADR | Name(_ADR, 0x00020000): the PCI bus address
|
||||
| | +------+
|
||||
| |
|
||||
| | +------+
|
||||
| +-| DD01 | Device(DD01): the LCD output device
|
||||
| +------+
|
||||
| |
|
||||
| | +------+
|
||||
| +-| _BCL | Method(_BCL): the backlight control method
|
||||
| +------+
|
||||
|
|
||||
| +------+
|
||||
+-| _TZ | Scope(_TZ): the thermal zone namespace
|
||||
| +------+
|
||||
| |
|
||||
| | +------+
|
||||
| +-| FN00 | PowerResource(FN00): the FAN0 power resource
|
||||
| | +------+
|
||||
| |
|
||||
| | +------+
|
||||
| +-| FAN0 | Device(FAN0): the FAN0 cooling device
|
||||
| | +------+
|
||||
| | |
|
||||
| | | +------+
|
||||
| | +-| _HID | Name(_HID, "PNP0A0B"): the hardware ID
|
||||
| | +------+
|
||||
| |
|
||||
| | +------+
|
||||
| +-| TZ00 | ThermalZone(TZ00); the FAN thermal zone
|
||||
| +------+
|
||||
|
|
||||
| +------+
|
||||
+-| _GPE | Scope(_GPE): the GPE namespace
|
||||
+------+
|
||||
|
||||
Figure 2. Example ACPI Namespace
|
||||
|
||||
|
||||
3. Linux ACPI Device Objects
|
||||
|
||||
The Linux kernel's core ACPI subsystem creates struct acpi_device
|
||||
objects for ACPI namespace objects representing devices, power resources
|
||||
processors, thermal zones. Those objects are exported to user space via
|
||||
sysfs as directories in the subtree under /sys/devices/LNXSYSTM:00. The
|
||||
format of their names is <bus_id:instance>, where 'bus_id' refers to the
|
||||
ACPI namespace representation of the given object and 'instance' is used
|
||||
for distinguishing different object of the same 'bus_id' (it is
|
||||
two-digit decimal representation of an unsigned integer).
|
||||
|
||||
The value of 'bus_id' depends on the type of the object whose name it is
|
||||
part of as listed in the table below.
|
||||
|
||||
+---+-----------------+-------+----------+
|
||||
| | Object/Feature | Table | bus_id |
|
||||
+---+-----------------+-------+----------+
|
||||
| N | Root | xSDT | LNXSYSTM |
|
||||
+---+-----------------+-------+----------+
|
||||
| N | Device | xSDT | _HID |
|
||||
+---+-----------------+-------+----------+
|
||||
| N | Processor | xSDT | LNXCPU |
|
||||
+---+-----------------+-------+----------+
|
||||
| N | ThermalZone | xSDT | LNXTHERM |
|
||||
+---+-----------------+-------+----------+
|
||||
| N | PowerResource | xSDT | LNXPOWER |
|
||||
+---+-----------------+-------+----------+
|
||||
| N | Other Devices | xSDT | device |
|
||||
+---+-----------------+-------+----------+
|
||||
| F | PWR_BUTTON | FADT | LNXPWRBN |
|
||||
+---+-----------------+-------+----------+
|
||||
| F | SLP_BUTTON | FADT | LNXSLPBN |
|
||||
+---+-----------------+-------+----------+
|
||||
| M | Video Extension | xSDT | LNXVIDEO |
|
||||
+---+-----------------+-------+----------+
|
||||
| M | ATA Controller | xSDT | LNXIOBAY |
|
||||
+---+-----------------+-------+----------+
|
||||
| M | Docking Station | xSDT | LNXDOCK |
|
||||
+---+-----------------+-------+----------+
|
||||
|
||||
Table 1. ACPI Namespace Objects Mapping
|
||||
|
||||
The following rules apply when creating struct acpi_device objects on
|
||||
the basis of the contents of ACPI System Description Tables (as
|
||||
indicated by the letter in the first column and the notation in the
|
||||
second column of the table above):
|
||||
N:
|
||||
The object's source is an ACPI namespace node (as indicated by the
|
||||
named object's type in the second column). In that case the object's
|
||||
directory in sysfs will contain the 'path' attribute whose value is
|
||||
the full path to the node from the namespace root.
|
||||
struct acpi_device objects are created for the ACPI namespace nodes
|
||||
whose _STA control methods return PRESENT or FUNCTIONING. The power
|
||||
resource nodes or nodes without _STA are assumed to be both PRESENT
|
||||
and FUNCTIONING.
|
||||
F:
|
||||
The struct acpi_device object is created for a fixed hardware
|
||||
feature (as indicated by the fixed feature flag's name in the second
|
||||
column), so its sysfs directory will not contain the 'path'
|
||||
attribute.
|
||||
M:
|
||||
The struct acpi_device object is created for an ACPI namespace node
|
||||
with specific control methods (as indicated by the ACPI defined
|
||||
device's type in the second column). The 'path' attribute containing
|
||||
its namespace path will be present in its sysfs directory. For
|
||||
example, if the _BCL method is present for an ACPI namespace node, a
|
||||
struct acpi_device object with LNXVIDEO 'bus_id' will be created for
|
||||
it.
|
||||
|
||||
The third column of the above table indicates which ACPI System
|
||||
Description Tables contain information used for the creation of the
|
||||
struct acpi_device objects represented by the given row (xSDT means DSDT
|
||||
or SSDT).
|
||||
|
||||
The forth column of the above table indicates the 'bus_id' generation
|
||||
rule of the struct acpi_device object:
|
||||
_HID:
|
||||
_HID in the last column of the table means that the object's bus_id
|
||||
is derived from the _HID/_CID identification objects present under
|
||||
the corresponding ACPI namespace node. The object's sysfs directory
|
||||
will then contain the 'hid' and 'modalias' attributes that can be
|
||||
used to retrieve the _HID and _CIDs of that object.
|
||||
LNXxxxxx:
|
||||
The 'modalias' attribute is also present for struct acpi_device
|
||||
objects having bus_id of the "LNXxxxxx" form (pseudo devices), in
|
||||
which cases it contains the bus_id string itself.
|
||||
device:
|
||||
'device' in the last column of the table indicates that the object's
|
||||
bus_id cannot be determined from _HID/_CID of the corresponding
|
||||
ACPI namespace node, although that object represents a device (for
|
||||
example, it may be a PCI device with _ADR defined and without _HID
|
||||
or _CID). In that case the string 'device' will be used as the
|
||||
object's bus_id.
|
||||
|
||||
|
||||
4. Linux ACPI Physical Device Glue
|
||||
|
||||
ACPI device (i.e. struct acpi_device) objects may be linked to other
|
||||
objects in the Linux' device hierarchy that represent "physical" devices
|
||||
(for example, devices on the PCI bus). If that happens, it means that
|
||||
the ACPI device object is a "companion" of a device otherwise
|
||||
represented in a different way and is used (1) to provide configuration
|
||||
information on that device which cannot be obtained by other means and
|
||||
(2) to do specific things to the device with the help of its ACPI
|
||||
control methods. One ACPI device object may be linked this way to
|
||||
multiple "physical" devices.
|
||||
|
||||
If an ACPI device object is linked to a "physical" device, its sysfs
|
||||
directory contains the "physical_node" symbolic link to the sysfs
|
||||
directory of the target device object. In turn, the target device's
|
||||
sysfs directory will then contain the "firmware_node" symbolic link to
|
||||
the sysfs directory of the companion ACPI device object.
|
||||
The linking mechanism relies on device identification provided by the
|
||||
ACPI namespace. For example, if there's an ACPI namespace object
|
||||
representing a PCI device (i.e. a device object under an ACPI namespace
|
||||
object representing a PCI bridge) whose _ADR returns 0x00020000 and the
|
||||
bus number of the parent PCI bridge is 0, the sysfs directory
|
||||
representing the struct acpi_device object created for that ACPI
|
||||
namespace object will contain the 'physical_node' symbolic link to the
|
||||
/sys/devices/pci0000:00/0000:00:02:0/ sysfs directory of the
|
||||
corresponding PCI device.
|
||||
|
||||
The linking mechanism is generally bus-specific. The core of its
|
||||
implementation is located in the drivers/acpi/glue.c file, but there are
|
||||
complementary parts depending on the bus types in question located
|
||||
elsewhere. For example, the PCI-specific part of it is located in
|
||||
drivers/pci/pci-acpi.c.
|
||||
|
||||
|
||||
5. Example Linux ACPI Device Tree
|
||||
|
||||
The sysfs hierarchy of struct acpi_device objects corresponding to the
|
||||
example ACPI namespace illustrated in Figure 2 with the addition of
|
||||
fixed PWR_BUTTON/SLP_BUTTON devices is shown below.
|
||||
|
||||
+--------------+---+-----------------+
|
||||
| LNXSYSTEM:00 | \ | acpi:LNXSYSTEM: |
|
||||
+--------------+---+-----------------+
|
||||
|
|
||||
| +-------------+-----+----------------+
|
||||
+-| LNXPWRBN:00 | N/A | acpi:LNXPWRBN: |
|
||||
| +-------------+-----+----------------+
|
||||
|
|
||||
| +-------------+-----+----------------+
|
||||
+-| LNXSLPBN:00 | N/A | acpi:LNXSLPBN: |
|
||||
| +-------------+-----+----------------+
|
||||
|
|
||||
| +-----------+------------+--------------+
|
||||
+-| LNXCPU:00 | \_PR_.CPU0 | acpi:LNXCPU: |
|
||||
| +-----------+------------+--------------+
|
||||
|
|
||||
| +-------------+-------+----------------+
|
||||
+-| LNXSYBUS:00 | \_SB_ | acpi:LNXSYBUS: |
|
||||
| +-------------+-------+----------------+
|
||||
| |
|
||||
| | +- - - - - - - +- - - - - - +- - - - - - - -+
|
||||
| +-| * PNP0C0D:00 | \_SB_.LID0 | acpi:PNP0C0D: |
|
||||
| | +- - - - - - - +- - - - - - +- - - - - - - -+
|
||||
| |
|
||||
| | +------------+------------+-----------------------+
|
||||
| +-| PNP0A08:00 | \_SB_.PCI0 | acpi:PNP0A08:PNP0A03: |
|
||||
| +------------+------------+-----------------------+
|
||||
| |
|
||||
| | +-----------+-----------------+-----+
|
||||
| +-| device:00 | \_SB_.PCI0.RP03 | N/A |
|
||||
| | +-----------+-----------------+-----+
|
||||
| | |
|
||||
| | | +-------------+----------------------+----------------+
|
||||
| | +-| LNXPOWER:00 | \_SB_.PCI0.RP03.PXP3 | acpi:LNXPOWER: |
|
||||
| | +-------------+----------------------+----------------+
|
||||
| |
|
||||
| | +-------------+-----------------+----------------+
|
||||
| +-| LNXVIDEO:00 | \_SB_.PCI0.GFX0 | acpi:LNXVIDEO: |
|
||||
| +-------------+-----------------+----------------+
|
||||
| |
|
||||
| | +-----------+-----------------+-----+
|
||||
| +-| device:01 | \_SB_.PCI0.DD01 | N/A |
|
||||
| +-----------+-----------------+-----+
|
||||
|
|
||||
| +-------------+-------+----------------+
|
||||
+-| LNXSYBUS:01 | \_TZ_ | acpi:LNXSYBUS: |
|
||||
+-------------+-------+----------------+
|
||||
|
|
||||
| +-------------+------------+----------------+
|
||||
+-| LNXPOWER:0a | \_TZ_.FN00 | acpi:LNXPOWER: |
|
||||
| +-------------+------------+----------------+
|
||||
|
|
||||
| +------------+------------+---------------+
|
||||
+-| PNP0C0B:00 | \_TZ_.FAN0 | acpi:PNP0C0B: |
|
||||
| +------------+------------+---------------+
|
||||
|
|
||||
| +-------------+------------+----------------+
|
||||
+-| LNXTHERM:00 | \_TZ_.TZ00 | acpi:LNXTHERM: |
|
||||
+-------------+------------+----------------+
|
||||
|
||||
Figure 3. Example Linux ACPI Device Tree
|
||||
|
||||
NOTE: Each node is represented as "object/path/modalias", where:
|
||||
1. 'object' is the name of the object's directory in sysfs.
|
||||
2. 'path' is the ACPI namespace path of the corresponding
|
||||
ACPI namespace object, as returned by the object's 'path'
|
||||
sysfs attribute.
|
||||
3. 'modalias' is the value of the object's 'modalias' sysfs
|
||||
attribute (as described earlier in this document).
|
||||
NOTE: N/A indicates the device object does not have the 'path' or the
|
||||
'modalias' attribute.
|
||||
NOTE: The PNP0C0D device listed above is highlighted (marked by "*")
|
||||
to indicate it will be created only when its _STA methods return
|
||||
PRESENT or FUNCTIONING.
|
106
Documentation/acpi/video_extension.txt
Normal file
106
Documentation/acpi/video_extension.txt
Normal file
@ -0,0 +1,106 @@
|
||||
ACPI video extensions
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This driver implement the ACPI Extensions For Display Adapters for
|
||||
integrated graphics devices on motherboard, as specified in ACPI 2.0
|
||||
Specification, Appendix B, allowing to perform some basic control like
|
||||
defining the video POST device, retrieving EDID information or to
|
||||
setup a video output, etc. Note that this is an ref. implementation
|
||||
only. It may or may not work for your integrated video device.
|
||||
|
||||
The ACPI video driver does 3 things regarding backlight control:
|
||||
|
||||
1 Export a sysfs interface for user space to control backlight level
|
||||
|
||||
If the ACPI table has a video device, and acpi_backlight=vendor kernel
|
||||
command line is not present, the driver will register a backlight device
|
||||
and set the required backlight operation structure for it for the sysfs
|
||||
interface control. For every registered class device, there will be a
|
||||
directory named acpi_videoX under /sys/class/backlight.
|
||||
|
||||
The backlight sysfs interface has a standard definition here:
|
||||
Documentation/ABI/stable/sysfs-class-backlight.
|
||||
|
||||
And what ACPI video driver does is:
|
||||
actual_brightness: on read, control method _BQC will be evaluated to
|
||||
get the brightness level the firmware thinks it is at;
|
||||
bl_power: not implemented, will set the current brightness instead;
|
||||
brightness: on write, control method _BCM will run to set the requested
|
||||
brightness level;
|
||||
max_brightness: Derived from the _BCL package(see below);
|
||||
type: firmware
|
||||
|
||||
Note that ACPI video backlight driver will always use index for
|
||||
brightness, actual_brightness and max_brightness. So if we have
|
||||
the following _BCL package:
|
||||
|
||||
Method (_BCL, 0, NotSerialized)
|
||||
{
|
||||
Return (Package (0x0C)
|
||||
{
|
||||
0x64,
|
||||
0x32,
|
||||
0x0A,
|
||||
0x14,
|
||||
0x1E,
|
||||
0x28,
|
||||
0x32,
|
||||
0x3C,
|
||||
0x46,
|
||||
0x50,
|
||||
0x5A,
|
||||
0x64
|
||||
})
|
||||
}
|
||||
|
||||
The first two levels are for when laptop are on AC or on battery and are
|
||||
not used by Linux currently. The remaining 10 levels are supported levels
|
||||
that we can choose from. The applicable index values are from 0 (that
|
||||
corresponds to the 0x0A brightness value) to 9 (that corresponds to the
|
||||
0x64 brightness value) inclusive. Each of those index values is regarded
|
||||
as a "brightness level" indicator. Thus from the user space perspective
|
||||
the range of available brightness levels is from 0 to 9 (max_brightness)
|
||||
inclusive.
|
||||
|
||||
2 Notify user space about hotkey event
|
||||
|
||||
There are generally two cases for hotkey event reporting:
|
||||
i) For some laptops, when user presses the hotkey, a scancode will be
|
||||
generated and sent to user space through the input device created by
|
||||
the keyboard driver as a key type input event, with proper remap, the
|
||||
following key code will appear to user space:
|
||||
|
||||
EV_KEY, KEY_BRIGHTNESSUP
|
||||
EV_KEY, KEY_BRIGHTNESSDOWN
|
||||
etc.
|
||||
|
||||
For this case, ACPI video driver does not need to do anything(actually,
|
||||
it doesn't even know this happened).
|
||||
|
||||
ii) For some laptops, the press of the hotkey will not generate the
|
||||
scancode, instead, firmware will notify the video device ACPI node
|
||||
about the event. The event value is defined in the ACPI spec. ACPI
|
||||
video driver will generate an key type input event according to the
|
||||
notify value it received and send the event to user space through the
|
||||
input device it created:
|
||||
|
||||
event keycode
|
||||
0x86 KEY_BRIGHTNESSUP
|
||||
0x87 KEY_BRIGHTNESSDOWN
|
||||
etc.
|
||||
|
||||
so this would lead to the same effect as case i) now.
|
||||
|
||||
Once user space tool receives this event, it can modify the backlight
|
||||
level through the sysfs interface.
|
||||
|
||||
3 Change backlight level in the kernel
|
||||
|
||||
This works for machines covered by case ii) in Section 2. Once the driver
|
||||
received a notification, it will set the backlight level accordingly. This does
|
||||
not affect the sending of event to user space, they are always sent to user
|
||||
space regardless of whether or not the video module controls the backlight level
|
||||
directly. This behaviour can be controlled through the brightness_switch_enabled
|
||||
module parameter as documented in kernel-parameters.txt. It is recommended to
|
||||
disable this behaviour once a GUI environment starts up and wants to have full
|
||||
control of the backlight level.
|
@ -186,7 +186,7 @@ As most cpufreq processors only allow for being set to a few specific
|
||||
frequencies, a "frequency table" with some functions might assist in
|
||||
some work of the processor driver. Such a "frequency table" consists
|
||||
of an array of struct cpufreq_frequency_table entries, with any value in
|
||||
"index" you want to use, and the corresponding frequency in
|
||||
"driver_data" you want to use, and the corresponding frequency in
|
||||
"frequency". At the end of the table, you need to add a
|
||||
cpufreq_frequency_table entry with frequency set to CPUFREQ_TABLE_END. And
|
||||
if you want to skip one entry in the table, set the frequency to
|
||||
@ -214,10 +214,4 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
|
||||
is the corresponding frequency table helper for the ->target
|
||||
stage. Just pass the values to this function, and the unsigned int
|
||||
index returns the number of the frequency table entry which contains
|
||||
the frequency the CPU shall be set to. PLEASE NOTE: This is not the
|
||||
"index" which is in this cpufreq_table_entry.index, but instead
|
||||
cpufreq_table[index]. So, the new frequency is
|
||||
cpufreq_table[index].frequency, and the value you stored into the
|
||||
frequency table "index" field is
|
||||
cpufreq_table[index].index.
|
||||
|
||||
the frequency the CPU shall be set to.
|
||||
|
@ -370,8 +370,10 @@ A: There is no clear spec defined way from ACPI that can give us that
|
||||
CPUs in MADT as hotpluggable CPUS. In the case there are no disabled CPUS
|
||||
we assume 1/2 the number of CPUs currently present can be hotplugged.
|
||||
|
||||
Caveat: Today's ACPI MADT can only provide 256 entries since the apicid field
|
||||
in MADT is only 8 bits.
|
||||
Caveat: ACPI MADT can only provide 256 entries in systems with only ACPI 2.0c
|
||||
or earlier ACPI version supported, because the apicid field in MADT is only
|
||||
8 bits. From ACPI 3.0, this limitation was removed since the apicid field
|
||||
was extended to 32 bits with x2APIC introduced.
|
||||
|
||||
User Space Notification
|
||||
|
||||
|
@ -3231,6 +3231,15 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
||||
video= [FB] Frame buffer configuration
|
||||
See Documentation/fb/modedb.txt.
|
||||
|
||||
video.brightness_switch_enabled= [0,1]
|
||||
If set to 1, on receiving an ACPI notify event
|
||||
generated by hotkey, video driver will adjust brightness
|
||||
level and then send out the event to user space through
|
||||
the allocated input device; If set to 0, video driver
|
||||
will only send out the event without touching backlight
|
||||
brightness level.
|
||||
default: 1
|
||||
|
||||
virtio_mmio.device=
|
||||
[VMMIO] Memory mapped virtio (platform) device.
|
||||
|
||||
|
@ -7,7 +7,7 @@ one of the parameters.
|
||||
Two different PM QoS frameworks are available:
|
||||
1. PM QoS classes for cpu_dma_latency, network_latency, network_throughput.
|
||||
2. the per-device PM QoS framework provides the API to manage the per-device latency
|
||||
constraints.
|
||||
constraints and PM QoS flags.
|
||||
|
||||
Each parameters have defined units:
|
||||
* latency: usec
|
||||
@ -86,13 +86,17 @@ To remove the user mode request for a target value simply close the device
|
||||
node.
|
||||
|
||||
|
||||
2. PM QoS per-device latency framework
|
||||
2. PM QoS per-device latency and flags framework
|
||||
|
||||
For each device, there are two lists of PM QoS requests. One is maintained
|
||||
along with the aggregated target of latency value and the other is for PM QoS
|
||||
flags. Values are updated in response to changes of the request list.
|
||||
|
||||
Target latency value is simply the minimum of the request values held in the
|
||||
parameter list elements. The PM QoS flags aggregate value is a gather (bitwise
|
||||
OR) of all list elements' values. Two device PM QoS flags are defined currently:
|
||||
PM_QOS_FLAG_NO_POWER_OFF and PM_QOS_FLAG_REMOTE_WAKEUP.
|
||||
|
||||
For each device a list of performance requests is maintained along with
|
||||
an aggregated target value. The aggregated target value is updated with
|
||||
changes to the request list or elements of the list. Typically the
|
||||
aggregated target value is simply the max or min of the request values held
|
||||
in the parameter list elements.
|
||||
Note: the aggregated target value is implemented as an atomic variable so that
|
||||
reading the aggregated value does not require any locking mechanism.
|
||||
|
||||
@ -119,6 +123,38 @@ the request.
|
||||
s32 dev_pm_qos_read_value(device):
|
||||
Returns the aggregated value for a given device's constraints list.
|
||||
|
||||
enum pm_qos_flags_status dev_pm_qos_flags(device, mask)
|
||||
Check PM QoS flags of the given device against the given mask of flags.
|
||||
The meaning of the return values is as follows:
|
||||
PM_QOS_FLAGS_ALL: All flags from the mask are set
|
||||
PM_QOS_FLAGS_SOME: Some flags from the mask are set
|
||||
PM_QOS_FLAGS_NONE: No flags from the mask are set
|
||||
PM_QOS_FLAGS_UNDEFINED: The device's PM QoS structure has not been
|
||||
initialized or the list of requests is empty.
|
||||
|
||||
int dev_pm_qos_add_ancestor_request(dev, handle, value)
|
||||
Add a PM QoS request for the first direct ancestor of the given device whose
|
||||
power.ignore_children flag is unset.
|
||||
|
||||
int dev_pm_qos_expose_latency_limit(device, value)
|
||||
Add a request to the device's PM QoS list of latency constraints and create
|
||||
a sysfs attribute pm_qos_resume_latency_us under the device's power directory
|
||||
allowing user space to manipulate that request.
|
||||
|
||||
void dev_pm_qos_hide_latency_limit(device)
|
||||
Drop the request added by dev_pm_qos_expose_latency_limit() from the device's
|
||||
PM QoS list of latency constraints and remove sysfs attribute pm_qos_resume_latency_us
|
||||
from the device's power directory.
|
||||
|
||||
int dev_pm_qos_expose_flags(device, value)
|
||||
Add a request to the device's PM QoS list of flags and create sysfs attributes
|
||||
pm_qos_no_power_off and pm_qos_remote_wakeup under the device's power directory
|
||||
allowing user space to change these flags' value.
|
||||
|
||||
void dev_pm_qos_hide_flags(device)
|
||||
Drop the request added by dev_pm_qos_expose_flags() from the device's PM QoS list
|
||||
of flags and remove sysfs attributes pm_qos_no_power_off and pm_qos_remote_wakeup
|
||||
under the device's power directory.
|
||||
|
||||
Notification mechanisms:
|
||||
The per-device PM QoS framework has 2 different and distinct notification trees:
|
||||
|
@ -144,8 +144,12 @@ The action performed by the idle callback is totally dependent on the subsystem
|
||||
(or driver) in question, but the expected and recommended action is to check
|
||||
if the device can be suspended (i.e. if all of the conditions necessary for
|
||||
suspending the device are satisfied) and to queue up a suspend request for the
|
||||
device in that case. The value returned by this callback is ignored by the PM
|
||||
core.
|
||||
device in that case. If there is no idle callback, or if the callback returns
|
||||
0, then the PM core will attempt to carry out a runtime suspend of the device;
|
||||
in essence, it will call pm_runtime_suspend() directly. To prevent this (for
|
||||
example, if the callback routine has started a delayed suspend), the routine
|
||||
should return a non-zero value. Negative error return codes are ignored by the
|
||||
PM core.
|
||||
|
||||
The helper functions provided by the PM core, described in Section 4, guarantee
|
||||
that the following constraints are met with respect to runtime PM callbacks for
|
||||
@ -301,9 +305,10 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
|
||||
removing the device from device hierarchy
|
||||
|
||||
int pm_runtime_idle(struct device *dev);
|
||||
- execute the subsystem-level idle callback for the device; returns 0 on
|
||||
success or error code on failure, where -EINPROGRESS means that
|
||||
->runtime_idle() is already being executed
|
||||
- execute the subsystem-level idle callback for the device; returns an
|
||||
error code on failure, where -EINPROGRESS means that ->runtime_idle() is
|
||||
already being executed; if there is no callback or the callback returns 0
|
||||
then run pm_runtime_suspend(dev) and return its result
|
||||
|
||||
int pm_runtime_suspend(struct device *dev);
|
||||
- execute the subsystem-level suspend callback for the device; returns 0 on
|
||||
@ -660,11 +665,6 @@ Subsystems may wish to conserve code space by using the set of generic power
|
||||
management callbacks provided by the PM core, defined in
|
||||
driver/base/power/generic_ops.c:
|
||||
|
||||
int pm_generic_runtime_idle(struct device *dev);
|
||||
- invoke the ->runtime_idle() callback provided by the driver of this
|
||||
device, if defined, and call pm_runtime_suspend() for this device if the
|
||||
return value is 0 or the callback is not defined
|
||||
|
||||
int pm_generic_runtime_suspend(struct device *dev);
|
||||
- invoke the ->runtime_suspend() callback provided by the driver of this
|
||||
device and return its result, or return -EINVAL if not defined
|
||||
|
@ -1,37 +0,0 @@
|
||||
ACPI video extensions
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This driver implement the ACPI Extensions For Display Adapters for
|
||||
integrated graphics devices on motherboard, as specified in ACPI 2.0
|
||||
Specification, Appendix B, allowing to perform some basic control like
|
||||
defining the video POST device, retrieving EDID information or to
|
||||
setup a video output, etc. Note that this is an ref. implementation
|
||||
only. It may or may not work for your integrated video device.
|
||||
|
||||
Interfaces exposed to userland through /proc/acpi/video:
|
||||
|
||||
VGA/info : display the supported video bus device capability like Video ROM, CRT/LCD/TV.
|
||||
VGA/ROM : Used to get a copy of the display devices' ROM data (up to 4k).
|
||||
VGA/POST_info : Used to determine what options are implemented.
|
||||
VGA/POST : Used to get/set POST device.
|
||||
VGA/DOS : Used to get/set ownership of output switching:
|
||||
Please refer ACPI spec B.4.1 _DOS
|
||||
VGA/CRT : CRT output
|
||||
VGA/LCD : LCD output
|
||||
VGA/TVO : TV output
|
||||
VGA/*/brightness : Used to get/set brightness of output device
|
||||
|
||||
Notify event through /proc/acpi/event:
|
||||
|
||||
#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 0x82
|
||||
#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x83
|
||||
#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x84
|
||||
#define ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS 0x85
|
||||
#define ACPI_VIDEO_NOTIFY_DISPLAY_OFF 0x86
|
||||
|
@ -63,3 +63,34 @@ power_domain_target "%s state=%lu cpu_id=%lu"
|
||||
The first parameter gives the power domain name (e.g. "mpu_pwrdm").
|
||||
The second parameter is the power domain target state.
|
||||
|
||||
4. PM QoS events
|
||||
================
|
||||
The PM QoS events are used for QoS add/update/remove request and for
|
||||
target/flags update.
|
||||
|
||||
pm_qos_add_request "pm_qos_class=%s value=%d"
|
||||
pm_qos_update_request "pm_qos_class=%s value=%d"
|
||||
pm_qos_remove_request "pm_qos_class=%s value=%d"
|
||||
pm_qos_update_request_timeout "pm_qos_class=%s value=%d, timeout_us=%ld"
|
||||
|
||||
The first parameter gives the QoS class name (e.g. "CPU_DMA_LATENCY").
|
||||
The second parameter is value to be added/updated/removed.
|
||||
The third parameter is timeout value in usec.
|
||||
|
||||
pm_qos_update_target "action=%s prev_value=%d curr_value=%d"
|
||||
pm_qos_update_flags "action=%s prev_value=0x%x curr_value=0x%x"
|
||||
|
||||
The first parameter gives the QoS action name (e.g. "ADD_REQ").
|
||||
The second parameter is the previous QoS value.
|
||||
The third parameter is the current QoS value to update.
|
||||
|
||||
And, there are also events used for device PM QoS add/update/remove request.
|
||||
|
||||
dev_pm_qos_add_request "device=%s type=%s new_value=%d"
|
||||
dev_pm_qos_update_request "device=%s type=%s new_value=%d"
|
||||
dev_pm_qos_remove_request "device=%s type=%s new_value=%d"
|
||||
|
||||
The first parameter gives the device name which tries to add/update/remove
|
||||
QoS requests.
|
||||
The second parameter gives the request type (e.g. "DEV_PM_QOS_LATENCY").
|
||||
The third parameter is value to be added/updated/removed.
|
||||
|
@ -242,6 +242,8 @@ F: drivers/acpi/
|
||||
F: drivers/pnp/pnpacpi/
|
||||
F: include/linux/acpi.h
|
||||
F: include/acpi/
|
||||
F: Documentation/acpi
|
||||
F: Documentation/ABI/testing/sysfs-bus-acpi
|
||||
|
||||
ACPI FAN DRIVER
|
||||
M: Zhang Rui <rui.zhang@intel.com>
|
||||
@ -1320,6 +1322,7 @@ W: http://wiki.xilinx.com
|
||||
T: git git://git.xilinx.com/linux-xlnx.git
|
||||
S: Supported
|
||||
F: arch/arm/mach-zynq/
|
||||
F: drivers/cpuidle/cpuidle-zynq.c
|
||||
|
||||
ARM64 PORT (AARCH64 ARCHITECTURE)
|
||||
M: Catalin Marinas <catalin.marinas@arm.com>
|
||||
@ -2227,7 +2230,8 @@ M: Viresh Kumar <viresh.kumar@linaro.org>
|
||||
L: cpufreq@vger.kernel.org
|
||||
L: linux-pm@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git
|
||||
T: git git://git.linaro.org/people/vireshk/linux.git (For ARM Updates)
|
||||
F: drivers/cpufreq/
|
||||
F: include/linux/cpufreq.h
|
||||
|
||||
@ -2528,7 +2532,7 @@ F: drivers/usb/dwc3/
|
||||
DEVICE FREQUENCY (DEVFREQ)
|
||||
M: MyungJoo Ham <myungjoo.ham@samsung.com>
|
||||
M: Kyungmin Park <kyungmin.park@samsung.com>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
L: linux-pm@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/devfreq/
|
||||
|
||||
|
@ -40,6 +40,7 @@ config ARCH_DAVINCI_DA850
|
||||
bool "DA850/OMAP-L138/AM18x based system"
|
||||
select ARCH_DAVINCI_DA8XX
|
||||
select ARCH_HAS_CPUFREQ
|
||||
select CPU_FREQ_TABLE
|
||||
select CP_INTC
|
||||
|
||||
config ARCH_DAVINCI_DA8XX
|
||||
|
@ -1004,7 +1004,7 @@ static const struct da850_opp da850_opp_96 = {
|
||||
|
||||
#define OPP(freq) \
|
||||
{ \
|
||||
.index = (unsigned int) &da850_opp_##freq, \
|
||||
.driver_data = (unsigned int) &da850_opp_##freq, \
|
||||
.frequency = freq * 1000, \
|
||||
}
|
||||
|
||||
@ -1016,7 +1016,7 @@ static struct cpufreq_frequency_table da850_freq_table[] = {
|
||||
OPP(200),
|
||||
OPP(96),
|
||||
{
|
||||
.index = 0,
|
||||
.driver_data = 0,
|
||||
.frequency = CPUFREQ_TABLE_END,
|
||||
},
|
||||
};
|
||||
@ -1044,7 +1044,7 @@ static int da850_set_voltage(unsigned int index)
|
||||
if (!cvdd)
|
||||
return -ENODEV;
|
||||
|
||||
opp = (struct da850_opp *) cpufreq_info.freq_table[index].index;
|
||||
opp = (struct da850_opp *) cpufreq_info.freq_table[index].driver_data;
|
||||
|
||||
return regulator_set_voltage(cvdd, opp->cvdd_min, opp->cvdd_max);
|
||||
}
|
||||
@ -1125,7 +1125,7 @@ static int da850_set_pll0rate(struct clk *clk, unsigned long index)
|
||||
struct pll_data *pll = clk->pll_data;
|
||||
int ret;
|
||||
|
||||
opp = (struct da850_opp *) cpufreq_info.freq_table[index].index;
|
||||
opp = (struct da850_opp *) cpufreq_info.freq_table[index].driver_data;
|
||||
prediv = opp->prediv;
|
||||
mult = opp->mult;
|
||||
postdiv = opp->postdiv;
|
||||
|
@ -588,11 +588,6 @@ static int _od_runtime_suspend(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int _od_runtime_idle(struct device *dev)
|
||||
{
|
||||
return pm_generic_runtime_idle(dev);
|
||||
}
|
||||
|
||||
static int _od_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
@ -648,7 +643,7 @@ static int _od_resume_noirq(struct device *dev)
|
||||
struct dev_pm_domain omap_device_pm_domain = {
|
||||
.ops = {
|
||||
SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume,
|
||||
_od_runtime_idle)
|
||||
NULL)
|
||||
USE_PLATFORM_PM_SLEEP_OPS
|
||||
.suspend_noirq = _od_suspend_noirq,
|
||||
.resume_noirq = _od_resume_noirq,
|
||||
|
@ -26,14 +26,14 @@ static int sr_class3_enable(struct omap_sr *sr)
|
||||
}
|
||||
|
||||
omap_vp_enable(sr->voltdm);
|
||||
return sr_enable(sr->voltdm, volt);
|
||||
return sr_enable(sr, volt);
|
||||
}
|
||||
|
||||
static int sr_class3_disable(struct omap_sr *sr, int is_volt_reset)
|
||||
{
|
||||
sr_disable_errgen(sr->voltdm);
|
||||
sr_disable_errgen(sr);
|
||||
omap_vp_disable(sr->voltdm);
|
||||
sr_disable(sr->voltdm);
|
||||
sr_disable(sr);
|
||||
if (is_volt_reset)
|
||||
voltdm_reset(sr->voltdm);
|
||||
|
||||
@ -42,7 +42,7 @@ static int sr_class3_disable(struct omap_sr *sr, int is_volt_reset)
|
||||
|
||||
static int sr_class3_configure(struct omap_sr *sr)
|
||||
{
|
||||
return sr_configure_errgen(sr->voltdm);
|
||||
return sr_configure_errgen(sr);
|
||||
}
|
||||
|
||||
/* SR class3 structure */
|
||||
|
@ -615,12 +615,14 @@ endmenu
|
||||
config PXA25x
|
||||
bool
|
||||
select CPU_XSCALE
|
||||
select CPU_FREQ_TABLE if CPU_FREQ
|
||||
help
|
||||
Select code specific to PXA21x/25x/26x variants
|
||||
|
||||
config PXA27x
|
||||
bool
|
||||
select CPU_XSCALE
|
||||
select CPU_FREQ_TABLE if CPU_FREQ
|
||||
help
|
||||
Select code specific to PXA27x variants
|
||||
|
||||
@ -633,6 +635,7 @@ config CPU_PXA26x
|
||||
config PXA3xx
|
||||
bool
|
||||
select CPU_XSC3
|
||||
select CPU_FREQ_TABLE if CPU_FREQ
|
||||
help
|
||||
Select code specific to PXA3xx variants
|
||||
|
||||
|
@ -60,5 +60,5 @@ void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
|
||||
*/
|
||||
void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg)
|
||||
{
|
||||
__raw_writel(cfg->pll.index, S3C2410_MPLLCON);
|
||||
__raw_writel(cfg->pll.driver_data, S3C2410_MPLLCON);
|
||||
}
|
||||
|
@ -33,36 +33,36 @@
|
||||
#include <plat/cpu-freq-core.h>
|
||||
|
||||
static struct cpufreq_frequency_table pll_vals_12MHz[] = {
|
||||
{ .frequency = 34000000, .index = PLLVAL(82, 2, 3), },
|
||||
{ .frequency = 45000000, .index = PLLVAL(82, 1, 3), },
|
||||
{ .frequency = 51000000, .index = PLLVAL(161, 3, 3), },
|
||||
{ .frequency = 48000000, .index = PLLVAL(120, 2, 3), },
|
||||
{ .frequency = 56000000, .index = PLLVAL(142, 2, 3), },
|
||||
{ .frequency = 68000000, .index = PLLVAL(82, 2, 2), },
|
||||
{ .frequency = 79000000, .index = PLLVAL(71, 1, 2), },
|
||||
{ .frequency = 85000000, .index = PLLVAL(105, 2, 2), },
|
||||
{ .frequency = 90000000, .index = PLLVAL(112, 2, 2), },
|
||||
{ .frequency = 101000000, .index = PLLVAL(127, 2, 2), },
|
||||
{ .frequency = 113000000, .index = PLLVAL(105, 1, 2), },
|
||||
{ .frequency = 118000000, .index = PLLVAL(150, 2, 2), },
|
||||
{ .frequency = 124000000, .index = PLLVAL(116, 1, 2), },
|
||||
{ .frequency = 135000000, .index = PLLVAL(82, 2, 1), },
|
||||
{ .frequency = 147000000, .index = PLLVAL(90, 2, 1), },
|
||||
{ .frequency = 152000000, .index = PLLVAL(68, 1, 1), },
|
||||
{ .frequency = 158000000, .index = PLLVAL(71, 1, 1), },
|
||||
{ .frequency = 170000000, .index = PLLVAL(77, 1, 1), },
|
||||
{ .frequency = 180000000, .index = PLLVAL(82, 1, 1), },
|
||||
{ .frequency = 186000000, .index = PLLVAL(85, 1, 1), },
|
||||
{ .frequency = 192000000, .index = PLLVAL(88, 1, 1), },
|
||||
{ .frequency = 203000000, .index = PLLVAL(161, 3, 1), },
|
||||
{ .frequency = 34000000, .driver_data = PLLVAL(82, 2, 3), },
|
||||
{ .frequency = 45000000, .driver_data = PLLVAL(82, 1, 3), },
|
||||
{ .frequency = 51000000, .driver_data = PLLVAL(161, 3, 3), },
|
||||
{ .frequency = 48000000, .driver_data = PLLVAL(120, 2, 3), },
|
||||
{ .frequency = 56000000, .driver_data = PLLVAL(142, 2, 3), },
|
||||
{ .frequency = 68000000, .driver_data = PLLVAL(82, 2, 2), },
|
||||
{ .frequency = 79000000, .driver_data = PLLVAL(71, 1, 2), },
|
||||
{ .frequency = 85000000, .driver_data = PLLVAL(105, 2, 2), },
|
||||
{ .frequency = 90000000, .driver_data = PLLVAL(112, 2, 2), },
|
||||
{ .frequency = 101000000, .driver_data = PLLVAL(127, 2, 2), },
|
||||
{ .frequency = 113000000, .driver_data = PLLVAL(105, 1, 2), },
|
||||
{ .frequency = 118000000, .driver_data = PLLVAL(150, 2, 2), },
|
||||
{ .frequency = 124000000, .driver_data = PLLVAL(116, 1, 2), },
|
||||
{ .frequency = 135000000, .driver_data = PLLVAL(82, 2, 1), },
|
||||
{ .frequency = 147000000, .driver_data = PLLVAL(90, 2, 1), },
|
||||
{ .frequency = 152000000, .driver_data = PLLVAL(68, 1, 1), },
|
||||
{ .frequency = 158000000, .driver_data = PLLVAL(71, 1, 1), },
|
||||
{ .frequency = 170000000, .driver_data = PLLVAL(77, 1, 1), },
|
||||
{ .frequency = 180000000, .driver_data = PLLVAL(82, 1, 1), },
|
||||
{ .frequency = 186000000, .driver_data = PLLVAL(85, 1, 1), },
|
||||
{ .frequency = 192000000, .driver_data = PLLVAL(88, 1, 1), },
|
||||
{ .frequency = 203000000, .driver_data = PLLVAL(161, 3, 1), },
|
||||
|
||||
/* 2410A extras */
|
||||
|
||||
{ .frequency = 210000000, .index = PLLVAL(132, 2, 1), },
|
||||
{ .frequency = 226000000, .index = PLLVAL(105, 1, 1), },
|
||||
{ .frequency = 266000000, .index = PLLVAL(125, 1, 1), },
|
||||
{ .frequency = 268000000, .index = PLLVAL(126, 1, 1), },
|
||||
{ .frequency = 270000000, .index = PLLVAL(127, 1, 1), },
|
||||
{ .frequency = 210000000, .driver_data = PLLVAL(132, 2, 1), },
|
||||
{ .frequency = 226000000, .driver_data = PLLVAL(105, 1, 1), },
|
||||
{ .frequency = 266000000, .driver_data = PLLVAL(125, 1, 1), },
|
||||
{ .frequency = 268000000, .driver_data = PLLVAL(126, 1, 1), },
|
||||
{ .frequency = 270000000, .driver_data = PLLVAL(127, 1, 1), },
|
||||
};
|
||||
|
||||
static int s3c2410_plls_add(struct device *dev, struct subsys_interface *sif)
|
||||
|
@ -21,33 +21,33 @@
|
||||
#include <plat/cpu-freq-core.h>
|
||||
|
||||
static struct cpufreq_frequency_table s3c2440_plls_12[] __initdata = {
|
||||
{ .frequency = 75000000, .index = PLLVAL(0x75, 3, 3), }, /* FVco 600.000000 */
|
||||
{ .frequency = 80000000, .index = PLLVAL(0x98, 4, 3), }, /* FVco 640.000000 */
|
||||
{ .frequency = 90000000, .index = PLLVAL(0x70, 2, 3), }, /* FVco 720.000000 */
|
||||
{ .frequency = 100000000, .index = PLLVAL(0x5c, 1, 3), }, /* FVco 800.000000 */
|
||||
{ .frequency = 110000000, .index = PLLVAL(0x66, 1, 3), }, /* FVco 880.000000 */
|
||||
{ .frequency = 120000000, .index = PLLVAL(0x70, 1, 3), }, /* FVco 960.000000 */
|
||||
{ .frequency = 150000000, .index = PLLVAL(0x75, 3, 2), }, /* FVco 600.000000 */
|
||||
{ .frequency = 160000000, .index = PLLVAL(0x98, 4, 2), }, /* FVco 640.000000 */
|
||||
{ .frequency = 170000000, .index = PLLVAL(0x4d, 1, 2), }, /* FVco 680.000000 */
|
||||
{ .frequency = 180000000, .index = PLLVAL(0x70, 2, 2), }, /* FVco 720.000000 */
|
||||
{ .frequency = 190000000, .index = PLLVAL(0x57, 1, 2), }, /* FVco 760.000000 */
|
||||
{ .frequency = 200000000, .index = PLLVAL(0x5c, 1, 2), }, /* FVco 800.000000 */
|
||||
{ .frequency = 210000000, .index = PLLVAL(0x84, 2, 2), }, /* FVco 840.000000 */
|
||||
{ .frequency = 220000000, .index = PLLVAL(0x66, 1, 2), }, /* FVco 880.000000 */
|
||||
{ .frequency = 230000000, .index = PLLVAL(0x6b, 1, 2), }, /* FVco 920.000000 */
|
||||
{ .frequency = 240000000, .index = PLLVAL(0x70, 1, 2), }, /* FVco 960.000000 */
|
||||
{ .frequency = 300000000, .index = PLLVAL(0x75, 3, 1), }, /* FVco 600.000000 */
|
||||
{ .frequency = 310000000, .index = PLLVAL(0x93, 4, 1), }, /* FVco 620.000000 */
|
||||
{ .frequency = 320000000, .index = PLLVAL(0x98, 4, 1), }, /* FVco 640.000000 */
|
||||
{ .frequency = 330000000, .index = PLLVAL(0x66, 2, 1), }, /* FVco 660.000000 */
|
||||
{ .frequency = 340000000, .index = PLLVAL(0x4d, 1, 1), }, /* FVco 680.000000 */
|
||||
{ .frequency = 350000000, .index = PLLVAL(0xa7, 4, 1), }, /* FVco 700.000000 */
|
||||
{ .frequency = 360000000, .index = PLLVAL(0x70, 2, 1), }, /* FVco 720.000000 */
|
||||
{ .frequency = 370000000, .index = PLLVAL(0xb1, 4, 1), }, /* FVco 740.000000 */
|
||||
{ .frequency = 380000000, .index = PLLVAL(0x57, 1, 1), }, /* FVco 760.000000 */
|
||||
{ .frequency = 390000000, .index = PLLVAL(0x7a, 2, 1), }, /* FVco 780.000000 */
|
||||
{ .frequency = 400000000, .index = PLLVAL(0x5c, 1, 1), }, /* FVco 800.000000 */
|
||||
{ .frequency = 75000000, .driver_data = PLLVAL(0x75, 3, 3), }, /* FVco 600.000000 */
|
||||
{ .frequency = 80000000, .driver_data = PLLVAL(0x98, 4, 3), }, /* FVco 640.000000 */
|
||||
{ .frequency = 90000000, .driver_data = PLLVAL(0x70, 2, 3), }, /* FVco 720.000000 */
|
||||
{ .frequency = 100000000, .driver_data = PLLVAL(0x5c, 1, 3), }, /* FVco 800.000000 */
|
||||
{ .frequency = 110000000, .driver_data = PLLVAL(0x66, 1, 3), }, /* FVco 880.000000 */
|
||||
{ .frequency = 120000000, .driver_data = PLLVAL(0x70, 1, 3), }, /* FVco 960.000000 */
|
||||
{ .frequency = 150000000, .driver_data = PLLVAL(0x75, 3, 2), }, /* FVco 600.000000 */
|
||||
{ .frequency = 160000000, .driver_data = PLLVAL(0x98, 4, 2), }, /* FVco 640.000000 */
|
||||
{ .frequency = 170000000, .driver_data = PLLVAL(0x4d, 1, 2), }, /* FVco 680.000000 */
|
||||
{ .frequency = 180000000, .driver_data = PLLVAL(0x70, 2, 2), }, /* FVco 720.000000 */
|
||||
{ .frequency = 190000000, .driver_data = PLLVAL(0x57, 1, 2), }, /* FVco 760.000000 */
|
||||
{ .frequency = 200000000, .driver_data = PLLVAL(0x5c, 1, 2), }, /* FVco 800.000000 */
|
||||
{ .frequency = 210000000, .driver_data = PLLVAL(0x84, 2, 2), }, /* FVco 840.000000 */
|
||||
{ .frequency = 220000000, .driver_data = PLLVAL(0x66, 1, 2), }, /* FVco 880.000000 */
|
||||
{ .frequency = 230000000, .driver_data = PLLVAL(0x6b, 1, 2), }, /* FVco 920.000000 */
|
||||
{ .frequency = 240000000, .driver_data = PLLVAL(0x70, 1, 2), }, /* FVco 960.000000 */
|
||||
{ .frequency = 300000000, .driver_data = PLLVAL(0x75, 3, 1), }, /* FVco 600.000000 */
|
||||
{ .frequency = 310000000, .driver_data = PLLVAL(0x93, 4, 1), }, /* FVco 620.000000 */
|
||||
{ .frequency = 320000000, .driver_data = PLLVAL(0x98, 4, 1), }, /* FVco 640.000000 */
|
||||
{ .frequency = 330000000, .driver_data = PLLVAL(0x66, 2, 1), }, /* FVco 660.000000 */
|
||||
{ .frequency = 340000000, .driver_data = PLLVAL(0x4d, 1, 1), }, /* FVco 680.000000 */
|
||||
{ .frequency = 350000000, .driver_data = PLLVAL(0xa7, 4, 1), }, /* FVco 700.000000 */
|
||||
{ .frequency = 360000000, .driver_data = PLLVAL(0x70, 2, 1), }, /* FVco 720.000000 */
|
||||
{ .frequency = 370000000, .driver_data = PLLVAL(0xb1, 4, 1), }, /* FVco 740.000000 */
|
||||
{ .frequency = 380000000, .driver_data = PLLVAL(0x57, 1, 1), }, /* FVco 760.000000 */
|
||||
{ .frequency = 390000000, .driver_data = PLLVAL(0x7a, 2, 1), }, /* FVco 780.000000 */
|
||||
{ .frequency = 400000000, .driver_data = PLLVAL(0x5c, 1, 1), }, /* FVco 800.000000 */
|
||||
};
|
||||
|
||||
static int s3c2440_plls12_add(struct device *dev, struct subsys_interface *sif)
|
||||
|
@ -21,61 +21,61 @@
|
||||
#include <plat/cpu-freq-core.h>
|
||||
|
||||
static struct cpufreq_frequency_table s3c2440_plls_169344[] __initdata = {
|
||||
{ .frequency = 78019200, .index = PLLVAL(121, 5, 3), }, /* FVco 624.153600 */
|
||||
{ .frequency = 84067200, .index = PLLVAL(131, 5, 3), }, /* FVco 672.537600 */
|
||||
{ .frequency = 90115200, .index = PLLVAL(141, 5, 3), }, /* FVco 720.921600 */
|
||||
{ .frequency = 96163200, .index = PLLVAL(151, 5, 3), }, /* FVco 769.305600 */
|
||||
{ .frequency = 102135600, .index = PLLVAL(185, 6, 3), }, /* FVco 817.084800 */
|
||||
{ .frequency = 108259200, .index = PLLVAL(171, 5, 3), }, /* FVco 866.073600 */
|
||||
{ .frequency = 114307200, .index = PLLVAL(127, 3, 3), }, /* FVco 914.457600 */
|
||||
{ .frequency = 120234240, .index = PLLVAL(134, 3, 3), }, /* FVco 961.873920 */
|
||||
{ .frequency = 126161280, .index = PLLVAL(141, 3, 3), }, /* FVco 1009.290240 */
|
||||
{ .frequency = 132088320, .index = PLLVAL(148, 3, 3), }, /* FVco 1056.706560 */
|
||||
{ .frequency = 138015360, .index = PLLVAL(155, 3, 3), }, /* FVco 1104.122880 */
|
||||
{ .frequency = 144789120, .index = PLLVAL(163, 3, 3), }, /* FVco 1158.312960 */
|
||||
{ .frequency = 150100363, .index = PLLVAL(187, 9, 2), }, /* FVco 600.401454 */
|
||||
{ .frequency = 156038400, .index = PLLVAL(121, 5, 2), }, /* FVco 624.153600 */
|
||||
{ .frequency = 162086400, .index = PLLVAL(126, 5, 2), }, /* FVco 648.345600 */
|
||||
{ .frequency = 168134400, .index = PLLVAL(131, 5, 2), }, /* FVco 672.537600 */
|
||||
{ .frequency = 174048000, .index = PLLVAL(177, 7, 2), }, /* FVco 696.192000 */
|
||||
{ .frequency = 180230400, .index = PLLVAL(141, 5, 2), }, /* FVco 720.921600 */
|
||||
{ .frequency = 186278400, .index = PLLVAL(124, 4, 2), }, /* FVco 745.113600 */
|
||||
{ .frequency = 192326400, .index = PLLVAL(151, 5, 2), }, /* FVco 769.305600 */
|
||||
{ .frequency = 198132480, .index = PLLVAL(109, 3, 2), }, /* FVco 792.529920 */
|
||||
{ .frequency = 204271200, .index = PLLVAL(185, 6, 2), }, /* FVco 817.084800 */
|
||||
{ .frequency = 210268800, .index = PLLVAL(141, 4, 2), }, /* FVco 841.075200 */
|
||||
{ .frequency = 216518400, .index = PLLVAL(171, 5, 2), }, /* FVco 866.073600 */
|
||||
{ .frequency = 222264000, .index = PLLVAL(97, 2, 2), }, /* FVco 889.056000 */
|
||||
{ .frequency = 228614400, .index = PLLVAL(127, 3, 2), }, /* FVco 914.457600 */
|
||||
{ .frequency = 234259200, .index = PLLVAL(158, 4, 2), }, /* FVco 937.036800 */
|
||||
{ .frequency = 240468480, .index = PLLVAL(134, 3, 2), }, /* FVco 961.873920 */
|
||||
{ .frequency = 246960000, .index = PLLVAL(167, 4, 2), }, /* FVco 987.840000 */
|
||||
{ .frequency = 252322560, .index = PLLVAL(141, 3, 2), }, /* FVco 1009.290240 */
|
||||
{ .frequency = 258249600, .index = PLLVAL(114, 2, 2), }, /* FVco 1032.998400 */
|
||||
{ .frequency = 264176640, .index = PLLVAL(148, 3, 2), }, /* FVco 1056.706560 */
|
||||
{ .frequency = 270950400, .index = PLLVAL(120, 2, 2), }, /* FVco 1083.801600 */
|
||||
{ .frequency = 276030720, .index = PLLVAL(155, 3, 2), }, /* FVco 1104.122880 */
|
||||
{ .frequency = 282240000, .index = PLLVAL(92, 1, 2), }, /* FVco 1128.960000 */
|
||||
{ .frequency = 289578240, .index = PLLVAL(163, 3, 2), }, /* FVco 1158.312960 */
|
||||
{ .frequency = 294235200, .index = PLLVAL(131, 2, 2), }, /* FVco 1176.940800 */
|
||||
{ .frequency = 300200727, .index = PLLVAL(187, 9, 1), }, /* FVco 600.401454 */
|
||||
{ .frequency = 306358690, .index = PLLVAL(191, 9, 1), }, /* FVco 612.717380 */
|
||||
{ .frequency = 312076800, .index = PLLVAL(121, 5, 1), }, /* FVco 624.153600 */
|
||||
{ .frequency = 318366720, .index = PLLVAL(86, 3, 1), }, /* FVco 636.733440 */
|
||||
{ .frequency = 324172800, .index = PLLVAL(126, 5, 1), }, /* FVco 648.345600 */
|
||||
{ .frequency = 330220800, .index = PLLVAL(109, 4, 1), }, /* FVco 660.441600 */
|
||||
{ .frequency = 336268800, .index = PLLVAL(131, 5, 1), }, /* FVco 672.537600 */
|
||||
{ .frequency = 342074880, .index = PLLVAL(93, 3, 1), }, /* FVco 684.149760 */
|
||||
{ .frequency = 348096000, .index = PLLVAL(177, 7, 1), }, /* FVco 696.192000 */
|
||||
{ .frequency = 355622400, .index = PLLVAL(118, 4, 1), }, /* FVco 711.244800 */
|
||||
{ .frequency = 360460800, .index = PLLVAL(141, 5, 1), }, /* FVco 720.921600 */
|
||||
{ .frequency = 366206400, .index = PLLVAL(165, 6, 1), }, /* FVco 732.412800 */
|
||||
{ .frequency = 372556800, .index = PLLVAL(124, 4, 1), }, /* FVco 745.113600 */
|
||||
{ .frequency = 378201600, .index = PLLVAL(126, 4, 1), }, /* FVco 756.403200 */
|
||||
{ .frequency = 384652800, .index = PLLVAL(151, 5, 1), }, /* FVco 769.305600 */
|
||||
{ .frequency = 391608000, .index = PLLVAL(177, 6, 1), }, /* FVco 783.216000 */
|
||||
{ .frequency = 396264960, .index = PLLVAL(109, 3, 1), }, /* FVco 792.529920 */
|
||||
{ .frequency = 402192000, .index = PLLVAL(87, 2, 1), }, /* FVco 804.384000 */
|
||||
{ .frequency = 78019200, .driver_data = PLLVAL(121, 5, 3), }, /* FVco 624.153600 */
|
||||
{ .frequency = 84067200, .driver_data = PLLVAL(131, 5, 3), }, /* FVco 672.537600 */
|
||||
{ .frequency = 90115200, .driver_data = PLLVAL(141, 5, 3), }, /* FVco 720.921600 */
|
||||
{ .frequency = 96163200, .driver_data = PLLVAL(151, 5, 3), }, /* FVco 769.305600 */
|
||||
{ .frequency = 102135600, .driver_data = PLLVAL(185, 6, 3), }, /* FVco 817.084800 */
|
||||
{ .frequency = 108259200, .driver_data = PLLVAL(171, 5, 3), }, /* FVco 866.073600 */
|
||||
{ .frequency = 114307200, .driver_data = PLLVAL(127, 3, 3), }, /* FVco 914.457600 */
|
||||
{ .frequency = 120234240, .driver_data = PLLVAL(134, 3, 3), }, /* FVco 961.873920 */
|
||||
{ .frequency = 126161280, .driver_data = PLLVAL(141, 3, 3), }, /* FVco 1009.290240 */
|
||||
{ .frequency = 132088320, .driver_data = PLLVAL(148, 3, 3), }, /* FVco 1056.706560 */
|
||||
{ .frequency = 138015360, .driver_data = PLLVAL(155, 3, 3), }, /* FVco 1104.122880 */
|
||||
{ .frequency = 144789120, .driver_data = PLLVAL(163, 3, 3), }, /* FVco 1158.312960 */
|
||||
{ .frequency = 150100363, .driver_data = PLLVAL(187, 9, 2), }, /* FVco 600.401454 */
|
||||
{ .frequency = 156038400, .driver_data = PLLVAL(121, 5, 2), }, /* FVco 624.153600 */
|
||||
{ .frequency = 162086400, .driver_data = PLLVAL(126, 5, 2), }, /* FVco 648.345600 */
|
||||
{ .frequency = 168134400, .driver_data = PLLVAL(131, 5, 2), }, /* FVco 672.537600 */
|
||||
{ .frequency = 174048000, .driver_data = PLLVAL(177, 7, 2), }, /* FVco 696.192000 */
|
||||
{ .frequency = 180230400, .driver_data = PLLVAL(141, 5, 2), }, /* FVco 720.921600 */
|
||||
{ .frequency = 186278400, .driver_data = PLLVAL(124, 4, 2), }, /* FVco 745.113600 */
|
||||
{ .frequency = 192326400, .driver_data = PLLVAL(151, 5, 2), }, /* FVco 769.305600 */
|
||||
{ .frequency = 198132480, .driver_data = PLLVAL(109, 3, 2), }, /* FVco 792.529920 */
|
||||
{ .frequency = 204271200, .driver_data = PLLVAL(185, 6, 2), }, /* FVco 817.084800 */
|
||||
{ .frequency = 210268800, .driver_data = PLLVAL(141, 4, 2), }, /* FVco 841.075200 */
|
||||
{ .frequency = 216518400, .driver_data = PLLVAL(171, 5, 2), }, /* FVco 866.073600 */
|
||||
{ .frequency = 222264000, .driver_data = PLLVAL(97, 2, 2), }, /* FVco 889.056000 */
|
||||
{ .frequency = 228614400, .driver_data = PLLVAL(127, 3, 2), }, /* FVco 914.457600 */
|
||||
{ .frequency = 234259200, .driver_data = PLLVAL(158, 4, 2), }, /* FVco 937.036800 */
|
||||
{ .frequency = 240468480, .driver_data = PLLVAL(134, 3, 2), }, /* FVco 961.873920 */
|
||||
{ .frequency = 246960000, .driver_data = PLLVAL(167, 4, 2), }, /* FVco 987.840000 */
|
||||
{ .frequency = 252322560, .driver_data = PLLVAL(141, 3, 2), }, /* FVco 1009.290240 */
|
||||
{ .frequency = 258249600, .driver_data = PLLVAL(114, 2, 2), }, /* FVco 1032.998400 */
|
||||
{ .frequency = 264176640, .driver_data = PLLVAL(148, 3, 2), }, /* FVco 1056.706560 */
|
||||
{ .frequency = 270950400, .driver_data = PLLVAL(120, 2, 2), }, /* FVco 1083.801600 */
|
||||
{ .frequency = 276030720, .driver_data = PLLVAL(155, 3, 2), }, /* FVco 1104.122880 */
|
||||
{ .frequency = 282240000, .driver_data = PLLVAL(92, 1, 2), }, /* FVco 1128.960000 */
|
||||
{ .frequency = 289578240, .driver_data = PLLVAL(163, 3, 2), }, /* FVco 1158.312960 */
|
||||
{ .frequency = 294235200, .driver_data = PLLVAL(131, 2, 2), }, /* FVco 1176.940800 */
|
||||
{ .frequency = 300200727, .driver_data = PLLVAL(187, 9, 1), }, /* FVco 600.401454 */
|
||||
{ .frequency = 306358690, .driver_data = PLLVAL(191, 9, 1), }, /* FVco 612.717380 */
|
||||
{ .frequency = 312076800, .driver_data = PLLVAL(121, 5, 1), }, /* FVco 624.153600 */
|
||||
{ .frequency = 318366720, .driver_data = PLLVAL(86, 3, 1), }, /* FVco 636.733440 */
|
||||
{ .frequency = 324172800, .driver_data = PLLVAL(126, 5, 1), }, /* FVco 648.345600 */
|
||||
{ .frequency = 330220800, .driver_data = PLLVAL(109, 4, 1), }, /* FVco 660.441600 */
|
||||
{ .frequency = 336268800, .driver_data = PLLVAL(131, 5, 1), }, /* FVco 672.537600 */
|
||||
{ .frequency = 342074880, .driver_data = PLLVAL(93, 3, 1), }, /* FVco 684.149760 */
|
||||
{ .frequency = 348096000, .driver_data = PLLVAL(177, 7, 1), }, /* FVco 696.192000 */
|
||||
{ .frequency = 355622400, .driver_data = PLLVAL(118, 4, 1), }, /* FVco 711.244800 */
|
||||
{ .frequency = 360460800, .driver_data = PLLVAL(141, 5, 1), }, /* FVco 720.921600 */
|
||||
{ .frequency = 366206400, .driver_data = PLLVAL(165, 6, 1), }, /* FVco 732.412800 */
|
||||
{ .frequency = 372556800, .driver_data = PLLVAL(124, 4, 1), }, /* FVco 745.113600 */
|
||||
{ .frequency = 378201600, .driver_data = PLLVAL(126, 4, 1), }, /* FVco 756.403200 */
|
||||
{ .frequency = 384652800, .driver_data = PLLVAL(151, 5, 1), }, /* FVco 769.305600 */
|
||||
{ .frequency = 391608000, .driver_data = PLLVAL(177, 6, 1), }, /* FVco 783.216000 */
|
||||
{ .frequency = 396264960, .driver_data = PLLVAL(109, 3, 1), }, /* FVco 792.529920 */
|
||||
{ .frequency = 402192000, .driver_data = PLLVAL(87, 2, 1), }, /* FVco 804.384000 */
|
||||
};
|
||||
|
||||
static int s3c2440_plls169344_add(struct device *dev,
|
||||
|
@ -142,15 +142,15 @@ static void pllc2_table_rebuild(struct clk *clk)
|
||||
/* Initialise PLLC2 frequency table */
|
||||
for (i = 0; i < ARRAY_SIZE(pllc2_freq_table) - 2; i++) {
|
||||
pllc2_freq_table[i].frequency = clk->parent->rate * (i + 20) * 2;
|
||||
pllc2_freq_table[i].index = i;
|
||||
pllc2_freq_table[i].driver_data = i;
|
||||
}
|
||||
|
||||
/* This is a special entry - switching PLL off makes it a repeater */
|
||||
pllc2_freq_table[i].frequency = clk->parent->rate;
|
||||
pllc2_freq_table[i].index = i;
|
||||
pllc2_freq_table[i].driver_data = i;
|
||||
|
||||
pllc2_freq_table[++i].frequency = CPUFREQ_TABLE_END;
|
||||
pllc2_freq_table[i].index = i;
|
||||
pllc2_freq_table[i].driver_data = i;
|
||||
}
|
||||
|
||||
static unsigned long pllc2_recalc(struct clk *clk)
|
||||
|
@ -28,7 +28,6 @@ config ARCH_TEGRA_2x_SOC
|
||||
select ARM_ERRATA_754327 if SMP
|
||||
select ARM_ERRATA_764369 if SMP
|
||||
select ARM_GIC
|
||||
select CPU_FREQ_TABLE if CPU_FREQ
|
||||
select CPU_V7
|
||||
select PINCTRL
|
||||
select PINCTRL_TEGRA20
|
||||
@ -46,7 +45,6 @@ config ARCH_TEGRA_3x_SOC
|
||||
select ARM_ERRATA_754322
|
||||
select ARM_ERRATA_764369 if SMP
|
||||
select ARM_GIC
|
||||
select CPU_FREQ_TABLE if CPU_FREQ
|
||||
select CPU_V7
|
||||
select PINCTRL
|
||||
select PINCTRL_TEGRA30
|
||||
@ -63,7 +61,6 @@ config ARCH_TEGRA_114_SOC
|
||||
select HAVE_ARM_ARCH_TIMER
|
||||
select ARM_GIC
|
||||
select ARM_L1_CACHE_SHIFT_6
|
||||
select CPU_FREQ_TABLE if CPU_FREQ
|
||||
select CPU_V7
|
||||
select PINCTRL
|
||||
select PINCTRL_TEGRA114
|
||||
|
@ -285,7 +285,7 @@ static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table,
|
||||
s3c_freq_dbg("%s: { %d = %u kHz }\n",
|
||||
__func__, index, freq);
|
||||
|
||||
table[index].index = index;
|
||||
table[index].driver_data = index;
|
||||
table[index].frequency = freq;
|
||||
}
|
||||
|
||||
|
@ -134,11 +134,13 @@ config SVINTO_SIM
|
||||
|
||||
config ETRAXFS
|
||||
bool "ETRAX-FS-V32"
|
||||
select CPU_FREQ_TABLE if CPU_FREQ
|
||||
help
|
||||
Support CRIS V32.
|
||||
|
||||
config CRIS_MACH_ARTPEC3
|
||||
bool "ARTPEC-3"
|
||||
select CPU_FREQ_TABLE if CPU_FREQ
|
||||
help
|
||||
Support Axis ARTPEC-3.
|
||||
|
||||
|
@ -2042,7 +2042,8 @@ sba_map_ioc_to_node(struct ioc *ioc, acpi_handle handle)
|
||||
#endif
|
||||
|
||||
static int __init
|
||||
acpi_sba_ioc_add(struct acpi_device *device)
|
||||
acpi_sba_ioc_add(struct acpi_device *device,
|
||||
const struct acpi_device_id *not_used)
|
||||
{
|
||||
struct ioc *ioc;
|
||||
acpi_status status;
|
||||
@ -2090,14 +2091,18 @@ static const struct acpi_device_id hp_ioc_iommu_device_ids[] = {
|
||||
{"HWP0004", 0},
|
||||
{"", 0},
|
||||
};
|
||||
static struct acpi_driver acpi_sba_ioc_driver = {
|
||||
.name = "IOC IOMMU Driver",
|
||||
static struct acpi_scan_handler acpi_sba_ioc_handler = {
|
||||
.ids = hp_ioc_iommu_device_ids,
|
||||
.ops = {
|
||||
.add = acpi_sba_ioc_add,
|
||||
},
|
||||
.attach = acpi_sba_ioc_add,
|
||||
};
|
||||
|
||||
static int __init acpi_sba_ioc_init_acpi(void)
|
||||
{
|
||||
return acpi_scan_add_handler(&acpi_sba_ioc_handler);
|
||||
}
|
||||
/* This has to run before acpi_scan_init(). */
|
||||
arch_initcall(acpi_sba_ioc_init_acpi);
|
||||
|
||||
extern struct dma_map_ops swiotlb_dma_ops;
|
||||
|
||||
static int __init
|
||||
@ -2122,7 +2127,10 @@ sba_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
acpi_bus_register_driver(&acpi_sba_ioc_driver);
|
||||
/*
|
||||
* ioc_list should be populated by the acpi_sba_ioc_handler's .attach()
|
||||
* routine, but that only happens if acpi_scan_init() has already run.
|
||||
*/
|
||||
if (!ioc_list) {
|
||||
#ifdef CONFIG_IA64_GENERIC
|
||||
/*
|
||||
|
@ -121,7 +121,8 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
|
||||
clk->rate = rate;
|
||||
|
||||
regval = LOONGSON_CHIPCFG0;
|
||||
regval = (regval & ~0x7) | (loongson2_clockmod_table[i].index - 1);
|
||||
regval = (regval & ~0x7) |
|
||||
(loongson2_clockmod_table[i].driver_data - 1);
|
||||
LOONGSON_CHIPCFG0 = regval;
|
||||
|
||||
return ret;
|
||||
|
@ -193,37 +193,6 @@ config PPC_IO_WORKAROUNDS
|
||||
|
||||
source "drivers/cpufreq/Kconfig"
|
||||
|
||||
menu "CPU Frequency drivers"
|
||||
depends on CPU_FREQ
|
||||
|
||||
config CPU_FREQ_PMAC
|
||||
bool "Support for Apple PowerBooks"
|
||||
depends on ADB_PMU && PPC32
|
||||
select CPU_FREQ_TABLE
|
||||
help
|
||||
This adds support for frequency switching on Apple PowerBooks,
|
||||
this currently includes some models of iBook & Titanium
|
||||
PowerBook.
|
||||
|
||||
config CPU_FREQ_PMAC64
|
||||
bool "Support for some Apple G5s"
|
||||
depends on PPC_PMAC && PPC64
|
||||
select CPU_FREQ_TABLE
|
||||
help
|
||||
This adds support for frequency switching on Apple iMac G5,
|
||||
and some of the more recent desktop G5 machines as well.
|
||||
|
||||
config PPC_PASEMI_CPUFREQ
|
||||
bool "Support for PA Semi PWRficient"
|
||||
depends on PPC_PASEMI
|
||||
default y
|
||||
select CPU_FREQ_TABLE
|
||||
help
|
||||
This adds the support for frequency switching on PA Semi
|
||||
PWRficient processors.
|
||||
|
||||
endmenu
|
||||
|
||||
menu "CPUIdle driver"
|
||||
|
||||
source "drivers/cpuidle/Kconfig"
|
||||
|
@ -1,3 +1,2 @@
|
||||
obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o dma_lib.o misc.o
|
||||
obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o
|
||||
obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o
|
||||
|
@ -9,8 +9,6 @@ obj-y += pic.o setup.o time.o feature.o pci.o \
|
||||
sleep.o low_i2c.o cache.o pfunc_core.o \
|
||||
pfunc_base.o udbg_scc.o udbg_adb.o
|
||||
obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o
|
||||
obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq_32.o
|
||||
obj-$(CONFIG_CPU_FREQ_PMAC64) += cpufreq_64.o
|
||||
# CONFIG_NVRAM is an arch. independent tristate symbol, for pmac32 we really
|
||||
# need this to be a bool. Cheat here and pretend CONFIG_NVRAM=m is really
|
||||
# CONFIG_NVRAM=y
|
||||
|
@ -111,7 +111,7 @@ static inline void acpi_disable_pci(void)
|
||||
}
|
||||
|
||||
/* Low-level suspend routine. */
|
||||
extern int acpi_suspend_lowlevel(void);
|
||||
extern int (*acpi_suspend_lowlevel)(void);
|
||||
|
||||
/* Physical address to resume after wakeup */
|
||||
#define acpi_wakeup_address ((unsigned long)(real_mode_header->wakeup_start))
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <asm/mpspec.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
#include "sleep.h" /* To include x86_acpi_suspend_lowlevel */
|
||||
static int __initdata acpi_force = 0;
|
||||
u32 acpi_rsdt_forced;
|
||||
int acpi_disabled;
|
||||
@ -559,6 +560,12 @@ static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi,
|
||||
int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
|
||||
int trigger, int polarity) = acpi_register_gsi_pic;
|
||||
|
||||
#ifdef CONFIG_ACPI_SLEEP
|
||||
int (*acpi_suspend_lowlevel)(void) = x86_acpi_suspend_lowlevel;
|
||||
#else
|
||||
int (*acpi_suspend_lowlevel)(void);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* success: return IRQ number (>=0)
|
||||
* failure: return < 0
|
||||
|
@ -26,12 +26,12 @@ static char temp_stack[4096];
|
||||
#endif
|
||||
|
||||
/**
|
||||
* acpi_suspend_lowlevel - save kernel state
|
||||
* x86_acpi_suspend_lowlevel - save kernel state
|
||||
*
|
||||
* Create an identity mapped page table and copy the wakeup routine to
|
||||
* low memory.
|
||||
*/
|
||||
int acpi_suspend_lowlevel(void)
|
||||
int x86_acpi_suspend_lowlevel(void)
|
||||
{
|
||||
struct wakeup_header *header =
|
||||
(struct wakeup_header *) __va(real_mode_header->wakeup_header);
|
||||
|
@ -15,3 +15,5 @@ extern unsigned long acpi_copy_wakeup_routine(unsigned long);
|
||||
extern void wakeup_long64(void);
|
||||
|
||||
extern void do_suspend_lowlevel(void);
|
||||
|
||||
extern int x86_acpi_suspend_lowlevel(void);
|
||||
|
@ -34,6 +34,7 @@ acpi-$(CONFIG_ACPI_SLEEP) += proc.o
|
||||
acpi-y += bus.o glue.o
|
||||
acpi-y += scan.o
|
||||
acpi-y += resource.o
|
||||
acpi-y += acpi_processor.o
|
||||
acpi-y += processor_core.o
|
||||
acpi-y += ec.o
|
||||
acpi-$(CONFIG_ACPI_DOCK) += dock.o
|
||||
@ -43,6 +44,7 @@ acpi-y += acpi_platform.o
|
||||
acpi-y += power.o
|
||||
acpi-y += event.o
|
||||
acpi-y += sysfs.o
|
||||
acpi-$(CONFIG_X86) += acpi_cmos_rtc.o
|
||||
acpi-$(CONFIG_DEBUG_FS) += debugfs.o
|
||||
acpi-$(CONFIG_ACPI_NUMA) += numa.o
|
||||
acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
|
||||
|
92
drivers/acpi/acpi_cmos_rtc.c
Normal file
92
drivers/acpi/acpi_cmos_rtc.c
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* ACPI support for CMOS RTC Address Space access
|
||||
*
|
||||
* Copyright (C) 2013, Intel Corporation
|
||||
* Authors: Lan Tianyu <tianyu.lan@intel.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm-generic/rtc.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#define PREFIX "ACPI: "
|
||||
|
||||
ACPI_MODULE_NAME("cmos rtc");
|
||||
|
||||
static const struct acpi_device_id acpi_cmos_rtc_ids[] = {
|
||||
{ "PNP0B00" },
|
||||
{ "PNP0B01" },
|
||||
{ "PNP0B02" },
|
||||
{}
|
||||
};
|
||||
|
||||
static acpi_status
|
||||
acpi_cmos_rtc_space_handler(u32 function, acpi_physical_address address,
|
||||
u32 bits, u64 *value64,
|
||||
void *handler_context, void *region_context)
|
||||
{
|
||||
int i;
|
||||
u8 *value = (u8 *)&value64;
|
||||
|
||||
if (address > 0xff || !value64)
|
||||
return AE_BAD_PARAMETER;
|
||||
|
||||
if (function != ACPI_WRITE && function != ACPI_READ)
|
||||
return AE_BAD_PARAMETER;
|
||||
|
||||
spin_lock_irq(&rtc_lock);
|
||||
|
||||
for (i = 0; i < DIV_ROUND_UP(bits, 8); ++i, ++address, ++value)
|
||||
if (function == ACPI_READ)
|
||||
*value = CMOS_READ(address);
|
||||
else
|
||||
CMOS_WRITE(*value, address);
|
||||
|
||||
spin_unlock_irq(&rtc_lock);
|
||||
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
static int acpi_install_cmos_rtc_space_handler(struct acpi_device *adev,
|
||||
const struct acpi_device_id *id)
|
||||
{
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_install_address_space_handler(adev->handle,
|
||||
ACPI_ADR_SPACE_CMOS,
|
||||
&acpi_cmos_rtc_space_handler,
|
||||
NULL, NULL);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
pr_err(PREFIX "Error installing CMOS-RTC region handler\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acpi_remove_cmos_rtc_space_handler(struct acpi_device *adev)
|
||||
{
|
||||
if (ACPI_FAILURE(acpi_remove_address_space_handler(adev->handle,
|
||||
ACPI_ADR_SPACE_CMOS, &acpi_cmos_rtc_space_handler)))
|
||||
pr_err(PREFIX "Error removing CMOS-RTC region handler\n");
|
||||
}
|
||||
|
||||
static struct acpi_scan_handler cmos_rtc_handler = {
|
||||
.ids = acpi_cmos_rtc_ids,
|
||||
.attach = acpi_install_cmos_rtc_space_handler,
|
||||
.detach = acpi_remove_cmos_rtc_space_handler,
|
||||
};
|
||||
|
||||
void __init acpi_cmos_rtc_init(void)
|
||||
{
|
||||
acpi_scan_add_handler(&cmos_rtc_handler);
|
||||
}
|
@ -32,12 +32,26 @@ ACPI_MODULE_NAME("acpi_lpss");
|
||||
#define LPSS_GENERAL_LTR_MODE_SW BIT(2)
|
||||
#define LPSS_SW_LTR 0x10
|
||||
#define LPSS_AUTO_LTR 0x14
|
||||
#define LPSS_TX_INT 0x20
|
||||
#define LPSS_TX_INT_MASK BIT(1)
|
||||
|
||||
struct lpss_shared_clock {
|
||||
const char *name;
|
||||
unsigned long rate;
|
||||
struct clk *clk;
|
||||
};
|
||||
|
||||
struct lpss_private_data;
|
||||
|
||||
struct lpss_device_desc {
|
||||
bool clk_required;
|
||||
const char *clkdev_name;
|
||||
bool ltr_required;
|
||||
unsigned int prv_offset;
|
||||
size_t prv_size_override;
|
||||
bool clk_gate;
|
||||
struct lpss_shared_clock *shared_clock;
|
||||
void (*setup)(struct lpss_private_data *pdata);
|
||||
};
|
||||
|
||||
static struct lpss_device_desc lpss_dma_desc = {
|
||||
@ -52,17 +66,76 @@ struct lpss_private_data {
|
||||
const struct lpss_device_desc *dev_desc;
|
||||
};
|
||||
|
||||
static void lpss_uart_setup(struct lpss_private_data *pdata)
|
||||
{
|
||||
unsigned int tx_int_offset = pdata->dev_desc->prv_offset + LPSS_TX_INT;
|
||||
u32 reg;
|
||||
|
||||
reg = readl(pdata->mmio_base + tx_int_offset);
|
||||
writel(reg | LPSS_TX_INT_MASK, pdata->mmio_base + tx_int_offset);
|
||||
}
|
||||
|
||||
static struct lpss_device_desc lpt_dev_desc = {
|
||||
.clk_required = true,
|
||||
.prv_offset = 0x800,
|
||||
.ltr_required = true,
|
||||
.clk_gate = true,
|
||||
};
|
||||
|
||||
static struct lpss_device_desc lpt_uart_dev_desc = {
|
||||
.clk_required = true,
|
||||
.prv_offset = 0x800,
|
||||
.ltr_required = true,
|
||||
.clk_gate = true,
|
||||
.setup = lpss_uart_setup,
|
||||
};
|
||||
|
||||
static struct lpss_device_desc lpt_sdio_dev_desc = {
|
||||
.prv_offset = 0x1000,
|
||||
.prv_size_override = 0x1018,
|
||||
.ltr_required = true,
|
||||
};
|
||||
|
||||
static struct lpss_shared_clock uart_clock = {
|
||||
.name = "uart_clk",
|
||||
.rate = 44236800,
|
||||
};
|
||||
|
||||
static struct lpss_device_desc byt_uart_dev_desc = {
|
||||
.clk_required = true,
|
||||
.prv_offset = 0x800,
|
||||
.clk_gate = true,
|
||||
.shared_clock = &uart_clock,
|
||||
.setup = lpss_uart_setup,
|
||||
};
|
||||
|
||||
static struct lpss_shared_clock spi_clock = {
|
||||
.name = "spi_clk",
|
||||
.rate = 50000000,
|
||||
};
|
||||
|
||||
static struct lpss_device_desc byt_spi_dev_desc = {
|
||||
.clk_required = true,
|
||||
.prv_offset = 0x400,
|
||||
.clk_gate = true,
|
||||
.shared_clock = &spi_clock,
|
||||
};
|
||||
|
||||
static struct lpss_device_desc byt_sdio_dev_desc = {
|
||||
.clk_required = true,
|
||||
};
|
||||
|
||||
static struct lpss_shared_clock i2c_clock = {
|
||||
.name = "i2c_clk",
|
||||
.rate = 100000000,
|
||||
};
|
||||
|
||||
static struct lpss_device_desc byt_i2c_dev_desc = {
|
||||
.clk_required = true,
|
||||
.prv_offset = 0x800,
|
||||
.shared_clock = &i2c_clock,
|
||||
};
|
||||
|
||||
static const struct acpi_device_id acpi_lpss_device_ids[] = {
|
||||
/* Generic LPSS devices */
|
||||
{ "INTL9C60", (unsigned long)&lpss_dma_desc },
|
||||
@ -72,11 +145,18 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
|
||||
{ "INT33C1", (unsigned long)&lpt_dev_desc },
|
||||
{ "INT33C2", (unsigned long)&lpt_dev_desc },
|
||||
{ "INT33C3", (unsigned long)&lpt_dev_desc },
|
||||
{ "INT33C4", (unsigned long)&lpt_dev_desc },
|
||||
{ "INT33C5", (unsigned long)&lpt_dev_desc },
|
||||
{ "INT33C4", (unsigned long)&lpt_uart_dev_desc },
|
||||
{ "INT33C5", (unsigned long)&lpt_uart_dev_desc },
|
||||
{ "INT33C6", (unsigned long)&lpt_sdio_dev_desc },
|
||||
{ "INT33C7", },
|
||||
|
||||
/* BayTrail LPSS devices */
|
||||
{ "80860F0A", (unsigned long)&byt_uart_dev_desc },
|
||||
{ "80860F0E", (unsigned long)&byt_spi_dev_desc },
|
||||
{ "80860F14", (unsigned long)&byt_sdio_dev_desc },
|
||||
{ "80860F41", (unsigned long)&byt_i2c_dev_desc },
|
||||
{ "INT33B2", },
|
||||
|
||||
{ }
|
||||
};
|
||||
|
||||
@ -98,7 +178,10 @@ static int register_device_clock(struct acpi_device *adev,
|
||||
struct lpss_private_data *pdata)
|
||||
{
|
||||
const struct lpss_device_desc *dev_desc = pdata->dev_desc;
|
||||
struct lpss_shared_clock *shared_clock = dev_desc->shared_clock;
|
||||
struct clk *clk = ERR_PTR(-ENODEV);
|
||||
struct lpss_clk_data *clk_data;
|
||||
const char *parent;
|
||||
|
||||
if (!lpss_clk_dev)
|
||||
lpt_register_clock_device();
|
||||
@ -117,14 +200,30 @@ static int register_device_clock(struct acpi_device *adev,
|
||||
|| pdata->mmio_size < dev_desc->prv_offset + LPSS_CLK_SIZE)
|
||||
return -ENODATA;
|
||||
|
||||
pdata->clk = clk_register_gate(NULL, dev_name(&adev->dev),
|
||||
clk_data->name, 0,
|
||||
parent = clk_data->name;
|
||||
|
||||
if (shared_clock) {
|
||||
clk = shared_clock->clk;
|
||||
if (!clk) {
|
||||
clk = clk_register_fixed_rate(NULL, shared_clock->name,
|
||||
"lpss_clk", 0,
|
||||
shared_clock->rate);
|
||||
shared_clock->clk = clk;
|
||||
}
|
||||
parent = shared_clock->name;
|
||||
}
|
||||
|
||||
if (dev_desc->clk_gate) {
|
||||
clk = clk_register_gate(NULL, dev_name(&adev->dev), parent, 0,
|
||||
pdata->mmio_base + dev_desc->prv_offset,
|
||||
0, 0, NULL);
|
||||
if (IS_ERR(pdata->clk))
|
||||
return PTR_ERR(pdata->clk);
|
||||
pdata->clk = clk;
|
||||
}
|
||||
|
||||
clk_register_clkdev(pdata->clk, NULL, dev_name(&adev->dev));
|
||||
if (IS_ERR(clk))
|
||||
return PTR_ERR(clk);
|
||||
|
||||
clk_register_clkdev(clk, NULL, dev_name(&adev->dev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -152,6 +251,9 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
|
||||
|
||||
list_for_each_entry(rentry, &resource_list, node)
|
||||
if (resource_type(&rentry->res) == IORESOURCE_MEM) {
|
||||
if (dev_desc->prv_size_override)
|
||||
pdata->mmio_size = dev_desc->prv_size_override;
|
||||
else
|
||||
pdata->mmio_size = resource_size(&rentry->res);
|
||||
pdata->mmio_base = ioremap(rentry->res.start,
|
||||
pdata->mmio_size);
|
||||
@ -182,6 +284,9 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (dev_desc->setup)
|
||||
dev_desc->setup(pdata);
|
||||
|
||||
adev->driver_data = pdata;
|
||||
ret = acpi_create_platform_device(adev, id);
|
||||
if (ret > 0)
|
||||
|
@ -28,6 +28,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/memory.h>
|
||||
#include <linux/memory_hotplug.h>
|
||||
|
||||
#include "internal.h"
|
||||
@ -166,13 +167,50 @@ static int acpi_memory_check_device(struct acpi_memory_device *mem_device)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long acpi_meminfo_start_pfn(struct acpi_memory_info *info)
|
||||
{
|
||||
return PFN_DOWN(info->start_addr);
|
||||
}
|
||||
|
||||
static unsigned long acpi_meminfo_end_pfn(struct acpi_memory_info *info)
|
||||
{
|
||||
return PFN_UP(info->start_addr + info->length-1);
|
||||
}
|
||||
|
||||
static int acpi_bind_memblk(struct memory_block *mem, void *arg)
|
||||
{
|
||||
return acpi_bind_one(&mem->dev, (acpi_handle)arg);
|
||||
}
|
||||
|
||||
static int acpi_bind_memory_blocks(struct acpi_memory_info *info,
|
||||
acpi_handle handle)
|
||||
{
|
||||
return walk_memory_range(acpi_meminfo_start_pfn(info),
|
||||
acpi_meminfo_end_pfn(info), (void *)handle,
|
||||
acpi_bind_memblk);
|
||||
}
|
||||
|
||||
static int acpi_unbind_memblk(struct memory_block *mem, void *arg)
|
||||
{
|
||||
acpi_unbind_one(&mem->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void acpi_unbind_memory_blocks(struct acpi_memory_info *info,
|
||||
acpi_handle handle)
|
||||
{
|
||||
walk_memory_range(acpi_meminfo_start_pfn(info),
|
||||
acpi_meminfo_end_pfn(info), NULL, acpi_unbind_memblk);
|
||||
}
|
||||
|
||||
static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
|
||||
{
|
||||
acpi_handle handle = mem_device->device->handle;
|
||||
int result, num_enabled = 0;
|
||||
struct acpi_memory_info *info;
|
||||
int node;
|
||||
|
||||
node = acpi_get_node(mem_device->device->handle);
|
||||
node = acpi_get_node(handle);
|
||||
/*
|
||||
* Tell the VM there is more memory here...
|
||||
* Note: Assume that this function returns zero on success
|
||||
@ -203,6 +241,12 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
|
||||
if (result && result != -EEXIST)
|
||||
continue;
|
||||
|
||||
result = acpi_bind_memory_blocks(info, handle);
|
||||
if (result) {
|
||||
acpi_unbind_memory_blocks(info, handle);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
info->enabled = 1;
|
||||
|
||||
/*
|
||||
@ -227,12 +271,11 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device)
|
||||
static void acpi_memory_remove_memory(struct acpi_memory_device *mem_device)
|
||||
{
|
||||
int result = 0, nid;
|
||||
acpi_handle handle = mem_device->device->handle;
|
||||
struct acpi_memory_info *info, *n;
|
||||
|
||||
nid = acpi_get_node(mem_device->device->handle);
|
||||
int nid = acpi_get_node(handle);
|
||||
|
||||
list_for_each_entry_safe(info, n, &mem_device->res_list, list) {
|
||||
if (!info->enabled)
|
||||
@ -240,15 +283,12 @@ static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device)
|
||||
|
||||
if (nid < 0)
|
||||
nid = memory_add_physaddr_to_nid(info->start_addr);
|
||||
result = remove_memory(nid, info->start_addr, info->length);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
acpi_unbind_memory_blocks(info, handle);
|
||||
remove_memory(nid, info->start_addr, info->length);
|
||||
list_del(&info->list);
|
||||
kfree(info);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void acpi_memory_device_free(struct acpi_memory_device *mem_device)
|
||||
@ -300,7 +340,7 @@ static int acpi_memory_device_add(struct acpi_device *device,
|
||||
if (result) {
|
||||
dev_err(&device->dev, "acpi_memory_enable_device() error\n");
|
||||
acpi_memory_device_free(mem_device);
|
||||
return -ENODEV;
|
||||
return result;
|
||||
}
|
||||
|
||||
dev_dbg(&device->dev, "Memory device configured by ACPI\n");
|
||||
|
494
drivers/acpi/acpi_processor.c
Normal file
494
drivers/acpi/acpi_processor.c
Normal file
@ -0,0 +1,494 @@
|
||||
/*
|
||||
* acpi_processor.c - ACPI processor enumeration support
|
||||
*
|
||||
* Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
|
||||
* Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
|
||||
* Copyright (C) 2004 Dominik Brodowski <linux@brodo.de>
|
||||
* Copyright (C) 2004 Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
|
||||
* Copyright (C) 2013, Intel Corporation
|
||||
* Rafael J. Wysocki <rafael.j.wysocki@intel.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <acpi/processor.h>
|
||||
|
||||
#include <asm/cpu.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
|
||||
|
||||
ACPI_MODULE_NAME("processor");
|
||||
|
||||
DEFINE_PER_CPU(struct acpi_processor *, processors);
|
||||
EXPORT_PER_CPU_SYMBOL(processors);
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Errata Handling
|
||||
-------------------------------------------------------------------------- */
|
||||
|
||||
struct acpi_processor_errata errata __read_mostly;
|
||||
EXPORT_SYMBOL_GPL(errata);
|
||||
|
||||
static int acpi_processor_errata_piix4(struct pci_dev *dev)
|
||||
{
|
||||
u8 value1 = 0;
|
||||
u8 value2 = 0;
|
||||
|
||||
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Note that 'dev' references the PIIX4 ACPI Controller.
|
||||
*/
|
||||
|
||||
switch (dev->revision) {
|
||||
case 0:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 A-step\n"));
|
||||
break;
|
||||
case 1:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4 B-step\n"));
|
||||
break;
|
||||
case 2:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4E\n"));
|
||||
break;
|
||||
case 3:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found PIIX4M\n"));
|
||||
break;
|
||||
default:
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unknown PIIX4\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
switch (dev->revision) {
|
||||
|
||||
case 0: /* PIIX4 A-step */
|
||||
case 1: /* PIIX4 B-step */
|
||||
/*
|
||||
* See specification changes #13 ("Manual Throttle Duty Cycle")
|
||||
* and #14 ("Enabling and Disabling Manual Throttle"), plus
|
||||
* erratum #5 ("STPCLK# Deassertion Time") from the January
|
||||
* 2002 PIIX4 specification update. Applies to only older
|
||||
* PIIX4 models.
|
||||
*/
|
||||
errata.piix4.throttle = 1;
|
||||
|
||||
case 2: /* PIIX4E */
|
||||
case 3: /* PIIX4M */
|
||||
/*
|
||||
* See erratum #18 ("C3 Power State/BMIDE and Type-F DMA
|
||||
* Livelock") from the January 2002 PIIX4 specification update.
|
||||
* Applies to all PIIX4 models.
|
||||
*/
|
||||
|
||||
/*
|
||||
* BM-IDE
|
||||
* ------
|
||||
* Find the PIIX4 IDE Controller and get the Bus Master IDE
|
||||
* Status register address. We'll use this later to read
|
||||
* each IDE controller's DMA status to make sure we catch all
|
||||
* DMA activity.
|
||||
*/
|
||||
dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_82371AB,
|
||||
PCI_ANY_ID, PCI_ANY_ID, NULL);
|
||||
if (dev) {
|
||||
errata.piix4.bmisx = pci_resource_start(dev, 4);
|
||||
pci_dev_put(dev);
|
||||
}
|
||||
|
||||
/*
|
||||
* Type-F DMA
|
||||
* ----------
|
||||
* Find the PIIX4 ISA Controller and read the Motherboard
|
||||
* DMA controller's status to see if Type-F (Fast) DMA mode
|
||||
* is enabled (bit 7) on either channel. Note that we'll
|
||||
* disable C3 support if this is enabled, as some legacy
|
||||
* devices won't operate well if fast DMA is disabled.
|
||||
*/
|
||||
dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_82371AB_0,
|
||||
PCI_ANY_ID, PCI_ANY_ID, NULL);
|
||||
if (dev) {
|
||||
pci_read_config_byte(dev, 0x76, &value1);
|
||||
pci_read_config_byte(dev, 0x77, &value2);
|
||||
if ((value1 & 0x80) || (value2 & 0x80))
|
||||
errata.piix4.fdma = 1;
|
||||
pci_dev_put(dev);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (errata.piix4.bmisx)
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Bus master activity detection (BM-IDE) erratum enabled\n"));
|
||||
if (errata.piix4.fdma)
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Type-F DMA livelock erratum (C3 disabled)\n"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpi_processor_errata(struct acpi_processor *pr)
|
||||
{
|
||||
int result = 0;
|
||||
struct pci_dev *dev = NULL;
|
||||
|
||||
|
||||
if (!pr)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* PIIX4
|
||||
*/
|
||||
dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_82371AB_3, PCI_ANY_ID,
|
||||
PCI_ANY_ID, NULL);
|
||||
if (dev) {
|
||||
result = acpi_processor_errata_piix4(dev);
|
||||
pci_dev_put(dev);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
Initialization
|
||||
-------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef CONFIG_ACPI_HOTPLUG_CPU
|
||||
static int acpi_processor_hotadd_init(struct acpi_processor *pr)
|
||||
{
|
||||
unsigned long long sta;
|
||||
acpi_status status;
|
||||
int ret;
|
||||
|
||||
status = acpi_evaluate_integer(pr->handle, "_STA", NULL, &sta);
|
||||
if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT))
|
||||
return -ENODEV;
|
||||
|
||||
ret = acpi_map_lsapic(pr->handle, &pr->id);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = arch_register_cpu(pr->id);
|
||||
if (ret) {
|
||||
acpi_unmap_lsapic(pr->id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* CPU got hot-added, but cpu_data is not initialized yet. Set a flag
|
||||
* to delay cpu_idle/throttling initialization and do it when the CPU
|
||||
* gets online for the first time.
|
||||
*/
|
||||
pr_info("CPU%d has been hot-added\n", pr->id);
|
||||
pr->flags.need_hotplug_init = 1;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static inline int acpi_processor_hotadd_init(struct acpi_processor *pr)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif /* CONFIG_ACPI_HOTPLUG_CPU */
|
||||
|
||||
static int acpi_processor_get_info(struct acpi_device *device)
|
||||
{
|
||||
union acpi_object object = { 0 };
|
||||
struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
|
||||
struct acpi_processor *pr = acpi_driver_data(device);
|
||||
int cpu_index, device_declaration = 0;
|
||||
acpi_status status = AE_OK;
|
||||
static int cpu0_initialized;
|
||||
|
||||
if (num_online_cpus() > 1)
|
||||
errata.smp = TRUE;
|
||||
|
||||
acpi_processor_errata(pr);
|
||||
|
||||
/*
|
||||
* Check to see if we have bus mastering arbitration control. This
|
||||
* is required for proper C3 usage (to maintain cache coherency).
|
||||
*/
|
||||
if (acpi_gbl_FADT.pm2_control_block && acpi_gbl_FADT.pm2_control_length) {
|
||||
pr->flags.bm_control = 1;
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"Bus mastering arbitration control present\n"));
|
||||
} else
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
|
||||
"No bus mastering arbitration control\n"));
|
||||
|
||||
if (!strcmp(acpi_device_hid(device), ACPI_PROCESSOR_OBJECT_HID)) {
|
||||
/* Declared with "Processor" statement; match ProcessorID */
|
||||
status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_err(&device->dev,
|
||||
"Failed to evaluate processor object (0x%x)\n",
|
||||
status);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* TBD: Synch processor ID (via LAPIC/LSAPIC structures) on SMP.
|
||||
* >>> 'acpi_get_processor_id(acpi_id, &id)' in
|
||||
* arch/xxx/acpi.c
|
||||
*/
|
||||
pr->acpi_id = object.processor.proc_id;
|
||||
} else {
|
||||
/*
|
||||
* Declared with "Device" statement; match _UID.
|
||||
* Note that we don't handle string _UIDs yet.
|
||||
*/
|
||||
unsigned long long value;
|
||||
status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID,
|
||||
NULL, &value);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_err(&device->dev,
|
||||
"Failed to evaluate processor _UID (0x%x)\n",
|
||||
status);
|
||||
return -ENODEV;
|
||||
}
|
||||
device_declaration = 1;
|
||||
pr->acpi_id = value;
|
||||
}
|
||||
cpu_index = acpi_get_cpuid(pr->handle, device_declaration, pr->acpi_id);
|
||||
|
||||
/* Handle UP system running SMP kernel, with no LAPIC in MADT */
|
||||
if (!cpu0_initialized && (cpu_index == -1) &&
|
||||
(num_online_cpus() == 1)) {
|
||||
cpu_index = 0;
|
||||
}
|
||||
|
||||
cpu0_initialized = 1;
|
||||
|
||||
pr->id = cpu_index;
|
||||
|
||||
/*
|
||||
* Extra Processor objects may be enumerated on MP systems with
|
||||
* less than the max # of CPUs. They should be ignored _iff
|
||||
* they are physically not present.
|
||||
*/
|
||||
if (pr->id == -1) {
|
||||
int ret = acpi_processor_hotadd_init(pr);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* On some boxes several processors use the same processor bus id.
|
||||
* But they are located in different scope. For example:
|
||||
* \_SB.SCK0.CPU0
|
||||
* \_SB.SCK1.CPU0
|
||||
* Rename the processor device bus id. And the new bus id will be
|
||||
* generated as the following format:
|
||||
* CPU+CPU ID.
|
||||
*/
|
||||
sprintf(acpi_device_bid(device), "CPU%X", pr->id);
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Processor [%d:%d]\n", pr->id,
|
||||
pr->acpi_id));
|
||||
|
||||
if (!object.processor.pblk_address)
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n"));
|
||||
else if (object.processor.pblk_length != 6)
|
||||
dev_err(&device->dev, "Invalid PBLK length [%d]\n",
|
||||
object.processor.pblk_length);
|
||||
else {
|
||||
pr->throttling.address = object.processor.pblk_address;
|
||||
pr->throttling.duty_offset = acpi_gbl_FADT.duty_offset;
|
||||
pr->throttling.duty_width = acpi_gbl_FADT.duty_width;
|
||||
|
||||
pr->pblk = object.processor.pblk_address;
|
||||
|
||||
/*
|
||||
* We don't care about error returns - we just try to mark
|
||||
* these reserved so that nobody else is confused into thinking
|
||||
* that this region might be unused..
|
||||
*
|
||||
* (In particular, allocating the IO range for Cardbus)
|
||||
*/
|
||||
request_region(pr->throttling.address, 6, "ACPI CPU throttle");
|
||||
}
|
||||
|
||||
/*
|
||||
* If ACPI describes a slot number for this CPU, we can use it to
|
||||
* ensure we get the right value in the "physical id" field
|
||||
* of /proc/cpuinfo
|
||||
*/
|
||||
status = acpi_evaluate_object(pr->handle, "_SUN", NULL, &buffer);
|
||||
if (ACPI_SUCCESS(status))
|
||||
arch_fix_phys_package_id(pr->id, object.integer.value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not put anything in here which needs the core to be online.
|
||||
* For example MSR access or setting up things which check for cpuinfo_x86
|
||||
* (cpu_data(cpu)) values, like CPU feature flags, family, model, etc.
|
||||
* Such things have to be put in and set up by the processor driver's .probe().
|
||||
*/
|
||||
static DEFINE_PER_CPU(void *, processor_device_array);
|
||||
|
||||
static int __cpuinit acpi_processor_add(struct acpi_device *device,
|
||||
const struct acpi_device_id *id)
|
||||
{
|
||||
struct acpi_processor *pr;
|
||||
struct device *dev;
|
||||
int result = 0;
|
||||
|
||||
pr = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
|
||||
if (!pr)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!zalloc_cpumask_var(&pr->throttling.shared_cpu_map, GFP_KERNEL)) {
|
||||
result = -ENOMEM;
|
||||
goto err_free_pr;
|
||||
}
|
||||
|
||||
pr->handle = device->handle;
|
||||
strcpy(acpi_device_name(device), ACPI_PROCESSOR_DEVICE_NAME);
|
||||
strcpy(acpi_device_class(device), ACPI_PROCESSOR_CLASS);
|
||||
device->driver_data = pr;
|
||||
|
||||
result = acpi_processor_get_info(device);
|
||||
if (result) /* Processor is not physically present or unavailable */
|
||||
return 0;
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (pr->id >= setup_max_cpus && pr->id != 0)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
BUG_ON(pr->id >= nr_cpu_ids);
|
||||
|
||||
/*
|
||||
* Buggy BIOS check.
|
||||
* ACPI id of processors can be reported wrongly by the BIOS.
|
||||
* Don't trust it blindly
|
||||
*/
|
||||
if (per_cpu(processor_device_array, pr->id) != NULL &&
|
||||
per_cpu(processor_device_array, pr->id) != device) {
|
||||
dev_warn(&device->dev,
|
||||
"BIOS reported wrong ACPI id %d for the processor\n",
|
||||
pr->id);
|
||||
/* Give up, but do not abort the namespace scan. */
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* processor_device_array is not cleared on errors to allow buggy BIOS
|
||||
* checks.
|
||||
*/
|
||||
per_cpu(processor_device_array, pr->id) = device;
|
||||
per_cpu(processors, pr->id) = pr;
|
||||
|
||||
dev = get_cpu_device(pr->id);
|
||||
if (!dev) {
|
||||
result = -ENODEV;
|
||||
goto err;
|
||||
}
|
||||
|
||||
result = acpi_bind_one(dev, pr->handle);
|
||||
if (result)
|
||||
goto err;
|
||||
|
||||
pr->dev = dev;
|
||||
dev->offline = pr->flags.need_hotplug_init;
|
||||
|
||||
/* Trigger the processor driver's .probe() if present. */
|
||||
if (device_attach(dev) >= 0)
|
||||
return 1;
|
||||
|
||||
dev_err(dev, "Processor driver could not be attached\n");
|
||||
acpi_unbind_one(dev);
|
||||
|
||||
err:
|
||||
free_cpumask_var(pr->throttling.shared_cpu_map);
|
||||
device->driver_data = NULL;
|
||||
per_cpu(processors, pr->id) = NULL;
|
||||
err_free_pr:
|
||||
kfree(pr);
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ACPI_HOTPLUG_CPU
|
||||
/* --------------------------------------------------------------------------
|
||||
Removal
|
||||
-------------------------------------------------------------------------- */
|
||||
|
||||
static void acpi_processor_remove(struct acpi_device *device)
|
||||
{
|
||||
struct acpi_processor *pr;
|
||||
|
||||
if (!device || !acpi_driver_data(device))
|
||||
return;
|
||||
|
||||
pr = acpi_driver_data(device);
|
||||
if (pr->id >= nr_cpu_ids)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* The only reason why we ever get here is CPU hot-removal. The CPU is
|
||||
* already offline and the ACPI device removal locking prevents it from
|
||||
* being put back online at this point.
|
||||
*
|
||||
* Unbind the driver from the processor device and detach it from the
|
||||
* ACPI companion object.
|
||||
*/
|
||||
device_release_driver(pr->dev);
|
||||
acpi_unbind_one(pr->dev);
|
||||
|
||||
/* Clean up. */
|
||||
per_cpu(processor_device_array, pr->id) = NULL;
|
||||
per_cpu(processors, pr->id) = NULL;
|
||||
try_offline_node(cpu_to_node(pr->id));
|
||||
|
||||
/* Remove the CPU. */
|
||||
get_online_cpus();
|
||||
arch_unregister_cpu(pr->id);
|
||||
acpi_unmap_lsapic(pr->id);
|
||||
put_online_cpus();
|
||||
|
||||
out:
|
||||
free_cpumask_var(pr->throttling.shared_cpu_map);
|
||||
kfree(pr);
|
||||
}
|
||||
#endif /* CONFIG_ACPI_HOTPLUG_CPU */
|
||||
|
||||
/*
|
||||
* The following ACPI IDs are known to be suitable for representing as
|
||||
* processor devices.
|
||||
*/
|
||||
static const struct acpi_device_id processor_device_ids[] = {
|
||||
|
||||
{ ACPI_PROCESSOR_OBJECT_HID, },
|
||||
{ ACPI_PROCESSOR_DEVICE_HID, },
|
||||
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct acpi_scan_handler __refdata processor_handler = {
|
||||
.ids = processor_device_ids,
|
||||
.attach = acpi_processor_add,
|
||||
#ifdef CONFIG_ACPI_HOTPLUG_CPU
|
||||
.detach = acpi_processor_remove,
|
||||
#endif
|
||||
.hotplug = {
|
||||
.enabled = true,
|
||||
},
|
||||
};
|
||||
|
||||
void __init acpi_processor_init(void)
|
||||
{
|
||||
acpi_scan_add_handler_with_hotplug(&processor_handler, "processor");
|
||||
}
|
@ -83,6 +83,7 @@ acpi-$(ACPI_FUTURE_USAGE) += hwtimer.o
|
||||
acpi-y += \
|
||||
nsaccess.o \
|
||||
nsalloc.o \
|
||||
nsarguments.o \
|
||||
nsconvert.o \
|
||||
nsdump.o \
|
||||
nseval.o \
|
||||
@ -137,6 +138,7 @@ acpi-y += \
|
||||
tbfadt.o \
|
||||
tbfind.o \
|
||||
tbinstal.o \
|
||||
tbprint.o \
|
||||
tbutils.o \
|
||||
tbxface.o \
|
||||
tbxfload.o \
|
||||
@ -145,11 +147,13 @@ acpi-y += \
|
||||
acpi-y += \
|
||||
utaddress.o \
|
||||
utalloc.o \
|
||||
utbuffer.o \
|
||||
utcopy.o \
|
||||
utexcep.o \
|
||||
utdebug.o \
|
||||
utdecode.o \
|
||||
utdelete.o \
|
||||
uterror.o \
|
||||
uteval.o \
|
||||
utglobal.o \
|
||||
utids.o \
|
||||
|
@ -132,6 +132,12 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_truncate_io_addresses, FALSE);
|
||||
*/
|
||||
u8 ACPI_INIT_GLOBAL(acpi_gbl_disable_auto_repair, FALSE);
|
||||
|
||||
/*
|
||||
* Optionally do not load any SSDTs from the RSDT/XSDT during initialization.
|
||||
* This can be useful for debugging ACPI problems on some machines.
|
||||
*/
|
||||
u8 ACPI_INIT_GLOBAL(acpi_gbl_disable_ssdt_table_load, FALSE);
|
||||
|
||||
/* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */
|
||||
|
||||
struct acpi_table_fadt acpi_gbl_FADT;
|
||||
|
@ -362,23 +362,6 @@ union acpi_predefined_info {
|
||||
|
||||
#pragma pack()
|
||||
|
||||
/* Data block used during object validation */
|
||||
|
||||
struct acpi_predefined_data {
|
||||
char *pathname;
|
||||
const union acpi_predefined_info *predefined;
|
||||
union acpi_operand_object *parent_package;
|
||||
struct acpi_namespace_node *node;
|
||||
u32 flags;
|
||||
u32 return_btype;
|
||||
u8 node_flags;
|
||||
};
|
||||
|
||||
/* Defines for Flags field above */
|
||||
|
||||
#define ACPI_OBJECT_REPAIRED 1
|
||||
#define ACPI_OBJECT_WRAPPED 2
|
||||
|
||||
/* Return object auto-repair info */
|
||||
|
||||
typedef acpi_status(*acpi_object_converter) (union acpi_operand_object
|
||||
|
@ -378,6 +378,7 @@
|
||||
#define ACPI_ERROR_METHOD(s, n, p, e) acpi_ut_method_error (AE_INFO, s, n, p, e);
|
||||
#define ACPI_WARN_PREDEFINED(plist) acpi_ut_predefined_warning plist
|
||||
#define ACPI_INFO_PREDEFINED(plist) acpi_ut_predefined_info plist
|
||||
#define ACPI_BIOS_ERROR_PREDEFINED(plist) acpi_ut_predefined_bios_error plist
|
||||
|
||||
#else
|
||||
|
||||
@ -387,6 +388,7 @@
|
||||
#define ACPI_ERROR_METHOD(s, n, p, e)
|
||||
#define ACPI_WARN_PREDEFINED(plist)
|
||||
#define ACPI_INFO_PREDEFINED(plist)
|
||||
#define ACPI_BIOS_ERROR_PREDEFINED(plist)
|
||||
|
||||
#endif /* ACPI_NO_ERROR_MESSAGES */
|
||||
|
||||
|
@ -223,22 +223,33 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info);
|
||||
void acpi_ns_exec_module_code_list(void);
|
||||
|
||||
/*
|
||||
* nspredef - Support for predefined/reserved names
|
||||
* nsarguments - Argument count/type checking for predefined/reserved names
|
||||
*/
|
||||
acpi_status
|
||||
acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
|
||||
u32 user_param_count,
|
||||
acpi_status return_status,
|
||||
union acpi_operand_object **return_object);
|
||||
|
||||
void
|
||||
acpi_ns_check_parameter_count(char *pathname,
|
||||
acpi_ns_check_argument_count(char *pathname,
|
||||
struct acpi_namespace_node *node,
|
||||
u32 user_param_count,
|
||||
const union acpi_predefined_info *info);
|
||||
|
||||
void
|
||||
acpi_ns_check_acpi_compliance(char *pathname,
|
||||
struct acpi_namespace_node *node,
|
||||
const union acpi_predefined_info *predefined);
|
||||
|
||||
void acpi_ns_check_argument_types(struct acpi_evaluate_info *info);
|
||||
|
||||
/*
|
||||
* nspredef - Return value checking for predefined/reserved names
|
||||
*/
|
||||
acpi_status
|
||||
acpi_ns_check_object_type(struct acpi_predefined_data *data,
|
||||
acpi_ns_check_return_value(struct acpi_namespace_node *node,
|
||||
struct acpi_evaluate_info *info,
|
||||
u32 user_param_count,
|
||||
acpi_status return_status,
|
||||
union acpi_operand_object **return_object);
|
||||
|
||||
acpi_status
|
||||
acpi_ns_check_object_type(struct acpi_evaluate_info *info,
|
||||
union acpi_operand_object **return_object_ptr,
|
||||
u32 expected_btypes, u32 package_index);
|
||||
|
||||
@ -246,7 +257,7 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data,
|
||||
* nsprepkg - Validation of predefined name packages
|
||||
*/
|
||||
acpi_status
|
||||
acpi_ns_check_package(struct acpi_predefined_data *data,
|
||||
acpi_ns_check_package(struct acpi_evaluate_info *info,
|
||||
union acpi_operand_object **return_object_ptr);
|
||||
|
||||
/*
|
||||
@ -308,24 +319,24 @@ acpi_ns_get_attached_data(struct acpi_namespace_node *node,
|
||||
* predefined methods/objects
|
||||
*/
|
||||
acpi_status
|
||||
acpi_ns_simple_repair(struct acpi_predefined_data *data,
|
||||
acpi_ns_simple_repair(struct acpi_evaluate_info *info,
|
||||
u32 expected_btypes,
|
||||
u32 package_index,
|
||||
union acpi_operand_object **return_object_ptr);
|
||||
|
||||
acpi_status
|
||||
acpi_ns_wrap_with_package(struct acpi_predefined_data *data,
|
||||
acpi_ns_wrap_with_package(struct acpi_evaluate_info *info,
|
||||
union acpi_operand_object *original_object,
|
||||
union acpi_operand_object **obj_desc_ptr);
|
||||
|
||||
acpi_status
|
||||
acpi_ns_repair_null_element(struct acpi_predefined_data *data,
|
||||
acpi_ns_repair_null_element(struct acpi_evaluate_info *info,
|
||||
u32 expected_btypes,
|
||||
u32 package_index,
|
||||
union acpi_operand_object **return_object_ptr);
|
||||
|
||||
void
|
||||
acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
|
||||
acpi_ns_remove_null_elements(struct acpi_evaluate_info *info,
|
||||
u8 package_type,
|
||||
union acpi_operand_object *obj_desc);
|
||||
|
||||
@ -334,7 +345,7 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
|
||||
* predefined methods/objects
|
||||
*/
|
||||
acpi_status
|
||||
acpi_ns_complex_repairs(struct acpi_predefined_data *data,
|
||||
acpi_ns_complex_repairs(struct acpi_evaluate_info *info,
|
||||
struct acpi_namespace_node *node,
|
||||
acpi_status validate_status,
|
||||
union acpi_operand_object **return_object_ptr);
|
||||
|
@ -128,8 +128,8 @@ enum acpi_return_package_types {
|
||||
#define ARG_COUNT_IS_MINIMUM 0x8000
|
||||
#define METHOD_MAX_ARG_TYPE ACPI_TYPE_PACKAGE
|
||||
|
||||
#define METHOD_GET_COUNT(arg_list) (arg_list & METHOD_ARG_MASK)
|
||||
#define METHOD_GET_NEXT_ARG(arg_list) (arg_list >> METHOD_ARG_BIT_WIDTH)
|
||||
#define METHOD_GET_ARG_COUNT(arg_list) ((arg_list) & METHOD_ARG_MASK)
|
||||
#define METHOD_GET_NEXT_TYPE(arg_list) (((arg_list) >>= METHOD_ARG_BIT_WIDTH) & METHOD_ARG_MASK)
|
||||
|
||||
/* Macros used to build the predefined info table */
|
||||
|
||||
|
@ -178,26 +178,42 @@ union acpi_aml_operands {
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure used to pass object evaluation parameters.
|
||||
* Structure used to pass object evaluation information and parameters.
|
||||
* Purpose is to reduce CPU stack use.
|
||||
*/
|
||||
struct acpi_evaluate_info {
|
||||
struct acpi_namespace_node *prefix_node;
|
||||
char *pathname;
|
||||
union acpi_operand_object *obj_desc;
|
||||
union acpi_operand_object **parameters;
|
||||
struct acpi_namespace_node *resolved_node;
|
||||
union acpi_operand_object *return_object;
|
||||
u8 param_count;
|
||||
u8 pass_number;
|
||||
u8 return_object_type;
|
||||
u8 flags;
|
||||
/* The first 3 elements are passed by the caller to acpi_ns_evaluate */
|
||||
|
||||
struct acpi_namespace_node *prefix_node; /* Input: starting node */
|
||||
char *relative_pathname; /* Input: path relative to prefix_node */
|
||||
union acpi_operand_object **parameters; /* Input: argument list */
|
||||
|
||||
struct acpi_namespace_node *node; /* Resolved node (prefix_node:relative_pathname) */
|
||||
union acpi_operand_object *obj_desc; /* Object attached to the resolved node */
|
||||
char *full_pathname; /* Full pathname of the resolved node */
|
||||
|
||||
const union acpi_predefined_info *predefined; /* Used if Node is a predefined name */
|
||||
union acpi_operand_object *return_object; /* Object returned from the evaluation */
|
||||
union acpi_operand_object *parent_package; /* Used if return object is a Package */
|
||||
|
||||
u32 return_flags; /* Used for return value analysis */
|
||||
u32 return_btype; /* Bitmapped type of the returned object */
|
||||
u16 param_count; /* Count of the input argument list */
|
||||
u8 pass_number; /* Parser pass number */
|
||||
u8 return_object_type; /* Object type of the returned object */
|
||||
u8 node_flags; /* Same as Node->Flags */
|
||||
u8 flags; /* General flags */
|
||||
};
|
||||
|
||||
/* Values for Flags above */
|
||||
|
||||
#define ACPI_IGNORE_RETURN_VALUE 1
|
||||
|
||||
/* Defines for return_flags field above */
|
||||
|
||||
#define ACPI_OBJECT_REPAIRED 1
|
||||
#define ACPI_OBJECT_WRAPPED 2
|
||||
|
||||
/* Info used by acpi_ns_initialize_devices */
|
||||
|
||||
struct acpi_device_walk_info {
|
||||
|
@ -87,6 +87,48 @@ extern const char *acpi_gbl_fc_decode[];
|
||||
extern const char *acpi_gbl_pt_decode[];
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For the iASL compiler case, the output is redirected to stderr so that
|
||||
* any of the various ACPI errors and warnings do not appear in the output
|
||||
* files, for either the compiler or disassembler portions of the tool.
|
||||
*/
|
||||
#ifdef ACPI_ASL_COMPILER
|
||||
|
||||
#include <stdio.h>
|
||||
extern FILE *acpi_gbl_output_file;
|
||||
|
||||
#define ACPI_MSG_REDIRECT_BEGIN \
|
||||
FILE *output_file = acpi_gbl_output_file; \
|
||||
acpi_os_redirect_output (stderr);
|
||||
|
||||
#define ACPI_MSG_REDIRECT_END \
|
||||
acpi_os_redirect_output (output_file);
|
||||
|
||||
#else
|
||||
/*
|
||||
* non-iASL case - no redirection, nothing to do
|
||||
*/
|
||||
#define ACPI_MSG_REDIRECT_BEGIN
|
||||
#define ACPI_MSG_REDIRECT_END
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Common error message prefixes
|
||||
*/
|
||||
#define ACPI_MSG_ERROR "ACPI Error: "
|
||||
#define ACPI_MSG_EXCEPTION "ACPI Exception: "
|
||||
#define ACPI_MSG_WARNING "ACPI Warning: "
|
||||
#define ACPI_MSG_INFO "ACPI: "
|
||||
|
||||
#define ACPI_MSG_BIOS_ERROR "ACPI BIOS Error (bug): "
|
||||
#define ACPI_MSG_BIOS_WARNING "ACPI BIOS Warning (bug): "
|
||||
|
||||
/*
|
||||
* Common message suffix
|
||||
*/
|
||||
#define ACPI_MSG_SUFFIX \
|
||||
acpi_os_printf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number)
|
||||
|
||||
/* Types for Resource descriptor entries */
|
||||
|
||||
#define ACPI_INVALID_RESOURCE 0
|
||||
@ -578,7 +620,7 @@ void acpi_ut_print_string(char *string, u8 max_length);
|
||||
|
||||
void ut_convert_backslashes(char *pathname);
|
||||
|
||||
u8 acpi_ut_valid_acpi_name(u32 name);
|
||||
u8 acpi_ut_valid_acpi_name(char *name);
|
||||
|
||||
u8 acpi_ut_valid_acpi_char(char character, u32 position);
|
||||
|
||||
@ -670,6 +712,12 @@ acpi_ut_predefined_info(const char *module_name,
|
||||
u32 line_number,
|
||||
char *pathname, u8 node_flags, const char *format, ...);
|
||||
|
||||
void ACPI_INTERNAL_VAR_XFACE
|
||||
acpi_ut_predefined_bios_error(const char *module_name,
|
||||
u32 line_number,
|
||||
char *pathname,
|
||||
u8 node_flags, const char *format, ...);
|
||||
|
||||
void
|
||||
acpi_ut_namespace_error(const char *module_name,
|
||||
u32 line_number,
|
||||
|
@ -78,7 +78,6 @@ acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
|
||||
|
||||
switch (op->common.aml_opcode) {
|
||||
case AML_WHILE_OP:
|
||||
|
||||
/*
|
||||
* If this is an additional iteration of a while loop, continue.
|
||||
* There is no need to allocate a new control state.
|
||||
@ -99,7 +98,6 @@ acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
|
||||
/*lint -fallthrough */
|
||||
|
||||
case AML_IF_OP:
|
||||
|
||||
/*
|
||||
* IF/WHILE: Create a new control state to manage these
|
||||
* constructs. We need to manage these as a stack, in order
|
||||
@ -142,6 +140,7 @@ acpi_ds_exec_begin_control_op(struct acpi_walk_state *walk_state,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -344,6 +343,7 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
|
||||
case AML_NOOP_OP:
|
||||
|
||||
/* Just do nothing! */
|
||||
|
||||
break;
|
||||
|
||||
case AML_BREAK_POINT_OP:
|
||||
|
@ -563,21 +563,25 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
|
||||
*/
|
||||
switch (walk_state->opcode) {
|
||||
case AML_FIELD_OP:
|
||||
|
||||
arg = acpi_ps_get_arg(op, 2);
|
||||
type = ACPI_TYPE_LOCAL_REGION_FIELD;
|
||||
break;
|
||||
|
||||
case AML_BANK_FIELD_OP:
|
||||
|
||||
arg = acpi_ps_get_arg(op, 4);
|
||||
type = ACPI_TYPE_LOCAL_BANK_FIELD;
|
||||
break;
|
||||
|
||||
case AML_INDEX_FIELD_OP:
|
||||
|
||||
arg = acpi_ps_get_arg(op, 3);
|
||||
type = ACPI_TYPE_LOCAL_INDEX_FIELD;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
|
@ -127,6 +127,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -285,6 +285,7 @@ acpi_ds_method_data_get_node(u8 type,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ACPI_ERROR((AE_INFO, "Type %u is invalid", type));
|
||||
return_ACPI_STATUS(AE_TYPE);
|
||||
}
|
||||
@ -428,7 +429,6 @@ acpi_ds_method_data_get_value(u8 type,
|
||||
return_ACPI_STATUS(AE_AML_UNINITIALIZED_ARG);
|
||||
|
||||
case ACPI_REFCLASS_LOCAL:
|
||||
|
||||
/*
|
||||
* No error message for this case, will be trapped again later to
|
||||
* detect and ignore cases of Store(local_x,local_x)
|
||||
|
@ -648,7 +648,6 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
|
||||
|
||||
switch (obj_desc->common.type) {
|
||||
case ACPI_TYPE_BUFFER:
|
||||
|
||||
/*
|
||||
* Defer evaluation of Buffer term_arg operand
|
||||
*/
|
||||
@ -660,7 +659,6 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_PACKAGE:
|
||||
|
||||
/*
|
||||
* Defer evaluation of Package term_arg operand
|
||||
*/
|
||||
@ -741,6 +739,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ACPI_ERROR((AE_INFO, "Unknown Integer type 0x%X",
|
||||
op_info->type));
|
||||
status = AE_AML_OPERAND_TYPE;
|
||||
|
@ -636,6 +636,7 @@ acpi_ds_eval_data_object_operands(struct acpi_walk_state *walk_state,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return_ACPI_STATUS(AE_AML_BAD_OPCODE);
|
||||
}
|
||||
|
||||
|
@ -240,7 +240,6 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
|
||||
|
||||
case AML_IF_OP:
|
||||
case AML_WHILE_OP:
|
||||
|
||||
/*
|
||||
* If we are executing the predicate AND this is the predicate op,
|
||||
* we will use the return value
|
||||
@ -254,7 +253,9 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Ignore other control opcodes */
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -263,7 +264,6 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
|
||||
goto result_not_used;
|
||||
|
||||
case AML_CLASS_CREATE:
|
||||
|
||||
/*
|
||||
* These opcodes allow term_arg(s) as operands and therefore
|
||||
* the operands can be method calls. The result is used.
|
||||
@ -292,7 +292,6 @@ acpi_ds_is_result_used(union acpi_parse_object * op,
|
||||
goto result_not_used;
|
||||
|
||||
default:
|
||||
|
||||
/*
|
||||
* In all other cases. the parent will actually use the return
|
||||
* object, so keep it.
|
||||
|
@ -327,6 +327,7 @@ acpi_ds_exec_begin_op(struct acpi_walk_state *walk_state,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -488,7 +489,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
|
||||
break;
|
||||
|
||||
case AML_TYPE_METHOD_CALL:
|
||||
|
||||
/*
|
||||
* If the method is referenced from within a package
|
||||
* declaration, it is not a invocation of the method, just
|
||||
@ -582,7 +582,6 @@ acpi_status acpi_ds_exec_end_op(struct acpi_walk_state *walk_state)
|
||||
|
||||
switch (op->common.parent->common.aml_opcode) {
|
||||
case AML_NAME_OP:
|
||||
|
||||
/*
|
||||
* Put the Node on the object stack (Contains the ACPI Name
|
||||
* of this object)
|
||||
|
@ -74,6 +74,7 @@ acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number)
|
||||
|
||||
switch (pass_number) {
|
||||
case 1:
|
||||
|
||||
walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
|
||||
ACPI_PARSE_DELETE_TREE;
|
||||
walk_state->descending_callback = acpi_ds_load1_begin_op;
|
||||
@ -81,6 +82,7 @@ acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number)
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
||||
walk_state->parse_flags = ACPI_PARSE_LOAD_PASS1 |
|
||||
ACPI_PARSE_DELETE_TREE;
|
||||
walk_state->descending_callback = acpi_ds_load2_begin_op;
|
||||
@ -88,6 +90,7 @@ acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number)
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
||||
#ifndef ACPI_NO_METHOD_EXECUTION
|
||||
walk_state->parse_flags |= ACPI_PARSE_EXECUTE |
|
||||
ACPI_PARSE_DELETE_TREE;
|
||||
@ -97,6 +100,7 @@ acpi_ds_init_callbacks(struct acpi_walk_state *walk_state, u32 pass_number)
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return (AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
@ -161,7 +165,6 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
|
||||
|
||||
switch (walk_state->opcode) {
|
||||
case AML_SCOPE_OP:
|
||||
|
||||
/*
|
||||
* The target name of the Scope() operator must exist at this point so
|
||||
* that we can actually open the scope to enter new names underneath it.
|
||||
@ -210,7 +213,6 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
|
||||
case ACPI_TYPE_INTEGER:
|
||||
case ACPI_TYPE_STRING:
|
||||
case ACPI_TYPE_BUFFER:
|
||||
|
||||
/*
|
||||
* These types we will allow, but we will change the type.
|
||||
* This enables some existing code of the form:
|
||||
@ -232,7 +234,6 @@ acpi_ds_load1_begin_op(struct acpi_walk_state * walk_state,
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_METHOD:
|
||||
|
||||
/*
|
||||
* Allow scope change to root during execution of module-level
|
||||
* code. Root is typed METHOD during this time.
|
||||
|
@ -509,6 +509,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* All NAMED_FIELD opcodes must be handled above */
|
||||
break;
|
||||
}
|
||||
@ -548,6 +549,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Unknown opcode */
|
||||
|
||||
status = AE_OK;
|
||||
@ -674,6 +676,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
|
||||
#endif /* ACPI_NO_METHOD_EXECUTION */
|
||||
|
||||
default:
|
||||
|
||||
/* All NAMED_COMPLEX opcodes must be handled above */
|
||||
break;
|
||||
}
|
||||
@ -721,6 +724,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -128,6 +128,7 @@ acpi_status acpi_ev_remove_global_lock_handler(void)
|
||||
status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL,
|
||||
acpi_ev_global_lock_handler);
|
||||
|
||||
acpi_os_delete_lock(acpi_gbl_global_lock_pending_lock);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
|
@ -529,7 +529,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
|
||||
|
||||
switch (local_gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
|
||||
case ACPI_GPE_DISPATCH_NOTIFY:
|
||||
|
||||
/*
|
||||
* Implicit notify.
|
||||
* Dispatch a DEVICE_WAKE notify to the appropriate handler.
|
||||
@ -579,10 +578,10 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
|
||||
(local_gpe_event_info->dispatch.
|
||||
method_node)));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return_VOID; /* Should never happen */
|
||||
}
|
||||
|
||||
@ -755,7 +754,6 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
|
||||
|
||||
case ACPI_GPE_DISPATCH_METHOD:
|
||||
case ACPI_GPE_DISPATCH_NOTIFY:
|
||||
|
||||
/*
|
||||
* Execute the method associated with the GPE
|
||||
* NOTE: Level-triggered GPEs are cleared after the method completes.
|
||||
@ -771,7 +769,6 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/*
|
||||
* No handler or method to run!
|
||||
* 03/2010: This case should no longer be possible. We will not allow
|
||||
|
@ -382,6 +382,8 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
|
||||
|
||||
status = acpi_ev_install_gpe_block(gpe_block, interrupt_number);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_FREE(gpe_block->register_info);
|
||||
ACPI_FREE(gpe_block->event_info);
|
||||
ACPI_FREE(gpe_block);
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
@ -363,14 +363,17 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
|
||||
*/
|
||||
switch (name[1]) {
|
||||
case 'L':
|
||||
|
||||
type = ACPI_GPE_LEVEL_TRIGGERED;
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
|
||||
type = ACPI_GPE_EDGE_TRIGGERED;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Unknown method type, just ignore it */
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
|
||||
|
@ -354,36 +354,43 @@ acpi_ev_install_space_handler(struct acpi_namespace_node * node,
|
||||
|
||||
switch (space_id) {
|
||||
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
|
||||
|
||||
handler = acpi_ex_system_memory_space_handler;
|
||||
setup = acpi_ev_system_memory_region_setup;
|
||||
break;
|
||||
|
||||
case ACPI_ADR_SPACE_SYSTEM_IO:
|
||||
|
||||
handler = acpi_ex_system_io_space_handler;
|
||||
setup = acpi_ev_io_space_region_setup;
|
||||
break;
|
||||
|
||||
case ACPI_ADR_SPACE_PCI_CONFIG:
|
||||
|
||||
handler = acpi_ex_pci_config_space_handler;
|
||||
setup = acpi_ev_pci_config_region_setup;
|
||||
break;
|
||||
|
||||
case ACPI_ADR_SPACE_CMOS:
|
||||
|
||||
handler = acpi_ex_cmos_space_handler;
|
||||
setup = acpi_ev_cmos_region_setup;
|
||||
break;
|
||||
|
||||
case ACPI_ADR_SPACE_PCI_BAR_TARGET:
|
||||
|
||||
handler = acpi_ex_pci_bar_space_handler;
|
||||
setup = acpi_ev_pci_bar_region_setup;
|
||||
break;
|
||||
|
||||
case ACPI_ADR_SPACE_DATA_TABLE:
|
||||
|
||||
handler = acpi_ex_data_table_space_handler;
|
||||
setup = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
status = AE_BAD_PARAMETER;
|
||||
goto unlock_and_exit;
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node)
|
||||
return (TRUE);
|
||||
|
||||
default:
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
}
|
||||
@ -275,6 +276,8 @@ void acpi_ev_terminate(void)
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Could not remove Global Lock handler"));
|
||||
}
|
||||
|
||||
acpi_gbl_events_initialized = FALSE;
|
||||
}
|
||||
|
||||
/* Deallocate all handler objects installed within GPE info structs */
|
||||
|
@ -54,7 +54,8 @@ extern u8 acpi_gbl_default_address_spaces[];
|
||||
|
||||
/* Local prototypes */
|
||||
|
||||
static void acpi_ev_orphan_ec_reg_method(void);
|
||||
static void
|
||||
acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node);
|
||||
|
||||
static acpi_status
|
||||
acpi_ev_reg_run(acpi_handle obj_handle,
|
||||
@ -532,7 +533,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
|
||||
}
|
||||
|
||||
info->prefix_node = region_obj2->extra.method_REG;
|
||||
info->pathname = NULL;
|
||||
info->relative_pathname = NULL;
|
||||
info->parameters = args;
|
||||
info->flags = ACPI_IGNORE_RETURN_VALUE;
|
||||
|
||||
@ -612,7 +613,7 @@ acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
|
||||
/* Special case for EC: handle "orphan" _REG methods with no region */
|
||||
|
||||
if (space_id == ACPI_ADR_SPACE_EC) {
|
||||
acpi_ev_orphan_ec_reg_method();
|
||||
acpi_ev_orphan_ec_reg_method(node);
|
||||
}
|
||||
|
||||
return_ACPI_STATUS(status);
|
||||
@ -681,7 +682,7 @@ acpi_ev_reg_run(acpi_handle obj_handle,
|
||||
*
|
||||
* FUNCTION: acpi_ev_orphan_ec_reg_method
|
||||
*
|
||||
* PARAMETERS: None
|
||||
* PARAMETERS: ec_device_node - Namespace node for an EC device
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
@ -693,37 +694,27 @@ acpi_ev_reg_run(acpi_handle obj_handle,
|
||||
* detected by providing a _REG method object underneath the
|
||||
* Embedded Controller device."
|
||||
*
|
||||
* To quickly access the EC device, we use the EC_ID that appears
|
||||
* within the ECDT. Otherwise, we would need to perform a time-
|
||||
* consuming namespace walk, executing _HID methods to find the
|
||||
* EC device.
|
||||
* To quickly access the EC device, we use the ec_device_node used
|
||||
* during EC handler installation. Otherwise, we would need to
|
||||
* perform a time consuming namespace walk, executing _HID
|
||||
* methods to find the EC device.
|
||||
*
|
||||
* MUTEX: Assumes the namespace is locked
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
static void acpi_ev_orphan_ec_reg_method(void)
|
||||
static void
|
||||
acpi_ev_orphan_ec_reg_method(struct acpi_namespace_node *ec_device_node)
|
||||
{
|
||||
struct acpi_table_ecdt *table;
|
||||
acpi_handle reg_method;
|
||||
struct acpi_namespace_node *next_node;
|
||||
acpi_status status;
|
||||
struct acpi_object_list args;
|
||||
union acpi_object objects[2];
|
||||
struct acpi_namespace_node *ec_device_node;
|
||||
struct acpi_namespace_node *reg_method;
|
||||
struct acpi_namespace_node *next_node;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method);
|
||||
|
||||
/* Get the ECDT (if present in system) */
|
||||
|
||||
status = acpi_get_table(ACPI_SIG_ECDT, 0,
|
||||
ACPI_CAST_INDIRECT_PTR(struct acpi_table_header,
|
||||
&table));
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
/* We need a valid EC_ID string */
|
||||
|
||||
if (!(*table->id)) {
|
||||
if (!ec_device_node) {
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
@ -731,22 +722,11 @@ static void acpi_ev_orphan_ec_reg_method(void)
|
||||
|
||||
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
|
||||
|
||||
/* Get a handle to the EC device referenced in the ECDT */
|
||||
|
||||
status = acpi_get_handle(NULL,
|
||||
ACPI_CAST_PTR(char, table->id),
|
||||
ACPI_CAST_PTR(acpi_handle, &ec_device_node));
|
||||
if (ACPI_FAILURE(status)) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Get a handle to a _REG method immediately under the EC device */
|
||||
|
||||
status = acpi_get_handle(ec_device_node,
|
||||
METHOD_NAME__REG, ACPI_CAST_PTR(acpi_handle,
|
||||
®_method));
|
||||
status = acpi_get_handle(ec_device_node, METHOD_NAME__REG, ®_method);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
goto exit;
|
||||
goto exit; /* There is no _REG method present */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -754,19 +734,20 @@ static void acpi_ev_orphan_ec_reg_method(void)
|
||||
* this scope with the Embedded Controller space ID. Otherwise, it
|
||||
* will already have been executed. Note, this allows for Regions
|
||||
* with other space IDs to be present; but the code below will then
|
||||
* execute the _REG method with the EC space ID argument.
|
||||
* execute the _REG method with the embedded_control space_ID argument.
|
||||
*/
|
||||
next_node = acpi_ns_get_next_node(ec_device_node, NULL);
|
||||
while (next_node) {
|
||||
if ((next_node->type == ACPI_TYPE_REGION) &&
|
||||
(next_node->object) &&
|
||||
(next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) {
|
||||
goto exit; /* Do not execute _REG */
|
||||
goto exit; /* Do not execute the _REG */
|
||||
}
|
||||
|
||||
next_node = acpi_ns_get_next_node(ec_device_node, next_node);
|
||||
}
|
||||
|
||||
/* Evaluate the _REG(EC,Connect) method */
|
||||
/* Evaluate the _REG(embedded_control,Connect) method */
|
||||
|
||||
args.count = 2;
|
||||
args.pointer = objects;
|
||||
|
@ -596,7 +596,9 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Ignore other objects */
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -366,16 +366,19 @@ acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action)
|
||||
|
||||
switch (action) {
|
||||
case ACPI_GPE_ENABLE:
|
||||
|
||||
ACPI_SET_BIT(gpe_register_info->enable_for_wake,
|
||||
(u8)register_bit);
|
||||
break;
|
||||
|
||||
case ACPI_GPE_DISABLE:
|
||||
|
||||
ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake,
|
||||
(u8)register_bit);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ACPI_ERROR((AE_INFO, "%u, Invalid action", action));
|
||||
status = AE_BAD_PARAMETER;
|
||||
break;
|
||||
|
@ -139,6 +139,7 @@ acpi_install_address_space_handler(acpi_handle device,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -480,6 +480,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
|
||||
}
|
||||
|
||||
@ -588,7 +589,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
|
||||
(ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
|
||||
(ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE) ||
|
||||
(!(ddb_handle->common.flags & AOPOBJ_DATA_VALID))) {
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
|
||||
}
|
||||
|
||||
/* Get the table index from the ddb_handle */
|
||||
|
@ -99,6 +99,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return_ACPI_STATUS(AE_TYPE);
|
||||
}
|
||||
|
||||
@ -117,7 +118,6 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
|
||||
|
||||
switch (obj_desc->common.type) {
|
||||
case ACPI_TYPE_STRING:
|
||||
|
||||
/*
|
||||
* Convert string to an integer - for most cases, the string must be
|
||||
* hexadecimal as per the ACPI specification. The only exception (as
|
||||
@ -161,6 +161,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
|
||||
default:
|
||||
|
||||
/* No other types can get here */
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -213,7 +214,6 @@ acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc,
|
||||
return_ACPI_STATUS(AE_OK);
|
||||
|
||||
case ACPI_TYPE_INTEGER:
|
||||
|
||||
/*
|
||||
* Create a new Buffer object.
|
||||
* Need enough space for one integer
|
||||
@ -233,7 +233,6 @@ acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc,
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_STRING:
|
||||
|
||||
/*
|
||||
* Create a new Buffer object
|
||||
* Size will be the string length
|
||||
@ -258,6 +257,7 @@ acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return_ACPI_STATUS(AE_TYPE);
|
||||
}
|
||||
|
||||
@ -304,15 +304,18 @@ acpi_ex_convert_to_ascii(u64 integer, u16 base, u8 *string, u8 data_width)
|
||||
|
||||
switch (data_width) {
|
||||
case 1:
|
||||
|
||||
decimal_length = ACPI_MAX8_DECIMAL_DIGITS;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
|
||||
decimal_length = ACPI_MAX32_DECIMAL_DIGITS;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
default:
|
||||
|
||||
decimal_length = ACPI_MAX64_DECIMAL_DIGITS;
|
||||
break;
|
||||
}
|
||||
@ -546,6 +549,7 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return_ACPI_STATUS(AE_TYPE);
|
||||
}
|
||||
|
||||
@ -599,6 +603,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* No conversion allowed for these types */
|
||||
|
||||
if (destination_type != source_desc->common.type) {
|
||||
@ -649,6 +654,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Bad destination type during conversion: 0x%X",
|
||||
destination_type));
|
||||
@ -664,6 +670,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Unknown Target type ID 0x%X AmlOpcode 0x%X DestType %s",
|
||||
GET_CURRENT_ARG_TYPE(walk_state->op_info->
|
||||
|
@ -103,7 +103,6 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
|
||||
case ACPI_TYPE_BUFFER:
|
||||
case ACPI_TYPE_PACKAGE:
|
||||
case ACPI_TYPE_BUFFER_FIELD:
|
||||
|
||||
/*
|
||||
* These types open a new scope, so we need the NS node in order to access
|
||||
* any children.
|
||||
@ -113,7 +112,6 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
|
||||
case ACPI_TYPE_PROCESSOR:
|
||||
case ACPI_TYPE_THERMAL:
|
||||
case ACPI_TYPE_LOCAL_SCOPE:
|
||||
|
||||
/*
|
||||
* The new alias has the type ALIAS and points to the original
|
||||
* NS node, not the object itself.
|
||||
@ -124,7 +122,6 @@ acpi_status acpi_ex_create_alias(struct acpi_walk_state *walk_state)
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_METHOD:
|
||||
|
||||
/*
|
||||
* Control method aliases need to be differentiated
|
||||
*/
|
||||
|
@ -193,6 +193,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
|
||||
return_VOID;
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -226,6 +227,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
acpi_ex_do_debug_object((source_desc->
|
||||
reference.
|
||||
node)->object,
|
||||
|
@ -357,6 +357,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
|
||||
|
||||
switch (info->opcode) {
|
||||
case ACPI_EXD_INIT:
|
||||
|
||||
break;
|
||||
|
||||
case ACPI_EXD_TYPE:
|
||||
@ -718,6 +719,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Unknown Type */
|
||||
|
||||
acpi_os_printf("Unknown Type %X\n", obj_desc->common.type);
|
||||
|
@ -331,21 +331,25 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
|
||||
|
||||
switch (source_desc->common.type) {
|
||||
case ACPI_TYPE_INTEGER:
|
||||
|
||||
buffer = &source_desc->integer.value;
|
||||
length = sizeof(source_desc->integer.value);
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_BUFFER:
|
||||
|
||||
buffer = source_desc->buffer.pointer;
|
||||
length = source_desc->buffer.length;
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_STRING:
|
||||
|
||||
buffer = source_desc->string.pointer;
|
||||
length = source_desc->string.length;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
|
||||
}
|
||||
|
||||
|
@ -446,7 +446,6 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_LOCAL_BANK_FIELD:
|
||||
|
||||
/*
|
||||
* Ensure that the bank_value is not beyond the capacity of
|
||||
* the register
|
||||
@ -488,7 +487,6 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_LOCAL_INDEX_FIELD:
|
||||
|
||||
/*
|
||||
* Ensure that the index_value is not beyond the capacity of
|
||||
* the register
|
||||
|
@ -105,7 +105,6 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc,
|
||||
break;
|
||||
|
||||
case ACPI_DESC_TYPE_NAMED:
|
||||
|
||||
/*
|
||||
* A named reference that has already been resolved to a Node
|
||||
*/
|
||||
@ -261,20 +260,24 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
|
||||
*/
|
||||
switch (operand0->common.type) {
|
||||
case ACPI_TYPE_INTEGER:
|
||||
|
||||
status =
|
||||
acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_STRING:
|
||||
|
||||
status = acpi_ex_convert_to_string(operand1, &local_operand1,
|
||||
ACPI_IMPLICIT_CONVERT_HEX);
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_BUFFER:
|
||||
|
||||
status = acpi_ex_convert_to_buffer(operand1, &local_operand1);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ACPI_ERROR((AE_INFO, "Invalid object type: 0x%X",
|
||||
operand0->common.type));
|
||||
status = AE_AML_INTERNAL;
|
||||
@ -519,6 +522,7 @@ acpi_ex_do_logical_numeric_op(u16 opcode,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
status = AE_AML_INTERNAL;
|
||||
break;
|
||||
}
|
||||
@ -580,20 +584,24 @@ acpi_ex_do_logical_op(u16 opcode,
|
||||
*/
|
||||
switch (operand0->common.type) {
|
||||
case ACPI_TYPE_INTEGER:
|
||||
|
||||
status =
|
||||
acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_STRING:
|
||||
|
||||
status = acpi_ex_convert_to_string(operand1, &local_operand1,
|
||||
ACPI_IMPLICIT_CONVERT_HEX);
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_BUFFER:
|
||||
|
||||
status = acpi_ex_convert_to_buffer(operand1, &local_operand1);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
status = AE_AML_INTERNAL;
|
||||
break;
|
||||
}
|
||||
@ -636,6 +644,7 @@ acpi_ex_do_logical_op(u16 opcode,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
status = AE_AML_INTERNAL;
|
||||
break;
|
||||
}
|
||||
@ -703,6 +712,7 @@ acpi_ex_do_logical_op(u16 opcode,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
status = AE_AML_INTERNAL;
|
||||
break;
|
||||
}
|
||||
|
@ -327,7 +327,6 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state)
|
||||
break;
|
||||
|
||||
case AML_FROM_BCD_OP: /* from_bcd (BCDValue, Result) */
|
||||
|
||||
/*
|
||||
* The 64-bit ACPI integer can hold 16 4-bit BCD characters
|
||||
* (if table is 32-bit, integer can hold 8 BCD characters)
|
||||
@ -407,7 +406,6 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state)
|
||||
break;
|
||||
|
||||
case AML_COND_REF_OF_OP: /* cond_ref_of (source_object, Result) */
|
||||
|
||||
/*
|
||||
* This op is a little strange because the internal return value is
|
||||
* different than the return value stored in the result descriptor
|
||||
@ -442,13 +440,14 @@ acpi_status acpi_ex_opcode_1A_1T_1R(struct acpi_walk_state *walk_state)
|
||||
goto cleanup;
|
||||
|
||||
default:
|
||||
|
||||
/* No other opcodes get here */
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case AML_STORE_OP: /* Store (Source, Target) */
|
||||
|
||||
/*
|
||||
* A store operand is typically a number, string, buffer or lvalue
|
||||
* Be careful about deleting the source object,
|
||||
@ -615,7 +614,6 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
|
||||
|
||||
case AML_DECREMENT_OP: /* Decrement (Operand) */
|
||||
case AML_INCREMENT_OP: /* Increment (Operand) */
|
||||
|
||||
/*
|
||||
* Create a new integer. Can't just get the base integer and
|
||||
* increment it because it may be an Arg or Field.
|
||||
@ -682,7 +680,6 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
|
||||
break;
|
||||
|
||||
case AML_TYPE_OP: /* object_type (source_object) */
|
||||
|
||||
/*
|
||||
* Note: The operand is not resolved at this point because we want to
|
||||
* get the associated object, not its value. For example, we don't
|
||||
@ -709,7 +706,6 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
|
||||
break;
|
||||
|
||||
case AML_SIZE_OF_OP: /* size_of (source_object) */
|
||||
|
||||
/*
|
||||
* Note: The operand is not resolved at this point because we want to
|
||||
* get the associated object, not its value.
|
||||
@ -735,10 +731,12 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
|
||||
*/
|
||||
switch (type) {
|
||||
case ACPI_TYPE_INTEGER:
|
||||
|
||||
value = acpi_gbl_integer_byte_width;
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_STRING:
|
||||
|
||||
value = temp_desc->string.length;
|
||||
break;
|
||||
|
||||
@ -759,6 +757,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Operand must be Buffer/Integer/String/Package - found type %s",
|
||||
acpi_ut_get_type_name(type)));
|
||||
@ -860,9 +859,11 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_STRING:
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
status = AE_AML_OPERAND_TYPE;
|
||||
goto cleanup;
|
||||
}
|
||||
@ -923,7 +924,6 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
|
||||
*/
|
||||
switch (operand[0]->reference.class) {
|
||||
case ACPI_REFCLASS_INDEX:
|
||||
|
||||
/*
|
||||
* The target type for the Index operator must be
|
||||
* either a Buffer or a Package
|
||||
@ -956,7 +956,6 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_PACKAGE:
|
||||
|
||||
/*
|
||||
* Return the referenced element of the package. We must
|
||||
* add another reference to the referenced object, however.
|
||||
@ -999,6 +998,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Unknown class in reference(%p) - 0x%2.2X",
|
||||
operand[0],
|
||||
|
@ -304,7 +304,6 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state)
|
||||
break;
|
||||
|
||||
case AML_TO_STRING_OP: /* to_string (Buffer, Length, Result) (ACPI 2.0) */
|
||||
|
||||
/*
|
||||
* Input object is guaranteed to be a buffer at this point (it may have
|
||||
* been converted.) Copy the raw buffer data to a new object of
|
||||
|
@ -155,7 +155,6 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state)
|
||||
|
||||
switch (walk_state->opcode) {
|
||||
case AML_MID_OP: /* Mid (Source[0], Index[1], Length[2], Result[3]) */
|
||||
|
||||
/*
|
||||
* Create the return object. The Source operand is guaranteed to be
|
||||
* either a String or a Buffer, so just use its type.
|
||||
|
@ -119,7 +119,6 @@ acpi_ex_do_match(u32 match_op,
|
||||
break;
|
||||
|
||||
case MATCH_MEQ:
|
||||
|
||||
/*
|
||||
* True if equal: (P[i] == M)
|
||||
* Change to: (M == P[i])
|
||||
@ -133,7 +132,6 @@ acpi_ex_do_match(u32 match_op,
|
||||
break;
|
||||
|
||||
case MATCH_MLE:
|
||||
|
||||
/*
|
||||
* True if less than or equal: (P[i] <= M) (P[i] not_greater than M)
|
||||
* Change to: (M >= P[i]) (M not_less than P[i])
|
||||
@ -148,7 +146,6 @@ acpi_ex_do_match(u32 match_op,
|
||||
break;
|
||||
|
||||
case MATCH_MLT:
|
||||
|
||||
/*
|
||||
* True if less than: (P[i] < M)
|
||||
* Change to: (M > P[i])
|
||||
@ -162,7 +159,6 @@ acpi_ex_do_match(u32 match_op,
|
||||
break;
|
||||
|
||||
case MATCH_MGE:
|
||||
|
||||
/*
|
||||
* True if greater than or equal: (P[i] >= M) (P[i] not_less than M)
|
||||
* Change to: (M <= P[i]) (M not_greater than P[i])
|
||||
@ -177,7 +173,6 @@ acpi_ex_do_match(u32 match_op,
|
||||
break;
|
||||
|
||||
case MATCH_MGT:
|
||||
|
||||
/*
|
||||
* True if greater than: (P[i] > M)
|
||||
* Change to: (M < P[i])
|
||||
|
@ -253,26 +253,31 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc,
|
||||
|
||||
case AML_FIELD_ACCESS_BYTE:
|
||||
case AML_FIELD_ACCESS_BUFFER: /* ACPI 2.0 (SMBus Buffer) */
|
||||
|
||||
byte_alignment = 1;
|
||||
bit_length = 8;
|
||||
break;
|
||||
|
||||
case AML_FIELD_ACCESS_WORD:
|
||||
|
||||
byte_alignment = 2;
|
||||
bit_length = 16;
|
||||
break;
|
||||
|
||||
case AML_FIELD_ACCESS_DWORD:
|
||||
|
||||
byte_alignment = 4;
|
||||
bit_length = 32;
|
||||
break;
|
||||
|
||||
case AML_FIELD_ACCESS_QWORD: /* ACPI 2.0 */
|
||||
|
||||
byte_alignment = 8;
|
||||
bit_length = 64;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* Invalid field access type */
|
||||
|
||||
ACPI_ERROR((AE_INFO, "Unknown field access type 0x%X", access));
|
||||
@ -598,7 +603,9 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* No other types should get here */
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -88,22 +88,27 @@ acpi_ex_system_memory_space_handler(u32 function,
|
||||
|
||||
switch (bit_width) {
|
||||
case 8:
|
||||
|
||||
length = 1;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
|
||||
length = 2;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
|
||||
length = 4;
|
||||
break;
|
||||
|
||||
case 64:
|
||||
|
||||
length = 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ACPI_ERROR((AE_INFO, "Invalid SystemMemory width %u",
|
||||
bit_width));
|
||||
return_ACPI_STATUS(AE_AML_OPERAND_VALUE);
|
||||
@ -214,23 +219,29 @@ acpi_ex_system_memory_space_handler(u32 function,
|
||||
*value = 0;
|
||||
switch (bit_width) {
|
||||
case 8:
|
||||
|
||||
*value = (u64)ACPI_GET8(logical_addr_ptr);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
|
||||
*value = (u64)ACPI_GET16(logical_addr_ptr);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
|
||||
*value = (u64)ACPI_GET32(logical_addr_ptr);
|
||||
break;
|
||||
|
||||
case 64:
|
||||
|
||||
*value = (u64)ACPI_GET64(logical_addr_ptr);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* bit_width was already validated */
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -239,28 +250,35 @@ acpi_ex_system_memory_space_handler(u32 function,
|
||||
|
||||
switch (bit_width) {
|
||||
case 8:
|
||||
|
||||
ACPI_SET8(logical_addr_ptr, *value);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
|
||||
ACPI_SET16(logical_addr_ptr, *value);
|
||||
break;
|
||||
|
||||
case 32:
|
||||
|
||||
ACPI_SET32(logical_addr_ptr, *value);
|
||||
break;
|
||||
|
||||
case 64:
|
||||
|
||||
ACPI_SET64(logical_addr_ptr, *value);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* bit_width was already validated */
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
status = AE_BAD_PARAMETER;
|
||||
break;
|
||||
}
|
||||
@ -320,6 +338,7 @@ acpi_ex_system_io_space_handler(u32 function,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
status = AE_BAD_PARAMETER;
|
||||
break;
|
||||
}
|
||||
|
@ -248,6 +248,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* No named references are allowed here */
|
||||
|
||||
ACPI_ERROR((AE_INFO,
|
||||
|
@ -156,7 +156,6 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
|
||||
switch (ref_type) {
|
||||
case ACPI_REFCLASS_LOCAL:
|
||||
case ACPI_REFCLASS_ARG:
|
||||
|
||||
/*
|
||||
* Get the local from the method's state info
|
||||
* Note: this increments the local's object reference count
|
||||
@ -309,6 +308,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -348,10 +348,12 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
|
||||
|
||||
switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
|
||||
case ACPI_DESC_TYPE_OPERAND:
|
||||
|
||||
type = obj_desc->common.type;
|
||||
break;
|
||||
|
||||
case ACPI_DESC_TYPE_NAMED:
|
||||
|
||||
type = ((struct acpi_namespace_node *)obj_desc)->type;
|
||||
obj_desc =
|
||||
acpi_ns_get_attached_object((struct acpi_namespace_node *)
|
||||
@ -538,7 +540,9 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* No change to Type required */
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -307,7 +307,6 @@ acpi_ex_resolve_operands(u16 opcode,
|
||||
case ARGI_TARGETREF: /* Allows implicit conversion rules before store */
|
||||
case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */
|
||||
case ARGI_SIMPLE_TARGET: /* Name, Local, or arg - no implicit conversion */
|
||||
|
||||
/*
|
||||
* Need an operand of type ACPI_TYPE_LOCAL_REFERENCE
|
||||
* A Namespace Node is OK as-is
|
||||
@ -326,7 +325,6 @@ acpi_ex_resolve_operands(u16 opcode,
|
||||
goto next_operand;
|
||||
|
||||
case ARGI_DATAREFOBJ: /* Store operator only */
|
||||
|
||||
/*
|
||||
* We don't want to resolve index_op reference objects during
|
||||
* a store because this would be an implicit de_ref_of operation.
|
||||
@ -343,7 +341,9 @@ acpi_ex_resolve_operands(u16 opcode,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
/* All cases covered above */
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -433,7 +433,6 @@ acpi_ex_resolve_operands(u16 opcode,
|
||||
goto next_operand;
|
||||
|
||||
case ARGI_BUFFER:
|
||||
|
||||
/*
|
||||
* Need an operand of type ACPI_TYPE_BUFFER,
|
||||
* But we can implicitly convert from a STRING or INTEGER
|
||||
@ -459,7 +458,6 @@ acpi_ex_resolve_operands(u16 opcode,
|
||||
goto next_operand;
|
||||
|
||||
case ARGI_STRING:
|
||||
|
||||
/*
|
||||
* Need an operand of type ACPI_TYPE_STRING,
|
||||
* But we can implicitly convert from a BUFFER or INTEGER
|
||||
@ -562,6 +560,7 @@ acpi_ex_resolve_operands(u16 opcode,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Needed [Buffer/String/Package/Reference], found [%s] %p",
|
||||
acpi_ut_get_object_type_name
|
||||
@ -584,6 +583,7 @@ acpi_ex_resolve_operands(u16 opcode,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Needed [Buffer/String/Package], found [%s] %p",
|
||||
acpi_ut_get_object_type_name
|
||||
@ -605,6 +605,7 @@ acpi_ex_resolve_operands(u16 opcode,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Needed [Region/Buffer], found [%s] %p",
|
||||
acpi_ut_get_object_type_name
|
||||
|
@ -114,6 +114,7 @@ acpi_ex_store(union acpi_operand_object *source_desc,
|
||||
|
||||
switch (dest_desc->common.type) {
|
||||
case ACPI_TYPE_LOCAL_REFERENCE:
|
||||
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_INTEGER:
|
||||
@ -178,7 +179,6 @@ acpi_ex_store(union acpi_operand_object *source_desc,
|
||||
break;
|
||||
|
||||
case ACPI_REFCLASS_DEBUG:
|
||||
|
||||
/*
|
||||
* Storing to the Debug object causes the value stored to be
|
||||
* displayed and otherwise has no effect -- see ACPI Specification
|
||||
@ -291,7 +291,6 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_BUFFER_FIELD:
|
||||
|
||||
/*
|
||||
* Store into a Buffer or String (not actually a real buffer_field)
|
||||
* at a location defined by an Index.
|
||||
@ -447,7 +446,6 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
|
||||
case ACPI_TYPE_INTEGER:
|
||||
case ACPI_TYPE_STRING:
|
||||
case ACPI_TYPE_BUFFER:
|
||||
|
||||
/*
|
||||
* These target types are all of type Integer/String/Buffer, and
|
||||
* therefore support implicit conversion before the store.
|
||||
|
@ -85,11 +85,9 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
|
||||
* These cases all require only Integers or values that
|
||||
* can be converted to Integers (Strings or Buffers)
|
||||
*/
|
||||
|
||||
case ACPI_TYPE_INTEGER:
|
||||
case ACPI_TYPE_STRING:
|
||||
case ACPI_TYPE_BUFFER:
|
||||
|
||||
/*
|
||||
* Stores into a Field/Region or into a Integer/Buffer/String
|
||||
* are all essentially the same. This case handles the
|
||||
@ -133,7 +131,6 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
|
||||
|
||||
case ACPI_TYPE_LOCAL_ALIAS:
|
||||
case ACPI_TYPE_LOCAL_METHOD_ALIAS:
|
||||
|
||||
/*
|
||||
* All aliases should have been resolved earlier, during the
|
||||
* operand resolution phase.
|
||||
@ -144,7 +141,6 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
|
||||
|
||||
case ACPI_TYPE_PACKAGE:
|
||||
default:
|
||||
|
||||
/*
|
||||
* All other types than Alias and the various Fields come here,
|
||||
* including the untyped case - ACPI_TYPE_ANY.
|
||||
|
@ -108,7 +108,6 @@ acpi_status acpi_hw_set_mode(u32 mode)
|
||||
break;
|
||||
|
||||
case ACPI_SYS_MODE_LEGACY:
|
||||
|
||||
/*
|
||||
* BIOS should clear all fixed status bits and restore fixed event
|
||||
* enable bits to default
|
||||
@ -120,6 +119,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
|
@ -127,14 +127,17 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
|
||||
/*lint -fallthrough */
|
||||
|
||||
case ACPI_GPE_ENABLE:
|
||||
|
||||
ACPI_SET_BIT(enable_mask, register_bit);
|
||||
break;
|
||||
|
||||
case ACPI_GPE_DISABLE:
|
||||
|
||||
ACPI_CLEAR_BIT(enable_mask, register_bit);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u", action));
|
||||
return (AE_BAD_PARAMETER);
|
||||
}
|
||||
|
@ -419,6 +419,7 @@ acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value)
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ACPI_ERROR((AE_INFO, "Unknown Register ID: 0x%X", register_id));
|
||||
status = AE_BAD_PARAMETER;
|
||||
break;
|
||||
@ -491,7 +492,6 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
|
||||
break;
|
||||
|
||||
case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
|
||||
|
||||
/*
|
||||
* Perform a read first to preserve certain bits (per ACPI spec)
|
||||
* Note: This includes SCI_EN, we never want to change this bit
|
||||
@ -520,7 +520,6 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
|
||||
break;
|
||||
|
||||
case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
|
||||
|
||||
/*
|
||||
* For control registers, all reserved bits must be preserved,
|
||||
* as per the ACPI spec.
|
||||
@ -555,6 +554,7 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
ACPI_ERROR((AE_INFO, "Unknown Register ID: 0x%X", register_id));
|
||||
status = AE_BAD_PARAMETER;
|
||||
break;
|
||||
|
@ -495,7 +495,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
|
||||
* Evaluate the \_Sx namespace object containing the register values
|
||||
* for this state
|
||||
*/
|
||||
info->pathname =
|
||||
info->relative_pathname =
|
||||
ACPI_CAST_PTR(char, acpi_gbl_sleep_state_names[sleep_state]);
|
||||
status = acpi_ns_evaluate(info);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
@ -506,7 +506,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
|
||||
|
||||
if (!info->return_object) {
|
||||
ACPI_ERROR((AE_INFO, "No Sleep State object returned from [%s]",
|
||||
info->pathname));
|
||||
info->relative_pathname));
|
||||
status = AE_AML_NO_RETURN_VALUE;
|
||||
goto cleanup;
|
||||
}
|
||||
@ -528,10 +528,12 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
|
||||
elements = info->return_object->package.elements;
|
||||
switch (info->return_object->package.count) {
|
||||
case 0:
|
||||
|
||||
status = AE_AML_PACKAGE_LIMIT;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
if (elements[0]->common.type != ACPI_TYPE_INTEGER) {
|
||||
status = AE_AML_OPERAND_TYPE;
|
||||
break;
|
||||
@ -545,6 +547,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
|
||||
|
||||
case 2:
|
||||
default:
|
||||
|
||||
if ((elements[0]->common.type != ACPI_TYPE_INTEGER) ||
|
||||
(elements[1]->common.type != ACPI_TYPE_INTEGER)) {
|
||||
status = AE_AML_OPERAND_TYPE;
|
||||
@ -565,7 +568,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
|
||||
if (ACPI_FAILURE(status)) {
|
||||
ACPI_EXCEPTION((AE_INFO, status,
|
||||
"While evaluating Sleep State [%s]",
|
||||
info->pathname));
|
||||
info->relative_pathname));
|
||||
}
|
||||
|
||||
ACPI_FREE(info);
|
||||
|
@ -240,12 +240,14 @@ static acpi_status acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id)
|
||||
&acpi_sleep_dispatch[function_id];
|
||||
|
||||
#if (!ACPI_REDUCED_HARDWARE)
|
||||
|
||||
/*
|
||||
* If the Hardware Reduced flag is set (from the FADT), we must
|
||||
* use the extended sleep registers
|
||||
* use the extended sleep registers (FADT). Note: As per the ACPI
|
||||
* specification, these extended registers are to be used for HW-reduced
|
||||
* platforms only. They are not general-purpose replacements for the
|
||||
* legacy PM register sleep support.
|
||||
*/
|
||||
if (acpi_gbl_reduced_hardware || acpi_gbl_FADT.sleep_control.address) {
|
||||
if (acpi_gbl_reduced_hardware) {
|
||||
status = sleep_functions->extended_function(sleep_state);
|
||||
} else {
|
||||
/* Legacy sleep */
|
||||
@ -314,20 +316,24 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
|
||||
|
||||
switch (sleep_state) {
|
||||
case ACPI_STATE_S0:
|
||||
|
||||
sst_value = ACPI_SST_WORKING;
|
||||
break;
|
||||
|
||||
case ACPI_STATE_S1:
|
||||
case ACPI_STATE_S2:
|
||||
case ACPI_STATE_S3:
|
||||
|
||||
sst_value = ACPI_SST_SLEEPING;
|
||||
break;
|
||||
|
||||
case ACPI_STATE_S4:
|
||||
|
||||
sst_value = ACPI_SST_SLEEP_CONTEXT;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
sst_value = ACPI_SST_INDICATOR_OFF; /* Default is off */
|
||||
break;
|
||||
}
|
||||
|
@ -151,6 +151,7 @@ acpi_status acpi_ns_root_initialize(void)
|
||||
*/
|
||||
switch (init_val->type) {
|
||||
case ACPI_TYPE_METHOD:
|
||||
|
||||
obj_desc->method.param_count =
|
||||
(u8) ACPI_TO_INTEGER(val);
|
||||
obj_desc->common.flags |= AOPOBJ_DATA_VALID;
|
||||
|
294
drivers/acpi/acpica/nsarguments.c
Normal file
294
drivers/acpi/acpica/nsarguments.c
Normal file
@ -0,0 +1,294 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Module Name: nsarguments - Validation of args for ACPI predefined methods
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2000 - 2013, Intel Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions, and the following disclaimer,
|
||||
* without modification.
|
||||
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
|
||||
* substantially similar to the "NO WARRANTY" disclaimer below
|
||||
* ("Disclaimer") and any redistribution must be conditioned upon
|
||||
* including a substantially similar Disclaimer requirement for further
|
||||
* binary redistribution.
|
||||
* 3. Neither the names of the above-listed copyright holders nor the names
|
||||
* of any contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of the
|
||||
* GNU General Public License ("GPL") version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#include <acpi/acpi.h>
|
||||
#include "accommon.h"
|
||||
#include "acnamesp.h"
|
||||
#include "acpredef.h"
|
||||
|
||||
#define _COMPONENT ACPI_NAMESPACE
|
||||
ACPI_MODULE_NAME("nsarguments")
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ns_check_argument_types
|
||||
*
|
||||
* PARAMETERS: info - Method execution information block
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Check the incoming argument count and all argument types
|
||||
* against the argument type list for a predefined name.
|
||||
*
|
||||
******************************************************************************/
|
||||
void acpi_ns_check_argument_types(struct acpi_evaluate_info *info)
|
||||
{
|
||||
u16 arg_type_list;
|
||||
u8 arg_count;
|
||||
u8 arg_type;
|
||||
u8 user_arg_type;
|
||||
u32 i;
|
||||
|
||||
/* If not a predefined name, cannot typecheck args */
|
||||
|
||||
if (!info->predefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
arg_type_list = info->predefined->info.argument_list;
|
||||
arg_count = METHOD_GET_ARG_COUNT(arg_type_list);
|
||||
|
||||
/* Typecheck all arguments */
|
||||
|
||||
for (i = 0; ((i < arg_count) && (i < info->param_count)); i++) {
|
||||
arg_type = METHOD_GET_NEXT_TYPE(arg_type_list);
|
||||
user_arg_type = info->parameters[i]->common.type;
|
||||
|
||||
if (user_arg_type != arg_type) {
|
||||
ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
|
||||
ACPI_WARN_ALWAYS,
|
||||
"Argument #%u type mismatch - "
|
||||
"Found [%s], ACPI requires [%s]",
|
||||
(i + 1),
|
||||
acpi_ut_get_type_name
|
||||
(user_arg_type),
|
||||
acpi_ut_get_type_name(arg_type)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ns_check_acpi_compliance
|
||||
*
|
||||
* PARAMETERS: pathname - Full pathname to the node (for error msgs)
|
||||
* node - Namespace node for the method/object
|
||||
* predefined - Pointer to entry in predefined name table
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Check that the declared parameter count (in ASL/AML) for a
|
||||
* predefined name is what is expected (matches what is defined in
|
||||
* the ACPI specification for this predefined name.)
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void
|
||||
acpi_ns_check_acpi_compliance(char *pathname,
|
||||
struct acpi_namespace_node *node,
|
||||
const union acpi_predefined_info *predefined)
|
||||
{
|
||||
u32 aml_param_count;
|
||||
u32 required_param_count;
|
||||
|
||||
if (!predefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get the ACPI-required arg count from the predefined info table */
|
||||
|
||||
required_param_count =
|
||||
METHOD_GET_ARG_COUNT(predefined->info.argument_list);
|
||||
|
||||
/*
|
||||
* If this object is not a control method, we can check if the ACPI
|
||||
* spec requires that it be a method.
|
||||
*/
|
||||
if (node->type != ACPI_TYPE_METHOD) {
|
||||
if (required_param_count > 0) {
|
||||
|
||||
/* Object requires args, must be implemented as a method */
|
||||
|
||||
ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname,
|
||||
ACPI_WARN_ALWAYS,
|
||||
"Object (%s) must be a control method with %u arguments",
|
||||
acpi_ut_get_type_name(node->
|
||||
type),
|
||||
required_param_count));
|
||||
} else if (!required_param_count
|
||||
&& !predefined->info.expected_btypes) {
|
||||
|
||||
/* Object requires no args and no return value, must be a method */
|
||||
|
||||
ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname,
|
||||
ACPI_WARN_ALWAYS,
|
||||
"Object (%s) must be a control method "
|
||||
"with no arguments and no return value",
|
||||
acpi_ut_get_type_name(node->
|
||||
type)));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a control method.
|
||||
* Check that the ASL/AML-defined parameter count for this method
|
||||
* matches the ACPI-required parameter count
|
||||
*
|
||||
* Some methods are allowed to have a "minimum" number of args (_SCP)
|
||||
* because their definition in ACPI has changed over time.
|
||||
*
|
||||
* Note: These are BIOS errors in the declaration of the object
|
||||
*/
|
||||
aml_param_count = node->object->method.param_count;
|
||||
|
||||
if (aml_param_count < required_param_count) {
|
||||
ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,
|
||||
"Insufficient arguments - "
|
||||
"ASL declared %u, ACPI requires %u",
|
||||
aml_param_count,
|
||||
required_param_count));
|
||||
} else if ((aml_param_count > required_param_count)
|
||||
&& !(predefined->info.
|
||||
argument_list & ARG_COUNT_IS_MINIMUM)) {
|
||||
ACPI_BIOS_ERROR_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,
|
||||
"Excess arguments - "
|
||||
"ASL declared %u, ACPI requires %u",
|
||||
aml_param_count,
|
||||
required_param_count));
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: acpi_ns_check_argument_count
|
||||
*
|
||||
* PARAMETERS: pathname - Full pathname to the node (for error msgs)
|
||||
* node - Namespace node for the method/object
|
||||
* user_param_count - Number of args passed in by the caller
|
||||
* predefined - Pointer to entry in predefined name table
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Check that incoming argument count matches the declared
|
||||
* parameter count (in the ASL/AML) for an object.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void
|
||||
acpi_ns_check_argument_count(char *pathname,
|
||||
struct acpi_namespace_node *node,
|
||||
u32 user_param_count,
|
||||
const union acpi_predefined_info *predefined)
|
||||
{
|
||||
u32 aml_param_count;
|
||||
u32 required_param_count;
|
||||
|
||||
if (!predefined) {
|
||||
/*
|
||||
* Not a predefined name. Check the incoming user argument count
|
||||
* against the count that is specified in the method/object.
|
||||
*/
|
||||
if (node->type != ACPI_TYPE_METHOD) {
|
||||
if (user_param_count) {
|
||||
ACPI_INFO_PREDEFINED((AE_INFO, pathname,
|
||||
ACPI_WARN_ALWAYS,
|
||||
"%u arguments were passed to a non-method ACPI object (%s)",
|
||||
user_param_count,
|
||||
acpi_ut_get_type_name
|
||||
(node->type)));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a control method. Check the parameter count.
|
||||
* We can only check the incoming argument count against the
|
||||
* argument count declared for the method in the ASL/AML.
|
||||
*
|
||||
* Emit a message if too few or too many arguments have been passed
|
||||
* by the caller.
|
||||
*
|
||||
* Note: Too many arguments will not cause the method to
|
||||
* fail. However, the method will fail if there are too few
|
||||
* arguments and the method attempts to use one of the missing ones.
|
||||
*/
|
||||
aml_param_count = node->object->method.param_count;
|
||||
|
||||
if (user_param_count < aml_param_count) {
|
||||
ACPI_WARN_PREDEFINED((AE_INFO, pathname,
|
||||
ACPI_WARN_ALWAYS,
|
||||
"Insufficient arguments - "
|
||||
"Caller passed %u, method requires %u",
|
||||
user_param_count,
|
||||
aml_param_count));
|
||||
} else if (user_param_count > aml_param_count) {
|
||||
ACPI_INFO_PREDEFINED((AE_INFO, pathname,
|
||||
ACPI_WARN_ALWAYS,
|
||||
"Excess arguments - "
|
||||
"Caller passed %u, method requires %u",
|
||||
user_param_count,
|
||||
aml_param_count));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a predefined name. Validate the user-supplied parameter
|
||||
* count against the ACPI specification. We don't validate against
|
||||
* the method itself because what is important here is that the
|
||||
* caller is in conformance with the spec. (The arg count for the
|
||||
* method was checked against the ACPI spec earlier.)
|
||||
*
|
||||
* Some methods are allowed to have a "minimum" number of args (_SCP)
|
||||
* because their definition in ACPI has changed over time.
|
||||
*/
|
||||
required_param_count =
|
||||
METHOD_GET_ARG_COUNT(predefined->info.argument_list);
|
||||
|
||||
if (user_param_count < required_param_count) {
|
||||
ACPI_WARN_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,
|
||||
"Insufficient arguments - "
|
||||
"Caller passed %u, ACPI requires %u",
|
||||
user_param_count, required_param_count));
|
||||
} else if ((user_param_count > required_param_count) &&
|
||||
!(predefined->info.argument_list & ARG_COUNT_IS_MINIMUM)) {
|
||||
ACPI_INFO_PREDEFINED((AE_INFO, pathname, ACPI_WARN_ALWAYS,
|
||||
"Excess arguments - "
|
||||
"Caller passed %u, ACPI requires %u",
|
||||
user_param_count, required_param_count));
|
||||
}
|
||||
}
|
@ -103,6 +103,7 @@ acpi_ns_convert_to_integer(union acpi_operand_object *original_object,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return (AE_AML_OPERAND_TYPE);
|
||||
}
|
||||
|
||||
@ -191,6 +192,7 @@ acpi_ns_convert_to_string(union acpi_operand_object *original_object,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return (AE_AML_OPERAND_TYPE);
|
||||
}
|
||||
|
||||
@ -294,6 +296,7 @@ acpi_ns_convert_to_buffer(union acpi_operand_object *original_object,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
return (AE_AML_OPERAND_TYPE);
|
||||
}
|
||||
|
||||
|
@ -244,10 +244,12 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
|
||||
case ACPI_TYPE_BUFFER:
|
||||
case ACPI_TYPE_STRING:
|
||||
case ACPI_TYPE_METHOD:
|
||||
|
||||
acpi_os_printf("<No attached object>");
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -433,6 +435,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -567,32 +570,39 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
|
||||
goto cleanup;
|
||||
|
||||
case ACPI_TYPE_BUFFER_FIELD:
|
||||
|
||||
obj_desc =
|
||||
(union acpi_operand_object *)obj_desc->buffer_field.
|
||||
buffer_obj;
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_PACKAGE:
|
||||
|
||||
obj_desc = (void *)obj_desc->package.elements;
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_METHOD:
|
||||
|
||||
obj_desc = (void *)obj_desc->method.aml_start;
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_LOCAL_REGION_FIELD:
|
||||
|
||||
obj_desc = (void *)obj_desc->field.region_obj;
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_LOCAL_BANK_FIELD:
|
||||
|
||||
obj_desc = (void *)obj_desc->bank_field.region_obj;
|
||||
break;
|
||||
|
||||
case ACPI_TYPE_LOCAL_INDEX_FIELD:
|
||||
|
||||
obj_desc = (void *)obj_desc->index_field.index_obj;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ acpi_ns_exec_module_code(union acpi_operand_object *method_obj,
|
||||
*
|
||||
* PARAMETERS: info - Evaluation info block, contains:
|
||||
* prefix_node - Prefix or Method/Object Node to execute
|
||||
* pathname - Name of method to execute, If NULL, the
|
||||
* relative_path - Name of method to execute, If NULL, the
|
||||
* Node is the object to execute
|
||||
* parameters - List of parameters to pass to the method,
|
||||
* terminated by NULL. Params itself may be
|
||||
@ -85,7 +85,6 @@ acpi_ns_exec_module_code(union acpi_operand_object *method_obj,
|
||||
acpi_status acpi_ns_evaluate(struct acpi_evaluate_info *info)
|
||||
{
|
||||
acpi_status status;
|
||||
struct acpi_namespace_node *node;
|
||||
|
||||
ACPI_FUNCTION_TRACE(ns_evaluate);
|
||||
|
||||
@ -93,83 +92,138 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
|
||||
return_ACPI_STATUS(AE_BAD_PARAMETER);
|
||||
}
|
||||
|
||||
/* Initialize the return value to an invalid object */
|
||||
|
||||
info->return_object = NULL;
|
||||
info->param_count = 0;
|
||||
|
||||
if (!info->resolved_node) {
|
||||
if (!info->node) {
|
||||
/*
|
||||
* Get the actual namespace node for the target object if we need to.
|
||||
* Handles these cases:
|
||||
* Get the actual namespace node for the target object if we
|
||||
* need to. Handles these cases:
|
||||
*
|
||||
* 1) Null node, Pathname (absolute path)
|
||||
* 2) Node, Pathname (path relative to Node)
|
||||
* 3) Node, Null Pathname
|
||||
* 1) Null node, valid pathname from root (absolute path)
|
||||
* 2) Node and valid pathname (path relative to Node)
|
||||
* 3) Node, Null pathname
|
||||
*/
|
||||
status = acpi_ns_get_node(info->prefix_node, info->pathname,
|
||||
ACPI_NS_NO_UPSEARCH,
|
||||
&info->resolved_node);
|
||||
status =
|
||||
acpi_ns_get_node(info->prefix_node, info->relative_pathname,
|
||||
ACPI_NS_NO_UPSEARCH, &info->node);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For a method alias, we must grab the actual method node so that proper
|
||||
* scoping context will be established before execution.
|
||||
* For a method alias, we must grab the actual method node so that
|
||||
* proper scoping context will be established before execution.
|
||||
*/
|
||||
if (acpi_ns_get_type(info->resolved_node) ==
|
||||
ACPI_TYPE_LOCAL_METHOD_ALIAS) {
|
||||
info->resolved_node =
|
||||
if (acpi_ns_get_type(info->node) == ACPI_TYPE_LOCAL_METHOD_ALIAS) {
|
||||
info->node =
|
||||
ACPI_CAST_PTR(struct acpi_namespace_node,
|
||||
info->resolved_node->object);
|
||||
info->node->object);
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n", info->pathname,
|
||||
info->resolved_node,
|
||||
acpi_ns_get_attached_object(info->resolved_node)));
|
||||
/* Complete the info block initialization */
|
||||
|
||||
node = info->resolved_node;
|
||||
info->return_object = NULL;
|
||||
info->node_flags = info->node->flags;
|
||||
info->obj_desc = acpi_ns_get_attached_object(info->node);
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n",
|
||||
info->relative_pathname, info->node,
|
||||
acpi_ns_get_attached_object(info->node)));
|
||||
|
||||
/* Get info if we have a predefined name (_HID, etc.) */
|
||||
|
||||
info->predefined =
|
||||
acpi_ut_match_predefined_method(info->node->name.ascii);
|
||||
|
||||
/* Get the full pathname to the object, for use in warning messages */
|
||||
|
||||
info->full_pathname = acpi_ns_get_external_pathname(info->node);
|
||||
if (!info->full_pathname) {
|
||||
return_ACPI_STATUS(AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* Count the number of arguments being passed in */
|
||||
|
||||
info->param_count = 0;
|
||||
if (info->parameters) {
|
||||
while (info->parameters[info->param_count]) {
|
||||
info->param_count++;
|
||||
}
|
||||
|
||||
/* Warn on impossible argument count */
|
||||
|
||||
if (info->param_count > ACPI_METHOD_NUM_ARGS) {
|
||||
ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
|
||||
ACPI_WARN_ALWAYS,
|
||||
"Excess arguments (%u) - using only %u",
|
||||
info->param_count,
|
||||
ACPI_METHOD_NUM_ARGS));
|
||||
|
||||
info->param_count = ACPI_METHOD_NUM_ARGS;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Two major cases here:
|
||||
*
|
||||
* 1) The object is a control method -- execute it
|
||||
* 2) The object is not a method -- just return it's current value
|
||||
* For predefined names: Check that the declared argument count
|
||||
* matches the ACPI spec -- otherwise this is a BIOS error.
|
||||
*/
|
||||
if (acpi_ns_get_type(info->resolved_node) == ACPI_TYPE_METHOD) {
|
||||
acpi_ns_check_acpi_compliance(info->full_pathname, info->node,
|
||||
info->predefined);
|
||||
|
||||
/*
|
||||
* 1) Object is a control method - execute it
|
||||
* For all names: Check that the incoming argument count for
|
||||
* this method/object matches the actual ASL/AML definition.
|
||||
*/
|
||||
acpi_ns_check_argument_count(info->full_pathname, info->node,
|
||||
info->param_count, info->predefined);
|
||||
|
||||
/* For predefined names: Typecheck all incoming arguments */
|
||||
|
||||
acpi_ns_check_argument_types(info);
|
||||
|
||||
/*
|
||||
* Three major evaluation cases:
|
||||
*
|
||||
* 1) Object types that cannot be evaluated by definition
|
||||
* 2) The object is a control method -- execute it
|
||||
* 3) The object is not a method -- just return it's current value
|
||||
*/
|
||||
switch (acpi_ns_get_type(info->node)) {
|
||||
case ACPI_TYPE_DEVICE:
|
||||
case ACPI_TYPE_EVENT:
|
||||
case ACPI_TYPE_MUTEX:
|
||||
case ACPI_TYPE_REGION:
|
||||
case ACPI_TYPE_THERMAL:
|
||||
case ACPI_TYPE_LOCAL_SCOPE:
|
||||
/*
|
||||
* 1) Disallow evaluation of certain object types. For these,
|
||||
* object evaluation is undefined and not supported.
|
||||
*/
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"%s: Evaluation of object type [%s] is not supported",
|
||||
info->full_pathname,
|
||||
acpi_ut_get_type_name(info->node->type)));
|
||||
|
||||
status = AE_TYPE;
|
||||
goto cleanup;
|
||||
|
||||
case ACPI_TYPE_METHOD:
|
||||
/*
|
||||
* 2) Object is a control method - execute it
|
||||
*/
|
||||
|
||||
/* Verify that there is a method object associated with this node */
|
||||
|
||||
info->obj_desc =
|
||||
acpi_ns_get_attached_object(info->resolved_node);
|
||||
if (!info->obj_desc) {
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"Control method has no attached sub-object"));
|
||||
return_ACPI_STATUS(AE_NULL_OBJECT);
|
||||
"%s: Method has no attached sub-object",
|
||||
info->full_pathname));
|
||||
status = AE_NULL_OBJECT;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Count the number of arguments being passed to the method */
|
||||
|
||||
if (info->parameters) {
|
||||
while (info->parameters[info->param_count]) {
|
||||
if (info->param_count > ACPI_METHOD_MAX_ARG) {
|
||||
return_ACPI_STATUS(AE_LIMIT);
|
||||
}
|
||||
info->param_count++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ACPI_DUMP_PATHNAME(info->resolved_node, "ACPI: Execute Method",
|
||||
ACPI_LV_INFO, _COMPONENT);
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
|
||||
"Method at AML address %p Length %X\n",
|
||||
"**** Execute method [%s] at AML address %p length %X\n",
|
||||
info->full_pathname,
|
||||
info->obj_desc->method.aml_start + 1,
|
||||
info->obj_desc->method.aml_length - 1));
|
||||
|
||||
@ -184,80 +238,60 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
|
||||
acpi_ex_enter_interpreter();
|
||||
status = acpi_ps_execute_method(info);
|
||||
acpi_ex_exit_interpreter();
|
||||
} else {
|
||||
/*
|
||||
* 2) Object is not a method, return its current value
|
||||
*
|
||||
* Disallow certain object types. For these, "evaluation" is undefined.
|
||||
*/
|
||||
switch (info->resolved_node->type) {
|
||||
case ACPI_TYPE_DEVICE:
|
||||
case ACPI_TYPE_EVENT:
|
||||
case ACPI_TYPE_MUTEX:
|
||||
case ACPI_TYPE_REGION:
|
||||
case ACPI_TYPE_THERMAL:
|
||||
case ACPI_TYPE_LOCAL_SCOPE:
|
||||
|
||||
ACPI_ERROR((AE_INFO,
|
||||
"[%4.4s] Evaluation of object type [%s] is not supported",
|
||||
info->resolved_node->name.ascii,
|
||||
acpi_ut_get_type_name(info->resolved_node->
|
||||
type)));
|
||||
|
||||
return_ACPI_STATUS(AE_TYPE);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* 3) All other non-method objects -- get the current object value
|
||||
*/
|
||||
|
||||
/*
|
||||
* Objects require additional resolution steps (e.g., the Node may be
|
||||
* a field that must be read, etc.) -- we can't just grab the object
|
||||
* out of the node.
|
||||
* Some objects require additional resolution steps (e.g., the Node
|
||||
* may be a field that must be read, etc.) -- we can't just grab
|
||||
* the object out of the node.
|
||||
*
|
||||
* Use resolve_node_to_value() to get the associated value.
|
||||
*
|
||||
* NOTE: we can get away with passing in NULL for a walk state because
|
||||
* resolved_node is guaranteed to not be a reference to either a method
|
||||
* the Node is guaranteed to not be a reference to either a method
|
||||
* local or a method argument (because this interface is never called
|
||||
* from a running method.)
|
||||
*
|
||||
* Even though we do not directly invoke the interpreter for object
|
||||
* resolution, we must lock it because we could access an opregion.
|
||||
* The opregion access code assumes that the interpreter is locked.
|
||||
* resolution, we must lock it because we could access an op_region.
|
||||
* The op_region access code assumes that the interpreter is locked.
|
||||
*/
|
||||
acpi_ex_enter_interpreter();
|
||||
|
||||
/* Function has a strange interface */
|
||||
/* TBD: resolve_node_to_value has a strange interface, fix */
|
||||
|
||||
info->return_object =
|
||||
ACPI_CAST_PTR(union acpi_operand_object, info->node);
|
||||
|
||||
status =
|
||||
acpi_ex_resolve_node_to_value(&info->resolved_node, NULL);
|
||||
acpi_ex_resolve_node_to_value(ACPI_CAST_INDIRECT_PTR
|
||||
(struct acpi_namespace_node,
|
||||
&info->return_object), NULL);
|
||||
acpi_ex_exit_interpreter();
|
||||
|
||||
/*
|
||||
* If acpi_ex_resolve_node_to_value() succeeded, the return value was placed
|
||||
* in resolved_node.
|
||||
*/
|
||||
if (ACPI_SUCCESS(status)) {
|
||||
status = AE_CTRL_RETURN_VALUE;
|
||||
info->return_object =
|
||||
ACPI_CAST_PTR(union acpi_operand_object,
|
||||
info->resolved_node);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
|
||||
"Returning object %p [%s]\n",
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "Returned object %p [%s]\n",
|
||||
info->return_object,
|
||||
acpi_ut_get_object_type_name(info->
|
||||
return_object)));
|
||||
}
|
||||
|
||||
status = AE_CTRL_RETURN_VALUE; /* Always has a "return value" */
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check input argument count against the ASL-defined count for a method.
|
||||
* Also check predefined names: argument count and return value against
|
||||
* the ACPI specification. Some incorrect return value types are repaired.
|
||||
* For predefined names, check the return value against the ACPI
|
||||
* specification. Some incorrect return value types are repaired.
|
||||
*/
|
||||
(void)acpi_ns_check_predefined_names(node, info->param_count,
|
||||
(void)acpi_ns_check_return_value(info->node, info, info->param_count,
|
||||
status, &info->return_object);
|
||||
|
||||
/* Check if there is a return value that must be dealt with */
|
||||
@ -278,12 +312,15 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
|
||||
|
||||
ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
|
||||
"*** Completed evaluation of object %s ***\n",
|
||||
info->pathname));
|
||||
info->relative_pathname));
|
||||
|
||||
cleanup:
|
||||
/*
|
||||
* Namespace was unlocked by the handling acpi_ns* function, so we
|
||||
* just return
|
||||
* just free the pathname and return
|
||||
*/
|
||||
ACPI_FREE(info->full_pathname);
|
||||
info->full_pathname = NULL;
|
||||
return_ACPI_STATUS(status);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user