From: Jonas Gorski Date: Mon, 11 Aug 2014 11:37:01 +0000 (+0000) Subject: brcm63xx: add support for registering parallel flash through dtb X-Git-Tag: reboot~6236 X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=9c6287d6a14b7f7105e4b61774c5310cb96489c3;p=openwrt%2Fstaging%2Fblogic.git 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 SVN-Revision: 42123 --- diff --git a/target/linux/brcm63xx/dts/bcm6338.dtsi b/target/linux/brcm63xx/dts/bcm6338.dtsi index 0e0f2787928c..b06d3988d79a 100644 --- a/target/linux/brcm63xx/dts/bcm6338.dtsi +++ b/target/linux/brcm63xx/dts/bcm6338.dtsi @@ -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>; diff --git a/target/linux/brcm63xx/dts/bcm6345.dtsi b/target/linux/brcm63xx/dts/bcm6345.dtsi index e1daacc73a9c..78e06c2192d5 100644 --- a/target/linux/brcm63xx/dts/bcm6345.dtsi +++ b/target/linux/brcm63xx/dts/bcm6345.dtsi @@ -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>; diff --git a/target/linux/brcm63xx/dts/bcm6348.dtsi b/target/linux/brcm63xx/dts/bcm6348.dtsi index 1ab13b622d4e..a2beafdbf194 100644 --- a/target/linux/brcm63xx/dts/bcm6348.dtsi +++ b/target/linux/brcm63xx/dts/bcm6348.dtsi @@ -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>; diff --git a/target/linux/brcm63xx/dts/bcm6358.dtsi b/target/linux/brcm63xx/dts/bcm6358.dtsi index 5db534ecfbc9..d5a84a4ca4fd 100644 --- a/target/linux/brcm63xx/dts/bcm6358.dtsi +++ b/target/linux/brcm63xx/dts/bcm6358.dtsi @@ -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>; diff --git a/target/linux/brcm63xx/dts/bcm6368.dtsi b/target/linux/brcm63xx/dts/bcm6368.dtsi index b923b07be8f4..8dfb6e80caa6 100644 --- a/target/linux/brcm63xx/dts/bcm6368.dtsi +++ b/target/linux/brcm63xx/dts/bcm6368.dtsi @@ -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"; + }; }; 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 index 000000000000..13957890b9c6 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.14/001-of-Create-unlocked-version-of-for_each_child_of_node.patch @@ -0,0 +1,52 @@ +From 0d0e02d605c5696a5076510f564fefe659127aa4 Mon Sep 17 00:00:00 2001 +From: Grant Likely +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 +--- + 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 index 000000000000..33d7c9f3e549 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.14/002-lib-add-glibc-style-strchrnul-variant.patch @@ -0,0 +1,56 @@ +From 11d200e95f3e84c1102e4cc9863a3614fd41f3ad Mon Sep 17 00:00:00 2001 +From: Grant Likely +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 +--- + 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 index 000000000000..9ad07806cb08 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.14/003-of-Make-of_find_node_by_path-handle-aliases.patch @@ -0,0 +1,106 @@ +From c22e650e66b862babe9c00bebb20b8029c7b0362 Mon Sep 17 00:00:00 2001 +From: Grant Likely +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 +Signed-off-by: Pantelis Antoniou +[grant.likely: Rework to not require allocating at runtime] +Acked-by: Rob Herring +Signed-off-by: Grant Likely +--- + 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 index 000000000000..99d778deb770 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.14/371_add_of_node_available_by_alias.patch @@ -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 index 000000000000..88efc2360bc5 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.14/372_dont_register_pflash_when_available_in_dtb.patch @@ -0,0 +1,21 @@ +--- a/arch/mips/bcm63xx/dev-flash.c ++++ b/arch/mips/bcm63xx/dev-flash.c +@@ -22,6 +22,8 @@ + #include + #include + ++#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) */ diff --git a/target/linux/brcm63xx/patches-3.14/400-bcm963xx_flashmap.patch b/target/linux/brcm63xx/patches-3.14/400-bcm963xx_flashmap.patch index 0bbb4e5289c6..03534c0aab07 100644 --- a/target/linux/brcm63xx/patches-3.14/400-bcm963xx_flashmap.patch +++ b/target/linux/brcm63xx/patches-3.14/400-bcm963xx_flashmap.patch @@ -12,7 +12,7 @@ Signed-off-by: Axel Gembe --- 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 } }; diff --git a/target/linux/brcm63xx/patches-3.14/411-MIPS-BCM63XX-Register-SPI-flash-if-present.patch b/target/linux/brcm63xx/patches-3.14/411-MIPS-BCM63XX-Register-SPI-flash-if-present.patch index bc10d96635b8..5fe20784662b 100644 --- a/target/linux/brcm63xx/patches-3.14/411-MIPS-BCM63XX-Register-SPI-flash-if-present.patch +++ b/target/linux/brcm63xx/patches-3.14/411-MIPS-BCM63XX-Register-SPI-flash-if-present.patch @@ -24,7 +24,7 @@ Signed-off-by: Jonas Gorski #include #include -@@ -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 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 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 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 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: diff --git a/target/linux/brcm63xx/patches-3.14/413-BCM63XX-allow-providing-fixup-data-in-board-data.patch b/target/linux/brcm63xx/patches-3.14/413-BCM63XX-allow-providing-fixup-data-in-board-data.patch index 3ef4585590f6..320c2977467d 100644 --- a/target/linux/brcm63xx/patches-3.14/413-BCM63XX-allow-providing-fixup-data-in-board-data.patch +++ b/target/linux/brcm63xx/patches-3.14/413-BCM63XX-allow-providing-fixup-data-in-board-data.patch @@ -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); } diff --git a/target/linux/brcm63xx/patches-3.14/415-MIPS-BCM63XX-export-the-attached-flash-type.patch b/target/linux/brcm63xx/patches-3.14/415-MIPS-BCM63XX-export-the-attached-flash-type.patch index 742c735cbe61..55639cafab75 100644 --- a/target/linux/brcm63xx/patches-3.14/415-MIPS-BCM63XX-export-the-attached-flash-type.patch +++ b/target/linux/brcm63xx/patches-3.14/415-MIPS-BCM63XX-export-the-attached-flash-type.patch @@ -11,7 +11,7 @@ Signed-off-by: Jonas Gorski --- 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; } } diff --git a/target/linux/brcm63xx/patches-3.14/418-MIPS-BCM63XX-pass-caldata-info-to-flash.patch b/target/linux/brcm63xx/patches-3.14/418-MIPS-BCM63XX-pass-caldata-info-to-flash.patch index 38f934d8c999..fdcfa19e5e83 100644 --- a/target/linux/brcm63xx/patches-3.14/418-MIPS-BCM63XX-pass-caldata-info-to-flash.patch +++ b/target/linux/brcm63xx/patches-3.14/418-MIPS-BCM63XX-pass-caldata-info-to-flash.patch @@ -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) } } diff --git a/target/linux/brcm63xx/patches-3.14/420-BCM63XX-add-endian-check-for-ath9k.patch b/target/linux/brcm63xx/patches-3.14/420-BCM63XX-add-endian-check-for-ath9k.patch index 7d0c475101c6..0e01be15b3bc 100644 --- a/target/linux/brcm63xx/patches-3.14/420-BCM63XX-add-endian-check-for-ath9k.patch +++ b/target/linux/brcm63xx/patches-3.14/420-BCM63XX-add-endian-check-for-ath9k.patch @@ -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++) diff --git a/target/linux/brcm63xx/patches-3.14/421-BCM63XX-add-led-pin-for-ath9k.patch b/target/linux/brcm63xx/patches-3.14/421-BCM63XX-add-led-pin-for-ath9k.patch index 1a0fe4a37763..27ea83f3cccd 100644 --- a/target/linux/brcm63xx/patches-3.14/421-BCM63XX-add-led-pin-for-ath9k.patch +++ b/target/linux/brcm63xx/patches-3.14/421-BCM63XX-add-led-pin-for-ath9k.patch @@ -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, diff --git a/target/linux/brcm63xx/patches-3.14/422-BCM63XX-add-a-fixup-for-rt2x00-devices.patch b/target/linux/brcm63xx/patches-3.14/422-BCM63XX-add-a-fixup-for-rt2x00-devices.patch index 9dc520a230a0..49eb89798adc 100644 --- a/target/linux/brcm63xx/patches-3.14/422-BCM63XX-add-a-fixup-for-rt2x00-devices.patch +++ b/target/linux/brcm63xx/patches-3.14/422-BCM63XX-add-a-fixup-for-rt2x00-devices.patch @@ -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 index 000000000000..dd0ba7054d90 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.14/425-bcm63xxpart_parse_paritions_from_dt.patch @@ -0,0 +1,349 @@ +--- a/drivers/mtd/bcm63xxpart.c ++++ b/drivers/mtd/bcm63xxpart.c +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -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", + }; + diff --git a/target/linux/brcm63xx/patches-3.14/511-board_V2500V.patch b/target/linux/brcm63xx/patches-3.14/511-board_V2500V.patch index 7990a54f1ee7..4a7ffa6de38b 100644 --- a/target/linux/brcm63xx/patches-3.14/511-board_V2500V.patch +++ b/target/linux/brcm63xx/patches-3.14/511-board_V2500V.patch @@ -107,7 +107,7 @@ #include #include #include -@@ -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; diff --git a/target/linux/brcm63xx/patches-3.14/513-MIPS-BCM63XX-add-inventel-Livebox-support.patch b/target/linux/brcm63xx/patches-3.14/513-MIPS-BCM63XX-add-inventel-Livebox-support.patch index 464ffdff2dbe..2f7bf49ca86e 100644 --- a/target/linux/brcm63xx/patches-3.14/513-MIPS-BCM63XX-add-inventel-Livebox-support.patch +++ b/target/linux/brcm63xx/patches-3.14/513-MIPS-BCM63XX-add-inventel-Livebox-support.patch @@ -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) diff --git a/target/linux/brcm63xx/patches-3.14/534-board_hw556.patch b/target/linux/brcm63xx/patches-3.14/534-board_hw556.patch index 32b2ad6ad16d..8b6dc1157ae7 100644 --- a/target/linux/brcm63xx/patches-3.14/534-board_hw556.patch +++ b/target/linux/brcm63xx/patches-3.14/534-board_hw556.patch @@ -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;