Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9dba837 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+97 −7
Original line number Diff line number Diff line
@@ -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,6 +124,7 @@ 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,
			     union acpi_operand_object *obj_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;
+2 −3
Original line number Diff line number Diff line
@@ -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);
+1 −5
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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

+1 −1
Original line number Diff line number Diff line
@@ -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;
Loading