Merge branches 'pm-core', 'pm-pci', 'pm-sleep', 'pm-domains' and 'powercap'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 26 Apr 2021 14:57:17 +0000 (16:57 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 26 Apr 2021 14:57:17 +0000 (16:57 +0200)
* pm-core:
  PM: runtime: Add documentation for pm_runtime_resume_and_get()
  PM: runtime: Replace inline function pm_runtime_callbacks_present()
  PM: core: Remove duplicate declaration from header file

* pm-pci:
  PCI: PM: Do not read power state in pci_enable_device_flags()

* pm-sleep:
  PM: wakeup: remove redundant assignment to variable retval
  PM: hibernate: x86: Use crc32 instead of md5 for hibernation e820 integrity check
  PM: wakeup: use dev_set_name() directly
  PM: sleep: fix typos in comments
  freezer: Remove unused inline function try_to_freeze_nowarn()

* pm-domains:
  PM: domains: Don't runtime resume devices at genpd_prepare()

* powercap:
  powercap: RAPL: Fix struct declaration in header file
  MAINTAINERS: Add DTPM subsystem maintainer
  powercap: Add Hygon Fam18h RAPL support

16 files changed:
Documentation/power/runtime_pm.rst
MAINTAINERS
arch/x86/kernel/e820.c
arch/x86/power/hibernate.c
drivers/base/power/domain.c
drivers/base/power/wakeup_stats.c
drivers/pci/pci.c
drivers/powercap/intel_rapl_common.c
drivers/powercap/intel_rapl_msr.c
include/linux/freezer.h
include/linux/intel_rapl.h
include/linux/pm.h
include/linux/pm_runtime.h
kernel/power/autosleep.c
kernel/power/snapshot.c
kernel/power/swap.c

index d9c777b..18ae21b 100644 (file)
@@ -339,6 +339,10 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
       checked additionally, and -EACCES means that 'power.disable_depth' is
       different from 0
 
+  `int pm_runtime_resume_and_get(struct device *dev);`
+    - run pm_runtime_resume(dev) and if successful, increment the device's
+      usage counter; return the result of pm_runtime_resume
+
   `int pm_request_idle(struct device *dev);`
     - submit a request to execute the subsystem-level idle callback for the
       device (the request is represented by a work item in pm_wq); returns 0 on
index c80ad73..154132b 100644 (file)
@@ -14312,6 +14312,15 @@ F:     include/linux/pm_*
 F:     include/linux/powercap.h
 F:     kernel/configs/nopm.config
 
+DYNAMIC THERMAL POWER MANAGEMENT (DTPM)
+M:     Daniel Lezcano <daniel.lezcano@kernel.org>
+L:     linux-pm@vger.kernel.org
+S:     Supported
+B:     https://bugzilla.kernel.org
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
+F:     drivers/powercap/dtpm*
+F:     include/linux/dtpm.h
+
 POWER STATE COORDINATION INTERFACE (PSCI)
 M:     Mark Rutland <mark.rutland@arm.com>
 M:     Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
index 22aad41..629c499 100644 (file)
@@ -31,8 +31,8 @@
  *       - inform the user about the firmware's notion of memory layout
  *         via /sys/firmware/memmap
  *
- *       - the hibernation code uses it to generate a kernel-independent MD5
- *         fingerprint of the physical memory layout of a system.
+ *       - the hibernation code uses it to generate a kernel-independent CRC32
+ *         checksum of the physical memory layout of a system.
  *
  * - 'e820_table_kexec': a slightly modified (by the kernel) firmware version
  *   passed to us by the bootloader - the major difference between
index cd3914f..e94e005 100644 (file)
@@ -13,8 +13,8 @@
 #include <linux/kdebug.h>
 #include <linux/cpu.h>
 #include <linux/pgtable.h>
-
-#include <crypto/hash.h>
+#include <linux/types.h>
+#include <linux/crc32.h>
 
 #include <asm/e820/api.h>
 #include <asm/init.h>
@@ -54,95 +54,33 @@ int pfn_is_nosave(unsigned long pfn)
        return pfn >= nosave_begin_pfn && pfn < nosave_end_pfn;
 }
 
-
-#define MD5_DIGEST_SIZE 16
-
 struct restore_data_record {
        unsigned long jump_address;
        unsigned long jump_address_phys;
        unsigned long cr3;
        unsigned long magic;
-       u8 e820_digest[MD5_DIGEST_SIZE];
+       unsigned long e820_checksum;
 };
 
-#if IS_BUILTIN(CONFIG_CRYPTO_MD5)
 /**
- * get_e820_md5 - calculate md5 according to given e820 table
+ * compute_e820_crc32 - calculate crc32 of a given e820 table
  *
  * @table: the e820 table to be calculated
- * @buf: the md5 result to be stored to
+ *
+ * Return: the resulting checksum
  */
-static int get_e820_md5(struct e820_table *table, void *buf)
+static inline u32 compute_e820_crc32(struct e820_table *table)
 {
-       struct crypto_shash *tfm;
-       struct shash_desc *desc;
-       int size;
-       int ret = 0;
-
-       tfm = crypto_alloc_shash("md5", 0, 0);
-       if (IS_ERR(tfm))
-               return -ENOMEM;
-
-       desc = kmalloc(sizeof(struct shash_desc) + crypto_shash_descsize(tfm),
-                      GFP_KERNEL);
-       if (!desc) {
-               ret = -ENOMEM;
-               goto free_tfm;
-       }
-
-       desc->tfm = tfm;
-
-       size = offsetof(struct e820_table, entries) +
+       int size = offsetof(struct e820_table, entries) +
                sizeof(struct e820_entry) * table->nr_entries;
 
-       if (crypto_shash_digest(desc, (u8 *)table, size, buf))
-               ret = -EINVAL;
-
-       kfree_sensitive(desc);
-
-free_tfm:
-       crypto_free_shash(tfm);
-       return ret;
-}
-
-static int hibernation_e820_save(void *buf)
-{
-       return get_e820_md5(e820_table_firmware, buf);
-}
-
-static bool hibernation_e820_mismatch(void *buf)
-{
-       int ret;
-       u8 result[MD5_DIGEST_SIZE];
-
-       memset(result, 0, MD5_DIGEST_SIZE);
-       /* If there is no digest in suspend kernel, let it go. */
-       if (!memcmp(result, buf, MD5_DIGEST_SIZE))
-               return false;
-
-       ret = get_e820_md5(e820_table_firmware, result);
-       if (ret)
-               return true;
-
-       return memcmp(result, buf, MD5_DIGEST_SIZE) ? true : false;
-}
-#else
-static int hibernation_e820_save(void *buf)
-{
-       return 0;
-}
-
-static bool hibernation_e820_mismatch(void *buf)
-{
-       /* If md5 is not builtin for restore kernel, let it go. */
-       return false;
+       return ~crc32_le(~0, (unsigned char const *)table, size);
 }
-#endif
 
 #ifdef CONFIG_X86_64
-#define RESTORE_MAGIC  0x23456789ABCDEF01UL
+#define RESTORE_MAGIC  0x23456789ABCDEF02UL
 #else
-#define RESTORE_MAGIC  0x12345678UL
+#define RESTORE_MAGIC  0x12345679UL
 #endif
 
 /**
@@ -179,7 +117,8 @@ int arch_hibernation_header_save(void *addr, unsigned int max_size)
         */
        rdr->cr3 = restore_cr3 & ~CR3_PCID_MASK;
 
-       return hibernation_e820_save(rdr->e820_digest);
+       rdr->e820_checksum = compute_e820_crc32(e820_table_firmware);
+       return 0;
 }
 
 /**
@@ -200,7 +139,7 @@ int arch_hibernation_header_restore(void *addr)
        jump_address_phys = rdr->jump_address_phys;
        restore_cr3 = rdr->cr3;
 
-       if (hibernation_e820_mismatch(rdr->e820_digest)) {
+       if (rdr->e820_checksum != compute_e820_crc32(e820_table_firmware)) {
                pr_crit("Hibernate inconsistent memory map detected!\n");
                return -ENODEV;
        }
index 78c310d..b6a782c 100644 (file)
@@ -1088,34 +1088,6 @@ static void genpd_sync_power_on(struct generic_pm_domain *genpd, bool use_lock,
 }
 
 /**
- * resume_needed - Check whether to resume a device before system suspend.
- * @dev: Device to check.
- * @genpd: PM domain the device belongs to.
- *
- * There are two cases in which a device that can wake up the system from sleep
- * states should be resumed by genpd_prepare(): (1) if the device is enabled
- * to wake up the system and it has to remain active for this purpose while the
- * system is in the sleep state and (2) if the device is not enabled to wake up
- * the system from sleep states and it generally doesn't generate wakeup signals
- * by itself (those signals are generated on its behalf by other parts of the
- * system).  In the latter case it may be necessary to reconfigure the device's
- * wakeup settings during system suspend, because it may have been set up to
- * signal remote wakeup from the system's working state as needed by runtime PM.
- * Return 'true' in either of the above cases.
- */
-static bool resume_needed(struct device *dev,
-                         const struct generic_pm_domain *genpd)
-{
-       bool active_wakeup;
-
-       if (!device_can_wakeup(dev))
-               return false;
-
-       active_wakeup = genpd_is_active_wakeup(genpd);
-       return device_may_wakeup(dev) ? active_wakeup : !active_wakeup;
-}
-
-/**
  * genpd_prepare - Start power transition of a device in a PM domain.
  * @dev: Device to start the transition of.
  *
@@ -1135,14 +1107,6 @@ static int genpd_prepare(struct device *dev)
        if (IS_ERR(genpd))
                return -EINVAL;
 
-       /*
-        * If a wakeup request is pending for the device, it should be woken up
-        * at this point and a system wakeup event should be reported if it's
-        * set up to wake up the system from sleep states.
-        */
-       if (resume_needed(dev, genpd))
-               pm_runtime_resume(dev);
-
        genpd_lock(genpd);
 
        if (genpd->prepared_count++ == 0)
index d638259..924fac4 100644 (file)
@@ -137,7 +137,7 @@ static struct device *wakeup_source_device_create(struct device *parent,
                                                  struct wakeup_source *ws)
 {
        struct device *dev = NULL;
-       int retval = -ENODEV;
+       int retval;
 
        dev = kzalloc(sizeof(*dev), GFP_KERNEL);
        if (!dev) {
@@ -154,7 +154,7 @@ static struct device *wakeup_source_device_create(struct device *parent,
        dev_set_drvdata(dev, ws);
        device_set_pm_not_required(dev);
 
-       retval = kobject_set_name(&dev->kobj, "wakeup%d", ws->id);
+       retval = dev_set_name(dev, "wakeup%d", ws->id);
        if (retval)
                goto error;
 
index 16a1721..e4d4e39 100644 (file)
@@ -1870,20 +1870,10 @@ static int pci_enable_device_flags(struct pci_dev *dev, unsigned long flags)
        int err;
        int i, bars = 0;
 
-       /*
-        * Power state could be unknown at this point, either due to a fresh
-        * boot or a device removal call.  So get the current power state
-        * so that things like MSI message writing will behave as expected
-        * (e.g. if the device really is in D0 at enable time).
-        */
-       if (dev->pm_cap) {
-               u16 pmcsr;
-               pci_read_config_word(dev, dev->pm_cap + PCI_PM_CTRL, &pmcsr);
-               dev->current_state = (pmcsr & PCI_PM_CTRL_STATE_MASK);
-       }
-
-       if (atomic_inc_return(&dev->enable_cnt) > 1)
+       if (atomic_inc_return(&dev->enable_cnt) > 1) {
+               pci_update_current_state(dev, dev->current_state);
                return 0;               /* already enabled */
+       }
 
        bridge = pci_upstream_bridge(dev);
        if (bridge)
index fdda2a7..73cf68a 100644 (file)
@@ -1069,6 +1069,7 @@ static const struct x86_cpu_id rapl_ids[] __initconst = {
 
        X86_MATCH_VENDOR_FAM(AMD, 0x17, &rapl_defaults_amd),
        X86_MATCH_VENDOR_FAM(AMD, 0x19, &rapl_defaults_amd),
+       X86_MATCH_VENDOR_FAM(HYGON, 0x18, &rapl_defaults_amd),
        {}
 };
 MODULE_DEVICE_TABLE(x86cpu, rapl_ids);
index 78213d4..cc3b228 100644 (file)
@@ -150,6 +150,7 @@ static int rapl_msr_probe(struct platform_device *pdev)
        case X86_VENDOR_INTEL:
                rapl_msr_priv = &rapl_msr_priv_intel;
                break;
+       case X86_VENDOR_HYGON:
        case X86_VENDOR_AMD:
                rapl_msr_priv = &rapl_msr_priv_amd;
                break;
index 2782814..0621c5f 100644 (file)
@@ -279,7 +279,6 @@ static inline int freeze_kernel_threads(void) { return -ENOSYS; }
 static inline void thaw_processes(void) {}
 static inline void thaw_kernel_threads(void) {}
 
-static inline bool try_to_freeze_nowarn(void) { return false; }
 static inline bool try_to_freeze(void) { return false; }
 
 static inline void freezer_do_not_count(void) {}
index 50b8398..9378083 100644 (file)
@@ -33,7 +33,7 @@ enum rapl_domain_reg_id {
        RAPL_DOMAIN_REG_MAX,
 };
 
-struct rapl_package;
+struct rapl_domain;
 
 enum rapl_primitives {
        ENERGY_COUNTER,
index 482313a..c965740 100644 (file)
@@ -39,7 +39,6 @@ static inline void pm_vt_switch_unregister(struct device *dev)
  * Device power management
  */
 
-struct device;
 
 #ifdef CONFIG_PM
 extern const char power_group_name[];          /* = "power" */
index b492ae0..6c08a08 100644 (file)
@@ -265,7 +265,7 @@ static inline void pm_runtime_no_callbacks(struct device *dev) {}
 static inline void pm_runtime_irq_safe(struct device *dev) {}
 static inline bool pm_runtime_is_irq_safe(struct device *dev) { return false; }
 
-static inline bool pm_runtime_callbacks_present(struct device *dev) { return false; }
+static inline bool pm_runtime_has_no_callbacks(struct device *dev) { return false; }
 static inline void pm_runtime_mark_last_busy(struct device *dev) {}
 static inline void __pm_runtime_use_autosuspend(struct device *dev,
                                                bool use) {}
index 9af5a50..b29c8ac 100644 (file)
@@ -54,7 +54,7 @@ static void try_to_suspend(struct work_struct *work)
                goto out;
 
        /*
-        * If the wakeup occured for an unknown reason, wait to prevent the
+        * If the wakeup occurred for an unknown reason, wait to prevent the
         * system from trying to suspend and waking up in a tight loop.
         */
        if (final_count == initial_count)
index d63560e..1a221dc 100644 (file)
@@ -329,7 +329,7 @@ static void *chain_alloc(struct chain_allocator *ca, unsigned int size)
 /**
  * Data types related to memory bitmaps.
  *
- * Memory bitmap is a structure consiting of many linked lists of
+ * Memory bitmap is a structure consisting of many linked lists of
  * objects.  The main list's elements are of type struct zone_bitmap
  * and each of them corresonds to one zone.  For each zone bitmap
  * object there is a list of objects of type struct bm_block that
index 72e3305..bea3cb8 100644 (file)
@@ -884,7 +884,7 @@ out_clean:
  *     enough_swap - Make sure we have enough swap to save the image.
  *
  *     Returns TRUE or FALSE after checking the total amount of swap
- *     space avaiable from the resume partition.
+ *     space available from the resume partition.
  */
 
 static int enough_swap(unsigned int nr_pages)