bcm53xx: add early support for Buffalo WZR-900DHP
[openwrt.git] / target / linux / bcm53xx / patches-3.14 / 111-bcm47xx-nvram-add-new-nvram-driver-with-dt-support.patch
1 From 71a6bff8656a1713615ffdd9139a83d65ba46c6d Mon Sep 17 00:00:00 2001
2 From: Hauke Mehrtens <hauke@hauke-m.de>
3 Date: Sat, 3 May 2014 22:54:59 +0200
4 Subject: [PATCH 02/17] bcm47xx-nvram: add new broadcom nvram driver with dt
5  support
6
7 This adds a new driver which searches at a given memory range for a
8 nvram like it is used on the bcm47xx and bcm53xx SoCs with ARM and MIPS
9 CPUs. This driver provides acces to this nvram to other device in the
10 device tree. You have to specify the memory ranges where the content of
11 the flash chip is memory mapped and this driver will search there for
12 some nvram and parse it. Other drivers can use this driver to access the
13 device nvram. The nvram is used to store board configurations like the
14 mac addresses, the switch configuration and the calibration data for
15 the wifi devices.
16
17 This was copied from arch/mips/bcm47xx/nvram.c and modified to interact
18 with device tree. My plan is to make the MIPS bcm47xx also use this new
19 driver some time later.
20
21 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
22 ---
23  .../devicetree/bindings/misc/bcm47xx-nvram.txt     |  19 ++
24  arch/mips/bcm47xx/board.c                          |  40 ++--
25  arch/mips/bcm47xx/nvram.c                          |   7 +-
26  arch/mips/bcm47xx/setup.c                          |   4 +-
27  arch/mips/bcm47xx/sprom.c                          |   4 +-
28  arch/mips/bcm47xx/time.c                           |   2 +-
29  drivers/misc/Kconfig                               |   5 +
30  drivers/misc/Makefile                              |   1 +
31  drivers/misc/bcm47xx-nvram.c                       | 215 +++++++++++++++++++++
32  drivers/net/ethernet/broadcom/b44.c                |   2 +-
33  drivers/net/ethernet/broadcom/bgmac.c              |   5 +-
34  drivers/ssb/driver_chipcommon_pmu.c                |   3 +-
35  include/linux/bcm47xx_nvram.h                      |  17 +-
36  13 files changed, 286 insertions(+), 38 deletions(-)
37  create mode 100644 Documentation/devicetree/bindings/misc/bcm47xx-nvram.txt
38  create mode 100644 drivers/misc/bcm47xx-nvram.c
39
40 --- /dev/null
41 +++ b/Documentation/devicetree/bindings/misc/bcm47xx-nvram.txt
42 @@ -0,0 +1,19 @@
43 +Broadcom bcm47xx/bcm53xx nvram access driver
44 +
45 +This driver provides access to the nvram for other drivers.
46 +
47 +Required properties:
48 +
49 +- compatible : brcm,bcm47xx-nvram
50 +
51 +- reg : iomem address range
52 +
53 +On NorthStar ARM SoCs the NAND flash is available at 0x1c000000 and the
54 +NOR flash is at 0x1e000000
55 +
56 +Example:
57 +
58 +nvram0: nvram@0 {
59 +       compatible = "brcm,bcm47xx-nvram";
60 +       reg = <0x1c000000 0x01000000>;
61 +};
62 --- a/arch/mips/bcm47xx/board.c
63 +++ b/arch/mips/bcm47xx/board.c
64 @@ -196,50 +196,50 @@ static __init const struct bcm47xx_board
65         const struct bcm47xx_board_type_list2 *e2;
66         const struct bcm47xx_board_type_list3 *e3;
67  
68 -       if (bcm47xx_nvram_getenv("model_name", buf1, sizeof(buf1)) >= 0) {
69 +       if (bcm47xx_nvram_getenv(NULL, "model_name", buf1, sizeof(buf1)) >= 0) {
70                 for (e1 = bcm47xx_board_list_model_name; e1->value1; e1++) {
71                         if (!strcmp(buf1, e1->value1))
72                                 return &e1->board;
73                 }
74         }
75  
76 -       if (bcm47xx_nvram_getenv("model_no", buf1, sizeof(buf1)) >= 0) {
77 +       if (bcm47xx_nvram_getenv(NULL, "model_no", buf1, sizeof(buf1)) >= 0) {
78                 for (e1 = bcm47xx_board_list_model_no; e1->value1; e1++) {
79                         if (strstarts(buf1, e1->value1))
80                                 return &e1->board;
81                 }
82         }
83  
84 -       if (bcm47xx_nvram_getenv("machine_name", buf1, sizeof(buf1)) >= 0) {
85 +       if (bcm47xx_nvram_getenv(NULL, "machine_name", buf1, sizeof(buf1)) >= 0) {
86                 for (e1 = bcm47xx_board_list_machine_name; e1->value1; e1++) {
87                         if (strstarts(buf1, e1->value1))
88                                 return &e1->board;
89                 }
90         }
91  
92 -       if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0) {
93 +       if (bcm47xx_nvram_getenv(NULL, "hardware_version", buf1, sizeof(buf1)) >= 0) {
94                 for (e1 = bcm47xx_board_list_hardware_version; e1->value1; e1++) {
95                         if (strstarts(buf1, e1->value1))
96                                 return &e1->board;
97                 }
98         }
99  
100 -       if (bcm47xx_nvram_getenv("productid", buf1, sizeof(buf1)) >= 0) {
101 +       if (bcm47xx_nvram_getenv(NULL, "productid", buf1, sizeof(buf1)) >= 0) {
102                 for (e1 = bcm47xx_board_list_productid; e1->value1; e1++) {
103                         if (!strcmp(buf1, e1->value1))
104                                 return &e1->board;
105                 }
106         }
107  
108 -       if (bcm47xx_nvram_getenv("ModelId", buf1, sizeof(buf1)) >= 0) {
109 +       if (bcm47xx_nvram_getenv(NULL, "ModelId", buf1, sizeof(buf1)) >= 0) {
110                 for (e1 = bcm47xx_board_list_ModelId; e1->value1; e1++) {
111                         if (!strcmp(buf1, e1->value1))
112                                 return &e1->board;
113                 }
114         }
115  
116 -       if (bcm47xx_nvram_getenv("melco_id", buf1, sizeof(buf1)) >= 0 ||
117 -           bcm47xx_nvram_getenv("buf1falo_id", buf1, sizeof(buf1)) >= 0) {
118 +       if (bcm47xx_nvram_getenv(NULL, "melco_id", buf1, sizeof(buf1)) >= 0 ||
119 +           bcm47xx_nvram_getenv(NULL, "buf1falo_id", buf1, sizeof(buf1)) >= 0) {
120                 /* buffalo hardware, check id for specific hardware matches */
121                 for (e1 = bcm47xx_board_list_melco_id; e1->value1; e1++) {
122                         if (!strcmp(buf1, e1->value1))
123 @@ -247,8 +247,8 @@ static __init const struct bcm47xx_board
124                 }
125         }
126  
127 -       if (bcm47xx_nvram_getenv("boot_hw_model", buf1, sizeof(buf1)) >= 0 &&
128 -           bcm47xx_nvram_getenv("boot_hw_ver", buf2, sizeof(buf2)) >= 0) {
129 +       if (bcm47xx_nvram_getenv(NULL, "boot_hw_model", buf1, sizeof(buf1)) >= 0 &&
130 +           bcm47xx_nvram_getenv(NULL, "boot_hw_ver", buf2, sizeof(buf2)) >= 0) {
131                 for (e2 = bcm47xx_board_list_boot_hw; e2->value1; e2++) {
132                         if (!strcmp(buf1, e2->value1) &&
133                             !strcmp(buf2, e2->value2))
134 @@ -256,16 +256,16 @@ static __init const struct bcm47xx_board
135                 }
136         }
137  
138 -       if (bcm47xx_nvram_getenv("board_id", buf1, sizeof(buf1)) >= 0) {
139 +       if (bcm47xx_nvram_getenv(NULL, "board_id", buf1, sizeof(buf1)) >= 0) {
140                 for (e1 = bcm47xx_board_list_board_id; e1->value1; e1++) {
141                         if (!strcmp(buf1, e1->value1))
142                                 return &e1->board;
143                 }
144         }
145  
146 -       if (bcm47xx_nvram_getenv("boardtype", buf1, sizeof(buf1)) >= 0 &&
147 -           bcm47xx_nvram_getenv("boardnum", buf2, sizeof(buf2)) >= 0 &&
148 -           bcm47xx_nvram_getenv("boardrev", buf3, sizeof(buf3)) >= 0) {
149 +       if (bcm47xx_nvram_getenv(NULL, "boardtype", buf1, sizeof(buf1)) >= 0 &&
150 +           bcm47xx_nvram_getenv(NULL, "boardnum", buf2, sizeof(buf2)) >= 0 &&
151 +           bcm47xx_nvram_getenv(NULL, "boardrev", buf3, sizeof(buf3)) >= 0) {
152                 for (e3 = bcm47xx_board_list_board; e3->value1; e3++) {
153                         if (!strcmp(buf1, e3->value1) &&
154                             !strcmp(buf2, e3->value2) &&
155 @@ -286,7 +286,7 @@ void __init bcm47xx_board_detect(void)
156                 return;
157  
158         /* check if the nvram is available */
159 -       err = bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf));
160 +       err = bcm47xx_nvram_getenv(NULL, "boardtype", buf, sizeof(buf));
161  
162         /* init of nvram failed, probably too early now */
163         if (err == -ENXIO) {
164 --- a/arch/mips/bcm47xx/nvram.c
165 +++ b/arch/mips/bcm47xx/nvram.c
166 @@ -158,7 +158,8 @@ static int nvram_init(void)
167         return -ENXIO;
168  }
169  
170 -int bcm47xx_nvram_getenv(char *name, char *val, size_t val_len)
171 +int bcm47xx_nvram_getenv(const struct device *dev, const char *name, char *val,
172 +                        size_t val_len)
173  {
174         char *var, *value, *end, *eq;
175         int err;
176 @@ -190,7 +191,7 @@ int bcm47xx_nvram_getenv(char *name, cha
177  }
178  EXPORT_SYMBOL(bcm47xx_nvram_getenv);
179  
180 -int bcm47xx_nvram_gpio_pin(const char *name)
181 +int bcm47xx_nvram_gpio_pin(const struct device *dev, const char *name)
182  {
183         int i, err;
184         char nvram_var[10];
185 @@ -200,7 +201,7 @@ int bcm47xx_nvram_gpio_pin(const char *n
186                 err = snprintf(nvram_var, sizeof(nvram_var), "gpio%i", i);
187                 if (err <= 0)
188                         continue;
189 -               err = bcm47xx_nvram_getenv(nvram_var, buf, sizeof(buf));
190 +               err = bcm47xx_nvram_getenv(dev, nvram_var, buf, sizeof(buf));
191                 if (err <= 0)
192                         continue;
193                 if (!strcmp(name, buf))
194 --- a/arch/mips/bcm47xx/setup.c
195 +++ b/arch/mips/bcm47xx/setup.c
196 @@ -123,7 +123,7 @@ static int bcm47xx_get_invariants(struct
197         memset(&iv->sprom, 0, sizeof(struct ssb_sprom));
198         bcm47xx_fill_sprom(&iv->sprom, NULL, false);
199  
200 -       if (bcm47xx_nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
201 +       if (bcm47xx_nvram_getenv(NULL, "cardbus", buf, sizeof(buf)) >= 0)
202                 iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
203  
204         return 0;
205 @@ -146,7 +146,7 @@ static void __init bcm47xx_register_ssb(
206                 panic("Failed to initialize SSB bus (err %d)", err);
207  
208         mcore = &bcm47xx_bus.ssb.mipscore;
209 -       if (bcm47xx_nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
210 +       if (bcm47xx_nvram_getenv(NULL, "kernel_args", buf, sizeof(buf)) >= 0) {
211                 if (strstr(buf, "console=ttyS1")) {
212                         struct ssb_serial_port port;
213  
214 --- a/arch/mips/bcm47xx/sprom.c
215 +++ b/arch/mips/bcm47xx/sprom.c
216 @@ -50,10 +50,10 @@ static int get_nvram_var(const char *pre
217  
218         create_key(prefix, postfix, name, key, sizeof(key));
219  
220 -       err = bcm47xx_nvram_getenv(key, buf, len);
221 +       err = bcm47xx_nvram_getenv(NULL, key, buf, len);
222         if (fallback && err == -ENOENT && prefix) {
223                 create_key(NULL, postfix, name, key, sizeof(key));
224 -               err = bcm47xx_nvram_getenv(key, buf, len);
225 +               err = bcm47xx_nvram_getenv(NULL, key, buf, len);
226         }
227         return err;
228  }
229 --- a/arch/mips/bcm47xx/time.c
230 +++ b/arch/mips/bcm47xx/time.c
231 @@ -61,7 +61,7 @@ void __init plat_time_init(void)
232         }
233  
234         if (chip_id == 0x5354) {
235 -               len = bcm47xx_nvram_getenv("clkfreq", buf, sizeof(buf));
236 +               len = bcm47xx_nvram_getenv(NULL, "clkfreq", buf, sizeof(buf));
237                 if (len >= 0 && !strncmp(buf, "200", 4))
238                         hz = 100000000;
239         }
240 --- a/drivers/misc/Kconfig
241 +++ b/drivers/misc/Kconfig
242 @@ -515,6 +515,11 @@ config SRAM
243           the genalloc API. It is supposed to be used for small on-chip SRAM
244           areas found on many SoCs.
245  
246 +config BCM47XX_NVRAM
247 +       tristate "BCM47XX nvram driver"
248 +       help
249 +               This adds support for the brcm47xx nvram driver.
250 +
251  source "drivers/misc/c2port/Kconfig"
252  source "drivers/misc/eeprom/Kconfig"
253  source "drivers/misc/cb710/Kconfig"
254 --- a/drivers/misc/Makefile
255 +++ b/drivers/misc/Makefile
256 @@ -54,3 +54,4 @@ obj-$(CONFIG_LATTICE_ECP3_CONFIG)     += lat
257  obj-$(CONFIG_SRAM)             += sram.o
258  obj-y                          += mic/
259  obj-$(CONFIG_GENWQE)           += genwqe/
260 +obj-$(CONFIG_BCM47XX_NVRAM)    += bcm47xx-nvram.o
261 --- /dev/null
262 +++ b/drivers/misc/bcm47xx-nvram.c
263 @@ -0,0 +1,215 @@
264 +/*
265 + * BCM947xx nvram variable access
266 + *
267 + * Copyright (C) 2005 Broadcom Corporation
268 + * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
269 + * Copyright (C) 2010-2014 Hauke Mehrtens <hauke@hauke-m.de>
270 + *
271 + * This program is free software; you can redistribute it and/or modify it
272 + * under  the terms of the GNU General  Public License as published by the
273 + * Free Software Foundation;  either version 2 of the  License, or (at your
274 + * option) any later version.
275 + */
276 +
277 +#include <linux/types.h>
278 +#include <linux/module.h>
279 +#include <linux/kernel.h>
280 +#include <linux/string.h>
281 +#include <linux/of_address.h>
282 +#include <linux/device.h>
283 +#include <linux/platform_device.h>
284 +#include <linux/io.h>
285 +#include <linux/bcm47xx_nvram.h>
286 +
287 +struct bcm47xx_nvram {
288 +       size_t nvram_len;
289 +       char *nvram_buf;
290 +};
291 +
292 +static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000};
293 +
294 +static u32 find_nvram_size(void __iomem *end)
295 +{
296 +       struct nvram_header __iomem *header;
297 +       int i;
298 +
299 +       for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) {
300 +               header = (struct nvram_header __iomem *)(end - nvram_sizes[i]);
301 +               if (__raw_readl(&header->magic) == NVRAM_HEADER)
302 +                       return nvram_sizes[i];
303 +       }
304 +
305 +       return 0;
306 +}
307 +
308 +/* Probe for NVRAM header */
309 +static int nvram_find_and_copy(struct device *dev, void __iomem *base,
310 +                              size_t len, char **nvram_buf,
311 +                              size_t *nvram_len)
312 +{
313 +       struct nvram_header __iomem *header;
314 +       int i;
315 +       u32 off;
316 +       u32 *dst;
317 +       __le32 __iomem *src;
318 +       u32 size;
319 +
320 +       /* TODO: when nvram is on nand flash check for bad blocks first. */
321 +       off = FLASH_MIN;
322 +       while (off <= len) {
323 +               /* Windowed flash access */
324 +               size = find_nvram_size(base + off);
325 +               if (size) {
326 +                       header = (struct nvram_header __iomem *)
327 +                                       (base + off - size);
328 +                       goto found;
329 +               }
330 +               off += 0x10000;
331 +       }
332 +
333 +       /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
334 +       header = (struct nvram_header __iomem *)(base + 4096);
335 +       if (__raw_readl(&header->magic) == NVRAM_HEADER) {
336 +               size = NVRAM_SPACE;
337 +               goto found;
338 +       }
339 +
340 +       header = (struct nvram_header __iomem *)(base + 1024);
341 +       if (__raw_readl(&header->magic) == NVRAM_HEADER) {
342 +               size = NVRAM_SPACE;
343 +               goto found;
344 +       }
345 +
346 +       *nvram_buf = NULL;
347 +       *nvram_len = 0;
348 +       pr_err("no nvram found\n");
349 +       return -ENXIO;
350 +
351 +found:
352 +       if (readl(&header->len) > size)
353 +               pr_err("The nvram size accoridng to the header seems to be bigger than the partition on flash\n");
354 +       *nvram_len = min_t(u32, readl(&header->len), size);
355 +
356 +       *nvram_buf = devm_kzalloc(dev, *nvram_len, GFP_KERNEL);
357 +       if (!*nvram_buf)
358 +               return -ENOMEM;
359 +
360 +       src = (__le32 __iomem *) header;
361 +       dst = (u32 *) *nvram_buf;
362 +       for (i = 0; i < sizeof(struct nvram_header); i += 4)
363 +               *dst++ = __raw_readl(src++);
364 +       for (; i < *nvram_len; i += 4)
365 +               *dst++ = readl(src++);
366 +
367 +       return 0;
368 +}
369 +
370 +int bcm47xx_nvram_getenv(const struct device *dev, const char *name, char *val,
371 +                        size_t val_len)
372 +{
373 +       char *var, *value, *end, *eq;
374 +       struct bcm47xx_nvram *nvram;
375 +
376 +       if (!dev)
377 +               return -ENODEV;
378 +
379 +       nvram = dev_get_drvdata(dev);
380 +
381 +       if (!name || !nvram || !nvram->nvram_len)
382 +               return -EINVAL;
383 +
384 +       /* Look for name=value and return value */
385 +       var = nvram->nvram_buf + sizeof(struct nvram_header);
386 +       end = nvram->nvram_buf + nvram->nvram_len - 2;
387 +       end[0] = end[1] = '\0';
388 +       for (; *var; var = value + strlen(value) + 1) {
389 +               eq = strchr(var, '=');
390 +               if (!eq)
391 +                       break;
392 +               value = eq + 1;
393 +               if ((eq - var) == strlen(name) &&
394 +                       strncmp(var, name, (eq - var)) == 0) {
395 +                       return snprintf(val, val_len, "%s", value);
396 +               }
397 +       }
398 +       return -ENOENT;
399 +}
400 +EXPORT_SYMBOL(bcm47xx_nvram_getenv);
401 +
402 +int bcm47xx_nvram_gpio_pin(const struct device *dev, const char *name)
403 +{
404 +       int i, err;
405 +       char nvram_var[10];
406 +       char buf[30];
407 +
408 +       if (!dev)
409 +               return -ENODEV;
410 +
411 +       for (i = 0; i < 32; i++) {
412 +               err = snprintf(nvram_var, sizeof(nvram_var), "gpio%i", i);
413 +               if (err <= 0)
414 +                       continue;
415 +               err = bcm47xx_nvram_getenv(dev, nvram_var, buf, sizeof(buf));
416 +               if (err <= 0)
417 +                       continue;
418 +               if (!strcmp(name, buf))
419 +                       return i;
420 +       }
421 +       return -ENOENT;
422 +}
423 +EXPORT_SYMBOL(bcm47xx_nvram_gpio_pin);
424 +
425 +static int bcm47xx_nvram_probe(struct platform_device *pdev)
426 +{
427 +       struct device *dev = &pdev->dev;
428 +       struct device_node *np = dev->of_node;
429 +       struct bcm47xx_nvram *nvram;
430 +       int err;
431 +       struct resource flash_mem;
432 +       void __iomem *mmio;
433 +
434 +       /* Alloc */
435 +       nvram = devm_kzalloc(dev, sizeof(*nvram), GFP_KERNEL);
436 +       if (!nvram)
437 +               return -ENOMEM;
438 +
439 +       err = of_address_to_resource(np, 0, &flash_mem);
440 +       if (err)
441 +               return err;
442 +
443 +       mmio = ioremap_nocache(flash_mem.start, resource_size(&flash_mem));
444 +       if (!mmio)
445 +               return -ENOMEM;
446 +
447 +       err = nvram_find_and_copy(dev, mmio, resource_size(&flash_mem),
448 +                                 &nvram->nvram_buf, &nvram->nvram_len);
449 +       if (err)
450 +               goto err_unmap_mmio;
451 +
452 +       platform_set_drvdata(pdev, nvram);
453 +
454 +err_unmap_mmio:
455 +       iounmap(mmio);
456 +       return err;
457 +}
458 +
459 +static const struct of_device_id bcm47xx_nvram_of_match_table[] = {
460 +       { .compatible = "brcm,bcm47xx-nvram", },
461 +       {},
462 +};
463 +MODULE_DEVICE_TABLE(of, mvebu_pcie_of_match_table);
464 +
465 +static struct platform_driver bcm47xx_nvram_driver = {
466 +       .driver = {
467 +               .owner = THIS_MODULE,
468 +               .name = "bcm47xx-nvram",
469 +               .of_match_table = bcm47xx_nvram_of_match_table,
470 +               /* driver unloading/unbinding currently not supported */
471 +               .suppress_bind_attrs = true,
472 +       },
473 +       .probe = bcm47xx_nvram_probe,
474 +};
475 +module_platform_driver(bcm47xx_nvram_driver);
476 +
477 +MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>");
478 +MODULE_LICENSE("GPLv2");
479 --- a/drivers/net/ethernet/broadcom/b44.c
480 +++ b/drivers/net/ethernet/broadcom/b44.c
481 @@ -411,7 +411,7 @@ static void b44_wap54g10_workaround(stru
482          * see https://dev.openwrt.org/ticket/146
483          * check and reset bit "isolate"
484          */
485 -       if (bcm47xx_nvram_getenv("boardnum", buf, sizeof(buf)) < 0)
486 +       if (bcm47xx_nvram_getenv(NULL, "boardnum", buf, sizeof(buf)) < 0)
487                 return;
488         if (simple_strtoul(buf, NULL, 0) == 2) {
489                 err = __b44_readphy(bp, 0, MII_BMCR, &val);
490 --- a/drivers/net/ethernet/broadcom/bgmac.c
491 +++ b/drivers/net/ethernet/broadcom/bgmac.c
492 @@ -974,7 +974,8 @@ static void bgmac_chip_reset(struct bgma
493                              BGMAC_CHIPCTL_1_IF_TYPE_MII;
494                 char buf[4];
495  
496 -               if (bcm47xx_nvram_getenv("et_swtype", buf, sizeof(buf)) > 0) {
497 +               if (bcm47xx_nvram_getenv(NULL, "et_swtype", buf,
498 +                                        sizeof(buf)) > 0) {
499                         if (kstrtou8(buf, 0, &et_swtype))
500                                 bgmac_err(bgmac, "Failed to parse et_swtype (%s)\n",
501                                           buf);
502 @@ -1534,7 +1535,7 @@ static int bgmac_probe(struct bcma_devic
503         }
504  
505         bgmac->int_mask = BGMAC_IS_ERRMASK | BGMAC_IS_RX | BGMAC_IS_TX_MASK;
506 -       if (bcm47xx_nvram_getenv("et0_no_txint", NULL, 0) == 0)
507 +       if (bcm47xx_nvram_getenv(NULL, "et0_no_txint", NULL, 0) == 0)
508                 bgmac->int_mask &= ~BGMAC_IS_TX_MASK;
509  
510         /* TODO: reset the external phy. Specs are needed */
511 --- a/drivers/ssb/driver_chipcommon_pmu.c
512 +++ b/drivers/ssb/driver_chipcommon_pmu.c
513 @@ -319,7 +319,8 @@ static void ssb_pmu_pll_init(struct ssb_
514  
515         if (bus->bustype == SSB_BUSTYPE_SSB) {
516                 char buf[20];
517 -               if (bcm47xx_nvram_getenv("xtalfreq", buf, sizeof(buf)) >= 0)
518 +               if (bcm47xx_nvram_getenv(NULL, "xtalfreq", buf,
519 +                                        sizeof(buf)) >= 0)
520                         crystalfreq = simple_strtoul(buf, NULL, 0);
521         }
522  
523 --- a/include/linux/bcm47xx_nvram.h
524 +++ b/include/linux/bcm47xx_nvram.h
525 @@ -15,9 +15,11 @@
526  #include <linux/types.h>
527  #include <linux/kernel.h>
528  
529 +struct device;
530 +
531  struct nvram_header {
532         u32 magic;
533 -       u32 len;
534 +       __le32 len;
535         u32 crc_ver_init;       /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
536         u32 config_refresh;     /* 0:15 sdram_config, 16:31 sdram_refresh */
537         u32 config_ncdl;        /* ncdl values for memc */
538 @@ -33,18 +35,21 @@ struct nvram_header {
539  #define NVRAM_MAX_VALUE_LEN 255
540  #define NVRAM_MAX_PARAM_LEN 64
541  
542 -#ifdef CONFIG_BCM47XX
543 -int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len);
544 +#if defined(CONFIG_BCM47XX) || defined(CONFIG_BCM47XX_NVRAM)
545 +int bcm47xx_nvram_getenv(const struct device *dev, const char *name, char *val,
546 +                        size_t val_len);
547  
548 -int bcm47xx_nvram_gpio_pin(const char *name);
549 +int bcm47xx_nvram_gpio_pin(const struct device *dev, const char *name);
550  #else
551 -static inline int bcm47xx_nvram_getenv(const char *name, char *val,
552 +static inline int bcm47xx_nvram_getenv(const struct device *dev,
553 +                                      const char *name, char *val,
554                                        size_t val_len)
555  {
556         return -ENXIO;
557  }
558  
559 -static inline int bcm47xx_nvram_gpio_pin(const char *name)
560 +static inline int bcm47xx_nvram_gpio_pin(const struct device *dev,
561 +                                        const char *name)
562  {
563         return -ENXIO;
564  }