From patchwork Wed Jan 10 16:44:14 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 124120 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp5494751qgn; Wed, 10 Jan 2018 08:44:50 -0800 (PST) X-Google-Smtp-Source: ACJfBotQb6I9l8H5ivEuIrbbPiTCw+gAMb6ZW0pUvSWzzmxD7qKINODYz3xl1HsaPYSfxkL5qgpW X-Received: by 10.98.150.5 with SMTP id c5mr17128418pfe.232.1515602690177; Wed, 10 Jan 2018 08:44:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515602690; cv=none; d=google.com; s=arc-20160816; b=anT36yWb5WlDXRxYSuGlnOMVa3uUcZmqhlUMJSoNmfr1wJVe812Z7RJ34vywv9hgfM 9KMwpBj15/VR1xP6dvD5EOWVpjS8hA4lnGUUUwgFaIy0Z/knmaDeqbx+8b7lqAyVFAua Q7zAZbvEvFKIF2UUuFLKHGBmJ9v7vIhR+051Y8ytFKDu4R/HQ7jYXwsC0/Phn3S+6DES 8K4AwCOsi5oAWD8bG2haEieeF8CQmZkSZqxP8bMCRon+0W4vVBe7pPwQ2WlCNYa6attx RgfPtiBGzN0QEwBlPiCPZCHS0xMY6O3cJlkoFwnhP7OT3+5yV4qs8VMQo9LRpYfDAw0P 61Xw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=BwAHP7oK5Nmr1zUYb3jG4gg666xWTYJysYf2ZL9MUdU=; b=cIugXqRZcZx72a5lFuQzmVUKkY8kIdd3mcWPakAdngGZt3iUTtFC18vLQ3uyY28y2g ZLHoGxGHK5MjJZ951J8B//FzlFbYJX3fGCDzHxMG4RM8UjqyfTi7jw15AVxsx3BSE8rG CO03fMj+8DUi71hgF8BoFXSxn5OH+HELLbuBOptWjxCKjcfJOFcqiQHntK4rEf/WQXqd +VErS3j6QvKsV/UA+ost1qwoS1GB06HfxypxewqZrHBCGXSMLcog5APLyiQxEblWDyHM h5RKf3dNHUQdC5FsgkPmwV5VO9SdO2UKFVE3NZDqW5K7cYWJR5RmlyJ4iJs1m3o1gEYq ykNQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o16si6376869pgd.563.2018.01.10.08.44.49; Wed, 10 Jan 2018 08:44:50 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S966492AbeAJQor (ORCPT + 28 others); Wed, 10 Jan 2018 11:44:47 -0500 Received: from foss.arm.com ([217.140.101.70]:45374 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S966324AbeAJQok (ORCPT ); Wed, 10 Jan 2018 11:44:40 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D046E15A2; Wed, 10 Jan 2018 08:44:39 -0800 (PST) Received: from e107155-lin.cambridge.arm.com (e107155-lin.cambridge.arm.com [10.1.210.28]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 341F13F487; Wed, 10 Jan 2018 08:44:38 -0800 (PST) From: Sudeep Holla To: linux-amlogic@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-pm@vger.kernel.org Cc: Sudeep Holla , linux-kernel@vger.kernel.org, Viresh Kumar , Jeremy Linton , Lorenzo Pieralisi , Mark Rutland Subject: [PATCH v2 1/2] drivers: psci: remove cluster terminology and dependency on physical_package_id Date: Wed, 10 Jan 2018 16:44:14 +0000 Message-Id: <1515602655-12740-2-git-send-email-sudeep.holla@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515602655-12740-1-git-send-email-sudeep.holla@arm.com> References: <1515602655-12740-1-git-send-email-sudeep.holla@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Since the definition of the term "cluster" is not well defined in the architecture, we should avoid using it. Also the physical package id is currently mapped to so called "clusters" in ARM/ARM64 platforms which is already argumentative. Currently PSCI checker uses the physical package id assuming that CPU power domains map to "clusters" and the physical package id in the code as it stands also maps to cluster boundaries. It does that trying to test "cluster" idle states to its best. However the CPU power domain often but not always maps directly to the processor topology. This patch removes the dependency on physical_package_id from the topology in this PSCI checker. Also it replaces all the occurences of clusters to cpu_groups which is derived from core_sibling_mask and may not directly map to physical "cluster". Cc: Mark Rutland Acked-by: Lorenzo Pieralisi Signed-off-by: Sudeep Holla --- drivers/firmware/psci_checker.c | 46 ++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 24 deletions(-) -- 2.7.4 diff --git a/drivers/firmware/psci_checker.c b/drivers/firmware/psci_checker.c index f3f4f810e5df..bb1c068bff19 100644 --- a/drivers/firmware/psci_checker.c +++ b/drivers/firmware/psci_checker.c @@ -77,8 +77,8 @@ static int psci_ops_check(void) return 0; } -static int find_clusters(const struct cpumask *cpus, - const struct cpumask **clusters) +static int find_cpu_groups(const struct cpumask *cpus, + const struct cpumask **cpu_groups) { unsigned int nb = 0; cpumask_var_t tmp; @@ -88,11 +88,11 @@ static int find_clusters(const struct cpumask *cpus, cpumask_copy(tmp, cpus); while (!cpumask_empty(tmp)) { - const struct cpumask *cluster = + const struct cpumask *cpu_group = topology_core_cpumask(cpumask_any(tmp)); - clusters[nb++] = cluster; - cpumask_andnot(tmp, tmp, cluster); + cpu_groups[nb++] = cpu_group; + cpumask_andnot(tmp, tmp, cpu_group); } free_cpumask_var(tmp); @@ -170,24 +170,24 @@ static int hotplug_tests(void) { int err; cpumask_var_t offlined_cpus; - int i, nb_cluster; - const struct cpumask **clusters; + int i, nb_cpu_group; + const struct cpumask **cpu_groups; char *page_buf; err = -ENOMEM; if (!alloc_cpumask_var(&offlined_cpus, GFP_KERNEL)) return err; - /* We may have up to nb_available_cpus clusters. */ - clusters = kmalloc_array(nb_available_cpus, sizeof(*clusters), - GFP_KERNEL); - if (!clusters) + /* We may have up to nb_available_cpus cpu_groups. */ + cpu_groups = kmalloc_array(nb_available_cpus, sizeof(*cpu_groups), + GFP_KERNEL); + if (!cpu_groups) goto out_free_cpus; page_buf = (char *)__get_free_page(GFP_KERNEL); if (!page_buf) - goto out_free_clusters; + goto out_free_cpu_groups; err = 0; - nb_cluster = find_clusters(cpu_online_mask, clusters); + nb_cpu_group = find_cpu_groups(cpu_online_mask, cpu_groups); /* * Of course the last CPU cannot be powered down and cpu_down() should @@ -197,24 +197,22 @@ static int hotplug_tests(void) err += down_and_up_cpus(cpu_online_mask, offlined_cpus); /* - * Take down CPUs by cluster this time. When the last CPU is turned - * off, the cluster itself should shut down. + * Take down CPUs by cpu group this time. When the last CPU is turned + * off, the cpu group itself should shut down. */ - for (i = 0; i < nb_cluster; ++i) { - int cluster_id = - topology_physical_package_id(cpumask_any(clusters[i])); + for (i = 0; i < nb_cpu_group; ++i) { ssize_t len = cpumap_print_to_pagebuf(true, page_buf, - clusters[i]); + cpu_groups[i]); /* Remove trailing newline. */ page_buf[len - 1] = '\0'; - pr_info("Trying to turn off and on again cluster %d " - "(CPUs %s)\n", cluster_id, page_buf); - err += down_and_up_cpus(clusters[i], offlined_cpus); + pr_info("Trying to turn off and on again group %d (CPUs %s)\n", + i, page_buf); + err += down_and_up_cpus(cpu_groups[i], offlined_cpus); } free_page((unsigned long)page_buf); -out_free_clusters: - kfree(clusters); +out_free_cpu_groups: + kfree(cpu_groups); out_free_cpus: free_cpumask_var(offlined_cpus); return err; From patchwork Wed Jan 10 16:44:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sudeep Holla X-Patchwork-Id: 124121 Delivered-To: patch@linaro.org Received: by 10.140.22.227 with SMTP id 90csp5494933qgn; Wed, 10 Jan 2018 08:45:01 -0800 (PST) X-Google-Smtp-Source: ACJfBos8XXkYHlFpk8MGBG5wE/1rD0aMR28Zl3aOazko2tFVohK2dJWA2ivTbs19Ef1HKV6Is/Lk X-Received: by 10.84.215.15 with SMTP id k15mr6591187pli.197.1515602701010; Wed, 10 Jan 2018 08:45:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1515602701; cv=none; d=google.com; s=arc-20160816; b=UxeGDrinNLTnWLMvMb0NPOE5bBAzJNcRE06wzYkyOpV5tzgepuQBA33Eqfp/IK2KNE Cq1SyEX+qrtbxDY3ncoZxOvxBU6BNR8X3Ze9OpmIIgpKTZp2ZNVH11HJENwl54XogPmM /uuA4fJMyfxpTmvTGJbgyJilwaEwqZJ930L2/ZNidvBVYNy1OmqQOjBY/Ld0DK7UIjue HO4BuHVPoqyYZsODpdjAyoYN4/w8fZY+e8taPKk/HRG/EjdNsDCSnSlSJ8orflIkcsrt x1KFxlATKCfOZjR/4vwLqK8qpNeaZZnpzM/SvG/UHHXpg5FkZyqUw5IPL4vhncOkX2ao rcSQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=UPDiSs8h7DiS5GTSEJwFtoLLtZcmd/0kS1l94oI5AGs=; b=oHU8q2Kmq74Z2rmN0eK3Af6zcPSr5C2Puz5XNGHnTbuaYQqn0ncJjlTX9tioDQ0AIq stABI9ry9rRq3POfkPmjAAoflzTxyzqjrpFP/sDHMx3dScbtqgqjX06WogmautHk5rM0 3VK30IpayRXvLZZrCANsfom68Qk6Tvi/QpKCs8bFVMneG4KT1bJVjP0DWN9zRiZT0Ibm kkSyE21vBB3QjIhFjRi/9vVKMmEFsRJQgwZqqlAMWEDhHw+0h7DZCVW7SMd6I72lZk6k SuMqKDxpY+Bth/5LtRKPXC0NNCQ+wARiZ628Jb8sRT47Xyw1+PtVrNDQE/jNx9bduzxp uGnQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z2si11971032pfd.326.2018.01.10.08.45.00; Wed, 10 Jan 2018 08:45:00 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S966480AbeAJQop (ORCPT + 28 others); Wed, 10 Jan 2018 11:44:45 -0500 Received: from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70]:45388 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S966458AbeAJQom (ORCPT ); Wed, 10 Jan 2018 11:44:42 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B71761610; Wed, 10 Jan 2018 08:44:41 -0800 (PST) Received: from e107155-lin.cambridge.arm.com (e107155-lin.cambridge.arm.com [10.1.210.28]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 1AED63F487; Wed, 10 Jan 2018 08:44:39 -0800 (PST) From: Sudeep Holla To: linux-amlogic@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-pm@vger.kernel.org Cc: Sudeep Holla , linux-kernel@vger.kernel.org, Viresh Kumar , Jeremy Linton , Lorenzo Pieralisi , "Rafael J. Wysocki" Subject: [PATCH v2 2/2] cpufreq: scpi: remove arm_big_little dependency Date: Wed, 10 Jan 2018 16:44:15 +0000 Message-Id: <1515602655-12740-3-git-send-email-sudeep.holla@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1515602655-12740-1-git-send-email-sudeep.holla@arm.com> References: <1515602655-12740-1-git-send-email-sudeep.holla@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The dependency on physical_package_id from the topology to get the cluster identifier is wrong. The concept of cluster used in ARM topology is unfortunately not well defined in the architecture, we should avoid using it. Further the frequency domain need not be mapped to so called "clusters" one to one. SCPI already provides means to obtain the frequency domain id from the device tree. In order to support some new topologies(e.g. DSU which contains 2 frequency domains within the physical cluster), pseudo clusters are created to make this driver work which is wrong again. In order to solve those issues and also remove dependency of topological physical id for frequency domain, this patch removes the arm_big_little dependency from scpi driver. Cc: linux-amlogic@lists.infradead.org Cc: "Rafael J. Wysocki" Acked-by: Viresh Kumar Signed-off-by: Sudeep Holla --- drivers/cpufreq/scpi-cpufreq.c | 193 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 178 insertions(+), 15 deletions(-) Hi AmLogic team, I would like to get tested-by tag so that there's no last minute surprise from this patch on Amlogic platforms. Regards, Sudeep -- 2.7.4 diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c index 05d299052c5c..247fcbfa4cb5 100644 --- a/drivers/cpufreq/scpi-cpufreq.c +++ b/drivers/cpufreq/scpi-cpufreq.c @@ -18,27 +18,89 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include +#include +#include +#include #include -#include +#include #include #include +#include #include -#include "arm_big_little.h" +struct scpi_data { + struct clk *clk; + struct device *cpu_dev; + struct thermal_cooling_device *cdev; +}; static struct scpi_ops *scpi_ops; -static int scpi_get_transition_latency(struct device *cpu_dev) +static unsigned int scpi_cpufreq_get_rate(unsigned int cpu) +{ + struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu); + struct scpi_data *priv = policy->driver_data; + unsigned long rate = clk_get_rate(priv->clk); + + return rate / 1000; +} + +static int +scpi_cpufreq_set_target(struct cpufreq_policy *policy, unsigned int index) +{ + struct scpi_data *priv = policy->driver_data; + u64 rate = policy->freq_table[index].frequency * 1000; + int ret; + + ret = clk_set_rate(priv->clk, rate); + if (!ret && (clk_get_rate(priv->clk) != rate)) + ret = -EIO; + + return ret; +} + +static int +scpi_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask) { - return scpi_ops->get_transition_latency(cpu_dev); + int cpu, domain, tdomain; + struct device *tcpu_dev; + + domain = scpi_ops->device_domain_id(cpu_dev); + if (domain < 0) + return domain; + + for_each_possible_cpu(cpu) { + if (cpu == cpu_dev->id) + continue; + + tcpu_dev = get_cpu_device(cpu); + if (!tcpu_dev) + continue; + + tdomain = scpi_ops->device_domain_id(tcpu_dev); + if (tdomain == domain) + cpumask_set_cpu(cpu, cpumask); + } + + return 0; } -static int scpi_init_opp_table(const struct cpumask *cpumask) +static int scpi_cpufreq_init(struct cpufreq_policy *policy) { int ret; - struct device *cpu_dev = get_cpu_device(cpumask_first(cpumask)); + unsigned int latency; + struct device *cpu_dev; + struct scpi_data *priv; + struct cpufreq_frequency_table *freq_table; + + cpu_dev = get_cpu_device(policy->cpu); + if (!cpu_dev) { + pr_err("failed to get cpu%d device\n", policy->cpu); + return -ENODEV; + } ret = scpi_ops->add_opps_to_device(cpu_dev); if (ret) { @@ -46,32 +108,133 @@ static int scpi_init_opp_table(const struct cpumask *cpumask) return ret; } - ret = dev_pm_opp_set_sharing_cpus(cpu_dev, cpumask); - if (ret) + ret = scpi_get_sharing_cpus(cpu_dev, policy->cpus); + if (ret) { + dev_warn(cpu_dev, "failed to get sharing cpumask\n"); + return ret; + } + + ret = dev_pm_opp_set_sharing_cpus(cpu_dev, policy->cpus); + if (ret) { dev_err(cpu_dev, "%s: failed to mark OPPs as shared: %d\n", __func__, ret); + return ret; + } + + ret = dev_pm_opp_get_opp_count(cpu_dev); + if (ret <= 0) { + dev_dbg(cpu_dev, "OPP table is not ready, deferring probe\n"); + ret = -EPROBE_DEFER; + goto out_free_opp; + } + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + ret = -ENOMEM; + goto out_free_opp; + } + + ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); + if (ret) { + dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret); + goto out_free_priv; + } + + priv->cpu_dev = cpu_dev; + priv->clk = clk_get(cpu_dev, NULL); + if (IS_ERR(priv->clk)) { + dev_err(cpu_dev, "%s: Failed to get clk for cpu: %d\n", + __func__, cpu_dev->id); + goto out_free_cpufreq_table; + } + + 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; + } + + /* scpi allows DVFS request for any domain from any CPU */ + policy->dvfs_possible_from_any_cpu = true; + + latency = scpi_ops->get_transition_latency(cpu_dev); + if (!latency) + latency = CPUFREQ_ETERNAL; + + policy->cpuinfo.transition_latency = latency; + + 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: + kfree(priv); +out_free_opp: + dev_pm_opp_cpumask_remove_table(policy->cpus); + return ret; } -static const struct cpufreq_arm_bL_ops scpi_cpufreq_ops = { - .name = "scpi", - .get_transition_latency = scpi_get_transition_latency, - .init_opp_table = scpi_init_opp_table, - .free_opp_table = dev_pm_opp_cpumask_remove_table, +static int scpi_cpufreq_exit(struct cpufreq_policy *policy) +{ + struct scpi_data *priv = policy->driver_data; + + cpufreq_cooling_unregister(priv->cdev); + clk_put(priv->clk); + dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table); + kfree(priv); + dev_pm_opp_cpumask_remove_table(policy->related_cpus); + + return 0; +} + +static void scpi_cpufreq_ready(struct cpufreq_policy *policy) +{ + struct scpi_data *priv = policy->driver_data; + struct thermal_cooling_device *cdev; + + cdev = of_cpufreq_cooling_register(policy); + if (!IS_ERR(cdev)) + priv->cdev = cdev; +} + +static struct cpufreq_driver scpi_cpufreq_driver = { + .name = "scpi-cpufreq", + .flags = CPUFREQ_STICKY | CPUFREQ_HAVE_GOVERNOR_PER_POLICY | + CPUFREQ_NEED_INITIAL_FREQ_CHECK, + .verify = cpufreq_generic_frequency_table_verify, + .attr = cpufreq_generic_attr, + .get = scpi_cpufreq_get_rate, + .init = scpi_cpufreq_init, + .exit = scpi_cpufreq_exit, + .ready = scpi_cpufreq_ready, + .target_index = scpi_cpufreq_set_target, }; static int scpi_cpufreq_probe(struct platform_device *pdev) { + int ret; + scpi_ops = get_scpi_ops(); if (!scpi_ops) return -EIO; - return bL_cpufreq_register(&scpi_cpufreq_ops); + ret = cpufreq_register_driver(&scpi_cpufreq_driver); + if (ret) + dev_err(&pdev->dev, "%s: registering cpufreq failed, err: %d\n", + __func__, ret); + return ret; } static int scpi_cpufreq_remove(struct platform_device *pdev) { - bL_cpufreq_unregister(&scpi_cpufreq_ops); + cpufreq_unregister_driver(&scpi_cpufreq_driver); scpi_ops = NULL; return 0; }