Merge suspend-to-idle rework material for v5.4.
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 17 Sep 2019 07:35:35 +0000 (09:35 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Tue, 17 Sep 2019 07:35:35 +0000 (09:35 +0200)
* pm-s2idle-rework: (21 commits)
  ACPI: PM: s2idle: Always set up EC GPE for system wakeup
  ACPI: PM: s2idle: Avoid rearming SCI for wakeup unnecessarily
  PM: suspend: Fix platform_suspend_prepare_noirq()
  intel-hid: Disable button array during suspend-to-idle
  intel-hid: intel-vbtn: Avoid leaking wakeup_mode set
  ACPI: PM: s2idle: Execute LPS0 _DSM functions with suspended devices
  ACPI: EC: PM: Make acpi_ec_dispatch_gpe() print debug message
  ACPI: EC: PM: Consolidate some code depending on PM_SLEEP
  ACPI: PM: s2idle: Eliminate acpi_sleep_no_ec_events()
  ACPI: PM: s2idle: Switch EC over to polling during "noirq" suspend
  ACPI: PM: s2idle: Add acpi.sleep_no_lps0 module parameter
  ACPI: PM: s2idle: Rearrange lps0_device_attach()
  ACPI: PM: Set up EC GPE for system wakeup from drivers that need it
  PM: sleep: Drop dpm_noirq_begin() and dpm_noirq_end()
  PM: sleep: Integrate suspend-to-idle with generig suspend flow
  PM: sleep: Simplify suspend-to-idle control flow
  ACPI: PM: Set s2idle_wakeup earlier and clear it later
  PM: sleep: Fix possible overflow in pm_system_cancel_wakeup()
  ACPI: EC: Return bool from acpi_ec_dispatch_gpe()
  ACPICA: Return u32 from acpi_dispatch_gpe()
  ...

1  2 
drivers/base/power/wakeup.c

index e58b070985b14eb5eaf5c8a69453fa046785d448,b30c45aad10f1b35dfa4a7a7c8b13c7f78ac857e..5817b51d2b1537017320926312f46c3f029ff50b
@@@ -72,7 -72,22 +72,7 @@@ static struct wakeup_source deleted_ws 
        .lock =  __SPIN_LOCK_UNLOCKED(deleted_ws.lock),
  };
  
 -/**
 - * wakeup_source_prepare - Prepare a new wakeup source for initialization.
 - * @ws: Wakeup source to prepare.
 - * @name: Pointer to the name of the new wakeup source.
 - *
 - * Callers must ensure that the @name string won't be freed when @ws is still in
 - * use.
 - */
 -void wakeup_source_prepare(struct wakeup_source *ws, const char *name)
 -{
 -      if (ws) {
 -              memset(ws, 0, sizeof(*ws));
 -              ws->name = name;
 -      }
 -}
 -EXPORT_SYMBOL_GPL(wakeup_source_prepare);
 +static DEFINE_IDA(wakeup_ida);
  
  /**
   * wakeup_source_create - Create a struct wakeup_source object.
  struct wakeup_source *wakeup_source_create(const char *name)
  {
        struct wakeup_source *ws;
 +      const char *ws_name;
 +      int id;
  
 -      ws = kmalloc(sizeof(*ws), GFP_KERNEL);
 +      ws = kzalloc(sizeof(*ws), GFP_KERNEL);
        if (!ws)
 -              return NULL;
 +              goto err_ws;
 +
 +      ws_name = kstrdup_const(name, GFP_KERNEL);
 +      if (!ws_name)
 +              goto err_name;
 +      ws->name = ws_name;
 +
 +      id = ida_alloc(&wakeup_ida, GFP_KERNEL);
 +      if (id < 0)
 +              goto err_id;
 +      ws->id = id;
  
 -      wakeup_source_prepare(ws, name ? kstrdup_const(name, GFP_KERNEL) : NULL);
        return ws;
 +
 +err_id:
 +      kfree_const(ws->name);
 +err_name:
 +      kfree(ws);
 +err_ws:
 +      return NULL;
  }
  EXPORT_SYMBOL_GPL(wakeup_source_create);
  
@@@ -137,13 -134,6 +137,13 @@@ static void wakeup_source_record(struc
        spin_unlock_irqrestore(&deleted_ws.lock, flags);
  }
  
 +static void wakeup_source_free(struct wakeup_source *ws)
 +{
 +      ida_free(&wakeup_ida, ws->id);
 +      kfree_const(ws->name);
 +      kfree(ws);
 +}
 +
  /**
   * wakeup_source_destroy - Destroy a struct wakeup_source object.
   * @ws: Wakeup source to destroy.
@@@ -157,7 -147,8 +157,7 @@@ void wakeup_source_destroy(struct wakeu
  
        __pm_relax(ws);
        wakeup_source_record(ws);
 -      kfree_const(ws->name);
 -      kfree(ws);
 +      wakeup_source_free(ws);
  }
  EXPORT_SYMBOL_GPL(wakeup_source_destroy);
  
@@@ -209,26 -200,16 +209,26 @@@ EXPORT_SYMBOL_GPL(wakeup_source_remove)
  
  /**
   * wakeup_source_register - Create wakeup source and add it to the list.
 + * @dev: Device this wakeup source is associated with (or NULL if virtual).
   * @name: Name of the wakeup source to register.
   */
 -struct wakeup_source *wakeup_source_register(const char *name)
 +struct wakeup_source *wakeup_source_register(struct device *dev,
 +                                           const char *name)
  {
        struct wakeup_source *ws;
 +      int ret;
  
        ws = wakeup_source_create(name);
 -      if (ws)
 +      if (ws) {
 +              if (!dev || device_is_registered(dev)) {
 +                      ret = wakeup_source_sysfs_add(dev, ws);
 +                      if (ret) {
 +                              wakeup_source_free(ws);
 +                              return NULL;
 +                      }
 +              }
                wakeup_source_add(ws);
 -
 +      }
        return ws;
  }
  EXPORT_SYMBOL_GPL(wakeup_source_register);
@@@ -241,7 -222,6 +241,7 @@@ void wakeup_source_unregister(struct wa
  {
        if (ws) {
                wakeup_source_remove(ws);
 +              wakeup_source_sysfs_remove(ws);
                wakeup_source_destroy(ws);
        }
  }
@@@ -285,7 -265,7 +285,7 @@@ int device_wakeup_enable(struct device 
        if (pm_suspend_target_state != PM_SUSPEND_ON)
                dev_dbg(dev, "Suspicious %s() during system transition!\n", __func__);
  
 -      ws = wakeup_source_register(dev_name(dev));
 +      ws = wakeup_source_register(dev, dev_name(dev));
        if (!ws)
                return -ENOMEM;
  
@@@ -879,7 -859,7 +879,7 @@@ EXPORT_SYMBOL_GPL(pm_system_wakeup)
  
  void pm_system_cancel_wakeup(void)
  {
-       atomic_dec(&pm_abort_suspend);
+       atomic_dec_if_positive(&pm_abort_suspend);
  }
  
  void pm_wakeup_clear(bool reset)