LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] powerpc: Fix build failure
From: Pranith Kumar @ 2014-08-21 13:04 UTC (permalink / raw)
  To: Alistair Popple, Matt Porter, Benjamin Herrenschmidt,
	Paul Mackerras, Michael Ellerman, open list:LINUX FOR POWERPC...,
	open list

Fix the following build failure

drivers/built-in.o: In function `nhi_init':
nhi.c:(.init.text+0x63390): undefined reference to `ehci_init_driver'

by adding a dependency on USB_EHCI_HCD which supplies the ehci_init_driver().

Also we need to depend on USB_OHCI_HCD similarly

Signed-off-by: Pranith Kumar <bobby.prani@gmail.com>
---
 arch/powerpc/platforms/44x/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig
index 4d88f6a..3e7deb2 100644
--- a/arch/powerpc/platforms/44x/Kconfig
+++ b/arch/powerpc/platforms/44x/Kconfig
@@ -216,8 +216,8 @@ config AKEBONO
 	select IBM_EMAC_EMAC4
 	select IBM_EMAC_RGMII_WOL
 	select USB
-	select USB_OHCI_HCD_PLATFORM
-	select USB_EHCI_HCD_PLATFORM
+	select USB_OHCI_HCD_PLATFORM if USB_OHCI_HCD
+	select USB_EHCI_HCD_PLATFORM if USB_EHCI_HCD
 	select MMC_SDHCI
 	select MMC_SDHCI_PLTFM
 	select MMC_SDHCI_OF_476GTR
-- 
1.9.1

^ permalink raw reply related

* [PATCH v3 00/11] drivers: cacheinfo support
From: Sudeep Holla @ 2014-08-21 10:59 UTC (permalink / raw)
  To: LKML
  Cc: linux-s390, Lorenzo Pieralisi, linux-ia64, Heiko Carstens,
	sudeep.holla, Stephen Boyd, x86, Greg Kroah-Hartman, linux390,
	linuxppc-dev, linux-arm-kernel
In-Reply-To: <1406306692-7135-1-git-send-email-sudeep.holla@arm.com>

From: Sudeep Holla <sudeep.holla@arm.com>

This series adds a generic cacheinfo support similar to topology. The
implementation is based on x86 cacheinfo support. Currently x86, powerpc,
ia64 and s390 have their own implementations. While adding similar support
to ARM and ARM64, here is the attempt to make it generic quite similar to
topology info support. It also adds the missing ABI documentation for
the cacheinfo sysfs which is already being used.

It moves all the existing different implementations on x86, ia64, powerpc
and s390 to use the generic cacheinfo infrastructure introduced here.
These changes on non-ARM platforms are only compile tested and tested on x86.

This series also adds support for ARM and ARM64 architectures based on
the generic support.

The code can be fetched from:
 git://linux-arm.org/linux-skn cacheinfo

Changes v2->v3:
	- Added {allocation,write}_policy instead of single attributes sysfs
	  (attributes retained on ia64 privately as it was used only on that)
	- factored out show_cpumap into separate helper in cpumask.h
	- populate cpu_{map,list} for non-DT system if they are not populated
	  by arch specific callbacks
	- removed use of sysfs *_show callback in cache_attrs_is_visible
	- all the review comments from Stephen Boyd implemented

Changes v1->v2:
	- removed custom device_{add,remove}_attrs, using is_visible callback
	  instead(suggested by GregKH)
	- arm64: changes as per MarkR review comments
	- Moved smp_call_function_single to architectures using it(arm, arm64,
	  x86) (suggested by Stephen Boyd)
	- arm (mostly changes as per RMK's review comments)
		- fixed to allow v7 + v6 build
		- l2 cache changes to remove extra structure
		- populated CTR for few StrongARM CPU's not implementing CTR

[v1] https://lkml.org/lkml/2014/6/25/603
[v2] https://lkml.org/lkml/2014/7/25/467

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-ia64@vger.kernel.org
Cc: linux390@de.ibm.com
Cc: linux-s390@vger.kernel.org
Cc: x86@kernel.org
Cc: linuxppc-dev@lists.ozlabs.org
Cc: linux-arm-kernel@lists.infradead.org

Sudeep Holla (11):
  cpumask: factor out show_cpumap into separate helper function
  topology: replace custom attribute macros with standard DEVICE_ATTR*
  drivers: base: add new class "cpu" to group cpu devices
  drivers: base: support cpu cache information interface to userspace
    via sysfs
  ia64: move cacheinfo sysfs to generic cacheinfo infrastructure
  s390: move cacheinfo sysfs to generic cacheinfo infrastructure
  x86: move cacheinfo sysfs to generic cacheinfo infrastructure
  powerpc: move cacheinfo sysfs to generic cacheinfo infrastructure
  ARM64: kernel: add support for cpu cache information
  ARM: kernel: add support for cpu cache information
  ARM: kernel: add outer cache support for cacheinfo implementation

 Documentation/ABI/testing/sysfs-devices-system-cpu |  47 ++
 arch/arm/include/asm/outercache.h                  |   9 +
 arch/arm/kernel/Makefile                           |   1 +
 arch/arm/kernel/cacheinfo.c                        | 287 ++++++++
 arch/arm/mm/Kconfig                                |  13 +
 arch/arm/mm/cache-l2x0.c                           |  35 +-
 arch/arm/mm/cache-tauros2.c                        |  36 +
 arch/arm/mm/cache-xsc3l2.c                         |  17 +
 arch/arm64/kernel/Makefile                         |   2 +-
 arch/arm64/kernel/cacheinfo.c                      | 142 ++++
 arch/ia64/kernel/topology.c                        | 421 +++--------
 arch/powerpc/kernel/cacheinfo.c                    | 812 +++------------------
 arch/powerpc/kernel/cacheinfo.h                    |   8 -
 arch/powerpc/kernel/sysfs.c                        |  12 +-
 arch/s390/kernel/cache.c                           | 388 +++-------
 arch/x86/kernel/cpu/intel_cacheinfo.c              | 709 +++++-------------
 arch/x86/kernel/cpu/perf_event_amd_iommu.c         |   5 +-
 arch/x86/kernel/cpu/perf_event_amd_uncore.c        |   6 +-
 arch/x86/kernel/cpu/perf_event_intel_rapl.c        |   6 +-
 arch/x86/kernel/cpu/perf_event_intel_uncore.c      |   6 +-
 drivers/acpi/acpi_pad.c                            |   6 +-
 drivers/base/Makefile                              |   2 +-
 drivers/base/cacheinfo.c                           | 543 ++++++++++++++
 drivers/base/core.c                                |  39 +-
 drivers/base/cpu.c                                 |  12 +-
 drivers/base/node.c                                |  14 +-
 drivers/base/topology.c                            |  71 +-
 drivers/pci/pci-sysfs.c                            |  39 +-
 include/linux/cacheinfo.h                          | 100 +++
 include/linux/cpu.h                                |   2 +
 include/linux/cpumask.h                            |  27 +
 31 files changed, 1826 insertions(+), 1991 deletions(-)
 create mode 100644 arch/arm/kernel/cacheinfo.c
 create mode 100644 arch/arm64/kernel/cacheinfo.c
 delete mode 100644 arch/powerpc/kernel/cacheinfo.h
 create mode 100644 drivers/base/cacheinfo.c
 create mode 100644 include/linux/cacheinfo.h

-- 
1.8.3.2

^ permalink raw reply

* [PATCH v3 08/11] powerpc: move cacheinfo sysfs to generic cacheinfo infrastructure
From: Sudeep Holla @ 2014-08-21 10:59 UTC (permalink / raw)
  To: LKML
  Cc: Lorenzo Pieralisi, Heiko Carstens, sudeep.holla, Stephen Boyd,
	Paul Mackerras, linuxppc-dev
In-Reply-To: <1408618794-28497-1-git-send-email-sudeep.holla@arm.com>

From: Sudeep Holla <sudeep.holla@arm.com>

This patch removes the redundant sysfs cacheinfo code by making use of
the newly introduced generic cacheinfo infrastructure.

Signed-off-by: Sudeep Holla <sudeep.holla@arm.com>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
---
 arch/powerpc/kernel/cacheinfo.c | 812 +++++-----------------------------------
 arch/powerpc/kernel/cacheinfo.h |   8 -
 arch/powerpc/kernel/sysfs.c     |  12 +-
 3 files changed, 90 insertions(+), 742 deletions(-)
 delete mode 100644 arch/powerpc/kernel/cacheinfo.h

diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c
index 40198d50b4c2..6845eb7fcc18 100644
--- a/arch/powerpc/kernel/cacheinfo.c
+++ b/arch/powerpc/kernel/cacheinfo.c
@@ -10,38 +10,10 @@
  * 2 as published by the Free Software Foundation.
  */
 
+#include <linux/cacheinfo.h>
 #include <linux/cpu.h>
-#include <linux/cpumask.h>
 #include <linux/kernel.h>
-#include <linux/kobject.h>
-#include <linux/list.h>
-#include <linux/notifier.h>
 #include <linux/of.h>
-#include <linux/percpu.h>
-#include <linux/slab.h>
-#include <asm/prom.h>
-
-#include "cacheinfo.h"
-
-/* per-cpu object for tracking:
- * - a "cache" kobject for the top-level directory
- * - a list of "index" objects representing the cpu's local cache hierarchy
- */
-struct cache_dir {
-	struct kobject *kobj; /* bare (not embedded) kobject for cache
-			       * directory */
-	struct cache_index_dir *index; /* list of index objects */
-};
-
-/* "index" object: each cpu's cache directory has an index
- * subdirectory corresponding to a cache object associated with the
- * cpu.  This object's lifetime is managed via the embedded kobject.
- */
-struct cache_index_dir {
-	struct kobject kobj;
-	struct cache_index_dir *next; /* next index in parent directory */
-	struct cache *cache;
-};
 
 /* Template for determining which OF properties to query for a given
  * cache type */
@@ -60,11 +32,6 @@ struct cache_type_info {
 	const char *nr_sets_prop;
 };
 
-/* These are used to index the cache_type_info array. */
-#define CACHE_TYPE_UNIFIED     0
-#define CACHE_TYPE_INSTRUCTION 1
-#define CACHE_TYPE_DATA        2
-
 static const struct cache_type_info cache_type_info[] = {
 	{
 		/* PowerPC Processor binding says the [di]-cache-*
@@ -92,231 +59,82 @@ static const struct cache_type_info cache_type_info[] = {
 	},
 };
 
-/* Cache object: each instance of this corresponds to a distinct cache
- * in the system.  There are separate objects for Harvard caches: one
- * each for instruction and data, and each refers to the same OF node.
- * The refcount of the OF node is elevated for the lifetime of the
- * cache object.  A cache object is released when its shared_cpu_map
- * is cleared (see cache_cpu_clear).
- *
- * A cache object is on two lists: an unsorted global list
- * (cache_list) of cache objects; and a singly-linked list
- * representing the local cache hierarchy, which is ordered by level
- * (e.g. L1d -> L1i -> L2 -> L3).
- */
-struct cache {
-	struct device_node *ofnode;    /* OF node for this cache, may be cpu */
-	struct cpumask shared_cpu_map; /* online CPUs using this cache */
-	int type;                      /* split cache disambiguation */
-	int level;                     /* level not explicit in device tree */
-	struct list_head list;         /* global list of cache objects */
-	struct cache *next_local;      /* next cache of >= level */
-};
-
-static DEFINE_PER_CPU(struct cache_dir *, cache_dir_pcpu);
-
-/* traversal/modification of this list occurs only at cpu hotplug time;
- * access is serialized by cpu hotplug locking
- */
-static LIST_HEAD(cache_list);
-
-static struct cache_index_dir *kobj_to_cache_index_dir(struct kobject *k)
-{
-	return container_of(k, struct cache_index_dir, kobj);
-}
-
-static const char *cache_type_string(const struct cache *cache)
+static inline int get_cacheinfo_idx(enum cache_type type)
 {
-	return cache_type_info[cache->type].name;
-}
-
-static void cache_init(struct cache *cache, int type, int level,
-		       struct device_node *ofnode)
-{
-	cache->type = type;
-	cache->level = level;
-	cache->ofnode = of_node_get(ofnode);
-	INIT_LIST_HEAD(&cache->list);
-	list_add(&cache->list, &cache_list);
-}
-
-static struct cache *new_cache(int type, int level, struct device_node *ofnode)
-{
-	struct cache *cache;
-
-	cache = kzalloc(sizeof(*cache), GFP_KERNEL);
-	if (cache)
-		cache_init(cache, type, level, ofnode);
-
-	return cache;
-}
-
-static void release_cache_debugcheck(struct cache *cache)
-{
-	struct cache *iter;
-
-	list_for_each_entry(iter, &cache_list, list)
-		WARN_ONCE(iter->next_local == cache,
-			  "cache for %s(%s) refers to cache for %s(%s)\n",
-			  iter->ofnode->full_name,
-			  cache_type_string(iter),
-			  cache->ofnode->full_name,
-			  cache_type_string(cache));
-}
-
-static void release_cache(struct cache *cache)
-{
-	if (!cache)
-		return;
-
-	pr_debug("freeing L%d %s cache for %s\n", cache->level,
-		 cache_type_string(cache), cache->ofnode->full_name);
-
-	release_cache_debugcheck(cache);
-	list_del(&cache->list);
-	of_node_put(cache->ofnode);
-	kfree(cache);
-}
-
-static void cache_cpu_set(struct cache *cache, int cpu)
-{
-	struct cache *next = cache;
-
-	while (next) {
-		WARN_ONCE(cpumask_test_cpu(cpu, &next->shared_cpu_map),
-			  "CPU %i already accounted in %s(%s)\n",
-			  cpu, next->ofnode->full_name,
-			  cache_type_string(next));
-		cpumask_set_cpu(cpu, &next->shared_cpu_map);
-		next = next->next_local;
-	}
+	if (type == CACHE_TYPE_UNIFIED)
+		return 0;
+	return type;
 }
 
-static int cache_size(const struct cache *cache, unsigned int *ret)
+static void cache_size(struct cacheinfo *this_leaf)
 {
 	const char *propname;
 	const __be32 *cache_size;
+	int ct_idx;
 
-	propname = cache_type_info[cache->type].size_prop;
+	ct_idx = get_cacheinfo_idx(this_leaf->type);
+	propname = cache_type_info[ct_idx].size_prop;
 
-	cache_size = of_get_property(cache->ofnode, propname, NULL);
+	cache_size = of_get_property(this_leaf->of_node, propname, NULL);
 	if (!cache_size)
-		return -ENODEV;
-
-	*ret = of_read_number(cache_size, 1);
-	return 0;
-}
-
-static int cache_size_kb(const struct cache *cache, unsigned int *ret)
-{
-	unsigned int size;
-
-	if (cache_size(cache, &size))
-		return -ENODEV;
-
-	*ret = size / 1024;
-	return 0;
+		this_leaf->size = 0;
+	else
+		this_leaf->size = of_read_number(cache_size, 1);
 }
 
 /* not cache_line_size() because that's a macro in include/linux/cache.h */
-static int cache_get_line_size(const struct cache *cache, unsigned int *ret)
+static void cache_get_line_size(struct cacheinfo *this_leaf)
 {
 	const __be32 *line_size;
-	int i, lim;
+	int i, lim, ct_idx;
 
-	lim = ARRAY_SIZE(cache_type_info[cache->type].line_size_props);
+	ct_idx = get_cacheinfo_idx(this_leaf->type);
+	lim = ARRAY_SIZE(cache_type_info[ct_idx].line_size_props);
 
 	for (i = 0; i < lim; i++) {
 		const char *propname;
 
-		propname = cache_type_info[cache->type].line_size_props[i];
-		line_size = of_get_property(cache->ofnode, propname, NULL);
+		propname = cache_type_info[ct_idx].line_size_props[i];
+		line_size = of_get_property(this_leaf->of_node, propname, NULL);
 		if (line_size)
 			break;
 	}
 
 	if (!line_size)
-		return -ENODEV;
-
-	*ret = of_read_number(line_size, 1);
-	return 0;
+		this_leaf->coherency_line_size = 0;
+	else
+		this_leaf->coherency_line_size = of_read_number(line_size, 1);
 }
 
-static int cache_nr_sets(const struct cache *cache, unsigned int *ret)
+static void cache_nr_sets(struct cacheinfo *this_leaf)
 {
 	const char *propname;
 	const __be32 *nr_sets;
+	int ct_idx;
 
-	propname = cache_type_info[cache->type].nr_sets_prop;
+	ct_idx = get_cacheinfo_idx(this_leaf->type);
+	propname = cache_type_info[ct_idx].nr_sets_prop;
 
-	nr_sets = of_get_property(cache->ofnode, propname, NULL);
+	nr_sets = of_get_property(this_leaf->of_node, propname, NULL);
 	if (!nr_sets)
-		return -ENODEV;
-
-	*ret = of_read_number(nr_sets, 1);
-	return 0;
+		this_leaf->number_of_sets = 0;
+	else
+		this_leaf->number_of_sets = of_read_number(nr_sets, 1);
 }
 
-static int cache_associativity(const struct cache *cache, unsigned int *ret)
+static void cache_associativity(struct cacheinfo *this_leaf)
 {
-	unsigned int line_size;
-	unsigned int nr_sets;
-	unsigned int size;
-
-	if (cache_nr_sets(cache, &nr_sets))
-		goto err;
+	unsigned int line_size = this_leaf->coherency_line_size;
+	unsigned int nr_sets = this_leaf->number_of_sets;
+	unsigned int size = this_leaf->size;
 
 	/* If the cache is fully associative, there is no need to
 	 * check the other properties.
 	 */
-	if (nr_sets == 1) {
-		*ret = 0;
-		return 0;
-	}
-
-	if (cache_get_line_size(cache, &line_size))
-		goto err;
-	if (cache_size(cache, &size))
-		goto err;
-
-	if (!(nr_sets > 0 && size > 0 && line_size > 0))
-		goto err;
-
-	*ret = (size / nr_sets) / line_size;
-	return 0;
-err:
-	return -ENODEV;
-}
-
-/* helper for dealing with split caches */
-static struct cache *cache_find_first_sibling(struct cache *cache)
-{
-	struct cache *iter;
-
-	if (cache->type == CACHE_TYPE_UNIFIED)
-		return cache;
-
-	list_for_each_entry(iter, &cache_list, list)
-		if (iter->ofnode == cache->ofnode && iter->next_local == cache)
-			return iter;
-
-	return cache;
-}
-
-/* return the first cache on a local list matching node */
-static struct cache *cache_lookup_by_node(const struct device_node *node)
-{
-	struct cache *cache = NULL;
-	struct cache *iter;
-
-	list_for_each_entry(iter, &cache_list, list) {
-		if (iter->ofnode != node)
-			continue;
-		cache = cache_find_first_sibling(iter);
-		break;
-	}
-
-	return cache;
+	if ((nr_sets == 1) || !(nr_sets > 0 && size > 0 && line_size > 0))
+		this_leaf->ways_of_associativity = 0;
+	else
+		this_leaf->ways_of_associativity = (size / nr_sets) / line_size;
 }
 
 static bool cache_node_is_unified(const struct device_node *np)
@@ -324,526 +142,74 @@ static bool cache_node_is_unified(const struct device_node *np)
 	return of_get_property(np, "cache-unified", NULL);
 }
 
-static struct cache *cache_do_one_devnode_unified(struct device_node *node,
-						  int level)
-{
-	struct cache *cache;
-
-	pr_debug("creating L%d ucache for %s\n", level, node->full_name);
-
-	cache = new_cache(CACHE_TYPE_UNIFIED, level, node);
-
-	return cache;
-}
-
-static struct cache *cache_do_one_devnode_split(struct device_node *node,
-						int level)
-{
-	struct cache *dcache, *icache;
-
-	pr_debug("creating L%d dcache and icache for %s\n", level,
-		 node->full_name);
-
-	dcache = new_cache(CACHE_TYPE_DATA, level, node);
-	icache = new_cache(CACHE_TYPE_INSTRUCTION, level, node);
-
-	if (!dcache || !icache)
-		goto err;
-
-	dcache->next_local = icache;
-
-	return dcache;
-err:
-	release_cache(dcache);
-	release_cache(icache);
-	return NULL;
-}
-
-static struct cache *cache_do_one_devnode(struct device_node *node, int level)
-{
-	struct cache *cache;
-
-	if (cache_node_is_unified(node))
-		cache = cache_do_one_devnode_unified(node, level);
-	else
-		cache = cache_do_one_devnode_split(node, level);
-
-	return cache;
-}
-
-static struct cache *cache_lookup_or_instantiate(struct device_node *node,
-						 int level)
-{
-	struct cache *cache;
-
-	cache = cache_lookup_by_node(node);
-
-	WARN_ONCE(cache && cache->level != level,
-		  "cache level mismatch on lookup (got %d, expected %d)\n",
-		  cache->level, level);
-
-	if (!cache)
-		cache = cache_do_one_devnode(node, level);
-
-	return cache;
-}
-
-static void link_cache_lists(struct cache *smaller, struct cache *bigger)
-{
-	while (smaller->next_local) {
-		if (smaller->next_local == bigger)
-			return; /* already linked */
-		smaller = smaller->next_local;
-	}
-
-	smaller->next_local = bigger;
-}
-
-static void do_subsidiary_caches_debugcheck(struct cache *cache)
-{
-	WARN_ON_ONCE(cache->level != 1);
-	WARN_ON_ONCE(strcmp(cache->ofnode->type, "cpu"));
-}
-
-static void do_subsidiary_caches(struct cache *cache)
-{
-	struct device_node *subcache_node;
-	int level = cache->level;
-
-	do_subsidiary_caches_debugcheck(cache);
-
-	while ((subcache_node = of_find_next_cache_node(cache->ofnode))) {
-		struct cache *subcache;
-
-		level++;
-		subcache = cache_lookup_or_instantiate(subcache_node, level);
-		of_node_put(subcache_node);
-		if (!subcache)
-			break;
-
-		link_cache_lists(cache, subcache);
-		cache = subcache;
-	}
-}
-
-static struct cache *cache_chain_instantiate(unsigned int cpu_id)
+static void ci_leaf_init(struct cacheinfo *this_leaf,
+			 enum cache_type type, unsigned int level)
 {
-	struct device_node *cpu_node;
-	struct cache *cpu_cache = NULL;
-
-	pr_debug("creating cache object(s) for CPU %i\n", cpu_id);
-
-	cpu_node = of_get_cpu_node(cpu_id, NULL);
-	WARN_ONCE(!cpu_node, "no OF node found for CPU %i\n", cpu_id);
-	if (!cpu_node)
-		goto out;
-
-	cpu_cache = cache_lookup_or_instantiate(cpu_node, 1);
-	if (!cpu_cache)
-		goto out;
-
-	do_subsidiary_caches(cpu_cache);
-
-	cache_cpu_set(cpu_cache, cpu_id);
-out:
-	of_node_put(cpu_node);
-
-	return cpu_cache;
+	this_leaf->level = level;
+	this_leaf->type = type;
+	cache_size(this_leaf);
+	cache_get_line_size(this_leaf);
+	cache_nr_sets(this_leaf);
+	cache_associativity(this_leaf);
 }
 
-static struct cache_dir *cacheinfo_create_cache_dir(unsigned int cpu_id)
+int init_cache_level(unsigned int cpu)
 {
-	struct cache_dir *cache_dir;
-	struct device *dev;
-	struct kobject *kobj = NULL;
-
-	dev = get_cpu_device(cpu_id);
-	WARN_ONCE(!dev, "no dev for CPU %i\n", cpu_id);
-	if (!dev)
-		goto err;
-
-	kobj = kobject_create_and_add("cache", &dev->kobj);
-	if (!kobj)
-		goto err;
-
-	cache_dir = kzalloc(sizeof(*cache_dir), GFP_KERNEL);
-	if (!cache_dir)
-		goto err;
-
-	cache_dir->kobj = kobj;
-
-	WARN_ON_ONCE(per_cpu(cache_dir_pcpu, cpu_id) != NULL);
-
-	per_cpu(cache_dir_pcpu, cpu_id) = cache_dir;
+	struct device_node *np;
+	struct device *cpu_dev = get_cpu_device(cpu);
+	struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
+	unsigned int level = 0, leaves = 0;
 
-	return cache_dir;
-err:
-	kobject_put(kobj);
-	return NULL;
-}
-
-static void cache_index_release(struct kobject *kobj)
-{
-	struct cache_index_dir *index;
-
-	index = kobj_to_cache_index_dir(kobj);
-
-	pr_debug("freeing index directory for L%d %s cache\n",
-		 index->cache->level, cache_type_string(index->cache));
-
-	kfree(index);
-}
-
-static ssize_t cache_index_show(struct kobject *k, struct attribute *attr, char *buf)
-{
-	struct kobj_attribute *kobj_attr;
-
-	kobj_attr = container_of(attr, struct kobj_attribute, attr);
-
-	return kobj_attr->show(k, kobj_attr, buf);
-}
-
-static struct cache *index_kobj_to_cache(struct kobject *k)
-{
-	struct cache_index_dir *index;
-
-	index = kobj_to_cache_index_dir(k);
-
-	return index->cache;
-}
-
-static ssize_t size_show(struct kobject *k, struct kobj_attribute *attr, char *buf)
-{
-	unsigned int size_kb;
-	struct cache *cache;
-
-	cache = index_kobj_to_cache(k);
-
-	if (cache_size_kb(cache, &size_kb))
-		return -ENODEV;
-
-	return sprintf(buf, "%uK\n", size_kb);
-}
-
-static struct kobj_attribute cache_size_attr =
-	__ATTR(size, 0444, size_show, NULL);
-
-
-static ssize_t line_size_show(struct kobject *k, struct kobj_attribute *attr, char *buf)
-{
-	unsigned int line_size;
-	struct cache *cache;
-
-	cache = index_kobj_to_cache(k);
-
-	if (cache_get_line_size(cache, &line_size))
-		return -ENODEV;
-
-	return sprintf(buf, "%u\n", line_size);
-}
-
-static struct kobj_attribute cache_line_size_attr =
-	__ATTR(coherency_line_size, 0444, line_size_show, NULL);
-
-static ssize_t nr_sets_show(struct kobject *k, struct kobj_attribute *attr, char *buf)
-{
-	unsigned int nr_sets;
-	struct cache *cache;
-
-	cache = index_kobj_to_cache(k);
-
-	if (cache_nr_sets(cache, &nr_sets))
+	if (!cpu_dev) {
+		pr_err("No cpu device for CPU %d\n", cpu);
 		return -ENODEV;
-
-	return sprintf(buf, "%u\n", nr_sets);
-}
-
-static struct kobj_attribute cache_nr_sets_attr =
-	__ATTR(number_of_sets, 0444, nr_sets_show, NULL);
-
-static ssize_t associativity_show(struct kobject *k, struct kobj_attribute *attr, char *buf)
-{
-	unsigned int associativity;
-	struct cache *cache;
-
-	cache = index_kobj_to_cache(k);
-
-	if (cache_associativity(cache, &associativity))
-		return -ENODEV;
-
-	return sprintf(buf, "%u\n", associativity);
-}
-
-static struct kobj_attribute cache_assoc_attr =
-	__ATTR(ways_of_associativity, 0444, associativity_show, NULL);
-
-static ssize_t type_show(struct kobject *k, struct kobj_attribute *attr, char *buf)
-{
-	struct cache *cache;
-
-	cache = index_kobj_to_cache(k);
-
-	return sprintf(buf, "%s\n", cache_type_string(cache));
-}
-
-static struct kobj_attribute cache_type_attr =
-	__ATTR(type, 0444, type_show, NULL);
-
-static ssize_t level_show(struct kobject *k, struct kobj_attribute *attr, char *buf)
-{
-	struct cache_index_dir *index;
-	struct cache *cache;
-
-	index = kobj_to_cache_index_dir(k);
-	cache = index->cache;
-
-	return sprintf(buf, "%d\n", cache->level);
-}
-
-static struct kobj_attribute cache_level_attr =
-	__ATTR(level, 0444, level_show, NULL);
-
-static ssize_t shared_cpu_map_show(struct kobject *k, struct kobj_attribute *attr, char *buf)
-{
-	struct cache_index_dir *index;
-	struct cache *cache;
-	int len;
-	int n = 0;
-
-	index = kobj_to_cache_index_dir(k);
-	cache = index->cache;
-	len = PAGE_SIZE - 2;
-
-	if (len > 1) {
-		n = cpumask_scnprintf(buf, len, &cache->shared_cpu_map);
-		buf[n++] = '\n';
-		buf[n] = '\0';
 	}
-	return n;
-}
-
-static struct kobj_attribute cache_shared_cpu_map_attr =
-	__ATTR(shared_cpu_map, 0444, shared_cpu_map_show, NULL);
-
-/* Attributes which should always be created -- the kobject/sysfs core
- * does this automatically via kobj_type->default_attrs.  This is the
- * minimum data required to uniquely identify a cache.
- */
-static struct attribute *cache_index_default_attrs[] = {
-	&cache_type_attr.attr,
-	&cache_level_attr.attr,
-	&cache_shared_cpu_map_attr.attr,
-	NULL,
-};
-
-/* Attributes which should be created if the cache device node has the
- * right properties -- see cacheinfo_create_index_opt_attrs
- */
-static struct kobj_attribute *cache_index_opt_attrs[] = {
-	&cache_size_attr,
-	&cache_line_size_attr,
-	&cache_nr_sets_attr,
-	&cache_assoc_attr,
-};
-
-static const struct sysfs_ops cache_index_ops = {
-	.show = cache_index_show,
-};
-
-static struct kobj_type cache_index_type = {
-	.release = cache_index_release,
-	.sysfs_ops = &cache_index_ops,
-	.default_attrs = cache_index_default_attrs,
-};
-
-static void cacheinfo_create_index_opt_attrs(struct cache_index_dir *dir)
-{
-	const char *cache_name;
-	const char *cache_type;
-	struct cache *cache;
-	char *buf;
-	int i;
-
-	buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-	if (!buf)
-		return;
-
-	cache = dir->cache;
-	cache_name = cache->ofnode->full_name;
-	cache_type = cache_type_string(cache);
-
-	/* We don't want to create an attribute that can't provide a
-	 * meaningful value.  Check the return value of each optional
-	 * attribute's ->show method before registering the
-	 * attribute.
-	 */
-	for (i = 0; i < ARRAY_SIZE(cache_index_opt_attrs); i++) {
-		struct kobj_attribute *attr;
-		ssize_t rc;
-
-		attr = cache_index_opt_attrs[i];
-
-		rc = attr->show(&dir->kobj, attr, buf);
-		if (rc <= 0) {
-			pr_debug("not creating %s attribute for "
-				 "%s(%s) (rc = %zd)\n",
-				 attr->attr.name, cache_name,
-				 cache_type, rc);
-			continue;
-		}
-		if (sysfs_create_file(&dir->kobj, &attr->attr))
-			pr_debug("could not create %s attribute for %s(%s)\n",
-				 attr->attr.name, cache_name, cache_type);
+	np = cpu_dev->of_node;
+	if (!np) {
+		pr_err("Failed to find cpu%d device node\n", cpu);
+		return -ENOENT;
 	}
 
-	kfree(buf);
-}
-
-static void cacheinfo_create_index_dir(struct cache *cache, int index,
-				       struct cache_dir *cache_dir)
-{
-	struct cache_index_dir *index_dir;
-	int rc;
-
-	index_dir = kzalloc(sizeof(*index_dir), GFP_KERNEL);
-	if (!index_dir)
-		goto err;
-
-	index_dir->cache = cache;
-
-	rc = kobject_init_and_add(&index_dir->kobj, &cache_index_type,
-				  cache_dir->kobj, "index%d", index);
-	if (rc)
-		goto err;
-
-	index_dir->next = cache_dir->index;
-	cache_dir->index = index_dir;
-
-	cacheinfo_create_index_opt_attrs(index_dir);
-
-	return;
-err:
-	kfree(index_dir);
-}
-
-static void cacheinfo_sysfs_populate(unsigned int cpu_id,
-				     struct cache *cache_list)
-{
-	struct cache_dir *cache_dir;
-	struct cache *cache;
-	int index = 0;
-
-	cache_dir = cacheinfo_create_cache_dir(cpu_id);
-	if (!cache_dir)
-		return;
-
-	cache = cache_list;
-	while (cache) {
-		cacheinfo_create_index_dir(cache, index, cache_dir);
-		index++;
-		cache = cache->next_local;
+	while (np) {
+		leaves += cache_node_is_unified(np) ? 1 : 2;
+		level++;
+		of_node_put(np);
+		np = of_find_next_cache_node(np);
 	}
-}
+	this_cpu_ci->num_levels = level;
+	this_cpu_ci->num_leaves = leaves;
 
-void cacheinfo_cpu_online(unsigned int cpu_id)
-{
-	struct cache *cache;
-
-	cache = cache_chain_instantiate(cpu_id);
-	if (!cache)
-		return;
-
-	cacheinfo_sysfs_populate(cpu_id, cache);
-}
-
-/* functions needed to remove cache entry for cpu offline or suspend/resume */
-
-#if (defined(CONFIG_PPC_PSERIES) && defined(CONFIG_SUSPEND)) || \
-    defined(CONFIG_HOTPLUG_CPU)
-
-static struct cache *cache_lookup_by_cpu(unsigned int cpu_id)
-{
-	struct device_node *cpu_node;
-	struct cache *cache;
-
-	cpu_node = of_get_cpu_node(cpu_id, NULL);
-	WARN_ONCE(!cpu_node, "no OF node found for CPU %i\n", cpu_id);
-	if (!cpu_node)
-		return NULL;
-
-	cache = cache_lookup_by_node(cpu_node);
-	of_node_put(cpu_node);
-
-	return cache;
+	return 0;
 }
 
-static void remove_index_dirs(struct cache_dir *cache_dir)
+int populate_cache_leaves(unsigned int cpu)
 {
-	struct cache_index_dir *index;
-
-	index = cache_dir->index;
+	struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
+	struct cacheinfo *this_leaf = this_cpu_ci->info_list;
+	struct device *cpu_dev = get_cpu_device(cpu);
+	struct device_node *np;
+	unsigned int level, idx;
 
-	while (index) {
-		struct cache_index_dir *next;
-
-		next = index->next;
-		kobject_put(&index->kobj);
-		index = next;
+	np = of_node_get(cpu_dev->of_node);
+	if (!np) {
+		pr_err("Failed to find cpu%d device node\n", cpu);
+		return -ENOENT;
 	}
-}
-
-static void remove_cache_dir(struct cache_dir *cache_dir)
-{
-	remove_index_dirs(cache_dir);
 
-	/* Remove cache dir from sysfs */
-	kobject_del(cache_dir->kobj);
-
-	kobject_put(cache_dir->kobj);
-
-	kfree(cache_dir);
-}
-
-static void cache_cpu_clear(struct cache *cache, int cpu)
-{
-	while (cache) {
-		struct cache *next = cache->next_local;
-
-		WARN_ONCE(!cpumask_test_cpu(cpu, &cache->shared_cpu_map),
-			  "CPU %i not accounted in %s(%s)\n",
-			  cpu, cache->ofnode->full_name,
-			  cache_type_string(cache));
-
-		cpumask_clear_cpu(cpu, &cache->shared_cpu_map);
-
-		/* Release the cache object if all the cpus using it
-		 * are offline */
-		if (cpumask_empty(&cache->shared_cpu_map))
-			release_cache(cache);
-
-		cache = next;
+	for (idx = 0, level = 1; level <= this_cpu_ci->num_levels &&
+	     idx < this_cpu_ci->num_leaves; idx++, level++) {
+		if (!this_leaf)
+			return -EINVAL;
+
+		this_leaf->of_node = np;
+		if (cache_node_is_unified(np)) {
+			ci_leaf_init(this_leaf++, CACHE_TYPE_UNIFIED, level);
+		} else {
+			ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level);
+			ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level);
+		}
+		np = of_find_next_cache_node(np);
 	}
+	return 0;
 }
 
-void cacheinfo_cpu_offline(unsigned int cpu_id)
-{
-	struct cache_dir *cache_dir;
-	struct cache *cache;
-
-	/* Prevent userspace from seeing inconsistent state - remove
-	 * the sysfs hierarchy first */
-	cache_dir = per_cpu(cache_dir_pcpu, cpu_id);
-
-	/* careful, sysfs population may have failed */
-	if (cache_dir)
-		remove_cache_dir(cache_dir);
-
-	per_cpu(cache_dir_pcpu, cpu_id) = NULL;
-
-	/* clear the CPU's bit in its cache chain, possibly freeing
-	 * cache objects */
-	cache = cache_lookup_by_cpu(cpu_id);
-	if (cache)
-		cache_cpu_clear(cache, cpu_id);
-}
-#endif /* (CONFIG_PPC_PSERIES && CONFIG_SUSPEND) || CONFIG_HOTPLUG_CPU */
diff --git a/arch/powerpc/kernel/cacheinfo.h b/arch/powerpc/kernel/cacheinfo.h
deleted file mode 100644
index a7b74d36acd7..000000000000
--- a/arch/powerpc/kernel/cacheinfo.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _PPC_CACHEINFO_H
-#define _PPC_CACHEINFO_H
-
-/* These are just hooks for sysfs.c to use. */
-extern void cacheinfo_cpu_online(unsigned int cpu_id);
-extern void cacheinfo_cpu_offline(unsigned int cpu_id);
-
-#endif /* _PPC_CACHEINFO_H */
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index 67fd2fd2620a..6e9c5a8141bb 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -19,8 +19,6 @@
 #include <asm/pmc.h>
 #include <asm/firmware.h>
 
-#include "cacheinfo.h"
-
 #ifdef CONFIG_PPC64
 #include <asm/paca.h>
 #include <asm/lppaca.h>
@@ -743,7 +741,6 @@ static void register_cpu_online(unsigned int cpu)
 		device_create_file(s, &dev_attr_altivec_idle_wait_time);
 	}
 #endif
-	cacheinfo_cpu_online(cpu);
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
@@ -824,7 +821,6 @@ static void unregister_cpu_online(unsigned int cpu)
 		device_remove_file(s, &dev_attr_altivec_idle_wait_time);
 	}
 #endif
-	cacheinfo_cpu_offline(cpu);
 }
 
 #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
@@ -988,8 +984,7 @@ static int __init topology_init(void)
 	int cpu;
 
 	register_nodes();
-
-	cpu_notifier_register_begin();
+	register_cpu_notifier(&sysfs_cpu_nb);
 
 	for_each_possible_cpu(cpu) {
 		struct cpu *c = &per_cpu(cpu_devices, cpu);
@@ -1013,11 +1008,6 @@ static int __init topology_init(void)
 		if (cpu_online(cpu))
 			register_cpu_online(cpu);
 	}
-
-	__register_cpu_notifier(&sysfs_cpu_nb);
-
-	cpu_notifier_register_done();
-
 #ifdef CONFIG_PPC64
 	sysfs_create_dscr_default();
 #endif /* CONFIG_PPC64 */
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH] powerpc: dts: t208x: Change T208x USB controller version
From: Nikhil Badola @ 2014-08-21 10:31 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nikhil Badola

Change USB controller version to 2.5 in compatible string for T2080/T2081

Signed-off-by: Nikhil Badola <nikhil.badola@freescale.com>
---
	Checkpatch warnings handled by commit 61a8c2c6fe71082de3ea8629589dcdd0cc5c3f02
	Documentation: dts: fsl-usb: Document USB node compatible string for IP version	

 arch/powerpc/boot/dts/fsl/t2081si-post.dtsi | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
index 97479f0..aecee96 100644
--- a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
+++ b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
@@ -410,7 +410,7 @@
 /include/ "qoriq-gpio-3.dtsi"
 /include/ "qoriq-usb2-mph-0.dtsi"
 	usb0: usb@210000 {
-		compatible = "fsl-usb2-mph-v2.4", "fsl-usb2-mph";
+		compatible = "fsl-usb2-mph-v2.5", "fsl-usb2-mph";
 		fsl,iommu-parent = <&pamu1>;
 		fsl,liodn-reg = <&guts 0x520>; /* USB1LIODNR */
 		phy_type = "utmi";
@@ -418,7 +418,7 @@
 	};
 /include/ "qoriq-usb2-dr-0.dtsi"
 	usb1: usb@211000 {
-		compatible = "fsl-usb2-dr-v2.4", "fsl-usb2-dr";
+		compatible = "fsl-usb2-dr-v2.5", "fsl-usb2-dr";
 		fsl,iommu-parent = <&pamu1>;
 		fsl,liodn-reg = <&guts 0x524>; /* USB1LIODNR */
 		dr_mode = "host";
-- 
1.7.11.7

^ permalink raw reply related

* Re: [PATCH 2/3] MSI: Use __read_msi_msg() instead of read_msi_msg()
From: Yijing Wang @ 2014-08-21 10:21 UTC (permalink / raw)
  To: Wei Yang; +Cc: Bjorn Helgaas, linux-pci, linuxppc-dev
In-Reply-To: <20140821093839.GA15667@richard>

On 2014/8/21 17:38, Wei Yang wrote:
> On Fri, Aug 15, 2014 at 11:14:29AM +0800, Yijing Wang wrote:
>> Read_msi_msg() only be called in rtas_setup_msi_irqs(),
> 
>  read_msi_msg()
> 
> This code looks good to me, while I can't apply on top of 3.17-rc1.
> If you rebase it, it would be more convenient for maintainer to merge.

OK, thanks!

> 
>> use __read_msi_msg() instead of read_msi_msg for
>> simplification. And rename __read_msi_msg() to
>> read_msi_msg().
>>
>> Signed-off-by: Yijing Wang <wangyijing@huawei.com>
>> CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>> CC: linuxppc-dev@lists.ozlabs.org
>> ---
>> arch/powerpc/platforms/pseries/msi.c |    2 +-
>> arch/x86/pci/xen.c                   |    2 +-
>> drivers/pci/msi.c                    |    9 +--------
>> include/linux/msi.h                  |    3 +--
>> 4 files changed, 4 insertions(+), 12 deletions(-)
>>
>> diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
>> index 0c882e8..591650b 100644
>> --- a/arch/powerpc/platforms/pseries/msi.c
>> +++ b/arch/powerpc/platforms/pseries/msi.c
>> @@ -484,7 +484,7 @@ again:
>> 		irq_set_msi_desc(virq, entry);
>>
>> 		/* Read config space back so we can restore after reset */
>> -		read_msi_msg(virq, &msg);
>> +		read_msi_msg(entry, &msg);
>> 		entry->msg = msg;
>> 	}
>>
>> diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
>> index 905956f..4656099 100644
>> --- a/arch/x86/pci/xen.c
>> +++ b/arch/x86/pci/xen.c
>> @@ -228,7 +228,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
>> 		return 1;
>>
>> 	list_for_each_entry(msidesc, &dev->msi_list, list) {
>> -		__read_msi_msg(msidesc, &msg);
>> +		read_msi_msg(msidesc, &msg);
>> 		pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
>> 			((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff);
>> 		if (msg.data != XEN_PIRQ_MSI_DATA ||
>> diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
>> index 988224f..cbb41d6 100644
>> --- a/drivers/pci/msi.c
>> +++ b/drivers/pci/msi.c
>> @@ -259,7 +259,7 @@ void default_restore_msi_irqs(struct pci_dev *dev)
>> 	}
>> }
>>
>> -void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
>> +void read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
>> {
>> 	BUG_ON(entry->dev->current_state != PCI_D0);
>>
>> @@ -289,13 +289,6 @@ void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
>> 	}
>> }
>>
>> -void read_msi_msg(unsigned int irq, struct msi_msg *msg)
>> -{
>> -	struct msi_desc *entry = irq_get_msi_desc(irq);
>> -
>> -	__read_msi_msg(entry, msg);
>> -}
>> -
>> void get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
>> {
>> 	/* Assert that the cache is valid, assuming that
>> diff --git a/include/linux/msi.h b/include/linux/msi.h
>> index e3adf93..4d7c0f5 100644
>> --- a/include/linux/msi.h
>> +++ b/include/linux/msi.h
>> @@ -15,10 +15,9 @@ struct irq_data;
>> struct msi_desc;
>> void mask_msi_irq(struct irq_data *data);
>> void unmask_msi_irq(struct irq_data *data);
>> -void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
>> +void read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
>> void get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
>> void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
>> -void read_msi_msg(unsigned int irq, struct msi_msg *msg);
>> void write_msi_msg(unsigned int irq, struct msi_msg *msg);
>>
>> struct msi_desc {
>> -- 
>> 1.7.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 


-- 
Thanks!
Yijing

^ permalink raw reply

* Re: [PATCH 2/3] MSI: Use __read_msi_msg() instead of read_msi_msg()
From: Wei Yang @ 2014-08-21  9:38 UTC (permalink / raw)
  To: Yijing Wang; +Cc: Bjorn Helgaas, linux-pci, linuxppc-dev
In-Reply-To: <1408072469-9959-1-git-send-email-wangyijing@huawei.com>

On Fri, Aug 15, 2014 at 11:14:29AM +0800, Yijing Wang wrote:
>Read_msi_msg() only be called in rtas_setup_msi_irqs(),

 read_msi_msg()

This code looks good to me, while I can't apply on top of 3.17-rc1.
If you rebase it, it would be more convenient for maintainer to merge.

>use __read_msi_msg() instead of read_msi_msg for
>simplification. And rename __read_msi_msg() to
>read_msi_msg().
>
>Signed-off-by: Yijing Wang <wangyijing@huawei.com>
>CC: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>CC: linuxppc-dev@lists.ozlabs.org
>---
> arch/powerpc/platforms/pseries/msi.c |    2 +-
> arch/x86/pci/xen.c                   |    2 +-
> drivers/pci/msi.c                    |    9 +--------
> include/linux/msi.h                  |    3 +--
> 4 files changed, 4 insertions(+), 12 deletions(-)
>
>diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
>index 0c882e8..591650b 100644
>--- a/arch/powerpc/platforms/pseries/msi.c
>+++ b/arch/powerpc/platforms/pseries/msi.c
>@@ -484,7 +484,7 @@ again:
> 		irq_set_msi_desc(virq, entry);
>
> 		/* Read config space back so we can restore after reset */
>-		read_msi_msg(virq, &msg);
>+		read_msi_msg(entry, &msg);
> 		entry->msg = msg;
> 	}
>
>diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
>index 905956f..4656099 100644
>--- a/arch/x86/pci/xen.c
>+++ b/arch/x86/pci/xen.c
>@@ -228,7 +228,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
> 		return 1;
>
> 	list_for_each_entry(msidesc, &dev->msi_list, list) {
>-		__read_msi_msg(msidesc, &msg);
>+		read_msi_msg(msidesc, &msg);
> 		pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
> 			((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff);
> 		if (msg.data != XEN_PIRQ_MSI_DATA ||
>diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
>index 988224f..cbb41d6 100644
>--- a/drivers/pci/msi.c
>+++ b/drivers/pci/msi.c
>@@ -259,7 +259,7 @@ void default_restore_msi_irqs(struct pci_dev *dev)
> 	}
> }
>
>-void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
>+void read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
> {
> 	BUG_ON(entry->dev->current_state != PCI_D0);
>
>@@ -289,13 +289,6 @@ void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
> 	}
> }
>
>-void read_msi_msg(unsigned int irq, struct msi_msg *msg)
>-{
>-	struct msi_desc *entry = irq_get_msi_desc(irq);
>-
>-	__read_msi_msg(entry, msg);
>-}
>-
> void get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
> {
> 	/* Assert that the cache is valid, assuming that
>diff --git a/include/linux/msi.h b/include/linux/msi.h
>index e3adf93..4d7c0f5 100644
>--- a/include/linux/msi.h
>+++ b/include/linux/msi.h
>@@ -15,10 +15,9 @@ struct irq_data;
> struct msi_desc;
> void mask_msi_irq(struct irq_data *data);
> void unmask_msi_irq(struct irq_data *data);
>-void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
>+void read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
> void get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
> void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
>-void read_msi_msg(unsigned int irq, struct msi_msg *msg);
> void write_msi_msg(unsigned int irq, struct msi_msg *msg);
>
> struct msi_desc {
>-- 
>1.7.1
>
>--
>To unsubscribe from this list: send the line "unsubscribe linux-pci" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html

-- 
Richard Yang
Help you, Help me

^ permalink raw reply

* [PATCH 4/4][v2] powerpc/fsl_msi: spread msi ints across different MSIRs
From: Laurentiu Tudor @ 2014-08-21  9:33 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Scott Wood, Mihai Caraman, Laurentiu Tudor

Allocate msis such that each time a new interrupt is requested,
the SRS (MSIR register select) to be used is allocated in a
round-robin fashion.
The end result is that the msi interrupts will be spread across
distinct MSIRs with the main benefit that now users can set
affinity to each msi int through the mpic irq backing up the
MSIR register.
This is achieved with the help of a newly introduced msi bitmap
api that allows specifying the starting point when searching
for a free msi interrupt.

Signed-off-by: Laurentiu Tudor <Laurentiu.Tudor@freescale.com>
Cc: Scott Wood <scottwood@freescale.com>
Cc: Mihai Caraman <mihai.caraman@freescale.com>
---
v2:
 - re-wrapped commit message
 - fixed weird way of doing a simple A <<= B

 arch/powerpc/include/asm/msi_bitmap.h |  2 ++
 arch/powerpc/sysdev/fsl_msi.c         | 31 ++++++++++++++++++++++++++++++-
 arch/powerpc/sysdev/fsl_msi.h         |  5 +++++
 arch/powerpc/sysdev/msi_bitmap.c      | 25 +++++++++++++++----------
 4 files changed, 52 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/include/asm/msi_bitmap.h b/arch/powerpc/include/asm/msi_bitmap.h
index 97ac3f4..96c2f95 100644
--- a/arch/powerpc/include/asm/msi_bitmap.h
+++ b/arch/powerpc/include/asm/msi_bitmap.h
@@ -25,6 +25,8 @@ int msi_bitmap_alloc_hwirqs(struct msi_bitmap *bmp, int num);
 void msi_bitmap_free_hwirqs(struct msi_bitmap *bmp, unsigned int offset,
 			    unsigned int num);
 void msi_bitmap_reserve_hwirq(struct msi_bitmap *bmp, unsigned int hwirq);
+int msi_bitmap_alloc_hwirqs_from_offset(struct msi_bitmap *bmp, int offset,
+					int num);
 
 int msi_bitmap_reserve_dt_hwirqs(struct msi_bitmap *bmp);
 
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index e2ee226..37254ef 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -213,6 +213,8 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
 		 * available interrupt.
 		 */
 		list_for_each_entry(msi_data, &msi_head, list) {
+			int off;
+
 			/*
 			 * If the PCI node has an fsl,msi property, then we
 			 * restrict our search to the corresponding MSI node.
@@ -224,7 +226,28 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
 			if (phandle && (phandle != msi_data->phandle))
 				continue;
 
-			hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1);
+			/*
+			 * Allocate the msi message so that it fits on distinct
+			 * MSIR registers. Obviously, since MSIR registers are
+			 * limited they will overlap at one point.
+			 *
+			 * Due to the format of the newly introduced MSIIR1 in
+			 * mpic 4.3, consecutive msi message values map to
+			 * distinct MSIRs, thus distinct msi irq cascades, so
+			 * nothing special needs to be done in this case.
+			 * On older mpic versions the chose distinct SRS
+			 * values by aligning the msi message value to the
+			 * SRS field shift.
+			 */
+			if (msi_data->feature & FSL_PIC_FTR_MPIC_4_3) {
+				off = 0;
+			} else {
+				off = atomic_inc_return(&msi_data->msi_alloc_cnt) %
+					msi_data->msir_num;
+				off <<= msi_data->srs_shift;
+			}
+			hwirq = msi_bitmap_alloc_hwirqs_from_offset(
+						&msi_data->bitmap, off, 1);
 			if (hwirq >= 0)
 				break;
 		}
@@ -464,12 +487,17 @@ static int fsl_of_msi_probe(struct platform_device *dev)
 		goto error_out;
 	}
 
+	atomic_set(&msi->msi_alloc_cnt, -1);
+
 	p = of_get_property(dev->dev.of_node, "msi-available-ranges", &len);
 
 	if (of_device_is_compatible(dev->dev.of_node, "fsl,mpic-msi-v4.3") ||
 	    of_device_is_compatible(dev->dev.of_node, "fsl,vmpic-msi-v4.3")) {
 		msi->srs_shift = MSIIR1_SRS_SHIFT;
 		msi->ibs_shift = MSIIR1_IBS_SHIFT;
+		msi->msir_num = NR_MSI_REG_MSIIR1;
+		msi->feature |= FSL_PIC_FTR_MPIC_4_3;
+
 		if (p)
 			dev_warn(&dev->dev, "%s: dose not support msi-available-ranges property\n",
 				__func__);
@@ -487,6 +515,7 @@ static int fsl_of_msi_probe(struct platform_device *dev)
 
 		msi->srs_shift = MSIIR_SRS_SHIFT;
 		msi->ibs_shift = MSIIR_IBS_SHIFT;
+		msi->msir_num = NR_MSI_REG_MSIIR;
 
 		if (p && len % (2 * sizeof(u32)) != 0) {
 			dev_err(&dev->dev, "%s: Malformed msi-available-ranges property\n",
diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h
index 420cfcb..50ec4b0 100644
--- a/arch/powerpc/sysdev/fsl_msi.h
+++ b/arch/powerpc/sysdev/fsl_msi.h
@@ -15,6 +15,7 @@
 
 #include <linux/of.h>
 #include <asm/msi_bitmap.h>
+#include <asm/atomic.h>
 
 #define NR_MSI_REG_MSIIR	8  /* MSIIR can index 8 MSI registers */
 #define NR_MSI_REG_MSIIR1	16 /* MSIIR1 can index 16 MSI registers */
@@ -27,6 +28,8 @@
 #define FSL_PIC_IP_IPIC   0x00000002
 #define FSL_PIC_IP_VMPIC  0x00000003
 
+#define FSL_PIC_FTR_MPIC_4_3 0x00000010
+
 struct fsl_msi_cascade_data;
 
 struct fsl_msi {
@@ -37,6 +40,8 @@ struct fsl_msi {
 	u32 msiir_offset; /* Offset of MSIIR, relative to start of CCSR */
 	u32 ibs_shift; /* Shift of interrupt bit select */
 	u32 srs_shift; /* Shift of the shared interrupt register select */
+	u32 msir_num; /* Number of available MSIR regs */
+	atomic_t msi_alloc_cnt; /* Counter for MSI hwirq allocations */
 	void __iomem *msi_regs;
 	u32 feature;
 	struct fsl_msi_cascade_data *cascade_array[NR_MSI_REG_MAX];
diff --git a/arch/powerpc/sysdev/msi_bitmap.c b/arch/powerpc/sysdev/msi_bitmap.c
index 2ff6302..8b7d8fc 100644
--- a/arch/powerpc/sysdev/msi_bitmap.c
+++ b/arch/powerpc/sysdev/msi_bitmap.c
@@ -14,23 +14,28 @@
 #include <asm/msi_bitmap.h>
 #include <asm/setup.h>
 
-int msi_bitmap_alloc_hwirqs(struct msi_bitmap *bmp, int num)
+int msi_bitmap_alloc_hwirqs_from_offset(struct msi_bitmap *bmp, int offset,
+					int num)
 {
 	unsigned long flags;
-	int offset, order = get_count_order(num);
+	int index;
+	int order = get_count_order(num);
 
 	spin_lock_irqsave(&bmp->lock, flags);
-	/*
-	 * This is fast, but stricter than we need. We might want to add
-	 * a fallback routine which does a linear search with no alignment.
-	 */
-	offset = bitmap_find_free_region(bmp->bitmap, bmp->irq_count, order);
+	index = bitmap_find_next_zero_area(bmp->bitmap, bmp->irq_count,
+					   offset, num, (1 << order) - 1);
+	bitmap_set(bmp->bitmap, index, num);
 	spin_unlock_irqrestore(&bmp->lock, flags);
 
-	pr_debug("msi_bitmap: allocated 0x%x (2^%d) at offset 0x%x\n",
-		 num, order, offset);
+	pr_debug("msi_bitmap: found %d free bits starting from offset %d at index %d\n",
+		 num, offset, index);
 
-	return offset;
+	return index;
+}
+
+int msi_bitmap_alloc_hwirqs(struct msi_bitmap *bmp, int num)
+{
+	return msi_bitmap_alloc_hwirqs_from_offset(bmp, 0, num);
 }
 
 void msi_bitmap_free_hwirqs(struct msi_bitmap *bmp, unsigned int offset,
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH] Documentation: dts: fsl-usb: Document USB node compatible string for IP version
From: Nikhil Badola @ 2014-08-21  9:18 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nikhil Badola

Document compatible string containing IP version in USB device tree node

Signed-off-by: Nikhil Badola <nikhil.badola@freescale.com>
---
 Documentation/devicetree/bindings/usb/fsl-usb.txt | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/fsl-usb.txt b/Documentation/devicetree/bindings/usb/fsl-usb.txt
index 4779c02..5a3a0a8 100644
--- a/Documentation/devicetree/bindings/usb/fsl-usb.txt
+++ b/Documentation/devicetree/bindings/usb/fsl-usb.txt
@@ -10,7 +10,10 @@ Required properties :
    controllers, or "fsl-usb2-dr" for dual role USB controllers
    or "fsl,mpc5121-usb2-dr" for dual role USB controllers of MPC5121.
    Wherever applicable, the IP version of the USB controller should
-   also be mentioned (for eg. fsl-usb2-dr-v2.2 for bsc9132).
+   also be mentioned in another string.
+   For multi port host USB controller with IP version <IP_Ver>, it should be
+   "fsl-usb2-mph-<IP_Ver>". For dual role USB controller with IP version
+   <IP_Ver>, it should be "fsl-usb2-dr-<IP_Ver>".
  - phy_type : For multi port host USB controllers, should be one of
    "ulpi", or "serial". For dual role USB controllers, should be
    one of "ulpi", "utmi", "utmi_wide", or "serial".
@@ -42,9 +45,9 @@ Optional properties :
  - fsl,invert-pwr-fault : boolean; for MPC5121 USB0 only. Indicates
    the PWR_FAULT signal polarity is inverted.
 
-Example multi port host USB controller device node :
+Example multi port host USB controller version 2.5 device node :
 	usb@22000 {
-		compatible = "fsl-usb2-mph";
+		compatible = "fsl-usb2-mph-v2.5", "fsl-usb2-mph";
 		reg = <22000 1000>;
 		#address-cells = <1>;
 		#size-cells = <0>;
@@ -55,9 +58,9 @@ Example multi port host USB controller device node :
 		port1;
 	};
 
-Example dual role USB controller device node :
+Example dual role USB controller version 2.5 device node :
 	usb@23000 {
-		compatible = "fsl-usb2-dr";
+		compatible = "fsl-usb2-dr-v2.5", "fsl-usb2-dr";
 		reg = <23000 1000>;
 		#address-cells = <1>;
 		#size-cells = <0>;
-- 
1.7.11.7

^ permalink raw reply related

* Re: [PATCH v4] powerpc/kvm: support to handle sw breakpoint
From: Alexander Graf @ 2014-08-21  9:10 UTC (permalink / raw)
  To: Madhavan Srinivasan, benh, paulus, mpe; +Cc: linuxppc-dev, kvm-ppc, kvm
In-Reply-To: <1408513929-5267-1-git-send-email-maddy@linux.vnet.ibm.com>



On 20.08.14 07:52, Madhavan Srinivasan wrote:
> This patch adds kernel side support for software breakpoint.
> Design is that, by using an illegal instruction, we trap to hypervisor
> via Emulation Assistance interrupt, where we check for the illegal instruction
> and accordingly we return to Host or Guest. Patch also adds support for
> software breakpoint in PR KVM.
> 
> Changes v3->v4:
>  Made changes to code comments and removed #define of zero opcode
>  Added a new function to handle the debug instruction emulation in book3s_hv
>  Rebased the code to latest upstream source.
> 
> Changes v2->v3:
>  Changed the debug instructions. Using the all zero opcode in the instruction word
>   as illegal instruction as mentioned in Power ISA instead of ABS
>  Removed reg updated in emulation assist and added a call to
>   kvmppc_emulate_instruction for reg update.
> 
> Changes v1->v2:
> 
>  Moved the debug instruction #def to kvm_book3s.h. This way PR_KVM can also share it.
>  Added code to use KVM get one reg infrastructure to get debug opcode.
>  Updated emulate.c to include emulation of debug instruction incase of PR_KVM.
>  Made changes to commit message.
> 
> Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
> ---
>  arch/powerpc/include/asm/kvm_book3s.h |  7 +++++++
>  arch/powerpc/kvm/book3s.c             |  3 ++-
>  arch/powerpc/kvm/book3s_hv.c          | 32 ++++++++++++++++++++++++++++++--
>  arch/powerpc/kvm/book3s_pr.c          |  3 +++
>  arch/powerpc/kvm/emulate.c            | 11 +++++++++++
>  5 files changed, 53 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
> index 6acf0c2..a1944f8 100644
> --- a/arch/powerpc/include/asm/kvm_book3s.h
> +++ b/arch/powerpc/include/asm/kvm_book3s.h
> @@ -24,6 +24,13 @@
>  #include <linux/kvm_host.h>
>  #include <asm/kvm_book3s_asm.h>
>  
> +/*
> + * KVMPPC_INST_BOOK3S_DEBUG is debug Instruction for supporting Software Breakpoint.
> + * Based on PowerISA v2.07, Instruction with primary opcode 0 will be treated as illegal
> + * instruction.
> + */
> +#define KVMPPC_INST_BOOK3S_DEBUG	0x00dddd00

Please change the BookE version of this as well, put the define in a
common header and use a non book specific name.

> +
>  struct kvmppc_bat {
>  	u64 raw;
>  	u32 bepi;
> diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
> index dd03f6b..00e9c9f 100644
> --- a/arch/powerpc/kvm/book3s.c
> +++ b/arch/powerpc/kvm/book3s.c
> @@ -778,7 +778,8 @@ int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
>  int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
>  					struct kvm_guest_debug *dbg)
>  {
> -	return -EINVAL;
> +	vcpu->guest_debug = dbg->control;
> +	return 0;
>  }
>  
>  void kvmppc_decrementer_func(unsigned long data)
> diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
> index 27cced9..0a92e45 100644
> --- a/arch/powerpc/kvm/book3s_hv.c
> +++ b/arch/powerpc/kvm/book3s_hv.c
> @@ -725,6 +725,14 @@ static int kvmppc_hcall_impl_hv(unsigned long cmd)
>  	return kvmppc_hcall_impl_hv_realmode(cmd);
>  }
>  
> +static int kvmppc_emulate_debug_instruction_hv(struct kvm_run *run,
> +					struct kvm_vcpu *vcpu)
> +{
> +	run->exit_reason = KVM_EXIT_DEBUG;
> +	run->debug.arch.address = kvmppc_get_pc(vcpu);
> +	return 0;
> +}
> +
>  static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu,
>  				 struct task_struct *tsk)
>  {
> @@ -811,9 +819,26 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu,
>  	 * we don't emulate any guest instructions at this stage.

This comment is no longer true, it should get changed.

>  	 */
>  	case BOOK3S_INTERRUPT_H_EMUL_ASSIST:
> -		kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
> -		r = RESUME_GUEST;
> +	{
> +		u32 last_inst;
> +		if(kvmppc_get_last_inst(vcpu, INST_GENERIC, &last_inst) !=
> +					EMULATE_DONE) {

Please only do this if debugging is active.

> +			/*
> +			 * Fetch failed, so return to guest and
> +			 * try executing it again.
> +			 */
> +			r = RESUME_GUEST;
> +		} else {
> +			if (last_inst == KVMPPC_INST_BOOK3S_DEBUG) {
> +				kvmppc_emulate_debug_instruction_hv(run, vcpu);
> +				r = RESUME_HOST;
> +			} else {
> +				kvmppc_core_queue_program(vcpu, SRR1_PROGILL);
> +				r = RESUME_GUEST;
> +			}
> +		}
>  		break;
> +	}
>  	/*
>  	 * This occurs if the guest (kernel or userspace), does something that
>  	 * is prohibited by HFSCR.  We just generate a program interrupt to
> @@ -922,6 +947,9 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
>  	long int i;
>  
>  	switch (id) {
> +	case KVM_REG_PPC_DEBUG_INST:
> +		*val = get_reg_val(id, KVMPPC_INST_BOOK3S_DEBUG);
> +		break;
>  	case KVM_REG_PPC_HIOR:
>  		*val = get_reg_val(id, 0);
>  		break;
> diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
> index faffb27..cd2a39d 100644
> --- a/arch/powerpc/kvm/book3s_pr.c
> +++ b/arch/powerpc/kvm/book3s_pr.c
> @@ -1319,6 +1319,9 @@ static int kvmppc_get_one_reg_pr(struct kvm_vcpu *vcpu, u64 id,
>  	int r = 0;
>  
>  	switch (id) {
> +	case KVM_REG_PPC_DEBUG_INST:
> +		*val = get_reg_val(id, KVMPPC_INST_BOOK3S_DEBUG);
> +		break;
>  	case KVM_REG_PPC_HIOR:
>  		*val = get_reg_val(id, to_book3s(vcpu)->hior);
>  		break;
> diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c
> index e96b50d..68f38b2 100644
> --- a/arch/powerpc/kvm/emulate.c
> +++ b/arch/powerpc/kvm/emulate.c
> @@ -274,6 +274,17 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
>  		}
>  		break;
>  
> +	case 0:
> +		/*
> +		 * Instruction with primary opcode 0. Based on PowerISA
> +		 * these are illegal instructions.
> +		 */
> +		run->exit_reason = KVM_EXIT_DEBUG;

This is wrong. We need to check that the instruction is 0x00dddd00. Any
other op0 instruction should trigger an invalid instruction trap.


Alex

> +		run->debug.arch.address = kvmppc_get_pc(vcpu);
> +		emulated = EMULATE_EXIT_USER;
> +		advance = 0;
> +		break;
> +
>  	default:
>  		emulated = EMULATE_FAIL;
>  	}
> 

^ permalink raw reply

* [RFC PATCH powerpc] Fix warning reported by verify_cpu_node_mapping()
From: Li Zhong @ 2014-08-21  8:14 UTC (permalink / raw)
  To: PowerPC email list; +Cc: Michael Ellerman, Nishanth Aravamudan, Paul Mackerras

With commit 2fabf084b, during boottime, cpu_numa_callback() is called
earlier(before their online) for each cpu, and verify_cpu_node_mapping()
uses cpu_to_node() to check whether siblings are in the same node. 

It skips the checking for siblings that are not online yet. So the only
check done here is for the bootcpu, which is online at that time. But
the per-cpu numa_node cpu_to_node() uses hasn't been set up yet (which
will be set up in smp_prepare_cpus()).

So I could see something like following reported:
[    0.000000] CPU thread siblings 1/2/3 and 0 don't belong to the same
node!

As we don't actually do the checking during this early stage, so maybe
we could directly call numa_setup_cpu() in do_init_bootmem()?

Signed-off-by: Li Zhong <zhong@linux.vnet.ibm.com>
---
 arch/powerpc/mm/numa.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index d7737a5..9918c02 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1128,8 +1128,7 @@ void __init do_init_bootmem(void)
 	 * early in boot, cf. smp_prepare_cpus().
 	 */
 	for_each_possible_cpu(cpu) {
-		cpu_numa_callback(&ppc64_numa_nb, CPU_UP_PREPARE,
-				  (void *)(unsigned long)cpu);
+		numa_setup_cpu((unsigned long)cpu);
 	}
 }
 

^ permalink raw reply related

* Re: [PATCH 1/1] powerpc/jump_label: use HAVE_JUMP_LABEL?
From: Michael Ellerman @ 2014-08-21  7:34 UTC (permalink / raw)
  To: Zhouyi Zhou
  Cc: aneesh.kumar, linux-kernel, jbaron, paulus, jk, Zhouyi Zhou,
	paulmck, linuxppc-dev, anton
In-Reply-To: <1408588883-26783-1-git-send-email-yizhouzhou@ict.ac.cn>

On Thu, 2014-08-21 at 10:41 +0800, Zhouyi Zhou wrote:
> CONFIG_JUMP_LABEL doesn't ensure HAVE_JUMP_LABEL, if it
> is not the case use maintainers's own mutex to guard
> the modification of global values.
 
OK, so CONFIG_JUMP_LABEL says the user wants to use jump labels. But we also
need the toolchain to support it.

That is reflected in CC_HAVE_ASM_GOTO=y, and if both are set then
HAVE_JUMP_LABEL is set to true.

So this looks right to me.

cheers

^ permalink raw reply

* Re: [PATCH v4 02/16] KVM: PPC: Use RCU for arch.spapr_tce_tables
From: Paul Mackerras @ 2014-08-21  5:25 UTC (permalink / raw)
  To: Alexey Kardashevskiy; +Cc: Michael Ellerman, linuxppc-dev, Gavin Shan
In-Reply-To: <1406712695-9491-3-git-send-email-aik@ozlabs.ru>

On Wed, Jul 30, 2014 at 07:31:21PM +1000, Alexey Kardashevskiy wrote:
> At the moment spapr_tce_tables is not protected against races. This makes
> use of RCU-variants of list helpers. As some bits are executed in real
> mode, this makes use of just introduced list_for_each_entry_rcu_notrace().
> 
> This converts release_spapr_tce_table() to a RCU scheduled handler.

...

> @@ -106,7 +108,8 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>  	int i;
>  
>  	/* Check this LIOBN hasn't been previously allocated */
> -	list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
> +	list_for_each_entry_rcu_notrace(stt, &kvm->arch.spapr_tce_tables,
> +			list) {
>  		if (stt->liobn == args->liobn)
>  			return -EBUSY;
>  	}

You need something to protect this traversal of the list.  In fact...

> @@ -131,7 +134,7 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm,
>  	kvm_get_kvm(kvm);
>  
>  	mutex_lock(&kvm->lock);
> -	list_add(&stt->list, &kvm->arch.spapr_tce_tables);
> +	list_add_rcu(&stt->list, &kvm->arch.spapr_tce_tables);
>  
>  	mutex_unlock(&kvm->lock);
>  

since it is the kvm->lock mutex that protects the list against
changes, you should do the check for whether the liobn is already in
the list inside the same mutex_lock ... unlock pair that protects the
list_add_rcu.

Or, if there is some other reason why two threads can't race and both
add the same liobn here, you need to explain that (and in that case
it's presumably unnecessary to hold kvm->lock).

> diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c
> index 89e96b3..b1914d9 100644
> --- a/arch/powerpc/kvm/book3s_64_vio_hv.c
> +++ b/arch/powerpc/kvm/book3s_64_vio_hv.c
> @@ -50,7 +50,8 @@ long kvmppc_h_put_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
>  	/* udbg_printf("H_PUT_TCE(): liobn=0x%lx ioba=0x%lx, tce=0x%lx\n", */
>  	/* 	    liobn, ioba, tce); */
>  
> -	list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
> +	list_for_each_entry_rcu_notrace(stt, &kvm->arch.spapr_tce_tables,
> +			list) {
>  		if (stt->liobn == liobn) {
>  			unsigned long idx = ioba >> SPAPR_TCE_SHIFT;
>  			struct page *page;
> @@ -82,7 +83,8 @@ long kvmppc_h_get_tce(struct kvm_vcpu *vcpu, unsigned long liobn,
>  	struct kvm *kvm = vcpu->kvm;
>  	struct kvmppc_spapr_tce_table *stt;
>  
> -	list_for_each_entry(stt, &kvm->arch.spapr_tce_tables, list) {
> +	list_for_each_entry_rcu_notrace(stt, &kvm->arch.spapr_tce_tables,
> +			list) {
>  		if (stt->liobn == liobn) {
>  			unsigned long idx = ioba >> SPAPR_TCE_SHIFT;
>  			struct page *page;

What protects these list iterations?  Do we know that interrupts are
always disabled here, or that the caller has done an rcu_read_lock or
something?  It seems a little odd that you haven't added any calls to
rcu_read_lock/unlock().

Paul.

^ permalink raw reply

* Re: [PATCH 1/3] powerpc: Split out instruction analysis part of emulate_step()
From: Michael Ellerman @ 2014-08-21  6:38 UTC (permalink / raw)
  To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <1408363992-7929-2-git-send-email-paulus@samba.org>

On Mon, 2014-08-18 at 22:13 +1000, Paul Mackerras wrote:
> This splits out the instruction analysis part of emulate_step() into
> a separate analyse_instr() function, which decodes the instruction,
> but doesn't execute any load or store instructions.  It does execute
> integer instructions and branches which can be executed purely by
> updating register values in the pt_regs struct.  For other instructions,
> it returns the instruction type and other details in a new
> instruction_op struct.  emulate_step() then uses that information
> to execute loads, stores, cache operations, mfmsr, mtmsr[d], and
> (on 64-bit) sc instructions.
> 
> The reason for doing this is so that the KVM code can use it instead
> of having its own separate instruction emulation code.  Possibly the
> alignment interrupt handler could also use this.

Breaks the ppc64e_defconfig build:

  arch/powerpc/lib/sstep.c: In function 'emulate_step':
  arch/powerpc/lib/sstep.c:1794:3: error: implicit declaration of function 'do_vec_load' [-Werror=implicit-function-declaration]
  reg, do_lvx, op.ea & ~0xfUL, regs);
  
  arch/powerpc/lib/sstep.c:1840:3: error: implicit declaration of function 'do_vec_store' [-Werror=implicit-function-declaration]
     err = do_vec_store(op.reg, do_stvx, op.ea & ~0xfUL, regs);
     ^

cheers

^ permalink raw reply

* Re: [PATCH] cpufreq: powernv: Register the driver with reboot notifier
From: Viresh Kumar @ 2014-08-21  6:26 UTC (permalink / raw)
  To: Shilpasri G Bhat
  Cc: linux-pm@vger.kernel.org, Rafael J. Wysocki,
	Linux Kernel Mailing List, Shilpasri G Bhat,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <53F57E51.4060200@gmail.com>

On 21 August 2014 10:36, Shilpasri G Bhat <shilpabhatppc@gmail.com> wrote:
> The intention here is stop the cpufreq governor and then to set the cpus to
> nominal frequency so as to ensure that the frequency won't be changed later.
>
> The .suspend callback of the driver is not called during reboot/kexec.
> So we need an explicit reboot notifier to call cpufreq-suspend() to
> suffice the requirement.

Hi Shilpa,

No, we can't allow any platform driver to misuse cpufreq_suspend().
Platform drivers aren't *allowed* to call this routine.

Now the deal is how do we move to nominal frequency on reboot..
@Rafael: Any suggestions? How do we ensure that governors
are stopped on these notifiers, or if there is some other solution here?

^ permalink raw reply

* Re: [PATCH] cpufreq: powernv: Register the driver with reboot notifier
From: Shilpasri G Bhat @ 2014-08-21  5:06 UTC (permalink / raw)
  To: Viresh Kumar, Shilpasri G Bhat
  Cc: linux-pm@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	Linux Kernel Mailing List, Rafael J. Wysocki
In-Reply-To: <CAKohponDNHYrD9b==cp+pVmAi2ygA9-HcLZWqr4w3DDivB=-Ng@mail.gmail.com>


On 08/18/2014 01:16 PM, Viresh Kumar wrote:
> On 14 August 2014 16:49, Shilpasri G Bhat
> <shilpa.bhat@linux.vnet.ibm.com> wrote:
>> This patch ensures the cpus to kexec/reboot at nominal frequency.
>> Nominal frequency is the highest cpu frequency on PowerPC at
>> which the cores can run without getting throttled.
>>
>> If the host kernel had set the cpus to a low pstate and then it
>> kexecs/reboots to a cpufreq disabled kernel it would cause the target
>> kernel to perform poorly. It will also increase the boot up time of
>> the target kernel. So set the cpus to high pstate, in this case to
>> nominal frequency before rebooting to avoid such scenarios.
>>
>> The reboot notifier will suspend the cpufreq governor and enable
>> nominal frequency to be set during a reboot/kexec similar to the
>> suspend operartion.
>>
>> Signed-off-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
>> Reviewed-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
>> ---
>>   drivers/cpufreq/powernv-cpufreq.c | 16 ++++++++++++++++
>>   1 file changed, 16 insertions(+)
>>
>> diff --git a/drivers/cpufreq/powernv-cpufreq.c b/drivers/cpufreq/powernv-cpufreq.c
>> index 379c083..e9f3d3a 100644
>> --- a/drivers/cpufreq/powernv-cpufreq.c
>> +++ b/drivers/cpufreq/powernv-cpufreq.c
>> @@ -26,6 +26,7 @@
>>   #include <linux/cpufreq.h>
>>   #include <linux/smp.h>
>>   #include <linux/of.h>
>> +#include <linux/reboot.h>
>>
>>   #include <asm/cputhreads.h>
>>   #include <asm/firmware.h>
>> @@ -314,9 +315,21 @@ static int powernv_cpufreq_cpu_init(struct cpufreq_policy *policy)
>>          for (i = 0; i < threads_per_core; i++)
>>                  cpumask_set_cpu(base + i, policy->cpus);
>>
>> +       policy->suspend_freq = pstate_id_to_freq(powernv_pstate_info.nominal);
>>          return cpufreq_table_validate_and_show(policy, powernv_freqs);
>>   }
>>
>> +static int powernv_cpufreq_reboot_notifier(struct notifier_block *nb,
>> +                               unsigned long action, void *unused)
>> +{
>> +       cpufreq_suspend();
>> +       return NOTIFY_DONE;
>> +}
>> +
>> +static struct notifier_block powernv_cpufreq_reboot_nb = {
>> +       .notifier_call = powernv_cpufreq_reboot_notifier,
>> +};
>> +
>>   static struct cpufreq_driver powernv_cpufreq_driver = {
>>          .name           = "powernv-cpufreq",
>>          .flags          = CPUFREQ_CONST_LOOPS,
>> @@ -325,6 +338,7 @@ static struct cpufreq_driver powernv_cpufreq_driver = {
>>          .target_index   = powernv_cpufreq_target_index,
>>          .get            = powernv_cpufreq_get,
>>          .attr           = powernv_cpu_freq_attr,
>> +       .suspend        = cpufreq_generic_suspend,
> I couldn't understand why you have added a notifier here. This callback
> by itself should be enough. Isn't it?
>
> And then you have called cpufreq_suspend(), which is absolutely wrong,
> from that notifier..

Hi Viresh,

The intention here is stop the cpufreq governor and then to set the cpus to
nominal frequency so as to ensure that the frequency won't be changed later.

The .suspend callback of the driver is not called during reboot/kexec.
So we need an explicit reboot notifier to call cpufreq-suspend() to
suffice the requirement.

Thanks and Regards,
Shilpa

^ permalink raw reply

* Re: [PATCH] powerpc/pseries: Drop unnecessary continue
From: Michael Ellerman @ 2014-08-21  4:41 UTC (permalink / raw)
  To: Himangi Saraogi
  Cc: linux-kernel, Julia Lawall, Paul Mackerras, linuxppc-dev, rcj4747
In-Reply-To: <20140813091847.GA3078@himangi-Dell>

On Wed, 2014-08-13 at 14:48 +0530, Himangi Saraogi wrote:
> Continue is not needed at the bottom of a loop.
 
True.

I wonder though, is the code trying to continue to the outer loop? I stared at
it for a minute but it wasn't obvious.

I wonder if Robert still remembers?

cheers

> diff --git a/arch/powerpc/platforms/pseries/cmm.c b/arch/powerpc/platforms/pseries/cmm.c
> index 2d8bf15..fc44ad0 100644
> --- a/arch/powerpc/platforms/pseries/cmm.c
> +++ b/arch/powerpc/platforms/pseries/cmm.c
> @@ -555,7 +555,6 @@ static int cmm_mem_going_offline(void *arg)
>  				pa_last = pa_last->next;
>  				free_page((unsigned long)cmm_page_list);
>  				cmm_page_list = pa_last;
> -				continue;
>  			}
>  		}
>  		pa_curr = pa_curr->next;

^ permalink raw reply

* [PATCH 1/1] powerpc/jump_label: use HAVE_JUMP_LABEL?
From: Zhouyi Zhou @ 2014-08-21  2:41 UTC (permalink / raw)
  To: benh, paulus, mpe, paulmck, anton, aneesh.kumar, jk, linuxppc-dev,
	linux-kernel, jbaron
  Cc: Zhouyi Zhou

CONFIG_JUMP_LABEL doesn't ensure HAVE_JUMP_LABEL, if it
is not the case use maintainers's own mutex to guard
the modification of global values.


Signed-off-by: Zhouyi Zhou <yizhouzhou@ict.ac.cn>
---
 arch/powerpc/platforms/powernv/opal-tracepoints.c |    2 +-
 arch/powerpc/platforms/pseries/lpar.c             |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/opal-tracepoints.c b/arch/powerpc/platforms/powernv/opal-tracepoints.c
index d8a000a..ae14c40 100644
--- a/arch/powerpc/platforms/powernv/opal-tracepoints.c
+++ b/arch/powerpc/platforms/powernv/opal-tracepoints.c
@@ -2,7 +2,7 @@
 #include <linux/jump_label.h>
 #include <asm/trace.h>
 
-#ifdef CONFIG_JUMP_LABEL
+#ifdef HAVE_JUMP_LABEL
 struct static_key opal_tracepoint_key = STATIC_KEY_INIT;
 
 void opal_tracepoint_regfunc(void)
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 34e6423..059cfe0 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -642,7 +642,7 @@ EXPORT_SYMBOL(arch_free_page);
 #endif
 
 #ifdef CONFIG_TRACEPOINTS
-#ifdef CONFIG_JUMP_LABEL
+#ifdef HAVE_JUMP_LABEL
 struct static_key hcall_tracepoint_key = STATIC_KEY_INIT;
 
 void hcall_tracepoint_regfunc(void)
-- 
1.7.10.4

^ permalink raw reply related

* Re: [PATCH v2 2/2] powerpc/booke: Revert SPE/AltiVec common defines for interrupt numbers
From: Scott Wood @ 2014-08-21  1:58 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: linuxppc-dev, Alexander Graf, kvm-ppc
In-Reply-To: <1408540144-24436-2-git-send-email-mihai.caraman@freescale.com>

On Wed, 2014-08-20 at 16:09 +0300, Mihai Caraman wrote:
> Book3E specification defines shared interrupt numbers for SPE and AltiVec
> units. Still SPE is present in e200/e500v2 cores while AltiVec is present in
> e6500 core. So we can currently decide at compile-time which unit to support
> exclusively. As Alexander Graf suggested, this will improve code readability
> especially in KVM.
> 
> Use distinct defines to identify SPE/AltiVec interrupt numbers, reverting
> c58ce397 and 6b310fc5 patches that added common defines.
> 
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> Cc: Scott Wood <scottwood@freescale.com>
> Cc: Alexander Graf <agraf@suse.de>
> ---
>  arch/powerpc/kernel/exceptions-64e.S | 4 ++--
>  arch/powerpc/kernel/head_fsl_booke.S | 8 ++++----
>  2 files changed, 6 insertions(+), 6 deletions(-)

Acked-by: Scott Wood <scottwood@freescale.com>

-Scott

^ permalink raw reply

* Re: [PATCH v2 1/2] powerpc/booke: Restrict SPE exception handlers to e200/e500 cores
From: Scott Wood @ 2014-08-21  1:57 UTC (permalink / raw)
  To: Mihai Caraman; +Cc: linuxppc-dev, Alexander Graf, kvm-ppc
In-Reply-To: <1408540144-24436-1-git-send-email-mihai.caraman@freescale.com>

On Wed, 2014-08-20 at 16:09 +0300, Mihai Caraman wrote:
> SPE exception handlers are now defined for 32-bit e500mc cores even though
> SPE unit is not present and CONFIG_SPE is undefined.
> 
> Restrict SPE exception handlers to e200/e500 cores adding CONFIG_SPE_POSSIBLE
> and consequently guard __stup_ivors and __setup_cpu functions.
> 
> Signed-off-by: Mihai Caraman <mihai.caraman@freescale.com>
> Cc: Scott Wood <scottwood@freescale.com>
> Cc: Alexander Graf <agraf@suse.de>
> ---
> v2:
>  - use CONFIG_PPC_E500MC without CONFIG_E500
>  - use elif defined()
> 
>  arch/powerpc/kernel/cpu_setup_fsl_booke.S | 12 +++++++++++-
>  arch/powerpc/kernel/cputable.c            |  5 +++++
>  arch/powerpc/kernel/head_fsl_booke.S      | 18 +++++++++++++-----
>  arch/powerpc/platforms/Kconfig.cputype    |  6 +++++-
>  4 files changed, 34 insertions(+), 7 deletions(-)

Acked-by: Scott Wood <scottwood@freescale.com>

-Scott

^ permalink raw reply

* [PATCH] powerpc: fsl_pci: Fix PCI/PCI-X regression
From: Aaron Sierra @ 2014-08-20 23:51 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Minghuan Lian
In-Reply-To: <1884375274.96749.1408578481814.JavaMail.zimbra@xes-inc.com>

The following commit prevents the MPC8548E on the XPedite5200 PrPMC
module from enumerating its PCI/PCI-X bus, though it was previously
able to:

    powerpc/fsl-pci: use 'Header Type' to identify PCIE mode

The previous patch prevents any Freescale PCI-X bridge from enumerating
the bus, if it is hardware strapped into Agent mode.

In PCI-X, the Host is responsible for driving the PCI-X initialization
pattern to devices on the bus, so that they know whether to operate in
conventional PCI or PCI-X mode as well as what the bus timing will be.
For a PCI-X PrPMC, the pattern is driven by the mezzanine carrier it is
installed onto. Therefore, PrPMCs are PCI-X Agents, but they may still
enumerate the bus.

This patch depends on firmware to determine if the bridge should
perform enumeration based on factors other than the Host/Agent mode,
such as the state of the VITA 32-defined MONARCH# signal. If firmware
has determined that enumeration should be allowed, then it will set the
bridge's Bus Master bit in the Command register.

Without firmware intervention, the Bus Master bit defaults to 1 in Host
mode and 0 in Agent mode.

Cc: Minghuan Lian <Minghuan.Lian@freescale.com>
Signed-off-by: Aaron Sierra <asierra@xes-inc.com>
---
 arch/powerpc/sysdev/fsl_pci.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index 4bd091a..88d8844 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -463,7 +463,7 @@ int fsl_add_bridge(struct platform_device *pdev, int is_primary)
 	struct pci_controller *hose;
 	struct resource rsrc;
 	const int *bus_range;
-	u8 hdr_type, progif;
+	u8 hdr_type;
 	struct device_node *dev;
 	struct ccsr_pci __iomem *pci;
 
@@ -520,9 +520,22 @@ int fsl_add_bridge(struct platform_device *pdev, int is_primary)
 			goto no_bridge;
 
 	} else {
-		/* For PCI read PROG to identify controller mode */
-		early_read_config_byte(hose, 0, 0, PCI_CLASS_PROG, &progif);
-		if ((progif & 1) == 1)
+		u16 master;
+
+		/*
+		 * If the controller is PCI-X, then Host mode refers to a
+		 * bridge that drives the PCI-X initialization pattern to
+		 * indicate bus operating mode/frequency to devices on the bus.
+		 * Some hardware (specifically PrPMC modules) are Agents, since
+		 * the mezzanine carrier is responsible for driving the
+		 * pattern, but they still may perform bus enumeration.
+		 *
+		 * Allow the bridge to be used for enumeration, if hardware
+		 * strapping (Host mode) or firmware (Agent mode) has enabled
+		 * bus mastering.
+		 */
+		early_read_config_word(hose, 0, 0, PCI_COMMAND, &master);
+		if (!(master & PCI_COMMAND_MASTER))
 			goto no_bridge;
 	}
 
-- 
1.9.1

^ permalink raw reply related

* [PATCH] PCI: Increase BAR size quirk for IBM ipr SAS Crocodile adapters
From: Anton Blanchard @ 2014-08-20 23:26 UTC (permalink / raw)
  To: bhelgaas; +Cc: linux-pci, miltonm, linuxppc-dev, linux-kernel, dllehr

From: Douglas Lehr <dllehr@us.ibm.com>

The Crocodile chip occasionally comes up with 4k and 8k BAR sizes.
Due to an errata, setting the SR-IOV page size causes the physical
function BARs to expand to the system page size.  Since ppc64 uses
64k pages, when Linux tries to assign the smaller resource sizes
to the now 64k BARs the address will be truncated and the BARs will
overlap.

This quirk will force Linux to allocate the resource as a full page,
which will avoid the overlap.

Cc: <stable@vger.kernel.org> 
Signed-off-by: Douglas Lehr <dllehr@us.ibm.com>
Signed-off-by: Anton Blanchard <anton@samba.org>
Acked-by: Milton Miller <miltonm@us.ibm.com>
---
 drivers/pci/quirks.c |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 80c2d01..45b946d 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -24,6 +24,7 @@
 #include <linux/ioport.h>
 #include <linux/sched.h>
 #include <linux/ktime.h>
+#include <linux/mm.h>
 #include <asm/dma.h>	/* isa_dma_bridge_buggy */
 #include "pci.h"
 
@@ -287,6 +288,24 @@ static void quirk_citrine(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM,	PCI_DEVICE_ID_IBM_CITRINE,	quirk_citrine);
 
+/*  On IBM Crocodile ipr SAS adapters, expand bar size to system page size. */
+static void quirk_extend_bar_to_page(struct pci_dev *dev)
+{
+	int i;
+
+	for (i = 0; i < PCI_STD_RESOURCE_END; i++) {
+		struct resource *r = &dev->resource[i];
+
+		if (r->flags & IORESOURCE_MEM && resource_size(r) < PAGE_SIZE) {
+			dev_info(&dev->dev, "Setting Bar size to Page size");
+			r->end = PAGE_SIZE-1;
+			r->start = 0;
+			r->flags |= IORESOURCE_UNSET;
+		}
+	}
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_IBM, 0x034a, quirk_extend_bar_to_page);
+
 /*
  *  S3 868 and 968 chips report region size equal to 32M, but they decode 64M.
  *  If it's needed, re-allocate the region.
-- 
1.7.9.5

^ permalink raw reply related

* Re: [PATCH 2/2] fsl_ifc: Support all 8 IFC chip selects
From: Scott Wood @ 2014-08-20 23:21 UTC (permalink / raw)
  To: Prabhakar Kushwaha
  Cc: Greg Kroah-Hartman, Aaron Sierra, linuxppc-dev, Arnd Bergmann
In-Reply-To: <53F4179F.1010803@freescale.com>

On Wed, 2014-08-20 at 09:05 +0530, Prabhakar Kushwaha wrote:
> On 8/20/2014 5:38 AM, Scott Wood wrote:
> > On Fri, 2014-08-15 at 16:07 -0500, Aaron Sierra wrote:
> >> Freescale's QorIQ T Series processors support 8 IFC chip selects
> >> within a memory map backward compatible with previous P Series
> >> processors which supported only 4 chip selects.
> >>
> >> Signed-off-by: Aaron Sierra <asierra@xes-inc.com>
> >> ---
> >>   include/linux/fsl_ifc.h | 10 +++++-----
> >>   1 file changed, 5 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/include/linux/fsl_ifc.h b/include/linux/fsl_ifc.h
> >> index 84d60cb..62762ff 100644
> >> --- a/include/linux/fsl_ifc.h
> >> +++ b/include/linux/fsl_ifc.h
> >> @@ -29,7 +29,7 @@
> >>   #include <linux/of_platform.h>
> >>   #include <linux/interrupt.h>
> >>   
> >> -#define FSL_IFC_BANK_COUNT 4
> >> +#define FSL_IFC_BANK_COUNT 8
> > First please modify fsl_ifc_nand.c to limit itself to the number of
> > banks it dynamically determines are present based on the IFC version.
> >
> >
> 
> Number of available bank/chip select are defined by SoC and it is 
> independent of SoC.

Do you mean defined by the SoC and independent of the IFC version?

> It should be fix in following way
> 
> Option 1:
> u-boot:  fix device tree with number of available chip select. It may 
> require IFC binding change
> Linux: Read device tree and determine the Chip Selects

If we do this then it will need to be an optional property that defaults
to the current assumption being made (4).

In the future we really ought to check whether there are integration
parameters when coming up with the initial binding for a hardware
block...

> Option 2:
> Make it static because any way IFC NAND driver polls to 
> FSL_IFC_BANK_COUNT to know NAND flash chip select. This patch is doing same.

I don't understand what you're saying here.  The driver does not know at
compile time how many there are.  What this patch does is assume it's OK
to access non-existent registers in the rare case that there's no match
in the registers that exist.

Aaron tested this on P1010 and it seemed to work, though I'm not
generally fond of relying on such things.

-Scott

^ permalink raw reply

* Re: PCIe driver not working properly after upgrading to linux 3.8.13
From: Aaron Sierra @ 2014-08-20 16:21 UTC (permalink / raw)
  To: Gokul C G; +Cc: meta-freescale, linux-pci, linuxppc-dev, djiang
In-Reply-To: <53F3629A.6060208@kalkitech.in>

----- Original Message -----
> From: "Gokul C G" <gokul.g@kalkitech.in>
> Sent: Tuesday, August 19, 2014 9:43:38 AM
> 
> HI,
> 
> I am facing problem with PCIE driver in new Linux kernel compiled for powerpc
> architecture (Big endian) ,freescales P2040 processor.I was using old kernel
> Linux version 3.0.48 previously and now updated to Linux version
> 3.8.13-rt9.After updating to the new kernel, PCIe device drivers not working
> properly and i am getting some error messages in the boot-up .My intention
> is to use EXAR PCIe Multiport serial driver and add 8 serial ports in
> addition to 4 built in serial ports provided by P2040 processor. The PCIe
> driver form EXAR is compiled and loaded as kernel module . The same was
> working with linux kernel 3.0.48 and following prints observed while loading
> kernel module.
> 

Have you attempted to use the XR17V35x support present in the updated version
of the kernel that you're using (I assume it's Freescale SDK 1.4.x)?

8250 core support for Exar parts:
http://git.freescale.com/git/cgit.cgi/ppc/sdk/linux.git/tree/drivers/tty/serial/8250/8250.c?h=sdk-v.1.4.x#n296

PCI vendor and device IDs for 2, 4 and 8 port Exar parts:
http://git.freescale.com/git/cgit.cgi/ppc/sdk/linux.git/tree/drivers/tty/serial/8250/8250_pci.c?h=sdk-v.1.4.x#n1722

-Aaron

^ permalink raw reply

* Re: [PATCH 2/2] fsl_ifc: Support all 8 IFC chip selects
From: Aaron Sierra @ 2014-08-20 15:54 UTC (permalink / raw)
  To: Prabhakar Kushwaha, Scott Wood
  Cc: Greg Kroah-Hartman, linuxppc-dev, Arnd Bergmann
In-Reply-To: <53F4179F.1010803@freescale.com>

> >> -#define FSL_IFC_BANK_COUNT 4
> >> +#define FSL_IFC_BANK_COUNT 8
> > First please modify fsl_ifc_nand.c to limit itself to the number of
> > banks it dynamically determines are present based on the IFC version.
> >
> >
> 
> Number of available bank/chip select are defined by SoC and it is
> independent of SoC.

You mean that there is no way to tell from an IFC-specific register how
many chip selects are valid for a given SoC, correct?

> It should be fix in following way
> 
> Option 1:
> u-boot:  fix device tree with number of available chip select. It may
> require IFC binding change
> Linux: Read device tree and determine the Chip Selects
> 
> or
> 
> Option 2:
> Make it static because any way IFC NAND driver polls to
> FSL_IFC_BANK_COUNT to know NAND flash chip select. This patch is doing same.

My patch is based on the assumption that it is safe to access the addresses of
the four nonexistent (unconnected?) chip selects in devices with fewer than
eight chip selects.

Also, the full FSL_IFC_BANK_COUNT range of chip selects should only be probed
when no match is not found for a chip select's DTS-defined address base within
any IFC bank. The typical case would be for the device tree to properly define
the address space prepared by the bootloader, which would result in only banks
present in the SoC being probed.

I have tested this patch on P1010 and T1042 processors, which feature four and
eight chip selects respectively with no apparent ill effects.

Our P1010 product has NAND attached to chip selects 0 and 1:

    ranges = <0x0 0x0 0x0 0xef800000 0x0010000
              0x1 0x0 0x0 0xef840000 0x0010000>;

I mangled chip-select 0 so that the DTS-defined base would not match the
address programmed by firmware, so that all eight chip selects would be
scanned on this four chip-select part:

    ranges = <0x0 0x0 0x0 0xefc00000 0x0010000
              0x1 0x0 0x0 0xef840000 0x0010000>;

This resulted in the following kernel message:

fsl,ifc-nand efc00000.nand0: fsl_ifc_nand_probe: address did not match any chip selects

The NAND device at chip select 1 was properly detected.

> Regards,
> Prabhakar

^ permalink raw reply

* Re: [PATCH v2 00/14] Add support for parameterized events from sysfs
From: Jiri Olsa @ 2014-08-20 14:15 UTC (permalink / raw)
  To: Sukadev Bhattiprolu
  Cc: ak, Michael Ellerman, peterz, linux-kernel, eranian, dev,
	Arnaldo Carvalho de Melo, linuxppc-dev, Anshuman Khandual
In-Reply-To: <1408087583-32239-1-git-send-email-sukadev@linux.vnet.ibm.com>

On Fri, Aug 15, 2014 at 12:26:09AM -0700, Sukadev Bhattiprolu wrote:
> From: Cody P Schafer <dev@codyps.com>
> 
> What this patchset does:
> 
>  - the first patch (override sysfs in tools/perf via SYSFS_PATH) was sent out
>    previously, but needed a resend anyhow. Having it is useful for testing the
>    later changes to tools/perf.
>  - the second patch is a bugfix to the powerpc hv-24x7 code which was
>    previously sent out, which is a good idea to have when testing these patches
>    on POWER8 hardware.
> 
>  - document perf sysfs and the changes to add parameterized events
>    - semi-notably: removes the growing list of specific POWER cpu events and
>      begins documenting them generically, much like the docs for
>      /sys/modules/MODULENAME do for modules.
>  - tools/perf changes to support parameterized events
>  - export some parameterized events from the powerpc pmus hv_24x7 and hv_gpci
> 
> Description of "event parameters" from the documentation patch:
> 
>     Event parameters are a basic way for partial events to be specified in
>     sysfs with per-event names given to the fields that need to be filled in
>     when using a particular event.
> 
>     It is intended for supporting cases where the single 'cpu' parameter is
>     insufficient. For example, POWER 8 has events for physical
>     sockets/cores/cpus that are accessible from with virtual machines. To
>     keep using the single 'cpu' parameter we'd need to perform a mapping
>     between Linux's cpus and the physical machine's cpus (in this case
>     Linux is running under a hypervisor). This isn't possible because
>     bindings between our cpus and physical cpus may not be fixed, and we
>     probably won't have a "cpu" on each physical cpu.
> 
> Description of the sysfs contents when events are parameterized (copied from an
> included patch):
> 
> 	Examples:
> 
> 		domain=0x1,offset=0x8,starting_index=phys_cpu
> 
> 	In the case of the last example, a value replacing "phys_cpu"
> 	would need to be provided by the user selecting the particular
> 	event. This is refered to as "event parameterization". All
> 	non-numerical values indicate an event parameter.
> 
> Notes on how perf-list displays parameterized events (and how to use them,
> again culled from an included patch):
> 
> 	PARAMETERIZED EVENTS
> 	--------------------
> 
> 	Some pmu events listed by 'perf-list' will be displayed with '?' in
> 	them. For example:
> 
> 	  hv_gpci/dtbp_ptitc,phys_processor_idx=?/
> 
> 	This means that when provided as an event, a value for
> 	phys_processor_idx must also be supplied. For example:
> 
> 	  perf stat -e 'hv_gpci/dtbp_ptitc,phys_processor_idx=0x2/' ...

hi,
is the reason for this to document this field for event
in "events/<event>" file?

Because once you have the field (phys_processor_idx) defined in
"formats/phys_processor_idx" you should be able to use it as in
your example:

   perf stat -e 'hv_gpci/dtbp_ptitc,phys_processor_idx=0x2/'

without any changes

thanks,
jirka

^ 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