From 8ab86c5dc38ad4de1442e50e0adbc354d9184d71 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Tue, 1 May 2012 14:38:41 +0200 Subject: [PATCH 68/79] MTD: bcm63xxpart: allow passing a caldata offset Allow bcm63xxpart to receive a caldata offset if calibration data is contained in flash. --- drivers/mtd/bcm63xxpart.c | 47 ++++++++++++++++++++++++++++++++++++++-- include/linux/mtd/partitions.h | 2 ++ 2 files changed, 47 insertions(+), 2 deletions(-) --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c @@ -80,6 +80,8 @@ static int bcm63xx_parse_cfe_partitions( 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; @@ -94,6 +96,23 @@ static int bcm63xx_parse_cfe_partitions( nvramlen = bcm63xx_nvram_get_psi_size() * 1024; nvramlen = roundup(nvramlen, cfe_erasesize); + 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)); if (!buf) @@ -144,7 +163,7 @@ static int bcm63xx_parse_cfe_partitions( rootfsaddr = 0; spareaddr = cfelen; } - sparelen = master->size - spareaddr - nvramlen; + sparelen = master->size - spareaddr - nvramlen - caldatalen1 - caldatalen2; /* Determine number of partitions */ if (rootfslen > 0) @@ -153,6 +172,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) { @@ -190,6 +215,23 @@ 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].size = nvramlen; @@ -198,7 +240,8 @@ 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 = master->size - cfelen - nvramlen; + parts[curpart].size = master->size - cfelen - nvramlen + - caldatalen1 - caldatalen2; 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 @@ -58,10 +58,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; };