diff options
-rw-r--r-- | Documentation/power/runtime_pm.rst | 4 | ||||
-rw-r--r-- | MAINTAINERS | 9 | ||||
-rw-r--r-- | arch/x86/kernel/e820.c | 4 | ||||
-rw-r--r-- | arch/x86/power/hibernate.c | 89 | ||||
-rw-r--r-- | drivers/base/power/domain.c | 36 | ||||
-rw-r--r-- | drivers/base/power/wakeup_stats.c | 4 | ||||
-rw-r--r-- | drivers/pci/pci.c | 16 | ||||
-rw-r--r-- | drivers/powercap/intel_rapl_common.c | 1 | ||||
-rw-r--r-- | drivers/powercap/intel_rapl_msr.c | 1 | ||||
-rw-r--r-- | include/linux/freezer.h | 1 | ||||
-rw-r--r-- | include/linux/intel_rapl.h | 2 | ||||
-rw-r--r-- | include/linux/pm.h | 1 | ||||
-rw-r--r-- | include/linux/pm_runtime.h | 2 | ||||
-rw-r--r-- | kernel/power/autosleep.c | 2 | ||||
-rw-r--r-- | kernel/power/snapshot.c | 2 | ||||
-rw-r--r-- | kernel/power/swap.c | 2 |
16 files changed, 41 insertions, 135 deletions
diff --git a/Documentation/power/runtime_pm.rst b/Documentation/power/runtime_pm.rst index d9c777b18f7a..18ae21bf7f92 100644 --- a/Documentation/power/runtime_pm.rst +++ b/Documentation/power/runtime_pm.rst @@ -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 diff --git a/MAINTAINERS b/MAINTAINERS index c80ad735b384..154132b75fbf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -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> diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 22aad412f965..629c4994f165 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -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 diff --git a/arch/x86/power/hibernate.c b/arch/x86/power/hibernate.c index cd3914fc9f3d..e94e0050a583 100644 --- a/arch/x86/power/hibernate.c +++ b/arch/x86/power/hibernate.c @@ -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; } diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 78c310d3179d..b6a782c31613 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -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) diff --git a/drivers/base/power/wakeup_stats.c b/drivers/base/power/wakeup_stats.c index d638259b829a..924fac493c4f 100644 --- a/drivers/base/power/wakeup_stats.c +++ b/drivers/base/power/wakeup_stats.c @@ -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; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 16a17215f633..e4d4e399004b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -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) diff --git a/drivers/powercap/intel_rapl_common.c b/drivers/powercap/intel_rapl_common.c index fdda2a737186..73cf68af9770 100644 --- a/drivers/powercap/intel_rapl_common.c +++ b/drivers/powercap/intel_rapl_common.c @@ -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); diff --git a/drivers/powercap/intel_rapl_msr.c b/drivers/powercap/intel_rapl_msr.c index 78213d4b5b16..cc3b22881bfe 100644 --- a/drivers/powercap/intel_rapl_msr.c +++ b/drivers/powercap/intel_rapl_msr.c @@ -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; diff --git a/include/linux/freezer.h b/include/linux/freezer.h index 27828145ca09..0621c5f86c39 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h @@ -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) {} diff --git a/include/linux/intel_rapl.h b/include/linux/intel_rapl.h index 50b8398ffd21..93780834fc8f 100644 --- a/include/linux/intel_rapl.h +++ b/include/linux/intel_rapl.h @@ -33,7 +33,7 @@ enum rapl_domain_reg_id { RAPL_DOMAIN_REG_MAX, }; -struct rapl_package; +struct rapl_domain; enum rapl_primitives { ENERGY_COUNTER, diff --git a/include/linux/pm.h b/include/linux/pm.h index 482313a8ccfc..c9657408fee1 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -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" */ diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index b492ae00cc90..6c08a085367b 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -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) {} diff --git a/kernel/power/autosleep.c b/kernel/power/autosleep.c index 9af5a50d3489..b29c8aca7486 100644 --- a/kernel/power/autosleep.c +++ b/kernel/power/autosleep.c @@ -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) diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index d63560e1cf87..1a221dcb3c01 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c @@ -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 diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 72e33054a2e1..bea3cb8afa11 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -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) |