Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Simon Arlott and committed by
Brian Norris
436e94a6 94248462

+58 -16
+1 -1
drivers/mtd/Kconfig
··· 142 142 143 143 config MTD_BCM63XX_PARTS 144 144 tristate "BCM63XX CFE partitioning support" 145 - depends on BCM63XX 145 + depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST 146 146 select CRC32 147 147 help 148 148 This provides partions parsing for BCM63xx devices with CFE
+57 -15
drivers/mtd/bcm63xxpart.c
··· 24 24 25 25 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 26 26 27 + #include <linux/bcm963xx_nvram.h> 27 28 #include <linux/bcm963xx_tag.h> 28 29 #include <linux/crc32.h> 29 30 #include <linux/module.h> ··· 35 34 #include <linux/mtd/mtd.h> 36 35 #include <linux/mtd/partitions.h> 37 36 38 - #include <asm/mach-bcm63xx/bcm63xx_nvram.h> 39 - #include <asm/mach-bcm63xx/board_bcm963xx.h> 37 + #define BCM963XX_CFE_BLOCK_SIZE SZ_64K /* always at least 64KiB */ 40 38 41 - #define BCM63XX_CFE_BLOCK_SIZE SZ_64K /* always at least 64KiB */ 42 - 43 - #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0 39 + #define BCM963XX_CFE_MAGIC_OFFSET 0x4e0 40 + #define BCM963XX_CFE_VERSION_OFFSET 0x570 41 + #define BCM963XX_NVRAM_OFFSET 0x580 44 42 45 43 static int bcm63xx_detect_cfe(struct mtd_info *master) 46 44 { ··· 58 58 return 0; 59 59 60 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 62 (void *)buf); 63 63 buf[retlen] = 0; 64 64 65 65 return strncmp("CFE1CFE1", buf, 8); 66 + } 67 + 68 + static 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; 66 90 } 67 91 68 92 static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, ··· 95 71 { 96 72 /* CFE, NVRAM and global Linux are always present */ 97 73 int nrparts = 3, curpart = 0; 98 - struct bcm_tag *buf; 74 + struct bcm963xx_nvram *nvram = NULL; 75 + struct bcm_tag *buf = NULL; 99 76 struct mtd_partition *parts; 100 77 int ret; 101 78 size_t retlen; ··· 111 86 if (bcm63xx_detect_cfe(master)) 112 87 return -EINVAL; 113 88 89 + nvram = vzalloc(sizeof(*nvram)); 90 + if (!nvram) 91 + return -ENOMEM; 92 + 93 + ret = bcm63xx_read_nvram(master, nvram); 94 + if (ret) 95 + goto out; 96 + 114 97 cfe_erasesize = max_t(uint32_t, master->erasesize, 115 - BCM63XX_CFE_BLOCK_SIZE); 98 + BCM963XX_CFE_BLOCK_SIZE); 116 99 117 100 cfelen = cfe_erasesize; 118 - nvramlen = bcm63xx_nvram_get_psi_size() * SZ_1K; 101 + nvramlen = nvram->psi_size * SZ_1K; 119 102 nvramlen = roundup(nvramlen, cfe_erasesize); 120 103 121 104 /* Allocate memory for buffer */ 122 105 buf = vmalloc(sizeof(struct bcm_tag)); 123 - if (!buf) 124 - return -ENOMEM; 106 + if (!buf) { 107 + ret = -ENOMEM; 108 + goto out; 109 + } 125 110 126 111 /* Get the tag */ 127 112 ret = mtd_read(master, cfelen, sizeof(struct bcm_tag), &retlen, 128 113 (void *)buf); 129 114 130 115 if (retlen != sizeof(struct bcm_tag)) { 131 - vfree(buf); 132 - return -EIO; 116 + ret = -EIO; 117 + goto out; 133 118 } 134 119 135 120 computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf, ··· 189 154 /* Ask kernel for more memory */ 190 155 parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); 191 156 if (!parts) { 192 - vfree(buf); 193 - return -ENOMEM; 157 + ret = -ENOMEM; 158 + goto out; 194 159 } 195 160 196 161 /* Start building partition list */ ··· 241 206 sparelen); 242 207 243 208 *pparts = parts; 209 + ret = 0; 210 + 211 + out: 212 + vfree(nvram); 244 213 vfree(buf); 214 + 215 + if (ret) 216 + return ret; 245 217 246 218 return nrparts; 247 219 };