LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 07/13] sparc/PCI: Use new pci_is_bridge() to simplify code
From: David Miller @ 2014-04-25 16:49 UTC (permalink / raw)
  To: wangyijing
  Cc: tony.luck, linux-ia64, x86, linux-kernel, sparclinux, bhelgaas,
	tglx, linuxppc-dev
In-Reply-To: <1398417515-8740-8-git-send-email-wangyijing@huawei.com>

From: Yijing Wang <wangyijing@huawei.com>
Date: Fri, 25 Apr 2014 17:18:29 +0800

> Now we can use new pci_is_bridge() helper function
> to simplify code.
> 
> Signed-off-by: Yijing Wang <wangyijing@huawei.com>

Acked-by: David S. Miller <davem@davemloft.net>

^ permalink raw reply

* Re: [PATCH] PCI/hotplug/rphahp: Fix endianess issues
From: Bjorn Helgaas @ 2014-04-25 17:50 UTC (permalink / raw)
  To: Laurent Dufour; +Cc: linux-pci, linuxppc-dev, mdroth
In-Reply-To: <20140410130213.8435.16459.stgit@nimbus>

On Thu, Apr 10, 2014 at 03:02:13PM +0200, Laurent Dufour wrote:
> Numerical values stored in the device tree are encoded in Big Endian and
> should be byte swapped when running in Little Endian.
> 
> RPA hot plug module should convert those values as well.
> 
> Note that in rpaphp_get_drc_props the comparison between indexes[i+1] and
> *index is done using the BE values (whatever is the current endianess).
> This doesn't matter since we are checking for equality here. This way only
> the returned value is byte swapped.
> 
> RPA also made RTAS calls which implies BE values to be used. According to
> the patch done in RTAS (http://patchwork.ozlabs.org/patch/336865), no
> additional conversion is required in RPA.
> 
> Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>

I applied this to pci/hotplug for v3.16, thanks!

> ---
>  drivers/pci/hotplug/rpaphp_core.c |   15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
> index 4796c15..984d708 100644
> --- a/drivers/pci/hotplug/rpaphp_core.c
> +++ b/drivers/pci/hotplug/rpaphp_core.c
> @@ -223,16 +223,16 @@ int rpaphp_get_drc_props(struct device_node *dn, int *drc_index,
>  	type_tmp = (char *) &types[1];
>  
>  	/* Iterate through parent properties, looking for my-drc-index */
> -	for (i = 0; i < indexes[0]; i++) {
> +	for (i = 0; i < be32_to_cpu(indexes[0]); i++) {
>  		if ((unsigned int) indexes[i + 1] == *my_index) {
>  			if (drc_name)
>  				*drc_name = name_tmp;
>  			if (drc_type)
>  				*drc_type = type_tmp;
>  			if (drc_index)
> -				*drc_index = *my_index;
> +				*drc_index = be32_to_cpu(*my_index);
>  			if (drc_power_domain)
> -				*drc_power_domain = domains[i+1];
> +				*drc_power_domain = be32_to_cpu(domains[i+1]);
>  			return 0;
>  		}
>  		name_tmp += (strlen(name_tmp) + 1);
> @@ -321,16 +321,19 @@ int rpaphp_add_slot(struct device_node *dn)
>  	/* register PCI devices */
>  	name = (char *) &names[1];
>  	type = (char *) &types[1];
> -	for (i = 0; i < indexes[0]; i++) {
> +	for (i = 0; i < be32_to_cpu(indexes[0]); i++) {
> +		int index;
>  
> -		slot = alloc_slot_struct(dn, indexes[i + 1], name, power_domains[i + 1]);
> +		index = be32_to_cpu(indexes[i + 1]);
> +		slot = alloc_slot_struct(dn, index, name,
> +					 be32_to_cpu(power_domains[i + 1]));
>  		if (!slot)
>  			return -ENOMEM;
>  
>  		slot->type = simple_strtoul(type, NULL, 10);
>  
>  		dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n",
> -				indexes[i + 1], name, type);
> +				index, name, type);
>  
>  		retval = rpaphp_enable_slot(slot);
>  		if (!retval)
> 

^ permalink raw reply

* [PATCH v5 2/8] cpufreq: Use cpufreq_for_each_* macros for frequency table iteration
From: Stratos Karafotis @ 2014-04-25 20:15 UTC (permalink / raw)
  To: Rafael J. Wysocki, Viresh Kumar
  Cc: Kukjin Kim, linux-pm, LKML, cpufreq@vger.kernel.org,
	Prabhakar Lad, linux-samsung-soc, Sudeep Holla, Olof Johansson,
	linuxppc-dev, linux-arm-kernel@lists.infradead.org

The cpufreq core now supports the cpufreq_for_each_entry and
cpufreq_for_each_valid_entry macros helpers for iteration over the
cpufreq_frequency_table, so use them.

It should have no functional changes.

Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>
---
 drivers/cpufreq/acpi-cpufreq.c       |  9 +++---
 drivers/cpufreq/arm_big_little.c     | 16 +++++------
 drivers/cpufreq/cpufreq_stats.c      | 24 ++++++----------
 drivers/cpufreq/dbx500-cpufreq.c     |  8 ++----
 drivers/cpufreq/elanfreq.c           |  9 +++---
 drivers/cpufreq/exynos-cpufreq.c     | 11 ++++---
 drivers/cpufreq/exynos5440-cpufreq.c | 30 +++++++++----------
 drivers/cpufreq/freq_table.c         | 56 ++++++++++++++++--------------------
 drivers/cpufreq/longhaul.c           | 11 ++++---
 drivers/cpufreq/pasemi-cpufreq.c     | 10 +++----
 drivers/cpufreq/powernow-k6.c        | 14 ++++-----
 drivers/cpufreq/ppc_cbe_cpufreq.c    |  9 +++---
 drivers/cpufreq/s3c2416-cpufreq.c    | 40 +++++++++++---------------
 drivers/cpufreq/s3c64xx-cpufreq.c    | 15 ++++------
 14 files changed, 116 insertions(+), 146 deletions(-)

diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
index 000e4e0..b0c18ed 100644
--- a/drivers/cpufreq/acpi-cpufreq.c
+++ b/drivers/cpufreq/acpi-cpufreq.c
@@ -213,7 +213,7 @@ static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data)
 
 static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
 {
-	int i;
+	struct cpufreq_frequency_table *pos;
 	struct acpi_processor_performance *perf;
 
 	if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
@@ -223,10 +223,9 @@ static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
 
 	perf = data->acpi_data;
 
-	for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
-		if (msr == perf->states[data->freq_table[i].driver_data].status)
-			return data->freq_table[i].frequency;
-	}
+	cpufreq_for_each_entry(pos, data->freq_table)
+		if (msr == perf->states[pos->driver_data].status)
+			return pos->frequency;
 	return data->freq_table[0].frequency;
 }
 
diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c
index bad2ed3..1f4d4e3 100644
--- a/drivers/cpufreq/arm_big_little.c
+++ b/drivers/cpufreq/arm_big_little.c
@@ -226,22 +226,22 @@ static inline u32 get_table_count(struct cpufreq_frequency_table *table)
 /* get the minimum frequency in the cpufreq_frequency_table */
 static inline u32 get_table_min(struct cpufreq_frequency_table *table)
 {
-	int i;
+	struct cpufreq_frequency_table *pos;
 	uint32_t min_freq = ~0;
-	for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++)
-		if (table[i].frequency < min_freq)
-			min_freq = table[i].frequency;
+	cpufreq_for_each_entry(pos, table)
+		if (pos->frequency < min_freq)
+			min_freq = pos->frequency;
 	return min_freq;
 }
 
 /* get the maximum frequency in the cpufreq_frequency_table */
 static inline u32 get_table_max(struct cpufreq_frequency_table *table)
 {
-	int i;
+	struct cpufreq_frequency_table *pos;
 	uint32_t max_freq = 0;
-	for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++)
-		if (table[i].frequency > max_freq)
-			max_freq = table[i].frequency;
+	cpufreq_for_each_entry(pos, table)
+		if (pos->frequency > max_freq)
+			max_freq = pos->frequency;
 	return max_freq;
 }
 
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index ecaaebf..0cd9b4d 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -182,11 +182,11 @@ static void cpufreq_stats_free_table(unsigned int cpu)
 
 static int __cpufreq_stats_create_table(struct cpufreq_policy *policy)
 {
-	unsigned int i, j, count = 0, ret = 0;
+	unsigned int i, count = 0, ret = 0;
 	struct cpufreq_stats *stat;
 	unsigned int alloc_size;
 	unsigned int cpu = policy->cpu;
-	struct cpufreq_frequency_table *table;
+	struct cpufreq_frequency_table *pos, *table;
 
 	table = cpufreq_frequency_get_table(cpu);
 	if (unlikely(!table))
@@ -205,12 +205,8 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy)
 	stat->cpu = cpu;
 	per_cpu(cpufreq_stats_table, cpu) = stat;
 
-	for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
-		unsigned int freq = table[i].frequency;
-		if (freq == CPUFREQ_ENTRY_INVALID)
-			continue;
+	cpufreq_for_each_valid_entry(pos, table)
 		count++;
-	}
 
 	alloc_size = count * sizeof(int) + count * sizeof(u64);
 
@@ -228,15 +224,11 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy)
 #ifdef CONFIG_CPU_FREQ_STAT_DETAILS
 	stat->trans_table = stat->freq_table + count;
 #endif
-	j = 0;
-	for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
-		unsigned int freq = table[i].frequency;
-		if (freq == CPUFREQ_ENTRY_INVALID)
-			continue;
-		if (freq_table_get_index(stat, freq) == -1)
-			stat->freq_table[j++] = freq;
-	}
-	stat->state_num = j;
+	i = 0;
+	cpufreq_for_each_valid_entry(pos, table)
+		if (freq_table_get_index(stat, pos->frequency) == -1)
+			stat->freq_table[i++] = pos->frequency;
+	stat->state_num = i;
 	spin_lock(&cpufreq_stats_lock);
 	stat->last_time = get_jiffies_64();
 	stat->last_index = freq_table_get_index(stat, policy->cur);
diff --git a/drivers/cpufreq/dbx500-cpufreq.c b/drivers/cpufreq/dbx500-cpufreq.c
index 412a78b..4bebc1b 100644
--- a/drivers/cpufreq/dbx500-cpufreq.c
+++ b/drivers/cpufreq/dbx500-cpufreq.c
@@ -45,7 +45,7 @@ static struct cpufreq_driver dbx500_cpufreq_driver = {
 
 static int dbx500_cpufreq_probe(struct platform_device *pdev)
 {
-	int i = 0;
+	struct cpufreq_frequency_table *pos;
 
 	freq_table = dev_get_platdata(&pdev->dev);
 	if (!freq_table) {
@@ -60,10 +60,8 @@ static int dbx500_cpufreq_probe(struct platform_device *pdev)
 	}
 
 	pr_info("dbx500-cpufreq: Available frequencies:\n");
-	while (freq_table[i].frequency != CPUFREQ_TABLE_END) {
-		pr_info("  %d Mhz\n", freq_table[i].frequency/1000);
-		i++;
-	}
+	cpufreq_for_each_entry(pos, freq_table)
+		pr_info("  %d Mhz\n", pos->frequency / 1000);
 
 	return cpufreq_register_driver(&dbx500_cpufreq_driver);
 }
diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c
index 7f5d2a6..1c06e78 100644
--- a/drivers/cpufreq/elanfreq.c
+++ b/drivers/cpufreq/elanfreq.c
@@ -147,7 +147,7 @@ static int elanfreq_target(struct cpufreq_policy *policy,
 static int elanfreq_cpu_init(struct cpufreq_policy *policy)
 {
 	struct cpuinfo_x86 *c = &cpu_data(0);
-	unsigned int i;
+	struct cpufreq_frequency_table *pos;
 
 	/* capability check */
 	if ((c->x86_vendor != X86_VENDOR_AMD) ||
@@ -159,10 +159,9 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy)
 		max_freq = elanfreq_get_cpu_frequency(0);
 
 	/* table init */
-	for (i = 0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) {
-		if (elanfreq_table[i].frequency > max_freq)
-			elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
-	}
+	cpufreq_for_each_entry(pos, elanfreq_table)
+		if (pos->frequency > max_freq)
+			pos->frequency = CPUFREQ_ENTRY_INVALID;
 
 	/* cpuinfo and default policy values */
 	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
index f99cfe2..9c13255 100644
--- a/drivers/cpufreq/exynos-cpufreq.c
+++ b/drivers/cpufreq/exynos-cpufreq.c
@@ -29,17 +29,16 @@ static unsigned int locking_frequency;
 static int exynos_cpufreq_get_index(unsigned int freq)
 {
 	struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
-	int index;
+	struct cpufreq_frequency_table *pos;
 
-	for (index = 0;
-		freq_table[index].frequency != CPUFREQ_TABLE_END; index++)
-		if (freq_table[index].frequency == freq)
+	cpufreq_for_each_entry(pos, freq_table)
+		if (pos->frequency == freq)
 			break;
 
-	if (freq_table[index].frequency == CPUFREQ_TABLE_END)
+	if (pos->frequency == CPUFREQ_TABLE_END)
 		return -EINVAL;
 
-	return index;
+	return pos - freq_table;
 }
 
 static int exynos_cpufreq_scale(unsigned int target_freq)
diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c
index a6b8214..f33f25b 100644
--- a/drivers/cpufreq/exynos5440-cpufreq.c
+++ b/drivers/cpufreq/exynos5440-cpufreq.c
@@ -114,25 +114,23 @@ static struct cpufreq_freqs freqs;
 
 static int init_div_table(void)
 {
-	struct cpufreq_frequency_table *freq_tbl = dvfs_info->freq_table;
+	struct cpufreq_frequency_table *pos, *freq_tbl = dvfs_info->freq_table;
 	unsigned int tmp, clk_div, ema_div, freq, volt_id;
-	int i = 0;
 	struct dev_pm_opp *opp;
 
 	rcu_read_lock();
-	for (i = 0; freq_tbl[i].frequency != CPUFREQ_TABLE_END; i++) {
-
+	cpufreq_for_each_entry(pos, freq_tbl) {
 		opp = dev_pm_opp_find_freq_exact(dvfs_info->dev,
-					freq_tbl[i].frequency * 1000, true);
+					pos->frequency * 1000, true);
 		if (IS_ERR(opp)) {
 			rcu_read_unlock();
 			dev_err(dvfs_info->dev,
 				"failed to find valid OPP for %u KHZ\n",
-				freq_tbl[i].frequency);
+				pos->frequency);
 			return PTR_ERR(opp);
 		}
 
-		freq = freq_tbl[i].frequency / 1000; /* In MHZ */
+		freq = pos->frequency / 1000; /* In MHZ */
 		clk_div = ((freq / CPU_DIV_FREQ_MAX) & P0_7_CPUCLKDEV_MASK)
 					<< P0_7_CPUCLKDEV_SHIFT;
 		clk_div |= ((freq / CPU_ATB_FREQ_MAX) & P0_7_ATBCLKDEV_MASK)
@@ -157,7 +155,8 @@ static int init_div_table(void)
 		tmp = (clk_div | ema_div | (volt_id << P0_7_VDD_SHIFT)
 			| ((freq / FREQ_UNIT) << P0_7_FREQ_SHIFT));
 
-		__raw_writel(tmp, dvfs_info->base + XMU_PMU_P0_7 + 4 * i);
+		__raw_writel(tmp, dvfs_info->base + XMU_PMU_P0_7 + 4 *
+						(pos - freq_tbl));
 	}
 
 	rcu_read_unlock();
@@ -166,8 +165,9 @@ static int init_div_table(void)
 
 static void exynos_enable_dvfs(unsigned int cur_frequency)
 {
-	unsigned int tmp, i, cpu;
+	unsigned int tmp, cpu;
 	struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table;
+	struct cpufreq_frequency_table *pos;
 	/* Disable DVFS */
 	__raw_writel(0,	dvfs_info->base + XMU_DVFS_CTRL);
 
@@ -182,15 +182,15 @@ static void exynos_enable_dvfs(unsigned int cur_frequency)
 	 __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQEN);
 
 	/* Set initial performance index */
-	for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++)
-		if (freq_table[i].frequency == cur_frequency)
+	cpufreq_for_each_entry(pos, freq_table)
+		if (pos->frequency == cur_frequency)
 			break;
 
-	if (freq_table[i].frequency == CPUFREQ_TABLE_END) {
+	if (pos->frequency == CPUFREQ_TABLE_END) {
 		dev_crit(dvfs_info->dev, "Boot up frequency not supported\n");
 		/* Assign the highest frequency */
-		i = 0;
-		cur_frequency = freq_table[i].frequency;
+		pos = freq_table;
+		cur_frequency = pos->frequency;
 	}
 
 	dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ",
@@ -199,7 +199,7 @@ static void exynos_enable_dvfs(unsigned int cur_frequency)
 	for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) {
 		tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4);
 		tmp &= ~(P_VALUE_MASK << C0_3_PSTATE_NEW_SHIFT);
-		tmp |= (i << C0_3_PSTATE_NEW_SHIFT);
+		tmp |= ((pos - freq_table) << C0_3_PSTATE_NEW_SHIFT);
 		__raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4);
 	}
 
diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
index 08e7bbc..8e518c6 100644
--- a/drivers/cpufreq/freq_table.c
+++ b/drivers/cpufreq/freq_table.c
@@ -21,22 +21,19 @@
 int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
 				    struct cpufreq_frequency_table *table)
 {
+	struct cpufreq_frequency_table *pos;
 	unsigned int min_freq = ~0;
 	unsigned int max_freq = 0;
-	unsigned int i;
+	unsigned int freq;
 
-	for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
-		unsigned int freq = table[i].frequency;
-		if (freq == CPUFREQ_ENTRY_INVALID) {
-			pr_debug("table entry %u is invalid, skipping\n", i);
+	cpufreq_for_each_valid_entry(pos, table) {
+		freq = pos->frequency;
 
-			continue;
-		}
 		if (!cpufreq_boost_enabled()
-		    && (table[i].flags & CPUFREQ_BOOST_FREQ))
+		    && (pos->flags & CPUFREQ_BOOST_FREQ))
 			continue;
 
-		pr_debug("table entry %u: %u kHz\n", i, freq);
+		pr_debug("table entry %u: %u kHz\n", (int)(pos - table), freq);
 		if (freq < min_freq)
 			min_freq = freq;
 		if (freq > max_freq)
@@ -57,7 +54,8 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_cpuinfo);
 int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
 				   struct cpufreq_frequency_table *table)
 {
-	unsigned int next_larger = ~0, freq, i = 0;
+	struct cpufreq_frequency_table *pos;
+	unsigned int freq, next_larger = ~0;
 	bool found = false;
 
 	pr_debug("request for verification of policy (%u - %u kHz) for cpu %u\n",
@@ -65,9 +63,9 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
 
 	cpufreq_verify_within_cpu_limits(policy);
 
-	for (; freq = table[i].frequency, freq != CPUFREQ_TABLE_END; i++) {
-		if (freq == CPUFREQ_ENTRY_INVALID)
-			continue;
+	cpufreq_for_each_valid_entry(pos, table) {
+		freq = pos->frequency;
+
 		if ((freq >= policy->min) && (freq <= policy->max)) {
 			found = true;
 			break;
@@ -118,7 +116,8 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
 		.driver_data = ~0,
 		.frequency = 0,
 	};
-	unsigned int i;
+	struct cpufreq_frequency_table *pos;
+	unsigned int freq, i = 0;
 
 	pr_debug("request for target %u kHz (relation: %u) for cpu %u\n",
 					target_freq, relation, policy->cpu);
@@ -132,10 +131,10 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
 		break;
 	}
 
-	for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
-		unsigned int freq = table[i].frequency;
-		if (freq == CPUFREQ_ENTRY_INVALID)
-			continue;
+	cpufreq_for_each_valid_entry(pos, table) {
+		freq = pos->frequency;
+
+		i = pos - table;
 		if ((freq < policy->min) || (freq > policy->max))
 			continue;
 		switch (relation) {
@@ -184,8 +183,7 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
 int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy,
 		unsigned int freq)
 {
-	struct cpufreq_frequency_table *table;
-	int i;
+	struct cpufreq_frequency_table *pos, *table;
 
 	table = cpufreq_frequency_get_table(policy->cpu);
 	if (unlikely(!table)) {
@@ -193,10 +191,9 @@ int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy,
 		return -ENOENT;
 	}
 
-	for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
-		if (table[i].frequency == freq)
-			return i;
-	}
+	cpufreq_for_each_valid_entry(pos, table)
+		if (pos->frequency == freq)
+			return pos - table;
 
 	return -EINVAL;
 }
@@ -208,16 +205,13 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_index);
 static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf,
 				    bool show_boost)
 {
-	unsigned int i = 0;
 	ssize_t count = 0;
-	struct cpufreq_frequency_table *table = policy->freq_table;
+	struct cpufreq_frequency_table *pos, *table = policy->freq_table;
 
 	if (!table)
 		return -ENODEV;
 
-	for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
-		if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
-			continue;
+	cpufreq_for_each_valid_entry(pos, table) {
 		/*
 		 * show_boost = true and driver_data = BOOST freq
 		 * display BOOST freqs
@@ -229,10 +223,10 @@ static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf,
 		 * show_boost = false and driver_data != BOOST freq
 		 * display NON BOOST freqs
 		 */
-		if (show_boost ^ (table[i].flags & CPUFREQ_BOOST_FREQ))
+		if (show_boost ^ (pos->flags & CPUFREQ_BOOST_FREQ))
 			continue;
 
-		count += sprintf(&buf[count], "%d ", table[i].frequency);
+		count += sprintf(&buf[count], "%d ", pos->frequency);
 	}
 	count += sprintf(&buf[count], "\n");
 
diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c
index d00e5d1..f4024d4 100644
--- a/drivers/cpufreq/longhaul.c
+++ b/drivers/cpufreq/longhaul.c
@@ -528,6 +528,7 @@ static int longhaul_get_ranges(void)
 
 static void longhaul_setup_voltagescaling(void)
 {
+	struct cpufreq_frequency_table *freq_pos;
 	union msr_longhaul longhaul;
 	struct mV_pos minvid, maxvid, vid;
 	unsigned int j, speed, pos, kHz_step, numvscales;
@@ -606,18 +607,16 @@ static void longhaul_setup_voltagescaling(void)
 	/* Calculate kHz for one voltage step */
 	kHz_step = (highest_speed - min_vid_speed) / numvscales;
 
-	j = 0;
-	while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) {
-		speed = longhaul_table[j].frequency;
+	cpufreq_for_each_entry(freq_pos, longhaul_table) {
+		speed = freq_pos->frequency;
 		if (speed > min_vid_speed)
 			pos = (speed - min_vid_speed) / kHz_step + minvid.pos;
 		else
 			pos = minvid.pos;
-		longhaul_table[j].driver_data |= mV_vrm_table[pos] << 8;
+		freq_pos->driver_data |= mV_vrm_table[pos] << 8;
 		vid = vrm_mV_table[mV_vrm_table[pos]];
 		printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n",
-				speed, j, vid.mV);
-		j++;
+			speed, (int)(freq_pos - longhaul_table), vid.mV);
 	}
 
 	can_scale_voltage = 1;
diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c
index 84c84b5..35dd4d7 100644
--- a/drivers/cpufreq/pasemi-cpufreq.c
+++ b/drivers/cpufreq/pasemi-cpufreq.c
@@ -136,9 +136,10 @@ void restore_astate(int cpu)
 
 static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
 {
+	struct cpufreq_frequency_table *pos;
 	const u32 *max_freqp;
 	u32 max_freq;
-	int i, cur_astate;
+	int cur_astate;
 	struct resource res;
 	struct device_node *cpu, *dn;
 	int err = -ENODEV;
@@ -197,10 +198,9 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	pr_debug("initializing frequency table\n");
 
 	/* initialize frequency table */
-	for (i=0; pas_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) {
-		pas_freqs[i].frequency =
-			get_astate_freq(pas_freqs[i].driver_data) * 100000;
-		pr_debug("%d: %d\n", i, pas_freqs[i].frequency);
+	cpufreq_for_each_entry(pos, pas_freqs) {
+		pos->frequency = get_astate_freq(pos->driver_data) * 100000;
+		pr_debug("%d: %d\n", (int)(pos - pas_freqs), pos->frequency);
 	}
 
 	cur_astate = get_cur_astate(policy->cpu);
diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c
index 49f120e..a133236 100644
--- a/drivers/cpufreq/powernow-k6.c
+++ b/drivers/cpufreq/powernow-k6.c
@@ -159,6 +159,7 @@ static int powernow_k6_target(struct cpufreq_policy *policy,
 
 static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
 {
+	struct cpufreq_frequency_table *pos;
 	unsigned int i, f;
 	unsigned khz;
 
@@ -176,12 +177,11 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
 		}
 	}
 	if (param_max_multiplier) {
-		for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
-			if (clock_ratio[i].driver_data == param_max_multiplier) {
+		cpufreq_for_each_entry(pos, clock_ratio)
+			if (pos->driver_data == param_max_multiplier) {
 				max_multiplier = param_max_multiplier;
 				goto have_max_multiplier;
 			}
-		}
 		printk(KERN_ERR "powernow-k6: invalid max_multiplier parameter, valid parameters 20, 30, 35, 40, 45, 50, 55, 60\n");
 		return -EINVAL;
 	}
@@ -209,12 +209,12 @@ have_busfreq:
 	param_busfreq = busfreq * 10;
 
 	/* table init */
-	for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
-		f = clock_ratio[i].driver_data;
+	cpufreq_for_each_entry(pos, clock_ratio) {
+		f = pos->driver_data;
 		if (f > max_multiplier)
-			clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID;
+			pos->frequency = CPUFREQ_ENTRY_INVALID;
 		else
-			clock_ratio[i].frequency = busfreq * f;
+			pos->frequency = busfreq * f;
 	}
 
 	/* cpuinfo and default policy values */
diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c
index 5be8a48..5a4c5a6 100644
--- a/drivers/cpufreq/ppc_cbe_cpufreq.c
+++ b/drivers/cpufreq/ppc_cbe_cpufreq.c
@@ -67,9 +67,10 @@ static int set_pmode(unsigned int cpu, unsigned int slow_mode)
 
 static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
 {
+	struct cpufreq_frequency_table *pos;
 	const u32 *max_freqp;
 	u32 max_freq;
-	int i, cur_pmode;
+	int cur_pmode;
 	struct device_node *cpu;
 
 	cpu = of_get_cpu_node(policy->cpu, NULL);
@@ -102,9 +103,9 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	pr_debug("initializing frequency table\n");
 
 	/* initialize frequency table */
-	for (i=0; cbe_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) {
-		cbe_freqs[i].frequency = max_freq / cbe_freqs[i].driver_data;
-		pr_debug("%d: %d\n", i, cbe_freqs[i].frequency);
+	cpufreq_for_each_entry(pos, cbe_freqs) {
+		pos->frequency = max_freq / pos->driver_data;
+		pr_debug("%d: %d\n", (int)(pos - cbe_freqs), pos->frequency);
 	}
 
 	/* if DEBUG is enabled set_pmode() measures the latency
diff --git a/drivers/cpufreq/s3c2416-cpufreq.c b/drivers/cpufreq/s3c2416-cpufreq.c
index 4626f90..2fd53ea 100644
--- a/drivers/cpufreq/s3c2416-cpufreq.c
+++ b/drivers/cpufreq/s3c2416-cpufreq.c
@@ -266,7 +266,7 @@ out:
 static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq)
 {
 	int count, v, i, found;
-	struct cpufreq_frequency_table *freq;
+	struct cpufreq_frequency_table *pos;
 	struct s3c2416_dvfs *dvfs;
 
 	count = regulator_count_voltages(s3c_freq->vddarm);
@@ -275,12 +275,11 @@ static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq)
 		return;
 	}
 
-	freq = s3c_freq->freq_table;
-	while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) {
-		if (freq->frequency == CPUFREQ_ENTRY_INVALID)
-			continue;
+	if (!count)
+		goto out;
 
-		dvfs = &s3c2416_dvfs_table[freq->driver_data];
+	cpufreq_for_each_valid_entry(pos, s3c_freq->freq_table) {
+		dvfs = &s3c2416_dvfs_table[pos->driver_data];
 		found = 0;
 
 		/* Check only the min-voltage, more is always ok on S3C2416 */
@@ -292,13 +291,12 @@ static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq)
 
 		if (!found) {
 			pr_debug("cpufreq: %dkHz unsupported by regulator\n",
-				 freq->frequency);
-			freq->frequency = CPUFREQ_ENTRY_INVALID;
+				 pos->frequency);
+			pos->frequency = CPUFREQ_ENTRY_INVALID;
 		}
-
-		freq++;
 	}
 
+out:
 	/* Guessed */
 	s3c_freq->regulator_latency = 1 * 1000 * 1000;
 }
@@ -338,7 +336,7 @@ static struct notifier_block s3c2416_cpufreq_reboot_notifier = {
 static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy)
 {
 	struct s3c2416_data *s3c_freq = &s3c2416_cpufreq;
-	struct cpufreq_frequency_table *freq;
+	struct cpufreq_frequency_table *pos;
 	struct clk *msysclk;
 	unsigned long rate;
 	int ret;
@@ -427,31 +425,27 @@ static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy)
 	s3c_freq->regulator_latency = 0;
 #endif
 
-	freq = s3c_freq->freq_table;
-	while (freq->frequency != CPUFREQ_TABLE_END) {
+	cpufreq_for_each_entry(pos, s3c_freq->freq_table) {
 		/* special handling for dvs mode */
-		if (freq->driver_data == 0) {
+		if (pos->driver_data == 0) {
 			if (!s3c_freq->hclk) {
 				pr_debug("cpufreq: %dkHz unsupported as it would need unavailable dvs mode\n",
-					 freq->frequency);
-				freq->frequency = CPUFREQ_ENTRY_INVALID;
+					 pos->frequency);
+				pos->frequency = CPUFREQ_ENTRY_INVALID;
 			} else {
-				freq++;
 				continue;
 			}
 		}
 
 		/* Check for frequencies we can generate */
 		rate = clk_round_rate(s3c_freq->armdiv,
-				      freq->frequency * 1000);
+				      pos->frequency * 1000);
 		rate /= 1000;
-		if (rate != freq->frequency) {
+		if (rate != pos->frequency) {
 			pr_debug("cpufreq: %dkHz unsupported by clock (clk_round_rate return %lu)\n",
-				 freq->frequency, rate);
-			freq->frequency = CPUFREQ_ENTRY_INVALID;
+				pos->frequency, rate);
+			pos->frequency = CPUFREQ_ENTRY_INVALID;
 		}
-
-		freq++;
 	}
 
 	/* Datasheet says PLL stabalisation time must be at least 300us,
diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c
index ff7d3ec..176e84c 100644
--- a/drivers/cpufreq/s3c64xx-cpufreq.c
+++ b/drivers/cpufreq/s3c64xx-cpufreq.c
@@ -118,11 +118,10 @@ static void __init s3c64xx_cpufreq_config_regulator(void)
 		pr_err("Unable to check supported voltages\n");
 	}
 
-	freq = s3c64xx_freq_table;
-	while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) {
-		if (freq->frequency == CPUFREQ_ENTRY_INVALID)
-			continue;
+	if (!count)
+		goto out;
 
+	cpufreq_for_each_valid_entry(freq, s3c64xx_freq_table) {
 		dvfs = &s3c64xx_dvfs_table[freq->driver_data];
 		found = 0;
 
@@ -137,10 +136,9 @@ static void __init s3c64xx_cpufreq_config_regulator(void)
 				 freq->frequency);
 			freq->frequency = CPUFREQ_ENTRY_INVALID;
 		}
-
-		freq++;
 	}
 
+out:
 	/* Guess based on having to do an I2C/SPI write; in future we
 	 * will be able to query the regulator performance here. */
 	regulator_latency = 1 * 1000 * 1000;
@@ -179,8 +177,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
 	}
 #endif
 
-	freq = s3c64xx_freq_table;
-	while (freq->frequency != CPUFREQ_TABLE_END) {
+	cpufreq_for_each_entry(freq, s3c64xx_freq_table) {
 		unsigned long r;
 
 		/* Check for frequencies we can generate */
@@ -196,8 +193,6 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
 		 * frequency is the maximum we can support. */
 		if (!vddarm && freq->frequency > clk_get_rate(policy->clk) / 1000)
 			freq->frequency = CPUFREQ_ENTRY_INVALID;
-
-		freq++;
 	}
 
 	/* Datasheet says PLL stabalisation time (if we were to use
-- 
1.9.0

^ permalink raw reply related

* Re: [PATCH v2 1/2] powerpc/pm: add api to get suspend state which is STANDBY or MEM
From: Scott Wood @ 2014-04-25 21:45 UTC (permalink / raw)
  To: Dongsheng Wang; +Cc: linuxppc-dev, chenhui.zhao, jason.jin
In-Reply-To: <1398319908-30166-1-git-send-email-dongsheng.wang@freescale.com>

On Thu, 2014-04-24 at 14:11 +0800, Dongsheng Wang wrote:
> From: Wang Dongsheng <dongsheng.wang@freescale.com>
> 
> Add set_pm_suspend_state & pm_suspend_state functions to set/get
> suspend state. When system going to sleep or deep sleep, devices
> can get the system suspend state(STANDBY/MEM) through pm_suspend_state
> function and to handle different situations.
> 
> Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
> ---
> *v2*
> Move pm api from fsl platform to powerpc general framework.

What is powerpc-specific about this?

-Scott

^ permalink raw reply

* Re: [PATCH 2/3] powerpc, ptrace: Add new ptrace request macros for transactional memory
From: Pedro Alves @ 2014-04-25 23:42 UTC (permalink / raw)
  To: Anshuman Khandual; +Cc: mikey, avagin, oleg, linux-kernel, linuxppc-dev
In-Reply-To: <1396422144-11032-3-git-send-email-khandual@linux.vnet.ibm.com>

On 04/02/2014 08:02 AM, Anshuman Khandual wrote:
> This patch adds following new sets of ptrace request macros for transactional
> memory expanding the existing ptrace ABI on PowerPC.
> 
> 	/* TM special purpose registers */
> 	PTRACE_GETTM_SPRREGS
> 	PTRACE_SETTM_SPRREGS
> 
> 	/* TM checkpointed GPR registers */
> 	PTRACE_GETTM_CGPRREGS
> 	PTRACE_SETTM_CGPRREGS
> 
> 	/* TM checkpointed FPR registers */
> 	PTRACE_GETTM_CFPRREGS
> 	PTRACE_SETTM_CFPRREGS
> 
> 	/* TM checkpointed VMX registers */
> 	PTRACE_GETTM_CVMXREGS
> 	PTRACE_SETTM_CVMXREGS

Urgh, we're _still_ adding specialized register specific calls?
Why aren't these exported as new register sets, accessible through
PTRACE_GETREGSET /  PTRACE_SETREGSET?  That's supposed to be the
Modern Way to do things.

-- 
Pedro Alves

^ permalink raw reply

* Re: [PATCH 00/13] Refactor pci_is_brdige() to simplify code
From: Yijing Wang @ 2014-04-26  2:49 UTC (permalink / raw)
  To: David Laight, Bjorn Helgaas
  Cc: Tony Luck, linux-ia64@vger.kernel.org, x86@kernel.org,
	linux-kernel@vger.kernel.org, sparclinux@vger.kernel.org,
	Thomas Gleixner, linuxppc-dev@lists.ozlabs.org, David S. Miller
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6D0F6FEEB0@AcuExch.aculab.com>

On 2014/4/25 17:42, David Laight wrote:
> From: Yijing Wang
>> This patchset rename the current pci_is_bridge() to pci_has_subordinate(),
>> and introduce a new pci_is_bridge() which determine pci bridge by check
>> dev->hdr_type. The new one is more accurate. PCIe Spec define the pci
>> device is a bridge by the dev->hdr_type = 0x01 || 0x02.
> 
> That is a dangerous rename and is likely to cause difficult to

Hi David,
   I renamed pci_is_bridge() to pci_has_subordinate() because

static inline bool pci_is_bridge(struct pci_dev *pci_dev)
{
	return !!(pci_dev->subordinate);
}

which always check dev->subordinate.

> identify bugs in any code you've missed.

What are you referring to ?


Thanks!
Yijing.






> 
> 	David
> 
> \x04�{.n�+�������+%��lzwm��b�맲��r��zX��\x19\x1e�w��{ay�\x1dʇڙ�,j\a��f���h���z�\x1e�w���\f���j:+v���w�j�m����\a����zZ+�����ݢj"��!�iO��z��v�^\x14\x04\x1a�^[m����\vnƊ��Y&�
> 


-- 
Thanks!
Yijing

^ permalink raw reply

* Re: [PATCH v5 2/8] cpufreq: Use cpufreq_for_each_* macros for frequency table iteration
From: Prabhakar Lad @ 2014-04-26  9:57 UTC (permalink / raw)
  To: Stratos Karafotis
  Cc: Kukjin Kim, linux-pm, Viresh Kumar, Rafael J. Wysocki, LKML,
	cpufreq@vger.kernel.org, linux-samsung-soc, Sudeep Holla,
	Olof Johansson, linuxppc-dev,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <535AC26A.1000006@semaphore.gr>

Hi Stratos,

Thanks for the patch,

On Sat, Apr 26, 2014 at 1:45 AM, Stratos Karafotis
<stratosk@semaphore.gr> wrote:
> The cpufreq core now supports the cpufreq_for_each_entry and
> cpufreq_for_each_valid_entry macros helpers for iteration over the
> cpufreq_frequency_table, so use them.
>
> It should have no functional changes.
>
> Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>

For patches 1 & 2:  Acked-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>

and for patch 3: Acked-and-tested-by: Lad, Prabhakar
<prabhakar.csengg@gmail.com>

Thanks,
--Prabhakar lad

> ---
>  drivers/cpufreq/acpi-cpufreq.c       |  9 +++---
>  drivers/cpufreq/arm_big_little.c     | 16 +++++------
>  drivers/cpufreq/cpufreq_stats.c      | 24 ++++++----------
>  drivers/cpufreq/dbx500-cpufreq.c     |  8 ++----
>  drivers/cpufreq/elanfreq.c           |  9 +++---
>  drivers/cpufreq/exynos-cpufreq.c     | 11 ++++---
>  drivers/cpufreq/exynos5440-cpufreq.c | 30 +++++++++----------
>  drivers/cpufreq/freq_table.c         | 56 ++++++++++++++++--------------------
>  drivers/cpufreq/longhaul.c           | 11 ++++---
>  drivers/cpufreq/pasemi-cpufreq.c     | 10 +++----
>  drivers/cpufreq/powernow-k6.c        | 14 ++++-----
>  drivers/cpufreq/ppc_cbe_cpufreq.c    |  9 +++---
>  drivers/cpufreq/s3c2416-cpufreq.c    | 40 +++++++++++---------------
>  drivers/cpufreq/s3c64xx-cpufreq.c    | 15 ++++------
>  14 files changed, 116 insertions(+), 146 deletions(-)
>
> diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c
> index 000e4e0..b0c18ed 100644
> --- a/drivers/cpufreq/acpi-cpufreq.c
> +++ b/drivers/cpufreq/acpi-cpufreq.c
> @@ -213,7 +213,7 @@ static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data)
>
>  static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
>  {
> -       int i;
> +       struct cpufreq_frequency_table *pos;
>         struct acpi_processor_performance *perf;
>
>         if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)
> @@ -223,10 +223,9 @@ static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
>
>         perf = data->acpi_data;
>
> -       for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
> -               if (msr == perf->states[data->freq_table[i].driver_data].status)
> -                       return data->freq_table[i].frequency;
> -       }
> +       cpufreq_for_each_entry(pos, data->freq_table)
> +               if (msr == perf->states[pos->driver_data].status)
> +                       return pos->frequency;
>         return data->freq_table[0].frequency;
>  }
>
> diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c
> index bad2ed3..1f4d4e3 100644
> --- a/drivers/cpufreq/arm_big_little.c
> +++ b/drivers/cpufreq/arm_big_little.c
> @@ -226,22 +226,22 @@ static inline u32 get_table_count(struct cpufreq_frequency_table *table)
>  /* get the minimum frequency in the cpufreq_frequency_table */
>  static inline u32 get_table_min(struct cpufreq_frequency_table *table)
>  {
> -       int i;
> +       struct cpufreq_frequency_table *pos;
>         uint32_t min_freq = ~0;
> -       for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++)
> -               if (table[i].frequency < min_freq)
> -                       min_freq = table[i].frequency;
> +       cpufreq_for_each_entry(pos, table)
> +               if (pos->frequency < min_freq)
> +                       min_freq = pos->frequency;
>         return min_freq;
>  }
>
>  /* get the maximum frequency in the cpufreq_frequency_table */
>  static inline u32 get_table_max(struct cpufreq_frequency_table *table)
>  {
> -       int i;
> +       struct cpufreq_frequency_table *pos;
>         uint32_t max_freq = 0;
> -       for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++)
> -               if (table[i].frequency > max_freq)
> -                       max_freq = table[i].frequency;
> +       cpufreq_for_each_entry(pos, table)
> +               if (pos->frequency > max_freq)
> +                       max_freq = pos->frequency;
>         return max_freq;
>  }
>
> diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
> index ecaaebf..0cd9b4d 100644
> --- a/drivers/cpufreq/cpufreq_stats.c
> +++ b/drivers/cpufreq/cpufreq_stats.c
> @@ -182,11 +182,11 @@ static void cpufreq_stats_free_table(unsigned int cpu)
>
>  static int __cpufreq_stats_create_table(struct cpufreq_policy *policy)
>  {
> -       unsigned int i, j, count = 0, ret = 0;
> +       unsigned int i, count = 0, ret = 0;
>         struct cpufreq_stats *stat;
>         unsigned int alloc_size;
>         unsigned int cpu = policy->cpu;
> -       struct cpufreq_frequency_table *table;
> +       struct cpufreq_frequency_table *pos, *table;
>
>         table = cpufreq_frequency_get_table(cpu);
>         if (unlikely(!table))
> @@ -205,12 +205,8 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy)
>         stat->cpu = cpu;
>         per_cpu(cpufreq_stats_table, cpu) = stat;
>
> -       for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
> -               unsigned int freq = table[i].frequency;
> -               if (freq == CPUFREQ_ENTRY_INVALID)
> -                       continue;
> +       cpufreq_for_each_valid_entry(pos, table)
>                 count++;
> -       }
>
>         alloc_size = count * sizeof(int) + count * sizeof(u64);
>
> @@ -228,15 +224,11 @@ static int __cpufreq_stats_create_table(struct cpufreq_policy *policy)
>  #ifdef CONFIG_CPU_FREQ_STAT_DETAILS
>         stat->trans_table = stat->freq_table + count;
>  #endif
> -       j = 0;
> -       for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
> -               unsigned int freq = table[i].frequency;
> -               if (freq == CPUFREQ_ENTRY_INVALID)
> -                       continue;
> -               if (freq_table_get_index(stat, freq) == -1)
> -                       stat->freq_table[j++] = freq;
> -       }
> -       stat->state_num = j;
> +       i = 0;
> +       cpufreq_for_each_valid_entry(pos, table)
> +               if (freq_table_get_index(stat, pos->frequency) == -1)
> +                       stat->freq_table[i++] = pos->frequency;
> +       stat->state_num = i;
>         spin_lock(&cpufreq_stats_lock);
>         stat->last_time = get_jiffies_64();
>         stat->last_index = freq_table_get_index(stat, policy->cur);
> diff --git a/drivers/cpufreq/dbx500-cpufreq.c b/drivers/cpufreq/dbx500-cpufreq.c
> index 412a78b..4bebc1b 100644
> --- a/drivers/cpufreq/dbx500-cpufreq.c
> +++ b/drivers/cpufreq/dbx500-cpufreq.c
> @@ -45,7 +45,7 @@ static struct cpufreq_driver dbx500_cpufreq_driver = {
>
>  static int dbx500_cpufreq_probe(struct platform_device *pdev)
>  {
> -       int i = 0;
> +       struct cpufreq_frequency_table *pos;
>
>         freq_table = dev_get_platdata(&pdev->dev);
>         if (!freq_table) {
> @@ -60,10 +60,8 @@ static int dbx500_cpufreq_probe(struct platform_device *pdev)
>         }
>
>         pr_info("dbx500-cpufreq: Available frequencies:\n");
> -       while (freq_table[i].frequency != CPUFREQ_TABLE_END) {
> -               pr_info("  %d Mhz\n", freq_table[i].frequency/1000);
> -               i++;
> -       }
> +       cpufreq_for_each_entry(pos, freq_table)
> +               pr_info("  %d Mhz\n", pos->frequency / 1000);
>
>         return cpufreq_register_driver(&dbx500_cpufreq_driver);
>  }
> diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c
> index 7f5d2a6..1c06e78 100644
> --- a/drivers/cpufreq/elanfreq.c
> +++ b/drivers/cpufreq/elanfreq.c
> @@ -147,7 +147,7 @@ static int elanfreq_target(struct cpufreq_policy *policy,
>  static int elanfreq_cpu_init(struct cpufreq_policy *policy)
>  {
>         struct cpuinfo_x86 *c = &cpu_data(0);
> -       unsigned int i;
> +       struct cpufreq_frequency_table *pos;
>
>         /* capability check */
>         if ((c->x86_vendor != X86_VENDOR_AMD) ||
> @@ -159,10 +159,9 @@ static int elanfreq_cpu_init(struct cpufreq_policy *policy)
>                 max_freq = elanfreq_get_cpu_frequency(0);
>
>         /* table init */
> -       for (i = 0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) {
> -               if (elanfreq_table[i].frequency > max_freq)
> -                       elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
> -       }
> +       cpufreq_for_each_entry(pos, elanfreq_table)
> +               if (pos->frequency > max_freq)
> +                       pos->frequency = CPUFREQ_ENTRY_INVALID;
>
>         /* cpuinfo and default policy values */
>         policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
> diff --git a/drivers/cpufreq/exynos-cpufreq.c b/drivers/cpufreq/exynos-cpufreq.c
> index f99cfe2..9c13255 100644
> --- a/drivers/cpufreq/exynos-cpufreq.c
> +++ b/drivers/cpufreq/exynos-cpufreq.c
> @@ -29,17 +29,16 @@ static unsigned int locking_frequency;
>  static int exynos_cpufreq_get_index(unsigned int freq)
>  {
>         struct cpufreq_frequency_table *freq_table = exynos_info->freq_table;
> -       int index;
> +       struct cpufreq_frequency_table *pos;
>
> -       for (index = 0;
> -               freq_table[index].frequency != CPUFREQ_TABLE_END; index++)
> -               if (freq_table[index].frequency == freq)
> +       cpufreq_for_each_entry(pos, freq_table)
> +               if (pos->frequency == freq)
>                         break;
>
> -       if (freq_table[index].frequency == CPUFREQ_TABLE_END)
> +       if (pos->frequency == CPUFREQ_TABLE_END)
>                 return -EINVAL;
>
> -       return index;
> +       return pos - freq_table;
>  }
>
>  static int exynos_cpufreq_scale(unsigned int target_freq)
> diff --git a/drivers/cpufreq/exynos5440-cpufreq.c b/drivers/cpufreq/exynos5440-cpufreq.c
> index a6b8214..f33f25b 100644
> --- a/drivers/cpufreq/exynos5440-cpufreq.c
> +++ b/drivers/cpufreq/exynos5440-cpufreq.c
> @@ -114,25 +114,23 @@ static struct cpufreq_freqs freqs;
>
>  static int init_div_table(void)
>  {
> -       struct cpufreq_frequency_table *freq_tbl = dvfs_info->freq_table;
> +       struct cpufreq_frequency_table *pos, *freq_tbl = dvfs_info->freq_table;
>         unsigned int tmp, clk_div, ema_div, freq, volt_id;
> -       int i = 0;
>         struct dev_pm_opp *opp;
>
>         rcu_read_lock();
> -       for (i = 0; freq_tbl[i].frequency != CPUFREQ_TABLE_END; i++) {
> -
> +       cpufreq_for_each_entry(pos, freq_tbl) {
>                 opp = dev_pm_opp_find_freq_exact(dvfs_info->dev,
> -                                       freq_tbl[i].frequency * 1000, true);
> +                                       pos->frequency * 1000, true);
>                 if (IS_ERR(opp)) {
>                         rcu_read_unlock();
>                         dev_err(dvfs_info->dev,
>                                 "failed to find valid OPP for %u KHZ\n",
> -                               freq_tbl[i].frequency);
> +                               pos->frequency);
>                         return PTR_ERR(opp);
>                 }
>
> -               freq = freq_tbl[i].frequency / 1000; /* In MHZ */
> +               freq = pos->frequency / 1000; /* In MHZ */
>                 clk_div = ((freq / CPU_DIV_FREQ_MAX) & P0_7_CPUCLKDEV_MASK)
>                                         << P0_7_CPUCLKDEV_SHIFT;
>                 clk_div |= ((freq / CPU_ATB_FREQ_MAX) & P0_7_ATBCLKDEV_MASK)
> @@ -157,7 +155,8 @@ static int init_div_table(void)
>                 tmp = (clk_div | ema_div | (volt_id << P0_7_VDD_SHIFT)
>                         | ((freq / FREQ_UNIT) << P0_7_FREQ_SHIFT));
>
> -               __raw_writel(tmp, dvfs_info->base + XMU_PMU_P0_7 + 4 * i);
> +               __raw_writel(tmp, dvfs_info->base + XMU_PMU_P0_7 + 4 *
> +                                               (pos - freq_tbl));
>         }
>
>         rcu_read_unlock();
> @@ -166,8 +165,9 @@ static int init_div_table(void)
>
>  static void exynos_enable_dvfs(unsigned int cur_frequency)
>  {
> -       unsigned int tmp, i, cpu;
> +       unsigned int tmp, cpu;
>         struct cpufreq_frequency_table *freq_table = dvfs_info->freq_table;
> +       struct cpufreq_frequency_table *pos;
>         /* Disable DVFS */
>         __raw_writel(0, dvfs_info->base + XMU_DVFS_CTRL);
>
> @@ -182,15 +182,15 @@ static void exynos_enable_dvfs(unsigned int cur_frequency)
>          __raw_writel(tmp, dvfs_info->base + XMU_PMUIRQEN);
>
>         /* Set initial performance index */
> -       for (i = 0; freq_table[i].frequency != CPUFREQ_TABLE_END; i++)
> -               if (freq_table[i].frequency == cur_frequency)
> +       cpufreq_for_each_entry(pos, freq_table)
> +               if (pos->frequency == cur_frequency)
>                         break;
>
> -       if (freq_table[i].frequency == CPUFREQ_TABLE_END) {
> +       if (pos->frequency == CPUFREQ_TABLE_END) {
>                 dev_crit(dvfs_info->dev, "Boot up frequency not supported\n");
>                 /* Assign the highest frequency */
> -               i = 0;
> -               cur_frequency = freq_table[i].frequency;
> +               pos = freq_table;
> +               cur_frequency = pos->frequency;
>         }
>
>         dev_info(dvfs_info->dev, "Setting dvfs initial frequency = %uKHZ",
> @@ -199,7 +199,7 @@ static void exynos_enable_dvfs(unsigned int cur_frequency)
>         for (cpu = 0; cpu < CONFIG_NR_CPUS; cpu++) {
>                 tmp = __raw_readl(dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4);
>                 tmp &= ~(P_VALUE_MASK << C0_3_PSTATE_NEW_SHIFT);
> -               tmp |= (i << C0_3_PSTATE_NEW_SHIFT);
> +               tmp |= ((pos - freq_table) << C0_3_PSTATE_NEW_SHIFT);
>                 __raw_writel(tmp, dvfs_info->base + XMU_C0_3_PSTATE + cpu * 4);
>         }
>
> diff --git a/drivers/cpufreq/freq_table.c b/drivers/cpufreq/freq_table.c
> index 08e7bbc..8e518c6 100644
> --- a/drivers/cpufreq/freq_table.c
> +++ b/drivers/cpufreq/freq_table.c
> @@ -21,22 +21,19 @@
>  int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy,
>                                     struct cpufreq_frequency_table *table)
>  {
> +       struct cpufreq_frequency_table *pos;
>         unsigned int min_freq = ~0;
>         unsigned int max_freq = 0;
> -       unsigned int i;
> +       unsigned int freq;
>
> -       for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
> -               unsigned int freq = table[i].frequency;
> -               if (freq == CPUFREQ_ENTRY_INVALID) {
> -                       pr_debug("table entry %u is invalid, skipping\n", i);
> +       cpufreq_for_each_valid_entry(pos, table) {
> +               freq = pos->frequency;
>
> -                       continue;
> -               }
>                 if (!cpufreq_boost_enabled()
> -                   && (table[i].flags & CPUFREQ_BOOST_FREQ))
> +                   && (pos->flags & CPUFREQ_BOOST_FREQ))
>                         continue;
>
> -               pr_debug("table entry %u: %u kHz\n", i, freq);
> +               pr_debug("table entry %u: %u kHz\n", (int)(pos - table), freq);
>                 if (freq < min_freq)
>                         min_freq = freq;
>                 if (freq > max_freq)
> @@ -57,7 +54,8 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_cpuinfo);
>  int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
>                                    struct cpufreq_frequency_table *table)
>  {
> -       unsigned int next_larger = ~0, freq, i = 0;
> +       struct cpufreq_frequency_table *pos;
> +       unsigned int freq, next_larger = ~0;
>         bool found = false;
>
>         pr_debug("request for verification of policy (%u - %u kHz) for cpu %u\n",
> @@ -65,9 +63,9 @@ int cpufreq_frequency_table_verify(struct cpufreq_policy *policy,
>
>         cpufreq_verify_within_cpu_limits(policy);
>
> -       for (; freq = table[i].frequency, freq != CPUFREQ_TABLE_END; i++) {
> -               if (freq == CPUFREQ_ENTRY_INVALID)
> -                       continue;
> +       cpufreq_for_each_valid_entry(pos, table) {
> +               freq = pos->frequency;
> +
>                 if ((freq >= policy->min) && (freq <= policy->max)) {
>                         found = true;
>                         break;
> @@ -118,7 +116,8 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
>                 .driver_data = ~0,
>                 .frequency = 0,
>         };
> -       unsigned int i;
> +       struct cpufreq_frequency_table *pos;
> +       unsigned int freq, i = 0;
>
>         pr_debug("request for target %u kHz (relation: %u) for cpu %u\n",
>                                         target_freq, relation, policy->cpu);
> @@ -132,10 +131,10 @@ int cpufreq_frequency_table_target(struct cpufreq_policy *policy,
>                 break;
>         }
>
> -       for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
> -               unsigned int freq = table[i].frequency;
> -               if (freq == CPUFREQ_ENTRY_INVALID)
> -                       continue;
> +       cpufreq_for_each_valid_entry(pos, table) {
> +               freq = pos->frequency;
> +
> +               i = pos - table;
>                 if ((freq < policy->min) || (freq > policy->max))
>                         continue;
>                 switch (relation) {
> @@ -184,8 +183,7 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_target);
>  int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy,
>                 unsigned int freq)
>  {
> -       struct cpufreq_frequency_table *table;
> -       int i;
> +       struct cpufreq_frequency_table *pos, *table;
>
>         table = cpufreq_frequency_get_table(policy->cpu);
>         if (unlikely(!table)) {
> @@ -193,10 +191,9 @@ int cpufreq_frequency_table_get_index(struct cpufreq_policy *policy,
>                 return -ENOENT;
>         }
>
> -       for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
> -               if (table[i].frequency == freq)
> -                       return i;
> -       }
> +       cpufreq_for_each_valid_entry(pos, table)
> +               if (pos->frequency == freq)
> +                       return pos - table;
>
>         return -EINVAL;
>  }
> @@ -208,16 +205,13 @@ EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_index);
>  static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf,
>                                     bool show_boost)
>  {
> -       unsigned int i = 0;
>         ssize_t count = 0;
> -       struct cpufreq_frequency_table *table = policy->freq_table;
> +       struct cpufreq_frequency_table *pos, *table = policy->freq_table;
>
>         if (!table)
>                 return -ENODEV;
>
> -       for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
> -               if (table[i].frequency == CPUFREQ_ENTRY_INVALID)
> -                       continue;
> +       cpufreq_for_each_valid_entry(pos, table) {
>                 /*
>                  * show_boost = true and driver_data = BOOST freq
>                  * display BOOST freqs
> @@ -229,10 +223,10 @@ static ssize_t show_available_freqs(struct cpufreq_policy *policy, char *buf,
>                  * show_boost = false and driver_data != BOOST freq
>                  * display NON BOOST freqs
>                  */
> -               if (show_boost ^ (table[i].flags & CPUFREQ_BOOST_FREQ))
> +               if (show_boost ^ (pos->flags & CPUFREQ_BOOST_FREQ))
>                         continue;
>
> -               count += sprintf(&buf[count], "%d ", table[i].frequency);
> +               count += sprintf(&buf[count], "%d ", pos->frequency);
>         }
>         count += sprintf(&buf[count], "\n");
>
> diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c
> index d00e5d1..f4024d4 100644
> --- a/drivers/cpufreq/longhaul.c
> +++ b/drivers/cpufreq/longhaul.c
> @@ -528,6 +528,7 @@ static int longhaul_get_ranges(void)
>
>  static void longhaul_setup_voltagescaling(void)
>  {
> +       struct cpufreq_frequency_table *freq_pos;
>         union msr_longhaul longhaul;
>         struct mV_pos minvid, maxvid, vid;
>         unsigned int j, speed, pos, kHz_step, numvscales;
> @@ -606,18 +607,16 @@ static void longhaul_setup_voltagescaling(void)
>         /* Calculate kHz for one voltage step */
>         kHz_step = (highest_speed - min_vid_speed) / numvscales;
>
> -       j = 0;
> -       while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) {
> -               speed = longhaul_table[j].frequency;
> +       cpufreq_for_each_entry(freq_pos, longhaul_table) {
> +               speed = freq_pos->frequency;
>                 if (speed > min_vid_speed)
>                         pos = (speed - min_vid_speed) / kHz_step + minvid.pos;
>                 else
>                         pos = minvid.pos;
> -               longhaul_table[j].driver_data |= mV_vrm_table[pos] << 8;
> +               freq_pos->driver_data |= mV_vrm_table[pos] << 8;
>                 vid = vrm_mV_table[mV_vrm_table[pos]];
>                 printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n",
> -                               speed, j, vid.mV);
> -               j++;
> +                       speed, (int)(freq_pos - longhaul_table), vid.mV);
>         }
>
>         can_scale_voltage = 1;
> diff --git a/drivers/cpufreq/pasemi-cpufreq.c b/drivers/cpufreq/pasemi-cpufreq.c
> index 84c84b5..35dd4d7 100644
> --- a/drivers/cpufreq/pasemi-cpufreq.c
> +++ b/drivers/cpufreq/pasemi-cpufreq.c
> @@ -136,9 +136,10 @@ void restore_astate(int cpu)
>
>  static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
>  {
> +       struct cpufreq_frequency_table *pos;
>         const u32 *max_freqp;
>         u32 max_freq;
> -       int i, cur_astate;
> +       int cur_astate;
>         struct resource res;
>         struct device_node *cpu, *dn;
>         int err = -ENODEV;
> @@ -197,10 +198,9 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
>         pr_debug("initializing frequency table\n");
>
>         /* initialize frequency table */
> -       for (i=0; pas_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) {
> -               pas_freqs[i].frequency =
> -                       get_astate_freq(pas_freqs[i].driver_data) * 100000;
> -               pr_debug("%d: %d\n", i, pas_freqs[i].frequency);
> +       cpufreq_for_each_entry(pos, pas_freqs) {
> +               pos->frequency = get_astate_freq(pos->driver_data) * 100000;
> +               pr_debug("%d: %d\n", (int)(pos - pas_freqs), pos->frequency);
>         }
>
>         cur_astate = get_cur_astate(policy->cpu);
> diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c
> index 49f120e..a133236 100644
> --- a/drivers/cpufreq/powernow-k6.c
> +++ b/drivers/cpufreq/powernow-k6.c
> @@ -159,6 +159,7 @@ static int powernow_k6_target(struct cpufreq_policy *policy,
>
>  static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
>  {
> +       struct cpufreq_frequency_table *pos;
>         unsigned int i, f;
>         unsigned khz;
>
> @@ -176,12 +177,11 @@ static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
>                 }
>         }
>         if (param_max_multiplier) {
> -               for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
> -                       if (clock_ratio[i].driver_data == param_max_multiplier) {
> +               cpufreq_for_each_entry(pos, clock_ratio)
> +                       if (pos->driver_data == param_max_multiplier) {
>                                 max_multiplier = param_max_multiplier;
>                                 goto have_max_multiplier;
>                         }
> -               }
>                 printk(KERN_ERR "powernow-k6: invalid max_multiplier parameter, valid parameters 20, 30, 35, 40, 45, 50, 55, 60\n");
>                 return -EINVAL;
>         }
> @@ -209,12 +209,12 @@ have_busfreq:
>         param_busfreq = busfreq * 10;
>
>         /* table init */
> -       for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
> -               f = clock_ratio[i].driver_data;
> +       cpufreq_for_each_entry(pos, clock_ratio) {
> +               f = pos->driver_data;
>                 if (f > max_multiplier)
> -                       clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID;
> +                       pos->frequency = CPUFREQ_ENTRY_INVALID;
>                 else
> -                       clock_ratio[i].frequency = busfreq * f;
> +                       pos->frequency = busfreq * f;
>         }
>
>         /* cpuinfo and default policy values */
> diff --git a/drivers/cpufreq/ppc_cbe_cpufreq.c b/drivers/cpufreq/ppc_cbe_cpufreq.c
> index 5be8a48..5a4c5a6 100644
> --- a/drivers/cpufreq/ppc_cbe_cpufreq.c
> +++ b/drivers/cpufreq/ppc_cbe_cpufreq.c
> @@ -67,9 +67,10 @@ static int set_pmode(unsigned int cpu, unsigned int slow_mode)
>
>  static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
>  {
> +       struct cpufreq_frequency_table *pos;
>         const u32 *max_freqp;
>         u32 max_freq;
> -       int i, cur_pmode;
> +       int cur_pmode;
>         struct device_node *cpu;
>
>         cpu = of_get_cpu_node(policy->cpu, NULL);
> @@ -102,9 +103,9 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
>         pr_debug("initializing frequency table\n");
>
>         /* initialize frequency table */
> -       for (i=0; cbe_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) {
> -               cbe_freqs[i].frequency = max_freq / cbe_freqs[i].driver_data;
> -               pr_debug("%d: %d\n", i, cbe_freqs[i].frequency);
> +       cpufreq_for_each_entry(pos, cbe_freqs) {
> +               pos->frequency = max_freq / pos->driver_data;
> +               pr_debug("%d: %d\n", (int)(pos - cbe_freqs), pos->frequency);
>         }
>
>         /* if DEBUG is enabled set_pmode() measures the latency
> diff --git a/drivers/cpufreq/s3c2416-cpufreq.c b/drivers/cpufreq/s3c2416-cpufreq.c
> index 4626f90..2fd53ea 100644
> --- a/drivers/cpufreq/s3c2416-cpufreq.c
> +++ b/drivers/cpufreq/s3c2416-cpufreq.c
> @@ -266,7 +266,7 @@ out:
>  static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq)
>  {
>         int count, v, i, found;
> -       struct cpufreq_frequency_table *freq;
> +       struct cpufreq_frequency_table *pos;
>         struct s3c2416_dvfs *dvfs;
>
>         count = regulator_count_voltages(s3c_freq->vddarm);
> @@ -275,12 +275,11 @@ static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq)
>                 return;
>         }
>
> -       freq = s3c_freq->freq_table;
> -       while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) {
> -               if (freq->frequency == CPUFREQ_ENTRY_INVALID)
> -                       continue;
> +       if (!count)
> +               goto out;
>
> -               dvfs = &s3c2416_dvfs_table[freq->driver_data];
> +       cpufreq_for_each_valid_entry(pos, s3c_freq->freq_table) {
> +               dvfs = &s3c2416_dvfs_table[pos->driver_data];
>                 found = 0;
>
>                 /* Check only the min-voltage, more is always ok on S3C2416 */
> @@ -292,13 +291,12 @@ static void __init s3c2416_cpufreq_cfg_regulator(struct s3c2416_data *s3c_freq)
>
>                 if (!found) {
>                         pr_debug("cpufreq: %dkHz unsupported by regulator\n",
> -                                freq->frequency);
> -                       freq->frequency = CPUFREQ_ENTRY_INVALID;
> +                                pos->frequency);
> +                       pos->frequency = CPUFREQ_ENTRY_INVALID;
>                 }
> -
> -               freq++;
>         }
>
> +out:
>         /* Guessed */
>         s3c_freq->regulator_latency = 1 * 1000 * 1000;
>  }
> @@ -338,7 +336,7 @@ static struct notifier_block s3c2416_cpufreq_reboot_notifier = {
>  static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy)
>  {
>         struct s3c2416_data *s3c_freq = &s3c2416_cpufreq;
> -       struct cpufreq_frequency_table *freq;
> +       struct cpufreq_frequency_table *pos;
>         struct clk *msysclk;
>         unsigned long rate;
>         int ret;
> @@ -427,31 +425,27 @@ static int __init s3c2416_cpufreq_driver_init(struct cpufreq_policy *policy)
>         s3c_freq->regulator_latency = 0;
>  #endif
>
> -       freq = s3c_freq->freq_table;
> -       while (freq->frequency != CPUFREQ_TABLE_END) {
> +       cpufreq_for_each_entry(pos, s3c_freq->freq_table) {
>                 /* special handling for dvs mode */
> -               if (freq->driver_data == 0) {
> +               if (pos->driver_data == 0) {
>                         if (!s3c_freq->hclk) {
>                                 pr_debug("cpufreq: %dkHz unsupported as it would need unavailable dvs mode\n",
> -                                        freq->frequency);
> -                               freq->frequency = CPUFREQ_ENTRY_INVALID;
> +                                        pos->frequency);
> +                               pos->frequency = CPUFREQ_ENTRY_INVALID;
>                         } else {
> -                               freq++;
>                                 continue;
>                         }
>                 }
>
>                 /* Check for frequencies we can generate */
>                 rate = clk_round_rate(s3c_freq->armdiv,
> -                                     freq->frequency * 1000);
> +                                     pos->frequency * 1000);
>                 rate /= 1000;
> -               if (rate != freq->frequency) {
> +               if (rate != pos->frequency) {
>                         pr_debug("cpufreq: %dkHz unsupported by clock (clk_round_rate return %lu)\n",
> -                                freq->frequency, rate);
> -                       freq->frequency = CPUFREQ_ENTRY_INVALID;
> +                               pos->frequency, rate);
> +                       pos->frequency = CPUFREQ_ENTRY_INVALID;
>                 }
> -
> -               freq++;
>         }
>
>         /* Datasheet says PLL stabalisation time must be at least 300us,
> diff --git a/drivers/cpufreq/s3c64xx-cpufreq.c b/drivers/cpufreq/s3c64xx-cpufreq.c
> index ff7d3ec..176e84c 100644
> --- a/drivers/cpufreq/s3c64xx-cpufreq.c
> +++ b/drivers/cpufreq/s3c64xx-cpufreq.c
> @@ -118,11 +118,10 @@ static void __init s3c64xx_cpufreq_config_regulator(void)
>                 pr_err("Unable to check supported voltages\n");
>         }
>
> -       freq = s3c64xx_freq_table;
> -       while (count > 0 && freq->frequency != CPUFREQ_TABLE_END) {
> -               if (freq->frequency == CPUFREQ_ENTRY_INVALID)
> -                       continue;
> +       if (!count)
> +               goto out;
>
> +       cpufreq_for_each_valid_entry(freq, s3c64xx_freq_table) {
>                 dvfs = &s3c64xx_dvfs_table[freq->driver_data];
>                 found = 0;
>
> @@ -137,10 +136,9 @@ static void __init s3c64xx_cpufreq_config_regulator(void)
>                                  freq->frequency);
>                         freq->frequency = CPUFREQ_ENTRY_INVALID;
>                 }
> -
> -               freq++;
>         }
>
> +out:
>         /* Guess based on having to do an I2C/SPI write; in future we
>          * will be able to query the regulator performance here. */
>         regulator_latency = 1 * 1000 * 1000;
> @@ -179,8 +177,7 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
>         }
>  #endif
>
> -       freq = s3c64xx_freq_table;
> -       while (freq->frequency != CPUFREQ_TABLE_END) {
> +       cpufreq_for_each_entry(freq, s3c64xx_freq_table) {
>                 unsigned long r;
>
>                 /* Check for frequencies we can generate */
> @@ -196,8 +193,6 @@ static int s3c64xx_cpufreq_driver_init(struct cpufreq_policy *policy)
>                  * frequency is the maximum we can support. */
>                 if (!vddarm && freq->frequency > clk_get_rate(policy->clk) / 1000)
>                         freq->frequency = CPUFREQ_ENTRY_INVALID;
> -
> -               freq++;
>         }
>
>         /* Datasheet says PLL stabalisation time (if we were to use
> --
> 1.9.0

^ permalink raw reply

* Re: [PATCH v5 2/8] cpufreq: Use cpufreq_for_each_* macros for frequency table iteration
From: Stratos Karafotis @ 2014-04-26 11:35 UTC (permalink / raw)
  To: Prabhakar Lad
  Cc: Kukjin Kim, linux-pm, Viresh Kumar, Rafael J. Wysocki, LKML,
	cpufreq@vger.kernel.org, linux-samsung-soc, Sudeep Holla,
	Olof Johansson, linuxppc-dev,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <CA+V-a8sg9sBi5mf9KoFWrCJjw6WN+tGrb=bgJwfV3VDZ2DGYig@mail.gmail.com>

Hi Prabhakar,

On 26/04/2014 12:57 μμ, Prabhakar Lad wrote:
> Hi Stratos,
> 
> Thanks for the patch,
> 
> On Sat, Apr 26, 2014 at 1:45 AM, Stratos Karafotis
> <stratosk@semaphore.gr> wrote:
>> The cpufreq core now supports the cpufreq_for_each_entry and
>> cpufreq_for_each_valid_entry macros helpers for iteration over the
>> cpufreq_frequency_table, so use them.
>>
>> It should have no functional changes.
>>
>> Signed-off-by: Stratos Karafotis <stratosk@semaphore.gr>
> 
> For patches 1 & 2:  Acked-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
> 
> and for patch 3: Acked-and-tested-by: Lad, Prabhakar
> <prabhakar.csengg@gmail.com>
> 
> Thanks,
> --Prabhakar lad
> 

Thank you very much!


Stratos Karafotis

^ permalink raw reply

* [PATCH] powerpc: export flush_icache_range
From: Jeff Mahoney @ 2014-04-27 22:10 UTC (permalink / raw)
  To: Benjamin Herrenschmidt, Paul Mackerras; +Cc: linuxppc-dev

Commit aac416fc38c (lkdtm: flush icache and report actions) calls
flush_icache_range from a module. It's exported on most architectures
that implement it, but not on powerpc. This patch exports it to fix
the module link failure.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
 arch/powerpc/kernel/ppc_ksyms.c |    1 +
 1 file changed, 1 insertion(+)

--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -120,6 +120,7 @@ EXPORT_SYMBOL(giveup_spe);
 EXPORT_SYMBOL(flush_instruction_cache);
 #endif
 EXPORT_SYMBOL(flush_dcache_range);
+EXPORT_SYMBOL(flush_icache_range);
 
 #ifdef CONFIG_SMP
 #ifdef CONFIG_PPC32

-- 
Jeff Mahoney
SUSE Labs

^ permalink raw reply

* Re: [RFC PATCH] Fix Oops in rtas_stop_self()
From: Li Zhong @ 2014-04-28  0:26 UTC (permalink / raw)
  To: Anton Blanchard
  Cc: Paul Mackerras, Benjamin Herrenschmidt, PowerPC email list
In-Reply-To: <20140425221833.3cc04b0c@kryten>

On Fri, 2014-04-25 at 22:18 +1000, Anton Blanchard wrote:
> Hi,
> 
> > When trying offline cpus, I noticed following Oops in
> > rtas_stop_self(), and it seems caused by commit 41dd03a9. The Oops
> > disappears after reverting this commit.
> > 
> > After reading the code, I guess it might be caused by moving the
> > rtas_args to stack. Still need some more time to read enter_rtas to
> > understand why it happens, but the problem seems could be solved by
> > moving the rtas_args away from stack by adding static before it.
> 
> Nice catch. RTAS is 32bit and if your box has more than 4GB RAM then
> your stack could easily be outside 32bit range.

Ah, yes, the stack here is obviously at a much higher address than 4GB.

> 
> You can add:
> 
> Signed-off-by: Anton Blanchard <anton@samba.org>
> 
> And also:
> 
> Cc: stable@vger.kernel.org # 3.14+

OK, 

Thanks, Zhong
> 
> > Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com>
> > ---
> >  arch/powerpc/platforms/pseries/hotplug-cpu.c | 5 +++--
> >  1 file changed, 3 insertions(+), 2 deletions(-)
> > 
> > diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c
> > b/arch/powerpc/platforms/pseries/hotplug-cpu.c index 9b8e050..20d6297
> > 100644 --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
> > +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
> > @@ -88,13 +88,14 @@ void set_default_offline_state(int cpu)
> >  
> >  static void rtas_stop_self(void)
> >  {
> > -	struct rtas_args args = {
> > -		.token = cpu_to_be32(rtas_stop_self_token),
> > +	static struct rtas_args args = {
> >  		.nargs = 0,
> >  		.nret = 1,
> >  		.rets = &args.args[0],
> >  	};
> >  
> > +	args.token = cpu_to_be32(rtas_stop_self_token);
> > +
> >  	local_irq_disable();
> >  
> >  	BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE);
> > 
> > 
> > _______________________________________________
> > Linuxppc-dev mailing list
> > Linuxppc-dev@lists.ozlabs.org
> > https://lists.ozlabs.org/listinfo/linuxppc-dev
> 

^ permalink raw reply

* [PATCH] powerpc: Fix Oops in rtas_stop_self()
From: Li Zhong @ 2014-04-28  0:29 UTC (permalink / raw)
  To: Anton Blanchard
  Cc: Paul Mackerras, Benjamin Herrenschmidt, PowerPC email list
In-Reply-To: <20140425221833.3cc04b0c@kryten>

commit 41dd03a9 may cause Oops in rtas_stop_self().

The reason is that the rtas_args was moved into stack space. For a box
with more that 4GB RAM, the stack could easily be outside 32bit range,
but RTAS is 32bit.

So the patch moves rtas_args away from stack by adding static before
it. 

Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com>
Signed-off-by: Anton Blanchard <anton@samba.org>
Cc: stable@vger.kernel.org # 3.14+
---
 arch/powerpc/platforms/pseries/hotplug-cpu.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 9b8e050..20d6297 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -88,13 +88,14 @@ void set_default_offline_state(int cpu)
 
 static void rtas_stop_self(void)
 {
-	struct rtas_args args = {
-		.token = cpu_to_be32(rtas_stop_self_token),
+	static struct rtas_args args = {
 		.nargs = 0,
 		.nret = 1,
 		.rets = &args.args[0],
 	};
 
+	args.token = cpu_to_be32(rtas_stop_self_token);
+
 	local_irq_disable();
 
 	BUG_ON(rtas_stop_self_token == RTAS_UNKNOWN_SERVICE);

^ permalink raw reply related

* Re: [PATCH 08/13] PCI, rpaphp: Use new pci_is_bridge() to simplify code
From: Benjamin Herrenschmidt @ 2014-04-28  0:43 UTC (permalink / raw)
  To: Yijing Wang
  Cc: Tony Luck, linux-ia64, x86, linux-kernel, sparclinux,
	Bjorn Helgaas, Thomas Gleixner, linuxppc-dev, David S. Miller
In-Reply-To: <1398417515-8740-9-git-send-email-wangyijing@huawei.com>

On Fri, 2014-04-25 at 17:18 +0800, Yijing Wang wrote:
> Now we can use new pci_is_bridge() helper function
> to simplify code.
> 
> Signed-off-by: Yijing Wang <wangyijing@huawei.com>

Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>

> ---
>  drivers/pci/hotplug/rpadlpar_core.c |    3 +--
>  1 files changed, 1 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c
> index 4fcdeed..7660232 100644
> --- a/drivers/pci/hotplug/rpadlpar_core.c
> +++ b/drivers/pci/hotplug/rpadlpar_core.c
> @@ -157,8 +157,7 @@ static void dlpar_pci_add_bus(struct device_node *dn)
>  	}
>  
>  	/* Scan below the new bridge */
> -	if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
> -	    dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
> +	if (pci_is_bridge(dev))
>  		of_scan_pci_bridge(dev);
>  
>  	/* Map IO space for child bus, which may or may not succeed */

^ permalink raw reply

* Re: [PATCH v2 21/21] of: push struct boot_param_header and defines into powerpc
From: Benjamin Herrenschmidt @ 2014-04-28  1:37 UTC (permalink / raw)
  To: Rob Herring
  Cc: devicetree, Rob Herring, linux-kernel, Paul Mackerras,
	Grant Likely, linuxppc-dev
In-Reply-To: <1398215901-25609-22-git-send-email-robherring2@gmail.com>

On Tue, 2014-04-22 at 20:18 -0500, Rob Herring wrote:
> From: Rob Herring <robh@kernel.org>
> 
> Now powerpc is the only user of struct boot_param_header and FDT defines,
> so they can be moved into the powerpc architecture code.
> 
> Signed-off-by: Rob Herring <robh@kernel.org>
> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: linuxppc-dev@lists.ozlabs.org
> ---

I assume we want to get rid of that too eventually ? :-)

We should be able to get the definitions from libfdt too....

In the meantime:

Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
--

> v2: no change
> 
>  arch/powerpc/include/asm/prom.h | 39 +++++++++++++++++++++++++++++++++++++++
>  include/linux/of_fdt.h          | 37 -------------------------------------
>  2 files changed, 39 insertions(+), 37 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h
> index d977b9b..74b79f0 100644
> --- a/arch/powerpc/include/asm/prom.h
> +++ b/arch/powerpc/include/asm/prom.h
> @@ -26,6 +26,45 @@
>  #include <linux/of_irq.h>
>  #include <linux/platform_device.h>
>  
> +#define OF_DT_BEGIN_NODE	0x1		/* Start of node, full name */
> +#define OF_DT_END_NODE		0x2		/* End node */
> +#define OF_DT_PROP		0x3		/* Property: name off, size,
> +						 * content */
> +#define OF_DT_NOP		0x4		/* nop */
> +#define OF_DT_END		0x9
> +
> +#define OF_DT_VERSION		0x10
> +
> +/*
> + * This is what gets passed to the kernel by prom_init or kexec
> + *
> + * The dt struct contains the device tree structure, full pathes and
> + * property contents. The dt strings contain a separate block with just
> + * the strings for the property names, and is fully page aligned and
> + * self contained in a page, so that it can be kept around by the kernel,
> + * each property name appears only once in this page (cheap compression)
> + *
> + * the mem_rsvmap contains a map of reserved ranges of physical memory,
> + * passing it here instead of in the device-tree itself greatly simplifies
> + * the job of everybody. It's just a list of u64 pairs (base/size) that
> + * ends when size is 0
> + */
> +struct boot_param_header {
> +	__be32	magic;			/* magic word OF_DT_HEADER */
> +	__be32	totalsize;		/* total size of DT block */
> +	__be32	off_dt_struct;		/* offset to structure */
> +	__be32	off_dt_strings;		/* offset to strings */
> +	__be32	off_mem_rsvmap;		/* offset to memory reserve map */
> +	__be32	version;		/* format version */
> +	__be32	last_comp_version;	/* last compatible version */
> +	/* version 2 fields below */
> +	__be32	boot_cpuid_phys;	/* Physical CPU id we're booting on */
> +	/* version 3 fields below */
> +	__be32	dt_strings_size;	/* size of the DT strings block */
> +	/* version 17 fields below */
> +	__be32	dt_struct_size;		/* size of the DT structure block */
> +};
> +
>  /*
>   * OF address retreival & translation
>   */
> diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h
> index 1f882e1..5c0ab05 100644
> --- a/include/linux/of_fdt.h
> +++ b/include/linux/of_fdt.h
> @@ -17,45 +17,8 @@
>  
>  /* Definitions used by the flattened device tree */
>  #define OF_DT_HEADER		0xd00dfeed	/* marker */
> -#define OF_DT_BEGIN_NODE	0x1		/* Start of node, full name */
> -#define OF_DT_END_NODE		0x2		/* End node */
> -#define OF_DT_PROP		0x3		/* Property: name off, size,
> -						 * content */
> -#define OF_DT_NOP		0x4		/* nop */
> -#define OF_DT_END		0x9
> -
> -#define OF_DT_VERSION		0x10
>  
>  #ifndef __ASSEMBLY__
> -/*
> - * This is what gets passed to the kernel by prom_init or kexec
> - *
> - * The dt struct contains the device tree structure, full pathes and
> - * property contents. The dt strings contain a separate block with just
> - * the strings for the property names, and is fully page aligned and
> - * self contained in a page, so that it can be kept around by the kernel,
> - * each property name appears only once in this page (cheap compression)
> - *
> - * the mem_rsvmap contains a map of reserved ranges of physical memory,
> - * passing it here instead of in the device-tree itself greatly simplifies
> - * the job of everybody. It's just a list of u64 pairs (base/size) that
> - * ends when size is 0
> - */
> -struct boot_param_header {
> -	__be32	magic;			/* magic word OF_DT_HEADER */
> -	__be32	totalsize;		/* total size of DT block */
> -	__be32	off_dt_struct;		/* offset to structure */
> -	__be32	off_dt_strings;		/* offset to strings */
> -	__be32	off_mem_rsvmap;		/* offset to memory reserve map */
> -	__be32	version;		/* format version */
> -	__be32	last_comp_version;	/* last compatible version */
> -	/* version 2 fields below */
> -	__be32	boot_cpuid_phys;	/* Physical CPU id we're booting on */
> -	/* version 3 fields below */
> -	__be32	dt_strings_size;	/* size of the DT strings block */
> -	/* version 17 fields below */
> -	__be32	dt_struct_size;		/* size of the DT structure block */
> -};
>  
>  #if defined(CONFIG_OF_FLATTREE)
>  

^ permalink raw reply

* Re: [PATCH v2 6/6] powerpc/perf/hv-24x7: catalog version number is be64, not be32
From: Benjamin Herrenschmidt @ 2014-04-28  4:47 UTC (permalink / raw)
  To: Cody P Schafer
  Cc: Michael Ellerman, David.Laight, Linux PPC, LKML, Anton Blanchard
In-Reply-To: <1397581855-4585-7-git-send-email-cody@linux.vnet.ibm.com>

On Tue, 2014-04-15 at 10:10 -0700, Cody P Schafer wrote:
> The catalog version number was changed from a be32 (with proceeding
> 32bits of padding) to a be64, update the code to treat it as a be64
> 
> Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
> --

Have you tested this ?

It doesn't build for me:

arch/powerpc/perf/hv-24x7.c: In function 'catalog_read':
arch/powerpc/perf/hv-24x7.c:223:3: error: format '%d' expects argument of type 'int', but argument 2 has type 'uint64_t' [-Werror=format]
cc1: all warnings being treated as errors

I'll fix that up in my tree.

Cheers,
Ben.

>  arch/powerpc/perf/hv-24x7.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c
> index 95a67f8..9d4badc 100644
> --- a/arch/powerpc/perf/hv-24x7.c
> +++ b/arch/powerpc/perf/hv-24x7.c
> @@ -171,7 +171,7 @@ static unsigned long h_get_24x7_catalog_page_(unsigned long phys_4096,
>  }
>  
>  static unsigned long h_get_24x7_catalog_page(char page[],
> -					     u32 version, u32 index)
> +					     u64 version, u32 index)
>  {
>  	return h_get_24x7_catalog_page_(virt_to_phys(page),
>  					version, index);
> @@ -185,7 +185,7 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj,
>  	ssize_t ret = 0;
>  	size_t catalog_len = 0, catalog_page_len = 0, page_count = 0;
>  	loff_t page_offset = 0;
> -	uint32_t catalog_version_num = 0;
> +	uint64_t catalog_version_num = 0;
>  	void *page = kmem_cache_alloc(hv_page_cache, GFP_USER);
>  	struct hv_24x7_catalog_page_0 *page_0 = page;
>  	if (!page)
> @@ -197,7 +197,7 @@ static ssize_t catalog_read(struct file *filp, struct kobject *kobj,
>  		goto e_free;
>  	}
>  
> -	catalog_version_num = be32_to_cpu(page_0->version);
> +	catalog_version_num = be64_to_cpu(page_0->version);
>  	catalog_page_len = be32_to_cpu(page_0->length);
>  	catalog_len = catalog_page_len * 4096;
>  
> @@ -255,7 +255,7 @@ e_free:								\
>  static DEVICE_ATTR_RO(_name)
>  
>  PAGE_0_ATTR(catalog_version, "%lld\n",
> -		(unsigned long long)be32_to_cpu(page_0->version));
> +		(unsigned long long)be64_to_cpu(page_0->version));
>  PAGE_0_ATTR(catalog_len, "%lld\n",
>  		(unsigned long long)be32_to_cpu(page_0->length) * 4096);
>  static BIN_ATTR_RO(catalog, 0/* real length varies */);

^ permalink raw reply

* Re: [PATCH v2 6/6] powerpc/perf/hv-24x7: catalog version number is be64, not be32
From: Cody P Schafer @ 2014-04-28  4:59 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Michael Ellerman, David.Laight, Linux PPC, LKML, Anton Blanchard
In-Reply-To: <1398660478.30694.10.camel@pasglop>

On 04/27/2014 09:47 PM, Benjamin Herrenschmidt wrote:
> On Tue, 2014-04-15 at 10:10 -0700, Cody P Schafer wrote:
>> The catalog version number was changed from a be32 (with proceeding
>> 32bits of padding) to a be64, update the code to treat it as a be64
>>
>> Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
>> --
>
> Have you tested this ?
>
> It doesn't build for me:
>
> arch/powerpc/perf/hv-24x7.c: In function 'catalog_read':
> arch/powerpc/perf/hv-24x7.c:223:3: error: format '%d' expects argument of type 'int', but argument 2 has type 'uint64_t' [-Werror=format]
> cc1: all warnings being treated as errors

I have, and I wasn't initially sure how I managed to miss that 
warning-as-error. On examination: My config (for some reason) has 
CONFIG_PPC_DISABLE_WERROR=y set (probably because it's a variation of a 
distro config). Must have been piping the warnings to a file and 
forgotten to check the file.

> I'll fix that up in my tree.

Thanks.

^ permalink raw reply

* Re: [PATCH v2 1/2] powerpc/pm: add api to get suspend state which is STANDBY or MEM
From: Leo Li @ 2014-04-28  5:53 UTC (permalink / raw)
  To: Scott Wood
  Cc: linuxppc-dev, Dongsheng Wang, 正雄 金,
	Zhao Chenhui
In-Reply-To: <1398462328.24575.20.camel@snotra.buserror.net>

On Sat, Apr 26, 2014 at 5:45 AM, Scott Wood <scottwood@freescale.com> wrote:
> On Thu, 2014-04-24 at 14:11 +0800, Dongsheng Wang wrote:
>> From: Wang Dongsheng <dongsheng.wang@freescale.com>
>>
>> Add set_pm_suspend_state & pm_suspend_state functions to set/get
>> suspend state. When system going to sleep or deep sleep, devices
>> can get the system suspend state(STANDBY/MEM) through pm_suspend_state
>> function and to handle different situations.
>>
>> Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
>> ---
>> *v2*
>> Move pm api from fsl platform to powerpc general framework.
>
> What is powerpc-specific about this?

Generally I agree with you.  But I had the discussion about this topic
a while ago with the PM maintainer.  He suggestion to go with the
platform way.

https://lkml.org/lkml/2013/8/16/505

Regards,
Leo

^ permalink raw reply

* [PATCH V5] mtd: m25p80: modify the name of mtd_info
From: Hou Zhiqiang @ 2014-04-28  6:28 UTC (permalink / raw)
  To: linux-mtd, linuxppc-dev
  Cc: shijie8, Hou Zhiqiang, scottwood, mingkai.hu, computersforpeace,
	dwmw2

To specify spi flash layouts by "mtdparts=..." in cmdline, we must
give mtd_info a fixed name, because the cmdlinepart's parser will
match the name of mtd_info given in cmdline.
Now, if it use DT, the mtd_info's name will be spi->dev->name. It
consists of spi_master->bus_num, and the spi_master->bus_num maybe
dynamically fetched. So, in this case, replace the component bus_num
with the physical address of spi master.

Signed-off-by: Hou Zhiqiang <B48286@freescale.com>
---
V5:
	Rebase on the latest l2-mtd tree.
V4:
	add check no-NULL for pointer of master's device node, and if it failed
	to get physcial address of the master, then name the mtd_info by the
	name of spi->dev.
V3:
	Fix a bug, matching unsigned long long with "%llx".
V2:
	1. Fix some code style issue.
	2. Cast physical address to unsigned long long.

 drivers/mtd/devices/m25p80.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 1557d8f..329aa2c 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -26,6 +26,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/flash.h>
 #include <linux/mtd/spi-nor.h>
+#include <linux/of_address.h>
 
 #define	MAX_CMD_SIZE		6
 struct m25p {
@@ -196,6 +197,8 @@ static int m25p_probe(struct spi_device *spi)
 	struct m25p *flash;
 	struct spi_nor *nor;
 	enum read_mode mode = SPI_NOR_NORMAL;
+	struct resource res;
+	struct device_node *mnp = spi->master->dev.of_node;
 	int ret;
 
 	flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL);
@@ -228,6 +231,17 @@ static int m25p_probe(struct spi_device *spi)
 	data = dev_get_platdata(&spi->dev);
 	ppdata.of_node = spi->dev.of_node;
 
+	if (mnp) {
+		ret = of_address_to_resource(mnp, 0, &res);
+		if (!ret) {
+			flash->mtd.name = kasprintf(GFP_KERNEL, "spi%llx.%d",
+					(unsigned long long)res.start,
+					spi->chip_select);
+			if (!flash->mtd.name)
+				return -ENOMEM;
+		}
+	}
+
 	return mtd_device_parse_register(&flash->mtd, NULL, &ppdata,
 			data ? data->parts : NULL,
 			data ? data->nr_parts : 0);
-- 
1.8.5

^ permalink raw reply related

* [git pull] Please pull powerpc.git merge branch
From: Benjamin Herrenschmidt @ 2014-04-28  6:52 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linuxppc-dev, Linux Kernel list

Hi Linus !

Here is a bunch of post-merge window fixes that have been accumulating
in patchwork while I was on vacation or buried under other stuff last
week.

We have the now usual batch of LE fixes from Anton (sadly some new stuff
that went into this merge window had endian issues, we'll try to make
sure we do better next time)

Some fixes and cleanups to the new 24x7 performance monitoring stuff
(mostly typos and cleaning up printk's)

A series of fixes for an issue with our runlatch bit, which wasn't set
properly for offlined threads/cores and under KVM, causing potentially
some counters to misbehave along with possible power management issues.

A fix for kexec nasty race where the new kernel wouldn't "see" the
secondary processors having reached back into firmware in time.

And finally a few other misc (and pretty simple) bug fixes.

Cheers,
Ben.

The following changes since commit a798c10faf62a505d24e5f6213fbaf904a39623f:

  Linux 3.15-rc2 (2014-04-20 11:08:50 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc.git merge

for you to fetch changes up to e4565362c7adc31201135c4b6d649fc1bdc3bf20:

  powerpc/4xx: Fix section mismatch in ppc4xx_pci.c (2014-04-28 16:32:53 +1000)

----------------------------------------------------------------
Alistair Popple (1):
      powerpc/4xx: Fix section mismatch in ppc4xx_pci.c

Aneesh Kumar K.V (1):
      powerpc/mm: Fix tlbie to add AVAL fields for 64K pages

Anton Blanchard (11):
      powerpc/powernv: Fix little endian issues in OPAL flash code
      powerpc/powernv: Use uint64_t instead of size_t in OPAL APIs
      powerpc/powernv: Remove some OPAL function declaration duplication
      powerpc/powernv: Fix little endian issues with opal_do_notifier calls
      powerpc/powernv: Fix little endian issues in OPAL error log code
      powerpc/powernv: Create OPAL sglist helper functions and fix endian issues
      powerpc/powernv: Fix little endian issues in OPAL dump code
      powerpc: Rename duplicate COMMAND_LINE_SIZE define
      powerpc: Bump COMMAND_LINE_SIZE to 2048
      powerpc: Bump BOOT_COMMAND_LINE_SIZE to 2048
      powerpc: Fix error return in rtas_flash module init

Benjamin Herrenschmidt (1):
      powerpc/powernv: Fix kexec races going back to OPAL

Cody P Schafer (6):
      powerpc/perf/hv_24x7: Probe errors changed to pr_debug(), padding fixed
      powerpc/perf/hv_gpci: Probe failures use pr_debug(), and padding reduced
      powerpc/perf/hv-gpci: Make device attr static
      powerpc/perf/hv-24x7: Use (unsigned long) not (u32) values when calling plpar_hcall_norets()
      powerpc/perf/hv-24x7: Remove [static 4096], sparse chokes on it
      powerpc/perf/hv-24x7: Catalog version number is be64, not be32

Jeff Mahoney (1):
      powerpc: Export flush_icache_range

Joel Stanley (5):
      powerpc/powernv: Fix sysparam sysfs error handling
      powerpc/powernv: Use ssize_t for sysparam return values
      powerpc/powernv: Check sysfs size before copying
      powerpc/powernv: Fix typos in sysparam code
      powerpc/powernv: Check sysparam size before creation

Li Zhong (2):
      powerpc: Fix Oops in rtas_stop_self()
      powerpc/pseries: Protect remove_memory() with device hotplug lock

Preeti U Murthy (3):
      ppc/powernv: Set the runlatch bits correctly for offline cpus
      ppc/kvm: Set the runlatch bit of a CPU just before starting guest
      ppc/kvm: Clear the runlatch bit of a vcpu before napping

Wei Yang (2):
      powerpc/powernv: Reduce multi-hit of iommu_add_device()
      powerpc/powernv: Release the refcount for pci_dev

 arch/powerpc/boot/main.c                        |   8 +-
 arch/powerpc/boot/ops.h                         |   2 +-
 arch/powerpc/boot/ps3.c                         |   4 +-
 arch/powerpc/include/asm/opal.h                 |  42 ++++-----
 arch/powerpc/include/uapi/asm/setup.h           |   7 +-
 arch/powerpc/kernel/ppc_ksyms.c                 |   1 +
 arch/powerpc/kernel/rtas_flash.c                |   2 +-
 arch/powerpc/kvm/book3s_hv_rmhandlers.S         |  18 +++-
 arch/powerpc/mm/hash_native_64.c                |  38 ++++----
 arch/powerpc/perf/hv-24x7.c                     |  35 ++++---
 arch/powerpc/perf/hv-gpci.c                     |   6 +-
 arch/powerpc/platforms/powernv/opal-dump.c      |  94 +++----------------
 arch/powerpc/platforms/powernv/opal-elog.c      |  11 ++-
 arch/powerpc/platforms/powernv/opal-flash.c     | 118 ++----------------------
 arch/powerpc/platforms/powernv/opal-sysparam.c  |  32 +++++--
 arch/powerpc/platforms/powernv/opal.c           |  69 +++++++++++++-
 arch/powerpc/platforms/powernv/pci-ioda.c       |   3 +-
 arch/powerpc/platforms/powernv/setup.c          |  48 +++++++++-
 arch/powerpc/platforms/powernv/smp.c            |   3 +
 arch/powerpc/platforms/pseries/hotplug-cpu.c    |   5 +-
 arch/powerpc/platforms/pseries/hotplug-memory.c |  10 +-
 arch/powerpc/sysdev/ppc4xx_pci.c                |   2 +-
 22 files changed, 273 insertions(+), 285 deletions(-)

^ permalink raw reply

* [PATCH V3 0/2] mm: FAULT_AROUND_ORDER patchset performance data for powerpc
From: Madhavan Srinivasan @ 2014-04-28  9:01 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev, linux-mm, linux-arch, x86
  Cc: riel, ak, peterz, rusty, dave.hansen, Madhavan Srinivasan, paulus,
	mgorman, akpm, mingo, kirill.shutemov

Kirill A. Shutemov with 8c6e50b029 commit introduced
vm_ops->map_pages() for mapping easy accessible pages around
fault address in hope to reduce number of minor page faults.

This patch creates infrastructure to modify the FAULT_AROUND_ORDER
value using mm/Kconfig. This will enable architecture maintainers
to decide on suitable FAULT_AROUND_ORDER value based on
performance data for that architecture. First patch also defaults
FAULT_AROUND_ORDER Kconfig element to 4. Second patch list
out the performance numbers for powerpc (platform pseries) and
initialize the fault around order variable for pseries platform of
powerpc.

V3 Changes:
  Replaced FAULT_AROUND_ORDER macro to a variable to support arch's that
   supports sub platforms.
  Made changes in commit messages.

V2 Changes:
  Created Kconfig parameter for FAULT_AROUND_ORDER
  Added check in do_read_fault to handle FAULT_AROUND_ORDER value of 0
  Made changes in commit messages.

Madhavan Srinivasan (2):
  mm: move FAULT_AROUND_ORDER to arch/
  powerpc/pseries: init fault_around_order for pseries

 arch/powerpc/platforms/pseries/setup.c |    5 +++++
 mm/Kconfig                             |    8 ++++++++
 mm/memory.c                            |   11 ++++-------
 3 files changed, 17 insertions(+), 7 deletions(-)

-- 
1.7.10.4

^ permalink raw reply

* [PATCH V3 1/2] mm: move FAULT_AROUND_ORDER to arch/
From: Madhavan Srinivasan @ 2014-04-28  9:01 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev, linux-mm, linux-arch, x86
  Cc: riel, ak, peterz, rusty, dave.hansen, Madhavan Srinivasan, paulus,
	mgorman, akpm, mingo, kirill.shutemov
In-Reply-To: <1398675690-16186-1-git-send-email-maddy@linux.vnet.ibm.com>

Kirill A. Shutemov with 8c6e50b029 commit introduced
vm_ops->map_pages() for mapping easy accessible pages around
fault address in hope to reduce number of minor page faults.

This patch creates infrastructure to modify the FAULT_AROUND_ORDER
value using mm/Kconfig. This will enable architecture maintainers
to decide on suitable FAULT_AROUND_ORDER value based on
performance data for that architecture. Patch also defaults
FAULT_AROUND_ORDER Kconfig element to 4.

Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
 mm/Kconfig  |    8 ++++++++
 mm/memory.c |   11 ++++-------
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/mm/Kconfig b/mm/Kconfig
index ebe5880..c7fc4f1 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -176,6 +176,14 @@ config MOVABLE_NODE
 config HAVE_BOOTMEM_INFO_NODE
 	def_bool n
 
+#
+# Fault around order is a control knob to decide the fault around pages.
+# Default value is set to 4 , but the arch can override it as desired.
+#
+config FAULT_AROUND_ORDER
+	int
+	default	4
+
 # eventually, we can have this option just 'select SPARSEMEM'
 config MEMORY_HOTPLUG
 	bool "Allow for memory hot-add"
diff --git a/mm/memory.c b/mm/memory.c
index d0f0bef..457436d 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3382,11 +3382,9 @@ void do_set_pte(struct vm_area_struct *vma, unsigned long address,
 	update_mmu_cache(vma, address, pte);
 }
 
-#define FAULT_AROUND_ORDER 4
+unsigned int fault_around_order = CONFIG_FAULT_AROUND_ORDER;
 
 #ifdef CONFIG_DEBUG_FS
-static unsigned int fault_around_order = FAULT_AROUND_ORDER;
-
 static int fault_around_order_get(void *data, u64 *val)
 {
 	*val = fault_around_order;
@@ -3395,7 +3393,6 @@ static int fault_around_order_get(void *data, u64 *val)
 
 static int fault_around_order_set(void *data, u64 val)
 {
-	BUILD_BUG_ON((1UL << FAULT_AROUND_ORDER) > PTRS_PER_PTE);
 	if (1UL << val > PTRS_PER_PTE)
 		return -EINVAL;
 	fault_around_order = val;
@@ -3430,14 +3427,14 @@ static inline unsigned long fault_around_pages(void)
 {
 	unsigned long nr_pages;
 
-	nr_pages = 1UL << FAULT_AROUND_ORDER;
+	nr_pages = 1UL << fault_around_order;
 	BUILD_BUG_ON(nr_pages > PTRS_PER_PTE);
 	return nr_pages;
 }
 
 static inline unsigned long fault_around_mask(void)
 {
-	return ~((1UL << (PAGE_SHIFT + FAULT_AROUND_ORDER)) - 1);
+	return ~((1UL << (PAGE_SHIFT + fault_around_order)) - 1);
 }
 #endif
 
@@ -3495,7 +3492,7 @@ static int do_read_fault(struct mm_struct *mm, struct vm_area_struct *vma,
 	 * if page by the offset is not ready to be mapped (cold cache or
 	 * something).
 	 */
-	if (vma->vm_ops->map_pages) {
+	if ((vma->vm_ops->map_pages) && (fault_around_order)) {
 		pte = pte_offset_map_lock(mm, pmd, address, &ptl);
 		do_fault_around(vma, address, pte, pgoff, flags);
 		if (!pte_same(*pte, orig_pte))
-- 
1.7.10.4

^ permalink raw reply related

* [PATCH V3 2/2] powerpc/pseries: init fault_around_order for pseries
From: Madhavan Srinivasan @ 2014-04-28  9:01 UTC (permalink / raw)
  To: linux-kernel, linuxppc-dev, linux-mm, linux-arch, x86
  Cc: riel, ak, peterz, rusty, dave.hansen, Madhavan Srinivasan, paulus,
	mgorman, akpm, mingo, kirill.shutemov
In-Reply-To: <1398675690-16186-1-git-send-email-maddy@linux.vnet.ibm.com>

Performance data for different FAULT_AROUND_ORDER values from 4 socket
Power7 system (128 Threads and 128GB memory). perf stat with repeat of 5
is used to get the stddev values. Test ran in v3.14 kernel (Baseline) and
v3.15-rc1 for different fault around order values.

FAULT_AROUND_ORDER      Baseline        1               3               4               5               8

Linux build (make -j64)
minor-faults            47,437,359      35,279,286      25,425,347      23,461,275      22,002,189      21,435,836
times in seconds        347.302528420   344.061588460   340.974022391   348.193508116   348.673900158   350.986543618
 stddev for time        ( +-  1.50% )   ( +-  0.73% )   ( +-  1.13% )   ( +-  1.01% )   ( +-  1.89% )   ( +-  1.55% )
 %chg time to baseline                  -0.9%           -1.8%           0.2%            0.39%           1.06%

Linux rebuild (make -j64)
minor-faults            941,552         718,319         486,625         440,124         410,510         397,416
times in seconds        30.569834718    31.219637539    31.319370649    31.434285472    31.972367174    31.443043580
 stddev for time        ( +-  1.07% )   ( +-  0.13% )   ( +-  0.43% )   ( +-  0.18% )   ( +-  0.95% )   ( +-  0.58% )
 %chg time to baseline                  2.1%            2.4%            2.8%            4.58%           2.85%

Binutils build (make all -j64 )
minor-faults            474,821         371,380         269,463         247,715         235,255         228,337
times in seconds        53.882492432    53.584289348    53.882773216    53.755816431    53.607824348    53.423759642
 stddev for time        ( +-  0.08% )   ( +-  0.56% )   ( +-  0.17% )   ( +-  0.11% )   ( +-  0.60% )   ( +-  0.69% )
 %chg time to baseline                  -0.55%          0.0%            -0.23%          -0.51%          -0.85%

Two synthetic tests: access every word in file in sequential/random order.

Sequential access 16GiB file
FAULT_AROUND_ORDER      Baseline        1               3               4               5               8
1 thread
       minor-faults     263,148         131,166         32,908          16,514          8,260           1,093
       times in seconds 53.091138345    53.113191672    53.188776177    53.233017218    53.206841347    53.429979442
       stddev for time  ( +-  0.06% )   ( +-  0.07% )   ( +-  0.08% )   ( +-  0.09% )   ( +-  0.03% )   ( +-  0.03% )
       %chg time to baseline            0.04%           0.18%           0.26%           0.21%           0.63%
8 threads
       minor-faults     2,097,267       1,048,753       262,237         131,397         65,621          8,274
       times in seconds 55.173790028    54.591880790    54.824623287    54.802162211    54.969680503    54.790387715
       stddev for time  ( +-  0.78% )   ( +-  0.09% )   ( +-  0.08% )   ( +-  0.07% )   ( +-  0.28% )   ( +-  0.05% )
       %chg time to baseline            -1.05%          -0.63%          -0.67%          -0.36%          -0.69%
32 threads
       minor-faults     8,388,751       4,195,621       1,049,664       525,461         262,535         32,924
       times in seconds 60.431573046    60.669110744    60.485336388    60.697789706    60.077959564    60.588855032
       stddev for time  ( +-  0.44% )   ( +-  0.27% )   ( +-  0.46% )   ( +-  0.67% )   ( +-  0.31% )   ( +-  0.49% )
       %chg time to baseline            0.39%           0.08%           0.44%           -0.58%          0.25%
64 threads
       minor-faults     16,777,409      8,607,527       2,289,766       1,202,264       598,405         67,587
       times in seconds 96.932617720    100.675418760   102.109880836   103.881733383   102.580199555   105.751194041
       stddev for time  ( +-  1.39% )   ( +-  1.06% )   ( +-  0.99% )   ( +-  0.76% )   ( +-  1.65% )   ( +-  1.60% )
       %chg time to baseline            3.86%           5.34%           7.16%           5.82%           9.09%
128 threads
       minor-faults     33,554,705      17,375,375      4,682,462       2,337,245       1,179,007       134,819
       times in seconds 128.766704495   115.659225437   120.353046307   115.291871270   115.450886036   113.991902150
       stddev for time  ( +-  2.93% )   ( +-  0.30% )   ( +-  2.93% )   ( +-  1.24% )   ( +-  1.03% )   ( +-  0.70% )
       %chg time to baseline            -10.17%         -6.53%          -10.46%         -10.34%         -11.47%

Random access 1GiB file
FAULT_AROUND_ORDER      Baseline        1               3               4               5               8
1 thread
       minor-faults     17,155          8,678           2,126           1,097           581             134
       times in seconds 51.904430523    51.658017987    51.919270792    51.560531738    52.354431597    51.976469502
       stddev for time  ( +-  3.19% )   ( +-  1.35% )   ( +-  1.56% )   ( +-  0.91% )   ( +-  1.70% )   ( +-  2.02% )
       %chg time to baseline            -0.47%          0.02%           -0.66%          0.86%           0.13%
8 threads
       minor-faults     131,844         70,705          17,457          8,505           4,251           598
       times in seconds 58.162813956    54.991706305    54.952675791    55.323057492    54.755587379    53.376722828
       stddev for time  ( +-  1.44% )   ( +-  0.69% )   ( +-  1.23% )   ( +-  2.78% )   ( +-  1.90% )   ( +-  2.91% )
       %chg time to baseline            -5.45%          -5.52%          -4.88%          -5.86%          -8.22%
32 threads
       minor-faults     524,437         270,760         67,069          33,414          16,641          2,204
       times in seconds 69.981777072    76.539570015    79.753578505    76.245943618    77.254258344    79.072596831
       stddev for time  ( +-  2.81% )   ( +-  1.95% )   ( +-  2.66% )   ( +-  0.99% )   ( +-  2.35% )   ( +-  3.22% )
       %chg time to baseline            9.37%           13.96%          8.95%           10.39%          12.98%
64 threads
       minor-faults     1,049,117       527,451         134,016         66,638          33,391          4,559
       times in seconds 108.024517536   117.575067996   115.322659914   111.943998437   115.049450815   119.218450840
       stddev for time  ( +-  2.40% )   ( +-  1.77% )   ( +-  1.19% )   ( +-  3.29% )   ( +-  2.32% )   ( +-  1.42% )
       %chg time to baseline            8.84%           6.75%           3.62%           6.5%            10.3%
128 threads
       minor-faults     2,097,440       1,054,360       267,042         133,328         66,532          8,652
       times in seconds 155.055861167   153.059625968   152.449492156   151.024005282   150.844647770   155.954366718
       stddev for time  ( +-  1.32% )   ( +-  1.14% )   ( +-  1.32% )   ( +-  0.81% )   ( +-  0.75% )   ( +-  0.72% )
       %chg time to baseline            -1.28%          -1.68%          -2.59%          -2.71%          0.57%

Incase of Kernel compilation, fault around order (fao) of 1 and 3 provides fast compilation time
when compared to a value of 4. On closer look, fao of 3 has higher agains. Incase of Sequential access
synthetic tests fao of 1 has higher gains and in Random access test, fao of 3 has marginal gains.
Going by compilation time, fao value of 3 is suggested in this patch for pseries platform.

Worst case scenario: we touch one page every 16M to demonstrate overhead.

Touch only one page in page table in 16GiB file
FAULT_AROUND_ORDER      Baseline        1               3               4               5               8
1 thread
       minor-faults     1,104           1,090           1,071           1,068           1,065           1,063
       times in seconds 0.006583298     0.008531502     0.019733795     0.036033763     0.062300553     0.406857086
       stddev for time  ( +-  2.79% )   ( +-  2.42% )   ( +-  3.47% )   ( +-  2.81% )   ( +-  2.01% )   ( +-  1.33% )
8 threads
       minor-faults     8,279           8,264           8,245           8,243           8,239           8,240
       times in seconds 0.044572398     0.057211811     0.107606306     0.205626815     0.381679120     2.647979955
       stddev for time  ( +-  1.95% )   ( +-  2.98% )   ( +-  1.74% )   ( +-  2.80% )   ( +-  2.01% )   ( +-  1.86% )
32 threads
       minor-faults     32,879          32,864          32,849          32,845          32,839          32,843
       times in seconds 0.197659343     0.218486087     0.445116407     0.694235883     1.296894038     9.127517045
       stddev for time  ( +-  3.05% )   ( +-  3.05% )   ( +-  4.33% )   ( +-  3.08% )   ( +-  3.75% )   ( +-  0.56% )
64 threads
       minor-faults     65,680          65,664          65,646          65,645          65,640          65,647
       times in seconds 0.455537304     0.489688780     0.866490093     1.427393118     2.379628982     17.059295051
       stddev for time  ( +-  4.01% )   ( +-  4.13% )   ( +-  2.92% )   ( +-  1.68% )   ( +-  1.79% )   ( +-  0.48% )
128 threads
       minor-faults     131,279         131,265         131,250         131,245         131,241         131,254
       times in seconds 1.026880651     1.095327536     1.721728274     2.808233068     4.662729948     31.732848290
       stddev for time  ( +-  6.85% )   ( +-  4.09% )   ( +-  1.71% )   ( +-  3.45% )   ( +-  2.40% )   ( +-  0.68% )

Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/setup.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 2db8cc6..c87e6b6 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -74,6 +74,8 @@ int CMO_SecPSP = -1;
 unsigned long CMO_PageSize = (ASM_CONST(1) << IOMMU_PAGE_SHIFT_4K);
 EXPORT_SYMBOL(CMO_PageSize);
 
+extern unsigned int fault_around_order;
+
 int fwnmi_active;  /* TRUE if an FWNMI handler is present */
 
 static struct device_node *pSeries_mpic_node;
@@ -465,6 +467,9 @@ static void __init pSeries_setup_arch(void)
 {
 	set_arch_panic_timeout(10, ARCH_PANIC_TIMEOUT);
 
+	/* Measured on a 4 socket Power7 system (128 Threads and 128GB memory) */
+	fault_around_order = 3;
+
 	/* Discover PIC type and setup ppc_md accordingly */
 	pseries_discover_pic();
 
-- 
1.7.10.4

^ permalink raw reply related

* Re: [PATCH V3 1/2] mm: move FAULT_AROUND_ORDER to arch/
From: Peter Zijlstra @ 2014-04-28  9:06 UTC (permalink / raw)
  To: Madhavan Srinivasan
  Cc: linux-arch, riel, rusty, dave.hansen, x86, linux-kernel, linux-mm,
	ak, paulus, mgorman, akpm, linuxppc-dev, mingo, kirill.shutemov
In-Reply-To: <1398675690-16186-2-git-send-email-maddy@linux.vnet.ibm.com>

On Mon, Apr 28, 2014 at 02:31:29PM +0530, Madhavan Srinivasan wrote:
> +unsigned int fault_around_order = CONFIG_FAULT_AROUND_ORDER;

__read_mostly?

^ permalink raw reply

* RE: [RFC PATCH] Fix Oops in rtas_stop_self()
From: David Laight @ 2014-04-28  9:06 UTC (permalink / raw)
  To: 'Li Zhong', Anton Blanchard
  Cc: PowerPC email list, Benjamin Herrenschmidt, Paul Mackerras
In-Reply-To: <1398644805.3046.7.camel@ThinkPad-T5421>

RnJvbTogTGkgWmhvbmcNCj4gT24gRnJpLCAyMDE0LTA0LTI1IGF0IDIyOjE4ICsxMDAwLCBBbnRv
biBCbGFuY2hhcmQgd3JvdGU6DQo+ID4gSGksDQo+ID4NCj4gPiA+IFdoZW4gdHJ5aW5nIG9mZmxp
bmUgY3B1cywgSSBub3RpY2VkIGZvbGxvd2luZyBPb3BzIGluDQo+ID4gPiBydGFzX3N0b3Bfc2Vs
ZigpLCBhbmQgaXQgc2VlbXMgY2F1c2VkIGJ5IGNvbW1pdCA0MWRkMDNhOS4gVGhlIE9vcHMNCj4g
PiA+IGRpc2FwcGVhcnMgYWZ0ZXIgcmV2ZXJ0aW5nIHRoaXMgY29tbWl0Lg0KPiA+ID4NCj4gPiA+
IEFmdGVyIHJlYWRpbmcgdGhlIGNvZGUsIEkgZ3Vlc3MgaXQgbWlnaHQgYmUgY2F1c2VkIGJ5IG1v
dmluZyB0aGUNCj4gPiA+IHJ0YXNfYXJncyB0byBzdGFjay4gU3RpbGwgbmVlZCBzb21lIG1vcmUg
dGltZSB0byByZWFkIGVudGVyX3J0YXMgdG8NCj4gPiA+IHVuZGVyc3RhbmQgd2h5IGl0IGhhcHBl
bnMsIGJ1dCB0aGUgcHJvYmxlbSBzZWVtcyBjb3VsZCBiZSBzb2x2ZWQgYnkNCj4gPiA+IG1vdmlu
ZyB0aGUgcnRhc19hcmdzIGF3YXkgZnJvbSBzdGFjayBieSBhZGRpbmcgc3RhdGljIGJlZm9yZSBp
dC4NCj4gPg0KPiA+IE5pY2UgY2F0Y2guIFJUQVMgaXMgMzJiaXQgYW5kIGlmIHlvdXIgYm94IGhh
cyBtb3JlIHRoYW4gNEdCIFJBTSB0aGVuDQo+ID4geW91ciBzdGFjayBjb3VsZCBlYXNpbHkgYmUg
b3V0c2lkZSAzMmJpdCByYW5nZS4NCj4gDQo+IEFoLCB5ZXMsIHRoZSBzdGFjayBoZXJlIGlzIG9i
dmlvdXNseSBhdCBhIG11Y2ggaGlnaGVyIGFkZHJlc3MgdGhhbiA0R0IuDQoNCkFyZSB3ZSB0YWxr
aW5nIG9mIHBoeXNpY2FsIG9yIHZpcnR1YWwgYWRkcmVzc2VzIGhlcmU/DQoob3IgZXZlbiB1c2Vy
PykNCg0KSXMgdGhlcmUgYSByZS1lbnRyYW5jeSBwcm9ibGVtIHVzaW5nIGtlcm5lbCBzdGF0aWMg
ZGF0YT8NCg0KCURhdmlkDQoNCg==

^ permalink raw reply

* Re: [RFC PATCH] Fix Oops in rtas_stop_self()
From: Benjamin Herrenschmidt @ 2014-04-28  9:17 UTC (permalink / raw)
  To: David Laight
  Cc: PowerPC email list, Paul Mackerras, Anton Blanchard,
	'Li Zhong'
In-Reply-To: <063D6719AE5E284EB5DD2968C1650D6D0F700501@AcuExch.aculab.com>

On Mon, 2014-04-28 at 09:06 +0000, David Laight wrote:
> > Ah, yes, the stack here is obviously at a much higher address than
> 4GB.
> 
> Are we talking of physical or virtual addresses here?
> (or even user?)

Real.

> Is there a re-entrancy problem using kernel static data?

Not for this code. This is called as the last thing a CPU does
before returning to firmware.

Cheers,
Ben.

^ permalink raw reply

* RE: [PATCH V3 1/2] mm: move FAULT_AROUND_ORDER to arch/
From: Kirill A. Shutemov @ 2014-04-28  9:36 UTC (permalink / raw)
  To: Madhavan Srinivasan
  Cc: linux-arch, riel, rusty, dave.hansen, peterz, x86, linux-kernel,
	Madhavan Srinivasan, linux-mm, ak, paulus, mgorman, akpm,
	linuxppc-dev, mingo, kirill.shutemov
In-Reply-To: <1398675690-16186-2-git-send-email-maddy@linux.vnet.ibm.com>

Madhavan Srinivasan wrote:
> Kirill A. Shutemov with 8c6e50b029 commit introduced
> vm_ops->map_pages() for mapping easy accessible pages around
> fault address in hope to reduce number of minor page faults.
> 
> This patch creates infrastructure to modify the FAULT_AROUND_ORDER
> value using mm/Kconfig. This will enable architecture maintainers
> to decide on suitable FAULT_AROUND_ORDER value based on
> performance data for that architecture. Patch also defaults
> FAULT_AROUND_ORDER Kconfig element to 4.
> 
> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
> ---
>  mm/Kconfig  |    8 ++++++++
>  mm/memory.c |   11 ++++-------
>  2 files changed, 12 insertions(+), 7 deletions(-)
> 
> diff --git a/mm/Kconfig b/mm/Kconfig
> index ebe5880..c7fc4f1 100644
> --- a/mm/Kconfig
> +++ b/mm/Kconfig
> @@ -176,6 +176,14 @@ config MOVABLE_NODE
>  config HAVE_BOOTMEM_INFO_NODE
>  	def_bool n
>  
> +#
> +# Fault around order is a control knob to decide the fault around pages.
> +# Default value is set to 4 , but the arch can override it as desired.
> +#
> +config FAULT_AROUND_ORDER
> +	int
> +	default	4
> +
>  # eventually, we can have this option just 'select SPARSEMEM'
>  config MEMORY_HOTPLUG
>  	bool "Allow for memory hot-add"
> diff --git a/mm/memory.c b/mm/memory.c
> index d0f0bef..457436d 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -3382,11 +3382,9 @@ void do_set_pte(struct vm_area_struct *vma, unsigned long address,
>  	update_mmu_cache(vma, address, pte);
>  }
>  
> -#define FAULT_AROUND_ORDER 4
> +unsigned int fault_around_order = CONFIG_FAULT_AROUND_ORDER;
>  
>  #ifdef CONFIG_DEBUG_FS
> -static unsigned int fault_around_order = FAULT_AROUND_ORDER;
> -
>  static int fault_around_order_get(void *data, u64 *val)
>  {
>  	*val = fault_around_order;
> @@ -3395,7 +3393,6 @@ static int fault_around_order_get(void *data, u64 *val)
>  
>  static int fault_around_order_set(void *data, u64 val)
>  {
> -	BUILD_BUG_ON((1UL << FAULT_AROUND_ORDER) > PTRS_PER_PTE);
>  	if (1UL << val > PTRS_PER_PTE)
>  		return -EINVAL;
>  	fault_around_order = val;
> @@ -3430,14 +3427,14 @@ static inline unsigned long fault_around_pages(void)
>  {
>  	unsigned long nr_pages;
>  
> -	nr_pages = 1UL << FAULT_AROUND_ORDER;
> +	nr_pages = 1UL << fault_around_order;
>  	BUILD_BUG_ON(nr_pages > PTRS_PER_PTE);

This BUILD_BUG_ON() doesn't make sense any more since compiler usually can't
prove anything about extern variable.

Drop it or change to VM_BUG_ON() or something.

>  	return nr_pages;
>  }
>  
>  static inline unsigned long fault_around_mask(void)
>  {
> -	return ~((1UL << (PAGE_SHIFT + FAULT_AROUND_ORDER)) - 1);
> +	return ~((1UL << (PAGE_SHIFT + fault_around_order)) - 1);

fault_around_pages() and fault_around_mask() should be moved outside of
#ifdef CONFIG_DEBUG_FS and consolidated since they are practically identical
both branches after the changes.

>  }
>  #endif
>  
> @@ -3495,7 +3492,7 @@ static int do_read_fault(struct mm_struct *mm, struct vm_area_struct *vma,
>  	 * if page by the offset is not ready to be mapped (cold cache or
>  	 * something).
>  	 */
> -	if (vma->vm_ops->map_pages) {
> +	if ((vma->vm_ops->map_pages) && (fault_around_order)) {

Way too many parentheses.

>  		pte = pte_offset_map_lock(mm, pmd, address, &ptl);
>  		do_fault_around(vma, address, pte, pgoff, flags);
>  		if (!pte_same(*pte, orig_pte))
-- 
 Kirill A. Shutemov

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox