Merge branches 'acpi-scan', 'acpi-utils' and 'acpi-pm'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 18 Dec 2014 17:42:56 +0000 (18:42 +0100)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Thu, 18 Dec 2014 17:42:56 +0000 (18:42 +0100)
* acpi-scan:
  ACPI / scan: Change the level of _DEP-related messages to KERN_DEBUG

* acpi-utils:
  ACPI / utils: Drop error messages from acpi_evaluate_reference()

* acpi-pm:
  ACPI / PM: Do not disable wakeup GPEs that have not been enabled

1  2  3  4 
drivers/acpi/device_pm.c
drivers/acpi/scan.c
drivers/acpi/utils.c
include/acpi/acpi_bus.h

diff --combined drivers/acpi/device_pm.c
index 897640188acdda6ce9b47a117fc5e50172dd072c,7db19316076659b493ab1d1c9a295dc88450381d,7db19316076659b493ab1d1c9a295dc88450381d,e6ff33ecd784c0b9a33f6e1efa69b5b53acb212f..c2daa85fc9f70fa5aca61a6f2a4fbaa6b85df100
@@@@@ -201,7 -201,7 -201,7 -201,7 +201,7 @@@@@ int acpi_device_set_power(struct acpi_d
         * Transition Power
         * ----------------
         * In accordance with the ACPI specification first apply power (via
 --      * power resources) and then evalute _PSx.
 ++      * power resources) and then evaluate _PSx.
         */
        if (device->power.flags.power_resources) {
                result = acpi_power_transition(device, state);
@@@@@ -680,18 -680,19 -680,19 -680,27 +680,26 @@@@@ static int acpi_device_wakeup(struct ac
                if (error)
                        return error;
    
+++             if (adev->wakeup.flags.enabled)
+++                     return 0;
+++ 
                res = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number);
---             if (ACPI_FAILURE(res)) {
+++             if (ACPI_SUCCESS(res)) {
+++                     adev->wakeup.flags.enabled = 1;
+++             } else {
                        acpi_disable_wakeup_device_power(adev);
                        return -EIO;
                }
        } else {
---             acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number);
+++             if (adev->wakeup.flags.enabled) {
+++                     acpi_disable_gpe(wakeup->gpe_device, wakeup->gpe_number);
+++                     adev->wakeup.flags.enabled = 0;
+++             }
                acpi_disable_wakeup_device_power(adev);
        }
        return 0;
    }
    
 ---#ifdef CONFIG_PM_RUNTIME
    /**
     * acpi_pm_device_run_wake - Enable/disable remote wakeup for given device.
     * @dev: Device to enable/disable the platform to wake up.
@@@@@ -713,6 -714,7 -714,7 -722,7 +721,6 @@@@@ int acpi_pm_device_run_wake(struct devi
        return acpi_device_wakeup(adev, ACPI_STATE_S0, enable);
    }
    EXPORT_SYMBOL(acpi_pm_device_run_wake);
 ---#endif /* CONFIG_PM_RUNTIME */
    
    #ifdef CONFIG_PM_SLEEP
    /**
@@@@@ -771,6 -773,7 -773,7 -781,7 +779,6 @@@@@ static int acpi_dev_pm_full_power(struc
                acpi_device_set_power(adev, ACPI_STATE_D0) : 0;
    }
    
 ---#ifdef CONFIG_PM_RUNTIME
    /**
     * acpi_dev_runtime_suspend - Put device into a low-power state using ACPI.
     * @dev: Device to put into a low-power state.
@@@@@ -852,6 -855,7 -855,7 -863,7 +860,6 @@@@@ int acpi_subsys_runtime_resume(struct d
        return ret ? ret : pm_generic_runtime_resume(dev);
    }
    EXPORT_SYMBOL_GPL(acpi_subsys_runtime_resume);
 ---#endif /* CONFIG_PM_RUNTIME */
    
    #ifdef CONFIG_PM_SLEEP
    /**
@@@@@ -1019,9 -1023,10 -1023,10 -1031,10 +1027,9 @@@@@ EXPORT_SYMBOL_GPL(acpi_subsys_freeze)
    
    static struct dev_pm_domain acpi_general_pm_domain = {
        .ops = {
 ---#ifdef CONFIG_PM_RUNTIME
 +++#ifdef CONFIG_PM
                .runtime_suspend = acpi_subsys_runtime_suspend,
                .runtime_resume = acpi_subsys_runtime_resume,
 ---#endif
    #ifdef CONFIG_PM_SLEEP
                .prepare = acpi_subsys_prepare,
                .complete = acpi_subsys_complete,
                .poweroff = acpi_subsys_suspend,
                .poweroff_late = acpi_subsys_suspend_late,
                .restore_early = acpi_subsys_resume_early,
 +++#endif
    #endif
        },
    };
diff --combined drivers/acpi/scan.c
index 1b1cf558d3d3d59b866cdba61aa096f9477d8c22,d838b2f83e214db88df7d662d92960c9f6e99c7b,0476e90b2091faac82867e686a8bddde36ed8781,0476e90b2091faac82867e686a8bddde36ed8781..16914cc308822798b091d51a15f337b28486fe51
@@@@@ -36,8 -36,8 -36,6 -36,6 +36,8 @@@@@ bool acpi_force_hot_remove
    
    static const char *dummy_hid = "device";
    
  ++static LIST_HEAD(acpi_dep_list);
  ++static DEFINE_MUTEX(acpi_dep_list_lock);
    static LIST_HEAD(acpi_bus_id_list);
    static DEFINE_MUTEX(acpi_scan_lock);
    static LIST_HEAD(acpi_scan_handlers_list);
@@@@@ -45,12 -45,12 -43,6 -43,6 +45,12 @@@@@ DEFINE_MUTEX(acpi_device_lock)
    LIST_HEAD(acpi_wakeup_device_list);
    static DEFINE_MUTEX(acpi_hp_context_lock);
    
  ++struct acpi_dep_data {
  ++    struct list_head node;
  ++    acpi_handle master;
  ++    acpi_handle slave;
  ++};
  ++
    struct acpi_device_bus_id{
        char bus_id[15];
        unsigned int instance_no;
@@@@@ -132,56 -132,17 -124,17 -124,17 +132,56 @@@@@ static int create_modalias(struct acpi_
        if (list_empty(&acpi_dev->pnp.ids))
                return 0;
    
 ---    len = snprintf(modalias, size, "acpi:");
 ---    size -= len;
 ---
 ---    list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
 ---            count = snprintf(&modalias[len], size, "%s:", id->id);
 ---            if (count < 0)
 ---                    return -EINVAL;
 ---            if (count >= size)
 ---                    return -ENOMEM;
 ---            len += count;
 ---            size -= count;
 +++    /*
 +++     * If the device has PRP0001 we expose DT compatible modalias
 +++     * instead in form of of:NnameTCcompatible.
 +++     */
 +++    if (acpi_dev->data.of_compatible) {
 +++            struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
 +++            const union acpi_object *of_compatible, *obj;
 +++            int i, nval;
 +++            char *c;
 +++
 +++            acpi_get_name(acpi_dev->handle, ACPI_SINGLE_NAME, &buf);
 +++            /* DT strings are all in lower case */
 +++            for (c = buf.pointer; *c != '\0'; c++)
 +++                    *c = tolower(*c);
 +++
 +++            len = snprintf(modalias, size, "of:N%sT", (char *)buf.pointer);
 +++            ACPI_FREE(buf.pointer);
 +++
 +++            of_compatible = acpi_dev->data.of_compatible;
 +++            if (of_compatible->type == ACPI_TYPE_PACKAGE) {
 +++                    nval = of_compatible->package.count;
 +++                    obj = of_compatible->package.elements;
 +++            } else { /* Must be ACPI_TYPE_STRING. */
 +++                    nval = 1;
 +++                    obj = of_compatible;
 +++            }
 +++            for (i = 0; i < nval; i++, obj++) {
 +++                    count = snprintf(&modalias[len], size, "C%s",
 +++                                     obj->string.pointer);
 +++                    if (count < 0)
 +++                            return -EINVAL;
 +++                    if (count >= size)
 +++                            return -ENOMEM;
 +++
 +++                    len += count;
 +++                    size -= count;
 +++            }
 +++    } else {
 +++            len = snprintf(modalias, size, "acpi:");
 +++            size -= len;
 +++
 +++            list_for_each_entry(id, &acpi_dev->pnp.ids, list) {
 +++                    count = snprintf(&modalias[len], size, "%s:", id->id);
 +++                    if (count < 0)
 +++                            return -EINVAL;
 +++                    if (count >= size)
 +++                            return -ENOMEM;
 +++                    len += count;
 +++                    size -= count;
 +++            }
        }
    
        modalias[len] = '\0';
@@@@@ -949,51 -910,6 -902,6 -902,6 +949,51 @@@@@ int acpi_match_device_ids(struct acpi_d
    }
    EXPORT_SYMBOL(acpi_match_device_ids);
    
 +++/* Performs match against special "PRP0001" shoehorn ACPI ID */
 +++static bool acpi_of_driver_match_device(struct device *dev,
 +++                                    const struct device_driver *drv)
 +++{
 +++    const union acpi_object *of_compatible, *obj;
 +++    struct acpi_device *adev;
 +++    int i, nval;
 +++
 +++    adev = ACPI_COMPANION(dev);
 +++    if (!adev)
 +++            return false;
 +++
 +++    of_compatible = adev->data.of_compatible;
 +++    if (!drv->of_match_table || !of_compatible)
 +++            return false;
 +++
 +++    if (of_compatible->type == ACPI_TYPE_PACKAGE) {
 +++            nval = of_compatible->package.count;
 +++            obj = of_compatible->package.elements;
 +++    } else { /* Must be ACPI_TYPE_STRING. */
 +++            nval = 1;
 +++            obj = of_compatible;
 +++    }
 +++    /* Now we can look for the driver DT compatible strings */
 +++    for (i = 0; i < nval; i++, obj++) {
 +++            const struct of_device_id *id;
 +++
 +++            for (id = drv->of_match_table; id->compatible[0]; id++)
 +++                    if (!strcasecmp(obj->string.pointer, id->compatible))
 +++                            return true;
 +++    }
 +++
 +++    return false;
 +++}
 +++
 +++bool acpi_driver_match_device(struct device *dev,
 +++                          const struct device_driver *drv)
 +++{
 +++    if (!drv->acpi_match_table)
 +++            return acpi_of_driver_match_device(dev, drv);
 +++
 +++    return !!acpi_match_device(drv->acpi_match_table, dev);
 +++}
 +++EXPORT_SYMBOL_GPL(acpi_driver_match_device);
 +++
    static void acpi_free_power_resources_lists(struct acpi_device *device)
    {
        int i;
@@@@@ -1014,7 -930,6 -922,6 -922,6 +1014,7 @@@@@ static void acpi_device_release(struct 
    {
        struct acpi_device *acpi_dev = to_acpi_device(dev);
    
 +++    acpi_free_properties(acpi_dev);
        acpi_free_pnp_ids(&acpi_dev->pnp);
        acpi_free_power_resources_lists(acpi_dev);
        kfree(acpi_dev);
@@@@@ -1397,26 -1312,6 -1304,6 -1304,6 +1397,26 @@@@@ int acpi_device_add(struct acpi_device 
        return result;
    }
    
 +++struct acpi_device *acpi_get_next_child(struct device *dev,
 +++                                    struct acpi_device *child)
 +++{
 +++    struct acpi_device *adev = ACPI_COMPANION(dev);
 +++    struct list_head *head, *next;
 +++
 +++    if (!adev)
 +++            return NULL;
 +++
 +++    head = &adev->children;
 +++    if (list_empty(head))
 +++            return NULL;
 +++
 +++    if (!child)
 +++            return list_first_entry(head, struct acpi_device, node);
 +++
 +++    next = child->node.next;
 +++    return next == head ? NULL : list_entry(next, struct acpi_device, node);
 +++}
 +++
    /* --------------------------------------------------------------------------
                                     Driver Management
       -------------------------------------------------------------------------- */
@@@@@ -2036,11 -1931,9 -1923,9 -1923,9 +2036,11 @@@@@ void acpi_init_device_object(struct acp
        device->device_type = type;
        device->handle = handle;
        device->parent = acpi_bus_get_parent(handle);
 +++    device->fwnode.type = FWNODE_ACPI;
        acpi_set_device_status(device, sta);
        acpi_device_get_busid(device);
        acpi_set_pnp_ids(handle, &device->pnp, type);
 +++    acpi_init_properties(device);
        acpi_bus_get_flags(device);
        device->flags.match_driver = false;
        device->flags.initialized = true;
@@@@@ -2201,59 -2094,59 -2086,6 -2086,6 +2201,59 @@@@@ static void acpi_scan_init_hotplug(stru
        }
    }
    
-               dev_err(&adev->dev, "Failed to evaluate _DEP.\n");
  ++static void acpi_device_dep_initialize(struct acpi_device *adev)
  ++{
  ++    struct acpi_dep_data *dep;
  ++    struct acpi_handle_list dep_devices;
  ++    acpi_status status;
  ++    int i;
  ++
  ++    if (!acpi_has_method(adev->handle, "_DEP"))
  ++            return;
  ++
  ++    status = acpi_evaluate_reference(adev->handle, "_DEP", NULL,
  ++                                    &dep_devices);
  ++    if (ACPI_FAILURE(status)) {
-                       dev_err(&adev->dev, "Error reading device info\n");
+ ++            dev_dbg(&adev->dev, "Failed to evaluate _DEP.\n");
  ++            return;
  ++    }
  ++
  ++    for (i = 0; i < dep_devices.count; i++) {
  ++            struct acpi_device_info *info;
  ++            int skip;
  ++
  ++            status = acpi_get_object_info(dep_devices.handles[i], &info);
  ++            if (ACPI_FAILURE(status)) {
+ ++                    dev_dbg(&adev->dev, "Error reading _DEP device info\n");
  ++                    continue;
  ++            }
  ++
  ++            /*
  ++             * Skip the dependency of Windows System Power
  ++             * Management Controller
  ++             */
  ++            skip = info->valid & ACPI_VALID_HID &&
  ++                    !strcmp(info->hardware_id.string, "INT3396");
  ++
  ++            kfree(info);
  ++
  ++            if (skip)
  ++                    continue;
  ++
  ++            dep = kzalloc(sizeof(struct acpi_dep_data), GFP_KERNEL);
  ++            if (!dep)
  ++                    return;
  ++
  ++            dep->master = dep_devices.handles[i];
  ++            dep->slave  = adev->handle;
  ++            adev->dep_unmet++;
  ++
  ++            mutex_lock(&acpi_dep_list_lock);
  ++            list_add_tail(&dep->node , &acpi_dep_list);
  ++            mutex_unlock(&acpi_dep_list_lock);
  ++    }
  ++}
  ++
    static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
                                      void *not_used, void **return_value)
    {
                return AE_CTRL_DEPTH;
    
        acpi_scan_init_hotplug(device);
  ++    acpi_device_dep_initialize(device);
    
     out:
        if (!*return_value)
@@@@@ -2401,29 -2294,29 -2232,6 -2232,6 +2401,29 @@@@@ static void acpi_bus_attach(struct acpi
                device->handler->hotplug.notify_online(device);
    }
    
  ++void acpi_walk_dep_device_list(acpi_handle handle)
  ++{
  ++    struct acpi_dep_data *dep, *tmp;
  ++    struct acpi_device *adev;
  ++
  ++    mutex_lock(&acpi_dep_list_lock);
  ++    list_for_each_entry_safe(dep, tmp, &acpi_dep_list, node) {
  ++            if (dep->master == handle) {
  ++                    acpi_bus_get_device(dep->slave, &adev);
  ++                    if (!adev)
  ++                            continue;
  ++
  ++                    adev->dep_unmet--;
  ++                    if (!adev->dep_unmet)
  ++                            acpi_bus_attach(adev);
  ++                    list_del(&dep->node);
  ++                    kfree(dep);
  ++            }
  ++    }
  ++    mutex_unlock(&acpi_dep_list_lock);
  ++}
  ++EXPORT_SYMBOL_GPL(acpi_walk_dep_device_list);
  ++
    /**
     * acpi_bus_scan - Add ACPI device node objects in a given namespace scope.
     * @handle: Root of the namespace scope to scan.
diff --combined drivers/acpi/utils.c
index dd8ff63ee2b43e255313f973a668e33e5a630ac3,371ac12d25b16ee4c651649a147c7e3e9f9fdc87,5512309d167bddfa930ea384aca6aa7661ce96d7,371ac12d25b16ee4c651649a147c7e3e9f9fdc87..cd49a3982b6ab9563bf18e4ea7c21ed58febd4d9
@@@@@ -136,7 -136,8 -136,8 -136,8 +136,7 @@@@@ acpi_extract_package(union acpi_object 
                                break;
                        case 'B':
                                size_required +=
 ---                                sizeof(u8 *) +
 ---                                (element->buffer.length * sizeof(u8));
 +++                                sizeof(u8 *) + element->buffer.length;
                                tail_offset += sizeof(u8 *);
                                break;
                        default:
                                memcpy(tail, element->buffer.pointer,
                                       element->buffer.length);
                                head += sizeof(u8 *);
 ---                            tail += element->buffer.length * sizeof(u8);
 +++                            tail += element->buffer.length;
                                break;
                        default:
                                /* Should never get here */
@@@@@ -346,22 -347,22 -347,16 -347,22 +346,16 @@@@@ acpi_evaluate_reference(acpi_handle han
        package = buffer.pointer;
    
        if ((buffer.length == 0) || !package) {
-- -            printk(KERN_ERR PREFIX "No return object (len %X ptr %p)\n",
-- -                        (unsigned)buffer.length, package);
                status = AE_BAD_DATA;
                acpi_util_eval_error(handle, pathname, status);
                goto end;
        }
        if (package->type != ACPI_TYPE_PACKAGE) {
-- -            printk(KERN_ERR PREFIX "Expecting a [Package], found type %X\n",
-- -                        package->type);
                status = AE_BAD_DATA;
                acpi_util_eval_error(handle, pathname, status);
                goto end;
        }
        if (!package->package.count) {
-- -            printk(KERN_ERR PREFIX "[Package] has zero elements (%p)\n",
-- -                        package);
                status = AE_BAD_DATA;
                acpi_util_eval_error(handle, pathname, status);
                goto end;
    
                if (element->type != ACPI_TYPE_LOCAL_REFERENCE) {
                        status = AE_BAD_DATA;
-- -                    printk(KERN_ERR PREFIX
-- -                                "Expecting a [Reference] package element, found type %X\n",
-- -                                element->type);
                        acpi_util_eval_error(handle, pathname, status);
                        break;
                }
    
                if (!element->reference.handle) {
-- -                    printk(KERN_WARNING PREFIX "Invalid reference in"
-- -                           " package %s\n", pathname);
                        status = AE_NULL_ENTRY;
++ +                    acpi_util_eval_error(handle, pathname, status);
                        break;
                }
                /* Get the  acpi_handle. */
diff --combined include/acpi/acpi_bus.h
index 7581518e3eff59a13d1c9efcaac1566909742956,ea3697dc7046ed62c5bd2e7694887f940b9a0312,f34a0835aa4f230f47c57d67e64425d80ba851b7,8de31d472fad2d9018907ff9c49c7ec9b3dbf8f6..61e32ec1fc4d40230965e4d2915b4701ec54b5c4
    #define __ACPI_BUS_H__
    
    #include <linux/device.h>
 +++#include <linux/property.h>
    
    /* TBD: Make dynamic */
    #define ACPI_MAX_HANDLES    10
@@@@@ -313,6 -312,6 -312,6 -312,7 +313,7 @@@@@ struct acpi_device_wakeup_flags 
        u8 valid:1;             /* Can successfully enable wakeup? */
        u8 run_wake:1;          /* Run-Wake GPE devices */
        u8 notifier_present:1;  /* Wake-up notify handler has been installed */
+++     u8 enabled:1;           /* Enabled for wakeup */
    };
    
    struct acpi_device_wakeup_context {
@@@@@ -338,20 -337,10 -337,10 -338,10 +339,20 @@@@@ struct acpi_device_physical_node 
        bool put_online:1;
    };
    
 +++/* ACPI Device Specific Data (_DSD) */
 +++struct acpi_device_data {
 +++    const union acpi_object *pointer;
 +++    const union acpi_object *properties;
 +++    const union acpi_object *of_compatible;
 +++};
 +++
 +++struct acpi_gpio_mapping;
 +++
    /* Device */
    struct acpi_device {
        int device_type;
        acpi_handle handle;             /* no handle for fixed hardware */
 +++    struct fwnode_handle fwnode;
        struct acpi_device *parent;
        struct list_head children;
        struct list_head node;
        struct acpi_device_wakeup wakeup;
        struct acpi_device_perf performance;
        struct acpi_device_dir dir;
 +++    struct acpi_device_data data;
        struct acpi_scan_handler *handler;
        struct acpi_hotplug_context *hp;
        struct acpi_driver *driver;
 +++    const struct acpi_gpio_mapping *driver_gpios;
        void *driver_data;
        struct device dev;
        unsigned int physical_node_count;
  ++    unsigned int dep_unmet;
        struct list_head physical_node_list;
        struct mutex physical_node_lock;
        void (*remove)(struct acpi_device *);
    };
    
 +++static inline bool is_acpi_node(struct fwnode_handle *fwnode)
 +++{
 +++    return fwnode && fwnode->type == FWNODE_ACPI;
 +++}
 +++
 +++static inline struct acpi_device *acpi_node(struct fwnode_handle *fwnode)
 +++{
 +++    return fwnode ? container_of(fwnode, struct acpi_device, fwnode) : NULL;
 +++}
 +++
 +++static inline struct fwnode_handle *acpi_fwnode_handle(struct acpi_device *adev)
 +++{
 +++    return &adev->fwnode;
 +++}
 +++
    static inline void *acpi_driver_data(struct acpi_device *d)
    {
        return d->driver_data;
@@@@@ -545,7 -517,6 -516,6 -517,6 +546,7 @@@@@ acpi_status acpi_add_pm_notifier(struc
                                 void (*work_func)(struct work_struct *work));
    acpi_status acpi_remove_pm_notifier(struct acpi_device *adev);
    int acpi_pm_device_sleep_state(struct device *, int *, int);
 +++int acpi_pm_device_run_wake(struct device *, bool);
    #else
    static inline acpi_status acpi_add_pm_notifier(struct acpi_device *adev,
                                               struct device *dev,
@@@@@ -565,6 -536,11 -535,11 -536,11 +566,6 @@@@@ static inline int acpi_pm_device_sleep_
        return (m >= ACPI_STATE_D0 && m <= ACPI_STATE_D3_COLD) ?
                m : ACPI_STATE_D0;
    }
 ---#endif
 ---
 ---#ifdef CONFIG_PM_RUNTIME
 ---int acpi_pm_device_run_wake(struct device *, bool);
 ---#else
    static inline int acpi_pm_device_run_wake(struct device *dev, bool enable)
    {
        return -ENODEV;