Commit b41d037a authored by Linus Torvalds's avatar Linus Torvalds

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

Pull more ACPI updates from Rafael Wysocki:
 "This includes a couple of fixes needed after recent changes, two ACPI
  driver fixes (fan and "Processor Aggregator"), an update of the ACPI
  device properties handling code and a new MAINTAINERS entry for ACPI
  on ARM64.

  Specifics:

   - Fix an unused function warning that started to appear after recent
     changes in the ACPI EC driver (Eric Biggers).

   - Fix the KERN_CONT usage in acpi_os_vprintf() that has become
     (particularly) annoying recently (Joe Perches).

   - Fix the fan status checking in the ACPI fan driver to avoid
     returning incorrect error codes sometimes (Srinivas Pandruvada).

   - Fix the ACPI Processor Aggregator driver (PAD) to always let the
     special processor_aggregator driver from Xen take over when running
     as Xen dom0 (Juergen Gross).

   - Update the handling of reference device properties in ACPI by
     allowing empty rows ("holes") to appear in reference property lists
     (Mika Westerberg).

   - Add a new MAINTAINERS entry for ACPI on ARM64 (Lorenzo Pieralisi)"

* tag 'acpi-extra-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  acpi_os_vprintf: Use printk_get_level() to avoid unnecessary KERN_CONT
  ACPI / PAD: don't register acpi_pad driver if running as Xen dom0
  ACPI / property: Allow holes in reference properties
  MAINTAINERS: Add ARM64-specific ACPI maintainers entry
  ACPI / EC: Fix unused function warning when CONFIG_PM_SLEEP=n
  ACPI / fan: Fix error reading cur_state
parents ef98988b 522533f3
...@@ -316,6 +316,14 @@ W: https://01.org/linux-acpi ...@@ -316,6 +316,14 @@ W: https://01.org/linux-acpi
S: Supported S: Supported
F: drivers/acpi/fan.c F: drivers/acpi/fan.c
ACPI FOR ARM64 (ACPI/arm64)
M: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
M: Hanjun Guo <hanjun.guo@linaro.org>
M: Sudeep Holla <sudeep.holla@arm.com>
L: linux-acpi@vger.kernel.org
S: Maintained
F: drivers/acpi/arm64
ACPI THERMAL DRIVER ACPI THERMAL DRIVER
M: Zhang Rui <rui.zhang@intel.com> M: Zhang Rui <rui.zhang@intel.com>
L: linux-acpi@vger.kernel.org L: linux-acpi@vger.kernel.org
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <asm/mwait.h> #include <asm/mwait.h>
#include <xen/xen.h>
#define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad" #define ACPI_PROCESSOR_AGGREGATOR_CLASS "acpi_pad"
#define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator" #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator"
...@@ -477,6 +478,10 @@ static struct acpi_driver acpi_pad_driver = { ...@@ -477,6 +478,10 @@ static struct acpi_driver acpi_pad_driver = {
static int __init acpi_pad_init(void) static int __init acpi_pad_init(void)
{ {
/* Xen ACPI PAD is used when running as Xen Dom0. */
if (xen_initial_domain())
return -ENODEV;
power_saving_mwait_init(); power_saving_mwait_init();
if (power_saving_mwait_eax == 0) if (power_saving_mwait_eax == 0)
return -EINVAL; return -EINVAL;
......
...@@ -526,6 +526,7 @@ static void acpi_ec_enable_event(struct acpi_ec *ec) ...@@ -526,6 +526,7 @@ static void acpi_ec_enable_event(struct acpi_ec *ec)
acpi_ec_clear(ec); acpi_ec_clear(ec);
} }
#ifdef CONFIG_PM_SLEEP
static bool acpi_ec_query_flushed(struct acpi_ec *ec) static bool acpi_ec_query_flushed(struct acpi_ec *ec)
{ {
bool flushed; bool flushed;
...@@ -557,6 +558,7 @@ static void acpi_ec_disable_event(struct acpi_ec *ec) ...@@ -557,6 +558,7 @@ static void acpi_ec_disable_event(struct acpi_ec *ec)
spin_unlock_irqrestore(&ec->lock, flags); spin_unlock_irqrestore(&ec->lock, flags);
__acpi_ec_flush_event(ec); __acpi_ec_flush_event(ec);
} }
#endif /* CONFIG_PM_SLEEP */
static bool acpi_ec_guard_event(struct acpi_ec *ec) static bool acpi_ec_guard_event(struct acpi_ec *ec)
{ {
......
...@@ -129,8 +129,18 @@ static int fan_get_state_acpi4(struct acpi_device *device, unsigned long *state) ...@@ -129,8 +129,18 @@ static int fan_get_state_acpi4(struct acpi_device *device, unsigned long *state)
control = obj->package.elements[1].integer.value; control = obj->package.elements[1].integer.value;
for (i = 0; i < fan->fps_count; i++) { for (i = 0; i < fan->fps_count; i++) {
if (control == fan->fps[i].control) /*
* When Fine Grain Control is set, return the state
* corresponding to maximum fan->fps[i].control
* value compared to the current speed. Here the
* fan->fps[] is sorted array with increasing speed.
*/
if (fan->fif.fine_grain_ctrl && control < fan->fps[i].control) {
i = (i > 0) ? i - 1 : 0;
break; break;
} else if (control == fan->fps[i].control) {
break;
}
} }
if (i == fan->fps_count) { if (i == fan->fps_count) {
dev_dbg(&device->dev, "Invalid control value returned\n"); dev_dbg(&device->dev, "Invalid control value returned\n");
......
...@@ -162,11 +162,18 @@ void acpi_os_vprintf(const char *fmt, va_list args) ...@@ -162,11 +162,18 @@ void acpi_os_vprintf(const char *fmt, va_list args)
if (acpi_in_debugger) { if (acpi_in_debugger) {
kdb_printf("%s", buffer); kdb_printf("%s", buffer);
} else { } else {
printk(KERN_CONT "%s", buffer); if (printk_get_level(buffer))
printk("%s", buffer);
else
printk(KERN_CONT "%s", buffer);
} }
#else #else
if (acpi_debugger_write_log(buffer) < 0) if (acpi_debugger_write_log(buffer) < 0) {
printk(KERN_CONT "%s", buffer); if (printk_get_level(buffer))
printk("%s", buffer);
else
printk(KERN_CONT "%s", buffer);
}
#endif #endif
} }
......
...@@ -468,10 +468,11 @@ static int acpi_data_get_property_array(struct acpi_device_data *data, ...@@ -468,10 +468,11 @@ static int acpi_data_get_property_array(struct acpi_device_data *data,
} }
/** /**
* acpi_data_get_property_reference - returns handle to the referenced object * __acpi_node_get_property_reference - returns handle to the referenced object
* @data: ACPI device data object containing the property * @fwnode: Firmware node to get the property from
* @propname: Name of the property * @propname: Name of the property
* @index: Index of the reference to return * @index: Index of the reference to return
* @num_args: Maximum number of arguments after each reference
* @args: Location to store the returned reference with optional arguments * @args: Location to store the returned reference with optional arguments
* *
* Find property with @name, verifify that it is a package containing at least * Find property with @name, verifify that it is a package containing at least
...@@ -482,17 +483,40 @@ static int acpi_data_get_property_array(struct acpi_device_data *data, ...@@ -482,17 +483,40 @@ static int acpi_data_get_property_array(struct acpi_device_data *data,
* If there's more than one reference in the property value package, @index is * If there's more than one reference in the property value package, @index is
* used to select the one to return. * used to select the one to return.
* *
* It is possible to leave holes in the property value set like in the
* example below:
*
* Package () {
* "cs-gpios",
* Package () {
* ^GPIO, 19, 0, 0,
* ^GPIO, 20, 0, 0,
* 0,
* ^GPIO, 21, 0, 0,
* }
* }
*
* Calling this function with index %2 return %-ENOENT and with index %3
* returns the last entry. If the property does not contain any more values
* %-ENODATA is returned. The NULL entry must be single integer and
* preferably contain value %0.
*
* Return: %0 on success, negative error code on failure. * Return: %0 on success, negative error code on failure.
*/ */
static int acpi_data_get_property_reference(struct acpi_device_data *data, int __acpi_node_get_property_reference(struct fwnode_handle *fwnode,
const char *propname, size_t index, const char *propname, size_t index, size_t num_args,
struct acpi_reference_args *args) struct acpi_reference_args *args)
{ {
const union acpi_object *element, *end; const union acpi_object *element, *end;
const union acpi_object *obj; const union acpi_object *obj;
struct acpi_device_data *data;
struct acpi_device *device; struct acpi_device *device;
int ret, idx = 0; int ret, idx = 0;
data = acpi_device_data_of_node(fwnode);
if (!data)
return -EINVAL;
ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj); ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj);
if (ret) if (ret)
return ret; return ret;
...@@ -532,59 +556,54 @@ static int acpi_data_get_property_reference(struct acpi_device_data *data, ...@@ -532,59 +556,54 @@ static int acpi_data_get_property_reference(struct acpi_device_data *data,
while (element < end) { while (element < end) {
u32 nargs, i; u32 nargs, i;
if (element->type != ACPI_TYPE_LOCAL_REFERENCE) if (element->type == ACPI_TYPE_LOCAL_REFERENCE) {
return -EPROTO; ret = acpi_bus_get_device(element->reference.handle,
&device);
ret = acpi_bus_get_device(element->reference.handle, &device); if (ret)
if (ret) return -ENODEV;
return -ENODEV;
nargs = 0;
element++; element++;
nargs = 0;
/* assume following integer elements are all args */
/* assume following integer elements are all args */ for (i = 0; element + i < end && i < num_args; i++) {
for (i = 0; element + i < end; i++) { int type = element[i].type;
int type = element[i].type;
if (type == ACPI_TYPE_INTEGER)
nargs++;
else if (type == ACPI_TYPE_LOCAL_REFERENCE)
break;
else
return -EPROTO;
}
if (type == ACPI_TYPE_INTEGER) if (nargs > MAX_ACPI_REFERENCE_ARGS)
nargs++;
else if (type == ACPI_TYPE_LOCAL_REFERENCE)
break;
else
return -EPROTO; return -EPROTO;
}
if (idx++ == index) { if (idx == index) {
args->adev = device; args->adev = device;
args->nargs = nargs; args->nargs = nargs;
for (i = 0; i < nargs; i++) for (i = 0; i < nargs; i++)
args->args[i] = element[i].integer.value; args->args[i] = element[i].integer.value;
return 0; return 0;
}
element += nargs;
} else if (element->type == ACPI_TYPE_INTEGER) {
if (idx == index)
return -ENOENT;
element++;
} else {
return -EPROTO;
} }
element += nargs; idx++;
} }
return -EPROTO; return -ENODATA;
}
/**
* acpi_node_get_property_reference - get a handle to the referenced object.
* @fwnode: Firmware node to get the property from.
* @propname: Name of the property.
* @index: Index of the reference to return.
* @args: Location to store the returned reference with optional arguments.
*/
int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
const char *name, size_t index,
struct acpi_reference_args *args)
{
struct acpi_device_data *data = acpi_device_data_of_node(fwnode);
return data ? acpi_data_get_property_reference(data, name, index, args) : -EINVAL;
} }
EXPORT_SYMBOL_GPL(acpi_node_get_property_reference); EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference);
static int acpi_data_prop_read_single(struct acpi_device_data *data, static int acpi_data_prop_read_single(struct acpi_device_data *data,
const char *propname, const char *propname,
......
...@@ -946,9 +946,17 @@ struct acpi_reference_args { ...@@ -946,9 +946,17 @@ struct acpi_reference_args {
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
int acpi_dev_get_property(struct acpi_device *adev, const char *name, int acpi_dev_get_property(struct acpi_device *adev, const char *name,
acpi_object_type type, const union acpi_object **obj); acpi_object_type type, const union acpi_object **obj);
int acpi_node_get_property_reference(struct fwnode_handle *fwnode, int __acpi_node_get_property_reference(struct fwnode_handle *fwnode,
const char *name, size_t index, const char *name, size_t index, size_t num_args,
struct acpi_reference_args *args); struct acpi_reference_args *args);
static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
const char *name, size_t index,
struct acpi_reference_args *args)
{
return __acpi_node_get_property_reference(fwnode, name, index,
MAX_ACPI_REFERENCE_ARGS, args);
}
int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname, int acpi_node_prop_get(struct fwnode_handle *fwnode, const char *propname,
void **valptr); void **valptr);
...@@ -1024,6 +1032,14 @@ static inline int acpi_dev_get_property(struct acpi_device *adev, ...@@ -1024,6 +1032,14 @@ static inline int acpi_dev_get_property(struct acpi_device *adev,
return -ENXIO; return -ENXIO;
} }
static inline int
__acpi_node_get_property_reference(struct fwnode_handle *fwnode,
const char *name, size_t index, size_t num_args,
struct acpi_reference_args *args)
{
return -ENXIO;
}
static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode, static inline int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
const char *name, size_t index, const char *name, size_t index,
struct acpi_reference_args *args) struct acpi_reference_args *args)
......
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