123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- Allow bcm63xxpart to receive a caldata offset if calibration data is
- contained in flash.
- ---
- drivers/mtd/bcm63xxpart.c | 51 ++++++++++++++++++++++++++++++++++++---
- include/linux/mtd/partitions.h | 2 +
- 2 files changed, 49 insertions(+), 4 deletions(-)
- --- a/drivers/mtd/bcm63xxpart.c
- +++ b/drivers/mtd/bcm63xxpart.c
- @@ -53,10 +53,12 @@ static int bcm63xx_parse_cfe_partitions(
- struct mtd_partition *parts;
- int ret;
- size_t retlen;
- - unsigned int rootfsaddr, kerneladdr, spareaddr;
- + 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;
- bool rootfs_first = false;
- @@ -70,6 +72,24 @@ static int bcm63xx_parse_cfe_partitions(
- 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;
- + }
- + }
-
- /* Allocate memory for buffer */
- buf = vmalloc(sizeof(struct bcm_tag));
- @@ -121,7 +141,7 @@ static int bcm63xx_parse_cfe_partitions(
- rootfsaddr = 0;
- spareaddr = cfelen;
- }
- - sparelen = master->size - spareaddr - nvramlen;
- + sparelen = min_not_zero(nvramaddr, caldataaddr1) - spareaddr;
-
- /* Determine number of partitions */
- if (rootfslen > 0)
- @@ -130,6 +150,12 @@ static int bcm63xx_parse_cfe_partitions(
- if (kernellen > 0)
- nrparts++;
-
- + if (caldatalen1 > 0)
- + nrparts++;
- +
- + if (caldatalen2 > 0)
- + nrparts++;
- +
- /* Ask kernel for more memory */
- parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
- if (!parts) {
- @@ -167,15 +193,32 @@ static int bcm63xx_parse_cfe_partitions(
- curpart++;
- }
-
- + if (caldatalen1 > 0) {
- + if (caldatalen2 > 0)
- + parts[curpart].name = "cal_data1";
- + else
- + parts[curpart].name = "cal_data";
- + parts[curpart].offset = caldataaddr1;
- + parts[curpart].size = caldatalen1;
- + curpart++;
- + }
- +
- + if (caldatalen2 > 0) {
- + parts[curpart].name = "cal_data2";
- + parts[curpart].offset = caldataaddr2;
- + parts[curpart].size = caldatalen2;
- + curpart++;
- + }
- +
- parts[curpart].name = "nvram";
- - parts[curpart].offset = master->size - nvramlen;
- + parts[curpart].offset = nvramaddr;
- parts[curpart].size = nvramlen;
- curpart++;
-
- /* Global partition "linux" to make easy firmware upgrade */
- parts[curpart].name = "linux";
- parts[curpart].offset = cfelen;
- - parts[curpart].size = master->size - cfelen - nvramlen;
- + parts[curpart].size = min_not_zero(nvramaddr, caldataaddr1) - cfelen;
-
- for (i = 0; i < nrparts; i++)
- pr_info("Partition %d is %s offset %llx and length %llx\n", i,
- --- a/include/linux/mtd/partitions.h
- +++ b/include/linux/mtd/partitions.h
- @@ -56,10 +56,12 @@ struct device_node;
- /**
- * struct mtd_part_parser_data - used to pass data to MTD partition parsers.
- * @origin: for RedBoot, start address of MTD device
- + * @caldata: for CFE, start address of wifi calibration data
- * @of_node: for OF parsers, device node containing partitioning information
- */
- struct mtd_part_parser_data {
- unsigned long origin;
- + unsigned long caldata[2];
- struct device_node *of_node;
- };
-
|