]> rtime.felk.cvut.cz Git - linux-imx.git/commitdiff
Merge branch 'pm-cpufreq'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Sun, 30 Jun 2013 22:41:12 +0000 (00:41 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Sun, 30 Jun 2013 22:41:12 +0000 (00:41 +0200)
* pm-cpufreq:
  cpufreq: Fix cpufreq regression after suspend/resume

221 files changed:
Documentation/ABI/testing/sysfs-bus-acpi [new file with mode: 0644]
Documentation/ABI/testing/sysfs-class-devfreq
Documentation/ABI/testing/sysfs-devices-online [new file with mode: 0644]
Documentation/ABI/testing/sysfs-devices-sun
Documentation/ABI/testing/sysfs-firmware-acpi
Documentation/acpi/namespace.txt [new file with mode: 0644]
Documentation/acpi/video_extension.txt [new file with mode: 0644]
Documentation/cpu-hotplug.txt
Documentation/kernel-parameters.txt
Documentation/power/pm_qos_interface.txt
Documentation/power/runtime_pm.txt
Documentation/power/video_extension.txt [deleted file]
Documentation/trace/events-power.txt
MAINTAINERS
arch/arm/mach-omap2/omap_device.c
arch/arm/mach-omap2/smartreflex-class3.c
arch/ia64/hp/common/sba_iommu.c
arch/x86/include/asm/acpi.h
arch/x86/kernel/acpi/boot.c
arch/x86/kernel/acpi/sleep.c
arch/x86/kernel/acpi/sleep.h
drivers/acpi/Makefile
drivers/acpi/acpi_cmos_rtc.c [new file with mode: 0644]
drivers/acpi/acpi_lpss.c
drivers/acpi/acpi_memhotplug.c
drivers/acpi/acpi_processor.c [new file with mode: 0644]
drivers/acpi/acpica/Makefile
drivers/acpi/acpica/acglobal.h
drivers/acpi/acpica/aclocal.h
drivers/acpi/acpica/acmacros.h
drivers/acpi/acpica/acnamesp.h
drivers/acpi/acpica/acpredef.h
drivers/acpi/acpica/acstruct.h
drivers/acpi/acpica/acutils.h
drivers/acpi/acpica/dscontrol.c
drivers/acpi/acpica/dsfield.c
drivers/acpi/acpica/dsinit.c
drivers/acpi/acpica/dsmthdat.c
drivers/acpi/acpica/dsobject.c
drivers/acpi/acpica/dsopcode.c
drivers/acpi/acpica/dsutils.c
drivers/acpi/acpica/dswexec.c
drivers/acpi/acpica/dswload.c
drivers/acpi/acpica/dswload2.c
drivers/acpi/acpica/evglock.c
drivers/acpi/acpica/evgpe.c
drivers/acpi/acpica/evgpeblk.c
drivers/acpi/acpica/evgpeinit.c
drivers/acpi/acpica/evhandler.c
drivers/acpi/acpica/evmisc.c
drivers/acpi/acpica/evregion.c
drivers/acpi/acpica/evrgnini.c
drivers/acpi/acpica/evxfgpe.c
drivers/acpi/acpica/evxfregn.c
drivers/acpi/acpica/exconfig.c
drivers/acpi/acpica/exconvrt.c
drivers/acpi/acpica/excreate.c
drivers/acpi/acpica/exdebug.c
drivers/acpi/acpica/exdump.c
drivers/acpi/acpica/exfield.c
drivers/acpi/acpica/exfldio.c
drivers/acpi/acpica/exmisc.c
drivers/acpi/acpica/exoparg1.c
drivers/acpi/acpica/exoparg2.c
drivers/acpi/acpica/exoparg3.c
drivers/acpi/acpica/exoparg6.c
drivers/acpi/acpica/exprep.c
drivers/acpi/acpica/exregion.c
drivers/acpi/acpica/exresnte.c
drivers/acpi/acpica/exresolv.c
drivers/acpi/acpica/exresop.c
drivers/acpi/acpica/exstore.c
drivers/acpi/acpica/exstoren.c
drivers/acpi/acpica/hwacpi.c
drivers/acpi/acpica/hwgpe.c
drivers/acpi/acpica/hwregs.c
drivers/acpi/acpica/hwxface.c
drivers/acpi/acpica/hwxfsleep.c
drivers/acpi/acpica/nsaccess.c
drivers/acpi/acpica/nsarguments.c [new file with mode: 0644]
drivers/acpi/acpica/nsconvert.c
drivers/acpi/acpica/nsdump.c
drivers/acpi/acpica/nseval.c
drivers/acpi/acpica/nsinit.c
drivers/acpi/acpica/nspredef.c
drivers/acpi/acpica/nsprepkg.c
drivers/acpi/acpica/nsrepair.c
drivers/acpi/acpica/nsrepair2.c
drivers/acpi/acpica/nsutils.c
drivers/acpi/acpica/nsxfeval.c
drivers/acpi/acpica/psargs.c
drivers/acpi/acpica/psloop.c
drivers/acpi/acpica/psobject.c
drivers/acpi/acpica/psparse.c
drivers/acpi/acpica/pstree.c
drivers/acpi/acpica/psxface.c
drivers/acpi/acpica/rscalc.c
drivers/acpi/acpica/rscreate.c
drivers/acpi/acpica/rsdump.c
drivers/acpi/acpica/rsmisc.c
drivers/acpi/acpica/rsutils.c
drivers/acpi/acpica/rsxface.c
drivers/acpi/acpica/tbinstal.c
drivers/acpi/acpica/tbprint.c [new file with mode: 0644]
drivers/acpi/acpica/tbutils.c
drivers/acpi/acpica/tbxfload.c
drivers/acpi/acpica/utbuffer.c [new file with mode: 0644]
drivers/acpi/acpica/utcopy.c
drivers/acpi/acpica/utdebug.c
drivers/acpi/acpica/utdelete.c
drivers/acpi/acpica/uterror.c [new file with mode: 0644]
drivers/acpi/acpica/uteval.c
drivers/acpi/acpica/utexcep.c
drivers/acpi/acpica/utids.c
drivers/acpi/acpica/utmisc.c
drivers/acpi/acpica/utobject.c
drivers/acpi/acpica/utpredef.c
drivers/acpi/acpica/utstring.c
drivers/acpi/acpica/uttrack.c
drivers/acpi/acpica/utxferror.c
drivers/acpi/battery.c
drivers/acpi/bus.c
drivers/acpi/device_pm.c
drivers/acpi/dock.c
drivers/acpi/ec.c
drivers/acpi/ec_sys.c
drivers/acpi/glue.c
drivers/acpi/internal.h
drivers/acpi/osl.c
drivers/acpi/processor_driver.c
drivers/acpi/processor_idle.c
drivers/acpi/processor_perflib.c
drivers/acpi/scan.c
drivers/acpi/sleep.c
drivers/acpi/sysfs.c
drivers/acpi/video.c
drivers/amba/bus.c
drivers/ata/libata-acpi.c
drivers/ata/libata-core.c
drivers/ata/libata.h
drivers/base/core.c
drivers/base/cpu.c
drivers/base/memory.c
drivers/base/platform.c
drivers/base/power/domain.c
drivers/base/power/generic_ops.c
drivers/base/power/qos.c
drivers/base/power/runtime.c
drivers/base/power/wakeup.c
drivers/clk/x86/clk-lpt.c
drivers/cpufreq/acpi-cpufreq.c
drivers/cpuidle/Kconfig
drivers/cpuidle/Makefile
drivers/cpuidle/cpuidle-zynq.c [new file with mode: 0644]
drivers/cpuidle/cpuidle.c
drivers/cpuidle/driver.c
drivers/devfreq/Kconfig
drivers/devfreq/Makefile
drivers/devfreq/devfreq.c
drivers/devfreq/exynos/Makefile [new file with mode: 0644]
drivers/devfreq/exynos/exynos4_bus.c [moved from drivers/devfreq/exynos4_bus.c with 99% similarity]
drivers/devfreq/exynos/exynos5_bus.c [new file with mode: 0644]
drivers/devfreq/exynos/exynos_ppmu.c [new file with mode: 0644]
drivers/devfreq/exynos/exynos_ppmu.h [new file with mode: 0644]
drivers/dma/intel_mid_dma.c
drivers/gpio/gpio-langwell.c
drivers/i2c/i2c-core.c
drivers/mfd/ab8500-gpadc.c
drivers/mmc/core/bus.c
drivers/mmc/core/sdio_bus.c
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/pci-driver.c
drivers/pci/pci.h
drivers/pci/setup-bus.c
drivers/pnp/manager.c
drivers/power/avs/smartreflex.c
drivers/scsi/scsi_pm.c
drivers/sh/pm_runtime.c
drivers/spi/spi.c
drivers/staging/android/binder.c
drivers/tty/serial/mfd.c
drivers/usb/core/driver.c
drivers/usb/core/port.c
fs/cifs/transport.c
fs/eventpoll.c
fs/nfs/inode.c
fs/nfs/nfs3proc.c
fs/nfs/nfs4proc.c
fs/select.c
include/acpi/acconfig.h
include/acpi/acoutput.h
include/acpi/acpi_bus.h
include/acpi/acpi_drivers.h
include/acpi/acpixf.h
include/acpi/processor.h
include/linux/acpi.h
include/linux/cpuidle.h
include/linux/debug_locks.h
include/linux/devfreq.h
include/linux/device.h
include/linux/freezer.h
include/linux/memory_hotplug.h
include/linux/pm_runtime.h
include/linux/power/smartreflex.h
include/linux/suspend.h
include/trace/events/power.h
include/xen/acpi.h
kernel/exit.c
kernel/freezer.c
kernel/futex.c
kernel/hrtimer.c
kernel/lockdep.c
kernel/power/main.c
kernel/power/process.c
kernel/power/qos.c
kernel/power/snapshot.c
kernel/power/suspend.c
kernel/signal.c
mm/memory_hotplug.c
net/sunrpc/sched.c
net/unix/af_unix.c

diff --git a/Documentation/ABI/testing/sysfs-bus-acpi b/Documentation/ABI/testing/sysfs-bus-acpi
new file mode 100644 (file)
index 0000000..7fa9cbc
--- /dev/null
@@ -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.
index 0ba6ea2f89d9b831bdebdcc2419727464a59d88c..ee39acacf6f8512cb81eedaf0d06685bbf004144 100644 (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.
diff --git a/Documentation/ABI/testing/sysfs-devices-online b/Documentation/ABI/testing/sysfs-devices-online
new file mode 100644 (file)
index 0000000..f990026
--- /dev/null
@@ -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.
index 86be9848a77e2251bcd2e2cb7b904145147cbff3..625ce4b6375825a1e5908a9323b655c177799e17 100644 (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:
index ce9bee98b43be62f84937502ed6fdfae38d43b3d..b4436cca97a83612fd3305630f5e0807eb53caeb 100644 (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>
diff --git a/Documentation/acpi/namespace.txt b/Documentation/acpi/namespace.txt
new file mode 100644 (file)
index 0000000..260f6a3
--- /dev/null
@@ -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.
diff --git a/Documentation/acpi/video_extension.txt b/Documentation/acpi/video_extension.txt
new file mode 100644 (file)
index 0000000..78b32ac
--- /dev/null
@@ -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.
index 9f401350f5021ce61eda8c6ce0a386bc93109d18..67f733d6f848d897fad19698fd2017675164d650 100644 (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
 
index 2fe6e767b3d6013f3d1023c2e518b0466fa27e2f..7f64e0f0258ae013bccc5766128420d7efaf12a4 100644 (file)
@@ -3229,6 +3229,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.
 
index 79a2a58425ee1c1df7df251bc12aa40fdbeb0ecb..483632087788db0532718d2a26ab2283c379c38d 100644 (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:
index 6c9f5d9aa115d04ee86c5297f5e3051bee31c0b9..71d8fe4e75d3e5301e25037a28d91600d633dba7 100644 (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
diff --git a/Documentation/power/video_extension.txt b/Documentation/power/video_extension.txt
deleted file mode 100644 (file)
index b2f9b15..0000000
+++ /dev/null
@@ -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
-
index e1498ff8cf94df2bf5a4e14fb93c04c94444e803..3bd33b8dc7c460f71885b169077f3df9ec2adaac 100644 (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.
index 041df42fc34dd1a0d53601309e922361141084b6..04a5fef844159f762193a72d9cd72fa40cf48df1 100644 (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>
@@ -1309,6 +1311,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>
@@ -2517,7 +2520,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/
 
index e6d230700b2bdf3d0702de3b4e9cfeef67d6801e..e37feb2f05a3355b4ebc52bad9246451ee859409 100644 (file)
@@ -591,11 +591,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);
@@ -653,7 +648,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,
index aee3c8940a30ca19f6d7819b2cc654481bbd1fd5..7a42e1960c3b5fe4aed135fa17d7717e735e044d 100644 (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 */
index bcda5b2d121a624ee784f81843a13c155b7865a8..d43daf192b21d54df034e52c809a4ac4b2178161 100644 (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",
-       .ids            = hp_ioc_iommu_device_ids,
-       .ops            = {
-               .add    = acpi_sba_ioc_add,
-       },
+static struct acpi_scan_handler acpi_sba_ioc_handler = {
+       .ids    = hp_ioc_iommu_device_ids,
+       .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
                /*
index b31bf97775fcbeea3b29a9537092b24b379aba67..2dfac58f3b11049e21b9ed752546f873b207adb0 100644 (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))
index 230c8ea878e5f41ce3f63d2be6a4490759e46b49..d81a972dd506f24059bcaa19a5259ca9ff908ede 100644 (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
index b44577bc97449c14af7988e18a14b4b9c31cc262..2a34aaf3c8f139ff8bd35f702b7431ff75895c9c 100644 (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);
index 67f59f8c695651977e45d88e15bc66781777f31c..c9c2c982d5e4e168a20a3a2e8fb98bbabf1860e0 100644 (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);
index 536562c626a2fab4bb20c128abcf27f4404ca23f..81dbeb83bb45805de6b0f7e083ed3bb421eabca9 100644 (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
diff --git a/drivers/acpi/acpi_cmos_rtc.c b/drivers/acpi/acpi_cmos_rtc.c
new file mode 100644 (file)
index 0000000..84190ed
--- /dev/null
@@ -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);
+}
index cab13f2fc28e3033aaed24adbbf618199473bb28..6a382188fa20a7f2f67f8f45d506439f8e45db7b 100644 (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,
-                                      pdata->mmio_base + dev_desc->prv_offset,
-                                      0, 0, NULL);
-       if (IS_ERR(pdata->clk))
-               return PTR_ERR(pdata->clk);
+       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);
+               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,7 +251,10 @@ 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) {
-                       pdata->mmio_size = resource_size(&rentry->res);
+                       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);
                        pdata->dev_desc = dev_desc;
@@ -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)
index 5e6301e949206adb9f9b512a4b44b9d093e588df..c711d1144044ec18b47a8aad9f0c0f43e5f5f690 100644 (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");
diff --git a/drivers/acpi/acpi_processor.c b/drivers/acpi/acpi_processor.c
new file mode 100644 (file)
index 0000000..e9b01e3
--- /dev/null
@@ -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");
+}
index 7ddf29eca9f59f42a9f98bd46c031ae89aa23fe1..438304086ff1bb117f946f79038ff586a80df9c5 100644 (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         \
index 07160928ca25cced7906412401d46d40b72194be..b8d38117a20c9f5971b719bea11d90017e571d69 100644 (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;
index d5bfbd331bfdda124d92a195b3418ae34cfbc2af..dfed26545ba28bb7858ce832fdce823460407992 100644 (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
index 53666bd9193d5c566d264275ea7ba38518317ccc..530a2f8c1252da88d0598071b3f32da2bb739f1d 100644 (file)
  * the plist contains a set of parens to allow variable-length lists.
  * These macros are used for both the debug and non-debug versions of the code.
  */
-#define ACPI_ERROR_NAMESPACE(s, e)      acpi_ut_namespace_error (AE_INFO, s, e);
-#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_ERROR_NAMESPACE(s, e)          acpi_ut_namespace_error (AE_INFO, s, e);
+#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
 
 #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 */
 
index d2e491876bc043c64d7bd12d7bdd6d8217497a0a..b83dc32a5ae053eee5a935e30aaedaf0f7b6f3c3 100644 (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_argument_count(char *pathname,
+                            struct acpi_namespace_node *node,
+                            u32 user_param_count,
+                            const union acpi_predefined_info *info);
 
 void
-acpi_ns_check_parameter_count(char *pathname,
+acpi_ns_check_acpi_compliance(char *pathname,
                              struct acpi_namespace_node *node,
-                             u32 user_param_count,
-                             const union acpi_predefined_info *info);
+                             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_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_predefined_data *data,
+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);
index b22b70944fd63175dc3f8f9876ad37c505948686..f600aded7261cde6762b3fee5d9b9a6a790664b8 100644 (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 */
 
index 7896d85876cacd534991bf72e4a920ce041947b8..fc83c0a5ca70fe228857d1336d967a91dd0765fa 100644 (file)
@@ -178,25 +178,41 @@ 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
+#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 */
 
index 202f4f12d3e2fad0e6d447a781c559a7bbcad88d..3c76edea6803faf0cf8c7db1b76431b5abafbf04 100644 (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,
index 7ea0f162f11ca42e11d7247fc3263d4c1fb0b2e1..eb56b66444b5e3d671572b6290a1245473e7d165 100644 (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:
index feadeed1012dc2256c1596bb79e7ff6190e6cb41..d4bfe7b7f90a54a5b5cdafb8119f0d60698be171 100644 (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);
        }
 
index bc8e63f7784b96a7bf39c5476dc9cacd07688bb5..14424200d246c8538bcde5070072100528dcf1dd 100644 (file)
@@ -127,6 +127,7 @@ acpi_ds_init_one_object(acpi_handle obj_handle,
                break;
 
        default:
+
                break;
        }
 
index 3da80460ce38af069241fb59ee41d2aeb695d319..c4b0b365723758fe5181e26eaeaa7cb5314f18d3 100644 (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)
index e20e9f84eee80653b6dfc932f140c6eaebf4a5ac..63f0d220ca3d99a2da601b1b4571972bf2f71397 100644 (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;
index ee6367b8eaf7afcf6866ff75193e5ca59bfa94f4..1fc1ff114f269867bf1a281e584511c00595d960 100644 (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);
        }
 
index 99778997c35ab8f1fb5c6249c030c9e48fd35366..c666fc01498795afdb76f6afad8383f75389d1bb 100644 (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.
index e2199a9474703196326024af6bbfc0c5460e7201..151d924817e1b2041bfd60cad46aaaf1a5dc9e20 100644 (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)
index 6e17c0e24e63ca4e758d1e2a2147419ed5e4b0ec..95e681a36f9c28d820b40f55d211426ae4b2de92 100644 (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.
index 4407ff2377d5918b10fe08875434ed07b981d836..b1f8f4725c230b0d6b0bf9155f13028f42d62667 100644 (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;
        }
 
index a621481c6cf27f946a6050f5ef9f6ea466b51689..fdb0a76e40a3020806cfce8c4e637273e2fc4f2c 100644 (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);
 }
 
index a493b528f8f9f3c5a88b13ed685befdbc07c9e13..c8a1f7d5931f518b004cc8311d31e5ad8e5cdaeb 100644 (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,11 +578,11 @@ 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 */
+
+               return_VOID;    /* Should never happen */
        }
 
        /* Defer enabling of GPE until all notify handlers are done */
@@ -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
index a2d688bbac02c7ee96e43b5764f97442c1dd2a6f..c1aa1eda26c32ec73dc68ac6d5433d783383348b 100644 (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);
        }
index 72b8f6b3f4cafeac10eee0bacfa2af5c1851f281..9037f17c9608f70a6bc2df68eca5b55043ad9723 100644 (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,
index d4f83112c2e266ff2fcf5f8415d9714ffa071330..068af96134b89787a739cce281f481db82e46e19 100644 (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;
                }
index c986b2336b81d6b1b85e60ee4e2e9568e2750a33..1b111ef74903771f8f9a8f690aef85b752f65c61 100644 (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 */
index 6555e350fc1fe21087cea7e219a9c4b170d70e25..cea14d6fc76c976db580144f93d28d890ff3938f 100644 (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;
index 3bb616794b3b46fe5aaaaa7b77335523b351b159..8354c4f7f10c55c604765a92020abd2d30547de9 100644 (file)
@@ -596,7 +596,9 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
                                break;
 
                        default:
+
                                /* Ignore other objects */
+
                                break;
                        }
 
index aff4cc2612115304f41ea11a6aa57a5038a6f101..7662f1a42ff6bb19513e0f9272f90c921f64ec90 100644 (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;
index 96c9e5f355aed40f7e07fc598d60b61907c501a6..80cecf8385917c7ed32ca75eb9afc807dbb6b0b2 100644 (file)
@@ -139,6 +139,7 @@ acpi_install_address_space_handler(acpi_handle device,
                break;
 
        default:
+
                break;
        }
 
index d93b70be60adf071c132687b208241d233bb4f3a..06d216c8d43ab18edc0fb1f66def077014b2aa3f 100644 (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 */
index d2b9613bbf01d231e72f44d87381e83ab87f11e4..69e4a8cc9b71728f98b1aad402a0a44538033457 100644 (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->
index 26a13f67977ea11248cc54ec9f034ecf1a584e45..269e81d86ef41c59e7eaa3d61bb7c63ba23457bd 100644 (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
                 */
index 7eb853cd279f776f5b384543dba38fdedfafff38..81c72a4ecd823eaca8542135aea5396d7d6d5626 100644 (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,
index e5a3c249f7fad23c544a856504d13d33134c104e..c740f24e3101069af922a5e5842a77fb60d34710 100644 (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);
index 7d4bae71e8c62da6399bc6af7e0f3fd132efa574..c2a65aaf29af006f3be629aab6b9f6b698650b40 100644 (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);
        }
 
index c84ee956fa4c58f50c8849cc660a151d46febe39..7e0afe72487ea73ee5504d73891b294b83aceb91 100644 (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
index 72a2a13b6d36de72eb97cf7d38aacb0cada1587b..00bf298775741763054eabd2d3030dcb6494e150 100644 (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;
                }
index b60c877f5906d9d8b7d00d9a022d3105f4aa2c2a..814b4a3d656ad1dc3d9acf438258735569017656 100644 (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],
index b0838a4ea53e6fc70cb9b57a8b3fc2fab1b2bce7..d5088f7030c753fb9e36b78b25d894e2c48cf74c 100644 (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
index 2d7491f3126ef906ee6e589494f7936f20885166..37656f12f204bcd3b12ae6c1d8384eb392990e1a 100644 (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.
index b76b97002dffd1701741b5fe18031f3104580dfb..879b6cd8319cdc09023e3852da1efe1b51f84282 100644 (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])
index 6b728aef2dcab54804d11509e23660b06e11d21e..5a588611ab484f12e33966fcbdf4ce2a03ffdc4e 100644 (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;
        }
 
index 182abaf045e165588606bd4a52de7c98413717c1..303429bb4d5d6631878878a872b3f0c46f82f390 100644 (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);
+
+                       *value = (u64)ACPI_GET8(logical_addr_ptr);
                        break;
 
                case 16:
-                       *value = (u64) ACPI_GET16(logical_addr_ptr);
+
+                       *value = (u64)ACPI_GET16(logical_addr_ptr);
                        break;
 
                case 32:
-                       *value = (u64) ACPI_GET32(logical_addr_ptr);
+
+                       *value = (u64)ACPI_GET32(logical_addr_ptr);
                        break;
 
                case 64:
-                       *value = (u64) ACPI_GET64(logical_addr_ptr);
+
+                       *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;
        }
index 8565b6bd12bb41a886aa8ad94d9355dd74d3a942..acd34f5993131d573aa6bcdf6046e7dd34afad12 100644 (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,
index e4f9dfbb2a13f737e37e65bba8d374a7e673a987..ac04278ad28f00294d6fc7a3034795bcbb1c0bfb 100644 (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;
        }
 
index 9fb9f5e9a4daefe2f3a477eeb222d6ba1e560719..00e5af7129c1234338e4c5f0aeddcde5941ce94d 100644 (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
index 93c6049c2d754d3e621729599510344e2d06d7dc..2bdba6f7d7620c43a8f6dafcbe83d5a14679f8b4 100644 (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.
index 1cefe777068eef26b2d66851418c7992ede3244a..20d809d90c5b8f113e7b0f3c56fcafa58893dda2 100644 (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.
index 579c3a53ac87ede953e7610dab23f1270c6bafcc..3d36df828f520b1c196783453905c3f05f34543c 100644 (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);
        }
 
index 20d02e93c99021e10038849b5290d77e360b55fc..96540506058fcc94351e2980feab2adf990d9ad6 100644 (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);
        }
index 083d6551f0e2b2db97020d6e0ecc4e9d7ed85211..8d2e866be15f84a301183cf5690205785ec4f2ea 100644 (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;
index 04c2e16f2c0a6ef86ab734cd309cfb1ce41d49db..5ee7a814cd9207db34d42b8945867e415ab733bb 100644 (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);
index 35eebdac0f9d1e02976d382376005abbe4a870a5..f2e669db8b65e90deddae8ee64a1e2b8ed3bfb39 100644 (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;
        }
index 8769cf83b044ff704db113a4ef7ffc8a5f78fbc0..c5316e5bd4abf2efce5aad7d4968708d3bccdb3d 100644 (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;
diff --git a/drivers/acpi/acpica/nsarguments.c b/drivers/acpi/acpica/nsarguments.c
new file mode 100644 (file)
index 0000000..74b24c8
--- /dev/null
@@ -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));
+       }
+}
index 8f79a9d2d50ec659f157e0c3ccd011d81c0658df..acd2964c26906f995b159bd382a42ce000cfa2c3 100644 (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);
        }
 
index ce6e9732620523ba36e1a474d76dddfcf03005d9..7418c77fde8c70db88d0d0af9c0c6a8fcad6cad5 100644 (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;
                }
 
index b61db69d56752160e5be0e4bd0ab430d2871fcb5..18108bc2e51cd76833c42b13d6c6e6e678bcb976 100644 (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
@@ -82,10 +82,9 @@ acpi_ns_exec_module_code(union acpi_operand_object *method_obj,
  *
  ******************************************************************************/
 
-acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
+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);
+       }
+
+       /* Complete the info block initialization */
+
+       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);
        }
 
-       ACPI_DEBUG_PRINT((ACPI_DB_NAMES, "%s [%p] Value %p\n", info->pathname,
-                         info->resolved_node,
-                         acpi_ns_get_attached_object(info->resolved_node)));
+       /* 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;
+               }
+       }
+
+       /*
+        * For predefined names: Check that the declared argument count
+        * matches the ACPI spec -- otherwise this is a BIOS error.
+        */
+       acpi_ns_check_acpi_compliance(info->full_pathname, info->node,
+                                     info->predefined);
+
+       /*
+        * 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);
 
-       node = info->resolved_node;
+       /* For predefined names: Typecheck all incoming arguments */
+
+       acpi_ns_check_argument_types(info);
 
        /*
-        * Two major cases here:
+        * Three major evaluation cases:
         *
-        * 1) The object is a control method -- execute it
-        * 2) The object is not a method -- just return it's current value
+        * 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
         */
-       if (acpi_ns_get_type(info->resolved_node) == ACPI_TYPE_METHOD) {
+       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:
                /*
-                * 1) Object is a control method - execute it
+                * 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,81 +238,61 @@ 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 {
+               break;
+
+       default:
                /*
-                * 2) Object is not a method, return its current value
-                *
-                * Disallow certain object types. For these, "evaluation" is undefined.
+                * 3) All other non-method objects -- get the current object value
                 */
-               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);
-
-               default:
-                       break;
-               }
 
                /*
-                * 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);
-
-                       ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
-                                         "Returning object %p [%s]\n",
-                                         info->return_object,
-                                         acpi_ut_get_object_type_name(info->
-                                                                      return_object)));
+               if (ACPI_FAILURE(status)) {
+                       goto cleanup;
                }
+
+               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,
-               status, &info->return_object);
+       (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);
 }
 
index 46f0f83417a1024613c39be6fe036996350107a7..dd2ceae3f7177aff169e56391292794c0651a74c 100644 (file)
@@ -176,7 +176,7 @@ acpi_status acpi_ns_initialize_devices(void)
         * part of the ACPI specification.
         */
        info.evaluate_info->prefix_node = acpi_gbl_root_node;
-       info.evaluate_info->pathname = METHOD_NAME__INI;
+       info.evaluate_info->relative_pathname = METHOD_NAME__INI;
        info.evaluate_info->parameters = NULL;
        info.evaluate_info->flags = ACPI_IGNORE_RETURN_VALUE;
 
@@ -266,28 +266,34 @@ acpi_ns_init_one_object(acpi_handle obj_handle,
 
        switch (type) {
        case ACPI_TYPE_REGION:
+
                info->op_region_count++;
                break;
 
        case ACPI_TYPE_BUFFER_FIELD:
+
                info->field_count++;
                break;
 
        case ACPI_TYPE_LOCAL_BANK_FIELD:
+
                info->field_count++;
                break;
 
        case ACPI_TYPE_BUFFER:
+
                info->buffer_count++;
                break;
 
        case ACPI_TYPE_PACKAGE:
+
                info->package_count++;
                break;
 
        default:
 
                /* No init required, just exit now */
+
                return (AE_OK);
        }
 
@@ -337,7 +343,9 @@ acpi_ns_init_one_object(acpi_handle obj_handle,
                break;
 
        default:
+
                /* No other types can get here */
+
                break;
        }
 
@@ -416,6 +424,7 @@ acpi_ns_find_ini_methods(acpi_handle obj_handle,
                break;
 
        default:
+
                break;
        }
 
@@ -560,7 +569,7 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
 
        ACPI_MEMSET(info, 0, sizeof(struct acpi_evaluate_info));
        info->prefix_node = device_node;
-       info->pathname = METHOD_NAME__INI;
+       info->relative_pathname = METHOD_NAME__INI;
        info->parameters = NULL;
        info->flags = ACPI_IGNORE_RETURN_VALUE;
 
@@ -574,8 +583,7 @@ acpi_ns_init_one_device(acpi_handle obj_handle,
 
                /* Ignore error and move on to next device */
 
-               char *scope_name =
-                   acpi_ns_get_external_pathname(info->resolved_node);
+               char *scope_name = acpi_ns_get_external_pathname(info->node);
 
                ACPI_EXCEPTION((AE_INFO, status, "during %s._INI execution",
                                scope_name));
index 8a52916148cb005a1dbe3da762788db2741b7a9a..24b71a01bf9398340c6c01f68c990ac7caa8c51f 100644 (file)
@@ -61,28 +61,29 @@ ACPI_MODULE_NAME("nspredef")
  * There are several areas that are validated:
  *
  *  1) The number of input arguments as defined by the method/object in the
- *      ASL is validated against the ACPI specification.
+ *     ASL is validated against the ACPI specification.
  *  2) The type of the return object (if any) is validated against the ACPI
- *      specification.
+ *     specification.
  *  3) For returned package objects, the count of package elements is
- *      validated, as well as the type of each package element. Nested
- *      packages are supported.
+ *     validated, as well as the type of each package element. Nested
+ *     packages are supported.
  *
  * For any problems found, a warning message is issued.
  *
  ******************************************************************************/
 /* Local prototypes */
 static acpi_status
-acpi_ns_check_reference(struct acpi_predefined_data *data,
+acpi_ns_check_reference(struct acpi_evaluate_info *info,
                        union acpi_operand_object *return_object);
 
 static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object);
 
 /*******************************************************************************
  *
- * FUNCTION:    acpi_ns_check_predefined_names
+ * FUNCTION:    acpi_ns_check_return_value
  *
  * PARAMETERS:  node            - Namespace node for the method/object
+ *              info            - Method execution information block
  *              user_param_count - Number of parameters actually passed
  *              return_status   - Status from the object evaluation
  *              return_object_ptr - Pointer to the object returned from the
@@ -90,44 +91,25 @@ static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object);
  *
  * RETURN:      Status
  *
- * DESCRIPTION: Check an ACPI name for a match in the predefined name list.
+ * DESCRIPTION: Check the value returned from a predefined name.
  *
  ******************************************************************************/
 
 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_ptr)
+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_ptr)
 {
-       acpi_status status = AE_OK;
+       acpi_status status;
        const union acpi_predefined_info *predefined;
-       char *pathname;
-       struct acpi_predefined_data *data;
-
-       /* Match the name for this method/object against the predefined list */
-
-       predefined = acpi_ut_match_predefined_method(node->name.ascii);
-
-       /* Get the full pathname to the object, for use in warning messages */
-
-       pathname = acpi_ns_get_external_pathname(node);
-       if (!pathname) {
-               return (AE_OK); /* Could not get pathname, ignore */
-       }
-
-       /*
-        * Check that the parameter count for this method matches the ASL
-        * definition. For predefined names, ensure that both the caller and
-        * the method itself are in accordance with the ACPI specification.
-        */
-       acpi_ns_check_parameter_count(pathname, node, user_param_count,
-                                     predefined);
 
        /* If not a predefined name, we cannot validate the return object */
 
+       predefined = info->predefined;
        if (!predefined) {
-               goto cleanup;
+               return (AE_OK);
        }
 
        /*
@@ -135,7 +117,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
         * validate the return object
         */
        if ((return_status != AE_OK) && (return_status != AE_CTRL_RETURN_VALUE)) {
-               goto cleanup;
+               return (AE_OK);
        }
 
        /*
@@ -154,25 +136,14 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
        if (acpi_gbl_disable_auto_repair ||
            (!predefined->info.expected_btypes) ||
            (predefined->info.expected_btypes == ACPI_RTYPE_ALL)) {
-               goto cleanup;
-       }
-
-       /* Create the parameter data block for object validation */
-
-       data = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_predefined_data));
-       if (!data) {
-               goto cleanup;
+               return (AE_OK);
        }
-       data->predefined = predefined;
-       data->node = node;
-       data->node_flags = node->flags;
-       data->pathname = pathname;
 
        /*
         * Check that the type of the main return object is what is expected
         * for this predefined name
         */
-       status = acpi_ns_check_object_type(data, return_object_ptr,
+       status = acpi_ns_check_object_type(info, return_object_ptr,
                                           predefined->info.expected_btypes,
                                           ACPI_NOT_PACKAGE_ELEMENT);
        if (ACPI_FAILURE(status)) {
@@ -184,10 +155,16 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
         * Note: Package may have been newly created by call above.
         */
        if ((*return_object_ptr)->common.type == ACPI_TYPE_PACKAGE) {
-               data->parent_package = *return_object_ptr;
-               status = acpi_ns_check_package(data, return_object_ptr);
+               info->parent_package = *return_object_ptr;
+               status = acpi_ns_check_package(info, return_object_ptr);
                if (ACPI_FAILURE(status)) {
-                       goto exit;
+
+                       /* We might be able to fix some errors */
+
+                       if ((status != AE_AML_OPERAND_TYPE) &&
+                           (status != AE_AML_OPERAND_VALUE)) {
+                               goto exit;
+                       }
                }
        }
 
@@ -199,7 +176,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
         * performed on a per-name basis, i.e., the code is specific to
         * particular predefined names.
         */
-       status = acpi_ns_complex_repairs(data, node, status, return_object_ptr);
+       status = acpi_ns_complex_repairs(info, node, status, return_object_ptr);
 
 exit:
        /*
@@ -207,112 +184,18 @@ exit:
         * or more objects, mark the parent node to suppress further warning
         * messages during the next evaluation of the same method/object.
         */
-       if (ACPI_FAILURE(status) || (data->flags & ACPI_OBJECT_REPAIRED)) {
+       if (ACPI_FAILURE(status) || (info->return_flags & ACPI_OBJECT_REPAIRED)) {
                node->flags |= ANOBJ_EVALUATED;
        }
-       ACPI_FREE(data);
 
-cleanup:
-       ACPI_FREE(pathname);
        return (status);
 }
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ns_check_parameter_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 the declared (in ASL/AML) parameter count for a
- *              predefined name is what is expected (i.e., what is defined in
- *              the ACPI specification for this predefined name.)
- *
- ******************************************************************************/
-
-void
-acpi_ns_check_parameter_count(char *pathname,
-                             struct acpi_namespace_node *node,
-                             u32 user_param_count,
-                             const union acpi_predefined_info *predefined)
-{
-       u32 param_count;
-       u32 required_params_current;
-       u32 required_params_old;
-
-       /* Methods have 0-7 parameters. All other types have zero. */
-
-       param_count = 0;
-       if (node->type == ACPI_TYPE_METHOD) {
-               param_count = node->object->method.param_count;
-       }
-
-       if (!predefined) {
-               /*
-                * Check the parameter count for non-predefined methods/objects.
-                *
-                * Warning if too few or too many arguments have been passed by the
-                * caller. An incorrect number of arguments may 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.
-                */
-               if (user_param_count < param_count) {
-                       ACPI_WARN_PREDEFINED((AE_INFO, pathname,
-                                             ACPI_WARN_ALWAYS,
-                                             "Insufficient arguments - needs %u, found %u",
-                                             param_count, user_param_count));
-               } else if (user_param_count > param_count) {
-                       ACPI_WARN_PREDEFINED((AE_INFO, pathname,
-                                             ACPI_WARN_ALWAYS,
-                                             "Excess arguments - needs %u, found %u",
-                                             param_count, user_param_count));
-               }
-               return;
-       }
-
-       /*
-        * Validate the user-supplied parameter count.
-        * Allow two different legal argument counts (_SCP, etc.)
-        */
-       required_params_current =
-           predefined->info.argument_list & METHOD_ARG_MASK;
-       required_params_old =
-           predefined->info.argument_list >> METHOD_ARG_BIT_WIDTH;
-
-       if (user_param_count != ACPI_UINT32_MAX) {
-               if ((user_param_count != required_params_current) &&
-                   (user_param_count != required_params_old)) {
-                       ACPI_WARN_PREDEFINED((AE_INFO, pathname,
-                                             ACPI_WARN_ALWAYS,
-                                             "Parameter count mismatch - "
-                                             "caller passed %u, ACPI requires %u",
-                                             user_param_count,
-                                             required_params_current));
-               }
-       }
-
-       /*
-        * Check that the ASL-defined parameter count is what is expected for
-        * this predefined name (parameter count as defined by the ACPI
-        * specification)
-        */
-       if ((param_count != required_params_current) &&
-           (param_count != required_params_old)) {
-               ACPI_WARN_PREDEFINED((AE_INFO, pathname, node->flags,
-                                     "Parameter count mismatch - ASL declared %u, ACPI requires %u",
-                                     param_count, required_params_current));
-       }
-}
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ns_check_object_type
  *
- * PARAMETERS:  data            - Pointer to validation data structure
+ * PARAMETERS:  info            - Method execution information block
  *              return_object_ptr - Pointer to the object returned from the
  *                                evaluation of a method or object
  *              expected_btypes - Bitmap of expected return type(s)
@@ -328,7 +211,7 @@ acpi_ns_check_parameter_count(char *pathname,
  ******************************************************************************/
 
 acpi_status
-acpi_ns_check_object_type(struct acpi_predefined_data *data,
+acpi_ns_check_object_type(struct acpi_evaluate_info *info,
                          union acpi_operand_object **return_object_ptr,
                          u32 expected_btypes, u32 package_index)
 {
@@ -340,7 +223,8 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data,
 
        if (return_object &&
            ACPI_GET_DESCRIPTOR_TYPE(return_object) == ACPI_DESC_TYPE_NAMED) {
-               ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+               ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+                                     info->node_flags,
                                      "Invalid return type - Found a Namespace node [%4.4s] type %s",
                                      return_object->node.name.ascii,
                                      acpi_ut_get_type_name(return_object->node.
@@ -356,8 +240,8 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data,
         * from all of the predefined names (including elements of returned
         * packages)
         */
-       data->return_btype = acpi_ns_get_bitmapped_type(return_object);
-       if (data->return_btype == ACPI_RTYPE_ANY) {
+       info->return_btype = acpi_ns_get_bitmapped_type(return_object);
+       if (info->return_btype == ACPI_RTYPE_ANY) {
 
                /* Not one of the supported objects, must be incorrect */
                goto type_error_exit;
@@ -365,16 +249,18 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data,
 
        /* For reference objects, check that the reference type is correct */
 
-       if ((data->return_btype & expected_btypes) == ACPI_RTYPE_REFERENCE) {
-               status = acpi_ns_check_reference(data, return_object);
+       if ((info->return_btype & expected_btypes) == ACPI_RTYPE_REFERENCE) {
+               status = acpi_ns_check_reference(info, return_object);
                return (status);
        }
 
        /* Attempt simple repair of the returned object if necessary */
 
-       status = acpi_ns_simple_repair(data, expected_btypes,
+       status = acpi_ns_simple_repair(info, expected_btypes,
                                       package_index, return_object_ptr);
-       return (status);
+       if (ACPI_SUCCESS(status)) {
+               return (AE_OK); /* Successful repair */
+       }
 
       type_error_exit:
 
@@ -383,12 +269,14 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data,
        acpi_ut_get_expected_return_types(type_buffer, expected_btypes);
 
        if (package_index == ACPI_NOT_PACKAGE_ELEMENT) {
-               ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+               ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+                                     info->node_flags,
                                      "Return type mismatch - found %s, expected %s",
                                      acpi_ut_get_object_type_name
                                      (return_object), type_buffer));
        } else {
-               ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+               ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+                                     info->node_flags,
                                      "Return Package type mismatch at index %u - "
                                      "found %s, expected %s", package_index,
                                      acpi_ut_get_object_type_name
@@ -402,7 +290,7 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data,
  *
  * FUNCTION:    acpi_ns_check_reference
  *
- * PARAMETERS:  data            - Pointer to validation data structure
+ * PARAMETERS:  info            - Method execution information block
  *              return_object   - Object returned from the evaluation of a
  *                                method or object
  *
@@ -415,7 +303,7 @@ acpi_ns_check_object_type(struct acpi_predefined_data *data,
  ******************************************************************************/
 
 static acpi_status
-acpi_ns_check_reference(struct acpi_predefined_data *data,
+acpi_ns_check_reference(struct acpi_evaluate_info *info,
                        union acpi_operand_object *return_object)
 {
 
@@ -428,7 +316,7 @@ acpi_ns_check_reference(struct acpi_predefined_data *data,
                return (AE_OK);
        }
 
-       ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+       ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags,
                              "Return type mismatch - unexpected reference object type [%s] %2.2X",
                              acpi_ut_get_reference_name(return_object),
                              return_object->reference.class));
@@ -462,26 +350,32 @@ static u32 acpi_ns_get_bitmapped_type(union acpi_operand_object *return_object)
 
        switch (return_object->common.type) {
        case ACPI_TYPE_INTEGER:
+
                return_btype = ACPI_RTYPE_INTEGER;
                break;
 
        case ACPI_TYPE_BUFFER:
+
                return_btype = ACPI_RTYPE_BUFFER;
                break;
 
        case ACPI_TYPE_STRING:
+
                return_btype = ACPI_RTYPE_STRING;
                break;
 
        case ACPI_TYPE_PACKAGE:
+
                return_btype = ACPI_RTYPE_PACKAGE;
                break;
 
        case ACPI_TYPE_LOCAL_REFERENCE:
+
                return_btype = ACPI_RTYPE_REFERENCE;
                break;
 
        default:
+
                /* Not one of the supported objects, must be incorrect */
 
                return_btype = ACPI_RTYPE_ANY;
index 77cdd539de16c7030659a5df53cf706497e30540..6d55cef7916c4ba4715a9108697073822edc48ec 100644 (file)
@@ -51,12 +51,12 @@ ACPI_MODULE_NAME("nsprepkg")
 
 /* Local prototypes */
 static acpi_status
-acpi_ns_check_package_list(struct acpi_predefined_data *data,
+acpi_ns_check_package_list(struct acpi_evaluate_info *info,
                           const union acpi_predefined_info *package,
                           union acpi_operand_object **elements, u32 count);
 
 static acpi_status
-acpi_ns_check_package_elements(struct acpi_predefined_data *data,
+acpi_ns_check_package_elements(struct acpi_evaluate_info *info,
                               union acpi_operand_object **elements,
                               u8 type1,
                               u32 count1,
@@ -66,7 +66,7 @@ acpi_ns_check_package_elements(struct acpi_predefined_data *data,
  *
  * FUNCTION:    acpi_ns_check_package
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              return_object_ptr   - Pointer to the object returned from the
  *                                    evaluation of a method or object
  *
@@ -78,7 +78,7 @@ acpi_ns_check_package_elements(struct acpi_predefined_data *data,
  ******************************************************************************/
 
 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)
 {
        union acpi_operand_object *return_object = *return_object_ptr;
@@ -93,18 +93,18 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
 
        /* The package info for this name is in the next table entry */
 
-       package = data->predefined + 1;
+       package = info->predefined + 1;
 
        ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
                          "%s Validating return Package of Type %X, Count %X\n",
-                         data->pathname, package->ret_info.type,
+                         info->full_pathname, package->ret_info.type,
                          return_object->package.count));
 
        /*
         * For variable-length Packages, we can safely remove all embedded
         * and trailing NULL package elements
         */
-       acpi_ns_remove_null_elements(data, package->ret_info.type,
+       acpi_ns_remove_null_elements(info, package->ret_info.type,
                                     return_object);
 
        /* Extract package count and elements array */
@@ -121,7 +121,8 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
                        return (AE_OK);
                }
 
-               ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+               ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+                                     info->node_flags,
                                      "Return Package has no elements (empty)"));
 
                return (AE_AML_OPERAND_VALUE);
@@ -135,7 +136,6 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
         */
        switch (package->ret_info.type) {
        case ACPI_PTYPE1_FIXED:
-
                /*
                 * The package count is fixed and there are no sub-packages
                 *
@@ -150,13 +150,13 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
                        ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
                                          "%s: Return Package is larger than needed - "
                                          "found %u, expected %u\n",
-                                         data->pathname, count,
+                                         info->full_pathname, count,
                                          expected_count));
                }
 
                /* Validate all elements of the returned package */
 
-               status = acpi_ns_check_package_elements(data, elements,
+               status = acpi_ns_check_package_elements(info, elements,
                                                        package->ret_info.
                                                        object_type1,
                                                        package->ret_info.
@@ -168,13 +168,12 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
                break;
 
        case ACPI_PTYPE1_VAR:
-
                /*
                 * The package count is variable, there are no sub-packages, and all
                 * elements must be of the same type
                 */
                for (i = 0; i < count; i++) {
-                       status = acpi_ns_check_object_type(data, elements,
+                       status = acpi_ns_check_object_type(info, elements,
                                                           package->ret_info.
                                                           object_type1, i);
                        if (ACPI_FAILURE(status)) {
@@ -185,7 +184,6 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
                break;
 
        case ACPI_PTYPE1_OPTION:
-
                /*
                 * The package count is variable, there are no sub-packages. There are
                 * a fixed number of required elements, and a variable number of
@@ -206,7 +204,7 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
                                /* These are the required package elements (0, 1, or 2) */
 
                                status =
-                                   acpi_ns_check_object_type(data, elements,
+                                   acpi_ns_check_object_type(info, elements,
                                                              package->
                                                              ret_info3.
                                                              object_type[i],
@@ -218,7 +216,7 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
                                /* These are the optional package elements */
 
                                status =
-                                   acpi_ns_check_object_type(data, elements,
+                                   acpi_ns_check_object_type(info, elements,
                                                              package->
                                                              ret_info3.
                                                              tail_object_type,
@@ -235,7 +233,7 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
 
                /* First element is the (Integer) revision */
 
-               status = acpi_ns_check_object_type(data, elements,
+               status = acpi_ns_check_object_type(info, elements,
                                                   ACPI_RTYPE_INTEGER, 0);
                if (ACPI_FAILURE(status)) {
                        return (status);
@@ -247,14 +245,14 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
                /* Examine the sub-packages */
 
                status =
-                   acpi_ns_check_package_list(data, package, elements, count);
+                   acpi_ns_check_package_list(info, package, elements, count);
                break;
 
        case ACPI_PTYPE2_PKG_COUNT:
 
                /* First element is the (Integer) count of sub-packages to follow */
 
-               status = acpi_ns_check_object_type(data, elements,
+               status = acpi_ns_check_object_type(info, elements,
                                                   ACPI_RTYPE_INTEGER, 0);
                if (ACPI_FAILURE(status)) {
                        return (status);
@@ -275,7 +273,7 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
                /* Examine the sub-packages */
 
                status =
-                   acpi_ns_check_package_list(data, package, elements, count);
+                   acpi_ns_check_package_list(info, package, elements, count);
                break;
 
        case ACPI_PTYPE2:
@@ -283,7 +281,6 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
        case ACPI_PTYPE2_MIN:
        case ACPI_PTYPE2_COUNT:
        case ACPI_PTYPE2_FIX_VAR:
-
                /*
                 * These types all return a single Package that consists of a
                 * variable number of sub-Packages.
@@ -300,7 +297,7 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
                        /* Create the new outer package and populate it */
 
                        status =
-                           acpi_ns_wrap_with_package(data, return_object,
+                           acpi_ns_wrap_with_package(info, return_object,
                                                      return_object_ptr);
                        if (ACPI_FAILURE(status)) {
                                return (status);
@@ -316,14 +313,15 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
                /* Examine the sub-packages */
 
                status =
-                   acpi_ns_check_package_list(data, package, elements, count);
+                   acpi_ns_check_package_list(info, package, elements, count);
                break;
 
        default:
 
                /* Should not get here if predefined info table is correct */
 
-               ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+               ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+                                     info->node_flags,
                                      "Invalid internal return type in table entry: %X",
                                      package->ret_info.type));
 
@@ -336,7 +334,7 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
 
        /* Error exit for the case with an incorrect package count */
 
-       ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+       ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags,
                              "Return Package is too small - found %u elements, expected %u",
                              count, expected_count));
 
@@ -347,7 +345,7 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
  *
  * FUNCTION:    acpi_ns_check_package_list
  *
- * PARAMETERS:  data            - Pointer to validation data structure
+ * PARAMETERS:  info            - Method execution information block
  *              package         - Pointer to package-specific info for method
  *              elements        - Element list of parent package. All elements
  *                                of this list should be of type Package.
@@ -360,7 +358,7 @@ acpi_ns_check_package(struct acpi_predefined_data *data,
  ******************************************************************************/
 
 static acpi_status
-acpi_ns_check_package_list(struct acpi_predefined_data *data,
+acpi_ns_check_package_list(struct acpi_evaluate_info *info,
                           const union acpi_predefined_info *package,
                           union acpi_operand_object **elements, u32 count)
 {
@@ -381,11 +379,11 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data,
        for (i = 0; i < count; i++) {
                sub_package = *elements;
                sub_elements = sub_package->package.elements;
-               data->parent_package = sub_package;
+               info->parent_package = sub_package;
 
                /* Each sub-object must be of type Package */
 
-               status = acpi_ns_check_object_type(data, &sub_package,
+               status = acpi_ns_check_object_type(info, &sub_package,
                                                   ACPI_RTYPE_PACKAGE, i);
                if (ACPI_FAILURE(status)) {
                        return (status);
@@ -393,7 +391,7 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data,
 
                /* Examine the different types of expected sub-packages */
 
-               data->parent_package = sub_package;
+               info->parent_package = sub_package;
                switch (package->ret_info.type) {
                case ACPI_PTYPE2:
                case ACPI_PTYPE2_PKG_COUNT:
@@ -408,7 +406,7 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data,
                        }
 
                        status =
-                           acpi_ns_check_package_elements(data, sub_elements,
+                           acpi_ns_check_package_elements(info, sub_elements,
                                                           package->ret_info.
                                                           object_type1,
                                                           package->ret_info.
@@ -434,7 +432,7 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data,
                        }
 
                        status =
-                           acpi_ns_check_package_elements(data, sub_elements,
+                           acpi_ns_check_package_elements(info, sub_elements,
                                                           package->ret_info.
                                                           object_type1,
                                                           package->ret_info.
@@ -463,7 +461,7 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data,
 
                        for (j = 0; j < expected_count; j++) {
                                status =
-                                   acpi_ns_check_object_type(data,
+                                   acpi_ns_check_object_type(info,
                                                              &sub_elements[j],
                                                              package->
                                                              ret_info2.
@@ -487,7 +485,7 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data,
                        /* Check the type of each sub-package element */
 
                        status =
-                           acpi_ns_check_package_elements(data, sub_elements,
+                           acpi_ns_check_package_elements(info, sub_elements,
                                                           package->ret_info.
                                                           object_type1,
                                                           sub_package->package.
@@ -498,12 +496,11 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data,
                        break;
 
                case ACPI_PTYPE2_COUNT:
-
                        /*
                         * First element is the (Integer) count of elements, including
                         * the count field (the ACPI name is num_elements)
                         */
-                       status = acpi_ns_check_object_type(data, sub_elements,
+                       status = acpi_ns_check_object_type(info, sub_elements,
                                                           ACPI_RTYPE_INTEGER,
                                                           0);
                        if (ACPI_FAILURE(status)) {
@@ -537,7 +534,7 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data,
                        /* Check the type of each sub-package element */
 
                        status =
-                           acpi_ns_check_package_elements(data,
+                           acpi_ns_check_package_elements(info,
                                                           (sub_elements + 1),
                                                           package->ret_info.
                                                           object_type1,
@@ -562,7 +559,7 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data,
 
        /* The sub-package count was smaller than required */
 
-       ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+       ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname, info->node_flags,
                              "Return Sub-Package[%u] is too small - found %u elements, expected %u",
                              i, sub_package->package.count, expected_count));
 
@@ -573,7 +570,7 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data,
  *
  * FUNCTION:    acpi_ns_check_package_elements
  *
- * PARAMETERS:  data            - Pointer to validation data structure
+ * PARAMETERS:  info            - Method execution information block
  *              elements        - Pointer to the package elements array
  *              type1           - Object type for first group
  *              count1          - Count for first group
@@ -589,7 +586,7 @@ acpi_ns_check_package_list(struct acpi_predefined_data *data,
  ******************************************************************************/
 
 static acpi_status
-acpi_ns_check_package_elements(struct acpi_predefined_data *data,
+acpi_ns_check_package_elements(struct acpi_evaluate_info *info,
                               union acpi_operand_object **elements,
                               u8 type1,
                               u32 count1,
@@ -605,7 +602,7 @@ acpi_ns_check_package_elements(struct acpi_predefined_data *data,
         * The second group can have a count of zero.
         */
        for (i = 0; i < count1; i++) {
-               status = acpi_ns_check_object_type(data, this_element,
+               status = acpi_ns_check_object_type(info, this_element,
                                                   type1, i + start_index);
                if (ACPI_FAILURE(status)) {
                        return (status);
@@ -614,7 +611,7 @@ acpi_ns_check_package_elements(struct acpi_predefined_data *data,
        }
 
        for (i = 0; i < count2; i++) {
-               status = acpi_ns_check_object_type(data, this_element,
+               status = acpi_ns_check_object_type(info, this_element,
                                                   type2,
                                                   (i + count1 + start_index));
                if (ACPI_FAILURE(status)) {
index 18f02e4ece01dbc626be1d6829ef27c3f9950590..f8e71ea60319b21b6c014c88c69efc0b5a2dc751 100644 (file)
@@ -130,7 +130,7 @@ static const struct acpi_simple_repair_info acpi_object_repair_info[] = {
  *
  * FUNCTION:    acpi_ns_simple_repair
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              expected_btypes     - Object types expected
  *              package_index       - Index of object within parent package (if
  *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
@@ -146,7 +146,7 @@ static const struct acpi_simple_repair_info acpi_object_repair_info[] = {
  ******************************************************************************/
 
 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)
@@ -162,12 +162,12 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data,
         * Special repairs for certain names that are in the repair table.
         * Check if this name is in the list of repairable names.
         */
-       predefined = acpi_ns_match_simple_repair(data->node,
-                                                data->return_btype,
+       predefined = acpi_ns_match_simple_repair(info->node,
+                                                info->return_btype,
                                                 package_index);
        if (predefined) {
                if (!return_object) {
-                       ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
+                       ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
                                              ACPI_WARN_ALWAYS,
                                              "Missing expected return value"));
                }
@@ -191,7 +191,7 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data,
         * Do not perform simple object repair unless the return type is not
         * expected.
         */
-       if (data->return_btype & expected_btypes) {
+       if (info->return_btype & expected_btypes) {
                return (AE_OK);
        }
 
@@ -211,7 +211,7 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data,
         */
        if (!return_object) {
                if (expected_btypes && (!(expected_btypes & ACPI_RTYPE_NONE))) {
-                       ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
+                       ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
                                              ACPI_WARN_ALWAYS,
                                              "Missing expected return value"));
 
@@ -247,14 +247,14 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data,
                 * for correct contents (expected object type or types).
                 */
                status =
-                   acpi_ns_wrap_with_package(data, return_object, &new_object);
+                   acpi_ns_wrap_with_package(info, return_object, &new_object);
                if (ACPI_SUCCESS(status)) {
                        /*
                         * The original object just had its reference count
                         * incremented for being inserted into the new package.
                         */
                        *return_object_ptr = new_object;        /* New Package object */
-                       data->flags |= ACPI_OBJECT_REPAIRED;
+                       info->return_flags |= ACPI_OBJECT_REPAIRED;
                        return (AE_OK);
                }
        }
@@ -277,7 +277,7 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data,
                 * package object as part of the repair, we don't need to
                 * change the reference count.
                 */
-               if (!(data->flags & ACPI_OBJECT_WRAPPED)) {
+               if (!(info->return_flags & ACPI_OBJECT_WRAPPED)) {
                        new_object->common.reference_count =
                            return_object->common.reference_count;
 
@@ -288,14 +288,14 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data,
 
                ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
                                  "%s: Converted %s to expected %s at Package index %u\n",
-                                 data->pathname,
+                                 info->full_pathname,
                                  acpi_ut_get_object_type_name(return_object),
                                  acpi_ut_get_object_type_name(new_object),
                                  package_index));
        } else {
                ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
                                  "%s: Converted %s to expected %s\n",
-                                 data->pathname,
+                                 info->full_pathname,
                                  acpi_ut_get_object_type_name(return_object),
                                  acpi_ut_get_object_type_name(new_object)));
        }
@@ -304,7 +304,7 @@ acpi_ns_simple_repair(struct acpi_predefined_data *data,
 
        acpi_ut_remove_reference(return_object);
        *return_object_ptr = new_object;
-       data->flags |= ACPI_OBJECT_REPAIRED;
+       info->return_flags |= ACPI_OBJECT_REPAIRED;
        return (AE_OK);
 }
 
@@ -359,7 +359,7 @@ static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
  *
  * FUNCTION:    acpi_ns_repair_null_element
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              expected_btypes     - Object types expected
  *              package_index       - Index of object within parent package (if
  *                                    applicable - ACPI_NOT_PACKAGE_ELEMENT
@@ -374,7 +374,7 @@ static const struct acpi_simple_repair_info *acpi_ns_match_simple_repair(struct
  ******************************************************************************/
 
 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)
@@ -424,16 +424,16 @@ acpi_ns_repair_null_element(struct acpi_predefined_data *data,
        /* Set the reference count according to the parent Package object */
 
        new_object->common.reference_count =
-           data->parent_package->common.reference_count;
+           info->parent_package->common.reference_count;
 
        ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
                          "%s: Converted NULL package element to expected %s at index %u\n",
-                         data->pathname,
+                         info->full_pathname,
                          acpi_ut_get_object_type_name(new_object),
                          package_index));
 
        *return_object_ptr = new_object;
-       data->flags |= ACPI_OBJECT_REPAIRED;
+       info->return_flags |= ACPI_OBJECT_REPAIRED;
        return (AE_OK);
 }
 
@@ -441,7 +441,7 @@ acpi_ns_repair_null_element(struct acpi_predefined_data *data,
  *
  * FUNCTION:    acpi_ns_remove_null_elements
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              package_type        - An acpi_return_package_types value
  *              obj_desc            - A Package object
  *
@@ -454,7 +454,7 @@ acpi_ns_repair_null_element(struct acpi_predefined_data *data,
  *****************************************************************************/
 
 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)
 {
@@ -480,6 +480,7 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
        case ACPI_PTYPE2_MIN:
        case ACPI_PTYPE2_REV_FIXED:
        case ACPI_PTYPE2_FIX_VAR:
+
                break;
 
        default:
@@ -511,7 +512,7 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
        if (new_count < count) {
                ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
                                  "%s: Found and removed %u NULL elements\n",
-                                 data->pathname, (count - new_count)));
+                                 info->full_pathname, (count - new_count)));
 
                /* NULL terminate list and update the package count */
 
@@ -524,7 +525,7 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
  *
  * FUNCTION:    acpi_ns_wrap_with_package
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              original_object     - Pointer to the object to repair.
  *              obj_desc_ptr        - The new package object is returned here
  *
@@ -545,7 +546,7 @@ acpi_ns_remove_null_elements(struct acpi_predefined_data *data,
  ******************************************************************************/
 
 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)
 {
@@ -566,12 +567,12 @@ acpi_ns_wrap_with_package(struct acpi_predefined_data *data,
 
        ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
                          "%s: Wrapped %s with expected Package object\n",
-                         data->pathname,
+                         info->full_pathname,
                          acpi_ut_get_object_type_name(original_object)));
 
        /* Return the new object in the object pointer */
 
        *obj_desc_ptr = pkg_obj_desc;
-       data->flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED;
+       info->return_flags |= ACPI_OBJECT_REPAIRED | ACPI_OBJECT_WRAPPED;
        return (AE_OK);
 }
index 149e9b9c2c1b1e3fbb8349de7338697b540d976d..c84603ee83ae084312f3936324a1bfb524b64f08 100644 (file)
@@ -54,7 +54,7 @@ ACPI_MODULE_NAME("nsrepair2")
  * be repaired on a per-name basis.
  */
 typedef
-acpi_status(*acpi_repair_function) (struct acpi_predefined_data *data,
+acpi_status(*acpi_repair_function) (struct acpi_evaluate_info * info,
                                    union acpi_operand_object
                                    **return_object_ptr);
 
@@ -71,45 +71,57 @@ static const struct acpi_repair_info *acpi_ns_match_complex_repair(struct
                                                                   *node);
 
 static acpi_status
-acpi_ns_repair_ALR(struct acpi_predefined_data *data,
+acpi_ns_repair_ALR(struct acpi_evaluate_info *info,
                   union acpi_operand_object **return_object_ptr);
 
 static acpi_status
-acpi_ns_repair_CID(struct acpi_predefined_data *data,
+acpi_ns_repair_CID(struct acpi_evaluate_info *info,
                   union acpi_operand_object **return_object_ptr);
 
 static acpi_status
-acpi_ns_repair_FDE(struct acpi_predefined_data *data,
+acpi_ns_repair_CST(struct acpi_evaluate_info *info,
                   union acpi_operand_object **return_object_ptr);
 
 static acpi_status
-acpi_ns_repair_HID(struct acpi_predefined_data *data,
+acpi_ns_repair_FDE(struct acpi_evaluate_info *info,
                   union acpi_operand_object **return_object_ptr);
 
 static acpi_status
-acpi_ns_repair_PSS(struct acpi_predefined_data *data,
+acpi_ns_repair_HID(struct acpi_evaluate_info *info,
                   union acpi_operand_object **return_object_ptr);
 
 static acpi_status
-acpi_ns_repair_TSS(struct acpi_predefined_data *data,
+acpi_ns_repair_PRT(struct acpi_evaluate_info *info,
                   union acpi_operand_object **return_object_ptr);
 
 static acpi_status
-acpi_ns_check_sorted_list(struct acpi_predefined_data *data,
+acpi_ns_repair_PSS(struct acpi_evaluate_info *info,
+                  union acpi_operand_object **return_object_ptr);
+
+static acpi_status
+acpi_ns_repair_TSS(struct acpi_evaluate_info *info,
+                  union acpi_operand_object **return_object_ptr);
+
+static acpi_status
+acpi_ns_check_sorted_list(struct acpi_evaluate_info *info,
                          union acpi_operand_object *return_object,
+                         u32 start_index,
                          u32 expected_count,
                          u32 sort_index,
                          u8 sort_direction, char *sort_key_name);
 
-static void
-acpi_ns_sort_list(union acpi_operand_object **elements,
-                 u32 count, u32 index, u8 sort_direction);
-
 /* Values for sort_direction above */
 
 #define ACPI_SORT_ASCENDING     0
 #define ACPI_SORT_DESCENDING    1
 
+static void
+acpi_ns_remove_element(union acpi_operand_object *obj_desc, u32 index);
+
+static void
+acpi_ns_sort_list(union acpi_operand_object **elements,
+                 u32 count, u32 index, u8 sort_direction);
+
 /*
  * This table contains the names of the predefined methods for which we can
  * perform more complex repairs.
@@ -118,9 +130,11 @@ acpi_ns_sort_list(union acpi_operand_object **elements,
  *
  * _ALR: Sort the list ascending by ambient_illuminance
  * _CID: Strings: uppercase all, remove any leading asterisk
+ * _CST: Sort the list ascending by C state type
  * _FDE: Convert Buffer of BYTEs to a Buffer of DWORDs
  * _GTM: Convert Buffer of BYTEs to a Buffer of DWORDs
  * _HID: Strings: uppercase all, remove any leading asterisk
+ * _PRT: Fix reversed source_name and source_index
  * _PSS: Sort the list descending by Power
  * _TSS: Sort the list descending by Power
  *
@@ -134,9 +148,11 @@ acpi_ns_sort_list(union acpi_operand_object **elements,
 static const struct acpi_repair_info acpi_ns_repairable_names[] = {
        {"_ALR", acpi_ns_repair_ALR},
        {"_CID", acpi_ns_repair_CID},
+       {"_CST", acpi_ns_repair_CST},
        {"_FDE", acpi_ns_repair_FDE},
        {"_GTM", acpi_ns_repair_FDE},   /* _GTM has same repair as _FDE */
        {"_HID", acpi_ns_repair_HID},
+       {"_PRT", acpi_ns_repair_PRT},
        {"_PSS", acpi_ns_repair_PSS},
        {"_TSS", acpi_ns_repair_TSS},
        {{0, 0, 0, 0}, NULL}    /* Table terminator */
@@ -150,7 +166,7 @@ static const struct acpi_repair_info acpi_ns_repairable_names[] = {
  *
  * FUNCTION:    acpi_ns_complex_repairs
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              node                - Namespace node for the method/object
  *              validate_status     - Original status of earlier validation
  *              return_object_ptr   - Pointer to the object returned from the
@@ -165,7 +181,7 @@ static const struct acpi_repair_info acpi_ns_repairable_names[] = {
  *****************************************************************************/
 
 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)
@@ -180,7 +196,7 @@ acpi_ns_complex_repairs(struct acpi_predefined_data *data,
                return (validate_status);
        }
 
-       status = predefined->repair_function(data, return_object_ptr);
+       status = predefined->repair_function(info, return_object_ptr);
        return (status);
 }
 
@@ -219,7 +235,7 @@ static const struct acpi_repair_info *acpi_ns_match_complex_repair(struct
  *
  * FUNCTION:    acpi_ns_repair_ALR
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              return_object_ptr   - Pointer to the object returned from the
  *                                    evaluation of a method or object
  *
@@ -231,13 +247,13 @@ static const struct acpi_repair_info *acpi_ns_match_complex_repair(struct
  *****************************************************************************/
 
 static acpi_status
-acpi_ns_repair_ALR(struct acpi_predefined_data *data,
+acpi_ns_repair_ALR(struct acpi_evaluate_info *info,
                   union acpi_operand_object **return_object_ptr)
 {
        union acpi_operand_object *return_object = *return_object_ptr;
        acpi_status status;
 
-       status = acpi_ns_check_sorted_list(data, return_object, 2, 1,
+       status = acpi_ns_check_sorted_list(info, return_object, 0, 2, 1,
                                           ACPI_SORT_ASCENDING,
                                           "AmbientIlluminance");
 
@@ -248,7 +264,7 @@ acpi_ns_repair_ALR(struct acpi_predefined_data *data,
  *
  * FUNCTION:    acpi_ns_repair_FDE
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              return_object_ptr   - Pointer to the object returned from the
  *                                    evaluation of a method or object
  *
@@ -262,7 +278,7 @@ acpi_ns_repair_ALR(struct acpi_predefined_data *data,
  *****************************************************************************/
 
 static acpi_status
-acpi_ns_repair_FDE(struct acpi_predefined_data *data,
+acpi_ns_repair_FDE(struct acpi_evaluate_info *info,
                   union acpi_operand_object **return_object_ptr)
 {
        union acpi_operand_object *return_object = *return_object_ptr;
@@ -285,8 +301,8 @@ acpi_ns_repair_FDE(struct acpi_predefined_data *data,
                /* We can only repair if we have exactly 5 BYTEs */
 
                if (return_object->buffer.length != ACPI_FDE_BYTE_BUFFER_SIZE) {
-                       ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
-                                             data->node_flags,
+                       ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+                                             info->node_flags,
                                              "Incorrect return buffer length %u, expected %u",
                                              return_object->buffer.length,
                                              ACPI_FDE_DWORD_BUFFER_SIZE));
@@ -316,10 +332,11 @@ acpi_ns_repair_FDE(struct acpi_predefined_data *data,
 
                ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
                                  "%s Expanded Byte Buffer to expected DWord Buffer\n",
-                                 data->pathname));
+                                 info->full_pathname));
                break;
 
        default:
+
                return (AE_AML_OPERAND_TYPE);
        }
 
@@ -328,7 +345,7 @@ acpi_ns_repair_FDE(struct acpi_predefined_data *data,
        acpi_ut_remove_reference(return_object);
        *return_object_ptr = buffer_object;
 
-       data->flags |= ACPI_OBJECT_REPAIRED;
+       info->return_flags |= ACPI_OBJECT_REPAIRED;
        return (AE_OK);
 }
 
@@ -336,7 +353,7 @@ acpi_ns_repair_FDE(struct acpi_predefined_data *data,
  *
  * FUNCTION:    acpi_ns_repair_CID
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              return_object_ptr   - Pointer to the object returned from the
  *                                    evaluation of a method or object
  *
@@ -349,7 +366,7 @@ acpi_ns_repair_FDE(struct acpi_predefined_data *data,
  *****************************************************************************/
 
 static acpi_status
-acpi_ns_repair_CID(struct acpi_predefined_data *data,
+acpi_ns_repair_CID(struct acpi_evaluate_info *info,
                   union acpi_operand_object **return_object_ptr)
 {
        acpi_status status;
@@ -362,7 +379,7 @@ acpi_ns_repair_CID(struct acpi_predefined_data *data,
        /* Check for _CID as a simple string */
 
        if (return_object->common.type == ACPI_TYPE_STRING) {
-               status = acpi_ns_repair_HID(data, return_object_ptr);
+               status = acpi_ns_repair_HID(info, return_object_ptr);
                return (status);
        }
 
@@ -379,7 +396,7 @@ acpi_ns_repair_CID(struct acpi_predefined_data *data,
                original_element = *element_ptr;
                original_ref_count = original_element->common.reference_count;
 
-               status = acpi_ns_repair_HID(data, element_ptr);
+               status = acpi_ns_repair_HID(info, element_ptr);
                if (ACPI_FAILURE(status)) {
                        return (status);
                }
@@ -402,11 +419,97 @@ acpi_ns_repair_CID(struct acpi_predefined_data *data,
        return (AE_OK);
 }
 
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_repair_CST
+ *
+ * PARAMETERS:  info                - Method execution information block
+ *              return_object_ptr   - Pointer to the object returned from the
+ *                                    evaluation of a method or object
+ *
+ * RETURN:      Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _CST object:
+ *              1. Sort the list ascending by C state type
+ *              2. Ensure type cannot be zero
+ *              3. A sub-package count of zero means _CST is meaningless
+ *              4. Count must match the number of C state sub-packages
+ *
+ *****************************************************************************/
+
+static acpi_status
+acpi_ns_repair_CST(struct acpi_evaluate_info *info,
+                  union acpi_operand_object **return_object_ptr)
+{
+       union acpi_operand_object *return_object = *return_object_ptr;
+       union acpi_operand_object **outer_elements;
+       u32 outer_element_count;
+       union acpi_operand_object *obj_desc;
+       acpi_status status;
+       u8 removing;
+       u32 i;
+
+       ACPI_FUNCTION_NAME(ns_repair_CST);
+
+       /*
+        * Check if the C-state type values are proportional.
+        */
+       outer_element_count = return_object->package.count - 1;
+       i = 0;
+       while (i < outer_element_count) {
+               outer_elements = &return_object->package.elements[i + 1];
+               removing = FALSE;
+
+               if ((*outer_elements)->package.count == 0) {
+                       ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+                                             info->node_flags,
+                                             "SubPackage[%u] - removing entry due to zero count",
+                                             i));
+                       removing = TRUE;
+                       goto remove_element;
+               }
+
+               obj_desc = (*outer_elements)->package.elements[1];      /* Index1 = Type */
+               if ((u32)obj_desc->integer.value == 0) {
+                       ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+                                             info->node_flags,
+                                             "SubPackage[%u] - removing entry due to invalid Type(0)",
+                                             i));
+                       removing = TRUE;
+               }
+
+             remove_element:
+               if (removing) {
+                       acpi_ns_remove_element(return_object, i + 1);
+                       outer_element_count--;
+               } else {
+                       i++;
+               }
+       }
+
+       /* Update top-level package count, Type "Integer" checked elsewhere */
+
+       obj_desc = return_object->package.elements[0];
+       obj_desc->integer.value = outer_element_count;
+
+       /*
+        * Entries (subpackages) in the _CST Package must be sorted by the
+        * C-state type, in ascending order.
+        */
+       status = acpi_ns_check_sorted_list(info, return_object, 1, 4, 1,
+                                          ACPI_SORT_ASCENDING, "C-State Type");
+       if (ACPI_FAILURE(status)) {
+               return (status);
+       }
+
+       return (AE_OK);
+}
+
 /******************************************************************************
  *
  * FUNCTION:    acpi_ns_repair_HID
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              return_object_ptr   - Pointer to the object returned from the
  *                                    evaluation of a method or object
  *
@@ -418,7 +521,7 @@ acpi_ns_repair_CID(struct acpi_predefined_data *data,
  *****************************************************************************/
 
 static acpi_status
-acpi_ns_repair_HID(struct acpi_predefined_data *data,
+acpi_ns_repair_HID(struct acpi_evaluate_info *info,
                   union acpi_operand_object **return_object_ptr)
 {
        union acpi_operand_object *return_object = *return_object_ptr;
@@ -435,12 +538,13 @@ acpi_ns_repair_HID(struct acpi_predefined_data *data,
        }
 
        if (return_object->string.length == 0) {
-               ACPI_WARN_PREDEFINED((AE_INFO, data->pathname, data->node_flags,
+               ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+                                     info->node_flags,
                                      "Invalid zero-length _HID or _CID string"));
 
                /* Return AE_OK anyway, let driver handle it */
 
-               data->flags |= ACPI_OBJECT_REPAIRED;
+               info->return_flags |= ACPI_OBJECT_REPAIRED;
                return (AE_OK);
        }
 
@@ -464,7 +568,7 @@ acpi_ns_repair_HID(struct acpi_predefined_data *data,
 
                ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
                                  "%s: Removed invalid leading asterisk\n",
-                                 data->pathname));
+                                 info->full_pathname));
        }
 
        /*
@@ -486,53 +590,69 @@ acpi_ns_repair_HID(struct acpi_predefined_data *data,
 
 /******************************************************************************
  *
- * FUNCTION:    acpi_ns_repair_TSS
+ * FUNCTION:    acpi_ns_repair_PRT
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              return_object_ptr   - Pointer to the object returned from the
  *                                    evaluation of a method or object
  *
  * RETURN:      Status. AE_OK if object is OK or was repaired successfully
  *
- * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
- *              descending by the power dissipation values.
+ * DESCRIPTION: Repair for the _PRT object. If necessary, fix reversed
+ *              source_name and source_index field, a common BIOS bug.
  *
  *****************************************************************************/
 
 static acpi_status
-acpi_ns_repair_TSS(struct acpi_predefined_data *data,
+acpi_ns_repair_PRT(struct acpi_evaluate_info *info,
                   union acpi_operand_object **return_object_ptr)
 {
-       union acpi_operand_object *return_object = *return_object_ptr;
-       acpi_status status;
-       struct acpi_namespace_node *node;
+       union acpi_operand_object *package_object = *return_object_ptr;
+       union acpi_operand_object **top_object_list;
+       union acpi_operand_object **sub_object_list;
+       union acpi_operand_object *obj_desc;
+       u32 element_count;
+       u32 index;
 
-       /*
-        * We can only sort the _TSS return package if there is no _PSS in the
-        * same scope. This is because if _PSS is present, the ACPI specification
-        * dictates that the _TSS Power Dissipation field is to be ignored, and
-        * therefore some BIOSs leave garbage values in the _TSS Power field(s).
-        * In this case, it is best to just return the _TSS package as-is.
-        * (May, 2011)
-        */
-       status =
-           acpi_ns_get_node(data->node, "^_PSS", ACPI_NS_NO_UPSEARCH, &node);
-       if (ACPI_SUCCESS(status)) {
-               return (AE_OK);
-       }
+       /* Each element in the _PRT package is a subpackage */
 
-       status = acpi_ns_check_sorted_list(data, return_object, 5, 1,
-                                          ACPI_SORT_DESCENDING,
-                                          "PowerDissipation");
+       top_object_list = package_object->package.elements;
+       element_count = package_object->package.count;
 
-       return (status);
+       for (index = 0; index < element_count; index++) {
+               sub_object_list = (*top_object_list)->package.elements;
+
+               /*
+                * If the BIOS has erroneously reversed the _PRT source_name (index 2)
+                * and the source_index (index 3), fix it. _PRT is important enough to
+                * workaround this BIOS error. This also provides compatibility with
+                * other ACPI implementations.
+                */
+               obj_desc = sub_object_list[3];
+               if (!obj_desc || (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
+                       sub_object_list[3] = sub_object_list[2];
+                       sub_object_list[2] = obj_desc;
+                       info->return_flags |= ACPI_OBJECT_REPAIRED;
+
+                       ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+                                             info->node_flags,
+                                             "PRT[%X]: Fixed reversed SourceName and SourceIndex",
+                                             index));
+               }
+
+               /* Point to the next union acpi_operand_object in the top level package */
+
+               top_object_list++;
+       }
+
+       return (AE_OK);
 }
 
 /******************************************************************************
  *
  * FUNCTION:    acpi_ns_repair_PSS
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              return_object_ptr   - Pointer to the object returned from the
  *                                    evaluation of a method or object
  *
@@ -546,7 +666,7 @@ acpi_ns_repair_TSS(struct acpi_predefined_data *data,
  *****************************************************************************/
 
 static acpi_status
-acpi_ns_repair_PSS(struct acpi_predefined_data *data,
+acpi_ns_repair_PSS(struct acpi_evaluate_info *info,
                   union acpi_operand_object **return_object_ptr)
 {
        union acpi_operand_object *return_object = *return_object_ptr;
@@ -564,7 +684,7 @@ acpi_ns_repair_PSS(struct acpi_predefined_data *data,
         * incorrectly sorted, sort it. We sort by cpu_frequency, since this
         * should be proportional to the power.
         */
-       status = acpi_ns_check_sorted_list(data, return_object, 6, 0,
+       status = acpi_ns_check_sorted_list(info, return_object, 0, 6, 0,
                                           ACPI_SORT_DESCENDING,
                                           "CpuFrequency");
        if (ACPI_FAILURE(status)) {
@@ -584,8 +704,8 @@ acpi_ns_repair_PSS(struct acpi_predefined_data *data,
                obj_desc = elements[1]; /* Index1 = power_dissipation */
 
                if ((u32) obj_desc->integer.value > previous_value) {
-                       ACPI_WARN_PREDEFINED((AE_INFO, data->pathname,
-                                             data->node_flags,
+                       ACPI_WARN_PREDEFINED((AE_INFO, info->full_pathname,
+                                             info->node_flags,
                                              "SubPackage[%u,%u] - suspicious power dissipation values",
                                              i - 1, i));
                }
@@ -597,12 +717,57 @@ acpi_ns_repair_PSS(struct acpi_predefined_data *data,
        return (AE_OK);
 }
 
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_repair_TSS
+ *
+ * PARAMETERS:  info                - Method execution information block
+ *              return_object_ptr   - Pointer to the object returned from the
+ *                                    evaluation of a method or object
+ *
+ * RETURN:      Status. AE_OK if object is OK or was repaired successfully
+ *
+ * DESCRIPTION: Repair for the _TSS object. If necessary, sort the object list
+ *              descending by the power dissipation values.
+ *
+ *****************************************************************************/
+
+static acpi_status
+acpi_ns_repair_TSS(struct acpi_evaluate_info *info,
+                  union acpi_operand_object **return_object_ptr)
+{
+       union acpi_operand_object *return_object = *return_object_ptr;
+       acpi_status status;
+       struct acpi_namespace_node *node;
+
+       /*
+        * We can only sort the _TSS return package if there is no _PSS in the
+        * same scope. This is because if _PSS is present, the ACPI specification
+        * dictates that the _TSS Power Dissipation field is to be ignored, and
+        * therefore some BIOSs leave garbage values in the _TSS Power field(s).
+        * In this case, it is best to just return the _TSS package as-is.
+        * (May, 2011)
+        */
+       status = acpi_ns_get_node(info->node, "^_PSS",
+                                 ACPI_NS_NO_UPSEARCH, &node);
+       if (ACPI_SUCCESS(status)) {
+               return (AE_OK);
+       }
+
+       status = acpi_ns_check_sorted_list(info, return_object, 0, 5, 1,
+                                          ACPI_SORT_DESCENDING,
+                                          "PowerDissipation");
+
+       return (status);
+}
+
 /******************************************************************************
  *
  * FUNCTION:    acpi_ns_check_sorted_list
  *
- * PARAMETERS:  data                - Pointer to validation data structure
+ * PARAMETERS:  info                - Method execution information block
  *              return_object       - Pointer to the top-level returned object
+ *              start_index         - Index of the first sub-package
  *              expected_count      - Minimum length of each sub-package
  *              sort_index          - Sub-package entry to sort on
  *              sort_direction      - Ascending or descending
@@ -617,8 +782,9 @@ acpi_ns_repair_PSS(struct acpi_predefined_data *data,
  *****************************************************************************/
 
 static acpi_status
-acpi_ns_check_sorted_list(struct acpi_predefined_data *data,
+acpi_ns_check_sorted_list(struct acpi_evaluate_info *info,
                          union acpi_operand_object *return_object,
+                         u32 start_index,
                          u32 expected_count,
                          u32 sort_index,
                          u8 sort_direction, char *sort_key_name)
@@ -643,12 +809,14 @@ acpi_ns_check_sorted_list(struct acpi_predefined_data *data,
         * Any NULL elements should have been removed by earlier call
         * to acpi_ns_remove_null_elements.
         */
-       outer_elements = return_object->package.elements;
        outer_element_count = return_object->package.count;
-       if (!outer_element_count) {
+       if (!outer_element_count || start_index >= outer_element_count) {
                return (AE_AML_PACKAGE_LIMIT);
        }
 
+       outer_elements = &return_object->package.elements[start_index];
+       outer_element_count -= start_index;
+
        previous_value = 0;
        if (sort_direction == ACPI_SORT_DESCENDING) {
                previous_value = ACPI_UINT32_MAX;
@@ -685,15 +853,16 @@ acpi_ns_check_sorted_list(struct acpi_predefined_data *data,
                     (obj_desc->integer.value < previous_value)) ||
                    ((sort_direction == ACPI_SORT_DESCENDING) &&
                     (obj_desc->integer.value > previous_value))) {
-                       acpi_ns_sort_list(return_object->package.elements,
+                       acpi_ns_sort_list(&return_object->package.
+                                         elements[start_index],
                                          outer_element_count, sort_index,
                                          sort_direction);
 
-                       data->flags |= ACPI_OBJECT_REPAIRED;
+                       info->return_flags |= ACPI_OBJECT_REPAIRED;
 
                        ACPI_DEBUG_PRINT((ACPI_DB_REPAIR,
                                          "%s: Repaired unsorted list - now sorted by %s\n",
-                                         data->pathname, sort_key_name));
+                                         info->full_pathname, sort_key_name));
                        return (AE_OK);
                }
 
@@ -752,3 +921,52 @@ acpi_ns_sort_list(union acpi_operand_object **elements,
                }
        }
 }
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_remove_element
+ *
+ * PARAMETERS:  obj_desc            - Package object element list
+ *              index               - Index of element to remove
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Remove the requested element of a package and delete it.
+ *
+ *****************************************************************************/
+
+static void
+acpi_ns_remove_element(union acpi_operand_object *obj_desc, u32 index)
+{
+       union acpi_operand_object **source;
+       union acpi_operand_object **dest;
+       u32 count;
+       u32 new_count;
+       u32 i;
+
+       ACPI_FUNCTION_NAME(ns_remove_element);
+
+       count = obj_desc->package.count;
+       new_count = count - 1;
+
+       source = obj_desc->package.elements;
+       dest = source;
+
+       /* Examine all elements of the package object, remove matched index */
+
+       for (i = 0; i < count; i++) {
+               if (i == index) {
+                       acpi_ut_remove_reference(*source);      /* Remove one ref for being in pkg */
+                       acpi_ut_remove_reference(*source);
+               } else {
+                       *dest = *source;
+                       dest++;
+               }
+               source++;
+       }
+
+       /* NULL terminate list and update the package count */
+
+       *dest = NULL;
+       obj_desc->package.count = new_count;
+}
index 2808586fad30c61a7bb6c5e014cde4b5a5dcff15..08c0b5beec888c65ea0d175f2795bb1be0f95227 100644 (file)
@@ -419,10 +419,12 @@ acpi_ns_externalize_name(u32 internal_name_length,
 
        switch (internal_name[0]) {
        case AML_ROOT_PREFIX:
+
                prefix_length = 1;
                break;
 
        case AML_PARENT_PREFIX:
+
                for (i = 0; i < internal_name_length; i++) {
                        if (ACPI_IS_PARENT_PREFIX(internal_name[i])) {
                                prefix_length = i + 1;
@@ -438,6 +440,7 @@ acpi_ns_externalize_name(u32 internal_name_length,
                break;
 
        default:
+
                break;
        }
 
index fc69949151bb9cc073d61b9702eb6ef1c5fa91fd..f553cfdb71ddd6ec350b63077f6eda49f30daac9 100644 (file)
@@ -187,8 +187,6 @@ acpi_evaluate_object(acpi_handle handle,
                return_ACPI_STATUS(AE_NO_MEMORY);
        }
 
-       info->pathname = pathname;
-
        /* Convert and validate the device handle */
 
        info->prefix_node = acpi_ns_validate_handle(handle);
@@ -198,17 +196,64 @@ acpi_evaluate_object(acpi_handle handle,
        }
 
        /*
-        * If there are parameters to be passed to a control method, the external
-        * objects must all be converted to internal objects
+        * Get the actual namespace node for the target object.
+        * Handles these cases:
+        *
+        * 1) Null node, valid pathname from root (absolute path)
+        * 2) Node and valid pathname (path relative to Node)
+        * 3) Node, Null pathname
+        */
+       if ((pathname) && (ACPI_IS_ROOT_PREFIX(pathname[0]))) {
+
+               /* The path is fully qualified, just evaluate by name */
+
+               info->prefix_node = NULL;
+       } else if (!handle) {
+               /*
+                * A handle is optional iff a fully qualified pathname is specified.
+                * Since we've already handled fully qualified names above, this is
+                * an error.
+                */
+               if (!pathname) {
+                       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                                         "Both Handle and Pathname are NULL"));
+               } else {
+                       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                                         "Null Handle with relative pathname [%s]",
+                                         pathname));
+               }
+
+               status = AE_BAD_PARAMETER;
+               goto cleanup;
+       }
+
+       info->relative_pathname = pathname;
+
+       /*
+        * Convert all external objects passed as arguments to the
+        * internal version(s).
         */
        if (external_params && external_params->count) {
+               info->param_count = (u16)external_params->count;
+
+               /* Warn on impossible argument count */
+
+               if (info->param_count > ACPI_METHOD_NUM_ARGS) {
+                       ACPI_WARN_PREDEFINED((AE_INFO, pathname,
+                                             ACPI_WARN_ALWAYS,
+                                             "Excess arguments (%u) - using only %u",
+                                             info->param_count,
+                                             ACPI_METHOD_NUM_ARGS));
+
+                       info->param_count = ACPI_METHOD_NUM_ARGS;
+               }
+
                /*
                 * Allocate a new parameter block for the internal objects
                 * Add 1 to count to allow for null terminated internal list
                 */
-               info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size)
-                                                        external_params->
-                                                        count +
+               info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size) info->
+                                                        param_count +
                                                         1) * sizeof(void *));
                if (!info->parameters) {
                        status = AE_NO_MEMORY;
@@ -217,7 +262,7 @@ acpi_evaluate_object(acpi_handle handle,
 
                /* Convert each external object in the list to an internal object */
 
-               for (i = 0; i < external_params->count; i++) {
+               for (i = 0; i < info->param_count; i++) {
                        status =
                            acpi_ut_copy_eobject_to_iobject(&external_params->
                                                            pointer[i],
@@ -227,43 +272,96 @@ acpi_evaluate_object(acpi_handle handle,
                                goto cleanup;
                        }
                }
-               info->parameters[external_params->count] = NULL;
+
+               info->parameters[info->param_count] = NULL;
        }
 
+#if 0
+
        /*
-        * Three major cases:
-        * 1) Fully qualified pathname
-        * 2) No handle, not fully qualified pathname (error)
-        * 3) Valid handle
+        * Begin incoming argument count analysis. Check for too few args
+        * and too many args.
         */
-       if ((pathname) && (ACPI_IS_ROOT_PREFIX(pathname[0]))) {
 
-               /* The path is fully qualified, just evaluate by name */
+       switch (acpi_ns_get_type(info->node)) {
+       case ACPI_TYPE_METHOD:
+
+               /* Check incoming argument count against the method definition */
+
+               if (info->obj_desc->method.param_count > info->param_count) {
+                       ACPI_ERROR((AE_INFO,
+                                   "Insufficient arguments (%u) - %u are required",
+                                   info->param_count,
+                                   info->obj_desc->method.param_count));
+
+                       status = AE_MISSING_ARGUMENTS;
+                       goto cleanup;
+               }
+
+               else if (info->obj_desc->method.param_count < info->param_count) {
+                       ACPI_WARNING((AE_INFO,
+                                     "Excess arguments (%u) - only %u are required",
+                                     info->param_count,
+                                     info->obj_desc->method.param_count));
+
+                       /* Just pass the required number of arguments */
+
+                       info->param_count = info->obj_desc->method.param_count;
+               }
 
-               info->prefix_node = NULL;
-               status = acpi_ns_evaluate(info);
-       } else if (!handle) {
                /*
-                * A handle is optional iff a fully qualified pathname is specified.
-                * Since we've already handled fully qualified names above, this is
-                * an error
+                * Any incoming external objects to be passed as arguments to the
+                * method must be converted to internal objects
                 */
-               if (!pathname) {
-                       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                         "Both Handle and Pathname are NULL"));
-               } else {
-                       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                         "Null Handle with relative pathname [%s]",
-                                         pathname));
+               if (info->param_count) {
+                       /*
+                        * Allocate a new parameter block for the internal objects
+                        * Add 1 to count to allow for null terminated internal list
+                        */
+                       info->parameters = ACPI_ALLOCATE_ZEROED(((acpi_size)
+                                                                info->
+                                                                param_count +
+                                                                1) *
+                                                               sizeof(void *));
+                       if (!info->parameters) {
+                               status = AE_NO_MEMORY;
+                               goto cleanup;
+                       }
+
+                       /* Convert each external object in the list to an internal object */
+
+                       for (i = 0; i < info->param_count; i++) {
+                               status =
+                                   acpi_ut_copy_eobject_to_iobject
+                                   (&external_params->pointer[i],
+                                    &info->parameters[i]);
+                               if (ACPI_FAILURE(status)) {
+                                       goto cleanup;
+                               }
+                       }
+
+                       info->parameters[info->param_count] = NULL;
                }
+               break;
 
-               status = AE_BAD_PARAMETER;
-       } else {
-               /* We have a namespace a node and a possible relative path */
+       default:
+
+               /* Warn if arguments passed to an object that is not a method */
 
-               status = acpi_ns_evaluate(info);
+               if (info->param_count) {
+                       ACPI_WARNING((AE_INFO,
+                                     "%u arguments were passed to a non-method ACPI object",
+                                     info->param_count));
+               }
+               break;
        }
 
+#endif
+
+       /* Now we can evaluate the object */
+
+       status = acpi_ns_evaluate(info);
+
        /*
         * If we are expecting a return value, and all went well above,
         * copy the return value to an external object.
@@ -413,6 +511,7 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
                break;
 
        default:
+
                return;
        }
 
index 9f25a3d4e992c0dc890325f8ed0029942c3bac5b..91a5a69db80c316552e13f9704eb9435f9b94a30 100644 (file)
@@ -629,24 +629,28 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
 
                                switch (opcode) {
                                case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
+
                                        buffer_length =
                                            ACPI_GET8(parser_state->aml);
                                        parser_state->aml += 1;
                                        break;
 
                                case AML_WORD_OP:       /* AML_WORDDATA_ARG */
+
                                        buffer_length =
                                            ACPI_GET16(parser_state->aml);
                                        parser_state->aml += 2;
                                        break;
 
                                case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
+
                                        buffer_length =
                                            ACPI_GET32(parser_state->aml);
                                        parser_state->aml += 4;
                                        break;
 
                                default:
+
                                        buffer_length = 0;
                                        break;
                                }
index 63c4554474817b591fdc0d71771dde8f2cf970ed..065b44ae538f28b7595fe9af1870b5c824052237 100644 (file)
@@ -164,7 +164,6 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
                        case AML_IF_OP:
                        case AML_ELSE_OP:
                        case AML_WHILE_OP:
-
                                /*
                                 * Currently supported module-level opcodes are:
                                 * IF/ELSE/WHILE. These appear to be the most common,
@@ -289,6 +288,7 @@ acpi_ps_get_arguments(struct acpi_walk_state *walk_state,
                default:
 
                        /* No action for all other opcodes */
+
                        break;
                }
 
index 12c4028002b145e0fef8b9ed60ab9f00ccd100dc..95dc608a66a85b3b01e5a461b58a39f4a02b20f7 100644 (file)
@@ -402,6 +402,7 @@ acpi_ps_complete_op(struct acpi_walk_state *walk_state,
 
        switch (status) {
        case AE_OK:
+
                break;
 
        case AE_CTRL_TRANSFER:
index abc4c48b2eddd7c18acb854a5eeb960d73080393..86198a9139b52a653d24d6758ba63ed0d04df800 100644 (file)
@@ -176,10 +176,10 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
 
                switch (parent_info->class) {
                case AML_CLASS_CONTROL:
+
                        break;
 
                case AML_CLASS_CREATE:
-
                        /*
                         * These opcodes contain term_arg operands. The current
                         * op must be replaced by a placeholder return op
@@ -192,7 +192,6 @@ acpi_ps_complete_this_op(struct acpi_walk_state * walk_state,
                        break;
 
                case AML_CLASS_NAMED_OBJECT:
-
                        /*
                         * These opcodes contain term_arg operands. The current
                         * op must be replaced by a placeholder return op
index c1934bf04f0af56f16db267dcdc5d3a914b749ab..877dc0de8df3e19da7057a8fd99042eb2d6f80b6 100644 (file)
@@ -308,7 +308,9 @@ union acpi_parse_object *acpi_ps_get_child(union acpi_parse_object *op)
                break;
 
        default:
+
                /* All others have no children */
+
                break;
        }
 
index f682542689656d5ce98ba93db973fad907d41899..11b99ab20bb3a3c1a96cd5322149a4fefe7fbb4a 100644 (file)
@@ -125,7 +125,7 @@ static void acpi_ps_start_trace(struct acpi_evaluate_info *info)
        }
 
        if ((!acpi_gbl_trace_method_name) ||
-           (acpi_gbl_trace_method_name != info->resolved_node->name.integer)) {
+           (acpi_gbl_trace_method_name != info->node->name.integer)) {
                goto exit;
        }
 
@@ -170,7 +170,7 @@ static void acpi_ps_stop_trace(struct acpi_evaluate_info *info)
        }
 
        if ((!acpi_gbl_trace_method_name) ||
-           (acpi_gbl_trace_method_name != info->resolved_node->name.integer)) {
+           (acpi_gbl_trace_method_name != info->node->name.integer)) {
                goto exit;
        }
 
@@ -226,15 +226,14 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
 
        /* Validate the Info and method Node */
 
-       if (!info || !info->resolved_node) {
+       if (!info || !info->node) {
                return_ACPI_STATUS(AE_NULL_ENTRY);
        }
 
        /* Init for new method, wait on concurrency semaphore */
 
        status =
-           acpi_ds_begin_method_execution(info->resolved_node, info->obj_desc,
-                                          NULL);
+           acpi_ds_begin_method_execution(info->node, info->obj_desc, NULL);
        if (ACPI_FAILURE(status)) {
                return_ACPI_STATUS(status);
        }
@@ -253,8 +252,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
         */
        ACPI_DEBUG_PRINT((ACPI_DB_PARSE,
                          "**** Begin Method Parse/Execute [%4.4s] **** Node=%p Obj=%p\n",
-                         info->resolved_node->name.ascii, info->resolved_node,
-                         info->obj_desc));
+                         info->node->name.ascii, info->node, info->obj_desc));
 
        /* Create and init a Root Node */
 
@@ -275,7 +273,7 @@ acpi_status acpi_ps_execute_method(struct acpi_evaluate_info *info)
                goto cleanup;
        }
 
-       status = acpi_ds_init_aml_walk(walk_state, op, info->resolved_node,
+       status = acpi_ds_init_aml_walk(walk_state, op, info->node,
                                       info->obj_desc->method.aml_start,
                                       info->obj_desc->method.aml_length, info,
                                       info->pass_number);
index 72077fa1eea5ecd7e5c489e3b65632c0be639ef2..b62a0f4f4f9bb527cd49fc95279b7032ba1a689a 100644 (file)
@@ -352,6 +352,7 @@ acpi_rs_get_aml_length(struct acpi_resource * resource, acpi_size * size_needed)
                        break;
 
                default:
+
                        break;
                }
 
@@ -539,6 +540,7 @@ acpi_rs_get_list_length(u8 * aml_buffer,
                        break;
 
                default:
+
                        break;
                }
 
@@ -650,8 +652,9 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
 
                name_found = FALSE;
 
-               for (table_index = 0; table_index < 4 && !name_found;
-                    table_index++) {
+               for (table_index = 0;
+                    table_index < package_element->package.count
+                    && !name_found; table_index++) {
                        if (*sub_object_list && /* Null object allowed */
                            ((ACPI_TYPE_STRING ==
                              (*sub_object_list)->common.type) ||
index f8b55b426c9d9b83abfe7f1d1a42692406cf0cc7..65f3e1c5b5989f61bdcb03e6620cdd1a7371dba9 100644 (file)
@@ -273,17 +273,6 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
                 */
                user_prt->length = (sizeof(struct acpi_pci_routing_table) - 4);
 
-               /* Each element of the top-level package must also be a package */
-
-               if ((*top_object_list)->common.type != ACPI_TYPE_PACKAGE) {
-                       ACPI_ERROR((AE_INFO,
-                                   "(PRT[%u]) Need sub-package, found %s",
-                                   index,
-                                   acpi_ut_get_object_type_name
-                                   (*top_object_list)));
-                       return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
-               }
-
                /* Each sub-package must be of length 4 */
 
                if ((*top_object_list)->package.count != 4) {
@@ -326,22 +315,6 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
 
                user_prt->pin = (u32) obj_desc->integer.value;
 
-               /*
-                * If the BIOS has erroneously reversed the _PRT source_name (index 2)
-                * and the source_index (index 3), fix it. _PRT is important enough to
-                * workaround this BIOS error. This also provides compatibility with
-                * other ACPI implementations.
-                */
-               obj_desc = sub_object_list[3];
-               if (!obj_desc || (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
-                       sub_object_list[3] = sub_object_list[2];
-                       sub_object_list[2] = obj_desc;
-
-                       ACPI_WARNING((AE_INFO,
-                                     "(PRT[%X].Source) SourceName and SourceIndex are reversed, fixed",
-                                     index));
-               }
-
                /*
                 * 3) Third subobject: Dereference the PRT.source_name
                 * The name may be unresolved (slack mode), so allow a null object
index b5fc0db2e87bb4a78ddbaa707ee91a886b4e7215..8a2d4986b0aa576695ed2f479703cfa8dc4fd139 100644 (file)
@@ -120,17 +120,20 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table)
                        /* Strings */
 
                case ACPI_RSD_LITERAL:
+
                        acpi_rs_out_string(name,
                                           ACPI_CAST_PTR(char, table->pointer));
                        break;
 
                case ACPI_RSD_STRING:
+
                        acpi_rs_out_string(name, ACPI_CAST_PTR(char, target));
                        break;
 
                        /* Data items, 8/16/32/64 bit */
 
                case ACPI_RSD_UINT8:
+
                        if (table->pointer) {
                                acpi_rs_out_string(name, ACPI_CAST_PTR(char,
                                                                       table->
@@ -142,20 +145,24 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table)
                        break;
 
                case ACPI_RSD_UINT16:
+
                        acpi_rs_out_integer16(name, ACPI_GET16(target));
                        break;
 
                case ACPI_RSD_UINT32:
+
                        acpi_rs_out_integer32(name, ACPI_GET32(target));
                        break;
 
                case ACPI_RSD_UINT64:
+
                        acpi_rs_out_integer64(name, ACPI_GET64(target));
                        break;
 
                        /* Flags: 1-bit and 2-bit flags supported */
 
                case ACPI_RSD_1BITFLAG:
+
                        acpi_rs_out_string(name, ACPI_CAST_PTR(char,
                                                               table->
                                                               pointer[*target &
@@ -163,6 +170,7 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table)
                        break;
 
                case ACPI_RSD_2BITFLAG:
+
                        acpi_rs_out_string(name, ACPI_CAST_PTR(char,
                                                               table->
                                                               pointer[*target &
@@ -170,6 +178,7 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table)
                        break;
 
                case ACPI_RSD_3BITFLAG:
+
                        acpi_rs_out_string(name, ACPI_CAST_PTR(char,
                                                               table->
                                                               pointer[*target &
@@ -258,6 +267,7 @@ acpi_rs_dump_descriptor(void *resource, struct acpi_rsdump_info *table)
                        break;
 
                default:
+
                        acpi_os_printf("**** Invalid table opcode [%X] ****\n",
                                       table->opcode);
                        return;
index d5bf05a96096ad785897966876929b02dba60c02..80d12994e0d078f10b8842d6c5ee3d8a4c965c35 100644 (file)
@@ -194,7 +194,6 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
                        break;
 
                case ACPI_RSC_COUNT_GPIO_RES:
-
                        /*
                         * Vendor data is optional (length/offset may both be zero)
                         * Examine vendor data length field first
@@ -410,12 +409,14 @@ acpi_rs_convert_aml_to_resource(struct acpi_resource *resource,
                         */
                        switch (info->resource_offset) {
                        case ACPI_RSC_COMPARE_AML_LENGTH:
+
                                if (aml_resource_length != info->value) {
                                        goto exit;
                                }
                                break;
 
                        case ACPI_RSC_COMPARE_VALUE:
+
                                if (ACPI_GET8(source) != info->value) {
                                        goto exit;
                                }
index a44953c6f75da74d7c0e160078eff90b5abfc5ba..480b6b40c5eaa3527ce58b4f76f2b8a23b16db97 100644 (file)
@@ -147,6 +147,7 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
                case ACPI_RSC_MOVE_GPIO_RES:
                case ACPI_RSC_MOVE_SERIAL_VEN:
                case ACPI_RSC_MOVE_SERIAL_RES:
+
                        ACPI_MEMCPY(destination, source, item_count);
                        return;
 
@@ -157,21 +158,25 @@ acpi_rs_move_data(void *destination, void *source, u16 item_count, u8 move_type)
                         */
                case ACPI_RSC_MOVE16:
                case ACPI_RSC_MOVE_GPIO_PIN:
+
                        ACPI_MOVE_16_TO_16(&ACPI_CAST_PTR(u16, destination)[i],
                                           &ACPI_CAST_PTR(u16, source)[i]);
                        break;
 
                case ACPI_RSC_MOVE32:
+
                        ACPI_MOVE_32_TO_32(&ACPI_CAST_PTR(u32, destination)[i],
                                           &ACPI_CAST_PTR(u32, source)[i]);
                        break;
 
                case ACPI_RSC_MOVE64:
+
                        ACPI_MOVE_64_TO_64(&ACPI_CAST_PTR(u64, destination)[i],
                                           &ACPI_CAST_PTR(u64, source)[i]);
                        break;
 
                default:
+
                        return;
                }
        }
@@ -736,7 +741,7 @@ acpi_rs_set_srs_method_data(struct acpi_namespace_node *node,
        }
 
        info->prefix_node = node;
-       info->pathname = METHOD_NAME__SRS;
+       info->relative_pathname = METHOD_NAME__SRS;
        info->parameters = args;
        info->flags = ACPI_IGNORE_RETURN_VALUE;
 
index c0e5d2d3ce6757380928c9e50d1f2de0f158160a..94e3517554f9d52d121dd4f31469ddb4a9ec6567 100644 (file)
@@ -402,6 +402,7 @@ acpi_resource_to_address64(struct acpi_resource *resource,
                break;
 
        default:
+
                return (AE_BAD_PARAMETER);
        }
 
index e57cd38004e33c3adb3b7850bc25b4f23f577430..42a13c0d7015360ab44c684ab9645500fc63f1d8 100644 (file)
@@ -141,8 +141,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
                ACPI_BIOS_ERROR((AE_INFO,
                                 "Table has invalid signature [%4.4s] (0x%8.8X), "
                                 "must be SSDT or OEMx",
-                                acpi_ut_valid_acpi_name(*(u32 *)table_desc->
-                                                        pointer->
+                                acpi_ut_valid_acpi_name(table_desc->pointer->
                                                         signature) ?
                                 table_desc->pointer->signature : "????",
                                 *(u32 *)table_desc->pointer->signature));
@@ -471,15 +470,19 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc)
        }
        switch (table_desc->flags & ACPI_TABLE_ORIGIN_MASK) {
        case ACPI_TABLE_ORIGIN_MAPPED:
+
                acpi_os_unmap_memory(table_desc->pointer, table_desc->length);
                break;
+
        case ACPI_TABLE_ORIGIN_ALLOCATED:
+
                ACPI_FREE(table_desc->pointer);
                break;
 
                /* Not mapped or allocated, there is nothing we can do */
 
        default:
+
                return;
        }
 
diff --git a/drivers/acpi/acpica/tbprint.c b/drivers/acpi/acpica/tbprint.c
new file mode 100644 (file)
index 0000000..dc963f8
--- /dev/null
@@ -0,0 +1,237 @@
+/******************************************************************************
+ *
+ * Module Name: tbprint - Table output utilities
+ *
+ *****************************************************************************/
+
+/*
+ * 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 "actables.h"
+
+#define _COMPONENT          ACPI_TABLES
+ACPI_MODULE_NAME("tbprint")
+
+/* Local prototypes */
+static void acpi_tb_fix_string(char *string, acpi_size length);
+
+static void
+acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
+                            struct acpi_table_header *header);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_fix_string
+ *
+ * PARAMETERS:  string              - String to be repaired
+ *              length              - Maximum length
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Replace every non-printable or non-ascii byte in the string
+ *              with a question mark '?'.
+ *
+ ******************************************************************************/
+
+static void acpi_tb_fix_string(char *string, acpi_size length)
+{
+
+       while (length && *string) {
+               if (!ACPI_IS_PRINT(*string)) {
+                       *string = '?';
+               }
+               string++;
+               length--;
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_cleanup_table_header
+ *
+ * PARAMETERS:  out_header          - Where the cleaned header is returned
+ *              header              - Input ACPI table header
+ *
+ * RETURN:      Returns the cleaned header in out_header
+ *
+ * DESCRIPTION: Copy the table header and ensure that all "string" fields in
+ *              the header consist of printable characters.
+ *
+ ******************************************************************************/
+
+static void
+acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
+                            struct acpi_table_header *header)
+{
+
+       ACPI_MEMCPY(out_header, header, sizeof(struct acpi_table_header));
+
+       acpi_tb_fix_string(out_header->signature, ACPI_NAME_SIZE);
+       acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE);
+       acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
+       acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAME_SIZE);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_print_table_header
+ *
+ * PARAMETERS:  address             - Table physical address
+ *              header              - Table header
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP.
+ *
+ ******************************************************************************/
+
+void
+acpi_tb_print_table_header(acpi_physical_address address,
+                          struct acpi_table_header *header)
+{
+       struct acpi_table_header local_header;
+
+       /*
+        * The reason that the Address is cast to a void pointer is so that we
+        * can use %p which will work properly on both 32-bit and 64-bit hosts.
+        */
+       if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) {
+
+               /* FACS only has signature and length fields */
+
+               ACPI_INFO((AE_INFO, "%4.4s %p %05X",
+                          header->signature, ACPI_CAST_PTR(void, address),
+                          header->length));
+       } else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) {
+
+               /* RSDP has no common fields */
+
+               ACPI_MEMCPY(local_header.oem_id,
+                           ACPI_CAST_PTR(struct acpi_table_rsdp,
+                                         header)->oem_id, ACPI_OEM_ID_SIZE);
+               acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE);
+
+               ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)",
+                          ACPI_CAST_PTR(void, address),
+                          (ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
+                           revision >
+                           0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
+                                              header)->length : 20,
+                          ACPI_CAST_PTR(struct acpi_table_rsdp,
+                                        header)->revision,
+                          local_header.oem_id));
+       } else {
+               /* Standard ACPI table with full common header */
+
+               acpi_tb_cleanup_table_header(&local_header, header);
+
+               ACPI_INFO((AE_INFO,
+                          "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)",
+                          local_header.signature, ACPI_CAST_PTR(void, address),
+                          local_header.length, local_header.revision,
+                          local_header.oem_id, local_header.oem_table_id,
+                          local_header.oem_revision,
+                          local_header.asl_compiler_id,
+                          local_header.asl_compiler_revision));
+       }
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_validate_checksum
+ *
+ * PARAMETERS:  table               - ACPI table to verify
+ *              length              - Length of entire table
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
+ *              exception on bad checksum.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
+{
+       u8 checksum;
+
+       /* Compute the checksum on the table */
+
+       checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length);
+
+       /* Checksum ok? (should be zero) */
+
+       if (checksum) {
+               ACPI_BIOS_WARNING((AE_INFO,
+                                  "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
+                                  "should be 0x%2.2X",
+                                  table->signature, table->checksum,
+                                  (u8)(table->checksum - checksum)));
+
+#if (ACPI_CHECKSUM_ABORT)
+               return (AE_BAD_CHECKSUM);
+#endif
+       }
+
+       return (AE_OK);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_checksum
+ *
+ * PARAMETERS:  buffer          - Pointer to memory region to be checked
+ *              length          - Length of this memory region
+ *
+ * RETURN:      Checksum (u8)
+ *
+ * DESCRIPTION: Calculates circular checksum of memory region.
+ *
+ ******************************************************************************/
+
+u8 acpi_tb_checksum(u8 *buffer, u32 length)
+{
+       u8 sum = 0;
+       u8 *end = buffer + length;
+
+       while (buffer < end) {
+               sum = (u8)(sum + *(buffer++));
+       }
+
+       return (sum);
+}
index ce3d5db39a9c742d49fc7aa9103121942da73c6a..bffdfc7b832254068378320a94385abdd359c715 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Module Name: tbutils   - table utilities
+ * Module Name: tbutils - ACPI Table utilities
  *
  *****************************************************************************/
 
 ACPI_MODULE_NAME("tbutils")
 
 /* Local prototypes */
-static void acpi_tb_fix_string(char *string, acpi_size length);
-
-static void
-acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
-                            struct acpi_table_header *header);
-
 static acpi_physical_address
 acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size);
 
@@ -174,189 +168,6 @@ u8 acpi_tb_tables_loaded(void)
        return (FALSE);
 }
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_fix_string
- *
- * PARAMETERS:  string              - String to be repaired
- *              length              - Maximum length
- *
- * RETURN:      None
- *
- * DESCRIPTION: Replace every non-printable or non-ascii byte in the string
- *              with a question mark '?'.
- *
- ******************************************************************************/
-
-static void acpi_tb_fix_string(char *string, acpi_size length)
-{
-
-       while (length && *string) {
-               if (!ACPI_IS_PRINT(*string)) {
-                       *string = '?';
-               }
-               string++;
-               length--;
-       }
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_cleanup_table_header
- *
- * PARAMETERS:  out_header          - Where the cleaned header is returned
- *              header              - Input ACPI table header
- *
- * RETURN:      Returns the cleaned header in out_header
- *
- * DESCRIPTION: Copy the table header and ensure that all "string" fields in
- *              the header consist of printable characters.
- *
- ******************************************************************************/
-
-static void
-acpi_tb_cleanup_table_header(struct acpi_table_header *out_header,
-                            struct acpi_table_header *header)
-{
-
-       ACPI_MEMCPY(out_header, header, sizeof(struct acpi_table_header));
-
-       acpi_tb_fix_string(out_header->signature, ACPI_NAME_SIZE);
-       acpi_tb_fix_string(out_header->oem_id, ACPI_OEM_ID_SIZE);
-       acpi_tb_fix_string(out_header->oem_table_id, ACPI_OEM_TABLE_ID_SIZE);
-       acpi_tb_fix_string(out_header->asl_compiler_id, ACPI_NAME_SIZE);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_print_table_header
- *
- * PARAMETERS:  address             - Table physical address
- *              header              - Table header
- *
- * RETURN:      None
- *
- * DESCRIPTION: Print an ACPI table header. Special cases for FACS and RSDP.
- *
- ******************************************************************************/
-
-void
-acpi_tb_print_table_header(acpi_physical_address address,
-                          struct acpi_table_header *header)
-{
-       struct acpi_table_header local_header;
-
-       /*
-        * The reason that the Address is cast to a void pointer is so that we
-        * can use %p which will work properly on both 32-bit and 64-bit hosts.
-        */
-       if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) {
-
-               /* FACS only has signature and length fields */
-
-               ACPI_INFO((AE_INFO, "%4.4s %p %05X",
-                          header->signature, ACPI_CAST_PTR(void, address),
-                          header->length));
-       } else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) {
-
-               /* RSDP has no common fields */
-
-               ACPI_MEMCPY(local_header.oem_id,
-                           ACPI_CAST_PTR(struct acpi_table_rsdp,
-                                         header)->oem_id, ACPI_OEM_ID_SIZE);
-               acpi_tb_fix_string(local_header.oem_id, ACPI_OEM_ID_SIZE);
-
-               ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)",
-                          ACPI_CAST_PTR (void, address),
-                          (ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
-                           revision >
-                           0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
-                                              header)->length : 20,
-                          ACPI_CAST_PTR(struct acpi_table_rsdp,
-                                        header)->revision,
-                          local_header.oem_id));
-       } else {
-               /* Standard ACPI table with full common header */
-
-               acpi_tb_cleanup_table_header(&local_header, header);
-
-               ACPI_INFO((AE_INFO,
-                          "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)",
-                          local_header.signature, ACPI_CAST_PTR(void, address),
-                          local_header.length, local_header.revision,
-                          local_header.oem_id, local_header.oem_table_id,
-                          local_header.oem_revision,
-                          local_header.asl_compiler_id,
-                          local_header.asl_compiler_revision));
-
-       }
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_validate_checksum
- *
- * PARAMETERS:  table               - ACPI table to verify
- *              length              - Length of entire table
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Verifies that the table checksums to zero. Optionally returns
- *              exception on bad checksum.
- *
- ******************************************************************************/
-
-acpi_status acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length)
-{
-       u8 checksum;
-
-       /* Compute the checksum on the table */
-
-       checksum = acpi_tb_checksum(ACPI_CAST_PTR(u8, table), length);
-
-       /* Checksum ok? (should be zero) */
-
-       if (checksum) {
-               ACPI_BIOS_WARNING((AE_INFO,
-                                  "Incorrect checksum in table [%4.4s] - 0x%2.2X, "
-                                  "should be 0x%2.2X",
-                                  table->signature, table->checksum,
-                                  (u8)(table->checksum - checksum)));
-
-#if (ACPI_CHECKSUM_ABORT)
-
-               return (AE_BAD_CHECKSUM);
-#endif
-       }
-
-       return (AE_OK);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_tb_checksum
- *
- * PARAMETERS:  buffer          - Pointer to memory region to be checked
- *              length          - Length of this memory region
- *
- * RETURN:      Checksum (u8)
- *
- * DESCRIPTION: Calculates circular checksum of memory region.
- *
- ******************************************************************************/
-
-u8 acpi_tb_checksum(u8 *buffer, u32 length)
-{
-       u8 sum = 0;
-       u8 *end = buffer + length;
-
-       while (buffer < end) {
-               sum = (u8) (sum + *(buffer++));
-       }
-
-       return (sum);
-}
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_tb_check_dsdt_header
index 67e046ec8f0afaedfec54d273b3193a9cffbb63a..0ba9e328d5d7b0c6fa199f4c7c8bc11ad135c9a1 100644 (file)
@@ -53,8 +53,6 @@ ACPI_MODULE_NAME("tbxfload")
 /* Local prototypes */
 static acpi_status acpi_tb_load_namespace(void);
 
-static int no_auto_ssdt;
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_load_tables
@@ -180,8 +178,16 @@ static acpi_status acpi_tb_load_namespace(void)
                        continue;
                }
 
-               if (no_auto_ssdt) {
-                       printk(KERN_WARNING "ACPI: SSDT ignored due to \"acpi_no_auto_ssdt\"\n");
+               /*
+                * Optionally do not load any SSDTs from the RSDT/XSDT. This can
+                * be useful for debugging ACPI problems on some machines.
+                */
+               if (acpi_gbl_disable_ssdt_table_load) {
+                       ACPI_INFO((AE_INFO, "Ignoring %4.4s at %p",
+                                  acpi_gbl_root_table_list.tables[i].signature.
+                                  ascii, ACPI_CAST_PTR(void,
+                                                       acpi_gbl_root_table_list.
+                                                       tables[i].address)));
                        continue;
                }
 
@@ -376,14 +382,3 @@ acpi_status acpi_unload_parent_table(acpi_handle object)
 }
 
 ACPI_EXPORT_SYMBOL(acpi_unload_parent_table)
-
-static int __init acpi_no_auto_ssdt_setup(char *s) {
-
-        printk(KERN_NOTICE "ACPI: SSDT auto-load disabled\n");
-
-        no_auto_ssdt = 1;
-
-        return 1;
-}
-
-__setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup);
diff --git a/drivers/acpi/acpica/utbuffer.c b/drivers/acpi/acpica/utbuffer.c
new file mode 100644 (file)
index 0000000..11fde93
--- /dev/null
@@ -0,0 +1,201 @@
+/******************************************************************************
+ *
+ * Module Name: utbuffer - Buffer dump routines
+ *
+ *****************************************************************************/
+
+/*
+ * 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"
+
+#define _COMPONENT          ACPI_UTILITIES
+ACPI_MODULE_NAME("utbuffer")
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_dump_buffer
+ *
+ * PARAMETERS:  buffer              - Buffer to dump
+ *              count               - Amount to dump, in bytes
+ *              display             - BYTE, WORD, DWORD, or QWORD display:
+ *                                      DB_BYTE_DISPLAY
+ *                                      DB_WORD_DISPLAY
+ *                                      DB_DWORD_DISPLAY
+ *                                      DB_QWORD_DISPLAY
+ *              base_offset         - Beginning buffer offset (display only)
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Generic dump buffer in both hex and ascii.
+ *
+ ******************************************************************************/
+void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 base_offset)
+{
+       u32 i = 0;
+       u32 j;
+       u32 temp32;
+       u8 buf_char;
+
+       if (!buffer) {
+               acpi_os_printf("Null Buffer Pointer in DumpBuffer!\n");
+               return;
+       }
+
+       if ((count < 4) || (count & 0x01)) {
+               display = DB_BYTE_DISPLAY;
+       }
+
+       /* Nasty little dump buffer routine! */
+
+       while (i < count) {
+
+               /* Print current offset */
+
+               acpi_os_printf("%6.4X: ", (base_offset + i));
+
+               /* Print 16 hex chars */
+
+               for (j = 0; j < 16;) {
+                       if (i + j >= count) {
+
+                               /* Dump fill spaces */
+
+                               acpi_os_printf("%*s", ((display * 2) + 1), " ");
+                               j += display;
+                               continue;
+                       }
+
+                       switch (display) {
+                       case DB_BYTE_DISPLAY:
+                       default:        /* Default is BYTE display */
+
+                               acpi_os_printf("%02X ",
+                                              buffer[(acpi_size) i + j]);
+                               break;
+
+                       case DB_WORD_DISPLAY:
+
+                               ACPI_MOVE_16_TO_32(&temp32,
+                                                  &buffer[(acpi_size) i + j]);
+                               acpi_os_printf("%04X ", temp32);
+                               break;
+
+                       case DB_DWORD_DISPLAY:
+
+                               ACPI_MOVE_32_TO_32(&temp32,
+                                                  &buffer[(acpi_size) i + j]);
+                               acpi_os_printf("%08X ", temp32);
+                               break;
+
+                       case DB_QWORD_DISPLAY:
+
+                               ACPI_MOVE_32_TO_32(&temp32,
+                                                  &buffer[(acpi_size) i + j]);
+                               acpi_os_printf("%08X", temp32);
+
+                               ACPI_MOVE_32_TO_32(&temp32,
+                                                  &buffer[(acpi_size) i + j +
+                                                          4]);
+                               acpi_os_printf("%08X ", temp32);
+                               break;
+                       }
+
+                       j += display;
+               }
+
+               /*
+                * Print the ASCII equivalent characters but watch out for the bad
+                * unprintable ones (printable chars are 0x20 through 0x7E)
+                */
+               acpi_os_printf(" ");
+               for (j = 0; j < 16; j++) {
+                       if (i + j >= count) {
+                               acpi_os_printf("\n");
+                               return;
+                       }
+
+                       buf_char = buffer[(acpi_size) i + j];
+                       if (ACPI_IS_PRINT(buf_char)) {
+                               acpi_os_printf("%c", buf_char);
+                       } else {
+                               acpi_os_printf(".");
+                       }
+               }
+
+               /* Done with that line. */
+
+               acpi_os_printf("\n");
+               i += 16;
+       }
+
+       return;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_debug_dump_buffer
+ *
+ * PARAMETERS:  buffer              - Buffer to dump
+ *              count               - Amount to dump, in bytes
+ *              display             - BYTE, WORD, DWORD, or QWORD display:
+ *                                      DB_BYTE_DISPLAY
+ *                                      DB_WORD_DISPLAY
+ *                                      DB_DWORD_DISPLAY
+ *                                      DB_QWORD_DISPLAY
+ *              component_ID        - Caller's component ID
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Generic dump buffer in both hex and ascii.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id)
+{
+
+       /* Only dump the buffer if tracing is enabled */
+
+       if (!((ACPI_LV_TABLES & acpi_dbg_level) &&
+             (component_id & acpi_dbg_layer))) {
+               return;
+       }
+
+       acpi_ut_dump_buffer(buffer, count, display, 0);
+}
index e4c9291fc0a3f530bfaea472895f6217a23f8b99..1731c27c36a682e5d47beba328096ff9c633043a 100644 (file)
@@ -178,7 +178,6 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
 
                switch (internal_object->reference.class) {
                case ACPI_REFCLASS_NAME:
-
                        /*
                         * For namepath, return the object handle ("reference")
                         * We are referring to the namespace node
@@ -264,7 +263,6 @@ acpi_ut_copy_ielement_to_eelement(u8 object_type,
 
        switch (object_type) {
        case ACPI_COPY_TYPE_SIMPLE:
-
                /*
                 * This is a simple or null object
                 */
@@ -278,7 +276,6 @@ acpi_ut_copy_ielement_to_eelement(u8 object_type,
                break;
 
        case ACPI_COPY_TYPE_PACKAGE:
-
                /*
                 * Build the package object
                 */
@@ -304,6 +301,7 @@ acpi_ut_copy_ielement_to_eelement(u8 object_type,
                break;
 
        default:
+
                return (AE_BAD_PARAMETER);
        }
 
@@ -481,6 +479,7 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
                return_ACPI_STATUS(AE_OK);
 
        default:
+
                /* All other types are not supported */
 
                ACPI_ERROR((AE_INFO,
@@ -544,7 +543,9 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
                break;
 
        default:
+
                /* Other types can't get here */
+
                break;
        }
 
@@ -800,7 +801,9 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
                break;
 
        default:
+
                /* Nothing to do for other simple objects */
+
                break;
        }
 
@@ -868,7 +871,6 @@ acpi_ut_copy_ielement_to_ielement(u8 object_type,
                break;
 
        case ACPI_COPY_TYPE_PACKAGE:
-
                /*
                 * This object is a package - go down another nesting level
                 * Create and build the package object
@@ -891,6 +893,7 @@ acpi_ut_copy_ielement_to_ielement(u8 object_type,
                break;
 
        default:
+
                return (AE_BAD_PARAMETER);
        }
 
index c57d9cc07ba913c9576792f395ffcea08a76fc03..5796e11a0671d32fad4329262e05b51d038cd38e 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Module Name: utdebug - Debug print routines
+ * Module Name: utdebug - Debug print/trace routines
  *
  *****************************************************************************/
 
@@ -543,149 +543,3 @@ acpi_ut_ptr_exit(u32 line_number,
 }
 
 #endif
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_dump_buffer
- *
- * PARAMETERS:  buffer              - Buffer to dump
- *              count               - Amount to dump, in bytes
- *              display             - BYTE, WORD, DWORD, or QWORD display
- *              offset              - Beginning buffer offset (display only)
- *
- * RETURN:      None
- *
- * DESCRIPTION: Generic dump buffer in both hex and ascii.
- *
- ******************************************************************************/
-
-void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 base_offset)
-{
-       u32 i = 0;
-       u32 j;
-       u32 temp32;
-       u8 buf_char;
-
-       if (!buffer) {
-               acpi_os_printf("Null Buffer Pointer in DumpBuffer!\n");
-               return;
-       }
-
-       if ((count < 4) || (count & 0x01)) {
-               display = DB_BYTE_DISPLAY;
-       }
-
-       /* Nasty little dump buffer routine! */
-
-       while (i < count) {
-
-               /* Print current offset */
-
-               acpi_os_printf("%6.4X: ", (base_offset + i));
-
-               /* Print 16 hex chars */
-
-               for (j = 0; j < 16;) {
-                       if (i + j >= count) {
-
-                               /* Dump fill spaces */
-
-                               acpi_os_printf("%*s", ((display * 2) + 1), " ");
-                               j += display;
-                               continue;
-                       }
-
-                       switch (display) {
-                       case DB_BYTE_DISPLAY:
-                       default:        /* Default is BYTE display */
-
-                               acpi_os_printf("%02X ",
-                                              buffer[(acpi_size) i + j]);
-                               break;
-
-                       case DB_WORD_DISPLAY:
-
-                               ACPI_MOVE_16_TO_32(&temp32,
-                                                  &buffer[(acpi_size) i + j]);
-                               acpi_os_printf("%04X ", temp32);
-                               break;
-
-                       case DB_DWORD_DISPLAY:
-
-                               ACPI_MOVE_32_TO_32(&temp32,
-                                                  &buffer[(acpi_size) i + j]);
-                               acpi_os_printf("%08X ", temp32);
-                               break;
-
-                       case DB_QWORD_DISPLAY:
-
-                               ACPI_MOVE_32_TO_32(&temp32,
-                                                  &buffer[(acpi_size) i + j]);
-                               acpi_os_printf("%08X", temp32);
-
-                               ACPI_MOVE_32_TO_32(&temp32,
-                                                  &buffer[(acpi_size) i + j +
-                                                          4]);
-                               acpi_os_printf("%08X ", temp32);
-                               break;
-                       }
-
-                       j += display;
-               }
-
-               /*
-                * Print the ASCII equivalent characters but watch out for the bad
-                * unprintable ones (printable chars are 0x20 through 0x7E)
-                */
-               acpi_os_printf(" ");
-               for (j = 0; j < 16; j++) {
-                       if (i + j >= count) {
-                               acpi_os_printf("\n");
-                               return;
-                       }
-
-                       buf_char = buffer[(acpi_size) i + j];
-                       if (ACPI_IS_PRINT(buf_char)) {
-                               acpi_os_printf("%c", buf_char);
-                       } else {
-                               acpi_os_printf(".");
-                       }
-               }
-
-               /* Done with that line. */
-
-               acpi_os_printf("\n");
-               i += 16;
-       }
-
-       return;
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_debug_dump_buffer
- *
- * PARAMETERS:  buffer              - Buffer to dump
- *              count               - Amount to dump, in bytes
- *              display             - BYTE, WORD, DWORD, or QWORD display
- *              component_ID        - Caller's component ID
- *
- * RETURN:      None
- *
- * DESCRIPTION: Generic dump buffer in both hex and ascii.
- *
- ******************************************************************************/
-
-void
-acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id)
-{
-
-       /* Only dump the buffer if tracing is enabled */
-
-       if (!((ACPI_LV_TABLES & acpi_dbg_level) &&
-             (component_id & acpi_dbg_layer))) {
-               return;
-       }
-
-       acpi_ut_dump_buffer(buffer, count, display, 0);
-}
index 29b930250b6fe01a7822a229dc0f45ed80290a52..d6b33f29d32754a50eef108ce1287b59886b013b 100644 (file)
@@ -303,6 +303,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
                break;
 
        default:
+
                break;
        }
 
@@ -508,7 +509,6 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
                case ACPI_TYPE_PROCESSOR:
                case ACPI_TYPE_POWER:
                case ACPI_TYPE_THERMAL:
-
                        /*
                         * Update the notify objects for these types (if present)
                         * Two lists, system and device notify handlers.
@@ -623,6 +623,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
 
                case ACPI_TYPE_REGION:
                default:
+
                        break;  /* No subobjects for all other types */
                }
 
diff --git a/drivers/acpi/acpica/uterror.c b/drivers/acpi/acpica/uterror.c
new file mode 100644 (file)
index 0000000..154fdca
--- /dev/null
@@ -0,0 +1,289 @@
+/*******************************************************************************
+ *
+ * Module Name: uterror - Various internal error/warning output functions
+ *
+ ******************************************************************************/
+
+/*
+ * 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"
+
+#define _COMPONENT          ACPI_UTILITIES
+ACPI_MODULE_NAME("uterror")
+
+/*
+ * This module contains internal error functions that may
+ * be configured out.
+ */
+#if !defined (ACPI_NO_ERROR_MESSAGES)
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_predefined_warning
+ *
+ * PARAMETERS:  module_name     - Caller's module name (for error output)
+ *              line_number     - Caller's line number (for error output)
+ *              pathname        - Full pathname to the node
+ *              node_flags      - From Namespace node for the method/object
+ *              format          - Printf format string + additional args
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Warnings for the predefined validation module. Messages are
+ *              only emitted the first time a problem with a particular
+ *              method/object is detected. This prevents a flood of error
+ *              messages for methods that are repeatedly evaluated.
+ *
+ ******************************************************************************/
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_predefined_warning(const char *module_name,
+                          u32 line_number,
+                          char *pathname,
+                          u8 node_flags, const char *format, ...)
+{
+       va_list arg_list;
+
+       /*
+        * Warning messages for this method/object will be disabled after the
+        * first time a validation fails or an object is successfully repaired.
+        */
+       if (node_flags & ANOBJ_EVALUATED) {
+               return;
+       }
+
+       acpi_os_printf(ACPI_MSG_WARNING "%s: ", pathname);
+
+       va_start(arg_list, format);
+       acpi_os_vprintf(format, arg_list);
+       ACPI_MSG_SUFFIX;
+       va_end(arg_list);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_predefined_info
+ *
+ * PARAMETERS:  module_name     - Caller's module name (for error output)
+ *              line_number     - Caller's line number (for error output)
+ *              pathname        - Full pathname to the node
+ *              node_flags      - From Namespace node for the method/object
+ *              format          - Printf format string + additional args
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Info messages for the predefined validation module. Messages
+ *              are only emitted the first time a problem with a particular
+ *              method/object is detected. This prevents a flood of
+ *              messages for methods that are repeatedly evaluated.
+ *
+ ******************************************************************************/
+
+void ACPI_INTERNAL_VAR_XFACE
+acpi_ut_predefined_info(const char *module_name,
+                       u32 line_number,
+                       char *pathname, u8 node_flags, const char *format, ...)
+{
+       va_list arg_list;
+
+       /*
+        * Warning messages for this method/object will be disabled after the
+        * first time a validation fails or an object is successfully repaired.
+        */
+       if (node_flags & ANOBJ_EVALUATED) {
+               return;
+       }
+
+       acpi_os_printf(ACPI_MSG_INFO "%s: ", pathname);
+
+       va_start(arg_list, format);
+       acpi_os_vprintf(format, arg_list);
+       ACPI_MSG_SUFFIX;
+       va_end(arg_list);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_predefined_bios_error
+ *
+ * PARAMETERS:  module_name     - Caller's module name (for error output)
+ *              line_number     - Caller's line number (for error output)
+ *              pathname        - Full pathname to the node
+ *              node_flags      - From Namespace node for the method/object
+ *              format          - Printf format string + additional args
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: BIOS error message for predefined names. Messages
+ *              are only emitted the first time a problem with a particular
+ *              method/object is detected. This prevents a flood of
+ *              messages for methods that are repeatedly evaluated.
+ *
+ ******************************************************************************/
+
+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, ...)
+{
+       va_list arg_list;
+
+       /*
+        * Warning messages for this method/object will be disabled after the
+        * first time a validation fails or an object is successfully repaired.
+        */
+       if (node_flags & ANOBJ_EVALUATED) {
+               return;
+       }
+
+       acpi_os_printf(ACPI_MSG_BIOS_ERROR "%s: ", pathname);
+
+       va_start(arg_list, format);
+       acpi_os_vprintf(format, arg_list);
+       ACPI_MSG_SUFFIX;
+       va_end(arg_list);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_namespace_error
+ *
+ * PARAMETERS:  module_name         - Caller's module name (for error output)
+ *              line_number         - Caller's line number (for error output)
+ *              internal_name       - Name or path of the namespace node
+ *              lookup_status       - Exception code from NS lookup
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print error message with the full pathname for the NS node.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_namespace_error(const char *module_name,
+                       u32 line_number,
+                       const char *internal_name, acpi_status lookup_status)
+{
+       acpi_status status;
+       u32 bad_name;
+       char *name = NULL;
+
+       ACPI_MSG_REDIRECT_BEGIN;
+       acpi_os_printf(ACPI_MSG_ERROR);
+
+       if (lookup_status == AE_BAD_CHARACTER) {
+
+               /* There is a non-ascii character in the name */
+
+               ACPI_MOVE_32_TO_32(&bad_name,
+                                  ACPI_CAST_PTR(u32, internal_name));
+               acpi_os_printf("[0x%.8X] (NON-ASCII)", bad_name);
+       } else {
+               /* Convert path to external format */
+
+               status = acpi_ns_externalize_name(ACPI_UINT32_MAX,
+                                                 internal_name, NULL, &name);
+
+               /* Print target name */
+
+               if (ACPI_SUCCESS(status)) {
+                       acpi_os_printf("[%s]", name);
+               } else {
+                       acpi_os_printf("[COULD NOT EXTERNALIZE NAME]");
+               }
+
+               if (name) {
+                       ACPI_FREE(name);
+               }
+       }
+
+       acpi_os_printf(" Namespace lookup failure, %s",
+                      acpi_format_exception(lookup_status));
+
+       ACPI_MSG_SUFFIX;
+       ACPI_MSG_REDIRECT_END;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ut_method_error
+ *
+ * PARAMETERS:  module_name         - Caller's module name (for error output)
+ *              line_number         - Caller's line number (for error output)
+ *              message             - Error message to use on failure
+ *              prefix_node         - Prefix relative to the path
+ *              path                - Path to the node (optional)
+ *              method_status       - Execution status
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Print error message with the full pathname for the method.
+ *
+ ******************************************************************************/
+
+void
+acpi_ut_method_error(const char *module_name,
+                    u32 line_number,
+                    const char *message,
+                    struct acpi_namespace_node *prefix_node,
+                    const char *path, acpi_status method_status)
+{
+       acpi_status status;
+       struct acpi_namespace_node *node = prefix_node;
+
+       ACPI_MSG_REDIRECT_BEGIN;
+       acpi_os_printf(ACPI_MSG_ERROR);
+
+       if (path) {
+               status =
+                   acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH,
+                                    &node);
+               if (ACPI_FAILURE(status)) {
+                       acpi_os_printf("[Could not get node by pathname]");
+               }
+       }
+
+       acpi_ns_print_node_pathname(node, message);
+       acpi_os_printf(", %s", acpi_format_exception(method_status));
+
+       ACPI_MSG_SUFFIX;
+       ACPI_MSG_REDIRECT_END;
+}
+
+#endif                         /* ACPI_NO_ERROR_MESSAGES */
index c3f3a7e7bdc7fd6bc51ba43b1d8ff8e3c6d6eb76..ee83adb97b1e73827a6a7740de03edb3680e2a28 100644 (file)
@@ -68,7 +68,7 @@ ACPI_MODULE_NAME("uteval")
  ******************************************************************************/
 
 acpi_status
-acpi_ut_evaluate_object(struct acpi_namespace_node * prefix_node,
+acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
                        char *path,
                        u32 expected_return_btypes,
                        union acpi_operand_object **return_desc)
@@ -87,7 +87,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node * prefix_node,
        }
 
        info->prefix_node = prefix_node;
-       info->pathname = path;
+       info->relative_pathname = path;
 
        /* Evaluate the object/method */
 
@@ -123,22 +123,27 @@ acpi_ut_evaluate_object(struct acpi_namespace_node * prefix_node,
 
        switch ((info->return_object)->common.type) {
        case ACPI_TYPE_INTEGER:
+
                return_btype = ACPI_BTYPE_INTEGER;
                break;
 
        case ACPI_TYPE_BUFFER:
+
                return_btype = ACPI_BTYPE_BUFFER;
                break;
 
        case ACPI_TYPE_STRING:
+
                return_btype = ACPI_BTYPE_STRING;
                break;
 
        case ACPI_TYPE_PACKAGE:
+
                return_btype = ACPI_BTYPE_PACKAGE;
                break;
 
        default:
+
                return_btype = 0;
                break;
        }
index b543a144941a295a81c7aa9f237b56ac07e1a748..ff6d9e8aa8423ef04ed68ec18023d61ee570493b 100644 (file)
@@ -146,6 +146,7 @@ const struct acpi_exception_info *acpi_ut_validate_exception(acpi_status status)
                break;
 
        default:
+
                break;
        }
 
index 43a170a74a6139ae3aa10ae1120b27f773103085..fa69071db4181dc100e3242053756944590679f8 100644 (file)
@@ -341,14 +341,17 @@ acpi_ut_execute_CID(struct acpi_namespace_node *device_node,
 
                switch (cid_objects[i]->common.type) {
                case ACPI_TYPE_INTEGER:
+
                        string_area_size += ACPI_EISAID_STRING_SIZE;
                        break;
 
                case ACPI_TYPE_STRING:
+
                        string_area_size += cid_objects[i]->string.length + 1;
                        break;
 
                default:
+
                        status = AE_TYPE;
                        goto cleanup;
                }
index 785fdd07ae5673db012d27b1519dce75e85c3827..02f9101b65e47c29dc974020a8701322c9dc3824 100644 (file)
@@ -382,10 +382,12 @@ acpi_ut_display_init_pathname(u8 type,
 
        switch (type) {
        case ACPI_TYPE_METHOD:
+
                acpi_os_printf("Executing  ");
                break;
 
        default:
+
                acpi_os_printf("Initializing ");
                break;
        }
index 1099f5c069f8287fb354f148c9f8d681fcc94e44..aa61f66ee861ed1de71fee8bb72d0e412627382c 100644 (file)
@@ -129,6 +129,7 @@ union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char
                break;
 
        default:
+
                /* All others have no secondary object */
                break;
        }
@@ -353,6 +354,7 @@ u8 acpi_ut_valid_internal_object(void *object)
                return (TRUE);
 
        default:
+
                ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
                                  "%p is not not an ACPI operand obj [%s]\n",
                                  object, acpi_ut_get_descriptor_name(object)));
@@ -509,7 +511,6 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
 
                switch (internal_object->reference.class) {
                case ACPI_REFCLASS_NAME:
-
                        /*
                         * Get the actual length of the full pathname to this object.
                         * The reference will be converted to the pathname to the object
@@ -525,7 +526,6 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
                        break;
 
                default:
-
                        /*
                         * No other reference opcodes are supported.
                         * Notably, Locals and Args are not supported, but this may be
@@ -585,7 +585,6 @@ acpi_ut_get_element_length(u8 object_type,
 
        switch (object_type) {
        case ACPI_COPY_TYPE_SIMPLE:
-
                /*
                 * Simple object - just get the size (Null object/entry is handled
                 * here also) and sum it into the running package length
index 29459479148fe7b1e23f7b0fe64ea85a0c48b7bb..2b1ce4cd32073fc23e6bcb7d6c5666d156ae6432 100644 (file)
@@ -147,6 +147,11 @@ void acpi_ut_get_expected_return_types(char *buffer, u32 expected_btypes)
        u32 i;
        u32 j;
 
+       if (!expected_btypes) {
+               ACPI_STRCPY(buffer, "NONE");
+               return;
+       }
+
        j = 1;
        buffer[0] = 0;
        this_rtype = ACPI_RTYPE_INTEGER;
@@ -328,9 +333,7 @@ static u32 acpi_ut_get_argument_types(char *buffer, u16 argument_types)
 
        /* First field in the types list is the count of args to follow */
 
-       arg_count = (argument_types & METHOD_ARG_MASK);
-       argument_types >>= METHOD_ARG_BIT_WIDTH;
-
+       arg_count = METHOD_GET_ARG_COUNT(argument_types);
        if (arg_count > METHOD_PREDEF_ARGS_MAX) {
                printf("**** Invalid argument count (%u) "
                       "in predefined info structure\n", arg_count);
@@ -340,7 +343,8 @@ static u32 acpi_ut_get_argument_types(char *buffer, u16 argument_types)
        /* Get each argument from the list, convert to ascii, store to buffer */
 
        for (i = 0; i < arg_count; i++) {
-               this_argument_type = (argument_types & METHOD_ARG_MASK);
+               this_argument_type = METHOD_GET_NEXT_TYPE(argument_types);
+
                if (!this_argument_type
                    || (this_argument_type > METHOD_MAX_ARG_TYPE)) {
                        printf("**** Invalid argument type (%u) "
@@ -351,10 +355,6 @@ static u32 acpi_ut_get_argument_types(char *buffer, u16 argument_types)
 
                strcat(buffer,
                       ut_external_type_names[this_argument_type] + sub_index);
-
-               /* Shift to next argument type field */
-
-               argument_types >>= METHOD_ARG_BIT_WIDTH;
                sub_index = 0;
        }
 
index b3e36a81aa4d1360b9280d2edd6d9d5f9e7330dd..c53759b76a3f97d0fe5558f36ad9b656fbc905fa 100644 (file)
@@ -186,10 +186,13 @@ acpi_status acpi_ut_strtoul64(char *string, u32 base, u64 *ret_integer)
        switch (base) {
        case ACPI_ANY_BASE:
        case 16:
+
                break;
 
        default:
+
                /* Invalid Base */
+
                return_ACPI_STATUS(AE_BAD_PARAMETER);
        }
 
@@ -355,36 +358,44 @@ void acpi_ut_print_string(char *string, u8 max_length)
 
                switch (string[i]) {
                case 0x07:
+
                        acpi_os_printf("\\a");  /* BELL */
                        break;
 
                case 0x08:
+
                        acpi_os_printf("\\b");  /* BACKSPACE */
                        break;
 
                case 0x0C:
+
                        acpi_os_printf("\\f");  /* FORMFEED */
                        break;
 
                case 0x0A:
+
                        acpi_os_printf("\\n");  /* LINEFEED */
                        break;
 
                case 0x0D:
+
                        acpi_os_printf("\\r");  /* CARRIAGE RETURN */
                        break;
 
                case 0x09:
+
                        acpi_os_printf("\\t");  /* HORIZONTAL TAB */
                        break;
 
                case 0x0B:
+
                        acpi_os_printf("\\v");  /* VERTICAL TAB */
                        break;
 
                case '\'':      /* Single Quote */
                case '\"':      /* Double Quote */
                case '\\':      /* Backslash */
+
                        acpi_os_printf("\\%c", (int)string[i]);
                        break;
 
@@ -451,7 +462,8 @@ u8 acpi_ut_valid_acpi_char(char character, u32 position)
  *
  * FUNCTION:    acpi_ut_valid_acpi_name
  *
- * PARAMETERS:  name            - The name to be examined
+ * PARAMETERS:  name            - The name to be examined. Does not have to
+ *                                be NULL terminated string.
  *
  * RETURN:      TRUE if the name is valid, FALSE otherwise
  *
@@ -462,15 +474,14 @@ u8 acpi_ut_valid_acpi_char(char character, u32 position)
  *
  ******************************************************************************/
 
-u8 acpi_ut_valid_acpi_name(u32 name)
+u8 acpi_ut_valid_acpi_name(char *name)
 {
        u32 i;
 
        ACPI_FUNCTION_ENTRY();
 
        for (i = 0; i < ACPI_NAME_SIZE; i++) {
-               if (!acpi_ut_valid_acpi_char
-                   ((ACPI_CAST_PTR(char, &name))[i], i)) {
+               if (!acpi_ut_valid_acpi_char(name[i], i)) {
                        return (FALSE);
                }
        }
index 62774c7b76a81402633d417277be05c5953239d0..160f13f4aab51a196200184c60cc625a5de4acc6 100644 (file)
@@ -603,6 +603,7 @@ void acpi_ut_dump_allocations(u32 component, const char *module)
                                        switch (ACPI_GET_DESCRIPTOR_TYPE
                                                (descriptor)) {
                                        case ACPI_DESC_TYPE_OPERAND:
+
                                                if (element->size ==
                                                    sizeof(union
                                                           acpi_operand_object))
@@ -613,6 +614,7 @@ void acpi_ut_dump_allocations(u32 component, const char *module)
                                                break;
 
                                        case ACPI_DESC_TYPE_PARSER:
+
                                                if (element->size ==
                                                    sizeof(union
                                                           acpi_parse_object)) {
@@ -622,6 +624,7 @@ void acpi_ut_dump_allocations(u32 component, const char *module)
                                                break;
 
                                        case ACPI_DESC_TYPE_NAMED:
+
                                                if (element->size ==
                                                    sizeof(struct
                                                           acpi_namespace_node))
@@ -632,6 +635,7 @@ void acpi_ut_dump_allocations(u32 component, const char *module)
                                                break;
 
                                        default:
+
                                                break;
                                        }
 
@@ -639,6 +643,7 @@ void acpi_ut_dump_allocations(u32 component, const char *module)
 
                                        switch (descriptor_type) {
                                        case ACPI_DESC_TYPE_OPERAND:
+
                                                acpi_os_printf
                                                    ("%12.12s RefCount 0x%04X\n",
                                                     acpi_ut_get_type_name
@@ -649,6 +654,7 @@ void acpi_ut_dump_allocations(u32 component, const char *module)
                                                break;
 
                                        case ACPI_DESC_TYPE_PARSER:
+
                                                acpi_os_printf
                                                    ("AmlOpcode 0x%04hX\n",
                                                     descriptor->op.asl.
@@ -656,6 +662,7 @@ void acpi_ut_dump_allocations(u32 component, const char *module)
                                                break;
 
                                        case ACPI_DESC_TYPE_NAMED:
+
                                                acpi_os_printf("%4.4s\n",
                                                               acpi_ut_get_node_name
                                                               (&descriptor->
@@ -663,6 +670,7 @@ void acpi_ut_dump_allocations(u32 component, const char *module)
                                                break;
 
                                        default:
+
                                                acpi_os_printf("\n");
                                                break;
                                        }
index 976b6c734fce961b44a94773a4e8357b02727735..e966a2e47b765e6c097ca7973b54fa2d987ab6cd 100644 (file)
@@ -44,7 +44,6 @@
 #include <linux/export.h>
 #include <acpi/acpi.h>
 #include "accommon.h"
-#include "acnamesp.h"
 
 #define _COMPONENT          ACPI_UTILITIES
 ACPI_MODULE_NAME("utxferror")
@@ -52,43 +51,7 @@ ACPI_MODULE_NAME("utxferror")
 /*
  * This module is used for the in-kernel ACPICA as well as the ACPICA
  * tools/applications.
- *
- * 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 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 Bug: Error: "
-#define ACPI_MSG_BIOS_WARNING   "ACPI BIOS Bug: Warning: "
-/*
- * Common message suffix
- */
-#define ACPI_MSG_SUFFIX \
-       acpi_os_printf (" (%8.8X/%s-%u)\n", ACPI_CA_VERSION, module_name, line_number)
 /*******************************************************************************
  *
  * FUNCTION:    acpi_error
@@ -285,200 +248,3 @@ acpi_bios_warning(const char *module_name,
 }
 
 ACPI_EXPORT_SYMBOL(acpi_bios_warning)
-
-/*
- * The remainder of this module contains internal error functions that may
- * be configured out.
- */
-#if !defined (ACPI_NO_ERROR_MESSAGES) && !defined (ACPI_BIN_APP)
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_predefined_warning
- *
- * PARAMETERS:  module_name     - Caller's module name (for error output)
- *              line_number     - Caller's line number (for error output)
- *              pathname        - Full pathname to the node
- *              node_flags      - From Namespace node for the method/object
- *              format          - Printf format string + additional args
- *
- * RETURN:      None
- *
- * DESCRIPTION: Warnings for the predefined validation module. Messages are
- *              only emitted the first time a problem with a particular
- *              method/object is detected. This prevents a flood of error
- *              messages for methods that are repeatedly evaluated.
- *
- ******************************************************************************/
-void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_predefined_warning(const char *module_name,
-                          u32 line_number,
-                          char *pathname,
-                          u8 node_flags, const char *format, ...)
-{
-       va_list arg_list;
-
-       /*
-        * Warning messages for this method/object will be disabled after the
-        * first time a validation fails or an object is successfully repaired.
-        */
-       if (node_flags & ANOBJ_EVALUATED) {
-               return;
-       }
-
-       acpi_os_printf(ACPI_MSG_WARNING "For %s: ", pathname);
-
-       va_start(arg_list, format);
-       acpi_os_vprintf(format, arg_list);
-       ACPI_MSG_SUFFIX;
-       va_end(arg_list);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_predefined_info
- *
- * PARAMETERS:  module_name     - Caller's module name (for error output)
- *              line_number     - Caller's line number (for error output)
- *              pathname        - Full pathname to the node
- *              node_flags      - From Namespace node for the method/object
- *              format          - Printf format string + additional args
- *
- * RETURN:      None
- *
- * DESCRIPTION: Info messages for the predefined validation module. Messages
- *              are only emitted the first time a problem with a particular
- *              method/object is detected. This prevents a flood of
- *              messages for methods that are repeatedly evaluated.
- *
- ******************************************************************************/
-
-void ACPI_INTERNAL_VAR_XFACE
-acpi_ut_predefined_info(const char *module_name,
-                       u32 line_number,
-                       char *pathname, u8 node_flags, const char *format, ...)
-{
-       va_list arg_list;
-
-       /*
-        * Warning messages for this method/object will be disabled after the
-        * first time a validation fails or an object is successfully repaired.
-        */
-       if (node_flags & ANOBJ_EVALUATED) {
-               return;
-       }
-
-       acpi_os_printf(ACPI_MSG_INFO "For %s: ", pathname);
-
-       va_start(arg_list, format);
-       acpi_os_vprintf(format, arg_list);
-       ACPI_MSG_SUFFIX;
-       va_end(arg_list);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_namespace_error
- *
- * PARAMETERS:  module_name         - Caller's module name (for error output)
- *              line_number         - Caller's line number (for error output)
- *              internal_name       - Name or path of the namespace node
- *              lookup_status       - Exception code from NS lookup
- *
- * RETURN:      None
- *
- * DESCRIPTION: Print error message with the full pathname for the NS node.
- *
- ******************************************************************************/
-
-void
-acpi_ut_namespace_error(const char *module_name,
-                       u32 line_number,
-                       const char *internal_name, acpi_status lookup_status)
-{
-       acpi_status status;
-       u32 bad_name;
-       char *name = NULL;
-
-       ACPI_MSG_REDIRECT_BEGIN;
-       acpi_os_printf(ACPI_MSG_ERROR);
-
-       if (lookup_status == AE_BAD_CHARACTER) {
-
-               /* There is a non-ascii character in the name */
-
-               ACPI_MOVE_32_TO_32(&bad_name,
-                                  ACPI_CAST_PTR(u32, internal_name));
-               acpi_os_printf("[0x%.8X] (NON-ASCII)", bad_name);
-       } else {
-               /* Convert path to external format */
-
-               status = acpi_ns_externalize_name(ACPI_UINT32_MAX,
-                                                 internal_name, NULL, &name);
-
-               /* Print target name */
-
-               if (ACPI_SUCCESS(status)) {
-                       acpi_os_printf("[%s]", name);
-               } else {
-                       acpi_os_printf("[COULD NOT EXTERNALIZE NAME]");
-               }
-
-               if (name) {
-                       ACPI_FREE(name);
-               }
-       }
-
-       acpi_os_printf(" Namespace lookup failure, %s",
-                      acpi_format_exception(lookup_status));
-
-       ACPI_MSG_SUFFIX;
-       ACPI_MSG_REDIRECT_END;
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ut_method_error
- *
- * PARAMETERS:  module_name         - Caller's module name (for error output)
- *              line_number         - Caller's line number (for error output)
- *              message             - Error message to use on failure
- *              prefix_node         - Prefix relative to the path
- *              path                - Path to the node (optional)
- *              method_status       - Execution status
- *
- * RETURN:      None
- *
- * DESCRIPTION: Print error message with the full pathname for the method.
- *
- ******************************************************************************/
-
-void
-acpi_ut_method_error(const char *module_name,
-                    u32 line_number,
-                    const char *message,
-                    struct acpi_namespace_node *prefix_node,
-                    const char *path, acpi_status method_status)
-{
-       acpi_status status;
-       struct acpi_namespace_node *node = prefix_node;
-
-       ACPI_MSG_REDIRECT_BEGIN;
-       acpi_os_printf(ACPI_MSG_ERROR);
-
-       if (path) {
-               status =
-                   acpi_ns_get_node(prefix_node, path, ACPI_NS_NO_UPSEARCH,
-                                    &node);
-               if (ACPI_FAILURE(status)) {
-                       acpi_os_printf("[Could not get node by pathname]");
-               }
-       }
-
-       acpi_ns_print_node_pathname(node, message);
-       acpi_os_printf(", %s", acpi_format_exception(method_status));
-
-       ACPI_MSG_SUFFIX;
-       ACPI_MSG_REDIRECT_END;
-}
-
-#endif                         /* ACPI_NO_ERROR_MESSAGES */
index e7100459ac4ad0ab8432e3912841fa0da2988245..082b4dd252a82ab17f7fe7249913e1f7030d35fd 100644 (file)
@@ -425,7 +425,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
 {
        int result = -EFAULT;
        acpi_status status = 0;
-       char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags)?
+       char *name = test_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags) ?
                        "_BIX" : "_BIF";
 
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -661,11 +661,11 @@ static void find_battery(const struct dmi_header *dm, void *private)
 static void acpi_battery_quirks(struct acpi_battery *battery)
 {
        if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags))
-               return ;
+               return;
 
-        if (battery->full_charge_capacity == 100 &&
-            battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
-            battery->capacity_now >=0 && battery->capacity_now <= 100) {
+       if (battery->full_charge_capacity == 100 &&
+               battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN &&
+               battery->capacity_now >= 0 && battery->capacity_now <= 100) {
                set_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags);
                battery->full_charge_capacity = battery->design_capacity;
                battery->capacity_now = (battery->capacity_now *
@@ -673,7 +673,7 @@ static void acpi_battery_quirks(struct acpi_battery *battery)
        }
 
        if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags))
-               return ;
+               return;
 
        if (battery->power_unit && dmi_name_in_vendors("LENOVO")) {
                const char *s;
@@ -761,7 +761,7 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)
                goto end;
 
        seq_printf(seq, "present:                 %s\n",
-                  acpi_battery_present(battery)?"yes":"no");
+                  acpi_battery_present(battery) ? "yes" : "no");
        if (!acpi_battery_present(battery))
                goto end;
        if (battery->design_capacity == ACPI_BATTERY_VALUE_UNKNOWN)
@@ -817,12 +817,12 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)
                goto end;
 
        seq_printf(seq, "present:                 %s\n",
-                  acpi_battery_present(battery)?"yes":"no");
+                  acpi_battery_present(battery) ? "yes" : "no");
        if (!acpi_battery_present(battery))
                goto end;
 
        seq_printf(seq, "capacity state:          %s\n",
-                       (battery->state & 0x04)?"critical":"ok");
+                       (battery->state & 0x04) ? "critical" : "ok");
        if ((battery->state & 0x01) && (battery->state & 0x02))
                seq_printf(seq,
                           "charging state:          charging/discharging\n");
index 292de3cab9cc0d4ac42cc551c80f3efdbdfeaf6b..a5bb33bab4485307f7969b19ff9d9ea9cb3f67e2 100644 (file)
@@ -91,8 +91,7 @@ static struct dmi_system_id dsdt_dmi_table[] __initdata = {
 
 int acpi_bus_get_device(acpi_handle handle, struct acpi_device **device)
 {
-       acpi_status status = AE_OK;
-
+       acpi_status status;
 
        if (!device)
                return -EINVAL;
@@ -162,7 +161,7 @@ EXPORT_SYMBOL(acpi_bus_private_data_handler);
 
 int acpi_bus_get_private_data(acpi_handle handle, void **data)
 {
-       acpi_status status = AE_OK;
+       acpi_status status;
 
        if (!*data)
                return -EINVAL;
@@ -361,7 +360,7 @@ extern int event_is_open;
 int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data)
 {
        struct acpi_bus_event *event;
-       unsigned long flags = 0;
+       unsigned long flags;
 
        /* drop event on the floor if no one's listening */
        if (!event_is_open)
@@ -400,7 +399,7 @@ EXPORT_SYMBOL(acpi_bus_generate_proc_event);
 
 int acpi_bus_receive_event(struct acpi_bus_event *event)
 {
-       unsigned long flags = 0;
+       unsigned long flags;
        struct acpi_bus_event *entry = NULL;
 
        DECLARE_WAITQUEUE(wait, current);
@@ -593,7 +592,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
 
 static int __init acpi_bus_init_irq(void)
 {
-       acpi_status status = AE_OK;
+       acpi_status status;
        union acpi_object arg = { ACPI_TYPE_INTEGER };
        struct acpi_object_list arg_list = { 1, &arg };
        char *message = NULL;
@@ -640,7 +639,7 @@ u8 acpi_gbl_permanent_mmap;
 
 void __init acpi_early_init(void)
 {
-       acpi_status status = AE_OK;
+       acpi_status status;
 
        if (acpi_disabled)
                return;
@@ -714,8 +713,8 @@ void __init acpi_early_init(void)
 
 static int __init acpi_bus_init(void)
 {
-       int result = 0;
-       acpi_status status = AE_OK;
+       int result;
+       acpi_status status;
        extern acpi_status acpi_os_initialize1(void);
 
        acpi_os_initialize1();
index 31c217a42839dce40ee2039cd38f36d935bda543..e9e8bb24785b45e267b810fe8a7582ab22468d35 100644 (file)
@@ -419,62 +419,73 @@ bool acpi_bus_can_wakeup(acpi_handle handle)
 EXPORT_SYMBOL(acpi_bus_can_wakeup);
 
 /**
- * acpi_device_power_state - Get preferred power state of ACPI device.
+ * acpi_dev_pm_get_state - Get preferred power state of ACPI device.
  * @dev: Device whose preferred target power state to return.
  * @adev: ACPI device node corresponding to @dev.
  * @target_state: System state to match the resultant device state.
- * @d_max_in: Deepest low-power state to take into consideration.
- * @d_min_p: Location to store the upper limit of the allowed states range.
- * Return value: Preferred power state of the device on success, -ENODEV
- * (if there's no 'struct acpi_device' for @dev) or -EINVAL on failure
+ * @d_min_p: Location to store the highest power state available to the device.
+ * @d_max_p: Location to store the lowest power state available to the device.
  *
- * Find the lowest power (highest number) ACPI device power state that the
- * device can be in while the system is in the state represented by
- * @target_state.  If @d_min_p is set, the highest power (lowest number) device
- * power state that @dev can be in for the given system sleep state is stored
- * at the location pointed to by it.
+ * Find the lowest power (highest number) and highest power (lowest number) ACPI
+ * device power states that the device can be in while the system is in the
+ * state represented by @target_state.  Store the integer numbers representing
+ * those stats in the memory locations pointed to by @d_max_p and @d_min_p,
+ * respectively.
  *
  * Callers must ensure that @dev and @adev are valid pointers and that @adev
  * actually corresponds to @dev before using this function.
+ *
+ * Returns 0 on success or -ENODATA when one of the ACPI methods fails or
+ * returns a value that doesn't make sense.  The memory locations pointed to by
+ * @d_max_p and @d_min_p are only modified on success.
  */
-int acpi_device_power_state(struct device *dev, struct acpi_device *adev,
-                           u32 target_state, int d_max_in, int *d_min_p)
+static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev,
+                                u32 target_state, int *d_min_p, int *d_max_p)
 {
-       char acpi_method[] = "_SxD";
-       unsigned long long d_min, d_max;
+       char method[] = { '_', 'S', '0' + target_state, 'D', '\0' };
+       acpi_handle handle = adev->handle;
+       unsigned long long ret;
+       int d_min, d_max;
        bool wakeup = false;
+       acpi_status status;
 
-       if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3)
-               return -EINVAL;
-
-       if (d_max_in > ACPI_STATE_D3_HOT) {
-               enum pm_qos_flags_status stat;
-
-               stat = dev_pm_qos_flags(dev, PM_QOS_FLAG_NO_POWER_OFF);
-               if (stat == PM_QOS_FLAGS_ALL)
-                       d_max_in = ACPI_STATE_D3_HOT;
-       }
-
-       acpi_method[2] = '0' + target_state;
        /*
-        * If the sleep state is S0, the lowest limit from ACPI is D3,
-        * but if the device has _S0W, we will use the value from _S0W
-        * as the lowest limit from ACPI.  Finally, we will constrain
-        * the lowest limit with the specified one.
+        * If the system state is S0, the lowest power state the device can be
+        * in is D3cold, unless the device has _S0W and is supposed to signal
+        * wakeup, in which case the return value of _S0W has to be used as the
+        * lowest power state available to the device.
         */
        d_min = ACPI_STATE_D0;
-       d_max = ACPI_STATE_D3;
+       d_max = ACPI_STATE_D3_COLD;
 
        /*
         * If present, _SxD methods return the minimum D-state (highest power
         * state) we can use for the corresponding S-states.  Otherwise, the
         * minimum D-state is D0 (ACPI 3.x).
-        *
-        * NOTE: We rely on acpi_evaluate_integer() not clobbering the integer
-        * provided -- that's our fault recovery, we ignore retval.
         */
        if (target_state > ACPI_STATE_S0) {
-               acpi_evaluate_integer(adev->handle, acpi_method, NULL, &d_min);
+               /*
+                * We rely on acpi_evaluate_integer() not clobbering the integer
+                * provided if AE_NOT_FOUND is returned.
+                */
+               ret = d_min;
+               status = acpi_evaluate_integer(handle, method, NULL, &ret);
+               if ((ACPI_FAILURE(status) && status != AE_NOT_FOUND)
+                   || ret > ACPI_STATE_D3_COLD)
+                       return -ENODATA;
+
+               /*
+                * We need to handle legacy systems where D3hot and D3cold are
+                * the same and 3 is returned in both cases, so fall back to
+                * D3cold if D3hot is not a valid state.
+                */
+               if (!adev->power.states[ret].flags.valid) {
+                       if (ret == ACPI_STATE_D3_HOT)
+                               ret = ACPI_STATE_D3_COLD;
+                       else
+                               return -ENODATA;
+               }
+               d_min = ret;
                wakeup = device_may_wakeup(dev) && adev->wakeup.flags.valid
                        && adev->wakeup.sleep_state >= target_state;
        } else if (dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) !=
@@ -490,38 +501,30 @@ int acpi_device_power_state(struct device *dev, struct acpi_device *adev,
         * can wake the system.  _S0W may be valid, too.
         */
        if (wakeup) {
-               acpi_status status;
-
-               acpi_method[3] = 'W';
-               status = acpi_evaluate_integer(adev->handle, acpi_method, NULL,
-                                               &d_max);
-               if (ACPI_FAILURE(status)) {
-                       if (target_state != ACPI_STATE_S0 ||
-                           status != AE_NOT_FOUND)
+               method[3] = 'W';
+               status = acpi_evaluate_integer(handle, method, NULL, &ret);
+               if (status == AE_NOT_FOUND) {
+                       if (target_state > ACPI_STATE_S0)
                                d_max = d_min;
-               } else if (d_max < d_min) {
-                       /* Warn the user of the broken DSDT */
-                       printk(KERN_WARNING "ACPI: Wrong value from %s\n",
-                               acpi_method);
-                       /* Sanitize it */
-                       d_min = d_max;
+               } else if (ACPI_SUCCESS(status) && ret <= ACPI_STATE_D3_COLD) {
+                       /* Fall back to D3cold if ret is not a valid state. */
+                       if (!adev->power.states[ret].flags.valid)
+                               ret = ACPI_STATE_D3_COLD;
+
+                       d_max = ret > d_min ? ret : d_min;
+               } else {
+                       return -ENODATA;
                }
        }
 
-       if (d_max_in < d_min)
-               return -EINVAL;
        if (d_min_p)
                *d_min_p = d_min;
-       /* constrain d_max with specified lowest limit (max number) */
-       if (d_max > d_max_in) {
-               for (d_max = d_max_in; d_max > d_min; d_max--) {
-                       if (adev->power.states[d_max].flags.valid)
-                               break;
-               }
-       }
-       return d_max;
+
+       if (d_max_p)
+               *d_max_p = d_max;
+
+       return 0;
 }
-EXPORT_SYMBOL_GPL(acpi_device_power_state);
 
 /**
  * acpi_pm_device_sleep_state - Get preferred power state of ACPI device.
@@ -529,7 +532,8 @@ EXPORT_SYMBOL_GPL(acpi_device_power_state);
  * @d_min_p: Location to store the upper limit of the allowed states range.
  * @d_max_in: Deepest low-power state to take into consideration.
  * Return value: Preferred power state of the device on success, -ENODEV
- * (if there's no 'struct acpi_device' for @dev) or -EINVAL on failure
+ * if there's no 'struct acpi_device' for @dev, -EINVAL if @d_max_in is
+ * incorrect, or -ENODATA on ACPI method failure.
  *
  * The caller must ensure that @dev is valid before using this function.
  */
@@ -537,14 +541,43 @@ int acpi_pm_device_sleep_state(struct device *dev, int *d_min_p, int d_max_in)
 {
        acpi_handle handle = DEVICE_ACPI_HANDLE(dev);
        struct acpi_device *adev;
+       int ret, d_min, d_max;
+
+       if (d_max_in < ACPI_STATE_D0 || d_max_in > ACPI_STATE_D3_COLD)
+               return -EINVAL;
+
+       if (d_max_in > ACPI_STATE_D3_HOT) {
+               enum pm_qos_flags_status stat;
+
+               stat = dev_pm_qos_flags(dev, PM_QOS_FLAG_NO_POWER_OFF);
+               if (stat == PM_QOS_FLAGS_ALL)
+                       d_max_in = ACPI_STATE_D3_HOT;
+       }
 
        if (!handle || acpi_bus_get_device(handle, &adev)) {
                dev_dbg(dev, "ACPI handle without context in %s!\n", __func__);
                return -ENODEV;
        }
 
-       return acpi_device_power_state(dev, adev, acpi_target_system_state(),
-                                      d_max_in, d_min_p);
+       ret = acpi_dev_pm_get_state(dev, adev, acpi_target_system_state(),
+                                   &d_min, &d_max);
+       if (ret)
+               return ret;
+
+       if (d_max_in < d_min)
+               return -EINVAL;
+
+       if (d_max > d_max_in) {
+               for (d_max = d_max_in; d_max > d_min; d_max--) {
+                       if (adev->power.states[d_max].flags.valid)
+                               break;
+               }
+       }
+
+       if (d_min_p)
+               *d_min_p = d_min;
+
+       return d_max;
 }
 EXPORT_SYMBOL(acpi_pm_device_sleep_state);
 
@@ -695,17 +728,13 @@ struct acpi_device *acpi_dev_pm_get_node(struct device *dev)
 static int acpi_dev_pm_low_power(struct device *dev, struct acpi_device *adev,
                                 u32 system_state)
 {
-       int power_state;
+       int ret, state;
 
        if (!acpi_device_power_manageable(adev))
                return 0;
 
-       power_state = acpi_device_power_state(dev, adev, system_state,
-                                             ACPI_STATE_D3, NULL);
-       if (power_state < ACPI_STATE_D0 || power_state > ACPI_STATE_D3)
-               return -EIO;
-
-       return acpi_device_set_power(adev, power_state);
+       ret = acpi_dev_pm_get_state(dev, adev, system_state, NULL, &state);
+       return ret ? ret : acpi_device_set_power(adev, state);
 }
 
 /**
@@ -908,7 +937,6 @@ static struct dev_pm_domain acpi_general_pm_domain = {
 #ifdef CONFIG_PM_RUNTIME
                .runtime_suspend = acpi_subsys_runtime_suspend,
                .runtime_resume = acpi_subsys_runtime_resume,
-               .runtime_idle = pm_generic_runtime_idle,
 #endif
 #ifdef CONFIG_PM_SLEEP
                .prepare = acpi_subsys_prepare,
index ec117c6c996cc0e2c25bd63c7c47897b2546492a..14de9f46972ee798926e9a1805c356fc02bb291e 100644 (file)
@@ -66,20 +66,21 @@ struct dock_station {
        spinlock_t dd_lock;
        struct mutex hp_lock;
        struct list_head dependent_devices;
-       struct list_head hotplug_devices;
 
        struct list_head sibling;
        struct platform_device *dock_device;
 };
 static LIST_HEAD(dock_stations);
 static int dock_station_count;
+static DEFINE_MUTEX(hotplug_lock);
 
 struct dock_dependent_device {
        struct list_head list;
-       struct list_head hotplug_list;
        acpi_handle handle;
-       const struct acpi_dock_ops *ops;
-       void *context;
+       const struct acpi_dock_ops *hp_ops;
+       void *hp_context;
+       unsigned int hp_refcount;
+       void (*hp_release)(void *);
 };
 
 #define DOCK_DOCKING   0x00000001
@@ -111,7 +112,6 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
 
        dd->handle = handle;
        INIT_LIST_HEAD(&dd->list);
-       INIT_LIST_HEAD(&dd->hotplug_list);
 
        spin_lock(&ds->dd_lock);
        list_add_tail(&dd->list, &ds->dependent_devices);
@@ -121,35 +121,90 @@ add_dock_dependent_device(struct dock_station *ds, acpi_handle handle)
 }
 
 /**
- * dock_add_hotplug_device - associate a hotplug handler with the dock station
- * @ds: The dock station
- * @dd: The dependent device struct
- *
- * Add the dependent device to the dock's hotplug device list
+ * dock_init_hotplug - Initialize a hotplug device on a docking station.
+ * @dd: Dock-dependent device.
+ * @ops: Dock operations to attach to the dependent device.
+ * @context: Data to pass to the @ops callbacks and @release.
+ * @init: Optional initialization routine to run after setting up context.
+ * @release: Optional release routine to run on removal.
  */
-static void
-dock_add_hotplug_device(struct dock_station *ds,
-                       struct dock_dependent_device *dd)
+static int dock_init_hotplug(struct dock_dependent_device *dd,
+                            const struct acpi_dock_ops *ops, void *context,
+                            void (*init)(void *), void (*release)(void *))
 {
-       mutex_lock(&ds->hp_lock);
-       list_add_tail(&dd->hotplug_list, &ds->hotplug_devices);
-       mutex_unlock(&ds->hp_lock);
+       int ret = 0;
+
+       mutex_lock(&hotplug_lock);
+
+       if (dd->hp_context) {
+               ret = -EEXIST;
+       } else {
+               dd->hp_refcount = 1;
+               dd->hp_ops = ops;
+               dd->hp_context = context;
+               dd->hp_release = release;
+       }
+
+       if (!WARN_ON(ret) && init)
+               init(context);
+
+       mutex_unlock(&hotplug_lock);
+       return ret;
 }
 
 /**
- * dock_del_hotplug_device - remove a hotplug handler from the dock station
- * @ds: The dock station
- * @dd: the dependent device struct
+ * dock_release_hotplug - Decrement hotplug reference counter of dock device.
+ * @dd: Dock-dependent device.
  *
- * Delete the dependent device from the dock's hotplug device list
+ * Decrement the reference counter of @dd and if 0, detach its hotplug
+ * operations from it, reset its context pointer and run the optional release
+ * routine if present.
  */
-static void
-dock_del_hotplug_device(struct dock_station *ds,
-                       struct dock_dependent_device *dd)
+static void dock_release_hotplug(struct dock_dependent_device *dd)
 {
-       mutex_lock(&ds->hp_lock);
-       list_del(&dd->hotplug_list);
-       mutex_unlock(&ds->hp_lock);
+       void (*release)(void *) = NULL;
+       void *context = NULL;
+
+       mutex_lock(&hotplug_lock);
+
+       if (dd->hp_context && !--dd->hp_refcount) {
+               dd->hp_ops = NULL;
+               context = dd->hp_context;
+               dd->hp_context = NULL;
+               release = dd->hp_release;
+               dd->hp_release = NULL;
+       }
+
+       if (release && context)
+               release(context);
+
+       mutex_unlock(&hotplug_lock);
+}
+
+static void dock_hotplug_event(struct dock_dependent_device *dd, u32 event,
+                              bool uevent)
+{
+       acpi_notify_handler cb = NULL;
+       bool run = false;
+
+       mutex_lock(&hotplug_lock);
+
+       if (dd->hp_context) {
+               run = true;
+               dd->hp_refcount++;
+               if (dd->hp_ops)
+                       cb = uevent ? dd->hp_ops->uevent : dd->hp_ops->handler;
+       }
+
+       mutex_unlock(&hotplug_lock);
+
+       if (!run)
+               return;
+
+       if (cb)
+               cb(dd->handle, event, dd->hp_context);
+
+       dock_release_hotplug(dd);
 }
 
 /**
@@ -360,9 +415,8 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
        /*
         * First call driver specific hotplug functions
         */
-       list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
-               if (dd->ops && dd->ops->handler)
-                       dd->ops->handler(dd->handle, event, dd->context);
+       list_for_each_entry(dd, &ds->dependent_devices, list)
+               dock_hotplug_event(dd, event, false);
 
        /*
         * Now make sure that an acpi_device is created for each
@@ -398,9 +452,8 @@ static void dock_event(struct dock_station *ds, u32 event, int num)
        if (num == DOCK_EVENT)
                kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
 
-       list_for_each_entry(dd, &ds->hotplug_devices, hotplug_list)
-               if (dd->ops && dd->ops->uevent)
-                       dd->ops->uevent(dd->handle, event, dd->context);
+       list_for_each_entry(dd, &ds->dependent_devices, list)
+               dock_hotplug_event(dd, event, true);
 
        if (num != DOCK_EVENT)
                kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
@@ -570,19 +623,24 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier);
  * @handle: the handle of the device
  * @ops: handlers to call after docking
  * @context: device specific data
+ * @init: Optional initialization routine to run after registration
+ * @release: Optional release routine to run on unregistration
  *
  * If a driver would like to perform a hotplug operation after a dock
  * event, they can register an acpi_notifiy_handler to be called by
  * the dock driver after _DCK is executed.
  */
-int
-register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops,
-                            void *context)
+int register_hotplug_dock_device(acpi_handle handle,
+                                const struct acpi_dock_ops *ops, void *context,
+                                void (*init)(void *), void (*release)(void *))
 {
        struct dock_dependent_device *dd;
        struct dock_station *dock_station;
        int ret = -EINVAL;
 
+       if (WARN_ON(!context))
+               return -EINVAL;
+
        if (!dock_station_count)
                return -ENODEV;
 
@@ -597,12 +655,8 @@ register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops
                 * ops
                 */
                dd = find_dock_dependent_device(dock_station, handle);
-               if (dd) {
-                       dd->ops = ops;
-                       dd->context = context;
-                       dock_add_hotplug_device(dock_station, dd);
+               if (dd && !dock_init_hotplug(dd, ops, context, init, release))
                        ret = 0;
-               }
        }
 
        return ret;
@@ -624,7 +678,7 @@ void unregister_hotplug_dock_device(acpi_handle handle)
        list_for_each_entry(dock_station, &dock_stations, sibling) {
                dd = find_dock_dependent_device(dock_station, handle);
                if (dd)
-                       dock_del_hotplug_device(dock_station, dd);
+                       dock_release_hotplug(dd);
        }
 }
 EXPORT_SYMBOL_GPL(unregister_hotplug_dock_device);
@@ -953,7 +1007,6 @@ static int __init dock_add(acpi_handle handle)
        mutex_init(&dock_station->hp_lock);
        spin_lock_init(&dock_station->dd_lock);
        INIT_LIST_HEAD(&dock_station->sibling);
-       INIT_LIST_HEAD(&dock_station->hotplug_devices);
        ATOMIC_INIT_NOTIFIER_HEAD(&dock_notifier_list);
        INIT_LIST_HEAD(&dock_station->dependent_devices);
 
@@ -993,30 +1046,6 @@ err_unregister:
        return ret;
 }
 
-/**
- * dock_remove - free up resources related to the dock station
- */
-static int dock_remove(struct dock_station *ds)
-{
-       struct dock_dependent_device *dd, *tmp;
-       struct platform_device *dock_device = ds->dock_device;
-
-       if (!dock_station_count)
-               return 0;
-
-       /* remove dependent devices */
-       list_for_each_entry_safe(dd, tmp, &ds->dependent_devices, list)
-               kfree(dd);
-
-       list_del(&ds->sibling);
-
-       /* cleanup sysfs */
-       sysfs_remove_group(&dock_device->dev.kobj, &dock_attribute_group);
-       platform_device_unregister(dock_device);
-
-       return 0;
-}
-
 /**
  * find_dock_and_bay - look for dock stations and bays
  * @handle: acpi handle of a device
@@ -1035,7 +1064,7 @@ find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv)
        return AE_OK;
 }
 
-static int __init dock_init(void)
+int __init acpi_dock_init(void)
 {
        if (acpi_disabled)
                return 0;
@@ -1054,19 +1083,3 @@ static int __init dock_init(void)
                ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count);
        return 0;
 }
-
-static void __exit dock_exit(void)
-{
-       struct dock_station *tmp, *dock_station;
-
-       unregister_acpi_bus_notifier(&dock_acpi_notifier);
-       list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibling)
-               dock_remove(dock_station);
-}
-
-/*
- * Must be called before drivers of devices in dock, otherwise we can't know
- * which devices are in a dock
- */
-subsys_initcall(dock_init);
-module_exit(dock_exit);
index edc00818c80321086ff3938f5df3cf2afae04d61..80403c1a89f8969919c868e0fb3238e056adb581 100644 (file)
@@ -983,6 +983,10 @@ static struct dmi_system_id __initdata ec_dmi_table[] = {
        ec_enlarge_storm_threshold, "CLEVO hardware", {
        DMI_MATCH(DMI_SYS_VENDOR, "CLEVO Co."),
        DMI_MATCH(DMI_PRODUCT_NAME, "M720T/M730T"),}, NULL},
+       {
+       ec_skip_dsdt_scan, "HP Folio 13", {
+       DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+       DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13"),}, NULL},
        {},
 };
 
index 7586544fddb41b9cc1761a294dc57f79245d6286..4e7b798900f21df7bf60c75d2132e2ad86e89e38 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/acpi.h>
 #include <linux/debugfs.h>
 #include <linux/module.h>
+#include <linux/uaccess.h>
 #include "internal.h"
 
 MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
@@ -34,7 +35,6 @@ static ssize_t acpi_ec_read_io(struct file *f, char __user *buf,
         * struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private;
         */
        unsigned int size = EC_SPACE_SIZE;
-       u8 *data = (u8 *) buf;
        loff_t init_off = *off;
        int err = 0;
 
@@ -47,9 +47,15 @@ static ssize_t acpi_ec_read_io(struct file *f, char __user *buf,
                size = count;
 
        while (size) {
-               err = ec_read(*off, &data[*off - init_off]);
+               u8 byte_read;
+               err = ec_read(*off, &byte_read);
                if (err)
                        return err;
+               if (put_user(byte_read, buf + *off - init_off)) {
+                       if (*off - init_off)
+                               return *off - init_off; /* partial read */
+                       return -EFAULT;
+               }
                *off += 1;
                size--;
        }
@@ -65,7 +71,6 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf,
 
        unsigned int size = count;
        loff_t init_off = *off;
-       u8 *data = (u8 *) buf;
        int err = 0;
 
        if (*off >= EC_SPACE_SIZE)
@@ -76,7 +81,12 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf,
        }
 
        while (size) {
-               u8 byte_write = data[*off - init_off];
+               u8 byte_write;
+               if (get_user(byte_write, buf + *off - init_off)) {
+                       if (*off - init_off)
+                               return *off - init_off; /* partial write */
+                       return -EFAULT;
+               }
                err = ec_write(*off, byte_write);
                if (err)
                        return err;
index 40a84cc6740c6c6522afc6bac6d5d5d2178a86bd..f68095756fb7465bc034ca5335f9345a806dd97d 100644 (file)
@@ -81,13 +81,15 @@ static struct acpi_bus_type *acpi_get_bus_type(struct device *dev)
 static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used,
                                      void *addr_p, void **ret_p)
 {
-       unsigned long long addr;
+       unsigned long long addr, sta;
        acpi_status status;
 
        status = acpi_evaluate_integer(handle, METHOD_NAME__ADR, NULL, &addr);
        if (ACPI_SUCCESS(status) && addr == *((u64 *)addr_p)) {
                *ret_p = handle;
-               return AE_CTRL_TERMINATE;
+               status = acpi_bus_get_status_handle(handle, &sta);
+               if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_ENABLED))
+                       return AE_CTRL_TERMINATE;
        }
        return AE_OK;
 }
@@ -105,7 +107,7 @@ acpi_handle acpi_get_child(acpi_handle parent, u64 address)
 }
 EXPORT_SYMBOL(acpi_get_child);
 
-static int acpi_bind_one(struct device *dev, acpi_handle handle)
+int acpi_bind_one(struct device *dev, acpi_handle handle)
 {
        struct acpi_device *acpi_dev;
        acpi_status status;
@@ -188,8 +190,9 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle)
        kfree(physical_node);
        goto err;
 }
+EXPORT_SYMBOL_GPL(acpi_bind_one);
 
-static int acpi_unbind_one(struct device *dev)
+int acpi_unbind_one(struct device *dev)
 {
        struct acpi_device_physical_node *entry;
        struct acpi_device *acpi_dev;
@@ -238,6 +241,7 @@ err:
        dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
        return -EINVAL;
 }
+EXPORT_SYMBOL_GPL(acpi_unbind_one);
 
 static int acpi_platform_notify(struct device *dev)
 {
index 297cbf456f86bee35300ef6c72058615663f563f..3a50a34fe176b34bb77a3ff8cfff9588fe523da8 100644 (file)
@@ -33,6 +33,7 @@ static inline void acpi_pci_slot_init(void) { }
 void acpi_pci_root_init(void);
 void acpi_pci_link_init(void);
 void acpi_pci_root_hp_init(void);
+void acpi_processor_init(void);
 void acpi_platform_init(void);
 int acpi_sysfs_init(void);
 #ifdef CONFIG_ACPI_CONTAINER
@@ -40,11 +41,23 @@ void acpi_container_init(void);
 #else
 static inline void acpi_container_init(void) {}
 #endif
+#ifdef CONFIG_ACPI_DOCK
+void acpi_dock_init(void);
+#else
+static inline void acpi_dock_init(void) {}
+#endif
 #ifdef CONFIG_ACPI_HOTPLUG_MEMORY
 void acpi_memory_hotplug_init(void);
 #else
 static inline void acpi_memory_hotplug_init(void) {}
 #endif
+#ifdef CONFIG_X86
+void acpi_cmos_rtc_init(void);
+#else
+static inline void acpi_cmos_rtc_init(void) {}
+#endif
+
+extern bool acpi_force_hot_remove;
 
 void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug,
                                    const char *name);
@@ -76,6 +89,8 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
                             int type, unsigned long long sta);
 void acpi_device_add_finalize(struct acpi_device *device);
 void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
+int acpi_bind_one(struct device *dev, acpi_handle handle);
+int acpi_unbind_one(struct device *dev);
 
 /* --------------------------------------------------------------------------
                                   Power Resource
index e72186340fec50212f5da151a1e7137dde31d019..6ab2c350552061893ded7355d376406de5d98ed8 100644 (file)
@@ -835,19 +835,9 @@ void acpi_os_stall(u32 us)
  */
 u64 acpi_os_get_timer(void)
 {
-       static u64 t;
-
-#ifdef CONFIG_HPET
-       /* TBD: use HPET if available */
-#endif
-
-#ifdef CONFIG_X86_PM_TIMER
-       /* TBD: default to PM timer if HPET was not available */
-#endif
-       if (!t)
-               printk(KERN_ERR PREFIX "acpi_os_get_timer() TBD\n");
-
-       return ++t;
+       u64 time_ns = ktime_to_ns(ktime_get());
+       do_div(time_ns, 100);
+       return time_ns;
 }
 
 acpi_status acpi_os_read_port(acpi_io_address port, u32 * value, u32 width)
@@ -1715,6 +1705,17 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
 }
 #endif
 
+static int __init acpi_no_auto_ssdt_setup(char *s)
+{
+        printk(KERN_NOTICE PREFIX "SSDT auto-load disabled\n");
+
+        acpi_gbl_disable_ssdt_table_load = TRUE;
+
+        return 1;
+}
+
+__setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup);
+
 acpi_status __init acpi_os_initialize(void)
 {
        acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
index c266cdc117840bcdfc7909c2605840501b2c87c2..823be116619e9d802ed2ca7cc9fc2f1c924b5119 100644 (file)
@@ -1,11 +1,13 @@
 /*
- * acpi_processor.c - ACPI Processor Driver ($Revision: 71 $)
+ * processor_driver.c - ACPI Processor Driver
  *
  *  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>
  *                     - Added processor hotplug support
+ *  Copyright (C) 2013, Intel Corporation
+ *                      Rafael J. Wysocki <rafael.j.wysocki@intel.com>
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
  *
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *  TBD:
- *     1. Make # power states dynamic.
- *     2. Support duty_cycle values that span bit 4.
- *     3. Optimize by having scheduler determine business instead of
- *        having us try to calculate it here.
- *     4. Need C1 timing -- must modify kernel (IRQ handler) to get this.
  */
 
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pm.h>
 #include <linux/cpufreq.h>
 #include <linux/cpu.h>
-#include <linux/dmi.h>
-#include <linux/moduleparam.h>
 #include <linux/cpuidle.h>
 #include <linux/slab.h>
 #include <linux/acpi.h>
-#include <linux/memory_hotplug.h>
-
-#include <asm/io.h>
-#include <asm/cpu.h>
-#include <asm/delay.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
-#include <asm/smp.h>
-#include <asm/acpi.h>
-
-#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+
 #include <acpi/processor.h>
 
+#include "internal.h"
+
 #define PREFIX "ACPI: "
 
-#define ACPI_PROCESSOR_CLASS           "processor"
-#define ACPI_PROCESSOR_DEVICE_NAME     "Processor"
-#define ACPI_PROCESSOR_FILE_INFO       "info"
-#define ACPI_PROCESSOR_FILE_THROTTLING "throttling"
-#define ACPI_PROCESSOR_FILE_LIMIT      "limit"
 #define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
 #define ACPI_PROCESSOR_NOTIFY_POWER    0x81
 #define ACPI_PROCESSOR_NOTIFY_THROTTLING       0x82
-#define ACPI_PROCESSOR_DEVICE_HID      "ACPI0007"
-
-#define ACPI_PROCESSOR_LIMIT_USER      0
-#define ACPI_PROCESSOR_LIMIT_THERMAL   1
 
 #define _COMPONENT             ACPI_PROCESSOR_COMPONENT
 ACPI_MODULE_NAME("processor_driver");
@@ -81,12 +54,8 @@ MODULE_AUTHOR("Paul Diefenbaugh");
 MODULE_DESCRIPTION("ACPI Processor Driver");
 MODULE_LICENSE("GPL");
 
-static int acpi_processor_add(struct acpi_device *device);
-static int acpi_processor_remove(struct acpi_device *device);
-static void acpi_processor_notify(struct acpi_device *device, u32 event);
-static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr);
-static int acpi_processor_handle_eject(struct acpi_processor *pr);
-static int acpi_processor_start(struct acpi_processor *pr);
+static int acpi_processor_start(struct device *dev);
+static int acpi_processor_stop(struct device *dev);
 
 static const struct acpi_device_id processor_device_ids[] = {
        {ACPI_PROCESSOR_OBJECT_HID, 0},
@@ -95,295 +64,24 @@ static const struct acpi_device_id processor_device_ids[] = {
 };
 MODULE_DEVICE_TABLE(acpi, processor_device_ids);
 
-static struct acpi_driver acpi_processor_driver = {
+static struct device_driver acpi_processor_driver = {
        .name = "processor",
-       .class = ACPI_PROCESSOR_CLASS,
-       .ids = processor_device_ids,
-       .ops = {
-               .add = acpi_processor_add,
-               .remove = acpi_processor_remove,
-               .notify = acpi_processor_notify,
-               },
+       .bus = &cpu_subsys,
+       .acpi_match_table = processor_device_ids,
+       .probe = acpi_processor_start,
+       .remove = acpi_processor_stop,
 };
 
-#define INSTALL_NOTIFY_HANDLER         1
-#define UNINSTALL_NOTIFY_HANDLER       2
-
-DEFINE_PER_CPU(struct acpi_processor *, processors);
-EXPORT_PER_CPU_SYMBOL(processors);
-
-struct acpi_processor_errata errata __read_mostly;
-
-/* --------------------------------------------------------------------------
-                                Errata Handling
-   -------------------------------------------------------------------------- */
-
-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)
+static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
 {
-       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;
-}
-
-/* --------------------------------------------------------------------------
-                                 Driver Interface
-   -------------------------------------------------------------------------- */
-
-static int acpi_processor_get_info(struct acpi_device *device)
-{
-       acpi_status status = 0;
-       union acpi_object object = { 0 };
-       struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
+       struct acpi_device *device = data;
        struct acpi_processor *pr;
-       int cpu_index, device_declaration = 0;
-       static int cpu0_initialized;
-
-       pr = acpi_driver_data(device);
-       if (!pr)
-               return -EINVAL;
-
-       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) {
-               if (ACPI_FAILURE(acpi_processor_hotadd_init(pr)))
-                       return -ENODEV;
-       }
-       /*
-        * 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
-        * 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;
-}
-
-static DEFINE_PER_CPU(void *, processor_device_array);
-
-static void acpi_processor_notify(struct acpi_device *device, u32 event)
-{
-       struct acpi_processor *pr = acpi_driver_data(device);
        int saved;
 
+       if (device->handle != handle)
+               return;
+
+       pr = acpi_driver_data(device);
        if (!pr)
                return;
 
@@ -420,55 +118,62 @@ static void acpi_processor_notify(struct acpi_device *device, u32 event)
        return;
 }
 
-static int acpi_cpu_soft_notify(struct notifier_block *nfb,
-               unsigned long action, void *hcpu)
+static __cpuinit int __acpi_processor_start(struct acpi_device *device);
+
+static int __cpuinit acpi_cpu_soft_notify(struct notifier_block *nfb,
+                                         unsigned long action, void *hcpu)
 {
        unsigned int cpu = (unsigned long)hcpu;
        struct acpi_processor *pr = per_cpu(processors, cpu);
+       struct acpi_device *device;
+
+       if (!pr || acpi_bus_get_device(pr->handle, &device))
+               return NOTIFY_DONE;
 
-       if (action == CPU_ONLINE && pr) {
-               /* CPU got physically hotplugged and onlined the first time:
-                * Initialize missing things
+       if (action == CPU_ONLINE) {
+               /*
+                * CPU got physically hotplugged and onlined for the first time:
+                * Initialize missing things.
                 */
                if (pr->flags.need_hotplug_init) {
+                       int ret;
+
                        pr_info("Will online and init hotplugged CPU: %d\n",
                                pr->id);
-                       WARN(acpi_processor_start(pr), "Failed to start CPU:"
-                               " %d\n", pr->id);
                        pr->flags.need_hotplug_init = 0;
-               /* Normal CPU soft online event */
+                       ret = __acpi_processor_start(device);
+                       WARN(ret, "Failed to start CPU: %d\n", pr->id);
                } else {
+                       /* Normal CPU soft online event. */
                        acpi_processor_ppc_has_changed(pr, 0);
                        acpi_processor_hotplug(pr);
                        acpi_processor_reevaluate_tstate(pr, action);
                        acpi_processor_tstate_has_changed(pr);
                }
-       }
-       if (action == CPU_DEAD && pr) {
-               /* invalidate the flag.throttling after one CPU is offline */
+       } else if (action == CPU_DEAD) {
+               /* Invalidate flag.throttling after the CPU is offline. */
                acpi_processor_reevaluate_tstate(pr, action);
        }
        return NOTIFY_OK;
 }
 
-static struct notifier_block acpi_cpu_notifier =
+static struct notifier_block __refdata acpi_cpu_notifier =
 {
            .notifier_call = acpi_cpu_soft_notify,
 };
 
-/*
- * acpi_processor_start() is called by the cpu_hotplug_notifier func:
- * acpi_cpu_soft_notify(). Getting it __cpuinit{data} is difficult, the
- * root cause seem to be that acpi_processor_uninstall_hotplug_notify()
- * is in the module_exit (__exit) func. Allowing acpi_processor_start()
- * to not be in __cpuinit section, but being called from __cpuinit funcs
- * via __ref looks like the right thing to do here.
- */
-static __ref int acpi_processor_start(struct acpi_processor *pr)
+static __cpuinit int __acpi_processor_start(struct acpi_device *device)
 {
-       struct acpi_device *device = per_cpu(processor_device_array, pr->id);
+       struct acpi_processor *pr = acpi_driver_data(device);
+       acpi_status status;
        int result = 0;
 
+       if (!pr)
+               return -ENODEV;
+
+       if (pr->flags.need_hotplug_init)
+               return 0;
+
 #ifdef CONFIG_CPU_FREQ
        acpi_processor_ppc_has_changed(pr, 0);
        acpi_processor_load_module(pr);
@@ -506,462 +211,95 @@ static __ref int acpi_processor_start(struct acpi_processor *pr)
                goto err_remove_sysfs_thermal;
        }
 
-       return 0;
+       status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
+                                            acpi_processor_notify, device);
+       if (ACPI_SUCCESS(status))
+               return 0;
 
-err_remove_sysfs_thermal:
+       sysfs_remove_link(&pr->cdev->device.kobj, "device");
+ err_remove_sysfs_thermal:
        sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
-err_thermal_unregister:
+ err_thermal_unregister:
        thermal_cooling_device_unregister(pr->cdev);
-err_power_exit:
+ err_power_exit:
        acpi_processor_power_exit(pr);
-
        return result;
 }
 
-/*
- * 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 above in acpi_processor_start()
- */
-static int __cpuinit acpi_processor_add(struct acpi_device *device)
+static int __cpuinit acpi_processor_start(struct device *dev)
 {
-       struct acpi_processor *pr = NULL;
-       int result = 0;
-       struct device *dev;
-
-       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 physically not present */
-               return 0;
-       }
+       struct acpi_device *device;
 
-#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);
-               result = -ENODEV;
-               goto err_free_cpumask;
-       }
-       per_cpu(processor_device_array, pr->id) = device;
+       if (acpi_bus_get_device(ACPI_HANDLE(dev), &device))
+               return -ENODEV;
 
-       per_cpu(processors, pr->id) = pr;
-
-       dev = get_cpu_device(pr->id);
-       if (sysfs_create_link(&device->dev.kobj, &dev->kobj, "sysdev")) {
-               result = -EFAULT;
-               goto err_clear_processor;
-       }
-
-       /*
-        * Do not start hotplugged CPUs now, but when they
-        * are onlined the first time
-        */
-       if (pr->flags.need_hotplug_init)
-               return 0;
-
-       result = acpi_processor_start(pr);
-       if (result)
-               goto err_remove_sysfs;
-
-       return 0;
-
-err_remove_sysfs:
-       sysfs_remove_link(&device->dev.kobj, "sysdev");
-err_clear_processor:
-       /*
-        * processor_device_array is not cleared to allow checks for buggy BIOS
-        */ 
-       per_cpu(processors, pr->id) = NULL;
-err_free_cpumask:
-       free_cpumask_var(pr->throttling.shared_cpu_map);
-err_free_pr:
-       kfree(pr);
-       return result;
+       return __acpi_processor_start(device);
 }
 
-static int acpi_processor_remove(struct acpi_device *device)
+static int acpi_processor_stop(struct device *dev)
 {
-       struct acpi_processor *pr = NULL;
+       struct acpi_device *device;
+       struct acpi_processor *pr;
 
+       if (acpi_bus_get_device(ACPI_HANDLE(dev), &device))
+               return 0;
 
-       if (!device || !acpi_driver_data(device))
-               return -EINVAL;
+       acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
+                                  acpi_processor_notify);
 
        pr = acpi_driver_data(device);
-
-       if (pr->id >= nr_cpu_ids)
-               goto free;
-
-       if (device->removal_type == ACPI_BUS_REMOVAL_EJECT) {
-               if (acpi_processor_handle_eject(pr))
-                       return -EINVAL;
-       }
+       if (!pr)
+               return 0;
 
        acpi_processor_power_exit(pr);
 
-       sysfs_remove_link(&device->dev.kobj, "sysdev");
-
        if (pr->cdev) {
                sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
                sysfs_remove_link(&pr->cdev->device.kobj, "device");
                thermal_cooling_device_unregister(pr->cdev);
                pr->cdev = NULL;
        }
-
-       per_cpu(processors, pr->id) = NULL;
-       per_cpu(processor_device_array, pr->id) = NULL;
-       try_offline_node(cpu_to_node(pr->id));
-
-free:
-       free_cpumask_var(pr->throttling.shared_cpu_map);
-       kfree(pr);
-
        return 0;
 }
 
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
-/****************************************************************************
- *     Acpi processor hotplug support                                      *
- ****************************************************************************/
-
-static int is_processor_present(acpi_handle handle)
-{
-       acpi_status status;
-       unsigned long long sta = 0;
-
-
-       status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
-
-       if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
-               return 1;
-
-       /*
-        * _STA is mandatory for a processor that supports hot plug
-        */
-       if (status == AE_NOT_FOUND)
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                               "Processor does not support hot plug\n"));
-       else
-               ACPI_EXCEPTION((AE_INFO, status,
-                               "Processor Device is not present"));
-       return 0;
-}
-
-static void acpi_processor_hotplug_notify(acpi_handle handle,
-                                         u32 event, void *data)
-{
-       struct acpi_device *device = NULL;
-       struct acpi_eject_event *ej_event = NULL;
-       u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
-       acpi_status status;
-       int result;
-
-       acpi_scan_lock_acquire();
-
-       switch (event) {
-       case ACPI_NOTIFY_BUS_CHECK:
-       case ACPI_NOTIFY_DEVICE_CHECK:
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-               "Processor driver received %s event\n",
-                      (event == ACPI_NOTIFY_BUS_CHECK) ?
-                      "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"));
-
-               if (!is_processor_present(handle))
-                       break;
-
-               if (!acpi_bus_get_device(handle, &device))
-                       break;
-
-               result = acpi_bus_scan(handle);
-               if (result) {
-                       acpi_handle_err(handle, "Unable to add the device\n");
-                       break;
-               }
-               result = acpi_bus_get_device(handle, &device);
-               if (result) {
-                       acpi_handle_err(handle, "Missing device object\n");
-                       break;
-               }
-               ost_code = ACPI_OST_SC_SUCCESS;
-               break;
-
-       case ACPI_NOTIFY_EJECT_REQUEST:
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                 "received ACPI_NOTIFY_EJECT_REQUEST\n"));
-
-               if (acpi_bus_get_device(handle, &device)) {
-                       acpi_handle_err(handle,
-                               "Device don't exist, dropping EJECT\n");
-                       break;
-               }
-               if (!acpi_driver_data(device)) {
-                       acpi_handle_err(handle,
-                               "Driver data is NULL, dropping EJECT\n");
-                       break;
-               }
-
-               ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
-               if (!ej_event) {
-                       acpi_handle_err(handle, "No memory, dropping EJECT\n");
-                       break;
-               }
-
-               get_device(&device->dev);
-               ej_event->device = device;
-               ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
-               /* The eject is carried out asynchronously. */
-               status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
-                                                ej_event);
-               if (ACPI_FAILURE(status)) {
-                       put_device(&device->dev);
-                       kfree(ej_event);
-                       break;
-               }
-               goto out;
-
-       default:
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                                 "Unsupported event [0x%x]\n", event));
-
-               /* non-hotplug event; possibly handled by other handler */
-               goto out;
-       }
-
-       /* Inform firmware that the hotplug operation has completed */
-       (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
-
- out:
-       acpi_scan_lock_release();
-}
-
-static acpi_status is_processor_device(acpi_handle handle)
-{
-       struct acpi_device_info *info;
-       char *hid;
-       acpi_status status;
-
-       status = acpi_get_object_info(handle, &info);
-       if (ACPI_FAILURE(status))
-               return status;
-
-       if (info->type == ACPI_TYPE_PROCESSOR) {
-               kfree(info);
-               return AE_OK;   /* found a processor object */
-       }
-
-       if (!(info->valid & ACPI_VALID_HID)) {
-               kfree(info);
-               return AE_ERROR;
-       }
-
-       hid = info->hardware_id.string;
-       if ((hid == NULL) || strcmp(hid, ACPI_PROCESSOR_DEVICE_HID)) {
-               kfree(info);
-               return AE_ERROR;
-       }
-
-       kfree(info);
-       return AE_OK;   /* found a processor device object */
-}
-
-static acpi_status
-processor_walk_namespace_cb(acpi_handle handle,
-                           u32 lvl, void *context, void **rv)
-{
-       acpi_status status;
-       int *action = context;
-
-       status = is_processor_device(handle);
-       if (ACPI_FAILURE(status))
-               return AE_OK;   /* not a processor; continue to walk */
-
-       switch (*action) {
-       case INSTALL_NOTIFY_HANDLER:
-               acpi_install_notify_handler(handle,
-                                           ACPI_SYSTEM_NOTIFY,
-                                           acpi_processor_hotplug_notify,
-                                           NULL);
-               break;
-       case UNINSTALL_NOTIFY_HANDLER:
-               acpi_remove_notify_handler(handle,
-                                          ACPI_SYSTEM_NOTIFY,
-                                          acpi_processor_hotplug_notify);
-               break;
-       default:
-               break;
-       }
-
-       /* found a processor; skip walking underneath */
-       return AE_CTRL_DEPTH;
-}
-
-static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr)
-{
-       acpi_handle handle = pr->handle;
-
-       if (!is_processor_present(handle)) {
-               return AE_ERROR;
-       }
-
-       if (acpi_map_lsapic(handle, &pr->id))
-               return AE_ERROR;
-
-       if (arch_register_cpu(pr->id)) {
-               acpi_unmap_lsapic(pr->id);
-               return AE_ERROR;
-       }
-
-       /* CPU got hot-plugged, but cpu_data is not initialized yet
-        * Set flag to delay cpu_idle/throttling initialization
-        * in:
-        * acpi_processor_add()
-        *   acpi_processor_get_info()
-        * and do it when the CPU gets online the first time
-        * TBD: Cleanup above functions and try to do this more elegant.
-        */
-       pr_info("CPU %d got hotplugged\n", pr->id);
-       pr->flags.need_hotplug_init = 1;
-
-       return AE_OK;
-}
-
-static int acpi_processor_handle_eject(struct acpi_processor *pr)
-{
-       if (cpu_online(pr->id))
-               cpu_down(pr->id);
-
-       get_online_cpus();
-       /*
-        * The cpu might become online again at this point. So we check whether
-        * the cpu has been onlined or not. If the cpu became online, it means
-        * that someone wants to use the cpu. So acpi_processor_handle_eject()
-        * returns -EAGAIN.
-        */
-       if (unlikely(cpu_online(pr->id))) {
-               put_online_cpus();
-               pr_warn("Failed to remove CPU %d, because other task "
-                       "brought the CPU back online\n", pr->id);
-               return -EAGAIN;
-       }
-       arch_unregister_cpu(pr->id);
-       acpi_unmap_lsapic(pr->id);
-       put_online_cpus();
-       return (0);
-}
-#else
-static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr)
-{
-       return AE_ERROR;
-}
-static int acpi_processor_handle_eject(struct acpi_processor *pr)
-{
-       return (-EINVAL);
-}
-#endif
-
-static
-void acpi_processor_install_hotplug_notify(void)
-{
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
-       int action = INSTALL_NOTIFY_HANDLER;
-       acpi_walk_namespace(ACPI_TYPE_ANY,
-                           ACPI_ROOT_OBJECT,
-                           ACPI_UINT32_MAX,
-                           processor_walk_namespace_cb, NULL, &action, NULL);
-#endif
-       register_hotcpu_notifier(&acpi_cpu_notifier);
-}
-
-static
-void acpi_processor_uninstall_hotplug_notify(void)
-{
-#ifdef CONFIG_ACPI_HOTPLUG_CPU
-       int action = UNINSTALL_NOTIFY_HANDLER;
-       acpi_walk_namespace(ACPI_TYPE_ANY,
-                           ACPI_ROOT_OBJECT,
-                           ACPI_UINT32_MAX,
-                           processor_walk_namespace_cb, NULL, &action, NULL);
-#endif
-       unregister_hotcpu_notifier(&acpi_cpu_notifier);
-}
-
 /*
  * We keep the driver loaded even when ACPI is not running.
  * This is needed for the powernow-k8 driver, that works even without
  * ACPI, but needs symbols from this driver
  */
 
-static int __init acpi_processor_init(void)
+static int __init acpi_processor_driver_init(void)
 {
        int result = 0;
 
        if (acpi_disabled)
                return 0;
 
-       result = acpi_bus_register_driver(&acpi_processor_driver);
+       result = driver_register(&acpi_processor_driver);
        if (result < 0)
                return result;
 
        acpi_processor_syscore_init();
-
-       acpi_processor_install_hotplug_notify();
-
+       register_hotcpu_notifier(&acpi_cpu_notifier);
        acpi_thermal_cpufreq_init();
-
        acpi_processor_ppc_init();
-
        acpi_processor_throttling_init();
-
        return 0;
 }
 
-static void __exit acpi_processor_exit(void)
+static void __exit acpi_processor_driver_exit(void)
 {
        if (acpi_disabled)
                return;
 
        acpi_processor_ppc_exit();
-
        acpi_thermal_cpufreq_exit();
-
-       acpi_processor_uninstall_hotplug_notify();
-
+       unregister_hotcpu_notifier(&acpi_cpu_notifier);
        acpi_processor_syscore_exit();
-
-       acpi_bus_unregister_driver(&acpi_processor_driver);
-
-       return;
+       driver_unregister(&acpi_processor_driver);
 }
 
-module_init(acpi_processor_init);
-module_exit(acpi_processor_exit);
+module_init(acpi_processor_driver_init);
+module_exit(acpi_processor_driver_exit);
 
 MODULE_ALIAS("processor");
index eb133c77aadb5f38a7d60824958fa02457c4c67b..0461ccc92c54912142098a7d9b30dcb30685d21d 100644 (file)
@@ -214,13 +214,13 @@ static void lapic_timer_state_broadcast(struct acpi_processor *pr,
 #ifdef CONFIG_PM_SLEEP
 static u32 saved_bm_rld;
 
-int acpi_processor_suspend(void)
+static int acpi_processor_suspend(void)
 {
        acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_RLD, &saved_bm_rld);
        return 0;
 }
 
-void acpi_processor_resume(void)
+static void acpi_processor_resume(void)
 {
        u32 resumed_bm_rld;
 
index e854582f29a672a5920500333e26a0b77b310e58..1e9732d809bf67ad19eee32f83617428291025b7 100644 (file)
@@ -639,7 +639,7 @@ end:
 int acpi_processor_preregister_performance(
                struct acpi_processor_performance __percpu *performance)
 {
-       int count, count_target;
+       int count_target;
        int retval = 0;
        unsigned int i, j;
        cpumask_var_t covered_cpus;
@@ -711,7 +711,6 @@ int acpi_processor_preregister_performance(
 
                /* Validate the Domain info */
                count_target = pdomain->num_processors;
-               count = 1;
                if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL)
                        pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ALL;
                else if (pdomain->coord_type == DOMAIN_COORD_TYPE_HW_ALL)
@@ -745,7 +744,6 @@ int acpi_processor_preregister_performance(
 
                        cpumask_set_cpu(j, covered_cpus);
                        cpumask_set_cpu(j, pr->performance->shared_cpu_map);
-                       count++;
                }
 
                for_each_possible_cpu(j) {
index b14ac46948c9e444246eba50e367ed1a16399ea2..dfe76f17cfc4740e0f260c70b25023339d37c210 100644 (file)
@@ -27,6 +27,12 @@ extern struct acpi_device *acpi_root;
 
 #define ACPI_IS_ROOT_DEVICE(device)    (!(device)->parent)
 
+/*
+ * If set, devices will be hot-removed even if they cannot be put offline
+ * gracefully (from the kernel's standpoint).
+ */
+bool acpi_force_hot_remove;
+
 static const char *dummy_hid = "device";
 
 static LIST_HEAD(acpi_device_list);
@@ -120,12 +126,78 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha
 }
 static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
 
+static acpi_status acpi_bus_offline_companions(acpi_handle handle, u32 lvl,
+                                              void *data, void **ret_p)
+{
+       struct acpi_device *device = NULL;
+       struct acpi_device_physical_node *pn;
+       bool second_pass = (bool)data;
+       acpi_status status = AE_OK;
+
+       if (acpi_bus_get_device(handle, &device))
+               return AE_OK;
+
+       mutex_lock(&device->physical_node_lock);
+
+       list_for_each_entry(pn, &device->physical_node_list, node) {
+               int ret;
+
+               if (second_pass) {
+                       /* Skip devices offlined by the first pass. */
+                       if (pn->put_online)
+                               continue;
+               } else {
+                       pn->put_online = false;
+               }
+               ret = device_offline(pn->dev);
+               if (acpi_force_hot_remove)
+                       continue;
+
+               if (ret >= 0) {
+                       pn->put_online = !ret;
+               } else {
+                       *ret_p = pn->dev;
+                       if (second_pass) {
+                               status = AE_ERROR;
+                               break;
+                       }
+               }
+       }
+
+       mutex_unlock(&device->physical_node_lock);
+
+       return status;
+}
+
+static acpi_status acpi_bus_online_companions(acpi_handle handle, u32 lvl,
+                                             void *data, void **ret_p)
+{
+       struct acpi_device *device = NULL;
+       struct acpi_device_physical_node *pn;
+
+       if (acpi_bus_get_device(handle, &device))
+               return AE_OK;
+
+       mutex_lock(&device->physical_node_lock);
+
+       list_for_each_entry(pn, &device->physical_node_list, node)
+               if (pn->put_online) {
+                       device_online(pn->dev);
+                       pn->put_online = false;
+               }
+
+       mutex_unlock(&device->physical_node_lock);
+
+       return AE_OK;
+}
+
 static int acpi_scan_hot_remove(struct acpi_device *device)
 {
        acpi_handle handle = device->handle;
        acpi_handle not_used;
        struct acpi_object_list arg_list;
        union acpi_object arg;
+       struct device *errdev;
        acpi_status status;
        unsigned long long sta;
 
@@ -136,10 +208,53 @@ static int acpi_scan_hot_remove(struct acpi_device *device)
                return -EINVAL;
        }
 
+       lock_device_hotplug();
+
+       /*
+        * Carry out two passes here and ignore errors in the first pass,
+        * because if the devices in question are memory blocks and
+        * CONFIG_MEMCG is set, one of the blocks may hold data structures
+        * that the other blocks depend on, but it is not known in advance which
+        * block holds them.
+        *
+        * If the first pass is successful, the second one isn't needed, though.
+        */
+       errdev = NULL;
+       acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
+                           NULL, acpi_bus_offline_companions,
+                           (void *)false, (void **)&errdev);
+       acpi_bus_offline_companions(handle, 0, (void *)false, (void **)&errdev);
+       if (errdev) {
+               errdev = NULL;
+               acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
+                                   NULL, acpi_bus_offline_companions,
+                                   (void *)true , (void **)&errdev);
+               if (!errdev || acpi_force_hot_remove)
+                       acpi_bus_offline_companions(handle, 0, (void *)true,
+                                                   (void **)&errdev);
+
+               if (errdev && !acpi_force_hot_remove) {
+                       dev_warn(errdev, "Offline failed.\n");
+                       acpi_bus_online_companions(handle, 0, NULL, NULL);
+                       acpi_walk_namespace(ACPI_TYPE_ANY, handle,
+                                           ACPI_UINT32_MAX,
+                                           acpi_bus_online_companions, NULL,
+                                           NULL, NULL);
+
+                       unlock_device_hotplug();
+
+                       put_device(&device->dev);
+                       return -EBUSY;
+               }
+       }
+
        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
                "Hot-removing device %s...\n", dev_name(&device->dev)));
 
        acpi_bus_trim(device);
+
+       unlock_device_hotplug();
+
        /* Device node has been unregistered. */
        put_device(&device->dev);
        device = NULL;
@@ -236,6 +351,7 @@ static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source)
        int error;
 
        mutex_lock(&acpi_scan_lock);
+       lock_device_hotplug();
 
        acpi_bus_get_device(handle, &device);
        if (device) {
@@ -259,6 +375,7 @@ static void acpi_scan_bus_device_check(acpi_handle handle, u32 ost_source)
                kobject_uevent(&device->dev.kobj, KOBJ_ONLINE);
 
  out:
+       unlock_device_hotplug();
        acpi_evaluate_hotplug_ost(handle, ost_source, ost_code, NULL);
        mutex_unlock(&acpi_scan_lock);
 }
@@ -816,32 +933,43 @@ static void acpi_device_remove_notify_handler(struct acpi_device *device)
                                           acpi_device_notify);
 }
 
-static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
-static int acpi_device_probe(struct device * dev)
+static int acpi_device_probe(struct device *dev)
 {
        struct acpi_device *acpi_dev = to_acpi_device(dev);
        struct acpi_driver *acpi_drv = to_acpi_driver(dev->driver);
        int ret;
 
-       ret = acpi_bus_driver_init(acpi_dev, acpi_drv);
-       if (!ret) {
-               if (acpi_drv->ops.notify) {
-                       ret = acpi_device_install_notify_handler(acpi_dev);
-                       if (ret) {
-                               if (acpi_drv->ops.remove)
-                                       acpi_drv->ops.remove(acpi_dev);
-                               acpi_dev->driver = NULL;
-                               acpi_dev->driver_data = NULL;
-                               return ret;
-                       }
-               }
+       if (acpi_dev->handler)
+               return -EINVAL;
 
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                       "Found driver [%s] for device [%s]\n",
-                       acpi_drv->name, acpi_dev->pnp.bus_id));
-               get_device(dev);
+       if (!acpi_drv->ops.add)
+               return -ENOSYS;
+
+       ret = acpi_drv->ops.add(acpi_dev);
+       if (ret)
+               return ret;
+
+       acpi_dev->driver = acpi_drv;
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+                         "Driver [%s] successfully bound to device [%s]\n",
+                         acpi_drv->name, acpi_dev->pnp.bus_id));
+
+       if (acpi_drv->ops.notify) {
+               ret = acpi_device_install_notify_handler(acpi_dev);
+               if (ret) {
+                       if (acpi_drv->ops.remove)
+                               acpi_drv->ops.remove(acpi_dev);
+
+                       acpi_dev->driver = NULL;
+                       acpi_dev->driver_data = NULL;
+                       return ret;
+               }
        }
-       return ret;
+
+       ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n",
+                         acpi_drv->name, acpi_dev->pnp.bus_id));
+       get_device(dev);
+       return 0;
 }
 
 static int acpi_device_remove(struct device * dev)
@@ -952,7 +1080,6 @@ int acpi_device_add(struct acpi_device *device,
                printk(KERN_ERR PREFIX "Error creating sysfs interface for device %s\n",
                       dev_name(&device->dev));
 
-       device->removal_type = ACPI_BUS_REMOVAL_NORMAL;
        return 0;
 
  err:
@@ -997,41 +1124,6 @@ static void acpi_device_unregister(struct acpi_device *device)
 /* --------------------------------------------------------------------------
                                  Driver Management
    -------------------------------------------------------------------------- */
-/**
- * acpi_bus_driver_init - add a device to a driver
- * @device: the device to add and initialize
- * @driver: driver for the device
- *
- * Used to initialize a device via its device driver.  Called whenever a
- * driver is bound to a device.  Invokes the driver's add() ops.
- */
-static int
-acpi_bus_driver_init(struct acpi_device *device, struct acpi_driver *driver)
-{
-       int result = 0;
-
-       if (!device || !driver)
-               return -EINVAL;
-
-       if (!driver->ops.add)
-               return -ENOSYS;
-
-       result = driver->ops.add(device);
-       if (result)
-               return result;
-
-       device->driver = driver;
-
-       /*
-        * TBD - Configuration Management: Assign resources to device based
-        * upon possible configuration and currently allocated resources.
-        */
-
-       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-                         "Driver successfully bound to device\n"));
-       return 0;
-}
-
 /**
  * acpi_bus_register_driver - register a driver with the ACPI bus
  * @driver: driver being registered
@@ -1939,7 +2031,6 @@ static acpi_status acpi_bus_device_detach(acpi_handle handle, u32 lvl_not_used,
        if (!acpi_bus_get_device(handle, &device)) {
                struct acpi_scan_handler *dev_handler = device->handler;
 
-               device->removal_type = ACPI_BUS_REMOVAL_EJECT;
                if (dev_handler) {
                        if (dev_handler->detach)
                                dev_handler->detach(device);
@@ -2038,10 +2129,13 @@ int __init acpi_scan_init(void)
 
        acpi_pci_root_init();
        acpi_pci_link_init();
+       acpi_processor_init();
        acpi_platform_init();
        acpi_lpss_init();
+       acpi_cmos_rtc_init();
        acpi_container_init();
        acpi_memory_hotplug_init();
+       acpi_dock_init();
 
        mutex_lock(&acpi_scan_lock);
        /*
index 9c1a435d10e69c8228516346832a8d2d2d242890..187ab61889e6da5fab9312e987a620a4cb212280 100644 (file)
@@ -494,6 +494,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
                break;
 
        case ACPI_STATE_S3:
+               if (!acpi_suspend_lowlevel)
+                       return -ENOSYS;
                error = acpi_suspend_lowlevel();
                if (error)
                        return error;
index fcae5fa2e1b322481ec2b331c4df0430bff66d53..5c5d1624fa2c261c8b6dca89a34156268a91d799 100644 (file)
@@ -780,6 +780,33 @@ void acpi_sysfs_add_hotplug_profile(struct acpi_hotplug_profile *hotplug,
        pr_err(PREFIX "Unable to add hotplug profile '%s'\n", name);
 }
 
+static ssize_t force_remove_show(struct kobject *kobj,
+                                struct kobj_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%d\n", !!acpi_force_hot_remove);
+}
+
+static ssize_t force_remove_store(struct kobject *kobj,
+                                 struct kobj_attribute *attr,
+                                 const char *buf, size_t size)
+{
+       bool val;
+       int ret;
+
+       ret = strtobool(buf, &val);
+       if (ret < 0)
+               return ret;
+
+       lock_device_hotplug();
+       acpi_force_hot_remove = val;
+       unlock_device_hotplug();
+       return size;
+}
+
+static const struct kobj_attribute force_remove_attr =
+       __ATTR(force_remove, S_IRUGO | S_IWUSR, force_remove_show,
+              force_remove_store);
+
 int __init acpi_sysfs_init(void)
 {
        int result;
@@ -789,6 +816,10 @@ int __init acpi_sysfs_init(void)
                return result;
 
        hotplug_kobj = kobject_create_and_add("hotplug", acpi_kobj);
+       result = sysfs_create_file(hotplug_kobj, &force_remove_attr.attr);
+       if (result)
+               return result;
+
        result = sysfs_create_file(acpi_kobj, &pm_profile_attr.attr);
        return result;
 }
index 440eadf2d32cdd270a75e9023f9ef31a1d9ae794..5d7075d25700b3bbd2cbe65772391155d1a10d30 100644 (file)
@@ -1722,9 +1722,6 @@ static int acpi_video_bus_add(struct acpi_device *device)
        int error;
        acpi_status status;
 
-       if (device->handler)
-               return -EINVAL;
-
        status = acpi_walk_namespace(ACPI_TYPE_DEVICE,
                                device->parent->handle, 1,
                                acpi_video_bus_match, NULL,
index cdbad3a454a085a7aa17bf1ae29e4a22b73c5c37..c6707278a6bb496d200caf9f0bd4a57233b9b1a1 100644 (file)
@@ -284,7 +284,7 @@ static const struct dev_pm_ops amba_pm = {
        SET_RUNTIME_PM_OPS(
                amba_pm_runtime_suspend,
                amba_pm_runtime_resume,
-               pm_generic_runtime_idle
+               NULL
        )
 };
 
index 87f2f395d79a1f9a9cd3dbc81675f0d71ac6f2cd..cf4e7020adacde5e69881a21adb0c578d31d7a3e 100644 (file)
@@ -156,8 +156,10 @@ static void ata_acpi_handle_hotplug(struct ata_port *ap, struct ata_device *dev,
 
        spin_unlock_irqrestore(ap->lock, flags);
 
-       if (wait)
+       if (wait) {
                ata_port_wait_eh(ap);
+               flush_work(&ap->hotplug_task.work);
+       }
 }
 
 static void ata_acpi_dev_notify_dock(acpi_handle handle, u32 event, void *data)
@@ -214,6 +216,39 @@ static const struct acpi_dock_ops ata_acpi_ap_dock_ops = {
        .uevent = ata_acpi_ap_uevent,
 };
 
+void ata_acpi_hotplug_init(struct ata_host *host)
+{
+       int i;
+
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+               acpi_handle handle;
+               struct ata_device *dev;
+
+               if (!ap)
+                       continue;
+
+               handle = ata_ap_acpi_handle(ap);
+               if (handle) {
+                       /* we might be on a docking station */
+                       register_hotplug_dock_device(handle,
+                                                    &ata_acpi_ap_dock_ops, ap,
+                                                    NULL, NULL);
+               }
+
+               ata_for_each_dev(dev, &ap->link, ALL) {
+                       handle = ata_dev_acpi_handle(dev);
+                       if (!handle)
+                               continue;
+
+                       /* we might be on a docking station */
+                       register_hotplug_dock_device(handle,
+                                                    &ata_acpi_dev_dock_ops,
+                                                    dev, NULL, NULL);
+               }
+       }
+}
+
 /**
  * ata_acpi_dissociate - dissociate ATA host from ACPI objects
  * @host: target ATA host
index f2184276539d885d167c2048a305847b51e58417..6e458a40a93bd36d03378af8aa54ac3df23f4183 100644 (file)
@@ -5436,7 +5436,7 @@ static int ata_port_runtime_idle(struct device *dev)
                                return -EBUSY;
        }
 
-       return pm_runtime_suspend(dev);
+       return 0;
 }
 
 static int ata_port_runtime_suspend(struct device *dev)
@@ -6148,6 +6148,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
        if (rc)
                goto err_tadd;
 
+       ata_acpi_hotplug_init(host);
+
        /* set cable, sata_spd_limit and report */
        for (i = 0; i < host->n_ports; i++) {
                struct ata_port *ap = host->ports[i];
index c949dd311b2ecd2e6d65e294409d24c4afea6eb7..577d902bc4deaa12d69d1acdc8aa304732163227 100644 (file)
@@ -122,6 +122,7 @@ extern int ata_acpi_register(void);
 extern void ata_acpi_unregister(void);
 extern void ata_acpi_bind(struct ata_device *dev);
 extern void ata_acpi_unbind(struct ata_device *dev);
+extern void ata_acpi_hotplug_init(struct ata_host *host);
 #else
 static inline void ata_acpi_dissociate(struct ata_host *host) { }
 static inline int ata_acpi_on_suspend(struct ata_port *ap) { return 0; }
@@ -134,6 +135,7 @@ static inline int ata_acpi_register(void) { return 0; }
 static inline void ata_acpi_unregister(void) { }
 static inline void ata_acpi_bind(struct ata_device *dev) { }
 static inline void ata_acpi_unbind(struct ata_device *dev) { }
+static inline void ata_acpi_hotplug_init(struct ata_host *host) {}
 #endif
 
 /* libata-scsi.c */
index 2499cefdcdf2429d9503506d5514a4943f9ec4e1..2166f34b7d842ac7fa8d129858dac244e9e5394a 100644 (file)
@@ -403,6 +403,36 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr,
 static struct device_attribute uevent_attr =
        __ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent);
 
+static ssize_t show_online(struct device *dev, struct device_attribute *attr,
+                          char *buf)
+{
+       bool val;
+
+       lock_device_hotplug();
+       val = !dev->offline;
+       unlock_device_hotplug();
+       return sprintf(buf, "%u\n", val);
+}
+
+static ssize_t store_online(struct device *dev, struct device_attribute *attr,
+                           const char *buf, size_t count)
+{
+       bool val;
+       int ret;
+
+       ret = strtobool(buf, &val);
+       if (ret < 0)
+               return ret;
+
+       lock_device_hotplug();
+       ret = val ? device_online(dev) : device_offline(dev);
+       unlock_device_hotplug();
+       return ret < 0 ? ret : count;
+}
+
+static struct device_attribute online_attr =
+       __ATTR(online, S_IRUGO | S_IWUSR, show_online, store_online);
+
 static int device_add_attributes(struct device *dev,
                                 struct device_attribute *attrs)
 {
@@ -516,6 +546,12 @@ static int device_add_attrs(struct device *dev)
        if (error)
                goto err_remove_type_groups;
 
+       if (device_supports_offline(dev) && !dev->offline_disabled) {
+               error = device_create_file(dev, &online_attr);
+               if (error)
+                       goto err_remove_type_groups;
+       }
+
        return 0;
 
  err_remove_type_groups:
@@ -536,6 +572,7 @@ static void device_remove_attrs(struct device *dev)
        struct class *class = dev->class;
        const struct device_type *type = dev->type;
 
+       device_remove_file(dev, &online_attr);
        device_remove_groups(dev, dev->groups);
 
        if (type)
@@ -1433,6 +1470,99 @@ EXPORT_SYMBOL_GPL(put_device);
 EXPORT_SYMBOL_GPL(device_create_file);
 EXPORT_SYMBOL_GPL(device_remove_file);
 
+static DEFINE_MUTEX(device_hotplug_lock);
+
+void lock_device_hotplug(void)
+{
+       mutex_lock(&device_hotplug_lock);
+}
+
+void unlock_device_hotplug(void)
+{
+       mutex_unlock(&device_hotplug_lock);
+}
+
+static int device_check_offline(struct device *dev, void *not_used)
+{
+       int ret;
+
+       ret = device_for_each_child(dev, NULL, device_check_offline);
+       if (ret)
+               return ret;
+
+       return device_supports_offline(dev) && !dev->offline ? -EBUSY : 0;
+}
+
+/**
+ * device_offline - Prepare the device for hot-removal.
+ * @dev: Device to be put offline.
+ *
+ * Execute the device bus type's .offline() callback, if present, to prepare
+ * the device for a subsequent hot-removal.  If that succeeds, the device must
+ * not be used until either it is removed or its bus type's .online() callback
+ * is executed.
+ *
+ * Call under device_hotplug_lock.
+ */
+int device_offline(struct device *dev)
+{
+       int ret;
+
+       if (dev->offline_disabled)
+               return -EPERM;
+
+       ret = device_for_each_child(dev, NULL, device_check_offline);
+       if (ret)
+               return ret;
+
+       device_lock(dev);
+       if (device_supports_offline(dev)) {
+               if (dev->offline) {
+                       ret = 1;
+               } else {
+                       ret = dev->bus->offline(dev);
+                       if (!ret) {
+                               kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
+                               dev->offline = true;
+                       }
+               }
+       }
+       device_unlock(dev);
+
+       return ret;
+}
+
+/**
+ * device_online - Put the device back online after successful device_offline().
+ * @dev: Device to be put back online.
+ *
+ * If device_offline() has been successfully executed for @dev, but the device
+ * has not been removed subsequently, execute its bus type's .online() callback
+ * to indicate that the device can be used again.
+ *
+ * Call under device_hotplug_lock.
+ */
+int device_online(struct device *dev)
+{
+       int ret = 0;
+
+       device_lock(dev);
+       if (device_supports_offline(dev)) {
+               if (dev->offline) {
+                       ret = dev->bus->online(dev);
+                       if (!ret) {
+                               kobject_uevent(&dev->kobj, KOBJ_ONLINE);
+                               dev->offline = false;
+                       }
+               } else {
+                       ret = 1;
+               }
+       }
+       device_unlock(dev);
+
+       return ret;
+}
+
 struct root_device {
        struct device dev;
        struct module *owner;
index 3d48fc887ef4b3a3da1aadefaf9129578e3d1ef2..1d110dc6f0c1f371ac262a9f6e352b5d626bf2fa 100644 (file)
 #include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/percpu.h>
+#include <linux/acpi.h>
 
 #include "base.h"
 
-struct bus_type cpu_subsys = {
-       .name = "cpu",
-       .dev_name = "cpu",
-};
-EXPORT_SYMBOL_GPL(cpu_subsys);
-
 static DEFINE_PER_CPU(struct device *, cpu_sys_devices);
 
+static int cpu_subsys_match(struct device *dev, struct device_driver *drv)
+{
+       /* ACPI style match is the only one that may succeed. */
+       if (acpi_driver_match_device(dev, drv))
+               return 1;
+
+       return 0;
+}
+
 #ifdef CONFIG_HOTPLUG_CPU
 static void change_cpu_under_node(struct cpu *cpu,
                        unsigned int from_nid, unsigned int to_nid)
@@ -34,69 +38,45 @@ static void change_cpu_under_node(struct cpu *cpu,
        cpu->node_id = to_nid;
 }
 
-static ssize_t show_online(struct device *dev,
-                          struct device_attribute *attr,
-                          char *buf)
+static int __ref cpu_subsys_online(struct device *dev)
 {
        struct cpu *cpu = container_of(dev, struct cpu, dev);
+       int cpuid = dev->id;
+       int from_nid, to_nid;
+       int ret;
 
-       return sprintf(buf, "%u\n", !!cpu_online(cpu->dev.id));
+       cpu_hotplug_driver_lock();
+
+       from_nid = cpu_to_node(cpuid);
+       ret = cpu_up(cpuid);
+       /*
+        * When hot adding memory to memoryless node and enabling a cpu
+        * on the node, node number of the cpu may internally change.
+        */
+       to_nid = cpu_to_node(cpuid);
+       if (from_nid != to_nid)
+               change_cpu_under_node(cpu, from_nid, to_nid);
+
+       cpu_hotplug_driver_unlock();
+       return ret;
 }
 
-static ssize_t __ref store_online(struct device *dev,
-                                 struct device_attribute *attr,
-                                 const char *buf, size_t count)
+static int cpu_subsys_offline(struct device *dev)
 {
-       struct cpu *cpu = container_of(dev, struct cpu, dev);
-       int cpuid = cpu->dev.id;
-       int from_nid, to_nid;
-       ssize_t ret;
+       int ret;
 
        cpu_hotplug_driver_lock();
-       switch (buf[0]) {
-       case '0':
-               ret = cpu_down(cpuid);
-               if (!ret)
-                       kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
-               break;
-       case '1':
-               from_nid = cpu_to_node(cpuid);
-               ret = cpu_up(cpuid);
-
-               /*
-                * When hot adding memory to memoryless node and enabling a cpu
-                * on the node, node number of the cpu may internally change.
-                */
-               to_nid = cpu_to_node(cpuid);
-               if (from_nid != to_nid)
-                       change_cpu_under_node(cpu, from_nid, to_nid);
-
-               if (!ret)
-                       kobject_uevent(&dev->kobj, KOBJ_ONLINE);
-               break;
-       default:
-               ret = -EINVAL;
-       }
+       ret = cpu_down(dev->id);
        cpu_hotplug_driver_unlock();
-
-       if (ret >= 0)
-               ret = count;
        return ret;
 }
-static DEVICE_ATTR(online, 0644, show_online, store_online);
 
-static void __cpuinit register_cpu_control(struct cpu *cpu)
-{
-       device_create_file(&cpu->dev, &dev_attr_online);
-}
 void unregister_cpu(struct cpu *cpu)
 {
        int logical_cpu = cpu->dev.id;
 
        unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu));
 
-       device_remove_file(&cpu->dev, &dev_attr_online);
-
        device_unregister(&cpu->dev);
        per_cpu(cpu_sys_devices, logical_cpu) = NULL;
        return;
@@ -123,12 +103,19 @@ static DEVICE_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
 static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store);
 #endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
 
-#else /* ... !CONFIG_HOTPLUG_CPU */
-static inline void register_cpu_control(struct cpu *cpu)
-{
-}
 #endif /* CONFIG_HOTPLUG_CPU */
 
+struct bus_type cpu_subsys = {
+       .name = "cpu",
+       .dev_name = "cpu",
+       .match = cpu_subsys_match,
+#ifdef CONFIG_HOTPLUG_CPU
+       .online = cpu_subsys_online,
+       .offline = cpu_subsys_offline,
+#endif
+};
+EXPORT_SYMBOL_GPL(cpu_subsys);
+
 #ifdef CONFIG_KEXEC
 #include <linux/kexec.h>
 
@@ -277,12 +264,12 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)
        cpu->dev.id = num;
        cpu->dev.bus = &cpu_subsys;
        cpu->dev.release = cpu_device_release;
+       cpu->dev.offline_disabled = !cpu->hotpluggable;
+       cpu->dev.offline = !cpu_online(num);
 #ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
        cpu->dev.bus->uevent = arch_cpu_uevent;
 #endif
        error = device_register(&cpu->dev);
-       if (!error && cpu->hotpluggable)
-               register_cpu_control(cpu);
        if (!error)
                per_cpu(cpu_sys_devices, num) = &cpu->dev;
        if (!error)
index 14f8a6954da0a11f1250b75b050318a9c63a4cb2..4ebf97f99fae0f84fb7d8f28bc9a9bd513f7b5aa 100644 (file)
@@ -37,9 +37,14 @@ static inline int base_memory_block_id(int section_nr)
        return section_nr / sections_per_block;
 }
 
+static int memory_subsys_online(struct device *dev);
+static int memory_subsys_offline(struct device *dev);
+
 static struct bus_type memory_subsys = {
        .name = MEMORY_CLASS_NAME,
        .dev_name = MEMORY_CLASS_NAME,
+       .online = memory_subsys_online,
+       .offline = memory_subsys_offline,
 };
 
 static BLOCKING_NOTIFIER_HEAD(memory_chain);
@@ -88,6 +93,7 @@ int register_memory(struct memory_block *memory)
        memory->dev.bus = &memory_subsys;
        memory->dev.id = memory->start_section_nr / sections_per_block;
        memory->dev.release = memory_block_release;
+       memory->dev.offline = memory->state == MEM_OFFLINE;
 
        error = device_register(&memory->dev);
        return error;
@@ -278,33 +284,64 @@ static int __memory_block_change_state(struct memory_block *mem,
 {
        int ret = 0;
 
-       if (mem->state != from_state_req) {
-               ret = -EINVAL;
-               goto out;
-       }
+       if (mem->state != from_state_req)
+               return -EINVAL;
 
        if (to_state == MEM_OFFLINE)
                mem->state = MEM_GOING_OFFLINE;
 
        ret = memory_block_action(mem->start_section_nr, to_state, online_type);
+       mem->state = ret ? from_state_req : to_state;
+       return ret;
+}
 
-       if (ret) {
-               mem->state = from_state_req;
-               goto out;
-       }
+static int memory_subsys_online(struct device *dev)
+{
+       struct memory_block *mem = container_of(dev, struct memory_block, dev);
+       int ret;
 
-       mem->state = to_state;
-       switch (mem->state) {
-       case MEM_OFFLINE:
-               kobject_uevent(&mem->dev.kobj, KOBJ_OFFLINE);
-               break;
-       case MEM_ONLINE:
-               kobject_uevent(&mem->dev.kobj, KOBJ_ONLINE);
-               break;
-       default:
-               break;
+       mutex_lock(&mem->state_mutex);
+
+       ret = mem->state == MEM_ONLINE ? 0 :
+               __memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE,
+                                           ONLINE_KEEP);
+
+       mutex_unlock(&mem->state_mutex);
+       return ret;
+}
+
+static int memory_subsys_offline(struct device *dev)
+{
+       struct memory_block *mem = container_of(dev, struct memory_block, dev);
+       int ret;
+
+       mutex_lock(&mem->state_mutex);
+
+       ret = mem->state == MEM_OFFLINE ? 0 :
+               __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE, -1);
+
+       mutex_unlock(&mem->state_mutex);
+       return ret;
+}
+
+static int __memory_block_change_state_uevent(struct memory_block *mem,
+               unsigned long to_state, unsigned long from_state_req,
+               int online_type)
+{
+       int ret = __memory_block_change_state(mem, to_state, from_state_req,
+                                             online_type);
+       if (!ret) {
+               switch (mem->state) {
+               case MEM_OFFLINE:
+                       kobject_uevent(&mem->dev.kobj, KOBJ_OFFLINE);
+                       break;
+               case MEM_ONLINE:
+                       kobject_uevent(&mem->dev.kobj, KOBJ_ONLINE);
+                       break;
+               default:
+                       break;
+               }
        }
-out:
        return ret;
 }
 
@@ -315,8 +352,8 @@ static int memory_block_change_state(struct memory_block *mem,
        int ret;
 
        mutex_lock(&mem->state_mutex);
-       ret = __memory_block_change_state(mem, to_state, from_state_req,
-                                         online_type);
+       ret = __memory_block_change_state_uevent(mem, to_state, from_state_req,
+                                                online_type);
        mutex_unlock(&mem->state_mutex);
 
        return ret;
@@ -326,22 +363,34 @@ store_mem_state(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t count)
 {
        struct memory_block *mem;
+       bool offline;
        int ret = -EINVAL;
 
        mem = container_of(dev, struct memory_block, dev);
 
-       if (!strncmp(buf, "online_kernel", min_t(int, count, 13)))
+       lock_device_hotplug();
+
+       if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) {
+               offline = false;
                ret = memory_block_change_state(mem, MEM_ONLINE,
                                                MEM_OFFLINE, ONLINE_KERNEL);
-       else if (!strncmp(buf, "online_movable", min_t(int, count, 14)))
+       } else if (!strncmp(buf, "online_movable", min_t(int, count, 14))) {
+               offline = false;
                ret = memory_block_change_state(mem, MEM_ONLINE,
                                                MEM_OFFLINE, ONLINE_MOVABLE);
-       else if (!strncmp(buf, "online", min_t(int, count, 6)))
+       } else if (!strncmp(buf, "online", min_t(int, count, 6))) {
+               offline = false;
                ret = memory_block_change_state(mem, MEM_ONLINE,
                                                MEM_OFFLINE, ONLINE_KEEP);
-       else if(!strncmp(buf, "offline", min_t(int, count, 7)))
+       } else if(!strncmp(buf, "offline", min_t(int, count, 7))) {
+               offline = true;
                ret = memory_block_change_state(mem, MEM_OFFLINE,
                                                MEM_ONLINE, -1);
+       }
+       if (!ret)
+               dev->offline = offline;
+
+       unlock_device_hotplug();
 
        if (ret)
                return ret;
@@ -679,21 +728,6 @@ int unregister_memory_section(struct mem_section *section)
 }
 #endif /* CONFIG_MEMORY_HOTREMOVE */
 
-/*
- * offline one memory block. If the memory block has been offlined, do nothing.
- */
-int offline_memory_block(struct memory_block *mem)
-{
-       int ret = 0;
-
-       mutex_lock(&mem->state_mutex);
-       if (mem->state != MEM_OFFLINE)
-               ret = __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE, -1);
-       mutex_unlock(&mem->state_mutex);
-
-       return ret;
-}
-
 /* return true if the memory block is offlined, otherwise, return false */
 bool is_memblock_offlined(struct memory_block *mem)
 {
index 9eda84246ffd5eda7d1d6947ef27a5ba05a75951..96a930387ebc749977b3f4ec6007f1478ba95fe3 100644 (file)
@@ -888,7 +888,6 @@ int platform_pm_restore(struct device *dev)
 static const struct dev_pm_ops platform_dev_pm_ops = {
        .runtime_suspend = pm_generic_runtime_suspend,
        .runtime_resume = pm_generic_runtime_resume,
-       .runtime_idle = pm_generic_runtime_idle,
        USE_PLATFORM_PM_SLEEP_OPS
 };
 
index 7072404c8b6da6ddb7ba6633cab5da087e49868e..bfb8955c406c5ef02d819d4d5fa02d709f0a6ec0 100644 (file)
@@ -2143,7 +2143,6 @@ void pm_genpd_init(struct generic_pm_domain *genpd,
        genpd->max_off_time_changed = true;
        genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
        genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
-       genpd->domain.ops.runtime_idle = pm_generic_runtime_idle;
        genpd->domain.ops.prepare = pm_genpd_prepare;
        genpd->domain.ops.suspend = pm_genpd_suspend;
        genpd->domain.ops.suspend_late = pm_genpd_suspend_late;
index bfd898b8988e37ca0dcc985fc28c57fdcde27fa0..5ee030a864f9266bb6c8ea18dd897e736fd2727c 100644 (file)
 #include <linux/export.h>
 
 #ifdef CONFIG_PM_RUNTIME
-/**
- * pm_generic_runtime_idle - Generic runtime idle callback for subsystems.
- * @dev: Device to handle.
- *
- * If PM operations are defined for the @dev's driver and they include
- * ->runtime_idle(), execute it and return its error code, if nonzero.
- * Otherwise, execute pm_runtime_suspend() for the device and return 0.
- */
-int pm_generic_runtime_idle(struct device *dev)
-{
-       const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
-
-       if (pm && pm->runtime_idle) {
-               int ret = pm->runtime_idle(dev);
-               if (ret)
-                       return ret;
-       }
-
-       pm_runtime_suspend(dev);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(pm_generic_runtime_idle);
-
 /**
  * pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems.
  * @dev: Device to suspend.
index 71671c42ef457e3486f13b770114a0c09459a708..5c1361a9e5dd58049c3835d414f42607cdb46411 100644 (file)
@@ -42,6 +42,7 @@
 #include <linux/export.h>
 #include <linux/pm_runtime.h>
 #include <linux/err.h>
+#include <trace/events/power.h>
 
 #include "power.h"
 
@@ -305,6 +306,7 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req,
        else if (!dev->power.qos)
                ret = dev_pm_qos_constraints_allocate(dev);
 
+       trace_dev_pm_qos_add_request(dev_name(dev), type, value);
        if (!ret) {
                req->dev = dev;
                req->type = type;
@@ -349,6 +351,8 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req,
                return -EINVAL;
        }
 
+       trace_dev_pm_qos_update_request(dev_name(req->dev), req->type,
+                                       new_value);
        if (curr_value != new_value)
                ret = apply_constraint(req, PM_QOS_UPDATE_REQ, new_value);
 
@@ -398,6 +402,8 @@ static int __dev_pm_qos_remove_request(struct dev_pm_qos_request *req)
        if (IS_ERR_OR_NULL(req->dev->power.qos))
                return -ENODEV;
 
+       trace_dev_pm_qos_remove_request(dev_name(req->dev), req->type,
+                                       PM_QOS_DEFAULT_VALUE);
        ret = apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE);
        memset(req, 0, sizeof(*req));
        return ret;
index ef13ad08afb2cf845340bb28463ad3df63e5b04b..268a35097578d94f78f4baef4d9cc8b3fa1c31cd 100644 (file)
@@ -293,11 +293,8 @@ static int rpm_idle(struct device *dev, int rpmflags)
        /* Pending requests need to be canceled. */
        dev->power.request = RPM_REQ_NONE;
 
-       if (dev->power.no_callbacks) {
-               /* Assume ->runtime_idle() callback would have suspended. */
-               retval = rpm_suspend(dev, rpmflags);
+       if (dev->power.no_callbacks)
                goto out;
-       }
 
        /* Carry out an asynchronous or a synchronous idle notification. */
        if (rpmflags & RPM_ASYNC) {
@@ -306,7 +303,8 @@ static int rpm_idle(struct device *dev, int rpmflags)
                        dev->power.request_pending = true;
                        queue_work(pm_wq, &dev->power.work);
                }
-               goto out;
+               trace_rpm_return_int(dev, _THIS_IP_, 0);
+               return 0;
        }
 
        dev->power.idle_notification = true;
@@ -326,14 +324,14 @@ static int rpm_idle(struct device *dev, int rpmflags)
                callback = dev->driver->pm->runtime_idle;
 
        if (callback)
-               __rpm_callback(callback, dev);
+               retval = __rpm_callback(callback, dev);
 
        dev->power.idle_notification = false;
        wake_up_all(&dev->power.wait_queue);
 
  out:
        trace_rpm_return_int(dev, _THIS_IP_, retval);
-       return retval;
+       return retval ? retval : rpm_suspend(dev, rpmflags);
 }
 
 /**
index 79715e7fa43e34c9cbf9a4521a657d7bb952f9c6..2d56f4113ae761a406fca80c8d39c892ae4b2416 100644 (file)
@@ -659,7 +659,7 @@ void pm_wakeup_event(struct device *dev, unsigned int msec)
 }
 EXPORT_SYMBOL_GPL(pm_wakeup_event);
 
-static void print_active_wakeup_sources(void)
+void pm_print_active_wakeup_sources(void)
 {
        struct wakeup_source *ws;
        int active = 0;
@@ -683,6 +683,7 @@ static void print_active_wakeup_sources(void)
                        last_activity_ws->name);
        rcu_read_unlock();
 }
+EXPORT_SYMBOL_GPL(pm_print_active_wakeup_sources);
 
 /**
  * pm_wakeup_pending - Check if power transition in progress should be aborted.
@@ -707,8 +708,10 @@ bool pm_wakeup_pending(void)
        }
        spin_unlock_irqrestore(&events_lock, flags);
 
-       if (ret)
-               print_active_wakeup_sources();
+       if (ret) {
+               pr_info("PM: Wakeup pending, aborting suspend\n");
+               pm_print_active_wakeup_sources();
+       }
 
        return ret;
 }
index 4f45eee9e33b2746f95c42867c2339f67707fb30..812f83f8b0c646758c9ac6144ccc6c76e0ed03f6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Intel Lynxpoint LPSS clocks.
+ * Intel Low Power Subsystem clocks.
  *
  * Copyright (C) 2013, Intel Corporation
  * Authors: Mika Westerberg <mika.westerberg@linux.intel.com>
@@ -18,8 +18,6 @@
 #include <linux/platform_data/clk-lpss.h>
 #include <linux/platform_device.h>
 
-#define PRV_CLOCK_PARAMS 0x800
-
 static int lpt_clk_probe(struct platform_device *pdev)
 {
        struct lpss_clk_data *drvdata;
index 403dad646abe6169a3c07244120eafa52fb117f3..39264020b88a1b2e7d461a8d0a3f2f909a31dbb4 100644 (file)
@@ -1057,4 +1057,11 @@ static const struct x86_cpu_id acpi_cpufreq_ids[] = {
 };
 MODULE_DEVICE_TABLE(x86cpu, acpi_cpufreq_ids);
 
+static const struct acpi_device_id processor_device_ids[] = {
+       {ACPI_PROCESSOR_OBJECT_HID, },
+       {ACPI_PROCESSOR_DEVICE_HID, },
+       {},
+};
+MODULE_DEVICE_TABLE(acpi, processor_device_ids);
+
 MODULE_ALIAS("acpi");
index c4cc27e5c8a5c22e5439c8ed7ceed322ed45eb8a..81de5d96749bcdc0f4c9a7f6722671eb30a6cd03 100644 (file)
@@ -1,7 +1,9 @@
 
-config CPU_IDLE
+menuconfig CPU_IDLE
        bool "CPU idle PM support"
        default y if ACPI || PPC_PSERIES
+       select CPU_IDLE_GOV_LADDER if (!NO_HZ && !NO_HZ_IDLE)
+       select CPU_IDLE_GOV_MENU if (NO_HZ || NO_HZ_IDLE)
        help
          CPU idle is a generic framework for supporting software-controlled
          idle processor power management.  It includes modular cross-platform
@@ -9,9 +11,10 @@ config CPU_IDLE
 
          If you're using an ACPI-enabled platform, you should say Y here.
 
+if CPU_IDLE
+
 config CPU_IDLE_MULTIPLE_DRIVERS
         bool "Support multiple cpuidle drivers"
-        depends on CPU_IDLE
         default n
         help
          Allows the cpuidle framework to use different drivers for each CPU.
@@ -19,24 +22,26 @@ config CPU_IDLE_MULTIPLE_DRIVERS
          states. If unsure say N.
 
 config CPU_IDLE_GOV_LADDER
-       bool
-       depends on CPU_IDLE
+       bool "Ladder governor (for periodic timer tick)"
        default y
 
 config CPU_IDLE_GOV_MENU
-       bool
-       depends on CPU_IDLE && NO_HZ
+       bool "Menu governor (for tickless system)"
        default y
 
-config ARCH_NEEDS_CPU_IDLE_COUPLED
-       def_bool n
-
-if CPU_IDLE
-
 config CPU_IDLE_CALXEDA
        bool "CPU Idle Driver for Calxeda processors"
        depends on ARCH_HIGHBANK
        help
          Select this to enable cpuidle on Calxeda processors.
 
+config CPU_IDLE_ZYNQ
+       bool "CPU Idle Driver for Xilinx Zynq processors"
+       depends on ARCH_ZYNQ
+       help
+         Select this to enable cpuidle on Xilinx Zynq processors.
+
 endif
+
+config ARCH_NEEDS_CPU_IDLE_COUPLED
+       def_bool n
index 0d8bd55e776f64d5e3f45c2f5d776366d98b9f86..8767a7b3eb913d9b5eb530f6df208eafe6476aa2 100644 (file)
@@ -7,3 +7,4 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o
 
 obj-$(CONFIG_CPU_IDLE_CALXEDA) += cpuidle-calxeda.o
 obj-$(CONFIG_ARCH_KIRKWOOD) += cpuidle-kirkwood.o
+obj-$(CONFIG_CPU_IDLE_ZYNQ) += cpuidle-zynq.o
diff --git a/drivers/cpuidle/cpuidle-zynq.c b/drivers/cpuidle/cpuidle-zynq.c
new file mode 100644 (file)
index 0000000..38e03a1
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2012-2013 Xilinx
+ *
+ * CPU idle support for Xilinx Zynq
+ *
+ * based on arch/arm/mach-at91/cpuidle.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * The cpu idle uses wait-for-interrupt and RAM self refresh in order
+ * to implement two idle states -
+ * #1 wait-for-interrupt
+ * #2 wait-for-interrupt and RAM self refresh
+ *
+ * Maintainer: Michal Simek <michal.simek@xilinx.com>
+ */
+
+#include <linux/init.h>
+#include <linux/cpu_pm.h>
+#include <linux/cpuidle.h>
+#include <linux/of.h>
+#include <asm/proc-fns.h>
+#include <asm/cpuidle.h>
+
+#define ZYNQ_MAX_STATES                2
+
+/* Actual code that puts the SoC in different idle states */
+static int zynq_enter_idle(struct cpuidle_device *dev,
+                          struct cpuidle_driver *drv, int index)
+{
+       /* Devices must be stopped here */
+       cpu_pm_enter();
+
+       /* Add code for DDR self refresh start */
+       cpu_do_idle();
+
+       /* Add code for DDR self refresh stop */
+       cpu_pm_exit();
+
+       return index;
+}
+
+static struct cpuidle_driver zynq_idle_driver = {
+       .name = "zynq_idle",
+       .owner = THIS_MODULE,
+       .states = {
+               ARM_CPUIDLE_WFI_STATE,
+               {
+                       .enter                  = zynq_enter_idle,
+                       .exit_latency           = 10,
+                       .target_residency       = 10000,
+                       .flags                  = CPUIDLE_FLAG_TIME_VALID |
+                                                 CPUIDLE_FLAG_TIMER_STOP,
+                       .name                   = "RAM_SR",
+                       .desc                   = "WFI and RAM Self Refresh",
+               },
+       },
+       .safe_state_index = 0,
+       .state_count = ZYNQ_MAX_STATES,
+};
+
+/* Initialize CPU idle by registering the idle states */
+static int __init zynq_cpuidle_init(void)
+{
+       if (!of_machine_is_compatible("xlnx,zynq-7000"))
+               return -ENODEV;
+
+       pr_info("Xilinx Zynq CpuIdle Driver started\n");
+
+       return cpuidle_register(&zynq_idle_driver, NULL);
+}
+
+device_initcall(zynq_cpuidle_init);
index c3a93fece819e71adb5fcae2acd84f885c0f2583..fdc432f18022b331f2102dccf13b539e74fae3ec 100644 (file)
@@ -466,7 +466,7 @@ void cpuidle_unregister(struct cpuidle_driver *drv)
        int cpu;
        struct cpuidle_device *device;
 
-       for_each_possible_cpu(cpu) {
+       for_each_cpu(cpu, drv->cpumask) {
                device = &per_cpu(cpuidle_dev, cpu);
                cpuidle_unregister_device(device);
        }
@@ -498,7 +498,7 @@ int cpuidle_register(struct cpuidle_driver *drv,
                return ret;
        }
 
-       for_each_possible_cpu(cpu) {
+       for_each_cpu(cpu, drv->cpumask) {
                device = &per_cpu(cpuidle_dev, cpu);
                device->cpu = cpu;
 
index 8dfaaae944443b5aa534c7d7a9ed5f1d7a36a4e3..3ac499d5a20784c0432e91f51575022f95c3d3d5 100644 (file)
 
 DEFINE_SPINLOCK(cpuidle_driver_lock);
 
-static void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu);
-static struct cpuidle_driver * __cpuidle_get_cpu_driver(int cpu);
+#ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS
 
-static void cpuidle_setup_broadcast_timer(void *arg)
+static DEFINE_PER_CPU(struct cpuidle_driver *, cpuidle_drivers);
+
+/**
+ * __cpuidle_get_cpu_driver - return the cpuidle driver tied to a CPU.
+ * @cpu: the CPU handled by the driver
+ *
+ * Returns a pointer to struct cpuidle_driver or NULL if no driver has been
+ * registered for @cpu.
+ */
+static struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu)
 {
-       int cpu = smp_processor_id();
-       clockevents_notify((long)(arg), &cpu);
+       return per_cpu(cpuidle_drivers, cpu);
 }
 
-static void __cpuidle_driver_init(struct cpuidle_driver *drv, int cpu)
+/**
+ * __cpuidle_unset_driver - unset per CPU driver variables.
+ * @drv: a valid pointer to a struct cpuidle_driver
+ *
+ * For each CPU in the driver's CPU mask, unset the registered driver per CPU
+ * variable. If @drv is different from the registered driver, the corresponding
+ * variable is not cleared.
+ */
+static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)
 {
-       int i;
-
-       drv->refcnt = 0;
+       int cpu;
 
-       for (i = drv->state_count - 1; i >= 0 ; i--) {
+       for_each_cpu(cpu, drv->cpumask) {
 
-               if (!(drv->states[i].flags & CPUIDLE_FLAG_TIMER_STOP))
+               if (drv != __cpuidle_get_cpu_driver(cpu))
                        continue;
 
-               drv->bctimer = 1;
-               on_each_cpu_mask(get_cpu_mask(cpu), cpuidle_setup_broadcast_timer,
-                                (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1);
-               break;
+               per_cpu(cpuidle_drivers, cpu) = NULL;
        }
 }
 
-static int __cpuidle_register_driver(struct cpuidle_driver *drv, int cpu)
+/**
+ * __cpuidle_set_driver - set per CPU driver variables the the given driver.
+ * @drv: a valid pointer to a struct cpuidle_driver
+ *
+ * For each CPU in the driver's cpumask, unset the registered driver per CPU
+ * to @drv.
+ *
+ * Returns 0 on success, -EBUSY if the CPUs have driver(s) already.
+ */
+static inline int __cpuidle_set_driver(struct cpuidle_driver *drv)
 {
-       if (!drv || !drv->state_count)
-               return -EINVAL;
-
-       if (cpuidle_disabled())
-               return -ENODEV;
+       int cpu;
 
-       if (__cpuidle_get_cpu_driver(cpu))
-               return -EBUSY;
+       for_each_cpu(cpu, drv->cpumask) {
 
-       __cpuidle_driver_init(drv, cpu);
+               if (__cpuidle_get_cpu_driver(cpu)) {
+                       __cpuidle_unset_driver(drv);
+                       return -EBUSY;
+               }
 
-       __cpuidle_set_cpu_driver(drv, cpu);
+               per_cpu(cpuidle_drivers, cpu) = drv;
+       }
 
        return 0;
 }
 
-static void __cpuidle_unregister_driver(struct cpuidle_driver *drv, int cpu)
-{
-       if (drv != __cpuidle_get_cpu_driver(cpu))
-               return;
+#else
 
-       if (!WARN_ON(drv->refcnt > 0))
-               __cpuidle_set_cpu_driver(NULL, cpu);
+static struct cpuidle_driver *cpuidle_curr_driver;
 
-       if (drv->bctimer) {
-               drv->bctimer = 0;
-               on_each_cpu_mask(get_cpu_mask(cpu), cpuidle_setup_broadcast_timer,
-                                (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF, 1);
-       }
+/**
+ * __cpuidle_get_cpu_driver - return the global cpuidle driver pointer.
+ * @cpu: ignored without the multiple driver support
+ *
+ * Return a pointer to a struct cpuidle_driver object or NULL if no driver was
+ * previously registered.
+ */
+static inline struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu)
+{
+       return cpuidle_curr_driver;
 }
 
-#ifdef CONFIG_CPU_IDLE_MULTIPLE_DRIVERS
+/**
+ * __cpuidle_set_driver - assign the global cpuidle driver variable.
+ * @drv: pointer to a struct cpuidle_driver object
+ *
+ * Returns 0 on success, -EBUSY if the driver is already registered.
+ */
+static inline int __cpuidle_set_driver(struct cpuidle_driver *drv)
+{
+       if (cpuidle_curr_driver)
+               return -EBUSY;
 
-static DEFINE_PER_CPU(struct cpuidle_driver *, cpuidle_drivers);
+       cpuidle_curr_driver = drv;
 
-static void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu)
-{
-       per_cpu(cpuidle_drivers, cpu) = drv;
+       return 0;
 }
 
-static struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu)
+/**
+ * __cpuidle_unset_driver - unset the global cpuidle driver variable.
+ * @drv: a pointer to a struct cpuidle_driver
+ *
+ * Reset the global cpuidle variable to NULL.  If @drv does not match the
+ * registered driver, do nothing.
+ */
+static inline void __cpuidle_unset_driver(struct cpuidle_driver *drv)
 {
-       return per_cpu(cpuidle_drivers, cpu);
+       if (drv == cpuidle_curr_driver)
+               cpuidle_curr_driver = NULL;
 }
 
-static void __cpuidle_unregister_all_cpu_driver(struct cpuidle_driver *drv)
+#endif
+
+/**
+ * cpuidle_setup_broadcast_timer - enable/disable the broadcast timer
+ * @arg: a void pointer used to match the SMP cross call API
+ *
+ * @arg is used as a value of type 'long' with on of the two values:
+ * - CLOCK_EVT_NOTIFY_BROADCAST_ON
+ * - CLOCK_EVT_NOTIFY_BROADCAST_OFF
+ *
+ * Set the broadcast timer notification for the current CPU.  This function
+ * is executed per CPU by an SMP cross call.  It not supposed to be called
+ * directly.
+ */
+static void cpuidle_setup_broadcast_timer(void *arg)
 {
-       int cpu;
-       for_each_present_cpu(cpu)
-               __cpuidle_unregister_driver(drv, cpu);
+       int cpu = smp_processor_id();
+       clockevents_notify((long)(arg), &cpu);
 }
 
-static int __cpuidle_register_all_cpu_driver(struct cpuidle_driver *drv)
+/**
+ * __cpuidle_driver_init - initialize the driver's internal data
+ * @drv: a valid pointer to a struct cpuidle_driver
+ *
+ * Returns 0 on success, a negative error code otherwise.
+ */
+static int __cpuidle_driver_init(struct cpuidle_driver *drv)
 {
-       int ret = 0;
-       int i, cpu;
+       int i;
 
-       for_each_present_cpu(cpu) {
-               ret = __cpuidle_register_driver(drv, cpu);
-               if (ret)
-                       break;
-       }
+       drv->refcnt = 0;
 
-       if (ret)
-               for_each_present_cpu(i) {
-                       if (i == cpu)
-                               break;
-                       __cpuidle_unregister_driver(drv, i);
-               }
+       /*
+        * Use all possible CPUs as the default, because if the kernel boots
+        * with some CPUs offline and then we online one of them, the CPU
+        * notifier has to know which driver to assign.
+        */
+       if (!drv->cpumask)
+               drv->cpumask = (struct cpumask *)cpu_possible_mask;
+
+       /*
+        * Look for the timer stop flag in the different states, so that we know
+        * if the broadcast timer has to be set up.  The loop is in the reverse
+        * order, because usually on of the the deeper states has this flag set.
+        */
+       for (i = drv->state_count - 1; i >= 0 ; i--) {
 
+               if (!(drv->states[i].flags & CPUIDLE_FLAG_TIMER_STOP))
+                       continue;
 
-       return ret;
+               drv->bctimer = 1;
+               break;
+       }
+
+       return 0;
 }
 
-int cpuidle_register_cpu_driver(struct cpuidle_driver *drv, int cpu)
+/**
+ * __cpuidle_register_driver: register the driver
+ * @drv: a valid pointer to a struct cpuidle_driver
+ *
+ * Do some sanity checks, initialize the driver, assign the driver to the
+ * global cpuidle driver variable(s) and set up the broadcast timer if the
+ * cpuidle driver has some states that shut down the local timer.
+ *
+ * Returns 0 on success, a negative error code otherwise:
+ *  * -EINVAL if the driver pointer is NULL or no idle states are available
+ *  * -ENODEV if the cpuidle framework is disabled
+ *  * -EBUSY if the driver is already assigned to the global variable(s)
+ */
+static int __cpuidle_register_driver(struct cpuidle_driver *drv)
 {
        int ret;
 
-       spin_lock(&cpuidle_driver_lock);
-       ret = __cpuidle_register_driver(drv, cpu);
-       spin_unlock(&cpuidle_driver_lock);
+       if (!drv || !drv->state_count)
+               return -EINVAL;
 
-       return ret;
-}
+       if (cpuidle_disabled())
+               return -ENODEV;
 
-void cpuidle_unregister_cpu_driver(struct cpuidle_driver *drv, int cpu)
-{
-       spin_lock(&cpuidle_driver_lock);
-       __cpuidle_unregister_driver(drv, cpu);
-       spin_unlock(&cpuidle_driver_lock);
-}
+       ret = __cpuidle_driver_init(drv);
+       if (ret)
+               return ret;
 
-/**
- * cpuidle_register_driver - registers a driver
- * @drv: the driver
- */
-int cpuidle_register_driver(struct cpuidle_driver *drv)
-{
-       int ret;
+       ret = __cpuidle_set_driver(drv);
+       if (ret)
+               return ret;
 
-       spin_lock(&cpuidle_driver_lock);
-       ret = __cpuidle_register_all_cpu_driver(drv);
-       spin_unlock(&cpuidle_driver_lock);
+       if (drv->bctimer)
+               on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
+                                (void *)CLOCK_EVT_NOTIFY_BROADCAST_ON, 1);
 
-       return ret;
+       return 0;
 }
-EXPORT_SYMBOL_GPL(cpuidle_register_driver);
 
 /**
- * cpuidle_unregister_driver - unregisters a driver
- * @drv: the driver
+ * __cpuidle_unregister_driver - unregister the driver
+ * @drv: a valid pointer to a struct cpuidle_driver
+ *
+ * Check if the driver is no longer in use, reset the global cpuidle driver
+ * variable(s) and disable the timer broadcast notification mechanism if it was
+ * in use.
+ *
  */
-void cpuidle_unregister_driver(struct cpuidle_driver *drv)
+static void __cpuidle_unregister_driver(struct cpuidle_driver *drv)
 {
-       spin_lock(&cpuidle_driver_lock);
-       __cpuidle_unregister_all_cpu_driver(drv);
-       spin_unlock(&cpuidle_driver_lock);
-}
-EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
-
-#else
-
-static struct cpuidle_driver *cpuidle_curr_driver;
+       if (WARN_ON(drv->refcnt > 0))
+               return;
 
-static inline void __cpuidle_set_cpu_driver(struct cpuidle_driver *drv, int cpu)
-{
-       cpuidle_curr_driver = drv;
-}
+       if (drv->bctimer) {
+               drv->bctimer = 0;
+               on_each_cpu_mask(drv->cpumask, cpuidle_setup_broadcast_timer,
+                                (void *)CLOCK_EVT_NOTIFY_BROADCAST_OFF, 1);
+       }
 
-static inline struct cpuidle_driver *__cpuidle_get_cpu_driver(int cpu)
-{
-       return cpuidle_curr_driver;
+       __cpuidle_unset_driver(drv);
 }
 
 /**
  * cpuidle_register_driver - registers a driver
- * @drv: the driver
+ * @drv: a pointer to a valid struct cpuidle_driver
+ *
+ * Register the driver under a lock to prevent concurrent attempts to
+ * [un]register the driver from occuring at the same time.
+ *
+ * Returns 0 on success, a negative error code (returned by
+ * __cpuidle_register_driver()) otherwise.
  */
 int cpuidle_register_driver(struct cpuidle_driver *drv)
 {
-       int ret, cpu;
+       int ret;
 
-       cpu = get_cpu();
        spin_lock(&cpuidle_driver_lock);
-       ret = __cpuidle_register_driver(drv, cpu);
+       ret = __cpuidle_register_driver(drv);
        spin_unlock(&cpuidle_driver_lock);
-       put_cpu();
 
        return ret;
 }
@@ -201,23 +268,24 @@ EXPORT_SYMBOL_GPL(cpuidle_register_driver);
 
 /**
  * cpuidle_unregister_driver - unregisters a driver
- * @drv: the driver
+ * @drv: a pointer to a valid struct cpuidle_driver
+ *
+ * Unregisters the cpuidle driver under a lock to prevent concurrent attempts
+ * to [un]register the driver from occuring at the same time.  @drv has to
+ * match the currently registered driver.
  */
 void cpuidle_unregister_driver(struct cpuidle_driver *drv)
 {
-       int cpu;
-
-       cpu = get_cpu();
        spin_lock(&cpuidle_driver_lock);
-       __cpuidle_unregister_driver(drv, cpu);
+       __cpuidle_unregister_driver(drv);
        spin_unlock(&cpuidle_driver_lock);
-       put_cpu();
 }
 EXPORT_SYMBOL_GPL(cpuidle_unregister_driver);
-#endif
 
 /**
- * cpuidle_get_driver - return the current driver
+ * cpuidle_get_driver - return the driver tied to the current CPU.
+ *
+ * Returns a struct cpuidle_driver pointer, or NULL if no driver is registered.
  */
 struct cpuidle_driver *cpuidle_get_driver(void)
 {
@@ -233,7 +301,11 @@ struct cpuidle_driver *cpuidle_get_driver(void)
 EXPORT_SYMBOL_GPL(cpuidle_get_driver);
 
 /**
- * cpuidle_get_cpu_driver - return the driver tied with a cpu
+ * cpuidle_get_cpu_driver - return the driver registered for a CPU.
+ * @dev: a valid pointer to a struct cpuidle_device
+ *
+ * Returns a struct cpuidle_driver pointer, or NULL if no driver is registered
+ * for the CPU associated with @dev.
  */
 struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev)
 {
@@ -244,6 +316,14 @@ struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev)
 }
 EXPORT_SYMBOL_GPL(cpuidle_get_cpu_driver);
 
+/**
+ * cpuidle_driver_ref - get a reference to the driver.
+ *
+ * Increment the reference counter of the cpuidle driver associated with
+ * the current CPU.
+ *
+ * Returns a pointer to the driver, or NULL if the current CPU has no driver.
+ */
 struct cpuidle_driver *cpuidle_driver_ref(void)
 {
        struct cpuidle_driver *drv;
@@ -257,6 +337,12 @@ struct cpuidle_driver *cpuidle_driver_ref(void)
        return drv;
 }
 
+/**
+ * cpuidle_driver_unref - puts down the refcount for the driver
+ *
+ * Decrement the reference counter of the cpuidle driver associated with
+ * the current CPU.
+ */
 void cpuidle_driver_unref(void)
 {
        struct cpuidle_driver *drv = cpuidle_get_driver();
index 0f079be133051540c62d8c83d03579e132f7d6bd..31f3adba4cf3f15a693e0f3ae40d921e53a576c5 100644 (file)
@@ -67,7 +67,7 @@ comment "DEVFREQ Drivers"
 
 config ARM_EXYNOS4_BUS_DEVFREQ
        bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver"
-       depends on CPU_EXYNOS4210 || CPU_EXYNOS4212 || CPU_EXYNOS4412
+       depends on CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412
        select ARCH_HAS_OPP
        select DEVFREQ_GOV_SIMPLE_ONDEMAND
        help
@@ -78,4 +78,14 @@ config ARM_EXYNOS4_BUS_DEVFREQ
          To operate with optimal voltages, ASV support is required
          (CONFIG_EXYNOS_ASV).
 
+config ARM_EXYNOS5_BUS_DEVFREQ
+       bool "ARM Exynos5250 Bus DEVFREQ Driver"
+       depends on SOC_EXYNOS5250
+       select ARCH_HAS_OPP
+       select DEVFREQ_GOV_SIMPLE_ONDEMAND
+       help
+         This adds the DEVFREQ driver for Exynos5250 bus interface (vdd_int).
+         It reads PPMU counters of memory controllers and adjusts the
+         operating frequencies and voltages with OPP support.
+
 endif # PM_DEVFREQ
index 8c464234f7e729155c291d9ad7f15b1883655623..16138c9e0d587595f24d9d61535714e1b788d5cd 100644 (file)
@@ -5,4 +5,5 @@ obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE)     += governor_powersave.o
 obj-$(CONFIG_DEVFREQ_GOV_USERSPACE)    += governor_userspace.o
 
 # DEVFREQ Drivers
-obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)  += exynos4_bus.o
+obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)  += exynos/
+obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ)  += exynos/
index 3b367973a8028c5d1cd32bd823bcf9e005d269b6..44c407986f647bfe9fec6fcfd35395907f56d611 100644 (file)
@@ -271,6 +271,7 @@ void devfreq_monitor_suspend(struct devfreq *devfreq)
                return;
        }
 
+       devfreq_update_status(devfreq, devfreq->previous_freq);
        devfreq->stop_polling = true;
        mutex_unlock(&devfreq->lock);
        cancel_delayed_work_sync(&devfreq->work);
@@ -287,6 +288,8 @@ EXPORT_SYMBOL(devfreq_monitor_suspend);
  */
 void devfreq_monitor_resume(struct devfreq *devfreq)
 {
+       unsigned long freq;
+
        mutex_lock(&devfreq->lock);
        if (!devfreq->stop_polling)
                goto out;
@@ -295,8 +298,14 @@ void devfreq_monitor_resume(struct devfreq *devfreq)
                        devfreq->profile->polling_ms)
                queue_delayed_work(devfreq_wq, &devfreq->work,
                        msecs_to_jiffies(devfreq->profile->polling_ms));
+
+       devfreq->last_stat_updated = jiffies;
        devfreq->stop_polling = false;
 
+       if (devfreq->profile->get_cur_freq &&
+               !devfreq->profile->get_cur_freq(devfreq->dev.parent, &freq))
+               devfreq->previous_freq = freq;
+
 out:
        mutex_unlock(&devfreq->lock);
 }
@@ -518,6 +527,8 @@ EXPORT_SYMBOL(devfreq_add_device);
 /**
  * devfreq_remove_device() - Remove devfreq feature from a device.
  * @devfreq:   the devfreq instance to be removed
+ *
+ * The opposite of devfreq_add_device().
  */
 int devfreq_remove_device(struct devfreq *devfreq)
 {
@@ -533,6 +544,10 @@ EXPORT_SYMBOL(devfreq_remove_device);
 /**
  * devfreq_suspend_device() - Suspend devfreq of a device.
  * @devfreq: the devfreq instance to be suspended
+ *
+ * This function is intended to be called by the pm callbacks
+ * (e.g., runtime_suspend, suspend) of the device driver that
+ * holds the devfreq.
  */
 int devfreq_suspend_device(struct devfreq *devfreq)
 {
@@ -550,6 +565,10 @@ EXPORT_SYMBOL(devfreq_suspend_device);
 /**
  * devfreq_resume_device() - Resume devfreq of a device.
  * @devfreq: the devfreq instance to be resumed
+ *
+ * This function is intended to be called by the pm callbacks
+ * (e.g., runtime_resume, resume) of the device driver that
+ * holds the devfreq.
  */
 int devfreq_resume_device(struct devfreq *devfreq)
 {
@@ -905,11 +924,11 @@ static ssize_t show_trans_table(struct device *dev, struct device_attribute *att
 {
        struct devfreq *devfreq = to_devfreq(dev);
        ssize_t len;
-       int i, j, err;
+       int i, j;
        unsigned int max_state = devfreq->profile->max_state;
 
-       err = devfreq_update_status(devfreq, devfreq->previous_freq);
-       if (err)
+       if (!devfreq->stop_polling &&
+                       devfreq_update_status(devfreq, devfreq->previous_freq))
                return 0;
 
        len = sprintf(buf, "   From  :   To\n");
diff --git a/drivers/devfreq/exynos/Makefile b/drivers/devfreq/exynos/Makefile
new file mode 100644 (file)
index 0000000..bfaaf5b
--- /dev/null
@@ -0,0 +1,3 @@
+# Exynos DEVFREQ Drivers
+obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ)  += exynos4_bus.o
+obj-$(CONFIG_ARM_EXYNOS5_BUS_DEVFREQ)  += exynos_ppmu.o exynos5_bus.o
similarity index 99%
rename from drivers/devfreq/exynos4_bus.c
rename to drivers/devfreq/exynos/exynos4_bus.c
index 3f37f3b3f2689bd76438d6ac5e079ce26b433642..c5f86d8caca34c6a7a3ea2341da5c242ddf41c83 100644 (file)
@@ -974,6 +974,7 @@ static int exynos4_busfreq_pm_notifier_event(struct notifier_block *this,
                        rcu_read_unlock();
                        dev_err(data->dev, "%s: unable to find a min freq\n",
                                __func__);
+                       mutex_unlock(&data->lock);
                        return PTR_ERR(opp);
                }
                new_oppinfo.rate = opp_get_freq(opp);
diff --git a/drivers/devfreq/exynos/exynos5_bus.c b/drivers/devfreq/exynos/exynos5_bus.c
new file mode 100644 (file)
index 0000000..574b16b
--- /dev/null
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * EXYNOS5 INT clock frequency scaling support using DEVFREQ framework
+ * Based on work done by Jonghwan Choi <jhbird.choi@samsung.com>
+ * Support for only EXYNOS5250 is present.
+ *
+ * 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/module.h>
+#include <linux/devfreq.h>
+#include <linux/io.h>
+#include <linux/opp.h>
+#include <linux/slab.h>
+#include <linux/suspend.h>
+#include <linux/opp.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/pm_qos.h>
+#include <linux/regulator/consumer.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+
+#include "exynos_ppmu.h"
+
+#define MAX_SAFEVOLT                   1100000 /* 1.10V */
+/* Assume that the bus is saturated if the utilization is 25% */
+#define INT_BUS_SATURATION_RATIO       25
+
+enum int_level_idx {
+       LV_0,
+       LV_1,
+       LV_2,
+       LV_3,
+       LV_4,
+       _LV_END
+};
+
+enum exynos_ppmu_list {
+       PPMU_RIGHT,
+       PPMU_END,
+};
+
+struct busfreq_data_int {
+       struct device *dev;
+       struct devfreq *devfreq;
+       struct regulator *vdd_int;
+       struct exynos_ppmu ppmu[PPMU_END];
+       unsigned long curr_freq;
+       bool disabled;
+
+       struct notifier_block pm_notifier;
+       struct mutex lock;
+       struct pm_qos_request int_req;
+       struct clk *int_clk;
+};
+
+struct int_bus_opp_table {
+       unsigned int idx;
+       unsigned long clk;
+       unsigned long volt;
+};
+
+static struct int_bus_opp_table exynos5_int_opp_table[] = {
+       {LV_0, 266000, 1025000},
+       {LV_1, 200000, 1025000},
+       {LV_2, 160000, 1025000},
+       {LV_3, 133000, 1025000},
+       {LV_4, 100000, 1025000},
+       {0, 0, 0},
+};
+
+static void busfreq_mon_reset(struct busfreq_data_int *data)
+{
+       unsigned int i;
+
+       for (i = PPMU_RIGHT; i < PPMU_END; i++) {
+               void __iomem *ppmu_base = data->ppmu[i].hw_base;
+
+               /* Reset the performance and cycle counters */
+               exynos_ppmu_reset(ppmu_base);
+
+               /* Setup count registers to monitor read/write transactions */
+               data->ppmu[i].event[PPMU_PMNCNT3] = RDWR_DATA_COUNT;
+               exynos_ppmu_setevent(ppmu_base, PPMU_PMNCNT3,
+                                       data->ppmu[i].event[PPMU_PMNCNT3]);
+
+               exynos_ppmu_start(ppmu_base);
+       }
+}
+
+static void exynos5_read_ppmu(struct busfreq_data_int *data)
+{
+       int i, j;
+
+       for (i = PPMU_RIGHT; i < PPMU_END; i++) {
+               void __iomem *ppmu_base = data->ppmu[i].hw_base;
+
+               exynos_ppmu_stop(ppmu_base);
+
+               /* Update local data from PPMU */
+               data->ppmu[i].ccnt = __raw_readl(ppmu_base + PPMU_CCNT);
+
+               for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
+                       if (data->ppmu[i].event[j] == 0)
+                               data->ppmu[i].count[j] = 0;
+                       else
+                               data->ppmu[i].count[j] =
+                                       exynos_ppmu_read(ppmu_base, j);
+               }
+       }
+
+       busfreq_mon_reset(data);
+}
+
+static int exynos5_int_setvolt(struct busfreq_data_int *data,
+                               unsigned long volt)
+{
+       return regulator_set_voltage(data->vdd_int, volt, MAX_SAFEVOLT);
+}
+
+static int exynos5_busfreq_int_target(struct device *dev, unsigned long *_freq,
+                             u32 flags)
+{
+       int err = 0;
+       struct platform_device *pdev = container_of(dev, struct platform_device,
+                                                   dev);
+       struct busfreq_data_int *data = platform_get_drvdata(pdev);
+       struct opp *opp;
+       unsigned long old_freq, freq;
+       unsigned long volt;
+
+       rcu_read_lock();
+       opp = devfreq_recommended_opp(dev, _freq, flags);
+       if (IS_ERR(opp)) {
+               rcu_read_unlock();
+               dev_err(dev, "%s: Invalid OPP.\n", __func__);
+               return PTR_ERR(opp);
+       }
+
+       freq = opp_get_freq(opp);
+       volt = opp_get_voltage(opp);
+       rcu_read_unlock();
+
+       old_freq = data->curr_freq;
+
+       if (old_freq == freq)
+               return 0;
+
+       dev_dbg(dev, "targetting %lukHz %luuV\n", freq, volt);
+
+       mutex_lock(&data->lock);
+
+       if (data->disabled)
+               goto out;
+
+       if (freq > exynos5_int_opp_table[0].clk)
+               pm_qos_update_request(&data->int_req, freq * 16 / 1000);
+       else
+               pm_qos_update_request(&data->int_req, -1);
+
+       if (old_freq < freq)
+               err = exynos5_int_setvolt(data, volt);
+       if (err)
+               goto out;
+
+       err = clk_set_rate(data->int_clk, freq * 1000);
+
+       if (err)
+               goto out;
+
+       if (old_freq > freq)
+               err = exynos5_int_setvolt(data, volt);
+       if (err)
+               goto out;
+
+       data->curr_freq = freq;
+out:
+       mutex_unlock(&data->lock);
+       return err;
+}
+
+static int exynos5_get_busier_dmc(struct busfreq_data_int *data)
+{
+       int i, j;
+       int busy = 0;
+       unsigned int temp = 0;
+
+       for (i = PPMU_RIGHT; i < PPMU_END; i++) {
+               for (j = PPMU_PMNCNT0; j < PPMU_PMNCNT_MAX; j++) {
+                       if (data->ppmu[i].count[j] > temp) {
+                               temp = data->ppmu[i].count[j];
+                               busy = i;
+                       }
+               }
+       }
+
+       return busy;
+}
+
+static int exynos5_int_get_dev_status(struct device *dev,
+                                     struct devfreq_dev_status *stat)
+{
+       struct platform_device *pdev = container_of(dev, struct platform_device,
+                                                   dev);
+       struct busfreq_data_int *data = platform_get_drvdata(pdev);
+       int busier_dmc;
+
+       exynos5_read_ppmu(data);
+       busier_dmc = exynos5_get_busier_dmc(data);
+
+       stat->current_frequency = data->curr_freq;
+
+       /* Number of cycles spent on memory access */
+       stat->busy_time = data->ppmu[busier_dmc].count[PPMU_PMNCNT3];
+       stat->busy_time *= 100 / INT_BUS_SATURATION_RATIO;
+       stat->total_time = data->ppmu[busier_dmc].ccnt;
+
+       return 0;
+}
+static void exynos5_int_exit(struct device *dev)
+{
+       struct platform_device *pdev = container_of(dev, struct platform_device,
+                                                   dev);
+       struct busfreq_data_int *data = platform_get_drvdata(pdev);
+
+       devfreq_unregister_opp_notifier(dev, data->devfreq);
+}
+
+static struct devfreq_dev_profile exynos5_devfreq_int_profile = {
+       .initial_freq           = 160000,
+       .polling_ms             = 100,
+       .target                 = exynos5_busfreq_int_target,
+       .get_dev_status         = exynos5_int_get_dev_status,
+       .exit                   = exynos5_int_exit,
+};
+
+static int exynos5250_init_int_tables(struct busfreq_data_int *data)
+{
+       int i, err = 0;
+
+       for (i = LV_0; i < _LV_END; i++) {
+               err = opp_add(data->dev, exynos5_int_opp_table[i].clk,
+                               exynos5_int_opp_table[i].volt);
+               if (err) {
+                       dev_err(data->dev, "Cannot add opp entries.\n");
+                       return err;
+               }
+       }
+
+       return 0;
+}
+
+static int exynos5_busfreq_int_pm_notifier_event(struct notifier_block *this,
+               unsigned long event, void *ptr)
+{
+       struct busfreq_data_int *data = container_of(this,
+                                       struct busfreq_data_int, pm_notifier);
+       struct opp *opp;
+       unsigned long maxfreq = ULONG_MAX;
+       unsigned long freq;
+       unsigned long volt;
+       int err = 0;
+
+       switch (event) {
+       case PM_SUSPEND_PREPARE:
+               /* Set Fastest and Deactivate DVFS */
+               mutex_lock(&data->lock);
+
+               data->disabled = true;
+
+               rcu_read_lock();
+               opp = opp_find_freq_floor(data->dev, &maxfreq);
+               if (IS_ERR(opp)) {
+                       rcu_read_unlock();
+                       err = PTR_ERR(opp);
+                       goto unlock;
+               }
+               freq = opp_get_freq(opp);
+               volt = opp_get_voltage(opp);
+               rcu_read_unlock();
+
+               err = exynos5_int_setvolt(data, volt);
+               if (err)
+                       goto unlock;
+
+               err = clk_set_rate(data->int_clk, freq * 1000);
+
+               if (err)
+                       goto unlock;
+
+               data->curr_freq = freq;
+unlock:
+               mutex_unlock(&data->lock);
+               if (err)
+                       return NOTIFY_BAD;
+               return NOTIFY_OK;
+       case PM_POST_RESTORE:
+       case PM_POST_SUSPEND:
+               /* Reactivate */
+               mutex_lock(&data->lock);
+               data->disabled = false;
+               mutex_unlock(&data->lock);
+               return NOTIFY_OK;
+       }
+
+       return NOTIFY_DONE;
+}
+
+static int exynos5_busfreq_int_probe(struct platform_device *pdev)
+{
+       struct busfreq_data_int *data;
+       struct opp *opp;
+       struct device *dev = &pdev->dev;
+       struct device_node *np;
+       unsigned long initial_freq;
+       unsigned long initial_volt;
+       int err = 0;
+       int i;
+
+       data = devm_kzalloc(&pdev->dev, sizeof(struct busfreq_data_int),
+                               GFP_KERNEL);
+       if (data == NULL) {
+               dev_err(dev, "Cannot allocate memory.\n");
+               return -ENOMEM;
+       }
+
+       np = of_find_compatible_node(NULL, NULL, "samsung,exynos5250-ppmu");
+       if (np == NULL) {
+               pr_err("Unable to find PPMU node\n");
+               return -ENOENT;
+       }
+
+       for (i = PPMU_RIGHT; i < PPMU_END; i++) {
+               /* map PPMU memory region */
+               data->ppmu[i].hw_base = of_iomap(np, i);
+               if (data->ppmu[i].hw_base == NULL) {
+                       dev_err(&pdev->dev, "failed to map memory region\n");
+                       return -ENOMEM;
+               }
+       }
+       data->pm_notifier.notifier_call = exynos5_busfreq_int_pm_notifier_event;
+       data->dev = dev;
+       mutex_init(&data->lock);
+
+       err = exynos5250_init_int_tables(data);
+       if (err)
+               goto err_regulator;
+
+       data->vdd_int = regulator_get(dev, "vdd_int");
+       if (IS_ERR(data->vdd_int)) {
+               dev_err(dev, "Cannot get the regulator \"vdd_int\"\n");
+               err = PTR_ERR(data->vdd_int);
+               goto err_regulator;
+       }
+
+       data->int_clk = clk_get(dev, "int_clk");
+       if (IS_ERR(data->int_clk)) {
+               dev_err(dev, "Cannot get clock \"int_clk\"\n");
+               err = PTR_ERR(data->int_clk);
+               goto err_clock;
+       }
+
+       rcu_read_lock();
+       opp = opp_find_freq_floor(dev,
+                       &exynos5_devfreq_int_profile.initial_freq);
+       if (IS_ERR(opp)) {
+               rcu_read_unlock();
+               dev_err(dev, "Invalid initial frequency %lu kHz.\n",
+                      exynos5_devfreq_int_profile.initial_freq);
+               err = PTR_ERR(opp);
+               goto err_opp_add;
+       }
+       initial_freq = opp_get_freq(opp);
+       initial_volt = opp_get_voltage(opp);
+       rcu_read_unlock();
+       data->curr_freq = initial_freq;
+
+       err = clk_set_rate(data->int_clk, initial_freq * 1000);
+       if (err) {
+               dev_err(dev, "Failed to set initial frequency\n");
+               goto err_opp_add;
+       }
+
+       err = exynos5_int_setvolt(data, initial_volt);
+       if (err)
+               goto err_opp_add;
+
+       platform_set_drvdata(pdev, data);
+
+       busfreq_mon_reset(data);
+
+       data->devfreq = devfreq_add_device(dev, &exynos5_devfreq_int_profile,
+                                          "simple_ondemand", NULL);
+
+       if (IS_ERR(data->devfreq)) {
+               err = PTR_ERR(data->devfreq);
+               goto err_devfreq_add;
+       }
+
+       devfreq_register_opp_notifier(dev, data->devfreq);
+
+       err = register_pm_notifier(&data->pm_notifier);
+       if (err) {
+               dev_err(dev, "Failed to setup pm notifier\n");
+               goto err_devfreq_add;
+       }
+
+       /* TODO: Add a new QOS class for int/mif bus */
+       pm_qos_add_request(&data->int_req, PM_QOS_NETWORK_THROUGHPUT, -1);
+
+       return 0;
+
+err_devfreq_add:
+       devfreq_remove_device(data->devfreq);
+       platform_set_drvdata(pdev, NULL);
+err_opp_add:
+       clk_put(data->int_clk);
+err_clock:
+       regulator_put(data->vdd_int);
+err_regulator:
+       return err;
+}
+
+static int exynos5_busfreq_int_remove(struct platform_device *pdev)
+{
+       struct busfreq_data_int *data = platform_get_drvdata(pdev);
+
+       pm_qos_remove_request(&data->int_req);
+       unregister_pm_notifier(&data->pm_notifier);
+       devfreq_remove_device(data->devfreq);
+       regulator_put(data->vdd_int);
+       clk_put(data->int_clk);
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+static int exynos5_busfreq_int_resume(struct device *dev)
+{
+       struct platform_device *pdev = container_of(dev, struct platform_device,
+                                                   dev);
+       struct busfreq_data_int *data = platform_get_drvdata(pdev);
+
+       busfreq_mon_reset(data);
+       return 0;
+}
+
+static const struct dev_pm_ops exynos5_busfreq_int_pm = {
+       .resume = exynos5_busfreq_int_resume,
+};
+
+/* platform device pointer for exynos5 devfreq device. */
+static struct platform_device *exynos5_devfreq_pdev;
+
+static struct platform_driver exynos5_busfreq_int_driver = {
+       .probe          = exynos5_busfreq_int_probe,
+       .remove         = exynos5_busfreq_int_remove,
+       .driver         = {
+               .name           = "exynos5-bus-int",
+               .owner          = THIS_MODULE,
+               .pm             = &exynos5_busfreq_int_pm,
+       },
+};
+
+static int __init exynos5_busfreq_int_init(void)
+{
+       int ret;
+
+       ret = platform_driver_register(&exynos5_busfreq_int_driver);
+       if (ret < 0)
+               goto out;
+
+       exynos5_devfreq_pdev =
+               platform_device_register_simple("exynos5-bus-int", -1, NULL, 0);
+       if (IS_ERR_OR_NULL(exynos5_devfreq_pdev)) {
+               ret = PTR_ERR(exynos5_devfreq_pdev);
+               goto out1;
+       }
+
+       return 0;
+out1:
+       platform_driver_unregister(&exynos5_busfreq_int_driver);
+out:
+       return ret;
+}
+late_initcall(exynos5_busfreq_int_init);
+
+static void __exit exynos5_busfreq_int_exit(void)
+{
+       platform_device_unregister(exynos5_devfreq_pdev);
+       platform_driver_unregister(&exynos5_busfreq_int_driver);
+}
+module_exit(exynos5_busfreq_int_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("EXYNOS5 busfreq driver with devfreq framework");
diff --git a/drivers/devfreq/exynos/exynos_ppmu.c b/drivers/devfreq/exynos/exynos_ppmu.c
new file mode 100644 (file)
index 0000000..85fc5ac
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * EXYNOS - PPMU support
+ *
+ * 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/kernel.h>
+#include <linux/types.h>
+#include <linux/io.h>
+
+#include "exynos_ppmu.h"
+
+void exynos_ppmu_reset(void __iomem *ppmu_base)
+{
+       __raw_writel(PPMU_CYCLE_RESET | PPMU_COUNTER_RESET, ppmu_base);
+       __raw_writel(PPMU_ENABLE_CYCLE  |
+                    PPMU_ENABLE_COUNT0 |
+                    PPMU_ENABLE_COUNT1 |
+                    PPMU_ENABLE_COUNT2 |
+                    PPMU_ENABLE_COUNT3,
+                    ppmu_base + PPMU_CNTENS);
+}
+
+void exynos_ppmu_setevent(void __iomem *ppmu_base, unsigned int ch,
+                       unsigned int evt)
+{
+       __raw_writel(evt, ppmu_base + PPMU_BEVTSEL(ch));
+}
+
+void exynos_ppmu_start(void __iomem *ppmu_base)
+{
+       __raw_writel(PPMU_ENABLE, ppmu_base);
+}
+
+void exynos_ppmu_stop(void __iomem *ppmu_base)
+{
+       __raw_writel(PPMU_DISABLE, ppmu_base);
+}
+
+unsigned int exynos_ppmu_read(void __iomem *ppmu_base, unsigned int ch)
+{
+       unsigned int total;
+
+       if (ch == PPMU_PMNCNT3)
+               total = ((__raw_readl(ppmu_base + PMCNT_OFFSET(ch)) << 8) |
+                         __raw_readl(ppmu_base + PMCNT_OFFSET(ch + 1)));
+       else
+               total = __raw_readl(ppmu_base + PMCNT_OFFSET(ch));
+
+       return total;
+}
diff --git a/drivers/devfreq/exynos/exynos_ppmu.h b/drivers/devfreq/exynos/exynos_ppmu.h
new file mode 100644 (file)
index 0000000..7dfb221
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *             http://www.samsung.com/
+ *
+ * EXYNOS PPMU header
+ *
+ * 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.
+*/
+
+#ifndef __DEVFREQ_EXYNOS_PPMU_H
+#define __DEVFREQ_EXYNOS_PPMU_H __FILE__
+
+#include <linux/ktime.h>
+
+/* For PPMU Control */
+#define PPMU_ENABLE             BIT(0)
+#define PPMU_DISABLE            0x0
+#define PPMU_CYCLE_RESET        BIT(1)
+#define PPMU_COUNTER_RESET      BIT(2)
+
+#define PPMU_ENABLE_COUNT0      BIT(0)
+#define PPMU_ENABLE_COUNT1      BIT(1)
+#define PPMU_ENABLE_COUNT2      BIT(2)
+#define PPMU_ENABLE_COUNT3      BIT(3)
+#define PPMU_ENABLE_CYCLE       BIT(31)
+
+#define PPMU_CNTENS            0x10
+#define PPMU_FLAG              0x50
+#define PPMU_CCNT_OVERFLOW     BIT(31)
+#define PPMU_CCNT              0x100
+
+#define PPMU_PMCNT0            0x110
+#define PPMU_PMCNT_OFFSET      0x10
+#define PMCNT_OFFSET(x)                (PPMU_PMCNT0 + (PPMU_PMCNT_OFFSET * x))
+
+#define PPMU_BEVT0SEL          0x1000
+#define PPMU_BEVTSEL_OFFSET    0x100
+#define PPMU_BEVTSEL(x)                (PPMU_BEVT0SEL + (ch * PPMU_BEVTSEL_OFFSET))
+
+/* For Event Selection */
+#define RD_DATA_COUNT          0x5
+#define WR_DATA_COUNT          0x6
+#define RDWR_DATA_COUNT                0x7
+
+enum ppmu_counter {
+       PPMU_PMNCNT0,
+       PPMU_PMCCNT1,
+       PPMU_PMNCNT2,
+       PPMU_PMNCNT3,
+       PPMU_PMNCNT_MAX,
+};
+
+struct bus_opp_table {
+       unsigned int idx;
+       unsigned long clk;
+       unsigned long volt;
+};
+
+struct exynos_ppmu {
+       void __iomem *hw_base;
+       unsigned int ccnt;
+       unsigned int event[PPMU_PMNCNT_MAX];
+       unsigned int count[PPMU_PMNCNT_MAX];
+       unsigned long long ns;
+       ktime_t reset_time;
+       bool ccnt_overflow;
+       bool count_overflow[PPMU_PMNCNT_MAX];
+};
+
+void exynos_ppmu_reset(void __iomem *ppmu_base);
+void exynos_ppmu_setevent(void __iomem *ppmu_base, unsigned int ch,
+                       unsigned int evt);
+void exynos_ppmu_start(void __iomem *ppmu_base);
+void exynos_ppmu_stop(void __iomem *ppmu_base);
+unsigned int exynos_ppmu_read(void __iomem *ppmu_base, unsigned int ch);
+#endif /* __DEVFREQ_EXYNOS_PPMU_H */
index a0de82e21a7c30d00f122071783c9280583990f4..a975ebebea8aaf9b8950497eefdcaf3793d930d2 100644 (file)
@@ -1405,7 +1405,7 @@ static int dma_runtime_idle(struct device *dev)
                        return -EAGAIN;
        }
 
-       return pm_schedule_suspend(dev, 0);
+       return 0;
 }
 
 /******************************************************************************
index 62ef10a641c4250b273263c78e51bd2534ed632a..89d0d2a3b1bb62289a6c9a862abc19f98ad30097 100644 (file)
@@ -305,11 +305,7 @@ static const struct irq_domain_ops lnw_gpio_irq_ops = {
 
 static int lnw_gpio_runtime_idle(struct device *dev)
 {
-       int err = pm_schedule_suspend(dev, 500);
-
-       if (!err)
-               return 0;
-
+       pm_schedule_suspend(dev, 500);
        return -EBUSY;
 }
 
index 48e31ed69dbf159f5e44f2ab2a4968896320c3eb..f32ca293ae0e30674a436afb4bc431cdb743de28 100644 (file)
@@ -435,7 +435,7 @@ static const struct dev_pm_ops i2c_device_pm_ops = {
        SET_RUNTIME_PM_OPS(
                pm_generic_runtime_suspend,
                pm_generic_runtime_resume,
-               pm_generic_runtime_idle
+               NULL
        )
 };
 
index 13f7866de46eb21a4cdf0363f0386d315f8171dd..3598b0ecf8c74c3c9a3377379bb20a4b9f70fa36 100644 (file)
@@ -886,12 +886,6 @@ static int ab8500_gpadc_runtime_resume(struct device *dev)
        return ret;
 }
 
-static int ab8500_gpadc_runtime_idle(struct device *dev)
-{
-       pm_runtime_suspend(dev);
-       return 0;
-}
-
 static int ab8500_gpadc_suspend(struct device *dev)
 {
        struct ab8500_gpadc *gpadc = dev_get_drvdata(dev);
@@ -1039,7 +1033,7 @@ static int ab8500_gpadc_remove(struct platform_device *pdev)
 static const struct dev_pm_ops ab8500_gpadc_pm_ops = {
        SET_RUNTIME_PM_OPS(ab8500_gpadc_runtime_suspend,
                           ab8500_gpadc_runtime_resume,
-                          ab8500_gpadc_runtime_idle)
+                          NULL)
        SET_SYSTEM_SLEEP_PM_OPS(ab8500_gpadc_suspend,
                                ab8500_gpadc_resume)
 
index e219c97a02a416e2439f6640093ac29de4e5d371..9d5c7112557640623b839029498aba8fc47c4f7c 100644 (file)
@@ -164,7 +164,7 @@ static int mmc_runtime_resume(struct device *dev)
 
 static int mmc_runtime_idle(struct device *dev)
 {
-       return pm_runtime_suspend(dev);
+       return 0;
 }
 
 #endif /* !CONFIG_PM_RUNTIME */
index 546c67c2bbbf14aacfe6c3a2d3a8d66037705c1d..6d67492a9247b14f0ed07c2c2f9373bf0be7cdcd 100644 (file)
@@ -211,7 +211,7 @@ static const struct dev_pm_ops sdio_bus_pm_ops = {
        SET_RUNTIME_PM_OPS(
                pm_generic_runtime_suspend,
                pm_generic_runtime_resume,
-               pm_generic_runtime_idle
+               NULL
        )
 };
 
index 716aa93fff76437ab0038de385d7c4fa7ec04834..59df8575a48ce834fb48ea002689ed97ed9ca51a 100644 (file)
@@ -61,6 +61,7 @@ static DEFINE_MUTEX(bridge_mutex);
 static void handle_hotplug_event_bridge (acpi_handle, u32, void *);
 static void acpiphp_sanitize_bus(struct pci_bus *bus);
 static void acpiphp_set_hpp_values(struct pci_bus *bus);
+static void hotplug_event_func(acpi_handle handle, u32 type, void *context);
 static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *context);
 static void free_bridge(struct kref *kref);
 
@@ -147,7 +148,7 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val,
 
 
 static const struct acpi_dock_ops acpiphp_dock_ops = {
-       .handler = handle_hotplug_event_func,
+       .handler = hotplug_event_func,
 };
 
 /* Check whether the PCI device is managed by native PCIe hotplug driver */
@@ -179,6 +180,20 @@ static bool device_is_managed_by_native_pciehp(struct pci_dev *pdev)
        return true;
 }
 
+static void acpiphp_dock_init(void *data)
+{
+       struct acpiphp_func *func = data;
+
+       get_bridge(func->slot->bridge);
+}
+
+static void acpiphp_dock_release(void *data)
+{
+       struct acpiphp_func *func = data;
+
+       put_bridge(func->slot->bridge);
+}
+
 /* callback routine to register each ACPI PCI slot object */
 static acpi_status
 register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
@@ -298,7 +313,8 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv)
                 */
                newfunc->flags &= ~FUNC_HAS_EJ0;
                if (register_hotplug_dock_device(handle,
-                       &acpiphp_dock_ops, newfunc))
+                       &acpiphp_dock_ops, newfunc,
+                       acpiphp_dock_init, acpiphp_dock_release))
                        dbg("failed to register dock device\n");
 
                /* we need to be notified when dock events happen
@@ -670,6 +686,7 @@ static int __ref enable_device(struct acpiphp_slot *slot)
        struct pci_bus *bus = slot->bridge->pci_bus;
        struct acpiphp_func *func;
        int num, max, pass;
+       LIST_HEAD(add_list);
 
        if (slot->flags & SLOT_ENABLED)
                goto err_exit;
@@ -694,13 +711,15 @@ static int __ref enable_device(struct acpiphp_slot *slot)
                                max = pci_scan_bridge(bus, dev, max, pass);
                                if (pass && dev->subordinate) {
                                        check_hotplug_bridge(slot, dev);
-                                       pci_bus_size_bridges(dev->subordinate);
+                                       pcibios_resource_survey_bus(dev->subordinate);
+                                       __pci_bus_size_bridges(dev->subordinate,
+                                                              &add_list);
                                }
                        }
                }
        }
 
-       pci_bus_assign_resources(bus);
+       __pci_bus_assign_resources(bus, &add_list, NULL);
        acpiphp_sanitize_bus(bus);
        acpiphp_set_hpp_values(bus);
        acpiphp_set_acpi_region(slot);
@@ -1065,22 +1084,12 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type,
        alloc_acpi_hp_work(handle, type, context, _handle_hotplug_event_bridge);
 }
 
-static void _handle_hotplug_event_func(struct work_struct *work)
+static void hotplug_event_func(acpi_handle handle, u32 type, void *context)
 {
-       struct acpiphp_func *func;
+       struct acpiphp_func *func = context;
        char objname[64];
        struct acpi_buffer buffer = { .length = sizeof(objname),
                                      .pointer = objname };
-       struct acpi_hp_work *hp_work;
-       acpi_handle handle;
-       u32 type;
-
-       hp_work = container_of(work, struct acpi_hp_work, work);
-       handle = hp_work->handle;
-       type = hp_work->type;
-       func = (struct acpiphp_func *)hp_work->context;
-
-       acpi_scan_lock_acquire();
 
        acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
 
@@ -1113,6 +1122,18 @@ static void _handle_hotplug_event_func(struct work_struct *work)
                warn("notify_handler: unknown event type 0x%x for %s\n", type, objname);
                break;
        }
+}
+
+static void _handle_hotplug_event_func(struct work_struct *work)
+{
+       struct acpi_hp_work *hp_work;
+       struct acpiphp_func *func;
+
+       hp_work = container_of(work, struct acpi_hp_work, work);
+       func = hp_work->context;
+       acpi_scan_lock_acquire();
+
+       hotplug_event_func(hp_work->handle, hp_work->type, func);
 
        acpi_scan_lock_release();
        kfree(hp_work); /* allocated in handle_hotplug_event_func */
index 79277fb36c6bf7a85b4634df28ff13d1905d703d..e6515e21afa3d7fdccd9edb1cbe68ea97253255c 100644 (file)
@@ -1050,26 +1050,22 @@ static int pci_pm_runtime_idle(struct device *dev)
 {
        struct pci_dev *pci_dev = to_pci_dev(dev);
        const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+       int ret = 0;
 
        /*
         * If pci_dev->driver is not set (unbound), the device should
         * always remain in D0 regardless of the runtime PM status
         */
        if (!pci_dev->driver)
-               goto out;
+               return 0;
 
        if (!pm)
                return -ENOSYS;
 
-       if (pm->runtime_idle) {
-               int ret = pm->runtime_idle(dev);
-               if (ret)
-                       return ret;
-       }
+       if (pm->runtime_idle)
+               ret = pm->runtime_idle(dev);
 
-out:
-       pm_runtime_suspend(dev);
-       return 0;
+       return ret;
 }
 
 #else /* !CONFIG_PM_RUNTIME */
index 68678ed76b0da93114280ae2ec878457159f63c5..d1182c4a754e235b25fb2914d658010d05157756 100644 (file)
@@ -202,6 +202,11 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
                    struct resource *res, unsigned int reg);
 int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type);
 void pci_configure_ari(struct pci_dev *dev);
+void __ref __pci_bus_size_bridges(struct pci_bus *bus,
+                       struct list_head *realloc_head);
+void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
+                                     struct list_head *realloc_head,
+                                     struct list_head *fail_head);
 
 /**
  * pci_ari_enabled - query ARI forwarding status
index 16abaaa1f83caed1009fb04018ece089b0138f26..d254e237953382bb99768c7cca79b65c3b9aded8 100644 (file)
@@ -1044,7 +1044,7 @@ handle_done:
        ;
 }
 
-static void __ref __pci_bus_size_bridges(struct pci_bus *bus,
+void __ref __pci_bus_size_bridges(struct pci_bus *bus,
                        struct list_head *realloc_head)
 {
        struct pci_dev *dev;
@@ -1115,9 +1115,9 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
 }
 EXPORT_SYMBOL(pci_bus_size_bridges);
 
-static void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
-                                        struct list_head *realloc_head,
-                                        struct list_head *fail_head)
+void __ref __pci_bus_assign_resources(const struct pci_bus *bus,
+                                     struct list_head *realloc_head,
+                                     struct list_head *fail_head)
 {
        struct pci_bus *b;
        struct pci_dev *dev;
index 95cebf0185decdd48134892b43f5d45928ab3515..9357aa779048a241e6dafe6bbaa1058b9eabb89f 100644 (file)
@@ -211,6 +211,12 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
        res->start = -1;
        res->end = -1;
 
+       if (!rule->map) {
+               res->flags |= IORESOURCE_DISABLED;
+               pnp_dbg(&dev->dev, "  dma %d disabled\n", idx);
+               goto __add;
+       }
+
        for (i = 0; i < 8; i++) {
                if (rule->map & (1 << xtab[i])) {
                        res->start = res->end = xtab[i];
@@ -218,11 +224,9 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx)
                                goto __add;
                }
        }
-#ifdef MAX_DMA_CHANNELS
-       res->start = res->end = MAX_DMA_CHANNELS;
-#endif
-       res->flags |= IORESOURCE_DISABLED;
-       pnp_dbg(&dev->dev, "  disable dma %d\n", idx);
+
+       pnp_dbg(&dev->dev, "  couldn't assign dma %d\n", idx);
+       return -EBUSY;
 
 __add:
        pnp_add_dma_resource(dev, res->start, res->flags);
index 6b2238bb6a8111d1362ea00733f25787354efad6..db9973bb53f19efbf691bd12c87042b2246a374f 100644 (file)
@@ -27,7 +27,8 @@
 #include <linux/pm_runtime.h>
 #include <linux/power/smartreflex.h>
 
-#define SMARTREFLEX_NAME_LEN   16
+#define DRIVER_NAME    "smartreflex"
+#define SMARTREFLEX_NAME_LEN   32
 #define NVALUE_NAME_LEN                40
 #define SR_DISABLE_TIMEOUT     200
 
@@ -207,12 +208,11 @@ static void sr_stop_vddautocomp(struct omap_sr *sr)
 static int sr_late_init(struct omap_sr *sr_info)
 {
        struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data;
-       struct resource *mem;
        int ret = 0;
 
        if (sr_class->notify && sr_class->notify_flags && sr_info->irq) {
-               ret = request_irq(sr_info->irq, sr_interrupt,
-                                 0, sr_info->name, sr_info);
+               ret = devm_request_irq(&sr_info->pdev->dev, sr_info->irq,
+                                      sr_interrupt, 0, sr_info->name, sr_info);
                if (ret)
                        goto error;
                disable_irq(sr_info->irq);
@@ -224,14 +224,10 @@ static int sr_late_init(struct omap_sr *sr_info)
        return ret;
 
 error:
-       iounmap(sr_info->base);
-       mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
-       release_mem_region(mem->start, resource_size(mem));
        list_del(&sr_info->node);
        dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
                "interrupt handler. Smartreflex will"
                "not function as desired\n", __func__);
-       kfree(sr_info);
 
        return ret;
 }
@@ -341,9 +337,9 @@ static struct omap_sr_nvalue_table *sr_retrieve_nvalue_row(
 /* Public Functions */
 
 /**
- * sr_configure_errgen() - Configures the smrtreflex to perform AVS using the
+ * sr_configure_errgen() - Configures the SmartReflex to perform AVS using the
  *                      error generator module.
- * @voltdm:    VDD pointer to which the SR module to be configured belongs to.
+ * @sr:                        SR module to be configured.
  *
  * This API is to be called from the smartreflex class driver to
  * configure the error generator module inside the smartreflex module.
@@ -352,17 +348,17 @@ static struct omap_sr_nvalue_table *sr_retrieve_nvalue_row(
  * SR CLASS 2 can choose between ERROR module and MINMAXAVG
  * module. Returns 0 on success and error value in case of failure.
  */
-int sr_configure_errgen(struct voltagedomain *voltdm)
+int sr_configure_errgen(struct omap_sr *sr)
 {
        u32 sr_config, sr_errconfig, errconfig_offs;
        u32 vpboundint_en, vpboundint_st;
        u32 senp_en = 0, senn_en = 0;
        u8 senp_shift, senn_shift;
-       struct omap_sr *sr = _sr_lookup(voltdm);
 
-       if (IS_ERR(sr)) {
-               pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
-               return PTR_ERR(sr);
+       if (!sr) {
+               pr_warn("%s: NULL omap_sr from %pF\n", __func__,
+                       (void *)_RET_IP_);
+               return -EINVAL;
        }
 
        if (!sr->clk_length)
@@ -414,22 +410,22 @@ int sr_configure_errgen(struct voltagedomain *voltdm)
 
 /**
  * sr_disable_errgen() - Disables SmartReflex AVS module's errgen component
- * @voltdm:    VDD pointer to which the SR module to be configured belongs to.
+ * @sr:                        SR module to be configured.
  *
  * This API is to be called from the smartreflex class driver to
  * disable the error generator module inside the smartreflex module.
  *
  * Returns 0 on success and error value in case of failure.
  */
-int sr_disable_errgen(struct voltagedomain *voltdm)
+int sr_disable_errgen(struct omap_sr *sr)
 {
        u32 errconfig_offs;
        u32 vpboundint_en, vpboundint_st;
-       struct omap_sr *sr = _sr_lookup(voltdm);
 
-       if (IS_ERR(sr)) {
-               pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
-               return PTR_ERR(sr);
+       if (!sr) {
+               pr_warn("%s: NULL omap_sr from %pF\n", __func__,
+                       (void *)_RET_IP_);
+               return -EINVAL;
        }
 
        switch (sr->ip_type) {
@@ -449,19 +445,24 @@ int sr_disable_errgen(struct voltagedomain *voltdm)
                return -EINVAL;
        }
 
-       /* Disable the interrupts of ERROR module */
-       sr_modify_reg(sr, errconfig_offs, vpboundint_en | vpboundint_st, 0);
-
        /* Disable the Sensor and errorgen */
        sr_modify_reg(sr, SRCONFIG, SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN, 0);
 
+       /*
+        * Disable the interrupts of ERROR module
+        * NOTE: modify is a read, modify,write - an implicit OCP barrier
+        * which is required is present here - sequencing is critical
+        * at this point (after errgen is disabled, vpboundint disable)
+        */
+       sr_modify_reg(sr, errconfig_offs, vpboundint_en | vpboundint_st, 0);
+
        return 0;
 }
 
 /**
- * sr_configure_minmax() - Configures the smrtreflex to perform AVS using the
+ * sr_configure_minmax() - Configures the SmartReflex to perform AVS using the
  *                      minmaxavg module.
- * @voltdm:    VDD pointer to which the SR module to be configured belongs to.
+ * @sr:                        SR module to be configured.
  *
  * This API is to be called from the smartreflex class driver to
  * configure the minmaxavg module inside the smartreflex module.
@@ -470,16 +471,16 @@ int sr_disable_errgen(struct voltagedomain *voltdm)
  * SR CLASS 2 can choose between ERROR module and MINMAXAVG
  * module. Returns 0 on success and error value in case of failure.
  */
-int sr_configure_minmax(struct voltagedomain *voltdm)
+int sr_configure_minmax(struct omap_sr *sr)
 {
        u32 sr_config, sr_avgwt;
        u32 senp_en = 0, senn_en = 0;
        u8 senp_shift, senn_shift;
-       struct omap_sr *sr = _sr_lookup(voltdm);
 
-       if (IS_ERR(sr)) {
-               pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
-               return PTR_ERR(sr);
+       if (!sr) {
+               pr_warn("%s: NULL omap_sr from %pF\n", __func__,
+                       (void *)_RET_IP_);
+               return -EINVAL;
        }
 
        if (!sr->clk_length)
@@ -546,7 +547,7 @@ int sr_configure_minmax(struct voltagedomain *voltdm)
 
 /**
  * sr_enable() - Enables the smartreflex module.
- * @voltdm:    VDD pointer to which the SR module to be configured belongs to.
+ * @sr:                pointer to which the SR module to be configured belongs to.
  * @volt:      The voltage at which the Voltage domain associated with
  *             the smartreflex module is operating at.
  *             This is required only to program the correct Ntarget value.
@@ -555,16 +556,16 @@ int sr_configure_minmax(struct voltagedomain *voltdm)
  * enable a smartreflex module. Returns 0 on success. Returns error
  * value if the voltage passed is wrong or if ntarget value is wrong.
  */
-int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
+int sr_enable(struct omap_sr *sr, unsigned long volt)
 {
        struct omap_volt_data *volt_data;
-       struct omap_sr *sr = _sr_lookup(voltdm);
        struct omap_sr_nvalue_table *nvalue_row;
        int ret;
 
-       if (IS_ERR(sr)) {
-               pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
-               return PTR_ERR(sr);
+       if (!sr) {
+               pr_warn("%s: NULL omap_sr from %pF\n", __func__,
+                       (void *)_RET_IP_);
+               return -EINVAL;
        }
 
        volt_data = omap_voltage_get_voltdata(sr->voltdm, volt);
@@ -606,17 +607,16 @@ int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
 
 /**
  * sr_disable() - Disables the smartreflex module.
- * @voltdm:    VDD pointer to which the SR module to be configured belongs to.
+ * @sr:                pointer to which the SR module to be configured belongs to.
  *
  * This API is to be called from the smartreflex class driver to
  * disable a smartreflex module.
  */
-void sr_disable(struct voltagedomain *voltdm)
+void sr_disable(struct omap_sr *sr)
 {
-       struct omap_sr *sr = _sr_lookup(voltdm);
-
-       if (IS_ERR(sr)) {
-               pr_warning("%s: omap_sr struct for voltdm not found\n", __func__);
+       if (!sr) {
+               pr_warn("%s: NULL omap_sr from %pF\n", __func__,
+                       (void *)_RET_IP_);
                return;
        }
 
@@ -847,34 +847,33 @@ static int __init omap_sr_probe(struct platform_device *pdev)
        struct dentry *nvalue_dir;
        int i, ret = 0;
 
-       sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
+       sr_info = devm_kzalloc(&pdev->dev, sizeof(struct omap_sr), GFP_KERNEL);
        if (!sr_info) {
                dev_err(&pdev->dev, "%s: unable to allocate sr_info\n",
                        __func__);
                return -ENOMEM;
        }
 
+       sr_info->name = devm_kzalloc(&pdev->dev,
+                                    SMARTREFLEX_NAME_LEN, GFP_KERNEL);
+       if (!sr_info->name) {
+               dev_err(&pdev->dev, "%s: unable to allocate SR instance name\n",
+                       __func__);
+               return -ENOMEM;
+       }
+
        platform_set_drvdata(pdev, sr_info);
 
        if (!pdata) {
                dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
-               ret = -EINVAL;
-               goto err_free_devinfo;
+               return -EINVAL;
        }
 
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!mem) {
-               dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
-               ret = -ENODEV;
-               goto err_free_devinfo;
-       }
-
-       mem = request_mem_region(mem->start, resource_size(mem),
-                                       dev_name(&pdev->dev));
-       if (!mem) {
-               dev_err(&pdev->dev, "%s: no mem region\n", __func__);
-               ret = -EBUSY;
-               goto err_free_devinfo;
+       sr_info->base = devm_ioremap_resource(&pdev->dev, mem);
+       if (IS_ERR(sr_info->base)) {
+               dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
+               return PTR_ERR(sr_info->base);
        }
 
        irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -882,13 +881,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
        pm_runtime_enable(&pdev->dev);
        pm_runtime_irq_safe(&pdev->dev);
 
-       sr_info->name = kasprintf(GFP_KERNEL, "%s", pdata->name);
-       if (!sr_info->name) {
-               dev_err(&pdev->dev, "%s: Unable to alloc SR instance name\n",
-                       __func__);
-               ret = -ENOMEM;
-               goto err_release_region;
-       }
+       snprintf(sr_info->name, SMARTREFLEX_NAME_LEN, "%s", pdata->name);
 
        sr_info->pdev = pdev;
        sr_info->srid = pdev->id;
@@ -905,13 +898,6 @@ static int __init omap_sr_probe(struct platform_device *pdev)
        sr_info->autocomp_active = false;
        sr_info->ip_type = pdata->ip_type;
 
-       sr_info->base = ioremap(mem->start, resource_size(mem));
-       if (!sr_info->base) {
-               dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
-               ret = -ENOMEM;
-               goto err_free_name;
-       }
-
        if (irq)
                sr_info->irq = irq->start;
 
@@ -927,7 +913,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
                ret = sr_late_init(sr_info);
                if (ret) {
                        pr_warning("%s: Error in SR late init\n", __func__);
-                       goto err_iounmap;
+                       goto err_list_del;
                }
        }
 
@@ -938,7 +924,7 @@ static int __init omap_sr_probe(struct platform_device *pdev)
                        ret = PTR_ERR(sr_dbg_dir);
                        pr_err("%s:sr debugfs dir creation failed(%d)\n",
                                __func__, ret);
-                       goto err_iounmap;
+                       goto err_list_del;
                }
        }
 
@@ -991,16 +977,8 @@ static int __init omap_sr_probe(struct platform_device *pdev)
 
 err_debugfs:
        debugfs_remove_recursive(sr_info->dbg_dir);
-err_iounmap:
+err_list_del:
        list_del(&sr_info->node);
-       iounmap(sr_info->base);
-err_free_name:
-       kfree(sr_info->name);
-err_release_region:
-       release_mem_region(mem->start, resource_size(mem));
-err_free_devinfo:
-       kfree(sr_info);
-
        return ret;
 }
 
@@ -1008,7 +986,6 @@ static int omap_sr_remove(struct platform_device *pdev)
 {
        struct omap_sr_data *pdata = pdev->dev.platform_data;
        struct omap_sr *sr_info;
-       struct resource *mem;
 
        if (!pdata) {
                dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
@@ -1027,13 +1004,8 @@ static int omap_sr_remove(struct platform_device *pdev)
        if (sr_info->dbg_dir)
                debugfs_remove_recursive(sr_info->dbg_dir);
 
+       pm_runtime_disable(&pdev->dev);
        list_del(&sr_info->node);
-       iounmap(sr_info->base);
-       kfree(sr_info->name);
-       kfree(sr_info);
-       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       release_mem_region(mem->start, resource_size(mem));
-
        return 0;
 }
 
@@ -1064,7 +1036,7 @@ static struct platform_driver smartreflex_driver = {
        .remove         = omap_sr_remove,
        .shutdown       = omap_sr_shutdown,
        .driver         = {
-               .name   = "smartreflex",
+               .name   = DRIVER_NAME,
        },
 };
 
index 42539ee2cb111f0e10a6b152d9a0d60cbb2d895b..4c5aabe21755cb82450876666145f1f2add7ad1f 100644 (file)
@@ -229,8 +229,6 @@ static int scsi_runtime_resume(struct device *dev)
 
 static int scsi_runtime_idle(struct device *dev)
 {
-       int err;
-
        dev_dbg(dev, "scsi_runtime_idle\n");
 
        /* Insert hooks here for targets, hosts, and transport classes */
@@ -240,14 +238,11 @@ static int scsi_runtime_idle(struct device *dev)
 
                if (sdev->request_queue->dev) {
                        pm_runtime_mark_last_busy(dev);
-                       err = pm_runtime_autosuspend(dev);
-               } else {
-                       err = pm_runtime_suspend(dev);
+                       pm_runtime_autosuspend(dev);
+                       return -EBUSY;
                }
-       } else {
-               err = pm_runtime_suspend(dev);
        }
-       return err;
+       return 0;
 }
 
 int scsi_autopm_get_device(struct scsi_device *sdev)
index afe9282629b900262da4e8ea178f3f6816b771bd..8afa5a4589f2dd03771acaac8be585447e8033c0 100644 (file)
@@ -25,7 +25,7 @@
 static int default_platform_runtime_idle(struct device *dev)
 {
        /* suspend synchronously to disable clocks immediately */
-       return pm_runtime_suspend(dev);
+       return 0;
 }
 
 static struct dev_pm_domain default_pm_domain = {
index 32b7bb111eb6b53d9e96808f7bd5fd0982cffd9d..095cfaded1c0dd084111af40d0e0a2c70ebe32d7 100644 (file)
@@ -223,7 +223,7 @@ static const struct dev_pm_ops spi_pm = {
        SET_RUNTIME_PM_OPS(
                pm_generic_runtime_suspend,
                pm_generic_runtime_resume,
-               pm_generic_runtime_idle
+               NULL
        )
 };
 
index 1567ac296b393163225237c830c48a726e529b4e..1ffc2ebdf612df7afbf90371e7ba4a4b226131b3 100644 (file)
@@ -20,6 +20,7 @@
 #include <asm/cacheflush.h>
 #include <linux/fdtable.h>
 #include <linux/file.h>
+#include <linux/freezer.h>
 #include <linux/fs.h>
 #include <linux/list.h>
 #include <linux/miscdevice.h>
@@ -2140,13 +2141,13 @@ retry:
                        if (!binder_has_proc_work(proc, thread))
                                ret = -EAGAIN;
                } else
-                       ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_work(proc, thread));
+                       ret = wait_event_freezable_exclusive(proc->wait, binder_has_proc_work(proc, thread));
        } else {
                if (non_block) {
                        if (!binder_has_thread_work(thread))
                                ret = -EAGAIN;
                } else
-                       ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread));
+                       ret = wait_event_freezable(thread->wait, binder_has_thread_work(thread));
        }
 
        binder_lock(__func__);
index 5f4765a7a5c54d6d3b845c9e9f7df402978afbff..5dfcf3bae23aa62ddb3d90dc8b72f06eac81e99c 100644 (file)
@@ -1248,13 +1248,8 @@ static int serial_hsu_resume(struct pci_dev *pdev)
 #ifdef CONFIG_PM_RUNTIME
 static int serial_hsu_runtime_idle(struct device *dev)
 {
-       int err;
-
-       err = pm_schedule_suspend(dev, 500);
-       if (err)
-               return -EBUSY;
-
-       return 0;
+       pm_schedule_suspend(dev, 500);
+       return -EBUSY;
 }
 
 static int serial_hsu_runtime_suspend(struct device *dev)
index 6eab440e1542e450f7733fb4cbbf35b1b1044313..7609ac4aed1cdc29493b3924c76b254cfdd09cae 100644 (file)
@@ -1765,7 +1765,8 @@ int usb_runtime_idle(struct device *dev)
         */
        if (autosuspend_check(udev) == 0)
                pm_runtime_autosuspend(dev);
-       return 0;
+       /* Tell the core not to suspend it, though. */
+       return -EBUSY;
 }
 
 int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable)
index b8bad294eeb8d168d58a30e92875cb55c1dbbe81..8c1b2c509467bf1dae5ef83a8a4dd9064ab93a4d 100644 (file)
@@ -141,7 +141,6 @@ static const struct dev_pm_ops usb_port_pm_ops = {
 #ifdef CONFIG_PM_RUNTIME
        .runtime_suspend =      usb_port_runtime_suspend,
        .runtime_resume =       usb_port_runtime_resume,
-       .runtime_idle =         pm_generic_runtime_idle,
 #endif
 };
 
index bfbf4700d160f8a4d54f7cc0446a35c4de8c747d..b70aa7c913940c3766263b67e564a053883f9f32 100644 (file)
@@ -447,7 +447,7 @@ wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
 {
        int error;
 
-       error = wait_event_freezekillable(server->response_q,
+       error = wait_event_freezekillable_unsafe(server->response_q,
                                    midQ->mid_state != MID_REQUEST_SUBMITTED);
        if (error < 0)
                return -ERESTARTSYS;
index deecc7294a672c3fa64cf3884c4ee28f4c7f80a7..0cff4434880d1fff3b799e6c1e2df6328b7b5282 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/mutex.h>
 #include <linux/anon_inodes.h>
 #include <linux/device.h>
+#include <linux/freezer.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/mman.h>
@@ -1602,7 +1603,8 @@ fetch_events:
                        }
 
                        spin_unlock_irqrestore(&ep->lock, flags);
-                       if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS))
+                       if (!freezable_schedule_hrtimeout_range(to, slack,
+                                                               HRTIMER_MODE_ABS))
                                timed_out = 1;
 
                        spin_lock_irqsave(&ep->lock, flags);
index c1c7a9d78722257867846f39c74780536b28d0c5..ce727047ee87786bcf4d20d8573a24a0990e2e62 100644 (file)
@@ -79,7 +79,7 @@ int nfs_wait_bit_killable(void *word)
 {
        if (fatal_signal_pending(current))
                return -ERESTARTSYS;
-       freezable_schedule();
+       freezable_schedule_unsafe();
        return 0;
 }
 EXPORT_SYMBOL_GPL(nfs_wait_bit_killable);
index 43ea96ced28cbc763a60048ab95cefcf737ecf40..ce90eb4775c2f888547bd98911062f8eede4af97 100644 (file)
@@ -33,7 +33,7 @@ nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
                res = rpc_call_sync(clnt, msg, flags);
                if (res != -EJUKEBOX)
                        break;
-               freezable_schedule_timeout_killable(NFS_JUKEBOX_RETRY_TIME);
+               freezable_schedule_timeout_killable_unsafe(NFS_JUKEBOX_RETRY_TIME);
                res = -ERESTARTSYS;
        } while (!fatal_signal_pending(current));
        return res;
index d7ba5616989c49fe52d396d41187a663744598f1..28241a42f363581341b3ed81de137fc0da1b428e 100644 (file)
@@ -268,7 +268,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout)
                *timeout = NFS4_POLL_RETRY_MIN;
        if (*timeout > NFS4_POLL_RETRY_MAX)
                *timeout = NFS4_POLL_RETRY_MAX;
-       freezable_schedule_timeout_killable(*timeout);
+       freezable_schedule_timeout_killable_unsafe(*timeout);
        if (fatal_signal_pending(current))
                res = -ERESTARTSYS;
        *timeout <<= 1;
@@ -4528,7 +4528,7 @@ int nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, const nfs4
 static unsigned long
 nfs4_set_lock_task_retry(unsigned long timeout)
 {
-       freezable_schedule_timeout_killable(timeout);
+       freezable_schedule_timeout_killable_unsafe(timeout);
        timeout <<= 1;
        if (timeout > NFS4_LOCK_MAXTIMEOUT)
                return NFS4_LOCK_MAXTIMEOUT;
index 8c1c96c27062a504bfc151f33d335fcd8f6779b5..6b14dc7df3a46df3293da538abc2d65b3b67f94f 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/rcupdate.h>
 #include <linux/hrtimer.h>
 #include <linux/sched/rt.h>
+#include <linux/freezer.h>
 
 #include <asm/uaccess.h>
 
@@ -236,7 +237,8 @@ int poll_schedule_timeout(struct poll_wqueues *pwq, int state,
 
        set_current_state(state);
        if (!pwq->triggered)
-               rc = schedule_hrtimeout_range(expires, slack, HRTIMER_MODE_ABS);
+               rc = freezable_schedule_hrtimeout_range(expires, slack,
+                                                       HRTIMER_MODE_ABS);
        __set_current_state(TASK_RUNNING);
 
        /*
index 14ceff788c40b75cc7e7240db5bb07587d6ec783..1c16f821434f9c2ffee4ea793605800fa99a56b4 100644 (file)
  *
  *****************************************************************************/
 
-#define ACPI_DEBUGGER_MAX_ARGS          8      /* Must be max method args + 1 */
-#define ACPI_DB_LINE_BUFFER_SIZE       512
+#define ACPI_DEBUGGER_MAX_ARGS          ACPI_METHOD_NUM_ARGS + 4       /* Max command line arguments */
+#define ACPI_DB_LINE_BUFFER_SIZE        512
 
 #define ACPI_DEBUGGER_COMMAND_PROMPT    '-'
 #define ACPI_DEBUGGER_EXECUTE_PROMPT    '%'
index 4f52ea795c7ac2e5e39ff97703ad71ebe705351f..4607b027a6577111d3179d07cc292e25ba8de493 100644 (file)
  * This is the non-debug case -- make everything go away,
  * leaving no executable debug code!
  */
-#define ACPI_FUNCTION_NAME(a)
 #define ACPI_DEBUG_PRINT(pl)
 #define ACPI_DEBUG_PRINT_RAW(pl)
 #define ACPI_DEBUG_EXEC(a)
 #define ACPI_DEBUG_ONLY_MEMBERS(a)
+#define ACPI_FUNCTION_NAME(a)
 #define ACPI_FUNCTION_TRACE(a)
 #define ACPI_FUNCTION_TRACE_PTR(a, b)
 #define ACPI_FUNCTION_TRACE_U32(a, b)
 #define ACPI_FUNCTION_TRACE_STR(a, b)
-#define ACPI_FUNCTION_EXIT
-#define ACPI_FUNCTION_STATUS_EXIT(s)
-#define ACPI_FUNCTION_VALUE_EXIT(s)
 #define ACPI_FUNCTION_ENTRY()
 #define ACPI_DUMP_STACK_ENTRY(a)
 #define ACPI_DUMP_OPERANDS(a, b, c)
 #define ACPI_DUMP_ENTRY(a, b)
-#define ACPI_DUMP_TABLES(a, b)
 #define ACPI_DUMP_PATHNAME(a, b, c, d)
 #define ACPI_DUMP_BUFFER(a, b)
-#define ACPI_DEBUG_PRINT(pl)
-#define ACPI_DEBUG_PRINT_RAW(pl)
 #define ACPI_IS_DEBUG_ENABLED(level, component) 0
 
 /* Return macros must have a return statement at the minimum */
index c13c919ab99e9803b2ebe18d36eb93ab98bf6076..ca081ace2a1dc01434e7ee64c77fb26a049376a7 100644 (file)
@@ -63,13 +63,6 @@ acpi_get_physical_device_location(acpi_handle handle, struct acpi_pld_info **pld
 #define ACPI_BUS_FILE_ROOT     "acpi"
 extern struct proc_dir_entry *acpi_root_dir;
 
-enum acpi_bus_removal_type {
-       ACPI_BUS_REMOVAL_NORMAL = 0,
-       ACPI_BUS_REMOVAL_EJECT,
-       ACPI_BUS_REMOVAL_SUPRISE,
-       ACPI_BUS_REMOVAL_TYPE_COUNT
-};
-
 enum acpi_bus_device_type {
        ACPI_BUS_TYPE_DEVICE = 0,
        ACPI_BUS_TYPE_POWER,
@@ -163,12 +156,10 @@ struct acpi_device_flags {
        u32 dynamic_status:1;
        u32 removable:1;
        u32 ejectable:1;
-       u32 suprise_removal_ok:1;
        u32 power_manageable:1;
-       u32 performance_manageable:1;
        u32 eject_pending:1;
        u32 match_driver:1;
-       u32 reserved:24;
+       u32 reserved:26;
 };
 
 /* File System */
@@ -286,6 +277,7 @@ struct acpi_device_physical_node {
        u8 node_id;
        struct list_head node;
        struct device *dev;
+       bool put_online:1;
 };
 
 /* set maximum of physical nodes to 32 for expansibility */
@@ -310,7 +302,6 @@ struct acpi_device {
        struct acpi_driver *driver;
        void *driver_data;
        struct device dev;
-       enum acpi_bus_removal_type removal_type;        /* indicate for different removal type */
        u8 physical_node_count;
        struct list_head physical_node_list;
        struct mutex physical_node_lock;
@@ -468,8 +459,6 @@ acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
                                 acpi_notify_handler handler, void *context);
 acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
                                    acpi_notify_handler handler);
-int acpi_device_power_state(struct device *dev, struct acpi_device *adev,
-                           u32 target_state, int d_max_in, int *d_min_p);
 int acpi_pm_device_sleep_state(struct device *, int *, int);
 void acpi_dev_pm_add_dependent(acpi_handle handle, struct device *depdev);
 void acpi_dev_pm_remove_dependent(acpi_handle handle, struct device *depdev);
@@ -485,23 +474,13 @@ static inline acpi_status acpi_remove_pm_notifier(struct acpi_device *adev,
 {
        return AE_SUPPORT;
 }
-static inline int __acpi_device_power_state(int m, int *p)
+static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
 {
        if (p)
                *p = ACPI_STATE_D0;
+
        return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3) ? m : ACPI_STATE_D0;
 }
-static inline int acpi_device_power_state(struct device *dev,
-                                         struct acpi_device *adev,
-                                         u32 target_state, int d_max_in,
-                                         int *d_min_p)
-{
-       return __acpi_device_power_state(d_max_in, d_min_p);
-}
-static inline int acpi_pm_device_sleep_state(struct device *d, int *p, int m)
-{
-       return __acpi_device_power_state(m, p);
-}
 static inline void acpi_dev_pm_add_dependent(acpi_handle handle,
                                             struct device *depdev) {}
 static inline void acpi_dev_pm_remove_dependent(acpi_handle handle,
index e6168a24b9f0f202e9403f946c9aecbb8049f67b..b420939f5eb5608f2335e0b4ae4087176911022b 100644 (file)
@@ -123,7 +123,9 @@ extern int register_dock_notifier(struct notifier_block *nb);
 extern void unregister_dock_notifier(struct notifier_block *nb);
 extern int register_hotplug_dock_device(acpi_handle handle,
                                        const struct acpi_dock_ops *ops,
-                                       void *context);
+                                       void *context,
+                                       void (*init)(void *),
+                                       void (*release)(void *));
 extern void unregister_hotplug_dock_device(acpi_handle handle);
 #else
 static inline int is_dock_device(acpi_handle handle)
@@ -139,7 +141,9 @@ static inline void unregister_dock_notifier(struct notifier_block *nb)
 }
 static inline int register_hotplug_dock_device(acpi_handle handle,
                                               const struct acpi_dock_ops *ops,
-                                              void *context)
+                                              void *context,
+                                              void (*init)(void *),
+                                              void (*release)(void *))
 {
        return -ENODEV;
 }
index 454881e6450a4493eabf6fa5de03fd005fccc761..1b09300810e647dc71fbd7b490cd081ef7c0862d 100644 (file)
@@ -46,7 +46,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20130328
+#define ACPI_CA_VERSION                 0x20130517
 
 #include <acpi/acconfig.h>
 #include <acpi/actypes.h>
@@ -80,6 +80,7 @@ extern bool acpi_gbl_enable_aml_debug_object;
 extern u8 acpi_gbl_copy_dsdt_locally;
 extern u8 acpi_gbl_truncate_io_addresses;
 extern u8 acpi_gbl_disable_auto_repair;
+extern u8 acpi_gbl_disable_ssdt_table_load;
 
 /*
  * Hardware-reduced prototypes. All interfaces that use these macros will
index ea69367fdd3bbafaf1775da248c7cc998c47fba8..66096d06925e417d70d6b8974a00a035d05ef1d8 100644 (file)
@@ -6,6 +6,10 @@
 #include <linux/thermal.h>
 #include <asm/acpi.h>
 
+#define ACPI_PROCESSOR_CLASS           "processor"
+#define ACPI_PROCESSOR_DEVICE_NAME     "Processor"
+#define ACPI_PROCESSOR_DEVICE_HID      "ACPI0007"
+
 #define ACPI_PROCESSOR_BUSY_METRIC     10
 
 #define ACPI_PROCESSOR_MAX_POWER       8
@@ -207,6 +211,7 @@ struct acpi_processor {
        struct acpi_processor_throttling throttling;
        struct acpi_processor_limit limit;
        struct thermal_cooling_device *cdev;
+       struct device *dev; /* Processor device. */
 };
 
 struct acpi_processor_errata {
index 17b5b596764100ae14400437b86e84b0c068291f..353ba256f3681e4f6ddd8b18b9feba61b1d98cec 100644 (file)
@@ -352,8 +352,7 @@ extern acpi_status acpi_pci_osc_control_set(acpi_handle handle,
 
 /* Enable _OST when all relevant hotplug operations are enabled */
 #if defined(CONFIG_ACPI_HOTPLUG_CPU) &&                        \
-       (defined(CONFIG_ACPI_HOTPLUG_MEMORY) ||         \
-        defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) && \
+       defined(CONFIG_ACPI_HOTPLUG_MEMORY) &&          \
        defined(CONFIG_ACPI_CONTAINER)
 #define ACPI_HOTPLUG_OST
 #endif
index 8f0406230a0a4890b4247e60215795c11e0a30d3..0bc4b74668e95f561e6cad07d038f6822f86faa0 100644 (file)
@@ -111,6 +111,9 @@ struct cpuidle_driver {
        struct cpuidle_state    states[CPUIDLE_STATE_MAX];
        int                     state_count;
        int                     safe_state_index;
+
+       /* the driver handles the cpus in cpumask */
+       struct cpumask       *cpumask;
 };
 
 #ifdef CONFIG_CPU_IDLE
@@ -135,9 +138,6 @@ extern void cpuidle_disable_device(struct cpuidle_device *dev);
 extern int cpuidle_play_dead(void);
 
 extern struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev);
-extern int cpuidle_register_cpu_driver(struct cpuidle_driver *drv, int cpu);
-extern void cpuidle_unregister_cpu_driver(struct cpuidle_driver *drv, int cpu);
-
 #else
 static inline void disable_cpuidle(void) { }
 static inline int cpuidle_idle_call(void) { return -ENODEV; }
index 21ca773f77bf7fd2543b111371279c4ef749722d..822c1354f3a69dae20e7f6cacaf340b40ea9d7c4 100644 (file)
@@ -51,7 +51,7 @@ struct task_struct;
 extern void debug_show_all_locks(void);
 extern void debug_show_held_locks(struct task_struct *task);
 extern void debug_check_no_locks_freed(const void *from, unsigned long len);
-extern void debug_check_no_locks_held(struct task_struct *task);
+extern void debug_check_no_locks_held(void);
 #else
 static inline void debug_show_all_locks(void)
 {
@@ -67,7 +67,7 @@ debug_check_no_locks_freed(const void *from, unsigned long len)
 }
 
 static inline void
-debug_check_no_locks_held(struct task_struct *task)
+debug_check_no_locks_held(void)
 {
 }
 #endif
index fe8c4476f7e4b36f4f7b4a778c73b8cfd77c2336..5f1ab92107e63b1889da7e544189f8b73cc740fb 100644 (file)
@@ -181,6 +181,8 @@ extern struct devfreq *devfreq_add_device(struct device *dev,
                                  const char *governor_name,
                                  void *data);
 extern int devfreq_remove_device(struct devfreq *devfreq);
+
+/* Supposed to be called by PM_SLEEP/PM_RUNTIME callbacks */
 extern int devfreq_suspend_device(struct devfreq *devfreq);
 extern int devfreq_resume_device(struct devfreq *devfreq);
 
index c0a12612532512bab2f792fba4b40580c48b13dd..eeb33315514c332ddf83b9fcf4183a580555bab6 100644 (file)
@@ -71,6 +71,10 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *);
  *             the specific driver's probe to initial the matched device.
  * @remove:    Called when a device removed from this bus.
  * @shutdown:  Called at shut-down time to quiesce the device.
+ *
+ * @online:    Called to put the device back online (after offlining it).
+ * @offline:   Called to put the device offline for hot-removal. May fail.
+ *
  * @suspend:   Called when a device on this bus wants to go to sleep mode.
  * @resume:    Called to bring a device on this bus out of sleep mode.
  * @pm:                Power management operations of this bus, callback the specific
@@ -104,6 +108,9 @@ struct bus_type {
        int (*remove)(struct device *dev);
        void (*shutdown)(struct device *dev);
 
+       int (*online)(struct device *dev);
+       int (*offline)(struct device *dev);
+
        int (*suspend)(struct device *dev, pm_message_t state);
        int (*resume)(struct device *dev);
 
@@ -648,6 +655,8 @@ struct acpi_dev_node {
  * @release:   Callback to free the device after all references have
  *             gone away. This should be set by the allocator of the
  *             device (i.e. the bus driver that discovered the device).
+ * @offline_disabled: If set, the device is permanently online.
+ * @offline:   Set after successful invocation of bus type's .offline().
  *
  * At the lowest level, every device in a Linux system is represented by an
  * instance of struct device. The device structure contains the information
@@ -720,6 +729,9 @@ struct device {
 
        void    (*release)(struct device *dev);
        struct iommu_group      *iommu_group;
+
+       bool                    offline_disabled:1;
+       bool                    offline:1;
 };
 
 static inline struct device *kobj_to_dev(struct kobject *kobj)
@@ -856,6 +868,15 @@ extern const char *device_get_devnode(struct device *dev,
 extern void *dev_get_drvdata(const struct device *dev);
 extern int dev_set_drvdata(struct device *dev, void *data);
 
+static inline bool device_supports_offline(struct device *dev)
+{
+       return dev->bus && dev->bus->offline && dev->bus->online;
+}
+
+extern void lock_device_hotplug(void);
+extern void unlock_device_hotplug(void);
+extern int device_offline(struct device *dev);
+extern int device_online(struct device *dev);
 /*
  * Root device objects for grouping under /sys/devices
  */
index e70df40d84f6fe83c72f732aa44b454148661b6e..7fd81b8c48971676cd52362f09722dfd2dd28153 100644 (file)
@@ -3,6 +3,7 @@
 #ifndef FREEZER_H_INCLUDED
 #define FREEZER_H_INCLUDED
 
+#include <linux/debug_locks.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/atomic.h>
@@ -46,7 +47,11 @@ extern int freeze_kernel_threads(void);
 extern void thaw_processes(void);
 extern void thaw_kernel_threads(void);
 
-static inline bool try_to_freeze(void)
+/*
+ * DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION
+ * If try_to_freeze causes a lockdep warning it means the caller may deadlock
+ */
+static inline bool try_to_freeze_unsafe(void)
 {
        might_sleep();
        if (likely(!freezing(current)))
@@ -54,6 +59,13 @@ static inline bool try_to_freeze(void)
        return __refrigerator(false);
 }
 
+static inline bool try_to_freeze(void)
+{
+       if (!(current->flags & PF_NOFREEZE))
+               debug_check_no_locks_held();
+       return try_to_freeze_unsafe();
+}
+
 extern bool freeze_task(struct task_struct *p);
 extern bool set_freezable(void);
 
@@ -115,6 +127,14 @@ static inline void freezer_count(void)
        try_to_freeze();
 }
 
+/* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
+static inline void freezer_count_unsafe(void)
+{
+       current->flags &= ~PF_FREEZER_SKIP;
+       smp_mb();
+       try_to_freeze_unsafe();
+}
+
 /**
  * freezer_should_skip - whether to skip a task when determining frozen
  *                      state is reached
@@ -139,28 +159,86 @@ static inline bool freezer_should_skip(struct task_struct *p)
 }
 
 /*
- * These macros are intended to be used whenever you want allow a sleeping
+ * These functions are intended to be used whenever you want allow a sleeping
  * task to be frozen. Note that neither return any clear indication of
  * whether a freeze event happened while in this function.
  */
 
 /* Like schedule(), but should not block the freezer. */
-#define freezable_schedule()                                           \
-({                                                                     \
-       freezer_do_not_count();                                         \
-       schedule();                                                     \
-       freezer_count();                                                \
-})
+static inline void freezable_schedule(void)
+{
+       freezer_do_not_count();
+       schedule();
+       freezer_count();
+}
+
+/* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
+static inline void freezable_schedule_unsafe(void)
+{
+       freezer_do_not_count();
+       schedule();
+       freezer_count_unsafe();
+}
+
+/*
+ * Like freezable_schedule_timeout(), but should not block the freezer.  Do not
+ * call this with locks held.
+ */
+static inline long freezable_schedule_timeout(long timeout)
+{
+       long __retval;
+       freezer_do_not_count();
+       __retval = schedule_timeout(timeout);
+       freezer_count();
+       return __retval;
+}
+
+/*
+ * Like schedule_timeout_interruptible(), but should not block the freezer.  Do not
+ * call this with locks held.
+ */
+static inline long freezable_schedule_timeout_interruptible(long timeout)
+{
+       long __retval;
+       freezer_do_not_count();
+       __retval = schedule_timeout_interruptible(timeout);
+       freezer_count();
+       return __retval;
+}
 
 /* Like schedule_timeout_killable(), but should not block the freezer. */
-#define freezable_schedule_timeout_killable(timeout)                   \
-({                                                                     \
-       long __retval;                                                  \
-       freezer_do_not_count();                                         \
-       __retval = schedule_timeout_killable(timeout);                  \
-       freezer_count();                                                \
-       __retval;                                                       \
-})
+static inline long freezable_schedule_timeout_killable(long timeout)
+{
+       long __retval;
+       freezer_do_not_count();
+       __retval = schedule_timeout_killable(timeout);
+       freezer_count();
+       return __retval;
+}
+
+/* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
+static inline long freezable_schedule_timeout_killable_unsafe(long timeout)
+{
+       long __retval;
+       freezer_do_not_count();
+       __retval = schedule_timeout_killable(timeout);
+       freezer_count_unsafe();
+       return __retval;
+}
+
+/*
+ * Like schedule_hrtimeout_range(), but should not block the freezer.  Do not
+ * call this with locks held.
+ */
+static inline int freezable_schedule_hrtimeout_range(ktime_t *expires,
+               unsigned long delta, const enum hrtimer_mode mode)
+{
+       int __retval;
+       freezer_do_not_count();
+       __retval = schedule_hrtimeout_range(expires, delta, mode);
+       freezer_count();
+       return __retval;
+}
 
 /*
  * Freezer-friendly wrappers around wait_event_interruptible(),
@@ -177,33 +255,45 @@ static inline bool freezer_should_skip(struct task_struct *p)
        __retval;                                                       \
 })
 
+/* DO NOT ADD ANY NEW CALLERS OF THIS FUNCTION */
+#define wait_event_freezekillable_unsafe(wq, condition)                        \
+({                                                                     \
+       int __retval;                                                   \
+       freezer_do_not_count();                                         \
+       __retval = wait_event_killable(wq, (condition));                \
+       freezer_count_unsafe();                                         \
+       __retval;                                                       \
+})
+
 #define wait_event_freezable(wq, condition)                            \
 ({                                                                     \
        int __retval;                                                   \
-       for (;;) {                                                      \
-               __retval = wait_event_interruptible(wq,                 \
-                               (condition) || freezing(current));      \
-               if (__retval || (condition))                            \
-                       break;                                          \
-               try_to_freeze();                                        \
-       }                                                               \
+       freezer_do_not_count();                                         \
+       __retval = wait_event_interruptible(wq, (condition));           \
+       freezer_count();                                                \
        __retval;                                                       \
 })
 
 #define wait_event_freezable_timeout(wq, condition, timeout)           \
 ({                                                                     \
        long __retval = timeout;                                        \
-       for (;;) {                                                      \
-               __retval = wait_event_interruptible_timeout(wq,         \
-                               (condition) || freezing(current),       \
-                               __retval);                              \
-               if (__retval <= 0 || (condition))                       \
-                       break;                                          \
-               try_to_freeze();                                        \
-       }                                                               \
+       freezer_do_not_count();                                         \
+       __retval = wait_event_interruptible_timeout(wq, (condition),    \
+                               __retval);                              \
+       freezer_count();                                                \
        __retval;                                                       \
 })
 
+#define wait_event_freezable_exclusive(wq, condition)                  \
+({                                                                     \
+       int __retval;                                                   \
+       freezer_do_not_count();                                         \
+       __retval = wait_event_interruptible_exclusive(wq, condition);   \
+       freezer_count();                                                \
+       __retval;                                                       \
+})
+
+
 #else /* !CONFIG_FREEZER */
 static inline bool frozen(struct task_struct *p) { return false; }
 static inline bool freezing(struct task_struct *p) { return false; }
@@ -225,18 +315,37 @@ static inline void set_freezable(void) {}
 
 #define freezable_schedule()  schedule()
 
+#define freezable_schedule_unsafe()  schedule()
+
+#define freezable_schedule_timeout(timeout)  schedule_timeout(timeout)
+
+#define freezable_schedule_timeout_interruptible(timeout)              \
+       schedule_timeout_interruptible(timeout)
+
 #define freezable_schedule_timeout_killable(timeout)                   \
        schedule_timeout_killable(timeout)
 
+#define freezable_schedule_timeout_killable_unsafe(timeout)            \
+       schedule_timeout_killable(timeout)
+
+#define freezable_schedule_hrtimeout_range(expires, delta, mode)       \
+       schedule_hrtimeout_range(expires, delta, mode)
+
 #define wait_event_freezable(wq, condition)                            \
                wait_event_interruptible(wq, condition)
 
 #define wait_event_freezable_timeout(wq, condition, timeout)           \
                wait_event_interruptible_timeout(wq, condition, timeout)
 
+#define wait_event_freezable_exclusive(wq, condition)                  \
+               wait_event_interruptible_exclusive(wq, condition)
+
 #define wait_event_freezekillable(wq, condition)               \
                wait_event_killable(wq, condition)
 
+#define wait_event_freezekillable_unsafe(wq, condition)                        \
+               wait_event_killable(wq, condition)
+
 #endif /* !CONFIG_FREEZER */
 
 #endif /* FREEZER_H_INCLUDED */
index 3e622c6109255650896ce67e141403ec1d36479e..dd38e62b84d2824ecf1e412cdd7fbb908dac675f 100644 (file)
@@ -234,6 +234,8 @@ static inline void unlock_memory_hotplug(void) {}
 
 extern int is_mem_section_removable(unsigned long pfn, unsigned long nr_pages);
 extern void try_offline_node(int nid);
+extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
+extern void remove_memory(int nid, u64 start, u64 size);
 
 #else
 static inline int is_mem_section_removable(unsigned long pfn,
@@ -243,15 +245,23 @@ static inline int is_mem_section_removable(unsigned long pfn,
 }
 
 static inline void try_offline_node(int nid) {}
+
+static inline int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
+{
+       return -EINVAL;
+}
+
+static inline void remove_memory(int nid, u64 start, u64 size) {}
 #endif /* CONFIG_MEMORY_HOTREMOVE */
 
+extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn,
+               void *arg, int (*func)(struct memory_block *, void *));
 extern int mem_online_node(int nid);
 extern int add_memory(int nid, u64 start, u64 size);
 extern int arch_add_memory(int nid, u64 start, u64 size);
 extern int offline_pages(unsigned long start_pfn, unsigned long nr_pages);
-extern int offline_memory_block(struct memory_block *mem);
 extern bool is_memblock_offlined(struct memory_block *mem);
-extern int remove_memory(int nid, u64 start, u64 size);
+extern void remove_memory(int nid, u64 start, u64 size);
 extern int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
                                                                int nr_pages);
 extern void sparse_remove_one_section(struct zone *zone, struct mem_section *ms);
index 7d7e09efff9b9eea0f29ce8fc37cbcdf0268e6f8..6fa7cea25da9afde1ffac4668c30f85d711a0fc0 100644 (file)
@@ -37,7 +37,6 @@ extern void pm_runtime_enable(struct device *dev);
 extern void __pm_runtime_disable(struct device *dev, bool check_resume);
 extern void pm_runtime_allow(struct device *dev);
 extern void pm_runtime_forbid(struct device *dev);
-extern int pm_generic_runtime_idle(struct device *dev);
 extern int pm_generic_runtime_suspend(struct device *dev);
 extern int pm_generic_runtime_resume(struct device *dev);
 extern void pm_runtime_no_callbacks(struct device *dev);
@@ -143,7 +142,6 @@ static inline bool pm_runtime_active(struct device *dev) { return true; }
 static inline bool pm_runtime_status_suspended(struct device *dev) { return false; }
 static inline bool pm_runtime_enabled(struct device *dev) { return false; }
 
-static inline int pm_generic_runtime_idle(struct device *dev) { return 0; }
 static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; }
 static inline int pm_generic_runtime_resume(struct device *dev) { return 0; }
 static inline void pm_runtime_no_callbacks(struct device *dev) {}
index c0f44c2b006da4ae05e4c55e7ed322fb50c581fd..d8b187c3925ddae170810cd7bf070c2a4b2ffbff 100644 (file)
@@ -299,11 +299,11 @@ void omap_sr_disable_reset_volt(struct voltagedomain *voltdm);
 void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data);
 
 /* Smartreflex driver hooks to be called from Smartreflex class driver */
-int sr_enable(struct voltagedomain *voltdm, unsigned long volt);
-void sr_disable(struct voltagedomain *voltdm);
-int sr_configure_errgen(struct voltagedomain *voltdm);
-int sr_disable_errgen(struct voltagedomain *voltdm);
-int sr_configure_minmax(struct voltagedomain *voltdm);
+int sr_enable(struct omap_sr *sr, unsigned long volt);
+void sr_disable(struct omap_sr *sr);
+int sr_configure_errgen(struct omap_sr *sr);
+int sr_disable_errgen(struct omap_sr *sr);
+int sr_configure_minmax(struct omap_sr *sr);
 
 /* API to register the smartreflex class driver with the smartreflex driver */
 int sr_register_class(struct omap_sr_class_data *class_data);
index d4e3f16d5e8932c56e059d906add432cf88c8dbc..f73cabf59012f1ead45eee1eb7aa97600b1bb902 100644 (file)
@@ -363,6 +363,7 @@ extern bool pm_wakeup_pending(void);
 extern bool pm_get_wakeup_count(unsigned int *count, bool block);
 extern bool pm_save_wakeup_count(unsigned int count);
 extern void pm_wakep_autosleep_enabled(bool set);
+extern void pm_print_active_wakeup_sources(void);
 
 static inline void lock_system_sleep(void)
 {
index 427acab5d69af24899c4daf19b194e4abd67a243..8e42410bd1591c5168d616d3ebcac66a1d22aed5 100644 (file)
@@ -5,6 +5,7 @@
 #define _TRACE_POWER_H
 
 #include <linux/ktime.h>
+#include <linux/pm_qos.h>
 #include <linux/tracepoint.h>
 
 DECLARE_EVENT_CLASS(cpu,
@@ -177,6 +178,178 @@ DEFINE_EVENT(power_domain, power_domain_target,
 
        TP_ARGS(name, state, cpu_id)
 );
+
+/*
+ * The pm qos events are used for pm qos update
+ */
+DECLARE_EVENT_CLASS(pm_qos_request,
+
+       TP_PROTO(int pm_qos_class, s32 value),
+
+       TP_ARGS(pm_qos_class, value),
+
+       TP_STRUCT__entry(
+               __field( int,                    pm_qos_class   )
+               __field( s32,                    value          )
+       ),
+
+       TP_fast_assign(
+               __entry->pm_qos_class = pm_qos_class;
+               __entry->value = value;
+       ),
+
+       TP_printk("pm_qos_class=%s value=%d",
+                 __print_symbolic(__entry->pm_qos_class,
+                       { PM_QOS_CPU_DMA_LATENCY,       "CPU_DMA_LATENCY" },
+                       { PM_QOS_NETWORK_LATENCY,       "NETWORK_LATENCY" },
+                       { PM_QOS_NETWORK_THROUGHPUT,    "NETWORK_THROUGHPUT" }),
+                 __entry->value)
+);
+
+DEFINE_EVENT(pm_qos_request, pm_qos_add_request,
+
+       TP_PROTO(int pm_qos_class, s32 value),
+
+       TP_ARGS(pm_qos_class, value)
+);
+
+DEFINE_EVENT(pm_qos_request, pm_qos_update_request,
+
+       TP_PROTO(int pm_qos_class, s32 value),
+
+       TP_ARGS(pm_qos_class, value)
+);
+
+DEFINE_EVENT(pm_qos_request, pm_qos_remove_request,
+
+       TP_PROTO(int pm_qos_class, s32 value),
+
+       TP_ARGS(pm_qos_class, value)
+);
+
+TRACE_EVENT(pm_qos_update_request_timeout,
+
+       TP_PROTO(int pm_qos_class, s32 value, unsigned long timeout_us),
+
+       TP_ARGS(pm_qos_class, value, timeout_us),
+
+       TP_STRUCT__entry(
+               __field( int,                    pm_qos_class   )
+               __field( s32,                    value          )
+               __field( unsigned long,          timeout_us     )
+       ),
+
+       TP_fast_assign(
+               __entry->pm_qos_class = pm_qos_class;
+               __entry->value = value;
+               __entry->timeout_us = timeout_us;
+       ),
+
+       TP_printk("pm_qos_class=%s value=%d, timeout_us=%ld",
+                 __print_symbolic(__entry->pm_qos_class,
+                       { PM_QOS_CPU_DMA_LATENCY,       "CPU_DMA_LATENCY" },
+                       { PM_QOS_NETWORK_LATENCY,       "NETWORK_LATENCY" },
+                       { PM_QOS_NETWORK_THROUGHPUT,    "NETWORK_THROUGHPUT" }),
+                 __entry->value, __entry->timeout_us)
+);
+
+DECLARE_EVENT_CLASS(pm_qos_update,
+
+       TP_PROTO(enum pm_qos_req_action action, int prev_value, int curr_value),
+
+       TP_ARGS(action, prev_value, curr_value),
+
+       TP_STRUCT__entry(
+               __field( enum pm_qos_req_action, action         )
+               __field( int,                    prev_value     )
+               __field( int,                    curr_value     )
+       ),
+
+       TP_fast_assign(
+               __entry->action = action;
+               __entry->prev_value = prev_value;
+               __entry->curr_value = curr_value;
+       ),
+
+       TP_printk("action=%s prev_value=%d curr_value=%d",
+                 __print_symbolic(__entry->action,
+                       { PM_QOS_ADD_REQ,       "ADD_REQ" },
+                       { PM_QOS_UPDATE_REQ,    "UPDATE_REQ" },
+                       { PM_QOS_REMOVE_REQ,    "REMOVE_REQ" }),
+                 __entry->prev_value, __entry->curr_value)
+);
+
+DEFINE_EVENT(pm_qos_update, pm_qos_update_target,
+
+       TP_PROTO(enum pm_qos_req_action action, int prev_value, int curr_value),
+
+       TP_ARGS(action, prev_value, curr_value)
+);
+
+DEFINE_EVENT_PRINT(pm_qos_update, pm_qos_update_flags,
+
+       TP_PROTO(enum pm_qos_req_action action, int prev_value, int curr_value),
+
+       TP_ARGS(action, prev_value, curr_value),
+
+       TP_printk("action=%s prev_value=0x%x curr_value=0x%x",
+                 __print_symbolic(__entry->action,
+                       { PM_QOS_ADD_REQ,       "ADD_REQ" },
+                       { PM_QOS_UPDATE_REQ,    "UPDATE_REQ" },
+                       { PM_QOS_REMOVE_REQ,    "REMOVE_REQ" }),
+                 __entry->prev_value, __entry->curr_value)
+);
+
+DECLARE_EVENT_CLASS(dev_pm_qos_request,
+
+       TP_PROTO(const char *name, enum dev_pm_qos_req_type type,
+                s32 new_value),
+
+       TP_ARGS(name, type, new_value),
+
+       TP_STRUCT__entry(
+               __string( name,                    name         )
+               __field( enum dev_pm_qos_req_type, type         )
+               __field( s32,                      new_value    )
+       ),
+
+       TP_fast_assign(
+               __assign_str(name, name);
+               __entry->type = type;
+               __entry->new_value = new_value;
+       ),
+
+       TP_printk("device=%s type=%s new_value=%d",
+                 __get_str(name),
+                 __print_symbolic(__entry->type,
+                       { DEV_PM_QOS_LATENCY,   "DEV_PM_QOS_LATENCY" },
+                       { DEV_PM_QOS_FLAGS,     "DEV_PM_QOS_FLAGS" }),
+                 __entry->new_value)
+);
+
+DEFINE_EVENT(dev_pm_qos_request, dev_pm_qos_add_request,
+
+       TP_PROTO(const char *name, enum dev_pm_qos_req_type type,
+                s32 new_value),
+
+       TP_ARGS(name, type, new_value)
+);
+
+DEFINE_EVENT(dev_pm_qos_request, dev_pm_qos_update_request,
+
+       TP_PROTO(const char *name, enum dev_pm_qos_req_type type,
+                s32 new_value),
+
+       TP_ARGS(name, type, new_value)
+);
+
+DEFINE_EVENT(dev_pm_qos_request, dev_pm_qos_remove_request,
+
+       TP_PROTO(const char *name, enum dev_pm_qos_req_type type,
+                s32 new_value),
+
+       TP_ARGS(name, type, new_value)
+);
 #endif /* _TRACE_POWER_H */
 
 /* This part must be outside protection */
index 68d73d09b770308b6cd23ffadbfa52780581a2a1..46aa3d1c1654776b6b223d6089a7eb1597662afc 100644 (file)
@@ -78,11 +78,25 @@ static inline int xen_acpi_get_pxm(acpi_handle h)
 int xen_acpi_notify_hypervisor_state(u8 sleep_state,
                                     u32 pm1a_cnt, u32 pm1b_cnd);
 
+static inline int xen_acpi_suspend_lowlevel(void)
+{
+       /*
+       * Xen will save and restore CPU context, so
+       * we can skip that and just go straight to
+       * the suspend.
+       */
+       acpi_enter_sleep_state(ACPI_STATE_S3);
+       return 0;
+}
+
 static inline void xen_acpi_sleep_register(void)
 {
-       if (xen_initial_domain())
+       if (xen_initial_domain()) {
                acpi_os_set_prepare_sleep(
                        &xen_acpi_notify_hypervisor_state);
+
+               acpi_suspend_lowlevel = xen_acpi_suspend_lowlevel;
+       }
 }
 #else
 static inline void xen_acpi_sleep_register(void)
index 7bb73f9d09dbeedcc6c07f6a8dc8257f76fc4963..6a057750ebbbdee49b9c2c2b578567401fd8540f 100644 (file)
@@ -835,7 +835,7 @@ void do_exit(long code)
        /*
         * Make sure we are holding no locks:
         */
-       debug_check_no_locks_held(tsk);
+       debug_check_no_locks_held();
        /*
         * We can do this unlocked here. The futex code uses this flag
         * just to verify whether the pi state cleanup has been done
index c38893b0efbaa39d770b11546dba9e97ec53ff51..8b2afc1c9df0c698eccd86664d25c33ed647fea7 100644 (file)
@@ -110,6 +110,18 @@ bool freeze_task(struct task_struct *p)
 {
        unsigned long flags;
 
+       /*
+        * This check can race with freezer_do_not_count, but worst case that
+        * will result in an extra wakeup being sent to the task.  It does not
+        * race with freezer_count(), the barriers in freezer_count() and
+        * freezer_should_skip() ensure that either freezer_count() sees
+        * freezing == true in try_to_freeze() and freezes, or
+        * freezer_should_skip() sees !PF_FREEZE_SKIP and freezes the task
+        * normally.
+        */
+       if (freezer_should_skip(p))
+               return false;
+
        spin_lock_irqsave(&freezer_lock, flags);
        if (!freezing(p) || frozen(p)) {
                spin_unlock_irqrestore(&freezer_lock, flags);
index b26dcfc02c9489b3ca00bfd076f2208bb4964366..d710fae8abbe933b97267b69ff2e27864d1291a4 100644 (file)
@@ -61,6 +61,7 @@
 #include <linux/nsproxy.h>
 #include <linux/ptrace.h>
 #include <linux/sched/rt.h>
+#include <linux/freezer.h>
 
 #include <asm/futex.h>
 
@@ -1807,7 +1808,7 @@ static void futex_wait_queue_me(struct futex_hash_bucket *hb, struct futex_q *q,
                 * is no timeout, or if it has yet to expire.
                 */
                if (!timeout || timeout->task)
-                       schedule();
+                       freezable_schedule();
        }
        __set_current_state(TASK_RUNNING);
 }
index fd4b13b131f8db23fb17055caf5d33e23bec7b50..3ee4d06c6fc20bda08fa052a1c42d70c7d094cb8 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/sched/sysctl.h>
 #include <linux/sched/rt.h>
 #include <linux/timer.h>
+#include <linux/freezer.h>
 
 #include <asm/uaccess.h>
 
@@ -1545,7 +1546,7 @@ static int __sched do_nanosleep(struct hrtimer_sleeper *t, enum hrtimer_mode mod
                        t->task = NULL;
 
                if (likely(t->task))
-                       schedule();
+                       freezable_schedule();
 
                hrtimer_cancel(&t->timer);
                mode = HRTIMER_MODE_ABS;
index 1f3186b37fd5390be1534f895eb413de19e0a6d7..e16c45b9ee77054f80becd37a51da00776f796c1 100644 (file)
@@ -4090,7 +4090,7 @@ void debug_check_no_locks_freed(const void *mem_from, unsigned long mem_len)
 }
 EXPORT_SYMBOL_GPL(debug_check_no_locks_freed);
 
-static void print_held_locks_bug(struct task_struct *curr)
+static void print_held_locks_bug(void)
 {
        if (!debug_locks_off())
                return;
@@ -4099,22 +4099,21 @@ static void print_held_locks_bug(struct task_struct *curr)
 
        printk("\n");
        printk("=====================================\n");
-       printk("[ BUG: lock held at task exit time! ]\n");
+       printk("[ BUG: %s/%d still has locks held! ]\n",
+              current->comm, task_pid_nr(current));
        print_kernel_ident();
        printk("-------------------------------------\n");
-       printk("%s/%d is exiting with locks still held!\n",
-               curr->comm, task_pid_nr(curr));
-       lockdep_print_held_locks(curr);
-
+       lockdep_print_held_locks(current);
        printk("\nstack backtrace:\n");
        dump_stack();
 }
 
-void debug_check_no_locks_held(struct task_struct *task)
+void debug_check_no_locks_held(void)
 {
-       if (unlikely(task->lockdep_depth > 0))
-               print_held_locks_bug(task);
+       if (unlikely(current->lockdep_depth > 0))
+               print_held_locks_bug();
 }
+EXPORT_SYMBOL_GPL(debug_check_no_locks_held);
 
 void debug_show_all_locks(void)
 {
index d77663bfedeb071370f584f2bf1e42cd8332e5a4..1d1bf630e6e900d5354413a6176b60b6a948a979 100644 (file)
@@ -424,6 +424,8 @@ static ssize_t wakeup_count_store(struct kobject *kobj,
        if (sscanf(buf, "%u", &val) == 1) {
                if (pm_save_wakeup_count(val))
                        error = n;
+               else
+                       pm_print_active_wakeup_sources();
        }
 
  out:
@@ -528,6 +530,10 @@ pm_trace_store(struct kobject *kobj, struct kobj_attribute *attr,
 
        if (sscanf(buf, "%d", &val) == 1) {
                pm_trace_enabled = !!val;
+               if (pm_trace_enabled) {
+                       pr_warn("PM: Enabling pm_trace changes system date and time during resume.\n"
+                               "PM: Correct system time has to be restored manually after resume.\n");
+               }
                return n;
        }
        return -EINVAL;
index 98088e0e71e83a3b9cd157c5415f9e79083592c0..fc0df84864495f8c44261961cb6909e66d24a21e 100644 (file)
@@ -30,9 +30,10 @@ static int try_to_freeze_tasks(bool user_only)
        unsigned int todo;
        bool wq_busy = false;
        struct timeval start, end;
-       u64 elapsed_csecs64;
-       unsigned int elapsed_csecs;
+       u64 elapsed_msecs64;
+       unsigned int elapsed_msecs;
        bool wakeup = false;
+       int sleep_usecs = USEC_PER_MSEC;
 
        do_gettimeofday(&start);
 
@@ -68,22 +69,25 @@ static int try_to_freeze_tasks(bool user_only)
 
                /*
                 * We need to retry, but first give the freezing tasks some
-                * time to enter the refrigerator.
+                * time to enter the refrigerator.  Start with an initial
+                * 1 ms sleep followed by exponential backoff until 8 ms.
                 */
-               msleep(10);
+               usleep_range(sleep_usecs / 2, sleep_usecs);
+               if (sleep_usecs < 8 * USEC_PER_MSEC)
+                       sleep_usecs *= 2;
        }
 
        do_gettimeofday(&end);
-       elapsed_csecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
-       do_div(elapsed_csecs64, NSEC_PER_SEC / 100);
-       elapsed_csecs = elapsed_csecs64;
+       elapsed_msecs64 = timeval_to_ns(&end) - timeval_to_ns(&start);
+       do_div(elapsed_msecs64, NSEC_PER_MSEC);
+       elapsed_msecs = elapsed_msecs64;
 
        if (todo) {
                printk("\n");
-               printk(KERN_ERR "Freezing of tasks %s after %d.%02d seconds "
+               printk(KERN_ERR "Freezing of tasks %s after %d.%03d seconds "
                       "(%d tasks refusing to freeze, wq_busy=%d):\n",
                       wakeup ? "aborted" : "failed",
-                      elapsed_csecs / 100, elapsed_csecs % 100,
+                      elapsed_msecs / 1000, elapsed_msecs % 1000,
                       todo - wq_busy, wq_busy);
 
                if (!wakeup) {
@@ -96,8 +100,8 @@ static int try_to_freeze_tasks(bool user_only)
                        read_unlock(&tasklist_lock);
                }
        } else {
-               printk("(elapsed %d.%02d seconds) ", elapsed_csecs / 100,
-                       elapsed_csecs % 100);
+               printk("(elapsed %d.%03d seconds) ", elapsed_msecs / 1000,
+                       elapsed_msecs % 1000);
        }
 
        return todo ? -EBUSY : 0;
index 587dddeebf15610da6f93c35874381ea5156365a..06fe28589e9c9e88b014315dfab33a9e6cdfd0eb 100644 (file)
@@ -44,6 +44,7 @@
 
 #include <linux/uaccess.h>
 #include <linux/export.h>
+#include <trace/events/power.h>
 
 /*
  * locking rule: all changes to constraints or notifiers lists
@@ -202,6 +203,7 @@ int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node,
 
        spin_unlock_irqrestore(&pm_qos_lock, flags);
 
+       trace_pm_qos_update_target(action, prev_value, curr_value);
        if (prev_value != curr_value) {
                blocking_notifier_call_chain(c->notifiers,
                                             (unsigned long)curr_value,
@@ -272,6 +274,7 @@ bool pm_qos_update_flags(struct pm_qos_flags *pqf,
 
        spin_unlock_irqrestore(&pm_qos_lock, irqflags);
 
+       trace_pm_qos_update_flags(action, prev_value, curr_value);
        return prev_value != curr_value;
 }
 
@@ -333,6 +336,7 @@ void pm_qos_add_request(struct pm_qos_request *req,
        }
        req->pm_qos_class = pm_qos_class;
        INIT_DELAYED_WORK(&req->work, pm_qos_work_fn);
+       trace_pm_qos_add_request(pm_qos_class, value);
        pm_qos_update_target(pm_qos_array[pm_qos_class]->constraints,
                             &req->node, PM_QOS_ADD_REQ, value);
 }
@@ -361,6 +365,7 @@ void pm_qos_update_request(struct pm_qos_request *req,
 
        cancel_delayed_work_sync(&req->work);
 
+       trace_pm_qos_update_request(req->pm_qos_class, new_value);
        if (new_value != req->node.prio)
                pm_qos_update_target(
                        pm_qos_array[req->pm_qos_class]->constraints,
@@ -387,6 +392,8 @@ void pm_qos_update_request_timeout(struct pm_qos_request *req, s32 new_value,
 
        cancel_delayed_work_sync(&req->work);
 
+       trace_pm_qos_update_request_timeout(req->pm_qos_class,
+                                           new_value, timeout_us);
        if (new_value != req->node.prio)
                pm_qos_update_target(
                        pm_qos_array[req->pm_qos_class]->constraints,
@@ -416,6 +423,7 @@ void pm_qos_remove_request(struct pm_qos_request *req)
 
        cancel_delayed_work_sync(&req->work);
 
+       trace_pm_qos_remove_request(req->pm_qos_class, PM_QOS_DEFAULT_VALUE);
        pm_qos_update_target(pm_qos_array[req->pm_qos_class]->constraints,
                             &req->node, PM_QOS_REMOVE_REQ,
                             PM_QOS_DEFAULT_VALUE);
@@ -477,7 +485,7 @@ static int find_pm_qos_object_by_minor(int minor)
 {
        int pm_qos_class;
 
-       for (pm_qos_class = 0;
+       for (pm_qos_class = PM_QOS_CPU_DMA_LATENCY;
                pm_qos_class < PM_QOS_NUM_CLASSES; pm_qos_class++) {
                if (minor ==
                        pm_qos_array[pm_qos_class]->pm_qos_power_miscdev.minor)
@@ -491,7 +499,7 @@ static int pm_qos_power_open(struct inode *inode, struct file *filp)
        long pm_qos_class;
 
        pm_qos_class = find_pm_qos_object_by_minor(iminor(inode));
-       if (pm_qos_class >= 0) {
+       if (pm_qos_class >= PM_QOS_CPU_DMA_LATENCY) {
                struct pm_qos_request *req = kzalloc(sizeof(*req), GFP_KERNEL);
                if (!req)
                        return -ENOMEM;
@@ -584,7 +592,7 @@ static int __init pm_qos_power_init(void)
 
        BUILD_BUG_ON(ARRAY_SIZE(pm_qos_array) != PM_QOS_NUM_CLASSES);
 
-       for (i = 1; i < PM_QOS_NUM_CLASSES; i++) {
+       for (i = PM_QOS_CPU_DMA_LATENCY; i < PM_QOS_NUM_CLASSES; i++) {
                ret = register_pm_qos_misc(pm_qos_array[i]);
                if (ret < 0) {
                        printk(KERN_ERR "pm_qos_param: %s setup failed\n",
index 0de28576807df9e7dc5be5f05d75a0faa937caf2..7872a35eafe754fb1cdb680ff579562b7f4a602b 100644 (file)
@@ -642,8 +642,9 @@ __register_nosave_region(unsigned long start_pfn, unsigned long end_pfn,
        region->end_pfn = end_pfn;
        list_add_tail(&region->list, &nosave_regions);
  Report:
-       printk(KERN_INFO "PM: Registered nosave memory: %016lx - %016lx\n",
-               start_pfn << PAGE_SHIFT, end_pfn << PAGE_SHIFT);
+       printk(KERN_INFO "PM: Registered nosave memory: [mem %#010llx-%#010llx]\n",
+               (unsigned long long) start_pfn << PAGE_SHIFT,
+               ((unsigned long long) end_pfn << PAGE_SHIFT) - 1);
 }
 
 /*
index bef86d121eb2ca5bcba2001a447f38e90476c5b5..ece04223bb1ebf99d08a1aa0aab99e14d0fbf994 100644 (file)
@@ -269,7 +269,7 @@ int suspend_devices_and_enter(suspend_state_t state)
        suspend_test_start();
        error = dpm_suspend_start(PMSG_SUSPEND);
        if (error) {
-               printk(KERN_ERR "PM: Some devices failed to suspend\n");
+               pr_err("PM: Some devices failed to suspend, or early wake event detected\n");
                goto Recover_platform;
        }
        suspend_test_finish("suspend devices");
index 113411bfe8b1205ad0f26556776f2a317e06eb0c..50e41075ac77105fd26d190b2068929af6c4becc 100644 (file)
@@ -2848,7 +2848,7 @@ int do_sigtimedwait(const sigset_t *which, siginfo_t *info,
                recalc_sigpending();
                spin_unlock_irq(&tsk->sighand->siglock);
 
-               timeout = schedule_timeout_interruptible(timeout);
+               timeout = freezable_schedule_timeout_interruptible(timeout);
 
                spin_lock_irq(&tsk->sighand->siglock);
                __set_task_blocked(tsk, &tsk->real_blocked);
index 1ad92b46753edfe8d9f54fae81c5f3aa15b34110..081b4d654ed6d68f5538a831719de7331110fa2f 100644 (file)
@@ -1621,6 +1621,7 @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
 {
        return __offline_pages(start_pfn, start_pfn + nr_pages, 120 * HZ);
 }
+#endif /* CONFIG_MEMORY_HOTREMOVE */
 
 /**
  * walk_memory_range - walks through all mem sections in [start_pfn, end_pfn)
@@ -1634,7 +1635,7 @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
  *
  * Returns the return value of func.
  */
-static int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn,
+int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn,
                void *arg, int (*func)(struct memory_block *, void *))
 {
        struct memory_block *mem = NULL;
@@ -1671,24 +1672,7 @@ static int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn,
        return 0;
 }
 
-/**
- * offline_memory_block_cb - callback function for offlining memory block
- * @mem: the memory block to be offlined
- * @arg: buffer to hold error msg
- *
- * Always return 0, and put the error msg in arg if any.
- */
-static int offline_memory_block_cb(struct memory_block *mem, void *arg)
-{
-       int *ret = arg;
-       int error = offline_memory_block(mem);
-
-       if (error != 0 && *ret == 0)
-               *ret = error;
-
-       return 0;
-}
-
+#ifdef CONFIG_MEMORY_HOTREMOVE
 static int is_memblock_offlined_cb(struct memory_block *mem, void *arg)
 {
        int ret = !is_memblock_offlined(mem);
@@ -1814,54 +1798,22 @@ void try_offline_node(int nid)
 }
 EXPORT_SYMBOL(try_offline_node);
 
-int __ref remove_memory(int nid, u64 start, u64 size)
+void __ref remove_memory(int nid, u64 start, u64 size)
 {
-       unsigned long start_pfn, end_pfn;
-       int ret = 0;
-       int retry = 1;
-
-       start_pfn = PFN_DOWN(start);
-       end_pfn = PFN_UP(start + size - 1);
-
-       /*
-        * When CONFIG_MEMCG is on, one memory block may be used by other
-        * blocks to store page cgroup when onlining pages. But we don't know
-        * in what order pages are onlined. So we iterate twice to offline
-        * memory:
-        * 1st iterate: offline every non primary memory block.
-        * 2nd iterate: offline primary (i.e. first added) memory block.
-        */
-repeat:
-       walk_memory_range(start_pfn, end_pfn, &ret,
-                         offline_memory_block_cb);
-       if (ret) {
-               if (!retry)
-                       return ret;
-
-               retry = 0;
-               ret = 0;
-               goto repeat;
-       }
+       int ret;
 
        lock_memory_hotplug();
 
        /*
-        * we have offlined all memory blocks like this:
-        *   1. lock memory hotplug
-        *   2. offline a memory block
-        *   3. unlock memory hotplug
-        *
-        * repeat step1-3 to offline the memory block. All memory blocks
-        * must be offlined before removing memory. But we don't hold the
-        * lock in the whole operation. So we should check whether all
-        * memory blocks are offlined.
+        * All memory blocks must be offlined before removing memory.  Check
+        * whether all memory blocks in question are offline and trigger a BUG()
+        * if this is not the case.
         */
-
-       ret = walk_memory_range(start_pfn, end_pfn, NULL,
+       ret = walk_memory_range(PFN_DOWN(start), PFN_UP(start + size - 1), NULL,
                                is_memblock_offlined_cb);
        if (ret) {
                unlock_memory_hotplug();
-               return ret;
+               BUG();
        }
 
        /* remove memmap entry */
@@ -1872,17 +1824,6 @@ repeat:
        try_offline_node(nid);
 
        unlock_memory_hotplug();
-
-       return 0;
 }
-#else
-int offline_pages(unsigned long start_pfn, unsigned long nr_pages)
-{
-       return -EINVAL;
-}
-int remove_memory(int nid, u64 start, u64 size)
-{
-       return -EINVAL;
-}
-#endif /* CONFIG_MEMORY_HOTREMOVE */
 EXPORT_SYMBOL_GPL(remove_memory);
+#endif /* CONFIG_MEMORY_HOTREMOVE */
index 5356b120dbf8e2fe61ba88081d1fab1941f135a9..77d251e0259315eeef4acd4de50def4382bba5e1 100644 (file)
@@ -254,7 +254,7 @@ static int rpc_wait_bit_killable(void *word)
 {
        if (fatal_signal_pending(current))
                return -ERESTARTSYS;
-       freezable_schedule();
+       freezable_schedule_unsafe();
        return 0;
 }
 
index 826e09938bff4203def6e5af33db49c4360f3019..c4ce243824bb19c6e600dd98da2d8a6d16747dc1 100644 (file)
 #include <linux/mount.h>
 #include <net/checksum.h>
 #include <linux/security.h>
+#include <linux/freezer.h>
 
 struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
 EXPORT_SYMBOL_GPL(unix_socket_table);
@@ -1879,7 +1880,7 @@ static long unix_stream_data_wait(struct sock *sk, long timeo,
 
                set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
                unix_state_unlock(sk);
-               timeo = schedule_timeout(timeo);
+               timeo = freezable_schedule_timeout(timeo);
                unix_state_lock(sk);
                clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
        }