From 147a7d9d25ca2551aab15071cb1f048ecd9b7953 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 20 Feb 2018 12:10:32 +0100 Subject: ACPI / PM: Do not reconfigure GPEs for suspend-to-idle It is reported that commit 235d81a630ca (ACPI / PM: Clean up device wakeup enable/disable code) broke wakeup from suspend-to-idle on some platforms. That is due to the acpi_enable_all_wakeup_gpes() in acpi_s2idle_prepare() which needs acpi_enable_wakeup_devices() to be called before it as the latter sets up the GPE masks used by the former and commit 235d81a630ca removed acpi_enable_wakeup_devices() invocation from the suspend-to-idle path. However, acpi_enable_wakeup_devices() does more than just setting the GPE masks and the remaining part of it is not necessary for suspend-to-idle. Moreover, non-wakeup GPEs are disabled on suspend- to-idle entry to avoid spurious wakeups, but that should not be strictly necessary any more after commit 33e4f80ee69b (ACPI / PM: Ignore spurious SCI wakeups from suspend-to-idle) which prevents spurious GPE wakeups from resuming the system. The only consequence of leaving non-wakeup GPEs enabled may be more interrupt-related activity while suspended, which is not ideal (more energy is used if that happens), but it is not critical too. For this reason, drop the GPE reconfiguration from the suspend-to-idle path entirely. This change also allows Dells XPS13 9360 blacklisted by commit 71630b7a832f (ACPI / PM: Blacklist Low Power S0 Idle _DSM for Dell XPS13 9360) to use the power button for waking up from suspend- to-idle and it helps at least one other older Dell system (the wakeup button GPE on that one is not listed in _PRW for any devices, so it is not regarded as a wakeup one and gets disabled on suspend-to-idle entry today). Fixes: 235d81a630ca (ACPI / PM: Clean up device wakeup enable/disable code) Reported-by: Du Wenkai Tested-by: Du Wenkai Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sleep.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 46cde0912762..c53119740a3c 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -953,15 +953,8 @@ static int acpi_s2idle_prepare(void) if (lps0_device_handle) { acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_OFF); acpi_sleep_run_lps0_dsm(ACPI_LPS0_ENTRY); - } else { - /* - * The configuration of GPEs is changed here to avoid spurious - * wakeups, but that should not be necessary if this is a - * "low-power S0" platform and the low-power S0 _DSM is present. - */ - acpi_enable_all_wakeup_gpes(); - acpi_os_wait_events_complete(); } + if (acpi_sci_irq_valid()) enable_irq_wake(acpi_sci_irq); @@ -1007,8 +1000,6 @@ static void acpi_s2idle_restore(void) if (lps0_device_handle) { acpi_sleep_run_lps0_dsm(ACPI_LPS0_EXIT); acpi_sleep_run_lps0_dsm(ACPI_LPS0_SCREEN_ON); - } else { - acpi_enable_all_runtime_gpes(); } } -- cgit v1.2.3-71-gd317 From dbdd0f58fd2cdde5cf945c9da67a2d52d32ba550 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 21 Feb 2018 13:24:16 +0100 Subject: PCMCIA / PM: Avoid noirq suspend aborts during suspend-to-idle There is a problem with PCMCIA system resume callbacks with respect to suspend-to-idle in which the ->suspend_noirq() callback may be invoked after the ->resume_noirq() one without resuming the system entirely in some cases. This doesn't work for PCMCIA because of the lack of symmetry between its system suspend and system resume "noirq" callbacks. The system resume handling in PCMCIA is split between socket_early_resume() and socket_late_resume() which are called in different phases of system resume and both need to run for socket_suspend() (invoked by the system suspend "noirq" callback) to work. Specifically, socket_suspend() returns an error when called after socket_early_resume() without socket_late_resume(), so if the suspend-to-idle core detects a spurious wakeup event and attempts to put the system back to sleep, that is aborted by the error coming from socket_suspend(). Avoid that by using a new socket state flag, SOCKET_IN_RESUME, to indicate that socket_early_resume() has already run for the socket in which case socket_suspend() will do minimum handling and return 0. This change has been tested on my venerable Toshiba Portege R500 (which is where the problem has been discovered in the first place), but admittedly I have no PCMCIA cards to test along with the socket itself. Fixes: 33e4f80ee69b (ACPI / PM: Ignore spurious SCI wakeups from suspend-to-idle) Signed-off-by: Rafael J. Wysocki [linux@dominikbrodowski.net: follow same codepaths for both suspend variants; call ->suspend()] Signed-off-by: Dominik Brodowski --- drivers/pcmcia/cs.c | 10 +++++++--- drivers/pcmcia/cs_internal.h | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index c3b615c94b4b..8c8caec3a72c 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -452,17 +452,20 @@ static int socket_insert(struct pcmcia_socket *skt) static int socket_suspend(struct pcmcia_socket *skt) { - if (skt->state & SOCKET_SUSPEND) + if ((skt->state & SOCKET_SUSPEND) && !(skt->state & SOCKET_IN_RESUME)) return -EBUSY; mutex_lock(&skt->ops_mutex); - skt->suspended_state = skt->state; + /* store state on first suspend, but not after spurious wakeups */ + if (!(skt->state & SOCKET_IN_RESUME)) + skt->suspended_state = skt->state; skt->socket = dead_socket; skt->ops->set_socket(skt, &skt->socket); if (skt->ops->suspend) skt->ops->suspend(skt); skt->state |= SOCKET_SUSPEND; + skt->state &= ~SOCKET_IN_RESUME; mutex_unlock(&skt->ops_mutex); return 0; } @@ -475,6 +478,7 @@ static int socket_early_resume(struct pcmcia_socket *skt) skt->ops->set_socket(skt, &skt->socket); if (skt->state & SOCKET_PRESENT) skt->resume_status = socket_setup(skt, resume_delay); + skt->state |= SOCKET_IN_RESUME; mutex_unlock(&skt->ops_mutex); return 0; } @@ -484,7 +488,7 @@ static int socket_late_resume(struct pcmcia_socket *skt) int ret = 0; mutex_lock(&skt->ops_mutex); - skt->state &= ~SOCKET_SUSPEND; + skt->state &= ~(SOCKET_SUSPEND | SOCKET_IN_RESUME); mutex_unlock(&skt->ops_mutex); if (!(skt->state & SOCKET_PRESENT)) { diff --git a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h index 6765beadea95..03ec43802909 100644 --- a/drivers/pcmcia/cs_internal.h +++ b/drivers/pcmcia/cs_internal.h @@ -70,6 +70,7 @@ struct pccard_resource_ops { /* Flags in socket state */ #define SOCKET_PRESENT 0x0008 #define SOCKET_INUSE 0x0010 +#define SOCKET_IN_RESUME 0x0040 #define SOCKET_SUSPEND 0x0080 #define SOCKET_WIN_REQ(i) (0x0100<<(i)) #define SOCKET_CARDBUS 0x8000 -- cgit v1.2.3-71-gd317 From da997b22c40473b7db60bde6ea188d35565d10c8 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 8 Feb 2018 08:30:10 -0800 Subject: PM / wakeirq: Add wakeup name to dedicated wake irqs This makes it easy to grep :wakeup /proc/interrupts. Suggested-by: Jeffy Chen Signed-off-by: Tony Lindgren Reviewed-by: Andy Shevchenko Signed-off-by: Rafael J. Wysocki --- drivers/base/power/power.h | 1 + drivers/base/power/wakeirq.c | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index 21244c53e377..86e67e70b509 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h @@ -31,6 +31,7 @@ struct wake_irq { struct device *dev; unsigned int status; int irq; + const char *name; }; extern void dev_pm_arm_wake_irq(struct wake_irq *wirq); diff --git a/drivers/base/power/wakeirq.c b/drivers/base/power/wakeirq.c index 6637fc319269..b8fa5c0f2d13 100644 --- a/drivers/base/power/wakeirq.c +++ b/drivers/base/power/wakeirq.c @@ -112,6 +112,7 @@ void dev_pm_clear_wake_irq(struct device *dev) free_irq(wirq->irq, wirq); wirq->status &= ~WAKE_IRQ_DEDICATED_MASK; } + kfree(wirq->name); kfree(wirq); } EXPORT_SYMBOL_GPL(dev_pm_clear_wake_irq); @@ -184,6 +185,12 @@ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) if (!wirq) return -ENOMEM; + wirq->name = kasprintf(GFP_KERNEL, "%s:wakeup", dev_name(dev)); + if (!wirq->name) { + err = -ENOMEM; + goto err_free; + } + wirq->dev = dev; wirq->irq = irq; irq_set_status_flags(irq, IRQ_NOAUTOEN); @@ -196,9 +203,9 @@ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) * so we use a threaded irq. */ err = request_threaded_irq(irq, NULL, handle_threaded_wake_irq, - IRQF_ONESHOT, dev_name(dev), wirq); + IRQF_ONESHOT, wirq->name, wirq); if (err) - goto err_free; + goto err_free_name; err = dev_pm_attach_wake_irq(dev, irq, wirq); if (err) @@ -210,6 +217,8 @@ int dev_pm_set_dedicated_wake_irq(struct device *dev, int irq) err_free_irq: free_irq(irq, wirq); +err_free_name: + kfree(wirq->name); err_free: kfree(wirq); -- cgit v1.2.3-71-gd317 From ead18c23c263374ed098a7d955b29b4a466d4573 Mon Sep 17 00:00:00 2001 From: Lukas Wunner Date: Sat, 10 Feb 2018 19:27:12 +0100 Subject: driver core: Introduce device links reference counting If device_link_add() is invoked multiple times with the same supplier and consumer combo, it will create the link on first addition and return a pointer to the already existing link on all subsequent additions. The semantics for device_link_del() are quite different, it deletes the link unconditionally, so multiple invocations are not allowed. In other words, this snippet ... struct device *dev1, *dev2; struct device_link *link1, *link2; link1 = device_link_add(dev1, dev2, 0); link2 = device_link_add(dev1, dev2, 0); device_link_del(link1); device_link_del(link2); ... causes the following crash: WARNING: CPU: 4 PID: 2686 at drivers/base/power/runtime.c:1611 pm_runtime_drop_link+0x40/0x50 [...] list_del corruption, 0000000039b800a4->prev is LIST_POISON2 (00000000ecf79852) kernel BUG at lib/list_debug.c:50! The issue isn't as arbitrary as it may seem: Imagine a device link which is added in both the supplier's and the consumer's ->probe hook. The two drivers can't just call device_link_del() in their ->remove hook without coordination. Fix by counting multiple additions and dropping the device link only when the last addition is unwound. Signed-off-by: Lukas Wunner [ rjw: Subject ] Signed-off-by: Rafael J. Wysocki --- drivers/base/core.c | 25 +++++++++++++++++-------- include/linux/device.h | 2 ++ 2 files changed, 19 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/base/core.c b/drivers/base/core.c index 5847364f25d9..b610816eb887 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -196,8 +196,10 @@ struct device_link *device_link_add(struct device *consumer, } list_for_each_entry(link, &supplier->links.consumers, s_node) - if (link->consumer == consumer) + if (link->consumer == consumer) { + kref_get(&link->kref); goto out; + } link = kzalloc(sizeof(*link), GFP_KERNEL); if (!link) @@ -222,6 +224,7 @@ struct device_link *device_link_add(struct device *consumer, link->consumer = consumer; INIT_LIST_HEAD(&link->c_node); link->flags = flags; + kref_init(&link->kref); /* Determine the initial link state. */ if (flags & DL_FLAG_STATELESS) { @@ -292,8 +295,10 @@ static void __device_link_free_srcu(struct rcu_head *rhead) device_link_free(container_of(rhead, struct device_link, rcu_head)); } -static void __device_link_del(struct device_link *link) +static void __device_link_del(struct kref *kref) { + struct device_link *link = container_of(kref, struct device_link, kref); + dev_info(link->consumer, "Dropping the link to %s\n", dev_name(link->supplier)); @@ -305,8 +310,10 @@ static void __device_link_del(struct device_link *link) call_srcu(&device_links_srcu, &link->rcu_head, __device_link_free_srcu); } #else /* !CONFIG_SRCU */ -static void __device_link_del(struct device_link *link) +static void __device_link_del(struct kref *kref) { + struct device_link *link = container_of(kref, struct device_link, kref); + dev_info(link->consumer, "Dropping the link to %s\n", dev_name(link->supplier)); @@ -324,13 +331,15 @@ static void __device_link_del(struct device_link *link) * @link: Device link to delete. * * The caller must ensure proper synchronization of this function with runtime - * PM. + * PM. If the link was added multiple times, it needs to be deleted as often. + * Care is required for hotplugged devices: Their links are purged on removal + * and calling device_link_del() is then no longer allowed. */ void device_link_del(struct device_link *link) { device_links_write_lock(); device_pm_lock(); - __device_link_del(link); + kref_put(&link->kref, __device_link_del); device_pm_unlock(); device_links_write_unlock(); } @@ -444,7 +453,7 @@ static void __device_links_no_driver(struct device *dev) continue; if (link->flags & DL_FLAG_AUTOREMOVE) - __device_link_del(link); + kref_put(&link->kref, __device_link_del); else if (link->status != DL_STATE_SUPPLIER_UNBIND) WRITE_ONCE(link->status, DL_STATE_AVAILABLE); } @@ -597,13 +606,13 @@ static void device_links_purge(struct device *dev) list_for_each_entry_safe_reverse(link, ln, &dev->links.suppliers, c_node) { WARN_ON(link->status == DL_STATE_ACTIVE); - __device_link_del(link); + __device_link_del(&link->kref); } list_for_each_entry_safe_reverse(link, ln, &dev->links.consumers, s_node) { WARN_ON(link->status != DL_STATE_DORMANT && link->status != DL_STATE_NONE); - __device_link_del(link); + __device_link_del(&link->kref); } device_links_write_unlock(); diff --git a/include/linux/device.h b/include/linux/device.h index b093405ed525..abf952c82c6d 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -769,6 +769,7 @@ enum device_link_state { * @status: The state of the link (with respect to the presence of drivers). * @flags: Link flags. * @rpm_active: Whether or not the consumer device is runtime-PM-active. + * @kref: Count repeated addition of the same link. * @rcu_head: An RCU head to use for deferred execution of SRCU callbacks. */ struct device_link { @@ -779,6 +780,7 @@ struct device_link { enum device_link_state status; u32 flags; bool rpm_active; + struct kref kref; #ifdef CONFIG_SRCU struct rcu_head rcu_head; #endif -- cgit v1.2.3-71-gd317 From cb8bd2ff1528a3f0234ec04b667bf91a3be7ac30 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 22 Feb 2018 11:26:31 +0530 Subject: cpufreq: mediatek: Convert pr_warn() to pr_debug() With multi-platform build images, this shows a message on non mediatek platforms, which is unnecessary. Convert pr_warn() to pr_debug() here. Signed-off-by: Viresh Kumar Acked-by: Sean Wang Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/mediatek-cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index 8c04dddd3c28..84d658d57029 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -578,7 +578,7 @@ static int __init mtk_cpufreq_driver_init(void) match = of_match_node(mtk_cpufreq_machines, np); of_node_put(np); if (!match) { - pr_warn("Machine is not compatible with mtk-cpufreq\n"); + pr_debug("Machine is not compatible with mtk-cpufreq\n"); return -ENODEV; } -- cgit v1.2.3-71-gd317 From b24b6478e65f140610ab1ffaadc7bc6bf0be8aad Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 22 Feb 2018 11:29:43 +0530 Subject: cpufreq: Reorder cpufreq_online() error code path Ideally the de-allocation of resources should happen in the exact opposite order in which they were allocated. It helps maintain the code in long term, even if nothing really breaks with incorrect ordering. That wasn't followed in cpufreq_online() and it has some inconsistencies. For example, the symlinks were created from within the locked region while they are removed only after putting the locks. Also ->exit() should have been called only after the symlinks are removed and the lock is dropped, as that was the case when ->init() was first called. Signed-off-by: Viresh Kumar [ rjw: Subject ] Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index de33ebf008ad..8814c572e263 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1327,14 +1327,14 @@ static int cpufreq_online(unsigned int cpu) return 0; out_exit_policy: + for_each_cpu(j, policy->real_cpus) + remove_cpu_dev_symlink(policy, get_cpu_device(j)); + up_write(&policy->rwsem); if (cpufreq_driver->exit) cpufreq_driver->exit(policy); - for_each_cpu(j, policy->real_cpus) - remove_cpu_dev_symlink(policy, get_cpu_device(j)); - out_free_policy: cpufreq_policy_free(policy); return ret; -- cgit v1.2.3-71-gd317 From d417e0691ac00d35c4e6b90fc3fc85631a7865ad Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 22 Feb 2018 11:29:44 +0530 Subject: cpufreq: Validate frequency table in the core By design, cpufreq drivers are responsible for calling cpufreq_frequency_table_cpuinfo() from their ->init() callbacks to validate the frequency table. However, if a cpufreq driver is buggy and fails to do so properly, it lead to unexpected behavior of the driver or the cpufreq core at a later point in time. It would be better if the core could validate the frequency table during driver initialization. To that end, introduce cpufreq_table_validate_and_sort() and make the cpufreq core call it right after invoking the ->init() callback of the driver and destroy the cpufreq policy if the table is invalid. For the time being the validation of the table happens twice, once from the driver and then from the core. The individual drivers will be updated separately to drop table validation if they don't need it for other reasons. The frequency table is marked "sorted" or "unsorted" by the new helper now instead of in cpufreq_table_validate_and_show(), as it should only be done after validating the table (which the drivers won't do going forward). Signed-off-by: Viresh Kumar [ rjw: Subject/changelog ] Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 13 +++++++++---- drivers/cpufreq/freq_table.c | 16 +++++++++++++++- include/linux/cpufreq.h | 1 + 3 files changed, 25 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 8814c572e263..239063fb6afc 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -1219,6 +1219,10 @@ static int cpufreq_online(unsigned int cpu) goto out_free_policy; } + ret = cpufreq_table_validate_and_sort(policy); + if (ret) + goto out_exit_policy; + down_write(&policy->rwsem); if (new_policy) { @@ -1249,7 +1253,7 @@ static int cpufreq_online(unsigned int cpu) policy->cur = cpufreq_driver->get(policy->cpu); if (!policy->cur) { pr_err("%s: ->get() failed\n", __func__); - goto out_exit_policy; + goto out_destroy_policy; } } @@ -1296,7 +1300,7 @@ static int cpufreq_online(unsigned int cpu) if (new_policy) { ret = cpufreq_add_dev_interface(policy); if (ret) - goto out_exit_policy; + goto out_destroy_policy; cpufreq_stats_create_table(policy); @@ -1311,7 +1315,7 @@ static int cpufreq_online(unsigned int cpu) __func__, cpu, ret); /* cpufreq_policy_free() will notify based on this */ new_policy = false; - goto out_exit_policy; + goto out_destroy_policy; } up_write(&policy->rwsem); @@ -1326,12 +1330,13 @@ static int cpufreq_online(unsigned int cpu) return 0; -out_exit_policy: +out_destroy_policy: for_each_cpu(j, policy->real_cpus) remove_cpu_dev_symlink(policy, get_cpu_device(j)); up_write(&policy->rwsem); +out_exit_policy: if (cpufreq_driver->exit) cpufreq_driver->exit(policy); diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c index 6d007f824ca7..10e119ae66dd 100644 --- a/drivers/cpufreq/freq_table.c +++ b/drivers/cpufreq/freq_table.c @@ -362,10 +362,24 @@ int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, return ret; policy->freq_table = table; - return set_freq_table_sorted(policy); + return 0; } EXPORT_SYMBOL_GPL(cpufreq_table_validate_and_show); +int cpufreq_table_validate_and_sort(struct cpufreq_policy *policy) +{ + int ret; + + if (!policy->freq_table) + return 0; + + ret = cpufreq_frequency_table_cpuinfo(policy, policy->freq_table); + if (ret) + return ret; + + return set_freq_table_sorted(policy); +} + MODULE_AUTHOR("Dominik Brodowski "); MODULE_DESCRIPTION("CPUfreq frequency table helpers"); MODULE_LICENSE("GPL"); diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 21e8d248d956..1fe49724da9e 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -962,6 +962,7 @@ extern struct freq_attr cpufreq_freq_attr_scaling_boost_freqs; extern struct freq_attr *cpufreq_generic_attr[]; int cpufreq_table_validate_and_show(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table); +int cpufreq_table_validate_and_sort(struct cpufreq_policy *policy); unsigned int cpufreq_generic_get(unsigned int cpu); int cpufreq_generic_init(struct cpufreq_policy *policy, -- cgit v1.2.3-71-gd317 From 3e3b507ef60cb53c209ef8f5d0fef48ddff1b3f4 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Thu, 22 Feb 2018 15:24:57 +0530 Subject: cpufreq: tegra186: Break after initialization is done for policy->cpu There are two clusters (2 + 4 CPUs) on this platform and a separate cpufreq policy is available for each of the CPUs. The loop in tegra186_cpufreq_init() tries to find the structure for the right CPU and finish initialization. But it is missing a `break` statement at the end, which forces it to restart the loop even when the CPU already matched and initialization is done. Fix that by adding the missing `break` statement. Signed-off-by: Viresh Kumar Reviewed-by: Mikko Perttunen Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/tegra186-cpufreq.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/cpufreq/tegra186-cpufreq.c b/drivers/cpufreq/tegra186-cpufreq.c index fe7875311d62..771df649ceb9 100644 --- a/drivers/cpufreq/tegra186-cpufreq.c +++ b/drivers/cpufreq/tegra186-cpufreq.c @@ -79,6 +79,7 @@ static int tegra186_cpufreq_init(struct cpufreq_policy *policy) policy->driver_data = data->regs + info->offset + EDVD_CORE_VOLT_FREQ(core); cpufreq_table_validate_and_show(policy, cluster->table); + break; } policy->cpuinfo.transition_latency = 300 * 1000; -- cgit v1.2.3-71-gd317 From d430fb998451eb99f5592c003598e8324976f0cd Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 15 Feb 2018 17:28:40 +0100 Subject: cpufreq: s3c24xx: Drop memory allocation error messages from two functions Omit an extra message for a memory allocation failure in these functions. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/s3c24xx-cpufreq.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c index 7b596fa38ad2..024afd0b9458 100644 --- a/drivers/cpufreq/s3c24xx-cpufreq.c +++ b/drivers/cpufreq/s3c24xx-cpufreq.c @@ -473,10 +473,8 @@ int __init s3c_cpufreq_setboard(struct s3c_cpufreq_board *board) * initdata. */ ours = kzalloc(sizeof(*ours), GFP_KERNEL); - if (ours == NULL) { - pr_err("%s: no memory\n", __func__); + if (!ours) return -ENOMEM; - } *ours = *board; cpu_cur.board = ours; @@ -562,10 +560,8 @@ static int s3c_cpufreq_build_freq(void) size++; ftab = kzalloc(sizeof(*ftab) * size, GFP_KERNEL); - if (!ftab) { - pr_err("%s: no memory for tables\n", __func__); + if (!ftab) return -ENOMEM; - } ftab_size = size; -- cgit v1.2.3-71-gd317 From d6b96e4706df9791f7c4915a567c498b0aafb659 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 15 Feb 2018 18:00:37 +0100 Subject: cpufreq: qoriq: Drop memory allocation error messages from qoriq_cpufreq_cpu_init() Omit extra messages for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/qoriq-cpufreq.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/qoriq-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c index 0562761a3dec..ee3e3656485b 100644 --- a/drivers/cpufreq/qoriq-cpufreq.c +++ b/drivers/cpufreq/qoriq-cpufreq.c @@ -192,16 +192,12 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy) count = clk_hw_get_num_parents(hwclk); data->pclk = kcalloc(count, sizeof(struct clk *), GFP_KERNEL); - if (!data->pclk) { - pr_err("%s: no memory\n", __func__); + if (!data->pclk) goto err_nomem2; - } table = kcalloc(count + 1, sizeof(*table), GFP_KERNEL); - if (!table) { - pr_err("%s: no memory\n", __func__); + if (!table) goto err_pclk; - } for (i = 0; i < count; i++) { clk = clk_hw_get_parent_by_index(hwclk, i)->clk; -- cgit v1.2.3-71-gd317 From 7f3a1d66df044709238ec674138dfff23b4712ff Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 15 Feb 2018 20:00:23 +0100 Subject: cpufreq: powernow-k8: Drop memory allocation error messages from three functions Omit an extra message for a memory allocation failure in these functions. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/powernow-k8.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index b01e31db5f83..460bf22a8a2b 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@ -591,10 +591,8 @@ static int fill_powernow_table(struct powernow_k8_data *data, powernow_table = kzalloc((sizeof(*powernow_table) * (data->numps + 1)), GFP_KERNEL); - if (!powernow_table) { - pr_err("powernow_table memory alloc failure\n"); + if (!powernow_table) return -ENOMEM; - } for (j = 0; j < data->numps; j++) { int freq; @@ -760,10 +758,8 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) /* fill in data->powernow_table */ powernow_table = kzalloc((sizeof(*powernow_table) * (data->acpi_data.state_count + 1)), GFP_KERNEL); - if (!powernow_table) { - pr_debug("powernow_table memory alloc failure\n"); + if (!powernow_table) goto err_out; - } /* fill in data */ data->numps = data->acpi_data.state_count; @@ -1042,10 +1038,8 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) return -ENODEV; data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) { - pr_err("unable to alloc powernow_k8_data\n"); + if (!data) return -ENOMEM; - } data->cpu = pol->cpu; -- cgit v1.2.3-71-gd317 From 0f555518eaee4f3855ffa9e8237b938af186df55 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 15 Feb 2018 20:14:32 +0100 Subject: cpufreq: powernow-k8: Drop unnecessary return statements from two functions The script "checkpatch.pl" pointed information out like the following. WARNING: void function return statements are not generally useful Thus remove such a statement in the affected functions. Signed-off-by: Markus Elfring Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/powernow-k8.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index 460bf22a8a2b..782a8c2a359d 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@ -122,14 +122,12 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data) static void count_off_irt(struct powernow_k8_data *data) { udelay((1 << data->irt) * 10); - return; } /* the voltage stabilization time */ static void count_off_vst(struct powernow_k8_data *data) { udelay(data->vstable * VST_UNITS_20US); - return; } /* need to init the control msr to a safe value (for each cpu) */ -- cgit v1.2.3-71-gd317 From bda4d21b6e5d423e3f21a6c49d3d5283592e3b65 Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Thu, 15 Feb 2018 16:40:38 +0100 Subject: ARM: cpuidle: Drop memory allocation error message from arm_idle_init_cpu() Omit an extra message for a memory allocation failure in this function. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring Acked-by: Daniel Lezcano Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/cpuidle-arm.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c index ddee1b601b89..e07bc7ace774 100644 --- a/drivers/cpuidle/cpuidle-arm.c +++ b/drivers/cpuidle/cpuidle-arm.c @@ -129,7 +129,6 @@ static int __init arm_idle_init_cpu(int cpu) dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (!dev) { - pr_err("Failed to allocate cpuidle device\n"); ret = -ENOMEM; goto out_unregister_drv; } -- cgit v1.2.3-71-gd317 From fa54150aad84dbbd92b26ce47e6b2cf7c686dca0 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 13 Mar 2018 10:47:36 +0100 Subject: ACPI / PM: Reduce LPI constraints logging noise If a device referred to by ACPI LPI constrains (coming from function 1 of the Low Power S0 Idle _DSM interface) is not power-manageable via ACPI (no _PS0 method and no power resources), the code generating diagnostic information for the LPI constraints will print a message about that to the kernel log on every system suspend-resume cycle (possibly for multiple times). That is not very useful and noisy, so modify that code to disregard the LPI list entries corresponding to the devices that are not power- manageable after printing that information for them once. Signed-off-by: Rafael J. Wysocki Reviewed-by: Srinivas Pandruvada --- drivers/acpi/sleep.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index c53119740a3c..b5d27a4213ab 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -851,23 +851,25 @@ static void lpi_check_constraints(void) int i; for (i = 0; i < lpi_constraints_table_size; ++i) { + acpi_handle handle = lpi_constraints_table[i].handle; struct acpi_device *adev; - if (acpi_bus_get_device(lpi_constraints_table[i].handle, &adev)) + if (!handle || acpi_bus_get_device(handle, &adev)) continue; - acpi_handle_debug(adev->handle, + acpi_handle_debug(handle, "LPI: required min power state:%s current power state:%s\n", acpi_power_state_string(lpi_constraints_table[i].min_dstate), acpi_power_state_string(adev->power.state)); if (!adev->flags.power_manageable) { - acpi_handle_info(adev->handle, "LPI: Device not power manageble\n"); + acpi_handle_info(handle, "LPI: Device not power manageable\n"); + lpi_constraints_table[i].handle = NULL; continue; } if (adev->power.state < lpi_constraints_table[i].min_dstate) - acpi_handle_info(adev->handle, + acpi_handle_info(handle, "LPI: Constraint not met; min power state:%s current power state:%s\n", acpi_power_state_string(lpi_constraints_table[i].min_dstate), acpi_power_state_string(adev->power.state)); -- cgit v1.2.3-71-gd317 From ef74b5bf22704bb1e7b67396704bbb41e1df0e39 Mon Sep 17 00:00:00 2001 From: Joe Konno Date: Fri, 2 Mar 2018 10:32:51 -0800 Subject: powercap: RAPL: Add support for Cannon Lake RAPL MSRs and handling for Cannon Lake are similar to Sky Lake and Kaby Lake. Signed-off-by: Joe Konno Signed-off-by: Rafael J. Wysocki --- drivers/powercap/intel_rapl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index 35636e1d8a3d..295d8dcba48c 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c @@ -1162,6 +1162,7 @@ static const struct x86_cpu_id rapl_ids[] __initconst = { RAPL_CPU(INTEL_FAM6_SKYLAKE_X, rapl_defaults_hsw_server), RAPL_CPU(INTEL_FAM6_KABYLAKE_MOBILE, rapl_defaults_core), RAPL_CPU(INTEL_FAM6_KABYLAKE_DESKTOP, rapl_defaults_core), + RAPL_CPU(INTEL_FAM6_CANNONLAKE_MOBILE, rapl_defaults_core), RAPL_CPU(INTEL_FAM6_ATOM_SILVERMONT1, rapl_defaults_byt), RAPL_CPU(INTEL_FAM6_ATOM_AIRMONT, rapl_defaults_cht), -- cgit v1.2.3-71-gd317 From bf14721c97f39514267ed844b6d62036f76c3e51 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 5 Mar 2018 09:49:32 +0530 Subject: cpufreq: powernv: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from powernv driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/powernv-cpufreq.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c index 29cdec198657..0591874856d3 100644 --- a/drivers/cpufreq/powernv-cpufreq.c +++ b/drivers/cpufreq/powernv-cpufreq.c @@ -812,7 +812,7 @@ gpstates_done: static int powernv_cpufreq_cpu_init(struct cpufreq_policy *policy) { - int base, i, ret; + int base, i; struct kernfs_node *kn; struct global_pstate_info *gpstates; @@ -848,15 +848,10 @@ static int powernv_cpufreq_cpu_init(struct cpufreq_policy *policy) gpstates->timer.expires = jiffies + msecs_to_jiffies(GPSTATE_TIMER_INTERVAL); spin_lock_init(&gpstates->gpstate_lock); - ret = cpufreq_table_validate_and_show(policy, powernv_freqs); - - if (ret < 0) { - kfree(policy->driver_data); - return ret; - } + policy->freq_table = powernv_freqs; policy->fast_switch_possible = true; - return ret; + return 0; } static int powernv_cpufreq_cpu_exit(struct cpufreq_policy *policy) -- cgit v1.2.3-71-gd317 From bf8c6184e0c3d4d5e005e085e9f96f478a267b20 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Tue, 20 Mar 2018 12:07:35 +0800 Subject: ACPI / PM: Allow deeper wakeup power states with no _SxD nor _SxW acpi_dev_pm_get_state() is used to determine the range of allowable device power states when going into S3 suspend. This is implemented by executing the _S3D and _S3W ACPI methods. Linux follows the ACPI spec behaviour in that when _S3D is implemented and _S3W is not, Linux will not go into a power state deeper than the one returned by _S3D for a wakeup-enabled device. However, this same logic is being applied to the case when neither _S3D nor _S3W are present, and the result is that this function decides that the device must stay in D0 (fully on) state. This is breaking USB wakeups on Asus V222GA and Acer XC-830. _S3D and _S3W are not present, so the USB controller is left in the D0 running state during S3, and hence it is unable to generate a PME# wake event. The ACPI spec is unclear on which power states are permissable for wakeup-enabled devices when both _S3D and _S3W are missing. However, USB wakeups work fine on these platforms under Windows, where device manager shows that they are using D3 device state for the USB controller in S3. I assume that the "max = min" clamping done by the code here is specifically written for the _S3D but no _S3W case. By making the code true to those conditions, avoiding them on these platforms, the controller will be put into D3 state and USB wakeups start working. Additionally I feel that this change makes the code more directly mirror the wording of the ACPI spec and it's associated lack of clarity. Thanks to Mathias Nyman for pointing us in the right direction. Signed-off-by: Daniel Drake Link: http://lkml.kernel.org/r/CAB4CAwf_k-WsF3zL4epm9TKAOu0h=Bv1XhXV_gY3bziOo_NPKA@mail.gmail.com https://phabricator.endlessm.com/T21410 Signed-off-by: Rafael J. Wysocki --- drivers/acpi/device_pm.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index c4d0a1c912f0..3d96e4da2d98 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -543,6 +543,7 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev, unsigned long long ret; int d_min, d_max; bool wakeup = false; + bool has_sxd = false; acpi_status status; /* @@ -581,6 +582,10 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev, else return -ENODATA; } + + if (status == AE_OK) + has_sxd = true; + d_min = ret; wakeup = device_may_wakeup(dev) && adev->wakeup.flags.valid && adev->wakeup.sleep_state >= target_state; @@ -599,7 +604,11 @@ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev, method[3] = 'W'; status = acpi_evaluate_integer(handle, method, NULL, &ret); if (status == AE_NOT_FOUND) { - if (target_state > ACPI_STATE_S0) + /* No _SxW. In this case, the ACPI spec says that we + * must not go into any power state deeper than the + * value returned from _SxD. + */ + if (has_sxd && target_state > ACPI_STATE_S0) d_max = d_min; } else if (ACPI_SUCCESS(status) && ret <= ACPI_STATE_D3_COLD) { /* Fall back to D3cold if ret is not a valid state. */ -- cgit v1.2.3-71-gd317 From 55b55abc17f238c61921360e61dde90dd9a326d1 Mon Sep 17 00:00:00 2001 From: Chunyu Hu Date: Mon, 5 Mar 2018 13:40:38 +0800 Subject: cpufreq: cppc_cpufreq: Fix cppc_cpufreq_init() failure path Kmemleak reported the below leak. When cppc_cpufreq_init went into failure path, the cpu mask is not freed. After fix, this report is gone. And to avaoid potential NULL pointer reference, check the cpu value first. unreferenced object 0xffff800fd5ea4880 (size 128): comm "swapper/0", pid 1, jiffies 4294939510 (age 668.680s) hex dump (first 32 bytes): 00 00 00 00 20 00 00 00 00 00 00 00 00 00 00 00 .... ........... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [] __kmalloc_node+0x278/0x634 [] alloc_cpumask_var_node+0x28/0x60 [] zalloc_cpumask_var+0x14/0x1c [] cppc_cpufreq_init+0xd0/0x19c [] do_one_initcall+0xec/0x15c [] kernel_init_freeable+0x1f4/0x2a4 [] kernel_init+0x18/0x10c [] ret_from_fork+0x10/0x18 [] 0xffffffffffffffff Signed-off-by: Chunyu Hu Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cppc_cpufreq.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index a1c3025f9df7..8f7b21a4d537 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -230,8 +230,13 @@ static int __init cppc_cpufreq_init(void) return ret; out: - for_each_possible_cpu(i) - kfree(all_cpu_data[i]); + for_each_possible_cpu(i) { + cpu = all_cpu_data[i]; + if (!cpu) + break; + free_cpumask_var(cpu->shared_cpu_map); + kfree(cpu); + } kfree(all_cpu_data); return -ENODEV; -- cgit v1.2.3-71-gd317 From 3478b24c5e6fd4f27616674ea94dba8e28fbc7f7 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 13 Mar 2018 12:45:40 +0100 Subject: cpufreq: scpi: Add thermal dependency A built-in scpi cpufreq driver cannot link against a modular thermal framework: drivers/cpufreq/scpi-cpufreq.o: In function `scpi_cpufreq_ready': scpi-cpufreq.c:(.text+0x4c): undefined reference to `of_cpufreq_cooling_register' drivers/cpufreq/scpi-cpufreq.o: In function `scpi_cpufreq_exit': scpi-cpufreq.c:(.text+0x9c): undefined reference to `cpufreq_cooling_unregister' This adds a Kconfig dependency that makes sure this configuration is not possible, while allowing all configurations that can work. Note that disabling CPU_THERMAL means we don't care about the THERMAL dependency. Signed-off-by: Arnd Bergmann Acked-by: Sudeep Holla Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/Kconfig.arm | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index fb586e09682d..833b5f41f596 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -45,6 +45,7 @@ config ARM_DT_BL_CPUFREQ config ARM_SCPI_CPUFREQ tristate "SCPI based CPUfreq driver" depends on ARM_SCPI_PROTOCOL && COMMON_CLK_SCPI + depends on !CPU_THERMAL || THERMAL help This adds the CPUfreq driver support for ARM platforms using SCPI protocol for CPU power management. -- cgit v1.2.3-71-gd317 From 8d768cdcf0f517c643690aeca8101a928a6c36c8 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:38:44 +0530 Subject: cpufreq: imx6q: Find max freq from frequency table itself This is a preparatory commit to make policy->suspend_freq independent of validation of the cpufreq table, as a later commit would update cpufreq_generic_init() to not validate the cpufreq table any longer. The driver already assumes the order in which the frequency table is sorted and we can get the max frequency easily. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/imx6q-cpufreq.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c index ff67859948b3..83cf631fc9bc 100644 --- a/drivers/cpufreq/imx6q-cpufreq.c +++ b/drivers/cpufreq/imx6q-cpufreq.c @@ -52,6 +52,7 @@ static struct clk_bulk_data clks[] = { static struct device *cpu_dev; static bool free_opp; static struct cpufreq_frequency_table *freq_table; +static unsigned int max_freq; static unsigned int transition_latency; static u32 *imx6_soc_volt; @@ -196,7 +197,7 @@ static int imx6q_cpufreq_init(struct cpufreq_policy *policy) policy->clk = clks[ARM].clk; ret = cpufreq_generic_init(policy, freq_table, transition_latency); - policy->suspend_freq = policy->max; + policy->suspend_freq = max_freq; return ret; } @@ -437,12 +438,12 @@ soc_opp_out: * freq_table initialised from OPP is therefore sorted in the * same order. */ + max_freq = freq_table[--num].frequency; opp = dev_pm_opp_find_freq_exact(cpu_dev, freq_table[0].frequency * 1000, true); min_volt = dev_pm_opp_get_voltage(opp); dev_pm_opp_put(opp); - opp = dev_pm_opp_find_freq_exact(cpu_dev, - freq_table[--num].frequency * 1000, true); + opp = dev_pm_opp_find_freq_exact(cpu_dev, max_freq * 1000, true); max_volt = dev_pm_opp_get_voltage(opp); dev_pm_opp_put(opp); -- cgit v1.2.3-71-gd317 From 92c99d159c38256e221ed8b50fd48953746a90e0 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:38:45 +0530 Subject: cpufreq: Don't validate cpufreq table from cpufreq_generic_init() The cpufreq table is already validated by the cpufreq core and none of the users of cpufreq_generic_init() have any dependency on it to validate the table as well. Don't validate the cpufreq table anymore from cpufreq_generic_init(). Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 239063fb6afc..075d18f6ba7a 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -178,14 +178,7 @@ int cpufreq_generic_init(struct cpufreq_policy *policy, struct cpufreq_frequency_table *table, unsigned int transition_latency) { - int ret; - - ret = cpufreq_table_validate_and_show(policy, table); - if (ret) { - pr_err("%s: invalid frequency table: %d\n", __func__, ret); - return ret; - } - + policy->freq_table = table; policy->cpuinfo.transition_latency = transition_latency; /* -- cgit v1.2.3-71-gd317 From 1a186d9e11fc53746e8d1400e2ff6037dc187a37 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:38:46 +0530 Subject: cpufreq: ACPI: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table in the acpi-cpufreq driver. The driver needs to crosscheck if the max frequency corresponds to the P-state 0 or not and the same is done from the ->ready() callback now. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/acpi-cpufreq.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index d0c34df0529c..9449657d72f0 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c @@ -794,15 +794,9 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) valid_states++; } freq_table[valid_states].frequency = CPUFREQ_TABLE_END; + policy->freq_table = freq_table; perf->state = 0; - result = cpufreq_table_validate_and_show(policy, freq_table); - if (result) - goto err_freqfree; - - if (perf->states[0].core_frequency * 1000 != policy->cpuinfo.max_freq) - pr_warn(FW_WARN "P-state 0 is not max freq\n"); - switch (perf->control_register.space_id) { case ACPI_ADR_SPACE_SYSTEM_IO: /* @@ -842,8 +836,6 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy) return result; -err_freqfree: - kfree(freq_table); err_unreg: acpi_processor_unregister_performance(cpu); err_free_mask: @@ -871,6 +863,15 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy) return 0; } +static void acpi_cpufreq_cpu_ready(struct cpufreq_policy *policy) +{ + struct acpi_processor_performance *perf = per_cpu_ptr(acpi_perf_data, + policy->cpu); + + if (perf->states[0].core_frequency * 1000 != policy->cpuinfo.max_freq) + pr_warn(FW_WARN "P-state 0 is not max freq\n"); +} + static int acpi_cpufreq_resume(struct cpufreq_policy *policy) { struct acpi_cpufreq_data *data = policy->driver_data; @@ -898,6 +899,7 @@ static struct cpufreq_driver acpi_cpufreq_driver = { .bios_limit = acpi_processor_get_bios_limit, .init = acpi_cpufreq_cpu_init, .exit = acpi_cpufreq_cpu_exit, + .ready = acpi_cpufreq_cpu_ready, .resume = acpi_cpufreq_resume, .name = "acpi-cpufreq", .attr = acpi_cpufreq_attr, -- cgit v1.2.3-71-gd317 From 3c1f5a462e799dde929411412e9f71d4e09efd16 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:38:47 +0530 Subject: cpufreq: arm_big_little: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from arm_big_little driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/arm_big_little.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index c56b57dcfda5..1d7ef5fc1977 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -483,14 +483,7 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy) if (ret) return ret; - ret = cpufreq_table_validate_and_show(policy, freq_table[cur_cluster]); - if (ret) { - dev_err(cpu_dev, "CPU %d, cluster: %d invalid freq table\n", - policy->cpu, cur_cluster); - put_cluster_clk_and_freq_table(cpu_dev, policy->cpus); - return ret; - } - + policy->freq_table = freq_table[cur_cluster]; policy->cpuinfo.transition_latency = arm_bL_ops->get_transition_latency(cpu_dev); -- cgit v1.2.3-71-gd317 From 5d8d4f9215ca830f76c6653998e1167198f64be0 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:38:49 +0530 Subject: cpufreq: brcmstb: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from brcmstb driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/brcmstb-avs-cpufreq.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/brcmstb-avs-cpufreq.c b/drivers/cpufreq/brcmstb-avs-cpufreq.c index 7281a2c19c36..6cdac1aaf23c 100644 --- a/drivers/cpufreq/brcmstb-avs-cpufreq.c +++ b/drivers/cpufreq/brcmstb-avs-cpufreq.c @@ -902,11 +902,7 @@ static int brcm_avs_cpufreq_init(struct cpufreq_policy *policy) return ret; } - ret = cpufreq_table_validate_and_show(policy, freq_table); - if (ret) { - dev_err(dev, "invalid frequency table: %d\n", ret); - return ret; - } + policy->freq_table = freq_table; /* All cores share the same clock and thus the same policy. */ cpumask_setall(policy->cpus); -- cgit v1.2.3-71-gd317 From 29aa18a762b8fcf6cbe3310b1f675849c171036b Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:38:50 +0530 Subject: cpufreq: cpufreq-dt: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from cpufreq-dt driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq-dt.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index de3d104c25d7..190ea0dccb79 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -258,16 +258,10 @@ static int cpufreq_init(struct cpufreq_policy *policy) priv->cpu_dev = cpu_dev; policy->driver_data = priv; policy->clk = cpu_clk; + policy->freq_table = freq_table; policy->suspend_freq = dev_pm_opp_get_suspend_opp_freq(cpu_dev) / 1000; - ret = cpufreq_table_validate_and_show(policy, freq_table); - if (ret) { - dev_err(cpu_dev, "%s: invalid frequency table: %d\n", __func__, - ret); - goto out_free_cpufreq_table; - } - /* Support turbo/boost mode */ if (policy_has_boost_freq(policy)) { /* This gets disabled by core on driver unregister */ -- cgit v1.2.3-71-gd317 From 0d105394450796d61d78fa04cc4445d201a3b976 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:38:51 +0530 Subject: cpufreq: e_powersaver: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from e_powersaver driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/e_powersaver.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c index cdf097b29862..60bea302abbe 100644 --- a/drivers/cpufreq/e_powersaver.c +++ b/drivers/cpufreq/e_powersaver.c @@ -184,7 +184,6 @@ static int eps_cpu_init(struct cpufreq_policy *policy) struct cpuinfo_x86 *c = &cpu_data(0); struct cpufreq_frequency_table *f_table; int k, step, voltage; - int ret; int states; #if IS_ENABLED(CONFIG_ACPI_PROCESSOR) unsigned int limit; @@ -359,12 +358,7 @@ static int eps_cpu_init(struct cpufreq_policy *policy) } policy->cpuinfo.transition_latency = 140000; /* 844mV -> 700mV in ns */ - - ret = cpufreq_table_validate_and_show(policy, ¢aur->freq_table[0]); - if (ret) { - kfree(centaur); - return ret; - } + policy->freq_table = ¢aur->freq_table[0]; return 0; } -- cgit v1.2.3-71-gd317 From c3e3cc8aa3a62a492ef7cff103a8f5cd6ff8bcef Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:38:52 +0530 Subject: cpufreq: elanfreq: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from elanfreq driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/elanfreq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c index 45e2ca62515e..03419f064752 100644 --- a/drivers/cpufreq/elanfreq.c +++ b/drivers/cpufreq/elanfreq.c @@ -165,7 +165,8 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy) if (pos->frequency > max_freq) pos->frequency = CPUFREQ_ENTRY_INVALID; - return cpufreq_table_validate_and_show(policy, elanfreq_table); + policy->freq_table = elanfreq_table; + return 0; } -- cgit v1.2.3-71-gd317 From b6663622a39742333c0bc3bf7d99df4ba8865f34 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:38:53 +0530 Subject: cpufreq: ia64-acpi: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from ia64-acpi driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/ia64-acpi-cpufreq.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/ia64-acpi-cpufreq.c b/drivers/cpufreq/ia64-acpi-cpufreq.c index a757c0a1e7b5..7974a2fdb760 100644 --- a/drivers/cpufreq/ia64-acpi-cpufreq.c +++ b/drivers/cpufreq/ia64-acpi-cpufreq.c @@ -270,10 +270,7 @@ acpi_cpufreq_cpu_init ( } } - result = cpufreq_table_validate_and_show(policy, freq_table); - if (result) { - goto err_freqfree; - } + policy->freq_table = freq_table; /* notify BIOS that we exist */ acpi_processor_notify_smm(THIS_MODULE); @@ -296,8 +293,6 @@ acpi_cpufreq_cpu_init ( return (result); - err_freqfree: - kfree(freq_table); err_unreg: acpi_processor_unregister_performance(cpu); err_free: -- cgit v1.2.3-71-gd317 From 2c65616b98ad357ffe867931916c1323cc985ed4 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:38:54 +0530 Subject: cpufreq: longhaul: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from longhaul driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/longhaul.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index f730b6528c18..61a4c5b08219 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c @@ -895,8 +895,9 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy) longhaul_setup_voltagescaling(); policy->transition_delay_us = 200000; /* usec */ + policy->freq_table = longhaul_table; - return cpufreq_table_validate_and_show(policy, longhaul_table); + return 0; } static struct cpufreq_driver longhaul_driver = { -- cgit v1.2.3-71-gd317 From b563afbaa85a05d049ad06f03bec65e71464a1b7 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:38:55 +0530 Subject: cpufreq: mediatek: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from mediatek driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/mediatek-cpufreq.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index 84d658d57029..eb8920d39818 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -460,21 +460,12 @@ static int mtk_cpufreq_init(struct cpufreq_policy *policy) return ret; } - ret = cpufreq_table_validate_and_show(policy, freq_table); - if (ret) { - pr_err("%s: invalid frequency table: %d\n", __func__, ret); - goto out_free_cpufreq_table; - } - cpumask_copy(policy->cpus, &info->cpus); + policy->freq_table = freq_table; policy->driver_data = info; policy->clk = info->cpu_clk; return 0; - -out_free_cpufreq_table: - dev_pm_opp_free_cpufreq_table(info->cpu_dev, &freq_table); - return ret; } static int mtk_cpufreq_exit(struct cpufreq_policy *policy) -- cgit v1.2.3-71-gd317 From b01b531f67a255df0d2c90fcda7c509ed55186a6 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:38:56 +0530 Subject: cpufreq: p4-clockmod: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from p4-clockmod driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/p4-clockmod.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c index a25741b1281b..911206243050 100644 --- a/drivers/cpufreq/p4-clockmod.c +++ b/drivers/cpufreq/p4-clockmod.c @@ -202,8 +202,9 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy) /* the transition latency is set to be 1 higher than the maximum * transition latency of the ondemand governor */ policy->cpuinfo.transition_latency = 10000001; + policy->freq_table = &p4clockmod_table[0]; - return cpufreq_table_validate_and_show(policy, &p4clockmod_table[0]); + return 0; } -- cgit v1.2.3-71-gd317 From e2376d1fa075238a93a4ca188e7cee0bea924975 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:38:57 +0530 Subject: cpufreq: powernow: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from powernow driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/powernow-k6.c | 3 ++- drivers/cpufreq/powernow-k7.c | 3 ++- drivers/cpufreq/powernow-k8.c | 10 +--------- 3 files changed, 5 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c index dedd2568e852..8a8ea68611a8 100644 --- a/drivers/cpufreq/powernow-k6.c +++ b/drivers/cpufreq/powernow-k6.c @@ -214,8 +214,9 @@ have_busfreq: /* cpuinfo and default policy values */ policy->cpuinfo.transition_latency = 500000; + policy->freq_table = clock_ratio; - return cpufreq_table_validate_and_show(policy, clock_ratio); + return 0; } diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c index 302e9ce793a0..d6cb052b0a75 100644 --- a/drivers/cpufreq/powernow-k7.c +++ b/drivers/cpufreq/powernow-k7.c @@ -639,8 +639,9 @@ static int powernow_cpu_init(struct cpufreq_policy *policy) policy->cpuinfo.transition_latency = cpufreq_scale(2000000UL, fsb, latency); + policy->freq_table = powernow_table; - return cpufreq_table_validate_and_show(policy, powernow_table); + return 0; } static int powernow_cpu_exit(struct cpufreq_policy *policy) diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index 782a8c2a359d..fb77b39a4ce3 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@ -1076,15 +1076,7 @@ static int powernowk8_cpu_init(struct cpufreq_policy *pol) cpumask_copy(pol->cpus, topology_core_cpumask(pol->cpu)); data->available_cores = pol->cpus; - - /* min/max the cpu is capable of */ - if (cpufreq_table_validate_and_show(pol, data->powernow_table)) { - pr_err(FW_BUG "invalid powernow_table\n"); - powernow_k8_cpu_exit_acpi(data); - kfree(data->powernow_table); - kfree(data); - return -EINVAL; - } + pol->freq_table = data->powernow_table; pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n", data->currfid, data->currvid); -- cgit v1.2.3-71-gd317 From 20dfdb9c80fa56fec05683a1d797d42843dfa63a Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:38:59 +0530 Subject: cpufreq: ppc_cbe: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from ppc_cbe driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/ppc_cbe_cpufreq.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c index 5a4c5a639f61..41a0f0be3f9f 100644 --- a/drivers/cpufreq/ppc_cbe_cpufreq.c +++ b/drivers/cpufreq/ppc_cbe_cpufreq.c @@ -121,9 +121,8 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy) cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu)); #endif - /* this ensures that policy->cpuinfo_min - * and policy->cpuinfo_max are set correctly */ - return cpufreq_table_validate_and_show(policy, cbe_freqs); + policy->freq_table = cbe_freqs; + return 0; } static int cbe_cpufreq_target(struct cpufreq_policy *policy, -- cgit v1.2.3-71-gd317 From 8ed5a219d0f01662072dfd186f98f550e4874ac3 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:39:00 +0530 Subject: cpufreq: pxa: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from pxa driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/pxa2xx-cpufreq.c | 4 ++-- drivers/cpufreq/pxa3xx-cpufreq.c | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/pxa2xx-cpufreq.c b/drivers/cpufreq/pxa2xx-cpufreq.c index 06b024a3e474..46254e583982 100644 --- a/drivers/cpufreq/pxa2xx-cpufreq.c +++ b/drivers/cpufreq/pxa2xx-cpufreq.c @@ -292,10 +292,10 @@ static int pxa_cpufreq_init(struct cpufreq_policy *policy) pr_info("using %s frequency table\n", pxa255_turbo_table ? "turbo" : "run"); - cpufreq_table_validate_and_show(policy, pxa255_freq_table); + policy->freq_table = pxa255_freq_table; } else if (cpu_is_pxa27x()) { - cpufreq_table_validate_and_show(policy, pxa27x_freq_table); + policy->freq_table = pxa27x_freq_table; } pr_info("frequency change support initialized\n"); diff --git a/drivers/cpufreq/pxa3xx-cpufreq.c b/drivers/cpufreq/pxa3xx-cpufreq.c index a01275900389..7acc7fa4536d 100644 --- a/drivers/cpufreq/pxa3xx-cpufreq.c +++ b/drivers/cpufreq/pxa3xx-cpufreq.c @@ -108,7 +108,9 @@ static int setup_freqs_table(struct cpufreq_policy *policy, pxa3xx_freqs_num = num; pxa3xx_freqs_table = table; - return cpufreq_table_validate_and_show(policy, table); + policy->freq_table = table; + + return 0; } static void __update_core_freq(struct pxa3xx_freq_info *info) -- cgit v1.2.3-71-gd317 From 5ab508bebf25c31c959013c7a0df496f661cd735 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:39:01 +0530 Subject: cpufreq: qoirq: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from qoirq driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/qoriq-cpufreq.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/qoriq-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c index ee3e3656485b..3d773f64b4df 100644 --- a/drivers/cpufreq/qoriq-cpufreq.c +++ b/drivers/cpufreq/qoriq-cpufreq.c @@ -165,7 +165,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table, static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy) { struct device_node *np; - int i, count, ret; + int i, count; u32 freq; struct clk *clk; const struct clk_hw *hwclk; @@ -209,14 +209,7 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy) freq_table_redup(table, count); freq_table_sort(table, count); table[i].frequency = CPUFREQ_TABLE_END; - - /* set the min and max frequency properly */ - ret = cpufreq_table_validate_and_show(policy, table); - if (ret) { - pr_err("invalid frequency table: %d\n", ret); - goto err_nomem1; - } - + policy->freq_table = table; data->table = table; /* update ->cpus if we have cluster, no harm if not */ @@ -232,8 +225,6 @@ static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy) return 0; -err_nomem1: - kfree(table); err_pclk: kfree(data->pclk); err_nomem2: -- cgit v1.2.3-71-gd317 From 09e390f30f44ee7a4f145af2c7c084332a52b6c1 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:39:02 +0530 Subject: cpufreq: s3c24xx: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from s3c24xx driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/s3c24xx-cpufreq.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/s3c24xx-cpufreq.c b/drivers/cpufreq/s3c24xx-cpufreq.c index 6bc083ffc04f..909bd6e27639 100644 --- a/drivers/cpufreq/s3c24xx-cpufreq.c +++ b/drivers/cpufreq/s3c24xx-cpufreq.c @@ -351,11 +351,8 @@ struct clk *s3c_cpufreq_clk_get(struct device *dev, const char *name) static int s3c_cpufreq_init(struct cpufreq_policy *policy) { policy->clk = clk_arm; - policy->cpuinfo.transition_latency = cpu_cur.info->latency; - - if (ftab) - return cpufreq_table_validate_and_show(policy, ftab); + policy->freq_table = ftab; return 0; } -- cgit v1.2.3-71-gd317 From f35750c88555513f1772fe2edb4d42b9178625b5 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:39:03 +0530 Subject: cpufreq: sc520: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from sc520 driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/sc520_freq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c index 4225501a4b78..abaa75e86148 100644 --- a/drivers/cpufreq/sc520_freq.c +++ b/drivers/cpufreq/sc520_freq.c @@ -83,8 +83,9 @@ static int sc520_freq_cpu_init(struct cpufreq_policy *policy) /* cpuinfo and default policy values */ policy->cpuinfo.transition_latency = 1000000; /* 1ms */ + policy->freq_table = sc520_freq_table; - return cpufreq_table_validate_and_show(policy, sc520_freq_table); + return 0; } -- cgit v1.2.3-71-gd317 From 472ada602179fd699817ede62d2d915b4b1a191b Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:39:04 +0530 Subject: cpufreq: scpi: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from scpi driver. Signed-off-by: Viresh Kumar Acked-by: Sudeep Holla Tested-by: Sudeep Holla Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/scpi-cpufreq.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c index d300a163945f..87a98ec77773 100644 --- a/drivers/cpufreq/scpi-cpufreq.c +++ b/drivers/cpufreq/scpi-cpufreq.c @@ -158,13 +158,7 @@ static int scpi_cpufreq_init(struct cpufreq_policy *policy) } policy->driver_data = priv; - - ret = cpufreq_table_validate_and_show(policy, freq_table); - if (ret) { - dev_err(cpu_dev, "%s: invalid frequency table: %d\n", __func__, - ret); - goto out_put_clk; - } + policy->freq_table = freq_table; /* scpi allows DVFS request for any domain from any CPU */ policy->dvfs_possible_from_any_cpu = true; @@ -178,8 +172,6 @@ static int scpi_cpufreq_init(struct cpufreq_policy *policy) policy->fast_switch_possible = false; return 0; -out_put_clk: - clk_put(priv->clk); out_free_cpufreq_table: dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); out_free_priv: -- cgit v1.2.3-71-gd317 From 54a277ebf20d9bfae458c4a8af4308693d619830 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:39:05 +0530 Subject: cpufreq: sfi: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from sfi driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/sfi-cpufreq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/sfi-cpufreq.c b/drivers/cpufreq/sfi-cpufreq.c index 3779742f86e3..9767afe05da2 100644 --- a/drivers/cpufreq/sfi-cpufreq.c +++ b/drivers/cpufreq/sfi-cpufreq.c @@ -72,8 +72,9 @@ static int sfi_cpufreq_cpu_init(struct cpufreq_policy *policy) { policy->shared_type = CPUFREQ_SHARED_TYPE_HW; policy->cpuinfo.transition_latency = 100000; /* 100us */ + policy->freq_table = freq_table; - return cpufreq_table_validate_and_show(policy, freq_table); + return 0; } static struct cpufreq_driver sfi_cpufreq_driver = { -- cgit v1.2.3-71-gd317 From ec8d2cc62ce5dd11000c3659ffd1d64e665372bb Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:39:06 +0530 Subject: cpufreq: sh: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from sh-cpufreq driver. The driver though prints the min/max frequency values and the same is done from the ->ready() callback now to keep the behavior unchanged. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/sh-cpufreq.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/sh-cpufreq.c b/drivers/cpufreq/sh-cpufreq.c index 28893d435cf5..5096c0ab781b 100644 --- a/drivers/cpufreq/sh-cpufreq.c +++ b/drivers/cpufreq/sh-cpufreq.c @@ -122,11 +122,7 @@ static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy) freq_table = cpuclk->nr_freqs ? cpuclk->freq_table : NULL; if (freq_table) { - int result; - - result = cpufreq_table_validate_and_show(policy, freq_table); - if (result) - return result; + policy->freq_table = freq_table; } else { dev_notice(dev, "no frequency table found, falling back " "to rate rounding.\n"); @@ -137,11 +133,6 @@ static int sh_cpufreq_cpu_init(struct cpufreq_policy *policy) (clk_round_rate(cpuclk, ~0UL) + 500) / 1000; } - dev_info(dev, "CPU Frequencies - Minimum %u.%03u MHz, " - "Maximum %u.%03u MHz.\n", - policy->min / 1000, policy->min % 1000, - policy->max / 1000, policy->max % 1000); - return 0; } @@ -155,6 +146,16 @@ static int sh_cpufreq_cpu_exit(struct cpufreq_policy *policy) return 0; } +static void sh_cpufreq_cpu_ready(struct cpufreq_policy *policy) +{ + struct device *dev = get_cpu_device(policy->cpu); + + dev_info(dev, "CPU Frequencies - Minimum %u.%03u MHz, " + "Maximum %u.%03u MHz.\n", + policy->min / 1000, policy->min % 1000, + policy->max / 1000, policy->max % 1000); +} + static struct cpufreq_driver sh_cpufreq_driver = { .name = "sh", .flags = CPUFREQ_NO_AUTO_DYNAMIC_SWITCHING, @@ -163,6 +164,7 @@ static struct cpufreq_driver sh_cpufreq_driver = { .verify = sh_cpufreq_verify, .init = sh_cpufreq_cpu_init, .exit = sh_cpufreq_cpu_exit, + .ready = sh_cpufreq_cpu_ready, .attr = cpufreq_generic_attr, }; -- cgit v1.2.3-71-gd317 From 31f4b7a86b53cfa3b6bcef67cda62708b596cd91 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:39:07 +0530 Subject: cpufreq: sparc: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from sparc driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/sparc-us2e-cpufreq.c | 3 ++- drivers/cpufreq/sparc-us3-cpufreq.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/sparc-us2e-cpufreq.c b/drivers/cpufreq/sparc-us2e-cpufreq.c index 90f33efee5fc..bbd1d1e166b8 100644 --- a/drivers/cpufreq/sparc-us2e-cpufreq.c +++ b/drivers/cpufreq/sparc-us2e-cpufreq.c @@ -292,8 +292,9 @@ static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy) policy->cpuinfo.transition_latency = 0; policy->cur = clock_tick; + policy->freq_table = table; - return cpufreq_table_validate_and_show(policy, table); + return 0; } static int us2e_freq_cpu_exit(struct cpufreq_policy *policy) diff --git a/drivers/cpufreq/sparc-us3-cpufreq.c b/drivers/cpufreq/sparc-us3-cpufreq.c index 30645b0118f9..51e3c6018e74 100644 --- a/drivers/cpufreq/sparc-us3-cpufreq.c +++ b/drivers/cpufreq/sparc-us3-cpufreq.c @@ -136,8 +136,9 @@ static int __init us3_freq_cpu_init(struct cpufreq_policy *policy) policy->cpuinfo.transition_latency = 0; policy->cur = clock_tick; + policy->freq_table = table; - return cpufreq_table_validate_and_show(policy, table); + return 0; } static int us3_freq_cpu_exit(struct cpufreq_policy *policy) -- cgit v1.2.3-71-gd317 From 2d28b03686846f3ca62135c6f06b93e77752d581 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:39:08 +0530 Subject: cpufreq: speedstep: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from speedstep driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/speedstep-centrino.c | 4 ++-- drivers/cpufreq/speedstep-ich.c | 4 +++- drivers/cpufreq/speedstep-smi.c | 4 +++- 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c index 4fa5adf16c70..a1fb735685db 100644 --- a/drivers/cpufreq/speedstep-centrino.c +++ b/drivers/cpufreq/speedstep-centrino.c @@ -394,9 +394,9 @@ static int centrino_cpu_init(struct cpufreq_policy *policy) policy->cpuinfo.transition_latency = 10000; /* 10uS transition latency */ + policy->freq_table = per_cpu(centrino_model, policy->cpu)->op_points; - return cpufreq_table_validate_and_show(policy, - per_cpu(centrino_model, policy->cpu)->op_points); + return 0; } static int centrino_cpu_exit(struct cpufreq_policy *policy) diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c index 0412a246a785..fbbcb88db061 100644 --- a/drivers/cpufreq/speedstep-ich.c +++ b/drivers/cpufreq/speedstep-ich.c @@ -304,7 +304,9 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) if (gf.ret) return gf.ret; - return cpufreq_table_validate_and_show(policy, speedstep_freqs); + policy->freq_table = speedstep_freqs; + + return 0; } diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c index d23f24ccff38..01fe70dae20b 100644 --- a/drivers/cpufreq/speedstep-smi.c +++ b/drivers/cpufreq/speedstep-smi.c @@ -266,7 +266,9 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy) pr_debug("workaround worked.\n"); } - return cpufreq_table_validate_and_show(policy, speedstep_freqs); + policy->freq_table = speedstep_freqs; + + return 0; } static unsigned int speedstep_get(unsigned int cpu) -- cgit v1.2.3-71-gd317 From a8b6966034ba88190eca397e2693b5bc16790517 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 26 Feb 2018 10:39:09 +0530 Subject: cpufreq: tegra186: Don't validate the frequency table twice The cpufreq core is already validating the CPU frequency table after calling the ->init() callback of the cpufreq drivers and the drivers don't need to do the same anymore. Though they need to set the policy->freq_table field directly from the ->init() callback now. Stop validating the frequency table from tegra186 driver. Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/tegra186-cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/tegra186-cpufreq.c b/drivers/cpufreq/tegra186-cpufreq.c index 771df649ceb9..1f59966573aa 100644 --- a/drivers/cpufreq/tegra186-cpufreq.c +++ b/drivers/cpufreq/tegra186-cpufreq.c @@ -78,7 +78,7 @@ static int tegra186_cpufreq_init(struct cpufreq_policy *policy) policy->driver_data = data->regs + info->offset + EDVD_CORE_VOLT_FREQ(core); - cpufreq_table_validate_and_show(policy, cluster->table); + policy->freq_table = cluster->table; break; } -- cgit v1.2.3-71-gd317 From a37b969a61c1efcd16da9c9ab3b237235c48560c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 14 Mar 2018 15:08:57 +0100 Subject: cpuidle: poll_state: Add time limit to poll_idle() If poll_idle() is allowed to spin until need_resched() returns 'true', it may actually spin for a much longer time than expected by the idle governor, since set_tsk_need_resched() is not always called by the timer interrupt handler. If that happens, the CPU may spend much more time than anticipated in the "polling" state. To prevent that from happening, limit the time of the spinning loop in poll_idle(). Suggested-by: Peter Zijlstra Signed-off-by: Rafael J. Wysocki Tested-by: Doug Smythies --- drivers/cpuidle/poll_state.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpuidle/poll_state.c b/drivers/cpuidle/poll_state.c index 7416b16287de..68cdc506524b 100644 --- a/drivers/cpuidle/poll_state.c +++ b/drivers/cpuidle/poll_state.c @@ -6,15 +6,24 @@ #include #include +#include #include +#define POLL_IDLE_TIME_LIMIT (TICK_NSEC / 16) + static int __cpuidle poll_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { + u64 time_start = local_clock(); + local_irq_enable(); if (!current_set_polling_and_test()) { - while (!need_resched()) + while (!need_resched()) { cpu_relax(); + + if (local_clock() - time_start > POLL_IDLE_TIME_LIMIT) + break; + } } current_clr_polling(); -- cgit v1.2.3-71-gd317 From 8919d779f1fd1ea8b06a46249f1a13c835b736af Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 13 Mar 2018 16:04:51 +0100 Subject: cpuidle: Enable coupled cpuidle support on Exynos3250 platform All the needed code has been already merged to mach-exynos core in commit af9971144dde ("ARM: EXYNOS: add coupled cpuidle support for Exynos3250"), so enable support for coupled variant also for Exynos3250 SoCs. Signed-off-by: Marek Szyprowski Acked-by: Krzysztof Kozlowski Acked-by: Bartlomiej Zolnierkiewicz Signed-off-by: Rafael J. Wysocki --- drivers/cpuidle/cpuidle-exynos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpuidle/cpuidle-exynos.c b/drivers/cpuidle/cpuidle-exynos.c index 00cd129b10a4..0171a6e190d7 100644 --- a/drivers/cpuidle/cpuidle-exynos.c +++ b/drivers/cpuidle/cpuidle-exynos.c @@ -117,7 +117,8 @@ static int exynos_cpuidle_probe(struct platform_device *pdev) int ret; if (IS_ENABLED(CONFIG_SMP) && - of_machine_is_compatible("samsung,exynos4210")) { + (of_machine_is_compatible("samsung,exynos4210") || + of_machine_is_compatible("samsung,exynos3250"))) { exynos_cpuidle_pdata = pdev->dev.platform_data; ret = cpuidle_register(&exynos_coupled_idle_driver, -- cgit v1.2.3-71-gd317 From 64bdff698092aa6be28c3b248f887022eec77902 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 14 Mar 2018 12:27:21 +0100 Subject: PM: cpuidle/suspend: Add s2idle usage and time state attributes Add a new attribute group called "s2idle" under the sysfs directory of each cpuidle state that supports the ->enter_s2idle callback and put two new attributes, "usage" and "time", into that group to represent the number of times the given state was requested for suspend-to-idle and the total time spent in suspend-to-idle after requesting that state, respectively. That will allow diagnostic information related to suspend-to-idle to be collected without enabling advanced debug features and analyzing dmesg output. Signed-off-by: Rafael J. Wysocki --- Documentation/ABI/testing/sysfs-devices-system-cpu | 25 ++++++++++ drivers/cpuidle/cpuidle.c | 9 ++++ drivers/cpuidle/sysfs.c | 54 ++++++++++++++++++++++ include/linux/cpuidle.h | 4 ++ 4 files changed, 92 insertions(+) (limited to 'drivers') diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index 4ed63b6cfb15..025b7cf3768d 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu @@ -198,6 +198,31 @@ Description: time (in microseconds) this cpu should spend in this idle state to make the transition worth the effort. +What: /sys/devices/system/cpu/cpuX/cpuidle/stateN/s2idle/ +Date: March 2018 +KernelVersion: v4.17 +Contact: Linux power management list +Description: + Idle state usage statistics related to suspend-to-idle. + + This attribute group is only present for states that can be + used in suspend-to-idle with suspended timekeeping. + +What: /sys/devices/system/cpu/cpuX/cpuidle/stateN/s2idle/time +Date: March 2018 +KernelVersion: v4.17 +Contact: Linux power management list +Description: + Total time spent by the CPU in suspend-to-idle (with scheduler + tick suspended) after requesting this state. + +What: /sys/devices/system/cpu/cpuX/cpuidle/stateN/s2idle/usage +Date: March 2018 +KernelVersion: v4.17 +Contact: Linux power management list +Description: + Total number of times this state has been requested by the CPU + while entering suspend-to-idle. What: /sys/devices/system/cpu/cpu#/cpufreq/* Date: pre-git history diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c index 68a16827f45f..0003e9a02637 100644 --- a/drivers/cpuidle/cpuidle.c +++ b/drivers/cpuidle/cpuidle.c @@ -131,6 +131,10 @@ int cpuidle_find_deepest_state(struct cpuidle_driver *drv, static void enter_s2idle_proper(struct cpuidle_driver *drv, struct cpuidle_device *dev, int index) { + ktime_t time_start, time_end; + + time_start = ns_to_ktime(local_clock()); + /* * trace_suspend_resume() called by tick_freeze() for the last CPU * executing it contains RCU usage regarded as invalid in the idle @@ -152,6 +156,11 @@ static void enter_s2idle_proper(struct cpuidle_driver *drv, */ RCU_NONIDLE(tick_unfreeze()); start_critical_timings(); + + time_end = ns_to_ktime(local_clock()); + + dev->states_usage[index].s2idle_time += ktime_us_delta(time_end, time_start); + dev->states_usage[index].s2idle_usage++; } /** diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c index ae948b1da93a..e754c7aae7f7 100644 --- a/drivers/cpuidle/sysfs.c +++ b/drivers/cpuidle/sysfs.c @@ -330,6 +330,58 @@ struct cpuidle_state_kobj { struct kobject kobj; }; +#ifdef CONFIG_SUSPEND +#define define_show_state_s2idle_ull_function(_name) \ +static ssize_t show_state_s2idle_##_name(struct cpuidle_state *state, \ + struct cpuidle_state_usage *state_usage, \ + char *buf) \ +{ \ + return sprintf(buf, "%llu\n", state_usage->s2idle_##_name);\ +} + +define_show_state_s2idle_ull_function(usage); +define_show_state_s2idle_ull_function(time); + +#define define_one_state_s2idle_ro(_name, show) \ +static struct cpuidle_state_attr attr_s2idle_##_name = \ + __ATTR(_name, 0444, show, NULL) + +define_one_state_s2idle_ro(usage, show_state_s2idle_usage); +define_one_state_s2idle_ro(time, show_state_s2idle_time); + +static struct attribute *cpuidle_state_s2idle_attrs[] = { + &attr_s2idle_usage.attr, + &attr_s2idle_time.attr, + NULL +}; + +static const struct attribute_group cpuidle_state_s2idle_group = { + .name = "s2idle", + .attrs = cpuidle_state_s2idle_attrs, +}; + +static void cpuidle_add_s2idle_attr_group(struct cpuidle_state_kobj *kobj) +{ + int ret; + + if (!kobj->state->enter_s2idle) + return; + + ret = sysfs_create_group(&kobj->kobj, &cpuidle_state_s2idle_group); + if (ret) + pr_debug("%s: sysfs attribute group not created\n", __func__); +} + +static void cpuidle_remove_s2idle_attr_group(struct cpuidle_state_kobj *kobj) +{ + if (kobj->state->enter_s2idle) + sysfs_remove_group(&kobj->kobj, &cpuidle_state_s2idle_group); +} +#else +static inline void cpuidle_add_s2idle_attr_group(struct cpuidle_state_kobj *kobj) { } +static inline void cpuidle_remove_s2idle_attr_group(struct cpuidle_state_kobj *kobj) { } +#endif /* CONFIG_SUSPEND */ + #define kobj_to_state_obj(k) container_of(k, struct cpuidle_state_kobj, kobj) #define kobj_to_state(k) (kobj_to_state_obj(k)->state) #define kobj_to_state_usage(k) (kobj_to_state_obj(k)->state_usage) @@ -383,6 +435,7 @@ static struct kobj_type ktype_state_cpuidle = { static inline void cpuidle_free_state_kobj(struct cpuidle_device *device, int i) { + cpuidle_remove_s2idle_attr_group(device->kobjs[i]); kobject_put(&device->kobjs[i]->kobj); wait_for_completion(&device->kobjs[i]->kobj_unregister); kfree(device->kobjs[i]); @@ -417,6 +470,7 @@ static int cpuidle_add_state_sysfs(struct cpuidle_device *device) kfree(kobj); goto error_state; } + cpuidle_add_s2idle_attr_group(kobj); kobject_uevent(&kobj->kobj, KOBJ_ADD); device->kobjs[i] = kobj; } diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h index 0b3fc229086c..a806e94c482f 100644 --- a/include/linux/cpuidle.h +++ b/include/linux/cpuidle.h @@ -33,6 +33,10 @@ struct cpuidle_state_usage { unsigned long long disable; unsigned long long usage; unsigned long long time; /* in US */ +#ifdef CONFIG_SUSPEND + unsigned long long s2idle_usage; + unsigned long long s2idle_time; /* in US */ +#endif }; struct cpuidle_state { -- cgit v1.2.3-71-gd317 From 4dc2375c1a4e88ed2701f6961e0e4f9a7696ad3c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Tue, 27 Mar 2018 23:58:45 +0200 Subject: cpuidle: poll_state: Avoid invoking local_clock() too often Rik reports that he sees an increase in CPU use in one benchmark due to commit 612f1a22f067 "cpuidle: poll_state: Add time limit to poll_idle()" that caused poll_idle() to call local_clock() in every iteration of the loop. Utilization increase generally means more non-idle time with respect to total CPU time (on the average) which implies reduced CPU frequency. Doug reports that limiting the rate of local_clock() invocations in there causes much less power to be drawn during a CPU-intensive parallel workload (with idle states 1 and 2 disabled to enforce more state 0 residency). These two reports together suggest that executing local_clock() on multiple CPUs in parallel at a high rate may cause chips to get hot and trigger thermal/power limits on them to kick in, so reduce the rate of local_clock() invocations in poll_idle() to avoid that issue. Fixes: 612f1a22f067 "cpuidle: poll_state: Add time limit to poll_idle()" Reported-by: Rik van Riel Reported-by: Doug Smythies Signed-off-by: Rafael J. Wysocki Tested-by: Rik van Riel Reviewed-by: Rik van Riel --- drivers/cpuidle/poll_state.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/cpuidle/poll_state.c b/drivers/cpuidle/poll_state.c index 68cdc506524b..3f86d23c592e 100644 --- a/drivers/cpuidle/poll_state.c +++ b/drivers/cpuidle/poll_state.c @@ -10,6 +10,7 @@ #include #define POLL_IDLE_TIME_LIMIT (TICK_NSEC / 16) +#define POLL_IDLE_RELAX_COUNT 200 static int __cpuidle poll_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) @@ -18,9 +19,14 @@ static int __cpuidle poll_idle(struct cpuidle_device *dev, local_irq_enable(); if (!current_set_polling_and_test()) { + unsigned int loop_count = 0; + while (!need_resched()) { cpu_relax(); + if (loop_count++ < POLL_IDLE_RELAX_COUNT) + continue; + loop_count = 0; if (local_clock() - time_start > POLL_IDLE_TIME_LIMIT) break; } -- cgit v1.2.3-71-gd317 From 3d41386d556db9f720e00de3e11e45f39cb5071c Mon Sep 17 00:00:00 2001 From: George Cherian Date: Fri, 23 Mar 2018 03:30:31 -0700 Subject: cpufreq: CPPC: Use transition_delay_us depending transition_latency With commit e948bc8fbee0 (cpufreq: Cap the default transition delay value to 10 ms) the cpufreq was not honouring the delay passed via ACPI (PCCT). Due to which on ARM based platforms using CPPC the cpufreq governor tries to change the frequency of CPUs faster than expected. This leads to continuous error messages like the following. " ACPI CPPC: PCC check channel failed. Status=0 " Earlier (without above commit) the default transition delay was taken form the value passed from PCCT. Use the same value provided by PCCT to set the transition_delay_us. Fixes: e948bc8fbee0 (cpufreq: Cap the default transition delay value to 10 ms) Signed-off-by: George Cherian Cc: 4.14+ # 4.14+ Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cppc_cpufreq.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index 8f7b21a4d537..8300a9fcb80c 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -162,6 +163,8 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) policy->cpuinfo.max_freq = cppc_dmi_max_khz; policy->cpuinfo.transition_latency = cppc_get_transition_latency(cpu_num); + policy->transition_delay_us = cppc_get_transition_latency(cpu_num) / + NSEC_PER_USEC; policy->shared_type = cpu->shared_type; if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) -- cgit v1.2.3-71-gd317 From 6f1d7c45dbbadd1a3c6eb9a9a485ef1975be4760 Mon Sep 17 00:00:00 2001 From: Chris Chiu Date: Sat, 31 Mar 2018 10:09:31 +0800 Subject: ACPI / PM: Fix keyboard wakeup from suspend-to-idle on ASUS UX331UA This issue happens on new ASUS laptop UX331UA which has modern standby mode (suspend-to-idle). Pressing keys on the PS2 keyboard can't wake up the system from suspend-to-idle which is not expected. However, pressing power button can wake up without problem. Per the engineers of ASUS, the keypress event is routed to Embedded Controller (EC) in standby mode. EC then signals the SCI event to BIOS so BIOS would Notify() power button to wake up the system. It's from BIOS perspective. What we observe here is that kernel receives the SCI event from SCI interrupt handler which informs that the GPE status bit belongs to EC needs to be handled and then queries the EC to find out what event is pending. Then execute the following ACPI _QDF method which defined in ACPI DSDT for EC to notify power button. Method (_QDF, 0, NotSerialized) // _Qxx: EC Query { Notify (PWRB, 0x80) // Status Change } With more debug messages added to analyze this problem, we find that the keypress does wake up the system from suspend-to-idle but it's back to suspend again almost immediately. As we see in the following messages, the acpi_button_notify() is invoked but acpi_pm_wakeup_event() can not really wake up the system here because acpi_s2idle_wakeup() is false. The acpi_s2idle_wakeup() returnd false because the acpi_s2idle_sync() has alrealdy exited. [ 52.987048] s2idle_loop going s2idle [ 59.713392] acpi_s2idle_wake enter [ 59.713394] acpi_s2idle_wake exit [ 59.760888] acpi_ev_gpe_detect enter [ 59.760893] acpi_s2idle_sync enter [ 59.760893] acpi_ec_query_flushed ec pending queries 0 [ 59.760953] Read registers for GPE 50-57: Status=01, Enable=01, RunEnable=01, WakeEnable=00 [ 59.760955] ACPI: EC: ===== IRQ (1) ===== [ 59.760972] ACPI: EC: EC_SC(R) = 0x28 SCI_EVT=1 BURST=0 CMD=1 IBF=0 OBF=0 [ 59.760979] ACPI: EC: +++++ Polling enabled +++++ [ 59.760979] ACPI: EC: ##### Command(QR_EC) submitted/blocked ##### [ 59.761003] acpi_s2idle_sync exit [ 59.769587] ACPI: EC: ##### Query(0xdf) started ##### [ 59.769611] ACPI: EC: ##### Query(0xdf) stopped ##### [ 59.774154] acpi_button_notify button type 1 [ 59.813175] s2idle_loop going s2idle acpi_s2idle_sync() already makes an effort to flush the EC event queue, but in this case, the EC event has yet to be generated when the call to acpi_ec_flush_work() is made. The event is generated shortly after, through the ongoing handling of the SCI interrupt which is happening on another CPU, and we must synchronize that to make sure that it has run and completed. Adding another call to acpi_os_wait_events_complete() solves this issue, since that function synchronizes with SCI interrupt completion. Signed-off-by: Chris Chiu [ rjw: Subject ] Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sleep.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index b5d27a4213ab..4a59c16915c3 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -989,8 +989,9 @@ static void acpi_s2idle_sync(void) * The EC driver uses the system workqueue and an additional special * one, so those need to be flushed too. */ + acpi_os_wait_events_complete(); /* synchronize SCI IRQ handling */ acpi_ec_flush_work(); - acpi_os_wait_events_complete(); + acpi_os_wait_events_complete(); /* synchronize Notify handling */ s2idle_wakeup = false; } -- cgit v1.2.3-71-gd317