Merge tag 'acpi-extra-4.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafae...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Oct 2016 19:50:05 +0000 (12:50 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 14 Oct 2016 19:50:05 +0000 (12:50 -0700)
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

MAINTAINERS
drivers/acpi/acpi_pad.c
drivers/acpi/ec.c
drivers/acpi/fan.c
drivers/acpi/osl.c
drivers/acpi/property.c
include/linux/acpi.h

index fc849cabf99e8cc26223f971e5126452849d2b63..146d1498aa014a6ecdf073bf1b4bcea66528a8b3 100644 (file)
@@ -316,6 +316,14 @@ W: https://01.org/linux-acpi
 S:     Supported
 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
 M:     Zhang Rui <rui.zhang@intel.com>
 L:     linux-acpi@vger.kernel.org
index 8ea8211b2d589c6618d5037e40d653a3771edc55..eb76a4c10dbfb170e43680d8b3f836bec169ad01 100644 (file)
@@ -26,6 +26,7 @@
 #include <linux/slab.h>
 #include <linux/acpi.h>
 #include <asm/mwait.h>
+#include <xen/xen.h>
 
 #define ACPI_PROCESSOR_AGGREGATOR_CLASS        "acpi_pad"
 #define ACPI_PROCESSOR_AGGREGATOR_DEVICE_NAME "Processor Aggregator"
@@ -477,6 +478,10 @@ static struct acpi_driver acpi_pad_driver = {
 
 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();
        if (power_saving_mwait_eax == 0)
                return -EINVAL;
index 6805310621607335a2cf14763acc48f629d3ba31..48e19d013170936ef494d0fa88d275d37f25071a 100644 (file)
@@ -526,6 +526,7 @@ static void acpi_ec_enable_event(struct acpi_ec *ec)
                acpi_ec_clear(ec);
 }
 
+#ifdef CONFIG_PM_SLEEP
 static bool acpi_ec_query_flushed(struct acpi_ec *ec)
 {
        bool flushed;
@@ -557,6 +558,7 @@ static void acpi_ec_disable_event(struct acpi_ec *ec)
        spin_unlock_irqrestore(&ec->lock, flags);
        __acpi_ec_flush_event(ec);
 }
+#endif /* CONFIG_PM_SLEEP */
 
 static bool acpi_ec_guard_event(struct acpi_ec *ec)
 {
index 384cfc3083e1d98c544918b49ec517a9399c27a3..6cf4988206f24e8292099ae7141914ced024affd 100644 (file)
@@ -129,8 +129,18 @@ static int fan_get_state_acpi4(struct acpi_device *device, unsigned long *state)
 
        control = obj->package.elements[1].integer.value;
        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;
+               } else if (control == fan->fps[i].control) {
+                       break;
+               }
        }
        if (i == fan->fps_count) {
                dev_dbg(&device->dev, "Invalid control value returned\n");
index 4305ee9db4b2d880faaf6314cde028546b5207a6..416953a4251094ce2066d724c1d88583b8e89705 100644 (file)
@@ -162,11 +162,18 @@ void acpi_os_vprintf(const char *fmt, va_list args)
        if (acpi_in_debugger) {
                kdb_printf("%s", buffer);
        } else {
-               printk(KERN_CONT "%s", buffer);
+               if (printk_get_level(buffer))
+                       printk("%s", buffer);
+               else
+                       printk(KERN_CONT "%s", buffer);
        }
 #else
-       if (acpi_debugger_write_log(buffer) < 0)
-               printk(KERN_CONT "%s", buffer);
+       if (acpi_debugger_write_log(buffer) < 0) {
+               if (printk_get_level(buffer))
+                       printk("%s", buffer);
+               else
+                       printk(KERN_CONT "%s", buffer);
+       }
 #endif
 }
 
index f2fd3fee588a8233a80bdc5da3549fea5703b9f8..03f5ec11ab3197de66ced4e7f09d39dbab6b8232 100644 (file)
@@ -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
- * @data: ACPI device data object containing the property
+ * __acpi_node_get_property_reference - returns 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
+ * @num_args: Maximum number of arguments after each reference
  * @args: Location to store the returned reference with optional arguments
  *
  * 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,
  * If there's more than one reference in the property value package, @index is
  * 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.
  */
-static int acpi_data_get_property_reference(struct acpi_device_data *data,
-                                           const char *propname, size_t index,
-                                           struct acpi_reference_args *args)
+int __acpi_node_get_property_reference(struct fwnode_handle *fwnode,
+       const char *propname, size_t index, size_t num_args,
+       struct acpi_reference_args *args)
 {
        const union acpi_object *element, *end;
        const union acpi_object *obj;
+       struct acpi_device_data *data;
        struct acpi_device *device;
        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);
        if (ret)
                return ret;
@@ -532,59 +556,54 @@ static int acpi_data_get_property_reference(struct acpi_device_data *data,
        while (element < end) {
                u32 nargs, i;
 
-               if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
-                       return -EPROTO;
-
-               ret = acpi_bus_get_device(element->reference.handle, &device);
-               if (ret)
-                       return -ENODEV;
-
-               element++;
-               nargs = 0;
-
-               /* assume following integer elements are all args */
-               for (i = 0; element + i < end; i++) {
-                       int type = element[i].type;
+               if (element->type == ACPI_TYPE_LOCAL_REFERENCE) {
+                       ret = acpi_bus_get_device(element->reference.handle,
+                                                 &device);
+                       if (ret)
+                               return -ENODEV;
+
+                       nargs = 0;
+                       element++;
+
+                       /* assume following integer elements are all args */
+                       for (i = 0; element + i < end && i < num_args; i++) {
+                               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)
-                               nargs++;
-                       else if (type == ACPI_TYPE_LOCAL_REFERENCE)
-                               break;
-                       else
+                       if (nargs > MAX_ACPI_REFERENCE_ARGS)
                                return -EPROTO;
-               }
 
-               if (idx++ == index) {
-                       args->adev = device;
-                       args->nargs = nargs;
-                       for (i = 0; i < nargs; i++)
-                               args->args[i] = element[i].integer.value;
+                       if (idx == index) {
+                               args->adev = device;
+                               args->nargs = nargs;
+                               for (i = 0; i < nargs; i++)
+                                       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;
-}
-
-/**
- * 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;
+       return -ENODATA;
 }
-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,
                                      const char *propname,
index 94afcb2c384cf2d7d184742e870c0becfeffe312..ddbeda6dbdc87b4121617631efa0f1a486d1b6e2 100644 (file)
@@ -946,9 +946,17 @@ struct acpi_reference_args {
 #ifdef CONFIG_ACPI
 int acpi_dev_get_property(struct acpi_device *adev, const char *name,
                          acpi_object_type type, const union acpi_object **obj);
-int acpi_node_get_property_reference(struct fwnode_handle *fwnode,
-                                    const char *name, size_t index,
-                                    struct acpi_reference_args *args);
+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);
+
+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,
                       void **valptr);
@@ -1024,6 +1032,14 @@ static inline int acpi_dev_get_property(struct acpi_device *adev,
        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,
                                const char *name, size_t index,
                                struct acpi_reference_args *args)