All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-10-17  3:13 ` B29983
  0 siblings, 0 replies; 29+ messages in thread
From: B29983 @ 2014-10-17  3:13 UTC (permalink / raw)
  To: rjw, viresh.kumar; +Cc: linux-kernel, linux-pm, linuxppc-dev, Tang Yuantian

From: Tang Yuantian <Yuantian.Tang@freescale.com>

Freescale introduced new ARM core-based SoCs which support dynamic
frequency switch feature. DFS on new SoCs are compatible with current
PowerPC CoreNet platforms. In order to support those new platforms,
this driver needs to be slightly adjusted. The main changes include:

1. Changed the names of driver and functions in driver.
2. Added two new functions get_cpu_physical_id() and get_bus_freq().
3. Used a new way to get all the CPUs which sharing clock wire.

Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
---
 drivers/cpufreq/Kconfig.arm                        |   8 ++
 drivers/cpufreq/Kconfig.powerpc                    |  11 +-
 drivers/cpufreq/Makefile                           |   2 +-
 .../{ppc-corenet-cpufreq.c => qoriq-cpufreq.c}     | 150 ++++++++++++++-------
 4 files changed, 114 insertions(+), 57 deletions(-)
 rename drivers/cpufreq/{ppc-corenet-cpufreq.c => qoriq-cpufreq.c} (72%)

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 83a75dc..1925ae94 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -247,3 +247,11 @@ config ARM_TEGRA_CPUFREQ
 	default y
 	help
 	  This adds the CPUFreq driver support for TEGRA SOCs.
+
+config QORIQ_CPUFREQ
+	tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
+	depends on OF && COMMON_CLK
+	select CLK_PPC_CORENET
+	help
+	  This adds the CPUFreq driver support for Freescale QorIQ SoCs
+	  which are capable of changing the CPU's frequency dynamically.
diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc
index 72564b7..3a34248 100644
--- a/drivers/cpufreq/Kconfig.powerpc
+++ b/drivers/cpufreq/Kconfig.powerpc
@@ -23,14 +23,13 @@ config CPU_FREQ_MAPLE
 	  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
+config QORIQ_CPUFREQ
+	tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
+	depends on OF && COMMON_CLK
 	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.
+	  This adds the CPUFreq driver support for Freescale QorIQ SoCs
+	  which are capable of changing the CPU's frequency dynamically.
 
 config CPU_FREQ_PMAC
 	bool "Support for Apple PowerBooks"
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 40c53dc..0020049 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -84,7 +84,7 @@ obj-$(CONFIG_CPU_FREQ_CBE)		+= ppc-cbe-cpufreq.o
 ppc-cbe-cpufreq-y			+= ppc_cbe_cpufreq_pervasive.o ppc_cbe_cpufreq.o
 obj-$(CONFIG_CPU_FREQ_CBE_PMI)		+= ppc_cbe_cpufreq_pmi.o
 obj-$(CONFIG_CPU_FREQ_MAPLE)		+= maple-cpufreq.o
-obj-$(CONFIG_PPC_CORENET_CPUFREQ)   += ppc-corenet-cpufreq.o
+obj-$(CONFIG_QORIQ_CPUFREQ)   		+= qoriq-cpufreq.o
 obj-$(CONFIG_CPU_FREQ_PMAC)		+= pmac32-cpufreq.o
 obj-$(CONFIG_CPU_FREQ_PMAC64)		+= pmac64-cpufreq.o
 obj-$(CONFIG_PPC_PASEMI_CPUFREQ)	+= pasemi-cpufreq.o
diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c
similarity index 72%
rename from drivers/cpufreq/ppc-corenet-cpufreq.c
rename to drivers/cpufreq/qoriq-cpufreq.c
index bee5df7..80def0c 100644
--- a/drivers/cpufreq/ppc-corenet-cpufreq.c
+++ b/drivers/cpufreq/qoriq-cpufreq.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2013 Freescale Semiconductor, Inc.
  *
- * CPU Frequency Scaling driver for Freescale PowerPC corenet SoCs.
+ * CPU Frequency Scaling driver for Freescale QorIQ 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
@@ -20,7 +20,6 @@
 #include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/smp.h>
-#include <sysdev/fsl_soc.h>
 
 /**
  * struct cpu_data - per CPU data struct
@@ -69,9 +68,6 @@ static const u32 *fmask;
 
 static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
 
-/* cpumask in a cluster */
-static DEFINE_PER_CPU(cpumask_var_t, cpu_mask);
-
 #ifndef CONFIG_SMP
 static inline const struct cpumask *cpu_core_mask(int cpu)
 {
@@ -79,6 +75,79 @@ static inline const struct cpumask *cpu_core_mask(int cpu)
 }
 #endif
 
+#if defined(CONFIG_PPC_E500MC)
+static int get_cpu_physical_id(int cpu)
+{
+	return get_hard_smp_processor_id(cpu);
+}
+#elif defined(CONFIG_ARM)
+static int get_cpu_physical_id(int cpu)
+{
+	return topology_core_id(cpu);
+}
+#endif
+
+static u32 get_bus_freq(void)
+{
+	struct device_node *soc;
+	u32 sysfreq;
+
+	soc = of_find_node_by_type(NULL, "soc");
+	if (!soc)
+		return 0;
+
+	if (of_property_read_u32(soc, "bus-frequency", &sysfreq))
+		sysfreq = 0;
+
+	of_node_put(soc);
+
+	return sysfreq;
+}
+
+static struct device_node *cpu_to_clk_node(int cpu)
+{
+	struct device_node *np, *clk_np;
+
+	if (!cpu_present(cpu))
+		return NULL;
+
+	np = of_get_cpu_node(cpu, NULL);
+	if (!np)
+		return NULL;
+
+	clk_np = of_parse_phandle(np, "clocks", 0);
+	if (!clk_np)
+		return NULL;
+
+	of_node_put(np);
+
+	return clk_np;
+}
+
+/* traverse cpu nodes to get cpu mask of sharing clock wire */
+static void set_affected_cpus(struct cpufreq_policy *policy)
+{
+	struct device_node *np, *clk_np;
+	struct cpumask *dstp = policy->cpus;
+	int i;
+
+	np = cpu_to_clk_node(policy->cpu);
+	if (!np)
+		return;
+
+	for_each_present_cpu(i) {
+		clk_np = cpu_to_clk_node(i);
+		if (!clk_np)
+			continue;
+
+		if (clk_np == np)
+			cpumask_set_cpu(i, dstp);
+
+		of_node_put(clk_np);
+	}
+	of_node_put(np);
+}
+
 /* reduce the duplicated frequencies in frequency table */
 static void freq_table_redup(struct cpufreq_frequency_table *freq_table,
 		int count)
@@ -105,6 +174,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
 	int i, j, ind;
 	unsigned int freq, max_freq;
 	struct cpufreq_frequency_table table;
+
 	for (i = 0; i < count - 1; i++) {
 		max_freq = freq_table[i].frequency;
 		ind = i;
@@ -129,7 +199,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
 	}
 }
 
-static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
+static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
 {
 	struct device_node *np;
 	int i, count, ret;
@@ -145,10 +215,8 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
 		return -ENODEV;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
-	if (!data) {
-		pr_err("%s: no memory\n", __func__);
+	if (!data)
 		goto err_np;
-	}
 
 	policy->clk = of_clk_get(np, 0);
 	if (IS_ERR(policy->clk)) {
@@ -170,7 +238,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	}
 
 	if (fmask)
-		mask = fmask[get_hard_smp_processor_id(cpu)];
+		mask = fmask[get_cpu_physical_id(cpu)];
 	else
 		mask = 0x0;
 
@@ -201,13 +269,13 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	data->table = table;
 
 	/* update ->cpus if we have cluster, no harm if not */
-	cpumask_copy(policy->cpus, per_cpu(cpu_mask, cpu));
-	for_each_cpu(i, per_cpu(cpu_mask, cpu))
+	set_affected_cpus(policy);
+	for_each_cpu(i, policy->cpus)
 		per_cpu(cpu_data, i) = data;
 
 	/* Minimum transition latency is 12 platform clocks */
 	u64temp = 12ULL * NSEC_PER_SEC;
-	do_div(u64temp, fsl_get_sys_freq());
+	do_div(u64temp, get_bus_freq());
 	policy->cpuinfo.transition_latency = u64temp + 1;
 
 	of_node_put(np);
@@ -227,7 +295,7 @@ err_np:
 	return -ENODEV;
 }
 
-static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy *policy)
 {
 	struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
 	unsigned int cpu;
@@ -236,13 +304,13 @@ static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
 	kfree(data->table);
 	kfree(data);
 
-	for_each_cpu(cpu, per_cpu(cpu_mask, policy->cpu))
+	for_each_cpu(cpu, policy->cpus)
 		per_cpu(cpu_data, cpu) = NULL;
 
 	return 0;
 }
 
-static int corenet_cpufreq_target(struct cpufreq_policy *policy,
+static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
 		unsigned int index)
 {
 	struct clk *parent;
@@ -252,18 +320,18 @@ static int corenet_cpufreq_target(struct cpufreq_policy *policy,
 	return clk_set_parent(policy->clk, parent);
 }
 
-static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
-	.name		= "ppc_cpufreq",
+static struct cpufreq_driver qoriq_cpufreq_driver = {
+	.name		= "qoriq_cpufreq",
 	.flags		= CPUFREQ_CONST_LOOPS,
-	.init		= corenet_cpufreq_cpu_init,
-	.exit		= __exit_p(corenet_cpufreq_cpu_exit),
+	.init		= qoriq_cpufreq_cpu_init,
+	.exit		= __exit_p(qoriq_cpufreq_cpu_exit),
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target_index	= corenet_cpufreq_target,
+	.target_index	= qoriq_cpufreq_target,
 	.get		= cpufreq_generic_get,
 	.attr		= cpufreq_generic_attr,
 };
 
-static const struct of_device_id node_matches[] __initdata = {
+static const struct of_device_id node_matches[] __initconst = {
 	{ .compatible = "fsl,p2041-clockgen", .data = &sdata[0], },
 	{ .compatible = "fsl,p3041-clockgen", .data = &sdata[0], },
 	{ .compatible = "fsl,p5020-clockgen", .data = &sdata[1], },
@@ -273,61 +341,43 @@ static const struct of_device_id node_matches[] __initdata = {
 	{}
 };
 
-static int __init ppc_corenet_cpufreq_init(void)
+static int __init qoriq_cpufreq_init(void)
 {
 	int ret;
 	struct device_node  *np;
 	const struct of_device_id *match;
 	const struct soc_data *data;
-	unsigned int cpu;
 
 	np = of_find_matching_node(NULL, node_matches);
 	if (!np)
 		return -ENODEV;
 
-	for_each_possible_cpu(cpu) {
-		if (!alloc_cpumask_var(&per_cpu(cpu_mask, cpu), GFP_KERNEL))
-			goto err_mask;
-		cpumask_copy(per_cpu(cpu_mask, cpu), cpu_core_mask(cpu));
-	}
-
 	match = of_match_node(node_matches, np);
 	data = match->data;
 	if (data) {
 		if (data->flag)
 			fmask = data->freq_mask;
-		min_cpufreq = fsl_get_sys_freq();
+		min_cpufreq = get_bus_freq();
 	} else {
-		min_cpufreq = fsl_get_sys_freq() / 2;
+		min_cpufreq = get_bus_freq() / 2;
 	}
 
 	of_node_put(np);
 
-	ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
+	ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
 	if (!ret)
-		pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
+		pr_info("Freescale QorIQ CPU frequency scaling driver\n");
 
 	return ret;
-
-err_mask:
-	for_each_possible_cpu(cpu)
-		free_cpumask_var(per_cpu(cpu_mask, cpu));
-
-	return -ENOMEM;
 }
-module_init(ppc_corenet_cpufreq_init);
+module_init(qoriq_cpufreq_init);
 
-static void __exit ppc_corenet_cpufreq_exit(void)
+static void __exit qoriq_cpufreq_exit(void)
 {
-	unsigned int cpu;
-
-	for_each_possible_cpu(cpu)
-		free_cpumask_var(per_cpu(cpu_mask, cpu));
-
-	cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
+	cpufreq_unregister_driver(&qoriq_cpufreq_driver);
 }
-module_exit(ppc_corenet_cpufreq_exit);
+module_exit(qoriq_cpufreq_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
-MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series SoCs");
+MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs");
-- 
2.1.0.27.g96db324


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-10-17  3:13 ` B29983
  0 siblings, 0 replies; 29+ messages in thread
From: B29983 @ 2014-10-17  3:13 UTC (permalink / raw)
  To: rjw, viresh.kumar; +Cc: linux-kernel, linux-pm, linuxppc-dev, Tang Yuantian

From: Tang Yuantian <Yuantian.Tang@freescale.com>

Freescale introduced new ARM core-based SoCs which support dynamic
frequency switch feature. DFS on new SoCs are compatible with current
PowerPC CoreNet platforms. In order to support those new platforms,
this driver needs to be slightly adjusted. The main changes include:

1. Changed the names of driver and functions in driver.
2. Added two new functions get_cpu_physical_id() and get_bus_freq().
3. Used a new way to get all the CPUs which sharing clock wire.

Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
---
 drivers/cpufreq/Kconfig.arm                        |   8 ++
 drivers/cpufreq/Kconfig.powerpc                    |  11 +-
 drivers/cpufreq/Makefile                           |   2 +-
 .../{ppc-corenet-cpufreq.c => qoriq-cpufreq.c}     | 150 ++++++++++++++-------
 4 files changed, 114 insertions(+), 57 deletions(-)
 rename drivers/cpufreq/{ppc-corenet-cpufreq.c => qoriq-cpufreq.c} (72%)

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 83a75dc..1925ae94 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -247,3 +247,11 @@ config ARM_TEGRA_CPUFREQ
 	default y
 	help
 	  This adds the CPUFreq driver support for TEGRA SOCs.
+
+config QORIQ_CPUFREQ
+	tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
+	depends on OF && COMMON_CLK
+	select CLK_PPC_CORENET
+	help
+	  This adds the CPUFreq driver support for Freescale QorIQ SoCs
+	  which are capable of changing the CPU's frequency dynamically.
diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc
index 72564b7..3a34248 100644
--- a/drivers/cpufreq/Kconfig.powerpc
+++ b/drivers/cpufreq/Kconfig.powerpc
@@ -23,14 +23,13 @@ config CPU_FREQ_MAPLE
 	  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
+config QORIQ_CPUFREQ
+	tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
+	depends on OF && COMMON_CLK
 	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.
+	  This adds the CPUFreq driver support for Freescale QorIQ SoCs
+	  which are capable of changing the CPU's frequency dynamically.
 
 config CPU_FREQ_PMAC
 	bool "Support for Apple PowerBooks"
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 40c53dc..0020049 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -84,7 +84,7 @@ obj-$(CONFIG_CPU_FREQ_CBE)		+= ppc-cbe-cpufreq.o
 ppc-cbe-cpufreq-y			+= ppc_cbe_cpufreq_pervasive.o ppc_cbe_cpufreq.o
 obj-$(CONFIG_CPU_FREQ_CBE_PMI)		+= ppc_cbe_cpufreq_pmi.o
 obj-$(CONFIG_CPU_FREQ_MAPLE)		+= maple-cpufreq.o
-obj-$(CONFIG_PPC_CORENET_CPUFREQ)   += ppc-corenet-cpufreq.o
+obj-$(CONFIG_QORIQ_CPUFREQ)   		+= qoriq-cpufreq.o
 obj-$(CONFIG_CPU_FREQ_PMAC)		+= pmac32-cpufreq.o
 obj-$(CONFIG_CPU_FREQ_PMAC64)		+= pmac64-cpufreq.o
 obj-$(CONFIG_PPC_PASEMI_CPUFREQ)	+= pasemi-cpufreq.o
diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c
similarity index 72%
rename from drivers/cpufreq/ppc-corenet-cpufreq.c
rename to drivers/cpufreq/qoriq-cpufreq.c
index bee5df7..80def0c 100644
--- a/drivers/cpufreq/ppc-corenet-cpufreq.c
+++ b/drivers/cpufreq/qoriq-cpufreq.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2013 Freescale Semiconductor, Inc.
  *
- * CPU Frequency Scaling driver for Freescale PowerPC corenet SoCs.
+ * CPU Frequency Scaling driver for Freescale QorIQ 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
@@ -20,7 +20,6 @@
 #include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/smp.h>
-#include <sysdev/fsl_soc.h>
 
 /**
  * struct cpu_data - per CPU data struct
@@ -69,9 +68,6 @@ static const u32 *fmask;
 
 static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
 
-/* cpumask in a cluster */
-static DEFINE_PER_CPU(cpumask_var_t, cpu_mask);
-
 #ifndef CONFIG_SMP
 static inline const struct cpumask *cpu_core_mask(int cpu)
 {
@@ -79,6 +75,79 @@ static inline const struct cpumask *cpu_core_mask(int cpu)
 }
 #endif
 
+#if defined(CONFIG_PPC_E500MC)
+static int get_cpu_physical_id(int cpu)
+{
+	return get_hard_smp_processor_id(cpu);
+}
+#elif defined(CONFIG_ARM)
+static int get_cpu_physical_id(int cpu)
+{
+	return topology_core_id(cpu);
+}
+#endif
+
+static u32 get_bus_freq(void)
+{
+	struct device_node *soc;
+	u32 sysfreq;
+
+	soc = of_find_node_by_type(NULL, "soc");
+	if (!soc)
+		return 0;
+
+	if (of_property_read_u32(soc, "bus-frequency", &sysfreq))
+		sysfreq = 0;
+
+	of_node_put(soc);
+
+	return sysfreq;
+}
+
+static struct device_node *cpu_to_clk_node(int cpu)
+{
+	struct device_node *np, *clk_np;
+
+	if (!cpu_present(cpu))
+		return NULL;
+
+	np = of_get_cpu_node(cpu, NULL);
+	if (!np)
+		return NULL;
+
+	clk_np = of_parse_phandle(np, "clocks", 0);
+	if (!clk_np)
+		return NULL;
+
+	of_node_put(np);
+
+	return clk_np;
+}
+
+/* traverse cpu nodes to get cpu mask of sharing clock wire */
+static void set_affected_cpus(struct cpufreq_policy *policy)
+{
+	struct device_node *np, *clk_np;
+	struct cpumask *dstp = policy->cpus;
+	int i;
+
+	np = cpu_to_clk_node(policy->cpu);
+	if (!np)
+		return;
+
+	for_each_present_cpu(i) {
+		clk_np = cpu_to_clk_node(i);
+		if (!clk_np)
+			continue;
+
+		if (clk_np == np)
+			cpumask_set_cpu(i, dstp);
+
+		of_node_put(clk_np);
+	}
+	of_node_put(np);
+}
+
 /* reduce the duplicated frequencies in frequency table */
 static void freq_table_redup(struct cpufreq_frequency_table *freq_table,
 		int count)
@@ -105,6 +174,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
 	int i, j, ind;
 	unsigned int freq, max_freq;
 	struct cpufreq_frequency_table table;
+
 	for (i = 0; i < count - 1; i++) {
 		max_freq = freq_table[i].frequency;
 		ind = i;
@@ -129,7 +199,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
 	}
 }
 
-static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
+static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
 {
 	struct device_node *np;
 	int i, count, ret;
@@ -145,10 +215,8 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
 		return -ENODEV;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
-	if (!data) {
-		pr_err("%s: no memory\n", __func__);
+	if (!data)
 		goto err_np;
-	}
 
 	policy->clk = of_clk_get(np, 0);
 	if (IS_ERR(policy->clk)) {
@@ -170,7 +238,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	}
 
 	if (fmask)
-		mask = fmask[get_hard_smp_processor_id(cpu)];
+		mask = fmask[get_cpu_physical_id(cpu)];
 	else
 		mask = 0x0;
 
@@ -201,13 +269,13 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	data->table = table;
 
 	/* update ->cpus if we have cluster, no harm if not */
-	cpumask_copy(policy->cpus, per_cpu(cpu_mask, cpu));
-	for_each_cpu(i, per_cpu(cpu_mask, cpu))
+	set_affected_cpus(policy);
+	for_each_cpu(i, policy->cpus)
 		per_cpu(cpu_data, i) = data;
 
 	/* Minimum transition latency is 12 platform clocks */
 	u64temp = 12ULL * NSEC_PER_SEC;
-	do_div(u64temp, fsl_get_sys_freq());
+	do_div(u64temp, get_bus_freq());
 	policy->cpuinfo.transition_latency = u64temp + 1;
 
 	of_node_put(np);
@@ -227,7 +295,7 @@ err_np:
 	return -ENODEV;
 }
 
-static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy *policy)
 {
 	struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
 	unsigned int cpu;
@@ -236,13 +304,13 @@ static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
 	kfree(data->table);
 	kfree(data);
 
-	for_each_cpu(cpu, per_cpu(cpu_mask, policy->cpu))
+	for_each_cpu(cpu, policy->cpus)
 		per_cpu(cpu_data, cpu) = NULL;
 
 	return 0;
 }
 
-static int corenet_cpufreq_target(struct cpufreq_policy *policy,
+static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
 		unsigned int index)
 {
 	struct clk *parent;
@@ -252,18 +320,18 @@ static int corenet_cpufreq_target(struct cpufreq_policy *policy,
 	return clk_set_parent(policy->clk, parent);
 }
 
-static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
-	.name		= "ppc_cpufreq",
+static struct cpufreq_driver qoriq_cpufreq_driver = {
+	.name		= "qoriq_cpufreq",
 	.flags		= CPUFREQ_CONST_LOOPS,
-	.init		= corenet_cpufreq_cpu_init,
-	.exit		= __exit_p(corenet_cpufreq_cpu_exit),
+	.init		= qoriq_cpufreq_cpu_init,
+	.exit		= __exit_p(qoriq_cpufreq_cpu_exit),
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target_index	= corenet_cpufreq_target,
+	.target_index	= qoriq_cpufreq_target,
 	.get		= cpufreq_generic_get,
 	.attr		= cpufreq_generic_attr,
 };
 
-static const struct of_device_id node_matches[] __initdata = {
+static const struct of_device_id node_matches[] __initconst = {
 	{ .compatible = "fsl,p2041-clockgen", .data = &sdata[0], },
 	{ .compatible = "fsl,p3041-clockgen", .data = &sdata[0], },
 	{ .compatible = "fsl,p5020-clockgen", .data = &sdata[1], },
@@ -273,61 +341,43 @@ static const struct of_device_id node_matches[] __initdata = {
 	{}
 };
 
-static int __init ppc_corenet_cpufreq_init(void)
+static int __init qoriq_cpufreq_init(void)
 {
 	int ret;
 	struct device_node  *np;
 	const struct of_device_id *match;
 	const struct soc_data *data;
-	unsigned int cpu;
 
 	np = of_find_matching_node(NULL, node_matches);
 	if (!np)
 		return -ENODEV;
 
-	for_each_possible_cpu(cpu) {
-		if (!alloc_cpumask_var(&per_cpu(cpu_mask, cpu), GFP_KERNEL))
-			goto err_mask;
-		cpumask_copy(per_cpu(cpu_mask, cpu), cpu_core_mask(cpu));
-	}
-
 	match = of_match_node(node_matches, np);
 	data = match->data;
 	if (data) {
 		if (data->flag)
 			fmask = data->freq_mask;
-		min_cpufreq = fsl_get_sys_freq();
+		min_cpufreq = get_bus_freq();
 	} else {
-		min_cpufreq = fsl_get_sys_freq() / 2;
+		min_cpufreq = get_bus_freq() / 2;
 	}
 
 	of_node_put(np);
 
-	ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
+	ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
 	if (!ret)
-		pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
+		pr_info("Freescale QorIQ CPU frequency scaling driver\n");
 
 	return ret;
-
-err_mask:
-	for_each_possible_cpu(cpu)
-		free_cpumask_var(per_cpu(cpu_mask, cpu));
-
-	return -ENOMEM;
 }
-module_init(ppc_corenet_cpufreq_init);
+module_init(qoriq_cpufreq_init);
 
-static void __exit ppc_corenet_cpufreq_exit(void)
+static void __exit qoriq_cpufreq_exit(void)
 {
-	unsigned int cpu;
-
-	for_each_possible_cpu(cpu)
-		free_cpumask_var(per_cpu(cpu_mask, cpu));
-
-	cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
+	cpufreq_unregister_driver(&qoriq_cpufreq_driver);
 }
-module_exit(ppc_corenet_cpufreq_exit);
+module_exit(qoriq_cpufreq_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
-MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series SoCs");
+MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs");
-- 
2.1.0.27.g96db324


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-10-17  3:13 ` B29983
  0 siblings, 0 replies; 29+ messages in thread
From: B29983 @ 2014-10-17  3:13 UTC (permalink / raw)
  To: rjw, viresh.kumar; +Cc: Tang Yuantian, linuxppc-dev, linux-kernel, linux-pm

From: Tang Yuantian <Yuantian.Tang@freescale.com>

Freescale introduced new ARM core-based SoCs which support dynamic
frequency switch feature. DFS on new SoCs are compatible with current
PowerPC CoreNet platforms. In order to support those new platforms,
this driver needs to be slightly adjusted. The main changes include:

1. Changed the names of driver and functions in driver.
2. Added two new functions get_cpu_physical_id() and get_bus_freq().
3. Used a new way to get all the CPUs which sharing clock wire.

Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
---
 drivers/cpufreq/Kconfig.arm                        |   8 ++
 drivers/cpufreq/Kconfig.powerpc                    |  11 +-
 drivers/cpufreq/Makefile                           |   2 +-
 .../{ppc-corenet-cpufreq.c => qoriq-cpufreq.c}     | 150 ++++++++++++++-------
 4 files changed, 114 insertions(+), 57 deletions(-)
 rename drivers/cpufreq/{ppc-corenet-cpufreq.c => qoriq-cpufreq.c} (72%)

diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
index 83a75dc..1925ae94 100644
--- a/drivers/cpufreq/Kconfig.arm
+++ b/drivers/cpufreq/Kconfig.arm
@@ -247,3 +247,11 @@ config ARM_TEGRA_CPUFREQ
 	default y
 	help
 	  This adds the CPUFreq driver support for TEGRA SOCs.
+
+config QORIQ_CPUFREQ
+	tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
+	depends on OF && COMMON_CLK
+	select CLK_PPC_CORENET
+	help
+	  This adds the CPUFreq driver support for Freescale QorIQ SoCs
+	  which are capable of changing the CPU's frequency dynamically.
diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc
index 72564b7..3a34248 100644
--- a/drivers/cpufreq/Kconfig.powerpc
+++ b/drivers/cpufreq/Kconfig.powerpc
@@ -23,14 +23,13 @@ config CPU_FREQ_MAPLE
 	  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
+config QORIQ_CPUFREQ
+	tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
+	depends on OF && COMMON_CLK
 	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.
+	  This adds the CPUFreq driver support for Freescale QorIQ SoCs
+	  which are capable of changing the CPU's frequency dynamically.
 
 config CPU_FREQ_PMAC
 	bool "Support for Apple PowerBooks"
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 40c53dc..0020049 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -84,7 +84,7 @@ obj-$(CONFIG_CPU_FREQ_CBE)		+= ppc-cbe-cpufreq.o
 ppc-cbe-cpufreq-y			+= ppc_cbe_cpufreq_pervasive.o ppc_cbe_cpufreq.o
 obj-$(CONFIG_CPU_FREQ_CBE_PMI)		+= ppc_cbe_cpufreq_pmi.o
 obj-$(CONFIG_CPU_FREQ_MAPLE)		+= maple-cpufreq.o
-obj-$(CONFIG_PPC_CORENET_CPUFREQ)   += ppc-corenet-cpufreq.o
+obj-$(CONFIG_QORIQ_CPUFREQ)   		+= qoriq-cpufreq.o
 obj-$(CONFIG_CPU_FREQ_PMAC)		+= pmac32-cpufreq.o
 obj-$(CONFIG_CPU_FREQ_PMAC64)		+= pmac64-cpufreq.o
 obj-$(CONFIG_PPC_PASEMI_CPUFREQ)	+= pasemi-cpufreq.o
diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c
similarity index 72%
rename from drivers/cpufreq/ppc-corenet-cpufreq.c
rename to drivers/cpufreq/qoriq-cpufreq.c
index bee5df7..80def0c 100644
--- a/drivers/cpufreq/ppc-corenet-cpufreq.c
+++ b/drivers/cpufreq/qoriq-cpufreq.c
@@ -1,7 +1,7 @@
 /*
  * Copyright 2013 Freescale Semiconductor, Inc.
  *
- * CPU Frequency Scaling driver for Freescale PowerPC corenet SoCs.
+ * CPU Frequency Scaling driver for Freescale QorIQ 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
@@ -20,7 +20,6 @@
 #include <linux/of.h>
 #include <linux/slab.h>
 #include <linux/smp.h>
-#include <sysdev/fsl_soc.h>
 
 /**
  * struct cpu_data - per CPU data struct
@@ -69,9 +68,6 @@ static const u32 *fmask;
 
 static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
 
-/* cpumask in a cluster */
-static DEFINE_PER_CPU(cpumask_var_t, cpu_mask);
-
 #ifndef CONFIG_SMP
 static inline const struct cpumask *cpu_core_mask(int cpu)
 {
@@ -79,6 +75,79 @@ static inline const struct cpumask *cpu_core_mask(int cpu)
 }
 #endif
 
+#if defined(CONFIG_PPC_E500MC)
+static int get_cpu_physical_id(int cpu)
+{
+	return get_hard_smp_processor_id(cpu);
+}
+#elif defined(CONFIG_ARM)
+static int get_cpu_physical_id(int cpu)
+{
+	return topology_core_id(cpu);
+}
+#endif
+
+static u32 get_bus_freq(void)
+{
+	struct device_node *soc;
+	u32 sysfreq;
+
+	soc = of_find_node_by_type(NULL, "soc");
+	if (!soc)
+		return 0;
+
+	if (of_property_read_u32(soc, "bus-frequency", &sysfreq))
+		sysfreq = 0;
+
+	of_node_put(soc);
+
+	return sysfreq;
+}
+
+static struct device_node *cpu_to_clk_node(int cpu)
+{
+	struct device_node *np, *clk_np;
+
+	if (!cpu_present(cpu))
+		return NULL;
+
+	np = of_get_cpu_node(cpu, NULL);
+	if (!np)
+		return NULL;
+
+	clk_np = of_parse_phandle(np, "clocks", 0);
+	if (!clk_np)
+		return NULL;
+
+	of_node_put(np);
+
+	return clk_np;
+}
+
+/* traverse cpu nodes to get cpu mask of sharing clock wire */
+static void set_affected_cpus(struct cpufreq_policy *policy)
+{
+	struct device_node *np, *clk_np;
+	struct cpumask *dstp = policy->cpus;
+	int i;
+
+	np = cpu_to_clk_node(policy->cpu);
+	if (!np)
+		return;
+
+	for_each_present_cpu(i) {
+		clk_np = cpu_to_clk_node(i);
+		if (!clk_np)
+			continue;
+
+		if (clk_np == np)
+			cpumask_set_cpu(i, dstp);
+
+		of_node_put(clk_np);
+	}
+	of_node_put(np);
+}
+
 /* reduce the duplicated frequencies in frequency table */
 static void freq_table_redup(struct cpufreq_frequency_table *freq_table,
 		int count)
@@ -105,6 +174,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
 	int i, j, ind;
 	unsigned int freq, max_freq;
 	struct cpufreq_frequency_table table;
+
 	for (i = 0; i < count - 1; i++) {
 		max_freq = freq_table[i].frequency;
 		ind = i;
@@ -129,7 +199,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
 	}
 }
 
-static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
+static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
 {
 	struct device_node *np;
 	int i, count, ret;
@@ -145,10 +215,8 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
 		return -ENODEV;
 
 	data = kzalloc(sizeof(*data), GFP_KERNEL);
-	if (!data) {
-		pr_err("%s: no memory\n", __func__);
+	if (!data)
 		goto err_np;
-	}
 
 	policy->clk = of_clk_get(np, 0);
 	if (IS_ERR(policy->clk)) {
@@ -170,7 +238,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	}
 
 	if (fmask)
-		mask = fmask[get_hard_smp_processor_id(cpu)];
+		mask = fmask[get_cpu_physical_id(cpu)];
 	else
 		mask = 0x0;
 
@@ -201,13 +269,13 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	data->table = table;
 
 	/* update ->cpus if we have cluster, no harm if not */
-	cpumask_copy(policy->cpus, per_cpu(cpu_mask, cpu));
-	for_each_cpu(i, per_cpu(cpu_mask, cpu))
+	set_affected_cpus(policy);
+	for_each_cpu(i, policy->cpus)
 		per_cpu(cpu_data, i) = data;
 
 	/* Minimum transition latency is 12 platform clocks */
 	u64temp = 12ULL * NSEC_PER_SEC;
-	do_div(u64temp, fsl_get_sys_freq());
+	do_div(u64temp, get_bus_freq());
 	policy->cpuinfo.transition_latency = u64temp + 1;
 
 	of_node_put(np);
@@ -227,7 +295,7 @@ err_np:
 	return -ENODEV;
 }
 
-static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy *policy)
 {
 	struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
 	unsigned int cpu;
@@ -236,13 +304,13 @@ static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
 	kfree(data->table);
 	kfree(data);
 
-	for_each_cpu(cpu, per_cpu(cpu_mask, policy->cpu))
+	for_each_cpu(cpu, policy->cpus)
 		per_cpu(cpu_data, cpu) = NULL;
 
 	return 0;
 }
 
-static int corenet_cpufreq_target(struct cpufreq_policy *policy,
+static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
 		unsigned int index)
 {
 	struct clk *parent;
@@ -252,18 +320,18 @@ static int corenet_cpufreq_target(struct cpufreq_policy *policy,
 	return clk_set_parent(policy->clk, parent);
 }
 
-static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
-	.name		= "ppc_cpufreq",
+static struct cpufreq_driver qoriq_cpufreq_driver = {
+	.name		= "qoriq_cpufreq",
 	.flags		= CPUFREQ_CONST_LOOPS,
-	.init		= corenet_cpufreq_cpu_init,
-	.exit		= __exit_p(corenet_cpufreq_cpu_exit),
+	.init		= qoriq_cpufreq_cpu_init,
+	.exit		= __exit_p(qoriq_cpufreq_cpu_exit),
 	.verify		= cpufreq_generic_frequency_table_verify,
-	.target_index	= corenet_cpufreq_target,
+	.target_index	= qoriq_cpufreq_target,
 	.get		= cpufreq_generic_get,
 	.attr		= cpufreq_generic_attr,
 };
 
-static const struct of_device_id node_matches[] __initdata = {
+static const struct of_device_id node_matches[] __initconst = {
 	{ .compatible = "fsl,p2041-clockgen", .data = &sdata[0], },
 	{ .compatible = "fsl,p3041-clockgen", .data = &sdata[0], },
 	{ .compatible = "fsl,p5020-clockgen", .data = &sdata[1], },
@@ -273,61 +341,43 @@ static const struct of_device_id node_matches[] __initdata = {
 	{}
 };
 
-static int __init ppc_corenet_cpufreq_init(void)
+static int __init qoriq_cpufreq_init(void)
 {
 	int ret;
 	struct device_node  *np;
 	const struct of_device_id *match;
 	const struct soc_data *data;
-	unsigned int cpu;
 
 	np = of_find_matching_node(NULL, node_matches);
 	if (!np)
 		return -ENODEV;
 
-	for_each_possible_cpu(cpu) {
-		if (!alloc_cpumask_var(&per_cpu(cpu_mask, cpu), GFP_KERNEL))
-			goto err_mask;
-		cpumask_copy(per_cpu(cpu_mask, cpu), cpu_core_mask(cpu));
-	}
-
 	match = of_match_node(node_matches, np);
 	data = match->data;
 	if (data) {
 		if (data->flag)
 			fmask = data->freq_mask;
-		min_cpufreq = fsl_get_sys_freq();
+		min_cpufreq = get_bus_freq();
 	} else {
-		min_cpufreq = fsl_get_sys_freq() / 2;
+		min_cpufreq = get_bus_freq() / 2;
 	}
 
 	of_node_put(np);
 
-	ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
+	ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
 	if (!ret)
-		pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
+		pr_info("Freescale QorIQ CPU frequency scaling driver\n");
 
 	return ret;
-
-err_mask:
-	for_each_possible_cpu(cpu)
-		free_cpumask_var(per_cpu(cpu_mask, cpu));
-
-	return -ENOMEM;
 }
-module_init(ppc_corenet_cpufreq_init);
+module_init(qoriq_cpufreq_init);
 
-static void __exit ppc_corenet_cpufreq_exit(void)
+static void __exit qoriq_cpufreq_exit(void)
 {
-	unsigned int cpu;
-
-	for_each_possible_cpu(cpu)
-		free_cpumask_var(per_cpu(cpu_mask, cpu));
-
-	cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
+	cpufreq_unregister_driver(&qoriq_cpufreq_driver);
 }
-module_exit(ppc_corenet_cpufreq_exit);
+module_exit(qoriq_cpufreq_exit);
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
-MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series SoCs");
+MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs");
-- 
2.1.0.27.g96db324

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
  2014-10-17  3:13 ` B29983
@ 2014-10-17  8:03   ` Kumar Gala
  -1 siblings, 0 replies; 29+ messages in thread
From: Kumar Gala @ 2014-10-17  8:03 UTC (permalink / raw)
  To: b29983
  Cc: rjw, viresh.kumar, linux-kernel, linux-pm, linuxppc-dev, Tang Yuantian


On Oct 17, 2014, at 5:13 AM, b29983@freescale.com wrote:

> From: Tang Yuantian <Yuantian.Tang@freescale.com>
> 
> Freescale introduced new ARM core-based SoCs which support dynamic
> frequency switch feature. DFS on new SoCs are compatible with current
> PowerPC CoreNet platforms. In order to support those new platforms,
> this driver needs to be slightly adjusted. The main changes include:
> 
> 1. Changed the names of driver and functions in driver.

split the name changes/renaming into a separate patch from the other changes.

> 2. Added two new functions get_cpu_physical_id() and get_bus_freq().
> 3. Used a new way to get all the CPUs which sharing clock wire.
> 
> Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> ---
> drivers/cpufreq/Kconfig.arm                        |   8 ++
> drivers/cpufreq/Kconfig.powerpc                    |  11 +-
> drivers/cpufreq/Makefile                           |   2 +-
> .../{ppc-corenet-cpufreq.c => qoriq-cpufreq.c}     | 150 ++++++++++++++-------
> 4 files changed, 114 insertions(+), 57 deletions(-)
> rename drivers/cpufreq/{ppc-corenet-cpufreq.c => qoriq-cpufreq.c} (72%)
> 
> diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
> index 83a75dc..1925ae94 100644
> --- a/drivers/cpufreq/Kconfig.arm
> +++ b/drivers/cpufreq/Kconfig.arm
> @@ -247,3 +247,11 @@ config ARM_TEGRA_CPUFREQ
> 	default y
> 	help
> 	  This adds the CPUFreq driver support for TEGRA SOCs.
> +
> +config QORIQ_CPUFREQ
> +	tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> +	depends on OF && COMMON_CLK
> +	select CLK_PPC_CORENET

Why are you not also renaming ‘CLK_PPC_CORENET’ to ‘CLK_QORIQ’ or something like that?  Seems rather odd to select a PPC CLK support on ARM ;)

> +	help
> +	  This adds the CPUFreq driver support for Freescale QorIQ SoCs
> +	  which are capable of changing the CPU's frequency dynamically.
> diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc
> index 72564b7..3a34248 100644
> --- a/drivers/cpufreq/Kconfig.powerpc
> +++ b/drivers/cpufreq/Kconfig.powerpc
> @@ -23,14 +23,13 @@ config CPU_FREQ_MAPLE
> 	  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
> +config QORIQ_CPUFREQ
> +	tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> +	depends on OF && COMMON_CLK
> 	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.
> +	  This adds the CPUFreq driver support for Freescale QorIQ SoCs
> +	  which are capable of changing the CPU's frequency dynamically.
> 
> config CPU_FREQ_PMAC
> 	bool "Support for Apple PowerBooks"
> diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
> index 40c53dc..0020049 100644
> --- a/drivers/cpufreq/Makefile
> +++ b/drivers/cpufreq/Makefile
> @@ -84,7 +84,7 @@ obj-$(CONFIG_CPU_FREQ_CBE)		+= ppc-cbe-cpufreq.o
> ppc-cbe-cpufreq-y			+= ppc_cbe_cpufreq_pervasive.o ppc_cbe_cpufreq.o
> obj-$(CONFIG_CPU_FREQ_CBE_PMI)		+= ppc_cbe_cpufreq_pmi.o
> obj-$(CONFIG_CPU_FREQ_MAPLE)		+= maple-cpufreq.o
> -obj-$(CONFIG_PPC_CORENET_CPUFREQ)   += ppc-corenet-cpufreq.o
> +obj-$(CONFIG_QORIQ_CPUFREQ)   		+= qoriq-cpufreq.o
> obj-$(CONFIG_CPU_FREQ_PMAC)		+= pmac32-cpufreq.o
> obj-$(CONFIG_CPU_FREQ_PMAC64)		+= pmac64-cpufreq.o
> obj-$(CONFIG_PPC_PASEMI_CPUFREQ)	+= pasemi-cpufreq.o
> diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c
> similarity index 72%
> rename from drivers/cpufreq/ppc-corenet-cpufreq.c
> rename to drivers/cpufreq/qoriq-cpufreq.c
> index bee5df7..80def0c 100644
> --- a/drivers/cpufreq/ppc-corenet-cpufreq.c
> +++ b/drivers/cpufreq/qoriq-cpufreq.c
> @@ -1,7 +1,7 @@
> /*
>  * Copyright 2013 Freescale Semiconductor, Inc.
>  *
> - * CPU Frequency Scaling driver for Freescale PowerPC corenet SoCs.
> + * CPU Frequency Scaling driver for Freescale QorIQ 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
> @@ -20,7 +20,6 @@
> #include <linux/of.h>
> #include <linux/slab.h>
> #include <linux/smp.h>
> -#include <sysdev/fsl_soc.h>
> 
> /**
>  * struct cpu_data - per CPU data struct
> @@ -69,9 +68,6 @@ static const u32 *fmask;
> 
> static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
> 
> -/* cpumask in a cluster */
> -static DEFINE_PER_CPU(cpumask_var_t, cpu_mask);
> -
> #ifndef CONFIG_SMP
> static inline const struct cpumask *cpu_core_mask(int cpu)
> {
> @@ -79,6 +75,79 @@ static inline const struct cpumask *cpu_core_mask(int cpu)
> }
> #endif
> 
> +#if defined(CONFIG_PPC_E500MC)

Probably should just be CONFIG_PPC, but do we need this at all.  Can’t we just use topology_core_id() on both ARM & PPC?

> +static int get_cpu_physical_id(int cpu)
> +{
> +	return get_hard_smp_processor_id(cpu);
> +}
> +#elif defined(CONFIG_ARM)
> +static int get_cpu_physical_id(int cpu)
> +{
> +	return topology_core_id(cpu);
> +}
> +#endif
> +
> +static u32 get_bus_freq(void)
> +{
> +	struct device_node *soc;
> +	u32 sysfreq;
> +
> +	soc = of_find_node_by_type(NULL, "soc");
> +	if (!soc)
> +		return 0;
> +
> +	if (of_property_read_u32(soc, "bus-frequency", &sysfreq))
> +		sysfreq = 0;
> +
> +	of_node_put(soc);
> +
> +	return sysfreq;
> +}
> +
> +static struct device_node *cpu_to_clk_node(int cpu)
> +{
> +	struct device_node *np, *clk_np;
> +
> +	if (!cpu_present(cpu))
> +		return NULL;
> +
> +	np = of_get_cpu_node(cpu, NULL);
> +	if (!np)
> +		return NULL;
> +
> +	clk_np = of_parse_phandle(np, "clocks", 0);
> +	if (!clk_np)
> +		return NULL;
> +
> +	of_node_put(np);
> +
> +	return clk_np;
> +}
> +
> +/* traverse cpu nodes to get cpu mask of sharing clock wire */
> +static void set_affected_cpus(struct cpufreq_policy *policy)
> +{
> +	struct device_node *np, *clk_np;
> +	struct cpumask *dstp = policy->cpus;
> +	int i;
> +
> +	np = cpu_to_clk_node(policy->cpu);
> +	if (!np)
> +		return;
> +
> +	for_each_present_cpu(i) {
> +		clk_np = cpu_to_clk_node(i);
> +		if (!clk_np)
> +			continue;
> +
> +		if (clk_np == np)
> +			cpumask_set_cpu(i, dstp);
> +
> +		of_node_put(clk_np);
> +	}
> +	of_node_put(np);
> +}
> +
> /* reduce the duplicated frequencies in frequency table */
> static void freq_table_redup(struct cpufreq_frequency_table *freq_table,
> 		int count)
> @@ -105,6 +174,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
> 	int i, j, ind;
> 	unsigned int freq, max_freq;
> 	struct cpufreq_frequency_table table;
> +
> 	for (i = 0; i < count - 1; i++) {
> 		max_freq = freq_table[i].frequency;
> 		ind = i;
> @@ -129,7 +199,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
> 	}
> }
> 
> -static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> +static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
> {
> 	struct device_node *np;
> 	int i, count, ret;
> @@ -145,10 +215,8 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> 		return -ENODEV;
> 
> 	data = kzalloc(sizeof(*data), GFP_KERNEL);
> -	if (!data) {
> -		pr_err("%s: no memory\n", __func__);
> +	if (!data)
> 		goto err_np;
> -	}
> 
> 	policy->clk = of_clk_get(np, 0);
> 	if (IS_ERR(policy->clk)) {
> @@ -170,7 +238,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> 	}
> 
> 	if (fmask)
> -		mask = fmask[get_hard_smp_processor_id(cpu)];
> +		mask = fmask[get_cpu_physical_id(cpu)];
> 	else
> 		mask = 0x0;
> 
> @@ -201,13 +269,13 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> 	data->table = table;
> 
> 	/* update ->cpus if we have cluster, no harm if not */
> -	cpumask_copy(policy->cpus, per_cpu(cpu_mask, cpu));
> -	for_each_cpu(i, per_cpu(cpu_mask, cpu))
> +	set_affected_cpus(policy);
> +	for_each_cpu(i, policy->cpus)
> 		per_cpu(cpu_data, i) = data;
> 
> 	/* Minimum transition latency is 12 platform clocks */
> 	u64temp = 12ULL * NSEC_PER_SEC;
> -	do_div(u64temp, fsl_get_sys_freq());
> +	do_div(u64temp, get_bus_freq());
> 	policy->cpuinfo.transition_latency = u64temp + 1;
> 
> 	of_node_put(np);
> @@ -227,7 +295,7 @@ err_np:
> 	return -ENODEV;
> }
> 
> -static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
> +static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy *policy)
> {
> 	struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
> 	unsigned int cpu;
> @@ -236,13 +304,13 @@ static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
> 	kfree(data->table);
> 	kfree(data);
> 
> -	for_each_cpu(cpu, per_cpu(cpu_mask, policy->cpu))
> +	for_each_cpu(cpu, policy->cpus)
> 		per_cpu(cpu_data, cpu) = NULL;
> 
> 	return 0;
> }
> 
> -static int corenet_cpufreq_target(struct cpufreq_policy *policy,
> +static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
> 		unsigned int index)
> {
> 	struct clk *parent;
> @@ -252,18 +320,18 @@ static int corenet_cpufreq_target(struct cpufreq_policy *policy,
> 	return clk_set_parent(policy->clk, parent);
> }
> 
> -static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
> -	.name		= "ppc_cpufreq",
> +static struct cpufreq_driver qoriq_cpufreq_driver = {
> +	.name		= "qoriq_cpufreq",
> 	.flags		= CPUFREQ_CONST_LOOPS,
> -	.init		= corenet_cpufreq_cpu_init,
> -	.exit		= __exit_p(corenet_cpufreq_cpu_exit),
> +	.init		= qoriq_cpufreq_cpu_init,
> +	.exit		= __exit_p(qoriq_cpufreq_cpu_exit),
> 	.verify		= cpufreq_generic_frequency_table_verify,
> -	.target_index	= corenet_cpufreq_target,
> +	.target_index	= qoriq_cpufreq_target,
> 	.get		= cpufreq_generic_get,
> 	.attr		= cpufreq_generic_attr,
> };
> 
> -static const struct of_device_id node_matches[] __initdata = {
> +static const struct of_device_id node_matches[] __initconst = {
> 	{ .compatible = "fsl,p2041-clockgen", .data = &sdata[0], },
> 	{ .compatible = "fsl,p3041-clockgen", .data = &sdata[0], },
> 	{ .compatible = "fsl,p5020-clockgen", .data = &sdata[1], },
> @@ -273,61 +341,43 @@ static const struct of_device_id node_matches[] __initdata = {
> 	{}
> };
> 
> -static int __init ppc_corenet_cpufreq_init(void)
> +static int __init qoriq_cpufreq_init(void)
> {
> 	int ret;
> 	struct device_node  *np;
> 	const struct of_device_id *match;
> 	const struct soc_data *data;
> -	unsigned int cpu;
> 
> 	np = of_find_matching_node(NULL, node_matches);
> 	if (!np)
> 		return -ENODEV;
> 
> -	for_each_possible_cpu(cpu) {
> -		if (!alloc_cpumask_var(&per_cpu(cpu_mask, cpu), GFP_KERNEL))
> -			goto err_mask;
> -		cpumask_copy(per_cpu(cpu_mask, cpu), cpu_core_mask(cpu));
> -	}
> -
> 	match = of_match_node(node_matches, np);
> 	data = match->data;
> 	if (data) {
> 		if (data->flag)
> 			fmask = data->freq_mask;
> -		min_cpufreq = fsl_get_sys_freq();
> +		min_cpufreq = get_bus_freq();
> 	} else {
> -		min_cpufreq = fsl_get_sys_freq() / 2;
> +		min_cpufreq = get_bus_freq() / 2;
> 	}
> 
> 	of_node_put(np);
> 
> -	ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
> +	ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
> 	if (!ret)
> -		pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
> +		pr_info("Freescale QorIQ CPU frequency scaling driver\n");
> 
> 	return ret;
> -
> -err_mask:
> -	for_each_possible_cpu(cpu)
> -		free_cpumask_var(per_cpu(cpu_mask, cpu));
> -
> -	return -ENOMEM;
> }
> -module_init(ppc_corenet_cpufreq_init);
> +module_init(qoriq_cpufreq_init);
> 
> -static void __exit ppc_corenet_cpufreq_exit(void)
> +static void __exit qoriq_cpufreq_exit(void)
> {
> -	unsigned int cpu;
> -
> -	for_each_possible_cpu(cpu)
> -		free_cpumask_var(per_cpu(cpu_mask, cpu));
> -
> -	cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
> +	cpufreq_unregister_driver(&qoriq_cpufreq_driver);
> }
> -module_exit(ppc_corenet_cpufreq_exit);
> +module_exit(qoriq_cpufreq_exit);
> 
> MODULE_LICENSE("GPL");
> MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
> -MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series SoCs");
> +MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs");
> -- 
> 2.1.0.27.g96db324
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-10-17  8:03   ` Kumar Gala
  0 siblings, 0 replies; 29+ messages in thread
From: Kumar Gala @ 2014-10-17  8:03 UTC (permalink / raw)
  To: b29983
  Cc: Tang Yuantian, viresh.kumar, linux-pm, rjw, linux-kernel, linuxppc-dev


On Oct 17, 2014, at 5:13 AM, b29983@freescale.com wrote:

> From: Tang Yuantian <Yuantian.Tang@freescale.com>
>=20
> Freescale introduced new ARM core-based SoCs which support dynamic
> frequency switch feature. DFS on new SoCs are compatible with current
> PowerPC CoreNet platforms. In order to support those new platforms,
> this driver needs to be slightly adjusted. The main changes include:
>=20
> 1. Changed the names of driver and functions in driver.

split the name changes/renaming into a separate patch from the other =
changes.

> 2. Added two new functions get_cpu_physical_id() and get_bus_freq().
> 3. Used a new way to get all the CPUs which sharing clock wire.
>=20
> Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> ---
> drivers/cpufreq/Kconfig.arm                        |   8 ++
> drivers/cpufreq/Kconfig.powerpc                    |  11 +-
> drivers/cpufreq/Makefile                           |   2 +-
> .../{ppc-corenet-cpufreq.c =3D> qoriq-cpufreq.c}     | 150 =
++++++++++++++-------
> 4 files changed, 114 insertions(+), 57 deletions(-)
> rename drivers/cpufreq/{ppc-corenet-cpufreq.c =3D> qoriq-cpufreq.c} =
(72%)
>=20
> diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
> index 83a75dc..1925ae94 100644
> --- a/drivers/cpufreq/Kconfig.arm
> +++ b/drivers/cpufreq/Kconfig.arm
> @@ -247,3 +247,11 @@ config ARM_TEGRA_CPUFREQ
> 	default y
> 	help
> 	  This adds the CPUFreq driver support for TEGRA SOCs.
> +
> +config QORIQ_CPUFREQ
> +	tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> +	depends on OF && COMMON_CLK
> +	select CLK_PPC_CORENET

Why are you not also renaming =91CLK_PPC_CORENET=92 to =91CLK_QORIQ=92 =
or something like that?  Seems rather odd to select a PPC CLK support on =
ARM ;)

> +	help
> +	  This adds the CPUFreq driver support for Freescale QorIQ SoCs
> +	  which are capable of changing the CPU's frequency dynamically.
> diff --git a/drivers/cpufreq/Kconfig.powerpc =
b/drivers/cpufreq/Kconfig.powerpc
> index 72564b7..3a34248 100644
> --- a/drivers/cpufreq/Kconfig.powerpc
> +++ b/drivers/cpufreq/Kconfig.powerpc
> @@ -23,14 +23,13 @@ config CPU_FREQ_MAPLE
> 	  This adds support for frequency switching on Maple 970FX
> 	  Evaluation Board and compatible boards (IBM JS2x blades).
>=20
> -config PPC_CORENET_CPUFREQ
> -	tristate "CPU frequency scaling driver for Freescale E500MC =
SoCs"
> -	depends on PPC_E500MC && OF && COMMON_CLK
> +config QORIQ_CPUFREQ
> +	tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> +	depends on OF && COMMON_CLK
> 	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.
> +	  This adds the CPUFreq driver support for Freescale QorIQ SoCs
> +	  which are capable of changing the CPU's frequency dynamically.
>=20
> config CPU_FREQ_PMAC
> 	bool "Support for Apple PowerBooks"
> diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
> index 40c53dc..0020049 100644
> --- a/drivers/cpufreq/Makefile
> +++ b/drivers/cpufreq/Makefile
> @@ -84,7 +84,7 @@ obj-$(CONFIG_CPU_FREQ_CBE)		+=3D =
ppc-cbe-cpufreq.o
> ppc-cbe-cpufreq-y			+=3D ppc_cbe_cpufreq_pervasive.o =
ppc_cbe_cpufreq.o
> obj-$(CONFIG_CPU_FREQ_CBE_PMI)		+=3D =
ppc_cbe_cpufreq_pmi.o
> obj-$(CONFIG_CPU_FREQ_MAPLE)		+=3D maple-cpufreq.o
> -obj-$(CONFIG_PPC_CORENET_CPUFREQ)   +=3D ppc-corenet-cpufreq.o
> +obj-$(CONFIG_QORIQ_CPUFREQ)   		+=3D qoriq-cpufreq.o
> obj-$(CONFIG_CPU_FREQ_PMAC)		+=3D pmac32-cpufreq.o
> obj-$(CONFIG_CPU_FREQ_PMAC64)		+=3D pmac64-cpufreq.o
> obj-$(CONFIG_PPC_PASEMI_CPUFREQ)	+=3D pasemi-cpufreq.o
> diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c =
b/drivers/cpufreq/qoriq-cpufreq.c
> similarity index 72%
> rename from drivers/cpufreq/ppc-corenet-cpufreq.c
> rename to drivers/cpufreq/qoriq-cpufreq.c
> index bee5df7..80def0c 100644
> --- a/drivers/cpufreq/ppc-corenet-cpufreq.c
> +++ b/drivers/cpufreq/qoriq-cpufreq.c
> @@ -1,7 +1,7 @@
> /*
>  * Copyright 2013 Freescale Semiconductor, Inc.
>  *
> - * CPU Frequency Scaling driver for Freescale PowerPC corenet SoCs.
> + * CPU Frequency Scaling driver for Freescale QorIQ 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
> @@ -20,7 +20,6 @@
> #include <linux/of.h>
> #include <linux/slab.h>
> #include <linux/smp.h>
> -#include <sysdev/fsl_soc.h>
>=20
> /**
>  * struct cpu_data - per CPU data struct
> @@ -69,9 +68,6 @@ static const u32 *fmask;
>=20
> static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
>=20
> -/* cpumask in a cluster */
> -static DEFINE_PER_CPU(cpumask_var_t, cpu_mask);
> -
> #ifndef CONFIG_SMP
> static inline const struct cpumask *cpu_core_mask(int cpu)
> {
> @@ -79,6 +75,79 @@ static inline const struct cpumask =
*cpu_core_mask(int cpu)
> }
> #endif
>=20
> +#if defined(CONFIG_PPC_E500MC)

Probably should just be CONFIG_PPC, but do we need this at all.  Can=92t =
we just use topology_core_id() on both ARM & PPC?

> +static int get_cpu_physical_id(int cpu)
> +{
> +	return get_hard_smp_processor_id(cpu);
> +}
> +#elif defined(CONFIG_ARM)
> +static int get_cpu_physical_id(int cpu)
> +{
> +	return topology_core_id(cpu);
> +}
> +#endif
> +
> +static u32 get_bus_freq(void)
> +{
> +	struct device_node *soc;
> +	u32 sysfreq;
> +
> +	soc =3D of_find_node_by_type(NULL, "soc");
> +	if (!soc)
> +		return 0;
> +
> +	if (of_property_read_u32(soc, "bus-frequency", &sysfreq))
> +		sysfreq =3D 0;
> +
> +	of_node_put(soc);
> +
> +	return sysfreq;
> +}
> +
> +static struct device_node *cpu_to_clk_node(int cpu)
> +{
> +	struct device_node *np, *clk_np;
> +
> +	if (!cpu_present(cpu))
> +		return NULL;
> +
> +	np =3D of_get_cpu_node(cpu, NULL);
> +	if (!np)
> +		return NULL;
> +
> +	clk_np =3D of_parse_phandle(np, "clocks", 0);
> +	if (!clk_np)
> +		return NULL;
> +
> +	of_node_put(np);
> +
> +	return clk_np;
> +}
> +
> +/* traverse cpu nodes to get cpu mask of sharing clock wire */
> +static void set_affected_cpus(struct cpufreq_policy *policy)
> +{
> +	struct device_node *np, *clk_np;
> +	struct cpumask *dstp =3D policy->cpus;
> +	int i;
> +
> +	np =3D cpu_to_clk_node(policy->cpu);
> +	if (!np)
> +		return;
> +
> +	for_each_present_cpu(i) {
> +		clk_np =3D cpu_to_clk_node(i);
> +		if (!clk_np)
> +			continue;
> +
> +		if (clk_np =3D=3D np)
> +			cpumask_set_cpu(i, dstp);
> +
> +		of_node_put(clk_np);
> +	}
> +	of_node_put(np);
> +}
> +
> /* reduce the duplicated frequencies in frequency table */
> static void freq_table_redup(struct cpufreq_frequency_table =
*freq_table,
> 		int count)
> @@ -105,6 +174,7 @@ static void freq_table_sort(struct =
cpufreq_frequency_table *freq_table,
> 	int i, j, ind;
> 	unsigned int freq, max_freq;
> 	struct cpufreq_frequency_table table;
> +
> 	for (i =3D 0; i < count - 1; i++) {
> 		max_freq =3D freq_table[i].frequency;
> 		ind =3D i;
> @@ -129,7 +199,7 @@ static void freq_table_sort(struct =
cpufreq_frequency_table *freq_table,
> 	}
> }
>=20
> -static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> +static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
> {
> 	struct device_node *np;
> 	int i, count, ret;
> @@ -145,10 +215,8 @@ static int corenet_cpufreq_cpu_init(struct =
cpufreq_policy *policy)
> 		return -ENODEV;
>=20
> 	data =3D kzalloc(sizeof(*data), GFP_KERNEL);
> -	if (!data) {
> -		pr_err("%s: no memory\n", __func__);
> +	if (!data)
> 		goto err_np;
> -	}
>=20
> 	policy->clk =3D of_clk_get(np, 0);
> 	if (IS_ERR(policy->clk)) {
> @@ -170,7 +238,7 @@ static int corenet_cpufreq_cpu_init(struct =
cpufreq_policy *policy)
> 	}
>=20
> 	if (fmask)
> -		mask =3D fmask[get_hard_smp_processor_id(cpu)];
> +		mask =3D fmask[get_cpu_physical_id(cpu)];
> 	else
> 		mask =3D 0x0;
>=20
> @@ -201,13 +269,13 @@ static int corenet_cpufreq_cpu_init(struct =
cpufreq_policy *policy)
> 	data->table =3D table;
>=20
> 	/* update ->cpus if we have cluster, no harm if not */
> -	cpumask_copy(policy->cpus, per_cpu(cpu_mask, cpu));
> -	for_each_cpu(i, per_cpu(cpu_mask, cpu))
> +	set_affected_cpus(policy);
> +	for_each_cpu(i, policy->cpus)
> 		per_cpu(cpu_data, i) =3D data;
>=20
> 	/* Minimum transition latency is 12 platform clocks */
> 	u64temp =3D 12ULL * NSEC_PER_SEC;
> -	do_div(u64temp, fsl_get_sys_freq());
> +	do_div(u64temp, get_bus_freq());
> 	policy->cpuinfo.transition_latency =3D u64temp + 1;
>=20
> 	of_node_put(np);
> @@ -227,7 +295,7 @@ err_np:
> 	return -ENODEV;
> }
>=20
> -static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy =
*policy)
> +static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy =
*policy)
> {
> 	struct cpu_data *data =3D per_cpu(cpu_data, policy->cpu);
> 	unsigned int cpu;
> @@ -236,13 +304,13 @@ static int __exit =
corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
> 	kfree(data->table);
> 	kfree(data);
>=20
> -	for_each_cpu(cpu, per_cpu(cpu_mask, policy->cpu))
> +	for_each_cpu(cpu, policy->cpus)
> 		per_cpu(cpu_data, cpu) =3D NULL;
>=20
> 	return 0;
> }
>=20
> -static int corenet_cpufreq_target(struct cpufreq_policy *policy,
> +static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
> 		unsigned int index)
> {
> 	struct clk *parent;
> @@ -252,18 +320,18 @@ static int corenet_cpufreq_target(struct =
cpufreq_policy *policy,
> 	return clk_set_parent(policy->clk, parent);
> }
>=20
> -static struct cpufreq_driver ppc_corenet_cpufreq_driver =3D {
> -	.name		=3D "ppc_cpufreq",
> +static struct cpufreq_driver qoriq_cpufreq_driver =3D {
> +	.name		=3D "qoriq_cpufreq",
> 	.flags		=3D CPUFREQ_CONST_LOOPS,
> -	.init		=3D corenet_cpufreq_cpu_init,
> -	.exit		=3D __exit_p(corenet_cpufreq_cpu_exit),
> +	.init		=3D qoriq_cpufreq_cpu_init,
> +	.exit		=3D __exit_p(qoriq_cpufreq_cpu_exit),
> 	.verify		=3D cpufreq_generic_frequency_table_verify,
> -	.target_index	=3D corenet_cpufreq_target,
> +	.target_index	=3D qoriq_cpufreq_target,
> 	.get		=3D cpufreq_generic_get,
> 	.attr		=3D cpufreq_generic_attr,
> };
>=20
> -static const struct of_device_id node_matches[] __initdata =3D {
> +static const struct of_device_id node_matches[] __initconst =3D {
> 	{ .compatible =3D "fsl,p2041-clockgen", .data =3D &sdata[0], },
> 	{ .compatible =3D "fsl,p3041-clockgen", .data =3D &sdata[0], },
> 	{ .compatible =3D "fsl,p5020-clockgen", .data =3D &sdata[1], },
> @@ -273,61 +341,43 @@ static const struct of_device_id node_matches[] =
__initdata =3D {
> 	{}
> };
>=20
> -static int __init ppc_corenet_cpufreq_init(void)
> +static int __init qoriq_cpufreq_init(void)
> {
> 	int ret;
> 	struct device_node  *np;
> 	const struct of_device_id *match;
> 	const struct soc_data *data;
> -	unsigned int cpu;
>=20
> 	np =3D of_find_matching_node(NULL, node_matches);
> 	if (!np)
> 		return -ENODEV;
>=20
> -	for_each_possible_cpu(cpu) {
> -		if (!alloc_cpumask_var(&per_cpu(cpu_mask, cpu), =
GFP_KERNEL))
> -			goto err_mask;
> -		cpumask_copy(per_cpu(cpu_mask, cpu), =
cpu_core_mask(cpu));
> -	}
> -
> 	match =3D of_match_node(node_matches, np);
> 	data =3D match->data;
> 	if (data) {
> 		if (data->flag)
> 			fmask =3D data->freq_mask;
> -		min_cpufreq =3D fsl_get_sys_freq();
> +		min_cpufreq =3D get_bus_freq();
> 	} else {
> -		min_cpufreq =3D fsl_get_sys_freq() / 2;
> +		min_cpufreq =3D get_bus_freq() / 2;
> 	}
>=20
> 	of_node_put(np);
>=20
> -	ret =3D cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
> +	ret =3D cpufreq_register_driver(&qoriq_cpufreq_driver);
> 	if (!ret)
> -		pr_info("Freescale PowerPC corenet CPU frequency scaling =
driver\n");
> +		pr_info("Freescale QorIQ CPU frequency scaling =
driver\n");
>=20
> 	return ret;
> -
> -err_mask:
> -	for_each_possible_cpu(cpu)
> -		free_cpumask_var(per_cpu(cpu_mask, cpu));
> -
> -	return -ENOMEM;
> }
> -module_init(ppc_corenet_cpufreq_init);
> +module_init(qoriq_cpufreq_init);
>=20
> -static void __exit ppc_corenet_cpufreq_exit(void)
> +static void __exit qoriq_cpufreq_exit(void)
> {
> -	unsigned int cpu;
> -
> -	for_each_possible_cpu(cpu)
> -		free_cpumask_var(per_cpu(cpu_mask, cpu));
> -
> -	cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
> +	cpufreq_unregister_driver(&qoriq_cpufreq_driver);
> }
> -module_exit(ppc_corenet_cpufreq_exit);
> +module_exit(qoriq_cpufreq_exit);
>=20
> MODULE_LICENSE("GPL");
> MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
> -MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series =
SoCs");
> +MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs");
> --=20
> 2.1.0.27.g96db324
>=20
> --
> To unsubscribe from this list: send the line "unsubscribe =
linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
  2014-10-17  3:13 ` B29983
@ 2014-10-17  8:08   ` Viresh Kumar
  -1 siblings, 0 replies; 29+ messages in thread
From: Viresh Kumar @ 2014-10-17  8:08 UTC (permalink / raw)
  To: Tang Yuantian-B29983
  Cc: Rafael J. Wysocki, Linux Kernel Mailing List, linux-pm,
	linuxppc-dev, Tang Yuantian

On 17 October 2014 08:43,  <B29983@freescale.com> wrote:

Hi B29983 :)

> From: Tang Yuantian <Yuantian.Tang@freescale.com>
>
> Freescale introduced new ARM core-based SoCs which support dynamic
> frequency switch feature. DFS on new SoCs are compatible with current
> PowerPC CoreNet platforms. In order to support those new platforms,
> this driver needs to be slightly adjusted. The main changes include:
>
> 1. Changed the names of driver and functions in driver.
> 2. Added two new functions get_cpu_physical_id() and get_bus_freq().
> 3. Used a new way to get all the CPUs which sharing clock wire.
>
> Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> ---
>  drivers/cpufreq/Kconfig.arm                        |   8 ++
>  drivers/cpufreq/Kconfig.powerpc                    |  11 +-
>  drivers/cpufreq/Makefile                           |   2 +-
>  .../{ppc-corenet-cpufreq.c => qoriq-cpufreq.c}     | 150 ++++++++++++++-------
>  4 files changed, 114 insertions(+), 57 deletions(-)
>  rename drivers/cpufreq/{ppc-corenet-cpufreq.c => qoriq-cpufreq.c} (72%)
>
> diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
> index 83a75dc..1925ae94 100644
> --- a/drivers/cpufreq/Kconfig.arm
> +++ b/drivers/cpufreq/Kconfig.arm
> @@ -247,3 +247,11 @@ config ARM_TEGRA_CPUFREQ
>         default y
>         help
>           This adds the CPUFreq driver support for TEGRA SOCs.
> +
> +config QORIQ_CPUFREQ
> +       tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> +       depends on OF && COMMON_CLK
> +       select CLK_PPC_CORENET
> +       help
> +         This adds the CPUFreq driver support for Freescale QorIQ SoCs
> +         which are capable of changing the CPU's frequency dynamically.
> diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc
> index 72564b7..3a34248 100644
> --- a/drivers/cpufreq/Kconfig.powerpc
> +++ b/drivers/cpufreq/Kconfig.powerpc
> @@ -23,14 +23,13 @@ config CPU_FREQ_MAPLE
>           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
> +config QORIQ_CPUFREQ
> +       tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> +       depends on OF && COMMON_CLK
>         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.
> +         This adds the CPUFreq driver support for Freescale QorIQ SoCs
> +         which are capable of changing the CPU's frequency dynamically.
>
>  config CPU_FREQ_PMAC
>         bool "Support for Apple PowerBooks"

Don't need this duplication at all. Just move this to Kconfig instead
of .arm and ppc.

> diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c

>  /**
>   * struct cpu_data - per CPU data struct
> @@ -69,9 +68,6 @@ static const u32 *fmask;
>
>  static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
>
> -/* cpumask in a cluster */
> -static DEFINE_PER_CPU(cpumask_var_t, cpu_mask);
> -
>  #ifndef CONFIG_SMP
>  static inline const struct cpumask *cpu_core_mask(int cpu)
>  {
> @@ -79,6 +75,79 @@ static inline const struct cpumask *cpu_core_mask(int cpu)
>  }
>  #endif
>
> +#if defined(CONFIG_PPC_E500MC)
> +static int get_cpu_physical_id(int cpu)
> +{
> +       return get_hard_smp_processor_id(cpu);
> +}
> +#elif defined(CONFIG_ARM)

Wouldn't a #else work here as there are just two platforms we are
talking about ?

> +static int get_cpu_physical_id(int cpu)
> +{
> +       return topology_core_id(cpu);
> +}
> +#endif
> +
> +static u32 get_bus_freq(void)
> +{
> +       struct device_node *soc;
> +       u32 sysfreq;
> +
> +       soc = of_find_node_by_type(NULL, "soc");
> +       if (!soc)
> +               return 0;
> +
> +       if (of_property_read_u32(soc, "bus-frequency", &sysfreq))
> +               sysfreq = 0;
> +
> +       of_node_put(soc);
> +
> +       return sysfreq;
> +}
> +
> +static struct device_node *cpu_to_clk_node(int cpu)
> +{
> +       struct device_node *np, *clk_np;
> +
> +       if (!cpu_present(cpu))
> +               return NULL;
> +
> +       np = of_get_cpu_node(cpu, NULL);
> +       if (!np)
> +               return NULL;
> +
> +       clk_np = of_parse_phandle(np, "clocks", 0);
> +       if (!clk_np)
> +               return NULL;
> +
> +       of_node_put(np);
> +
> +       return clk_np;
> +}
> +
> +/* traverse cpu nodes to get cpu mask of sharing clock wire */
> +static void set_affected_cpus(struct cpufreq_policy *policy)
> +{
> +       struct device_node *np, *clk_np;
> +       struct cpumask *dstp = policy->cpus;
> +       int i;
> +
> +       np = cpu_to_clk_node(policy->cpu);
> +       if (!np)
> +               return;
> +
> +       for_each_present_cpu(i) {
> +               clk_np = cpu_to_clk_node(i);
> +               if (!clk_np)
> +                       continue;
> +
> +               if (clk_np == np)
> +                       cpumask_set_cpu(i, dstp);

So you are depending on matching the clock-nodes from DT for
getting this information, right ? There is nothing that the architecture
gives?

> +
> +               of_node_put(clk_np);
> +       }
> +       of_node_put(np);
> +}
> +
>  /* reduce the duplicated frequencies in frequency table */
>  static void freq_table_redup(struct cpufreq_frequency_table *freq_table,
>                 int count)
> @@ -105,6 +174,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
>         int i, j, ind;
>         unsigned int freq, max_freq;
>         struct cpufreq_frequency_table table;
> +
>         for (i = 0; i < count - 1; i++) {
>                 max_freq = freq_table[i].frequency;
>                 ind = i;
> @@ -129,7 +199,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
>         }
>  }
>
> -static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> +static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
>  {
>         struct device_node *np;
>         int i, count, ret;
> @@ -145,10 +215,8 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
>                 return -ENODEV;
>
>         data = kzalloc(sizeof(*data), GFP_KERNEL);
> -       if (!data) {
> -               pr_err("%s: no memory\n", __func__);

Wasn't this useful ?

> +       if (!data)
>                 goto err_np;
> -       }
>
>         policy->clk = of_clk_get(np, 0);
>         if (IS_ERR(policy->clk)) {
> @@ -170,7 +238,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
>         }
>
>         if (fmask)
> -               mask = fmask[get_hard_smp_processor_id(cpu)];
> +               mask = fmask[get_cpu_physical_id(cpu)];
>         else
>                 mask = 0x0;
>
> @@ -201,13 +269,13 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
>         data->table = table;
>
>         /* update ->cpus if we have cluster, no harm if not */
> -       cpumask_copy(policy->cpus, per_cpu(cpu_mask, cpu));
> -       for_each_cpu(i, per_cpu(cpu_mask, cpu))
> +       set_affected_cpus(policy);
> +       for_each_cpu(i, policy->cpus)
>                 per_cpu(cpu_data, i) = data;

Get rid of this per-cpu data and use policy->driver_data instead.

>
>         /* Minimum transition latency is 12 platform clocks */
>         u64temp = 12ULL * NSEC_PER_SEC;
> -       do_div(u64temp, fsl_get_sys_freq());
> +       do_div(u64temp, get_bus_freq());
>         policy->cpuinfo.transition_latency = u64temp + 1;
>
>         of_node_put(np);
> @@ -227,7 +295,7 @@ err_np:
>         return -ENODEV;
>  }
>
> -static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
> +static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy *policy)
>  {
>         struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
>         unsigned int cpu;
> @@ -236,13 +304,13 @@ static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
>         kfree(data->table);
>         kfree(data);
>
> -       for_each_cpu(cpu, per_cpu(cpu_mask, policy->cpu))
> +       for_each_cpu(cpu, policy->cpus)
>                 per_cpu(cpu_data, cpu) = NULL;
>
>         return 0;
>  }
>
> -static int corenet_cpufreq_target(struct cpufreq_policy *policy,
> +static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
>                 unsigned int index)
>  {
>         struct clk *parent;
> @@ -252,18 +320,18 @@ static int corenet_cpufreq_target(struct cpufreq_policy *policy,
>         return clk_set_parent(policy->clk, parent);
>  }
>
> -static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
> -       .name           = "ppc_cpufreq",
> +static struct cpufreq_driver qoriq_cpufreq_driver = {
> +       .name           = "qoriq_cpufreq",
>         .flags          = CPUFREQ_CONST_LOOPS,
> -       .init           = corenet_cpufreq_cpu_init,
> -       .exit           = __exit_p(corenet_cpufreq_cpu_exit),
> +       .init           = qoriq_cpufreq_cpu_init,
> +       .exit           = __exit_p(qoriq_cpufreq_cpu_exit),
>         .verify         = cpufreq_generic_frequency_table_verify,
> -       .target_index   = corenet_cpufreq_target,
> +       .target_index   = qoriq_cpufreq_target,
>         .get            = cpufreq_generic_get,
>         .attr           = cpufreq_generic_attr,
>  };
>
> -static const struct of_device_id node_matches[] __initdata = {
> +static const struct of_device_id node_matches[] __initconst = {
>         { .compatible = "fsl,p2041-clockgen", .data = &sdata[0], },
>         { .compatible = "fsl,p3041-clockgen", .data = &sdata[0], },
>         { .compatible = "fsl,p5020-clockgen", .data = &sdata[1], },
> @@ -273,61 +341,43 @@ static const struct of_device_id node_matches[] __initdata = {
>         {}
>  };
>
> -static int __init ppc_corenet_cpufreq_init(void)
> +static int __init qoriq_cpufreq_init(void)
>  {
>         int ret;
>         struct device_node  *np;
>         const struct of_device_id *match;
>         const struct soc_data *data;
> -       unsigned int cpu;
>
>         np = of_find_matching_node(NULL, node_matches);
>         if (!np)
>                 return -ENODEV;
>
> -       for_each_possible_cpu(cpu) {
> -               if (!alloc_cpumask_var(&per_cpu(cpu_mask, cpu), GFP_KERNEL))
> -                       goto err_mask;
> -               cpumask_copy(per_cpu(cpu_mask, cpu), cpu_core_mask(cpu));
> -       }
> -
>         match = of_match_node(node_matches, np);
>         data = match->data;
>         if (data) {
>                 if (data->flag)
>                         fmask = data->freq_mask;
> -               min_cpufreq = fsl_get_sys_freq();
> +               min_cpufreq = get_bus_freq();
>         } else {
> -               min_cpufreq = fsl_get_sys_freq() / 2;
> +               min_cpufreq = get_bus_freq() / 2;
>         }
>
>         of_node_put(np);
>
> -       ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
> +       ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
>         if (!ret)
> -               pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
> +               pr_info("Freescale QorIQ CPU frequency scaling driver\n");
>
>         return ret;
> -
> -err_mask:
> -       for_each_possible_cpu(cpu)
> -               free_cpumask_var(per_cpu(cpu_mask, cpu));
> -
> -       return -ENOMEM;
>  }
> -module_init(ppc_corenet_cpufreq_init);
> +module_init(qoriq_cpufreq_init);
>
> -static void __exit ppc_corenet_cpufreq_exit(void)
> +static void __exit qoriq_cpufreq_exit(void)
>  {
> -       unsigned int cpu;
> -
> -       for_each_possible_cpu(cpu)
> -               free_cpumask_var(per_cpu(cpu_mask, cpu));
> -
> -       cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
> +       cpufreq_unregister_driver(&qoriq_cpufreq_driver);
>  }
> -module_exit(ppc_corenet_cpufreq_exit);
> +module_exit(qoriq_cpufreq_exit);
>
>  MODULE_LICENSE("GPL");
>  MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
> -MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series SoCs");
> +MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs");

+ comments from Kumar Gala :)

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-10-17  8:08   ` Viresh Kumar
  0 siblings, 0 replies; 29+ messages in thread
From: Viresh Kumar @ 2014-10-17  8:08 UTC (permalink / raw)
  To: Tang Yuantian-B29983
  Cc: Tang Yuantian, linuxppc-dev, Rafael J. Wysocki,
	Linux Kernel Mailing List, linux-pm

On 17 October 2014 08:43,  <B29983@freescale.com> wrote:

Hi B29983 :)

> From: Tang Yuantian <Yuantian.Tang@freescale.com>
>
> Freescale introduced new ARM core-based SoCs which support dynamic
> frequency switch feature. DFS on new SoCs are compatible with current
> PowerPC CoreNet platforms. In order to support those new platforms,
> this driver needs to be slightly adjusted. The main changes include:
>
> 1. Changed the names of driver and functions in driver.
> 2. Added two new functions get_cpu_physical_id() and get_bus_freq().
> 3. Used a new way to get all the CPUs which sharing clock wire.
>
> Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> ---
>  drivers/cpufreq/Kconfig.arm                        |   8 ++
>  drivers/cpufreq/Kconfig.powerpc                    |  11 +-
>  drivers/cpufreq/Makefile                           |   2 +-
>  .../{ppc-corenet-cpufreq.c => qoriq-cpufreq.c}     | 150 ++++++++++++++-------
>  4 files changed, 114 insertions(+), 57 deletions(-)
>  rename drivers/cpufreq/{ppc-corenet-cpufreq.c => qoriq-cpufreq.c} (72%)
>
> diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
> index 83a75dc..1925ae94 100644
> --- a/drivers/cpufreq/Kconfig.arm
> +++ b/drivers/cpufreq/Kconfig.arm
> @@ -247,3 +247,11 @@ config ARM_TEGRA_CPUFREQ
>         default y
>         help
>           This adds the CPUFreq driver support for TEGRA SOCs.
> +
> +config QORIQ_CPUFREQ
> +       tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> +       depends on OF && COMMON_CLK
> +       select CLK_PPC_CORENET
> +       help
> +         This adds the CPUFreq driver support for Freescale QorIQ SoCs
> +         which are capable of changing the CPU's frequency dynamically.
> diff --git a/drivers/cpufreq/Kconfig.powerpc b/drivers/cpufreq/Kconfig.powerpc
> index 72564b7..3a34248 100644
> --- a/drivers/cpufreq/Kconfig.powerpc
> +++ b/drivers/cpufreq/Kconfig.powerpc
> @@ -23,14 +23,13 @@ config CPU_FREQ_MAPLE
>           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
> +config QORIQ_CPUFREQ
> +       tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> +       depends on OF && COMMON_CLK
>         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.
> +         This adds the CPUFreq driver support for Freescale QorIQ SoCs
> +         which are capable of changing the CPU's frequency dynamically.
>
>  config CPU_FREQ_PMAC
>         bool "Support for Apple PowerBooks"

Don't need this duplication at all. Just move this to Kconfig instead
of .arm and ppc.

> diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c

>  /**
>   * struct cpu_data - per CPU data struct
> @@ -69,9 +68,6 @@ static const u32 *fmask;
>
>  static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
>
> -/* cpumask in a cluster */
> -static DEFINE_PER_CPU(cpumask_var_t, cpu_mask);
> -
>  #ifndef CONFIG_SMP
>  static inline const struct cpumask *cpu_core_mask(int cpu)
>  {
> @@ -79,6 +75,79 @@ static inline const struct cpumask *cpu_core_mask(int cpu)
>  }
>  #endif
>
> +#if defined(CONFIG_PPC_E500MC)
> +static int get_cpu_physical_id(int cpu)
> +{
> +       return get_hard_smp_processor_id(cpu);
> +}
> +#elif defined(CONFIG_ARM)

Wouldn't a #else work here as there are just two platforms we are
talking about ?

> +static int get_cpu_physical_id(int cpu)
> +{
> +       return topology_core_id(cpu);
> +}
> +#endif
> +
> +static u32 get_bus_freq(void)
> +{
> +       struct device_node *soc;
> +       u32 sysfreq;
> +
> +       soc = of_find_node_by_type(NULL, "soc");
> +       if (!soc)
> +               return 0;
> +
> +       if (of_property_read_u32(soc, "bus-frequency", &sysfreq))
> +               sysfreq = 0;
> +
> +       of_node_put(soc);
> +
> +       return sysfreq;
> +}
> +
> +static struct device_node *cpu_to_clk_node(int cpu)
> +{
> +       struct device_node *np, *clk_np;
> +
> +       if (!cpu_present(cpu))
> +               return NULL;
> +
> +       np = of_get_cpu_node(cpu, NULL);
> +       if (!np)
> +               return NULL;
> +
> +       clk_np = of_parse_phandle(np, "clocks", 0);
> +       if (!clk_np)
> +               return NULL;
> +
> +       of_node_put(np);
> +
> +       return clk_np;
> +}
> +
> +/* traverse cpu nodes to get cpu mask of sharing clock wire */
> +static void set_affected_cpus(struct cpufreq_policy *policy)
> +{
> +       struct device_node *np, *clk_np;
> +       struct cpumask *dstp = policy->cpus;
> +       int i;
> +
> +       np = cpu_to_clk_node(policy->cpu);
> +       if (!np)
> +               return;
> +
> +       for_each_present_cpu(i) {
> +               clk_np = cpu_to_clk_node(i);
> +               if (!clk_np)
> +                       continue;
> +
> +               if (clk_np == np)
> +                       cpumask_set_cpu(i, dstp);

So you are depending on matching the clock-nodes from DT for
getting this information, right ? There is nothing that the architecture
gives?

> +
> +               of_node_put(clk_np);
> +       }
> +       of_node_put(np);
> +}
> +
>  /* reduce the duplicated frequencies in frequency table */
>  static void freq_table_redup(struct cpufreq_frequency_table *freq_table,
>                 int count)
> @@ -105,6 +174,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
>         int i, j, ind;
>         unsigned int freq, max_freq;
>         struct cpufreq_frequency_table table;
> +
>         for (i = 0; i < count - 1; i++) {
>                 max_freq = freq_table[i].frequency;
>                 ind = i;
> @@ -129,7 +199,7 @@ static void freq_table_sort(struct cpufreq_frequency_table *freq_table,
>         }
>  }
>
> -static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> +static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
>  {
>         struct device_node *np;
>         int i, count, ret;
> @@ -145,10 +215,8 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
>                 return -ENODEV;
>
>         data = kzalloc(sizeof(*data), GFP_KERNEL);
> -       if (!data) {
> -               pr_err("%s: no memory\n", __func__);

Wasn't this useful ?

> +       if (!data)
>                 goto err_np;
> -       }
>
>         policy->clk = of_clk_get(np, 0);
>         if (IS_ERR(policy->clk)) {
> @@ -170,7 +238,7 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
>         }
>
>         if (fmask)
> -               mask = fmask[get_hard_smp_processor_id(cpu)];
> +               mask = fmask[get_cpu_physical_id(cpu)];
>         else
>                 mask = 0x0;
>
> @@ -201,13 +269,13 @@ static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
>         data->table = table;
>
>         /* update ->cpus if we have cluster, no harm if not */
> -       cpumask_copy(policy->cpus, per_cpu(cpu_mask, cpu));
> -       for_each_cpu(i, per_cpu(cpu_mask, cpu))
> +       set_affected_cpus(policy);
> +       for_each_cpu(i, policy->cpus)
>                 per_cpu(cpu_data, i) = data;

Get rid of this per-cpu data and use policy->driver_data instead.

>
>         /* Minimum transition latency is 12 platform clocks */
>         u64temp = 12ULL * NSEC_PER_SEC;
> -       do_div(u64temp, fsl_get_sys_freq());
> +       do_div(u64temp, get_bus_freq());
>         policy->cpuinfo.transition_latency = u64temp + 1;
>
>         of_node_put(np);
> @@ -227,7 +295,7 @@ err_np:
>         return -ENODEV;
>  }
>
> -static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
> +static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy *policy)
>  {
>         struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
>         unsigned int cpu;
> @@ -236,13 +304,13 @@ static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy *policy)
>         kfree(data->table);
>         kfree(data);
>
> -       for_each_cpu(cpu, per_cpu(cpu_mask, policy->cpu))
> +       for_each_cpu(cpu, policy->cpus)
>                 per_cpu(cpu_data, cpu) = NULL;
>
>         return 0;
>  }
>
> -static int corenet_cpufreq_target(struct cpufreq_policy *policy,
> +static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
>                 unsigned int index)
>  {
>         struct clk *parent;
> @@ -252,18 +320,18 @@ static int corenet_cpufreq_target(struct cpufreq_policy *policy,
>         return clk_set_parent(policy->clk, parent);
>  }
>
> -static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
> -       .name           = "ppc_cpufreq",
> +static struct cpufreq_driver qoriq_cpufreq_driver = {
> +       .name           = "qoriq_cpufreq",
>         .flags          = CPUFREQ_CONST_LOOPS,
> -       .init           = corenet_cpufreq_cpu_init,
> -       .exit           = __exit_p(corenet_cpufreq_cpu_exit),
> +       .init           = qoriq_cpufreq_cpu_init,
> +       .exit           = __exit_p(qoriq_cpufreq_cpu_exit),
>         .verify         = cpufreq_generic_frequency_table_verify,
> -       .target_index   = corenet_cpufreq_target,
> +       .target_index   = qoriq_cpufreq_target,
>         .get            = cpufreq_generic_get,
>         .attr           = cpufreq_generic_attr,
>  };
>
> -static const struct of_device_id node_matches[] __initdata = {
> +static const struct of_device_id node_matches[] __initconst = {
>         { .compatible = "fsl,p2041-clockgen", .data = &sdata[0], },
>         { .compatible = "fsl,p3041-clockgen", .data = &sdata[0], },
>         { .compatible = "fsl,p5020-clockgen", .data = &sdata[1], },
> @@ -273,61 +341,43 @@ static const struct of_device_id node_matches[] __initdata = {
>         {}
>  };
>
> -static int __init ppc_corenet_cpufreq_init(void)
> +static int __init qoriq_cpufreq_init(void)
>  {
>         int ret;
>         struct device_node  *np;
>         const struct of_device_id *match;
>         const struct soc_data *data;
> -       unsigned int cpu;
>
>         np = of_find_matching_node(NULL, node_matches);
>         if (!np)
>                 return -ENODEV;
>
> -       for_each_possible_cpu(cpu) {
> -               if (!alloc_cpumask_var(&per_cpu(cpu_mask, cpu), GFP_KERNEL))
> -                       goto err_mask;
> -               cpumask_copy(per_cpu(cpu_mask, cpu), cpu_core_mask(cpu));
> -       }
> -
>         match = of_match_node(node_matches, np);
>         data = match->data;
>         if (data) {
>                 if (data->flag)
>                         fmask = data->freq_mask;
> -               min_cpufreq = fsl_get_sys_freq();
> +               min_cpufreq = get_bus_freq();
>         } else {
> -               min_cpufreq = fsl_get_sys_freq() / 2;
> +               min_cpufreq = get_bus_freq() / 2;
>         }
>
>         of_node_put(np);
>
> -       ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
> +       ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
>         if (!ret)
> -               pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
> +               pr_info("Freescale QorIQ CPU frequency scaling driver\n");
>
>         return ret;
> -
> -err_mask:
> -       for_each_possible_cpu(cpu)
> -               free_cpumask_var(per_cpu(cpu_mask, cpu));
> -
> -       return -ENOMEM;
>  }
> -module_init(ppc_corenet_cpufreq_init);
> +module_init(qoriq_cpufreq_init);
>
> -static void __exit ppc_corenet_cpufreq_exit(void)
> +static void __exit qoriq_cpufreq_exit(void)
>  {
> -       unsigned int cpu;
> -
> -       for_each_possible_cpu(cpu)
> -               free_cpumask_var(per_cpu(cpu_mask, cpu));
> -
> -       cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
> +       cpufreq_unregister_driver(&qoriq_cpufreq_driver);
>  }
> -module_exit(ppc_corenet_cpufreq_exit);
> +module_exit(qoriq_cpufreq_exit);
>
>  MODULE_LICENSE("GPL");
>  MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
> -MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series SoCs");
> +MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs");

+ comments from Kumar Gala :)

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
  2014-10-17  8:03   ` Kumar Gala
@ 2014-10-20  2:20     ` Yuantian Tang
  -1 siblings, 0 replies; 29+ messages in thread
From: Yuantian Tang @ 2014-10-20  2:20 UTC (permalink / raw)
  To: Kumar Gala; +Cc: rjw, viresh.kumar, linux-kernel, linux-pm, linuxppc-dev

Thanks for your comments.  Will address them in next version.
Also some explanations inline for your comments.

Thanks,
Yuantian

> -----Original Message-----
> From: Kumar Gala [mailto:galak@kernel.crashing.org]
> Sent: Friday, October 17, 2014 4:04 PM
> To: Tang Yuantian-B29983
> Cc: rjw@rjwysocki.net; viresh.kumar@linaro.org; linux-kernel@vger.kernel.org;
> linux-pm@vger.kernel.org; linuxppc-dev@ozlabs.org; Tang Yuantian-B29983
> Subject: Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ
> platforms
> 
> 
> On Oct 17, 2014, at 5:13 AM, b29983@freescale.com wrote:
> 
> > From: Tang Yuantian <Yuantian.Tang@freescale.com>
> >
> > Freescale introduced new ARM core-based SoCs which support dynamic
> > frequency switch feature. DFS on new SoCs are compatible with current
> > PowerPC CoreNet platforms. In order to support those new platforms,
> > this driver needs to be slightly adjusted. The main changes include:
> >
> > 1. Changed the names of driver and functions in driver.
> 
> split the name changes/renaming into a separate patch from the other changes.
> 
> > 2. Added two new functions get_cpu_physical_id() and get_bus_freq().
> > 3. Used a new way to get all the CPUs which sharing clock wire.
> >
> > Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> > ---
> > drivers/cpufreq/Kconfig.arm                        |   8 ++
> > drivers/cpufreq/Kconfig.powerpc                    |  11 +-
> > drivers/cpufreq/Makefile                           |   2 +-
> > .../{ppc-corenet-cpufreq.c => qoriq-cpufreq.c}     | 150 ++++++++++++++-------
> > 4 files changed, 114 insertions(+), 57 deletions(-) rename
> > drivers/cpufreq/{ppc-corenet-cpufreq.c => qoriq-cpufreq.c} (72%)
> >
> > diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
> > index 83a75dc..1925ae94 100644
> > --- a/drivers/cpufreq/Kconfig.arm
> > +++ b/drivers/cpufreq/Kconfig.arm
> > @@ -247,3 +247,11 @@ config ARM_TEGRA_CPUFREQ
> > 	default y
> > 	help
> > 	  This adds the CPUFreq driver support for TEGRA SOCs.
> > +
> > +config QORIQ_CPUFREQ
> > +	tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> > +	depends on OF && COMMON_CLK
> > +	select CLK_PPC_CORENET
> 
> Why are you not also renaming 'CLK_PPC_CORENET' to 'CLK_QORIQ' or
> something like that?  Seems rather odd to select a PPC CLK support on ARM ;)
> 
Yes, someone else is working on that.

> > +	help
> > +	  This adds the CPUFreq driver support for Freescale QorIQ SoCs
> > +	  which are capable of changing the CPU's frequency dynamically.
> > diff --git a/drivers/cpufreq/Kconfig.powerpc
> > b/drivers/cpufreq/Kconfig.powerpc index 72564b7..3a34248 100644
> > --- a/drivers/cpufreq/Kconfig.powerpc
> > +++ b/drivers/cpufreq/Kconfig.powerpc
> > @@ -23,14 +23,13 @@ config CPU_FREQ_MAPLE
> > 	  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
> > +config QORIQ_CPUFREQ
> > +	tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> > +	depends on OF && COMMON_CLK
> > 	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.
> > +	  This adds the CPUFreq driver support for Freescale QorIQ SoCs
> > +	  which are capable of changing the CPU's frequency dynamically.
> >
> > config CPU_FREQ_PMAC
> > 	bool "Support for Apple PowerBooks"
> > diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index
> > 40c53dc..0020049 100644
> > --- a/drivers/cpufreq/Makefile
> > +++ b/drivers/cpufreq/Makefile
> > @@ -84,7 +84,7 @@ obj-$(CONFIG_CPU_FREQ_CBE)		+=
> ppc-cbe-cpufreq.o
> > ppc-cbe-cpufreq-y			+= ppc_cbe_cpufreq_pervasive.o
> ppc_cbe_cpufreq.o
> > obj-$(CONFIG_CPU_FREQ_CBE_PMI)		+= ppc_cbe_cpufreq_pmi.o
> > obj-$(CONFIG_CPU_FREQ_MAPLE)		+= maple-cpufreq.o
> > -obj-$(CONFIG_PPC_CORENET_CPUFREQ)   += ppc-corenet-cpufreq.o
> > +obj-$(CONFIG_QORIQ_CPUFREQ)   		+= qoriq-cpufreq.o
> > obj-$(CONFIG_CPU_FREQ_PMAC)		+= pmac32-cpufreq.o
> > obj-$(CONFIG_CPU_FREQ_PMAC64)		+= pmac64-cpufreq.o
> > obj-$(CONFIG_PPC_PASEMI_CPUFREQ)	+= pasemi-cpufreq.o
> > diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c
> > b/drivers/cpufreq/qoriq-cpufreq.c similarity index 72% rename from
> > drivers/cpufreq/ppc-corenet-cpufreq.c
> > rename to drivers/cpufreq/qoriq-cpufreq.c index bee5df7..80def0c
> > 100644
> > --- a/drivers/cpufreq/ppc-corenet-cpufreq.c
> > +++ b/drivers/cpufreq/qoriq-cpufreq.c
> > @@ -1,7 +1,7 @@
> > /*
> >  * Copyright 2013 Freescale Semiconductor, Inc.
> >  *
> > - * CPU Frequency Scaling driver for Freescale PowerPC corenet SoCs.
> > + * CPU Frequency Scaling driver for Freescale QorIQ 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
> > @@ -20,7 +20,6 @@ #include <linux/of.h> #include <linux/slab.h>
> > #include <linux/smp.h> -#include <sysdev/fsl_soc.h>
> >
> > /**
> >  * struct cpu_data - per CPU data struct @@ -69,9 +68,6 @@ static
> > const u32 *fmask;
> >
> > static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
> >
> > -/* cpumask in a cluster */
> > -static DEFINE_PER_CPU(cpumask_var_t, cpu_mask);
> > -
> > #ifndef CONFIG_SMP
> > static inline const struct cpumask *cpu_core_mask(int cpu) { @@ -79,6
> > +75,79 @@ static inline const struct cpumask *cpu_core_mask(int cpu) }
> > #endif
> >
> > +#if defined(CONFIG_PPC_E500MC)
> 
> Probably should just be CONFIG_PPC, but do we need this at all.  Can't we just
> use topology_core_id() on both ARM & PPC?
> 
I will investigate if topology_core_id() works for PPC.

Regards,
Yuantian

> > +static int get_cpu_physical_id(int cpu) {
> > +	return get_hard_smp_processor_id(cpu); } #elif defined(CONFIG_ARM)
> > +static int get_cpu_physical_id(int cpu) {
> > +	return topology_core_id(cpu);
> > +}
> > +#endif
> > +
> > +static u32 get_bus_freq(void)
> > +{
> > +	struct device_node *soc;
> > +	u32 sysfreq;
> > +
> > +	soc = of_find_node_by_type(NULL, "soc");
> > +	if (!soc)
> > +		return 0;
> > +
> > +	if (of_property_read_u32(soc, "bus-frequency", &sysfreq))
> > +		sysfreq = 0;
> > +
> > +	of_node_put(soc);
> > +
> > +	return sysfreq;
> > +}
> > +
> > +static struct device_node *cpu_to_clk_node(int cpu) {
> > +	struct device_node *np, *clk_np;
> > +
> > +	if (!cpu_present(cpu))
> > +		return NULL;
> > +
> > +	np = of_get_cpu_node(cpu, NULL);
> > +	if (!np)
> > +		return NULL;
> > +
> > +	clk_np = of_parse_phandle(np, "clocks", 0);
> > +	if (!clk_np)
> > +		return NULL;
> > +
> > +	of_node_put(np);
> > +
> > +	return clk_np;
> > +}
> > +
> > +/* traverse cpu nodes to get cpu mask of sharing clock wire */ static
> > +void set_affected_cpus(struct cpufreq_policy *policy) {
> > +	struct device_node *np, *clk_np;
> > +	struct cpumask *dstp = policy->cpus;
> > +	int i;
> > +
> > +	np = cpu_to_clk_node(policy->cpu);
> > +	if (!np)
> > +		return;
> > +
> > +	for_each_present_cpu(i) {
> > +		clk_np = cpu_to_clk_node(i);
> > +		if (!clk_np)
> > +			continue;
> > +
> > +		if (clk_np == np)
> > +			cpumask_set_cpu(i, dstp);
> > +
> > +		of_node_put(clk_np);
> > +	}
> > +	of_node_put(np);
> > +}
> > +
> > /* reduce the duplicated frequencies in frequency table */ static void
> > freq_table_redup(struct cpufreq_frequency_table *freq_table,
> > 		int count)
> > @@ -105,6 +174,7 @@ static void freq_table_sort(struct
> cpufreq_frequency_table *freq_table,
> > 	int i, j, ind;
> > 	unsigned int freq, max_freq;
> > 	struct cpufreq_frequency_table table;
> > +
> > 	for (i = 0; i < count - 1; i++) {
> > 		max_freq = freq_table[i].frequency;
> > 		ind = i;
> > @@ -129,7 +199,7 @@ static void freq_table_sort(struct
> cpufreq_frequency_table *freq_table,
> > 	}
> > }
> >
> > -static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> > +static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
> > {
> > 	struct device_node *np;
> > 	int i, count, ret;
> > @@ -145,10 +215,8 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> > 		return -ENODEV;
> >
> > 	data = kzalloc(sizeof(*data), GFP_KERNEL);
> > -	if (!data) {
> > -		pr_err("%s: no memory\n", __func__);
> > +	if (!data)
> > 		goto err_np;
> > -	}
> >
> > 	policy->clk = of_clk_get(np, 0);
> > 	if (IS_ERR(policy->clk)) {
> > @@ -170,7 +238,7 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> > 	}
> >
> > 	if (fmask)
> > -		mask = fmask[get_hard_smp_processor_id(cpu)];
> > +		mask = fmask[get_cpu_physical_id(cpu)];
> > 	else
> > 		mask = 0x0;
> >
> > @@ -201,13 +269,13 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> > 	data->table = table;
> >
> > 	/* update ->cpus if we have cluster, no harm if not */
> > -	cpumask_copy(policy->cpus, per_cpu(cpu_mask, cpu));
> > -	for_each_cpu(i, per_cpu(cpu_mask, cpu))
> > +	set_affected_cpus(policy);
> > +	for_each_cpu(i, policy->cpus)
> > 		per_cpu(cpu_data, i) = data;
> >
> > 	/* Minimum transition latency is 12 platform clocks */
> > 	u64temp = 12ULL * NSEC_PER_SEC;
> > -	do_div(u64temp, fsl_get_sys_freq());
> > +	do_div(u64temp, get_bus_freq());
> > 	policy->cpuinfo.transition_latency = u64temp + 1;
> >
> > 	of_node_put(np);
> > @@ -227,7 +295,7 @@ err_np:
> > 	return -ENODEV;
> > }
> >
> > -static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy
> > *policy)
> > +static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy
> > +*policy)
> > {
> > 	struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
> > 	unsigned int cpu;
> > @@ -236,13 +304,13 @@ static int __exit corenet_cpufreq_cpu_exit(struct
> cpufreq_policy *policy)
> > 	kfree(data->table);
> > 	kfree(data);
> >
> > -	for_each_cpu(cpu, per_cpu(cpu_mask, policy->cpu))
> > +	for_each_cpu(cpu, policy->cpus)
> > 		per_cpu(cpu_data, cpu) = NULL;
> >
> > 	return 0;
> > }
> >
> > -static int corenet_cpufreq_target(struct cpufreq_policy *policy,
> > +static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
> > 		unsigned int index)
> > {
> > 	struct clk *parent;
> > @@ -252,18 +320,18 @@ static int corenet_cpufreq_target(struct
> cpufreq_policy *policy,
> > 	return clk_set_parent(policy->clk, parent); }
> >
> > -static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
> > -	.name		= "ppc_cpufreq",
> > +static struct cpufreq_driver qoriq_cpufreq_driver = {
> > +	.name		= "qoriq_cpufreq",
> > 	.flags		= CPUFREQ_CONST_LOOPS,
> > -	.init		= corenet_cpufreq_cpu_init,
> > -	.exit		= __exit_p(corenet_cpufreq_cpu_exit),
> > +	.init		= qoriq_cpufreq_cpu_init,
> > +	.exit		= __exit_p(qoriq_cpufreq_cpu_exit),
> > 	.verify		= cpufreq_generic_frequency_table_verify,
> > -	.target_index	= corenet_cpufreq_target,
> > +	.target_index	= qoriq_cpufreq_target,
> > 	.get		= cpufreq_generic_get,
> > 	.attr		= cpufreq_generic_attr,
> > };
> >
> > -static const struct of_device_id node_matches[] __initdata = {
> > +static const struct of_device_id node_matches[] __initconst = {
> > 	{ .compatible = "fsl,p2041-clockgen", .data = &sdata[0], },
> > 	{ .compatible = "fsl,p3041-clockgen", .data = &sdata[0], },
> > 	{ .compatible = "fsl,p5020-clockgen", .data = &sdata[1], }, @@
> > -273,61 +341,43 @@ static const struct of_device_id node_matches[]
> __initdata = {
> > 	{}
> > };
> >
> > -static int __init ppc_corenet_cpufreq_init(void)
> > +static int __init qoriq_cpufreq_init(void)
> > {
> > 	int ret;
> > 	struct device_node  *np;
> > 	const struct of_device_id *match;
> > 	const struct soc_data *data;
> > -	unsigned int cpu;
> >
> > 	np = of_find_matching_node(NULL, node_matches);
> > 	if (!np)
> > 		return -ENODEV;
> >
> > -	for_each_possible_cpu(cpu) {
> > -		if (!alloc_cpumask_var(&per_cpu(cpu_mask, cpu), GFP_KERNEL))
> > -			goto err_mask;
> > -		cpumask_copy(per_cpu(cpu_mask, cpu), cpu_core_mask(cpu));
> > -	}
> > -
> > 	match = of_match_node(node_matches, np);
> > 	data = match->data;
> > 	if (data) {
> > 		if (data->flag)
> > 			fmask = data->freq_mask;
> > -		min_cpufreq = fsl_get_sys_freq();
> > +		min_cpufreq = get_bus_freq();
> > 	} else {
> > -		min_cpufreq = fsl_get_sys_freq() / 2;
> > +		min_cpufreq = get_bus_freq() / 2;
> > 	}
> >
> > 	of_node_put(np);
> >
> > -	ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
> > +	ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
> > 	if (!ret)
> > -		pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
> > +		pr_info("Freescale QorIQ CPU frequency scaling driver\n");
> >
> > 	return ret;
> > -
> > -err_mask:
> > -	for_each_possible_cpu(cpu)
> > -		free_cpumask_var(per_cpu(cpu_mask, cpu));
> > -
> > -	return -ENOMEM;
> > }
> > -module_init(ppc_corenet_cpufreq_init);
> > +module_init(qoriq_cpufreq_init);
> >
> > -static void __exit ppc_corenet_cpufreq_exit(void)
> > +static void __exit qoriq_cpufreq_exit(void)
> > {
> > -	unsigned int cpu;
> > -
> > -	for_each_possible_cpu(cpu)
> > -		free_cpumask_var(per_cpu(cpu_mask, cpu));
> > -
> > -	cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
> > +	cpufreq_unregister_driver(&qoriq_cpufreq_driver);
> > }
> > -module_exit(ppc_corenet_cpufreq_exit);
> > +module_exit(qoriq_cpufreq_exit);
> >
> > MODULE_LICENSE("GPL");
> > MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
> > -MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series
> > SoCs");
> > +MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs");
> > --
> > 2.1.0.27.g96db324
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe
> > linux-kernel" in the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at  http://www.tux.org/lkml/


^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-10-20  2:20     ` Yuantian Tang
  0 siblings, 0 replies; 29+ messages in thread
From: Yuantian Tang @ 2014-10-20  2:20 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, viresh.kumar, rjw, linux-kernel, linux-pm

Thanks for your comments.  Will address them in next version.
Also some explanations inline for your comments.

Thanks,
Yuantian

> -----Original Message-----
> From: Kumar Gala [mailto:galak@kernel.crashing.org]
> Sent: Friday, October 17, 2014 4:04 PM
> To: Tang Yuantian-B29983
> Cc: rjw@rjwysocki.net; viresh.kumar@linaro.org; linux-kernel@vger.kernel.=
org;
> linux-pm@vger.kernel.org; linuxppc-dev@ozlabs.org; Tang Yuantian-B29983
> Subject: Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ
> platforms
>=20
>=20
> On Oct 17, 2014, at 5:13 AM, b29983@freescale.com wrote:
>=20
> > From: Tang Yuantian <Yuantian.Tang@freescale.com>
> >
> > Freescale introduced new ARM core-based SoCs which support dynamic
> > frequency switch feature. DFS on new SoCs are compatible with current
> > PowerPC CoreNet platforms. In order to support those new platforms,
> > this driver needs to be slightly adjusted. The main changes include:
> >
> > 1. Changed the names of driver and functions in driver.
>=20
> split the name changes/renaming into a separate patch from the other chan=
ges.
>=20
> > 2. Added two new functions get_cpu_physical_id() and get_bus_freq().
> > 3. Used a new way to get all the CPUs which sharing clock wire.
> >
> > Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> > ---
> > drivers/cpufreq/Kconfig.arm                        |   8 ++
> > drivers/cpufreq/Kconfig.powerpc                    |  11 +-
> > drivers/cpufreq/Makefile                           |   2 +-
> > .../{ppc-corenet-cpufreq.c =3D> qoriq-cpufreq.c}     | 150 ++++++++++++=
++-------
> > 4 files changed, 114 insertions(+), 57 deletions(-) rename
> > drivers/cpufreq/{ppc-corenet-cpufreq.c =3D> qoriq-cpufreq.c} (72%)
> >
> > diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
> > index 83a75dc..1925ae94 100644
> > --- a/drivers/cpufreq/Kconfig.arm
> > +++ b/drivers/cpufreq/Kconfig.arm
> > @@ -247,3 +247,11 @@ config ARM_TEGRA_CPUFREQ
> > 	default y
> > 	help
> > 	  This adds the CPUFreq driver support for TEGRA SOCs.
> > +
> > +config QORIQ_CPUFREQ
> > +	tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> > +	depends on OF && COMMON_CLK
> > +	select CLK_PPC_CORENET
>=20
> Why are you not also renaming 'CLK_PPC_CORENET' to 'CLK_QORIQ' or
> something like that?  Seems rather odd to select a PPC CLK support on ARM=
 ;)
>=20
Yes, someone else is working on that.

> > +	help
> > +	  This adds the CPUFreq driver support for Freescale QorIQ SoCs
> > +	  which are capable of changing the CPU's frequency dynamically.
> > diff --git a/drivers/cpufreq/Kconfig.powerpc
> > b/drivers/cpufreq/Kconfig.powerpc index 72564b7..3a34248 100644
> > --- a/drivers/cpufreq/Kconfig.powerpc
> > +++ b/drivers/cpufreq/Kconfig.powerpc
> > @@ -23,14 +23,13 @@ config CPU_FREQ_MAPLE
> > 	  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
> > +config QORIQ_CPUFREQ
> > +	tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> > +	depends on OF && COMMON_CLK
> > 	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.
> > +	  This adds the CPUFreq driver support for Freescale QorIQ SoCs
> > +	  which are capable of changing the CPU's frequency dynamically.
> >
> > config CPU_FREQ_PMAC
> > 	bool "Support for Apple PowerBooks"
> > diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index
> > 40c53dc..0020049 100644
> > --- a/drivers/cpufreq/Makefile
> > +++ b/drivers/cpufreq/Makefile
> > @@ -84,7 +84,7 @@ obj-$(CONFIG_CPU_FREQ_CBE)		+=3D
> ppc-cbe-cpufreq.o
> > ppc-cbe-cpufreq-y			+=3D ppc_cbe_cpufreq_pervasive.o
> ppc_cbe_cpufreq.o
> > obj-$(CONFIG_CPU_FREQ_CBE_PMI)		+=3D ppc_cbe_cpufreq_pmi.o
> > obj-$(CONFIG_CPU_FREQ_MAPLE)		+=3D maple-cpufreq.o
> > -obj-$(CONFIG_PPC_CORENET_CPUFREQ)   +=3D ppc-corenet-cpufreq.o
> > +obj-$(CONFIG_QORIQ_CPUFREQ)   		+=3D qoriq-cpufreq.o
> > obj-$(CONFIG_CPU_FREQ_PMAC)		+=3D pmac32-cpufreq.o
> > obj-$(CONFIG_CPU_FREQ_PMAC64)		+=3D pmac64-cpufreq.o
> > obj-$(CONFIG_PPC_PASEMI_CPUFREQ)	+=3D pasemi-cpufreq.o
> > diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c
> > b/drivers/cpufreq/qoriq-cpufreq.c similarity index 72% rename from
> > drivers/cpufreq/ppc-corenet-cpufreq.c
> > rename to drivers/cpufreq/qoriq-cpufreq.c index bee5df7..80def0c
> > 100644
> > --- a/drivers/cpufreq/ppc-corenet-cpufreq.c
> > +++ b/drivers/cpufreq/qoriq-cpufreq.c
> > @@ -1,7 +1,7 @@
> > /*
> >  * Copyright 2013 Freescale Semiconductor, Inc.
> >  *
> > - * CPU Frequency Scaling driver for Freescale PowerPC corenet SoCs.
> > + * CPU Frequency Scaling driver for Freescale QorIQ 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
> > @@ -20,7 +20,6 @@ #include <linux/of.h> #include <linux/slab.h>
> > #include <linux/smp.h> -#include <sysdev/fsl_soc.h>
> >
> > /**
> >  * struct cpu_data - per CPU data struct @@ -69,9 +68,6 @@ static
> > const u32 *fmask;
> >
> > static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
> >
> > -/* cpumask in a cluster */
> > -static DEFINE_PER_CPU(cpumask_var_t, cpu_mask);
> > -
> > #ifndef CONFIG_SMP
> > static inline const struct cpumask *cpu_core_mask(int cpu) { @@ -79,6
> > +75,79 @@ static inline const struct cpumask *cpu_core_mask(int cpu) }
> > #endif
> >
> > +#if defined(CONFIG_PPC_E500MC)
>=20
> Probably should just be CONFIG_PPC, but do we need this at all.  Can't we=
 just
> use topology_core_id() on both ARM & PPC?
>=20
I will investigate if topology_core_id() works for PPC.

Regards,
Yuantian

> > +static int get_cpu_physical_id(int cpu) {
> > +	return get_hard_smp_processor_id(cpu); } #elif defined(CONFIG_ARM)
> > +static int get_cpu_physical_id(int cpu) {
> > +	return topology_core_id(cpu);
> > +}
> > +#endif
> > +
> > +static u32 get_bus_freq(void)
> > +{
> > +	struct device_node *soc;
> > +	u32 sysfreq;
> > +
> > +	soc =3D of_find_node_by_type(NULL, "soc");
> > +	if (!soc)
> > +		return 0;
> > +
> > +	if (of_property_read_u32(soc, "bus-frequency", &sysfreq))
> > +		sysfreq =3D 0;
> > +
> > +	of_node_put(soc);
> > +
> > +	return sysfreq;
> > +}
> > +
> > +static struct device_node *cpu_to_clk_node(int cpu) {
> > +	struct device_node *np, *clk_np;
> > +
> > +	if (!cpu_present(cpu))
> > +		return NULL;
> > +
> > +	np =3D of_get_cpu_node(cpu, NULL);
> > +	if (!np)
> > +		return NULL;
> > +
> > +	clk_np =3D of_parse_phandle(np, "clocks", 0);
> > +	if (!clk_np)
> > +		return NULL;
> > +
> > +	of_node_put(np);
> > +
> > +	return clk_np;
> > +}
> > +
> > +/* traverse cpu nodes to get cpu mask of sharing clock wire */ static
> > +void set_affected_cpus(struct cpufreq_policy *policy) {
> > +	struct device_node *np, *clk_np;
> > +	struct cpumask *dstp =3D policy->cpus;
> > +	int i;
> > +
> > +	np =3D cpu_to_clk_node(policy->cpu);
> > +	if (!np)
> > +		return;
> > +
> > +	for_each_present_cpu(i) {
> > +		clk_np =3D cpu_to_clk_node(i);
> > +		if (!clk_np)
> > +			continue;
> > +
> > +		if (clk_np =3D=3D np)
> > +			cpumask_set_cpu(i, dstp);
> > +
> > +		of_node_put(clk_np);
> > +	}
> > +	of_node_put(np);
> > +}
> > +
> > /* reduce the duplicated frequencies in frequency table */ static void
> > freq_table_redup(struct cpufreq_frequency_table *freq_table,
> > 		int count)
> > @@ -105,6 +174,7 @@ static void freq_table_sort(struct
> cpufreq_frequency_table *freq_table,
> > 	int i, j, ind;
> > 	unsigned int freq, max_freq;
> > 	struct cpufreq_frequency_table table;
> > +
> > 	for (i =3D 0; i < count - 1; i++) {
> > 		max_freq =3D freq_table[i].frequency;
> > 		ind =3D i;
> > @@ -129,7 +199,7 @@ static void freq_table_sort(struct
> cpufreq_frequency_table *freq_table,
> > 	}
> > }
> >
> > -static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> > +static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
> > {
> > 	struct device_node *np;
> > 	int i, count, ret;
> > @@ -145,10 +215,8 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> > 		return -ENODEV;
> >
> > 	data =3D kzalloc(sizeof(*data), GFP_KERNEL);
> > -	if (!data) {
> > -		pr_err("%s: no memory\n", __func__);
> > +	if (!data)
> > 		goto err_np;
> > -	}
> >
> > 	policy->clk =3D of_clk_get(np, 0);
> > 	if (IS_ERR(policy->clk)) {
> > @@ -170,7 +238,7 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> > 	}
> >
> > 	if (fmask)
> > -		mask =3D fmask[get_hard_smp_processor_id(cpu)];
> > +		mask =3D fmask[get_cpu_physical_id(cpu)];
> > 	else
> > 		mask =3D 0x0;
> >
> > @@ -201,13 +269,13 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> > 	data->table =3D table;
> >
> > 	/* update ->cpus if we have cluster, no harm if not */
> > -	cpumask_copy(policy->cpus, per_cpu(cpu_mask, cpu));
> > -	for_each_cpu(i, per_cpu(cpu_mask, cpu))
> > +	set_affected_cpus(policy);
> > +	for_each_cpu(i, policy->cpus)
> > 		per_cpu(cpu_data, i) =3D data;
> >
> > 	/* Minimum transition latency is 12 platform clocks */
> > 	u64temp =3D 12ULL * NSEC_PER_SEC;
> > -	do_div(u64temp, fsl_get_sys_freq());
> > +	do_div(u64temp, get_bus_freq());
> > 	policy->cpuinfo.transition_latency =3D u64temp + 1;
> >
> > 	of_node_put(np);
> > @@ -227,7 +295,7 @@ err_np:
> > 	return -ENODEV;
> > }
> >
> > -static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy
> > *policy)
> > +static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy
> > +*policy)
> > {
> > 	struct cpu_data *data =3D per_cpu(cpu_data, policy->cpu);
> > 	unsigned int cpu;
> > @@ -236,13 +304,13 @@ static int __exit corenet_cpufreq_cpu_exit(struct
> cpufreq_policy *policy)
> > 	kfree(data->table);
> > 	kfree(data);
> >
> > -	for_each_cpu(cpu, per_cpu(cpu_mask, policy->cpu))
> > +	for_each_cpu(cpu, policy->cpus)
> > 		per_cpu(cpu_data, cpu) =3D NULL;
> >
> > 	return 0;
> > }
> >
> > -static int corenet_cpufreq_target(struct cpufreq_policy *policy,
> > +static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
> > 		unsigned int index)
> > {
> > 	struct clk *parent;
> > @@ -252,18 +320,18 @@ static int corenet_cpufreq_target(struct
> cpufreq_policy *policy,
> > 	return clk_set_parent(policy->clk, parent); }
> >
> > -static struct cpufreq_driver ppc_corenet_cpufreq_driver =3D {
> > -	.name		=3D "ppc_cpufreq",
> > +static struct cpufreq_driver qoriq_cpufreq_driver =3D {
> > +	.name		=3D "qoriq_cpufreq",
> > 	.flags		=3D CPUFREQ_CONST_LOOPS,
> > -	.init		=3D corenet_cpufreq_cpu_init,
> > -	.exit		=3D __exit_p(corenet_cpufreq_cpu_exit),
> > +	.init		=3D qoriq_cpufreq_cpu_init,
> > +	.exit		=3D __exit_p(qoriq_cpufreq_cpu_exit),
> > 	.verify		=3D cpufreq_generic_frequency_table_verify,
> > -	.target_index	=3D corenet_cpufreq_target,
> > +	.target_index	=3D qoriq_cpufreq_target,
> > 	.get		=3D cpufreq_generic_get,
> > 	.attr		=3D cpufreq_generic_attr,
> > };
> >
> > -static const struct of_device_id node_matches[] __initdata =3D {
> > +static const struct of_device_id node_matches[] __initconst =3D {
> > 	{ .compatible =3D "fsl,p2041-clockgen", .data =3D &sdata[0], },
> > 	{ .compatible =3D "fsl,p3041-clockgen", .data =3D &sdata[0], },
> > 	{ .compatible =3D "fsl,p5020-clockgen", .data =3D &sdata[1], }, @@
> > -273,61 +341,43 @@ static const struct of_device_id node_matches[]
> __initdata =3D {
> > 	{}
> > };
> >
> > -static int __init ppc_corenet_cpufreq_init(void)
> > +static int __init qoriq_cpufreq_init(void)
> > {
> > 	int ret;
> > 	struct device_node  *np;
> > 	const struct of_device_id *match;
> > 	const struct soc_data *data;
> > -	unsigned int cpu;
> >
> > 	np =3D of_find_matching_node(NULL, node_matches);
> > 	if (!np)
> > 		return -ENODEV;
> >
> > -	for_each_possible_cpu(cpu) {
> > -		if (!alloc_cpumask_var(&per_cpu(cpu_mask, cpu), GFP_KERNEL))
> > -			goto err_mask;
> > -		cpumask_copy(per_cpu(cpu_mask, cpu), cpu_core_mask(cpu));
> > -	}
> > -
> > 	match =3D of_match_node(node_matches, np);
> > 	data =3D match->data;
> > 	if (data) {
> > 		if (data->flag)
> > 			fmask =3D data->freq_mask;
> > -		min_cpufreq =3D fsl_get_sys_freq();
> > +		min_cpufreq =3D get_bus_freq();
> > 	} else {
> > -		min_cpufreq =3D fsl_get_sys_freq() / 2;
> > +		min_cpufreq =3D get_bus_freq() / 2;
> > 	}
> >
> > 	of_node_put(np);
> >
> > -	ret =3D cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
> > +	ret =3D cpufreq_register_driver(&qoriq_cpufreq_driver);
> > 	if (!ret)
> > -		pr_info("Freescale PowerPC corenet CPU frequency scaling driver\n");
> > +		pr_info("Freescale QorIQ CPU frequency scaling driver\n");
> >
> > 	return ret;
> > -
> > -err_mask:
> > -	for_each_possible_cpu(cpu)
> > -		free_cpumask_var(per_cpu(cpu_mask, cpu));
> > -
> > -	return -ENOMEM;
> > }
> > -module_init(ppc_corenet_cpufreq_init);
> > +module_init(qoriq_cpufreq_init);
> >
> > -static void __exit ppc_corenet_cpufreq_exit(void)
> > +static void __exit qoriq_cpufreq_exit(void)
> > {
> > -	unsigned int cpu;
> > -
> > -	for_each_possible_cpu(cpu)
> > -		free_cpumask_var(per_cpu(cpu_mask, cpu));
> > -
> > -	cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
> > +	cpufreq_unregister_driver(&qoriq_cpufreq_driver);
> > }
> > -module_exit(ppc_corenet_cpufreq_exit);
> > +module_exit(qoriq_cpufreq_exit);
> >
> > MODULE_LICENSE("GPL");
> > MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
> > -MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series
> > SoCs");
> > +MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs");
> > --
> > 2.1.0.27.g96db324
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe
> > linux-kernel" in the body of a message to majordomo@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html
> > Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
  2014-10-17  8:08   ` Viresh Kumar
  (?)
@ 2014-10-20  6:10     ` Yuantian Tang
  -1 siblings, 0 replies; 29+ messages in thread
From: Yuantian Tang @ 2014-10-20  6:10 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, Linux Kernel Mailing List, linux-pm, linuxppc-dev

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 14020 bytes --]

Thanks for your comments.  Your comments will be addressed in next version.
Some explanations inline.

Thanks,
Yuantian

> -----Original Message-----
> From: Viresh Kumar [mailto:viresh.kumar@linaro.org]
> Sent: Friday, October 17, 2014 4:09 PM
> To: Tang Yuantian-B29983
> Cc: Rafael J. Wysocki; Linux Kernel Mailing List; linux-pm@vger.kernel.org;
> linuxppc-dev@ozlabs.org; Tang Yuantian-B29983
> Subject: Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ
> platforms
> 
> On 17 October 2014 08:43,  <B29983@freescale.com> wrote:
> 
> Hi B29983 :)
> 
> > From: Tang Yuantian <Yuantian.Tang@freescale.com>
> >
> > Freescale introduced new ARM core-based SoCs which support dynamic
> > frequency switch feature. DFS on new SoCs are compatible with current
> > PowerPC CoreNet platforms. In order to support those new platforms,
> > this driver needs to be slightly adjusted. The main changes include:
> >
> > 1. Changed the names of driver and functions in driver.
> > 2. Added two new functions get_cpu_physical_id() and get_bus_freq().
> > 3. Used a new way to get all the CPUs which sharing clock wire.
> >
> > Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> > ---
> >  drivers/cpufreq/Kconfig.arm                        |   8 ++
> >  drivers/cpufreq/Kconfig.powerpc                    |  11 +-
> >  drivers/cpufreq/Makefile                           |   2 +-
> >  .../{ppc-corenet-cpufreq.c => qoriq-cpufreq.c}     | 150
> ++++++++++++++-------
> >  4 files changed, 114 insertions(+), 57 deletions(-)  rename
> > drivers/cpufreq/{ppc-corenet-cpufreq.c => qoriq-cpufreq.c} (72%)
> >
> > diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
> > index 83a75dc..1925ae94 100644
> > --- a/drivers/cpufreq/Kconfig.arm
> > +++ b/drivers/cpufreq/Kconfig.arm
> > @@ -247,3 +247,11 @@ config ARM_TEGRA_CPUFREQ
> >         default y
> >         help
> >           This adds the CPUFreq driver support for TEGRA SOCs.
> > +
> > +config QORIQ_CPUFREQ
> > +       tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> > +       depends on OF && COMMON_CLK
> > +       select CLK_PPC_CORENET
> > +       help
> > +         This adds the CPUFreq driver support for Freescale QorIQ SoCs
> > +         which are capable of changing the CPU's frequency dynamically.
> > diff --git a/drivers/cpufreq/Kconfig.powerpc
> > b/drivers/cpufreq/Kconfig.powerpc index 72564b7..3a34248 100644
> > --- a/drivers/cpufreq/Kconfig.powerpc
> > +++ b/drivers/cpufreq/Kconfig.powerpc
> > @@ -23,14 +23,13 @@ config CPU_FREQ_MAPLE
> >           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
> > +config QORIQ_CPUFREQ
> > +       tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> > +       depends on OF && COMMON_CLK
> >         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.
> > +         This adds the CPUFreq driver support for Freescale QorIQ SoCs
> > +         which are capable of changing the CPU's frequency dynamically.
> >
> >  config CPU_FREQ_PMAC
> >         bool "Support for Apple PowerBooks"
> 
> Don't need this duplication at all. Just move this to Kconfig instead of .arm and
> ppc.
> 
> > diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c
> > b/drivers/cpufreq/qoriq-cpufreq.c
> 
> >  /**
> >   * struct cpu_data - per CPU data struct @@ -69,9 +68,6 @@ static
> > const u32 *fmask;
> >
> >  static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
> >
> > -/* cpumask in a cluster */
> > -static DEFINE_PER_CPU(cpumask_var_t, cpu_mask);
> > -
> >  #ifndef CONFIG_SMP
> >  static inline const struct cpumask *cpu_core_mask(int cpu)  { @@
> > -79,6 +75,79 @@ static inline const struct cpumask *cpu_core_mask(int
> > cpu)  }  #endif
> >
> > +#if defined(CONFIG_PPC_E500MC)
> > +static int get_cpu_physical_id(int cpu) {
> > +       return get_hard_smp_processor_id(cpu); } #elif
> > +defined(CONFIG_ARM)
> 
> Wouldn't a #else work here as there are just two platforms we are talking about ?
> 
> > +static int get_cpu_physical_id(int cpu) {
> > +       return topology_core_id(cpu);
> > +}
> > +#endif
> > +
> > +static u32 get_bus_freq(void)
> > +{
> > +       struct device_node *soc;
> > +       u32 sysfreq;
> > +
> > +       soc = of_find_node_by_type(NULL, "soc");
> > +       if (!soc)
> > +               return 0;
> > +
> > +       if (of_property_read_u32(soc, "bus-frequency", &sysfreq))
> > +               sysfreq = 0;
> > +
> > +       of_node_put(soc);
> > +
> > +       return sysfreq;
> > +}
> > +
> > +static struct device_node *cpu_to_clk_node(int cpu) {
> > +       struct device_node *np, *clk_np;
> > +
> > +       if (!cpu_present(cpu))
> > +               return NULL;
> > +
> > +       np = of_get_cpu_node(cpu, NULL);
> > +       if (!np)
> > +               return NULL;
> > +
> > +       clk_np = of_parse_phandle(np, "clocks", 0);
> > +       if (!clk_np)
> > +               return NULL;
> > +
> > +       of_node_put(np);
> > +
> > +       return clk_np;
> > +}
> > +
> > +/* traverse cpu nodes to get cpu mask of sharing clock wire */ static
> > +void set_affected_cpus(struct cpufreq_policy *policy) {
> > +       struct device_node *np, *clk_np;
> > +       struct cpumask *dstp = policy->cpus;
> > +       int i;
> > +
> > +       np = cpu_to_clk_node(policy->cpu);
> > +       if (!np)
> > +               return;
> > +
> > +       for_each_present_cpu(i) {
> > +               clk_np = cpu_to_clk_node(i);
> > +               if (!clk_np)
> > +                       continue;
> > +
> > +               if (clk_np == np)
> > +                       cpumask_set_cpu(i, dstp);
> 
> So you are depending on matching the clock-nodes from DT for getting this
> information, right ? There is nothing that the architecture gives?
> 
Yes. I used an architecture dependent way.

> > +
> > +               of_node_put(clk_np);
> > +       }
> > +       of_node_put(np);
> > +}
> > +
> >  /* reduce the duplicated frequencies in frequency table */  static
> > void freq_table_redup(struct cpufreq_frequency_table *freq_table,
> >                 int count)
> > @@ -105,6 +174,7 @@ static void freq_table_sort(struct
> cpufreq_frequency_table *freq_table,
> >         int i, j, ind;
> >         unsigned int freq, max_freq;
> >         struct cpufreq_frequency_table table;
> > +
> >         for (i = 0; i < count - 1; i++) {
> >                 max_freq = freq_table[i].frequency;
> >                 ind = i;
> > @@ -129,7 +199,7 @@ static void freq_table_sort(struct
> cpufreq_frequency_table *freq_table,
> >         }
> >  }
> >
> > -static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> > +static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
> >  {
> >         struct device_node *np;
> >         int i, count, ret;
> > @@ -145,10 +215,8 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> >                 return -ENODEV;
> >
> >         data = kzalloc(sizeof(*data), GFP_KERNEL);
> > -       if (!data) {
> > -               pr_err("%s: no memory\n", __func__);
> 
> Wasn't this useful ?
> 
To get rid of checkpatch warning.
Currently, checkpatch script doesn't allow to output memory allocation error information.
We will get memory information eventually if there are memory related error.

Regards,
Yuantian

> > +       if (!data)
> >                 goto err_np;
> > -       }
> >
> >         policy->clk = of_clk_get(np, 0);
> >         if (IS_ERR(policy->clk)) {
> > @@ -170,7 +238,7 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> >         }
> >
> >         if (fmask)
> > -               mask = fmask[get_hard_smp_processor_id(cpu)];
> > +               mask = fmask[get_cpu_physical_id(cpu)];
> >         else
> >                 mask = 0x0;
> >
> > @@ -201,13 +269,13 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> >         data->table = table;
> >
> >         /* update ->cpus if we have cluster, no harm if not */
> > -       cpumask_copy(policy->cpus, per_cpu(cpu_mask, cpu));
> > -       for_each_cpu(i, per_cpu(cpu_mask, cpu))
> > +       set_affected_cpus(policy);
> > +       for_each_cpu(i, policy->cpus)
> >                 per_cpu(cpu_data, i) = data;
> 
> Get rid of this per-cpu data and use policy->driver_data instead.
> 
> >
> >         /* Minimum transition latency is 12 platform clocks */
> >         u64temp = 12ULL * NSEC_PER_SEC;
> > -       do_div(u64temp, fsl_get_sys_freq());
> > +       do_div(u64temp, get_bus_freq());
> >         policy->cpuinfo.transition_latency = u64temp + 1;
> >
> >         of_node_put(np);
> > @@ -227,7 +295,7 @@ err_np:
> >         return -ENODEV;
> >  }
> >
> > -static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy
> > *policy)
> > +static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy
> > +*policy)
> >  {
> >         struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
> >         unsigned int cpu;
> > @@ -236,13 +304,13 @@ static int __exit corenet_cpufreq_cpu_exit(struct
> cpufreq_policy *policy)
> >         kfree(data->table);
> >         kfree(data);
> >
> > -       for_each_cpu(cpu, per_cpu(cpu_mask, policy->cpu))
> > +       for_each_cpu(cpu, policy->cpus)
> >                 per_cpu(cpu_data, cpu) = NULL;
> >
> >         return 0;
> >  }
> >
> > -static int corenet_cpufreq_target(struct cpufreq_policy *policy,
> > +static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
> >                 unsigned int index)
> >  {
> >         struct clk *parent;
> > @@ -252,18 +320,18 @@ static int corenet_cpufreq_target(struct
> cpufreq_policy *policy,
> >         return clk_set_parent(policy->clk, parent);  }
> >
> > -static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
> > -       .name           = "ppc_cpufreq",
> > +static struct cpufreq_driver qoriq_cpufreq_driver = {
> > +       .name           = "qoriq_cpufreq",
> >         .flags          = CPUFREQ_CONST_LOOPS,
> > -       .init           = corenet_cpufreq_cpu_init,
> > -       .exit           = __exit_p(corenet_cpufreq_cpu_exit),
> > +       .init           = qoriq_cpufreq_cpu_init,
> > +       .exit           = __exit_p(qoriq_cpufreq_cpu_exit),
> >         .verify         = cpufreq_generic_frequency_table_verify,
> > -       .target_index   = corenet_cpufreq_target,
> > +       .target_index   = qoriq_cpufreq_target,
> >         .get            = cpufreq_generic_get,
> >         .attr           = cpufreq_generic_attr,
> >  };
> >
> > -static const struct of_device_id node_matches[] __initdata = {
> > +static const struct of_device_id node_matches[] __initconst = {
> >         { .compatible = "fsl,p2041-clockgen", .data = &sdata[0], },
> >         { .compatible = "fsl,p3041-clockgen", .data = &sdata[0], },
> >         { .compatible = "fsl,p5020-clockgen", .data = &sdata[1], }, @@
> > -273,61 +341,43 @@ static const struct of_device_id node_matches[]
> __initdata = {
> >         {}
> >  };
> >
> > -static int __init ppc_corenet_cpufreq_init(void)
> > +static int __init qoriq_cpufreq_init(void)
> >  {
> >         int ret;
> >         struct device_node  *np;
> >         const struct of_device_id *match;
> >         const struct soc_data *data;
> > -       unsigned int cpu;
> >
> >         np = of_find_matching_node(NULL, node_matches);
> >         if (!np)
> >                 return -ENODEV;
> >
> > -       for_each_possible_cpu(cpu) {
> > -               if (!alloc_cpumask_var(&per_cpu(cpu_mask, cpu),
> GFP_KERNEL))
> > -                       goto err_mask;
> > -               cpumask_copy(per_cpu(cpu_mask, cpu),
> cpu_core_mask(cpu));
> > -       }
> > -
> >         match = of_match_node(node_matches, np);
> >         data = match->data;
> >         if (data) {
> >                 if (data->flag)
> >                         fmask = data->freq_mask;
> > -               min_cpufreq = fsl_get_sys_freq();
> > +               min_cpufreq = get_bus_freq();
> >         } else {
> > -               min_cpufreq = fsl_get_sys_freq() / 2;
> > +               min_cpufreq = get_bus_freq() / 2;
> >         }
> >
> >         of_node_put(np);
> >
> > -       ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
> > +       ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
> >         if (!ret)
> > -               pr_info("Freescale PowerPC corenet CPU frequency scaling
> driver\n");
> > +               pr_info("Freescale QorIQ CPU frequency scaling
> > + driver\n");
> >
> >         return ret;
> > -
> > -err_mask:
> > -       for_each_possible_cpu(cpu)
> > -               free_cpumask_var(per_cpu(cpu_mask, cpu));
> > -
> > -       return -ENOMEM;
> >  }
> > -module_init(ppc_corenet_cpufreq_init);
> > +module_init(qoriq_cpufreq_init);
> >
> > -static void __exit ppc_corenet_cpufreq_exit(void)
> > +static void __exit qoriq_cpufreq_exit(void)
> >  {
> > -       unsigned int cpu;
> > -
> > -       for_each_possible_cpu(cpu)
> > -               free_cpumask_var(per_cpu(cpu_mask, cpu));
> > -
> > -       cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
> > +       cpufreq_unregister_driver(&qoriq_cpufreq_driver);
> >  }
> > -module_exit(ppc_corenet_cpufreq_exit);
> > +module_exit(qoriq_cpufreq_exit);
> >
> >  MODULE_LICENSE("GPL");
> >  MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
> > -MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series
> > SoCs");
> > +MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs");
> 
> + comments from Kumar Gala :)
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-10-20  6:10     ` Yuantian Tang
  0 siblings, 0 replies; 29+ messages in thread
From: Yuantian Tang @ 2014-10-20  6:10 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, Linux Kernel Mailing List, linux-pm, linuxppc-dev

Thanks for your comments.  Your comments will be addressed in next version.
Some explanations inline.

Thanks,
Yuantian

> -----Original Message-----
> From: Viresh Kumar [mailto:viresh.kumar@linaro.org]
> Sent: Friday, October 17, 2014 4:09 PM
> To: Tang Yuantian-B29983
> Cc: Rafael J. Wysocki; Linux Kernel Mailing List; linux-pm@vger.kernel.org;
> linuxppc-dev@ozlabs.org; Tang Yuantian-B29983
> Subject: Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ
> platforms
> 
> On 17 October 2014 08:43,  <B29983@freescale.com> wrote:
> 
> Hi B29983 :)
> 
> > From: Tang Yuantian <Yuantian.Tang@freescale.com>
> >
> > Freescale introduced new ARM core-based SoCs which support dynamic
> > frequency switch feature. DFS on new SoCs are compatible with current
> > PowerPC CoreNet platforms. In order to support those new platforms,
> > this driver needs to be slightly adjusted. The main changes include:
> >
> > 1. Changed the names of driver and functions in driver.
> > 2. Added two new functions get_cpu_physical_id() and get_bus_freq().
> > 3. Used a new way to get all the CPUs which sharing clock wire.
> >
> > Signed-off-by: Tang Yuantian <Yuantian.Tang@freescale.com>
> > ---
> >  drivers/cpufreq/Kconfig.arm                        |   8 ++
> >  drivers/cpufreq/Kconfig.powerpc                    |  11 +-
> >  drivers/cpufreq/Makefile                           |   2 +-
> >  .../{ppc-corenet-cpufreq.c => qoriq-cpufreq.c}     | 150
> ++++++++++++++-------
> >  4 files changed, 114 insertions(+), 57 deletions(-)  rename
> > drivers/cpufreq/{ppc-corenet-cpufreq.c => qoriq-cpufreq.c} (72%)
> >
> > diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm
> > index 83a75dc..1925ae94 100644
> > --- a/drivers/cpufreq/Kconfig.arm
> > +++ b/drivers/cpufreq/Kconfig.arm
> > @@ -247,3 +247,11 @@ config ARM_TEGRA_CPUFREQ
> >         default y
> >         help
> >           This adds the CPUFreq driver support for TEGRA SOCs.
> > +
> > +config QORIQ_CPUFREQ
> > +       tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> > +       depends on OF && COMMON_CLK
> > +       select CLK_PPC_CORENET
> > +       help
> > +         This adds the CPUFreq driver support for Freescale QorIQ SoCs
> > +         which are capable of changing the CPU's frequency dynamically.
> > diff --git a/drivers/cpufreq/Kconfig.powerpc
> > b/drivers/cpufreq/Kconfig.powerpc index 72564b7..3a34248 100644
> > --- a/drivers/cpufreq/Kconfig.powerpc
> > +++ b/drivers/cpufreq/Kconfig.powerpc
> > @@ -23,14 +23,13 @@ config CPU_FREQ_MAPLE
> >           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
> > +config QORIQ_CPUFREQ
> > +       tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> > +       depends on OF && COMMON_CLK
> >         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.
> > +         This adds the CPUFreq driver support for Freescale QorIQ SoCs
> > +         which are capable of changing the CPU's frequency dynamically.
> >
> >  config CPU_FREQ_PMAC
> >         bool "Support for Apple PowerBooks"
> 
> Don't need this duplication at all. Just move this to Kconfig instead of .arm and
> ppc.
> 
> > diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c
> > b/drivers/cpufreq/qoriq-cpufreq.c
> 
> >  /**
> >   * struct cpu_data - per CPU data struct @@ -69,9 +68,6 @@ static
> > const u32 *fmask;
> >
> >  static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
> >
> > -/* cpumask in a cluster */
> > -static DEFINE_PER_CPU(cpumask_var_t, cpu_mask);
> > -
> >  #ifndef CONFIG_SMP
> >  static inline const struct cpumask *cpu_core_mask(int cpu)  { @@
> > -79,6 +75,79 @@ static inline const struct cpumask *cpu_core_mask(int
> > cpu)  }  #endif
> >
> > +#if defined(CONFIG_PPC_E500MC)
> > +static int get_cpu_physical_id(int cpu) {
> > +       return get_hard_smp_processor_id(cpu); } #elif
> > +defined(CONFIG_ARM)
> 
> Wouldn't a #else work here as there are just two platforms we are talking about ?
> 
> > +static int get_cpu_physical_id(int cpu) {
> > +       return topology_core_id(cpu);
> > +}
> > +#endif
> > +
> > +static u32 get_bus_freq(void)
> > +{
> > +       struct device_node *soc;
> > +       u32 sysfreq;
> > +
> > +       soc = of_find_node_by_type(NULL, "soc");
> > +       if (!soc)
> > +               return 0;
> > +
> > +       if (of_property_read_u32(soc, "bus-frequency", &sysfreq))
> > +               sysfreq = 0;
> > +
> > +       of_node_put(soc);
> > +
> > +       return sysfreq;
> > +}
> > +
> > +static struct device_node *cpu_to_clk_node(int cpu) {
> > +       struct device_node *np, *clk_np;
> > +
> > +       if (!cpu_present(cpu))
> > +               return NULL;
> > +
> > +       np = of_get_cpu_node(cpu, NULL);
> > +       if (!np)
> > +               return NULL;
> > +
> > +       clk_np = of_parse_phandle(np, "clocks", 0);
> > +       if (!clk_np)
> > +               return NULL;
> > +
> > +       of_node_put(np);
> > +
> > +       return clk_np;
> > +}
> > +
> > +/* traverse cpu nodes to get cpu mask of sharing clock wire */ static
> > +void set_affected_cpus(struct cpufreq_policy *policy) {
> > +       struct device_node *np, *clk_np;
> > +       struct cpumask *dstp = policy->cpus;
> > +       int i;
> > +
> > +       np = cpu_to_clk_node(policy->cpu);
> > +       if (!np)
> > +               return;
> > +
> > +       for_each_present_cpu(i) {
> > +               clk_np = cpu_to_clk_node(i);
> > +               if (!clk_np)
> > +                       continue;
> > +
> > +               if (clk_np == np)
> > +                       cpumask_set_cpu(i, dstp);
> 
> So you are depending on matching the clock-nodes from DT for getting this
> information, right ? There is nothing that the architecture gives?
> 
Yes. I used an architecture dependent way.

> > +
> > +               of_node_put(clk_np);
> > +       }
> > +       of_node_put(np);
> > +}
> > +
> >  /* reduce the duplicated frequencies in frequency table */  static
> > void freq_table_redup(struct cpufreq_frequency_table *freq_table,
> >                 int count)
> > @@ -105,6 +174,7 @@ static void freq_table_sort(struct
> cpufreq_frequency_table *freq_table,
> >         int i, j, ind;
> >         unsigned int freq, max_freq;
> >         struct cpufreq_frequency_table table;
> > +
> >         for (i = 0; i < count - 1; i++) {
> >                 max_freq = freq_table[i].frequency;
> >                 ind = i;
> > @@ -129,7 +199,7 @@ static void freq_table_sort(struct
> cpufreq_frequency_table *freq_table,
> >         }
> >  }
> >
> > -static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> > +static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
> >  {
> >         struct device_node *np;
> >         int i, count, ret;
> > @@ -145,10 +215,8 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> >                 return -ENODEV;
> >
> >         data = kzalloc(sizeof(*data), GFP_KERNEL);
> > -       if (!data) {
> > -               pr_err("%s: no memory\n", __func__);
> 
> Wasn't this useful ?
> 
To get rid of checkpatch warning.
Currently, checkpatch script doesn't allow to output memory allocation error information.
We will get memory information eventually if there are memory related error.

Regards,
Yuantian

> > +       if (!data)
> >                 goto err_np;
> > -       }
> >
> >         policy->clk = of_clk_get(np, 0);
> >         if (IS_ERR(policy->clk)) {
> > @@ -170,7 +238,7 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> >         }
> >
> >         if (fmask)
> > -               mask = fmask[get_hard_smp_processor_id(cpu)];
> > +               mask = fmask[get_cpu_physical_id(cpu)];
> >         else
> >                 mask = 0x0;
> >
> > @@ -201,13 +269,13 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> >         data->table = table;
> >
> >         /* update ->cpus if we have cluster, no harm if not */
> > -       cpumask_copy(policy->cpus, per_cpu(cpu_mask, cpu));
> > -       for_each_cpu(i, per_cpu(cpu_mask, cpu))
> > +       set_affected_cpus(policy);
> > +       for_each_cpu(i, policy->cpus)
> >                 per_cpu(cpu_data, i) = data;
> 
> Get rid of this per-cpu data and use policy->driver_data instead.
> 
> >
> >         /* Minimum transition latency is 12 platform clocks */
> >         u64temp = 12ULL * NSEC_PER_SEC;
> > -       do_div(u64temp, fsl_get_sys_freq());
> > +       do_div(u64temp, get_bus_freq());
> >         policy->cpuinfo.transition_latency = u64temp + 1;
> >
> >         of_node_put(np);
> > @@ -227,7 +295,7 @@ err_np:
> >         return -ENODEV;
> >  }
> >
> > -static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy
> > *policy)
> > +static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy
> > +*policy)
> >  {
> >         struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
> >         unsigned int cpu;
> > @@ -236,13 +304,13 @@ static int __exit corenet_cpufreq_cpu_exit(struct
> cpufreq_policy *policy)
> >         kfree(data->table);
> >         kfree(data);
> >
> > -       for_each_cpu(cpu, per_cpu(cpu_mask, policy->cpu))
> > +       for_each_cpu(cpu, policy->cpus)
> >                 per_cpu(cpu_data, cpu) = NULL;
> >
> >         return 0;
> >  }
> >
> > -static int corenet_cpufreq_target(struct cpufreq_policy *policy,
> > +static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
> >                 unsigned int index)
> >  {
> >         struct clk *parent;
> > @@ -252,18 +320,18 @@ static int corenet_cpufreq_target(struct
> cpufreq_policy *policy,
> >         return clk_set_parent(policy->clk, parent);  }
> >
> > -static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
> > -       .name           = "ppc_cpufreq",
> > +static struct cpufreq_driver qoriq_cpufreq_driver = {
> > +       .name           = "qoriq_cpufreq",
> >         .flags          = CPUFREQ_CONST_LOOPS,
> > -       .init           = corenet_cpufreq_cpu_init,
> > -       .exit           = __exit_p(corenet_cpufreq_cpu_exit),
> > +       .init           = qoriq_cpufreq_cpu_init,
> > +       .exit           = __exit_p(qoriq_cpufreq_cpu_exit),
> >         .verify         = cpufreq_generic_frequency_table_verify,
> > -       .target_index   = corenet_cpufreq_target,
> > +       .target_index   = qoriq_cpufreq_target,
> >         .get            = cpufreq_generic_get,
> >         .attr           = cpufreq_generic_attr,
> >  };
> >
> > -static const struct of_device_id node_matches[] __initdata = {
> > +static const struct of_device_id node_matches[] __initconst = {
> >         { .compatible = "fsl,p2041-clockgen", .data = &sdata[0], },
> >         { .compatible = "fsl,p3041-clockgen", .data = &sdata[0], },
> >         { .compatible = "fsl,p5020-clockgen", .data = &sdata[1], }, @@
> > -273,61 +341,43 @@ static const struct of_device_id node_matches[]
> __initdata = {
> >         {}
> >  };
> >
> > -static int __init ppc_corenet_cpufreq_init(void)
> > +static int __init qoriq_cpufreq_init(void)
> >  {
> >         int ret;
> >         struct device_node  *np;
> >         const struct of_device_id *match;
> >         const struct soc_data *data;
> > -       unsigned int cpu;
> >
> >         np = of_find_matching_node(NULL, node_matches);
> >         if (!np)
> >                 return -ENODEV;
> >
> > -       for_each_possible_cpu(cpu) {
> > -               if (!alloc_cpumask_var(&per_cpu(cpu_mask, cpu),
> GFP_KERNEL))
> > -                       goto err_mask;
> > -               cpumask_copy(per_cpu(cpu_mask, cpu),
> cpu_core_mask(cpu));
> > -       }
> > -
> >         match = of_match_node(node_matches, np);
> >         data = match->data;
> >         if (data) {
> >                 if (data->flag)
> >                         fmask = data->freq_mask;
> > -               min_cpufreq = fsl_get_sys_freq();
> > +               min_cpufreq = get_bus_freq();
> >         } else {
> > -               min_cpufreq = fsl_get_sys_freq() / 2;
> > +               min_cpufreq = get_bus_freq() / 2;
> >         }
> >
> >         of_node_put(np);
> >
> > -       ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
> > +       ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
> >         if (!ret)
> > -               pr_info("Freescale PowerPC corenet CPU frequency scaling
> driver\n");
> > +               pr_info("Freescale QorIQ CPU frequency scaling
> > + driver\n");
> >
> >         return ret;
> > -
> > -err_mask:
> > -       for_each_possible_cpu(cpu)
> > -               free_cpumask_var(per_cpu(cpu_mask, cpu));
> > -
> > -       return -ENOMEM;
> >  }
> > -module_init(ppc_corenet_cpufreq_init);
> > +module_init(qoriq_cpufreq_init);
> >
> > -static void __exit ppc_corenet_cpufreq_exit(void)
> > +static void __exit qoriq_cpufreq_exit(void)
> >  {
> > -       unsigned int cpu;
> > -
> > -       for_each_possible_cpu(cpu)
> > -               free_cpumask_var(per_cpu(cpu_mask, cpu));
> > -
> > -       cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
> > +       cpufreq_unregister_driver(&qoriq_cpufreq_driver);
> >  }
> > -module_exit(ppc_corenet_cpufreq_exit);
> > +module_exit(qoriq_cpufreq_exit);
> >
> >  MODULE_LICENSE("GPL");
> >  MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
> > -MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series
> > SoCs");
> > +MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs");
> 
> + comments from Kumar Gala :)

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-10-20  6:10     ` Yuantian Tang
  0 siblings, 0 replies; 29+ messages in thread
From: Yuantian Tang @ 2014-10-20  6:10 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: linuxppc-dev, Rafael J. Wysocki, Linux Kernel Mailing List, linux-pm

VGhhbmtzIGZvciB5b3VyIGNvbW1lbnRzLiAgWW91ciBjb21tZW50cyB3aWxsIGJlIGFkZHJlc3Nl
ZCBpbiBuZXh0IHZlcnNpb24uDQpTb21lIGV4cGxhbmF0aW9ucyBpbmxpbmUuDQoNClRoYW5rcywN
Cll1YW50aWFuDQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogVmlyZXNo
IEt1bWFyIFttYWlsdG86dmlyZXNoLmt1bWFyQGxpbmFyby5vcmddDQo+IFNlbnQ6IEZyaWRheSwg
T2N0b2JlciAxNywgMjAxNCA0OjA5IFBNDQo+IFRvOiBUYW5nIFl1YW50aWFuLUIyOTk4Mw0KPiBD
YzogUmFmYWVsIEouIFd5c29ja2k7IExpbnV4IEtlcm5lbCBNYWlsaW5nIExpc3Q7IGxpbnV4LXBt
QHZnZXIua2VybmVsLm9yZzsNCj4gbGludXhwcGMtZGV2QG96bGFicy5vcmc7IFRhbmcgWXVhbnRp
YW4tQjI5OTgzDQo+IFN1YmplY3Q6IFJlOiBbUEFUQ0hdIGNwdWZyZXE6IHFvcmlxOiBNYWtlIHRo
ZSBkcml2ZXIgdXNhYmxlIG9uIGFsbCBRb3JJUQ0KPiBwbGF0Zm9ybXMNCj4gDQo+IE9uIDE3IE9j
dG9iZXIgMjAxNCAwODo0MywgIDxCMjk5ODNAZnJlZXNjYWxlLmNvbT4gd3JvdGU6DQo+IA0KPiBI
aSBCMjk5ODMgOikNCj4gDQo+ID4gRnJvbTogVGFuZyBZdWFudGlhbiA8WXVhbnRpYW4uVGFuZ0Bm
cmVlc2NhbGUuY29tPg0KPiA+DQo+ID4gRnJlZXNjYWxlIGludHJvZHVjZWQgbmV3IEFSTSBjb3Jl
LWJhc2VkIFNvQ3Mgd2hpY2ggc3VwcG9ydCBkeW5hbWljDQo+ID4gZnJlcXVlbmN5IHN3aXRjaCBm
ZWF0dXJlLiBERlMgb24gbmV3IFNvQ3MgYXJlIGNvbXBhdGlibGUgd2l0aCBjdXJyZW50DQo+ID4g
UG93ZXJQQyBDb3JlTmV0IHBsYXRmb3Jtcy4gSW4gb3JkZXIgdG8gc3VwcG9ydCB0aG9zZSBuZXcg
cGxhdGZvcm1zLA0KPiA+IHRoaXMgZHJpdmVyIG5lZWRzIHRvIGJlIHNsaWdodGx5IGFkanVzdGVk
LiBUaGUgbWFpbiBjaGFuZ2VzIGluY2x1ZGU6DQo+ID4NCj4gPiAxLiBDaGFuZ2VkIHRoZSBuYW1l
cyBvZiBkcml2ZXIgYW5kIGZ1bmN0aW9ucyBpbiBkcml2ZXIuDQo+ID4gMi4gQWRkZWQgdHdvIG5l
dyBmdW5jdGlvbnMgZ2V0X2NwdV9waHlzaWNhbF9pZCgpIGFuZCBnZXRfYnVzX2ZyZXEoKS4NCj4g
PiAzLiBVc2VkIGEgbmV3IHdheSB0byBnZXQgYWxsIHRoZSBDUFVzIHdoaWNoIHNoYXJpbmcgY2xv
Y2sgd2lyZS4NCj4gPg0KPiA+IFNpZ25lZC1vZmYtYnk6IFRhbmcgWXVhbnRpYW4gPFl1YW50aWFu
LlRhbmdAZnJlZXNjYWxlLmNvbT4NCj4gPiAtLS0NCj4gPiAgZHJpdmVycy9jcHVmcmVxL0tjb25m
aWcuYXJtICAgICAgICAgICAgICAgICAgICAgICAgfCAgIDggKysNCj4gPiAgZHJpdmVycy9jcHVm
cmVxL0tjb25maWcucG93ZXJwYyAgICAgICAgICAgICAgICAgICAgfCAgMTEgKy0NCj4gPiAgZHJp
dmVycy9jcHVmcmVxL01ha2VmaWxlICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIDIgKy0N
Cj4gPiAgLi4uL3twcGMtY29yZW5ldC1jcHVmcmVxLmMgPT4gcW9yaXEtY3B1ZnJlcS5jfSAgICAg
fCAxNTANCj4gKysrKysrKysrKysrKystLS0tLS0tDQo+ID4gIDQgZmlsZXMgY2hhbmdlZCwgMTE0
IGluc2VydGlvbnMoKyksIDU3IGRlbGV0aW9ucygtKSAgcmVuYW1lDQo+ID4gZHJpdmVycy9jcHVm
cmVxL3twcGMtY29yZW5ldC1jcHVmcmVxLmMgPT4gcW9yaXEtY3B1ZnJlcS5jfSAoNzIlKQ0KPiA+
DQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvY3B1ZnJlcS9LY29uZmlnLmFybSBiL2RyaXZlcnMv
Y3B1ZnJlcS9LY29uZmlnLmFybQ0KPiA+IGluZGV4IDgzYTc1ZGMuLjE5MjVhZTk0IDEwMDY0NA0K
PiA+IC0tLSBhL2RyaXZlcnMvY3B1ZnJlcS9LY29uZmlnLmFybQ0KPiA+ICsrKyBiL2RyaXZlcnMv
Y3B1ZnJlcS9LY29uZmlnLmFybQ0KPiA+IEBAIC0yNDcsMyArMjQ3LDExIEBAIGNvbmZpZyBBUk1f
VEVHUkFfQ1BVRlJFUQ0KPiA+ICAgICAgICAgZGVmYXVsdCB5DQo+ID4gICAgICAgICBoZWxwDQo+
ID4gICAgICAgICAgIFRoaXMgYWRkcyB0aGUgQ1BVRnJlcSBkcml2ZXIgc3VwcG9ydCBmb3IgVEVH
UkEgU09Dcy4NCj4gPiArDQo+ID4gK2NvbmZpZyBRT1JJUV9DUFVGUkVRDQo+ID4gKyAgICAgICB0
cmlzdGF0ZSAiQ1BVIGZyZXF1ZW5jeSBzY2FsaW5nIGRyaXZlciBmb3IgRnJlZXNjYWxlIFFvcklR
IFNvQ3MiDQo+ID4gKyAgICAgICBkZXBlbmRzIG9uIE9GICYmIENPTU1PTl9DTEsNCj4gPiArICAg
ICAgIHNlbGVjdCBDTEtfUFBDX0NPUkVORVQNCj4gPiArICAgICAgIGhlbHANCj4gPiArICAgICAg
ICAgVGhpcyBhZGRzIHRoZSBDUFVGcmVxIGRyaXZlciBzdXBwb3J0IGZvciBGcmVlc2NhbGUgUW9y
SVEgU29Dcw0KPiA+ICsgICAgICAgICB3aGljaCBhcmUgY2FwYWJsZSBvZiBjaGFuZ2luZyB0aGUg
Q1BVJ3MgZnJlcXVlbmN5IGR5bmFtaWNhbGx5Lg0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2Nw
dWZyZXEvS2NvbmZpZy5wb3dlcnBjDQo+ID4gYi9kcml2ZXJzL2NwdWZyZXEvS2NvbmZpZy5wb3dl
cnBjIGluZGV4IDcyNTY0YjcuLjNhMzQyNDggMTAwNjQ0DQo+ID4gLS0tIGEvZHJpdmVycy9jcHVm
cmVxL0tjb25maWcucG93ZXJwYw0KPiA+ICsrKyBiL2RyaXZlcnMvY3B1ZnJlcS9LY29uZmlnLnBv
d2VycGMNCj4gPiBAQCAtMjMsMTQgKzIzLDEzIEBAIGNvbmZpZyBDUFVfRlJFUV9NQVBMRQ0KPiA+
ICAgICAgICAgICBUaGlzIGFkZHMgc3VwcG9ydCBmb3IgZnJlcXVlbmN5IHN3aXRjaGluZyBvbiBN
YXBsZSA5NzBGWA0KPiA+ICAgICAgICAgICBFdmFsdWF0aW9uIEJvYXJkIGFuZCBjb21wYXRpYmxl
IGJvYXJkcyAoSUJNIEpTMnggYmxhZGVzKS4NCj4gPg0KPiA+IC1jb25maWcgUFBDX0NPUkVORVRf
Q1BVRlJFUQ0KPiA+IC0gICAgICAgdHJpc3RhdGUgIkNQVSBmcmVxdWVuY3kgc2NhbGluZyBkcml2
ZXIgZm9yIEZyZWVzY2FsZSBFNTAwTUMgU29DcyINCj4gPiAtICAgICAgIGRlcGVuZHMgb24gUFBD
X0U1MDBNQyAmJiBPRiAmJiBDT01NT05fQ0xLDQo+ID4gK2NvbmZpZyBRT1JJUV9DUFVGUkVRDQo+
ID4gKyAgICAgICB0cmlzdGF0ZSAiQ1BVIGZyZXF1ZW5jeSBzY2FsaW5nIGRyaXZlciBmb3IgRnJl
ZXNjYWxlIFFvcklRIFNvQ3MiDQo+ID4gKyAgICAgICBkZXBlbmRzIG9uIE9GICYmIENPTU1PTl9D
TEsNCj4gPiAgICAgICAgIHNlbGVjdCBDTEtfUFBDX0NPUkVORVQNCj4gPiAgICAgICAgIGhlbHAN
Cj4gPiAtICAgICAgICAgVGhpcyBhZGRzIHRoZSBDUFVGcmVxIGRyaXZlciBzdXBwb3J0IGZvciBG
cmVlc2NhbGUgZTUwMG1jLA0KPiA+IC0gICAgICAgICBlNTUwMCBhbmQgZTY1MDAgc2VyaWVzIFNv
Q3Mgd2hpY2ggYXJlIGNhcGFibGUgb2YgY2hhbmdpbmcNCj4gPiAtICAgICAgICAgdGhlIENQVSdz
IGZyZXF1ZW5jeSBkeW5hbWljYWxseS4NCj4gPiArICAgICAgICAgVGhpcyBhZGRzIHRoZSBDUFVG
cmVxIGRyaXZlciBzdXBwb3J0IGZvciBGcmVlc2NhbGUgUW9ySVEgU29Dcw0KPiA+ICsgICAgICAg
ICB3aGljaCBhcmUgY2FwYWJsZSBvZiBjaGFuZ2luZyB0aGUgQ1BVJ3MgZnJlcXVlbmN5IGR5bmFt
aWNhbGx5Lg0KPiA+DQo+ID4gIGNvbmZpZyBDUFVfRlJFUV9QTUFDDQo+ID4gICAgICAgICBib29s
ICJTdXBwb3J0IGZvciBBcHBsZSBQb3dlckJvb2tzIg0KPiANCj4gRG9uJ3QgbmVlZCB0aGlzIGR1
cGxpY2F0aW9uIGF0IGFsbC4gSnVzdCBtb3ZlIHRoaXMgdG8gS2NvbmZpZyBpbnN0ZWFkIG9mIC5h
cm0gYW5kDQo+IHBwYy4NCj4gDQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvY3B1ZnJlcS9wcGMt
Y29yZW5ldC1jcHVmcmVxLmMNCj4gPiBiL2RyaXZlcnMvY3B1ZnJlcS9xb3JpcS1jcHVmcmVxLmMN
Cj4gDQo+ID4gIC8qKg0KPiA+ICAgKiBzdHJ1Y3QgY3B1X2RhdGEgLSBwZXIgQ1BVIGRhdGEgc3Ry
dWN0IEBAIC02OSw5ICs2OCw2IEBAIHN0YXRpYw0KPiA+IGNvbnN0IHUzMiAqZm1hc2s7DQo+ID4N
Cj4gPiAgc3RhdGljIERFRklORV9QRVJfQ1BVKHN0cnVjdCBjcHVfZGF0YSAqLCBjcHVfZGF0YSk7
DQo+ID4NCj4gPiAtLyogY3B1bWFzayBpbiBhIGNsdXN0ZXIgKi8NCj4gPiAtc3RhdGljIERFRklO
RV9QRVJfQ1BVKGNwdW1hc2tfdmFyX3QsIGNwdV9tYXNrKTsNCj4gPiAtDQo+ID4gICNpZm5kZWYg
Q09ORklHX1NNUA0KPiA+ICBzdGF0aWMgaW5saW5lIGNvbnN0IHN0cnVjdCBjcHVtYXNrICpjcHVf
Y29yZV9tYXNrKGludCBjcHUpICB7IEBADQo+ID4gLTc5LDYgKzc1LDc5IEBAIHN0YXRpYyBpbmxp
bmUgY29uc3Qgc3RydWN0IGNwdW1hc2sgKmNwdV9jb3JlX21hc2soaW50DQo+ID4gY3B1KSAgfSAg
I2VuZGlmDQo+ID4NCj4gPiArI2lmIGRlZmluZWQoQ09ORklHX1BQQ19FNTAwTUMpDQo+ID4gK3N0
YXRpYyBpbnQgZ2V0X2NwdV9waHlzaWNhbF9pZChpbnQgY3B1KSB7DQo+ID4gKyAgICAgICByZXR1
cm4gZ2V0X2hhcmRfc21wX3Byb2Nlc3Nvcl9pZChjcHUpOyB9ICNlbGlmDQo+ID4gK2RlZmluZWQo
Q09ORklHX0FSTSkNCj4gDQo+IFdvdWxkbid0IGEgI2Vsc2Ugd29yayBoZXJlIGFzIHRoZXJlIGFy
ZSBqdXN0IHR3byBwbGF0Zm9ybXMgd2UgYXJlIHRhbGtpbmcgYWJvdXQgPw0KPiANCj4gPiArc3Rh
dGljIGludCBnZXRfY3B1X3BoeXNpY2FsX2lkKGludCBjcHUpIHsNCj4gPiArICAgICAgIHJldHVy
biB0b3BvbG9neV9jb3JlX2lkKGNwdSk7DQo+ID4gK30NCj4gPiArI2VuZGlmDQo+ID4gKw0KPiA+
ICtzdGF0aWMgdTMyIGdldF9idXNfZnJlcSh2b2lkKQ0KPiA+ICt7DQo+ID4gKyAgICAgICBzdHJ1
Y3QgZGV2aWNlX25vZGUgKnNvYzsNCj4gPiArICAgICAgIHUzMiBzeXNmcmVxOw0KPiA+ICsNCj4g
PiArICAgICAgIHNvYyA9IG9mX2ZpbmRfbm9kZV9ieV90eXBlKE5VTEwsICJzb2MiKTsNCj4gPiAr
ICAgICAgIGlmICghc29jKQ0KPiA+ICsgICAgICAgICAgICAgICByZXR1cm4gMDsNCj4gPiArDQo+
ID4gKyAgICAgICBpZiAob2ZfcHJvcGVydHlfcmVhZF91MzIoc29jLCAiYnVzLWZyZXF1ZW5jeSIs
ICZzeXNmcmVxKSkNCj4gPiArICAgICAgICAgICAgICAgc3lzZnJlcSA9IDA7DQo+ID4gKw0KPiA+
ICsgICAgICAgb2Zfbm9kZV9wdXQoc29jKTsNCj4gPiArDQo+ID4gKyAgICAgICByZXR1cm4gc3lz
ZnJlcTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIHN0cnVjdCBkZXZpY2Vfbm9kZSAqY3B1
X3RvX2Nsa19ub2RlKGludCBjcHUpIHsNCj4gPiArICAgICAgIHN0cnVjdCBkZXZpY2Vfbm9kZSAq
bnAsICpjbGtfbnA7DQo+ID4gKw0KPiA+ICsgICAgICAgaWYgKCFjcHVfcHJlc2VudChjcHUpKQ0K
PiA+ICsgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsNCj4gPiArDQo+ID4gKyAgICAgICBucCA9
IG9mX2dldF9jcHVfbm9kZShjcHUsIE5VTEwpOw0KPiA+ICsgICAgICAgaWYgKCFucCkNCj4gPiAr
ICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7DQo+ID4gKw0KPiA+ICsgICAgICAgY2xrX25wID0g
b2ZfcGFyc2VfcGhhbmRsZShucCwgImNsb2NrcyIsIDApOw0KPiA+ICsgICAgICAgaWYgKCFjbGtf
bnApDQo+ID4gKyAgICAgICAgICAgICAgIHJldHVybiBOVUxMOw0KPiA+ICsNCj4gPiArICAgICAg
IG9mX25vZGVfcHV0KG5wKTsNCj4gPiArDQo+ID4gKyAgICAgICByZXR1cm4gY2xrX25wOw0KPiA+
ICt9DQo+ID4gKw0KPiA+ICsvKiB0cmF2ZXJzZSBjcHUgbm9kZXMgdG8gZ2V0IGNwdSBtYXNrIG9m
IHNoYXJpbmcgY2xvY2sgd2lyZSAqLyBzdGF0aWMNCj4gPiArdm9pZCBzZXRfYWZmZWN0ZWRfY3B1
cyhzdHJ1Y3QgY3B1ZnJlcV9wb2xpY3kgKnBvbGljeSkgew0KPiA+ICsgICAgICAgc3RydWN0IGRl
dmljZV9ub2RlICpucCwgKmNsa19ucDsNCj4gPiArICAgICAgIHN0cnVjdCBjcHVtYXNrICpkc3Rw
ID0gcG9saWN5LT5jcHVzOw0KPiA+ICsgICAgICAgaW50IGk7DQo+ID4gKw0KPiA+ICsgICAgICAg
bnAgPSBjcHVfdG9fY2xrX25vZGUocG9saWN5LT5jcHUpOw0KPiA+ICsgICAgICAgaWYgKCFucCkN
Cj4gPiArICAgICAgICAgICAgICAgcmV0dXJuOw0KPiA+ICsNCj4gPiArICAgICAgIGZvcl9lYWNo
X3ByZXNlbnRfY3B1KGkpIHsNCj4gPiArICAgICAgICAgICAgICAgY2xrX25wID0gY3B1X3RvX2Ns
a19ub2RlKGkpOw0KPiA+ICsgICAgICAgICAgICAgICBpZiAoIWNsa19ucCkNCj4gPiArICAgICAg
ICAgICAgICAgICAgICAgICBjb250aW51ZTsNCj4gPiArDQo+ID4gKyAgICAgICAgICAgICAgIGlm
IChjbGtfbnAgPT0gbnApDQo+ID4gKyAgICAgICAgICAgICAgICAgICAgICAgY3B1bWFza19zZXRf
Y3B1KGksIGRzdHApOw0KPiANCj4gU28geW91IGFyZSBkZXBlbmRpbmcgb24gbWF0Y2hpbmcgdGhl
IGNsb2NrLW5vZGVzIGZyb20gRFQgZm9yIGdldHRpbmcgdGhpcw0KPiBpbmZvcm1hdGlvbiwgcmln
aHQgPyBUaGVyZSBpcyBub3RoaW5nIHRoYXQgdGhlIGFyY2hpdGVjdHVyZSBnaXZlcz8NCj4gDQpZ
ZXMuIEkgdXNlZCBhbiBhcmNoaXRlY3R1cmUgZGVwZW5kZW50IHdheS4NCg0KPiA+ICsNCj4gPiAr
ICAgICAgICAgICAgICAgb2Zfbm9kZV9wdXQoY2xrX25wKTsNCj4gPiArICAgICAgIH0NCj4gPiAr
ICAgICAgIG9mX25vZGVfcHV0KG5wKTsNCj4gPiArfQ0KPiA+ICsNCj4gPiAgLyogcmVkdWNlIHRo
ZSBkdXBsaWNhdGVkIGZyZXF1ZW5jaWVzIGluIGZyZXF1ZW5jeSB0YWJsZSAqLyAgc3RhdGljDQo+
ID4gdm9pZCBmcmVxX3RhYmxlX3JlZHVwKHN0cnVjdCBjcHVmcmVxX2ZyZXF1ZW5jeV90YWJsZSAq
ZnJlcV90YWJsZSwNCj4gPiAgICAgICAgICAgICAgICAgaW50IGNvdW50KQ0KPiA+IEBAIC0xMDUs
NiArMTc0LDcgQEAgc3RhdGljIHZvaWQgZnJlcV90YWJsZV9zb3J0KHN0cnVjdA0KPiBjcHVmcmVx
X2ZyZXF1ZW5jeV90YWJsZSAqZnJlcV90YWJsZSwNCj4gPiAgICAgICAgIGludCBpLCBqLCBpbmQ7
DQo+ID4gICAgICAgICB1bnNpZ25lZCBpbnQgZnJlcSwgbWF4X2ZyZXE7DQo+ID4gICAgICAgICBz
dHJ1Y3QgY3B1ZnJlcV9mcmVxdWVuY3lfdGFibGUgdGFibGU7DQo+ID4gKw0KPiA+ICAgICAgICAg
Zm9yIChpID0gMDsgaSA8IGNvdW50IC0gMTsgaSsrKSB7DQo+ID4gICAgICAgICAgICAgICAgIG1h
eF9mcmVxID0gZnJlcV90YWJsZVtpXS5mcmVxdWVuY3k7DQo+ID4gICAgICAgICAgICAgICAgIGlu
ZCA9IGk7DQo+ID4gQEAgLTEyOSw3ICsxOTksNyBAQCBzdGF0aWMgdm9pZCBmcmVxX3RhYmxlX3Nv
cnQoc3RydWN0DQo+IGNwdWZyZXFfZnJlcXVlbmN5X3RhYmxlICpmcmVxX3RhYmxlLA0KPiA+ICAg
ICAgICAgfQ0KPiA+ICB9DQo+ID4NCj4gPiAtc3RhdGljIGludCBjb3JlbmV0X2NwdWZyZXFfY3B1
X2luaXQoc3RydWN0IGNwdWZyZXFfcG9saWN5ICpwb2xpY3kpDQo+ID4gK3N0YXRpYyBpbnQgcW9y
aXFfY3B1ZnJlcV9jcHVfaW5pdChzdHJ1Y3QgY3B1ZnJlcV9wb2xpY3kgKnBvbGljeSkNCj4gPiAg
ew0KPiA+ICAgICAgICAgc3RydWN0IGRldmljZV9ub2RlICpucDsNCj4gPiAgICAgICAgIGludCBp
LCBjb3VudCwgcmV0Ow0KPiA+IEBAIC0xNDUsMTAgKzIxNSw4IEBAIHN0YXRpYyBpbnQgY29yZW5l
dF9jcHVmcmVxX2NwdV9pbml0KHN0cnVjdA0KPiBjcHVmcmVxX3BvbGljeSAqcG9saWN5KQ0KPiA+
ICAgICAgICAgICAgICAgICByZXR1cm4gLUVOT0RFVjsNCj4gPg0KPiA+ICAgICAgICAgZGF0YSA9
IGt6YWxsb2Moc2l6ZW9mKCpkYXRhKSwgR0ZQX0tFUk5FTCk7DQo+ID4gLSAgICAgICBpZiAoIWRh
dGEpIHsNCj4gPiAtICAgICAgICAgICAgICAgcHJfZXJyKCIlczogbm8gbWVtb3J5XG4iLCBfX2Z1
bmNfXyk7DQo+IA0KPiBXYXNuJ3QgdGhpcyB1c2VmdWwgPw0KPiANClRvIGdldCByaWQgb2YgY2hl
Y2twYXRjaCB3YXJuaW5nLg0KQ3VycmVudGx5LCBjaGVja3BhdGNoIHNjcmlwdCBkb2Vzbid0IGFs
bG93IHRvIG91dHB1dCBtZW1vcnkgYWxsb2NhdGlvbiBlcnJvciBpbmZvcm1hdGlvbi4NCldlIHdp
bGwgZ2V0IG1lbW9yeSBpbmZvcm1hdGlvbiBldmVudHVhbGx5IGlmIHRoZXJlIGFyZSBtZW1vcnkg
cmVsYXRlZCBlcnJvci4NCg0KUmVnYXJkcywNCll1YW50aWFuDQoNCj4gPiArICAgICAgIGlmICgh
ZGF0YSkNCj4gPiAgICAgICAgICAgICAgICAgZ290byBlcnJfbnA7DQo+ID4gLSAgICAgICB9DQo+
ID4NCj4gPiAgICAgICAgIHBvbGljeS0+Y2xrID0gb2ZfY2xrX2dldChucCwgMCk7DQo+ID4gICAg
ICAgICBpZiAoSVNfRVJSKHBvbGljeS0+Y2xrKSkgew0KPiA+IEBAIC0xNzAsNyArMjM4LDcgQEAg
c3RhdGljIGludCBjb3JlbmV0X2NwdWZyZXFfY3B1X2luaXQoc3RydWN0DQo+IGNwdWZyZXFfcG9s
aWN5ICpwb2xpY3kpDQo+ID4gICAgICAgICB9DQo+ID4NCj4gPiAgICAgICAgIGlmIChmbWFzaykN
Cj4gPiAtICAgICAgICAgICAgICAgbWFzayA9IGZtYXNrW2dldF9oYXJkX3NtcF9wcm9jZXNzb3Jf
aWQoY3B1KV07DQo+ID4gKyAgICAgICAgICAgICAgIG1hc2sgPSBmbWFza1tnZXRfY3B1X3BoeXNp
Y2FsX2lkKGNwdSldOw0KPiA+ICAgICAgICAgZWxzZQ0KPiA+ICAgICAgICAgICAgICAgICBtYXNr
ID0gMHgwOw0KPiA+DQo+ID4gQEAgLTIwMSwxMyArMjY5LDEzIEBAIHN0YXRpYyBpbnQgY29yZW5l
dF9jcHVmcmVxX2NwdV9pbml0KHN0cnVjdA0KPiBjcHVmcmVxX3BvbGljeSAqcG9saWN5KQ0KPiA+
ICAgICAgICAgZGF0YS0+dGFibGUgPSB0YWJsZTsNCj4gPg0KPiA+ICAgICAgICAgLyogdXBkYXRl
IC0+Y3B1cyBpZiB3ZSBoYXZlIGNsdXN0ZXIsIG5vIGhhcm0gaWYgbm90ICovDQo+ID4gLSAgICAg
ICBjcHVtYXNrX2NvcHkocG9saWN5LT5jcHVzLCBwZXJfY3B1KGNwdV9tYXNrLCBjcHUpKTsNCj4g
PiAtICAgICAgIGZvcl9lYWNoX2NwdShpLCBwZXJfY3B1KGNwdV9tYXNrLCBjcHUpKQ0KPiA+ICsg
ICAgICAgc2V0X2FmZmVjdGVkX2NwdXMocG9saWN5KTsNCj4gPiArICAgICAgIGZvcl9lYWNoX2Nw
dShpLCBwb2xpY3ktPmNwdXMpDQo+ID4gICAgICAgICAgICAgICAgIHBlcl9jcHUoY3B1X2RhdGEs
IGkpID0gZGF0YTsNCj4gDQo+IEdldCByaWQgb2YgdGhpcyBwZXItY3B1IGRhdGEgYW5kIHVzZSBw
b2xpY3ktPmRyaXZlcl9kYXRhIGluc3RlYWQuDQo+IA0KPiA+DQo+ID4gICAgICAgICAvKiBNaW5p
bXVtIHRyYW5zaXRpb24gbGF0ZW5jeSBpcyAxMiBwbGF0Zm9ybSBjbG9ja3MgKi8NCj4gPiAgICAg
ICAgIHU2NHRlbXAgPSAxMlVMTCAqIE5TRUNfUEVSX1NFQzsNCj4gPiAtICAgICAgIGRvX2Rpdih1
NjR0ZW1wLCBmc2xfZ2V0X3N5c19mcmVxKCkpOw0KPiA+ICsgICAgICAgZG9fZGl2KHU2NHRlbXAs
IGdldF9idXNfZnJlcSgpKTsNCj4gPiAgICAgICAgIHBvbGljeS0+Y3B1aW5mby50cmFuc2l0aW9u
X2xhdGVuY3kgPSB1NjR0ZW1wICsgMTsNCj4gPg0KPiA+ICAgICAgICAgb2Zfbm9kZV9wdXQobnAp
Ow0KPiA+IEBAIC0yMjcsNyArMjk1LDcgQEAgZXJyX25wOg0KPiA+ICAgICAgICAgcmV0dXJuIC1F
Tk9ERVY7DQo+ID4gIH0NCj4gPg0KPiA+IC1zdGF0aWMgaW50IF9fZXhpdCBjb3JlbmV0X2NwdWZy
ZXFfY3B1X2V4aXQoc3RydWN0IGNwdWZyZXFfcG9saWN5DQo+ID4gKnBvbGljeSkNCj4gPiArc3Rh
dGljIGludCBfX2V4aXQgcW9yaXFfY3B1ZnJlcV9jcHVfZXhpdChzdHJ1Y3QgY3B1ZnJlcV9wb2xp
Y3kNCj4gPiArKnBvbGljeSkNCj4gPiAgew0KPiA+ICAgICAgICAgc3RydWN0IGNwdV9kYXRhICpk
YXRhID0gcGVyX2NwdShjcHVfZGF0YSwgcG9saWN5LT5jcHUpOw0KPiA+ICAgICAgICAgdW5zaWdu
ZWQgaW50IGNwdTsNCj4gPiBAQCAtMjM2LDEzICszMDQsMTMgQEAgc3RhdGljIGludCBfX2V4aXQg
Y29yZW5ldF9jcHVmcmVxX2NwdV9leGl0KHN0cnVjdA0KPiBjcHVmcmVxX3BvbGljeSAqcG9saWN5
KQ0KPiA+ICAgICAgICAga2ZyZWUoZGF0YS0+dGFibGUpOw0KPiA+ICAgICAgICAga2ZyZWUoZGF0
YSk7DQo+ID4NCj4gPiAtICAgICAgIGZvcl9lYWNoX2NwdShjcHUsIHBlcl9jcHUoY3B1X21hc2ss
IHBvbGljeS0+Y3B1KSkNCj4gPiArICAgICAgIGZvcl9lYWNoX2NwdShjcHUsIHBvbGljeS0+Y3B1
cykNCj4gPiAgICAgICAgICAgICAgICAgcGVyX2NwdShjcHVfZGF0YSwgY3B1KSA9IE5VTEw7DQo+
ID4NCj4gPiAgICAgICAgIHJldHVybiAwOw0KPiA+ICB9DQo+ID4NCj4gPiAtc3RhdGljIGludCBj
b3JlbmV0X2NwdWZyZXFfdGFyZ2V0KHN0cnVjdCBjcHVmcmVxX3BvbGljeSAqcG9saWN5LA0KPiA+
ICtzdGF0aWMgaW50IHFvcmlxX2NwdWZyZXFfdGFyZ2V0KHN0cnVjdCBjcHVmcmVxX3BvbGljeSAq
cG9saWN5LA0KPiA+ICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgaW5kZXgpDQo+ID4gIHsN
Cj4gPiAgICAgICAgIHN0cnVjdCBjbGsgKnBhcmVudDsNCj4gPiBAQCAtMjUyLDE4ICszMjAsMTgg
QEAgc3RhdGljIGludCBjb3JlbmV0X2NwdWZyZXFfdGFyZ2V0KHN0cnVjdA0KPiBjcHVmcmVxX3Bv
bGljeSAqcG9saWN5LA0KPiA+ICAgICAgICAgcmV0dXJuIGNsa19zZXRfcGFyZW50KHBvbGljeS0+
Y2xrLCBwYXJlbnQpOyAgfQ0KPiA+DQo+ID4gLXN0YXRpYyBzdHJ1Y3QgY3B1ZnJlcV9kcml2ZXIg
cHBjX2NvcmVuZXRfY3B1ZnJlcV9kcml2ZXIgPSB7DQo+ID4gLSAgICAgICAubmFtZSAgICAgICAg
ICAgPSAicHBjX2NwdWZyZXEiLA0KPiA+ICtzdGF0aWMgc3RydWN0IGNwdWZyZXFfZHJpdmVyIHFv
cmlxX2NwdWZyZXFfZHJpdmVyID0gew0KPiA+ICsgICAgICAgLm5hbWUgICAgICAgICAgID0gInFv
cmlxX2NwdWZyZXEiLA0KPiA+ICAgICAgICAgLmZsYWdzICAgICAgICAgID0gQ1BVRlJFUV9DT05T
VF9MT09QUywNCj4gPiAtICAgICAgIC5pbml0ICAgICAgICAgICA9IGNvcmVuZXRfY3B1ZnJlcV9j
cHVfaW5pdCwNCj4gPiAtICAgICAgIC5leGl0ICAgICAgICAgICA9IF9fZXhpdF9wKGNvcmVuZXRf
Y3B1ZnJlcV9jcHVfZXhpdCksDQo+ID4gKyAgICAgICAuaW5pdCAgICAgICAgICAgPSBxb3JpcV9j
cHVmcmVxX2NwdV9pbml0LA0KPiA+ICsgICAgICAgLmV4aXQgICAgICAgICAgID0gX19leGl0X3Ao
cW9yaXFfY3B1ZnJlcV9jcHVfZXhpdCksDQo+ID4gICAgICAgICAudmVyaWZ5ICAgICAgICAgPSBj
cHVmcmVxX2dlbmVyaWNfZnJlcXVlbmN5X3RhYmxlX3ZlcmlmeSwNCj4gPiAtICAgICAgIC50YXJn
ZXRfaW5kZXggICA9IGNvcmVuZXRfY3B1ZnJlcV90YXJnZXQsDQo+ID4gKyAgICAgICAudGFyZ2V0
X2luZGV4ICAgPSBxb3JpcV9jcHVmcmVxX3RhcmdldCwNCj4gPiAgICAgICAgIC5nZXQgICAgICAg
ICAgICA9IGNwdWZyZXFfZ2VuZXJpY19nZXQsDQo+ID4gICAgICAgICAuYXR0ciAgICAgICAgICAg
PSBjcHVmcmVxX2dlbmVyaWNfYXR0ciwNCj4gPiAgfTsNCj4gPg0KPiA+IC1zdGF0aWMgY29uc3Qg
c3RydWN0IG9mX2RldmljZV9pZCBub2RlX21hdGNoZXNbXSBfX2luaXRkYXRhID0gew0KPiA+ICtz
dGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBub2RlX21hdGNoZXNbXSBfX2luaXRjb25z
dCA9IHsNCj4gPiAgICAgICAgIHsgLmNvbXBhdGlibGUgPSAiZnNsLHAyMDQxLWNsb2NrZ2VuIiwg
LmRhdGEgPSAmc2RhdGFbMF0sIH0sDQo+ID4gICAgICAgICB7IC5jb21wYXRpYmxlID0gImZzbCxw
MzA0MS1jbG9ja2dlbiIsIC5kYXRhID0gJnNkYXRhWzBdLCB9LA0KPiA+ICAgICAgICAgeyAuY29t
cGF0aWJsZSA9ICJmc2wscDUwMjAtY2xvY2tnZW4iLCAuZGF0YSA9ICZzZGF0YVsxXSwgfSwgQEAN
Cj4gPiAtMjczLDYxICszNDEsNDMgQEAgc3RhdGljIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQg
bm9kZV9tYXRjaGVzW10NCj4gX19pbml0ZGF0YSA9IHsNCj4gPiAgICAgICAgIHt9DQo+ID4gIH07
DQo+ID4NCj4gPiAtc3RhdGljIGludCBfX2luaXQgcHBjX2NvcmVuZXRfY3B1ZnJlcV9pbml0KHZv
aWQpDQo+ID4gK3N0YXRpYyBpbnQgX19pbml0IHFvcmlxX2NwdWZyZXFfaW5pdCh2b2lkKQ0KPiA+
ICB7DQo+ID4gICAgICAgICBpbnQgcmV0Ow0KPiA+ICAgICAgICAgc3RydWN0IGRldmljZV9ub2Rl
ICAqbnA7DQo+ID4gICAgICAgICBjb25zdCBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkICptYXRjaDsNCj4g
PiAgICAgICAgIGNvbnN0IHN0cnVjdCBzb2NfZGF0YSAqZGF0YTsNCj4gPiAtICAgICAgIHVuc2ln
bmVkIGludCBjcHU7DQo+ID4NCj4gPiAgICAgICAgIG5wID0gb2ZfZmluZF9tYXRjaGluZ19ub2Rl
KE5VTEwsIG5vZGVfbWF0Y2hlcyk7DQo+ID4gICAgICAgICBpZiAoIW5wKQ0KPiA+ICAgICAgICAg
ICAgICAgICByZXR1cm4gLUVOT0RFVjsNCj4gPg0KPiA+IC0gICAgICAgZm9yX2VhY2hfcG9zc2li
bGVfY3B1KGNwdSkgew0KPiA+IC0gICAgICAgICAgICAgICBpZiAoIWFsbG9jX2NwdW1hc2tfdmFy
KCZwZXJfY3B1KGNwdV9tYXNrLCBjcHUpLA0KPiBHRlBfS0VSTkVMKSkNCj4gPiAtICAgICAgICAg
ICAgICAgICAgICAgICBnb3RvIGVycl9tYXNrOw0KPiA+IC0gICAgICAgICAgICAgICBjcHVtYXNr
X2NvcHkocGVyX2NwdShjcHVfbWFzaywgY3B1KSwNCj4gY3B1X2NvcmVfbWFzayhjcHUpKTsNCj4g
PiAtICAgICAgIH0NCj4gPiAtDQo+ID4gICAgICAgICBtYXRjaCA9IG9mX21hdGNoX25vZGUobm9k
ZV9tYXRjaGVzLCBucCk7DQo+ID4gICAgICAgICBkYXRhID0gbWF0Y2gtPmRhdGE7DQo+ID4gICAg
ICAgICBpZiAoZGF0YSkgew0KPiA+ICAgICAgICAgICAgICAgICBpZiAoZGF0YS0+ZmxhZykNCj4g
PiAgICAgICAgICAgICAgICAgICAgICAgICBmbWFzayA9IGRhdGEtPmZyZXFfbWFzazsNCj4gPiAt
ICAgICAgICAgICAgICAgbWluX2NwdWZyZXEgPSBmc2xfZ2V0X3N5c19mcmVxKCk7DQo+ID4gKyAg
ICAgICAgICAgICAgIG1pbl9jcHVmcmVxID0gZ2V0X2J1c19mcmVxKCk7DQo+ID4gICAgICAgICB9
IGVsc2Ugew0KPiA+IC0gICAgICAgICAgICAgICBtaW5fY3B1ZnJlcSA9IGZzbF9nZXRfc3lzX2Zy
ZXEoKSAvIDI7DQo+ID4gKyAgICAgICAgICAgICAgIG1pbl9jcHVmcmVxID0gZ2V0X2J1c19mcmVx
KCkgLyAyOw0KPiA+ICAgICAgICAgfQ0KPiA+DQo+ID4gICAgICAgICBvZl9ub2RlX3B1dChucCk7
DQo+ID4NCj4gPiAtICAgICAgIHJldCA9IGNwdWZyZXFfcmVnaXN0ZXJfZHJpdmVyKCZwcGNfY29y
ZW5ldF9jcHVmcmVxX2RyaXZlcik7DQo+ID4gKyAgICAgICByZXQgPSBjcHVmcmVxX3JlZ2lzdGVy
X2RyaXZlcigmcW9yaXFfY3B1ZnJlcV9kcml2ZXIpOw0KPiA+ICAgICAgICAgaWYgKCFyZXQpDQo+
ID4gLSAgICAgICAgICAgICAgIHByX2luZm8oIkZyZWVzY2FsZSBQb3dlclBDIGNvcmVuZXQgQ1BV
IGZyZXF1ZW5jeSBzY2FsaW5nDQo+IGRyaXZlclxuIik7DQo+ID4gKyAgICAgICAgICAgICAgIHBy
X2luZm8oIkZyZWVzY2FsZSBRb3JJUSBDUFUgZnJlcXVlbmN5IHNjYWxpbmcNCj4gPiArIGRyaXZl
clxuIik7DQo+ID4NCj4gPiAgICAgICAgIHJldHVybiByZXQ7DQo+ID4gLQ0KPiA+IC1lcnJfbWFz
azoNCj4gPiAtICAgICAgIGZvcl9lYWNoX3Bvc3NpYmxlX2NwdShjcHUpDQo+ID4gLSAgICAgICAg
ICAgICAgIGZyZWVfY3B1bWFza192YXIocGVyX2NwdShjcHVfbWFzaywgY3B1KSk7DQo+ID4gLQ0K
PiA+IC0gICAgICAgcmV0dXJuIC1FTk9NRU07DQo+ID4gIH0NCj4gPiAtbW9kdWxlX2luaXQocHBj
X2NvcmVuZXRfY3B1ZnJlcV9pbml0KTsNCj4gPiArbW9kdWxlX2luaXQocW9yaXFfY3B1ZnJlcV9p
bml0KTsNCj4gPg0KPiA+IC1zdGF0aWMgdm9pZCBfX2V4aXQgcHBjX2NvcmVuZXRfY3B1ZnJlcV9l
eGl0KHZvaWQpDQo+ID4gK3N0YXRpYyB2b2lkIF9fZXhpdCBxb3JpcV9jcHVmcmVxX2V4aXQodm9p
ZCkNCj4gPiAgew0KPiA+IC0gICAgICAgdW5zaWduZWQgaW50IGNwdTsNCj4gPiAtDQo+ID4gLSAg
ICAgICBmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KQ0KPiA+IC0gICAgICAgICAgICAgICBmcmVl
X2NwdW1hc2tfdmFyKHBlcl9jcHUoY3B1X21hc2ssIGNwdSkpOw0KPiA+IC0NCj4gPiAtICAgICAg
IGNwdWZyZXFfdW5yZWdpc3Rlcl9kcml2ZXIoJnBwY19jb3JlbmV0X2NwdWZyZXFfZHJpdmVyKTsN
Cj4gPiArICAgICAgIGNwdWZyZXFfdW5yZWdpc3Rlcl9kcml2ZXIoJnFvcmlxX2NwdWZyZXFfZHJp
dmVyKTsNCj4gPiAgfQ0KPiA+IC1tb2R1bGVfZXhpdChwcGNfY29yZW5ldF9jcHVmcmVxX2V4aXQp
Ow0KPiA+ICttb2R1bGVfZXhpdChxb3JpcV9jcHVmcmVxX2V4aXQpOw0KPiA+DQo+ID4gIE1PRFVM
RV9MSUNFTlNFKCJHUEwiKTsNCj4gPiAgTU9EVUxFX0FVVEhPUigiVGFuZyBZdWFudGlhbiA8WXVh
bnRpYW4uVGFuZ0BmcmVlc2NhbGUuY29tPiIpOw0KPiA+IC1NT0RVTEVfREVTQ1JJUFRJT04oImNw
dWZyZXEgZHJpdmVyIGZvciBGcmVlc2NhbGUgZTUwMG1jIHNlcmllcw0KPiA+IFNvQ3MiKTsNCj4g
PiArTU9EVUxFX0RFU0NSSVBUSU9OKCJjcHVmcmVxIGRyaXZlciBmb3IgRnJlZXNjYWxlIFFvcklR
IHNlcmllcyBTb0NzIik7DQo+IA0KPiArIGNvbW1lbnRzIGZyb20gS3VtYXIgR2FsYSA6KQ0K

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
  2014-10-17  8:03   ` Kumar Gala
  (?)
@ 2014-10-21  8:25     ` Yuantian Tang
  -1 siblings, 0 replies; 29+ messages in thread
From: Yuantian Tang @ 2014-10-21  8:25 UTC (permalink / raw)
  To: Kumar Gala; +Cc: rjw, viresh.kumar, linux-kernel, linux-pm, linuxppc-dev

> > #ifndef CONFIG_SMP
> > static inline const struct cpumask *cpu_core_mask(int cpu) { @@ -79,6
> > +75,79 @@ static inline const struct cpumask *cpu_core_mask(int cpu) }
> > #endif
> >
> > +#if defined(CONFIG_PPC_E500MC)
> 
> Probably should just be CONFIG_PPC, but do we need this at all.  Can't we just
> use topology_core_id() on both ARM & PPC?
> 
topology_core_id() doesn't work on PPC.
This function only supports PPC64 and non-thread SOCs.

I can make it work on PPC, but we are used to use get_hard_smp_processor_id() on ppc.

Regards,
Yuantian

> > +static int get_cpu_physical_id(int cpu) {
> > +	return get_hard_smp_processor_id(cpu); } #elif defined(CONFIG_ARM)
> > +static int get_cpu_physical_id(int cpu) {
> > +	return topology_core_id(cpu);
> > +}
> > +#endif
> > +


^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-10-21  8:25     ` Yuantian Tang
  0 siblings, 0 replies; 29+ messages in thread
From: Yuantian Tang @ 2014-10-21  8:25 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, viresh.kumar, rjw, linux-kernel, linux-pm

> > #ifndef CONFIG_SMP
> > static inline const struct cpumask *cpu_core_mask(int cpu) { @@ -79,6
> > +75,79 @@ static inline const struct cpumask *cpu_core_mask(int cpu) }
> > #endif
> >
> > +#if defined(CONFIG_PPC_E500MC)
> 
> Probably should just be CONFIG_PPC, but do we need this at all.  Can't we just
> use topology_core_id() on both ARM & PPC?
> 
topology_core_id() doesn't work on PPC.
This function only supports PPC64 and non-thread SOCs.

I can make it work on PPC, but we are used to use get_hard_smp_processor_id() on ppc.

Regards,
Yuantian

> > +static int get_cpu_physical_id(int cpu) {
> > +	return get_hard_smp_processor_id(cpu); } #elif defined(CONFIG_ARM)
> > +static int get_cpu_physical_id(int cpu) {
> > +	return topology_core_id(cpu);
> > +}
> > +#endif
> > +

_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-10-21  8:25     ` Yuantian Tang
  0 siblings, 0 replies; 29+ messages in thread
From: Yuantian Tang @ 2014-10-21  8:25 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-dev, viresh.kumar, rjw, linux-kernel, linux-pm

> > #ifndef CONFIG_SMP
> > static inline const struct cpumask *cpu_core_mask(int cpu) { @@ -79,6
> > +75,79 @@ static inline const struct cpumask *cpu_core_mask(int cpu) }
> > #endif
> >
> > +#if defined(CONFIG_PPC_E500MC)
>=20
> Probably should just be CONFIG_PPC, but do we need this at all.  Can't we=
 just
> use topology_core_id() on both ARM & PPC?
>=20
topology_core_id() doesn't work on PPC.
This function only supports PPC64 and non-thread SOCs.

I can make it work on PPC, but we are used to use get_hard_smp_processor_id=
() on ppc.

Regards,
Yuantian

> > +static int get_cpu_physical_id(int cpu) {
> > +	return get_hard_smp_processor_id(cpu); } #elif defined(CONFIG_ARM)
> > +static int get_cpu_physical_id(int cpu) {
> > +	return topology_core_id(cpu);
> > +}
> > +#endif
> > +

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
  2014-10-17  8:08   ` Viresh Kumar
  (?)
@ 2014-10-21  8:59     ` Yuantian Tang
  -1 siblings, 0 replies; 29+ messages in thread
From: Yuantian Tang @ 2014-10-21  8:59 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, Linux Kernel Mailing List, linux-pm, linuxppc-dev

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 11334 bytes --]

> > -config PPC_CORENET_CPUFREQ
> > -       tristate "CPU frequency scaling driver for Freescale E500MC SoCs"
> > -       depends on PPC_E500MC && OF && COMMON_CLK
> > +config QORIQ_CPUFREQ
> > +       tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> > +       depends on OF && COMMON_CLK
> >         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.
> > +         This adds the CPUFreq driver support for Freescale QorIQ SoCs
> > +         which are capable of changing the CPU's frequency dynamically.
> >
> >  config CPU_FREQ_PMAC
> >         bool "Support for Apple PowerBooks"
> 
> Don't need this duplication at all. Just move this to Kconfig instead of .arm and
> ppc.
> 
If I do so, menuconfig will display like this(on PPC):
	PowerPC CPU frequency scaling drivers  ----  
    QorIQ CPU Frequency scaling  --->    
  		<*> CPU frequency scaling driver for Freescale QorIQ SoCs
On ARM, there should be a similar problem.
Isn't weird?

Regards,
Yuantian
		
> > diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c
> > b/drivers/cpufreq/qoriq-cpufreq.c
> 
> >  /**
> >   * struct cpu_data - per CPU data struct @@ -69,9 +68,6 @@ static
> > const u32 *fmask;
> >
> >  static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
> >
> > -/* cpumask in a cluster */
> > -static DEFINE_PER_CPU(cpumask_var_t, cpu_mask);
> > -
> >  #ifndef CONFIG_SMP
> >  static inline const struct cpumask *cpu_core_mask(int cpu)  { @@
> > -79,6 +75,79 @@ static inline const struct cpumask *cpu_core_mask(int
> > cpu)  }  #endif
> >
> > +#if defined(CONFIG_PPC_E500MC)
> > +static int get_cpu_physical_id(int cpu) {
> > +       return get_hard_smp_processor_id(cpu); } #elif
> > +defined(CONFIG_ARM)
> 
> Wouldn't a #else work here as there are just two platforms we are talking about ?
> 
> > +static int get_cpu_physical_id(int cpu) {
> > +       return topology_core_id(cpu);
> > +}
> > +#endif
> > +
> > +static u32 get_bus_freq(void)
> > +{
> > +       struct device_node *soc;
> > +       u32 sysfreq;
> > +
> > +       soc = of_find_node_by_type(NULL, "soc");
> > +       if (!soc)
> > +               return 0;
> > +
> > +       if (of_property_read_u32(soc, "bus-frequency", &sysfreq))
> > +               sysfreq = 0;
> > +
> > +       of_node_put(soc);
> > +
> > +       return sysfreq;
> > +}
> > +
> > +static struct device_node *cpu_to_clk_node(int cpu) {
> > +       struct device_node *np, *clk_np;
> > +
> > +       if (!cpu_present(cpu))
> > +               return NULL;
> > +
> > +       np = of_get_cpu_node(cpu, NULL);
> > +       if (!np)
> > +               return NULL;
> > +
> > +       clk_np = of_parse_phandle(np, "clocks", 0);
> > +       if (!clk_np)
> > +               return NULL;
> > +
> > +       of_node_put(np);
> > +
> > +       return clk_np;
> > +}
> > +
> > +/* traverse cpu nodes to get cpu mask of sharing clock wire */ static
> > +void set_affected_cpus(struct cpufreq_policy *policy) {
> > +       struct device_node *np, *clk_np;
> > +       struct cpumask *dstp = policy->cpus;
> > +       int i;
> > +
> > +       np = cpu_to_clk_node(policy->cpu);
> > +       if (!np)
> > +               return;
> > +
> > +       for_each_present_cpu(i) {
> > +               clk_np = cpu_to_clk_node(i);
> > +               if (!clk_np)
> > +                       continue;
> > +
> > +               if (clk_np == np)
> > +                       cpumask_set_cpu(i, dstp);
> 
> So you are depending on matching the clock-nodes from DT for getting this
> information, right ? There is nothing that the architecture gives?
> 
> > +
> > +               of_node_put(clk_np);
> > +       }
> > +       of_node_put(np);
> > +}
> > +
> >  /* reduce the duplicated frequencies in frequency table */  static
> > void freq_table_redup(struct cpufreq_frequency_table *freq_table,
> >                 int count)
> > @@ -105,6 +174,7 @@ static void freq_table_sort(struct
> cpufreq_frequency_table *freq_table,
> >         int i, j, ind;
> >         unsigned int freq, max_freq;
> >         struct cpufreq_frequency_table table;
> > +
> >         for (i = 0; i < count - 1; i++) {
> >                 max_freq = freq_table[i].frequency;
> >                 ind = i;
> > @@ -129,7 +199,7 @@ static void freq_table_sort(struct
> cpufreq_frequency_table *freq_table,
> >         }
> >  }
> >
> > -static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> > +static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
> >  {
> >         struct device_node *np;
> >         int i, count, ret;
> > @@ -145,10 +215,8 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> >                 return -ENODEV;
> >
> >         data = kzalloc(sizeof(*data), GFP_KERNEL);
> > -       if (!data) {
> > -               pr_err("%s: no memory\n", __func__);
> 
> Wasn't this useful ?
> 
> > +       if (!data)
> >                 goto err_np;
> > -       }
> >
> >         policy->clk = of_clk_get(np, 0);
> >         if (IS_ERR(policy->clk)) {
> > @@ -170,7 +238,7 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> >         }
> >
> >         if (fmask)
> > -               mask = fmask[get_hard_smp_processor_id(cpu)];
> > +               mask = fmask[get_cpu_physical_id(cpu)];
> >         else
> >                 mask = 0x0;
> >
> > @@ -201,13 +269,13 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> >         data->table = table;
> >
> >         /* update ->cpus if we have cluster, no harm if not */
> > -       cpumask_copy(policy->cpus, per_cpu(cpu_mask, cpu));
> > -       for_each_cpu(i, per_cpu(cpu_mask, cpu))
> > +       set_affected_cpus(policy);
> > +       for_each_cpu(i, policy->cpus)
> >                 per_cpu(cpu_data, i) = data;
> 
> Get rid of this per-cpu data and use policy->driver_data instead.
> 
> >
> >         /* Minimum transition latency is 12 platform clocks */
> >         u64temp = 12ULL * NSEC_PER_SEC;
> > -       do_div(u64temp, fsl_get_sys_freq());
> > +       do_div(u64temp, get_bus_freq());
> >         policy->cpuinfo.transition_latency = u64temp + 1;
> >
> >         of_node_put(np);
> > @@ -227,7 +295,7 @@ err_np:
> >         return -ENODEV;
> >  }
> >
> > -static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy
> > *policy)
> > +static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy
> > +*policy)
> >  {
> >         struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
> >         unsigned int cpu;
> > @@ -236,13 +304,13 @@ static int __exit corenet_cpufreq_cpu_exit(struct
> cpufreq_policy *policy)
> >         kfree(data->table);
> >         kfree(data);
> >
> > -       for_each_cpu(cpu, per_cpu(cpu_mask, policy->cpu))
> > +       for_each_cpu(cpu, policy->cpus)
> >                 per_cpu(cpu_data, cpu) = NULL;
> >
> >         return 0;
> >  }
> >
> > -static int corenet_cpufreq_target(struct cpufreq_policy *policy,
> > +static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
> >                 unsigned int index)
> >  {
> >         struct clk *parent;
> > @@ -252,18 +320,18 @@ static int corenet_cpufreq_target(struct
> cpufreq_policy *policy,
> >         return clk_set_parent(policy->clk, parent);  }
> >
> > -static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
> > -       .name           = "ppc_cpufreq",
> > +static struct cpufreq_driver qoriq_cpufreq_driver = {
> > +       .name           = "qoriq_cpufreq",
> >         .flags          = CPUFREQ_CONST_LOOPS,
> > -       .init           = corenet_cpufreq_cpu_init,
> > -       .exit           = __exit_p(corenet_cpufreq_cpu_exit),
> > +       .init           = qoriq_cpufreq_cpu_init,
> > +       .exit           = __exit_p(qoriq_cpufreq_cpu_exit),
> >         .verify         = cpufreq_generic_frequency_table_verify,
> > -       .target_index   = corenet_cpufreq_target,
> > +       .target_index   = qoriq_cpufreq_target,
> >         .get            = cpufreq_generic_get,
> >         .attr           = cpufreq_generic_attr,
> >  };
> >
> > -static const struct of_device_id node_matches[] __initdata = {
> > +static const struct of_device_id node_matches[] __initconst = {
> >         { .compatible = "fsl,p2041-clockgen", .data = &sdata[0], },
> >         { .compatible = "fsl,p3041-clockgen", .data = &sdata[0], },
> >         { .compatible = "fsl,p5020-clockgen", .data = &sdata[1], }, @@
> > -273,61 +341,43 @@ static const struct of_device_id node_matches[]
> __initdata = {
> >         {}
> >  };
> >
> > -static int __init ppc_corenet_cpufreq_init(void)
> > +static int __init qoriq_cpufreq_init(void)
> >  {
> >         int ret;
> >         struct device_node  *np;
> >         const struct of_device_id *match;
> >         const struct soc_data *data;
> > -       unsigned int cpu;
> >
> >         np = of_find_matching_node(NULL, node_matches);
> >         if (!np)
> >                 return -ENODEV;
> >
> > -       for_each_possible_cpu(cpu) {
> > -               if (!alloc_cpumask_var(&per_cpu(cpu_mask, cpu),
> GFP_KERNEL))
> > -                       goto err_mask;
> > -               cpumask_copy(per_cpu(cpu_mask, cpu),
> cpu_core_mask(cpu));
> > -       }
> > -
> >         match = of_match_node(node_matches, np);
> >         data = match->data;
> >         if (data) {
> >                 if (data->flag)
> >                         fmask = data->freq_mask;
> > -               min_cpufreq = fsl_get_sys_freq();
> > +               min_cpufreq = get_bus_freq();
> >         } else {
> > -               min_cpufreq = fsl_get_sys_freq() / 2;
> > +               min_cpufreq = get_bus_freq() / 2;
> >         }
> >
> >         of_node_put(np);
> >
> > -       ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
> > +       ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
> >         if (!ret)
> > -               pr_info("Freescale PowerPC corenet CPU frequency scaling
> driver\n");
> > +               pr_info("Freescale QorIQ CPU frequency scaling
> > + driver\n");
> >
> >         return ret;
> > -
> > -err_mask:
> > -       for_each_possible_cpu(cpu)
> > -               free_cpumask_var(per_cpu(cpu_mask, cpu));
> > -
> > -       return -ENOMEM;
> >  }
> > -module_init(ppc_corenet_cpufreq_init);
> > +module_init(qoriq_cpufreq_init);
> >
> > -static void __exit ppc_corenet_cpufreq_exit(void)
> > +static void __exit qoriq_cpufreq_exit(void)
> >  {
> > -       unsigned int cpu;
> > -
> > -       for_each_possible_cpu(cpu)
> > -               free_cpumask_var(per_cpu(cpu_mask, cpu));
> > -
> > -       cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
> > +       cpufreq_unregister_driver(&qoriq_cpufreq_driver);
> >  }
> > -module_exit(ppc_corenet_cpufreq_exit);
> > +module_exit(qoriq_cpufreq_exit);
> >
> >  MODULE_LICENSE("GPL");
> >  MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
> > -MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series
> > SoCs");
> > +MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs");
> 
> + comments from Kumar Gala :)
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-10-21  8:59     ` Yuantian Tang
  0 siblings, 0 replies; 29+ messages in thread
From: Yuantian Tang @ 2014-10-21  8:59 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, Linux Kernel Mailing List, linux-pm, linuxppc-dev

> > -config PPC_CORENET_CPUFREQ
> > -       tristate "CPU frequency scaling driver for Freescale E500MC SoCs"
> > -       depends on PPC_E500MC && OF && COMMON_CLK
> > +config QORIQ_CPUFREQ
> > +       tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> > +       depends on OF && COMMON_CLK
> >         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.
> > +         This adds the CPUFreq driver support for Freescale QorIQ SoCs
> > +         which are capable of changing the CPU's frequency dynamically.
> >
> >  config CPU_FREQ_PMAC
> >         bool "Support for Apple PowerBooks"
> 
> Don't need this duplication at all. Just move this to Kconfig instead of .arm and
> ppc.
> 
If I do so, menuconfig will display like this(on PPC):
	PowerPC CPU frequency scaling drivers  ----  
    QorIQ CPU Frequency scaling  --->    
  		<*> CPU frequency scaling driver for Freescale QorIQ SoCs
On ARM, there should be a similar problem.
Isn't weird?

Regards,
Yuantian
		
> > diff --git a/drivers/cpufreq/ppc-corenet-cpufreq.c
> > b/drivers/cpufreq/qoriq-cpufreq.c
> 
> >  /**
> >   * struct cpu_data - per CPU data struct @@ -69,9 +68,6 @@ static
> > const u32 *fmask;
> >
> >  static DEFINE_PER_CPU(struct cpu_data *, cpu_data);
> >
> > -/* cpumask in a cluster */
> > -static DEFINE_PER_CPU(cpumask_var_t, cpu_mask);
> > -
> >  #ifndef CONFIG_SMP
> >  static inline const struct cpumask *cpu_core_mask(int cpu)  { @@
> > -79,6 +75,79 @@ static inline const struct cpumask *cpu_core_mask(int
> > cpu)  }  #endif
> >
> > +#if defined(CONFIG_PPC_E500MC)
> > +static int get_cpu_physical_id(int cpu) {
> > +       return get_hard_smp_processor_id(cpu); } #elif
> > +defined(CONFIG_ARM)
> 
> Wouldn't a #else work here as there are just two platforms we are talking about ?
> 
> > +static int get_cpu_physical_id(int cpu) {
> > +       return topology_core_id(cpu);
> > +}
> > +#endif
> > +
> > +static u32 get_bus_freq(void)
> > +{
> > +       struct device_node *soc;
> > +       u32 sysfreq;
> > +
> > +       soc = of_find_node_by_type(NULL, "soc");
> > +       if (!soc)
> > +               return 0;
> > +
> > +       if (of_property_read_u32(soc, "bus-frequency", &sysfreq))
> > +               sysfreq = 0;
> > +
> > +       of_node_put(soc);
> > +
> > +       return sysfreq;
> > +}
> > +
> > +static struct device_node *cpu_to_clk_node(int cpu) {
> > +       struct device_node *np, *clk_np;
> > +
> > +       if (!cpu_present(cpu))
> > +               return NULL;
> > +
> > +       np = of_get_cpu_node(cpu, NULL);
> > +       if (!np)
> > +               return NULL;
> > +
> > +       clk_np = of_parse_phandle(np, "clocks", 0);
> > +       if (!clk_np)
> > +               return NULL;
> > +
> > +       of_node_put(np);
> > +
> > +       return clk_np;
> > +}
> > +
> > +/* traverse cpu nodes to get cpu mask of sharing clock wire */ static
> > +void set_affected_cpus(struct cpufreq_policy *policy) {
> > +       struct device_node *np, *clk_np;
> > +       struct cpumask *dstp = policy->cpus;
> > +       int i;
> > +
> > +       np = cpu_to_clk_node(policy->cpu);
> > +       if (!np)
> > +               return;
> > +
> > +       for_each_present_cpu(i) {
> > +               clk_np = cpu_to_clk_node(i);
> > +               if (!clk_np)
> > +                       continue;
> > +
> > +               if (clk_np == np)
> > +                       cpumask_set_cpu(i, dstp);
> 
> So you are depending on matching the clock-nodes from DT for getting this
> information, right ? There is nothing that the architecture gives?
> 
> > +
> > +               of_node_put(clk_np);
> > +       }
> > +       of_node_put(np);
> > +}
> > +
> >  /* reduce the duplicated frequencies in frequency table */  static
> > void freq_table_redup(struct cpufreq_frequency_table *freq_table,
> >                 int count)
> > @@ -105,6 +174,7 @@ static void freq_table_sort(struct
> cpufreq_frequency_table *freq_table,
> >         int i, j, ind;
> >         unsigned int freq, max_freq;
> >         struct cpufreq_frequency_table table;
> > +
> >         for (i = 0; i < count - 1; i++) {
> >                 max_freq = freq_table[i].frequency;
> >                 ind = i;
> > @@ -129,7 +199,7 @@ static void freq_table_sort(struct
> cpufreq_frequency_table *freq_table,
> >         }
> >  }
> >
> > -static int corenet_cpufreq_cpu_init(struct cpufreq_policy *policy)
> > +static int qoriq_cpufreq_cpu_init(struct cpufreq_policy *policy)
> >  {
> >         struct device_node *np;
> >         int i, count, ret;
> > @@ -145,10 +215,8 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> >                 return -ENODEV;
> >
> >         data = kzalloc(sizeof(*data), GFP_KERNEL);
> > -       if (!data) {
> > -               pr_err("%s: no memory\n", __func__);
> 
> Wasn't this useful ?
> 
> > +       if (!data)
> >                 goto err_np;
> > -       }
> >
> >         policy->clk = of_clk_get(np, 0);
> >         if (IS_ERR(policy->clk)) {
> > @@ -170,7 +238,7 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> >         }
> >
> >         if (fmask)
> > -               mask = fmask[get_hard_smp_processor_id(cpu)];
> > +               mask = fmask[get_cpu_physical_id(cpu)];
> >         else
> >                 mask = 0x0;
> >
> > @@ -201,13 +269,13 @@ static int corenet_cpufreq_cpu_init(struct
> cpufreq_policy *policy)
> >         data->table = table;
> >
> >         /* update ->cpus if we have cluster, no harm if not */
> > -       cpumask_copy(policy->cpus, per_cpu(cpu_mask, cpu));
> > -       for_each_cpu(i, per_cpu(cpu_mask, cpu))
> > +       set_affected_cpus(policy);
> > +       for_each_cpu(i, policy->cpus)
> >                 per_cpu(cpu_data, i) = data;
> 
> Get rid of this per-cpu data and use policy->driver_data instead.
> 
> >
> >         /* Minimum transition latency is 12 platform clocks */
> >         u64temp = 12ULL * NSEC_PER_SEC;
> > -       do_div(u64temp, fsl_get_sys_freq());
> > +       do_div(u64temp, get_bus_freq());
> >         policy->cpuinfo.transition_latency = u64temp + 1;
> >
> >         of_node_put(np);
> > @@ -227,7 +295,7 @@ err_np:
> >         return -ENODEV;
> >  }
> >
> > -static int __exit corenet_cpufreq_cpu_exit(struct cpufreq_policy
> > *policy)
> > +static int __exit qoriq_cpufreq_cpu_exit(struct cpufreq_policy
> > +*policy)
> >  {
> >         struct cpu_data *data = per_cpu(cpu_data, policy->cpu);
> >         unsigned int cpu;
> > @@ -236,13 +304,13 @@ static int __exit corenet_cpufreq_cpu_exit(struct
> cpufreq_policy *policy)
> >         kfree(data->table);
> >         kfree(data);
> >
> > -       for_each_cpu(cpu, per_cpu(cpu_mask, policy->cpu))
> > +       for_each_cpu(cpu, policy->cpus)
> >                 per_cpu(cpu_data, cpu) = NULL;
> >
> >         return 0;
> >  }
> >
> > -static int corenet_cpufreq_target(struct cpufreq_policy *policy,
> > +static int qoriq_cpufreq_target(struct cpufreq_policy *policy,
> >                 unsigned int index)
> >  {
> >         struct clk *parent;
> > @@ -252,18 +320,18 @@ static int corenet_cpufreq_target(struct
> cpufreq_policy *policy,
> >         return clk_set_parent(policy->clk, parent);  }
> >
> > -static struct cpufreq_driver ppc_corenet_cpufreq_driver = {
> > -       .name           = "ppc_cpufreq",
> > +static struct cpufreq_driver qoriq_cpufreq_driver = {
> > +       .name           = "qoriq_cpufreq",
> >         .flags          = CPUFREQ_CONST_LOOPS,
> > -       .init           = corenet_cpufreq_cpu_init,
> > -       .exit           = __exit_p(corenet_cpufreq_cpu_exit),
> > +       .init           = qoriq_cpufreq_cpu_init,
> > +       .exit           = __exit_p(qoriq_cpufreq_cpu_exit),
> >         .verify         = cpufreq_generic_frequency_table_verify,
> > -       .target_index   = corenet_cpufreq_target,
> > +       .target_index   = qoriq_cpufreq_target,
> >         .get            = cpufreq_generic_get,
> >         .attr           = cpufreq_generic_attr,
> >  };
> >
> > -static const struct of_device_id node_matches[] __initdata = {
> > +static const struct of_device_id node_matches[] __initconst = {
> >         { .compatible = "fsl,p2041-clockgen", .data = &sdata[0], },
> >         { .compatible = "fsl,p3041-clockgen", .data = &sdata[0], },
> >         { .compatible = "fsl,p5020-clockgen", .data = &sdata[1], }, @@
> > -273,61 +341,43 @@ static const struct of_device_id node_matches[]
> __initdata = {
> >         {}
> >  };
> >
> > -static int __init ppc_corenet_cpufreq_init(void)
> > +static int __init qoriq_cpufreq_init(void)
> >  {
> >         int ret;
> >         struct device_node  *np;
> >         const struct of_device_id *match;
> >         const struct soc_data *data;
> > -       unsigned int cpu;
> >
> >         np = of_find_matching_node(NULL, node_matches);
> >         if (!np)
> >                 return -ENODEV;
> >
> > -       for_each_possible_cpu(cpu) {
> > -               if (!alloc_cpumask_var(&per_cpu(cpu_mask, cpu),
> GFP_KERNEL))
> > -                       goto err_mask;
> > -               cpumask_copy(per_cpu(cpu_mask, cpu),
> cpu_core_mask(cpu));
> > -       }
> > -
> >         match = of_match_node(node_matches, np);
> >         data = match->data;
> >         if (data) {
> >                 if (data->flag)
> >                         fmask = data->freq_mask;
> > -               min_cpufreq = fsl_get_sys_freq();
> > +               min_cpufreq = get_bus_freq();
> >         } else {
> > -               min_cpufreq = fsl_get_sys_freq() / 2;
> > +               min_cpufreq = get_bus_freq() / 2;
> >         }
> >
> >         of_node_put(np);
> >
> > -       ret = cpufreq_register_driver(&ppc_corenet_cpufreq_driver);
> > +       ret = cpufreq_register_driver(&qoriq_cpufreq_driver);
> >         if (!ret)
> > -               pr_info("Freescale PowerPC corenet CPU frequency scaling
> driver\n");
> > +               pr_info("Freescale QorIQ CPU frequency scaling
> > + driver\n");
> >
> >         return ret;
> > -
> > -err_mask:
> > -       for_each_possible_cpu(cpu)
> > -               free_cpumask_var(per_cpu(cpu_mask, cpu));
> > -
> > -       return -ENOMEM;
> >  }
> > -module_init(ppc_corenet_cpufreq_init);
> > +module_init(qoriq_cpufreq_init);
> >
> > -static void __exit ppc_corenet_cpufreq_exit(void)
> > +static void __exit qoriq_cpufreq_exit(void)
> >  {
> > -       unsigned int cpu;
> > -
> > -       for_each_possible_cpu(cpu)
> > -               free_cpumask_var(per_cpu(cpu_mask, cpu));
> > -
> > -       cpufreq_unregister_driver(&ppc_corenet_cpufreq_driver);
> > +       cpufreq_unregister_driver(&qoriq_cpufreq_driver);
> >  }
> > -module_exit(ppc_corenet_cpufreq_exit);
> > +module_exit(qoriq_cpufreq_exit);
> >
> >  MODULE_LICENSE("GPL");
> >  MODULE_AUTHOR("Tang Yuantian <Yuantian.Tang@freescale.com>");
> > -MODULE_DESCRIPTION("cpufreq driver for Freescale e500mc series
> > SoCs");
> > +MODULE_DESCRIPTION("cpufreq driver for Freescale QorIQ series SoCs");
> 
> + comments from Kumar Gala :)

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-10-21  8:59     ` Yuantian Tang
  0 siblings, 0 replies; 29+ messages in thread
From: Yuantian Tang @ 2014-10-21  8:59 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: linuxppc-dev, Rafael J. Wysocki, Linux Kernel Mailing List, linux-pm

PiA+IC1jb25maWcgUFBDX0NPUkVORVRfQ1BVRlJFUQ0KPiA+IC0gICAgICAgdHJpc3RhdGUgIkNQ
VSBmcmVxdWVuY3kgc2NhbGluZyBkcml2ZXIgZm9yIEZyZWVzY2FsZSBFNTAwTUMgU29DcyINCj4g
PiAtICAgICAgIGRlcGVuZHMgb24gUFBDX0U1MDBNQyAmJiBPRiAmJiBDT01NT05fQ0xLDQo+ID4g
K2NvbmZpZyBRT1JJUV9DUFVGUkVRDQo+ID4gKyAgICAgICB0cmlzdGF0ZSAiQ1BVIGZyZXF1ZW5j
eSBzY2FsaW5nIGRyaXZlciBmb3IgRnJlZXNjYWxlIFFvcklRIFNvQ3MiDQo+ID4gKyAgICAgICBk
ZXBlbmRzIG9uIE9GICYmIENPTU1PTl9DTEsNCj4gPiAgICAgICAgIHNlbGVjdCBDTEtfUFBDX0NP
UkVORVQNCj4gPiAgICAgICAgIGhlbHANCj4gPiAtICAgICAgICAgVGhpcyBhZGRzIHRoZSBDUFVG
cmVxIGRyaXZlciBzdXBwb3J0IGZvciBGcmVlc2NhbGUgZTUwMG1jLA0KPiA+IC0gICAgICAgICBl
NTUwMCBhbmQgZTY1MDAgc2VyaWVzIFNvQ3Mgd2hpY2ggYXJlIGNhcGFibGUgb2YgY2hhbmdpbmcN
Cj4gPiAtICAgICAgICAgdGhlIENQVSdzIGZyZXF1ZW5jeSBkeW5hbWljYWxseS4NCj4gPiArICAg
ICAgICAgVGhpcyBhZGRzIHRoZSBDUFVGcmVxIGRyaXZlciBzdXBwb3J0IGZvciBGcmVlc2NhbGUg
UW9ySVEgU29Dcw0KPiA+ICsgICAgICAgICB3aGljaCBhcmUgY2FwYWJsZSBvZiBjaGFuZ2luZyB0
aGUgQ1BVJ3MgZnJlcXVlbmN5IGR5bmFtaWNhbGx5Lg0KPiA+DQo+ID4gIGNvbmZpZyBDUFVfRlJF
UV9QTUFDDQo+ID4gICAgICAgICBib29sICJTdXBwb3J0IGZvciBBcHBsZSBQb3dlckJvb2tzIg0K
PiANCj4gRG9uJ3QgbmVlZCB0aGlzIGR1cGxpY2F0aW9uIGF0IGFsbC4gSnVzdCBtb3ZlIHRoaXMg
dG8gS2NvbmZpZyBpbnN0ZWFkIG9mIC5hcm0gYW5kDQo+IHBwYy4NCj4gDQpJZiBJIGRvIHNvLCBt
ZW51Y29uZmlnIHdpbGwgZGlzcGxheSBsaWtlIHRoaXMob24gUFBDKToNCglQb3dlclBDIENQVSBm
cmVxdWVuY3kgc2NhbGluZyBkcml2ZXJzICAtLS0tICANCiAgICBRb3JJUSBDUFUgRnJlcXVlbmN5
IHNjYWxpbmcgIC0tLT4gICAgDQogIAkJPCo+IENQVSBmcmVxdWVuY3kgc2NhbGluZyBkcml2ZXIg
Zm9yIEZyZWVzY2FsZSBRb3JJUSBTb0NzDQpPbiBBUk0sIHRoZXJlIHNob3VsZCBiZSBhIHNpbWls
YXIgcHJvYmxlbS4NCklzbid0IHdlaXJkPw0KDQpSZWdhcmRzLA0KWXVhbnRpYW4NCgkJDQo+ID4g
ZGlmZiAtLWdpdCBhL2RyaXZlcnMvY3B1ZnJlcS9wcGMtY29yZW5ldC1jcHVmcmVxLmMNCj4gPiBi
L2RyaXZlcnMvY3B1ZnJlcS9xb3JpcS1jcHVmcmVxLmMNCj4gDQo+ID4gIC8qKg0KPiA+ICAgKiBz
dHJ1Y3QgY3B1X2RhdGEgLSBwZXIgQ1BVIGRhdGEgc3RydWN0IEBAIC02OSw5ICs2OCw2IEBAIHN0
YXRpYw0KPiA+IGNvbnN0IHUzMiAqZm1hc2s7DQo+ID4NCj4gPiAgc3RhdGljIERFRklORV9QRVJf
Q1BVKHN0cnVjdCBjcHVfZGF0YSAqLCBjcHVfZGF0YSk7DQo+ID4NCj4gPiAtLyogY3B1bWFzayBp
biBhIGNsdXN0ZXIgKi8NCj4gPiAtc3RhdGljIERFRklORV9QRVJfQ1BVKGNwdW1hc2tfdmFyX3Qs
IGNwdV9tYXNrKTsNCj4gPiAtDQo+ID4gICNpZm5kZWYgQ09ORklHX1NNUA0KPiA+ICBzdGF0aWMg
aW5saW5lIGNvbnN0IHN0cnVjdCBjcHVtYXNrICpjcHVfY29yZV9tYXNrKGludCBjcHUpICB7IEBA
DQo+ID4gLTc5LDYgKzc1LDc5IEBAIHN0YXRpYyBpbmxpbmUgY29uc3Qgc3RydWN0IGNwdW1hc2sg
KmNwdV9jb3JlX21hc2soaW50DQo+ID4gY3B1KSAgfSAgI2VuZGlmDQo+ID4NCj4gPiArI2lmIGRl
ZmluZWQoQ09ORklHX1BQQ19FNTAwTUMpDQo+ID4gK3N0YXRpYyBpbnQgZ2V0X2NwdV9waHlzaWNh
bF9pZChpbnQgY3B1KSB7DQo+ID4gKyAgICAgICByZXR1cm4gZ2V0X2hhcmRfc21wX3Byb2Nlc3Nv
cl9pZChjcHUpOyB9ICNlbGlmDQo+ID4gK2RlZmluZWQoQ09ORklHX0FSTSkNCj4gDQo+IFdvdWxk
bid0IGEgI2Vsc2Ugd29yayBoZXJlIGFzIHRoZXJlIGFyZSBqdXN0IHR3byBwbGF0Zm9ybXMgd2Ug
YXJlIHRhbGtpbmcgYWJvdXQgPw0KPiANCj4gPiArc3RhdGljIGludCBnZXRfY3B1X3BoeXNpY2Fs
X2lkKGludCBjcHUpIHsNCj4gPiArICAgICAgIHJldHVybiB0b3BvbG9neV9jb3JlX2lkKGNwdSk7
DQo+ID4gK30NCj4gPiArI2VuZGlmDQo+ID4gKw0KPiA+ICtzdGF0aWMgdTMyIGdldF9idXNfZnJl
cSh2b2lkKQ0KPiA+ICt7DQo+ID4gKyAgICAgICBzdHJ1Y3QgZGV2aWNlX25vZGUgKnNvYzsNCj4g
PiArICAgICAgIHUzMiBzeXNmcmVxOw0KPiA+ICsNCj4gPiArICAgICAgIHNvYyA9IG9mX2ZpbmRf
bm9kZV9ieV90eXBlKE5VTEwsICJzb2MiKTsNCj4gPiArICAgICAgIGlmICghc29jKQ0KPiA+ICsg
ICAgICAgICAgICAgICByZXR1cm4gMDsNCj4gPiArDQo+ID4gKyAgICAgICBpZiAob2ZfcHJvcGVy
dHlfcmVhZF91MzIoc29jLCAiYnVzLWZyZXF1ZW5jeSIsICZzeXNmcmVxKSkNCj4gPiArICAgICAg
ICAgICAgICAgc3lzZnJlcSA9IDA7DQo+ID4gKw0KPiA+ICsgICAgICAgb2Zfbm9kZV9wdXQoc29j
KTsNCj4gPiArDQo+ID4gKyAgICAgICByZXR1cm4gc3lzZnJlcTsNCj4gPiArfQ0KPiA+ICsNCj4g
PiArc3RhdGljIHN0cnVjdCBkZXZpY2Vfbm9kZSAqY3B1X3RvX2Nsa19ub2RlKGludCBjcHUpIHsN
Cj4gPiArICAgICAgIHN0cnVjdCBkZXZpY2Vfbm9kZSAqbnAsICpjbGtfbnA7DQo+ID4gKw0KPiA+
ICsgICAgICAgaWYgKCFjcHVfcHJlc2VudChjcHUpKQ0KPiA+ICsgICAgICAgICAgICAgICByZXR1
cm4gTlVMTDsNCj4gPiArDQo+ID4gKyAgICAgICBucCA9IG9mX2dldF9jcHVfbm9kZShjcHUsIE5V
TEwpOw0KPiA+ICsgICAgICAgaWYgKCFucCkNCj4gPiArICAgICAgICAgICAgICAgcmV0dXJuIE5V
TEw7DQo+ID4gKw0KPiA+ICsgICAgICAgY2xrX25wID0gb2ZfcGFyc2VfcGhhbmRsZShucCwgImNs
b2NrcyIsIDApOw0KPiA+ICsgICAgICAgaWYgKCFjbGtfbnApDQo+ID4gKyAgICAgICAgICAgICAg
IHJldHVybiBOVUxMOw0KPiA+ICsNCj4gPiArICAgICAgIG9mX25vZGVfcHV0KG5wKTsNCj4gPiAr
DQo+ID4gKyAgICAgICByZXR1cm4gY2xrX25wOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICsvKiB0cmF2
ZXJzZSBjcHUgbm9kZXMgdG8gZ2V0IGNwdSBtYXNrIG9mIHNoYXJpbmcgY2xvY2sgd2lyZSAqLyBz
dGF0aWMNCj4gPiArdm9pZCBzZXRfYWZmZWN0ZWRfY3B1cyhzdHJ1Y3QgY3B1ZnJlcV9wb2xpY3kg
KnBvbGljeSkgew0KPiA+ICsgICAgICAgc3RydWN0IGRldmljZV9ub2RlICpucCwgKmNsa19ucDsN
Cj4gPiArICAgICAgIHN0cnVjdCBjcHVtYXNrICpkc3RwID0gcG9saWN5LT5jcHVzOw0KPiA+ICsg
ICAgICAgaW50IGk7DQo+ID4gKw0KPiA+ICsgICAgICAgbnAgPSBjcHVfdG9fY2xrX25vZGUocG9s
aWN5LT5jcHUpOw0KPiA+ICsgICAgICAgaWYgKCFucCkNCj4gPiArICAgICAgICAgICAgICAgcmV0
dXJuOw0KPiA+ICsNCj4gPiArICAgICAgIGZvcl9lYWNoX3ByZXNlbnRfY3B1KGkpIHsNCj4gPiAr
ICAgICAgICAgICAgICAgY2xrX25wID0gY3B1X3RvX2Nsa19ub2RlKGkpOw0KPiA+ICsgICAgICAg
ICAgICAgICBpZiAoIWNsa19ucCkNCj4gPiArICAgICAgICAgICAgICAgICAgICAgICBjb250aW51
ZTsNCj4gPiArDQo+ID4gKyAgICAgICAgICAgICAgIGlmIChjbGtfbnAgPT0gbnApDQo+ID4gKyAg
ICAgICAgICAgICAgICAgICAgICAgY3B1bWFza19zZXRfY3B1KGksIGRzdHApOw0KPiANCj4gU28g
eW91IGFyZSBkZXBlbmRpbmcgb24gbWF0Y2hpbmcgdGhlIGNsb2NrLW5vZGVzIGZyb20gRFQgZm9y
IGdldHRpbmcgdGhpcw0KPiBpbmZvcm1hdGlvbiwgcmlnaHQgPyBUaGVyZSBpcyBub3RoaW5nIHRo
YXQgdGhlIGFyY2hpdGVjdHVyZSBnaXZlcz8NCj4gDQo+ID4gKw0KPiA+ICsgICAgICAgICAgICAg
ICBvZl9ub2RlX3B1dChjbGtfbnApOw0KPiA+ICsgICAgICAgfQ0KPiA+ICsgICAgICAgb2Zfbm9k
ZV9wdXQobnApOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICAvKiByZWR1Y2UgdGhlIGR1cGxpY2F0ZWQg
ZnJlcXVlbmNpZXMgaW4gZnJlcXVlbmN5IHRhYmxlICovICBzdGF0aWMNCj4gPiB2b2lkIGZyZXFf
dGFibGVfcmVkdXAoc3RydWN0IGNwdWZyZXFfZnJlcXVlbmN5X3RhYmxlICpmcmVxX3RhYmxlLA0K
PiA+ICAgICAgICAgICAgICAgICBpbnQgY291bnQpDQo+ID4gQEAgLTEwNSw2ICsxNzQsNyBAQCBz
dGF0aWMgdm9pZCBmcmVxX3RhYmxlX3NvcnQoc3RydWN0DQo+IGNwdWZyZXFfZnJlcXVlbmN5X3Rh
YmxlICpmcmVxX3RhYmxlLA0KPiA+ICAgICAgICAgaW50IGksIGosIGluZDsNCj4gPiAgICAgICAg
IHVuc2lnbmVkIGludCBmcmVxLCBtYXhfZnJlcTsNCj4gPiAgICAgICAgIHN0cnVjdCBjcHVmcmVx
X2ZyZXF1ZW5jeV90YWJsZSB0YWJsZTsNCj4gPiArDQo+ID4gICAgICAgICBmb3IgKGkgPSAwOyBp
IDwgY291bnQgLSAxOyBpKyspIHsNCj4gPiAgICAgICAgICAgICAgICAgbWF4X2ZyZXEgPSBmcmVx
X3RhYmxlW2ldLmZyZXF1ZW5jeTsNCj4gPiAgICAgICAgICAgICAgICAgaW5kID0gaTsNCj4gPiBA
QCAtMTI5LDcgKzE5OSw3IEBAIHN0YXRpYyB2b2lkIGZyZXFfdGFibGVfc29ydChzdHJ1Y3QNCj4g
Y3B1ZnJlcV9mcmVxdWVuY3lfdGFibGUgKmZyZXFfdGFibGUsDQo+ID4gICAgICAgICB9DQo+ID4g
IH0NCj4gPg0KPiA+IC1zdGF0aWMgaW50IGNvcmVuZXRfY3B1ZnJlcV9jcHVfaW5pdChzdHJ1Y3Qg
Y3B1ZnJlcV9wb2xpY3kgKnBvbGljeSkNCj4gPiArc3RhdGljIGludCBxb3JpcV9jcHVmcmVxX2Nw
dV9pbml0KHN0cnVjdCBjcHVmcmVxX3BvbGljeSAqcG9saWN5KQ0KPiA+ICB7DQo+ID4gICAgICAg
ICBzdHJ1Y3QgZGV2aWNlX25vZGUgKm5wOw0KPiA+ICAgICAgICAgaW50IGksIGNvdW50LCByZXQ7
DQo+ID4gQEAgLTE0NSwxMCArMjE1LDggQEAgc3RhdGljIGludCBjb3JlbmV0X2NwdWZyZXFfY3B1
X2luaXQoc3RydWN0DQo+IGNwdWZyZXFfcG9saWN5ICpwb2xpY3kpDQo+ID4gICAgICAgICAgICAg
ICAgIHJldHVybiAtRU5PREVWOw0KPiA+DQo+ID4gICAgICAgICBkYXRhID0ga3phbGxvYyhzaXpl
b2YoKmRhdGEpLCBHRlBfS0VSTkVMKTsNCj4gPiAtICAgICAgIGlmICghZGF0YSkgew0KPiA+IC0g
ICAgICAgICAgICAgICBwcl9lcnIoIiVzOiBubyBtZW1vcnlcbiIsIF9fZnVuY19fKTsNCj4gDQo+
IFdhc24ndCB0aGlzIHVzZWZ1bCA/DQo+IA0KPiA+ICsgICAgICAgaWYgKCFkYXRhKQ0KPiA+ICAg
ICAgICAgICAgICAgICBnb3RvIGVycl9ucDsNCj4gPiAtICAgICAgIH0NCj4gPg0KPiA+ICAgICAg
ICAgcG9saWN5LT5jbGsgPSBvZl9jbGtfZ2V0KG5wLCAwKTsNCj4gPiAgICAgICAgIGlmIChJU19F
UlIocG9saWN5LT5jbGspKSB7DQo+ID4gQEAgLTE3MCw3ICsyMzgsNyBAQCBzdGF0aWMgaW50IGNv
cmVuZXRfY3B1ZnJlcV9jcHVfaW5pdChzdHJ1Y3QNCj4gY3B1ZnJlcV9wb2xpY3kgKnBvbGljeSkN
Cj4gPiAgICAgICAgIH0NCj4gPg0KPiA+ICAgICAgICAgaWYgKGZtYXNrKQ0KPiA+IC0gICAgICAg
ICAgICAgICBtYXNrID0gZm1hc2tbZ2V0X2hhcmRfc21wX3Byb2Nlc3Nvcl9pZChjcHUpXTsNCj4g
PiArICAgICAgICAgICAgICAgbWFzayA9IGZtYXNrW2dldF9jcHVfcGh5c2ljYWxfaWQoY3B1KV07
DQo+ID4gICAgICAgICBlbHNlDQo+ID4gICAgICAgICAgICAgICAgIG1hc2sgPSAweDA7DQo+ID4N
Cj4gPiBAQCAtMjAxLDEzICsyNjksMTMgQEAgc3RhdGljIGludCBjb3JlbmV0X2NwdWZyZXFfY3B1
X2luaXQoc3RydWN0DQo+IGNwdWZyZXFfcG9saWN5ICpwb2xpY3kpDQo+ID4gICAgICAgICBkYXRh
LT50YWJsZSA9IHRhYmxlOw0KPiA+DQo+ID4gICAgICAgICAvKiB1cGRhdGUgLT5jcHVzIGlmIHdl
IGhhdmUgY2x1c3Rlciwgbm8gaGFybSBpZiBub3QgKi8NCj4gPiAtICAgICAgIGNwdW1hc2tfY29w
eShwb2xpY3ktPmNwdXMsIHBlcl9jcHUoY3B1X21hc2ssIGNwdSkpOw0KPiA+IC0gICAgICAgZm9y
X2VhY2hfY3B1KGksIHBlcl9jcHUoY3B1X21hc2ssIGNwdSkpDQo+ID4gKyAgICAgICBzZXRfYWZm
ZWN0ZWRfY3B1cyhwb2xpY3kpOw0KPiA+ICsgICAgICAgZm9yX2VhY2hfY3B1KGksIHBvbGljeS0+
Y3B1cykNCj4gPiAgICAgICAgICAgICAgICAgcGVyX2NwdShjcHVfZGF0YSwgaSkgPSBkYXRhOw0K
PiANCj4gR2V0IHJpZCBvZiB0aGlzIHBlci1jcHUgZGF0YSBhbmQgdXNlIHBvbGljeS0+ZHJpdmVy
X2RhdGEgaW5zdGVhZC4NCj4gDQo+ID4NCj4gPiAgICAgICAgIC8qIE1pbmltdW0gdHJhbnNpdGlv
biBsYXRlbmN5IGlzIDEyIHBsYXRmb3JtIGNsb2NrcyAqLw0KPiA+ICAgICAgICAgdTY0dGVtcCA9
IDEyVUxMICogTlNFQ19QRVJfU0VDOw0KPiA+IC0gICAgICAgZG9fZGl2KHU2NHRlbXAsIGZzbF9n
ZXRfc3lzX2ZyZXEoKSk7DQo+ID4gKyAgICAgICBkb19kaXYodTY0dGVtcCwgZ2V0X2J1c19mcmVx
KCkpOw0KPiA+ICAgICAgICAgcG9saWN5LT5jcHVpbmZvLnRyYW5zaXRpb25fbGF0ZW5jeSA9IHU2
NHRlbXAgKyAxOw0KPiA+DQo+ID4gICAgICAgICBvZl9ub2RlX3B1dChucCk7DQo+ID4gQEAgLTIy
Nyw3ICsyOTUsNyBAQCBlcnJfbnA6DQo+ID4gICAgICAgICByZXR1cm4gLUVOT0RFVjsNCj4gPiAg
fQ0KPiA+DQo+ID4gLXN0YXRpYyBpbnQgX19leGl0IGNvcmVuZXRfY3B1ZnJlcV9jcHVfZXhpdChz
dHJ1Y3QgY3B1ZnJlcV9wb2xpY3kNCj4gPiAqcG9saWN5KQ0KPiA+ICtzdGF0aWMgaW50IF9fZXhp
dCBxb3JpcV9jcHVmcmVxX2NwdV9leGl0KHN0cnVjdCBjcHVmcmVxX3BvbGljeQ0KPiA+ICsqcG9s
aWN5KQ0KPiA+ICB7DQo+ID4gICAgICAgICBzdHJ1Y3QgY3B1X2RhdGEgKmRhdGEgPSBwZXJfY3B1
KGNwdV9kYXRhLCBwb2xpY3ktPmNwdSk7DQo+ID4gICAgICAgICB1bnNpZ25lZCBpbnQgY3B1Ow0K
PiA+IEBAIC0yMzYsMTMgKzMwNCwxMyBAQCBzdGF0aWMgaW50IF9fZXhpdCBjb3JlbmV0X2NwdWZy
ZXFfY3B1X2V4aXQoc3RydWN0DQo+IGNwdWZyZXFfcG9saWN5ICpwb2xpY3kpDQo+ID4gICAgICAg
ICBrZnJlZShkYXRhLT50YWJsZSk7DQo+ID4gICAgICAgICBrZnJlZShkYXRhKTsNCj4gPg0KPiA+
IC0gICAgICAgZm9yX2VhY2hfY3B1KGNwdSwgcGVyX2NwdShjcHVfbWFzaywgcG9saWN5LT5jcHUp
KQ0KPiA+ICsgICAgICAgZm9yX2VhY2hfY3B1KGNwdSwgcG9saWN5LT5jcHVzKQ0KPiA+ICAgICAg
ICAgICAgICAgICBwZXJfY3B1KGNwdV9kYXRhLCBjcHUpID0gTlVMTDsNCj4gPg0KPiA+ICAgICAg
ICAgcmV0dXJuIDA7DQo+ID4gIH0NCj4gPg0KPiA+IC1zdGF0aWMgaW50IGNvcmVuZXRfY3B1ZnJl
cV90YXJnZXQoc3RydWN0IGNwdWZyZXFfcG9saWN5ICpwb2xpY3ksDQo+ID4gK3N0YXRpYyBpbnQg
cW9yaXFfY3B1ZnJlcV90YXJnZXQoc3RydWN0IGNwdWZyZXFfcG9saWN5ICpwb2xpY3ksDQo+ID4g
ICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCBpbmRleCkNCj4gPiAgew0KPiA+ICAgICAgICAg
c3RydWN0IGNsayAqcGFyZW50Ow0KPiA+IEBAIC0yNTIsMTggKzMyMCwxOCBAQCBzdGF0aWMgaW50
IGNvcmVuZXRfY3B1ZnJlcV90YXJnZXQoc3RydWN0DQo+IGNwdWZyZXFfcG9saWN5ICpwb2xpY3ks
DQo+ID4gICAgICAgICByZXR1cm4gY2xrX3NldF9wYXJlbnQocG9saWN5LT5jbGssIHBhcmVudCk7
ICB9DQo+ID4NCj4gPiAtc3RhdGljIHN0cnVjdCBjcHVmcmVxX2RyaXZlciBwcGNfY29yZW5ldF9j
cHVmcmVxX2RyaXZlciA9IHsNCj4gPiAtICAgICAgIC5uYW1lICAgICAgICAgICA9ICJwcGNfY3B1
ZnJlcSIsDQo+ID4gK3N0YXRpYyBzdHJ1Y3QgY3B1ZnJlcV9kcml2ZXIgcW9yaXFfY3B1ZnJlcV9k
cml2ZXIgPSB7DQo+ID4gKyAgICAgICAubmFtZSAgICAgICAgICAgPSAicW9yaXFfY3B1ZnJlcSIs
DQo+ID4gICAgICAgICAuZmxhZ3MgICAgICAgICAgPSBDUFVGUkVRX0NPTlNUX0xPT1BTLA0KPiA+
IC0gICAgICAgLmluaXQgICAgICAgICAgID0gY29yZW5ldF9jcHVmcmVxX2NwdV9pbml0LA0KPiA+
IC0gICAgICAgLmV4aXQgICAgICAgICAgID0gX19leGl0X3AoY29yZW5ldF9jcHVmcmVxX2NwdV9l
eGl0KSwNCj4gPiArICAgICAgIC5pbml0ICAgICAgICAgICA9IHFvcmlxX2NwdWZyZXFfY3B1X2lu
aXQsDQo+ID4gKyAgICAgICAuZXhpdCAgICAgICAgICAgPSBfX2V4aXRfcChxb3JpcV9jcHVmcmVx
X2NwdV9leGl0KSwNCj4gPiAgICAgICAgIC52ZXJpZnkgICAgICAgICA9IGNwdWZyZXFfZ2VuZXJp
Y19mcmVxdWVuY3lfdGFibGVfdmVyaWZ5LA0KPiA+IC0gICAgICAgLnRhcmdldF9pbmRleCAgID0g
Y29yZW5ldF9jcHVmcmVxX3RhcmdldCwNCj4gPiArICAgICAgIC50YXJnZXRfaW5kZXggICA9IHFv
cmlxX2NwdWZyZXFfdGFyZ2V0LA0KPiA+ICAgICAgICAgLmdldCAgICAgICAgICAgID0gY3B1ZnJl
cV9nZW5lcmljX2dldCwNCj4gPiAgICAgICAgIC5hdHRyICAgICAgICAgICA9IGNwdWZyZXFfZ2Vu
ZXJpY19hdHRyLA0KPiA+ICB9Ow0KPiA+DQo+ID4gLXN0YXRpYyBjb25zdCBzdHJ1Y3Qgb2ZfZGV2
aWNlX2lkIG5vZGVfbWF0Y2hlc1tdIF9faW5pdGRhdGEgPSB7DQo+ID4gK3N0YXRpYyBjb25zdCBz
dHJ1Y3Qgb2ZfZGV2aWNlX2lkIG5vZGVfbWF0Y2hlc1tdIF9faW5pdGNvbnN0ID0gew0KPiA+ICAg
ICAgICAgeyAuY29tcGF0aWJsZSA9ICJmc2wscDIwNDEtY2xvY2tnZW4iLCAuZGF0YSA9ICZzZGF0
YVswXSwgfSwNCj4gPiAgICAgICAgIHsgLmNvbXBhdGlibGUgPSAiZnNsLHAzMDQxLWNsb2NrZ2Vu
IiwgLmRhdGEgPSAmc2RhdGFbMF0sIH0sDQo+ID4gICAgICAgICB7IC5jb21wYXRpYmxlID0gImZz
bCxwNTAyMC1jbG9ja2dlbiIsIC5kYXRhID0gJnNkYXRhWzFdLCB9LCBAQA0KPiA+IC0yNzMsNjEg
KzM0MSw0MyBAQCBzdGF0aWMgY29uc3Qgc3RydWN0IG9mX2RldmljZV9pZCBub2RlX21hdGNoZXNb
XQ0KPiBfX2luaXRkYXRhID0gew0KPiA+ICAgICAgICAge30NCj4gPiAgfTsNCj4gPg0KPiA+IC1z
dGF0aWMgaW50IF9faW5pdCBwcGNfY29yZW5ldF9jcHVmcmVxX2luaXQodm9pZCkNCj4gPiArc3Rh
dGljIGludCBfX2luaXQgcW9yaXFfY3B1ZnJlcV9pbml0KHZvaWQpDQo+ID4gIHsNCj4gPiAgICAg
ICAgIGludCByZXQ7DQo+ID4gICAgICAgICBzdHJ1Y3QgZGV2aWNlX25vZGUgICpucDsNCj4gPiAg
ICAgICAgIGNvbnN0IHN0cnVjdCBvZl9kZXZpY2VfaWQgKm1hdGNoOw0KPiA+ICAgICAgICAgY29u
c3Qgc3RydWN0IHNvY19kYXRhICpkYXRhOw0KPiA+IC0gICAgICAgdW5zaWduZWQgaW50IGNwdTsN
Cj4gPg0KPiA+ICAgICAgICAgbnAgPSBvZl9maW5kX21hdGNoaW5nX25vZGUoTlVMTCwgbm9kZV9t
YXRjaGVzKTsNCj4gPiAgICAgICAgIGlmICghbnApDQo+ID4gICAgICAgICAgICAgICAgIHJldHVy
biAtRU5PREVWOw0KPiA+DQo+ID4gLSAgICAgICBmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KSB7
DQo+ID4gLSAgICAgICAgICAgICAgIGlmICghYWxsb2NfY3B1bWFza192YXIoJnBlcl9jcHUoY3B1
X21hc2ssIGNwdSksDQo+IEdGUF9LRVJORUwpKQ0KPiA+IC0gICAgICAgICAgICAgICAgICAgICAg
IGdvdG8gZXJyX21hc2s7DQo+ID4gLSAgICAgICAgICAgICAgIGNwdW1hc2tfY29weShwZXJfY3B1
KGNwdV9tYXNrLCBjcHUpLA0KPiBjcHVfY29yZV9tYXNrKGNwdSkpOw0KPiA+IC0gICAgICAgfQ0K
PiA+IC0NCj4gPiAgICAgICAgIG1hdGNoID0gb2ZfbWF0Y2hfbm9kZShub2RlX21hdGNoZXMsIG5w
KTsNCj4gPiAgICAgICAgIGRhdGEgPSBtYXRjaC0+ZGF0YTsNCj4gPiAgICAgICAgIGlmIChkYXRh
KSB7DQo+ID4gICAgICAgICAgICAgICAgIGlmIChkYXRhLT5mbGFnKQ0KPiA+ICAgICAgICAgICAg
ICAgICAgICAgICAgIGZtYXNrID0gZGF0YS0+ZnJlcV9tYXNrOw0KPiA+IC0gICAgICAgICAgICAg
ICBtaW5fY3B1ZnJlcSA9IGZzbF9nZXRfc3lzX2ZyZXEoKTsNCj4gPiArICAgICAgICAgICAgICAg
bWluX2NwdWZyZXEgPSBnZXRfYnVzX2ZyZXEoKTsNCj4gPiAgICAgICAgIH0gZWxzZSB7DQo+ID4g
LSAgICAgICAgICAgICAgIG1pbl9jcHVmcmVxID0gZnNsX2dldF9zeXNfZnJlcSgpIC8gMjsNCj4g
PiArICAgICAgICAgICAgICAgbWluX2NwdWZyZXEgPSBnZXRfYnVzX2ZyZXEoKSAvIDI7DQo+ID4g
ICAgICAgICB9DQo+ID4NCj4gPiAgICAgICAgIG9mX25vZGVfcHV0KG5wKTsNCj4gPg0KPiA+IC0g
ICAgICAgcmV0ID0gY3B1ZnJlcV9yZWdpc3Rlcl9kcml2ZXIoJnBwY19jb3JlbmV0X2NwdWZyZXFf
ZHJpdmVyKTsNCj4gPiArICAgICAgIHJldCA9IGNwdWZyZXFfcmVnaXN0ZXJfZHJpdmVyKCZxb3Jp
cV9jcHVmcmVxX2RyaXZlcik7DQo+ID4gICAgICAgICBpZiAoIXJldCkNCj4gPiAtICAgICAgICAg
ICAgICAgcHJfaW5mbygiRnJlZXNjYWxlIFBvd2VyUEMgY29yZW5ldCBDUFUgZnJlcXVlbmN5IHNj
YWxpbmcNCj4gZHJpdmVyXG4iKTsNCj4gPiArICAgICAgICAgICAgICAgcHJfaW5mbygiRnJlZXNj
YWxlIFFvcklRIENQVSBmcmVxdWVuY3kgc2NhbGluZw0KPiA+ICsgZHJpdmVyXG4iKTsNCj4gPg0K
PiA+ICAgICAgICAgcmV0dXJuIHJldDsNCj4gPiAtDQo+ID4gLWVycl9tYXNrOg0KPiA+IC0gICAg
ICAgZm9yX2VhY2hfcG9zc2libGVfY3B1KGNwdSkNCj4gPiAtICAgICAgICAgICAgICAgZnJlZV9j
cHVtYXNrX3ZhcihwZXJfY3B1KGNwdV9tYXNrLCBjcHUpKTsNCj4gPiAtDQo+ID4gLSAgICAgICBy
ZXR1cm4gLUVOT01FTTsNCj4gPiAgfQ0KPiA+IC1tb2R1bGVfaW5pdChwcGNfY29yZW5ldF9jcHVm
cmVxX2luaXQpOw0KPiA+ICttb2R1bGVfaW5pdChxb3JpcV9jcHVmcmVxX2luaXQpOw0KPiA+DQo+
ID4gLXN0YXRpYyB2b2lkIF9fZXhpdCBwcGNfY29yZW5ldF9jcHVmcmVxX2V4aXQodm9pZCkNCj4g
PiArc3RhdGljIHZvaWQgX19leGl0IHFvcmlxX2NwdWZyZXFfZXhpdCh2b2lkKQ0KPiA+ICB7DQo+
ID4gLSAgICAgICB1bnNpZ25lZCBpbnQgY3B1Ow0KPiA+IC0NCj4gPiAtICAgICAgIGZvcl9lYWNo
X3Bvc3NpYmxlX2NwdShjcHUpDQo+ID4gLSAgICAgICAgICAgICAgIGZyZWVfY3B1bWFza192YXIo
cGVyX2NwdShjcHVfbWFzaywgY3B1KSk7DQo+ID4gLQ0KPiA+IC0gICAgICAgY3B1ZnJlcV91bnJl
Z2lzdGVyX2RyaXZlcigmcHBjX2NvcmVuZXRfY3B1ZnJlcV9kcml2ZXIpOw0KPiA+ICsgICAgICAg
Y3B1ZnJlcV91bnJlZ2lzdGVyX2RyaXZlcigmcW9yaXFfY3B1ZnJlcV9kcml2ZXIpOw0KPiA+ICB9
DQo+ID4gLW1vZHVsZV9leGl0KHBwY19jb3JlbmV0X2NwdWZyZXFfZXhpdCk7DQo+ID4gK21vZHVs
ZV9leGl0KHFvcmlxX2NwdWZyZXFfZXhpdCk7DQo+ID4NCj4gPiAgTU9EVUxFX0xJQ0VOU0UoIkdQ
TCIpOw0KPiA+ICBNT0RVTEVfQVVUSE9SKCJUYW5nIFl1YW50aWFuIDxZdWFudGlhbi5UYW5nQGZy
ZWVzY2FsZS5jb20+Iik7DQo+ID4gLU1PRFVMRV9ERVNDUklQVElPTigiY3B1ZnJlcSBkcml2ZXIg
Zm9yIEZyZWVzY2FsZSBlNTAwbWMgc2VyaWVzDQo+ID4gU29DcyIpOw0KPiA+ICtNT0RVTEVfREVT
Q1JJUFRJT04oImNwdWZyZXEgZHJpdmVyIGZvciBGcmVlc2NhbGUgUW9ySVEgc2VyaWVzIFNvQ3Mi
KTsNCj4gDQo+ICsgY29tbWVudHMgZnJvbSBLdW1hciBHYWxhIDopDQo=

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
  2014-10-21  8:59     ` Yuantian Tang
@ 2014-10-21  9:03       ` Viresh Kumar
  -1 siblings, 0 replies; 29+ messages in thread
From: Viresh Kumar @ 2014-10-21  9:03 UTC (permalink / raw)
  To: Yuantian Tang
  Cc: Rafael J. Wysocki, Linux Kernel Mailing List, linux-pm, linuxppc-dev

On 21 October 2014 14:29, Yuantian Tang <Yuantian.Tang@freescale.com> wrote:
> If I do so, menuconfig will display like this(on PPC):
>         PowerPC CPU frequency scaling drivers  ----
>     QorIQ CPU Frequency scaling  --->
>                 <*> CPU frequency scaling driver for Freescale QorIQ SoCs
> On ARM, there should be a similar problem.
> Isn't weird?

Similar is true for cpufreq-cpu0 driver as well.. Maybe we can create a
Kconfig.drivers configuration and include it from all architecture specific
ones ?

@ Rafael ?

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-10-21  9:03       ` Viresh Kumar
  0 siblings, 0 replies; 29+ messages in thread
From: Viresh Kumar @ 2014-10-21  9:03 UTC (permalink / raw)
  To: Yuantian Tang
  Cc: linuxppc-dev, Rafael J. Wysocki, Linux Kernel Mailing List, linux-pm

On 21 October 2014 14:29, Yuantian Tang <Yuantian.Tang@freescale.com> wrote:
> If I do so, menuconfig will display like this(on PPC):
>         PowerPC CPU frequency scaling drivers  ----
>     QorIQ CPU Frequency scaling  --->
>                 <*> CPU frequency scaling driver for Freescale QorIQ SoCs
> On ARM, there should be a similar problem.
> Isn't weird?

Similar is true for cpufreq-cpu0 driver as well.. Maybe we can create a
Kconfig.drivers configuration and include it from all architecture specific
ones ?

@ Rafael ?

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
  2014-10-21  9:03       ` Viresh Kumar
  (?)
@ 2014-10-27  3:39         ` Yuantian Tang
  -1 siblings, 0 replies; 29+ messages in thread
From: Yuantian Tang @ 2014-10-27  3:39 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, Linux Kernel Mailing List, linux-pm, linuxppc-dev

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 1114 bytes --]


> -----Original Message-----
> From: Viresh Kumar [mailto:viresh.kumar@linaro.org]
> Sent: Tuesday, October 21, 2014 5:04 PM
> To: Tang Yuantian-B29983
> Cc: Rafael J. Wysocki; Linux Kernel Mailing List; linux-pm@vger.kernel.org;
> linuxppc-dev@ozlabs.org
> Subject: Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ
> platforms
> 
> On 21 October 2014 14:29, Yuantian Tang <Yuantian.Tang@freescale.com>
> wrote:
> > If I do so, menuconfig will display like this(on PPC):
> >         PowerPC CPU frequency scaling drivers  ----
> >     QorIQ CPU Frequency scaling  --->
> >                 <*> CPU frequency scaling driver for Freescale QorIQ
> > SoCs On ARM, there should be a similar problem.
> > Isn't weird?
> 
> Similar is true for cpufreq-cpu0 driver as well.. Maybe we can create a
> Kconfig.drivers configuration and include it from all architecture specific ones ?
> 
> @ Rafael ?

Do we have a conclusion yet?

Regards,
Yuantian
ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-10-27  3:39         ` Yuantian Tang
  0 siblings, 0 replies; 29+ messages in thread
From: Yuantian Tang @ 2014-10-27  3:39 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, Linux Kernel Mailing List, linux-pm, linuxppc-dev


> -----Original Message-----
> From: Viresh Kumar [mailto:viresh.kumar@linaro.org]
> Sent: Tuesday, October 21, 2014 5:04 PM
> To: Tang Yuantian-B29983
> Cc: Rafael J. Wysocki; Linux Kernel Mailing List; linux-pm@vger.kernel.org;
> linuxppc-dev@ozlabs.org
> Subject: Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ
> platforms
> 
> On 21 October 2014 14:29, Yuantian Tang <Yuantian.Tang@freescale.com>
> wrote:
> > If I do so, menuconfig will display like this(on PPC):
> >         PowerPC CPU frequency scaling drivers  ----
> >     QorIQ CPU Frequency scaling  --->
> >                 <*> CPU frequency scaling driver for Freescale QorIQ
> > SoCs On ARM, there should be a similar problem.
> > Isn't weird?
> 
> Similar is true for cpufreq-cpu0 driver as well.. Maybe we can create a
> Kconfig.drivers configuration and include it from all architecture specific ones ?
> 
> @ Rafael ?

Do we have a conclusion yet?

Regards,
Yuantian

^ permalink raw reply	[flat|nested] 29+ messages in thread

* RE: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-10-27  3:39         ` Yuantian Tang
  0 siblings, 0 replies; 29+ messages in thread
From: Yuantian Tang @ 2014-10-27  3:39 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: linuxppc-dev, Rafael J. Wysocki, Linux Kernel Mailing List, linux-pm

DQo+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+IEZyb206IFZpcmVzaCBLdW1hciBbbWFp
bHRvOnZpcmVzaC5rdW1hckBsaW5hcm8ub3JnXQ0KPiBTZW50OiBUdWVzZGF5LCBPY3RvYmVyIDIx
LCAyMDE0IDU6MDQgUE0NCj4gVG86IFRhbmcgWXVhbnRpYW4tQjI5OTgzDQo+IENjOiBSYWZhZWwg
Si4gV3lzb2NraTsgTGludXggS2VybmVsIE1haWxpbmcgTGlzdDsgbGludXgtcG1Admdlci5rZXJu
ZWwub3JnOw0KPiBsaW51eHBwYy1kZXZAb3psYWJzLm9yZw0KPiBTdWJqZWN0OiBSZTogW1BBVENI
XSBjcHVmcmVxOiBxb3JpcTogTWFrZSB0aGUgZHJpdmVyIHVzYWJsZSBvbiBhbGwgUW9ySVENCj4g
cGxhdGZvcm1zDQo+IA0KPiBPbiAyMSBPY3RvYmVyIDIwMTQgMTQ6MjksIFl1YW50aWFuIFRhbmcg
PFl1YW50aWFuLlRhbmdAZnJlZXNjYWxlLmNvbT4NCj4gd3JvdGU6DQo+ID4gSWYgSSBkbyBzbywg
bWVudWNvbmZpZyB3aWxsIGRpc3BsYXkgbGlrZSB0aGlzKG9uIFBQQyk6DQo+ID4gICAgICAgICBQ
b3dlclBDIENQVSBmcmVxdWVuY3kgc2NhbGluZyBkcml2ZXJzICAtLS0tDQo+ID4gICAgIFFvcklR
IENQVSBGcmVxdWVuY3kgc2NhbGluZyAgLS0tPg0KPiA+ICAgICAgICAgICAgICAgICA8Kj4gQ1BV
IGZyZXF1ZW5jeSBzY2FsaW5nIGRyaXZlciBmb3IgRnJlZXNjYWxlIFFvcklRDQo+ID4gU29DcyBP
biBBUk0sIHRoZXJlIHNob3VsZCBiZSBhIHNpbWlsYXIgcHJvYmxlbS4NCj4gPiBJc24ndCB3ZWly
ZD8NCj4gDQo+IFNpbWlsYXIgaXMgdHJ1ZSBmb3IgY3B1ZnJlcS1jcHUwIGRyaXZlciBhcyB3ZWxs
Li4gTWF5YmUgd2UgY2FuIGNyZWF0ZSBhDQo+IEtjb25maWcuZHJpdmVycyBjb25maWd1cmF0aW9u
IGFuZCBpbmNsdWRlIGl0IGZyb20gYWxsIGFyY2hpdGVjdHVyZSBzcGVjaWZpYyBvbmVzID8NCj4g
DQo+IEAgUmFmYWVsID8NCg0KRG8gd2UgaGF2ZSBhIGNvbmNsdXNpb24geWV0Pw0KDQpSZWdhcmRz
LA0KWXVhbnRpYW4NCg==

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
  2014-10-27  3:39         ` Yuantian Tang
@ 2014-11-10  4:56           ` Viresh Kumar
  -1 siblings, 0 replies; 29+ messages in thread
From: Viresh Kumar @ 2014-11-10  4:56 UTC (permalink / raw)
  To: Yuantian Tang
  Cc: Rafael J. Wysocki, Linux Kernel Mailing List, linux-pm, linuxppc-dev

On 27 October 2014 09:09, Yuantian Tang <Yuantian.Tang@freescale.com> wrote:
> Do we have a conclusion yet?

No. You can keep your initial duplication of Kconfig entries for the time being.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-11-10  4:56           ` Viresh Kumar
  0 siblings, 0 replies; 29+ messages in thread
From: Viresh Kumar @ 2014-11-10  4:56 UTC (permalink / raw)
  To: Yuantian Tang
  Cc: linuxppc-dev, Rafael J. Wysocki, Linux Kernel Mailing List, linux-pm

On 27 October 2014 09:09, Yuantian Tang <Yuantian.Tang@freescale.com> wrote:
> Do we have a conclusion yet?

No. You can keep your initial duplication of Kconfig entries for the time being.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
  2014-10-21  8:59     ` Yuantian Tang
@ 2014-11-11 19:09       ` Scott Wood
  -1 siblings, 0 replies; 29+ messages in thread
From: Scott Wood @ 2014-11-11 19:09 UTC (permalink / raw)
  To: Yuantian Tang
  Cc: Viresh Kumar, linuxppc-dev, Rafael J. Wysocki,
	Linux Kernel Mailing List, linux-pm

On Tue, 2014-10-21 at 08:59 +0000, Yuantian Tang wrote:
> > > -config PPC_CORENET_CPUFREQ
> > > -       tristate "CPU frequency scaling driver for Freescale E500MC SoCs"
> > > -       depends on PPC_E500MC && OF && COMMON_CLK
> > > +config QORIQ_CPUFREQ
> > > +       tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> > > +       depends on OF && COMMON_CLK
> > >         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.
> > > +         This adds the CPUFreq driver support for Freescale QorIQ SoCs
> > > +         which are capable of changing the CPU's frequency dynamically.
> > >
> > >  config CPU_FREQ_PMAC
> > >         bool "Support for Apple PowerBooks"
> > 
> > Don't need this duplication at all. Just move this to Kconfig instead of .arm and
> > ppc.
> > 
> If I do so, menuconfig will display like this(on PPC):
> 	PowerPC CPU frequency scaling drivers  ----  
>     QorIQ CPU Frequency scaling  --->    
>   		<*> CPU frequency scaling driver for Freescale QorIQ SoCs
> On ARM, there should be a similar problem.
> Isn't weird?

What purpose do those "<arch> CPU frequency scaling drivers" submenus
serve, versus just including the options in the main cpufreq menu?  It's
not as if more than one arch would be visible at once (and when a
situation with multiple visible menus popped up, it was considered a
bug).

-Scott



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-11-11 19:09       ` Scott Wood
  0 siblings, 0 replies; 29+ messages in thread
From: Scott Wood @ 2014-11-11 19:09 UTC (permalink / raw)
  To: Yuantian Tang
  Cc: Viresh Kumar, linux-pm, Rafael J. Wysocki,
	Linux Kernel Mailing List, linuxppc-dev

On Tue, 2014-10-21 at 08:59 +0000, Yuantian Tang wrote:
> > > -config PPC_CORENET_CPUFREQ
> > > -       tristate "CPU frequency scaling driver for Freescale E500MC SoCs"
> > > -       depends on PPC_E500MC && OF && COMMON_CLK
> > > +config QORIQ_CPUFREQ
> > > +       tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
> > > +       depends on OF && COMMON_CLK
> > >         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.
> > > +         This adds the CPUFreq driver support for Freescale QorIQ SoCs
> > > +         which are capable of changing the CPU's frequency dynamically.
> > >
> > >  config CPU_FREQ_PMAC
> > >         bool "Support for Apple PowerBooks"
> > 
> > Don't need this duplication at all. Just move this to Kconfig instead of .arm and
> > ppc.
> > 
> If I do so, menuconfig will display like this(on PPC):
> 	PowerPC CPU frequency scaling drivers  ----  
>     QorIQ CPU Frequency scaling  --->    
>   		<*> CPU frequency scaling driver for Freescale QorIQ SoCs
> On ARM, there should be a similar problem.
> Isn't weird?

What purpose do those "<arch> CPU frequency scaling drivers" submenus
serve, versus just including the options in the main cpufreq menu?  It's
not as if more than one arch would be visible at once (and when a
situation with multiple visible menus popped up, it was considered a
bug).

-Scott

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
  2014-11-11 19:09       ` Scott Wood
@ 2014-11-12  3:41         ` Viresh Kumar
  -1 siblings, 0 replies; 29+ messages in thread
From: Viresh Kumar @ 2014-11-12  3:41 UTC (permalink / raw)
  To: Scott Wood
  Cc: Yuantian Tang, linuxppc-dev, Rafael J. Wysocki,
	Linux Kernel Mailing List, linux-pm

On 12 November 2014 00:39, Scott Wood <scottwood@freescale.com> wrote:
> What purpose do those "<arch> CPU frequency scaling drivers" submenus
> serve, versus just including the options in the main cpufreq menu?  It's
> not as if more than one arch would be visible at once (and when a
> situation with multiple visible menus popped up, it was considered a
> bug).

Oh, that really looks fine to me. I will send it formally as well:

diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index 3489f8f..a24d678 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -196,19 +196,19 @@ config CPUFREQ_DT

          If in doubt, say N.

-menu "x86 CPU frequency scaling drivers"
-depends on X86
+if X86
 source "drivers/cpufreq/Kconfig.x86"
-endmenu
+endif

-menu "ARM CPU frequency scaling drivers"
-depends on ARM || ARM64
+if ARM || ARM64
 source "drivers/cpufreq/Kconfig.arm"
-endmenu
+endif

-menu "AVR32 CPU frequency scaling drivers"
-depends on AVR32
+if PPC32 || PPC64
+source "drivers/cpufreq/Kconfig.powerpc"
+endif

+if AVR32
 config AVR32_AT32AP_CPUFREQ
        bool "CPU frequency driver for AT32AP"
        depends on PLATFORM_AT32AP
@@ -216,12 +216,9 @@ config AVR32_AT32AP_CPUFREQ
        help
          This enables the CPU frequency driver for AT32AP processors.
          If in doubt, say N.
+endif

-endmenu
-
-menu "CPUFreq processor drivers"
-depends on IA64
-
+if IA64
 config IA64_ACPI_CPUFREQ
        tristate "ACPI Processor P-States driver"
        depends on ACPI_PROCESSOR
@@ -232,12 +229,9 @@ config IA64_ACPI_CPUFREQ
        For details, take a look at <file:Documentation/cpu-freq/>.

        If in doubt, say N.
+endif

-endmenu
-
-menu "MIPS CPUFreq processor drivers"
-depends on MIPS
-
+if MIPS
 config LOONGSON2_CPUFREQ
        tristate "Loongson2 CPUFreq Driver"
        help
@@ -249,16 +243,9 @@ config LOONGSON2_CPUFREQ
          For details, take a look at <file:Documentation/cpu-freq/>.

          If in doubt, say N.
+endif

-endmenu
-
-menu "PowerPC CPU frequency scaling drivers"
-depends on PPC32 || PPC64
-source "drivers/cpufreq/Kconfig.powerpc"
-endmenu
-
-menu "SPARC CPU frequency scaling drivers"
-depends on SPARC64
+if SPARC64
 config SPARC_US3_CPUFREQ
        tristate "UltraSPARC-III CPU Frequency driver"
        help
@@ -276,10 +263,9 @@ config SPARC_US2E_CPUFREQ
          For details, take a look at <file:Documentation/cpu-freq>.

          If in doubt, say N.
-endmenu
+endif

-menu "SH CPU Frequency scaling"
-depends on SUPERH
+if SUPERH
 config SH_CPU_FREQ
        tristate "SuperH CPU Frequency driver"
        help
@@ -293,7 +279,7 @@ config SH_CPU_FREQ
          For details, take a look at <file:Documentation/cpu-freq>.

          If unsure, say N.
-endmenu
+endif

 endif
 endmenu

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms
@ 2014-11-12  3:41         ` Viresh Kumar
  0 siblings, 0 replies; 29+ messages in thread
From: Viresh Kumar @ 2014-11-12  3:41 UTC (permalink / raw)
  To: Scott Wood
  Cc: Yuantian Tang, linux-pm, Rafael J. Wysocki,
	Linux Kernel Mailing List, linuxppc-dev

On 12 November 2014 00:39, Scott Wood <scottwood@freescale.com> wrote:
> What purpose do those "<arch> CPU frequency scaling drivers" submenus
> serve, versus just including the options in the main cpufreq menu?  It's
> not as if more than one arch would be visible at once (and when a
> situation with multiple visible menus popped up, it was considered a
> bug).

Oh, that really looks fine to me. I will send it formally as well:

diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index 3489f8f..a24d678 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -196,19 +196,19 @@ config CPUFREQ_DT

          If in doubt, say N.

-menu "x86 CPU frequency scaling drivers"
-depends on X86
+if X86
 source "drivers/cpufreq/Kconfig.x86"
-endmenu
+endif

-menu "ARM CPU frequency scaling drivers"
-depends on ARM || ARM64
+if ARM || ARM64
 source "drivers/cpufreq/Kconfig.arm"
-endmenu
+endif

-menu "AVR32 CPU frequency scaling drivers"
-depends on AVR32
+if PPC32 || PPC64
+source "drivers/cpufreq/Kconfig.powerpc"
+endif

+if AVR32
 config AVR32_AT32AP_CPUFREQ
        bool "CPU frequency driver for AT32AP"
        depends on PLATFORM_AT32AP
@@ -216,12 +216,9 @@ config AVR32_AT32AP_CPUFREQ
        help
          This enables the CPU frequency driver for AT32AP processors.
          If in doubt, say N.
+endif

-endmenu
-
-menu "CPUFreq processor drivers"
-depends on IA64
-
+if IA64
 config IA64_ACPI_CPUFREQ
        tristate "ACPI Processor P-States driver"
        depends on ACPI_PROCESSOR
@@ -232,12 +229,9 @@ config IA64_ACPI_CPUFREQ
        For details, take a look at <file:Documentation/cpu-freq/>.

        If in doubt, say N.
+endif

-endmenu
-
-menu "MIPS CPUFreq processor drivers"
-depends on MIPS
-
+if MIPS
 config LOONGSON2_CPUFREQ
        tristate "Loongson2 CPUFreq Driver"
        help
@@ -249,16 +243,9 @@ config LOONGSON2_CPUFREQ
          For details, take a look at <file:Documentation/cpu-freq/>.

          If in doubt, say N.
+endif

-endmenu
-
-menu "PowerPC CPU frequency scaling drivers"
-depends on PPC32 || PPC64
-source "drivers/cpufreq/Kconfig.powerpc"
-endmenu
-
-menu "SPARC CPU frequency scaling drivers"
-depends on SPARC64
+if SPARC64
 config SPARC_US3_CPUFREQ
        tristate "UltraSPARC-III CPU Frequency driver"
        help
@@ -276,10 +263,9 @@ config SPARC_US2E_CPUFREQ
          For details, take a look at <file:Documentation/cpu-freq>.

          If in doubt, say N.
-endmenu
+endif

-menu "SH CPU Frequency scaling"
-depends on SUPERH
+if SUPERH
 config SH_CPU_FREQ
        tristate "SuperH CPU Frequency driver"
        help
@@ -293,7 +279,7 @@ config SH_CPU_FREQ
          For details, take a look at <file:Documentation/cpu-freq>.

          If unsure, say N.
-endmenu
+endif

 endif
 endmenu

^ permalink raw reply related	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2014-11-12  3:42 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-10-17  3:13 [PATCH] cpufreq: qoriq: Make the driver usable on all QorIQ platforms B29983
2014-10-17  3:13 ` B29983
2014-10-17  3:13 ` B29983
2014-10-17  8:03 ` Kumar Gala
2014-10-17  8:03   ` Kumar Gala
2014-10-20  2:20   ` Yuantian Tang
2014-10-20  2:20     ` Yuantian Tang
2014-10-21  8:25   ` Yuantian Tang
2014-10-21  8:25     ` Yuantian Tang
2014-10-21  8:25     ` Yuantian Tang
2014-10-17  8:08 ` Viresh Kumar
2014-10-17  8:08   ` Viresh Kumar
2014-10-20  6:10   ` Yuantian Tang
2014-10-20  6:10     ` Yuantian Tang
2014-10-20  6:10     ` Yuantian Tang
2014-10-21  8:59   ` Yuantian Tang
2014-10-21  8:59     ` Yuantian Tang
2014-10-21  8:59     ` Yuantian Tang
2014-10-21  9:03     ` Viresh Kumar
2014-10-21  9:03       ` Viresh Kumar
2014-10-27  3:39       ` Yuantian Tang
2014-10-27  3:39         ` Yuantian Tang
2014-10-27  3:39         ` Yuantian Tang
2014-11-10  4:56         ` Viresh Kumar
2014-11-10  4:56           ` Viresh Kumar
2014-11-11 19:09     ` Scott Wood
2014-11-11 19:09       ` Scott Wood
2014-11-12  3:41       ` Viresh Kumar
2014-11-12  3:41         ` Viresh Kumar

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.