bcm63xx: add support for linux 3.8
[openwrt.git] / target / linux / brcm63xx / patches-3.8 / 436-MTD-bcm63xxpart-allow-passing-a-caldata-offset.patch
1 Allow bcm63xxpart to receive a caldata offset if calibration data is
2 contained in flash.
3 ---
4  drivers/mtd/bcm63xxpart.c      |   51 ++++++++++++++++++++++++++++++++++++---
5  include/linux/mtd/partitions.h |    2 +
6  2 files changed, 49 insertions(+), 4 deletions(-)
7
8 --- a/drivers/mtd/bcm63xxpart.c
9 +++ b/drivers/mtd/bcm63xxpart.c
10 @@ -76,10 +76,12 @@ static int bcm63xx_parse_cfe_partitions(
11         struct mtd_partition *parts;
12         int ret;
13         size_t retlen;
14 -       unsigned int rootfsaddr, kerneladdr, spareaddr;
15 +       unsigned int rootfsaddr, kerneladdr, spareaddr, nvramaddr;
16         unsigned int rootfslen, kernellen, sparelen, totallen;
17         unsigned int cfelen, nvramlen;
18         unsigned int cfe_erasesize;
19 +       unsigned int caldatalen1 = 0, caldataaddr1 = 0;
20 +       unsigned int caldatalen2 = 0, caldataaddr2 = 0;
21         int i;
22         u32 computed_crc;
23         bool rootfs_first = false;
24 @@ -93,6 +95,24 @@ static int bcm63xx_parse_cfe_partitions(
25         cfelen = cfe_erasesize;
26         nvramlen = bcm63xx_nvram_get_psi_size() * 1024;
27         nvramlen = roundup(nvramlen, cfe_erasesize);
28 +       nvramaddr = master->size - nvramlen;
29 +
30 +       if (data) {
31 +               if (data->caldata[0]) {
32 +                       caldatalen1 = cfe_erasesize;
33 +                       caldataaddr1 = rounddown(data->caldata[0],
34 +                                                cfe_erasesize);
35 +               }
36 +               if (data->caldata[1]) {
37 +                       caldatalen2 = cfe_erasesize;
38 +                       caldataaddr2 = rounddown(data->caldata[1],
39 +                                                cfe_erasesize);
40 +               }
41 +               if (caldataaddr1 == caldataaddr2) {
42 +                       caldataaddr2 = 0;
43 +                       caldatalen2 = 0;
44 +               }
45 +       }
46  
47         /* Allocate memory for buffer */
48         buf = vmalloc(sizeof(struct bcm_tag));
49 @@ -144,7 +164,7 @@ static int bcm63xx_parse_cfe_partitions(
50                 rootfsaddr = 0;
51                 spareaddr = cfelen;
52         }
53 -       sparelen = master->size - spareaddr - nvramlen;
54 +       sparelen = min_not_zero(nvramaddr, caldataaddr1) - spareaddr;
55  
56         /* Determine number of partitions */
57         if (rootfslen > 0)
58 @@ -153,6 +173,12 @@ static int bcm63xx_parse_cfe_partitions(
59         if (kernellen > 0)
60                 nrparts++;
61  
62 +       if (caldatalen1 > 0)
63 +               nrparts++;
64 +
65 +       if (caldatalen2 > 0)
66 +               nrparts++;
67 +
68         /* Ask kernel for more memory */
69         parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
70         if (!parts) {
71 @@ -190,15 +216,32 @@ static int bcm63xx_parse_cfe_partitions(
72                 curpart++;
73         }
74  
75 +       if (caldatalen1 > 0) {
76 +               if (caldatalen2 > 0)
77 +                       parts[curpart].name = "cal_data1";
78 +               else
79 +                       parts[curpart].name = "cal_data";
80 +               parts[curpart].offset = caldataaddr1;
81 +               parts[curpart].size = caldatalen1;
82 +               curpart++;
83 +       }
84 +
85 +       if (caldatalen2 > 0) {
86 +               parts[curpart].name = "cal_data2";
87 +               parts[curpart].offset = caldataaddr2;
88 +               parts[curpart].size = caldatalen2;
89 +               curpart++;
90 +       }
91 +
92         parts[curpart].name = "nvram";
93 -       parts[curpart].offset = master->size - nvramlen;
94 +       parts[curpart].offset = nvramaddr;
95         parts[curpart].size = nvramlen;
96         curpart++;
97  
98         /* Global partition "linux" to make easy firmware upgrade */
99         parts[curpart].name = "linux";
100         parts[curpart].offset = cfelen;
101 -       parts[curpart].size = master->size - cfelen - nvramlen;
102 +       parts[curpart].size = min_not_zero(nvramaddr, caldataaddr1) - cfelen;
103  
104         for (i = 0; i < nrparts; i++)
105                 pr_info("Partition %d is %s offset %llx and length %llx\n", i,
106 --- a/include/linux/mtd/partitions.h
107 +++ b/include/linux/mtd/partitions.h
108 @@ -58,10 +58,12 @@ struct device_node;
109  /**
110   * struct mtd_part_parser_data - used to pass data to MTD partition parsers.
111   * @origin: for RedBoot, start address of MTD device
112 + * @caldata: for CFE, start address of wifi calibration data
113   * @of_node: for OF parsers, device node containing partitioning information
114   */
115  struct mtd_part_parser_data {
116         unsigned long origin;
117 +       unsigned long caldata[2];
118         struct device_node *of_node;
119  };
120