brcm63xx: add support for registering parallel flash through dtb
authorJonas Gorski <jogo@openwrt.org>
Mon, 11 Aug 2014 11:37:01 +0000 (11:37 +0000)
committerJonas Gorski <jogo@openwrt.org>
Mon, 11 Aug 2014 11:37:01 +0000 (11:37 +0000)
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

22 files changed:
target/linux/brcm63xx/dts/bcm6338.dtsi
target/linux/brcm63xx/dts/bcm6345.dtsi
target/linux/brcm63xx/dts/bcm6348.dtsi
target/linux/brcm63xx/dts/bcm6358.dtsi
target/linux/brcm63xx/dts/bcm6368.dtsi
target/linux/brcm63xx/patches-3.14/001-of-Create-unlocked-version-of-for_each_child_of_node.patch [new file with mode: 0644]
target/linux/brcm63xx/patches-3.14/002-lib-add-glibc-style-strchrnul-variant.patch [new file with mode: 0644]
target/linux/brcm63xx/patches-3.14/003-of-Make-of_find_node_by_path-handle-aliases.patch [new file with mode: 0644]
target/linux/brcm63xx/patches-3.14/371_add_of_node_available_by_alias.patch [new file with mode: 0644]
target/linux/brcm63xx/patches-3.14/372_dont_register_pflash_when_available_in_dtb.patch [new file with mode: 0644]
target/linux/brcm63xx/patches-3.14/400-bcm963xx_flashmap.patch
target/linux/brcm63xx/patches-3.14/411-MIPS-BCM63XX-Register-SPI-flash-if-present.patch
target/linux/brcm63xx/patches-3.14/413-BCM63XX-allow-providing-fixup-data-in-board-data.patch
target/linux/brcm63xx/patches-3.14/415-MIPS-BCM63XX-export-the-attached-flash-type.patch
target/linux/brcm63xx/patches-3.14/418-MIPS-BCM63XX-pass-caldata-info-to-flash.patch
target/linux/brcm63xx/patches-3.14/420-BCM63XX-add-endian-check-for-ath9k.patch
target/linux/brcm63xx/patches-3.14/421-BCM63XX-add-led-pin-for-ath9k.patch
target/linux/brcm63xx/patches-3.14/422-BCM63XX-add-a-fixup-for-rt2x00-devices.patch
target/linux/brcm63xx/patches-3.14/425-bcm63xxpart_parse_paritions_from_dt.patch [new file with mode: 0644]
target/linux/brcm63xx/patches-3.14/511-board_V2500V.patch
target/linux/brcm63xx/patches-3.14/513-MIPS-BCM63XX-add-inventel-Livebox-support.patch
target/linux/brcm63xx/patches-3.14/534-board_hw556.patch

index 0e0f2787928c1b7c20a549e78b3bbaa035846d23..b06d3988d79a65fcfdf14522949f86bc69ebb2ac 100644 (file)
@@ -3,6 +3,10 @@
        #size-cells = <1>;
        compatible = "brcm,bcm6338";
 
+       aliases {
+               pflash = &pflash;
+       };
+
        cpus {
                cpu@0 {
                        compatible = "brcm,bmips3300", "mips,mips4Kc";
 
        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>;
index e1daacc73a9c53f4c853aeaaa4ffe2a21873814a..78e06c2192d58fa4c321f35b2fe053b9099a1c8e 100644 (file)
@@ -3,6 +3,10 @@
        #size-cells = <1>;
        compatible = "brcm,bcm6345";
 
+       aliases {
+               pflash = &pflash;
+       };
+
        cpus {
                cpu@0 {
                        compatible = "brcm,bmips32", "mips,mips4Kc";
 
        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>;
index 1ab13b622d4e49daa85b35f72e9142cda0c0044b..a2beafdbf1941646919e5876bc267834843ea404 100644 (file)
@@ -3,6 +3,10 @@
        #size-cells = <1>;
        compatible = "brcm,bcm6348";
 
+       aliases {
+               pflash = &pflash;
+       };
+
        cpus {
                cpu@0 {
                        compatible = "brcm,bmips3300", "mips,mips4Kc";
 
        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>;
index 5db534ecfbc99d9890c6d03a3ec2f74f51c1fb9a..d5a84a4ca4fd47a35fedb2418e78463d5dbf95b5 100644 (file)
@@ -3,6 +3,10 @@
        #size-cells = <1>;
        compatible = "brcm,bcm6358";
 
+       aliases {
+               pflash = &pflash;
+       };
+
        cpus {
                cpu@0 {
                        compatible = "brcm,bmips4350", "mips,mips4Kc";
 
        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>;
index b923b07be8f40aa1a077bd976b16b70e6cf8ffd8..8dfb6e80caa69cd82b669a395a8294283466b37f 100644 (file)
@@ -3,6 +3,10 @@
        #size-cells = <1>;
        compatible = "brcm,bcm6368";
 
+       aliases {
+               pflash = &pflash;
+       };
+
        cpus {
                cpu@0 {
                        compatible = "brcm,bmips4350", "mips,mips4Kc";
                #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";
+       };
 };
diff --git a/target/linux/brcm63xx/patches-3.14/001-of-Create-unlocked-version-of-for_each_child_of_node.patch b/target/linux/brcm63xx/patches-3.14/001-of-Create-unlocked-version-of-for_each_child_of_node.patch
new file mode 100644 (file)
index 0000000..1395789
--- /dev/null
@@ -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;
+ }
diff --git a/target/linux/brcm63xx/patches-3.14/002-lib-add-glibc-style-strchrnul-variant.patch b/target/linux/brcm63xx/patches-3.14/002-lib-add-glibc-style-strchrnul-variant.patch
new file mode 100644 (file)
index 0000000..33d7c9f
--- /dev/null
@@ -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
diff --git a/target/linux/brcm63xx/patches-3.14/003-of-Make-of_find_node_by_path-handle-aliases.patch b/target/linux/brcm63xx/patches-3.14/003-of-Make-of_find_node_by_path-handle-aliases.patch
new file mode 100644 (file)
index 0000000..9ad0780
--- /dev/null
@@ -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;
diff --git a/target/linux/brcm63xx/patches-3.14/371_add_of_node_available_by_alias.patch b/target/linux/brcm63xx/patches-3.14/371_add_of_node_available_by_alias.patch
new file mode 100644 (file)
index 0000000..99d778d
--- /dev/null
@@ -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 */
diff --git a/target/linux/brcm63xx/patches-3.14/372_dont_register_pflash_when_available_in_dtb.patch b/target/linux/brcm63xx/patches-3.14/372_dont_register_pflash_when_available_in_dtb.patch
new file mode 100644 (file)
index 0000000..88efc23
--- /dev/null
@@ -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) */
index 0bbb4e5289c64cf164340b3491d2487f8190dc4a..03534c0aab073026de60615c25ae2fe40e956ba9 100644 (file)
@@ -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
        }
  };
  
index bc10d96635b85819db64a82c857754b07ced1b3d..5fe20784662b1859764188eeceefb2153d1b5f01 100644 (file)
@@ -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:
index 3ef4585590f6df459dbda1f88f591285210e04c1..320c2977467db511666a59f64c379e3177e2a42f 100644 (file)
@@ -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);
        }
  
index 742c735cbe619ed980c757a9625d25dfdc3e5057..55639cafab756ca4a1bff54d9ed9186d568cd242 100644 (file)
@@ -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;
        }
  }
index 38f934d8c9995f52451c0d16a64e6d5b29bc6679..fdcfa19e5e83d4b87532abee20180e2308138777 100644 (file)
@@ -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)
        }
  }
  
index 7d0c475101c6bb8f7c64aabb5d9167ec30a379c7..0e01be15b3bc9039ec5734ebfc9907d676612d5f 100644 (file)
@@ -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++)
index 1a0fe4a377630b4e72707a6f54ffe36267b437f4..27ea83f3cccd5681b4d0b92144a908514df04cd9 100644 (file)
@@ -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,
index 9dc520a230a0abe8d8e54fefb00ab97c8b6b6cbe..49eb89798adc3be5be268f9586769f7a6c859474 100644 (file)
@@ -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)
        }
  }
  
diff --git a/target/linux/brcm63xx/patches-3.14/425-bcm63xxpart_parse_paritions_from_dt.patch b/target/linux/brcm63xx/patches-3.14/425-bcm63xxpart_parse_paritions_from_dt.patch
new file mode 100644 (file)
index 0000000..dd0ba70
--- /dev/null
@@ -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",
+ };
index 7990a54f1ee7d2421ee96cc5052a05b01c436d24..4a7ffa6de38ba7699d1b401a633c3929bf5bf7a3 100644 (file)
  #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;
  
index 464ffdff2dbedea95aec783cfaff2be542bed081..2f7bf49ca86e70a568af51acba308726346aad6b 100644 (file)
@@ -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)
index 32b2ad6ad16dd2251004480eab0ecc89b38fc4f7..8b6dc1157ae72c8d0569209f527135a08cd09b26 100644 (file)
  
 --- 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;