ACPI and power management fixes for 3.15-rc3
- 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. / -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABCAAGBQJTWvQ7AAoJEILEb/54YlRxpf4P/R0yuUNC02E5zRD4VZdZ1fD7 H/7xJ9XDDcZiqe8sEAr8DiatoHsuQGfB5Vs+Vv/RGzGN7xz+wQ7V73niBGjHWekI kl7DFcnM7aF4zy+hNQUKJiB0O19D+ttH3Jfow5Vpd4rQj7qIjp9s3okQn5HArrKS KsoU4g+Mvt3VP3egeXGBmR4WqHYpEK8AIkV8d8XnOP7eTP4Q/Ed2aSFGsuwVhlft 63iBgB7yac+OSnTNTedsi5xxh+Bx/W6Q2SPSn0g2MVtzQICEMgGB6l+ftJZLBoI/ YRD6CkcYyOAllNjy6EGNg5UfwtbSh4qlfQ+dQkrpKZCgjVBfgeheiwrjrt/20/4l QsEMVDhdoIBZEfJyT0o6LkRA7EHH+gykAhxJ35ocVgJxMbDzcJG2/aHnEs+zJIxc TKWidhQYqangqfPZeLN3fGCJ8959ohBUWFNUO+JZDGKpguBFjC4GrC1bDuR5tF78 z5hm1QHGeJGrPZMg1qrAcRR2WMJv2tc/SBBeoNFzMy7Hi27bKJxPIktbUYWWD8NB jP93jRbg2eGnGJucidlZ1Xx31GWY7wzU4kMQ6jPEKhbn5lRSITvqrYPgEPeSaSyr xCUPGi+TrV18AD/OwSF+DJnIfgroKDETCtgBLponMr29Pa8bgTHu9HOe7/BbGf46 EbRPpwx8p6eaob2c7n5F =yMFR -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
e9dba83764
|
@ -45,10 +45,71 @@
|
|||
#include "accommon.h"
|
||||
#include "acdispat.h"
|
||||
#include "acinterp.h"
|
||||
#include "amlcode.h"
|
||||
|
||||
#define _COMPONENT ACPI_EXECUTER
|
||||
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
|
||||
|
@ -63,8 +124,9 @@ ACPI_MODULE_NAME("exfield")
|
|||
* Buffer, depending on the size of the field.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
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 **ret_buffer_desc)
|
||||
{
|
||||
|
@ -73,6 +135,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
|
|||
acpi_size length;
|
||||
void *buffer;
|
||||
u32 function;
|
||||
u16 accessor_type;
|
||||
|
||||
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,
|
|||
ACPI_READ | (obj_desc->field.attribute << 16);
|
||||
} else if (obj_desc->field.region_obj->region.space_id ==
|
||||
ACPI_ADR_SPACE_GSBUS) {
|
||||
length = ACPI_GSBUS_BUFFER_SIZE;
|
||||
function =
|
||||
ACPI_READ | (obj_desc->field.attribute << 16);
|
||||
accessor_type = obj_desc->field.attribute;
|
||||
length = acpi_ex_get_serial_access_length(accessor_type,
|
||||
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 */
|
||||
|
||||
length = ACPI_IPMI_BUFFER_SIZE;
|
||||
|
@ -231,6 +307,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
|
|||
void *buffer;
|
||||
union acpi_operand_object *buffer_desc;
|
||||
u32 function;
|
||||
u16 accessor_type;
|
||||
|
||||
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,
|
|||
ACPI_WRITE | (obj_desc->field.attribute << 16);
|
||||
} else if (obj_desc->field.region_obj->region.space_id ==
|
||||
ACPI_ADR_SPACE_GSBUS) {
|
||||
length = ACPI_GSBUS_BUFFER_SIZE;
|
||||
function =
|
||||
ACPI_WRITE | (obj_desc->field.attribute << 16);
|
||||
accessor_type = obj_desc->field.attribute;
|
||||
length = acpi_ex_get_serial_access_length(accessor_type,
|
||||
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 */
|
||||
|
||||
length = ACPI_IPMI_BUFFER_SIZE;
|
||||
|
|
|
@ -380,9 +380,8 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
|
|||
break;
|
||||
|
||||
default:
|
||||
acpi_handle_warn(handle, "Unsupported event type 0x%x\n", type);
|
||||
ost_code = ACPI_OST_SC_UNRECOGNIZED_NOTIFY;
|
||||
goto err;
|
||||
acpi_handle_debug(handle, "Unknown event type 0x%x\n", type);
|
||||
break;
|
||||
}
|
||||
|
||||
adev = acpi_bus_get_acpi_device(handle);
|
||||
|
|
|
@ -92,11 +92,7 @@ config ARM_EXYNOS_CPU_FREQ_BOOST_SW
|
|||
|
||||
config ARM_HIGHBANK_CPUFREQ
|
||||
tristate "Calxeda Highbank-based"
|
||||
depends on ARCH_HIGHBANK
|
||||
select GENERIC_CPUFREQ_CPU0
|
||||
select PM_OPP
|
||||
select REGULATOR
|
||||
|
||||
depends on ARCH_HIGHBANK && GENERIC_CPUFREQ_CPU0 && REGULATOR
|
||||
default m
|
||||
help
|
||||
This adds the CPUFreq driver for Calxeda Highbank SoC
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include <asm/cputhreads.h>
|
||||
#include <asm/reg.h>
|
||||
#include <asm/smp.h> /* Required for cpu_sibling_mask() in UP configs */
|
||||
|
||||
#define POWERNV_MAX_PSTATES 256
|
||||
|
||||
|
|
|
@ -206,7 +206,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
|
|||
per_cpu(cpu_data, i) = data;
|
||||
|
||||
policy->cpuinfo.transition_latency =
|
||||
(12 * NSEC_PER_SEC) / fsl_get_sys_freq();
|
||||
(12ULL * NSEC_PER_SEC) / fsl_get_sys_freq();
|
||||
of_node_put(np);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -60,9 +60,7 @@ static int __init ucv2_cpu_init(struct cpufreq_policy *policy)
|
|||
policy->max = policy->cpuinfo.max_freq = 1000000;
|
||||
policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
|
||||
policy->clk = clk_get(NULL, "MAIN_CLK");
|
||||
if (IS_ERR(policy->clk))
|
||||
return PTR_ERR(policy->clk);
|
||||
return 0;
|
||||
return PTR_ERR_OR_ZERO(policy->clk);
|
||||
}
|
||||
|
||||
static struct cpufreq_driver ucv2_driver = {
|
||||
|
|
|
@ -750,11 +750,12 @@ void intel_idle_state_table_update(void)
|
|||
if (package_num + 1 > num_sockets) {
|
||||
num_sockets = package_num + 1;
|
||||
|
||||
if (num_sockets > 4)
|
||||
if (num_sockets > 4) {
|
||||
cpuidle_state_table = ivt_cstates_8s;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (num_sockets > 2)
|
||||
cpuidle_state_table = ivt_cstates_4s;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pnp.h>
|
||||
|
@ -334,6 +335,81 @@ static void quirk_amd_mmconfig_area(struct pnp_dev *dev)
|
|||
}
|
||||
#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, ®ion);
|
||||
|
||||
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
|
||||
* Cards or devices that need some tweaking due to incomplete resource info
|
||||
|
@ -363,6 +439,9 @@ static struct pnp_fixup pnp_fixups[] = {
|
|||
{"PNP0c02", quirk_system_pci_resources},
|
||||
#ifdef CONFIG_AMD_NB
|
||||
{"PNP0c01", quirk_amd_mmconfig_area},
|
||||
#endif
|
||||
#ifdef CONFIG_X86
|
||||
{"PNP0c02", quirk_intel_mch},
|
||||
#endif
|
||||
{""}
|
||||
};
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/console.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -53,7 +54,9 @@ static void freeze_begin(void)
|
|||
|
||||
static void freeze_enter(void)
|
||||
{
|
||||
cpuidle_resume();
|
||||
wait_event(suspend_freeze_wait_head, suspend_freeze_wake);
|
||||
cpuidle_pause();
|
||||
}
|
||||
|
||||
void freeze_wake(void)
|
||||
|
|
|
@ -89,15 +89,6 @@ else
|
|||
STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment
|
||||
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 ---
|
||||
|
||||
vpath %.c \
|
||||
|
@ -128,7 +119,7 @@ clean:
|
|||
-rm -f $(OUTPUT)acpidump
|
||||
|
||||
install-tools:
|
||||
$(INSTALL) -d $(DESTDIR)${bindir}
|
||||
$(INSTALL) -d $(DESTDIR)${sbindir}
|
||||
$(INSTALL_PROGRAM) $(OUTPUT)acpidump $(DESTDIR)${sbindir}
|
||||
|
||||
install-man:
|
||||
|
|
Loading…
Reference in New Issue