1 From: Jonas Gorski <jogo@openwrt.org>
2 Subject: [PATCH] Allow bcm63xxpart to receive a caldata offset if calibration data is
5 drivers/mtd/bcm63xxpart.c | 51 ++++++++++++++++++++++++++++++++++++---
6 include/linux/mtd/partitions.h | 2 +
7 2 files changed, 49 insertions(+), 4 deletions(-)
9 --- a/drivers/mtd/bcm63xxpart.c
10 +++ b/drivers/mtd/bcm63xxpart.c
11 @@ -76,10 +76,12 @@ static int bcm63xx_parse_cfe_partitions(
12 struct mtd_partition *parts;
15 - unsigned int rootfsaddr, kerneladdr, spareaddr;
16 + unsigned int rootfsaddr, kerneladdr, spareaddr, nvramaddr;
17 unsigned int rootfslen, kernellen, sparelen, totallen;
18 unsigned int cfelen, nvramlen;
19 unsigned int cfe_erasesize;
20 + unsigned int caldatalen1 = 0, caldataaddr1 = 0;
21 + unsigned int caldatalen2 = 0, caldataaddr2 = 0;
24 bool rootfs_first = false;
25 @@ -93,6 +95,24 @@ static int bcm63xx_parse_cfe_partitions(
26 cfelen = cfe_erasesize;
27 nvramlen = bcm63xx_nvram_get_psi_size() * 1024;
28 nvramlen = roundup(nvramlen, cfe_erasesize);
29 + nvramaddr = master->size - nvramlen;
32 + if (data->caldata[0]) {
33 + caldatalen1 = cfe_erasesize;
34 + caldataaddr1 = rounddown(data->caldata[0],
37 + if (data->caldata[1]) {
38 + caldatalen2 = cfe_erasesize;
39 + caldataaddr2 = rounddown(data->caldata[1],
42 + if (caldataaddr1 == caldataaddr2) {
48 /* Allocate memory for buffer */
49 buf = vmalloc(sizeof(struct bcm_tag));
50 @@ -144,7 +164,7 @@ static int bcm63xx_parse_cfe_partitions(
54 - sparelen = master->size - spareaddr - nvramlen;
55 + sparelen = min_not_zero(nvramaddr, caldataaddr1) - spareaddr;
57 /* Determine number of partitions */
59 @@ -153,6 +173,12 @@ static int bcm63xx_parse_cfe_partitions(
63 + if (caldatalen1 > 0)
66 + if (caldatalen2 > 0)
69 /* Ask kernel for more memory */
70 parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
72 @@ -190,15 +216,32 @@ static int bcm63xx_parse_cfe_partitions(
76 + if (caldatalen1 > 0) {
77 + if (caldatalen2 > 0)
78 + parts[curpart].name = "cal_data1";
80 + parts[curpart].name = "cal_data";
81 + parts[curpart].offset = caldataaddr1;
82 + parts[curpart].size = caldatalen1;
86 + if (caldatalen2 > 0) {
87 + parts[curpart].name = "cal_data2";
88 + parts[curpart].offset = caldataaddr2;
89 + parts[curpart].size = caldatalen2;
93 parts[curpart].name = "nvram";
94 - parts[curpart].offset = master->size - nvramlen;
95 + parts[curpart].offset = nvramaddr;
96 parts[curpart].size = nvramlen;
99 /* Global partition "linux" to make easy firmware upgrade */
100 parts[curpart].name = "linux";
101 parts[curpart].offset = cfelen;
102 - parts[curpart].size = master->size - cfelen - nvramlen;
103 + parts[curpart].size = min_not_zero(nvramaddr, caldataaddr1) - cfelen;
105 for (i = 0; i < nrparts; i++)
106 pr_info("Partition %d is %s offset %llx and length %llx\n", i,
107 --- a/include/linux/mtd/partitions.h
108 +++ b/include/linux/mtd/partitions.h
109 @@ -58,10 +58,12 @@ struct device_node;
111 * struct mtd_part_parser_data - used to pass data to MTD partition parsers.
112 * @origin: for RedBoot, start address of MTD device
113 + * @caldata: for CFE, start address of wifi calibration data
114 * @of_node: for OF parsers, device node containing partitioning information
116 struct mtd_part_parser_data {
117 unsigned long origin;
118 + unsigned long caldata[2];
119 struct device_node *of_node;