brcm63xx: add support for registering parallel flash through dtb
Add the required nodes to the dtsi files and code to prevent double registration from the board support code. Signed-off-by: Jonas Gorski <jogo@openwrt.org> SVN-Revision: 42123
This commit is contained in:
parent
79057c7255
commit
9c6287d6a1
22 changed files with 711 additions and 21 deletions
|
@ -3,6 +3,10 @@
|
|||
#size-cells = <1>;
|
||||
compatible = "brcm,bcm6338";
|
||||
|
||||
aliases {
|
||||
pflash = &pflash;
|
||||
};
|
||||
|
||||
cpus {
|
||||
cpu@0 {
|
||||
compatible = "brcm,bmips3300", "mips,mips4Kc";
|
||||
|
@ -11,6 +15,16 @@
|
|||
|
||||
memory { device_type = "memory"; reg = <0 0>; };
|
||||
|
||||
pflash: nor@1fc00000 {
|
||||
compatible = "cfi-flash";
|
||||
reg = <0x1fc00000 0x400000>;
|
||||
bank-witdh = <2>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ubus@fff00000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
#size-cells = <1>;
|
||||
compatible = "brcm,bcm6345";
|
||||
|
||||
aliases {
|
||||
pflash = &pflash;
|
||||
};
|
||||
|
||||
cpus {
|
||||
cpu@0 {
|
||||
compatible = "brcm,bmips32", "mips,mips4Kc";
|
||||
|
@ -11,6 +15,16 @@
|
|||
|
||||
memory { device_type = "memory"; reg = <0 0>; };
|
||||
|
||||
pflash: nor@1fc00000 {
|
||||
compatible = "cfi-flash";
|
||||
reg = <0x1fc00000 0x400000>;
|
||||
bank-witdh = <2>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ubus@fff00000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
#size-cells = <1>;
|
||||
compatible = "brcm,bcm6348";
|
||||
|
||||
aliases {
|
||||
pflash = &pflash;
|
||||
};
|
||||
|
||||
cpus {
|
||||
cpu@0 {
|
||||
compatible = "brcm,bmips3300", "mips,mips4Kc";
|
||||
|
@ -11,6 +15,16 @@
|
|||
|
||||
memory { device_type = "memory"; reg = <0 0>; };
|
||||
|
||||
pflash: nor@1fc00000 {
|
||||
compatible = "cfi-flash";
|
||||
reg = <0x1fc00000 0x400000>;
|
||||
bank-witdh = <2>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ubus@fff00000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
#size-cells = <1>;
|
||||
compatible = "brcm,bcm6358";
|
||||
|
||||
aliases {
|
||||
pflash = &pflash;
|
||||
};
|
||||
|
||||
cpus {
|
||||
cpu@0 {
|
||||
compatible = "brcm,bmips4350", "mips,mips4Kc";
|
||||
|
@ -15,6 +19,16 @@
|
|||
|
||||
memory { device_type = "memory"; reg = <0 0>; };
|
||||
|
||||
pflash: nor@1e000000 {
|
||||
compatible = "cfi-flash";
|
||||
reg = <0x1e000000 0x2000000>;
|
||||
bank-width = <2>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ubus@fff00000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
#size-cells = <1>;
|
||||
compatible = "brcm,bcm6368";
|
||||
|
||||
aliases {
|
||||
pflash = &pflash;
|
||||
};
|
||||
|
||||
cpus {
|
||||
cpu@0 {
|
||||
compatible = "brcm,bmips4350", "mips,mips4Kc";
|
||||
|
@ -20,4 +24,13 @@
|
|||
#size-cells = <1>;
|
||||
compatible = "simple-bus";
|
||||
};
|
||||
|
||||
pflash: nor@18000000 {
|
||||
compatible = "cfi-flash";
|
||||
reg = <0x18000000 0x2000000>;
|
||||
bank-width = <2>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
From 0d0e02d605c5696a5076510f564fefe659127aa4 Mon Sep 17 00:00:00 2001
|
||||
From: Grant Likely <grant.likely@linaro.org>
|
||||
Date: Thu, 22 May 2014 01:04:17 +0900
|
||||
Subject: [PATCH] of: Create unlocked version of for_each_child_of_node()
|
||||
|
||||
When iterating over nodes, sometimes it needs to be done when the DT
|
||||
lock is already held. This patch makes an unlocked version of the
|
||||
for_each_child_of_node() macro.
|
||||
|
||||
Signed-off-by: Grant Likely <grant.likely@linaro.org>
|
||||
---
|
||||
drivers/of/base.c | 22 +++++++++++++++++-----
|
||||
1 file changed, 17 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/drivers/of/base.c
|
||||
+++ b/drivers/of/base.c
|
||||
@@ -545,6 +545,22 @@ struct device_node *of_get_next_parent(s
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_next_parent);
|
||||
|
||||
+static struct device_node *__of_get_next_child(const struct device_node *node,
|
||||
+ struct device_node *prev)
|
||||
+{
|
||||
+ struct device_node *next;
|
||||
+
|
||||
+ next = prev ? prev->sibling : node->child;
|
||||
+ for (; next; next = next->sibling)
|
||||
+ if (of_node_get(next))
|
||||
+ break;
|
||||
+ of_node_put(prev);
|
||||
+ return next;
|
||||
+}
|
||||
+#define __for_each_child_of_node(parent, child) \
|
||||
+ for (child = __of_get_next_child(parent, NULL); child != NULL; \
|
||||
+ child = __of_get_next_child(parent, child))
|
||||
+
|
||||
/**
|
||||
* of_get_next_child - Iterate a node childs
|
||||
* @node: parent node
|
||||
@@ -560,11 +576,7 @@ struct device_node *of_get_next_child(co
|
||||
unsigned long flags;
|
||||
|
||||
raw_spin_lock_irqsave(&devtree_lock, flags);
|
||||
- next = prev ? prev->sibling : node->child;
|
||||
- for (; next; next = next->sibling)
|
||||
- if (of_node_get(next))
|
||||
- break;
|
||||
- of_node_put(prev);
|
||||
+ next = __of_get_next_child(node, prev);
|
||||
raw_spin_unlock_irqrestore(&devtree_lock, flags);
|
||||
return next;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
From 11d200e95f3e84c1102e4cc9863a3614fd41f3ad Mon Sep 17 00:00:00 2001
|
||||
From: Grant Likely <grant.likely@linaro.org>
|
||||
Date: Fri, 14 Mar 2014 17:00:14 +0000
|
||||
Subject: [PATCH] lib: add glibc style strchrnul() variant
|
||||
|
||||
The strchrnul() variant helpfully returns a the end of the string
|
||||
instead of a NULL if the requested character is not found. This can
|
||||
simplify string parsing code since it doesn't need to expicitly check
|
||||
for a NULL return. If a valid string pointer is passed in, then a valid
|
||||
null terminated string will always come back out.
|
||||
|
||||
Signed-off-by: Grant Likely <grant.likely@linaro.org>
|
||||
---
|
||||
include/linux/string.h | 3 +++
|
||||
lib/string.c | 18 ++++++++++++++++++
|
||||
2 files changed, 21 insertions(+)
|
||||
|
||||
--- a/include/linux/string.h
|
||||
+++ b/include/linux/string.h
|
||||
@@ -52,6 +52,9 @@ extern int strncasecmp(const char *s1, c
|
||||
#ifndef __HAVE_ARCH_STRCHR
|
||||
extern char * strchr(const char *,int);
|
||||
#endif
|
||||
+#ifndef __HAVE_ARCH_STRCHRNUL
|
||||
+extern char * strchrnul(const char *,int);
|
||||
+#endif
|
||||
#ifndef __HAVE_ARCH_STRNCHR
|
||||
extern char * strnchr(const char *, size_t, int);
|
||||
#endif
|
||||
--- a/lib/string.c
|
||||
+++ b/lib/string.c
|
||||
@@ -301,6 +301,24 @@ char *strchr(const char *s, int c)
|
||||
EXPORT_SYMBOL(strchr);
|
||||
#endif
|
||||
|
||||
+#ifndef __HAVE_ARCH_STRCHRNUL
|
||||
+/**
|
||||
+ * strchrnul - Find and return a character in a string, or end of string
|
||||
+ * @s: The string to be searched
|
||||
+ * @c: The character to search for
|
||||
+ *
|
||||
+ * Returns pointer to first occurrence of 'c' in s. If c is not found, then
|
||||
+ * return a pointer to the null byte at the end of s.
|
||||
+ */
|
||||
+char *strchrnul(const char *s, int c)
|
||||
+{
|
||||
+ while (*s && *s != (char)c)
|
||||
+ s++;
|
||||
+ return (char *)s;
|
||||
+}
|
||||
+EXPORT_SYMBOL(strchrnul);
|
||||
+#endif
|
||||
+
|
||||
#ifndef __HAVE_ARCH_STRRCHR
|
||||
/**
|
||||
* strrchr - Find the last occurrence of a character in a string
|
|
@ -0,0 +1,106 @@
|
|||
From c22e650e66b862babe9c00bebb20b8029c7b0362 Mon Sep 17 00:00:00 2001
|
||||
From: Grant Likely <grant.likely@linaro.org>
|
||||
Date: Fri, 14 Mar 2014 17:07:12 +0000
|
||||
Subject: [PATCH] of: Make of_find_node_by_path() handle /aliases
|
||||
|
||||
Make of_find_node_by_path() handle aliases as prefixes. To make this
|
||||
work the name search is refactored to search by path component instead
|
||||
of by full string. This should be a more efficient search, and it makes
|
||||
it possible to start a search at a subnode of a tree.
|
||||
|
||||
Signed-off-by: David Daney <david.daney@cavium.com>
|
||||
Signed-off-by: Pantelis Antoniou <pantelis.antoniou@konsulko.com>
|
||||
[grant.likely: Rework to not require allocating at runtime]
|
||||
Acked-by: Rob Herring <robh@kernel.org>
|
||||
Signed-off-by: Grant Likely <grant.likely@linaro.org>
|
||||
---
|
||||
drivers/of/base.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 61 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/of/base.c
|
||||
+++ b/drivers/of/base.c
|
||||
@@ -633,23 +633,78 @@ struct device_node *of_get_child_by_name
|
||||
}
|
||||
EXPORT_SYMBOL(of_get_child_by_name);
|
||||
|
||||
+static struct device_node *__of_find_node_by_path(struct device_node *parent,
|
||||
+ const char *path)
|
||||
+{
|
||||
+ struct device_node *child;
|
||||
+ int len = strchrnul(path, '/') - path;
|
||||
+
|
||||
+ if (!len)
|
||||
+ return NULL;
|
||||
+
|
||||
+ __for_each_child_of_node(parent, child) {
|
||||
+ const char *name = strrchr(child->full_name, '/');
|
||||
+ if (WARN(!name, "malformed device_node %s\n", child->full_name))
|
||||
+ continue;
|
||||
+ name++;
|
||||
+ if (strncmp(path, name, len) == 0 && (strlen(name) == len))
|
||||
+ return child;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* of_find_node_by_path - Find a node matching a full OF path
|
||||
- * @path: The full path to match
|
||||
+ * @path: Either the full path to match, or if the path does not
|
||||
+ * start with '/', the name of a property of the /aliases
|
||||
+ * node (an alias). In the case of an alias, the node
|
||||
+ * matching the alias' value will be returned.
|
||||
+ *
|
||||
+ * Valid paths:
|
||||
+ * /foo/bar Full path
|
||||
+ * foo Valid alias
|
||||
+ * foo/bar Valid alias + relative path
|
||||
*
|
||||
* Returns a node pointer with refcount incremented, use
|
||||
* of_node_put() on it when done.
|
||||
*/
|
||||
struct device_node *of_find_node_by_path(const char *path)
|
||||
{
|
||||
- struct device_node *np = of_allnodes;
|
||||
+ struct device_node *np = NULL;
|
||||
+ struct property *pp;
|
||||
unsigned long flags;
|
||||
|
||||
+ if (strcmp(path, "/") == 0)
|
||||
+ return of_node_get(of_allnodes);
|
||||
+
|
||||
+ /* The path could begin with an alias */
|
||||
+ if (*path != '/') {
|
||||
+ char *p = strchrnul(path, '/');
|
||||
+ int len = p - path;
|
||||
+
|
||||
+ /* of_aliases must not be NULL */
|
||||
+ if (!of_aliases)
|
||||
+ return NULL;
|
||||
+
|
||||
+ for_each_property_of_node(of_aliases, pp) {
|
||||
+ if (strlen(pp->name) == len && !strncmp(pp->name, path, len)) {
|
||||
+ np = of_find_node_by_path(pp->value);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!np)
|
||||
+ return NULL;
|
||||
+ path = p;
|
||||
+ }
|
||||
+
|
||||
+ /* Step down the tree matching path components */
|
||||
raw_spin_lock_irqsave(&devtree_lock, flags);
|
||||
- for (; np; np = np->allnext) {
|
||||
- if (np->full_name && (of_node_cmp(np->full_name, path) == 0)
|
||||
- && of_node_get(np))
|
||||
- break;
|
||||
+ if (!np)
|
||||
+ np = of_node_get(of_allnodes);
|
||||
+ while (np && *path == '/') {
|
||||
+ path++; /* Increment past '/' delimiter */
|
||||
+ np = __of_find_node_by_path(np, path);
|
||||
+ path = strchrnul(path, '/');
|
||||
}
|
||||
raw_spin_unlock_irqrestore(&devtree_lock, flags);
|
||||
return np;
|
|
@ -0,0 +1,37 @@
|
|||
--- a/arch/mips/bcm63xx/boards/board_common.c
|
||||
+++ b/arch/mips/bcm63xx/boards/board_common.c
|
||||
@@ -147,6 +147,18 @@ void __init device_tree_init(void)
|
||||
|
||||
unflatten_and_copy_device_tree();
|
||||
}
|
||||
+
|
||||
+int board_of_device_present(const char *alias)
|
||||
+{
|
||||
+ bool present;
|
||||
+ struct device_node *np;
|
||||
+
|
||||
+ np = of_find_node_by_path(alias);
|
||||
+ present = of_device_is_available(np);
|
||||
+ of_node_put(np);
|
||||
+
|
||||
+ return present;
|
||||
+}
|
||||
#endif
|
||||
|
||||
static struct gpio_led_platform_data bcm63xx_led_data;
|
||||
--- a/arch/mips/bcm63xx/boards/board_common.h
|
||||
+++ b/arch/mips/bcm63xx/boards/board_common.h
|
||||
@@ -15,4 +15,13 @@ void board_bcm963xx_init(void);
|
||||
static inline void board_bcm963xx_init(void) { }
|
||||
#endif
|
||||
|
||||
+#if defined(CONFIG_OF)
|
||||
+int board_of_device_present(const char *alias);
|
||||
+#else
|
||||
+static inline void board_of_device_present(const char *alias)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
#endif /* __BOARD_COMMON_H */
|
|
@ -0,0 +1,21 @@
|
|||
--- a/arch/mips/bcm63xx/dev-flash.c
|
||||
+++ b/arch/mips/bcm63xx/dev-flash.c
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <bcm63xx_regs.h>
|
||||
#include <bcm63xx_io.h>
|
||||
|
||||
+#include "boards/board_common.h"
|
||||
+
|
||||
static int flash_type;
|
||||
|
||||
static struct mtd_partition mtd_partitions[] = {
|
||||
@@ -164,6 +166,9 @@ int __init bcm63xx_flash_register(void)
|
||||
|
||||
switch (flash_type) {
|
||||
case BCM63XX_FLASH_TYPE_PARALLEL:
|
||||
+ /* don't register when already registered through from dtb */
|
||||
+ if (board_of_device_present("pflash"))
|
||||
+ return 0;
|
||||
|
||||
if (!mtd_resources[0].start) {
|
||||
/* read base address of boot chip select (0) */
|
|
@ -12,7 +12,7 @@ Signed-off-by: Axel Gembe <ago@bastart.eu.org>
|
|||
|
||||
--- a/arch/mips/bcm63xx/dev-flash.c
|
||||
+++ b/arch/mips/bcm63xx/dev-flash.c
|
||||
@@ -32,7 +32,7 @@ static struct mtd_partition mtd_partitio
|
||||
@@ -34,7 +34,7 @@ static struct mtd_partition mtd_partitio
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
|
|||
#include <bcm63xx_regs.h>
|
||||
#include <bcm63xx_io.h>
|
||||
|
||||
@@ -63,6 +66,21 @@ void __init bcm63xx_flash_force_phys_bas
|
||||
@@ -65,6 +68,21 @@ void __init bcm63xx_flash_force_phys_bas
|
||||
mtd_resources[0].end = end;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
|
|||
static int __init bcm63xx_detect_flash_type(void)
|
||||
{
|
||||
u32 val;
|
||||
@@ -70,9 +88,15 @@ static int __init bcm63xx_detect_flash_t
|
||||
@@ -72,9 +90,15 @@ static int __init bcm63xx_detect_flash_t
|
||||
switch (bcm63xx_get_cpu_id()) {
|
||||
case BCM6318_CPU_ID:
|
||||
/* only support serial flash */
|
||||
|
@ -62,7 +62,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
|
|||
if (val & STRAPBUS_6328_BOOT_SEL_SERIAL)
|
||||
return BCM63XX_FLASH_TYPE_SERIAL;
|
||||
else
|
||||
@@ -91,12 +115,20 @@ static int __init bcm63xx_detect_flash_t
|
||||
@@ -93,12 +117,20 @@ static int __init bcm63xx_detect_flash_t
|
||||
return BCM63XX_FLASH_TYPE_SERIAL;
|
||||
case BCM6362_CPU_ID:
|
||||
val = bcm_misc_readl(MISC_STRAPBUS_6362_REG);
|
||||
|
@ -83,7 +83,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
|
|||
switch (val & STRAPBUS_6368_BOOT_SEL_MASK) {
|
||||
case STRAPBUS_6368_BOOT_SEL_NAND:
|
||||
return BCM63XX_FLASH_TYPE_NAND;
|
||||
@@ -107,6 +139,11 @@ static int __init bcm63xx_detect_flash_t
|
||||
@@ -109,6 +141,11 @@ static int __init bcm63xx_detect_flash_t
|
||||
}
|
||||
case BCM63268_CPU_ID:
|
||||
val = bcm_misc_readl(MISC_STRAPBUS_63268_REG);
|
||||
|
@ -95,7 +95,7 @@ Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
|
|||
if (val & STRAPBUS_63268_BOOT_SEL_SERIAL)
|
||||
return BCM63XX_FLASH_TYPE_SERIAL;
|
||||
else
|
||||
@@ -176,8 +213,15 @@ int __init bcm63xx_flash_register(void)
|
||||
@@ -181,8 +218,15 @@ int __init bcm63xx_flash_register(void)
|
||||
|
||||
return platform_device_register(&mtd_dev);
|
||||
case BCM63XX_FLASH_TYPE_SERIAL:
|
||||
|
|
|
@ -18,7 +18,7 @@ Subject: [PATCH 58/72] BCM63XX: allow providing fixup data in board data
|
|||
|
||||
#include "board_common.h"
|
||||
|
||||
@@ -184,6 +185,7 @@ int __init board_register_devices(void)
|
||||
@@ -196,6 +197,7 @@ int __init board_register_devices(void)
|
||||
int button_count = 0;
|
||||
int led_count = 0;
|
||||
int usbh_ports = 0;
|
||||
|
@ -26,7 +26,7 @@ Subject: [PATCH 58/72] BCM63XX: allow providing fixup data in board data
|
|||
|
||||
#if CONFIG_OF
|
||||
if (of_have_populated_dt()) {
|
||||
@@ -281,6 +283,10 @@ int __init board_register_devices(void)
|
||||
@@ -293,6 +295,10 @@ int __init board_register_devices(void)
|
||||
platform_device_register(&bcm63xx_gpio_keys_device);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ Signed-off-by: Jonas Gorski <jogo@openwrt.org>
|
|||
|
||||
--- a/arch/mips/bcm63xx/dev-flash.c
|
||||
+++ b/arch/mips/bcm63xx/dev-flash.c
|
||||
@@ -231,3 +231,8 @@ int __init bcm63xx_flash_register(void)
|
||||
@@ -236,3 +236,8 @@ int __init bcm63xx_flash_register(void)
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ Subject: [PATCH 69/80] MIPS: BCM63XX: pass caldata info to flash
|
|||
|
||||
--- a/arch/mips/bcm63xx/boards/board_common.c
|
||||
+++ b/arch/mips/bcm63xx/boards/board_common.c
|
||||
@@ -255,7 +255,7 @@ int __init board_register_devices(void)
|
||||
@@ -267,7 +267,7 @@ int __init board_register_devices(void)
|
||||
if (board.num_spis)
|
||||
spi_register_board_info(board.spis, board.num_spis);
|
||||
|
||||
|
@ -22,7 +22,7 @@ Subject: [PATCH 69/80] MIPS: BCM63XX: pass caldata info to flash
|
|||
while (led_count < ARRAY_SIZE(board.leds) && board.leds[led_count].name)
|
||||
--- a/arch/mips/bcm63xx/dev-flash.c
|
||||
+++ b/arch/mips/bcm63xx/dev-flash.c
|
||||
@@ -35,12 +35,15 @@ static struct mtd_partition mtd_partitio
|
||||
@@ -37,12 +37,15 @@ static struct mtd_partition mtd_partitio
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -38,7 +38,7 @@ Subject: [PATCH 69/80] MIPS: BCM63XX: pass caldata info to flash
|
|||
};
|
||||
|
||||
static struct resource mtd_resources[] = {
|
||||
@@ -68,6 +71,7 @@ void __init bcm63xx_flash_force_phys_bas
|
||||
@@ -70,6 +73,7 @@ void __init bcm63xx_flash_force_phys_bas
|
||||
|
||||
static struct flash_platform_data bcm63xx_flash_data = {
|
||||
.part_probe_types = bcm63xx_part_types,
|
||||
|
@ -46,7 +46,7 @@ Subject: [PATCH 69/80] MIPS: BCM63XX: pass caldata info to flash
|
|||
};
|
||||
|
||||
static struct spi_board_info bcm63xx_spi_flash_info[] = {
|
||||
@@ -195,9 +199,13 @@ void __init bcm63xx_flash_detect(void)
|
||||
@@ -197,9 +201,13 @@ void __init bcm63xx_flash_detect(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
return;
|
||||
--- a/arch/mips/bcm63xx/boards/board_common.c
|
||||
+++ b/arch/mips/bcm63xx/boards/board_common.c
|
||||
@@ -285,7 +285,8 @@ int __init board_register_devices(void)
|
||||
@@ -297,7 +297,8 @@ int __init board_register_devices(void)
|
||||
|
||||
/* register any fixups */
|
||||
for (i = 0; i < board.has_caldata; i++)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/arch/mips/bcm63xx/boards/board_common.c
|
||||
+++ b/arch/mips/bcm63xx/boards/board_common.c
|
||||
@@ -286,7 +286,7 @@ int __init board_register_devices(void)
|
||||
@@ -298,7 +298,7 @@ int __init board_register_devices(void)
|
||||
/* register any fixups */
|
||||
for (i = 0; i < board.has_caldata; i++)
|
||||
pci_enable_ath9k_fixup(board.caldata[i].slot, board.caldata[i].caldata_offset,
|
||||
|
|
|
@ -36,7 +36,7 @@ Subject: [PATCH 72/72] 446-BCM63XX-add-a-fixup-for-rt2x00-devices
|
|||
|
||||
#include "board_common.h"
|
||||
|
||||
@@ -284,9 +285,19 @@ int __init board_register_devices(void)
|
||||
@@ -296,9 +297,19 @@ int __init board_register_devices(void)
|
||||
}
|
||||
|
||||
/* register any fixups */
|
||||
|
@ -61,7 +61,7 @@ Subject: [PATCH 72/72] 446-BCM63XX-add-a-fixup-for-rt2x00-devices
|
|||
}
|
||||
--- a/arch/mips/bcm63xx/dev-flash.c
|
||||
+++ b/arch/mips/bcm63xx/dev-flash.c
|
||||
@@ -199,7 +199,7 @@ void __init bcm63xx_flash_detect(void)
|
||||
@@ -201,7 +201,7 @@ void __init bcm63xx_flash_detect(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,349 @@
|
|||
--- a/drivers/mtd/bcm63xxpart.c
|
||||
+++ b/drivers/mtd/bcm63xxpart.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
+#include <linux/of.h>
|
||||
|
||||
#include <asm/mach-bcm63xx/bcm63xx_nvram.h>
|
||||
#include <linux/bcm963xx_tag.h>
|
||||
@@ -43,66 +44,35 @@
|
||||
|
||||
#define BCM63XX_CFE_MAGIC_OFFSET 0x4e0
|
||||
|
||||
-static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
|
||||
- struct mtd_partition **pparts,
|
||||
- struct mtd_part_parser_data *data)
|
||||
+static bool node_has_compatible(struct device_node *pp)
|
||||
+{
|
||||
+ return of_get_property(pp, "compatible", NULL);
|
||||
+}
|
||||
+
|
||||
+static int parse_bcmtag(struct mtd_info *master, struct mtd_partition *pparts,
|
||||
+ int next_part, size_t offset, size_t size)
|
||||
{
|
||||
- /* CFE, NVRAM and global Linux are always present */
|
||||
- int nrparts = 3, curpart = 0;
|
||||
struct bcm_tag *buf;
|
||||
- struct mtd_partition *parts;
|
||||
+ u32 computed_crc;
|
||||
int ret;
|
||||
size_t retlen;
|
||||
- unsigned int rootfsaddr, kerneladdr, spareaddr, nvramaddr;
|
||||
- unsigned int rootfslen, kernellen, sparelen, totallen;
|
||||
- unsigned int cfelen, nvramlen;
|
||||
- unsigned int cfe_erasesize;
|
||||
- unsigned int caldatalen1 = 0, caldataaddr1 = 0;
|
||||
- unsigned int caldatalen2 = 0, caldataaddr2 = 0;
|
||||
- int i;
|
||||
- u32 computed_crc;
|
||||
+ unsigned int rootfsaddr, kerneladdr;
|
||||
+ unsigned int rootfslen, kernellen, totallen;
|
||||
bool rootfs_first = false;
|
||||
-
|
||||
- if (!bcm63xx_is_cfe_present())
|
||||
- return -EINVAL;
|
||||
-
|
||||
- cfe_erasesize = max_t(uint32_t, master->erasesize,
|
||||
- BCM63XX_CFE_BLOCK_SIZE);
|
||||
-
|
||||
- cfelen = cfe_erasesize;
|
||||
- nvramlen = bcm63xx_nvram_get_psi_size() * SZ_1K;
|
||||
- nvramlen = roundup(nvramlen, cfe_erasesize);
|
||||
- nvramaddr = master->size - nvramlen;
|
||||
-
|
||||
- if (data) {
|
||||
- if (data->caldata[0]) {
|
||||
- caldatalen1 = cfe_erasesize;
|
||||
- caldataaddr1 = rounddown(data->caldata[0],
|
||||
- cfe_erasesize);
|
||||
- }
|
||||
- if (data->caldata[1]) {
|
||||
- caldatalen2 = cfe_erasesize;
|
||||
- caldataaddr2 = rounddown(data->caldata[1],
|
||||
- cfe_erasesize);
|
||||
- }
|
||||
- if (caldataaddr1 == caldataaddr2) {
|
||||
- caldataaddr2 = 0;
|
||||
- caldatalen2 = 0;
|
||||
- }
|
||||
- }
|
||||
+ int curr_part = next_part;
|
||||
|
||||
/* Allocate memory for buffer */
|
||||
- buf = vmalloc(sizeof(struct bcm_tag));
|
||||
+ buf = vmalloc(sizeof(*buf));
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Get the tag */
|
||||
- ret = mtd_read(master, cfelen, sizeof(struct bcm_tag), &retlen,
|
||||
+ ret = mtd_read(master, offset, sizeof(*buf), &retlen,
|
||||
(void *)buf);
|
||||
|
||||
- if (retlen != sizeof(struct bcm_tag)) {
|
||||
+ if (retlen != sizeof(*buf)) {
|
||||
vfree(buf);
|
||||
- return -EIO;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf,
|
||||
@@ -121,7 +91,6 @@ static int bcm63xx_parse_cfe_partitions(
|
||||
|
||||
kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE;
|
||||
rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE;
|
||||
- spareaddr = roundup(totallen, master->erasesize) + cfelen;
|
||||
|
||||
if (rootfsaddr < kerneladdr) {
|
||||
/* default Broadcom layout */
|
||||
@@ -130,8 +99,8 @@ static int bcm63xx_parse_cfe_partitions(
|
||||
} else {
|
||||
/* OpenWrt layout */
|
||||
rootfsaddr = kerneladdr + kernellen;
|
||||
- rootfslen = buf->real_rootfs_length;
|
||||
- spareaddr = rootfsaddr + rootfslen;
|
||||
+ rootfslen = size - kernellen -
|
||||
+ sizeof(*buf);
|
||||
}
|
||||
} else {
|
||||
pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n",
|
||||
@@ -139,16 +108,145 @@ static int bcm63xx_parse_cfe_partitions(
|
||||
kernellen = 0;
|
||||
rootfslen = 0;
|
||||
rootfsaddr = 0;
|
||||
- spareaddr = cfelen;
|
||||
}
|
||||
- sparelen = min_not_zero(nvramaddr, caldataaddr1) - spareaddr;
|
||||
|
||||
- /* Determine number of partitions */
|
||||
- if (rootfslen > 0)
|
||||
- nrparts++;
|
||||
+ if (kernellen > 0) {
|
||||
+ int kernelpart = curr_part;
|
||||
|
||||
- if (kernellen > 0)
|
||||
- nrparts++;
|
||||
+ if (rootfslen > 0 && rootfs_first)
|
||||
+ kernelpart++;
|
||||
+ pparts[kernelpart].name = "kernel";
|
||||
+ pparts[kernelpart].offset = kerneladdr;
|
||||
+ pparts[kernelpart].size = kernellen;
|
||||
+ curr_part++;
|
||||
+ }
|
||||
+
|
||||
+ if (rootfslen > 0) {
|
||||
+ int rootfspart = curr_part;
|
||||
+
|
||||
+ if (kernellen > 0 && rootfs_first)
|
||||
+ rootfspart--;
|
||||
+ pparts[rootfspart].name = "rootfs";
|
||||
+ pparts[rootfspart].offset = rootfsaddr;
|
||||
+ pparts[rootfspart].size = rootfslen;
|
||||
+
|
||||
+ curr_part++;
|
||||
+ }
|
||||
+
|
||||
+ vfree(buf);
|
||||
+
|
||||
+ return curr_part - next_part;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int bcm63xx_parse_cfe_partitions_of(struct mtd_info *master,
|
||||
+ struct mtd_partition **pparts,
|
||||
+ struct mtd_part_parser_data *data)
|
||||
+{
|
||||
+ struct device_node *dp = data->of_node;
|
||||
+ struct device_node *pp;
|
||||
+ int i, nr_parts = 0;
|
||||
+ const char *partname;
|
||||
+ int len;
|
||||
+
|
||||
+ for_each_child_of_node(dp, pp) {
|
||||
+ if (node_has_compatible(pp))
|
||||
+ continue;
|
||||
+
|
||||
+ nr_parts++;
|
||||
+ }
|
||||
+
|
||||
+ *pparts = kzalloc(nr_parts * sizeof(**pparts), GFP_KERNEL);
|
||||
+ if (!*pparts)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ i = 0;
|
||||
+ for_each_child_of_node(dp, pp) {
|
||||
+ const __be32 *reg;
|
||||
+ int a_cells, s_cells;
|
||||
+ size_t size, offset;
|
||||
+
|
||||
+ if (node_has_compatible(pp))
|
||||
+ continue;
|
||||
+
|
||||
+ reg = of_get_property(pp, "reg", &len);
|
||||
+ if (!reg) {
|
||||
+ nr_parts--;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ a_cells = of_n_addr_cells(pp);
|
||||
+ s_cells = of_n_size_cells(pp);
|
||||
+ offset = of_read_number(reg, a_cells);
|
||||
+ size = of_read_number(reg + a_cells, s_cells);
|
||||
+ partname = of_get_property(pp, "label", &len);
|
||||
+ if (!partname)
|
||||
+ partname = of_get_property(pp, "name", &len);
|
||||
+
|
||||
+ if (!strcmp(partname, "linux"))
|
||||
+ i += parse_bcmtag(master, *pparts, i, offset, size);
|
||||
+
|
||||
+ if (of_get_property(pp, "read-only", &len))
|
||||
+ (*pparts)[i].mask_flags |= MTD_WRITEABLE;
|
||||
+
|
||||
+ if (of_get_property(pp, "lock", &len))
|
||||
+ (*pparts)[i].mask_flags |= MTD_POWERUP_LOCK;
|
||||
+
|
||||
+ (*pparts)[i].offset = offset;
|
||||
+ (*pparts)[i].size = size;
|
||||
+ (*pparts)[i].name = partname;
|
||||
+
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ return i;
|
||||
+}
|
||||
+
|
||||
+static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
|
||||
+ struct mtd_partition **pparts,
|
||||
+ struct mtd_part_parser_data *data)
|
||||
+{
|
||||
+ /* CFE, NVRAM and global Linux are always present */
|
||||
+ int nrparts = 5, curpart = 0;
|
||||
+ struct mtd_partition *parts;
|
||||
+ unsigned int nvramaddr;
|
||||
+ unsigned int cfelen, nvramlen;
|
||||
+ unsigned int cfe_erasesize;
|
||||
+ unsigned int caldatalen1 = 0, caldataaddr1 = 0;
|
||||
+ unsigned int caldatalen2 = 0, caldataaddr2 = 0;
|
||||
+ unsigned int imageaddr, imagelen;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!bcm63xx_is_cfe_present())
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ cfe_erasesize = max_t(uint32_t, master->erasesize,
|
||||
+ BCM63XX_CFE_BLOCK_SIZE);
|
||||
+
|
||||
+ cfelen = cfe_erasesize;
|
||||
+ nvramlen = bcm63xx_nvram_get_psi_size() * SZ_1K;
|
||||
+ nvramlen = roundup(nvramlen, cfe_erasesize);
|
||||
+ nvramaddr = master->size - nvramlen;
|
||||
+
|
||||
+ if (data) {
|
||||
+ if (data->caldata[0]) {
|
||||
+ caldatalen1 = cfe_erasesize;
|
||||
+ caldataaddr1 = rounddown(data->caldata[0],
|
||||
+ cfe_erasesize);
|
||||
+ }
|
||||
+ if (data->caldata[1]) {
|
||||
+ caldatalen2 = cfe_erasesize;
|
||||
+ caldataaddr2 = rounddown(data->caldata[1],
|
||||
+ cfe_erasesize);
|
||||
+ }
|
||||
+ if (caldataaddr1 == caldataaddr2) {
|
||||
+ caldataaddr2 = 0;
|
||||
+ caldatalen2 = 0;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ imageaddr = cfelen;
|
||||
+ imagelen = min_not_zero(nvramaddr, caldataaddr1) - imageaddr;
|
||||
|
||||
if (caldatalen1 > 0)
|
||||
nrparts++;
|
||||
@@ -158,10 +256,8 @@ static int bcm63xx_parse_cfe_partitions(
|
||||
|
||||
/* Ask kernel for more memory */
|
||||
parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
|
||||
- if (!parts) {
|
||||
- vfree(buf);
|
||||
+ if (!parts)
|
||||
return -ENOMEM;
|
||||
- }
|
||||
|
||||
/* Start building partition list */
|
||||
parts[curpart].name = "CFE";
|
||||
@@ -169,29 +265,7 @@ static int bcm63xx_parse_cfe_partitions(
|
||||
parts[curpart].size = cfelen;
|
||||
curpart++;
|
||||
|
||||
- if (kernellen > 0) {
|
||||
- int kernelpart = curpart;
|
||||
-
|
||||
- if (rootfslen > 0 && rootfs_first)
|
||||
- kernelpart++;
|
||||
- parts[kernelpart].name = "kernel";
|
||||
- parts[kernelpart].offset = kerneladdr;
|
||||
- parts[kernelpart].size = kernellen;
|
||||
- curpart++;
|
||||
- }
|
||||
-
|
||||
- if (rootfslen > 0) {
|
||||
- int rootfspart = curpart;
|
||||
-
|
||||
- if (kernellen > 0 && rootfs_first)
|
||||
- rootfspart--;
|
||||
- parts[rootfspart].name = "rootfs";
|
||||
- parts[rootfspart].offset = rootfsaddr;
|
||||
- parts[rootfspart].size = rootfslen;
|
||||
- if (sparelen > 0 && !rootfs_first)
|
||||
- parts[rootfspart].size += sparelen;
|
||||
- curpart++;
|
||||
- }
|
||||
+ curpart += parse_bcmtag(master, parts, curpart, imageaddr, imagelen);
|
||||
|
||||
if (caldatalen1 > 0) {
|
||||
if (caldatalen2 > 0)
|
||||
@@ -217,25 +291,33 @@ static int bcm63xx_parse_cfe_partitions(
|
||||
|
||||
/* Global partition "linux" to make easy firmware upgrade */
|
||||
parts[curpart].name = "linux";
|
||||
- parts[curpart].offset = cfelen;
|
||||
- parts[curpart].size = min_not_zero(nvramaddr, caldataaddr1) - cfelen;
|
||||
+ parts[curpart].offset = imageaddr;
|
||||
+ parts[curpart].size = imagelen;
|
||||
+ curpart++;
|
||||
|
||||
- for (i = 0; i < nrparts; i++)
|
||||
+ for (i = 0; i < curpart; i++)
|
||||
pr_info("Partition %d is %s offset %llx and length %llx\n", i,
|
||||
parts[i].name, parts[i].offset, parts[i].size);
|
||||
|
||||
- pr_info("Spare partition is offset %x and length %x\n", spareaddr,
|
||||
- sparelen);
|
||||
-
|
||||
*pparts = parts;
|
||||
- vfree(buf);
|
||||
|
||||
return nrparts;
|
||||
};
|
||||
|
||||
+
|
||||
+static int bcm63xx_parse_partitions(struct mtd_info *master,
|
||||
+ struct mtd_partition **pparts,
|
||||
+ struct mtd_part_parser_data *data)
|
||||
+{
|
||||
+ if (data && data->of_node)
|
||||
+ return bcm63xx_parse_cfe_partitions_of(master, pparts, data);
|
||||
+ else
|
||||
+ return bcm63xx_parse_cfe_partitions(master, pparts, data);
|
||||
+}
|
||||
+
|
||||
static struct mtd_part_parser bcm63xx_cfe_parser = {
|
||||
.owner = THIS_MODULE,
|
||||
- .parse_fn = bcm63xx_parse_cfe_partitions,
|
||||
+ .parse_fn = bcm63xx_parse_partitions,
|
||||
.name = "bcm63xxpart",
|
||||
};
|
||||
|
|
@ -107,7 +107,7 @@
|
|||
#include <bcm63xx_cpu.h>
|
||||
#include <bcm63xx_dev_flash.h>
|
||||
#include <bcm63xx_dev_hsspi.h>
|
||||
@@ -215,6 +216,13 @@ int __init bcm63xx_flash_register(int nu
|
||||
@@ -220,6 +221,13 @@ int __init bcm63xx_flash_register(int nu
|
||||
val = bcm_mpi_readl(MPI_CSBASE_REG(0));
|
||||
val &= MPI_CSBASE_BASE_MASK;
|
||||
|
||||
|
|
|
@ -44,8 +44,8 @@ Subject: [PATCH 44/44] MIPS: BCM63XX: add inventel Livebox support
|
|||
static int (*board_get_mac_address)(u8 mac[ETH_ALEN]);
|
||||
--- a/arch/mips/bcm63xx/boards/board_common.h
|
||||
+++ b/arch/mips/bcm63xx/boards/board_common.h
|
||||
@@ -15,4 +15,10 @@ void board_bcm963xx_init(void);
|
||||
static inline void board_bcm963xx_init(void) { }
|
||||
@@ -24,4 +24,10 @@ static inline void board_of_device_prese
|
||||
}
|
||||
#endif
|
||||
|
||||
+#if defined(CONFIG_BOARD_LIVEBOX)
|
||||
|
|
|
@ -559,7 +559,7 @@
|
|||
|
||||
--- a/drivers/mtd/bcm63xxpart.c
|
||||
+++ b/drivers/mtd/bcm63xxpart.c
|
||||
@@ -70,6 +70,11 @@ static int bcm63xx_parse_cfe_partitions(
|
||||
@@ -224,6 +224,11 @@ static int bcm63xx_parse_cfe_partitions(
|
||||
BCM63XX_CFE_BLOCK_SIZE);
|
||||
|
||||
cfelen = cfe_erasesize;
|
||||
|
|
Loading…
Reference in a new issue