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 commit
   9f29ab1 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 commit 9f29ab11dd ("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:
Linus Torvalds 2013-07-03 14:35:40 -07:00
commit f991fae5c6
279 changed files with 6918 additions and 3460 deletions

View 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.

View File

@ -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.

View 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.

View File

@ -1,4 +1,4 @@
Whatt: /sys/devices/.../sun
What: /sys/devices/.../sun
Date: October 2012
Contact: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Description:

View File

@ -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

View File

@ -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>

View 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.

View 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.

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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/

View File

@ -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

View File

@ -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;

View File

@ -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,

View File

@ -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 */

View File

@ -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

View File

@ -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);
}

View File

@ -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)

View File

@ -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)

View File

@ -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,

View File

@ -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)

View File

@ -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

View File

@ -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;
}

View File

@ -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.

View File

@ -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
/*

View File

@ -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;

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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

View 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);
}

View File

@ -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)

View File

@ -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");

View 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");
}

View File

@ -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 \

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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 {

View File

@ -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,

View File

@ -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:

View File

@ -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);
}

View File

@ -127,6 +127,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
break;
default:
break;
}

View File

@ -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)

View File

@ -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;

View File

@ -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);
}

View File

@ -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.

View File

@ -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)

View File

@ -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.

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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,

View File

@ -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;
}

View File

@ -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 */

View File

@ -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,
&reg_method));
status = acpi_get_handle(ec_device_node, METHOD_NAME__REG, &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;

View File

@ -596,7 +596,9 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
break;
default:
/* Ignore other objects */
break;
}

View File

@ -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;

View File

@ -139,6 +139,7 @@ acpi_install_address_space_handler(acpi_handle device,
break;
default:
break;
}

View File

@ -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 */

View File

@ -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->

View File

@ -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
*/

View File

@ -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,

View File

@ -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);

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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],

View File

@ -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

View File

@ -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.

View File

@ -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])

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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,

View File

@ -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;
}

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View 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));
}
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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