Commit e9dba837 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull ACPI and power management fixes from Rafael Wysocki:
 "These include a fix for a recent ACPI regression related to device
  notifications, intel_idle fix related to IvyTown support, fix for a
  buffer size issue in ACPICA, PM core fix related to the "freeze" sleep
  state, four fixes for various types of breakage in cpufreq drivers, a
  PNP workaround for a wrong memory region size in ACPI tables, and a
  fix and cleanup for the ACPI tools Makefile.

  Specifics:

   - Fix for broken ACPI notifications on some systems caused by a
     recent ACPI hotplug commit that blocked the propagation of unknown
     type notifications to device drivers inadvertently.

   - intel_idle fix to make the IvyTown C-states handling (added
     recently) work as intended which now is broken due to missing
     braces.  From Christoph Jaeger.

   - ACPICA fix to make it allocate buffers of the right sizes for the
     Generic Serial Bus operation region access.  From Lv Zheng.

   - PM core fix unblocking cpuidle before entering the "freeze" sleep
     state which causes that state to be able to actually save more
     energy than runtime idle.

   - Configuration and build fixes for the highbank and powernv cpufreq
     drivers from Kefeng Wang and Srivatsa S Bhat.

   - Coccinelle warning fix related to error pointers for the unicore32
     cpufreq driver from Duan Jiong.

   - Integer overflow fix for the ppc-corenet cpufreq driver from Geert
     Uytterhoeven.

   - Workaround for BIOSes that don't report the entire Intel MCH area
     in their ACPI tables from Bjorn Helgaas.

   - ACPI tools Makefile fix and cleanup from Thomas Renninger"

* tag 'pm+acpi-3.15-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  ACPI / notify: Do not block unknown type notifications in root handler
  PNP: Work around BIOS defects in Intel MCH area reporting
  cpufreq: highbank: fix ARM_HIGHBANK_CPUFREQ dependency warning
  cpufreq: ppc: Fix integer overflow in expression
  cpufreq, powernv: Fix build failure on UP
  cpufreq: unicore32: replace IS_ERR and PTR_ERR with PTR_ERR_OR_ZERO
  PM / suspend: Make cpuidle work in the "freeze" state
  intel_idle: fix IVT idle state table setting
  ACPICA: Fix buffer allocation issue for generic_serial_bus region accesses.
  tools/power/acpi: Minor bugfixes
parents 9a60ee11 d4c9c8a0
...@@ -45,10 +45,71 @@ ...@@ -45,10 +45,71 @@
#include "accommon.h" #include "accommon.h"
#include "acdispat.h" #include "acdispat.h"
#include "acinterp.h" #include "acinterp.h"
#include "amlcode.h"
#define _COMPONENT ACPI_EXECUTER #define _COMPONENT ACPI_EXECUTER
ACPI_MODULE_NAME("exfield") ACPI_MODULE_NAME("exfield")
/* Local prototypes */
static u32
acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length);
/*******************************************************************************
*
* FUNCTION: acpi_get_serial_access_bytes
*
* PARAMETERS: accessor_type - The type of the protocol indicated by region
* field access attributes
* access_length - The access length of the region field
*
* RETURN: Decoded access length
*
* DESCRIPTION: This routine returns the length of the generic_serial_bus
* protocol bytes
*
******************************************************************************/
static u32
acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length)
{
u32 length;
switch (accessor_type) {
case AML_FIELD_ATTRIB_QUICK:
length = 0;
break;
case AML_FIELD_ATTRIB_SEND_RCV:
case AML_FIELD_ATTRIB_BYTE:
length = 1;
break;
case AML_FIELD_ATTRIB_WORD:
case AML_FIELD_ATTRIB_WORD_CALL:
length = 2;
break;
case AML_FIELD_ATTRIB_MULTIBYTE:
case AML_FIELD_ATTRIB_RAW_BYTES:
case AML_FIELD_ATTRIB_RAW_PROCESS:
length = access_length;
break;
case AML_FIELD_ATTRIB_BLOCK:
case AML_FIELD_ATTRIB_BLOCK_CALL:
default:
length = ACPI_GSBUS_BUFFER_SIZE;
break;
}
return (length);
}
/******************************************************************************* /*******************************************************************************
* *
* FUNCTION: acpi_ex_read_data_from_field * FUNCTION: acpi_ex_read_data_from_field
...@@ -63,8 +124,9 @@ ACPI_MODULE_NAME("exfield") ...@@ -63,8 +124,9 @@ ACPI_MODULE_NAME("exfield")
* Buffer, depending on the size of the field. * Buffer, depending on the size of the field.
* *
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state,
union acpi_operand_object *obj_desc, union acpi_operand_object *obj_desc,
union acpi_operand_object **ret_buffer_desc) union acpi_operand_object **ret_buffer_desc)
{ {
...@@ -73,6 +135,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, ...@@ -73,6 +135,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
acpi_size length; acpi_size length;
void *buffer; void *buffer;
u32 function; u32 function;
u16 accessor_type;
ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc);
...@@ -116,9 +179,22 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, ...@@ -116,9 +179,22 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
ACPI_READ | (obj_desc->field.attribute << 16); ACPI_READ | (obj_desc->field.attribute << 16);
} else if (obj_desc->field.region_obj->region.space_id == } else if (obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_GSBUS) { ACPI_ADR_SPACE_GSBUS) {
length = ACPI_GSBUS_BUFFER_SIZE; accessor_type = obj_desc->field.attribute;
function = length = acpi_ex_get_serial_access_length(accessor_type,
ACPI_READ | (obj_desc->field.attribute << 16); obj_desc->
field.
access_length);
/*
* Add additional 2 bytes for modeled generic_serial_bus data buffer:
* typedef struct {
* BYTEStatus; // Byte 0 of the data buffer
* BYTELength; // Byte 1 of the data buffer
* BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer,
* }
*/
length += 2;
function = ACPI_READ | (accessor_type << 16);
} else { /* IPMI */ } else { /* IPMI */
length = ACPI_IPMI_BUFFER_SIZE; length = ACPI_IPMI_BUFFER_SIZE;
...@@ -231,6 +307,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, ...@@ -231,6 +307,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
void *buffer; void *buffer;
union acpi_operand_object *buffer_desc; union acpi_operand_object *buffer_desc;
u32 function; u32 function;
u16 accessor_type;
ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc);
...@@ -284,9 +361,22 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, ...@@ -284,9 +361,22 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
ACPI_WRITE | (obj_desc->field.attribute << 16); ACPI_WRITE | (obj_desc->field.attribute << 16);
} else if (obj_desc->field.region_obj->region.space_id == } else if (obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_GSBUS) { ACPI_ADR_SPACE_GSBUS) {
length = ACPI_GSBUS_BUFFER_SIZE; accessor_type = obj_desc->field.attribute;
function = length = acpi_ex_get_serial_access_length(accessor_type,
ACPI_WRITE | (obj_desc->field.attribute << 16); obj_desc->
field.
access_length);
/*
* Add additional 2 bytes for modeled generic_serial_bus data buffer:
* typedef struct {
* BYTEStatus; // Byte 0 of the data buffer
* BYTELength; // Byte 1 of the data buffer
* BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer,
* }
*/
length += 2;
function = ACPI_WRITE | (accessor_type << 16);
} else { /* IPMI */ } else { /* IPMI */
length = ACPI_IPMI_BUFFER_SIZE; length = ACPI_IPMI_BUFFER_SIZE;
......
...@@ -380,9 +380,8 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) ...@@ -380,9 +380,8 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
break; break;
default: default:
acpi_handle_warn(handle, "Unsupported event type 0x%x\n", type); acpi_handle_debug(handle, "Unknown event type 0x%x\n", type);
ost_code = ACPI_OST_SC_UNRECOGNIZED_NOTIFY; break;
goto err;
} }
adev = acpi_bus_get_acpi_device(handle); adev = acpi_bus_get_acpi_device(handle);
......
...@@ -92,11 +92,7 @@ config ARM_EXYNOS_CPU_FREQ_BOOST_SW ...@@ -92,11 +92,7 @@ config ARM_EXYNOS_CPU_FREQ_BOOST_SW
config ARM_HIGHBANK_CPUFREQ config ARM_HIGHBANK_CPUFREQ
tristate "Calxeda Highbank-based" tristate "Calxeda Highbank-based"
depends on ARCH_HIGHBANK depends on ARCH_HIGHBANK && GENERIC_CPUFREQ_CPU0 && REGULATOR
select GENERIC_CPUFREQ_CPU0
select PM_OPP
select REGULATOR
default m default m
help help
This adds the CPUFreq driver for Calxeda Highbank SoC This adds the CPUFreq driver for Calxeda Highbank SoC
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <asm/cputhreads.h> #include <asm/cputhreads.h>
#include <asm/reg.h> #include <asm/reg.h>
#include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */
#define POWERNV_MAX_PSTATES 256 #define POWERNV_MAX_PSTATES 256
......
...@@ -206,7 +206,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) ...@@ -206,7 +206,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
per_cpu(cpu_data, i) = data; per_cpu(cpu_data, i) = data;
policy->cpuinfo.transition_latency = policy->cpuinfo.transition_latency =
(12 * NSEC_PER_SEC) / fsl_get_sys_freq(); (12ULL * NSEC_PER_SEC) / fsl_get_sys_freq();
of_node_put(np); of_node_put(np);
return 0; return 0;
......
...@@ -60,9 +60,7 @@ static int __init ucv2_cpu_init(struct cpufreq_policy *policy) ...@@ -60,9 +60,7 @@ static int __init ucv2_cpu_init(struct cpufreq_policy *policy)
policy->max = policy->cpuinfo.max_freq = 1000000; policy->max = policy->cpuinfo.max_freq = 1000000;
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
policy->clk = clk_get(NULL, "MAIN_CLK"); policy->clk = clk_get(NULL, "MAIN_CLK");
if (IS_ERR(policy->clk)) return PTR_ERR_OR_ZERO(policy->clk);
return PTR_ERR(policy->clk);
return 0;
} }
static struct cpufreq_driver ucv2_driver = { static struct cpufreq_driver ucv2_driver = {
......
...@@ -750,11 +750,12 @@ void intel_idle_state_table_update(void) ...@@ -750,11 +750,12 @@ void intel_idle_state_table_update(void)
if (package_num + 1 > num_sockets) { if (package_num + 1 > num_sockets) {
num_sockets = package_num + 1; num_sockets = package_num + 1;
if (num_sockets > 4) if (num_sockets > 4) {
cpuidle_state_table = ivt_cstates_8s; cpuidle_state_table = ivt_cstates_8s;
return; return;
} }
} }
}
if (num_sockets > 2) if (num_sockets > 2)
cpuidle_state_table = ivt_cstates_4s; cpuidle_state_table = ivt_cstates_4s;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pnp.h> #include <linux/pnp.h>
...@@ -334,6 +335,81 @@ static void quirk_amd_mmconfig_area(struct pnp_dev *dev) ...@@ -334,6 +335,81 @@ static void quirk_amd_mmconfig_area(struct pnp_dev *dev)
} }
#endif #endif
#ifdef CONFIG_X86
/* Device IDs of parts that have 32KB MCH space */
static const unsigned int mch_quirk_devices[] = {
0x0154, /* Ivy Bridge */
0x0c00, /* Haswell */
};
static struct pci_dev *get_intel_host(void)
{
int i;
struct pci_dev *host;
for (i = 0; i < ARRAY_SIZE(mch_quirk_devices); i++) {
host = pci_get_device(PCI_VENDOR_ID_INTEL, mch_quirk_devices[i],
NULL);
if (host)
return host;
}
return NULL;
}
static void quirk_intel_mch(struct pnp_dev *dev)
{
struct pci_dev *host;
u32 addr_lo, addr_hi;
struct pci_bus_region region;
struct resource mch;
struct pnp_resource *pnp_res;
struct resource *res;
host = get_intel_host();
if (!host)
return;
/*
* MCHBAR is not an architected PCI BAR, so MCH space is usually
* reported as a PNP0C02 resource. The MCH space was originally
* 16KB, but is 32KB in newer parts. Some BIOSes still report a
* PNP0C02 resource that is only 16KB, which means the rest of the
* MCH space is consumed but unreported.
*/
/*
* Read MCHBAR for Host Member Mapped Register Range Base
* https://www-ssl.intel.com/content/www/us/en/processors/core/4th-gen-core-family-desktop-vol-2-datasheet
* Sec 3.1.12.
*/
pci_read_config_dword(host, 0x48, &addr_lo);
region.start = addr_lo & ~0x7fff;
pci_read_config_dword(host, 0x4c, &addr_hi);
region.start |= (u64) addr_hi << 32;
region.end = region.start + 32*1024 - 1;
memset(&mch, 0, sizeof(mch));
mch.flags = IORESOURCE_MEM;
pcibios_bus_to_resource(host->bus, &mch, &region);
list_for_each_entry(pnp_res, &dev->resources, list) {
res = &pnp_res->res;
if (res->end < mch.start || res->start > mch.end)
continue; /* no overlap */
if (res->start == mch.start && res->end == mch.end)
continue; /* exact match */
dev_info(&dev->dev, FW_BUG "PNP resource %pR covers only part of %s Intel MCH; extending to %pR\n",
res, pci_name(host), &mch);
res->start = mch.start;
res->end = mch.end;
break;
}
pci_dev_put(host);
}
#endif
/* /*
* PnP Quirks * PnP Quirks
* Cards or devices that need some tweaking due to incomplete resource info * Cards or devices that need some tweaking due to incomplete resource info
...@@ -363,6 +439,9 @@ static struct pnp_fixup pnp_fixups[] = { ...@@ -363,6 +439,9 @@ static struct pnp_fixup pnp_fixups[] = {
{"PNP0c02", quirk_system_pci_resources}, {"PNP0c02", quirk_system_pci_resources},
#ifdef CONFIG_AMD_NB #ifdef CONFIG_AMD_NB
{"PNP0c01", quirk_amd_mmconfig_area}, {"PNP0c01", quirk_amd_mmconfig_area},
#endif
#ifdef CONFIG_X86
{"PNP0c02", quirk_intel_mch},
#endif #endif
{""} {""}
}; };
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/console.h> #include <linux/console.h>
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/cpuidle.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/io.h> #include <linux/io.h>
...@@ -53,7 +54,9 @@ static void freeze_begin(void) ...@@ -53,7 +54,9 @@ static void freeze_begin(void)
static void freeze_enter(void) static void freeze_enter(void)
{ {
cpuidle_resume();
wait_event(suspend_freeze_wait_head, suspend_freeze_wake); wait_event(suspend_freeze_wait_head, suspend_freeze_wake);
cpuidle_pause();
} }
void freeze_wake(void) void freeze_wake(void)
......
...@@ -89,15 +89,6 @@ else ...@@ -89,15 +89,6 @@ else
STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment
endif endif
# if DEBUG is enabled, then we do not strip or optimize
ifeq ($(strip $(DEBUG)),true)
CFLAGS += -O1 -g -DDEBUG
STRIPCMD = /bin/true -Since_we_are_debugging
else
CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer
STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment
endif
# --- ACPIDUMP BEGIN --- # --- ACPIDUMP BEGIN ---
vpath %.c \ vpath %.c \
...@@ -128,7 +119,7 @@ clean: ...@@ -128,7 +119,7 @@ clean:
-rm -f $(OUTPUT)acpidump -rm -f $(OUTPUT)acpidump
install-tools: install-tools:
$(INSTALL) -d $(DESTDIR)${bindir} $(INSTALL) -d $(DESTDIR)${sbindir}
$(INSTALL_PROGRAM) $(OUTPUT)acpidump $(DESTDIR)${sbindir} $(INSTALL_PROGRAM) $(OUTPUT)acpidump $(DESTDIR)${sbindir}
install-man: install-man:
......
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