Merge branches 'acpi-pm', 'acpi-processor' and 'acpi-resources'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 29 Jun 2021 13:47:29 +0000 (15:47 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 29 Jun 2021 13:47:29 +0000 (15:47 +0200)
* acpi-pm:
  ACPI: PM: postpone bringing devices to D0 unless we need them
  ACPI: PM: Adjust behavior for field problems on AMD systems
  ACPI: PM: s2idle: Add support for new Microsoft UUID
  ACPI: PM: s2idle: Add support for multiple func mask
  ACPI: PM: s2idle: Refactor common code
  ACPI: PM: s2idle: Use correct revision id
  ACPI: power: Use dev_dbg() to print some messages
  ACPI: sleep: Fix acpi_pm_pre_suspend() kernel-doc
  ACPI: power: Rework turning off unused power resources
  ACPI: power: Save the last known state of each power resource
  ACPI: power: Use u8 as the power resource state data type
  ACPI: PM / fan: Put fan device IDs into separate header file
  ACPI: PM: s2idle: Add missing LPS0 functions for AMD

* acpi-processor:
  ACPI: processor_throttling: Fix several coding style issues
  ACPI: processor_throttling: Remove redundant initialization of 'obj'
  ACPI: processor idle: Fix up C-state latency if not ordered

* acpi-resources:
  ACPI: resources: Add checks for ACPI IRQ override

1  2  3  4 
drivers/acpi/internal.h
drivers/acpi/scan.c

diff --combined drivers/acpi/internal.h
@@@@@ -88,7 -88,7 -88,7 -88,7 +88,7 @@@@@ void acpi_device_hotplug(struct acpi_de
    bool acpi_scan_is_offline(struct acpi_device *adev, bool uevent);
    
    acpi_status acpi_sysfs_table_handler(u32 event, void *table, void *context);
 ---void acpi_scan_table_handler(u32 event, void *table, void *context);
 +++void acpi_scan_table_notify(void);
    
    /* --------------------------------------------------------------------------
                         Device Node Initialization / Removal
@@@@@ -134,7 -134,7 -134,7 -134,7 +134,7 @@@@@ int acpi_power_init(void)
    void acpi_power_resources_list_free(struct list_head *list);
    int acpi_extract_power_resources(union acpi_object *package, unsigned int start,
                                 struct list_head *list);
  - int acpi_add_power_resource(acpi_handle handle);
  + struct acpi_device *acpi_add_power_resource(acpi_handle handle);
    void acpi_power_add_remove_device(struct acpi_device *adev, bool add);
    int acpi_power_wakeup_list_init(struct list_head *list, int *system_level);
    int acpi_device_sleep_wake(struct acpi_device *dev,
    int acpi_power_get_inferred_state(struct acpi_device *device, int *state);
    int acpi_power_on_resources(struct acpi_device *device, int state);
    int acpi_power_transition(struct acpi_device *device, int state);
-  -void acpi_turn_off_unused_power_resources(bool init);
+  +void acpi_turn_off_unused_power_resources(void);
    
    /* --------------------------------------------------------------------------
                                  Device Power Management
diff --combined drivers/acpi/scan.c
@@@@@ -47,6 -47,12 -47,12 -47,12 +47,6 @@@@@ static DEFINE_MUTEX(acpi_hp_context_loc
     */
    static u64 spcr_uart_addr;
    
 ---struct acpi_dep_data {
 ---    struct list_head node;
 ---    acpi_handle supplier;
 ---    acpi_handle consumer;
 ---};
 ---
    void acpi_scan_lock_acquire(void)
    {
        mutex_lock(&acpi_scan_lock);
@@@@@ -606,6 -612,11 -612,11 -612,11 +606,6 @@@@@ struct acpi_device *acpi_bus_get_acpi_d
        return handle_to_device(handle, get_acpi_device);
    }
    
 ---void acpi_bus_put_acpi_device(struct acpi_device *adev)
 ---{
 ---    acpi_dev_put(adev);
 ---}
 ---
    static struct acpi_device_bus_id *acpi_device_bus_id_match(const char *dev_id)
    {
        struct acpi_device_bus_id *acpi_device_bus_id;
@@@@@ -633,29 -644,24 -644,24 -644,24 +633,29 @@@@@ static int acpi_device_set_name(struct 
        return 0;
    }
    
 ---int acpi_device_add(struct acpi_device *device,
 ---                void (*release)(struct device *))
 +++static int acpi_tie_acpi_dev(struct acpi_device *adev)
    {
 ---    struct acpi_device_bus_id *acpi_device_bus_id;
 ---    int result;
 +++    acpi_handle handle = adev->handle;
 +++    acpi_status status;
    
 ---    if (device->handle) {
 ---            acpi_status status;
 +++    if (!handle)
 +++            return 0;
    
 ---            status = acpi_attach_data(device->handle, acpi_scan_drop_device,
 ---                                      device);
 ---            if (ACPI_FAILURE(status)) {
 ---                    acpi_handle_err(device->handle,
 ---                                    "Unable to attach device data\n");
 ---                    return -ENODEV;
 ---            }
 +++    status = acpi_attach_data(handle, acpi_scan_drop_device, adev);
 +++    if (ACPI_FAILURE(status)) {
 +++            acpi_handle_err(handle, "Unable to attach device data\n");
 +++            return -ENODEV;
        }
    
 +++    return 0;
 +++}
 +++
 +++static int __acpi_device_add(struct acpi_device *device,
 +++                         void (*release)(struct device *))
 +++{
 +++    struct acpi_device_bus_id *acpi_device_bus_id;
 +++    int result;
 +++
        /*
         * Linkage
         * -------
@@@@@ -744,17 -750,6 -750,6 -750,6 +744,17 @@@@@ err_unlock
        return result;
    }
    
 +++int acpi_device_add(struct acpi_device *adev, void (*release)(struct device *))
 +++{
 +++    int ret;
 +++
 +++    ret = acpi_tie_acpi_dev(adev);
 +++    if (ret)
 +++            return ret;
 +++
 +++    return __acpi_device_add(adev, release);
 +++}
 +++
    /* --------------------------------------------------------------------------
                                     Device Enumeration
       -------------------------------------------------------------------------- */
@@@@@ -1676,16 -1671,8 -1671,8 -1671,8 +1676,16 @@@@@ void acpi_init_device_object(struct acp
        device_initialize(&device->dev);
        dev_set_uevent_suppress(&device->dev, true);
        acpi_init_coherency(device);
 ---    /* Assume there are unmet deps to start with. */
 ---    device->dep_unmet = 1;
 +++}
 +++
 +++static void acpi_scan_dep_init(struct acpi_device *adev)
 +++{
 +++    struct acpi_dep_data *dep;
 +++
 +++    list_for_each_entry(dep, &acpi_dep_list, node) {
 +++            if (dep->consumer == adev->handle)
 +++                    adev->dep_unmet++;
 +++    }
    }
    
    void acpi_device_add_finalize(struct acpi_device *device)
@@@@@ -1701,10 -1688,9 -1688,9 -1688,9 +1701,10 @@@@@ static void acpi_scan_init_status(struc
    }
    
    static int acpi_add_single_object(struct acpi_device **child,
 ---                              acpi_handle handle, int type)
 +++                              acpi_handle handle, int type, bool dep_init)
    {
        struct acpi_device *device;
 +++    bool release_dep_lock = false;
        int result;
    
        device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL);
         * acpi_bus_get_status() and use its quirk handling.  Note that
         * this must be done before the get power-/wakeup_dev-flags calls.
         */
 ---    if (type == ACPI_BUS_TYPE_DEVICE || type == ACPI_BUS_TYPE_PROCESSOR)
 +++    if (type == ACPI_BUS_TYPE_DEVICE || type == ACPI_BUS_TYPE_PROCESSOR) {
 +++            if (dep_init) {
 +++                    mutex_lock(&acpi_dep_list_lock);
 +++                    /*
 +++                     * Hold the lock until the acpi_tie_acpi_dev() call
 +++                     * below to prevent concurrent acpi_scan_clear_dep()
 +++                     * from deleting a dependency list entry without
 +++                     * updating dep_unmet for the device.
 +++                     */
 +++                    release_dep_lock = true;
 +++                    acpi_scan_dep_init(device);
 +++            }
                acpi_scan_init_status(device);
 +++    }
    
        acpi_bus_get_power_flags(device);
        acpi_bus_get_wakeup_device_flags(device);
    
 ---    result = acpi_device_add(device, acpi_device_release);
 +++    result = acpi_tie_acpi_dev(device);
 +++
 +++    if (release_dep_lock)
 +++            mutex_unlock(&acpi_dep_list_lock);
 +++
 +++    if (!result)
 +++            result = __acpi_device_add(device, acpi_device_release);
 +++
        if (result) {
                acpi_device_release(&device->dev);
                return result;
@@@@@ -1919,6 -1886,22 -1886,22 -1886,22 +1919,6 @@@@@ static u32 acpi_scan_check_dep(acpi_han
        return count;
    }
    
 ---static void acpi_scan_dep_init(struct acpi_device *adev)
 ---{
 ---    struct acpi_dep_data *dep;
 ---
 ---    adev->dep_unmet = 0;
 ---
 ---    mutex_lock(&acpi_dep_list_lock);
 ---
 ---    list_for_each_entry(dep, &acpi_dep_list, node) {
 ---            if (dep->consumer == adev->handle)
 ---                    adev->dep_unmet++;
 ---    }
 ---
 ---    mutex_unlock(&acpi_dep_list_lock);
 ---}
 ---
    static bool acpi_bus_scan_second_pass;
    
    static acpi_status acpi_bus_check_add(acpi_handle handle, bool check_dep,
                return AE_OK;
        }
    
 ---    acpi_add_single_object(&device, handle, type);
 ---    if (!device)
 ---            return AE_CTRL_DEPTH;
 ---
 ---    acpi_scan_init_hotplug(device);
        /*
         * If check_dep is true at this point, the device has no dependencies,
         * or the creation of the device object would have been postponed above.
         */
 ---    if (check_dep)
 ---            device->dep_unmet = 0;
 ---    else
 ---            acpi_scan_dep_init(device);
 +++    acpi_add_single_object(&device, handle, type, !check_dep);
 +++    if (!device)
 +++            return AE_CTRL_DEPTH;
 +++
 +++    acpi_scan_init_hotplug(device);
    
    out:
        if (!*adev_p)
@@@@@ -2124,141 -2111,29 -2111,29 -2111,29 +2124,141 @@@@@ static void acpi_bus_attach(struct acpi
                device->handler->hotplug.notify_online(device);
    }
    
 ---void acpi_walk_dep_device_list(acpi_handle handle)
 +++static int acpi_dev_get_first_consumer_dev_cb(struct acpi_dep_data *dep, void *data)
    {
 ---    struct acpi_dep_data *dep, *tmp;
        struct acpi_device *adev;
    
 +++    adev = acpi_bus_get_acpi_device(dep->consumer);
 +++    if (adev) {
 +++            *(struct acpi_device **)data = adev;
 +++            return 1;
 +++    }
 +++    /* Continue parsing if the device object is not present. */
 +++    return 0;
 +++}
 +++
 +++struct acpi_scan_clear_dep_work {
 +++    struct work_struct work;
 +++    struct acpi_device *adev;
 +++};
 +++
 +++static void acpi_scan_clear_dep_fn(struct work_struct *work)
 +++{
 +++    struct acpi_scan_clear_dep_work *cdw;
 +++
 +++    cdw = container_of(work, struct acpi_scan_clear_dep_work, work);
 +++
 +++    acpi_scan_lock_acquire();
 +++    acpi_bus_attach(cdw->adev, true);
 +++    acpi_scan_lock_release();
 +++
 +++    acpi_dev_put(cdw->adev);
 +++    kfree(cdw);
 +++}
 +++
 +++static bool acpi_scan_clear_dep_queue(struct acpi_device *adev)
 +++{
 +++    struct acpi_scan_clear_dep_work *cdw;
 +++
 +++    if (adev->dep_unmet)
 +++            return false;
 +++
 +++    cdw = kmalloc(sizeof(*cdw), GFP_KERNEL);
 +++    if (!cdw)
 +++            return false;
 +++
 +++    cdw->adev = adev;
 +++    INIT_WORK(&cdw->work, acpi_scan_clear_dep_fn);
 +++    /*
 +++     * Since the work function may block on the lock until the entire
 +++     * initial enumeration of devices is complete, put it into the unbound
 +++     * workqueue.
 +++     */
 +++    queue_work(system_unbound_wq, &cdw->work);
 +++
 +++    return true;
 +++}
 +++
 +++static int acpi_scan_clear_dep(struct acpi_dep_data *dep, void *data)
 +++{
 +++    struct acpi_device *adev = acpi_bus_get_acpi_device(dep->consumer);
 +++
 +++    if (adev) {
 +++            adev->dep_unmet--;
 +++            if (!acpi_scan_clear_dep_queue(adev))
 +++                    acpi_dev_put(adev);
 +++    }
 +++
 +++    list_del(&dep->node);
 +++    kfree(dep);
 +++
 +++    return 0;
 +++}
 +++
 +++/**
 +++ * acpi_walk_dep_device_list - Apply a callback to every entry in acpi_dep_list
 +++ * @handle: The ACPI handle of the supplier device
 +++ * @callback:       Pointer to the callback function to apply
 +++ * @data:   Pointer to some data to pass to the callback
 +++ *
 +++ * The return value of the callback determines this function's behaviour. If 0
 +++ * is returned we continue to iterate over acpi_dep_list. If a positive value
 +++ * is returned then the loop is broken but this function returns 0. If a
 +++ * negative value is returned by the callback then the loop is broken and that
 +++ * value is returned as the final error.
 +++ */
 +++static int acpi_walk_dep_device_list(acpi_handle handle,
 +++                            int (*callback)(struct acpi_dep_data *, void *),
 +++                            void *data)
 +++{
 +++    struct acpi_dep_data *dep, *tmp;
 +++    int ret = 0;
 +++
        mutex_lock(&acpi_dep_list_lock);
        list_for_each_entry_safe(dep, tmp, &acpi_dep_list, node) {
                if (dep->supplier == handle) {
 ---                    acpi_bus_get_device(dep->consumer, &adev);
 ---
 ---                    if (adev) {
 ---                            adev->dep_unmet--;
 ---                            if (!adev->dep_unmet)
 ---                                    acpi_bus_attach(adev, true);
 ---                    }
 ---
 ---                    list_del(&dep->node);
 ---                    kfree(dep);
 +++                    ret = callback(dep, data);
 +++                    if (ret)
 +++                            break;
                }
        }
        mutex_unlock(&acpi_dep_list_lock);
 +++
 +++    return ret > 0 ? 0 : ret;
 +++}
 +++
 +++/**
 +++ * acpi_dev_clear_dependencies - Inform consumers that the device is now active
 +++ * @supplier: Pointer to the supplier &struct acpi_device
 +++ *
 +++ * Clear dependencies on the given device.
 +++ */
 +++void acpi_dev_clear_dependencies(struct acpi_device *supplier)
 +++{
 +++    acpi_walk_dep_device_list(supplier->handle, acpi_scan_clear_dep, NULL);
 +++}
 +++EXPORT_SYMBOL_GPL(acpi_dev_clear_dependencies);
 +++
 +++/**
 +++ * acpi_dev_get_first_consumer_dev - Return ACPI device dependent on @supplier
 +++ * @supplier: Pointer to the dependee device
 +++ *
 +++ * Returns the first &struct acpi_device which declares itself dependent on
 +++ * @supplier via the _DEP buffer, parsed from the acpi_dep_list.
 +++ *
 +++ * The caller is responsible for putting the reference to adev when it is no
 +++ * longer needed.
 +++ */
 +++struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier)
 +++{
 +++    struct acpi_device *adev = NULL;
 +++
 +++    acpi_walk_dep_device_list(supplier->handle,
 +++                              acpi_dev_get_first_consumer_dev_cb, &adev);
 +++
 +++    return adev;
    }
 ---EXPORT_SYMBOL_GPL(acpi_walk_dep_device_list);
 +++EXPORT_SYMBOL_GPL(acpi_dev_get_first_consumer_dev);
    
    /**
     * acpi_bus_scan - Add ACPI device node objects in a given namespace scope.
@@@@@ -2348,7 -2223,7 -2223,7 -2223,7 +2348,7 @@@@@ int acpi_bus_register_early_device(int 
        struct acpi_device *device = NULL;
        int result;
    
 ---    result = acpi_add_single_object(&device, NULL, type);
 +++    result = acpi_add_single_object(&device, NULL, type, false);
        if (result)
                return result;
    
@@@@@ -2368,7 -2243,7 -2243,7 -2243,7 +2368,7 @@@@@ static int acpi_bus_scan_fixed(void
                struct acpi_device *device = NULL;
    
                result = acpi_add_single_object(&device, NULL,
 ---                                            ACPI_BUS_TYPE_POWER_BUTTON);
 +++                                            ACPI_BUS_TYPE_POWER_BUTTON, false);
                if (result)
                        return result;
    
                struct acpi_device *device = NULL;
    
                result = acpi_add_single_object(&device, NULL,
 ---                                            ACPI_BUS_TYPE_SLEEP_BUTTON);
 +++                                            ACPI_BUS_TYPE_SLEEP_BUTTON, false);
                if (result)
                        return result;
    
@@@@@ -2485,7 -2360,7 -2360,7 -2360,7 +2485,7 @@@@@ int __init acpi_scan_init(void
                }
        }
    
-  -    acpi_turn_off_unused_power_resources(true);
+  +    acpi_turn_off_unused_power_resources();
    
        acpi_scan_initialized = true;
    
@@@@@ -2533,28 -2408,46 -2408,46 -2408,46 +2533,28 @@@@@ int __init __acpi_probe_device_table(st
        return count;
    }
    
 ---struct acpi_table_events_work {
 ---    struct work_struct work;
 ---    void *table;
 ---    u32 event;
 ---};
 ---
    static void acpi_table_events_fn(struct work_struct *work)
    {
 ---    struct acpi_table_events_work *tew;
 +++    acpi_scan_lock_acquire();
 +++    acpi_bus_scan(ACPI_ROOT_OBJECT);
 +++    acpi_scan_lock_release();
    
 ---    tew = container_of(work, struct acpi_table_events_work, work);
 ---
 ---    if (tew->event == ACPI_TABLE_EVENT_LOAD) {
 ---            acpi_scan_lock_acquire();
 ---            acpi_bus_scan(ACPI_ROOT_OBJECT);
 ---            acpi_scan_lock_release();
 ---    }
 ---
 ---    kfree(tew);
 +++    kfree(work);
    }
    
 ---void acpi_scan_table_handler(u32 event, void *table, void *context)
 +++void acpi_scan_table_notify(void)
    {
 ---    struct acpi_table_events_work *tew;
 +++    struct work_struct *work;
    
        if (!acpi_scan_initialized)
                return;
    
 ---    if (event != ACPI_TABLE_EVENT_LOAD)
 ---            return;
 ---
 ---    tew = kmalloc(sizeof(*tew), GFP_KERNEL);
 ---    if (!tew)
 +++    work = kmalloc(sizeof(*work), GFP_KERNEL);
 +++    if (!work)
                return;
    
 ---    INIT_WORK(&tew->work, acpi_table_events_fn);
 ---    tew->table = table;
 ---    tew->event = event;
 ---
 ---    schedule_work(&tew->work);
 +++    INIT_WORK(work, acpi_table_events_fn);
 +++    schedule_work(work);
    }
    
    int acpi_reconfig_notifier_register(struct notifier_block *nb)