e1fd275af0013bf46ca581160b331e9626b02ecf
[openwrt.git] / target / linux / generic / patches-3.14 / 020-ssb_update.patch
1 --- a/drivers/ssb/b43_pci_bridge.c
2 +++ b/drivers/ssb/b43_pci_bridge.c
3 @@ -38,6 +38,7 @@ static const struct pci_device_id b43_pc
4         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432b) },
5         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432c) },
6         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4350) },
7 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4351) },
8         { 0, },
9  };
10  MODULE_DEVICE_TABLE(pci, b43_pci_bridge_tbl);
11 --- a/drivers/ssb/driver_gpio.c
12 +++ b/drivers/ssb/driver_gpio.c
13 @@ -475,7 +475,8 @@ int ssb_gpio_unregister(struct ssb_bus *
14  {
15         if (ssb_chipco_available(&bus->chipco) ||
16             ssb_extif_available(&bus->extif)) {
17 -               return gpiochip_remove(&bus->gpio);
18 +               gpiochip_remove(&bus->gpio);
19 +               return 0;
20         } else {
21                 SSB_WARN_ON(1);
22         }
23 --- a/drivers/ssb/pci.c
24 +++ b/drivers/ssb/pci.c
25 @@ -326,13 +326,13 @@ err_ctlreg:
26         return err;
27  }
28  
29 -static s8 r123_extract_antgain(u8 sprom_revision, const u16 *in,
30 -                              u16 mask, u16 shift)
31 +static s8 sprom_extract_antgain(u8 sprom_revision, const u16 *in, u16 offset,
32 +                               u16 mask, u16 shift)
33  {
34         u16 v;
35         u8 gain;
36  
37 -       v = in[SPOFF(SSB_SPROM1_AGAIN)];
38 +       v = in[SPOFF(offset)];
39         gain = (v & mask) >> shift;
40         if (gain == 0xFF)
41                 gain = 2; /* If unset use 2dBm */
42 @@ -416,12 +416,14 @@ static void sprom_extract_r123(struct ss
43         SPEX(alpha2[1], SSB_SPROM1_CCODE, 0x00ff, 0);
44  
45         /* Extract the antenna gain values. */
46 -       out->antenna_gain.a0 = r123_extract_antgain(out->revision, in,
47 -                                                   SSB_SPROM1_AGAIN_BG,
48 -                                                   SSB_SPROM1_AGAIN_BG_SHIFT);
49 -       out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
50 -                                                   SSB_SPROM1_AGAIN_A,
51 -                                                   SSB_SPROM1_AGAIN_A_SHIFT);
52 +       out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in,
53 +                                                    SSB_SPROM1_AGAIN,
54 +                                                    SSB_SPROM1_AGAIN_BG,
55 +                                                    SSB_SPROM1_AGAIN_BG_SHIFT);
56 +       out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in,
57 +                                                    SSB_SPROM1_AGAIN,
58 +                                                    SSB_SPROM1_AGAIN_A,
59 +                                                    SSB_SPROM1_AGAIN_A_SHIFT);
60         if (out->revision >= 2)
61                 sprom_extract_r23(out, in);
62  }
63 @@ -468,7 +470,15 @@ static void sprom_extract_r458(struct ss
64  
65  static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
66  {
67 +       static const u16 pwr_info_offset[] = {
68 +               SSB_SPROM4_PWR_INFO_CORE0, SSB_SPROM4_PWR_INFO_CORE1,
69 +               SSB_SPROM4_PWR_INFO_CORE2, SSB_SPROM4_PWR_INFO_CORE3
70 +       };
71         u16 il0mac_offset;
72 +       int i;
73 +
74 +       BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
75 +                    ARRAY_SIZE(out->core_pwr_info));
76  
77         if (out->revision == 4)
78                 il0mac_offset = SSB_SPROM4_IL0MAC;
79 @@ -524,14 +534,59 @@ static void sprom_extract_r45(struct ssb
80         }
81  
82         /* Extract the antenna gain values. */
83 -       SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01,
84 -            SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT);
85 -       SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01,
86 -            SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT);
87 -       SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23,
88 -            SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT);
89 -       SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23,
90 -            SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT);
91 +       out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in,
92 +                                                    SSB_SPROM4_AGAIN01,
93 +                                                    SSB_SPROM4_AGAIN0,
94 +                                                    SSB_SPROM4_AGAIN0_SHIFT);
95 +       out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in,
96 +                                                    SSB_SPROM4_AGAIN01,
97 +                                                    SSB_SPROM4_AGAIN1,
98 +                                                    SSB_SPROM4_AGAIN1_SHIFT);
99 +       out->antenna_gain.a2 = sprom_extract_antgain(out->revision, in,
100 +                                                    SSB_SPROM4_AGAIN23,
101 +                                                    SSB_SPROM4_AGAIN2,
102 +                                                    SSB_SPROM4_AGAIN2_SHIFT);
103 +       out->antenna_gain.a3 = sprom_extract_antgain(out->revision, in,
104 +                                                    SSB_SPROM4_AGAIN23,
105 +                                                    SSB_SPROM4_AGAIN3,
106 +                                                    SSB_SPROM4_AGAIN3_SHIFT);
107 +
108 +       /* Extract cores power info info */
109 +       for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
110 +               u16 o = pwr_info_offset[i];
111 +
112 +               SPEX(core_pwr_info[i].itssi_2g, o + SSB_SPROM4_2G_MAXP_ITSSI,
113 +                       SSB_SPROM4_2G_ITSSI, SSB_SPROM4_2G_ITSSI_SHIFT);
114 +               SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SPROM4_2G_MAXP_ITSSI,
115 +                       SSB_SPROM4_2G_MAXP, 0);
116 +
117 +               SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SPROM4_2G_PA_0, ~0, 0);
118 +               SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SPROM4_2G_PA_1, ~0, 0);
119 +               SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SPROM4_2G_PA_2, ~0, 0);
120 +               SPEX(core_pwr_info[i].pa_2g[3], o + SSB_SPROM4_2G_PA_3, ~0, 0);
121 +
122 +               SPEX(core_pwr_info[i].itssi_5g, o + SSB_SPROM4_5G_MAXP_ITSSI,
123 +                       SSB_SPROM4_5G_ITSSI, SSB_SPROM4_5G_ITSSI_SHIFT);
124 +               SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SPROM4_5G_MAXP_ITSSI,
125 +                       SSB_SPROM4_5G_MAXP, 0);
126 +               SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM4_5GHL_MAXP,
127 +                       SSB_SPROM4_5GH_MAXP, 0);
128 +               SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM4_5GHL_MAXP,
129 +                       SSB_SPROM4_5GL_MAXP, SSB_SPROM4_5GL_MAXP_SHIFT);
130 +
131 +               SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SPROM4_5GL_PA_0, ~0, 0);
132 +               SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SPROM4_5GL_PA_1, ~0, 0);
133 +               SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SPROM4_5GL_PA_2, ~0, 0);
134 +               SPEX(core_pwr_info[i].pa_5gl[3], o + SSB_SPROM4_5GL_PA_3, ~0, 0);
135 +               SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SPROM4_5G_PA_0, ~0, 0);
136 +               SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SPROM4_5G_PA_1, ~0, 0);
137 +               SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SPROM4_5G_PA_2, ~0, 0);
138 +               SPEX(core_pwr_info[i].pa_5g[3], o + SSB_SPROM4_5G_PA_3, ~0, 0);
139 +               SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SPROM4_5GH_PA_0, ~0, 0);
140 +               SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SPROM4_5GH_PA_1, ~0, 0);
141 +               SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SPROM4_5GH_PA_2, ~0, 0);
142 +               SPEX(core_pwr_info[i].pa_5gh[3], o + SSB_SPROM4_5GH_PA_3, ~0, 0);
143 +       }
144  
145         sprom_extract_r458(out, in);
146  
147 @@ -621,14 +676,22 @@ static void sprom_extract_r8(struct ssb_
148         SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
149  
150         /* Extract the antenna gain values. */
151 -       SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
152 -            SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
153 -       SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
154 -            SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
155 -       SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
156 -            SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
157 -       SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
158 -            SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
159 +       out->antenna_gain.a0 = sprom_extract_antgain(out->revision, in,
160 +                                                    SSB_SPROM8_AGAIN01,
161 +                                                    SSB_SPROM8_AGAIN0,
162 +                                                    SSB_SPROM8_AGAIN0_SHIFT);
163 +       out->antenna_gain.a1 = sprom_extract_antgain(out->revision, in,
164 +                                                    SSB_SPROM8_AGAIN01,
165 +                                                    SSB_SPROM8_AGAIN1,
166 +                                                    SSB_SPROM8_AGAIN1_SHIFT);
167 +       out->antenna_gain.a2 = sprom_extract_antgain(out->revision, in,
168 +                                                    SSB_SPROM8_AGAIN23,
169 +                                                    SSB_SPROM8_AGAIN2,
170 +                                                    SSB_SPROM8_AGAIN2_SHIFT);
171 +       out->antenna_gain.a3 = sprom_extract_antgain(out->revision, in,
172 +                                                    SSB_SPROM8_AGAIN23,
173 +                                                    SSB_SPROM8_AGAIN3,
174 +                                                    SSB_SPROM8_AGAIN3_SHIFT);
175  
176         /* Extract cores power info info */
177         for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
178 --- a/drivers/ssb/pcihost_wrapper.c
179 +++ b/drivers/ssb/pcihost_wrapper.c
180 @@ -11,15 +11,17 @@
181   * Licensed under the GNU/GPL. See COPYING for details.
182   */
183  
184 +#include <linux/pm.h>
185  #include <linux/pci.h>
186  #include <linux/export.h>
187  #include <linux/slab.h>
188  #include <linux/ssb/ssb.h>
189  
190  
191 -#ifdef CONFIG_PM
192 -static int ssb_pcihost_suspend(struct pci_dev *dev, pm_message_t state)
193 +#ifdef CONFIG_PM_SLEEP
194 +static int ssb_pcihost_suspend(struct device *d)
195  {
196 +       struct pci_dev *dev = to_pci_dev(d);
197         struct ssb_bus *ssb = pci_get_drvdata(dev);
198         int err;
199  
200 @@ -28,17 +30,23 @@ static int ssb_pcihost_suspend(struct pc
201                 return err;
202         pci_save_state(dev);
203         pci_disable_device(dev);
204 -       pci_set_power_state(dev, pci_choose_state(dev, state));
205 +
206 +       /* if there is a wakeup enabled child device on ssb bus,
207 +          enable pci wakeup posibility. */
208 +       device_set_wakeup_enable(d, d->power.wakeup_path);
209 +
210 +       pci_prepare_to_sleep(dev);
211  
212         return 0;
213  }
214  
215 -static int ssb_pcihost_resume(struct pci_dev *dev)
216 +static int ssb_pcihost_resume(struct device *d)
217  {
218 +       struct pci_dev *dev = to_pci_dev(d);
219         struct ssb_bus *ssb = pci_get_drvdata(dev);
220         int err;
221  
222 -       pci_set_power_state(dev, PCI_D0);
223 +       pci_back_from_sleep(dev);
224         err = pci_enable_device(dev);
225         if (err)
226                 return err;
227 @@ -49,10 +57,12 @@ static int ssb_pcihost_resume(struct pci
228  
229         return 0;
230  }
231 -#else /* CONFIG_PM */
232 -# define ssb_pcihost_suspend   NULL
233 -# define ssb_pcihost_resume    NULL
234 -#endif /* CONFIG_PM */
235 +
236 +static const struct dev_pm_ops ssb_pcihost_pm_ops = {
237 +       SET_SYSTEM_SLEEP_PM_OPS(ssb_pcihost_suspend, ssb_pcihost_resume)
238 +};
239 +
240 +#endif /* CONFIG_PM_SLEEP */
241  
242  static int ssb_pcihost_probe(struct pci_dev *dev,
243                              const struct pci_device_id *id)
244 @@ -115,8 +125,9 @@ int ssb_pcihost_register(struct pci_driv
245  {
246         driver->probe = ssb_pcihost_probe;
247         driver->remove = ssb_pcihost_remove;
248 -       driver->suspend = ssb_pcihost_suspend;
249 -       driver->resume = ssb_pcihost_resume;
250 +#ifdef CONFIG_PM_SLEEP
251 +       driver->driver.pm = &ssb_pcihost_pm_ops;
252 +#endif
253  
254         return pci_register_driver(driver);
255  }
256 --- a/include/linux/ssb/ssb.h
257 +++ b/include/linux/ssb/ssb.h
258 @@ -33,6 +33,7 @@ struct ssb_sprom {
259         u8 et1phyaddr;          /* MII address for enet1 */
260         u8 et0mdcport;          /* MDIO for enet0 */
261         u8 et1mdcport;          /* MDIO for enet1 */
262 +       u16 dev_id;             /* Device ID overriding e.g. PCI ID */
263         u16 board_rev;          /* Board revision number from SPROM. */
264         u16 board_num;          /* Board number from SPROM. */
265         u16 board_type;         /* Board type from SPROM. */
266 --- a/include/linux/ssb/ssb_regs.h
267 +++ b/include/linux/ssb/ssb_regs.h
268 @@ -345,6 +345,43 @@
269  #define  SSB_SPROM4_TXPID5GH2_SHIFT    0
270  #define  SSB_SPROM4_TXPID5GH3          0xFF00
271  #define  SSB_SPROM4_TXPID5GH3_SHIFT    8
272 +
273 +/* There are 4 blocks with power info sharing the same layout */
274 +#define SSB_SPROM4_PWR_INFO_CORE0      0x0080
275 +#define SSB_SPROM4_PWR_INFO_CORE1      0x00AE
276 +#define SSB_SPROM4_PWR_INFO_CORE2      0x00DC
277 +#define SSB_SPROM4_PWR_INFO_CORE3      0x010A
278 +
279 +#define SSB_SPROM4_2G_MAXP_ITSSI       0x00    /* 2 GHz ITSSI and 2 GHz Max Power */
280 +#define  SSB_SPROM4_2G_MAXP            0x00FF
281 +#define  SSB_SPROM4_2G_ITSSI           0xFF00
282 +#define  SSB_SPROM4_2G_ITSSI_SHIFT     8
283 +#define SSB_SPROM4_2G_PA_0             0x02    /* 2 GHz power amp */
284 +#define SSB_SPROM4_2G_PA_1             0x04
285 +#define SSB_SPROM4_2G_PA_2             0x06
286 +#define SSB_SPROM4_2G_PA_3             0x08
287 +#define SSB_SPROM4_5G_MAXP_ITSSI       0x0A    /* 5 GHz ITSSI and 5.3 GHz Max Power */
288 +#define  SSB_SPROM4_5G_MAXP            0x00FF
289 +#define  SSB_SPROM4_5G_ITSSI           0xFF00
290 +#define  SSB_SPROM4_5G_ITSSI_SHIFT     8
291 +#define SSB_SPROM4_5GHL_MAXP           0x0C    /* 5.2 GHz and 5.8 GHz Max Power */
292 +#define  SSB_SPROM4_5GH_MAXP           0x00FF
293 +#define  SSB_SPROM4_5GL_MAXP           0xFF00
294 +#define  SSB_SPROM4_5GL_MAXP_SHIFT     8
295 +#define SSB_SPROM4_5G_PA_0             0x0E    /* 5.3 GHz power amp */
296 +#define SSB_SPROM4_5G_PA_1             0x10
297 +#define SSB_SPROM4_5G_PA_2             0x12
298 +#define SSB_SPROM4_5G_PA_3             0x14
299 +#define SSB_SPROM4_5GL_PA_0            0x16    /* 5.2 GHz power amp */
300 +#define SSB_SPROM4_5GL_PA_1            0x18
301 +#define SSB_SPROM4_5GL_PA_2            0x1A
302 +#define SSB_SPROM4_5GL_PA_3            0x1C
303 +#define SSB_SPROM4_5GH_PA_0            0x1E    /* 5.8 GHz power amp */
304 +#define SSB_SPROM4_5GH_PA_1            0x20
305 +#define SSB_SPROM4_5GH_PA_2            0x22
306 +#define SSB_SPROM4_5GH_PA_3            0x24
307 +
308 +/* TODO: Make it deprecated */
309  #define SSB_SPROM4_MAXP_BG             0x0080  /* Max Power BG in path 1 */
310  #define  SSB_SPROM4_MAXP_BG_MASK       0x00FF  /* Mask for Max Power BG */
311  #define  SSB_SPROM4_ITSSI_BG           0xFF00  /* Mask for path 1 itssi_bg */
312 --- a/arch/mips/bcm47xx/sprom.c
313 +++ b/arch/mips/bcm47xx/sprom.c
314 @@ -168,6 +168,7 @@ static void nvram_read_alpha2(const char
315  static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom,
316                                         const char *prefix, bool fallback)
317  {
318 +       nvram_read_u16(prefix, NULL, "devid", &sprom->dev_id, 0, fallback);
319         nvram_read_u8(prefix, NULL, "ledbh0", &sprom->gpio0, 0xff, fallback);
320         nvram_read_u8(prefix, NULL, "ledbh1", &sprom->gpio1, 0xff, fallback);
321         nvram_read_u8(prefix, NULL, "ledbh2", &sprom->gpio2, 0xff, fallback);