ACPI and power management updates for v3.20-rc1

- Rework of the core ACPI resources parsing code to fix issues
    in it and make using resource offsets more convenient and
    consolidation of some resource-handing code in a couple of places
    that have grown analagous data structures and code to cover the
    the same gap in the core (Jiang Liu, Thomas Gleixner, Lv Zheng).
 
  - ACPI-based IOAPIC hotplug support on top of the resources handling
    rework (Jiang Liu, Yinghai Lu).
 
  - ACPICA update to upstream release 20150204 including an interrupt
    handling rework that allows drivers to install raw handlers for
    ACPI GPEs which then become entirely responsible for the given GPE
    and the ACPICA core code won't touch it (Lv Zheng, David E Box,
    Octavian Purdila).
 
  - ACPI EC driver rework to fix several concurrency issues and other
    problems related to events handling on top of the ACPICA's new
    support for raw GPE handlers (Lv Zheng).
 
  - New ACPI driver for AMD SoCs analogous to the LPSS (Low-Power
    Subsystem) driver for Intel chips (Ken Xue).
 
  - Two minor fixes of the ACPI LPSS driver (Heikki Krogerus,
    Jarkko Nikula).
 
  - Two new blacklist entries for machines (Samsung 730U3E/740U3E and
    510R) where the native backlight interface doesn't work correctly
    while the ACPI one does (Hans de Goede).
 
  - Rework of the ACPI processor driver's handling of idle states
    to make the code more straightforward and less bloated overall
    (Rafael J Wysocki).
 
  - Assorted minor fixes related to ACPI and SFI (Andreas Ruprecht,
    Andy Shevchenko, Hanjun Guo, Jan Beulich, Rafael J Wysocki,
    Yaowei Bai).
 
  - PCI core power management modification to avoid resuming (some)
    runtime-suspended devices during system suspend if they are in
    the right states already (Rafael J Wysocki).
 
  - New SFI-based cpufreq driver for Intel platforms using SFI
    (Srinidhi Kasagar).
 
  - cpufreq core fixes, cleanups and simplifications (Viresh Kumar,
    Doug Anderson, Wolfram Sang).
 
  - SkyLake CPU support and other updates for the intel_pstate driver
    (Kristen Carlson Accardi, Srinivas Pandruvada).
 
  - cpufreq-dt driver cleanup (Markus Elfring).
 
  - Init fix for the ARM big.LITTLE cpuidle driver (Sudeep Holla).
 
  - Generic power domains core code fixes and cleanups (Ulf Hansson).
 
  - Operating Performance Points (OPP) core code cleanups and kernel
    documentation update (Nishanth Menon).
 
  - New dabugfs interface to make the list of PM QoS constraints
    available to user space (Nishanth Menon).
 
  - New devfreq driver for Tegra Activity Monitor (Tomeu Vizoso).
 
  - New devfreq class (devfreq_event) to provide raw utilization data
    to devfreq governors (Chanwoo Choi).
 
  - Assorted minor fixes and cleanups related to power management
    (Andreas Ruprecht, Krzysztof Kozlowski, Rickard Strandqvist,
    Pavel Machek, Todd E Brandt, Wonhong Kwon).
 
  - turbostat updates (Len Brown) and cpupower Makefile improvement
    (Sriram Raghunathan).
 
 /
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABCAAGBQJU2neOAAoJEILEb/54YlRx51QP/jrv1Wb5eMaemzMksPIWI5Zn
 I8IbxzToxu7wDDsrTBRv+LuyllMPrnppFOHHvB35gUYu7Y6I066s3ErwuqeFlbmy
 +VicmyGMahv3yN74qg49MXzWtaJZa8hrFXn8ItujiUIcs08yELi0vBQFlZImIbTB
 PdQngO88VfiOVjDvmKkYUU//9Sc9LCU0ZcdUQXSnA1oNOxuUHjiARz98R03hhSqu
 BWR+7M0uaFbu6XeK+BExMXJTpKicIBZ1GAF6hWrS8V4aYg+hH1cwjf2neDAzZkcU
 UkXieJlLJrCq+ZBNcy7WEhkWQkqJNWei5WYiy6eoQeQpNoliY2V+2OtSMJaKqDye
 PIiMwXstyDc5rgyULN0d1UUzY6mbcUt2rOL0VN2bsFVIJ1HWCq8mr8qq689pQUYv
 tcH18VQ2/6r2zW28sTO/ByWLYomklD/Y6bw2onMhGx3Knl0D8xYJKapVnTGhr5eY
 d4k41ybHSWNKfXsZxdJc+RxndhPwj9rFLfvY/CZEhLcW+2pAiMarRDOPXDoUI7/l
 aJpmPzy/6mPXGBnTfr6jKDSY3gXNazRIvfPbAdiGayKcHcdRM4glbSbNH0/h1Iq6
 HKa8v9Fx87k1X5r4ZbhiPdABWlxuKDiM7725rfGpvjlWC3GNFOq7YTVMOuuBA225
 Mu9PRZbOsZsnyNkixBpX
 =zZER
 -----END PGP SIGNATURE-----

Merge tag 'pm+acpi-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull ACPI and power management updates from Rafael Wysocki:
 "We have a few new features this time, including a new SFI-based
  cpufreq driver, a new devfreq driver for Tegra Activity Monitor, a new
  devfreq class for providing its governors with raw utilization data
  and a new ACPI driver for AMD SoCs.

  Still, the majority of changes here are reworks of existing code to
  make it more straightforward or to prepare it for implementing new
  features on top of it.  The primary example is the rework of ACPI
  resources handling from Jiang Liu, Thomas Gleixner and Lv Zheng with
  support for IOAPIC hotplug implemented on top of it, but there is
  quite a number of changes of this kind in the cpufreq core, ACPICA,
  ACPI EC driver, ACPI processor driver and the generic power domains
  core code too.

  The most active developer is Viresh Kumar with his cpufreq changes.

  Specifics:

   - Rework of the core ACPI resources parsing code to fix issues in it
     and make using resource offsets more convenient and consolidation
     of some resource-handing code in a couple of places that have grown
     analagous data structures and code to cover the the same gap in the
     core (Jiang Liu, Thomas Gleixner, Lv Zheng).

   - ACPI-based IOAPIC hotplug support on top of the resources handling
     rework (Jiang Liu, Yinghai Lu).

   - ACPICA update to upstream release 20150204 including an interrupt
     handling rework that allows drivers to install raw handlers for
     ACPI GPEs which then become entirely responsible for the given GPE
     and the ACPICA core code won't touch it (Lv Zheng, David E Box,
     Octavian Purdila).

   - ACPI EC driver rework to fix several concurrency issues and other
     problems related to events handling on top of the ACPICA's new
     support for raw GPE handlers (Lv Zheng).

   - New ACPI driver for AMD SoCs analogous to the LPSS (Low-Power
     Subsystem) driver for Intel chips (Ken Xue).

   - Two minor fixes of the ACPI LPSS driver (Heikki Krogerus, Jarkko
     Nikula).

   - Two new blacklist entries for machines (Samsung 730U3E/740U3E and
     510R) where the native backlight interface doesn't work correctly
     while the ACPI one does (Hans de Goede).

   - Rework of the ACPI processor driver's handling of idle states to
     make the code more straightforward and less bloated overall (Rafael
     J Wysocki).

   - Assorted minor fixes related to ACPI and SFI (Andreas Ruprecht,
     Andy Shevchenko, Hanjun Guo, Jan Beulich, Rafael J Wysocki, Yaowei
     Bai).

   - PCI core power management modification to avoid resuming (some)
     runtime-suspended devices during system suspend if they are in the
     right states already (Rafael J Wysocki).

   - New SFI-based cpufreq driver for Intel platforms using SFI
     (Srinidhi Kasagar).

   - cpufreq core fixes, cleanups and simplifications (Viresh Kumar,
     Doug Anderson, Wolfram Sang).

   - SkyLake CPU support and other updates for the intel_pstate driver
     (Kristen Carlson Accardi, Srinivas Pandruvada).

   - cpufreq-dt driver cleanup (Markus Elfring).

   - Init fix for the ARM big.LITTLE cpuidle driver (Sudeep Holla).

   - Generic power domains core code fixes and cleanups (Ulf Hansson).

   - Operating Performance Points (OPP) core code cleanups and kernel
     documentation update (Nishanth Menon).

   - New dabugfs interface to make the list of PM QoS constraints
     available to user space (Nishanth Menon).

   - New devfreq driver for Tegra Activity Monitor (Tomeu Vizoso).

   - New devfreq class (devfreq_event) to provide raw utilization data
     to devfreq governors (Chanwoo Choi).

   - Assorted minor fixes and cleanups related to power management
     (Andreas Ruprecht, Krzysztof Kozlowski, Rickard Strandqvist, Pavel
     Machek, Todd E Brandt, Wonhong Kwon).

   - turbostat updates (Len Brown) and cpupower Makefile improvement
     (Sriram Raghunathan)"

* tag 'pm+acpi-3.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (151 commits)
  tools/power turbostat: relax dependency on APERF_MSR
  tools/power turbostat: relax dependency on invariant TSC
  Merge branch 'pci/host-generic' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci into acpi-resources
  tools/power turbostat: decode MSR_*_PERF_LIMIT_REASONS
  tools/power turbostat: relax dependency on root permission
  ACPI / video: Add disable_native_backlight quirk for Samsung 510R
  ACPI / PM: Remove unneeded nested #ifdef
  USB / PM: Remove unneeded #ifdef and associated dead code
  intel_pstate: provide option to only use intel_pstate with HWP
  ACPI / EC: Add GPE reference counting debugging messages
  ACPI / EC: Add query flushing support
  ACPI / EC: Refine command storm prevention support
  ACPI / EC: Add command flushing support.
  ACPI / EC: Introduce STARTED/STOPPED flags to replace BLOCKED flag
  ACPI: add AMD ACPI2Platform device support for x86 system
  ACPI / table: remove duplicate NULL check for the handler of acpi_table_parse()
  ACPI / EC: Update revision due to raw handler mode.
  ACPI / EC: Reduce ec_poll() by referencing the last register access timestamp.
  ACPI / EC: Fix several GPE handling issues by deploying ACPI_GPE_DISPATCH_RAW_HANDLER mode.
  ACPICA: Events: Enable APIs to allow interrupt/polling adaptive request based GPE handling model
  ...
This commit is contained in:
Linus Torvalds 2015-02-10 15:09:41 -08:00
commit 872912352c
299 changed files with 5325 additions and 1837 deletions

View File

@ -243,7 +243,7 @@ input driver:
.owner = THIS_MODULE,
.pm = &mpu3050_pm,
.of_match_table = mpu3050_of_match,
.acpi_match_table ACPI_PTR(mpu3050_acpi_match),
.acpi_match_table = ACPI_PTR(mpu3050_acpi_match),
},
.probe = mpu3050_probe,
.remove = mpu3050_remove,

View File

@ -37,6 +37,14 @@ controlling P state selection. These files have been added to
no_turbo: limits the driver to selecting P states below the turbo
frequency range.
turbo_pct: displays the percentage of the total performance that
is supported by hardware that is in the turbo range. This number
is independent of whether turbo has been disabled or not.
num_pstates: displays the number of pstates that are supported
by hardware. This number is independent of whether turbo has
been disabled or not.
For contemporary Intel processors, the frequency is controlled by the
processor itself and the P-states exposed to software are related to
performance levels. The idea that frequency can be set to a single

View File

@ -0,0 +1,110 @@
* Samsung Exynos PPMU (Platform Performance Monitoring Unit) device
The Samsung Exynos SoC has PPMU (Platform Performance Monitoring Unit) for
each IP. PPMU provides the primitive values to get performance data. These
PPMU events provide information of the SoC's behaviors so that you may
use to analyze system performance, to make behaviors visible and to count
usages of each IP (DMC, CPU, RIGHTBUS, LEFTBUS, CAM interface, LCD, G3D, MFC).
The Exynos PPMU driver uses the devfreq-event class to provide event data
to various devfreq devices. The devfreq devices would use the event data when
derterming the current state of each IP.
Required properties:
- compatible: Should be "samsung,exynos-ppmu".
- reg: physical base address of each PPMU and length of memory mapped region.
Optional properties:
- clock-names : the name of clock used by the PPMU, "ppmu"
- clocks : phandles for clock specified in "clock-names" property
- #clock-cells: should be 1.
Example1 : PPMU nodes in exynos3250.dtsi are listed below.
ppmu_dmc0: ppmu_dmc0@106a0000 {
compatible = "samsung,exynos-ppmu";
reg = <0x106a0000 0x2000>;
status = "disabled";
};
ppmu_dmc1: ppmu_dmc1@106b0000 {
compatible = "samsung,exynos-ppmu";
reg = <0x106b0000 0x2000>;
status = "disabled";
};
ppmu_cpu: ppmu_cpu@106c0000 {
compatible = "samsung,exynos-ppmu";
reg = <0x106c0000 0x2000>;
status = "disabled";
};
ppmu_rightbus: ppmu_rightbus@112a0000 {
compatible = "samsung,exynos-ppmu";
reg = <0x112a0000 0x2000>;
clocks = <&cmu CLK_PPMURIGHT>;
clock-names = "ppmu";
status = "disabled";
};
ppmu_leftbus: ppmu_leftbus0@116a0000 {
compatible = "samsung,exynos-ppmu";
reg = <0x116a0000 0x2000>;
clocks = <&cmu CLK_PPMULEFT>;
clock-names = "ppmu";
status = "disabled";
};
Example2 : Events of each PPMU node in exynos3250-rinato.dts are listed below.
&ppmu_dmc0 {
status = "okay";
events {
ppmu_dmc0_3: ppmu-event3-dmc0 {
event-name = "ppmu-event3-dmc0";
};
ppmu_dmc0_2: ppmu-event2-dmc0 {
event-name = "ppmu-event2-dmc0";
};
ppmu_dmc0_1: ppmu-event1-dmc0 {
event-name = "ppmu-event1-dmc0";
};
ppmu_dmc0_0: ppmu-event0-dmc0 {
event-name = "ppmu-event0-dmc0";
};
};
};
&ppmu_dmc1 {
status = "okay";
events {
ppmu_dmc1_3: ppmu-event3-dmc1 {
event-name = "ppmu-event3-dmc1";
};
};
};
&ppmu_leftbus {
status = "okay";
events {
ppmu_leftbus_3: ppmu-event3-leftbus {
event-name = "ppmu-event3-leftbus";
};
};
};
&ppmu_rightbus {
status = "okay";
events {
ppmu_rightbus_3: ppmu-event3-rightbus {
event-name = "ppmu-event3-rightbus";
};
};
};

View File

@ -1470,6 +1470,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
no_hwp
Do not enable hardware P state control (HWP)
if available.
hwp_only
Only load intel_pstate on systems which support
hardware P state control (HWP) if available.
intremap= [X86-64, Intel-IOMMU]
on enable Interrupt Remapping (default)

View File

@ -69,6 +69,10 @@ Reason for this is that the RTC is the only reliably available piece of
hardware during resume operations where a value can be set that will
survive a reboot.
pm_trace is not compatible with asynchronous suspend, so it turns
asynchronous suspend off (which may work around timing or
ordering-sensitive bugs).
Consequence is that after a resume (even if it is successful) your system
clock will have a value corresponding to the magic number instead of the
correct date/time! It is therefore advisable to use a program like ntp-date

View File

@ -270,12 +270,12 @@ F: drivers/acpi/
F: drivers/pnp/pnpacpi/
F: include/linux/acpi.h
F: include/acpi/
F: Documentation/acpi
F: Documentation/acpi/
F: Documentation/ABI/testing/sysfs-bus-acpi
F: drivers/pci/*acpi*
F: drivers/pci/*/*acpi*
F: drivers/pci/*/*/*acpi*
F: tools/power/acpi
F: tools/power/acpi/
ACPI COMPONENT ARCHITECTURE (ACPICA)
M: Robert Moore <robert.moore@intel.com>

View File

@ -422,17 +422,16 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
static int pcibios_init_resources(int busnr, struct pci_sys_data *sys)
{
int ret;
struct pci_host_bridge_window *window;
struct resource_entry *window;
if (list_empty(&sys->resources)) {
pci_add_resource_offset(&sys->resources,
&iomem_resource, sys->mem_offset);
}
list_for_each_entry(window, &sys->resources, list) {
resource_list_for_each_entry(window, &sys->resources)
if (resource_type(window->res) == IORESOURCE_IO)
return 0;
}
sys->io_res.start = (busnr * SZ_64K) ? : pcibios_min_io;
sys->io_res.end = (busnr + 1) * SZ_64K - 1;

View File

@ -69,10 +69,10 @@ static acpi_status find_csr_space(struct acpi_resource *resource, void *data)
status = acpi_resource_to_address64(resource, &addr);
if (ACPI_SUCCESS(status) &&
addr.resource_type == ACPI_MEMORY_RANGE &&
addr.address_length &&
addr.address.address_length &&
addr.producer_consumer == ACPI_CONSUMER) {
space->base = addr.minimum;
space->length = addr.address_length;
space->base = addr.address.minimum;
space->length = addr.address.address_length;
return AE_CTRL_TERMINATE;
}
return AE_OK; /* keep looking */

View File

@ -380,9 +380,6 @@ static void __init acpi_madt_oem_check(char *oem_id, char *oem_table_id)
static int __init acpi_parse_madt(struct acpi_table_header *table)
{
if (!table)
return -EINVAL;
acpi_madt = (struct acpi_table_madt *)table;
acpi_madt_rev = acpi_madt->header.revision;
@ -645,9 +642,6 @@ static int __init acpi_parse_fadt(struct acpi_table_header *table)
struct acpi_table_header *fadt_header;
struct acpi_table_fadt *fadt;
if (!table)
return -EINVAL;
fadt_header = (struct acpi_table_header *)table;
if (fadt_header->revision != 3)
return -ENODEV; /* Only deal with ACPI 2.0 FADT */

View File

@ -188,12 +188,12 @@ static u64 add_io_space(struct pci_root_info *info,
name = (char *)(iospace + 1);
min = addr->minimum;
max = min + addr->address_length - 1;
min = addr->address.minimum;
max = min + addr->address.address_length - 1;
if (addr->info.io.translation_type == ACPI_SPARSE_TRANSLATION)
sparse = 1;
space_nr = new_space(addr->translation_offset, sparse);
space_nr = new_space(addr->address.translation_offset, sparse);
if (space_nr == ~0)
goto free_resource;
@ -247,7 +247,7 @@ static acpi_status resource_to_window(struct acpi_resource *resource,
if (ACPI_SUCCESS(status) &&
(addr->resource_type == ACPI_MEMORY_RANGE ||
addr->resource_type == ACPI_IO_RANGE) &&
addr->address_length &&
addr->address.address_length &&
addr->producer_consumer == ACPI_PRODUCER)
return AE_OK;
@ -284,7 +284,7 @@ static acpi_status add_window(struct acpi_resource *res, void *data)
if (addr.resource_type == ACPI_MEMORY_RANGE) {
flags = IORESOURCE_MEM;
root = &iomem_resource;
offset = addr.translation_offset;
offset = addr.address.translation_offset;
} else if (addr.resource_type == ACPI_IO_RANGE) {
flags = IORESOURCE_IO;
root = &ioport_resource;
@ -297,8 +297,8 @@ static acpi_status add_window(struct acpi_resource *res, void *data)
resource = &info->res[info->res_num];
resource->name = info->name;
resource->flags = flags;
resource->start = addr.minimum + offset;
resource->end = resource->start + addr.address_length - 1;
resource->start = addr.address.minimum + offset;
resource->end = resource->start + addr.address.address_length - 1;
info->res_offset[info->res_num] = offset;
if (insert_resource(root, resource)) {

View File

@ -497,6 +497,17 @@ config X86_INTEL_LPSS
things like clock tree (common clock framework) and pincontrol
which are needed by the LPSS peripheral drivers.
config X86_AMD_PLATFORM_DEVICE
bool "AMD ACPI2Platform devices support"
depends on ACPI
select COMMON_CLK
select PINCTRL
---help---
Select to interpret AMD specific ACPI device to platform device
such as I2C, UART, GPIO found on AMD Carrizo and later chipsets.
I2C and UART depend on COMMON_CLK to set clock. GPIO driver is
implemented under PINCTRL subsystem.
config IOSF_MBI
tristate "Intel SoC IOSF Sideband support for SoC platforms"
depends on PCI

View File

@ -93,8 +93,6 @@ extern raw_spinlock_t pci_config_lock;
extern int (*pcibios_enable_irq)(struct pci_dev *dev);
extern void (*pcibios_disable_irq)(struct pci_dev *dev);
extern bool mp_should_keep_irq(struct device *dev);
struct pci_raw_ops {
int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn,
int reg, int len, u32 *val);

View File

@ -152,6 +152,10 @@
#define MSR_CC6_DEMOTION_POLICY_CONFIG 0x00000668
#define MSR_MC6_DEMOTION_POLICY_CONFIG 0x00000669
#define MSR_CORE_PERF_LIMIT_REASONS 0x00000690
#define MSR_GFX_PERF_LIMIT_REASONS 0x000006B0
#define MSR_RING_PERF_LIMIT_REASONS 0x000006B1
/* Hardware P state interface */
#define MSR_PPERF 0x0000064e
#define MSR_PERF_LIMIT_REASONS 0x0000064f
@ -362,6 +366,7 @@
#define MSR_IA32_PERF_STATUS 0x00000198
#define MSR_IA32_PERF_CTL 0x00000199
#define INTEL_PERF_CTL_MASK 0xffff
#define MSR_AMD_PSTATE_DEF_BASE 0xc0010064
#define MSR_AMD_PERF_STATUS 0xc0010063
#define MSR_AMD_PERF_CTL 0xc0010062

View File

@ -845,13 +845,7 @@ int acpi_ioapic_registered(acpi_handle handle, u32 gsi_base)
static int __init acpi_parse_sbf(struct acpi_table_header *table)
{
struct acpi_table_boot *sb;
sb = (struct acpi_table_boot *)table;
if (!sb) {
printk(KERN_WARNING PREFIX "Unable to map SBF\n");
return -ENODEV;
}
struct acpi_table_boot *sb = (struct acpi_table_boot *)table;
sbf_port = sb->cmos_index; /* Save CMOS port */
@ -865,13 +859,7 @@ static struct resource *hpet_res __initdata;
static int __init acpi_parse_hpet(struct acpi_table_header *table)
{
struct acpi_table_hpet *hpet_tbl;
hpet_tbl = (struct acpi_table_hpet *)table;
if (!hpet_tbl) {
printk(KERN_WARNING PREFIX "Unable to map HPET\n");
return -ENODEV;
}
struct acpi_table_hpet *hpet_tbl = (struct acpi_table_hpet *)table;
if (hpet_tbl->address.space_id != ACPI_SPACE_MEM) {
printk(KERN_WARNING PREFIX "HPET timers must be located in "

View File

@ -10,9 +10,6 @@
struct pci_root_info {
struct acpi_device *bridge;
char name[16];
unsigned int res_num;
struct resource *res;
resource_size_t *res_offset;
struct pci_sysdata sd;
#ifdef CONFIG_PCI_MMCONFIG
bool mcfg_added;
@ -218,130 +215,41 @@ static void teardown_mcfg_map(struct pci_root_info *info)
}
#endif
static acpi_status resource_to_addr(struct acpi_resource *resource,
struct acpi_resource_address64 *addr)
static void validate_resources(struct device *dev, struct list_head *crs_res,
unsigned long type)
{
acpi_status status;
struct acpi_resource_memory24 *memory24;
struct acpi_resource_memory32 *memory32;
struct acpi_resource_fixed_memory32 *fixed_memory32;
LIST_HEAD(list);
struct resource *res1, *res2, *root = NULL;
struct resource_entry *tmp, *entry, *entry2;
memset(addr, 0, sizeof(*addr));
switch (resource->type) {
case ACPI_RESOURCE_TYPE_MEMORY24:
memory24 = &resource->data.memory24;
addr->resource_type = ACPI_MEMORY_RANGE;
addr->minimum = memory24->minimum;
addr->address_length = memory24->address_length;
addr->maximum = addr->minimum + addr->address_length - 1;
return AE_OK;
case ACPI_RESOURCE_TYPE_MEMORY32:
memory32 = &resource->data.memory32;
addr->resource_type = ACPI_MEMORY_RANGE;
addr->minimum = memory32->minimum;
addr->address_length = memory32->address_length;
addr->maximum = addr->minimum + addr->address_length - 1;
return AE_OK;
case ACPI_RESOURCE_TYPE_FIXED_MEMORY32:
fixed_memory32 = &resource->data.fixed_memory32;
addr->resource_type = ACPI_MEMORY_RANGE;
addr->minimum = fixed_memory32->address;
addr->address_length = fixed_memory32->address_length;
addr->maximum = addr->minimum + addr->address_length - 1;
return AE_OK;
case ACPI_RESOURCE_TYPE_ADDRESS16:
case ACPI_RESOURCE_TYPE_ADDRESS32:
case ACPI_RESOURCE_TYPE_ADDRESS64:
status = acpi_resource_to_address64(resource, addr);
if (ACPI_SUCCESS(status) &&
(addr->resource_type == ACPI_MEMORY_RANGE ||
addr->resource_type == ACPI_IO_RANGE) &&
addr->address_length > 0) {
return AE_OK;
}
break;
}
return AE_ERROR;
}
BUG_ON((type & (IORESOURCE_MEM | IORESOURCE_IO)) == 0);
root = (type & IORESOURCE_MEM) ? &iomem_resource : &ioport_resource;
static acpi_status count_resource(struct acpi_resource *acpi_res, void *data)
{
struct pci_root_info *info = data;
struct acpi_resource_address64 addr;
acpi_status status;
list_splice_init(crs_res, &list);
resource_list_for_each_entry_safe(entry, tmp, &list) {
bool free = false;
resource_size_t end;
status = resource_to_addr(acpi_res, &addr);
if (ACPI_SUCCESS(status))
info->res_num++;
return AE_OK;
}
static acpi_status setup_resource(struct acpi_resource *acpi_res, void *data)
{
struct pci_root_info *info = data;
struct resource *res;
struct acpi_resource_address64 addr;
acpi_status status;
unsigned long flags;
u64 start, orig_end, end;
status = resource_to_addr(acpi_res, &addr);
if (!ACPI_SUCCESS(status))
return AE_OK;
if (addr.resource_type == ACPI_MEMORY_RANGE) {
flags = IORESOURCE_MEM;
if (addr.info.mem.caching == ACPI_PREFETCHABLE_MEMORY)
flags |= IORESOURCE_PREFETCH;
} else if (addr.resource_type == ACPI_IO_RANGE) {
flags = IORESOURCE_IO;
} else
return AE_OK;
start = addr.minimum + addr.translation_offset;
orig_end = end = addr.maximum + addr.translation_offset;
/* Exclude non-addressable range or non-addressable portion of range */
end = min(end, (u64)iomem_resource.end);
if (end <= start) {
dev_info(&info->bridge->dev,
"host bridge window [%#llx-%#llx] "
"(ignored, not CPU addressable)\n", start, orig_end);
return AE_OK;
} else if (orig_end != end) {
dev_info(&info->bridge->dev,
"host bridge window [%#llx-%#llx] "
"([%#llx-%#llx] ignored, not CPU addressable)\n",
start, orig_end, end + 1, orig_end);
}
res = &info->res[info->res_num];
res->name = info->name;
res->flags = flags;
res->start = start;
res->end = end;
info->res_offset[info->res_num] = addr.translation_offset;
info->res_num++;
if (!pci_use_crs)
dev_printk(KERN_DEBUG, &info->bridge->dev,
"host bridge window %pR (ignored)\n", res);
return AE_OK;
}
static void coalesce_windows(struct pci_root_info *info, unsigned long type)
{
int i, j;
struct resource *res1, *res2;
for (i = 0; i < info->res_num; i++) {
res1 = &info->res[i];
res1 = entry->res;
if (!(res1->flags & type))
continue;
goto next;
for (j = i + 1; j < info->res_num; j++) {
res2 = &info->res[j];
/* Exclude non-addressable range or non-addressable portion */
end = min(res1->end, root->end);
if (end <= res1->start) {
dev_info(dev, "host bridge window %pR (ignored, not CPU addressable)\n",
res1);
free = true;
goto next;
} else if (res1->end != end) {
dev_info(dev, "host bridge window %pR ([%#llx-%#llx] ignored, not CPU addressable)\n",
res1, (unsigned long long)end + 1,
(unsigned long long)res1->end);
res1->end = end;
}
resource_list_for_each_entry(entry2, crs_res) {
res2 = entry2->res;
if (!(res2->flags & type))
continue;
@ -353,118 +261,92 @@ static void coalesce_windows(struct pci_root_info *info, unsigned long type)
if (resource_overlaps(res1, res2)) {
res2->start = min(res1->start, res2->start);
res2->end = max(res1->end, res2->end);
dev_info(&info->bridge->dev,
"host bridge window expanded to %pR; %pR ignored\n",
dev_info(dev, "host bridge window expanded to %pR; %pR ignored\n",
res2, res1);
res1->flags = 0;
free = true;
goto next;
}
}
next:
resource_list_del(entry);
if (free)
resource_list_free_entry(entry);
else
resource_list_add_tail(entry, crs_res);
}
}
static void add_resources(struct pci_root_info *info,
struct list_head *resources)
struct list_head *resources,
struct list_head *crs_res)
{
int i;
struct resource *res, *root, *conflict;
struct resource_entry *entry, *tmp;
struct resource *res, *conflict, *root = NULL;
coalesce_windows(info, IORESOURCE_MEM);
coalesce_windows(info, IORESOURCE_IO);
for (i = 0; i < info->res_num; i++) {
res = &info->res[i];
validate_resources(&info->bridge->dev, crs_res, IORESOURCE_MEM);
validate_resources(&info->bridge->dev, crs_res, IORESOURCE_IO);
resource_list_for_each_entry_safe(entry, tmp, crs_res) {
res = entry->res;
if (res->flags & IORESOURCE_MEM)
root = &iomem_resource;
else if (res->flags & IORESOURCE_IO)
root = &ioport_resource;
else
continue;
BUG_ON(res);
conflict = insert_resource_conflict(root, res);
if (conflict)
if (conflict) {
dev_info(&info->bridge->dev,
"ignoring host bridge window %pR (conflicts with %s %pR)\n",
res, conflict->name, conflict);
else
pci_add_resource_offset(resources, res,
info->res_offset[i]);
}
}
static void free_pci_root_info_res(struct pci_root_info *info)
{
kfree(info->res);
info->res = NULL;
kfree(info->res_offset);
info->res_offset = NULL;
info->res_num = 0;
}
static void __release_pci_root_info(struct pci_root_info *info)
{
int i;
struct resource *res;
for (i = 0; i < info->res_num; i++) {
res = &info->res[i];
if (!res->parent)
continue;
if (!(res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
continue;
release_resource(res);
resource_list_destroy_entry(entry);
}
}
free_pci_root_info_res(info);
teardown_mcfg_map(info);
kfree(info);
list_splice_tail(crs_res, resources);
}
static void release_pci_root_info(struct pci_host_bridge *bridge)
{
struct resource *res;
struct resource_entry *entry;
struct pci_root_info *info = bridge->release_data;
__release_pci_root_info(info);
resource_list_for_each_entry(entry, &bridge->windows) {
res = entry->res;
if (res->parent &&
(res->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
release_resource(res);
}
teardown_mcfg_map(info);
kfree(info);
}
static void probe_pci_root_info(struct pci_root_info *info,
struct acpi_device *device,
int busnum, int domain)
int busnum, int domain,
struct list_head *list)
{
size_t size;
int ret;
struct resource_entry *entry;
sprintf(info->name, "PCI Bus %04x:%02x", domain, busnum);
info->bridge = device;
info->res_num = 0;
acpi_walk_resources(device->handle, METHOD_NAME__CRS, count_resource,
info);
if (!info->res_num)
return;
size = sizeof(*info->res) * info->res_num;
info->res = kzalloc_node(size, GFP_KERNEL, info->sd.node);
if (!info->res) {
info->res_num = 0;
return;
}
size = sizeof(*info->res_offset) * info->res_num;
info->res_num = 0;
info->res_offset = kzalloc_node(size, GFP_KERNEL, info->sd.node);
if (!info->res_offset) {
kfree(info->res);
info->res = NULL;
return;
}
acpi_walk_resources(device->handle, METHOD_NAME__CRS, setup_resource,
info);
ret = acpi_dev_get_resources(device, list,
acpi_dev_filter_resource_type_cb,
(void *)(IORESOURCE_IO | IORESOURCE_MEM));
if (ret < 0)
dev_warn(&device->dev,
"failed to parse _CRS method, error code %d\n", ret);
else if (ret == 0)
dev_dbg(&device->dev,
"no IO and memory resources present in _CRS\n");
else
resource_list_for_each_entry(entry, list)
entry->res->name = info->name;
}
struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
@ -473,6 +355,8 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
struct pci_root_info *info;
int domain = root->segment;
int busnum = root->secondary.start;
struct resource_entry *res_entry;
LIST_HEAD(crs_res);
LIST_HEAD(resources);
struct pci_bus *bus;
struct pci_sysdata *sd;
@ -520,18 +404,22 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
memcpy(bus->sysdata, sd, sizeof(*sd));
kfree(info);
} else {
probe_pci_root_info(info, device, busnum, domain);
/* insert busn res at first */
pci_add_resource(&resources, &root->secondary);
/*
* _CRS with no apertures is normal, so only fall back to
* defaults or native bridge info if we're ignoring _CRS.
*/
if (pci_use_crs)
add_resources(info, &resources);
else {
free_pci_root_info_res(info);
probe_pci_root_info(info, device, busnum, domain, &crs_res);
if (pci_use_crs) {
add_resources(info, &resources, &crs_res);
} else {
resource_list_for_each_entry(res_entry, &crs_res)
dev_printk(KERN_DEBUG, &device->dev,
"host bridge window %pR (ignored)\n",
res_entry->res);
resource_list_free(&crs_res);
x86_pci_root_bus_resources(busnum, &resources);
}
@ -546,8 +434,9 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
to_pci_host_bridge(bus->bridge),
release_pci_root_info, info);
} else {
pci_free_resource_list(&resources);
__release_pci_root_info(info);
resource_list_free(&resources);
teardown_mcfg_map(info);
kfree(info);
}
}

View File

@ -31,7 +31,7 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources)
{
struct pci_root_info *info = x86_find_pci_root_info(bus);
struct pci_root_res *root_res;
struct pci_host_bridge_window *window;
struct resource_entry *window;
bool found = false;
if (!info)
@ -41,7 +41,7 @@ void x86_pci_root_bus_resources(int bus, struct list_head *resources)
bus);
/* already added by acpi ? */
list_for_each_entry(window, resources, list)
resource_list_for_each_entry(window, resources)
if (window->res->flags & IORESOURCE_BUS) {
found = true;
break;

View File

@ -513,6 +513,31 @@ void __init pcibios_set_cache_line_size(void)
}
}
/*
* Some device drivers assume dev->irq won't change after calling
* pci_disable_device(). So delay releasing of IRQ resource to driver
* unbinding time. Otherwise it will break PM subsystem and drivers
* like xen-pciback etc.
*/
static int pci_irq_notifier(struct notifier_block *nb, unsigned long action,
void *data)
{
struct pci_dev *dev = to_pci_dev(data);
if (action != BUS_NOTIFY_UNBOUND_DRIVER)
return NOTIFY_DONE;
if (pcibios_disable_irq)
pcibios_disable_irq(dev);
return NOTIFY_OK;
}
static struct notifier_block pci_irq_nb = {
.notifier_call = pci_irq_notifier,
.priority = INT_MIN,
};
int __init pcibios_init(void)
{
if (!raw_pci_ops) {
@ -525,6 +550,9 @@ int __init pcibios_init(void)
if (pci_bf_sort >= pci_force_bf)
pci_sort_breadthfirst();
bus_register_notifier(&pci_bus_type, &pci_irq_nb);
return 0;
}
@ -683,12 +711,6 @@ int pcibios_enable_device(struct pci_dev *dev, int mask)
return 0;
}
void pcibios_disable_device (struct pci_dev *dev)
{
if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq)
pcibios_disable_irq(dev);
}
int pci_ext_cfg_avail(void)
{
if (raw_pci_ext_ops)

View File

@ -234,10 +234,10 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
static void intel_mid_pci_irq_disable(struct pci_dev *dev)
{
if (!mp_should_keep_irq(&dev->dev) && dev->irq_managed &&
dev->irq > 0) {
if (dev->irq_managed && dev->irq > 0) {
mp_unmap_irq(dev->irq);
dev->irq_managed = 0;
dev->irq = 0;
}
}

View File

@ -1256,22 +1256,9 @@ static int pirq_enable_irq(struct pci_dev *dev)
return 0;
}
bool mp_should_keep_irq(struct device *dev)
{
if (dev->power.is_prepared)
return true;
#ifdef CONFIG_PM
if (dev->power.runtime_status == RPM_SUSPENDING)
return true;
#endif
return false;
}
static void pirq_disable_irq(struct pci_dev *dev)
{
if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) &&
dev->irq_managed && dev->irq) {
if (io_apic_assign_pci_irqs && dev->irq_managed && dev->irq) {
mp_unmap_irq(dev->irq);
dev->irq = 0;
dev->irq_managed = 0;

View File

@ -397,12 +397,12 @@ static acpi_status check_mcfg_resource(struct acpi_resource *res, void *data)
status = acpi_resource_to_address64(res, &address);
if (ACPI_FAILURE(status) ||
(address.address_length <= 0) ||
(address.address.address_length <= 0) ||
(address.resource_type != ACPI_MEMORY_RANGE))
return AE_OK;
if ((mcfg_res->start >= address.minimum) &&
(mcfg_res->end < (address.minimum + address.address_length))) {
if ((mcfg_res->start >= address.address.minimum) &&
(mcfg_res->end < (address.address.minimum + address.address.address_length))) {
mcfg_res->flags = 1;
return AE_CTRL_TERMINATE;
}

View File

@ -315,6 +315,12 @@ config ACPI_HOTPLUG_MEMORY
To compile this driver as a module, choose M here:
the module will be called acpi_memhotplug.
config ACPI_HOTPLUG_IOAPIC
bool
depends on PCI
depends on X86_IO_APIC
default y
config ACPI_SBS
tristate "Smart Battery System"
depends on X86

View File

@ -40,7 +40,7 @@ acpi-$(CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC) += processor_pdc.o
acpi-y += ec.o
acpi-$(CONFIG_ACPI_DOCK) += dock.o
acpi-y += pci_root.o pci_link.o pci_irq.o
acpi-y += acpi_lpss.o
acpi-y += acpi_lpss.o acpi_apd.o
acpi-y += acpi_platform.o
acpi-y += acpi_pnp.o
acpi-y += int340x_thermal.o
@ -70,6 +70,7 @@ obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
obj-y += container.o
obj-$(CONFIG_ACPI_THERMAL) += thermal.o
obj-y += acpi_memhotplug.o
obj-$(CONFIG_ACPI_HOTPLUG_IOAPIC) += ioapic.o
obj-$(CONFIG_ACPI_BATTERY) += battery.o
obj-$(CONFIG_ACPI_SBS) += sbshc.o
obj-$(CONFIG_ACPI_SBS) += sbs.o

150
drivers/acpi/acpi_apd.c Normal file
View File

@ -0,0 +1,150 @@
/*
* AMD ACPI support for ACPI2platform device.
*
* Copyright (c) 2014,2015 AMD Corporation.
* Authors: Ken Xue <Ken.Xue@amd.com>
* Wu, Jeff <Jeff.Wu@amd.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/clk-provider.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/clkdev.h>
#include <linux/acpi.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/pm.h>
#include "internal.h"
ACPI_MODULE_NAME("acpi_apd");
struct apd_private_data;
/**
* ACPI_APD_SYSFS : add device attributes in sysfs
* ACPI_APD_PM : attach power domain to device
*/
#define ACPI_APD_SYSFS BIT(0)
#define ACPI_APD_PM BIT(1)
/**
* struct apd_device_desc - a descriptor for apd device
* @flags: device flags like %ACPI_APD_SYSFS, %ACPI_APD_PM
* @fixed_clk_rate: fixed rate input clock source for acpi device;
* 0 means no fixed rate input clock source
* @setup: a hook routine to set device resource during create platform device
*
* Device description defined as acpi_device_id.driver_data
*/
struct apd_device_desc {
unsigned int flags;
unsigned int fixed_clk_rate;
int (*setup)(struct apd_private_data *pdata);
};
struct apd_private_data {
struct clk *clk;
struct acpi_device *adev;
const struct apd_device_desc *dev_desc;
};
#ifdef CONFIG_X86_AMD_PLATFORM_DEVICE
#define APD_ADDR(desc) ((unsigned long)&desc)
static int acpi_apd_setup(struct apd_private_data *pdata)
{
const struct apd_device_desc *dev_desc = pdata->dev_desc;
struct clk *clk = ERR_PTR(-ENODEV);
if (dev_desc->fixed_clk_rate) {
clk = clk_register_fixed_rate(&pdata->adev->dev,
dev_name(&pdata->adev->dev),
NULL, CLK_IS_ROOT,
dev_desc->fixed_clk_rate);
clk_register_clkdev(clk, NULL, dev_name(&pdata->adev->dev));
pdata->clk = clk;
}
return 0;
}
static struct apd_device_desc cz_i2c_desc = {
.setup = acpi_apd_setup,
.fixed_clk_rate = 133000000,
};
static struct apd_device_desc cz_uart_desc = {
.setup = acpi_apd_setup,
.fixed_clk_rate = 48000000,
};
#else
#define APD_ADDR(desc) (0UL)
#endif /* CONFIG_X86_AMD_PLATFORM_DEVICE */
/**
* Create platform device during acpi scan attach handle.
* Return value > 0 on success of creating device.
*/
static int acpi_apd_create_device(struct acpi_device *adev,
const struct acpi_device_id *id)
{
const struct apd_device_desc *dev_desc = (void *)id->driver_data;
struct apd_private_data *pdata;
struct platform_device *pdev;
int ret;
if (!dev_desc) {
pdev = acpi_create_platform_device(adev);
return IS_ERR_OR_NULL(pdev) ? PTR_ERR(pdev) : 1;
}
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
pdata->adev = adev;
pdata->dev_desc = dev_desc;
if (dev_desc->setup) {
ret = dev_desc->setup(pdata);
if (ret)
goto err_out;
}
adev->driver_data = pdata;
pdev = acpi_create_platform_device(adev);
if (!IS_ERR_OR_NULL(pdev))
return 1;
ret = PTR_ERR(pdev);
adev->driver_data = NULL;
err_out:
kfree(pdata);
return ret;
}
static const struct acpi_device_id acpi_apd_device_ids[] = {
/* Generic apd devices */
{ "AMD0010", APD_ADDR(cz_i2c_desc) },
{ "AMD0020", APD_ADDR(cz_uart_desc) },
{ "AMD0030", },
{ }
};
static struct acpi_scan_handler apd_handler = {
.ids = acpi_apd_device_ids,
.attach = acpi_apd_create_device,
};
void __init acpi_apd_init(void)
{
acpi_scan_add_handler(&apd_handler);
}

View File

@ -125,7 +125,7 @@ static struct lpss_device_desc lpt_dev_desc = {
};
static struct lpss_device_desc lpt_i2c_dev_desc = {
.flags = LPSS_CLK | LPSS_CLK_GATE | LPSS_LTR,
.flags = LPSS_CLK | LPSS_LTR,
.prv_offset = 0x800,
};
@ -307,7 +307,7 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
{
struct lpss_device_desc *dev_desc;
struct lpss_private_data *pdata;
struct resource_list_entry *rentry;
struct resource_entry *rentry;
struct list_head resource_list;
struct platform_device *pdev;
int ret;
@ -327,13 +327,15 @@ static int acpi_lpss_create_device(struct acpi_device *adev,
goto err_out;
list_for_each_entry(rentry, &resource_list, node)
if (resource_type(&rentry->res) == IORESOURCE_MEM) {
if (resource_type(rentry->res) == IORESOURCE_MEM) {
if (dev_desc->prv_size_override)
pdata->mmio_size = dev_desc->prv_size_override;
else
pdata->mmio_size = resource_size(&rentry->res);
pdata->mmio_base = ioremap(rentry->res.start,
pdata->mmio_size = resource_size(rentry->res);
pdata->mmio_base = ioremap(rentry->res->start,
pdata->mmio_size);
if (!pdata->mmio_base)
goto err_out;
break;
}

View File

@ -101,8 +101,8 @@ acpi_memory_get_resource(struct acpi_resource *resource, void *context)
/* Can we combine the resource range information? */
if ((info->caching == address64.info.mem.caching) &&
(info->write_protect == address64.info.mem.write_protect) &&
(info->start_addr + info->length == address64.minimum)) {
info->length += address64.address_length;
(info->start_addr + info->length == address64.address.minimum)) {
info->length += address64.address.address_length;
return AE_OK;
}
}
@ -114,8 +114,8 @@ acpi_memory_get_resource(struct acpi_resource *resource, void *context)
INIT_LIST_HEAD(&new->list);
new->caching = address64.info.mem.caching;
new->write_protect = address64.info.mem.write_protect;
new->start_addr = address64.minimum;
new->length = address64.address_length;
new->start_addr = address64.address.minimum;
new->length = address64.address.address_length;
list_add_tail(&new->list, &mem_device->res_list);
return AE_OK;

View File

@ -45,7 +45,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
struct platform_device *pdev = NULL;
struct acpi_device *acpi_parent;
struct platform_device_info pdevinfo;
struct resource_list_entry *rentry;
struct resource_entry *rentry;
struct list_head resource_list;
struct resource *resources = NULL;
int count;
@ -71,7 +71,7 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev)
}
count = 0;
list_for_each_entry(rentry, &resource_list, node)
resources[count++] = rentry->res;
resources[count++] = *rentry->res;
acpi_dev_free_resource_list(&resource_list);
}

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -47,7 +47,7 @@
/* Common info for tool signons */
#define ACPICA_NAME "Intel ACPI Component Architecture"
#define ACPICA_COPYRIGHT "Copyright (c) 2000 - 2014 Intel Corporation"
#define ACPICA_COPYRIGHT "Copyright (c) 2000 - 2015 Intel Corporation"
#if ACPI_MACHINE_WIDTH == 64
#define ACPI_WIDTH "-64"

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -143,8 +143,6 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
acpi_status
acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context);
u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info);
acpi_status
acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
struct acpi_gpe_block_info *gpe_block, void *context);

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -7,7 +7,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -6,7 +6,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -6,7 +6,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
******************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
******************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -6,7 +6,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -114,17 +114,6 @@ acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info)
ACPI_FUNCTION_TRACE(ev_enable_gpe);
/*
* We will only allow a GPE to be enabled if it has either an associated
* method (_Lxx/_Exx) or a handler, or is using the implicit notify
* feature. Otherwise, the GPE will be immediately disabled by
* acpi_ev_gpe_dispatch the first time it fires.
*/
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_NONE) {
return_ACPI_STATUS(AE_NO_HANDLER);
}
/* Clear the GPE (of stale events) */
status = acpi_hw_clear_gpe(gpe_event_info);
@ -339,7 +328,11 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list)
{
acpi_status status;
struct acpi_gpe_block_info *gpe_block;
struct acpi_namespace_node *gpe_device;
struct acpi_gpe_register_info *gpe_register_info;
struct acpi_gpe_event_info *gpe_event_info;
u32 gpe_number;
struct acpi_gpe_handler_info *gpe_handler_info;
u32 int_status = ACPI_INTERRUPT_NOT_HANDLED;
u8 enabled_status_byte;
u32 status_reg;
@ -367,6 +360,8 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list)
gpe_block = gpe_xrupt_list->gpe_block_list_head;
while (gpe_block) {
gpe_device = gpe_block->node;
/*
* Read all of the 8-bit GPE status and enable registers in this GPE
* block, saving all of them. Find all currently active GP events.
@ -442,16 +437,68 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list)
/* Examine one GPE bit */
gpe_event_info =
&gpe_block->
event_info[((acpi_size) i *
ACPI_GPE_REGISTER_WIDTH) + j];
gpe_number =
j + gpe_register_info->base_gpe_number;
if (enabled_status_byte & (1 << j)) {
/*
* Found an active GPE. Dispatch the event to a handler
* or method.
*/
int_status |=
acpi_ev_gpe_dispatch(gpe_block->
node,
&gpe_block->
event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number);
/* Invoke global event handler if present */
acpi_gpe_count++;
if (acpi_gbl_global_event_handler) {
acpi_gbl_global_event_handler
(ACPI_EVENT_TYPE_GPE,
gpe_device, gpe_number,
acpi_gbl_global_event_handler_context);
}
/* Found an active GPE */
if (ACPI_GPE_DISPATCH_TYPE
(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_RAW_HANDLER) {
/* Dispatch the event to a raw handler */
gpe_handler_info =
gpe_event_info->dispatch.
handler;
/*
* There is no protection around the namespace node
* and the GPE handler to ensure a safe destruction
* because:
* 1. The namespace node is expected to always
* exist after loading a table.
* 2. The GPE handler is expected to be flushed by
* acpi_os_wait_events_complete() before the
* destruction.
*/
acpi_os_release_lock
(acpi_gbl_gpe_lock, flags);
int_status |=
gpe_handler_info->
address(gpe_device,
gpe_number,
gpe_handler_info->
context);
flags =
acpi_os_acquire_lock
(acpi_gbl_gpe_lock);
} else {
/*
* Dispatch the event to a standard handler or
* method.
*/
int_status |=
acpi_ev_gpe_dispatch
(gpe_device, gpe_event_info,
gpe_number);
}
}
}
}
@ -484,52 +531,15 @@ unlock_and_exit:
static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
{
struct acpi_gpe_event_info *gpe_event_info = context;
acpi_status status;
struct acpi_gpe_event_info *local_gpe_event_info;
acpi_status status = AE_OK;
struct acpi_evaluate_info *info;
struct acpi_gpe_notify_info *notify;
ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method);
/* Allocate a local GPE block */
local_gpe_event_info =
ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_event_info));
if (!local_gpe_event_info) {
ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "while handling a GPE"));
return_VOID;
}
status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS);
if (ACPI_FAILURE(status)) {
ACPI_FREE(local_gpe_event_info);
return_VOID;
}
/* Must revalidate the gpe_number/gpe_block */
if (!acpi_ev_valid_gpe_event(gpe_event_info)) {
status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
ACPI_FREE(local_gpe_event_info);
return_VOID;
}
/*
* Take a snapshot of the GPE info for this level - we copy the info to
* prevent a race condition with remove_handler/remove_block.
*/
ACPI_MEMCPY(local_gpe_event_info, gpe_event_info,
sizeof(struct acpi_gpe_event_info));
status = acpi_ut_release_mutex(ACPI_MTX_EVENTS);
if (ACPI_FAILURE(status)) {
ACPI_FREE(local_gpe_event_info);
return_VOID;
}
/* Do the correct dispatch - normal method or implicit notify */
switch (local_gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
switch (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)) {
case ACPI_GPE_DISPATCH_NOTIFY:
/*
* Implicit notify.
@ -542,7 +552,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
* June 2012: Expand implicit notify mechanism to support
* notifies on multiple device objects.
*/
notify = local_gpe_event_info->dispatch.notify_list;
notify = gpe_event_info->dispatch.notify_list;
while (ACPI_SUCCESS(status) && notify) {
status =
acpi_ev_queue_notify_request(notify->device_node,
@ -566,7 +576,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
* _Lxx/_Exx control method that corresponds to this GPE
*/
info->prefix_node =
local_gpe_event_info->dispatch.method_node;
gpe_event_info->dispatch.method_node;
info->flags = ACPI_IGNORE_RETURN_VALUE;
status = acpi_ns_evaluate(info);
@ -576,25 +586,27 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"while evaluating GPE method [%4.4s]",
acpi_ut_get_node_name
(local_gpe_event_info->dispatch.
method_node)));
acpi_ut_get_node_name(gpe_event_info->
dispatch.
method_node)));
}
break;
default:
return_VOID; /* Should never happen */
goto error_exit; /* Should never happen */
}
/* Defer enabling of GPE until all notify handlers are done */
status = acpi_os_execute(OSL_NOTIFY_HANDLER,
acpi_ev_asynch_enable_gpe,
local_gpe_event_info);
if (ACPI_FAILURE(status)) {
ACPI_FREE(local_gpe_event_info);
acpi_ev_asynch_enable_gpe, gpe_event_info);
if (ACPI_SUCCESS(status)) {
return_VOID;
}
error_exit:
acpi_ev_asynch_enable_gpe(gpe_event_info);
return_VOID;
}
@ -622,7 +634,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context)
(void)acpi_ev_finish_gpe(gpe_event_info);
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
ACPI_FREE(gpe_event_info);
return;
}
@ -692,15 +703,6 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
ACPI_FUNCTION_TRACE(ev_gpe_dispatch);
/* Invoke global event handler if present */
acpi_gpe_count++;
if (acpi_gbl_global_event_handler) {
acpi_gbl_global_event_handler(ACPI_EVENT_TYPE_GPE, gpe_device,
gpe_number,
acpi_gbl_global_event_handler_context);
}
/*
* Always disable the GPE so that it does not keep firing before
* any asynchronous activity completes (either from the execution
@ -741,7 +743,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
* If there is neither a handler nor a method, leave the GPE
* disabled.
*/
switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
switch (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)) {
case ACPI_GPE_DISPATCH_HANDLER:
/* Invoke the installed handler (at interrupt level) */

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -474,10 +474,12 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
* Ignore GPEs that have no corresponding _Lxx/_Exx method
* and GPEs that are used to wake the system
*/
if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_NONE)
|| ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
== ACPI_GPE_DISPATCH_HANDLER)
|| (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_HANDLER)
|| (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_RAW_HANDLER)
|| (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
continue;
}

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -401,15 +401,17 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
return_ACPI_STATUS(AE_OK);
}
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_HANDLER) {
if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_HANDLER) ||
(ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_RAW_HANDLER)) {
/* If there is already a handler, ignore this GPE method */
return_ACPI_STATUS(AE_OK);
}
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_METHOD) {
/*
* If there is already a method, ignore this method. But check

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -106,53 +106,6 @@ unlock_and_exit:
return_ACPI_STATUS(status);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_valid_gpe_event
*
* PARAMETERS: gpe_event_info - Info for this GPE
*
* RETURN: TRUE if the gpe_event is valid
*
* DESCRIPTION: Validate a GPE event. DO NOT CALL FROM INTERRUPT LEVEL.
* Should be called only when the GPE lists are semaphore locked
* and not subject to change.
*
******************************************************************************/
u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
{
struct acpi_gpe_xrupt_info *gpe_xrupt_block;
struct acpi_gpe_block_info *gpe_block;
ACPI_FUNCTION_ENTRY();
/* No need for spin lock since we are not changing any list elements */
/* Walk the GPE interrupt levels */
gpe_xrupt_block = acpi_gbl_gpe_xrupt_list_head;
while (gpe_xrupt_block) {
gpe_block = gpe_xrupt_block->gpe_block_list_head;
/* Walk the GPE blocks on this interrupt level */
while (gpe_block) {
if ((&gpe_block->event_info[0] <= gpe_event_info) &&
(&gpe_block->event_info[gpe_block->gpe_count] >
gpe_event_info)) {
return (TRUE);
}
gpe_block = gpe_block->next;
}
gpe_xrupt_block = gpe_xrupt_block->next;
}
return (FALSE);
}
/*******************************************************************************
*
* FUNCTION: acpi_ev_get_gpe_device
@ -371,8 +324,10 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
ACPI_GPE_REGISTER_WIDTH)
+ j];
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_HANDLER) {
if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_HANDLER) ||
(ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_RAW_HANDLER)) {
/* Delete an installed handler block */
@ -380,10 +335,8 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
gpe_event_info->dispatch.handler = NULL;
gpe_event_info->flags &=
~ACPI_GPE_DISPATCH_MASK;
} else
if ((gpe_event_info->
flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_NOTIFY) {
} else if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)
== ACPI_GPE_DISPATCH_NOTIFY) {
/* Delete the implicit notification device list */

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -6,7 +6,7 @@
******************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -51,6 +51,16 @@
#define _COMPONENT ACPI_EVENTS
ACPI_MODULE_NAME("evxface")
#if (!ACPI_REDUCED_HARDWARE)
/* Local prototypes */
static acpi_status
acpi_ev_install_gpe_handler(acpi_handle gpe_device,
u32 gpe_number,
u32 type,
u8 is_raw_handler,
acpi_gpe_handler address, void *context);
#endif
/*******************************************************************************
@ -76,6 +86,7 @@ ACPI_MODULE_NAME("evxface")
* handlers.
*
******************************************************************************/
acpi_status
acpi_install_notify_handler(acpi_handle device,
u32 handler_type,
@ -717,32 +728,37 @@ ACPI_EXPORT_SYMBOL(acpi_remove_fixed_event_handler)
/*******************************************************************************
*
* FUNCTION: acpi_install_gpe_handler
* FUNCTION: acpi_ev_install_gpe_handler
*
* PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT
* defined GPEs)
* gpe_number - The GPE number within the GPE block
* type - Whether this GPE should be treated as an
* edge- or level-triggered interrupt.
* is_raw_handler - Whether this GPE should be handled using
* the special GPE handler mode.
* address - Address of the handler
* context - Value passed to the handler on each GPE
*
* RETURN: Status
*
* DESCRIPTION: Install a handler for a General Purpose Event.
* DESCRIPTION: Internal function to install a handler for a General Purpose
* Event.
*
******************************************************************************/
acpi_status
acpi_install_gpe_handler(acpi_handle gpe_device,
u32 gpe_number,
u32 type, acpi_gpe_handler address, void *context)
static acpi_status
acpi_ev_install_gpe_handler(acpi_handle gpe_device,
u32 gpe_number,
u32 type,
u8 is_raw_handler,
acpi_gpe_handler address, void *context)
{
struct acpi_gpe_event_info *gpe_event_info;
struct acpi_gpe_handler_info *handler;
acpi_status status;
acpi_cpu_flags flags;
ACPI_FUNCTION_TRACE(acpi_install_gpe_handler);
ACPI_FUNCTION_TRACE(ev_install_gpe_handler);
/* Parameter validation */
@ -775,8 +791,10 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
/* Make sure that there isn't a handler there already */
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_HANDLER) {
if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_HANDLER) ||
(ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_RAW_HANDLER)) {
status = AE_ALREADY_EXISTS;
goto free_and_exit;
}
@ -793,9 +811,10 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
* automatically during initialization, in which case it has to be
* disabled now to avoid spurious execution of the handler.
*/
if (((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) ||
(handler->original_flags & ACPI_GPE_DISPATCH_NOTIFY)) &&
gpe_event_info->runtime_count) {
if (((ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
ACPI_GPE_DISPATCH_METHOD) ||
(ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
ACPI_GPE_DISPATCH_NOTIFY)) && gpe_event_info->runtime_count) {
handler->originally_enabled = TRUE;
(void)acpi_ev_remove_gpe_reference(gpe_event_info);
@ -816,7 +835,10 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
gpe_event_info->flags &=
~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_HANDLER);
gpe_event_info->flags |=
(u8)(type |
(is_raw_handler ? ACPI_GPE_DISPATCH_RAW_HANDLER :
ACPI_GPE_DISPATCH_HANDLER));
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
@ -830,8 +852,76 @@ free_and_exit:
goto unlock_and_exit;
}
/*******************************************************************************
*
* FUNCTION: acpi_install_gpe_handler
*
* PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT
* defined GPEs)
* gpe_number - The GPE number within the GPE block
* type - Whether this GPE should be treated as an
* edge- or level-triggered interrupt.
* address - Address of the handler
* context - Value passed to the handler on each GPE
*
* RETURN: Status
*
* DESCRIPTION: Install a handler for a General Purpose Event.
*
******************************************************************************/
acpi_status
acpi_install_gpe_handler(acpi_handle gpe_device,
u32 gpe_number,
u32 type, acpi_gpe_handler address, void *context)
{
acpi_status status;
ACPI_FUNCTION_TRACE(acpi_install_gpe_handler);
status =
acpi_ev_install_gpe_handler(gpe_device, gpe_number, type, FALSE,
address, context);
return_ACPI_STATUS(status);
}
ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler)
/*******************************************************************************
*
* FUNCTION: acpi_install_gpe_raw_handler
*
* PARAMETERS: gpe_device - Namespace node for the GPE (NULL for FADT
* defined GPEs)
* gpe_number - The GPE number within the GPE block
* type - Whether this GPE should be treated as an
* edge- or level-triggered interrupt.
* address - Address of the handler
* context - Value passed to the handler on each GPE
*
* RETURN: Status
*
* DESCRIPTION: Install a handler for a General Purpose Event.
*
******************************************************************************/
acpi_status
acpi_install_gpe_raw_handler(acpi_handle gpe_device,
u32 gpe_number,
u32 type, acpi_gpe_handler address, void *context)
{
acpi_status status;
ACPI_FUNCTION_TRACE(acpi_install_gpe_raw_handler);
status = acpi_ev_install_gpe_handler(gpe_device, gpe_number, type, TRUE,
address, context);
return_ACPI_STATUS(status);
}
ACPI_EXPORT_SYMBOL(acpi_install_gpe_raw_handler)
/*******************************************************************************
*
* FUNCTION: acpi_remove_gpe_handler
@ -880,8 +970,10 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
/* Make sure that a handler is indeed installed */
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) !=
ACPI_GPE_DISPATCH_HANDLER) {
if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
ACPI_GPE_DISPATCH_HANDLER) &&
(ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
ACPI_GPE_DISPATCH_RAW_HANDLER)) {
status = AE_NOT_EXIST;
goto unlock_and_exit;
}
@ -896,6 +988,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
/* Remove the handler */
handler = gpe_event_info->dispatch.handler;
gpe_event_info->dispatch.handler = NULL;
/* Restore Method node (if any), set dispatch flags */
@ -909,9 +1002,10 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
* enabled, it should be enabled at this point to restore the
* post-initialization configuration.
*/
if (((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) ||
(handler->original_flags & ACPI_GPE_DISPATCH_NOTIFY)) &&
handler->originally_enabled) {
if (((ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
ACPI_GPE_DISPATCH_METHOD) ||
(ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
ACPI_GPE_DISPATCH_NOTIFY)) && handler->originally_enabled) {
(void)acpi_ev_add_gpe_reference(gpe_event_info);
}

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -132,7 +132,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
*/
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (gpe_event_info) {
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) !=
if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
ACPI_GPE_DISPATCH_NONE) {
status = acpi_ev_add_gpe_reference(gpe_event_info);
} else {
@ -183,6 +183,77 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
/*******************************************************************************
*
* FUNCTION: acpi_set_gpe
*
* PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
* gpe_number - GPE level within the GPE block
* action - ACPI_GPE_ENABLE or ACPI_GPE_DISABLE
*
* RETURN: Status
*
* DESCRIPTION: Enable or disable an individual GPE. This function bypasses
* the reference count mechanism used in the acpi_enable_gpe(),
* acpi_disable_gpe() interfaces.
* This API is typically used by the GPE raw handler mode driver
* to switch between the polling mode and the interrupt mode after
* the driver has enabled the GPE.
* The APIs should be invoked in this order:
* acpi_enable_gpe() <- Ensure the reference count > 0
* acpi_set_gpe(ACPI_GPE_DISABLE) <- Enter polling mode
* acpi_set_gpe(ACPI_GPE_ENABLE) <- Leave polling mode
* acpi_disable_gpe() <- Decrease the reference count
*
* Note: If a GPE is shared by 2 silicon components, then both the drivers
* should support GPE polling mode or disabling the GPE for long period
* for one driver may break the other. So use it with care since all
* firmware _Lxx/_Exx handlers currently rely on the GPE interrupt mode.
*
******************************************************************************/
acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action)
{
struct acpi_gpe_event_info *gpe_event_info;
acpi_status status;
acpi_cpu_flags flags;
ACPI_FUNCTION_TRACE(acpi_set_gpe);
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
/* Ensure that we have a valid GPE number */
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
/* Perform the action */
switch (action) {
case ACPI_GPE_ENABLE:
status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE);
break;
case ACPI_GPE_DISABLE:
status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE);
break;
default:
status = AE_BAD_PARAMETER;
break;
}
unlock_and_exit:
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
return_ACPI_STATUS(status);
}
ACPI_EXPORT_SYMBOL(acpi_set_gpe)
/*******************************************************************************
*
@ -313,7 +384,7 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,
* known as an "implicit notify". Note: The GPE is assumed to be
* level-triggered (for windows compatibility).
*/
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_NONE) {
/*
* This is the first device for implicit notify on this GPE.
@ -327,7 +398,7 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device,
* If we already have an implicit notify on this GPE, add
* this device to the notify list.
*/
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
ACPI_GPE_DISPATCH_NOTIFY) {
/* Ensure that the device is not already in the list */
@ -530,6 +601,49 @@ unlock_and_exit:
ACPI_EXPORT_SYMBOL(acpi_get_gpe_status)
/*******************************************************************************
*
* FUNCTION: acpi_finish_gpe
*
* PARAMETERS: gpe_device - Namespace node for the GPE Block
* (NULL for FADT defined GPEs)
* gpe_number - GPE level within the GPE block
*
* RETURN: Status
*
* DESCRIPTION: Clear and conditionally reenable a GPE. This completes the GPE
* processing. Intended for use by asynchronous host-installed
* GPE handlers. The GPE is only reenabled if the enable_for_run bit
* is set in the GPE info.
*
******************************************************************************/
acpi_status acpi_finish_gpe(acpi_handle gpe_device, u32 gpe_number)
{
struct acpi_gpe_event_info *gpe_event_info;
acpi_status status;
acpi_cpu_flags flags;
ACPI_FUNCTION_TRACE(acpi_finish_gpe);
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
/* Ensure that we have a valid GPE number */
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (!gpe_event_info) {
status = AE_BAD_PARAMETER;
goto unlock_and_exit;
}
status = acpi_ev_finish_gpe(gpe_event_info);
unlock_and_exit:
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
return_ACPI_STATUS(status);
}
ACPI_EXPORT_SYMBOL(acpi_finish_gpe)
/******************************************************************************
*
* FUNCTION: acpi_disable_all_gpes
@ -604,7 +718,6 @@ ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes)
* all GPE blocks.
*
******************************************************************************/
acpi_status acpi_enable_all_wakeup_gpes(void)
{
acpi_status status;

View File

@ -6,7 +6,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -6,7 +6,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

View File

@ -5,7 +5,7 @@
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, Intel Corp.
* Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without

Some files were not shown because too many files have changed in this diff Show More