|
@@ -61,11 +61,21 @@ struct cache_type_info {
|
|
};
|
|
};
|
|
|
|
|
|
/* These are used to index the cache_type_info array. */
|
|
/* 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
|
|
|
|
|
|
+#define CACHE_TYPE_UNIFIED 0 /* cache-size, cache-block-size, etc. */
|
|
|
|
+#define CACHE_TYPE_UNIFIED_D 1 /* d-cache-size, d-cache-block-size, etc */
|
|
|
|
+#define CACHE_TYPE_INSTRUCTION 2
|
|
|
|
+#define CACHE_TYPE_DATA 3
|
|
|
|
|
|
static const struct cache_type_info cache_type_info[] = {
|
|
static const struct cache_type_info cache_type_info[] = {
|
|
|
|
+ {
|
|
|
|
+ /* Embedded systems that use cache-size, cache-block-size,
|
|
|
|
+ * etc. for the Unified (typically L2) cache. */
|
|
|
|
+ .name = "Unified",
|
|
|
|
+ .size_prop = "cache-size",
|
|
|
|
+ .line_size_props = { "cache-line-size",
|
|
|
|
+ "cache-block-size", },
|
|
|
|
+ .nr_sets_prop = "cache-sets",
|
|
|
|
+ },
|
|
{
|
|
{
|
|
/* PowerPC Processor binding says the [di]-cache-*
|
|
/* PowerPC Processor binding says the [di]-cache-*
|
|
* must be equal on unified caches, so just use
|
|
* must be equal on unified caches, so just use
|
|
@@ -293,7 +303,8 @@ static struct cache *cache_find_first_sibling(struct cache *cache)
|
|
{
|
|
{
|
|
struct cache *iter;
|
|
struct cache *iter;
|
|
|
|
|
|
- if (cache->type == CACHE_TYPE_UNIFIED)
|
|
|
|
|
|
+ if (cache->type == CACHE_TYPE_UNIFIED ||
|
|
|
|
+ cache->type == CACHE_TYPE_UNIFIED_D)
|
|
return cache;
|
|
return cache;
|
|
|
|
|
|
list_for_each_entry(iter, &cache_list, list)
|
|
list_for_each_entry(iter, &cache_list, list)
|
|
@@ -324,16 +335,29 @@ static bool cache_node_is_unified(const struct device_node *np)
|
|
return of_get_property(np, "cache-unified", NULL);
|
|
return of_get_property(np, "cache-unified", NULL);
|
|
}
|
|
}
|
|
|
|
|
|
-static struct cache *cache_do_one_devnode_unified(struct device_node *node,
|
|
|
|
- int level)
|
|
|
|
|
|
+/*
|
|
|
|
+ * Unified caches can have two different sets of tags. Most embedded
|
|
|
|
+ * use cache-size, etc. for the unified cache size, but open firmware systems
|
|
|
|
+ * use d-cache-size, etc. Check on initialization for which type we have, and
|
|
|
|
+ * return the appropriate structure type. Assume it's embedded if it isn't
|
|
|
|
+ * open firmware. If it's yet a 3rd type, then there will be missing entries
|
|
|
|
+ * in /sys/devices/system/cpu/cpu0/cache/index2/, and this code will need
|
|
|
|
+ * to be extended further.
|
|
|
|
+ */
|
|
|
|
+static int cache_is_unified_d(const struct device_node *np)
|
|
{
|
|
{
|
|
- struct cache *cache;
|
|
|
|
|
|
+ return of_get_property(np,
|
|
|
|
+ cache_type_info[CACHE_TYPE_UNIFIED_D].size_prop, NULL) ?
|
|
|
|
+ CACHE_TYPE_UNIFIED_D : CACHE_TYPE_UNIFIED;
|
|
|
|
+}
|
|
|
|
|
|
|
|
+/*
|
|
|
|
+ */
|
|
|
|
+static struct cache *cache_do_one_devnode_unified(struct device_node *node, int level)
|
|
|
|
+{
|
|
pr_debug("creating L%d ucache for %s\n", level, node->full_name);
|
|
pr_debug("creating L%d ucache for %s\n", level, node->full_name);
|
|
|
|
|
|
- cache = new_cache(CACHE_TYPE_UNIFIED, level, node);
|
|
|
|
-
|
|
|
|
- return cache;
|
|
|
|
|
|
+ return new_cache(cache_is_unified_d(node), level, node);
|
|
}
|
|
}
|
|
|
|
|
|
static struct cache *cache_do_one_devnode_split(struct device_node *node,
|
|
static struct cache *cache_do_one_devnode_split(struct device_node *node,
|