mac80211: add missing dependency to mac80211 to brcmsmac
[openwrt.git] / target / linux / brcm47xx / patches-3.2 / 196-bcma-add-support-for-sprom-not-found-on-the-device.patch
1
2 --- a/drivers/bcma/sprom.c
3 +++ b/drivers/bcma/sprom.c
4 @@ -2,6 +2,8 @@
5   * Broadcom specific AMBA
6   * SPROM reading
7   *
8 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
9 + *
10   * Licensed under the GNU/GPL. See COPYING for details.
11   */
12  
13 @@ -16,6 +18,45 @@
14  
15  #define SPOFF(offset)  ((offset) / sizeof(u16))
16  
17 +static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out);
18 +
19 +/**
20 + * bcma_arch_register_fallback_sprom - Registers a method providing a
21 + * fallback SPROM if no SPROM is found.
22 + *
23 + * @sprom_callback: The callback function.
24 + *
25 + * With this function the architecture implementation may register a
26 + * callback handler which fills the SPROM data structure. The fallback is
27 + * used for PCI based BCMA devices, where no valid SPROM can be found
28 + * in the shadow registers and to provide the SPROM for SoCs where BCMA is
29 + * to controll the system bus.
30 + *
31 + * This function is useful for weird architectures that have a half-assed
32 + * BCMA device hardwired to their PCI bus.
33 + *
34 + * This function is available for architecture code, only. So it is not
35 + * exported.
36 + */
37 +int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus,
38 +                                    struct ssb_sprom *out))
39 +{
40 +       if (get_fallback_sprom)
41 +               return -EEXIST;
42 +       get_fallback_sprom = sprom_callback;
43 +
44 +       return 0;
45 +}
46 +
47 +static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus,
48 +                                        struct ssb_sprom *out)
49 +{
50 +       if (!get_fallback_sprom)
51 +               return -ENOENT;
52 +
53 +       return get_fallback_sprom(bus, out);
54 +}
55 +
56  /**************************************************
57   * R/W ops.
58   **************************************************/
59 @@ -205,23 +246,43 @@ static void bcma_sprom_extract_r8(struct
60                 SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
61  }
62  
63 +static bool bcma_is_sprom_available(struct bcma_bus *bus)
64 +{
65 +       u32 sromctrl;
66 +
67 +       if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
68 +               return false;
69 +
70 +       if (bus->drv_cc.core->id.rev >= 32) {
71 +               sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL);
72 +               return sromctrl & BCMA_CC_SROM_CONTROL_PRESENT;
73 +       }
74 +       return true;
75 +}
76 +
77  int bcma_sprom_get(struct bcma_bus *bus)
78  {
79         u16 offset;
80         u16 *sprom;
81 -       u32 sromctrl;
82         int err = 0;
83  
84         if (!bus->drv_cc.core)
85                 return -EOPNOTSUPP;
86  
87 -       if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
88 -               return -ENOENT;
89 -
90 -       if (bus->drv_cc.core->id.rev >= 32) {
91 -               sromctrl = bcma_read32(bus->drv_cc.core, BCMA_CC_SROM_CONTROL);
92 -               if (!(sromctrl & BCMA_CC_SROM_CONTROL_PRESENT))
93 -                       return -ENOENT;
94 +       if (!bcma_is_sprom_available(bus)) {
95 +               /*
96 +                * Maybe there is no SPROM on the device?
97 +                * Now we ask the arch code if there is some sprom
98 +                * available for this device in some other storage.
99 +                */
100 +               err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
101 +               if (err) {
102 +                       pr_warn("Using fallback SPROM failed (err %d)\n", err);
103 +               } else {
104 +                       pr_debug("Using SPROM revision %d provided by"
105 +                                " platform.\n", bus->sprom.revision);
106 +                       return 0;
107 +               }
108         }
109  
110         sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
111 --- a/include/linux/bcma/bcma.h
112 +++ b/include/linux/bcma/bcma.h
113 @@ -177,6 +177,12 @@ int __bcma_driver_register(struct bcma_d
114  
115  extern void bcma_driver_unregister(struct bcma_driver *drv);
116  
117 +/* Set a fallback SPROM.
118 + * See kdoc at the function definition for complete documentation. */
119 +extern int bcma_arch_register_fallback_sprom(
120 +               int (*sprom_callback)(struct bcma_bus *bus,
121 +               struct ssb_sprom *out));
122 +
123  struct bcma_bus {
124         /* The MMIO area. */
125         void __iomem *mmio;