aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Arlott <simon@fire.lp0.eu>2015-12-13 17:49:26 -0500
committerBrian Norris <computersforpeace@gmail.com>2016-02-12 13:27:48 -0500
commit436e94a6fbcdca133a2546769db4ac0a84265ad1 (patch)
tree56868d9891e22c144572edff76b6c70d18fd39e5
parent94248462f066ec19b9c184ff66300e6e71977609 (diff)
mtd: bcm63xxpart: Remove dependency on mach-bcm63xx
Read nvram directly from flash instead of using the in-memory copy that mach-bcm63xx has, to remove the dependency on mach-bcm63xx and allow the parser to work on bmips too. Rename remaining BCM63XX defines to BCM963XX as these are properties of the flash layout on the board. BCM963XX_DEFAULT_PSI_SIZE changes from SZ_64K to 64 because it will be multiplied by SZ_1K later on. Signed-off-by: Simon Arlott <simon@fire.lp0.eu> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
-rw-r--r--drivers/mtd/Kconfig2
-rw-r--r--drivers/mtd/bcm63xxpart.c72
2 files changed, 58 insertions, 16 deletions
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 42cc953309f1..e83a279f1217 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -142,7 +142,7 @@ config MTD_AR7_PARTS
142 142
143config MTD_BCM63XX_PARTS 143config MTD_BCM63XX_PARTS
144 tristate "BCM63XX CFE partitioning support" 144 tristate "BCM63XX CFE partitioning support"
145 depends on BCM63XX 145 depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST
146 select CRC32 146 select CRC32
147 help 147 help
148 This provides partions parsing for BCM63xx devices with CFE 148 This provides partions parsing for BCM63xx devices with CFE
diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c
index cec3188a170d..1eea8b6bc66a 100644
--- a/drivers/mtd/bcm63xxpart.c
+++ b/drivers/mtd/bcm63xxpart.c
@@ -24,6 +24,7 @@
24 24
25#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 25#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
26 26
27#include <linux/bcm963xx_nvram.h>
27#include <linux/bcm963xx_tag.h> 28#include <linux/bcm963xx_tag.h>
28#include <linux/crc32.h> 29#include <linux/crc32.h>
29#include <linux/module.h> 30#include <linux/module.h>
@@ -34,12 +35,11 @@
34#include <linux/mtd/mtd.h> 35#include <linux/mtd/mtd.h>
35#include <linux/mtd/partitions.h> 36#include <linux/mtd/partitions.h>
36 37
37#include <asm/mach-bcm63xx/bcm63xx_nvram.h> 38#define BCM963XX_CFE_BLOCK_SIZE SZ_64K /* always at least 64KiB */
38#include <asm/mach-bcm63xx/board_bcm963xx.h>
39 39
40#define BCM63XX_CFE_BLOCK_SIZE SZ_64K /* always at least 64KiB */ 40#define BCM963XX_CFE_MAGIC_OFFSET 0x4e0
41 41#define BCM963XX_CFE_VERSION_OFFSET 0x570
42#define BCM63XX_CFE_MAGIC_OFFSET 0x4e0 42#define BCM963XX_NVRAM_OFFSET 0x580
43 43
44static int bcm63xx_detect_cfe(struct mtd_info *master) 44static int bcm63xx_detect_cfe(struct mtd_info *master)
45{ 45{
@@ -58,20 +58,45 @@ static int bcm63xx_detect_cfe(struct mtd_info *master)
58 return 0; 58 return 0;
59 59
60 /* very old CFE's do not have the cfe-v string, so check for magic */ 60 /* very old CFE's do not have the cfe-v string, so check for magic */
61 ret = mtd_read(master, BCM63XX_CFE_MAGIC_OFFSET, 8, &retlen, 61 ret = mtd_read(master, BCM963XX_CFE_MAGIC_OFFSET, 8, &retlen,
62 (void *)buf); 62 (void *)buf);
63 buf[retlen] = 0; 63 buf[retlen] = 0;
64 64
65 return strncmp("CFE1CFE1", buf, 8); 65 return strncmp("CFE1CFE1", buf, 8);
66} 66}
67 67
68static int bcm63xx_read_nvram(struct mtd_info *master,
69 struct bcm963xx_nvram *nvram)
70{
71 u32 actual_crc, expected_crc;
72 size_t retlen;
73 int ret;
74
75 /* extract nvram data */
76 ret = mtd_read(master, BCM963XX_NVRAM_OFFSET, BCM963XX_NVRAM_V5_SIZE,
77 &retlen, (void *)nvram);
78 if (ret)
79 return ret;
80
81 ret = bcm963xx_nvram_checksum(nvram, &expected_crc, &actual_crc);
82 if (ret)
83 pr_warn("nvram checksum failed, contents may be invalid (expected %08x, got %08x)\n",
84 expected_crc, actual_crc);
85
86 if (!nvram->psi_size)
87 nvram->psi_size = BCM963XX_DEFAULT_PSI_SIZE;
88
89 return 0;
90}
91
68static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, 92static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
69 const struct mtd_partition **pparts, 93 const struct mtd_partition **pparts,
70 struct mtd_part_parser_data *data) 94 struct mtd_part_parser_data *data)
71{ 95{
72 /* CFE, NVRAM and global Linux are always present */ 96 /* CFE, NVRAM and global Linux are always present */
73 int nrparts = 3, curpart = 0; 97 int nrparts = 3, curpart = 0;
74 struct bcm_tag *buf; 98 struct bcm963xx_nvram *nvram = NULL;
99 struct bcm_tag *buf = NULL;
75 struct mtd_partition *parts; 100 struct mtd_partition *parts;
76 int ret; 101 int ret;
77 size_t retlen; 102 size_t retlen;
@@ -86,25 +111,35 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
86 if (bcm63xx_detect_cfe(master)) 111 if (bcm63xx_detect_cfe(master))
87 return -EINVAL; 112 return -EINVAL;
88 113
114 nvram = vzalloc(sizeof(*nvram));
115 if (!nvram)
116 return -ENOMEM;
117
118 ret = bcm63xx_read_nvram(master, nvram);
119 if (ret)
120 goto out;
121
89 cfe_erasesize = max_t(uint32_t, master->erasesize, 122 cfe_erasesize = max_t(uint32_t, master->erasesize,
90 BCM63XX_CFE_BLOCK_SIZE); 123 BCM963XX_CFE_BLOCK_SIZE);
91 124
92 cfelen = cfe_erasesize; 125 cfelen = cfe_erasesize;
93 nvramlen = bcm63xx_nvram_get_psi_size() * SZ_1K; 126 nvramlen = nvram->psi_size * SZ_1K;
94 nvramlen = roundup(nvramlen, cfe_erasesize); 127 nvramlen = roundup(nvramlen, cfe_erasesize);
95 128
96 /* Allocate memory for buffer */ 129 /* Allocate memory for buffer */
97 buf = vmalloc(sizeof(struct bcm_tag)); 130 buf = vmalloc(sizeof(struct bcm_tag));
98 if (!buf) 131 if (!buf) {
99 return -ENOMEM; 132 ret = -ENOMEM;
133 goto out;
134 }
100 135
101 /* Get the tag */ 136 /* Get the tag */
102 ret = mtd_read(master, cfelen, sizeof(struct bcm_tag), &retlen, 137 ret = mtd_read(master, cfelen, sizeof(struct bcm_tag), &retlen,
103 (void *)buf); 138 (void *)buf);
104 139
105 if (retlen != sizeof(struct bcm_tag)) { 140 if (retlen != sizeof(struct bcm_tag)) {
106 vfree(buf); 141 ret = -EIO;
107 return -EIO; 142 goto out;
108 } 143 }
109 144
110 computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf, 145 computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf,
@@ -154,8 +189,8 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
154 /* Ask kernel for more memory */ 189 /* Ask kernel for more memory */
155 parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); 190 parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
156 if (!parts) { 191 if (!parts) {
157 vfree(buf); 192 ret = -ENOMEM;
158 return -ENOMEM; 193 goto out;
159 } 194 }
160 195
161 /* Start building partition list */ 196 /* Start building partition list */
@@ -206,8 +241,15 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master,
206 sparelen); 241 sparelen);
207 242
208 *pparts = parts; 243 *pparts = parts;
244 ret = 0;
245
246out:
247 vfree(nvram);
209 vfree(buf); 248 vfree(buf);
210 249
250 if (ret)
251 return ret;
252
211 return nrparts; 253 return nrparts;
212}; 254};
213 255