Commit 77251319 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull ACPI and power management updates from Rafael Wysocki:
 "Again, ACPICA leads the pack (47 commits), followed by cpufreq (18
  commits) and system suspend/hibernation (9 commits).

  From the new code perspective, the ACPICA update brings ACPI 5.1 to
  the table, including a new device configuration object called _DSD
  (Device Specific Data) that will hopefully help us to operate device
  properties like Device Trees do (at least to some extent) and changes
  related to supporting ACPI on ARM.

  Apart from that we have hibernation changes making it use radix trees
  to store memory bitmaps which should speed up some operations carried
  out by it quite significantly.  We also have some power management
  changes related to suspend-to-idle (the "freeze" sleep state) support
  and more preliminary changes needed to support ACPI on ARM (outside of
  ACPICA).

  The rest is fixes and cleanups pretty much everywhere.

  Specifics:

   - ACPICA update to upstream version 20140724.  That includes ACPI 5.1
     material (support for the _CCA and _DSD predefined names, changes
     related to the DMAR and PCCT tables and ARM support among other
     things) and cleanups related to using ACPICA's header files.  A
     major part of it is related to acpidump and the core code used by
     that utility.  Changes from Bob Moore, David E Box, Lv Zheng,
     Sascha Wildner, Tomasz Nowicki, Hanjun Guo.

   - Radix trees for memory bitmaps used by the hibernation core from
     Joerg Roedel.

   - Support for waking up the system from suspend-to-idle (also known
     as the "freeze" sleep state) using ACPI-based PCI wakeup signaling
     (Rafael J Wysocki).

   - Fixes for issues related to ACPI button events (Rafael J Wysocki).

   - New device ID for an ACPI-enumerated device included into the
     Wildcat Point PCH from Jie Yang.

   - ACPI video updates related to backlight handling from Hans de Goede
     and Linus Torvalds.

   - Preliminary changes needed to support ACPI on ARM from Hanjun Guo
     and Graeme Gregory.

   - ACPI PNP core cleanups from Arjun Sreedharan and Zhang Rui.

   - Cleanups related to ACPI_COMPANION() and ACPI_HANDLE() macros
     (Rafael J Wysocki).

   - ACPI-based device hotplug cleanups from Wei Yongjun and Rafael J
     Wysocki.

   - Cleanups and improvements related to system suspend from Lan
     Tianyu, Randy Dunlap and Rafael J Wysocki.

   - ACPI battery cleanup from Wei Yongjun.

   - cpufreq core fixes from Viresh Kumar.

   - Elimination of a deadband effect from the cpufreq ondemand governor
     and intel_pstate driver cleanups from Stratos Karafotis.

   - 350MHz CPU support for the powernow-k6 cpufreq driver from Mikulas
     Patocka.

   - Fix for the imx6 cpufreq driver from Anson Huang.

   - cpuidle core and governor cleanups from Daniel Lezcano, Sandeep
     Tripathy and Mohammad Merajul Islam Molla.

   - Build fix for the big_little cpuidle driver from Sachin Kamat.

   - Configuration fix for the Operation Performance Points (OPP)
     framework from Mark Brown.

   - APM cleanup from Jean Delvare.

   - cpupower utility fixes and cleanups from Peter Senna Tschudin,
     Andrey Utkin, Himangi Saraogi, Rickard Strandqvist, Thomas
     Renninger"

* tag 'pm+acpi-3.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (118 commits)
  ACPI / LPSS: add LPSS device for Wildcat Point PCH
  ACPI / PNP: Replace faulty is_hex_digit() by isxdigit()
  ACPICA: Update version to 20140724.
  ACPICA: ACPI 5.1: Update for PCCT table changes.
  ACPICA/ARM: ACPI 5.1: Update for GTDT table changes.
  ACPICA/ARM: ACPI 5.1: Update for MADT changes.
  ACPICA/ARM: ACPI 5.1: Update for FADT changes.
  ACPICA: ACPI 5.1: Support for the _CCA predifined name.
  ACPICA: ACPI 5.1: New notify value for System Affinity Update.
  ACPICA: ACPI 5.1: Support for the _DSD predefined name.
  ACPICA: Debug object: Add current value of Timer() to debug line prefix.
  ACPICA: acpihelp: Add UUID support, restructure some existing files.
  ACPICA: Utilities: Fix local printf issue.
  ACPICA: Tables: Update for DMAR table changes.
  ACPICA: Remove some extraneous printf arguments.
  ACPICA: Update for comments/formatting. No functional changes.
  ACPICA: Disassembler: Add support for the ToUUID opererator (macro).
  ACPICA: Remove a redundant cast to acpi_size for ACPI_OFFSET() macro.
  ACPICA: Work around an ancient GCC bug.
  ACPI / processor: Make it possible to get local x2apic id via _MAT
  ...
parents 6b22df74 7ef97e0e
...@@ -51,9 +51,6 @@ Typical usage of the OPP library is as follows: ...@@ -51,9 +51,6 @@ Typical usage of the OPP library is as follows:
SoC framework -> modifies on required cases certain OPPs -> OPP layer SoC framework -> modifies on required cases certain OPPs -> OPP layer
-> queries to search/retrieve information -> -> queries to search/retrieve information ->
Architectures that provide a SoC framework for OPP should select ARCH_HAS_OPP
to make the OPP layer available.
OPP layer expects each domain to be represented by a unique device pointer. SoC OPP layer expects each domain to be represented by a unique device pointer. SoC
framework registers a set of initial OPPs per device with the OPP layer. This framework registers a set of initial OPPs per device with the OPP layer. This
list is expected to be an optimally small number typically around 5 per device. list is expected to be an optimally small number typically around 5 per device.
......
...@@ -2556,8 +2556,8 @@ F: arch/x86/kernel/cpuid.c ...@@ -2556,8 +2556,8 @@ F: arch/x86/kernel/cpuid.c
F: arch/x86/kernel/msr.c F: arch/x86/kernel/msr.c
CPU POWER MONITORING SUBSYSTEM CPU POWER MONITORING SUBSYSTEM
M: Dominik Brodowski <linux@dominikbrodowski.net>
M: Thomas Renninger <trenn@suse.de> M: Thomas Renninger <trenn@suse.de>
L: linux-pm@vger.kernel.org
S: Maintained S: Maintained
F: tools/power/cpupower/ F: tools/power/cpupower/
...@@ -7066,8 +7066,10 @@ F: include/linux/timer* ...@@ -7066,8 +7066,10 @@ F: include/linux/timer*
F: kernel/time/*timer* F: kernel/time/*timer*
POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS POWER SUPPLY CLASS/SUBSYSTEM and DRIVERS
M: Sebastian Reichel <sre@kernel.org>
M: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> M: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
M: David Woodhouse <dwmw2@infradead.org> M: David Woodhouse <dwmw2@infradead.org>
L: linux-pm@vger.kernel.org
T: git git://git.infradead.org/battery-2.6.git T: git git://git.infradead.org/battery-2.6.git
S: Maintained S: Maintained
F: include/linux/power_supply.h F: include/linux/power_supply.h
......
...@@ -100,7 +100,6 @@ config SOC_EXYNOS5440 ...@@ -100,7 +100,6 @@ config SOC_EXYNOS5440
default y default y
depends on ARCH_EXYNOS5 depends on ARCH_EXYNOS5
select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
select ARCH_HAS_OPP
select HAVE_ARM_ARCH_TIMER select HAVE_ARM_ARCH_TIMER
select AUTO_ZRELADDR select AUTO_ZRELADDR
select MIGHT_HAVE_PCI select MIGHT_HAVE_PCI
......
...@@ -2,7 +2,6 @@ config ARCH_HIGHBANK ...@@ -2,7 +2,6 @@ config ARCH_HIGHBANK
bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7 bool "Calxeda ECX-1000/2000 (Highbank/Midway)" if ARCH_MULTI_V7
select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
select ARCH_HAS_HOLES_MEMORYMODEL select ARCH_HAS_HOLES_MEMORYMODEL
select ARCH_HAS_OPP
select ARCH_SUPPORTS_BIG_ENDIAN select ARCH_SUPPORTS_BIG_ENDIAN
select ARM_AMBA select ARM_AMBA
select ARM_ERRATA_764369 if SMP select ARM_ERRATA_764369 if SMP
......
menuconfig ARCH_MXC menuconfig ARCH_MXC
bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7
select ARCH_HAS_OPP
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select ARM_CPU_SUSPEND if PM select ARM_CPU_SUSPEND if PM
select CLKSRC_MMIO select CLKSRC_MMIO
......
...@@ -15,7 +15,6 @@ config ARCH_OMAP3 ...@@ -15,7 +15,6 @@ config ARCH_OMAP3
bool "TI OMAP3" bool "TI OMAP3"
depends on ARCH_MULTI_V7 depends on ARCH_MULTI_V7
select ARCH_OMAP2PLUS select ARCH_OMAP2PLUS
select ARCH_HAS_OPP
select ARM_CPU_SUSPEND if PM select ARM_CPU_SUSPEND if PM
select OMAP_INTERCONNECT select OMAP_INTERCONNECT
select PM_OPP if PM select PM_OPP if PM
......
...@@ -85,7 +85,6 @@ config ARCH_R8A73A4 ...@@ -85,7 +85,6 @@ config ARCH_R8A73A4
select CPU_V7 select CPU_V7
select SH_CLK_CPG select SH_CLK_CPG
select RENESAS_IRQC select RENESAS_IRQC
select ARCH_HAS_OPP
select SYS_SUPPORTS_SH_CMT select SYS_SUPPORTS_SH_CMT
select SYS_SUPPORTS_SH_TMU select SYS_SUPPORTS_SH_TMU
...@@ -263,7 +262,6 @@ config MACH_KOELSCH ...@@ -263,7 +262,6 @@ config MACH_KOELSCH
config MACH_KZM9G config MACH_KZM9G
bool "KZM-A9-GT board" bool "KZM-A9-GT board"
depends on ARCH_SH73A0 depends on ARCH_SH73A0
select ARCH_HAS_OPP
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select REGULATOR_FIXED_VOLTAGE if REGULATOR select REGULATOR_FIXED_VOLTAGE if REGULATOR
select SND_SOC_AK4642 if SND_SIMPLE_CARD select SND_SOC_AK4642 if SND_SIMPLE_CARD
......
...@@ -64,7 +64,6 @@ config ARCH_VEXPRESS_DCSCB ...@@ -64,7 +64,6 @@ config ARCH_VEXPRESS_DCSCB
config ARCH_VEXPRESS_SPC config ARCH_VEXPRESS_SPC
bool "Versatile Express Serial Power Controller (SPC)" bool "Versatile Express Serial Power Controller (SPC)"
select ARCH_HAS_OPP
select PM_OPP select PM_OPP
help help
The TC2 (A15x2 A7x3) versatile express core tile integrates a logic The TC2 (A15x2 A7x3) versatile express core tile integrates a logic
......
config ARCH_ZYNQ config ARCH_ZYNQ
bool "Xilinx Zynq ARM Cortex A9 Platform" if ARCH_MULTI_V7 bool "Xilinx Zynq ARM Cortex A9 Platform" if ARCH_MULTI_V7
select ARCH_HAS_OPP
select ARCH_SUPPORTS_BIG_ENDIAN select ARCH_SUPPORTS_BIG_ENDIAN
select ARM_AMBA select ARM_AMBA
select ARM_GIC select ARM_GIC
......
...@@ -10,6 +10,7 @@ config IA64 ...@@ -10,6 +10,7 @@ config IA64
select ARCH_MIGHT_HAVE_PC_SERIO select ARCH_MIGHT_HAVE_PC_SERIO
select PCI if (!IA64_HP_SIM) select PCI if (!IA64_HP_SIM)
select ACPI if (!IA64_HP_SIM) select ACPI if (!IA64_HP_SIM)
select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI
select PM if (!IA64_HP_SIM) select PM if (!IA64_HP_SIM)
select HAVE_UNSTABLE_SCHED_CLOCK select HAVE_UNSTABLE_SCHED_CLOCK
select HAVE_IDE select HAVE_IDE
......
...@@ -19,8 +19,6 @@ ...@@ -19,8 +19,6 @@
/* Asm macros */ /* Asm macros */
#ifdef CONFIG_ACPI
static inline int static inline int
ia64_acpi_acquire_global_lock(unsigned int *lock) ia64_acpi_acquire_global_lock(unsigned int *lock)
{ {
...@@ -51,6 +49,4 @@ ia64_acpi_release_global_lock(unsigned int *lock) ...@@ -51,6 +49,4 @@ ia64_acpi_release_global_lock(unsigned int *lock)
#define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \ #define ACPI_RELEASE_GLOBAL_LOCK(facs, Acq) \
((Acq) = ia64_acpi_release_global_lock(&facs->global_lock)) ((Acq) = ia64_acpi_release_global_lock(&facs->global_lock))
#endif
#endif /* _ASM_IA64_ACENV_H */ #endif /* _ASM_IA64_ACENV_H */
...@@ -40,6 +40,11 @@ extern int acpi_lapic; ...@@ -40,6 +40,11 @@ extern int acpi_lapic;
#define acpi_noirq 0 /* ACPI always enabled on IA64 */ #define acpi_noirq 0 /* ACPI always enabled on IA64 */
#define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */ #define acpi_pci_disabled 0 /* ACPI PCI always enabled on IA64 */
#define acpi_strict 1 /* no ACPI spec workarounds on IA64 */ #define acpi_strict 1 /* no ACPI spec workarounds on IA64 */
static inline bool acpi_has_cpu_in_madt(void)
{
return !!acpi_lapic;
}
#endif #endif
#define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */ #define acpi_processor_cstate_check(x) (x) /* no idle limits on IA64 :) */
static inline void disable_acpi(void) { } static inline void disable_acpi(void) { }
......
...@@ -21,6 +21,7 @@ config X86_64 ...@@ -21,6 +21,7 @@ config X86_64
### Arch settings ### Arch settings
config X86 config X86
def_bool y def_bool y
select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI
select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS select ARCH_HAS_DEBUG_STRICT_USER_COPY_CHECKS
select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO select ARCH_MIGHT_HAVE_PC_SERIO
...@@ -133,6 +134,7 @@ config X86 ...@@ -133,6 +134,7 @@ config X86
select ARCH_SUPPORTS_ATOMIC_RMW select ARCH_SUPPORTS_ATOMIC_RMW
select HAVE_ACPI_APEI if ACPI select HAVE_ACPI_APEI if ACPI
select HAVE_ACPI_APEI_NMI if ACPI select HAVE_ACPI_APEI_NMI if ACPI
select ACPI_LEGACY_TABLES_LOOKUP if ACPI
config INSTRUCTION_DECODER config INSTRUCTION_DECODER
def_bool y def_bool y
......
...@@ -18,8 +18,6 @@ ...@@ -18,8 +18,6 @@
#define ACPI_FLUSH_CPU_CACHE() wbinvd() #define ACPI_FLUSH_CPU_CACHE() wbinvd()
#ifdef CONFIG_ACPI
int __acpi_acquire_global_lock(unsigned int *lock); int __acpi_acquire_global_lock(unsigned int *lock);
int __acpi_release_global_lock(unsigned int *lock); int __acpi_release_global_lock(unsigned int *lock);
...@@ -44,6 +42,4 @@ int __acpi_release_global_lock(unsigned int *lock); ...@@ -44,6 +42,4 @@ int __acpi_release_global_lock(unsigned int *lock);
: "=r"(n_hi), "=r"(n_lo) \ : "=r"(n_hi), "=r"(n_lo) \
: "0"(n_hi), "1"(n_lo)) : "0"(n_hi), "1"(n_lo))
#endif
#endif /* _ASM_X86_ACENV_H */ #endif /* _ASM_X86_ACENV_H */
...@@ -121,6 +121,11 @@ static inline void arch_acpi_set_pdc_bits(u32 *buf) ...@@ -121,6 +121,11 @@ static inline void arch_acpi_set_pdc_bits(u32 *buf)
buf[2] &= ~(ACPI_PDC_C_C2C3_FFH); buf[2] &= ~(ACPI_PDC_C_C2C3_FFH);
} }
static inline bool acpi_has_cpu_in_madt(void)
{
return !!acpi_lapic;
}
#else /* !CONFIG_ACPI */ #else /* !CONFIG_ACPI */
#define acpi_lapic 0 #define acpi_lapic 0
......
...@@ -42,6 +42,12 @@ menuconfig ACPI ...@@ -42,6 +42,12 @@ menuconfig ACPI
if ACPI if ACPI
config ACPI_LEGACY_TABLES_LOOKUP
bool
config ARCH_MIGHT_HAVE_ACPI_PDC
bool
config ACPI_SLEEP config ACPI_SLEEP
bool bool
depends on SUSPEND || HIBERNATION depends on SUSPEND || HIBERNATION
......
...@@ -36,6 +36,7 @@ acpi-y += scan.o ...@@ -36,6 +36,7 @@ acpi-y += scan.o
acpi-y += resource.o acpi-y += resource.o
acpi-y += acpi_processor.o acpi-y += acpi_processor.o
acpi-y += processor_core.o acpi-y += processor_core.o
acpi-$(CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC) += processor_pdc.o
acpi-y += ec.o acpi-y += ec.o
acpi-$(CONFIG_ACPI_DOCK) += dock.o acpi-$(CONFIG_ACPI_DOCK) += dock.o
acpi-y += pci_root.o pci_link.o pci_irq.o acpi-y += pci_root.o pci_link.o pci_irq.o
......
...@@ -71,11 +71,11 @@ static u32 l1_percpu_entry; ...@@ -71,11 +71,11 @@ static u32 l1_percpu_entry;
#define ELOG_ENTRY_ADDR(phyaddr) \ #define ELOG_ENTRY_ADDR(phyaddr) \
(phyaddr - elog_base + (u8 *)elog_addr) (phyaddr - elog_base + (u8 *)elog_addr)
static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank) static struct acpi_hest_generic_status *extlog_elog_entry_check(int cpu, int bank)
{ {
int idx; int idx;
u64 data; u64 data;
struct acpi_generic_status *estatus; struct acpi_hest_generic_status *estatus;
WARN_ON(cpu < 0); WARN_ON(cpu < 0);
idx = ELOG_IDX(cpu, bank); idx = ELOG_IDX(cpu, bank);
...@@ -84,7 +84,7 @@ static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank) ...@@ -84,7 +84,7 @@ static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank)
return NULL; return NULL;
data &= EXT_ELOG_ENTRY_MASK; data &= EXT_ELOG_ENTRY_MASK;
estatus = (struct acpi_generic_status *)ELOG_ENTRY_ADDR(data); estatus = (struct acpi_hest_generic_status *)ELOG_ENTRY_ADDR(data);
/* if no valid data in elog entry, just return */ /* if no valid data in elog entry, just return */
if (estatus->block_status == 0) if (estatus->block_status == 0)
...@@ -94,7 +94,7 @@ static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank) ...@@ -94,7 +94,7 @@ static struct acpi_generic_status *extlog_elog_entry_check(int cpu, int bank)
} }
static void __print_extlog_rcd(const char *pfx, static void __print_extlog_rcd(const char *pfx,
struct acpi_generic_status *estatus, int cpu) struct acpi_hest_generic_status *estatus, int cpu)
{ {
static atomic_t seqno; static atomic_t seqno;
unsigned int curr_seqno; unsigned int curr_seqno;
...@@ -113,7 +113,7 @@ static void __print_extlog_rcd(const char *pfx, ...@@ -113,7 +113,7 @@ static void __print_extlog_rcd(const char *pfx,
} }
static int print_extlog_rcd(const char *pfx, static int print_extlog_rcd(const char *pfx,
struct acpi_generic_status *estatus, int cpu) struct acpi_hest_generic_status *estatus, int cpu)
{ {
/* Not more than 2 messages every 5 seconds */ /* Not more than 2 messages every 5 seconds */
static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2); static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2);
...@@ -139,8 +139,8 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, ...@@ -139,8 +139,8 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
struct mce *mce = (struct mce *)data; struct mce *mce = (struct mce *)data;
int bank = mce->bank; int bank = mce->bank;
int cpu = mce->extcpu; int cpu = mce->extcpu;
struct acpi_generic_status *estatus, *tmp; struct acpi_hest_generic_status *estatus, *tmp;
struct acpi_generic_data *gdata; struct acpi_hest_generic_data *gdata;
const uuid_le *fru_id = &NULL_UUID_LE; const uuid_le *fru_id = &NULL_UUID_LE;
char *fru_text = ""; char *fru_text = "";
uuid_le *sec_type; uuid_le *sec_type;
...@@ -154,7 +154,7 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, ...@@ -154,7 +154,7 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
/* clear record status to enable BIOS to update it again */ /* clear record status to enable BIOS to update it again */
estatus->block_status = 0; estatus->block_status = 0;
tmp = (struct acpi_generic_status *)elog_buf; tmp = (struct acpi_hest_generic_status *)elog_buf;
if (!ras_userspace_consumers()) { if (!ras_userspace_consumers()) {
print_extlog_rcd(NULL, tmp, cpu); print_extlog_rcd(NULL, tmp, cpu);
...@@ -163,7 +163,7 @@ static int extlog_print(struct notifier_block *nb, unsigned long val, ...@@ -163,7 +163,7 @@ static int extlog_print(struct notifier_block *nb, unsigned long val,
/* log event via trace */ /* log event via trace */
err_seq++; err_seq++;
gdata = (struct acpi_generic_data *)(tmp + 1); gdata = (struct acpi_hest_generic_data *)(tmp + 1);
if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID) if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
fru_id = (uuid_le *)gdata->fru_id; fru_id = (uuid_le *)gdata->fru_id;
if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT) if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
......
...@@ -113,6 +113,14 @@ static void lpss_i2c_setup(struct lpss_private_data *pdata) ...@@ -113,6 +113,14 @@ static void lpss_i2c_setup(struct lpss_private_data *pdata)
writel(val, pdata->mmio_base + offset); writel(val, pdata->mmio_base + offset);
} }
static struct lpss_device_desc wpt_dev_desc = {
.clk_required = true,
.prv_offset = 0x800,
.ltr_required = true,
.clk_divider = true,
.clk_gate = true,
};
static struct lpss_device_desc lpt_dev_desc = { static struct lpss_device_desc lpt_dev_desc = {
.clk_required = true, .clk_required = true,
.prv_offset = 0x800, .prv_offset = 0x800,
...@@ -226,6 +234,8 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = { ...@@ -226,6 +234,8 @@ static const struct acpi_device_id acpi_lpss_device_ids[] = {
{ "INT3436", LPSS_ADDR(lpt_sdio_dev_desc) }, { "INT3436", LPSS_ADDR(lpt_sdio_dev_desc) },
{ "INT3437", }, { "INT3437", },
{ "INT3438", LPSS_ADDR(wpt_dev_desc) },
{ } { }
}; };
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/ctype.h>
static const struct acpi_device_id acpi_pnp_device_ids[] = { static const struct acpi_device_id acpi_pnp_device_ids[] = {
/* soc_button_array */ /* soc_button_array */
...@@ -320,11 +321,6 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = { ...@@ -320,11 +321,6 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = {
{""}, {""},
}; };
static bool is_hex_digit(char c)
{
return (c >= 0 && c <= '9') || (c >= 'A' && c <= 'F');
}
static bool matching_id(char *idstr, char *list_id) static bool matching_id(char *idstr, char *list_id)
{ {
int i; int i;
...@@ -335,7 +331,7 @@ static bool matching_id(char *idstr, char *list_id) ...@@ -335,7 +331,7 @@ static bool matching_id(char *idstr, char *list_id)
for (i = 3; i < 7; i++) { for (i = 3; i < 7; i++) {
char c = toupper(idstr[i]); char c = toupper(idstr[i]);
if (!is_hex_digit(c) if (!isxdigit(c)
|| (list_id[i] != 'X' && c != toupper(list_id[i]))) || (list_id[i] != 'X' && c != toupper(list_id[i])))
return false; return false;
} }
......
...@@ -268,7 +268,7 @@ static int acpi_processor_get_info(struct acpi_device *device) ...@@ -268,7 +268,7 @@ static int acpi_processor_get_info(struct acpi_device *device)
pr->apic_id = apic_id; pr->apic_id = apic_id;
cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id); cpu_index = acpi_map_cpuid(pr->apic_id, pr->acpi_id);
if (!cpu0_initialized && !acpi_lapic) { if (!cpu0_initialized && !acpi_has_cpu_in_madt()) {
cpu0_initialized = 1; cpu0_initialized = 1;
/* Handle UP system running SMP kernel, with no LAPIC in MADT */ /* Handle UP system running SMP kernel, with no LAPIC in MADT */
if ((cpu_index == -1) && (num_online_cpus() == 1)) if ((cpu_index == -1) && (num_online_cpus() == 1))
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Makefile for ACPICA Core interpreter # Makefile for ACPICA Core interpreter
# #
ccflags-y := -Os ccflags-y := -Os -DBUILDING_ACPICA
ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT ccflags-$(CONFIG_ACPI_DEBUG) += -DACPI_DEBUG_OUTPUT
# use acpi.o to put all files here into acpi.o modparam namespace # use acpi.o to put all files here into acpi.o modparam namespace
...@@ -157,6 +157,7 @@ acpi-y += \ ...@@ -157,6 +157,7 @@ acpi-y += \
uterror.o \ uterror.o \
uteval.o \ uteval.o \
utglobal.o \ utglobal.o \
uthex.o \
utids.o \ utids.o \
utinit.o \ utinit.o \
utlock.o \ utlock.o \
...@@ -175,5 +176,10 @@ acpi-y += \ ...@@ -175,5 +176,10 @@ acpi-y += \
utxferror.o \ utxferror.o \
utxfmutex.o utxfmutex.o
acpi-$(ACPI_FUTURE_USAGE) += uttrack.o utcache.o acpi-$(ACPI_FUTURE_USAGE) += \
utcache.o \
utfileio.o \
utprint.o \
uttrack.o \
utuuid.o
...@@ -79,10 +79,13 @@ ...@@ -79,10 +79,13 @@
/* Macros for usage messages */ /* Macros for usage messages */
#define ACPI_USAGE_HEADER(usage) \ #define ACPI_USAGE_HEADER(usage) \
printf ("Usage: %s\nOptions:\n", usage); acpi_os_printf ("Usage: %s\nOptions:\n", usage);
#define ACPI_USAGE_TEXT(description) \
acpi_os_printf (description);
#define ACPI_OPTION(name, description) \ #define ACPI_OPTION(name, description) \
printf (" %-18s%s\n", name, description); acpi_os_printf (" %-18s%s\n", name, description);
#define FILE_SUFFIX_DISASSEMBLY "dsl" #define FILE_SUFFIX_DISASSEMBLY "dsl"
#define ACPI_TABLE_FILE_SUFFIX ".dat" #define ACPI_TABLE_FILE_SUFFIX ".dat"
...@@ -102,7 +105,7 @@ extern char *acpi_gbl_optarg; ...@@ -102,7 +105,7 @@ extern char *acpi_gbl_optarg;
/* /*
* cmfsize - Common get file size function * cmfsize - Common get file size function
*/ */
u32 cm_get_file_size(FILE * file); u32 cm_get_file_size(ACPI_FILE file);
#ifndef ACPI_DUMP_APP #ifndef ACPI_DUMP_APP
/* /*
......
...@@ -233,9 +233,6 @@ acpi_status acpi_db_load_acpi_table(char *filename); ...@@ -233,9 +233,6 @@ acpi_status acpi_db_load_acpi_table(char *filename);
acpi_status acpi_status
acpi_db_get_table_from_file(char *filename, struct acpi_table_header **table); acpi_db_get_table_from_file(char *filename, struct acpi_table_header **table);
acpi_status
acpi_db_read_table_from_file(char *filename, struct acpi_table_header **table);
/* /*
* dbhistry - debugger HISTORY command * dbhistry - debugger HISTORY command
*/ */
......
...@@ -297,7 +297,7 @@ ACPI_GLOBAL(u32, acpi_gbl_trace_dbg_layer); ...@@ -297,7 +297,7 @@ ACPI_GLOBAL(u32, acpi_gbl_trace_dbg_layer);
* *
****************************************************************************/ ****************************************************************************/
ACPI_GLOBAL(u8, acpi_gbl_db_output_flags); ACPI_INIT_GLOBAL(u8, acpi_gbl_db_output_flags, ACPI_DB_CONSOLE_OUTPUT);
#ifdef ACPI_DISASSEMBLER #ifdef ACPI_DISASSEMBLER
...@@ -362,6 +362,12 @@ ACPI_GLOBAL(u32, acpi_gbl_num_objects); ...@@ -362,6 +362,12 @@ ACPI_GLOBAL(u32, acpi_gbl_num_objects);
#ifdef ACPI_APPLICATION #ifdef ACPI_APPLICATION
ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL); ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_debug_file, NULL);
ACPI_INIT_GLOBAL(ACPI_FILE, acpi_gbl_output_file, NULL);
/* Print buffer */
ACPI_GLOBAL(acpi_spinlock, acpi_gbl_print_lock); /* For print buffer */
ACPI_GLOBAL(char, acpi_gbl_print_buffer[1024]);
#endif /* ACPI_APPLICATION */ #endif /* ACPI_APPLICATION */
......
...@@ -730,12 +730,13 @@ union acpi_parse_value { ...@@ -730,12 +730,13 @@ union acpi_parse_value {
#define ACPI_DASM_STRING 0x02 /* Buffer is a ASCII string */ #define ACPI_DASM_STRING 0x02 /* Buffer is a ASCII string */
#define ACPI_DASM_UNICODE 0x03 /* Buffer is a Unicode string */ #define ACPI_DASM_UNICODE 0x03 /* Buffer is a Unicode string */
#define ACPI_DASM_PLD_METHOD 0x04 /* Buffer is a _PLD method bit-packed buffer */ #define ACPI_DASM_PLD_METHOD 0x04 /* Buffer is a _PLD method bit-packed buffer */
#define ACPI_DASM_EISAID 0x05 /* Integer is an EISAID */ #define ACPI_DASM_UUID 0x05 /* Buffer is a UUID/GUID */
#define ACPI_DASM_MATCHOP 0x06 /* Parent opcode is a Match() operator */ #define ACPI_DASM_EISAID 0x06 /* Integer is an EISAID */
#define ACPI_DASM_LNOT_PREFIX 0x07 /* Start of a Lnot_equal (etc.) pair of opcodes */ #define ACPI_DASM_MATCHOP 0x07 /* Parent opcode is a Match() operator */
#define ACPI_DASM_LNOT_SUFFIX 0x08 /* End of a Lnot_equal (etc.) pair of opcodes */ #define ACPI_DASM_LNOT_PREFIX 0x08 /* Start of a Lnot_equal (etc.) pair of opcodes */
#define ACPI_DASM_HID_STRING 0x09 /* String is a _HID or _CID */ #define ACPI_DASM_LNOT_SUFFIX 0x09 /* End of a Lnot_equal (etc.) pair of opcodes */
#define ACPI_DASM_IGNORE 0x0A /* Not used at this time */ #define ACPI_DASM_HID_STRING 0x0A /* String is a _HID or _CID */
#define ACPI_DASM_IGNORE 0x0B /* Not used at this time */
/* /*
* Generic operation (for example: If, While, Store) * Generic operation (for example: If, While, Store)
...@@ -1154,4 +1155,9 @@ struct ah_device_id { ...@@ -1154,4 +1155,9 @@ struct ah_device_id {
char *description; char *description;
}; };
struct ah_uuid {
char *description;
char *string;
};
#endif /* __ACLOCAL_H__ */ #endif /* __ACLOCAL_H__ */
...@@ -105,6 +105,11 @@ ...@@ -105,6 +105,11 @@
* count = 0 (optional) * count = 0 (optional)
* (Used for _DLM) * (Used for _DLM)
* *
* ACPI_PTYPE2_UUID_PAIR: Each subpackage is preceded by a UUID Buffer. The UUID
* defines the format of the package. Zero-length parent package is
* allowed.
* (Used for _DSD)
*
*****************************************************************************/ *****************************************************************************/
enum acpi_return_package_types { enum acpi_return_package_types {
...@@ -117,7 +122,8 @@ enum acpi_return_package_types { ...@@ -117,7 +122,8 @@ enum acpi_return_package_types {
ACPI_PTYPE2_FIXED = 7, ACPI_PTYPE2_FIXED = 7,
ACPI_PTYPE2_MIN = 8, ACPI_PTYPE2_MIN = 8,
ACPI_PTYPE2_REV_FIXED = 9, ACPI_PTYPE2_REV_FIXED = 9,
ACPI_PTYPE2_FIX_VAR = 10 ACPI_PTYPE2_FIX_VAR = 10,
ACPI_PTYPE2_UUID_PAIR = 11
}; };
/* Support macros for users of the predefined info table */ /* Support macros for users of the predefined info table */
...@@ -364,6 +370,9 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = { ...@@ -364,6 +370,9 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = {
{{"_CBA", METHOD_0ARGS, {{"_CBA", METHOD_0ARGS,
METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, /* See PCI firmware spec 3.0 */ METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, /* See PCI firmware spec 3.0 */
{{"_CCA", METHOD_0ARGS,
METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, /* ACPI 5.1 */
{{"_CDM", METHOD_0ARGS, {{"_CDM", METHOD_0ARGS,
METHOD_RETURNS(ACPI_RTYPE_INTEGER)}}, METHOD_RETURNS(ACPI_RTYPE_INTEGER)}},
...@@ -436,6 +445,11 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = { ...@@ -436,6 +445,11 @@ const union acpi_predefined_info acpi_gbl_predefined_methods[] = {
{{"_DOS", METHOD_1ARGS(ACPI_TYPE_INTEGER), {{"_DOS", METHOD_1ARGS(ACPI_TYPE_INTEGER),
METHOD_NO_RETURN_VALUE}}, METHOD_NO_RETURN_VALUE}},
{{"_DSD", METHOD_0ARGS,
METHOD_RETURNS(ACPI_RTYPE_PACKAGE)}}, /* Variable-length (Pkgs) each: 1 Buf, 1 Pkg */
PACKAGE_INFO(ACPI_PTYPE2_UUID_PAIR, ACPI_RTYPE_BUFFER, 1,
ACPI_RTYPE_PACKAGE, 1, 0),
{{"_DSM", {{"_DSM",
METHOD_4ARGS(ACPI_TYPE_BUFFER, ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER, METHOD_4ARGS(ACPI_TYPE_BUFFER, ACPI_TYPE_INTEGER, ACPI_TYPE_INTEGER,
ACPI_TYPE_PACKAGE), ACPI_TYPE_PACKAGE),
......
...@@ -95,7 +95,6 @@ extern const char *acpi_gbl_pt_decode[]; ...@@ -95,7 +95,6 @@ extern const char *acpi_gbl_pt_decode[];
#ifdef ACPI_ASL_COMPILER #ifdef ACPI_ASL_COMPILER
#include <stdio.h> #include <stdio.h>
extern FILE *acpi_gbl_output_file;
#define ACPI_MSG_REDIRECT_BEGIN \ #define ACPI_MSG_REDIRECT_BEGIN \
FILE *output_file = acpi_gbl_output_file; \ FILE *output_file = acpi_gbl_output_file; \
...@@ -195,6 +194,8 @@ char *acpi_ut_get_event_name(u32 event_id); ...@@ -195,6 +194,8 @@ char *acpi_ut_get_event_name(u32 event_id);
char acpi_ut_hex_to_ascii_char(u64 integer, u32 position); char acpi_ut_hex_to_ascii_char(u64 integer, u32 position);
u8 acpi_ut_ascii_char_to_hex(int hex_char);
u8 acpi_ut_valid_object_type(acpi_object_type type); u8 acpi_ut_valid_object_type(acpi_object_type type);
/* /*
...@@ -211,6 +212,8 @@ void acpi_ut_subsystem_shutdown(void); ...@@ -211,6 +212,8 @@ void acpi_ut_subsystem_shutdown(void);
acpi_size acpi_ut_strlen(const char *string); acpi_size acpi_ut_strlen(const char *string);
char *acpi_ut_strchr(const char *string, int ch);
char *acpi_ut_strcpy(char *dst_string, const char *src_string); char *acpi_ut_strcpy(char *dst_string, const char *src_string);
char *acpi_ut_strncpy(char *dst_string, char *acpi_ut_strncpy(char *dst_string,
...@@ -257,7 +260,7 @@ extern const u8 _acpi_ctype[]; ...@@ -257,7 +260,7 @@ extern const u8 _acpi_ctype[];
#define ACPI_IS_XDIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_XD)) #define ACPI_IS_XDIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_XD))
#define ACPI_IS_UPPER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_UP)) #define ACPI_IS_UPPER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_UP))
#define ACPI_IS_LOWER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO)) #define ACPI_IS_LOWER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO))
#define ACPI_IS_PRINT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_SP | _ACPI_PU)) #define ACPI_IS_PRINT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP | _ACPI_DI | _ACPI_XS | _ACPI_PU))
#define ACPI_IS_ALPHA(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP)) #define ACPI_IS_ALPHA(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO | _ACPI_UP))
#endif /* !ACPI_USE_SYSTEM_CLIBRARY */ #endif /* !ACPI_USE_SYSTEM_CLIBRARY */
...@@ -352,6 +355,13 @@ acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id); ...@@ -352,6 +355,13 @@ acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id);
void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 offset); void acpi_ut_dump_buffer(u8 *buffer, u32 count, u32 display, u32 offset);
#ifdef ACPI_APPLICATION
void
acpi_ut_dump_buffer_to_file(ACPI_FILE file,
u8 *buffer,
u32 count, u32 display, u32 base_offset);
#endif
void acpi_ut_report_error(char *module_name, u32 line_number); void acpi_ut_report_error(char *module_name, u32 line_number);
void acpi_ut_report_info(char *module_name, u32 line_number); void acpi_ut_report_info(char *module_name, u32 line_number);
...@@ -393,6 +403,14 @@ acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node, ...@@ -393,6 +403,14 @@ acpi_ut_execute_power_methods(struct acpi_namespace_node *device_node,
const char **method_names, const char **method_names,
u8 method_count, u8 *out_values); u8 method_count, u8 *out_values);
/*
* utfileio - file operations
*/
#ifdef ACPI_APPLICATION
acpi_status
acpi_ut_read_table_from_file(char *filename, struct acpi_table_header **table);
#endif
/* /*
* utids - device ID support * utids - device ID support
*/ */
...@@ -743,4 +761,30 @@ const struct ah_predefined_name *acpi_ah_match_predefined_name(char *nameseg); ...@@ -743,4 +761,30 @@ const struct ah_predefined_name *acpi_ah_match_predefined_name(char *nameseg);
const struct ah_device_id *acpi_ah_match_hardware_id(char *hid); const struct ah_device_id *acpi_ah_match_hardware_id(char *hid);
const char *acpi_ah_match_uuid(u8 *data);
/*
* utprint - printf/vprintf output functions
*/
const char *acpi_ut_scan_number(const char *string, u64 *number_ptr);
const char *acpi_ut_print_number(char *string, u64 number);
int
acpi_ut_vsnprintf(char *string,
acpi_size size, const char *format, va_list args);
int acpi_ut_snprintf(char *string, acpi_size size, const char *format, ...);
#ifdef ACPI_APPLICATION
int acpi_ut_file_vprintf(ACPI_FILE file, const char *format, va_list args);
int acpi_ut_file_printf(ACPI_FILE file, const char *format, ...);
#endif
/*
* utuuid -- UUID support functions
*/
void acpi_ut_convert_string_to_uuid(char *in_string, u8 *uuid_buffer);
#endif /* _ACUTILS_H */ #endif /* _ACUTILS_H */
...@@ -697,21 +697,6 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, ...@@ -697,21 +697,6 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
acpi_gbl_global_event_handler_context); acpi_gbl_global_event_handler_context);
} }
/*
* If edge-triggered, clear the GPE status bit now. Note that
* level-triggered events are cleared after the GPE is serviced.
*/
if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
ACPI_GPE_EDGE_TRIGGERED) {
status = acpi_hw_clear_gpe(gpe_event_info);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Unable to clear GPE %02X",
gpe_number));
return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
}
}
/* /*
* Always disable the GPE so that it does not keep firing before * Always disable the GPE so that it does not keep firing before
* any asynchronous activity completes (either from the execution * any asynchronous activity completes (either from the execution
...@@ -728,6 +713,23 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, ...@@ -728,6 +713,23 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
} }
/*
* If edge-triggered, clear the GPE status bit now. Note that
* level-triggered events are cleared after the GPE is serviced.
*/
if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) ==
ACPI_GPE_EDGE_TRIGGERED) {
status = acpi_hw_clear_gpe(gpe_event_info);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
"Unable to clear GPE %02X",
gpe_number));
(void)acpi_hw_low_set_gpe(gpe_event_info,
ACPI_GPE_CONDITIONAL_ENABLE);
return_UINT32(ACPI_INTERRUPT_NOT_HANDLED);
}
}
/* /*
* Dispatch the GPE to either an installed handler or the control * Dispatch the GPE to either an installed handler or the control
* method associated with this GPE (_Lxx or _Exx). If a handler * method associated with this GPE (_Lxx or _Exx). If a handler
......
...@@ -126,11 +126,19 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) ...@@ -126,11 +126,19 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number)
flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock);
/* Ensure that we have a valid GPE number */ /*
* Ensure that we have a valid GPE number and that there is some way
* of handling the GPE (handler or a GPE method). In other words, we
* won't allow a valid GPE to be enabled if there is no way to handle it.
*/
gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number);
if (gpe_event_info) { if (gpe_event_info) {
status = acpi_ev_add_gpe_reference(gpe_event_info); if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) !=
ACPI_GPE_DISPATCH_NONE) {
status = acpi_ev_add_gpe_reference(gpe_event_info);
} else {
status = AE_NO_HANDLER;
}
} }
acpi_os_release_lock(acpi_gbl_gpe_lock, flags); acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
...@@ -177,6 +185,53 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) ...@@ -177,6 +185,53 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number)
ACPI_EXPORT_SYMBOL(acpi_disable_gpe) ACPI_EXPORT_SYMBOL(acpi_disable_gpe)
/*******************************************************************************
*
* FUNCTION: acpi_mark_gpe_for_wake
*
* PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1
* gpe_number - GPE level within the GPE block
*
* RETURN: Status
*
* DESCRIPTION: Mark a GPE as having the ability to wake the system. Simply
* sets the ACPI_GPE_CAN_WAKE flag.
*
* Some potential callers of acpi_setup_gpe_for_wake may know in advance that
* there won't be any notify handlers installed for device wake notifications
* from the given GPE (one example is a button GPE in Linux). For these cases,
* acpi_mark_gpe_for_wake should be used instead of acpi_setup_gpe_for_wake.
* This will set the ACPI_GPE_CAN_WAKE flag for the GPE without trying to
* setup implicit wake notification for it (since there's no handler method).
*
******************************************************************************/
acpi_status acpi_mark_gpe_for_wake(acpi_handle gpe_device, u32 gpe_number)
{
struct acpi_gpe_event_info *gpe_event_info;
acpi_status status = AE_BAD_PARAMETER;
acpi_cpu_flags flags;
ACPI_FUNCTION_TRACE(acpi_mark_gpe_for_wake);
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) {
/* Mark the GPE as a possible wake event */
gpe_event_info->flags |= ACPI_GPE_CAN_WAKE;
status = AE_OK;
}
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
return_ACPI_STATUS(status);
}
ACPI_EXPORT_SYMBOL(acpi_mark_gpe_for_wake)
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_setup_gpe_for_wake * FUNCTION: acpi_setup_gpe_for_wake
......
...@@ -75,6 +75,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, ...@@ -75,6 +75,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
u32 level, u32 index) u32 level, u32 index)
{ {
u32 i; u32 i;
u32 timer;
ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc); ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc);
...@@ -85,12 +86,20 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc, ...@@ -85,12 +86,20 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
return_VOID; return_VOID;
} }
/*
* We will emit the current timer value (in microseconds) with each
* debug output. Only need the lower 26 bits. This allows for 67
* million microseconds or 67 seconds before rollover.
*/
timer = ((u32)acpi_os_get_timer() / 10); /* (100 nanoseconds to microseconds) */
timer &= 0x03FFFFFF;
/* /*
* Print line header as long as we are not in the middle of an * Print line header as long as we are not in the middle of an
* object display * object display
*/ */
if (!((level > 0) && index == 0)) { if (!((level > 0) && index == 0)) {
acpi_os_printf("[ACPI Debug] %*s", level, " "); acpi_os_printf("[ACPI Debug %.8u] %*s", timer, level, " ");
} }
/* Display the index for package output only */ /* Display the index for package output only */
......
...@@ -494,7 +494,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, ...@@ -494,7 +494,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
} }
} }
acpi_os_printf("\n", next); acpi_os_printf("\n");
break; break;
case ACPI_EXD_HDLR_LIST: case ACPI_EXD_HDLR_LIST:
...@@ -528,7 +528,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, ...@@ -528,7 +528,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
} }
} }
acpi_os_printf("\n", next); acpi_os_printf("\n");
break; break;
case ACPI_EXD_RGN_LIST: case ACPI_EXD_RGN_LIST:
...@@ -562,7 +562,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc, ...@@ -562,7 +562,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
} }
} }
acpi_os_printf("\n", next); acpi_os_printf("\n");
break; break;
case ACPI_EXD_NODE: case ACPI_EXD_NODE:
......
...@@ -56,7 +56,7 @@ acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length); ...@@ -56,7 +56,7 @@ acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length);
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_get_serial_access_bytes * FUNCTION: acpi_ex_get_serial_access_length
* *
* PARAMETERS: accessor_type - The type of the protocol indicated by region * PARAMETERS: accessor_type - The type of the protocol indicated by region
* field access attributes * field access attributes
...@@ -103,7 +103,7 @@ acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length) ...@@ -103,7 +103,7 @@ acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length)
case AML_FIELD_ATTRIB_BLOCK_CALL: case AML_FIELD_ATTRIB_BLOCK_CALL:
default: default:
length = ACPI_GSBUS_BUFFER_SIZE; length = ACPI_GSBUS_BUFFER_SIZE - 2;
break; break;
} }
...@@ -186,12 +186,11 @@ acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state, ...@@ -186,12 +186,11 @@ acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state,
access_length); access_length);
/* /*
* Add additional 2 bytes for modeled generic_serial_bus data buffer: * Add additional 2 bytes for the generic_serial_bus data buffer:
* typedef struct { *
* BYTEStatus; // Byte 0 of the data buffer * Status; (Byte 0 of the data buffer)
* BYTELength; // Byte 1 of the data buffer * Length; (Byte 1 of the data buffer)
* BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer, * Data[x-1]; (Bytes 2-x of the arbitrary length data buffer)
* }
*/ */
length += 2; length += 2;
function = ACPI_READ | (accessor_type << 16); function = ACPI_READ | (accessor_type << 16);
...@@ -368,12 +367,11 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, ...@@ -368,12 +367,11 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
access_length); access_length);
/* /*
* Add additional 2 bytes for modeled generic_serial_bus data buffer: * Add additional 2 bytes for the generic_serial_bus data buffer:
* typedef struct { *
* BYTEStatus; // Byte 0 of the data buffer * Status; (Byte 0 of the data buffer)
* BYTELength; // Byte 1 of the data buffer * Length; (Byte 1 of the data buffer)
* BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer, * Data[x-1]; (Bytes 2-x of the arbitrary length data buffer)
* }
*/ */
length += 2; length += 2;
function = ACPI_WRITE | (accessor_type << 16); function = ACPI_WRITE | (accessor_type << 16);
......
...@@ -278,8 +278,9 @@ acpi_status acpi_hw_clear_acpi_status(void) ...@@ -278,8 +278,9 @@ acpi_status acpi_hw_clear_acpi_status(void)
acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags); acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
if (ACPI_FAILURE(status)) if (ACPI_FAILURE(status)) {
goto exit; goto exit;
}
/* Clear the GPE Bits in all GPE registers in all GPE blocks */ /* Clear the GPE Bits in all GPE registers in all GPE blocks */
......
...@@ -237,6 +237,16 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node) ...@@ -237,6 +237,16 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node)
(node->object->common.type != ACPI_TYPE_LOCAL_DATA)) { (node->object->common.type != ACPI_TYPE_LOCAL_DATA)) {
node->object = node->object->common.next_object; node->object = node->object->common.next_object;
} }
/*
* Detach the object from any data objects (which are still held by
* the namespace node)
*/
if (obj_desc->common.next_object &&
((obj_desc->common.next_object)->common.type ==
ACPI_TYPE_LOCAL_DATA)) {
obj_desc->common.next_object = NULL;
}
} }
/* Reset the node type to untyped */ /* Reset the node type to untyped */
......
...@@ -199,3 +199,131 @@ acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id) ...@@ -199,3 +199,131 @@ acpi_ut_debug_dump_buffer(u8 *buffer, u32 count, u32 display, u32 component_id)
acpi_ut_dump_buffer(buffer, count, display, 0); acpi_ut_dump_buffer(buffer, count, display, 0);
} }
#ifdef ACPI_APPLICATION
/*******************************************************************************
*
* FUNCTION: acpi_ut_dump_buffer_to_file
*
* PARAMETERS: file - File descriptor
* 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 to a file.
*
******************************************************************************/
void
acpi_ut_dump_buffer_to_file(ACPI_FILE file,
u8 *buffer, u32 count, u32 display, u32 base_offset)
{
u32 i = 0;
u32 j;
u32 temp32;
u8 buf_char;
if (!buffer) {
acpi_ut_file_printf(file,
"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_ut_file_printf(file, "%6.4X: ", (base_offset + i));
/* Print 16 hex chars */
for (j = 0; j < 16;) {
if (i + j >= count) {
/* Dump fill spaces */
acpi_ut_file_printf(file, "%*s",
((display * 2) + 1), " ");
j += display;
continue;
}
switch (display) {
case DB_BYTE_DISPLAY:
default: /* Default is BYTE display */
acpi_ut_file_printf(file, "%02X ",
buffer[(acpi_size) i + j]);
break;
case DB_WORD_DISPLAY:
ACPI_MOVE_16_TO_32(&temp32,
&buffer[(acpi_size) i + j]);
acpi_ut_file_printf(file, "%04X ", temp32);
break;
case DB_DWORD_DISPLAY:
ACPI_MOVE_32_TO_32(&temp32,
&buffer[(acpi_size) i + j]);
acpi_ut_file_printf(file, "%08X ", temp32);
break;
case DB_QWORD_DISPLAY:
ACPI_MOVE_32_TO_32(&temp32,
&buffer[(acpi_size) i + j]);
acpi_ut_file_printf(file, "%08X", temp32);
ACPI_MOVE_32_TO_32(&temp32,
&buffer[(acpi_size) i + j +
4]);
acpi_ut_file_printf(file, "%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_ut_file_printf(file, " ");
for (j = 0; j < 16; j++) {
if (i + j >= count) {
acpi_ut_file_printf(file, "\n");
return;
}
buf_char = buffer[(acpi_size) i + j];
if (ACPI_IS_PRINT(buf_char)) {
acpi_ut_file_printf(file, "%c", buf_char);
} else {
acpi_ut_file_printf(file, ".");
}
}
/* Done with that line. */
acpi_ut_file_printf(file, "\n");
i += 16;
}
return;
}
#endif
...@@ -1001,5 +1001,11 @@ acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc, ...@@ -1001,5 +1001,11 @@ acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,
status = acpi_ut_copy_simple_object(source_desc, *dest_desc); status = acpi_ut_copy_simple_object(source_desc, *dest_desc);
} }
/* Delete the allocated object if copy failed */
if (ACPI_FAILURE(status)) {
acpi_ut_remove_reference(*dest_desc);
}
return_ACPI_STATUS(status); return_ACPI_STATUS(status);
} }
...@@ -561,3 +561,29 @@ acpi_ut_ptr_exit(u32 line_number, ...@@ -561,3 +561,29 @@ acpi_ut_ptr_exit(u32 line_number,
} }
#endif #endif
#ifdef ACPI_APPLICATION
/*******************************************************************************
*
* FUNCTION: acpi_log_error
*
* PARAMETERS: format - Printf format field
* ... - Optional printf arguments
*
* RETURN: None
*
* DESCRIPTION: Print error message to the console, used by applications.
*
******************************************************************************/
void ACPI_INTERNAL_VAR_XFACE acpi_log_error(const char *format, ...)
{
va_list args;
va_start(args, format);
(void)acpi_ut_file_vprintf(ACPI_FILE_ERR, format, args);
va_end(args);
}
ACPI_EXPORT_SYMBOL(acpi_log_error)
#endif
...@@ -86,33 +86,6 @@ const u8 acpi_gbl_ns_properties[ACPI_NUM_NS_TYPES] = { ...@@ -86,33 +86,6 @@ const u8 acpi_gbl_ns_properties[ACPI_NUM_NS_TYPES] = {
ACPI_NS_NORMAL /* 30 Invalid */ ACPI_NS_NORMAL /* 30 Invalid */
}; };
/*******************************************************************************
*
* FUNCTION: acpi_ut_hex_to_ascii_char
*
* PARAMETERS: integer - Contains the hex digit
* position - bit position of the digit within the
* integer (multiple of 4)
*
* RETURN: The converted Ascii character
*
* DESCRIPTION: Convert a hex digit to an Ascii character
*
******************************************************************************/
/* Hex to ASCII conversion table */
static const char acpi_gbl_hex_to_ascii[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
char acpi_ut_hex_to_ascii_char(u64 integer, u32 position)
{
return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ut_get_region_name * FUNCTION: acpi_ut_get_region_name
...@@ -475,7 +448,8 @@ static const char *acpi_gbl_generic_notify[ACPI_NOTIFY_MAX + 1] = { ...@@ -475,7 +448,8 @@ static const char *acpi_gbl_generic_notify[ACPI_NOTIFY_MAX + 1] = {
/* 09 */ "Device PLD Check", /* 09 */ "Device PLD Check",
/* 0A */ "Reserved", /* 0A */ "Reserved",
/* 0B */ "System Locality Update", /* 0B */ "System Locality Update",
/* 0C */ "Shutdown Request" /* 0C */ "Shutdown Request",
/* 0D */ "System Resource Affinity Update"
}; };
static const char *acpi_gbl_device_notify[4] = { static const char *acpi_gbl_device_notify[4] = {
...@@ -502,7 +476,7 @@ static const char *acpi_gbl_thermal_notify[4] = { ...@@ -502,7 +476,7 @@ static const char *acpi_gbl_thermal_notify[4] = {
const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type) const char *acpi_ut_get_notify_name(u32 notify_value, acpi_object_type type)
{ {
/* 00 - 0C are common to all object types */ /* 00 - 0D are common to all object types */
if (notify_value <= ACPI_NOTIFY_MAX) { if (notify_value <= ACPI_NOTIFY_MAX) {
return (acpi_gbl_generic_notify[notify_value]); return (acpi_gbl_generic_notify[notify_value]);
......
/*******************************************************************************
*
* Module Name: utfileio - simple file I/O routines
*
******************************************************************************/
/*
* Copyright (C) 2000 - 2014, 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"
#include "acapps.h"
#ifdef ACPI_ASL_COMPILER
#include "aslcompiler.h"
#endif
#define _COMPONENT ACPI_CA_DEBUGGER
ACPI_MODULE_NAME("utfileio")
#ifdef ACPI_APPLICATION
/* Local prototypes */
static acpi_status
acpi_ut_check_text_mode_corruption(u8 *table,
u32 table_length, u32 file_length);
static acpi_status
acpi_ut_read_table(FILE * fp,
struct acpi_table_header **table, u32 *table_length);
/*******************************************************************************
*
* FUNCTION: acpi_ut_check_text_mode_corruption
*
* PARAMETERS: table - Table buffer
* table_length - Length of table from the table header
* file_length - Length of the file that contains the table
*
* RETURN: Status
*
* DESCRIPTION: Check table for text mode file corruption where all linefeed
* characters (LF) have been replaced by carriage return linefeed
* pairs (CR/LF).
*
******************************************************************************/
static acpi_status
acpi_ut_check_text_mode_corruption(u8 *table, u32 table_length, u32 file_length)
{
u32 i;
u32 pairs = 0;
if (table_length != file_length) {
ACPI_WARNING((AE_INFO,
"File length (0x%X) is not the same as the table length (0x%X)",
file_length, table_length));
}
/* Scan entire table to determine if each LF has been prefixed with a CR */
for (i = 1; i < file_length; i++) {
if (table[i] == 0x0A) {
if (table[i - 1] != 0x0D) {
/* The LF does not have a preceding CR, table not corrupted */
return (AE_OK);
} else {
/* Found a CR/LF pair */
pairs++;
}
i++;
}
}
if (!pairs) {
return (AE_OK);
}
/*
* Entire table scanned, each CR is part of a CR/LF pair --
* meaning that the table was treated as a text file somewhere.
*
* NOTE: We can't "fix" the table, because any existing CR/LF pairs in the
* original table are left untouched by the text conversion process --
* meaning that we cannot simply replace CR/LF pairs with LFs.
*/
acpi_os_printf("Table has been corrupted by text mode conversion\n");
acpi_os_printf("All LFs (%u) were changed to CR/LF pairs\n", pairs);
acpi_os_printf("Table cannot be repaired!\n");
return (AE_BAD_VALUE);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_read_table
*
* PARAMETERS: fp - File that contains table
* table - Return value, buffer with table
* table_length - Return value, length of table
*
* RETURN: Status
*
* DESCRIPTION: Load the DSDT from the file pointer
*
******************************************************************************/
static acpi_status
acpi_ut_read_table(FILE * fp,
struct acpi_table_header **table, u32 *table_length)
{
struct acpi_table_header table_header;
u32 actual;
acpi_status status;
u32 file_size;
u8 standard_header = TRUE;
s32 count;
/* Get the file size */
file_size = cm_get_file_size(fp);
if (file_size == ACPI_UINT32_MAX) {
return (AE_ERROR);
}
if (file_size < 4) {
return (AE_BAD_HEADER);
}
/* Read the signature */
fseek(fp, 0, SEEK_SET);
count = fread(&table_header, 1, sizeof(struct acpi_table_header), fp);
if (count != sizeof(struct acpi_table_header)) {
acpi_os_printf("Could not read the table header\n");
return (AE_BAD_HEADER);
}
/* The RSDP table does not have standard ACPI header */
if (ACPI_VALIDATE_RSDP_SIG(table_header.signature)) {
*table_length = file_size;
standard_header = FALSE;
} else {
#if 0
/* Validate the table header/length */
status = acpi_tb_validate_table_header(&table_header);
if (ACPI_FAILURE(status)) {
acpi_os_printf("Table header is invalid!\n");
return (status);
}
#endif
/* File size must be at least as long as the Header-specified length */
if (table_header.length > file_size) {
acpi_os_printf
("TableHeader length [0x%X] greater than the input file size [0x%X]\n",
table_header.length, file_size);
#ifdef ACPI_ASL_COMPILER
status = fl_check_for_ascii(fp, NULL, FALSE);
if (ACPI_SUCCESS(status)) {
acpi_os_printf
("File appears to be ASCII only, must be binary\n");
}
#endif
return (AE_BAD_HEADER);
}
#ifdef ACPI_OBSOLETE_CODE
/* We only support a limited number of table types */
if (!ACPI_COMPARE_NAME
((char *)table_header.signature, ACPI_SIG_DSDT)
&& !ACPI_COMPARE_NAME((char *)table_header.signature,
ACPI_SIG_PSDT)
&& !ACPI_COMPARE_NAME((char *)table_header.signature,
ACPI_SIG_SSDT)) {
acpi_os_printf
("Table signature [%4.4s] is invalid or not supported\n",
(char *)table_header.signature);
ACPI_DUMP_BUFFER(&table_header,
sizeof(struct acpi_table_header));
return (AE_ERROR);
}
#endif
*table_length = table_header.length;
}
/* Allocate a buffer for the table */
*table = acpi_os_allocate((size_t) file_size);
if (!*table) {
acpi_os_printf
("Could not allocate memory for ACPI table %4.4s (size=0x%X)\n",
table_header.signature, *table_length);
return (AE_NO_MEMORY);
}
/* Get the rest of the table */
fseek(fp, 0, SEEK_SET);
actual = fread(*table, 1, (size_t) file_size, fp);
if (actual == file_size) {
if (standard_header) {
/* Now validate the checksum */
status = acpi_tb_verify_checksum((void *)*table,
ACPI_CAST_PTR(struct
acpi_table_header,
*table)->
length);
if (status == AE_BAD_CHECKSUM) {
status =
acpi_ut_check_text_mode_corruption((u8 *)
*table,
file_size,
(*table)->
length);
return (status);
}
}
return (AE_OK);
}
if (actual > 0) {
acpi_os_printf("Warning - reading table, asked for %X got %X\n",
file_size, actual);
return (AE_OK);
}
acpi_os_printf("Error - could not read the table file\n");
acpi_os_free(*table);
*table = NULL;
*table_length = 0;
return (AE_ERROR);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_read_table_from_file
*
* PARAMETERS: filename - File where table is located
* table - Where a pointer to the table is returned
*
* RETURN: Status
*
* DESCRIPTION: Get an ACPI table from a file
*
******************************************************************************/
acpi_status
acpi_ut_read_table_from_file(char *filename, struct acpi_table_header ** table)
{
FILE *file;
u32 file_size;
u32 table_length;
acpi_status status = AE_ERROR;
/* Open the file, get current size */
file = fopen(filename, "rb");
if (!file) {
perror("Could not open input file");
return (status);
}
file_size = cm_get_file_size(file);
if (file_size == ACPI_UINT32_MAX) {
goto exit;
}
/* Get the entire file */
fprintf(stderr,
"Loading Acpi table from file %10s - Length %.8u (%06X)\n",
filename, file_size, file_size);
status = acpi_ut_read_table(file, table, &table_length);
if (ACPI_FAILURE(status)) {
acpi_os_printf("Could not get table from the file\n");
}
exit:
fclose(file);
return (status);
}
#endif
...@@ -214,152 +214,6 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] = ...@@ -214,152 +214,6 @@ struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS] =
}; };
#endif /* !ACPI_REDUCED_HARDWARE */ #endif /* !ACPI_REDUCED_HARDWARE */
/*******************************************************************************
*
* FUNCTION: acpi_ut_init_globals
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Initialize ACPICA globals. All globals that require specific
* initialization should be initialized here. This allows for
* a warm restart.
*
******************************************************************************/
acpi_status acpi_ut_init_globals(void)
{
acpi_status status;
u32 i;
ACPI_FUNCTION_TRACE(ut_init_globals);
/* Create all memory caches */
status = acpi_ut_create_caches();
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Address Range lists */
for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++) {
acpi_gbl_address_range_list[i] = NULL;
}
/* Mutex locked flags */
for (i = 0; i < ACPI_NUM_MUTEX; i++) {
acpi_gbl_mutex_info[i].mutex = NULL;
acpi_gbl_mutex_info[i].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
acpi_gbl_mutex_info[i].use_count = 0;
}
for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) {
acpi_gbl_owner_id_mask[i] = 0;
}
/* Last owner_ID is never valid */
acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;
/* Event counters */
acpi_method_count = 0;
acpi_sci_count = 0;
acpi_gpe_count = 0;
for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
acpi_fixed_event_count[i] = 0;
}
#if (!ACPI_REDUCED_HARDWARE)
/* GPE/SCI support */
acpi_gbl_all_gpes_initialized = FALSE;
acpi_gbl_gpe_xrupt_list_head = NULL;
acpi_gbl_gpe_fadt_blocks[0] = NULL;
acpi_gbl_gpe_fadt_blocks[1] = NULL;
acpi_current_gpe_count = 0;
acpi_gbl_global_event_handler = NULL;
acpi_gbl_sci_handler_list = NULL;
#endif /* !ACPI_REDUCED_HARDWARE */
/* Global handlers */
acpi_gbl_global_notify[0].handler = NULL;
acpi_gbl_global_notify[1].handler = NULL;
acpi_gbl_exception_handler = NULL;
acpi_gbl_init_handler = NULL;
acpi_gbl_table_handler = NULL;
acpi_gbl_interface_handler = NULL;
/* Global Lock support */
acpi_gbl_global_lock_semaphore = NULL;
acpi_gbl_global_lock_mutex = NULL;
acpi_gbl_global_lock_acquired = FALSE;
acpi_gbl_global_lock_handle = 0;
acpi_gbl_global_lock_present = FALSE;
/* Miscellaneous variables */
acpi_gbl_DSDT = NULL;
acpi_gbl_cm_single_step = FALSE;
acpi_gbl_shutdown = FALSE;
acpi_gbl_ns_lookup_count = 0;
acpi_gbl_ps_find_count = 0;
acpi_gbl_acpi_hardware_present = TRUE;
acpi_gbl_last_owner_id_index = 0;
acpi_gbl_next_owner_id_offset = 0;
acpi_gbl_trace_dbg_level = 0;
acpi_gbl_trace_dbg_layer = 0;
acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
acpi_gbl_osi_mutex = NULL;
acpi_gbl_reg_methods_executed = FALSE;
/* Hardware oriented */
acpi_gbl_events_initialized = FALSE;
acpi_gbl_system_awake_and_running = TRUE;
/* Namespace */
acpi_gbl_module_code_list = NULL;
acpi_gbl_root_node = NULL;
acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME;
acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED;
acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE;
acpi_gbl_root_node_struct.parent = NULL;
acpi_gbl_root_node_struct.child = NULL;
acpi_gbl_root_node_struct.peer = NULL;
acpi_gbl_root_node_struct.object = NULL;
#ifdef ACPI_DISASSEMBLER
acpi_gbl_external_list = NULL;
acpi_gbl_num_external_methods = 0;
acpi_gbl_resolved_external_methods = 0;
#endif
#ifdef ACPI_DEBUG_OUTPUT
acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX);
#endif
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
acpi_gbl_display_final_mem_stats = FALSE;
acpi_gbl_disable_mem_tracking = FALSE;
#endif
ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE);
return_ACPI_STATUS(AE_OK);
}
/* Public globals */ /* Public globals */
ACPI_EXPORT_SYMBOL(acpi_gbl_FADT) ACPI_EXPORT_SYMBOL(acpi_gbl_FADT)
......
/******************************************************************************
*
* Module Name: uthex -- Hex/ASCII support functions
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, 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_COMPILER
ACPI_MODULE_NAME("uthex")
/* Hex to ASCII conversion table */
static char acpi_gbl_hex_to_ascii[] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D',
'E', 'F'
};
/*******************************************************************************
*
* FUNCTION: acpi_ut_hex_to_ascii_char
*
* PARAMETERS: integer - Contains the hex digit
* position - bit position of the digit within the
* integer (multiple of 4)
*
* RETURN: The converted Ascii character
*
* DESCRIPTION: Convert a hex digit to an Ascii character
*
******************************************************************************/
char acpi_ut_hex_to_ascii_char(u64 integer, u32 position)
{
return (acpi_gbl_hex_to_ascii[(integer >> position) & 0xF]);
}
/*******************************************************************************
*
* FUNCTION: acpi_ut_hex_char_to_value
*
* PARAMETERS: ascii_char - Hex character in Ascii
*
* RETURN: The binary value of the ascii/hex character
*
* DESCRIPTION: Perform ascii-to-hex translation
*
******************************************************************************/
u8 acpi_ut_ascii_char_to_hex(int hex_char)
{
if (hex_char <= 0x39) {
return ((u8)(hex_char - 0x30));
}
if (hex_char <= 0x46) {
return ((u8)(hex_char - 0x37));
}
return ((u8)(hex_char - 0x57));
}
...@@ -102,6 +102,151 @@ static void acpi_ut_free_gpe_lists(void) ...@@ -102,6 +102,151 @@ static void acpi_ut_free_gpe_lists(void)
} }
#endif /* !ACPI_REDUCED_HARDWARE */ #endif /* !ACPI_REDUCED_HARDWARE */
/*******************************************************************************
*
* FUNCTION: acpi_ut_init_globals
*
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Initialize ACPICA globals. All globals that require specific
* initialization should be initialized here. This allows for
* a warm restart.
*
******************************************************************************/
acpi_status acpi_ut_init_globals(void)
{
acpi_status status;
u32 i;
ACPI_FUNCTION_TRACE(ut_init_globals);
/* Create all memory caches */
status = acpi_ut_create_caches();
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
/* Address Range lists */
for (i = 0; i < ACPI_ADDRESS_RANGE_MAX; i++) {
acpi_gbl_address_range_list[i] = NULL;
}
/* Mutex locked flags */
for (i = 0; i < ACPI_NUM_MUTEX; i++) {
acpi_gbl_mutex_info[i].mutex = NULL;
acpi_gbl_mutex_info[i].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
acpi_gbl_mutex_info[i].use_count = 0;
}
for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) {
acpi_gbl_owner_id_mask[i] = 0;
}
/* Last owner_ID is never valid */
acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;
/* Event counters */
acpi_method_count = 0;
acpi_sci_count = 0;
acpi_gpe_count = 0;
for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) {
acpi_fixed_event_count[i] = 0;
}
#if (!ACPI_REDUCED_HARDWARE)
/* GPE/SCI support */
acpi_gbl_all_gpes_initialized = FALSE;
acpi_gbl_gpe_xrupt_list_head = NULL;
acpi_gbl_gpe_fadt_blocks[0] = NULL;
acpi_gbl_gpe_fadt_blocks[1] = NULL;
acpi_current_gpe_count = 0;
acpi_gbl_global_event_handler = NULL;
acpi_gbl_sci_handler_list = NULL;
#endif /* !ACPI_REDUCED_HARDWARE */
/* Global handlers */
acpi_gbl_global_notify[0].handler = NULL;
acpi_gbl_global_notify[1].handler = NULL;
acpi_gbl_exception_handler = NULL;
acpi_gbl_init_handler = NULL;
acpi_gbl_table_handler = NULL;
acpi_gbl_interface_handler = NULL;
/* Global Lock support */
acpi_gbl_global_lock_semaphore = NULL;
acpi_gbl_global_lock_mutex = NULL;
acpi_gbl_global_lock_acquired = FALSE;
acpi_gbl_global_lock_handle = 0;
acpi_gbl_global_lock_present = FALSE;
/* Miscellaneous variables */
acpi_gbl_DSDT = NULL;
acpi_gbl_cm_single_step = FALSE;
acpi_gbl_shutdown = FALSE;
acpi_gbl_ns_lookup_count = 0;
acpi_gbl_ps_find_count = 0;
acpi_gbl_acpi_hardware_present = TRUE;
acpi_gbl_last_owner_id_index = 0;
acpi_gbl_next_owner_id_offset = 0;
acpi_gbl_trace_dbg_level = 0;
acpi_gbl_trace_dbg_layer = 0;
acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
acpi_gbl_osi_mutex = NULL;
acpi_gbl_reg_methods_executed = FALSE;
/* Hardware oriented */
acpi_gbl_events_initialized = FALSE;
acpi_gbl_system_awake_and_running = TRUE;
/* Namespace */
acpi_gbl_module_code_list = NULL;
acpi_gbl_root_node = NULL;
acpi_gbl_root_node_struct.name.integer = ACPI_ROOT_NAME;
acpi_gbl_root_node_struct.descriptor_type = ACPI_DESC_TYPE_NAMED;
acpi_gbl_root_node_struct.type = ACPI_TYPE_DEVICE;
acpi_gbl_root_node_struct.parent = NULL;
acpi_gbl_root_node_struct.child = NULL;
acpi_gbl_root_node_struct.peer = NULL;
acpi_gbl_root_node_struct.object = NULL;
#ifdef ACPI_DISASSEMBLER
acpi_gbl_external_list = NULL;
acpi_gbl_num_external_methods = 0;
acpi_gbl_resolved_external_methods = 0;
#endif
#ifdef ACPI_DEBUG_OUTPUT
acpi_gbl_lowest_stack_pointer = ACPI_CAST_PTR(acpi_size, ACPI_SIZE_MAX);
#endif
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
acpi_gbl_display_final_mem_stats = FALSE;
acpi_gbl_disable_mem_tracking = FALSE;
#endif
ACPI_DEBUGGER_EXEC(acpi_gbl_db_terminate_threads = FALSE);
return_ACPI_STATUS(AE_OK);
}
/****************************************************************************** /******************************************************************************
* *
* FUNCTION: acpi_ut_terminate * FUNCTION: acpi_ut_terminate
......
This diff is collapsed.
/******************************************************************************
*
* Module Name: utuuid -- UUID support functions
*
*****************************************************************************/
/*
* Copyright (C) 2000 - 2014, 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_COMPILER
ACPI_MODULE_NAME("utuuid")
/*
* UUID support functions.
*
* This table is used to convert an input UUID ascii string to a 16 byte
* buffer and the reverse. The table maps a UUID buffer index 0-15 to
* the index within the 36-byte UUID string where the associated 2-byte
* hex value can be found.
*
* 36-byte UUID strings are of the form:
* aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
* Where aa-pp are one byte hex numbers, made up of two hex digits
*
* Note: This table is basically the inverse of the string-to-offset table
* found in the ACPI spec in the description of the to_UUID macro.
*/
const u8 acpi_gbl_map_to_uuid_offset[UUID_BUFFER_LENGTH] = {
6, 4, 2, 0, 11, 9, 16, 14, 19, 21, 24, 26, 28, 30, 32, 34
};
/*******************************************************************************
*
* FUNCTION: acpi_ut_convert_string_to_uuid
*
* PARAMETERS: in_string - 36-byte formatted UUID string
* uuid_buffer - Where the 16-byte UUID buffer is returned
*
* RETURN: None. Output data is returned in the uuid_buffer
*
* DESCRIPTION: Convert a 36-byte formatted UUID string to 16-byte UUID buffer
*
******************************************************************************/
void acpi_ut_convert_string_to_uuid(char *in_string, u8 *uuid_buffer)
{
u32 i;
for (i = 0; i < UUID_BUFFER_LENGTH; i++) {
uuid_buffer[i] =
(acpi_ut_ascii_char_to_hex
(in_string[acpi_gbl_map_to_uuid_offset[i]]) << 4);
uuid_buffer[i] |=
acpi_ut_ascii_char_to_hex(in_string
[acpi_gbl_map_to_uuid_offset[i] +
1]);
}
}
...@@ -121,11 +121,11 @@ struct dentry; ...@@ -121,11 +121,11 @@ struct dentry;
struct dentry *apei_get_debugfs_dir(void); struct dentry *apei_get_debugfs_dir(void);
#define apei_estatus_for_each_section(estatus, section) \ #define apei_estatus_for_each_section(estatus, section) \
for (section = (struct acpi_generic_data *)(estatus + 1); \ for (section = (struct acpi_hest_generic_data *)(estatus + 1); \
(void *)section - (void *)estatus < estatus->data_length; \ (void *)section - (void *)estatus < estatus->data_length; \
section = (void *)(section+1) + section->error_data_length) section = (void *)(section+1) + section->error_data_length)
static inline u32 cper_estatus_len(struct acpi_generic_status *estatus) static inline u32 cper_estatus_len(struct acpi_hest_generic_status *estatus)
{ {
if (estatus->raw_data_length) if (estatus->raw_data_length)
return estatus->raw_data_offset + \ return estatus->raw_data_offset + \
...@@ -135,9 +135,9 @@ static inline u32 cper_estatus_len(struct acpi_generic_status *estatus) ...@@ -135,9 +135,9 @@ static inline u32 cper_estatus_len(struct acpi_generic_status *estatus)
} }
void cper_estatus_print(const char *pfx, void cper_estatus_print(const char *pfx,
const struct acpi_generic_status *estatus); const struct acpi_hest_generic_status *estatus);
int cper_estatus_check_header(const struct acpi_generic_status *estatus); int cper_estatus_check_header(const struct acpi_hest_generic_status *estatus);
int cper_estatus_check(const struct acpi_generic_status *estatus); int cper_estatus_check(const struct acpi_hest_generic_status *estatus);
int apei_osc_setup(void); int apei_osc_setup(void);
#endif #endif
...@@ -74,13 +74,13 @@ ...@@ -74,13 +74,13 @@
#define GHES_ESTATUS_CACHE_LEN(estatus_len) \ #define GHES_ESTATUS_CACHE_LEN(estatus_len) \
(sizeof(struct ghes_estatus_cache) + (estatus_len)) (sizeof(struct ghes_estatus_cache) + (estatus_len))
#define GHES_ESTATUS_FROM_CACHE(estatus_cache) \ #define GHES_ESTATUS_FROM_CACHE(estatus_cache) \
((struct acpi_generic_status *) \ ((struct acpi_hest_generic_status *) \
((struct ghes_estatus_cache *)(estatus_cache) + 1)) ((struct ghes_estatus_cache *)(estatus_cache) + 1))
#define GHES_ESTATUS_NODE_LEN(estatus_len) \ #define GHES_ESTATUS_NODE_LEN(estatus_len) \
(sizeof(struct ghes_estatus_node) + (estatus_len)) (sizeof(struct ghes_estatus_node) + (estatus_len))
#define GHES_ESTATUS_FROM_NODE(estatus_node) \ #define GHES_ESTATUS_FROM_NODE(estatus_node) \
((struct acpi_generic_status *) \ ((struct acpi_hest_generic_status *) \
((struct ghes_estatus_node *)(estatus_node) + 1)) ((struct ghes_estatus_node *)(estatus_node) + 1))
bool ghes_disable; bool ghes_disable;
...@@ -388,7 +388,7 @@ static void ghes_clear_estatus(struct ghes *ghes) ...@@ -388,7 +388,7 @@ static void ghes_clear_estatus(struct ghes *ghes)
ghes->flags &= ~GHES_TO_CLEAR; ghes->flags &= ~GHES_TO_CLEAR;
} }
static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev) static void ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, int sev)
{ {
#ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE #ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE
unsigned long pfn; unsigned long pfn;
...@@ -421,10 +421,10 @@ static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev) ...@@ -421,10 +421,10 @@ static void ghes_handle_memory_failure(struct acpi_generic_data *gdata, int sev)
} }
static void ghes_do_proc(struct ghes *ghes, static void ghes_do_proc(struct ghes *ghes,
const struct acpi_generic_status *estatus) const struct acpi_hest_generic_status *estatus)
{ {
int sev, sec_sev; int sev, sec_sev;
struct acpi_generic_data *gdata; struct acpi_hest_generic_data *gdata;
sev = ghes_severity(estatus->error_severity); sev = ghes_severity(estatus->error_severity);
apei_estatus_for_each_section(estatus, gdata) { apei_estatus_for_each_section(estatus, gdata) {
...@@ -476,7 +476,7 @@ static void ghes_do_proc(struct ghes *ghes, ...@@ -476,7 +476,7 @@ static void ghes_do_proc(struct ghes *ghes,
static void __ghes_print_estatus(const char *pfx, static void __ghes_print_estatus(const char *pfx,
const struct acpi_hest_generic *generic, const struct acpi_hest_generic *generic,
const struct acpi_generic_status *estatus) const struct acpi_hest_generic_status *estatus)
{ {
static atomic_t seqno; static atomic_t seqno;
unsigned int curr_seqno; unsigned int curr_seqno;
...@@ -498,7 +498,7 @@ static void __ghes_print_estatus(const char *pfx, ...@@ -498,7 +498,7 @@ static void __ghes_print_estatus(const char *pfx,
static int ghes_print_estatus(const char *pfx, static int ghes_print_estatus(const char *pfx,
const struct acpi_hest_generic *generic, const struct acpi_hest_generic *generic,
const struct acpi_generic_status *estatus) const struct acpi_hest_generic_status *estatus)
{ {
/* Not more than 2 messages every 5 seconds */ /* Not more than 2 messages every 5 seconds */
static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2); static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2);
...@@ -520,13 +520,13 @@ static int ghes_print_estatus(const char *pfx, ...@@ -520,13 +520,13 @@ static int ghes_print_estatus(const char *pfx,
* GHES error status reporting throttle, to report more kinds of * GHES error status reporting throttle, to report more kinds of
* errors, instead of just most frequently occurred errors. * errors, instead of just most frequently occurred errors.
*/ */
static int ghes_estatus_cached(struct acpi_generic_status *estatus) static int ghes_estatus_cached(struct acpi_hest_generic_status *estatus)
{ {
u32 len; u32 len;
int i, cached = 0; int i, cached = 0;
unsigned long long now; unsigned long long now;
struct ghes_estatus_cache *cache; struct ghes_estatus_cache *cache;
struct acpi_generic_status *cache_estatus; struct acpi_hest_generic_status *cache_estatus;
len = cper_estatus_len(estatus); len = cper_estatus_len(estatus);
rcu_read_lock(); rcu_read_lock();
...@@ -551,12 +551,12 @@ static int ghes_estatus_cached(struct acpi_generic_status *estatus) ...@@ -551,12 +551,12 @@ static int ghes_estatus_cached(struct acpi_generic_status *estatus)
static struct ghes_estatus_cache *ghes_estatus_cache_alloc( static struct ghes_estatus_cache *ghes_estatus_cache_alloc(
struct acpi_hest_generic *generic, struct acpi_hest_generic *generic,
struct acpi_generic_status *estatus) struct acpi_hest_generic_status *estatus)
{ {
int alloced; int alloced;
u32 len, cache_len; u32 len, cache_len;
struct ghes_estatus_cache *cache; struct ghes_estatus_cache *cache;
struct acpi_generic_status *cache_estatus; struct acpi_hest_generic_status *cache_estatus;
alloced = atomic_add_return(1, &ghes_estatus_cache_alloced); alloced = atomic_add_return(1, &ghes_estatus_cache_alloced);
if (alloced > GHES_ESTATUS_CACHE_ALLOCED_MAX) { if (alloced > GHES_ESTATUS_CACHE_ALLOCED_MAX) {
...@@ -599,7 +599,7 @@ static void ghes_estatus_cache_rcu_free(struct rcu_head *head) ...@@ -599,7 +599,7 @@ static void ghes_estatus_cache_rcu_free(struct rcu_head *head)
static void ghes_estatus_cache_add( static void ghes_estatus_cache_add(
struct acpi_hest_generic *generic, struct acpi_hest_generic *generic,
struct acpi_generic_status *estatus) struct acpi_hest_generic_status *estatus)
{ {
int i, slot = -1, count; int i, slot = -1, count;
unsigned long long now, duration, period, max_period = 0; unsigned long long now, duration, period, max_period = 0;
...@@ -757,7 +757,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work) ...@@ -757,7 +757,7 @@ static void ghes_proc_in_irq(struct irq_work *irq_work)
struct llist_node *llnode, *next; struct llist_node *llnode, *next;
struct ghes_estatus_node *estatus_node; struct ghes_estatus_node *estatus_node;
struct acpi_hest_generic *generic; struct acpi_hest_generic *generic;
struct acpi_generic_status *estatus; struct acpi_hest_generic_status *estatus;
u32 len, node_len; u32 len, node_len;
llnode = llist_del_all(&ghes_estatus_llist); llnode = llist_del_all(&ghes_estatus_llist);
...@@ -790,7 +790,7 @@ static void ghes_print_queued_estatus(void) ...@@ -790,7 +790,7 @@ static void ghes_print_queued_estatus(void)
struct llist_node *llnode; struct llist_node *llnode;
struct ghes_estatus_node *estatus_node; struct ghes_estatus_node *estatus_node;
struct acpi_hest_generic *generic; struct acpi_hest_generic *generic;
struct acpi_generic_status *estatus; struct acpi_hest_generic_status *estatus;
u32 len, node_len; u32 len, node_len;
llnode = llist_del_all(&ghes_estatus_llist); llnode = llist_del_all(&ghes_estatus_llist);
...@@ -849,7 +849,7 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs) ...@@ -849,7 +849,7 @@ static int ghes_notify_nmi(unsigned int cmd, struct pt_regs *regs)
#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG #ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
u32 len, node_len; u32 len, node_len;
struct ghes_estatus_node *estatus_node; struct ghes_estatus_node *estatus_node;
struct acpi_generic_status *estatus; struct acpi_hest_generic_status *estatus;
#endif #endif
if (!(ghes->flags & GHES_TO_CLEAR)) if (!(ghes->flags & GHES_TO_CLEAR))
continue; continue;
...@@ -991,7 +991,7 @@ static int ghes_probe(struct platform_device *ghes_dev) ...@@ -991,7 +991,7 @@ static int ghes_probe(struct platform_device *ghes_dev)
rc = -EIO; rc = -EIO;
if (generic->error_block_length < if (generic->error_block_length <
sizeof(struct acpi_generic_status)) { sizeof(struct acpi_hest_generic_status)) {
pr_warning(FW_BUG GHES_PFX "Invalid error block length: %u for generic hardware error source: %d\n", pr_warning(FW_BUG GHES_PFX "Invalid error block length: %u for generic hardware error source: %d\n",
generic->error_block_length, generic->error_block_length,
generic->header.source_id); generic->header.source_id);
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/delay.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#ifdef CONFIG_ACPI_PROCFS_POWER #ifdef CONFIG_ACPI_PROCFS_POWER
......
...@@ -247,75 +247,11 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { ...@@ -247,75 +247,11 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
}, },
/* /*
* The following machines have broken backlight support when reporting * These machines will power on immediately after shutdown when
* the Windows 2012 OSI, so disable it until their support is fixed. * reporting the Windows 2012 OSI.
*/ */
{ {
.callback = dmi_disable_osi_win8, .callback = dmi_disable_osi_win8,
.ident = "ASUS Zenbook Prime UX31A",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "UX31A"),
},
},
{
.callback = dmi_disable_osi_win8,
.ident = "ThinkPad Edge E530",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "3259A2G"),
},
},
{
.callback = dmi_disable_osi_win8,
.ident = "ThinkPad Edge E530",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "3259CTO"),
},
},
{
.callback = dmi_disable_osi_win8,
.ident = "ThinkPad Edge E530",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "3259HJG"),
},
},
{
.callback = dmi_disable_osi_win8,
.ident = "Acer Aspire V5-573G",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"),
DMI_MATCH(DMI_PRODUCT_VERSION, "V5-573G/Dazzle_HW"),
},
},
{
.callback = dmi_disable_osi_win8,
.ident = "Acer Aspire V5-572G",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"),
DMI_MATCH(DMI_PRODUCT_VERSION, "V5-572G/Dazzle_CX"),
},
},
{
.callback = dmi_disable_osi_win8,
.ident = "ThinkPad T431s",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "20AACTO1WW"),
},
},
{
.callback = dmi_disable_osi_win8,
.ident = "ThinkPad T430",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"),
},
},
{
.callback = dmi_disable_osi_win8,
.ident = "Dell Inspiron 7737", .ident = "Dell Inspiron 7737",
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
......
...@@ -477,9 +477,6 @@ static int __init acpi_bus_init_irq(void) ...@@ -477,9 +477,6 @@ static int __init acpi_bus_init_irq(void)
return 0; return 0;
} }
u8 acpi_gbl_permanent_mmap;
void __init acpi_early_init(void) void __init acpi_early_init(void)
{ {
acpi_status status; acpi_status status;
......
...@@ -79,11 +79,13 @@ static int acpi_button_remove(struct acpi_device *device); ...@@ -79,11 +79,13 @@ static int acpi_button_remove(struct acpi_device *device);
static void acpi_button_notify(struct acpi_device *device, u32 event); static void acpi_button_notify(struct acpi_device *device, u32 event);
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int acpi_button_suspend(struct device *dev);
static int acpi_button_resume(struct device *dev); static int acpi_button_resume(struct device *dev);
#else #else
#define acpi_button_suspend NULL
#define acpi_button_resume NULL #define acpi_button_resume NULL
#endif #endif
static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume); static SIMPLE_DEV_PM_OPS(acpi_button_pm, acpi_button_suspend, acpi_button_resume);
static struct acpi_driver acpi_button_driver = { static struct acpi_driver acpi_button_driver = {
.name = "button", .name = "button",
...@@ -102,6 +104,7 @@ struct acpi_button { ...@@ -102,6 +104,7 @@ struct acpi_button {
struct input_dev *input; struct input_dev *input;
char phys[32]; /* for input device */ char phys[32]; /* for input device */
unsigned long pushed; unsigned long pushed;
bool suspended;
}; };
static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier);
...@@ -293,15 +296,19 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) ...@@ -293,15 +296,19 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
if (button->type == ACPI_BUTTON_TYPE_LID) { if (button->type == ACPI_BUTTON_TYPE_LID) {
acpi_lid_send_state(device); acpi_lid_send_state(device);
} else { } else {
int keycode = test_bit(KEY_SLEEP, input->keybit) ? int keycode;
KEY_SLEEP : KEY_POWER;
pm_wakeup_event(&device->dev, 0);
if (button->suspended)
break;
keycode = test_bit(KEY_SLEEP, input->keybit) ?
KEY_SLEEP : KEY_POWER;
input_report_key(input, keycode, 1); input_report_key(input, keycode, 1);
input_sync(input); input_sync(input);
input_report_key(input, keycode, 0); input_report_key(input, keycode, 0);
input_sync(input); input_sync(input);
pm_wakeup_event(&device->dev, 0);
acpi_bus_generate_netlink_event( acpi_bus_generate_netlink_event(
device->pnp.device_class, device->pnp.device_class,
dev_name(&device->dev), dev_name(&device->dev),
...@@ -316,11 +323,21 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) ...@@ -316,11 +323,21 @@ static void acpi_button_notify(struct acpi_device *device, u32 event)
} }
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
static int acpi_button_suspend(struct device *dev)
{
struct acpi_device *device = to_acpi_device(dev);
struct acpi_button *button = acpi_driver_data(device);
button->suspended = true;
return 0;
}
static int acpi_button_resume(struct device *dev) static int acpi_button_resume(struct device *dev)
{ {
struct acpi_device *device = to_acpi_device(dev); struct acpi_device *device = to_acpi_device(dev);
struct acpi_button *button = acpi_driver_data(device); struct acpi_button *button = acpi_driver_data(device);
button->suspended = false;
if (button->type == ACPI_BUTTON_TYPE_LID) if (button->type == ACPI_BUTTON_TYPE_LID)
return acpi_lid_send_state(device); return acpi_lid_send_state(device);
return 0; return 0;
......
This diff is collapsed.
...@@ -84,8 +84,6 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, ...@@ -84,8 +84,6 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle,
int type, unsigned long long sta); int type, unsigned long long sta);
void acpi_device_add_finalize(struct acpi_device *device); void acpi_device_add_finalize(struct acpi_device *device);
void acpi_free_pnp_ids(struct acpi_device_pnp *pnp); void acpi_free_pnp_ids(struct acpi_device_pnp *pnp);
int acpi_bind_one(struct device *dev, struct acpi_device *adev);
int acpi_unbind_one(struct device *dev);
bool acpi_device_is_present(struct acpi_device *adev); bool acpi_device_is_present(struct acpi_device *adev);
bool acpi_device_is_battery(struct acpi_device *adev); bool acpi_device_is_battery(struct acpi_device *adev);
...@@ -108,7 +106,12 @@ int acpi_power_transition(struct acpi_device *device, int state); ...@@ -108,7 +106,12 @@ int acpi_power_transition(struct acpi_device *device, int state);
int acpi_device_update_power(struct acpi_device *device, int *state_p); int acpi_device_update_power(struct acpi_device *device, int *state_p);
int acpi_wakeup_device_init(void); int acpi_wakeup_device_init(void);
#ifdef CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC
void acpi_early_processor_set_pdc(void); void acpi_early_processor_set_pdc(void);
#else
static inline void acpi_early_processor_set_pdc(void) {}
#endif
/* -------------------------------------------------------------------------- /* --------------------------------------------------------------------------
Embedded Controller Embedded Controller
......
...@@ -259,12 +259,14 @@ acpi_physical_address __init acpi_os_get_root_pointer(void) ...@@ -259,12 +259,14 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
"System description tables not found\n"); "System description tables not found\n");
return 0; return 0;
} }
} else { } else if (IS_ENABLED(CONFIG_ACPI_LEGACY_TABLES_LOOKUP)) {
acpi_physical_address pa = 0; acpi_physical_address pa = 0;
acpi_find_root_pointer(&pa); acpi_find_root_pointer(&pa);
return pa; return pa;
} }
return 0;
} }
/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */ /* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
......
...@@ -593,7 +593,7 @@ static int acpi_pci_root_add(struct acpi_device *device, ...@@ -593,7 +593,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
if (no_aspm) if (no_aspm)
pcie_no_aspm(); pcie_no_aspm();
pci_acpi_add_bus_pm_notifier(device, root->bus); pci_acpi_add_bus_pm_notifier(device);
if (device->wakeup.flags.run_wake) if (device->wakeup.flags.run_wake)
device_set_run_wake(root->bus->bridge, true); device_set_run_wake(root->bus->bridge, true);
......
...@@ -4,17 +4,11 @@ ...@@ -4,17 +4,11 @@
* *
* Alex Chiang <achiang@hp.com> * Alex Chiang <achiang@hp.com>
* - Unified x86/ia64 implementations * - Unified x86/ia64 implementations
* Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
* - Added _PDC for platforms with Intel CPUs
*/ */
#include <linux/export.h> #include <linux/export.h>
#include <linux/dmi.h>
#include <linux/slab.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <acpi/processor.h> #include <acpi/processor.h>
#include "internal.h"
#define _COMPONENT ACPI_PROCESSOR_COMPONENT #define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME("processor_core"); ACPI_MODULE_NAME("processor_core");
...@@ -135,6 +129,8 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) ...@@ -135,6 +129,8 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id)
map_lapic_id(header, acpi_id, &apic_id); map_lapic_id(header, acpi_id, &apic_id);
} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) { } else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
map_lsapic_id(header, type, acpi_id, &apic_id); map_lsapic_id(header, type, acpi_id, &apic_id);
} else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
map_x2apic_id(header, type, acpi_id, &apic_id);
} }
exit: exit:
...@@ -208,195 +204,3 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id) ...@@ -208,195 +204,3 @@ int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
return acpi_map_cpuid(apic_id, acpi_id); return acpi_map_cpuid(apic_id, acpi_id);
} }
EXPORT_SYMBOL_GPL(acpi_get_cpuid); EXPORT_SYMBOL_GPL(acpi_get_cpuid);
static bool __init processor_physically_present(acpi_handle handle)
{
int cpuid, type;
u32 acpi_id;
acpi_status status;
acpi_object_type acpi_type;
unsigned long long tmp;
union acpi_object object = { 0 };
struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
status = acpi_get_type(handle, &acpi_type);
if (ACPI_FAILURE(status))
return false;
switch (acpi_type) {
case ACPI_TYPE_PROCESSOR:
status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
if (ACPI_FAILURE(status))
return false;
acpi_id = object.processor.proc_id;
break;
case ACPI_TYPE_DEVICE:
status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp);
if (ACPI_FAILURE(status))
return false;
acpi_id = tmp;
break;
default:
return false;
}
type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
cpuid = acpi_get_cpuid(handle, type, acpi_id);
if (cpuid == -1)
return false;
return true;
}
static void acpi_set_pdc_bits(u32 *buf)
{
buf[0] = ACPI_PDC_REVISION_ID;
buf[1] = 1;
/* Enable coordination with firmware's _TSD info */
buf[2] = ACPI_PDC_SMP_T_SWCOORD;
/* Twiddle arch-specific bits needed for _PDC */
arch_acpi_set_pdc_bits(buf);
}
static struct acpi_object_list *acpi_processor_alloc_pdc(void)
{
struct acpi_object_list *obj_list;
union acpi_object *obj;
u32 *buf;
/* allocate and initialize pdc. It will be used later. */
obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
if (!obj_list) {
printk(KERN_ERR "Memory allocation error\n");
return NULL;
}
obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
if (!obj) {
printk(KERN_ERR "Memory allocation error\n");
kfree(obj_list);
return NULL;
}
buf = kmalloc(12, GFP_KERNEL);
if (!buf) {
printk(KERN_ERR "Memory allocation error\n");
kfree(obj);
kfree(obj_list);
return NULL;
}
acpi_set_pdc_bits(buf);
obj->type = ACPI_TYPE_BUFFER;
obj->buffer.length = 12;
obj->buffer.pointer = (u8 *) buf;
obj_list->count = 1;
obj_list->pointer = obj;
return obj_list;
}
/*
* _PDC is required for a BIOS-OS handshake for most of the newer
* ACPI processor features.
*/
static acpi_status
acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
{
acpi_status status = AE_OK;
if (boot_option_idle_override == IDLE_NOMWAIT) {
/*
* If mwait is disabled for CPU C-states, the C2C3_FFH access
* mode will be disabled in the parameter of _PDC object.
* Of course C1_FFH access mode will also be disabled.
*/
union acpi_object *obj;
u32 *buffer = NULL;
obj = pdc_in->pointer;
buffer = (u32 *)(obj->buffer.pointer);
buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
}
status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL);
if (ACPI_FAILURE(status))
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Could not evaluate _PDC, using legacy perf. control.\n"));
return status;
}
void acpi_processor_set_pdc(acpi_handle handle)
{
struct acpi_object_list *obj_list;
if (arch_has_acpi_pdc() == false)
return;
obj_list = acpi_processor_alloc_pdc();
if (!obj_list)
return;
acpi_processor_eval_pdc(handle, obj_list);
kfree(obj_list->pointer->buffer.pointer);
kfree(obj_list->pointer);
kfree(obj_list);
}
static acpi_status __init
early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
{
if (processor_physically_present(handle) == false)
return AE_OK;
acpi_processor_set_pdc(handle);
return AE_OK;
}
#if defined(CONFIG_X86) || defined(CONFIG_IA64)
static int __init set_no_mwait(const struct dmi_system_id *id)
{
pr_notice(PREFIX "%s detected - disabling mwait for CPU C-states\n",
id->ident);
boot_option_idle_override = IDLE_NOMWAIT;
return 0;
}
static struct dmi_system_id processor_idle_dmi_table[] __initdata = {
{
set_no_mwait, "Extensa 5220", {
DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
{},
};
static void __init processor_dmi_check(void)
{
/*
* Check whether the system is DMI table. If yes, OSPM
* should not use mwait for CPU-states.
*/
dmi_check_system(processor_idle_dmi_table);
}
#else
static inline void processor_dmi_check(void) {}
#endif
void __init acpi_early_processor_set_pdc(void)
{
processor_dmi_check();
acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX,
early_init_pdc, NULL, NULL, NULL);
acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, early_init_pdc, NULL, NULL);
}
/*
* Copyright (C) 2005 Intel Corporation
* Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
*
* Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
* - Added _PDC for platforms with Intel CPUs
*/
#define pr_fmt(fmt) "ACPI: " fmt
#include <linux/dmi.h>
#include <linux/slab.h>
#include <linux/acpi.h>
#include <acpi/processor.h>
#include "internal.h"
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME("processor_pdc");
static bool __init processor_physically_present(acpi_handle handle)
{
int cpuid, type;
u32 acpi_id;
acpi_status status;
acpi_object_type acpi_type;
unsigned long long tmp;
union acpi_object object = { 0 };
struct acpi_buffer buffer = { sizeof(union acpi_object), &object };
status = acpi_get_type(handle, &acpi_type);
if (ACPI_FAILURE(status))
return false;
switch (acpi_type) {
case ACPI_TYPE_PROCESSOR:
status = acpi_evaluate_object(handle, NULL, NULL, &buffer);
if (ACPI_FAILURE(status))
return false;
acpi_id = object.processor.proc_id;
break;
case ACPI_TYPE_DEVICE:
status = acpi_evaluate_integer(handle, "_UID", NULL, &tmp);
if (ACPI_FAILURE(status))
return false;
acpi_id = tmp;
break;
default:
return false;
}
type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
cpuid = acpi_get_cpuid(handle, type, acpi_id);
if (cpuid == -1)
return false;
return true;
}
static void acpi_set_pdc_bits(u32 *buf)
{
buf[0] = ACPI_PDC_REVISION_ID;
buf[1] = 1;
/* Enable coordination with firmware's _TSD info */
buf[2] = ACPI_PDC_SMP_T_SWCOORD;
/* Twiddle arch-specific bits needed for _PDC */
arch_acpi_set_pdc_bits(buf);
}
static struct acpi_object_list *acpi_processor_alloc_pdc(void)
{
struct acpi_object_list *obj_list;
union acpi_object *obj;
u32 *buf;
/* allocate and initialize pdc. It will be used later. */
obj_list = kmalloc(sizeof(struct acpi_object_list), GFP_KERNEL);
if (!obj_list)
goto out;
obj = kmalloc(sizeof(union acpi_object), GFP_KERNEL);
if (!obj) {
kfree(obj_list);
goto out;
}
buf = kmalloc(12, GFP_KERNEL);
if (!buf) {
kfree(obj);
kfree(obj_list);
goto out;
}
acpi_set_pdc_bits(buf);
obj->type = ACPI_TYPE_BUFFER;
obj->buffer.length = 12;
obj->buffer.pointer = (u8 *) buf;
obj_list->count = 1;
obj_list->pointer = obj;
return obj_list;
out:
pr_err("Memory allocation error\n");
return NULL;
}
/*
* _PDC is required for a BIOS-OS handshake for most of the newer
* ACPI processor features.
*/
static acpi_status
acpi_processor_eval_pdc(acpi_handle handle, struct acpi_object_list *pdc_in)
{
acpi_status status = AE_OK;
if (boot_option_idle_override == IDLE_NOMWAIT) {
/*
* If mwait is disabled for CPU C-states, the C2C3_FFH access
* mode will be disabled in the parameter of _PDC object.
* Of course C1_FFH access mode will also be disabled.
*/
union acpi_object *obj;
u32 *buffer = NULL;
obj = pdc_in->pointer;
buffer = (u32 *)(obj->buffer.pointer);
buffer[2] &= ~(ACPI_PDC_C_C2C3_FFH | ACPI_PDC_C_C1_FFH);
}
status = acpi_evaluate_object(handle, "_PDC", pdc_in, NULL);
if (ACPI_FAILURE(status))
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Could not evaluate _PDC, using legacy perf. control.\n"));
return status;
}
void acpi_processor_set_pdc(acpi_handle handle)
{
struct acpi_object_list *obj_list;
if (arch_has_acpi_pdc() == false)
return;
obj_list = acpi_processor_alloc_pdc();
if (!obj_list)
return;
acpi_processor_eval_pdc(handle, obj_list);
kfree(obj_list->pointer->buffer.pointer);
kfree(obj_list->pointer);
kfree(obj_list);
}
static acpi_status __init
early_init_pdc(acpi_handle handle, u32 lvl, void *context, void **rv)
{
if (processor_physically_present(handle) == false)
return AE_OK;
acpi_processor_set_pdc(handle);
return AE_OK;
}
static int __init set_no_mwait(const struct dmi_system_id *id)
{
pr_notice("%s detected - disabling mwait for CPU C-states\n",
id->ident);
boot_option_idle_override = IDLE_NOMWAIT;
return 0;
}
static struct dmi_system_id processor_idle_dmi_table[] __initdata = {
{
set_no_mwait, "Extensa 5220", {
DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"),
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
DMI_MATCH(DMI_PRODUCT_VERSION, "0100"),
DMI_MATCH(DMI_BOARD_NAME, "Columbia") }, NULL},
{},
};
static void __init processor_dmi_check(void)
{
/*
* Check whether the system is DMI table. If yes, OSPM
* should not use mwait for CPU-states.
*/
dmi_check_system(processor_idle_dmi_table);
}
void __init acpi_early_processor_set_pdc(void)
{
processor_dmi_check();
acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
ACPI_UINT32_MAX,
early_init_pdc, NULL, NULL, NULL);
acpi_get_devices(ACPI_PROCESSOR_DEVICE_HID, early_init_pdc, NULL, NULL);
}
...@@ -77,7 +77,9 @@ void acpi_initialize_hp_context(struct acpi_device *adev, ...@@ -77,7 +77,9 @@ void acpi_initialize_hp_context(struct acpi_device *adev,
void (*uevent)(struct acpi_device *, u32)) void (*uevent)(struct acpi_device *, u32))
{ {
acpi_lock_hp_context(); acpi_lock_hp_context();
acpi_set_hp_context(adev, hp, notify, uevent, NULL); hp->notify = notify;
hp->uevent = uevent;
acpi_set_hp_context(adev, hp);
acpi_unlock_hp_context(); acpi_unlock_hp_context();
} }
EXPORT_SYMBOL_GPL(acpi_initialize_hp_context); EXPORT_SYMBOL_GPL(acpi_initialize_hp_context);
...@@ -1421,14 +1423,13 @@ static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, ...@@ -1421,14 +1423,13 @@ static int acpi_bus_extract_wakeup_device_power_package(acpi_handle handle,
wakeup->sleep_state = sleep_state; wakeup->sleep_state = sleep_state;
} }
} }
acpi_setup_gpe_for_wake(handle, wakeup->gpe_device, wakeup->gpe_number);
out: out:
kfree(buffer.pointer); kfree(buffer.pointer);
return err; return err;
} }
static void acpi_bus_set_run_wake_flags(struct acpi_device *device) static void acpi_wakeup_gpe_init(struct acpi_device *device)
{ {
struct acpi_device_id button_device_ids[] = { struct acpi_device_id button_device_ids[] = {
{"PNP0C0C", 0}, {"PNP0C0C", 0},
...@@ -1436,29 +1437,33 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) ...@@ -1436,29 +1437,33 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device)
{"PNP0C0E", 0}, {"PNP0C0E", 0},
{"", 0}, {"", 0},
}; };
struct acpi_device_wakeup *wakeup = &device->wakeup;
acpi_status status; acpi_status status;
acpi_event_status event_status; acpi_event_status event_status;
device->wakeup.flags.notifier_present = 0; wakeup->flags.notifier_present = 0;
/* Power button, Lid switch always enable wakeup */ /* Power button, Lid switch always enable wakeup */
if (!acpi_match_device_ids(device, button_device_ids)) { if (!acpi_match_device_ids(device, button_device_ids)) {
device->wakeup.flags.run_wake = 1; wakeup->flags.run_wake = 1;
if (!acpi_match_device_ids(device, &button_device_ids[1])) { if (!acpi_match_device_ids(device, &button_device_ids[1])) {
/* Do not use Lid/sleep button for S5 wakeup */ /* Do not use Lid/sleep button for S5 wakeup */
if (device->wakeup.sleep_state == ACPI_STATE_S5) if (wakeup->sleep_state == ACPI_STATE_S5)
device->wakeup.sleep_state = ACPI_STATE_S4; wakeup->sleep_state = ACPI_STATE_S4;
} }
acpi_mark_gpe_for_wake(wakeup->gpe_device, wakeup->gpe_number);
device_set_wakeup_capable(&device->dev, true); device_set_wakeup_capable(&device->dev, true);
return; return;
} }
status = acpi_get_gpe_status(device->wakeup.gpe_device, acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device,
device->wakeup.gpe_number, wakeup->gpe_number);
&event_status); status = acpi_get_gpe_status(wakeup->gpe_device, wakeup->gpe_number,
if (status == AE_OK) &event_status);
device->wakeup.flags.run_wake = if (ACPI_FAILURE(status))
!!(event_status & ACPI_EVENT_FLAG_HANDLE); return;
wakeup->flags.run_wake = !!(event_status & ACPI_EVENT_FLAG_HANDLE);
} }
static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
...@@ -1478,7 +1483,7 @@ static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device) ...@@ -1478,7 +1483,7 @@ static void acpi_bus_get_wakeup_device_flags(struct acpi_device *device)
device->wakeup.flags.valid = 1; device->wakeup.flags.valid = 1;
device->wakeup.prepare_count = 0; device->wakeup.prepare_count = 0;
acpi_bus_set_run_wake_flags(device); acpi_wakeup_gpe_init(device);
/* Call _PSW/_DSW object to disable its ability to wake the sleeping /* Call _PSW/_DSW object to disable its ability to wake the sleeping
* system for the ACPI device with the _PRW object. * system for the ACPI device with the _PRW object.
* The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW.
......
...@@ -322,6 +322,11 @@ static struct dmi_system_id acpisleep_dmi_table[] __initdata = { ...@@ -322,6 +322,11 @@ static struct dmi_system_id acpisleep_dmi_table[] __initdata = {
static void acpi_sleep_dmi_check(void) static void acpi_sleep_dmi_check(void)
{ {
int year;
if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2012)
acpi_nvs_nosave_s3();
dmi_check_system(acpisleep_dmi_table); dmi_check_system(acpisleep_dmi_table);
} }
......
...@@ -204,6 +204,8 @@ struct acpi_video_device { ...@@ -204,6 +204,8 @@ struct acpi_video_device {
struct acpi_video_device_flags flags; struct acpi_video_device_flags flags;
struct acpi_video_device_cap cap; struct acpi_video_device_cap cap;
struct list_head entry; struct list_head entry;
struct delayed_work switch_brightness_work;
int switch_brightness_event;
struct acpi_video_bus *video; struct acpi_video_bus *video;
struct acpi_device *dev; struct acpi_device *dev;
struct acpi_video_device_brightness *brightness; struct acpi_video_device_brightness *brightness;
...@@ -230,8 +232,7 @@ static int acpi_video_device_lcd_get_level_current( ...@@ -230,8 +232,7 @@ static int acpi_video_device_lcd_get_level_current(
unsigned long long *level, bool raw); unsigned long long *level, bool raw);
static int acpi_video_get_next_level(struct acpi_video_device *device, static int acpi_video_get_next_level(struct acpi_video_device *device,
u32 level_current, u32 event); u32 level_current, u32 event);
static int acpi_video_switch_brightness(struct acpi_video_device *device, static void acpi_video_switch_brightness(struct work_struct *work);
int event);
static bool acpi_video_use_native_backlight(void) static bool acpi_video_use_native_backlight(void)
{ {
...@@ -275,6 +276,7 @@ static int acpi_video_set_brightness(struct backlight_device *bd) ...@@ -275,6 +276,7 @@ static int acpi_video_set_brightness(struct backlight_device *bd)
int request_level = bd->props.brightness + 2; int request_level = bd->props.brightness + 2;
struct acpi_video_device *vd = bl_get_data(bd); struct acpi_video_device *vd = bl_get_data(bd);
cancel_delayed_work(&vd->switch_brightness_work);
return acpi_video_device_lcd_set_level(vd, return acpi_video_device_lcd_set_level(vd,
vd->brightness->levels[request_level]); vd->brightness->levels[request_level]);
} }
...@@ -459,6 +461,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = { ...@@ -459,6 +461,14 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"), DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720"),
}, },
}, },
{
.callback = video_set_use_native_backlight,
.ident = "ThinkPad X230",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"),
},
},
{ {
.callback = video_set_use_native_backlight, .callback = video_set_use_native_backlight,
.ident = "ThinkPad T430 and T430s", .ident = "ThinkPad T430 and T430s",
...@@ -469,10 +479,42 @@ static struct dmi_system_id video_dmi_table[] __initdata = { ...@@ -469,10 +479,42 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
}, },
{ {
.callback = video_set_use_native_backlight, .callback = video_set_use_native_backlight,
.ident = "ThinkPad X230", .ident = "ThinkPad T430",
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"), DMI_MATCH(DMI_PRODUCT_VERSION, "2349D15"),
},
},
{
.callback = video_set_use_native_backlight,
.ident = "ThinkPad T431s",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "20AACTO1WW"),
},
},
{
.callback = video_set_use_native_backlight,
.ident = "ThinkPad Edge E530",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "3259A2G"),
},
},
{
.callback = video_set_use_native_backlight,
.ident = "ThinkPad Edge E530",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "3259CTO"),
},
},
{
.callback = video_set_use_native_backlight,
.ident = "ThinkPad Edge E530",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
DMI_MATCH(DMI_PRODUCT_VERSION, "3259HJG"),
}, },
}, },
{ {
...@@ -571,6 +613,30 @@ static struct dmi_system_id video_dmi_table[] __initdata = { ...@@ -571,6 +613,30 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate B113"), DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate B113"),
}, },
}, },
{
.callback = video_set_use_native_backlight,
.ident = "Acer Aspire V5-572G",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"),
DMI_MATCH(DMI_PRODUCT_VERSION, "V5-572G/Dazzle_CX"),
},
},
{
.callback = video_set_use_native_backlight,
.ident = "Acer Aspire V5-573G",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Acer Aspire"),
DMI_MATCH(DMI_PRODUCT_VERSION, "V5-573G/Dazzle_HW"),
},
},
{
.callback = video_set_use_native_backlight,
.ident = "ASUS Zenbook Prime UX31A",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "UX31A"),
},
},
{ {
.callback = video_set_use_native_backlight, .callback = video_set_use_native_backlight,
.ident = "HP ProBook 4340s", .ident = "HP ProBook 4340s",
...@@ -607,6 +673,15 @@ static struct dmi_system_id video_dmi_table[] __initdata = { ...@@ -607,6 +673,15 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
}, },
{ {
.callback = video_set_use_native_backlight, .callback = video_set_use_native_backlight,
.ident = "HP EliteBook 2014 models",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
DMI_MATCH(DMI_PRODUCT_NAME, "HP EliteBook "),
DMI_MATCH(DMI_PRODUCT_NAME, " G2"),
},
},
{
.callback = video_set_use_native_backlight,
.ident = "HP ZBook 14", .ident = "HP ZBook 14",
.matches = { .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
...@@ -1188,6 +1263,8 @@ acpi_video_bus_get_one_device(struct acpi_device *device, ...@@ -1188,6 +1263,8 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
data->device_id = device_id; data->device_id = device_id;
data->video = video; data->video = video;
data->dev = device; data->dev = device;
INIT_DELAYED_WORK(&data->switch_brightness_work,
acpi_video_switch_brightness);
attribute = acpi_video_get_device_attr(video, device_id); attribute = acpi_video_get_device_attr(video, device_id);
...@@ -1410,15 +1487,18 @@ acpi_video_get_next_level(struct acpi_video_device *device, ...@@ -1410,15 +1487,18 @@ acpi_video_get_next_level(struct acpi_video_device *device,
} }
} }
static int static void
acpi_video_switch_brightness(struct acpi_video_device *device, int event) acpi_video_switch_brightness(struct work_struct *work)
{ {
struct acpi_video_device *device = container_of(to_delayed_work(work),
struct acpi_video_device, switch_brightness_work);
unsigned long long level_current, level_next; unsigned long long level_current, level_next;
int event = device->switch_brightness_event;
int result = -EINVAL; int result = -EINVAL;
/* no warning message if acpi_backlight=vendor or a quirk is used */ /* no warning message if acpi_backlight=vendor or a quirk is used */
if (!acpi_video_verify_backlight_support()) if (!acpi_video_verify_backlight_support())
return 0; return;
if (!device->brightness) if (!device->brightness)
goto out; goto out;
...@@ -1440,8 +1520,6 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event) ...@@ -1440,8 +1520,6 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event)
out: out:
if (result) if (result)
printk(KERN_ERR PREFIX "Failed to switch the brightness\n"); printk(KERN_ERR PREFIX "Failed to switch the brightness\n");
return result;
} }
int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
...@@ -1609,6 +1687,16 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event) ...@@ -1609,6 +1687,16 @@ static void acpi_video_bus_notify(struct acpi_device *device, u32 event)
return; return;
} }
static void brightness_switch_event(struct acpi_video_device *video_device,
u32 event)
{
if (!brightness_switch_enabled)
return;
video_device->switch_brightness_event = event;
schedule_delayed_work(&video_device->switch_brightness_work, HZ / 10);
}
static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
{ {
struct acpi_video_device *video_device = data; struct acpi_video_device *video_device = data;
...@@ -1626,28 +1714,23 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) ...@@ -1626,28 +1714,23 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
switch (event) { switch (event) {
case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */
if (brightness_switch_enabled) brightness_switch_event(video_device, event);
acpi_video_switch_brightness(video_device, event);
keycode = KEY_BRIGHTNESS_CYCLE; keycode = KEY_BRIGHTNESS_CYCLE;
break; break;
case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */
if (brightness_switch_enabled) brightness_switch_event(video_device, event);
acpi_video_switch_brightness(video_device, event);
keycode = KEY_BRIGHTNESSUP; keycode = KEY_BRIGHTNESSUP;
break; break;
case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */
if (brightness_switch_enabled) brightness_switch_event(video_device, event);
acpi_video_switch_brightness(video_device, event);
keycode = KEY_BRIGHTNESSDOWN; keycode = KEY_BRIGHTNESSDOWN;
break; break;
case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */ case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightness */
if (brightness_switch_enabled) brightness_switch_event(video_device, event);
acpi_video_switch_brightness(video_device, event);
keycode = KEY_BRIGHTNESS_ZERO; keycode = KEY_BRIGHTNESS_ZERO;
break; break;
case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */
if (brightness_switch_enabled) brightness_switch_event(video_device, event);
acpi_video_switch_brightness(video_device, event);
keycode = KEY_DISPLAY_OFF; keycode = KEY_DISPLAY_OFF;
break; break;
default: default:
......
...@@ -465,6 +465,7 @@ static void dpm_watchdog_clear(struct dpm_watchdog *wd) ...@@ -465,6 +465,7 @@ static void dpm_watchdog_clear(struct dpm_watchdog *wd)
* device_resume_noirq - Execute an "early resume" callback for given device. * device_resume_noirq - Execute an "early resume" callback for given device.
* @dev: Device to handle. * @dev: Device to handle.
* @state: PM transition of the system being carried out. * @state: PM transition of the system being carried out.
* @async: If true, the device is being resumed asynchronously.
* *
* The driver of @dev will not receive interrupts while this function is being * The driver of @dev will not receive interrupts while this function is being
* executed. * executed.
...@@ -594,6 +595,7 @@ static void dpm_resume_noirq(pm_message_t state) ...@@ -594,6 +595,7 @@ static void dpm_resume_noirq(pm_message_t state)
* device_resume_early - Execute an "early resume" callback for given device. * device_resume_early - Execute an "early resume" callback for given device.
* @dev: Device to handle. * @dev: Device to handle.
* @state: PM transition of the system being carried out. * @state: PM transition of the system being carried out.
* @async: If true, the device is being resumed asynchronously.
* *
* Runtime PM is disabled for @dev while this function is being executed. * Runtime PM is disabled for @dev while this function is being executed.
*/ */
...@@ -1004,6 +1006,7 @@ static pm_message_t resume_event(pm_message_t sleep_state) ...@@ -1004,6 +1006,7 @@ static pm_message_t resume_event(pm_message_t sleep_state)
* device_suspend_noirq - Execute a "late suspend" callback for given device. * device_suspend_noirq - Execute a "late suspend" callback for given device.
* @dev: Device to handle. * @dev: Device to handle.
* @state: PM transition of the system being carried out. * @state: PM transition of the system being carried out.
* @async: If true, the device is being suspended asynchronously.
* *
* The driver of @dev will not receive interrupts while this function is being * The driver of @dev will not receive interrupts while this function is being
* executed. * executed.
...@@ -1144,6 +1147,7 @@ static int dpm_suspend_noirq(pm_message_t state) ...@@ -1144,6 +1147,7 @@ static int dpm_suspend_noirq(pm_message_t state)
* device_suspend_late - Execute a "late suspend" callback for given device. * device_suspend_late - Execute a "late suspend" callback for given device.
* @dev: Device to handle. * @dev: Device to handle.
* @state: PM transition of the system being carried out. * @state: PM transition of the system being carried out.
* @async: If true, the device is being suspended asynchronously.
* *
* Runtime PM is disabled for @dev while this function is being executed. * Runtime PM is disabled for @dev while this function is being executed.
*/ */
...@@ -1298,6 +1302,7 @@ EXPORT_SYMBOL_GPL(dpm_suspend_end); ...@@ -1298,6 +1302,7 @@ EXPORT_SYMBOL_GPL(dpm_suspend_end);
* @dev: Device to suspend. * @dev: Device to suspend.
* @state: PM transition of the system being carried out. * @state: PM transition of the system being carried out.
* @cb: Suspend callback to execute. * @cb: Suspend callback to execute.
* @info: string description of caller.
*/ */
static int legacy_suspend(struct device *dev, pm_message_t state, static int legacy_suspend(struct device *dev, pm_message_t state,
int (*cb)(struct device *dev, pm_message_t state), int (*cb)(struct device *dev, pm_message_t state),
......
...@@ -1076,10 +1076,20 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy) ...@@ -1076,10 +1076,20 @@ static void cpufreq_policy_free(struct cpufreq_policy *policy)
kfree(policy); kfree(policy);
} }
static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) static int update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu,
struct device *cpu_dev)
{ {
int ret;
if (WARN_ON(cpu == policy->cpu)) if (WARN_ON(cpu == policy->cpu))
return; return 0;
/* Move kobject to the new policy->cpu */
ret = kobject_move(&policy->kobj, &cpu_dev->kobj);
if (ret) {
pr_err("%s: Failed to move kobj: %d\n", __func__, ret);
return ret;
}
down_write(&policy->rwsem); down_write(&policy->rwsem);
...@@ -1090,6 +1100,8 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) ...@@ -1090,6 +1100,8 @@ static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
blocking_notifier_call_chain(&cpufreq_policy_notifier_list, blocking_notifier_call_chain(&cpufreq_policy_notifier_list,
CPUFREQ_UPDATE_POLICY_CPU, policy); CPUFREQ_UPDATE_POLICY_CPU, policy);
return 0;
} }
static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
...@@ -1153,12 +1165,10 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) ...@@ -1153,12 +1165,10 @@ static int __cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
* the creation of a brand new one. So we need to perform this update * the creation of a brand new one. So we need to perform this update
* by invoking update_policy_cpu(). * by invoking update_policy_cpu().
*/ */
if (recover_policy && cpu != policy->cpu) { if (recover_policy && cpu != policy->cpu)
update_policy_cpu(policy, cpu); WARN_ON(update_policy_cpu(policy, cpu, dev));
WARN_ON(kobject_move(&policy->kobj, &dev->kobj)); else
} else {
policy->cpu = cpu; policy->cpu = cpu;
}
cpumask_copy(policy->cpus, cpumask_of(cpu)); cpumask_copy(policy->cpus, cpumask_of(cpu));
...@@ -1309,38 +1319,11 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif) ...@@ -1309,38 +1319,11 @@ static int cpufreq_add_dev(struct device *dev, struct subsys_interface *sif)
return __cpufreq_add_dev(dev, sif); return __cpufreq_add_dev(dev, sif);
} }
static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
unsigned int old_cpu)
{
struct device *cpu_dev;
int ret;
/* first sibling now owns the new sysfs dir */
cpu_dev = get_cpu_device(cpumask_any_but(policy->cpus, old_cpu));
sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
ret = kobject_move(&policy->kobj, &cpu_dev->kobj);
if (ret) {
pr_err("%s: Failed to move kobj: %d\n", __func__, ret);
down_write(&policy->rwsem);
cpumask_set_cpu(old_cpu, policy->cpus);
up_write(&policy->rwsem);
ret = sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
"cpufreq");
return -EINVAL;
}
return cpu_dev->id;
}
static int __cpufreq_remove_dev_prepare(struct device *dev, static int __cpufreq_remove_dev_prepare(struct device *dev,
struct subsys_interface *sif) struct subsys_interface *sif)
{ {
unsigned int cpu = dev->id, cpus; unsigned int cpu = dev->id, cpus;
int new_cpu, ret; int ret;
unsigned long flags; unsigned long flags;
struct cpufreq_policy *policy; struct cpufreq_policy *policy;
...@@ -1380,14 +1363,23 @@ static int __cpufreq_remove_dev_prepare(struct device *dev, ...@@ -1380,14 +1363,23 @@ static int __cpufreq_remove_dev_prepare(struct device *dev,
if (cpu != policy->cpu) { if (cpu != policy->cpu) {
sysfs_remove_link(&dev->kobj, "cpufreq"); sysfs_remove_link(&dev->kobj, "cpufreq");
} else if (cpus > 1) { } else if (cpus > 1) {
new_cpu = cpufreq_nominate_new_policy_cpu(policy, cpu); /* Nominate new CPU */
if (new_cpu >= 0) { int new_cpu = cpumask_any_but(policy->cpus, cpu);
update_policy_cpu(policy, new_cpu); struct device *cpu_dev = get_cpu_device(new_cpu);
if (!cpufreq_suspended) sysfs_remove_link(&cpu_dev->kobj, "cpufreq");
pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n", ret = update_policy_cpu(policy, new_cpu, cpu_dev);
__func__, new_cpu, cpu); if (ret) {
if (sysfs_create_link(&cpu_dev->kobj, &policy->kobj,
"cpufreq"))
pr_err("%s: Failed to restore kobj link to cpu:%d\n",
__func__, cpu_dev->id);
return ret;
} }
if (!cpufreq_suspended)
pr_debug("%s: policy Kobject moved to cpu: %d from: %d\n",
__func__, new_cpu, cpu);
} else if (cpufreq_driver->stop_cpu && cpufreq_driver->setpolicy) { } else if (cpufreq_driver->stop_cpu && cpufreq_driver->setpolicy) {
cpufreq_driver->stop_cpu(policy); cpufreq_driver->stop_cpu(policy);
} }
......
...@@ -170,21 +170,24 @@ static void od_check_cpu(int cpu, unsigned int load) ...@@ -170,21 +170,24 @@ static void od_check_cpu(int cpu, unsigned int load)
dbs_freq_increase(policy, policy->max); dbs_freq_increase(policy, policy->max);
} else { } else {
/* Calculate the next frequency proportional to load */ /* Calculate the next frequency proportional to load */
unsigned int freq_next; unsigned int freq_next, min_f, max_f;
freq_next = load * policy->cpuinfo.max_freq / 100;
min_f = policy->cpuinfo.min_freq;
max_f = policy->cpuinfo.max_freq;
freq_next = min_f + load * (max_f - min_f) / 100;
/* No longer fully busy, reset rate_mult */ /* No longer fully busy, reset rate_mult */
dbs_info->rate_mult = 1; dbs_info->rate_mult = 1;
if (!od_tuners->powersave_bias) { if (!od_tuners->powersave_bias) {
__cpufreq_driver_target(policy, freq_next, __cpufreq_driver_target(policy, freq_next,
CPUFREQ_RELATION_L); CPUFREQ_RELATION_C);
return; return;
} }
freq_next = od_ops.powersave_bias_target(policy, freq_next, freq_next = od_ops.powersave_bias_target(policy, freq_next,
CPUFREQ_RELATION_L); CPUFREQ_RELATION_L);
__cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_L); __cpufreq_driver_target(policy, freq_next, CPUFREQ_RELATION_C);
} }
} }
......
...@@ -117,7 +117,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, ...@@ -117,7 +117,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
.frequency = 0, .frequency = 0,
}; };
struct cpufreq_frequency_table *pos; struct cpufreq_frequency_table *pos;
unsigned int freq, i = 0; unsigned int freq, diff, i = 0;
pr_debug("request for target %u kHz (relation: %u) for cpu %u\n", pr_debug("request for target %u kHz (relation: %u) for cpu %u\n",
target_freq, relation, policy->cpu); target_freq, relation, policy->cpu);
...@@ -127,6 +127,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, ...@@ -127,6 +127,7 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
suboptimal.frequency = ~0; suboptimal.frequency = ~0;
break; break;
case CPUFREQ_RELATION_L: case CPUFREQ_RELATION_L:
case CPUFREQ_RELATION_C:
optimal.frequency = ~0; optimal.frequency = ~0;
break; break;
} }
...@@ -168,6 +169,15 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy, ...@@ -168,6 +169,15 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
} }
} }
break; break;
case CPUFREQ_RELATION_C:
diff = abs(freq - target_freq);
if (diff < optimal.frequency ||
(diff == optimal.frequency &&
freq > table[optimal.driver_data].frequency)) {
optimal.frequency = diff;
optimal.driver_data = i;
}
break;
} }
} }
if (optimal.driver_data > i) { if (optimal.driver_data > i) {
......
...@@ -66,10 +66,12 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) ...@@ -66,10 +66,12 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
/* scaling up? scale voltage before frequency */ /* scaling up? scale voltage before frequency */
if (new_freq > old_freq) { if (new_freq > old_freq) {
ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0); if (!IS_ERR(pu_reg)) {
if (ret) { ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
dev_err(cpu_dev, "failed to scale vddpu up: %d\n", ret); if (ret) {
return ret; dev_err(cpu_dev, "failed to scale vddpu up: %d\n", ret);
return ret;
}
} }
ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0); ret = regulator_set_voltage_tol(soc_reg, imx6_soc_volt[index], 0);
if (ret) { if (ret) {
...@@ -121,10 +123,12 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index) ...@@ -121,10 +123,12 @@ static int imx6q_set_target(struct cpufreq_policy *policy, unsigned int index)
dev_warn(cpu_dev, "failed to scale vddsoc down: %d\n", ret); dev_warn(cpu_dev, "failed to scale vddsoc down: %d\n", ret);
ret = 0; ret = 0;
} }
ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0); if (!IS_ERR(pu_reg)) {
if (ret) { ret = regulator_set_voltage_tol(pu_reg, imx6_soc_volt[index], 0);
dev_warn(cpu_dev, "failed to scale vddpu down: %d\n", ret); if (ret) {
ret = 0; dev_warn(cpu_dev, "failed to scale vddpu down: %d\n", ret);
ret = 0;
}
} }
} }
...@@ -182,9 +186,9 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) ...@@ -182,9 +186,9 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
} }
arm_reg = regulator_get(cpu_dev, "arm"); arm_reg = regulator_get(cpu_dev, "arm");
pu_reg = regulator_get(cpu_dev, "pu"); pu_reg = regulator_get_optional(cpu_dev, "pu");
soc_reg = regulator_get(cpu_dev, "soc"); soc_reg = regulator_get(cpu_dev, "soc");
if (IS_ERR(arm_reg) || IS_ERR(pu_reg) || IS_ERR(soc_reg)) { if (IS_ERR(arm_reg) || IS_ERR(soc_reg)) {
dev_err(cpu_dev, "failed to get regulators\n"); dev_err(cpu_dev, "failed to get regulators\n");
ret = -ENOENT; ret = -ENOENT;
goto put_reg; goto put_reg;
...@@ -268,9 +272,11 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev) ...@@ -268,9 +272,11 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
ret = regulator_set_voltage_time(soc_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]); ret = regulator_set_voltage_time(soc_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
if (ret > 0) if (ret > 0)
transition_latency += ret * 1000; transition_latency += ret * 1000;
ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]); if (!IS_ERR(pu_reg)) {
if (ret > 0) ret = regulator_set_voltage_time(pu_reg, imx6_soc_volt[0], imx6_soc_volt[num - 1]);
transition_latency += ret * 1000; if (ret > 0)
transition_latency += ret * 1000;
}
/* /*
* OPP is maintained in order of increasing frequency, and * OPP is maintained in order of increasing frequency, and
...@@ -327,7 +333,8 @@ static int imx6q_cpufreq_remove(struct platform_device *pdev) ...@@ -327,7 +333,8 @@ static int imx6q_cpufreq_remove(struct platform_device *pdev)
cpufreq_unregister_driver(&imx6q_cpufreq_driver); cpufreq_unregister_driver(&imx6q_cpufreq_driver);
dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table);
regulator_put(arm_reg); regulator_put(arm_reg);
regulator_put(pu_reg); if (!IS_ERR(pu_reg))
regulator_put(pu_reg);
regulator_put(soc_reg); regulator_put(soc_reg);
clk_put(arm_clk); clk_put(arm_clk);
clk_put(pll1_sys_clk); clk_put(pll1_sys_clk);
......
This diff is collapsed.
...@@ -55,6 +55,7 @@ static const struct { ...@@ -55,6 +55,7 @@ static const struct {
unsigned freq; unsigned freq;
unsigned mult; unsigned mult;
} usual_frequency_table[] = { } usual_frequency_table[] = {
{ 350000, 35 }, // 100 * 3.5
{ 400000, 40 }, // 100 * 4 { 400000, 40 }, // 100 * 4
{ 450000, 45 }, // 100 * 4.5 { 450000, 45 }, // 100 * 4.5
{ 475000, 50 }, // 95 * 5 { 475000, 50 }, // 95 * 5
......
...@@ -15,12 +15,7 @@ config CPU_IDLE ...@@ -15,12 +15,7 @@ config CPU_IDLE
if CPU_IDLE if CPU_IDLE
config CPU_IDLE_MULTIPLE_DRIVERS config CPU_IDLE_MULTIPLE_DRIVERS
bool "Support multiple cpuidle drivers" bool
default n
help
Allows the cpuidle framework to use different drivers for each CPU.
This is useful if you have a system with different CPU latencies and
states. If unsure say N.
config CPU_IDLE_GOV_LADDER config CPU_IDLE_GOV_LADDER
bool "Ladder governor (for periodic timer tick)" bool "Ladder governor (for periodic timer tick)"
......
...@@ -10,6 +10,7 @@ config ARM_ARMADA_370_XP_CPUIDLE ...@@ -10,6 +10,7 @@ config ARM_ARMADA_370_XP_CPUIDLE
config ARM_BIG_LITTLE_CPUIDLE config ARM_BIG_LITTLE_CPUIDLE
bool "Support for ARM big.LITTLE processors" bool "Support for ARM big.LITTLE processors"
depends on ARCH_VEXPRESS_TC2_PM depends on ARCH_VEXPRESS_TC2_PM
depends on MCPM
select ARM_CPU_SUSPEND select ARM_CPU_SUSPEND
select CPU_IDLE_MULTIPLE_DRIVERS select CPU_IDLE_MULTIPLE_DRIVERS
help help
......
...@@ -119,11 +119,13 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv, ...@@ -119,11 +119,13 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
ktime_t time_start, time_end; ktime_t time_start, time_end;
s64 diff; s64 diff;
trace_cpu_idle_rcuidle(index, dev->cpu);
time_start = ktime_get(); time_start = ktime_get();
entered_state = target_state->enter(dev, drv, index); entered_state = target_state->enter(dev, drv, index);
time_end = ktime_get(); time_end = ktime_get();
trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);
if (!cpuidle_state_is_coupled(dev, drv, entered_state)) if (!cpuidle_state_is_coupled(dev, drv, entered_state))
local_irq_enable(); local_irq_enable();
......
...@@ -182,10 +182,6 @@ static void __cpuidle_driver_init(struct cpuidle_driver *drv) ...@@ -182,10 +182,6 @@ static void __cpuidle_driver_init(struct cpuidle_driver *drv)
static int poll_idle(struct cpuidle_device *dev, static int poll_idle(struct cpuidle_device *dev,
struct cpuidle_driver *drv, int index) struct cpuidle_driver *drv, int index)
{ {
ktime_t t1, t2;
s64 diff;
t1 = ktime_get();
local_irq_enable(); local_irq_enable();
if (!current_set_polling_and_test()) { if (!current_set_polling_and_test()) {
while (!need_resched()) while (!need_resched())
...@@ -193,13 +189,6 @@ static int poll_idle(struct cpuidle_device *dev, ...@@ -193,13 +189,6 @@ static int poll_idle(struct cpuidle_device *dev,
} }
current_clr_polling(); current_clr_polling();
t2 = ktime_get();
diff = ktime_to_us(ktime_sub(t2, t1));
if (diff > INT_MAX)
diff = INT_MAX;
dev->last_residency = (int) diff;
return index; return index;
} }
......
...@@ -144,7 +144,7 @@ static int ladder_enable_device(struct cpuidle_driver *drv, ...@@ -144,7 +144,7 @@ static int ladder_enable_device(struct cpuidle_driver *drv,
ldev->last_state_idx = CPUIDLE_DRIVER_STATE_START; ldev->last_state_idx = CPUIDLE_DRIVER_STATE_START;
for (i = 0; i < drv->state_count; i++) { for (i = CPUIDLE_DRIVER_STATE_START; i < drv->state_count; i++) {
state = &drv->states[i]; state = &drv->states[i];
lstate = &ldev->states[i]; lstate = &ldev->states[i];
...@@ -156,7 +156,7 @@ static int ladder_enable_device(struct cpuidle_driver *drv, ...@@ -156,7 +156,7 @@ static int ladder_enable_device(struct cpuidle_driver *drv,
if (i < drv->state_count - 1) if (i < drv->state_count - 1)
lstate->threshold.promotion_time = state->exit_latency; lstate->threshold.promotion_time = state->exit_latency;
if (i > 0) if (i > CPUIDLE_DRIVER_STATE_START)
lstate->threshold.demotion_time = state->exit_latency; lstate->threshold.demotion_time = state->exit_latency;
} }
......
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
#define RESOLUTION 1024 #define RESOLUTION 1024
#define DECAY 8 #define DECAY 8
#define MAX_INTERESTING 50000 #define MAX_INTERESTING 50000
#define STDDEV_THRESH 400
/* /*
......
...@@ -445,7 +445,7 @@ static void cpuidle_remove_state_sysfs(struct cpuidle_device *device) ...@@ -445,7 +445,7 @@ static void cpuidle_remove_state_sysfs(struct cpuidle_device *device)
#define define_one_driver_ro(_name, show) \ #define define_one_driver_ro(_name, show) \
static struct cpuidle_driver_attr attr_driver_##_name = \ static struct cpuidle_driver_attr attr_driver_##_name = \
__ATTR(_name, 0644, show, NULL) __ATTR(_name, 0444, show, NULL)
struct cpuidle_driver_kobj { struct cpuidle_driver_kobj {
struct cpuidle_driver *drv; struct cpuidle_driver *drv;
......
...@@ -68,7 +68,6 @@ comment "DEVFREQ Drivers" ...@@ -68,7 +68,6 @@ comment "DEVFREQ Drivers"
config ARM_EXYNOS4_BUS_DEVFREQ config ARM_EXYNOS4_BUS_DEVFREQ
bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver" bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver"
depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM depends on (CPU_EXYNOS4210 || SOC_EXYNOS4212 || SOC_EXYNOS4412) && !ARCH_MULTIPLATFORM
select ARCH_HAS_OPP
select DEVFREQ_GOV_SIMPLE_ONDEMAND select DEVFREQ_GOV_SIMPLE_ONDEMAND
select PM_OPP select PM_OPP
help help
......
...@@ -344,7 +344,7 @@ static const char * const pcie_port_type_strs[] = { ...@@ -344,7 +344,7 @@ static const char * const pcie_port_type_strs[] = {
}; };
static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
const struct acpi_generic_data *gdata) const struct acpi_hest_generic_data *gdata)
{ {
if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE) if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)
printk("%s""port_type: %d, %s\n", pfx, pcie->port_type, printk("%s""port_type: %d, %s\n", pfx, pcie->port_type,
...@@ -380,7 +380,7 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie, ...@@ -380,7 +380,7 @@ static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
} }
static void cper_estatus_print_section( static void cper_estatus_print_section(
const char *pfx, const struct acpi_generic_data *gdata, int sec_no) const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no)
{ {
uuid_le *sec_type = (uuid_le *)gdata->section_type; uuid_le *sec_type = (uuid_le *)gdata->section_type;
__u16 severity; __u16 severity;
...@@ -426,9 +426,9 @@ static void cper_estatus_print_section( ...@@ -426,9 +426,9 @@ static void cper_estatus_print_section(
} }
void cper_estatus_print(const char *pfx, void cper_estatus_print(const char *pfx,
const struct acpi_generic_status *estatus) const struct acpi_hest_generic_status *estatus)
{ {
struct acpi_generic_data *gdata; struct acpi_hest_generic_data *gdata;
unsigned int data_len, gedata_len; unsigned int data_len, gedata_len;
int sec_no = 0; int sec_no = 0;
char newpfx[64]; char newpfx[64];
...@@ -441,7 +441,7 @@ void cper_estatus_print(const char *pfx, ...@@ -441,7 +441,7 @@ void cper_estatus_print(const char *pfx,
"and requires no further action"); "and requires no further action");
printk("%s""event severity: %s\n", pfx, cper_severity_str(severity)); printk("%s""event severity: %s\n", pfx, cper_severity_str(severity));
data_len = estatus->data_length; data_len = estatus->data_length;
gdata = (struct acpi_generic_data *)(estatus + 1); gdata = (struct acpi_hest_generic_data *)(estatus + 1);
snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP); snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);
while (data_len >= sizeof(*gdata)) { while (data_len >= sizeof(*gdata)) {
gedata_len = gdata->error_data_length; gedata_len = gdata->error_data_length;
...@@ -453,10 +453,10 @@ void cper_estatus_print(const char *pfx, ...@@ -453,10 +453,10 @@ void cper_estatus_print(const char *pfx,
} }
EXPORT_SYMBOL_GPL(cper_estatus_print); EXPORT_SYMBOL_GPL(cper_estatus_print);
int cper_estatus_check_header(const struct acpi_generic_status *estatus) int cper_estatus_check_header(const struct acpi_hest_generic_status *estatus)
{ {
if (estatus->data_length && if (estatus->data_length &&
estatus->data_length < sizeof(struct acpi_generic_data)) estatus->data_length < sizeof(struct acpi_hest_generic_data))
return -EINVAL; return -EINVAL;
if (estatus->raw_data_length && if (estatus->raw_data_length &&
estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length) estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length)
...@@ -466,9 +466,9 @@ int cper_estatus_check_header(const struct acpi_generic_status *estatus) ...@@ -466,9 +466,9 @@ int cper_estatus_check_header(const struct acpi_generic_status *estatus)
} }
EXPORT_SYMBOL_GPL(cper_estatus_check_header); EXPORT_SYMBOL_GPL(cper_estatus_check_header);
int cper_estatus_check(const struct acpi_generic_status *estatus) int cper_estatus_check(const struct acpi_hest_generic_status *estatus)
{ {
struct acpi_generic_data *gdata; struct acpi_hest_generic_data *gdata;
unsigned int data_len, gedata_len; unsigned int data_len, gedata_len;
int rc; int rc;
...@@ -476,7 +476,7 @@ int cper_estatus_check(const struct acpi_generic_status *estatus) ...@@ -476,7 +476,7 @@ int cper_estatus_check(const struct acpi_generic_status *estatus)
if (rc) if (rc)
return rc; return rc;
data_len = estatus->data_length; data_len = estatus->data_length;
gdata = (struct acpi_generic_data *)(estatus + 1); gdata = (struct acpi_hest_generic_data *)(estatus + 1);
while (data_len >= sizeof(*gdata)) { while (data_len >= sizeof(*gdata)) {
gedata_len = gdata->error_data_length; gedata_len = gdata->error_data_length;
if (gedata_len > data_len - sizeof(*gdata)) if (gedata_len > data_len - sizeof(*gdata))
......
...@@ -85,7 +85,7 @@ void *dmar_alloc_dev_scope(void *start, void *end, int *cnt) ...@@ -85,7 +85,7 @@ void *dmar_alloc_dev_scope(void *start, void *end, int *cnt)
*cnt = 0; *cnt = 0;
while (start < end) { while (start < end) {
scope = start; scope = start;
if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ACPI || if (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_NAMESPACE ||
scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT || scope->entry_type == ACPI_DMAR_SCOPE_TYPE_ENDPOINT ||
scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE) scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE)
(*cnt)++; (*cnt)++;
...@@ -381,7 +381,7 @@ static int __init dmar_parse_one_andd(struct acpi_dmar_header *header) ...@@ -381,7 +381,7 @@ static int __init dmar_parse_one_andd(struct acpi_dmar_header *header)
struct acpi_dmar_andd *andd = (void *)header; struct acpi_dmar_andd *andd = (void *)header;
/* Check for NUL termination within the designated length */ /* Check for NUL termination within the designated length */
if (strnlen(andd->object_name, header->length - 8) == header->length - 8) { if (strnlen(andd->device_name, header->length - 8) == header->length - 8) {
WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND, WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND,
"Your BIOS is broken; ANDD object name is not NUL-terminated\n" "Your BIOS is broken; ANDD object name is not NUL-terminated\n"
"BIOS vendor: %s; Ver: %s; Product Version: %s\n", "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
...@@ -391,7 +391,7 @@ static int __init dmar_parse_one_andd(struct acpi_dmar_header *header) ...@@ -391,7 +391,7 @@ static int __init dmar_parse_one_andd(struct acpi_dmar_header *header)
return -EINVAL; return -EINVAL;
} }
pr_info("ANDD device: %x name: %s\n", andd->device_number, pr_info("ANDD device: %x name: %s\n", andd->device_number,
andd->object_name); andd->device_name);
return 0; return 0;
} }
...@@ -449,17 +449,17 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header) ...@@ -449,17 +449,17 @@ dmar_table_print_dmar_entry(struct acpi_dmar_header *header)
(unsigned long long)rmrr->base_address, (unsigned long long)rmrr->base_address,
(unsigned long long)rmrr->end_address); (unsigned long long)rmrr->end_address);
break; break;
case ACPI_DMAR_TYPE_ATSR: case ACPI_DMAR_TYPE_ROOT_ATS:
atsr = container_of(header, struct acpi_dmar_atsr, header); atsr = container_of(header, struct acpi_dmar_atsr, header);
pr_info("ATSR flags: %#x\n", atsr->flags); pr_info("ATSR flags: %#x\n", atsr->flags);
break; break;
case ACPI_DMAR_HARDWARE_AFFINITY: case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
rhsa = container_of(header, struct acpi_dmar_rhsa, header); rhsa = container_of(header, struct acpi_dmar_rhsa, header);
pr_info("RHSA base: %#016Lx proximity domain: %#x\n", pr_info("RHSA base: %#016Lx proximity domain: %#x\n",
(unsigned long long)rhsa->base_address, (unsigned long long)rhsa->base_address,
rhsa->proximity_domain); rhsa->proximity_domain);
break; break;
case ACPI_DMAR_TYPE_ANDD: case ACPI_DMAR_TYPE_NAMESPACE:
/* We don't print this here because we need to sanity-check /* We don't print this here because we need to sanity-check
it first. So print it in dmar_parse_one_andd() instead. */ it first. So print it in dmar_parse_one_andd() instead. */
break; break;
...@@ -540,15 +540,15 @@ parse_dmar_table(void) ...@@ -540,15 +540,15 @@ parse_dmar_table(void)
case ACPI_DMAR_TYPE_RESERVED_MEMORY: case ACPI_DMAR_TYPE_RESERVED_MEMORY:
ret = dmar_parse_one_rmrr(entry_header); ret = dmar_parse_one_rmrr(entry_header);
break; break;
case ACPI_DMAR_TYPE_ATSR: case ACPI_DMAR_TYPE_ROOT_ATS:
ret = dmar_parse_one_atsr(entry_header); ret = dmar_parse_one_atsr(entry_header);
break; break;
case ACPI_DMAR_HARDWARE_AFFINITY: case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
#ifdef CONFIG_ACPI_NUMA #ifdef CONFIG_ACPI_NUMA
ret = dmar_parse_one_rhsa(entry_header); ret = dmar_parse_one_rhsa(entry_header);
#endif #endif
break; break;
case ACPI_DMAR_TYPE_ANDD: case ACPI_DMAR_TYPE_NAMESPACE:
ret = dmar_parse_one_andd(entry_header); ret = dmar_parse_one_andd(entry_header);
break; break;
default: default:
...@@ -632,7 +632,7 @@ static void __init dmar_acpi_insert_dev_scope(u8 device_number, ...@@ -632,7 +632,7 @@ static void __init dmar_acpi_insert_dev_scope(u8 device_number,
for (scope = (void *)(drhd + 1); for (scope = (void *)(drhd + 1);
(unsigned long)scope < ((unsigned long)drhd) + drhd->header.length; (unsigned long)scope < ((unsigned long)drhd) + drhd->header.length;
scope = ((void *)scope) + scope->length) { scope = ((void *)scope) + scope->length) {
if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_ACPI) if (scope->entry_type != ACPI_DMAR_SCOPE_TYPE_NAMESPACE)
continue; continue;
if (scope->enumeration_id != device_number) if (scope->enumeration_id != device_number)
continue; continue;
...@@ -667,21 +667,21 @@ static int __init dmar_acpi_dev_scope_init(void) ...@@ -667,21 +667,21 @@ static int __init dmar_acpi_dev_scope_init(void)
for (andd = (void *)dmar_tbl + sizeof(struct acpi_table_dmar); for (andd = (void *)dmar_tbl + sizeof(struct acpi_table_dmar);
((unsigned long)andd) < ((unsigned long)dmar_tbl) + dmar_tbl->length; ((unsigned long)andd) < ((unsigned long)dmar_tbl) + dmar_tbl->length;
andd = ((void *)andd) + andd->header.length) { andd = ((void *)andd) + andd->header.length) {
if (andd->header.type == ACPI_DMAR_TYPE_ANDD) { if (andd->header.type == ACPI_DMAR_TYPE_NAMESPACE) {
acpi_handle h; acpi_handle h;
struct acpi_device *adev; struct acpi_device *adev;
if (!ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, if (!ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT,
andd->object_name, andd->device_name,
&h))) { &h))) {
pr_err("Failed to find handle for ACPI object %s\n", pr_err("Failed to find handle for ACPI object %s\n",
andd->object_name); andd->device_name);
continue; continue;
} }
acpi_bus_get_device(h, &adev); acpi_bus_get_device(h, &adev);
if (!adev) { if (!adev) {
pr_err("Failed to get device for ACPI object %s\n", pr_err("Failed to get device for ACPI object %s\n",
andd->object_name); andd->device_name);
continue; continue;
} }
dmar_acpi_insert_dev_scope(andd->device_number, adev); dmar_acpi_insert_dev_scope(andd->device_number, adev);
......
...@@ -80,8 +80,9 @@ static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev) ...@@ -80,8 +80,9 @@ static struct acpiphp_context *acpiphp_init_context(struct acpi_device *adev)
return NULL; return NULL;
context->refcount = 1; context->refcount = 1;
acpi_set_hp_context(adev, &context->hp, acpiphp_hotplug_notify, NULL, context->hp.notify = acpiphp_hotplug_notify;
acpiphp_post_dock_fixup); context->hp.fixup = acpiphp_post_dock_fixup;
acpi_set_hp_context(adev, &context->hp);
return context; return context;
} }
...@@ -369,20 +370,6 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data, ...@@ -369,20 +370,6 @@ static acpi_status acpiphp_add_context(acpi_handle handle, u32 lvl, void *data,
return AE_OK; return AE_OK;
} }
static struct acpiphp_bridge *acpiphp_dev_to_bridge(struct acpi_device *adev)
{
struct acpiphp_bridge *bridge = NULL;
acpi_lock_hp_context();
if (adev->hp) {
bridge = to_acpiphp_root_context(adev->hp)->root_bridge;
if (bridge)
get_bridge(bridge);
}
acpi_unlock_hp_context();
return bridge;
}
static void cleanup_bridge(struct acpiphp_bridge *bridge) static void cleanup_bridge(struct acpiphp_bridge *bridge)
{ {
struct acpiphp_slot *slot; struct acpiphp_slot *slot;
...@@ -753,9 +740,15 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus) ...@@ -753,9 +740,15 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus)
void acpiphp_check_host_bridge(struct acpi_device *adev) void acpiphp_check_host_bridge(struct acpi_device *adev)
{ {
struct acpiphp_bridge *bridge; struct acpiphp_bridge *bridge = NULL;
bridge = acpiphp_dev_to_bridge(adev); acpi_lock_hp_context();
if (adev->hp) {
bridge = to_acpiphp_root_context(adev->hp)->root_bridge;
if (bridge)
get_bridge(bridge);
}
acpi_unlock_hp_context();
if (bridge) { if (bridge) {
pci_lock_rescan_remove(); pci_lock_rescan_remove();
...@@ -884,7 +877,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus) ...@@ -884,7 +877,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
goto err; goto err;
root_context->root_bridge = bridge; root_context->root_bridge = bridge;
acpi_set_hp_context(adev, &root_context->hp, NULL, NULL, NULL); acpi_set_hp_context(adev, &root_context->hp);
} else { } else {
struct acpiphp_context *context; struct acpiphp_context *context;
...@@ -927,7 +920,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus) ...@@ -927,7 +920,7 @@ void acpiphp_enumerate_slots(struct pci_bus *bus)
kfree(bridge); kfree(bridge);
} }
void acpiphp_drop_bridge(struct acpiphp_bridge *bridge) static void acpiphp_drop_bridge(struct acpiphp_bridge *bridge)
{ {
if (pci_is_root_bus(bridge->pci_bus)) { if (pci_is_root_bus(bridge->pci_bus)) {
struct acpiphp_root_context *root_context; struct acpiphp_root_context *root_context;
......
...@@ -18,31 +18,31 @@ ...@@ -18,31 +18,31 @@
#include "pci.h" #include "pci.h"
/** /**
* pci_acpi_wake_bus - Wake-up notification handler for root buses. * pci_acpi_wake_bus - Root bus wakeup notification fork function.
* @handle: ACPI handle of a device the notification is for. * @work: Work item to handle.
* @event: Type of the signaled event.
* @context: PCI root bus to wake up devices on.
*/ */
static void pci_acpi_wake_bus(acpi_handle handle, u32 event, void *context) static void pci_acpi_wake_bus(struct work_struct *work)
{ {
struct pci_bus *pci_bus = context; struct acpi_device *adev;
struct acpi_pci_root *root;
if (event == ACPI_NOTIFY_DEVICE_WAKE && pci_bus) adev = container_of(work, struct acpi_device, wakeup.context.work);
pci_pme_wakeup_bus(pci_bus); root = acpi_driver_data(adev);
pci_pme_wakeup_bus(root->bus);
} }
/** /**
* pci_acpi_wake_dev - Wake-up notification handler for PCI devices. * pci_acpi_wake_dev - PCI device wakeup notification work function.
* @handle: ACPI handle of a device the notification is for. * @handle: ACPI handle of a device the notification is for.
* @event: Type of the signaled event. * @work: Work item to handle.
* @context: PCI device object to wake up.
*/ */
static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) static void pci_acpi_wake_dev(struct work_struct *work)
{ {
struct pci_dev *pci_dev = context; struct acpi_device_wakeup_context *context;
struct pci_dev *pci_dev;
if (event != ACPI_NOTIFY_DEVICE_WAKE || !pci_dev) context = container_of(work, struct acpi_device_wakeup_context, work);
return; pci_dev = to_pci_dev(context->dev);
if (pci_dev->pme_poll) if (pci_dev->pme_poll)
pci_dev->pme_poll = false; pci_dev->pme_poll = false;
...@@ -65,23 +65,12 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context) ...@@ -65,23 +65,12 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
} }
/** /**
* pci_acpi_add_bus_pm_notifier - Register PM notifier for given PCI bus. * pci_acpi_add_bus_pm_notifier - Register PM notifier for root PCI bus.
* @dev: ACPI device to add the notifier for. * @dev: PCI root bridge ACPI device.
* @pci_bus: PCI bus to walk checking for PME status if an event is signaled.
*/
acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev,
struct pci_bus *pci_bus)
{
return acpi_add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus);
}
/**
* pci_acpi_remove_bus_pm_notifier - Unregister PCI bus PM notifier.
* @dev: ACPI device to remove the notifier from.
*/ */
acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev)
{ {
return acpi_remove_pm_notifier(dev, pci_acpi_wake_bus); return acpi_add_pm_notifier(dev, NULL, pci_acpi_wake_bus);
} }
/** /**
...@@ -92,16 +81,7 @@ acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev) ...@@ -92,16 +81,7 @@ acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev)
acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev, acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev,
struct pci_dev *pci_dev) struct pci_dev *pci_dev)
{ {
return acpi_add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev); return acpi_add_pm_notifier(dev, &pci_dev->dev, pci_acpi_wake_dev);
}
/**
* pci_acpi_remove_pm_notifier - Unregister PCI device PM notifier.
* @dev: ACPI device to remove the notifier from.
*/
acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
{
return acpi_remove_pm_notifier(dev, pci_acpi_wake_dev);
} }
phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle) phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle)
...@@ -170,14 +150,13 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev) ...@@ -170,14 +150,13 @@ static pci_power_t acpi_pci_choose_state(struct pci_dev *pdev)
static bool acpi_pci_power_manageable(struct pci_dev *dev) static bool acpi_pci_power_manageable(struct pci_dev *dev)
{ {
acpi_handle handle = ACPI_HANDLE(&dev->dev); struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
return adev ? acpi_device_power_manageable(adev) : false;
return handle ? acpi_bus_power_manageable(handle) : false;
} }
static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
{ {
acpi_handle handle = ACPI_HANDLE(&dev->dev); struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
static const u8 state_conv[] = { static const u8 state_conv[] = {
[PCI_D0] = ACPI_STATE_D0, [PCI_D0] = ACPI_STATE_D0,
[PCI_D1] = ACPI_STATE_D1, [PCI_D1] = ACPI_STATE_D1,
...@@ -188,7 +167,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) ...@@ -188,7 +167,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
int error = -EINVAL; int error = -EINVAL;
/* If the ACPI device has _EJ0, ignore the device */ /* If the ACPI device has _EJ0, ignore the device */
if (!handle || acpi_has_method(handle, "_EJ0")) if (!adev || acpi_has_method(adev->handle, "_EJ0"))
return -ENODEV; return -ENODEV;
switch (state) { switch (state) {
...@@ -202,7 +181,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) ...@@ -202,7 +181,7 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
case PCI_D1: case PCI_D1:
case PCI_D2: case PCI_D2:
case PCI_D3hot: case PCI_D3hot:
error = acpi_bus_set_power(handle, state_conv[state]); error = acpi_device_set_power(adev, state_conv[state]);
} }
if (!error) if (!error)
...@@ -214,9 +193,8 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) ...@@ -214,9 +193,8 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
static bool acpi_pci_can_wakeup(struct pci_dev *dev) static bool acpi_pci_can_wakeup(struct pci_dev *dev)
{ {
acpi_handle handle = ACPI_HANDLE(&dev->dev); struct acpi_device *adev = ACPI_COMPANION(&dev->dev);
return adev ? acpi_device_can_wakeup(adev) : false;
return handle ? acpi_bus_can_wakeup(handle) : false;
} }
static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable) static void acpi_pci_propagate_wakeup_enable(struct pci_bus *bus, bool enable)
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment