* [PATCH v3] cpufreq: Add cpufreq driver for Freescale e500mc SoCs
@ 2013-03-29 5:52 ` Yuantian.Tang
0 siblings, 0 replies; 9+ messages in thread
From: Yuantian.Tang @ 2013-03-29 5:52 UTC (permalink / raw)
To: rjw
Cc: cpufreq, linux-pm, linuxppc-dev, viresh.kumar, Tang Yuantian,
Tang Yuantian, Li Yang
From: Tang Yuantian <yuantian.tang@freescale.com>
Add cpufreq driver for Freescale e500mc, e5500 and e6500 SoCs
which are capable of changing the frequency of CPU dynamically
Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
v3:
- change sizeof(struct name).. to sizeof(*p)
- remove the struct cpufreq_data, use global variable instead
- resolve setting policy->cpus incorrectly
- add CPUFREQ_POSTCHANGE notifier when setting frequency error
v2:
- add depends on OF and COMMON_CLK in Kconfig
- use clk.h instead of clk-provider.h
- change per_cpu variable from struct to pointer
drivers/cpufreq/Kconfig.powerpc | 10 ++
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/ppc-corenet-cpufreq.c | 247 ++++++++++++++++++++++++++++++++++
3 files changed, 258 insertions(+)
create mode 100644 drivers/cpufreq/ppc-corenet-cpufreq.c
diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc
index e76992f..3a0d8d0 100644
--- a/drivers/cpufreq/Kconfig.powerpc
+++ b/drivers/cpufreq/Kconfig.powerpc
@@ -5,3 +5,13 @@ config CPU_FREQ_MAPLE
help
This adds support for frequency switching on Maple 970FX
Evaluation Board and compatible boards (IBM JS2x blades).
+
+config PPC_CORENET_CPUFREQ
+ tristate "CPU frequency scaling driver for Freescale E500MC SoCs"
+ depends on PPC_E500MC && OF && COMMON_CLK
+ select CPU_FREQ_TABLE
+ select CLK_PPC_CORENET
+ help
+ This adds the CPUFreq driver support for Freescale e500mc,
+ e5500 and e6500 series SoCs which are capable of changing
+ the CPU's frequency dynamically.
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 863fd18..2416559 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -61,3 +61,4 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
##################################################################################
# PowerPC platform drivers
obj-$(CONFIG_CPU_FREQ_MAPLE) += maple-cpufreq.o
+obj-$(CONFIG_PPC_CORENET_CPUFREQ) += ppc-corenet-cpufreq.o
diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c
new file mode 100644
index 0000000..08e820ee
--- /dev/null
+++ b/drivers/cpufreq/ppc-corenet-cpufreq.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * CPU Frequency Scaling driver for Freescale PowerPC corenet SoCs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+/**
+ * struct cpu_data - per CPU data struct
+ * @clk: the clk of CPU
+ * @parent: the parent node of cpu clock
+ * @table: frequency table
+ */
+struct cpu_data {
+ struct clk *clk;
+ struct device_node *parent;
+ struct cpufreq_frequency_table *table;
+};
+
+/* serialize frequency changes */
+static DEFINE_MUTEX(cpufreq_lock);
+
+static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
+static unsigned int cpus_per_cluster;
+
+static unsigned int corenet_cpufreq_get_speed(unsigned int cpu)
+{
+ struct cpu_data *data = per_cpu(cpu_data, cpu);
+
+ return clk_get_rate(data->clk) / 1000;
+}
+
+/* reduce the duplicated frequency in frequency table */
+static void freq_table_redup(struct cpufreq_frequency_table *freq_table,
+ int count)
+{
+ int i, j;
+
+ for (i = 1; i < count; i++) {
+ for (j = 0; j < i; j++) {
+ if (freq_table[j].frequency == CPUFREQ_ENTRY_INVALID ||
+ freq_table[j].frequency !=
+ freq_table[i].frequency)
+ continue;
+
+ freq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ break;
+ }
+ }
+}
+
+static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+ struct device_node *np;
+ int i, count, ret;
+ struct clk *clk;
+ struct cpufreq_frequency_table *table;
+ struct cpu_data *data;
+ unsigned int cpu = policy->cpu;
+
+ np = of_get_cpu_node(cpu, NULL);
+ if (!np)
+ return -ENODEV;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->clk = of_clk_get(np, 0);
+ data->parent = of_parse_phandle(np, "clocks", 0);
+ if (!data->parent) {
+ pr_err("%s: could not get clock information\n", __func__);
+ goto err_nomem2;
+ }
+
+ count = of_property_count_strings(data->parent, "clock-names");
+ table = kcalloc(count + 1, sizeof(*table), GFP_KERNEL);
+ if (!table) {
+ pr_err("%s: no memory\n", __func__);
+ goto err_nomem2;
+ }
+
+ for (i = 0; i < count; i++) {
+ table[i].index = i;
+ clk = of_clk_get(data->parent, i);
+ table[i].frequency = clk_get_rate(clk) / 1000;
+ }
+ freq_table_redup(table, count);
+ table[i].frequency = CPUFREQ_TABLE_END;
+
+ /* set the min and max frequency properly */
+ ret = cpufreq_frequency_table_cpuinfo(policy, table);
+ if (ret) {
+ pr_err("invalid frequency table: %d\n", ret);
+ goto err_nomem1;
+ }
+
+ data->table = table;
+ per_cpu(cpu_data, cpu) = data;
+
+ /* align the cpu id with cluster if any */
+ i = (cpu / cpus_per_cluster) * cpus_per_cluster;
+ for (count = 0; count < cpus_per_cluster; count++)
+ cpumask_set_cpu(i + count, policy->cpus);
+
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ policy->cur = corenet_cpufreq_get_speed(policy->cpu);
+
+ cpufreq_frequency_table_get_attr(table, cpu);
+
+ return 0;
+
+err_nomem1:
+ kfree(table);
+err_nomem2:
+ per_cpu(cpu_data, cpu) = NULL;
+ kfree(data);
+
+ return -ENODEV;
+}
+
+static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+{
+ struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
+
+ cpufreq_frequency_table_put_attr(policy->cpu);
+ kfree(data->table);
+ kfree(data);
+
+ return 0;
+}
+
+static int corenet_cpufreq_verify(struct cpufreq_policy *policy)
+{
+ struct cpufreq_frequency_table *table =
+ per_cpu(cpu_data, policy->cpu)->table;
+
+ return cpufreq_frequency_table_verify(policy, table);
+}
+
+static int corenet_cpufreq_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ unsigned int new;
+ struct clk *parent;
+ int ret;
+ struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
+
+ cpufreq_frequency_table_target(policy, data->table,
+ target_freq, relation, &new);
+
+ if (policy->cur == data->table[new].frequency)
+ return 0;
+
+ freqs.old = policy->cur;
+ freqs.new = data->table[new].frequency;
+ freqs.cpu = policy->cpu;
+
+ mutex_lock(&cpufreq_lock);
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ parent = of_clk_get(data->parent, new);
+ ret = clk_set_parent(data->clk, parent);
+ if (ret) {
+ freqs.new = freqs.old;
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ mutex_unlock(&cpufreq_lock);
+ return ret;
+ }
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ mutex_unlock(&cpufreq_lock);
+
+ return 0;
+}
+
+static struct freq_attr *corenet_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
+ .name = "ppc_cpufreq",
+ .owner = THIS_MODULE,
+ .flags = CPUFREQ_CONST_LOOPS,
+ .init = corenet_cpufreq_cpu_init,
+ .exit = __exit_p(corenet_cpufreq_cpu_exit),
+ .verify = corenet_cpufreq_verify,
+ .target = corenet_cpufreq_target,
+ .get = corenet_cpufreq_get_speed,
+ .attr = corenet_cpufreq_attr,
+};
+
+static const struct of_device_id node_matches[] __initconst = {
+ { .compatible = "fsl,qoriq-clockgen-1.0", .data = (void *)1, },
+ { .compatible = "fsl,qoriq-clockgen-2", .data = (void *)8, },
+ {}
+};
+
+static int __init ppc_corenet_cpufreq_init(void)
+{
+ int ret = 0;
+ struct device_node *np;
+ const struct of_device_id *match;
+
+ np = of_find_matching_node(NULL, node_matches);
+ if (!np)
+ return -ENODEV;
+
+ match = of_match_node(node_matches, np);
+ cpus_per_cluster = (unsigned long)match->data;
+ of_node_put(np);
+
+ ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
+ if (!ret)
+ pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
+
+ return ret;
+}
+module_init(ppc_corenet_cpufreq_init);
+
+static void __exit ppc_corenet_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
+}
+module_exit(ppc_corenet_cpufreq_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
+MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series SoCs");
--
1.8.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3] cpufreq: Add cpufreq driver for Freescale e500mc SoCs
@ 2013-03-29 5:52 ` Yuantian.Tang
0 siblings, 0 replies; 9+ messages in thread
From: Yuantian.Tang @ 2013-03-29 5:52 UTC (permalink / raw)
To: rjw; +Cc: linux-pm, viresh.kumar, cpufreq, Tang Yuantian, linuxppc-dev
From: Tang Yuantian <yuantian.tang@freescale.com>
Add cpufreq driver for Freescale e500mc, e5500 and e6500 SoCs
which are capable of changing the frequency of CPU dynamically
Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
Signed-off-by: Li Yang <leoli@freescale.com>
---
v3:
- change sizeof(struct name).. to sizeof(*p)
- remove the struct cpufreq_data, use global variable instead
- resolve setting policy->cpus incorrectly
- add CPUFREQ_POSTCHANGE notifier when setting frequency error
v2:
- add depends on OF and COMMON_CLK in Kconfig
- use clk.h instead of clk-provider.h
- change per_cpu variable from struct to pointer
drivers/cpufreq/Kconfig.powerpc | 10 ++
drivers/cpufreq/Makefile | 1 +
drivers/cpufreq/ppc-corenet-cpufreq.c | 247 ++++++++++++++++++++++++++++++++++
3 files changed, 258 insertions(+)
create mode 100644 drivers/cpufreq/ppc-corenet-cpufreq.c
diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc
index e76992f..3a0d8d0 100644
--- a/drivers/cpufreq/Kconfig.powerpc
+++ b/drivers/cpufreq/Kconfig.powerpc
@@ -5,3 +5,13 @@ config CPU_FREQ_MAPLE
help
This adds support for frequency switching on Maple 970FX
Evaluation Board and compatible boards (IBM JS2x blades).
+
+config PPC_CORENET_CPUFREQ
+ tristate "CPU frequency scaling driver for Freescale E500MC SoCs"
+ depends on PPC_E500MC && OF && COMMON_CLK
+ select CPU_FREQ_TABLE
+ select CLK_PPC_CORENET
+ help
+ This adds the CPUFreq driver support for Freescale e500mc,
+ e5500 and e6500 series SoCs which are capable of changing
+ the CPU's frequency dynamically.
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 863fd18..2416559 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -61,3 +61,4 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
##################################################################################
# PowerPC platform drivers
obj-$(CONFIG_CPU_FREQ_MAPLE) += maple-cpufreq.o
+obj-$(CONFIG_PPC_CORENET_CPUFREQ) += ppc-corenet-cpufreq.o
diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c
new file mode 100644
index 0000000..08e820ee
--- /dev/null
+++ b/drivers/cpufreq/ppc-corenet-cpufreq.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * CPU Frequency Scaling driver for Freescale PowerPC corenet SoCs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+/**
+ * struct cpu_data - per CPU data struct
+ * @clk: the clk of CPU
+ * @parent: the parent node of cpu clock
+ * @table: frequency table
+ */
+struct cpu_data {
+ struct clk *clk;
+ struct device_node *parent;
+ struct cpufreq_frequency_table *table;
+};
+
+/* serialize frequency changes */
+static DEFINE_MUTEX(cpufreq_lock);
+
+static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
+static unsigned int cpus_per_cluster;
+
+static unsigned int corenet_cpufreq_get_speed(unsigned int cpu)
+{
+ struct cpu_data *data = per_cpu(cpu_data, cpu);
+
+ return clk_get_rate(data->clk) / 1000;
+}
+
+/* reduce the duplicated frequency in frequency table */
+static void freq_table_redup(struct cpufreq_frequency_table *freq_table,
+ int count)
+{
+ int i, j;
+
+ for (i = 1; i < count; i++) {
+ for (j = 0; j < i; j++) {
+ if (freq_table[j].frequency == CPUFREQ_ENTRY_INVALID ||
+ freq_table[j].frequency !=
+ freq_table[i].frequency)
+ continue;
+
+ freq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+ break;
+ }
+ }
+}
+
+static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+ struct device_node *np;
+ int i, count, ret;
+ struct clk *clk;
+ struct cpufreq_frequency_table *table;
+ struct cpu_data *data;
+ unsigned int cpu = policy->cpu;
+
+ np = of_get_cpu_node(cpu, NULL);
+ if (!np)
+ return -ENODEV;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->clk = of_clk_get(np, 0);
+ data->parent = of_parse_phandle(np, "clocks", 0);
+ if (!data->parent) {
+ pr_err("%s: could not get clock information\n", __func__);
+ goto err_nomem2;
+ }
+
+ count = of_property_count_strings(data->parent, "clock-names");
+ table = kcalloc(count + 1, sizeof(*table), GFP_KERNEL);
+ if (!table) {
+ pr_err("%s: no memory\n", __func__);
+ goto err_nomem2;
+ }
+
+ for (i = 0; i < count; i++) {
+ table[i].index = i;
+ clk = of_clk_get(data->parent, i);
+ table[i].frequency = clk_get_rate(clk) / 1000;
+ }
+ freq_table_redup(table, count);
+ table[i].frequency = CPUFREQ_TABLE_END;
+
+ /* set the min and max frequency properly */
+ ret = cpufreq_frequency_table_cpuinfo(policy, table);
+ if (ret) {
+ pr_err("invalid frequency table: %d\n", ret);
+ goto err_nomem1;
+ }
+
+ data->table = table;
+ per_cpu(cpu_data, cpu) = data;
+
+ /* align the cpu id with cluster if any */
+ i = (cpu / cpus_per_cluster) * cpus_per_cluster;
+ for (count = 0; count < cpus_per_cluster; count++)
+ cpumask_set_cpu(i + count, policy->cpus);
+
+ policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+ policy->cur = corenet_cpufreq_get_speed(policy->cpu);
+
+ cpufreq_frequency_table_get_attr(table, cpu);
+
+ return 0;
+
+err_nomem1:
+ kfree(table);
+err_nomem2:
+ per_cpu(cpu_data, cpu) = NULL;
+ kfree(data);
+
+ return -ENODEV;
+}
+
+static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+{
+ struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
+
+ cpufreq_frequency_table_put_attr(policy->cpu);
+ kfree(data->table);
+ kfree(data);
+
+ return 0;
+}
+
+static int corenet_cpufreq_verify(struct cpufreq_policy *policy)
+{
+ struct cpufreq_frequency_table *table =
+ per_cpu(cpu_data, policy->cpu)->table;
+
+ return cpufreq_frequency_table_verify(policy, table);
+}
+
+static int corenet_cpufreq_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ unsigned int new;
+ struct clk *parent;
+ int ret;
+ struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
+
+ cpufreq_frequency_table_target(policy, data->table,
+ target_freq, relation, &new);
+
+ if (policy->cur == data->table[new].frequency)
+ return 0;
+
+ freqs.old = policy->cur;
+ freqs.new = data->table[new].frequency;
+ freqs.cpu = policy->cpu;
+
+ mutex_lock(&cpufreq_lock);
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ parent = of_clk_get(data->parent, new);
+ ret = clk_set_parent(data->clk, parent);
+ if (ret) {
+ freqs.new = freqs.old;
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ mutex_unlock(&cpufreq_lock);
+ return ret;
+ }
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ mutex_unlock(&cpufreq_lock);
+
+ return 0;
+}
+
+static struct freq_attr *corenet_cpufreq_attr[] = {
+ &cpufreq_freq_attr_scaling_available_freqs,
+ NULL,
+};
+
+static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
+ .name = "ppc_cpufreq",
+ .owner = THIS_MODULE,
+ .flags = CPUFREQ_CONST_LOOPS,
+ .init = corenet_cpufreq_cpu_init,
+ .exit = __exit_p(corenet_cpufreq_cpu_exit),
+ .verify = corenet_cpufreq_verify,
+ .target = corenet_cpufreq_target,
+ .get = corenet_cpufreq_get_speed,
+ .attr = corenet_cpufreq_attr,
+};
+
+static const struct of_device_id node_matches[] __initconst = {
+ { .compatible = "fsl,qoriq-clockgen-1.0", .data = (void *)1, },
+ { .compatible = "fsl,qoriq-clockgen-2", .data = (void *)8, },
+ {}
+};
+
+static int __init ppc_corenet_cpufreq_init(void)
+{
+ int ret = 0;
+ struct device_node *np;
+ const struct of_device_id *match;
+
+ np = of_find_matching_node(NULL, node_matches);
+ if (!np)
+ return -ENODEV;
+
+ match = of_match_node(node_matches, np);
+ cpus_per_cluster = (unsigned long)match->data;
+ of_node_put(np);
+
+ ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
+ if (!ret)
+ pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
+
+ return ret;
+}
+module_init(ppc_corenet_cpufreq_init);
+
+static void __exit ppc_corenet_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
+}
+module_exit(ppc_corenet_cpufreq_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
+MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series SoCs");
--
1.8.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v3] cpufreq: Add cpufreq driver for Freescale e500mc SoCs
2013-03-29 5:52 ` Yuantian.Tang
@ 2013-03-29 7:17 ` Viresh Kumar
-1 siblings, 0 replies; 9+ messages in thread
From: Viresh Kumar @ 2013-03-29 7:17 UTC (permalink / raw)
To: Yuantian.Tang; +Cc: rjw, cpufreq, linux-pm, linuxppc-dev, Li Yang
On 29 March 2013 11:22, <Yuantian.Tang@freescale.com> wrote:
> diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c
> +
Add following here for better debug prints (sorry, i should have done
it earlier)
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +#include <linux/clk.h>
> +#include <linux/cpu.h>
> +#include <linux/cpufreq.h>
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of.h>
> +#include <linux/slab.h>
> +#include <linux/types.h>
> +
> +static unsigned int cpus_per_cluster;
remove tab with space after int.
> +static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> +{
> + struct device_node *np;
> + int i, count, ret;
> + struct clk *clk;
> + struct cpufreq_frequency_table *table;
> + struct cpu_data *data;
> + unsigned int cpu = policy->cpu;
> +
> + np = of_get_cpu_node(cpu, NULL);
> + if (!np)
> + return -ENODEV;
> +
> + data = kzalloc(sizeof(*data), GFP_KERNEL);
> + if (!data)
> + return -ENOMEM;
> +
> + data->clk = of_clk_get(np, 0);
what if this fails?
> + /* align the cpu id with cluster if any */
> + i = (cpu / cpus_per_cluster) * cpus_per_cluster;
> + for (count = 0; count < cpus_per_cluster; count++)
> + cpumask_set_cpu(i + count, policy->cpus);
Better than before but i still see some regression with it :)
What if cpu order in DT is changed a bit and so cpus boot with following
order: 0 1 3 5 7 2 6 4
And so you will end up grouping 0135 and 7264 :)
See if topology_core_cpumask() gives you correct pairs.
> +static int corenet_cpufreq_target(struct cpufreq_policy *policy,
> + unsigned int target_freq, unsigned int relation)
> +{
> + struct cpufreq_freqs freqs;
> + unsigned int new;
> + struct clk *parent;
> + int ret;
> + struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
> +
> + cpufreq_frequency_table_target(policy, data->table,
> + target_freq, relation, &new);
> +
> + if (policy->cur == data->table[new].frequency)
> + return 0;
> +
> + freqs.old = policy->cur;
> + freqs.new = data->table[new].frequency;
> + freqs.cpu = policy->cpu;
> +
> + mutex_lock(&cpufreq_lock);
> + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
What i wanted here from you was:
for_each_cpu(freqs.cpu, policy->cpus)
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
Which would be fixed later by my patch, but until then you must have correct
code in your driver. What if my patchset is rejected :)
Mostly good now. Probably V4 would be the last one :)
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3] cpufreq: Add cpufreq driver for Freescale e500mc SoCs
@ 2013-03-29 7:17 ` Viresh Kumar
0 siblings, 0 replies; 9+ messages in thread
From: Viresh Kumar @ 2013-03-29 7:17 UTC (permalink / raw)
To: Yuantian.Tang; +Cc: rjw, linuxppc-dev, cpufreq, linux-pm
On 29 March 2013 11:22, <Yuantian.Tang@freescale.com> wrote:
> diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c
> +
Add following here for better debug prints (sorry, i should have done
it earlier)
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +#include <linux/clk.h>
> +#include <linux/cpu.h>
> +#include <linux/cpufreq.h>
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/mutex.h>
> +#include <linux/of.h>
> +#include <linux/slab.h>
> +#include <linux/types.h>
> +
> +static unsigned int cpus_per_cluster;
remove tab with space after int.
> +static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> +{
> + struct device_node *np;
> + int i, count, ret;
> + struct clk *clk;
> + struct cpufreq_frequency_table *table;
> + struct cpu_data *data;
> + unsigned int cpu = policy->cpu;
> +
> + np = of_get_cpu_node(cpu, NULL);
> + if (!np)
> + return -ENODEV;
> +
> + data = kzalloc(sizeof(*data), GFP_KERNEL);
> + if (!data)
> + return -ENOMEM;
> +
> + data->clk = of_clk_get(np, 0);
what if this fails?
> + /* align the cpu id with cluster if any */
> + i = (cpu / cpus_per_cluster) * cpus_per_cluster;
> + for (count = 0; count < cpus_per_cluster; count++)
> + cpumask_set_cpu(i + count, policy->cpus);
Better than before but i still see some regression with it :)
What if cpu order in DT is changed a bit and so cpus boot with following
order: 0 1 3 5 7 2 6 4
And so you will end up grouping 0135 and 7264 :)
See if topology_core_cpumask() gives you correct pairs.
> +static int corenet_cpufreq_target(struct cpufreq_policy *policy,
> + unsigned int target_freq, unsigned int relation)
> +{
> + struct cpufreq_freqs freqs;
> + unsigned int new;
> + struct clk *parent;
> + int ret;
> + struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
> +
> + cpufreq_frequency_table_target(policy, data->table,
> + target_freq, relation, &new);
> +
> + if (policy->cur == data->table[new].frequency)
> + return 0;
> +
> + freqs.old = policy->cur;
> + freqs.new = data->table[new].frequency;
> + freqs.cpu = policy->cpu;
> +
> + mutex_lock(&cpufreq_lock);
> + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
What i wanted here from you was:
for_each_cpu(freqs.cpu, policy->cpus)
cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
Which would be fixed later by my patch, but until then you must have correct
code in your driver. What if my patchset is rejected :)
Mostly good now. Probably V4 would be the last one :)
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3] cpufreq: Add cpufreq driver for Freescale e500mc SoCs
2013-03-29 5:52 ` Yuantian.Tang
@ 2013-03-30 13:52 ` Viresh Kumar
-1 siblings, 0 replies; 9+ messages in thread
From: Viresh Kumar @ 2013-03-30 13:52 UTC (permalink / raw)
To: Yuantian.Tang
Cc: Rafael J. Wysocki, cpufreq, Linux PM list, linuxppc-dev, Li Yang
On Fri, Mar 29, 2013 at 11:22 AM, <Yuantian.Tang@freescale.com> wrote:
> diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c
> +static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> +{
> + for (i = 0; i < count; i++) {
> + table[i].index = i;
One more thing, you don't need to set index at all as you aren't using it.
And cpufreq core never uses it.
> + clk = of_clk_get(data->parent, i);
> + table[i].frequency = clk_get_rate(clk) / 1000;
> + }
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v3] cpufreq: Add cpufreq driver for Freescale e500mc SoCs
@ 2013-03-30 13:52 ` Viresh Kumar
0 siblings, 0 replies; 9+ messages in thread
From: Viresh Kumar @ 2013-03-30 13:52 UTC (permalink / raw)
To: Yuantian.Tang; +Cc: Rafael J. Wysocki, linuxppc-dev, cpufreq, Linux PM list
On Fri, Mar 29, 2013 at 11:22 AM, <Yuantian.Tang@freescale.com> wrote:
> diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/ppc-corenet-cpufreq.c
> +static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> +{
> + for (i = 0; i < count; i++) {
> + table[i].index = i;
One more thing, you don't need to set index at all as you aren't using it.
And cpufreq core never uses it.
> + clk = of_clk_get(data->parent, i);
> + table[i].frequency = clk_get_rate(clk) / 1000;
> + }
^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [PATCH v3] cpufreq: Add cpufreq driver for Freescale e500mc SoCs
2013-03-30 13:52 ` Viresh Kumar
(?)
@ 2013-04-01 2:16 ` Tang Yuantian-B29983
-1 siblings, 0 replies; 9+ messages in thread
From: Tang Yuantian-B29983 @ 2013-04-01 2:16 UTC (permalink / raw)
To: Viresh Kumar
Cc: Rafael J. Wysocki, cpufreq, Linux PM list, linuxppc-dev, Li Yang-R58472
> -----Original Message-----
> From: cpufreq-owner@vger.kernel.org [mailto:cpufreq-owner@vger.kernel.org]
> On Behalf Of Viresh Kumar
> Sent: 2013年3月30日 21:52
> To: Tang Yuantian-B29983
> Cc: Rafael J. Wysocki; cpufreq@vger.kernel.org; Linux PM list; linuxppc-
> dev@lists.ozlabs.org; Li Yang-R58472
> Subject: Re: [PATCH v3] cpufreq: Add cpufreq driver for Freescale e500mc
> SoCs
>
> On Fri, Mar 29, 2013 at 11:22 AM, <Yuantian.Tang@freescale.com> wrote:
> > diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c
> > b/drivers/cpufreq/ppc-corenet-cpufreq.c
>
> > +static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) {
>
> > + for (i = 0; i < count; i++) {
> > + table[i].index = i;
>
> One more thing, you don't need to set index at all as you aren't using it.
> And cpufreq core never uses it.
>
OK, no problem.
Thanks,
Yuantian
> > + clk = of_clk_get(data->parent, i);
> > + table[i].frequency = clk_get_rate(clk) / 1000;
> > + }
> --
> To unsubscribe from this list: send the line "unsubscribe cpufreq" in the
> body of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [PATCH v3] cpufreq: Add cpufreq driver for Freescale e500mc SoCs
@ 2013-04-01 2:16 ` Tang Yuantian-B29983
0 siblings, 0 replies; 9+ messages in thread
From: Tang Yuantian-B29983 @ 2013-04-01 2:16 UTC (permalink / raw)
To: Viresh Kumar
Cc: Rafael J. Wysocki, linuxppc-dev, Li Yang-R58472, cpufreq, Linux PM list
DQo+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+IEZyb206IGNwdWZyZXEtb3duZXJAdmdl
ci5rZXJuZWwub3JnIFttYWlsdG86Y3B1ZnJlcS1vd25lckB2Z2VyLmtlcm5lbC5vcmddDQo+IE9u
IEJlaGFsZiBPZiBWaXJlc2ggS3VtYXINCj4gU2VudDogMjAxM8TqM9TCMzDI1SAyMTo1Mg0KPiBU
bzogVGFuZyBZdWFudGlhbi1CMjk5ODMNCj4gQ2M6IFJhZmFlbCBKLiBXeXNvY2tpOyBjcHVmcmVx
QHZnZXIua2VybmVsLm9yZzsgTGludXggUE0gbGlzdDsgbGludXhwcGMtDQo+IGRldkBsaXN0cy5v
emxhYnMub3JnOyBMaSBZYW5nLVI1ODQ3Mg0KPiBTdWJqZWN0OiBSZTogW1BBVENIIHYzXSBjcHVm
cmVxOiBBZGQgY3B1ZnJlcSBkcml2ZXIgZm9yIEZyZWVzY2FsZSBlNTAwbWMNCj4gU29Dcw0KPiAN
Cj4gT24gRnJpLCBNYXIgMjksIDIwMTMgYXQgMTE6MjIgQU0sICA8WXVhbnRpYW4uVGFuZ0BmcmVl
c2NhbGUuY29tPiB3cm90ZToNCj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9jcHVmcmVxL3BwYy1j
b3JlbmV0LWNwdWZyZXEuYw0KPiA+IGIvZHJpdmVycy9jcHVmcmVxL3BwYy1jb3JlbmV0LWNwdWZy
ZXEuYw0KPiANCj4gPiArc3RhdGljIGludCBjb3JlbmV0X2NwdWZyZXFfY3B1X2luaXQoc3RydWN0
IGNwdWZyZXFfcG9saWN5ICpwb2xpY3kpIHsNCj4gDQo+ID4gKyAgICAgICBmb3IgKGkgPSAwOyBp
IDwgY291bnQ7IGkrKykgew0KPiA+ICsgICAgICAgICAgICAgICB0YWJsZVtpXS5pbmRleCA9IGk7
DQo+IA0KPiBPbmUgbW9yZSB0aGluZywgeW91IGRvbid0IG5lZWQgdG8gc2V0IGluZGV4IGF0IGFs
bCBhcyB5b3UgYXJlbid0IHVzaW5nIGl0Lg0KPiBBbmQgY3B1ZnJlcSBjb3JlIG5ldmVyIHVzZXMg
aXQuDQo+IA0KT0ssIG5vIHByb2JsZW0uDQoNClRoYW5rcywNCll1YW50aWFuDQoNCj4gPiArICAg
ICAgICAgICAgICAgY2xrID0gb2ZfY2xrX2dldChkYXRhLT5wYXJlbnQsIGkpOw0KPiA+ICsgICAg
ICAgICAgICAgICB0YWJsZVtpXS5mcmVxdWVuY3kgPSBjbGtfZ2V0X3JhdGUoY2xrKSAvIDEwMDA7
DQo+ID4gKyAgICAgICB9DQo+IC0tDQo+IFRvIHVuc3Vic2NyaWJlIGZyb20gdGhpcyBsaXN0OiBz
ZW5kIHRoZSBsaW5lICJ1bnN1YnNjcmliZSBjcHVmcmVxIiBpbiB0aGUNCj4gYm9keSBvZiBhIG1l
c3NhZ2UgdG8gbWFqb3Jkb21vQHZnZXIua2VybmVsLm9yZyBNb3JlIG1ham9yZG9tbyBpbmZvIGF0
DQo+IGh0dHA6Ly92Z2VyLmtlcm5lbC5vcmcvbWFqb3Jkb21vLWluZm8uaHRtbA0KDQo=
^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: [PATCH v3] cpufreq: Add cpufreq driver for Freescale e500mc SoCs
@ 2013-04-01 2:16 ` Tang Yuantian-B29983
0 siblings, 0 replies; 9+ messages in thread
From: Tang Yuantian-B29983 @ 2013-04-01 2:16 UTC (permalink / raw)
To: Viresh Kumar
Cc: Rafael J. Wysocki, cpufreq, Linux PM list, linuxppc-dev, Li Yang-R58472
> -----Original Message-----
> From: cpufreq-owner@vger.kernel.org [mailto:cpufreq-owner@vger.kernel.org]
> On Behalf Of Viresh Kumar
> Sent: 2013Äê3ÔÂ30ÈÕ 21:52
> To: Tang Yuantian-B29983
> Cc: Rafael J. Wysocki; cpufreq@vger.kernel.org; Linux PM list; linuxppc-
> dev@lists.ozlabs.org; Li Yang-R58472
> Subject: Re: [PATCH v3] cpufreq: Add cpufreq driver for Freescale e500mc
> SoCs
>
> On Fri, Mar 29, 2013 at 11:22 AM, <Yuantian.Tang@freescale.com> wrote:
> > diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c
> > b/drivers/cpufreq/ppc-corenet-cpufreq.c
>
> > +static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy) {
>
> > + for (i = 0; i < count; i++) {
> > + table[i].index = i;
>
> One more thing, you don't need to set index at all as you aren't using it.
> And cpufreq core never uses it.
>
OK, no problem.
Thanks,
Yuantian
> > + clk = of_clk_get(data->parent, i);
> > + table[i].frequency = clk_get_rate(clk) / 1000;
> > + }
> --
> To unsubscribe from this list: send the line "unsubscribe cpufreq" in the
> body of a message to majordomo@vger.kernel.org More majordomo info at
> http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2013-04-01 2:17 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-29 5:52 [PATCH v3] cpufreq: Add cpufreq driver for Freescale e500mc SoCs Yuantian.Tang
2013-03-29 5:52 ` Yuantian.Tang
2013-03-29 7:17 ` Viresh Kumar
2013-03-29 7:17 ` Viresh Kumar
2013-03-30 13:52 ` Viresh Kumar
2013-03-30 13:52 ` Viresh Kumar
2013-04-01 2:16 ` Tang Yuantian-B29983
2013-04-01 2:16 ` Tang Yuantian-B29983
2013-04-01 2:16 ` Tang Yuantian-B29983
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.