kernel: fix bluetooth and zsmalloc for 3.14
[openwrt/svn-archive/archive.git] / target / linux / brcm63xx / patches-3.13 / 417-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 @@ -53,10 +53,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 @@ -70,6 +72,24 @@ static int bcm63xx_parse_cfe_partitions(
25 cfelen = cfe_erasesize;
26 nvramlen = bcm63xx_nvram_get_psi_size() * SZ_1K;
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 @@ -121,7 +141,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 @@ -130,6 +150,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 @@ -167,15 +193,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 @@ -56,10 +56,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