kernel: reorganize 2.6.37 patches
[openwrt.git] / target / linux / generic / patches-2.6.31 / 941-ssb_update.patch
1 --- a/drivers/ssb/Kconfig
2 +++ b/drivers/ssb/Kconfig
3 @@ -66,6 +66,20 @@ config SSB_PCMCIAHOST
4  
5           If unsure, say N
6  
7 +config SSB_SDIOHOST_POSSIBLE
8 +       bool
9 +       depends on SSB && (MMC = y || MMC = SSB)
10 +       default y
11 +
12 +config SSB_SDIOHOST
13 +       bool "Support for SSB on SDIO-bus host"
14 +       depends on SSB_SDIOHOST_POSSIBLE
15 +       help
16 +         Support for a Sonics Silicon Backplane on top
17 +         of a SDIO device.
18 +
19 +         If unsure, say N
20 +
21  config SSB_SILENT
22         bool "No SSB kernel messages"
23         depends on SSB && EMBEDDED
24 --- a/drivers/ssb/Makefile
25 +++ b/drivers/ssb/Makefile
26 @@ -6,6 +6,7 @@ ssb-$(CONFIG_SSB_SPROM)                 += sprom.o
27  # host support
28  ssb-$(CONFIG_SSB_PCIHOST)              += pci.o pcihost_wrapper.o
29  ssb-$(CONFIG_SSB_PCMCIAHOST)           += pcmcia.o
30 +ssb-$(CONFIG_SSB_SDIOHOST)             += sdio.o
31  
32  # built-in drivers
33  ssb-y                                  += driver_chipcommon.o
34 --- a/drivers/ssb/b43_pci_bridge.c
35 +++ b/drivers/ssb/b43_pci_bridge.c
36 @@ -24,6 +24,7 @@ static const struct pci_device_id b43_pc
37         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4312) },
38         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4315) },
39         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4318) },
40 +       { PCI_DEVICE(PCI_VENDOR_ID_BCM_GVC,  0x4318) },
41         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4319) },
42         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4320) },
43         { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4321) },
44 --- a/drivers/ssb/driver_chipcommon.c
45 +++ b/drivers/ssb/driver_chipcommon.c
46 @@ -209,6 +209,24 @@ static void chipco_powercontrol_init(str
47         }
48  }
49  
50 +/* http://bcm-v4.sipsolutions.net/802.11/PmuFastPwrupDelay */
51 +static u16 pmu_fast_powerup_delay(struct ssb_chipcommon *cc)
52 +{
53 +       struct ssb_bus *bus = cc->dev->bus;
54 +
55 +       switch (bus->chip_id) {
56 +       case 0x4312:
57 +       case 0x4322:
58 +       case 0x4328:
59 +               return 7000;
60 +       case 0x4325:
61 +               /* TODO: */
62 +       default:
63 +               return 15000;
64 +       }
65 +}
66 +
67 +/* http://bcm-v4.sipsolutions.net/802.11/ClkctlFastPwrupDelay */
68  static void calc_fast_powerup_delay(struct ssb_chipcommon *cc)
69  {
70         struct ssb_bus *bus = cc->dev->bus;
71 @@ -218,6 +236,12 @@ static void calc_fast_powerup_delay(stru
72  
73         if (bus->bustype != SSB_BUSTYPE_PCI)
74                 return;
75 +
76 +       if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
77 +               cc->fast_pwrup_delay = pmu_fast_powerup_delay(cc);
78 +               return;
79 +       }
80 +
81         if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
82                 return;
83  
84 @@ -233,6 +257,9 @@ void ssb_chipcommon_init(struct ssb_chip
85  {
86         if (!cc->dev)
87                 return; /* We don't have a ChipCommon */
88 +       if (cc->dev->id.revision >= 11)
89 +               cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
90 +       ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);
91         ssb_pmu_init(cc);
92         chipco_powercontrol_init(cc);
93         ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
94 @@ -370,6 +397,7 @@ u32 ssb_chipco_gpio_control(struct ssb_c
95  {
96         return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value);
97  }
98 +EXPORT_SYMBOL(ssb_chipco_gpio_control);
99  
100  u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value)
101  {
102 --- a/drivers/ssb/driver_chipcommon_pmu.c
103 +++ b/drivers/ssb/driver_chipcommon_pmu.c
104 @@ -28,6 +28,21 @@ static void ssb_chipco_pll_write(struct
105         chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, value);
106  }
107  
108 +static void ssb_chipco_regctl_maskset(struct ssb_chipcommon *cc,
109 +                                  u32 offset, u32 mask, u32 set)
110 +{
111 +       u32 value;
112 +
113 +       chipco_read32(cc, SSB_CHIPCO_REGCTL_ADDR);
114 +       chipco_write32(cc, SSB_CHIPCO_REGCTL_ADDR, offset);
115 +       chipco_read32(cc, SSB_CHIPCO_REGCTL_ADDR);
116 +       value = chipco_read32(cc, SSB_CHIPCO_REGCTL_DATA);
117 +       value &= mask;
118 +       value |= set;
119 +       chipco_write32(cc, SSB_CHIPCO_REGCTL_DATA, value);
120 +       chipco_read32(cc, SSB_CHIPCO_REGCTL_DATA);
121 +}
122 +
123  struct pmu0_plltab_entry {
124         u16 freq;       /* Crystal frequency in kHz.*/
125         u8 xf;          /* Crystal frequency value for PMU control */
126 @@ -317,6 +332,12 @@ static void ssb_pmu_pll_init(struct ssb_
127         case 0x5354:
128                 ssb_pmu0_pllinit_r0(cc, crystalfreq);
129                 break;
130 +       case 0x4322:
131 +               if (cc->pmu.rev == 2) {
132 +                       chipco_write32(cc, SSB_CHIPCO_PLLCTL_ADDR, 0x0000000A);
133 +                       chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, 0x380005C0);
134 +               }
135 +               break;
136         default:
137                 ssb_printk(KERN_ERR PFX
138                            "ERROR: PLL init unknown for device %04X\n",
139 @@ -402,6 +423,7 @@ static void ssb_pmu_resources_init(struc
140  
141         switch (bus->chip_id) {
142         case 0x4312:
143 +       case 0x4322:
144                 /* We keep the default settings:
145                  * min_msk = 0xCBB
146                  * max_msk = 0x7FFFF
147 @@ -480,9 +502,9 @@ static void ssb_pmu_resources_init(struc
148                 chipco_write32(cc, SSB_CHIPCO_PMU_MAXRES_MSK, max_msk);
149  }
150  
151 +/* http://bcm-v4.sipsolutions.net/802.11/SSB/PmuInit */
152  void ssb_pmu_init(struct ssb_chipcommon *cc)
153  {
154 -       struct ssb_bus *bus = cc->dev->bus;
155         u32 pmucap;
156  
157         if (!(cc->capabilities & SSB_CHIPCO_CAP_PMU))
158 @@ -494,15 +516,91 @@ void ssb_pmu_init(struct ssb_chipcommon
159         ssb_dprintk(KERN_DEBUG PFX "Found rev %u PMU (capabilities 0x%08X)\n",
160                     cc->pmu.rev, pmucap);
161  
162 -       if (cc->pmu.rev >= 1) {
163 -               if ((bus->chip_id == 0x4325) && (bus->chip_rev < 2)) {
164 -                       chipco_mask32(cc, SSB_CHIPCO_PMU_CTL,
165 -                                     ~SSB_CHIPCO_PMU_CTL_NOILPONW);
166 -               } else {
167 -                       chipco_set32(cc, SSB_CHIPCO_PMU_CTL,
168 -                                    SSB_CHIPCO_PMU_CTL_NOILPONW);
169 -               }
170 -       }
171 +       if (cc->pmu.rev == 1)
172 +               chipco_mask32(cc, SSB_CHIPCO_PMU_CTL,
173 +                             ~SSB_CHIPCO_PMU_CTL_NOILPONW);
174 +       else
175 +               chipco_set32(cc, SSB_CHIPCO_PMU_CTL,
176 +                            SSB_CHIPCO_PMU_CTL_NOILPONW);
177         ssb_pmu_pll_init(cc);
178         ssb_pmu_resources_init(cc);
179  }
180 +
181 +void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
182 +                            enum ssb_pmu_ldo_volt_id id, u32 voltage)
183 +{
184 +       struct ssb_bus *bus = cc->dev->bus;
185 +       u32 addr, shift, mask;
186 +
187 +       switch (bus->chip_id) {
188 +       case 0x4328:
189 +       case 0x5354:
190 +               switch (id) {
191 +               case LDO_VOLT1:
192 +                       addr = 2;
193 +                       shift = 25;
194 +                       mask = 0xF;
195 +                       break;
196 +               case LDO_VOLT2:
197 +                       addr = 3;
198 +                       shift = 1;
199 +                       mask = 0xF;
200 +                       break;
201 +               case LDO_VOLT3:
202 +                       addr = 3;
203 +                       shift = 9;
204 +                       mask = 0xF;
205 +                       break;
206 +               case LDO_PAREF:
207 +                       addr = 3;
208 +                       shift = 17;
209 +                       mask = 0x3F;
210 +                       break;
211 +               default:
212 +                       SSB_WARN_ON(1);
213 +                       return;
214 +               }
215 +               break;
216 +       case 0x4312:
217 +               if (SSB_WARN_ON(id != LDO_PAREF))
218 +                       return;
219 +               addr = 0;
220 +               shift = 21;
221 +               mask = 0x3F;
222 +               break;
223 +       default:
224 +               return;
225 +       }
226 +
227 +       ssb_chipco_regctl_maskset(cc, addr, ~(mask << shift),
228 +                                 (voltage & mask) << shift);
229 +}
230 +
231 +void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on)
232 +{
233 +       struct ssb_bus *bus = cc->dev->bus;
234 +       int ldo;
235 +
236 +       switch (bus->chip_id) {
237 +       case 0x4312:
238 +               ldo = SSB_PMURES_4312_PA_REF_LDO;
239 +               break;
240 +       case 0x4328:
241 +               ldo = SSB_PMURES_4328_PA_REF_LDO;
242 +               break;
243 +       case 0x5354:
244 +               ldo = SSB_PMURES_5354_PA_REF_LDO;
245 +               break;
246 +       default:
247 +               return;
248 +       }
249 +
250 +       if (on)
251 +               chipco_set32(cc, SSB_CHIPCO_PMU_MINRES_MSK, 1 << ldo);
252 +       else
253 +               chipco_mask32(cc, SSB_CHIPCO_PMU_MINRES_MSK, ~(1 << ldo));
254 +       chipco_read32(cc, SSB_CHIPCO_PMU_MINRES_MSK); //SPEC FIXME found via mmiotrace - dummy read?
255 +}
256 +
257 +EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage);
258 +EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
259 --- a/drivers/ssb/driver_gige.c
260 +++ b/drivers/ssb/driver_gige.c
261 @@ -12,6 +12,7 @@
262  #include <linux/ssb/ssb_driver_gige.h>
263  #include <linux/pci.h>
264  #include <linux/pci_regs.h>
265 +#include <linux/slab.h>
266  
267  
268  /*
269 --- a/drivers/ssb/driver_mipscore.c
270 +++ b/drivers/ssb/driver_mipscore.c
271 @@ -270,7 +270,6 @@ void ssb_mipscore_init(struct ssb_mipsco
272                                 set_irq(dev, irq++);
273                         }
274                         break;
275 -                       /* fallthrough */
276                 case SSB_DEV_PCI:
277                 case SSB_DEV_ETHERNET:
278                 case SSB_DEV_ETHERNET_GBIT:
279 @@ -281,6 +280,10 @@ void ssb_mipscore_init(struct ssb_mipsco
280                                 set_irq(dev, irq++);
281                                 break;
282                         }
283 +                       /* fallthrough */
284 +               case SSB_DEV_EXTIF:
285 +                       set_irq(dev, 0);
286 +                       break;
287                 }
288         }
289         ssb_dprintk(KERN_INFO PFX "after irq reconfiguration\n");
290 --- a/drivers/ssb/driver_pcicore.c
291 +++ b/drivers/ssb/driver_pcicore.c
292 @@ -246,20 +246,12 @@ static struct pci_controller ssb_pcicore
293         .pci_ops        = &ssb_pcicore_pciops,
294         .io_resource    = &ssb_pcicore_io_resource,
295         .mem_resource   = &ssb_pcicore_mem_resource,
296 -       .mem_offset     = 0x24000000,
297  };
298  
299 -static u32 ssb_pcicore_pcibus_iobase = 0x100;
300 -static u32 ssb_pcicore_pcibus_membase = SSB_PCI_DMA;
301 -
302  /* This function is called when doing a pci_enable_device().
303   * We must first check if the device is a device on the PCI-core bridge. */
304  int ssb_pcicore_plat_dev_init(struct pci_dev *d)
305  {
306 -       struct resource *res;
307 -       int pos, size;
308 -       u32 *base;
309 -
310         if (d->bus->ops != &ssb_pcicore_pciops) {
311                 /* This is not a device on the PCI-core bridge. */
312                 return -ENODEV;
313 @@ -268,27 +260,6 @@ int ssb_pcicore_plat_dev_init(struct pci
314         ssb_printk(KERN_INFO "PCI: Fixing up device %s\n",
315                    pci_name(d));
316  
317 -       /* Fix up resource bases */
318 -       for (pos = 0; pos < 6; pos++) {
319 -               res = &d->resource[pos];
320 -               if (res->flags & IORESOURCE_IO)
321 -                       base = &ssb_pcicore_pcibus_iobase;
322 -               else
323 -                       base = &ssb_pcicore_pcibus_membase;
324 -               res->flags |= IORESOURCE_PCI_FIXED;
325 -               if (res->end) {
326 -                       size = res->end - res->start + 1;
327 -                       if (*base & (size - 1))
328 -                               *base = (*base + size) & ~(size - 1);
329 -                       res->start = *base;
330 -                       res->end = res->start + size - 1;
331 -                       *base += size;
332 -                       pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
333 -               }
334 -               /* Fix up PCI bridge BAR0 only */
335 -               if (d->bus->number == 0 && PCI_SLOT(d->devfn) == 0)
336 -                       break;
337 -       }
338         /* Fix up interrupt lines */
339         d->irq = ssb_mips_irq(extpci_core->dev) + 2;
340         pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
341 @@ -551,13 +522,13 @@ int ssb_pcicore_dev_irqvecs_enable(struc
342         might_sleep_if(pdev->id.coreid != SSB_DEV_PCI);
343  
344         /* Enable interrupts for this device. */
345 -       if (bus->host_pci &&
346 -           ((pdev->id.revision >= 6) || (pdev->id.coreid == SSB_DEV_PCIE))) {
347 +       if ((pdev->id.revision >= 6) || (pdev->id.coreid == SSB_DEV_PCIE)) {
348                 u32 coremask;
349  
350                 /* Calculate the "coremask" for the device. */
351                 coremask = (1 << dev->core_index);
352  
353 +               SSB_WARN_ON(bus->bustype != SSB_BUSTYPE_PCI);
354                 err = pci_read_config_dword(bus->host_pci, SSB_PCI_IRQMASK, &tmp);
355                 if (err)
356                         goto out;
357 --- a/drivers/ssb/main.c
358 +++ b/drivers/ssb/main.c
359 @@ -17,6 +17,8 @@
360  #include <linux/ssb/ssb_driver_gige.h>
361  #include <linux/dma-mapping.h>
362  #include <linux/pci.h>
363 +#include <linux/mmc/sdio_func.h>
364 +#include <linux/slab.h>
365  
366  #include <pcmcia/cs_types.h>
367  #include <pcmcia/cs.h>
368 @@ -88,6 +90,25 @@ found:
369  }
370  #endif /* CONFIG_SSB_PCMCIAHOST */
371  
372 +#ifdef CONFIG_SSB_SDIOHOST
373 +struct ssb_bus *ssb_sdio_func_to_bus(struct sdio_func *func)
374 +{
375 +       struct ssb_bus *bus;
376 +
377 +       ssb_buses_lock();
378 +       list_for_each_entry(bus, &buses, list) {
379 +               if (bus->bustype == SSB_BUSTYPE_SDIO &&
380 +                   bus->host_sdio == func)
381 +                       goto found;
382 +       }
383 +       bus = NULL;
384 +found:
385 +       ssb_buses_unlock();
386 +
387 +       return bus;
388 +}
389 +#endif /* CONFIG_SSB_SDIOHOST */
390 +
391  int ssb_for_each_bus_call(unsigned long data,
392                           int (*func)(struct ssb_bus *bus, unsigned long data))
393  {
394 @@ -120,6 +141,19 @@ static void ssb_device_put(struct ssb_de
395                 put_device(dev->dev);
396  }
397  
398 +static inline struct ssb_driver *ssb_driver_get(struct ssb_driver *drv)
399 +{
400 +       if (drv)
401 +               get_driver(&drv->drv);
402 +       return drv;
403 +}
404 +
405 +static inline void ssb_driver_put(struct ssb_driver *drv)
406 +{
407 +       if (drv)
408 +               put_driver(&drv->drv);
409 +}
410 +
411  static int ssb_device_resume(struct device *dev)
412  {
413         struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
414 @@ -190,90 +224,81 @@ int ssb_bus_suspend(struct ssb_bus *bus)
415  EXPORT_SYMBOL(ssb_bus_suspend);
416  
417  #ifdef CONFIG_SSB_SPROM
418 -int ssb_devices_freeze(struct ssb_bus *bus)
419 +/** ssb_devices_freeze - Freeze all devices on the bus.
420 + *
421 + * After freezing no device driver will be handling a device
422 + * on this bus anymore. ssb_devices_thaw() must be called after
423 + * a successful freeze to reactivate the devices.
424 + *
425 + * @bus: The bus.
426 + * @ctx: Context structure. Pass this to ssb_devices_thaw().
427 + */
428 +int ssb_devices_freeze(struct ssb_bus *bus, struct ssb_freeze_context *ctx)
429  {
430 -       struct ssb_device *dev;
431 -       struct ssb_driver *drv;
432 -       int err = 0;
433 -       int i;
434 -       pm_message_t state = PMSG_FREEZE;
435 +       struct ssb_device *sdev;
436 +       struct ssb_driver *sdrv;
437 +       unsigned int i;
438 +
439 +       memset(ctx, 0, sizeof(*ctx));
440 +       ctx->bus = bus;
441 +       SSB_WARN_ON(bus->nr_devices > ARRAY_SIZE(ctx->device_frozen));
442  
443 -       /* First check that we are capable to freeze all devices. */
444         for (i = 0; i < bus->nr_devices; i++) {
445 -               dev = &(bus->devices[i]);
446 -               if (!dev->dev ||
447 -                   !dev->dev->driver ||
448 -                   !device_is_registered(dev->dev))
449 -                       continue;
450 -               drv = drv_to_ssb_drv(dev->dev->driver);
451 -               if (!drv)
452 +               sdev = ssb_device_get(&bus->devices[i]);
453 +
454 +               if (!sdev->dev || !sdev->dev->driver ||
455 +                   !device_is_registered(sdev->dev)) {
456 +                       ssb_device_put(sdev);
457                         continue;
458 -               if (!drv->suspend) {
459 -                       /* Nope, can't suspend this one. */
460 -                       return -EOPNOTSUPP;
461                 }
462 -       }
463 -       /* Now suspend all devices */
464 -       for (i = 0; i < bus->nr_devices; i++) {
465 -               dev = &(bus->devices[i]);
466 -               if (!dev->dev ||
467 -                   !dev->dev->driver ||
468 -                   !device_is_registered(dev->dev))
469 +               sdrv = ssb_driver_get(drv_to_ssb_drv(sdev->dev->driver));
470 +               if (!sdrv || SSB_WARN_ON(!sdrv->remove)) {
471 +                       ssb_device_put(sdev);
472                         continue;
473 -               drv = drv_to_ssb_drv(dev->dev->driver);
474 -               if (!drv)
475 -                       continue;
476 -               err = drv->suspend(dev, state);
477 -               if (err) {
478 -                       ssb_printk(KERN_ERR PFX "Failed to freeze device %s\n",
479 -                                  dev_name(dev->dev));
480 -                       goto err_unwind;
481                 }
482 +               sdrv->remove(sdev);
483 +               ctx->device_frozen[i] = 1;
484         }
485  
486         return 0;
487 -err_unwind:
488 -       for (i--; i >= 0; i--) {
489 -               dev = &(bus->devices[i]);
490 -               if (!dev->dev ||
491 -                   !dev->dev->driver ||
492 -                   !device_is_registered(dev->dev))
493 -                       continue;
494 -               drv = drv_to_ssb_drv(dev->dev->driver);
495 -               if (!drv)
496 -                       continue;
497 -               if (drv->resume)
498 -                       drv->resume(dev);
499 -       }
500 -       return err;
501  }
502  
503 -int ssb_devices_thaw(struct ssb_bus *bus)
504 +/** ssb_devices_thaw - Unfreeze all devices on the bus.
505 + *
506 + * This will re-attach the device drivers and re-init the devices.
507 + *
508 + * @ctx: The context structure from ssb_devices_freeze()
509 + */
510 +int ssb_devices_thaw(struct ssb_freeze_context *ctx)
511  {
512 -       struct ssb_device *dev;
513 -       struct ssb_driver *drv;
514 -       int err;
515 -       int i;
516 +       struct ssb_bus *bus = ctx->bus;
517 +       struct ssb_device *sdev;
518 +       struct ssb_driver *sdrv;
519 +       unsigned int i;
520 +       int err, result = 0;
521  
522         for (i = 0; i < bus->nr_devices; i++) {
523 -               dev = &(bus->devices[i]);
524 -               if (!dev->dev ||
525 -                   !dev->dev->driver ||
526 -                   !device_is_registered(dev->dev))
527 +               if (!ctx->device_frozen[i])
528                         continue;
529 -               drv = drv_to_ssb_drv(dev->dev->driver);
530 -               if (!drv)
531 +               sdev = &bus->devices[i];
532 +
533 +               if (SSB_WARN_ON(!sdev->dev || !sdev->dev->driver))
534                         continue;
535 -               if (SSB_WARN_ON(!drv->resume))
536 +               sdrv = drv_to_ssb_drv(sdev->dev->driver);
537 +               if (SSB_WARN_ON(!sdrv || !sdrv->probe))
538                         continue;
539 -               err = drv->resume(dev);
540 +
541 +               err = sdrv->probe(sdev, &sdev->id);
542                 if (err) {
543                         ssb_printk(KERN_ERR PFX "Failed to thaw device %s\n",
544 -                                  dev_name(dev->dev));
545 +                                  dev_name(sdev->dev));
546 +                       result = err;
547                 }
548 +               ssb_driver_put(sdrv);
549 +               ssb_device_put(sdev);
550         }
551  
552 -       return 0;
553 +       return result;
554  }
555  #endif /* CONFIG_SSB_SPROM */
556  
557 @@ -360,6 +385,35 @@ static int ssb_device_uevent(struct devi
558                              ssb_dev->id.revision);
559  }
560  
561 +#define ssb_config_attr(attrib, field, format_string) \
562 +static ssize_t \
563 +attrib##_show(struct device *dev, struct device_attribute *attr, char *buf) \
564 +{ \
565 +       return sprintf(buf, format_string, dev_to_ssb_dev(dev)->field); \
566 +}
567 +
568 +ssb_config_attr(core_num, core_index, "%u\n")
569 +ssb_config_attr(coreid, id.coreid, "0x%04x\n")
570 +ssb_config_attr(vendor, id.vendor, "0x%04x\n")
571 +ssb_config_attr(revision, id.revision, "%u\n")
572 +ssb_config_attr(irq, irq, "%u\n")
573 +static ssize_t
574 +name_show(struct device *dev, struct device_attribute *attr, char *buf)
575 +{
576 +       return sprintf(buf, "%s\n",
577 +                      ssb_core_name(dev_to_ssb_dev(dev)->id.coreid));
578 +}
579 +
580 +static struct device_attribute ssb_device_attrs[] = {
581 +       __ATTR_RO(name),
582 +       __ATTR_RO(core_num),
583 +       __ATTR_RO(coreid),
584 +       __ATTR_RO(vendor),
585 +       __ATTR_RO(revision),
586 +       __ATTR_RO(irq),
587 +       __ATTR_NULL,
588 +};
589 +
590  static struct bus_type ssb_bustype = {
591         .name           = "ssb",
592         .match          = ssb_bus_match,
593 @@ -369,6 +423,7 @@ static struct bus_type ssb_bustype = {
594         .suspend        = ssb_device_suspend,
595         .resume         = ssb_device_resume,
596         .uevent         = ssb_device_uevent,
597 +       .dev_attrs      = ssb_device_attrs,
598  };
599  
600  static void ssb_buses_lock(void)
601 @@ -461,6 +516,7 @@ static int ssb_devices_register(struct s
602  #ifdef CONFIG_SSB_PCIHOST
603                         sdev->irq = bus->host_pci->irq;
604                         dev->parent = &bus->host_pci->dev;
605 +                       sdev->dma_dev = dev->parent;
606  #endif
607                         break;
608                 case SSB_BUSTYPE_PCMCIA:
609 @@ -469,8 +525,14 @@ static int ssb_devices_register(struct s
610                         dev->parent = &bus->host_pcmcia->dev;
611  #endif
612                         break;
613 +               case SSB_BUSTYPE_SDIO:
614 +#ifdef CONFIG_SSB_SDIOHOST
615 +                       dev->parent = &bus->host_sdio->dev;
616 +#endif
617 +                       break;
618                 case SSB_BUSTYPE_SSB:
619                         dev->dma_mask = &dev->coherent_dma_mask;
620 +                       sdev->dma_dev = dev;
621                         break;
622                 }
623  
624 @@ -724,12 +786,18 @@ static int ssb_bus_register(struct ssb_b
625         err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
626         if (err)
627                 goto out;
628 +
629 +       /* Init SDIO-host device (if any), before the scan */
630 +       err = ssb_sdio_init(bus);
631 +       if (err)
632 +               goto err_disable_xtal;
633 +
634         ssb_buses_lock();
635         bus->busnumber = next_busnumber;
636         /* Scan for devices (cores) */
637         err = ssb_bus_scan(bus, baseaddr);
638         if (err)
639 -               goto err_disable_xtal;
640 +               goto err_sdio_exit;
641  
642         /* Init PCI-host device (if any) */
643         err = ssb_pci_init(bus);
644 @@ -776,6 +844,8 @@ err_pci_exit:
645         ssb_pci_exit(bus);
646  err_unmap:
647         ssb_iounmap(bus);
648 +err_sdio_exit:
649 +       ssb_sdio_exit(bus);
650  err_disable_xtal:
651         ssb_buses_unlock();
652         ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
653 @@ -796,6 +866,9 @@ int ssb_bus_pcibus_register(struct ssb_b
654         if (!err) {
655                 ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on "
656                            "PCI device %s\n", dev_name(&host_pci->dev));
657 +       } else {
658 +               ssb_printk(KERN_ERR PFX "Failed to register PCI version"
659 +                          " of SSB with error %d\n", err);
660         }
661  
662         return err;
663 @@ -825,6 +898,28 @@ int ssb_bus_pcmciabus_register(struct ss
664  EXPORT_SYMBOL(ssb_bus_pcmciabus_register);
665  #endif /* CONFIG_SSB_PCMCIAHOST */
666  
667 +#ifdef CONFIG_SSB_SDIOHOST
668 +int ssb_bus_sdiobus_register(struct ssb_bus *bus, struct sdio_func *func,
669 +                            unsigned int quirks)
670 +{
671 +       int err;
672 +
673 +       bus->bustype = SSB_BUSTYPE_SDIO;
674 +       bus->host_sdio = func;
675 +       bus->ops = &ssb_sdio_ops;
676 +       bus->quirks = quirks;
677 +
678 +       err = ssb_bus_register(bus, ssb_sdio_get_invariants, ~0);
679 +       if (!err) {
680 +               ssb_printk(KERN_INFO PFX "Sonics Silicon Backplane found on "
681 +                          "SDIO device %s\n", sdio_func_id(func));
682 +       }
683 +
684 +       return err;
685 +}
686 +EXPORT_SYMBOL(ssb_bus_sdiobus_register);
687 +#endif /* CONFIG_SSB_PCMCIAHOST */
688 +
689  int ssb_bus_ssbbus_register(struct ssb_bus *bus,
690                             unsigned long baseaddr,
691                             ssb_invariants_func_t get_invariants)
692 @@ -1099,10 +1194,10 @@ void ssb_device_enable(struct ssb_device
693  }
694  EXPORT_SYMBOL(ssb_device_enable);
695  
696 -/* Wait for a bit in a register to get set or unset.
697 +/* Wait for bitmask in a register to get set or cleared.
698   * timeout is in units of ten-microseconds */
699 -static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask,
700 -                       int timeout, int set)
701 +static int ssb_wait_bits(struct ssb_device *dev, u16 reg, u32 bitmask,
702 +                        int timeout, int set)
703  {
704         int i;
705         u32 val;
706 @@ -1110,7 +1205,7 @@ static int ssb_wait_bit(struct ssb_devic
707         for (i = 0; i < timeout; i++) {
708                 val = ssb_read32(dev, reg);
709                 if (set) {
710 -                       if (val & bitmask)
711 +                       if ((val & bitmask) == bitmask)
712                                 return 0;
713                 } else {
714                         if (!(val & bitmask))
715 @@ -1127,20 +1222,38 @@ static int ssb_wait_bit(struct ssb_devic
716  
717  void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags)
718  {
719 -       u32 reject;
720 +       u32 reject, val;
721  
722         if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET)
723                 return;
724  
725         reject = ssb_tmslow_reject_bitmask(dev);
726 -       ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK);
727 -       ssb_wait_bit(dev, SSB_TMSLOW, reject, 1000, 1);
728 -       ssb_wait_bit(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0);
729 -       ssb_write32(dev, SSB_TMSLOW,
730 -                   SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
731 -                   reject | SSB_TMSLOW_RESET |
732 -                   core_specific_flags);
733 -       ssb_flush_tmslow(dev);
734 +
735 +       if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_CLOCK) {
736 +               ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK);
737 +               ssb_wait_bits(dev, SSB_TMSLOW, reject, 1000, 1);
738 +               ssb_wait_bits(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0);
739 +
740 +               if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) {
741 +                       val = ssb_read32(dev, SSB_IMSTATE);
742 +                       val |= SSB_IMSTATE_REJECT;
743 +                       ssb_write32(dev, SSB_IMSTATE, val);
744 +                       ssb_wait_bits(dev, SSB_IMSTATE, SSB_IMSTATE_BUSY, 1000,
745 +                                     0);
746 +               }
747 +
748 +               ssb_write32(dev, SSB_TMSLOW,
749 +                       SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
750 +                       reject | SSB_TMSLOW_RESET |
751 +                       core_specific_flags);
752 +               ssb_flush_tmslow(dev);
753 +
754 +               if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) {
755 +                       val = ssb_read32(dev, SSB_IMSTATE);
756 +                       val &= ~SSB_IMSTATE_REJECT;
757 +                       ssb_write32(dev, SSB_IMSTATE, val);
758 +               }
759 +       }
760  
761         ssb_write32(dev, SSB_TMSLOW,
762                     reject | SSB_TMSLOW_RESET |
763 @@ -1358,8 +1471,10 @@ static int __init ssb_modinit(void)
764         ssb_buses_lock();
765         err = ssb_attach_queued_buses();
766         ssb_buses_unlock();
767 -       if (err)
768 +       if (err) {
769                 bus_unregister(&ssb_bustype);
770 +               goto out;
771 +       }
772  
773         err = b43_pci_ssb_bridge_init();
774         if (err) {
775 @@ -1375,7 +1490,7 @@ static int __init ssb_modinit(void)
776                 /* don't fail SSB init because of this */
777                 err = 0;
778         }
779 -
780 +out:
781         return err;
782  }
783  /* ssb must be initialized after PCI but before the ssb drivers.
784 --- a/drivers/ssb/pci.c
785 +++ b/drivers/ssb/pci.c
786 @@ -17,6 +17,7 @@
787  
788  #include <linux/ssb/ssb.h>
789  #include <linux/ssb/ssb_regs.h>
790 +#include <linux/slab.h>
791  #include <linux/pci.h>
792  #include <linux/delay.h>
793  
794 @@ -167,10 +168,16 @@ err_pci:
795  }
796  
797  /* Get the word-offset for a SSB_SPROM_XXX define. */
798 -#define SPOFF(offset)  (((offset) - SSB_SPROM_BASE) / sizeof(u16))
799 +#define SPOFF(offset)  ((offset) / sizeof(u16))
800  /* Helper to extract some _offset, which is one of the SSB_SPROM_XXX defines. */
801 -#define SPEX(_outvar, _offset, _mask, _shift)  \
802 +#define SPEX16(_outvar, _offset, _mask, _shift)        \
803         out->_outvar = ((in[SPOFF(_offset)] & (_mask)) >> (_shift))
804 +#define SPEX32(_outvar, _offset, _mask, _shift)        \
805 +       out->_outvar = ((((u32)in[SPOFF((_offset)+2)] << 16 | \
806 +                          in[SPOFF(_offset)]) & (_mask)) >> (_shift))
807 +#define SPEX(_outvar, _offset, _mask, _shift) \
808 +       SPEX16(_outvar, _offset, _mask, _shift)
809 +
810  
811  static inline u8 ssb_crc8(u8 crc, u8 data)
812  {
813 @@ -247,7 +254,7 @@ static int sprom_do_read(struct ssb_bus
814         int i;
815  
816         for (i = 0; i < bus->sprom_size; i++)
817 -               sprom[i] = ioread16(bus->mmio + SSB_SPROM_BASE + (i * 2));
818 +               sprom[i] = ioread16(bus->mmio + bus->sprom_offset + (i * 2));
819  
820         return 0;
821  }
822 @@ -278,7 +285,7 @@ static int sprom_do_write(struct ssb_bus
823                         ssb_printk("75%%");
824                 else if (i % 2)
825                         ssb_printk(".");
826 -               writew(sprom[i], bus->mmio + SSB_SPROM_BASE + (i * 2));
827 +               writew(sprom[i], bus->mmio + bus->sprom_offset + (i * 2));
828                 mmiowb();
829                 msleep(20);
830         }
831 @@ -399,6 +406,46 @@ static void sprom_extract_r123(struct ss
832         out->antenna_gain.ghz5.a3 = gain;
833  }
834  
835 +/* Revs 4 5 and 8 have partially shared layout */
836 +static void sprom_extract_r458(struct ssb_sprom *out, const u16 *in)
837 +{
838 +       SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01,
839 +            SSB_SPROM4_TXPID2G0, SSB_SPROM4_TXPID2G0_SHIFT);
840 +       SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01,
841 +            SSB_SPROM4_TXPID2G1, SSB_SPROM4_TXPID2G1_SHIFT);
842 +       SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23,
843 +            SSB_SPROM4_TXPID2G2, SSB_SPROM4_TXPID2G2_SHIFT);
844 +       SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23,
845 +            SSB_SPROM4_TXPID2G3, SSB_SPROM4_TXPID2G3_SHIFT);
846 +
847 +       SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01,
848 +            SSB_SPROM4_TXPID5GL0, SSB_SPROM4_TXPID5GL0_SHIFT);
849 +       SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01,
850 +            SSB_SPROM4_TXPID5GL1, SSB_SPROM4_TXPID5GL1_SHIFT);
851 +       SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23,
852 +            SSB_SPROM4_TXPID5GL2, SSB_SPROM4_TXPID5GL2_SHIFT);
853 +       SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23,
854 +            SSB_SPROM4_TXPID5GL3, SSB_SPROM4_TXPID5GL3_SHIFT);
855 +
856 +       SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01,
857 +            SSB_SPROM4_TXPID5G0, SSB_SPROM4_TXPID5G0_SHIFT);
858 +       SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01,
859 +            SSB_SPROM4_TXPID5G1, SSB_SPROM4_TXPID5G1_SHIFT);
860 +       SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23,
861 +            SSB_SPROM4_TXPID5G2, SSB_SPROM4_TXPID5G2_SHIFT);
862 +       SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23,
863 +            SSB_SPROM4_TXPID5G3, SSB_SPROM4_TXPID5G3_SHIFT);
864 +
865 +       SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01,
866 +            SSB_SPROM4_TXPID5GH0, SSB_SPROM4_TXPID5GH0_SHIFT);
867 +       SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01,
868 +            SSB_SPROM4_TXPID5GH1, SSB_SPROM4_TXPID5GH1_SHIFT);
869 +       SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23,
870 +            SSB_SPROM4_TXPID5GH2, SSB_SPROM4_TXPID5GH2_SHIFT);
871 +       SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23,
872 +            SSB_SPROM4_TXPID5GH3, SSB_SPROM4_TXPID5GH3_SHIFT);
873 +}
874 +
875  static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in)
876  {
877         int i;
878 @@ -421,10 +468,14 @@ static void sprom_extract_r45(struct ssb
879                 SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0);
880                 SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
881                 SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
882 +               SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0);
883 +               SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0);
884         } else {
885                 SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0);
886                 SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0);
887                 SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0);
888 +               SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0);
889 +               SPEX(boardflags2_hi, SSB_SPROM5_BFL2HI, 0xFFFF, 0);
890         }
891         SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A,
892              SSB_SPROM4_ANTAVAIL_A_SHIFT);
893 @@ -464,6 +515,8 @@ static void sprom_extract_r45(struct ssb
894         memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
895                sizeof(out->antenna_gain.ghz5));
896  
897 +       sprom_extract_r458(out, in);
898 +
899         /* TODO - get remaining rev 4 stuff needed */
900  }
901  
902 @@ -474,12 +527,14 @@ static void sprom_extract_r8(struct ssb_
903  
904         /* extract the MAC address */
905         for (i = 0; i < 3; i++) {
906 -               v = in[SPOFF(SSB_SPROM1_IL0MAC) + i];
907 +               v = in[SPOFF(SSB_SPROM8_IL0MAC) + i];
908                 *(((__be16 *)out->il0mac) + i) = cpu_to_be16(v);
909         }
910         SPEX(country_code, SSB_SPROM8_CCODE, 0xFFFF, 0);
911         SPEX(boardflags_lo, SSB_SPROM8_BFLLO, 0xFFFF, 0);
912         SPEX(boardflags_hi, SSB_SPROM8_BFLHI, 0xFFFF, 0);
913 +       SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, 0xFFFF, 0);
914 +       SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, 0xFFFF, 0);
915         SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
916              SSB_SPROM8_ANTAVAIL_A_SHIFT);
917         SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
918 @@ -490,12 +545,55 @@ static void sprom_extract_r8(struct ssb_
919         SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
920         SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
921              SSB_SPROM8_ITSSI_A_SHIFT);
922 +       SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0);
923 +       SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK,
924 +            SSB_SPROM8_MAXP_AL_SHIFT);
925         SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
926         SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
927              SSB_SPROM8_GPIOA_P1_SHIFT);
928         SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
929         SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
930              SSB_SPROM8_GPIOB_P3_SHIFT);
931 +       SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0);
932 +       SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G,
933 +            SSB_SPROM8_TRI5G_SHIFT);
934 +       SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0);
935 +       SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH,
936 +            SSB_SPROM8_TRI5GH_SHIFT);
937 +       SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G, 0);
938 +       SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G,
939 +            SSB_SPROM8_RXPO5G_SHIFT);
940 +       SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0);
941 +       SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G,
942 +            SSB_SPROM8_RSSISMC2G_SHIFT);
943 +       SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G,
944 +            SSB_SPROM8_RSSISAV2G_SHIFT);
945 +       SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G,
946 +            SSB_SPROM8_BXA2G_SHIFT);
947 +       SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0);
948 +       SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G,
949 +            SSB_SPROM8_RSSISMC5G_SHIFT);
950 +       SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G,
951 +            SSB_SPROM8_RSSISAV5G_SHIFT);
952 +       SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G,
953 +            SSB_SPROM8_BXA5G_SHIFT);
954 +       SPEX(pa0b0, SSB_SPROM8_PA0B0, 0xFFFF, 0);
955 +       SPEX(pa0b1, SSB_SPROM8_PA0B1, 0xFFFF, 0);
956 +       SPEX(pa0b2, SSB_SPROM8_PA0B2, 0xFFFF, 0);
957 +       SPEX(pa1b0, SSB_SPROM8_PA1B0, 0xFFFF, 0);
958 +       SPEX(pa1b1, SSB_SPROM8_PA1B1, 0xFFFF, 0);
959 +       SPEX(pa1b2, SSB_SPROM8_PA1B2, 0xFFFF, 0);
960 +       SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, 0xFFFF, 0);
961 +       SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, 0xFFFF, 0);
962 +       SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, 0xFFFF, 0);
963 +       SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, 0xFFFF, 0);
964 +       SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, 0xFFFF, 0);
965 +       SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, 0xFFFF, 0);
966 +       SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, 0xFFFF, 0);
967 +       SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, 0xFFFFFFFF, 0);
968 +       SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, 0xFFFFFFFF, 0);
969 +       SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, 0xFFFFFFFF, 0);
970 +       SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
971  
972         /* Extract the antenna gain values. */
973         SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01,
974 @@ -509,6 +607,8 @@ static void sprom_extract_r8(struct ssb_
975         memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
976                sizeof(out->antenna_gain.ghz5));
977  
978 +       sprom_extract_r458(out, in);
979 +
980         /* TODO - get remaining rev 8 stuff needed */
981  }
982  
983 @@ -521,36 +621,34 @@ static int sprom_extract(struct ssb_bus
984         ssb_dprintk(KERN_DEBUG PFX "SPROM revision %d detected.\n", out->revision);
985         memset(out->et0mac, 0xFF, 6);           /* preset et0 and et1 mac */
986         memset(out->et1mac, 0xFF, 6);
987 +
988         if ((bus->chip_id & 0xFF00) == 0x4400) {
989                 /* Workaround: The BCM44XX chip has a stupid revision
990                  * number stored in the SPROM.
991                  * Always extract r1. */
992                 out->revision = 1;
993 +               ssb_dprintk(KERN_DEBUG PFX "SPROM treated as revision %d\n", out->revision);
994 +       }
995 +
996 +       switch (out->revision) {
997 +       case 1:
998 +       case 2:
999 +       case 3:
1000                 sprom_extract_r123(out, in);
1001 -       } else if (bus->chip_id == 0x4321) {
1002 -               /* the BCM4328 has a chipid == 0x4321 and a rev 4 SPROM */
1003 -               out->revision = 4;
1004 +               break;
1005 +       case 4:
1006 +       case 5:
1007                 sprom_extract_r45(out, in);
1008 -       } else {
1009 -               switch (out->revision) {
1010 -               case 1:
1011 -               case 2:
1012 -               case 3:
1013 -                       sprom_extract_r123(out, in);
1014 -                       break;
1015 -               case 4:
1016 -               case 5:
1017 -                       sprom_extract_r45(out, in);
1018 -                       break;
1019 -               case 8:
1020 -                       sprom_extract_r8(out, in);
1021 -                       break;
1022 -               default:
1023 -                       ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
1024 -                                  "  revision %d detected. Will extract"
1025 -                                  " v1\n", out->revision);
1026 -                       sprom_extract_r123(out, in);
1027 -               }
1028 +               break;
1029 +       case 8:
1030 +               sprom_extract_r8(out, in);
1031 +               break;
1032 +       default:
1033 +               ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
1034 +                          " revision %d detected. Will extract"
1035 +                          " v1\n", out->revision);
1036 +               out->revision = 1;
1037 +               sprom_extract_r123(out, in);
1038         }
1039  
1040         if (out->boardflags_lo == 0xFFFF)
1041 @@ -565,12 +663,34 @@ static int ssb_pci_sprom_get(struct ssb_
1042                              struct ssb_sprom *sprom)
1043  {
1044         const struct ssb_sprom *fallback;
1045 -       int err = -ENOMEM;
1046 +       int err;
1047         u16 *buf;
1048  
1049 +       if (!ssb_is_sprom_available(bus)) {
1050 +               ssb_printk(KERN_ERR PFX "No SPROM available!\n");
1051 +               return -ENODEV;
1052 +       }
1053 +       if (bus->chipco.dev) {  /* can be unavailible! */
1054 +               /*
1055 +                * get SPROM offset: SSB_SPROM_BASE1 except for
1056 +                * chipcommon rev >= 31 or chip ID is 0x4312 and
1057 +                * chipcommon status & 3 == 2
1058 +                */
1059 +               if (bus->chipco.dev->id.revision >= 31)
1060 +                       bus->sprom_offset = SSB_SPROM_BASE31;
1061 +               else if (bus->chip_id == 0x4312 &&
1062 +                        (bus->chipco.status & 0x03) == 2)
1063 +                       bus->sprom_offset = SSB_SPROM_BASE31;
1064 +               else
1065 +                       bus->sprom_offset = SSB_SPROM_BASE1;
1066 +       } else {
1067 +               bus->sprom_offset = SSB_SPROM_BASE1;
1068 +       }
1069 +       ssb_dprintk(KERN_INFO PFX "SPROM offset is 0x%x\n", bus->sprom_offset);
1070 +
1071         buf = kcalloc(SSB_SPROMSIZE_WORDS_R123, sizeof(u16), GFP_KERNEL);
1072         if (!buf)
1073 -               goto out;
1074 +               return -ENOMEM;
1075         bus->sprom_size = SSB_SPROMSIZE_WORDS_R123;
1076         sprom_do_read(bus, buf);
1077         err = sprom_check_crc(buf, bus->sprom_size);
1078 @@ -580,7 +700,7 @@ static int ssb_pci_sprom_get(struct ssb_
1079                 buf = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
1080                               GFP_KERNEL);
1081                 if (!buf)
1082 -                       goto out;
1083 +                       return -ENOMEM;
1084                 bus->sprom_size = SSB_SPROMSIZE_WORDS_R4;
1085                 sprom_do_read(bus, buf);
1086                 err = sprom_check_crc(buf, bus->sprom_size);
1087 @@ -602,7 +722,6 @@ static int ssb_pci_sprom_get(struct ssb_
1088  
1089  out_free:
1090         kfree(buf);
1091 -out:
1092         return err;
1093  }
1094  
1095 --- a/drivers/ssb/pcihost_wrapper.c
1096 +++ b/drivers/ssb/pcihost_wrapper.c
1097 @@ -12,6 +12,7 @@
1098   */
1099  
1100  #include <linux/pci.h>
1101 +#include <linux/slab.h>
1102  #include <linux/ssb/ssb.h>
1103  
1104  
1105 @@ -58,6 +59,7 @@ static int ssb_pcihost_probe(struct pci_
1106         struct ssb_bus *ssb;
1107         int err = -ENOMEM;
1108         const char *name;
1109 +       u32 val;
1110  
1111         ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
1112         if (!ssb)
1113 @@ -73,6 +75,12 @@ static int ssb_pcihost_probe(struct pci_
1114                 goto err_pci_disable;
1115         pci_set_master(dev);
1116  
1117 +       /* Disable the RETRY_TIMEOUT register (0x41) to keep
1118 +        * PCI Tx retries from interfering with C3 CPU state */
1119 +       pci_read_config_dword(dev, 0x40, &val);
1120 +       if ((val & 0x0000ff00) != 0)
1121 +               pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
1122 +
1123         err = ssb_bus_pcibus_register(ssb, dev);
1124         if (err)
1125                 goto err_pci_release_regions;
1126 --- a/drivers/ssb/pcmcia.c
1127 +++ b/drivers/ssb/pcmcia.c
1128 @@ -617,136 +617,140 @@ static int ssb_pcmcia_sprom_check_crc(co
1129         }                                               \
1130    } while (0)
1131  
1132 -int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
1133 -                             struct ssb_init_invariants *iv)
1134 +static int ssb_pcmcia_get_mac(struct pcmcia_device *p_dev,
1135 +                       tuple_t *tuple,
1136 +                       void *priv)
1137  {
1138 -       tuple_t tuple;
1139 -       int res;
1140 -       unsigned char buf[32];
1141 +       struct ssb_sprom *sprom = priv;
1142 +
1143 +       if (tuple->TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID)
1144 +               return -EINVAL;
1145 +       if (tuple->TupleDataLen != ETH_ALEN + 2)
1146 +               return -EINVAL;
1147 +       if (tuple->TupleData[1] != ETH_ALEN)
1148 +               return -EINVAL;
1149 +       memcpy(sprom->il0mac, &tuple->TupleData[2], ETH_ALEN);
1150 +       return 0;
1151 +};
1152 +
1153 +static int ssb_pcmcia_do_get_invariants(struct pcmcia_device *p_dev,
1154 +                                       tuple_t *tuple,
1155 +                                       void *priv)
1156 +{
1157 +       struct ssb_init_invariants *iv = priv;
1158         struct ssb_sprom *sprom = &iv->sprom;
1159         struct ssb_boardinfo *bi = &iv->boardinfo;
1160         const char *error_description;
1161  
1162 +       GOTO_ERROR_ON(tuple->TupleDataLen < 1, "VEN tpl < 1");
1163 +       switch (tuple->TupleData[0]) {
1164 +       case SSB_PCMCIA_CIS_ID:
1165 +               GOTO_ERROR_ON((tuple->TupleDataLen != 5) &&
1166 +                             (tuple->TupleDataLen != 7),
1167 +                             "id tpl size");
1168 +               bi->vendor = tuple->TupleData[1] |
1169 +                       ((u16)tuple->TupleData[2] << 8);
1170 +               break;
1171 +       case SSB_PCMCIA_CIS_BOARDREV:
1172 +               GOTO_ERROR_ON(tuple->TupleDataLen != 2,
1173 +                       "boardrev tpl size");
1174 +               sprom->board_rev = tuple->TupleData[1];
1175 +               break;
1176 +       case SSB_PCMCIA_CIS_PA:
1177 +               GOTO_ERROR_ON((tuple->TupleDataLen != 9) &&
1178 +                       (tuple->TupleDataLen != 10),
1179 +                       "pa tpl size");
1180 +               sprom->pa0b0 = tuple->TupleData[1] |
1181 +                       ((u16)tuple->TupleData[2] << 8);
1182 +               sprom->pa0b1 = tuple->TupleData[3] |
1183 +                       ((u16)tuple->TupleData[4] << 8);
1184 +               sprom->pa0b2 = tuple->TupleData[5] |
1185 +                       ((u16)tuple->TupleData[6] << 8);
1186 +               sprom->itssi_a = tuple->TupleData[7];
1187 +               sprom->itssi_bg = tuple->TupleData[7];
1188 +               sprom->maxpwr_a = tuple->TupleData[8];
1189 +               sprom->maxpwr_bg = tuple->TupleData[8];
1190 +               break;
1191 +       case SSB_PCMCIA_CIS_OEMNAME:
1192 +               /* We ignore this. */
1193 +               break;
1194 +       case SSB_PCMCIA_CIS_CCODE:
1195 +               GOTO_ERROR_ON(tuple->TupleDataLen != 2,
1196 +                       "ccode tpl size");
1197 +               sprom->country_code = tuple->TupleData[1];
1198 +               break;
1199 +       case SSB_PCMCIA_CIS_ANTENNA:
1200 +               GOTO_ERROR_ON(tuple->TupleDataLen != 2,
1201 +                       "ant tpl size");
1202 +               sprom->ant_available_a = tuple->TupleData[1];
1203 +               sprom->ant_available_bg = tuple->TupleData[1];
1204 +               break;
1205 +       case SSB_PCMCIA_CIS_ANTGAIN:
1206 +               GOTO_ERROR_ON(tuple->TupleDataLen != 2,
1207 +                       "antg tpl size");
1208 +               sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1];
1209 +               sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1];
1210 +               sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1];
1211 +               sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1];
1212 +               sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1];
1213 +               sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1];
1214 +               sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1];
1215 +               sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1];
1216 +               break;
1217 +       case SSB_PCMCIA_CIS_BFLAGS:
1218 +               GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
1219 +                       (tuple->TupleDataLen != 5),
1220 +                       "bfl tpl size");
1221 +               sprom->boardflags_lo = tuple->TupleData[1] |
1222 +                       ((u16)tuple->TupleData[2] << 8);
1223 +               break;
1224 +       case SSB_PCMCIA_CIS_LEDS:
1225 +               GOTO_ERROR_ON(tuple->TupleDataLen != 5,
1226 +                       "leds tpl size");
1227 +               sprom->gpio0 = tuple->TupleData[1];
1228 +               sprom->gpio1 = tuple->TupleData[2];
1229 +               sprom->gpio2 = tuple->TupleData[3];
1230 +               sprom->gpio3 = tuple->TupleData[4];
1231 +               break;
1232 +       }
1233 +       return -ENOSPC; /* continue with next entry */
1234 +
1235 +error:
1236 +       ssb_printk(KERN_ERR PFX
1237 +                  "PCMCIA: Failed to fetch device invariants: %s\n",
1238 +                  error_description);
1239 +       return -ENODEV;
1240 +}
1241 +
1242 +
1243 +int ssb_pcmcia_get_invariants(struct ssb_bus *bus,
1244 +                             struct ssb_init_invariants *iv)
1245 +{
1246 +       struct ssb_sprom *sprom = &iv->sprom;
1247 +       int res;
1248 +
1249         memset(sprom, 0xFF, sizeof(*sprom));
1250         sprom->revision = 1;
1251         sprom->boardflags_lo = 0;
1252         sprom->boardflags_hi = 0;
1253  
1254         /* First fetch the MAC address. */
1255 -       memset(&tuple, 0, sizeof(tuple));
1256 -       tuple.DesiredTuple = CISTPL_FUNCE;
1257 -       tuple.TupleData = buf;
1258 -       tuple.TupleDataMax = sizeof(buf);
1259 -       res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
1260 -       GOTO_ERROR_ON(res != 0, "MAC first tpl");
1261 -       res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
1262 -       GOTO_ERROR_ON(res != 0, "MAC first tpl data");
1263 -       while (1) {
1264 -               GOTO_ERROR_ON(tuple.TupleDataLen < 1, "MAC tpl < 1");
1265 -               if (tuple.TupleData[0] == CISTPL_FUNCE_LAN_NODE_ID)
1266 -                       break;
1267 -               res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
1268 -               GOTO_ERROR_ON(res != 0, "MAC next tpl");
1269 -               res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
1270 -               GOTO_ERROR_ON(res != 0, "MAC next tpl data");
1271 +       res = pcmcia_loop_tuple(bus->host_pcmcia, CISTPL_FUNCE,
1272 +                               ssb_pcmcia_get_mac, sprom);
1273 +       if (res != 0) {
1274 +               ssb_printk(KERN_ERR PFX
1275 +                       "PCMCIA: Failed to fetch MAC address\n");
1276 +               return -ENODEV;
1277         }
1278 -       GOTO_ERROR_ON(tuple.TupleDataLen != ETH_ALEN + 2, "MAC tpl size");
1279 -       memcpy(sprom->il0mac, &tuple.TupleData[2], ETH_ALEN);
1280  
1281         /* Fetch the vendor specific tuples. */
1282 -       memset(&tuple, 0, sizeof(tuple));
1283 -       tuple.DesiredTuple = SSB_PCMCIA_CIS;
1284 -       tuple.TupleData = buf;
1285 -       tuple.TupleDataMax = sizeof(buf);
1286 -       res = pcmcia_get_first_tuple(bus->host_pcmcia, &tuple);
1287 -       GOTO_ERROR_ON(res != 0, "VEN first tpl");
1288 -       res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
1289 -       GOTO_ERROR_ON(res != 0, "VEN first tpl data");
1290 -       while (1) {
1291 -               GOTO_ERROR_ON(tuple.TupleDataLen < 1, "VEN tpl < 1");
1292 -               switch (tuple.TupleData[0]) {
1293 -               case SSB_PCMCIA_CIS_ID:
1294 -                       GOTO_ERROR_ON((tuple.TupleDataLen != 5) &&
1295 -                                     (tuple.TupleDataLen != 7),
1296 -                                     "id tpl size");
1297 -                       bi->vendor = tuple.TupleData[1] |
1298 -                              ((u16)tuple.TupleData[2] << 8);
1299 -                       break;
1300 -               case SSB_PCMCIA_CIS_BOARDREV:
1301 -                       GOTO_ERROR_ON(tuple.TupleDataLen != 2,
1302 -                                     "boardrev tpl size");
1303 -                       sprom->board_rev = tuple.TupleData[1];
1304 -                       break;
1305 -               case SSB_PCMCIA_CIS_PA:
1306 -                       GOTO_ERROR_ON((tuple.TupleDataLen != 9) &&
1307 -                                     (tuple.TupleDataLen != 10),
1308 -                                     "pa tpl size");
1309 -                       sprom->pa0b0 = tuple.TupleData[1] |
1310 -                                ((u16)tuple.TupleData[2] << 8);
1311 -                       sprom->pa0b1 = tuple.TupleData[3] |
1312 -                                ((u16)tuple.TupleData[4] << 8);
1313 -                       sprom->pa0b2 = tuple.TupleData[5] |
1314 -                                ((u16)tuple.TupleData[6] << 8);
1315 -                       sprom->itssi_a = tuple.TupleData[7];
1316 -                       sprom->itssi_bg = tuple.TupleData[7];
1317 -                       sprom->maxpwr_a = tuple.TupleData[8];
1318 -                       sprom->maxpwr_bg = tuple.TupleData[8];
1319 -                       break;
1320 -               case SSB_PCMCIA_CIS_OEMNAME:
1321 -                       /* We ignore this. */
1322 -                       break;
1323 -               case SSB_PCMCIA_CIS_CCODE:
1324 -                       GOTO_ERROR_ON(tuple.TupleDataLen != 2,
1325 -                                     "ccode tpl size");
1326 -                       sprom->country_code = tuple.TupleData[1];
1327 -                       break;
1328 -               case SSB_PCMCIA_CIS_ANTENNA:
1329 -                       GOTO_ERROR_ON(tuple.TupleDataLen != 2,
1330 -                                     "ant tpl size");
1331 -                       sprom->ant_available_a = tuple.TupleData[1];
1332 -                       sprom->ant_available_bg = tuple.TupleData[1];
1333 -                       break;
1334 -               case SSB_PCMCIA_CIS_ANTGAIN:
1335 -                       GOTO_ERROR_ON(tuple.TupleDataLen != 2,
1336 -                                     "antg tpl size");
1337 -                       sprom->antenna_gain.ghz24.a0 = tuple.TupleData[1];
1338 -                       sprom->antenna_gain.ghz24.a1 = tuple.TupleData[1];
1339 -                       sprom->antenna_gain.ghz24.a2 = tuple.TupleData[1];
1340 -                       sprom->antenna_gain.ghz24.a3 = tuple.TupleData[1];
1341 -                       sprom->antenna_gain.ghz5.a0 = tuple.TupleData[1];
1342 -                       sprom->antenna_gain.ghz5.a1 = tuple.TupleData[1];
1343 -                       sprom->antenna_gain.ghz5.a2 = tuple.TupleData[1];
1344 -                       sprom->antenna_gain.ghz5.a3 = tuple.TupleData[1];
1345 -                       break;
1346 -               case SSB_PCMCIA_CIS_BFLAGS:
1347 -                       GOTO_ERROR_ON((tuple.TupleDataLen != 3) &&
1348 -                                     (tuple.TupleDataLen != 5),
1349 -                                     "bfl tpl size");
1350 -                       sprom->boardflags_lo = tuple.TupleData[1] |
1351 -                                        ((u16)tuple.TupleData[2] << 8);
1352 -                       break;
1353 -               case SSB_PCMCIA_CIS_LEDS:
1354 -                       GOTO_ERROR_ON(tuple.TupleDataLen != 5,
1355 -                                     "leds tpl size");
1356 -                       sprom->gpio0 = tuple.TupleData[1];
1357 -                       sprom->gpio1 = tuple.TupleData[2];
1358 -                       sprom->gpio2 = tuple.TupleData[3];
1359 -                       sprom->gpio3 = tuple.TupleData[4];
1360 -                       break;
1361 -               }
1362 -               res = pcmcia_get_next_tuple(bus->host_pcmcia, &tuple);
1363 -               if (res == -ENOSPC)
1364 -                       break;
1365 -               GOTO_ERROR_ON(res != 0, "VEN next tpl");
1366 -               res = pcmcia_get_tuple_data(bus->host_pcmcia, &tuple);
1367 -               GOTO_ERROR_ON(res != 0, "VEN next tpl data");
1368 -       }
1369 +       res = pcmcia_loop_tuple(bus->host_pcmcia, SSB_PCMCIA_CIS,
1370 +                               ssb_pcmcia_do_get_invariants, iv);
1371 +       if ((res == 0) || (res == -ENOSPC))
1372 +               return 0;
1373  
1374 -       return 0;
1375 -error:
1376         ssb_printk(KERN_ERR PFX
1377 -                  "PCMCIA: Failed to fetch device invariants: %s\n",
1378 -                  error_description);
1379 +                       "PCMCIA: Failed to fetch device invariants\n");
1380         return -ENODEV;
1381  }
1382  
1383 --- a/drivers/ssb/scan.c
1384 +++ b/drivers/ssb/scan.c
1385 @@ -162,6 +162,8 @@ static u8 chipid_to_nrcores(u16 chipid)
1386  static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
1387                        u16 offset)
1388  {
1389 +       u32 lo, hi;
1390 +
1391         switch (bus->bustype) {
1392         case SSB_BUSTYPE_SSB:
1393                 offset += current_coreidx * SSB_CORE_SIZE;
1394 @@ -174,7 +176,12 @@ static u32 scan_read32(struct ssb_bus *b
1395                         offset -= 0x800;
1396                 } else
1397                         ssb_pcmcia_switch_segment(bus, 0);
1398 -               break;
1399 +               lo = readw(bus->mmio + offset);
1400 +               hi = readw(bus->mmio + offset + 2);
1401 +               return lo | (hi << 16);
1402 +       case SSB_BUSTYPE_SDIO:
1403 +               offset += current_coreidx * SSB_CORE_SIZE;
1404 +               return ssb_sdio_scan_read32(bus, offset);
1405         }
1406         return readl(bus->mmio + offset);
1407  }
1408 @@ -188,6 +195,8 @@ static int scan_switchcore(struct ssb_bu
1409                 return ssb_pci_switch_coreidx(bus, coreidx);
1410         case SSB_BUSTYPE_PCMCIA:
1411                 return ssb_pcmcia_switch_coreidx(bus, coreidx);
1412 +       case SSB_BUSTYPE_SDIO:
1413 +               return ssb_sdio_scan_switch_coreidx(bus, coreidx);
1414         }
1415         return 0;
1416  }
1417 @@ -206,6 +215,8 @@ void ssb_iounmap(struct ssb_bus *bus)
1418                 SSB_BUG_ON(1); /* Can't reach this code. */
1419  #endif
1420                 break;
1421 +       case SSB_BUSTYPE_SDIO:
1422 +               break;
1423         }
1424         bus->mmio = NULL;
1425         bus->mapped_device = NULL;
1426 @@ -230,6 +241,10 @@ static void __iomem *ssb_ioremap(struct
1427                 SSB_BUG_ON(1); /* Can't reach this code. */
1428  #endif
1429                 break;
1430 +       case SSB_BUSTYPE_SDIO:
1431 +               /* Nothing to ioremap in the SDIO case, just fake it */
1432 +               mmio = (void __iomem *)baseaddr;
1433 +               break;
1434         }
1435  
1436         return mmio;
1437 @@ -339,7 +354,7 @@ int ssb_bus_scan(struct ssb_bus *bus,
1438                 dev->bus = bus;
1439                 dev->ops = bus->ops;
1440  
1441 -               ssb_dprintk(KERN_INFO PFX
1442 +               printk(KERN_DEBUG PFX
1443                             "Core %d found: %s "
1444                             "(cc 0x%03X, rev 0x%02X, vendor 0x%04X)\n",
1445                             i, ssb_core_name(dev->id.coreid),
1446 @@ -407,6 +422,16 @@ int ssb_bus_scan(struct ssb_bus *bus,
1447                         bus->pcicore.dev = dev;
1448  #endif /* CONFIG_SSB_DRIVER_PCICORE */
1449                         break;
1450 +               case SSB_DEV_ETHERNET:
1451 +                       if (bus->bustype == SSB_BUSTYPE_PCI) {
1452 +                               if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
1453 +                                   (bus->host_pci->device & 0xFF00) == 0x4300) {
1454 +                                       /* This is a dangling ethernet core on a
1455 +                                        * wireless device. Ignore it. */
1456 +                                       continue;
1457 +                               }
1458 +                       }
1459 +                       break;
1460                 default:
1461                         break;
1462                 }
1463 --- /dev/null
1464 +++ b/drivers/ssb/sdio.c
1465 @@ -0,0 +1,610 @@
1466 +/*
1467 + * Sonics Silicon Backplane
1468 + * SDIO-Hostbus related functions
1469 + *
1470 + * Copyright 2009 Albert Herranz <albert_herranz@yahoo.es>
1471 + *
1472 + * Based on drivers/ssb/pcmcia.c
1473 + * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
1474 + * Copyright 2007-2008 Michael Buesch <mb@bu3sch.de>
1475 + *
1476 + * Licensed under the GNU/GPL. See COPYING for details.
1477 + *
1478 + */
1479 +
1480 +#include <linux/ssb/ssb.h>
1481 +#include <linux/delay.h>
1482 +#include <linux/io.h>
1483 +#include <linux/etherdevice.h>
1484 +#include <linux/mmc/sdio_func.h>
1485 +
1486 +#include "ssb_private.h"
1487 +
1488 +/* Define the following to 1 to enable a printk on each coreswitch. */
1489 +#define SSB_VERBOSE_SDIOCORESWITCH_DEBUG               0
1490 +
1491 +
1492 +/* Hardware invariants CIS tuples */
1493 +#define SSB_SDIO_CIS                   0x80
1494 +#define  SSB_SDIO_CIS_SROMREV          0x00
1495 +#define  SSB_SDIO_CIS_ID               0x01
1496 +#define  SSB_SDIO_CIS_BOARDREV         0x02
1497 +#define  SSB_SDIO_CIS_PA               0x03
1498 +#define   SSB_SDIO_CIS_PA_PA0B0_LO     0
1499 +#define   SSB_SDIO_CIS_PA_PA0B0_HI     1
1500 +#define   SSB_SDIO_CIS_PA_PA0B1_LO     2
1501 +#define   SSB_SDIO_CIS_PA_PA0B1_HI     3
1502 +#define   SSB_SDIO_CIS_PA_PA0B2_LO     4
1503 +#define   SSB_SDIO_CIS_PA_PA0B2_HI     5
1504 +#define   SSB_SDIO_CIS_PA_ITSSI                6
1505 +#define   SSB_SDIO_CIS_PA_MAXPOW       7
1506 +#define  SSB_SDIO_CIS_OEMNAME          0x04
1507 +#define  SSB_SDIO_CIS_CCODE            0x05
1508 +#define  SSB_SDIO_CIS_ANTENNA          0x06
1509 +#define  SSB_SDIO_CIS_ANTGAIN          0x07
1510 +#define  SSB_SDIO_CIS_BFLAGS           0x08
1511 +#define  SSB_SDIO_CIS_LEDS             0x09
1512 +
1513 +#define CISTPL_FUNCE_LAN_NODE_ID        0x04   /* same as in PCMCIA */
1514 +
1515 +
1516 +/*
1517 + * Function 1 miscellaneous registers.
1518 + *
1519 + * Definitions match src/include/sbsdio.h from the
1520 + * Android Open Source Project
1521 + * http://android.git.kernel.org/?p=platform/system/wlan/broadcom.git
1522 + *
1523 + */
1524 +#define SBSDIO_FUNC1_SBADDRLOW 0x1000a /* SB Address window Low (b15) */
1525 +#define SBSDIO_FUNC1_SBADDRMID 0x1000b /* SB Address window Mid (b23-b16) */
1526 +#define SBSDIO_FUNC1_SBADDRHIGH        0x1000c /* SB Address window High (b24-b31) */
1527 +
1528 +/* valid bits in SBSDIO_FUNC1_SBADDRxxx regs */
1529 +#define SBSDIO_SBADDRLOW_MASK  0x80    /* Valid address bits in SBADDRLOW */
1530 +#define SBSDIO_SBADDRMID_MASK  0xff    /* Valid address bits in SBADDRMID */
1531 +#define SBSDIO_SBADDRHIGH_MASK 0xff    /* Valid address bits in SBADDRHIGH */
1532 +
1533 +#define SBSDIO_SB_OFT_ADDR_MASK        0x7FFF  /* sb offset addr is <= 15 bits, 32k */
1534 +
1535 +/* REVISIT: this flag doesn't seem to matter */
1536 +#define SBSDIO_SB_ACCESS_2_4B_FLAG     0x8000  /* forces 32-bit SB access */
1537 +
1538 +
1539 +/*
1540 + * Address map within the SDIO function address space (128K).
1541 + *
1542 + *   Start   End     Description
1543 + *   ------- ------- ------------------------------------------
1544 + *   0x00000 0x0ffff selected backplane address window (64K)
1545 + *   0x10000 0x1ffff backplane control registers (max 64K)
1546 + *
1547 + * The current address window is configured by writing to registers
1548 + * SBADDRLOW, SBADDRMID and SBADDRHIGH.
1549 + *
1550 + * In order to access the contents of a 32-bit Silicon Backplane address
1551 + * the backplane address window must be first loaded with the highest
1552 + * 16 bits of the target address. Then, an access must be done to the
1553 + * SDIO function address space using the lower 15 bits of the address.
1554 + * Bit 15 of the address must be set when doing 32 bit accesses.
1555 + *
1556 + * 10987654321098765432109876543210
1557 + * WWWWWWWWWWWWWWWWW                 SB Address Window
1558 + *                 OOOOOOOOOOOOOOOO  Offset within SB Address Window
1559 + *                 a                 32-bit access flag
1560 + */
1561 +
1562 +
1563 +/*
1564 + * SSB I/O via SDIO.
1565 + *
1566 + * NOTE: SDIO address @addr is 17 bits long (SDIO address space is 128K).
1567 + */
1568 +
1569 +static inline struct device *ssb_sdio_dev(struct ssb_bus *bus)
1570 +{
1571 +       return &bus->host_sdio->dev;
1572 +}
1573 +
1574 +/* host claimed */
1575 +static int ssb_sdio_writeb(struct ssb_bus *bus, unsigned int addr, u8 val)
1576 +{
1577 +       int error = 0;
1578 +
1579 +       sdio_writeb(bus->host_sdio, val, addr, &error);
1580 +       if (unlikely(error)) {
1581 +               dev_dbg(ssb_sdio_dev(bus), "%08X <- %02x, error %d\n",
1582 +                       addr, val, error);
1583 +       }
1584 +
1585 +       return error;
1586 +}
1587 +
1588 +#if 0
1589 +static u8 ssb_sdio_readb(struct ssb_bus *bus, unsigned int addr)
1590 +{
1591 +       u8 val;
1592 +       int error = 0;
1593 +
1594 +       val = sdio_readb(bus->host_sdio, addr, &error);
1595 +       if (unlikely(error)) {
1596 +               dev_dbg(ssb_sdio_dev(bus), "%08X -> %02x, error %d\n",
1597 +                       addr, val, error);
1598 +       }
1599 +
1600 +       return val;
1601 +}
1602 +#endif
1603 +
1604 +/* host claimed */
1605 +static int ssb_sdio_set_sbaddr_window(struct ssb_bus *bus, u32 address)
1606 +{
1607 +       int error;
1608 +
1609 +       error = ssb_sdio_writeb(bus, SBSDIO_FUNC1_SBADDRLOW,
1610 +                               (address >> 8) & SBSDIO_SBADDRLOW_MASK);
1611 +       if (error)
1612 +               goto out;
1613 +       error = ssb_sdio_writeb(bus, SBSDIO_FUNC1_SBADDRMID,
1614 +                               (address >> 16) & SBSDIO_SBADDRMID_MASK);
1615 +       if (error)
1616 +               goto out;
1617 +       error = ssb_sdio_writeb(bus, SBSDIO_FUNC1_SBADDRHIGH,
1618 +                               (address >> 24) & SBSDIO_SBADDRHIGH_MASK);
1619 +       if (error)
1620 +               goto out;
1621 +       bus->sdio_sbaddr = address;
1622 +out:
1623 +       if (error) {
1624 +               dev_dbg(ssb_sdio_dev(bus), "failed to set address window"
1625 +                       " to 0x%08x, error %d\n", address, error);
1626 +       }
1627 +
1628 +       return error;
1629 +}
1630 +
1631 +/* for enumeration use only */
1632 +u32 ssb_sdio_scan_read32(struct ssb_bus *bus, u16 offset)
1633 +{
1634 +       u32 val;
1635 +       int error;
1636 +
1637 +       sdio_claim_host(bus->host_sdio);
1638 +       val = sdio_readl(bus->host_sdio, offset, &error);
1639 +       sdio_release_host(bus->host_sdio);
1640 +       if (unlikely(error)) {
1641 +               dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %08x, error %d\n",
1642 +                       bus->sdio_sbaddr >> 16, offset, val, error);
1643 +       }
1644 +
1645 +       return val;
1646 +}
1647 +
1648 +/* for enumeration use only */
1649 +int ssb_sdio_scan_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
1650 +{
1651 +       u32 sbaddr;
1652 +       int error;
1653 +
1654 +       sbaddr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
1655 +       sdio_claim_host(bus->host_sdio);
1656 +       error = ssb_sdio_set_sbaddr_window(bus, sbaddr);
1657 +       sdio_release_host(bus->host_sdio);
1658 +       if (error) {
1659 +               dev_err(ssb_sdio_dev(bus), "failed to switch to core %u,"
1660 +                       " error %d\n", coreidx, error);
1661 +               goto out;
1662 +       }
1663 +out:
1664 +       return error;
1665 +}
1666 +
1667 +/* host must be already claimed */
1668 +int ssb_sdio_switch_core(struct ssb_bus *bus, struct ssb_device *dev)
1669 +{
1670 +       u8 coreidx = dev->core_index;
1671 +       u32 sbaddr;
1672 +       int error = 0;
1673 +
1674 +       sbaddr = (coreidx * SSB_CORE_SIZE) + SSB_ENUM_BASE;
1675 +       if (unlikely(bus->sdio_sbaddr != sbaddr)) {
1676 +#if SSB_VERBOSE_SDIOCORESWITCH_DEBUG
1677 +               dev_info(ssb_sdio_dev(bus),
1678 +                          "switching to %s core, index %d\n",
1679 +                          ssb_core_name(dev->id.coreid), coreidx);
1680 +#endif
1681 +               error = ssb_sdio_set_sbaddr_window(bus, sbaddr);
1682 +               if (error) {
1683 +                       dev_dbg(ssb_sdio_dev(bus), "failed to switch to"
1684 +                               " core %u, error %d\n", coreidx, error);
1685 +                       goto out;
1686 +               }
1687 +               bus->mapped_device = dev;
1688 +       }
1689 +
1690 +out:
1691 +       return error;
1692 +}
1693 +
1694 +static u8 ssb_sdio_read8(struct ssb_device *dev, u16 offset)
1695 +{
1696 +       struct ssb_bus *bus = dev->bus;
1697 +       u8 val = 0xff;
1698 +       int error = 0;
1699 +
1700 +       sdio_claim_host(bus->host_sdio);
1701 +       if (unlikely(ssb_sdio_switch_core(bus, dev)))
1702 +               goto out;
1703 +       offset |= bus->sdio_sbaddr & 0xffff;
1704 +       offset &= SBSDIO_SB_OFT_ADDR_MASK;
1705 +       val = sdio_readb(bus->host_sdio, offset, &error);
1706 +       if (error) {
1707 +               dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %02x, error %d\n",
1708 +                       bus->sdio_sbaddr >> 16, offset, val, error);
1709 +       }
1710 +out:
1711 +       sdio_release_host(bus->host_sdio);
1712 +
1713 +       return val;
1714 +}
1715 +
1716 +static u16 ssb_sdio_read16(struct ssb_device *dev, u16 offset)
1717 +{
1718 +       struct ssb_bus *bus = dev->bus;
1719 +       u16 val = 0xffff;
1720 +       int error = 0;
1721 +
1722 +       sdio_claim_host(bus->host_sdio);
1723 +       if (unlikely(ssb_sdio_switch_core(bus, dev)))
1724 +               goto out;
1725 +       offset |= bus->sdio_sbaddr & 0xffff;
1726 +       offset &= SBSDIO_SB_OFT_ADDR_MASK;
1727 +       val = sdio_readw(bus->host_sdio, offset, &error);
1728 +       if (error) {
1729 +               dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %04x, error %d\n",
1730 +                       bus->sdio_sbaddr >> 16, offset, val, error);
1731 +       }
1732 +out:
1733 +       sdio_release_host(bus->host_sdio);
1734 +
1735 +       return val;
1736 +}
1737 +
1738 +static u32 ssb_sdio_read32(struct ssb_device *dev, u16 offset)
1739 +{
1740 +       struct ssb_bus *bus = dev->bus;
1741 +       u32 val = 0xffffffff;
1742 +       int error = 0;
1743 +
1744 +       sdio_claim_host(bus->host_sdio);
1745 +       if (unlikely(ssb_sdio_switch_core(bus, dev)))
1746 +               goto out;
1747 +       offset |= bus->sdio_sbaddr & 0xffff;
1748 +       offset &= SBSDIO_SB_OFT_ADDR_MASK;
1749 +       offset |= SBSDIO_SB_ACCESS_2_4B_FLAG;   /* 32 bit data access */
1750 +       val = sdio_readl(bus->host_sdio, offset, &error);
1751 +       if (error) {
1752 +               dev_dbg(ssb_sdio_dev(bus), "%04X:%04X > %08x, error %d\n",
1753 +                       bus->sdio_sbaddr >> 16, offset, val, error);
1754 +       }
1755 +out:
1756 +       sdio_release_host(bus->host_sdio);
1757 +
1758 +       return val;
1759 +}
1760 +
1761 +#ifdef CONFIG_SSB_BLOCKIO
1762 +static void ssb_sdio_block_read(struct ssb_device *dev, void *buffer,
1763 +                                 size_t count, u16 offset, u8 reg_width)
1764 +{
1765 +       size_t saved_count = count;
1766 +       struct ssb_bus *bus = dev->bus;
1767 +       int error = 0;
1768 +
1769 +       sdio_claim_host(bus->host_sdio);
1770 +       if (unlikely(ssb_sdio_switch_core(bus, dev))) {
1771 +               error = -EIO;
1772 +               memset(buffer, 0xff, count);
1773 +               goto err_out;
1774 +       }
1775 +       offset |= bus->sdio_sbaddr & 0xffff;
1776 +       offset &= SBSDIO_SB_OFT_ADDR_MASK;
1777 +
1778 +       switch (reg_width) {
1779 +       case sizeof(u8): {
1780 +               error = sdio_readsb(bus->host_sdio, buffer, offset, count);
1781 +               break;
1782 +       }
1783 +       case sizeof(u16): {
1784 +               SSB_WARN_ON(count & 1);
1785 +               error = sdio_readsb(bus->host_sdio, buffer, offset, count);
1786 +               break;
1787 +       }
1788 +       case sizeof(u32): {
1789 +               SSB_WARN_ON(count & 3);
1790 +               offset |= SBSDIO_SB_ACCESS_2_4B_FLAG;   /* 32 bit data access */
1791 +               error = sdio_readsb(bus->host_sdio, buffer, offset, count);
1792 +               break;
1793 +       }
1794 +       default:
1795 +               SSB_WARN_ON(1);
1796 +       }
1797 +       if (!error)
1798 +               goto out;
1799 +
1800 +err_out:
1801 +       dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%zu), error %d\n",
1802 +               bus->sdio_sbaddr >> 16, offset, reg_width, saved_count, error);
1803 +out:
1804 +       sdio_release_host(bus->host_sdio);
1805 +}
1806 +#endif /* CONFIG_SSB_BLOCKIO */
1807 +
1808 +static void ssb_sdio_write8(struct ssb_device *dev, u16 offset, u8 val)
1809 +{
1810 +       struct ssb_bus *bus = dev->bus;
1811 +       int error = 0;
1812 +
1813 +       sdio_claim_host(bus->host_sdio);
1814 +       if (unlikely(ssb_sdio_switch_core(bus, dev)))
1815 +               goto out;
1816 +       offset |= bus->sdio_sbaddr & 0xffff;
1817 +       offset &= SBSDIO_SB_OFT_ADDR_MASK;
1818 +       sdio_writeb(bus->host_sdio, val, offset, &error);
1819 +       if (error) {
1820 +               dev_dbg(ssb_sdio_dev(bus), "%04X:%04X < %02x, error %d\n",
1821 +                       bus->sdio_sbaddr >> 16, offset, val, error);
1822 +       }
1823 +out:
1824 +       sdio_release_host(bus->host_sdio);
1825 +}
1826 +
1827 +static void ssb_sdio_write16(struct ssb_device *dev, u16 offset, u16 val)
1828 +{
1829 +       struct ssb_bus *bus = dev->bus;
1830 +       int error = 0;
1831 +
1832 +       sdio_claim_host(bus->host_sdio);
1833 +       if (unlikely(ssb_sdio_switch_core(bus, dev)))
1834 +               goto out;
1835 +       offset |= bus->sdio_sbaddr & 0xffff;
1836 +       offset &= SBSDIO_SB_OFT_ADDR_MASK;
1837 +       sdio_writew(bus->host_sdio, val, offset, &error);
1838 +       if (error) {
1839 +               dev_dbg(ssb_sdio_dev(bus), "%04X:%04X < %04x, error %d\n",
1840 +                       bus->sdio_sbaddr >> 16, offset, val, error);
1841 +       }
1842 +out:
1843 +       sdio_release_host(bus->host_sdio);
1844 +}
1845 +
1846 +static void ssb_sdio_write32(struct ssb_device *dev, u16 offset, u32 val)
1847 +{
1848 +       struct ssb_bus *bus = dev->bus;
1849 +       int error = 0;
1850 +
1851 +       sdio_claim_host(bus->host_sdio);
1852 +       if (unlikely(ssb_sdio_switch_core(bus, dev)))
1853 +               goto out;
1854 +       offset |= bus->sdio_sbaddr & 0xffff;
1855 +       offset &= SBSDIO_SB_OFT_ADDR_MASK;
1856 +       offset |= SBSDIO_SB_ACCESS_2_4B_FLAG;   /* 32 bit data access */
1857 +       sdio_writel(bus->host_sdio, val, offset, &error);
1858 +       if (error) {
1859 +               dev_dbg(ssb_sdio_dev(bus), "%04X:%04X < %08x, error %d\n",
1860 +                       bus->sdio_sbaddr >> 16, offset, val, error);
1861 +       }
1862 +       if (bus->quirks & SSB_QUIRK_SDIO_READ_AFTER_WRITE32)
1863 +               sdio_readl(bus->host_sdio, 0, &error);
1864 +out:
1865 +       sdio_release_host(bus->host_sdio);
1866 +}
1867 +
1868 +#ifdef CONFIG_SSB_BLOCKIO
1869 +static void ssb_sdio_block_write(struct ssb_device *dev, const void *buffer,
1870 +                                  size_t count, u16 offset, u8 reg_width)
1871 +{
1872 +       size_t saved_count = count;
1873 +       struct ssb_bus *bus = dev->bus;
1874 +       int error = 0;
1875 +
1876 +       sdio_claim_host(bus->host_sdio);
1877 +       if (unlikely(ssb_sdio_switch_core(bus, dev))) {
1878 +               error = -EIO;
1879 +               memset((void *)buffer, 0xff, count);
1880 +               goto err_out;
1881 +       }
1882 +       offset |= bus->sdio_sbaddr & 0xffff;
1883 +       offset &= SBSDIO_SB_OFT_ADDR_MASK;
1884 +
1885 +       switch (reg_width) {
1886 +       case sizeof(u8):
1887 +               error = sdio_writesb(bus->host_sdio, offset,
1888 +                                    (void *)buffer, count);
1889 +               break;
1890 +       case sizeof(u16):
1891 +               SSB_WARN_ON(count & 1);
1892 +               error = sdio_writesb(bus->host_sdio, offset,
1893 +                                    (void *)buffer, count);
1894 +               break;
1895 +       case sizeof(u32):
1896 +               SSB_WARN_ON(count & 3);
1897 +               offset |= SBSDIO_SB_ACCESS_2_4B_FLAG;   /* 32 bit data access */
1898 +               error = sdio_writesb(bus->host_sdio, offset,
1899 +                                    (void *)buffer, count);
1900 +               break;
1901 +       default:
1902 +               SSB_WARN_ON(1);
1903 +       }
1904 +       if (!error)
1905 +               goto out;
1906 +
1907 +err_out:
1908 +       dev_dbg(ssb_sdio_dev(bus), "%04X:%04X (width=%u, len=%zu), error %d\n",
1909 +               bus->sdio_sbaddr >> 16, offset, reg_width, saved_count, error);
1910 +out:
1911 +       sdio_release_host(bus->host_sdio);
1912 +}
1913 +
1914 +#endif /* CONFIG_SSB_BLOCKIO */
1915 +
1916 +/* Not "static", as it's used in main.c */
1917 +const struct ssb_bus_ops ssb_sdio_ops = {
1918 +       .read8          = ssb_sdio_read8,
1919 +       .read16         = ssb_sdio_read16,
1920 +       .read32         = ssb_sdio_read32,
1921 +       .write8         = ssb_sdio_write8,
1922 +       .write16        = ssb_sdio_write16,
1923 +       .write32        = ssb_sdio_write32,
1924 +#ifdef CONFIG_SSB_BLOCKIO
1925 +       .block_read     = ssb_sdio_block_read,
1926 +       .block_write    = ssb_sdio_block_write,
1927 +#endif
1928 +};
1929 +
1930 +#define GOTO_ERROR_ON(condition, description) do {     \
1931 +       if (unlikely(condition)) {                      \
1932 +               error_description = description;        \
1933 +               goto error;                             \
1934 +       }                                               \
1935 +  } while (0)
1936 +
1937 +int ssb_sdio_get_invariants(struct ssb_bus *bus,
1938 +                           struct ssb_init_invariants *iv)
1939 +{
1940 +       struct ssb_sprom *sprom = &iv->sprom;
1941 +       struct ssb_boardinfo *bi = &iv->boardinfo;
1942 +       const char *error_description = "none";
1943 +       struct sdio_func_tuple *tuple;
1944 +       void *mac;
1945 +
1946 +       memset(sprom, 0xFF, sizeof(*sprom));
1947 +       sprom->boardflags_lo = 0;
1948 +       sprom->boardflags_hi = 0;
1949 +
1950 +       tuple = bus->host_sdio->tuples;
1951 +       while (tuple) {
1952 +               switch (tuple->code) {
1953 +               case 0x22: /* extended function */
1954 +                       switch (tuple->data[0]) {
1955 +                       case CISTPL_FUNCE_LAN_NODE_ID:
1956 +                               GOTO_ERROR_ON((tuple->size != 7) &&
1957 +                                             (tuple->data[1] != 6),
1958 +                                             "mac tpl size");
1959 +                               /* fetch the MAC address. */
1960 +                               mac = tuple->data + 2;
1961 +                               memcpy(sprom->il0mac, mac, ETH_ALEN);
1962 +                               memcpy(sprom->et1mac, mac, ETH_ALEN);
1963 +                               break;
1964 +                       default:
1965 +                               break;
1966 +                       }
1967 +                       break;
1968 +               case 0x80: /* vendor specific tuple */
1969 +                       switch (tuple->data[0]) {
1970 +                       case SSB_SDIO_CIS_SROMREV:
1971 +                               GOTO_ERROR_ON(tuple->size != 2,
1972 +                                             "sromrev tpl size");
1973 +                               sprom->revision = tuple->data[1];
1974 +                               break;
1975 +                       case SSB_SDIO_CIS_ID:
1976 +                               GOTO_ERROR_ON((tuple->size != 5) &&
1977 +                                             (tuple->size != 7),
1978 +                                             "id tpl size");
1979 +                               bi->vendor = tuple->data[1] |
1980 +                                            (tuple->data[2]<<8);
1981 +                               break;
1982 +                       case SSB_SDIO_CIS_BOARDREV:
1983 +                               GOTO_ERROR_ON(tuple->size != 2,
1984 +                                             "boardrev tpl size");
1985 +                               sprom->board_rev = tuple->data[1];
1986 +                               break;
1987 +                       case SSB_SDIO_CIS_PA:
1988 +                               GOTO_ERROR_ON((tuple->size != 9) &&
1989 +                                             (tuple->size != 10),
1990 +                                             "pa tpl size");
1991 +                               sprom->pa0b0 = tuple->data[1] |
1992 +                                        ((u16)tuple->data[2] << 8);
1993 +                               sprom->pa0b1 = tuple->data[3] |
1994 +                                        ((u16)tuple->data[4] << 8);
1995 +                               sprom->pa0b2 = tuple->data[5] |
1996 +                                        ((u16)tuple->data[6] << 8);
1997 +                               sprom->itssi_a = tuple->data[7];
1998 +                               sprom->itssi_bg = tuple->data[7];
1999 +                               sprom->maxpwr_a = tuple->data[8];
2000 +                               sprom->maxpwr_bg = tuple->data[8];
2001 +                               break;
2002 +                       case SSB_SDIO_CIS_OEMNAME:
2003 +                               /* Not present */
2004 +                               break;
2005 +                       case SSB_SDIO_CIS_CCODE:
2006 +                               GOTO_ERROR_ON(tuple->size != 2,
2007 +                                             "ccode tpl size");
2008 +                               sprom->country_code = tuple->data[1];
2009 +                               break;
2010 +                       case SSB_SDIO_CIS_ANTENNA:
2011 +                               GOTO_ERROR_ON(tuple->size != 2,
2012 +                                             "ant tpl size");
2013 +                               sprom->ant_available_a = tuple->data[1];
2014 +                               sprom->ant_available_bg = tuple->data[1];
2015 +                               break;
2016 +                       case SSB_SDIO_CIS_ANTGAIN:
2017 +                               GOTO_ERROR_ON(tuple->size != 2,
2018 +                                             "antg tpl size");
2019 +                               sprom->antenna_gain.ghz24.a0 = tuple->data[1];
2020 +                               sprom->antenna_gain.ghz24.a1 = tuple->data[1];
2021 +                               sprom->antenna_gain.ghz24.a2 = tuple->data[1];
2022 +                               sprom->antenna_gain.ghz24.a3 = tuple->data[1];
2023 +                               sprom->antenna_gain.ghz5.a0 = tuple->data[1];
2024 +                               sprom->antenna_gain.ghz5.a1 = tuple->data[1];
2025 +                               sprom->antenna_gain.ghz5.a2 = tuple->data[1];
2026 +                               sprom->antenna_gain.ghz5.a3 = tuple->data[1];
2027 +                               break;
2028 +                       case SSB_SDIO_CIS_BFLAGS:
2029 +                               GOTO_ERROR_ON((tuple->size != 3) &&
2030 +                                             (tuple->size != 5),
2031 +                                             "bfl tpl size");
2032 +                               sprom->boardflags_lo = tuple->data[1] |
2033 +                                                ((u16)tuple->data[2] << 8);
2034 +                               break;
2035 +                       case SSB_SDIO_CIS_LEDS:
2036 +                               GOTO_ERROR_ON(tuple->size != 5,
2037 +                                             "leds tpl size");
2038 +                               sprom->gpio0 = tuple->data[1];
2039 +                               sprom->gpio1 = tuple->data[2];
2040 +                               sprom->gpio2 = tuple->data[3];
2041 +                               sprom->gpio3 = tuple->data[4];
2042 +                               break;
2043 +                       default:
2044 +                               break;
2045 +                       }
2046 +                       break;
2047 +               default:
2048 +                       break;
2049 +               }
2050 +               tuple = tuple->next;
2051 +       }
2052 +
2053 +       return 0;
2054 +error:
2055 +       dev_err(ssb_sdio_dev(bus), "failed to fetch device invariants: %s\n",
2056 +               error_description);
2057 +       return -ENODEV;
2058 +}
2059 +
2060 +void ssb_sdio_exit(struct ssb_bus *bus)
2061 +{
2062 +       if (bus->bustype != SSB_BUSTYPE_SDIO)
2063 +               return;
2064 +       /* Nothing to do here. */
2065 +}
2066 +
2067 +int ssb_sdio_init(struct ssb_bus *bus)
2068 +{
2069 +       if (bus->bustype != SSB_BUSTYPE_SDIO)
2070 +               return 0;
2071 +
2072 +       bus->sdio_sbaddr = ~0;
2073 +
2074 +       return 0;
2075 +}
2076 --- a/drivers/ssb/sprom.c
2077 +++ b/drivers/ssb/sprom.c
2078 @@ -14,6 +14,7 @@
2079  #include "ssb_private.h"
2080  
2081  #include <linux/ctype.h>
2082 +#include <linux/slab.h>
2083  
2084  
2085  static const struct ssb_sprom *fallback_sprom;
2086 @@ -102,6 +103,7 @@ ssize_t ssb_attr_sprom_store(struct ssb_
2087         u16 *sprom;
2088         int res = 0, err = -ENOMEM;
2089         size_t sprom_size_words = bus->sprom_size;
2090 +       struct ssb_freeze_context freeze;
2091  
2092         sprom = kcalloc(bus->sprom_size, sizeof(u16), GFP_KERNEL);
2093         if (!sprom)
2094 @@ -123,18 +125,13 @@ ssize_t ssb_attr_sprom_store(struct ssb_
2095         err = -ERESTARTSYS;
2096         if (mutex_lock_interruptible(&bus->sprom_mutex))
2097                 goto out_kfree;
2098 -       err = ssb_devices_freeze(bus);
2099 -       if (err == -EOPNOTSUPP) {
2100 -               ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze devices. "
2101 -                          "No suspend support. Is CONFIG_PM enabled?\n");
2102 -               goto out_unlock;
2103 -       }
2104 +       err = ssb_devices_freeze(bus, &freeze);
2105         if (err) {
2106                 ssb_printk(KERN_ERR PFX "SPROM write: Could not freeze all devices\n");
2107                 goto out_unlock;
2108         }
2109         res = sprom_write(bus, sprom);
2110 -       err = ssb_devices_thaw(bus);
2111 +       err = ssb_devices_thaw(&freeze);
2112         if (err)
2113                 ssb_printk(KERN_ERR PFX "SPROM write: Could not thaw all devices\n");
2114  out_unlock:
2115 @@ -179,3 +176,18 @@ const struct ssb_sprom *ssb_get_fallback
2116  {
2117         return fallback_sprom;
2118  }
2119 +
2120 +/* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */
2121 +bool ssb_is_sprom_available(struct ssb_bus *bus)
2122 +{
2123 +       /* status register only exists on chipcomon rev >= 11 and we need check
2124 +          for >= 31 only */
2125 +       /* this routine differs from specs as we do not access SPROM directly
2126 +          on PCMCIA */
2127 +       if (bus->bustype == SSB_BUSTYPE_PCI &&
2128 +           bus->chipco.dev &&  /* can be unavailible! */
2129 +           bus->chipco.dev->id.revision >= 31)
2130 +               return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM;
2131 +
2132 +       return true;
2133 +}
2134 --- a/drivers/ssb/ssb_private.h
2135 +++ b/drivers/ssb/ssb_private.h
2136 @@ -114,6 +114,46 @@ static inline int ssb_pcmcia_init(struct
2137  }
2138  #endif /* CONFIG_SSB_PCMCIAHOST */
2139  
2140 +/* sdio.c */
2141 +#ifdef CONFIG_SSB_SDIOHOST
2142 +extern int ssb_sdio_get_invariants(struct ssb_bus *bus,
2143 +                                    struct ssb_init_invariants *iv);
2144 +
2145 +extern u32 ssb_sdio_scan_read32(struct ssb_bus *bus, u16 offset);
2146 +extern int ssb_sdio_switch_core(struct ssb_bus *bus, struct ssb_device *dev);
2147 +extern int ssb_sdio_scan_switch_coreidx(struct ssb_bus *bus, u8 coreidx);
2148 +extern int ssb_sdio_hardware_setup(struct ssb_bus *bus);
2149 +extern void ssb_sdio_exit(struct ssb_bus *bus);
2150 +extern int ssb_sdio_init(struct ssb_bus *bus);
2151 +
2152 +extern const struct ssb_bus_ops ssb_sdio_ops;
2153 +#else /* CONFIG_SSB_SDIOHOST */
2154 +static inline u32 ssb_sdio_scan_read32(struct ssb_bus *bus, u16 offset)
2155 +{
2156 +       return 0;
2157 +}
2158 +static inline int ssb_sdio_switch_core(struct ssb_bus *bus,
2159 +                                        struct ssb_device *dev)
2160 +{
2161 +       return 0;
2162 +}
2163 +static inline int ssb_sdio_scan_switch_coreidx(struct ssb_bus *bus, u8 coreidx)
2164 +{
2165 +       return 0;
2166 +}
2167 +static inline int ssb_sdio_hardware_setup(struct ssb_bus *bus)
2168 +{
2169 +       return 0;
2170 +}
2171 +static inline void ssb_sdio_exit(struct ssb_bus *bus)
2172 +{
2173 +}
2174 +static inline int ssb_sdio_init(struct ssb_bus *bus)
2175 +{
2176 +       return 0;
2177 +}
2178 +#endif /* CONFIG_SSB_SDIOHOST */
2179 +
2180  
2181  /* scan.c */
2182  extern const char *ssb_core_name(u16 coreid);
2183 @@ -136,19 +176,27 @@ extern const struct ssb_sprom *ssb_get_f
2184  
2185  /* core.c */
2186  extern u32 ssb_calc_clock_rate(u32 plltype, u32 n, u32 m);
2187 -extern int ssb_devices_freeze(struct ssb_bus *bus);
2188 -extern int ssb_devices_thaw(struct ssb_bus *bus);
2189  extern struct ssb_bus *ssb_pci_dev_to_bus(struct pci_dev *pdev);
2190  int ssb_for_each_bus_call(unsigned long data,
2191                           int (*func)(struct ssb_bus *bus, unsigned long data));
2192  extern struct ssb_bus *ssb_pcmcia_dev_to_bus(struct pcmcia_device *pdev);
2193  
2194 +struct ssb_freeze_context {
2195 +       /* Pointer to the bus */
2196 +       struct ssb_bus *bus;
2197 +       /* Boolean list to indicate whether a device is frozen on this bus. */
2198 +       bool device_frozen[SSB_MAX_NR_CORES];
2199 +};
2200 +extern int ssb_devices_freeze(struct ssb_bus *bus, struct ssb_freeze_context *ctx);
2201 +extern int ssb_devices_thaw(struct ssb_freeze_context *ctx);
2202 +
2203 +
2204  
2205  /* b43_pci_bridge.c */
2206  #ifdef CONFIG_SSB_B43_PCI_BRIDGE
2207  extern int __init b43_pci_ssb_bridge_init(void);
2208  extern void __exit b43_pci_ssb_bridge_exit(void);
2209 -#else /* CONFIG_SSB_B43_PCI_BRIDGR */
2210 +#else /* CONFIG_SSB_B43_PCI_BRIDGE */
2211  static inline int b43_pci_ssb_bridge_init(void)
2212  {
2213         return 0;
2214 @@ -156,6 +204,6 @@ static inline int b43_pci_ssb_bridge_ini
2215  static inline void b43_pci_ssb_bridge_exit(void)
2216  {
2217  }
2218 -#endif /* CONFIG_SSB_PCIHOST */
2219 +#endif /* CONFIG_SSB_B43_PCI_BRIDGE */
2220  
2221  #endif /* LINUX_SSB_PRIVATE_H_ */
2222 --- a/include/linux/pci_ids.h
2223 +++ b/include/linux/pci_ids.h
2224 @@ -2017,6 +2017,7 @@
2225  #define PCI_DEVICE_ID_AFAVLAB_P030     0x2182
2226  #define PCI_SUBDEVICE_ID_AFAVLAB_P061          0x2150
2227  
2228 +#define PCI_VENDOR_ID_BCM_GVC          0x14a4
2229  #define PCI_VENDOR_ID_BROADCOM         0x14e4
2230  #define PCI_DEVICE_ID_TIGON3_5752      0x1600
2231  #define PCI_DEVICE_ID_TIGON3_5752M     0x1601
2232 --- a/include/linux/ssb/ssb.h
2233 +++ b/include/linux/ssb/ssb.h
2234 @@ -27,24 +27,58 @@ struct ssb_sprom {
2235         u8 et1mdcport;          /* MDIO for enet1 */
2236         u8 board_rev;           /* Board revision number from SPROM. */
2237         u8 country_code;        /* Country Code */
2238 -       u8 ant_available_a;     /* A-PHY antenna available bits (up to 4) */
2239 -       u8 ant_available_bg;    /* B/G-PHY antenna available bits (up to 4) */
2240 +       u8 ant_available_a;     /* 2GHz antenna available bits (up to 4) */
2241 +       u8 ant_available_bg;    /* 5GHz antenna available bits (up to 4) */
2242         u16 pa0b0;
2243         u16 pa0b1;
2244         u16 pa0b2;
2245         u16 pa1b0;
2246         u16 pa1b1;
2247         u16 pa1b2;
2248 +       u16 pa1lob0;
2249 +       u16 pa1lob1;
2250 +       u16 pa1lob2;
2251 +       u16 pa1hib0;
2252 +       u16 pa1hib1;
2253 +       u16 pa1hib2;
2254         u8 gpio0;               /* GPIO pin 0 */
2255         u8 gpio1;               /* GPIO pin 1 */
2256         u8 gpio2;               /* GPIO pin 2 */
2257         u8 gpio3;               /* GPIO pin 3 */
2258 -       u16 maxpwr_a;           /* A-PHY Amplifier Max Power (in dBm Q5.2) */
2259 -       u16 maxpwr_bg;          /* B/G-PHY Amplifier Max Power (in dBm Q5.2) */
2260 +       u16 maxpwr_bg;          /* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
2261 +       u16 maxpwr_al;          /* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
2262 +       u16 maxpwr_a;           /* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
2263 +       u16 maxpwr_ah;          /* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
2264         u8 itssi_a;             /* Idle TSSI Target for A-PHY */
2265         u8 itssi_bg;            /* Idle TSSI Target for B/G-PHY */
2266 -       u16 boardflags_lo;      /* Boardflags (low 16 bits) */
2267 -       u16 boardflags_hi;      /* Boardflags (high 16 bits) */
2268 +       u8 tri2g;               /* 2.4GHz TX isolation */
2269 +       u8 tri5gl;              /* 5.2GHz TX isolation */
2270 +       u8 tri5g;               /* 5.3GHz TX isolation */
2271 +       u8 tri5gh;              /* 5.8GHz TX isolation */
2272 +       u8 txpid2g[4];          /* 2GHz TX power index */
2273 +       u8 txpid5gl[4];         /* 4.9 - 5.1GHz TX power index */
2274 +       u8 txpid5g[4];          /* 5.1 - 5.5GHz TX power index */
2275 +       u8 txpid5gh[4];         /* 5.5 - ...GHz TX power index */
2276 +       u8 rxpo2g;              /* 2GHz RX power offset */
2277 +       u8 rxpo5g;              /* 5GHz RX power offset */
2278 +       u8 rssisav2g;           /* 2GHz RSSI params */
2279 +       u8 rssismc2g;
2280 +       u8 rssismf2g;
2281 +       u8 bxa2g;               /* 2GHz BX arch */
2282 +       u8 rssisav5g;           /* 5GHz RSSI params */
2283 +       u8 rssismc5g;
2284 +       u8 rssismf5g;
2285 +       u8 bxa5g;               /* 5GHz BX arch */
2286 +       u16 cck2gpo;            /* CCK power offset */
2287 +       u32 ofdm2gpo;           /* 2.4GHz OFDM power offset */
2288 +       u32 ofdm5glpo;          /* 5.2GHz OFDM power offset */
2289 +       u32 ofdm5gpo;           /* 5.3GHz OFDM power offset */
2290 +       u32 ofdm5ghpo;          /* 5.8GHz OFDM power offset */
2291 +       u16 boardflags_lo;      /* Board flags (bits 0-15) */
2292 +       u16 boardflags_hi;      /* Board flags (bits 16-31) */
2293 +       u16 boardflags2_lo;     /* Board flags (bits 32-47) */
2294 +       u16 boardflags2_hi;     /* Board flags (bits 48-63) */
2295 +       /* TODO store board flags in a single u64 */
2296  
2297         /* Antenna gain values for up to 4 antennas
2298          * on each band. Values in dBm/4 (Q5.2). Negative gain means the
2299 @@ -58,7 +92,7 @@ struct ssb_sprom {
2300                 } ghz5;         /* 5GHz band */
2301         } antenna_gain;
2302  
2303 -       /* TODO - add any parameters needed from rev 2, 3, or 4 SPROMs */
2304 +       /* TODO - add any parameters needed from rev 2, 3, 4, 5 or 8 SPROMs */
2305  };
2306  
2307  /* Information about the PCB the circuitry is soldered on. */
2308 @@ -137,7 +171,7 @@ struct ssb_device {
2309          * is an optimization. */
2310         const struct ssb_bus_ops *ops;
2311  
2312 -       struct device *dev;
2313 +       struct device *dev, *dma_dev;
2314  
2315         struct ssb_bus *bus;
2316         struct ssb_device_id id;
2317 @@ -208,6 +242,7 @@ enum ssb_bustype {
2318         SSB_BUSTYPE_SSB,        /* This SSB bus is the system bus */
2319         SSB_BUSTYPE_PCI,        /* SSB is connected to PCI bus */
2320         SSB_BUSTYPE_PCMCIA,     /* SSB is connected to PCMCIA bus */
2321 +       SSB_BUSTYPE_SDIO,       /* SSB is connected to SDIO bus */
2322  };
2323  
2324  /* board_vendor */
2325 @@ -238,20 +273,33 @@ struct ssb_bus {
2326  
2327         const struct ssb_bus_ops *ops;
2328  
2329 -       /* The core in the basic address register window. (PCI bus only) */
2330 +       /* The core currently mapped into the MMIO window.
2331 +        * Not valid on all host-buses. So don't use outside of SSB. */
2332         struct ssb_device *mapped_device;
2333 -       /* Currently mapped PCMCIA segment. (bustype == SSB_BUSTYPE_PCMCIA only) */
2334 -       u8 mapped_pcmcia_seg;
2335 +       union {
2336 +               /* Currently mapped PCMCIA segment. (bustype == SSB_BUSTYPE_PCMCIA only) */
2337 +               u8 mapped_pcmcia_seg;
2338 +               /* Current SSB base address window for SDIO. */
2339 +               u32 sdio_sbaddr;
2340 +       };
2341         /* Lock for core and segment switching.
2342          * On PCMCIA-host busses this is used to protect the whole MMIO access. */
2343         spinlock_t bar_lock;
2344  
2345 -       /* The bus this backplane is running on. */
2346 +       /* The host-bus this backplane is running on. */
2347         enum ssb_bustype bustype;
2348 -       /* Pointer to the PCI bus (only valid if bustype == SSB_BUSTYPE_PCI). */
2349 -       struct pci_dev *host_pci;
2350 -       /* Pointer to the PCMCIA device (only if bustype == SSB_BUSTYPE_PCMCIA). */
2351 -       struct pcmcia_device *host_pcmcia;
2352 +       /* Pointers to the host-bus. Check bustype before using any of these pointers. */
2353 +       union {
2354 +               /* Pointer to the PCI bus (only valid if bustype == SSB_BUSTYPE_PCI). */
2355 +               struct pci_dev *host_pci;
2356 +               /* Pointer to the PCMCIA device (only if bustype == SSB_BUSTYPE_PCMCIA). */
2357 +               struct pcmcia_device *host_pcmcia;
2358 +               /* Pointer to the SDIO device (only if bustype == SSB_BUSTYPE_SDIO). */
2359 +               struct sdio_func *host_sdio;
2360 +       };
2361 +
2362 +       /* See enum ssb_quirks */
2363 +       unsigned int quirks;
2364  
2365  #ifdef CONFIG_SSB_SPROM
2366         /* Mutex to protect the SPROM writing. */
2367 @@ -261,6 +309,7 @@ struct ssb_bus {
2368         /* ID information about the Chip. */
2369         u16 chip_id;
2370         u16 chip_rev;
2371 +       u16 sprom_offset;
2372         u16 sprom_size;         /* number of words in sprom */
2373         u8 chip_package;
2374  
2375 @@ -306,6 +355,11 @@ struct ssb_bus {
2376  #endif /* DEBUG */
2377  };
2378  
2379 +enum ssb_quirks {
2380 +       /* SDIO connected card requires performing a read after writing a 32-bit value */
2381 +       SSB_QUIRK_SDIO_READ_AFTER_WRITE32       = (1 << 0),
2382 +};
2383 +
2384  /* The initialization-invariants. */
2385  struct ssb_init_invariants {
2386         /* Versioning information about the PCB. */
2387 @@ -336,9 +390,18 @@ extern int ssb_bus_pcmciabus_register(st
2388                                       struct pcmcia_device *pcmcia_dev,
2389                                       unsigned long baseaddr);
2390  #endif /* CONFIG_SSB_PCMCIAHOST */
2391 +#ifdef CONFIG_SSB_SDIOHOST
2392 +extern int ssb_bus_sdiobus_register(struct ssb_bus *bus,
2393 +                                   struct sdio_func *sdio_func,
2394 +                                   unsigned int quirks);
2395 +#endif /* CONFIG_SSB_SDIOHOST */
2396 +
2397  
2398  extern void ssb_bus_unregister(struct ssb_bus *bus);
2399  
2400 +/* Does the device have an SPROM? */
2401 +extern bool ssb_is_sprom_available(struct ssb_bus *bus);
2402 +
2403  /* Set a fallback SPROM.
2404   * See kdoc at the function definition for complete documentation. */
2405  extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom);
2406 --- a/include/linux/ssb/ssb_driver_chipcommon.h
2407 +++ b/include/linux/ssb/ssb_driver_chipcommon.h
2408 @@ -53,6 +53,7 @@
2409  #define  SSB_CHIPCO_CAP_64BIT          0x08000000      /* 64-bit Backplane */
2410  #define  SSB_CHIPCO_CAP_PMU            0x10000000      /* PMU available (rev >= 20) */
2411  #define  SSB_CHIPCO_CAP_ECI            0x20000000      /* ECI available (rev >= 20) */
2412 +#define  SSB_CHIPCO_CAP_SPROM          0x40000000      /* SPROM present */
2413  #define SSB_CHIPCO_CORECTL             0x0008
2414  #define  SSB_CHIPCO_CORECTL_UARTCLK0   0x00000001      /* Drive UART with internal clock */
2415  #define         SSB_CHIPCO_CORECTL_SE          0x00000002      /* sync clk out enable (corerev >= 3) */
2416 @@ -385,6 +386,7 @@
2417  
2418  
2419  /** Chip specific Chip-Status register contents. */
2420 +#define SSB_CHIPCO_CHST_4322_SPROM_EXISTS      0x00000040 /* SPROM present */
2421  #define SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL     0x00000003
2422  #define SSB_CHIPCO_CHST_4325_DEFCIS_SEL                0 /* OTP is powered up, use def. CIS, no SPROM */
2423  #define SSB_CHIPCO_CHST_4325_SPROM_SEL         1 /* OTP is powered up, SPROM is present */
2424 @@ -398,6 +400,18 @@
2425  #define SSB_CHIPCO_CHST_4325_RCAL_VALUE_SHIFT  4
2426  #define SSB_CHIPCO_CHST_4325_PMUTOP_2B                 0x00000200 /* 1 for 2b, 0 for to 2a */
2427  
2428 +/** Macros to determine SPROM presence based on Chip-Status register. */
2429 +#define SSB_CHIPCO_CHST_4312_SPROM_PRESENT(status) \
2430 +       ((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \
2431 +               SSB_CHIPCO_CHST_4325_OTP_SEL)
2432 +#define SSB_CHIPCO_CHST_4322_SPROM_PRESENT(status) \
2433 +       (status & SSB_CHIPCO_CHST_4322_SPROM_EXISTS)
2434 +#define SSB_CHIPCO_CHST_4325_SPROM_PRESENT(status) \
2435 +       (((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \
2436 +               SSB_CHIPCO_CHST_4325_DEFCIS_SEL) && \
2437 +        ((status & SSB_CHIPCO_CHST_4325_SPROM_OTP_SEL) != \
2438 +               SSB_CHIPCO_CHST_4325_OTP_SEL))
2439 +
2440  
2441  
2442  /** Clockcontrol masks and values **/
2443 @@ -564,6 +578,7 @@ struct ssb_chipcommon_pmu {
2444  struct ssb_chipcommon {
2445         struct ssb_device *dev;
2446         u32 capabilities;
2447 +       u32 status;
2448         /* Fast Powerup Delay constant */
2449         u16 fast_pwrup_delay;
2450         struct ssb_chipcommon_pmu pmu;
2451 @@ -629,5 +644,15 @@ extern int ssb_chipco_serial_init(struct
2452  /* PMU support */
2453  extern void ssb_pmu_init(struct ssb_chipcommon *cc);
2454  
2455 +enum ssb_pmu_ldo_volt_id {
2456 +       LDO_PAREF = 0,
2457 +       LDO_VOLT1,
2458 +       LDO_VOLT2,
2459 +       LDO_VOLT3,
2460 +};
2461 +
2462 +void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
2463 +                            enum ssb_pmu_ldo_volt_id id, u32 voltage);
2464 +void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on);
2465  
2466  #endif /* LINUX_SSB_CHIPCO_H_ */
2467 --- a/include/linux/ssb/ssb_regs.h
2468 +++ b/include/linux/ssb/ssb_regs.h
2469 @@ -85,6 +85,8 @@
2470  #define  SSB_IMSTATE_AP_RSV    0x00000030 /* Reserved */
2471  #define  SSB_IMSTATE_IBE       0x00020000 /* In Band Error */
2472  #define  SSB_IMSTATE_TO                0x00040000 /* Timeout */
2473 +#define  SSB_IMSTATE_BUSY      0x01800000 /* Busy (Backplane rev >= 2.3 only) */
2474 +#define  SSB_IMSTATE_REJECT    0x02000000 /* Reject (Backplane rev >= 2.3 only) */
2475  #define SSB_INTVEC             0x0F94     /* SB Interrupt Mask */
2476  #define  SSB_INTVEC_PCI                0x00000001 /* Enable interrupts for PCI */
2477  #define  SSB_INTVEC_ENET0      0x00000002 /* Enable interrupts for enet 0 */
2478 @@ -162,7 +164,7 @@
2479  
2480  /* SPROM shadow area. If not otherwise noted, fields are
2481   * two bytes wide. Note that the SPROM can _only_ be read
2482 - * in two-byte quantinies.
2483 + * in two-byte quantities.
2484   */
2485  #define SSB_SPROMSIZE_WORDS            64
2486  #define SSB_SPROMSIZE_BYTES            (SSB_SPROMSIZE_WORDS * sizeof(u16))
2487 @@ -170,26 +172,27 @@
2488  #define SSB_SPROMSIZE_WORDS_R4         220
2489  #define SSB_SPROMSIZE_BYTES_R123       (SSB_SPROMSIZE_WORDS_R123 * sizeof(u16))
2490  #define SSB_SPROMSIZE_BYTES_R4         (SSB_SPROMSIZE_WORDS_R4 * sizeof(u16))
2491 -#define SSB_SPROM_BASE                 0x1000
2492 -#define SSB_SPROM_REVISION             0x107E
2493 +#define SSB_SPROM_BASE1                        0x1000
2494 +#define SSB_SPROM_BASE31               0x0800
2495 +#define SSB_SPROM_REVISION             0x007E
2496  #define  SSB_SPROM_REVISION_REV                0x00FF  /* SPROM Revision number */
2497  #define  SSB_SPROM_REVISION_CRC                0xFF00  /* SPROM CRC8 value */
2498  #define  SSB_SPROM_REVISION_CRC_SHIFT  8
2499  
2500  /* SPROM Revision 1 */
2501 -#define SSB_SPROM1_SPID                        0x1004  /* Subsystem Product ID for PCI */
2502 -#define SSB_SPROM1_SVID                        0x1006  /* Subsystem Vendor ID for PCI */
2503 -#define SSB_SPROM1_PID                 0x1008  /* Product ID for PCI */
2504 -#define SSB_SPROM1_IL0MAC              0x1048  /* 6 bytes MAC address for 802.11b/g */
2505 -#define SSB_SPROM1_ET0MAC              0x104E  /* 6 bytes MAC address for Ethernet */
2506 -#define SSB_SPROM1_ET1MAC              0x1054  /* 6 bytes MAC address for 802.11a */
2507 -#define SSB_SPROM1_ETHPHY              0x105A  /* Ethernet PHY settings */
2508 +#define SSB_SPROM1_SPID                        0x0004  /* Subsystem Product ID for PCI */
2509 +#define SSB_SPROM1_SVID                        0x0006  /* Subsystem Vendor ID for PCI */
2510 +#define SSB_SPROM1_PID                 0x0008  /* Product ID for PCI */
2511 +#define SSB_SPROM1_IL0MAC              0x0048  /* 6 bytes MAC address for 802.11b/g */
2512 +#define SSB_SPROM1_ET0MAC              0x004E  /* 6 bytes MAC address for Ethernet */
2513 +#define SSB_SPROM1_ET1MAC              0x0054  /* 6 bytes MAC address for 802.11a */
2514 +#define SSB_SPROM1_ETHPHY              0x005A  /* Ethernet PHY settings */
2515  #define  SSB_SPROM1_ETHPHY_ET0A                0x001F  /* MII Address for enet0 */
2516  #define  SSB_SPROM1_ETHPHY_ET1A                0x03E0  /* MII Address for enet1 */
2517  #define  SSB_SPROM1_ETHPHY_ET1A_SHIFT  5
2518  #define  SSB_SPROM1_ETHPHY_ET0M                (1<<14) /* MDIO for enet0 */
2519  #define  SSB_SPROM1_ETHPHY_ET1M                (1<<15) /* MDIO for enet1 */
2520 -#define SSB_SPROM1_BINF                        0x105C  /* Board info */
2521 +#define SSB_SPROM1_BINF                        0x005C  /* Board info */
2522  #define  SSB_SPROM1_BINF_BREV          0x00FF  /* Board Revision */
2523  #define  SSB_SPROM1_BINF_CCODE         0x0F00  /* Country Code */
2524  #define  SSB_SPROM1_BINF_CCODE_SHIFT   8
2525 @@ -197,63 +200,63 @@
2526  #define  SSB_SPROM1_BINF_ANTBG_SHIFT   12
2527  #define  SSB_SPROM1_BINF_ANTA          0xC000  /* Available A-PHY antennas */
2528  #define  SSB_SPROM1_BINF_ANTA_SHIFT    14
2529 -#define SSB_SPROM1_PA0B0               0x105E
2530 -#define SSB_SPROM1_PA0B1               0x1060
2531 -#define SSB_SPROM1_PA0B2               0x1062
2532 -#define SSB_SPROM1_GPIOA               0x1064  /* General Purpose IO pins 0 and 1 */
2533 +#define SSB_SPROM1_PA0B0               0x005E
2534 +#define SSB_SPROM1_PA0B1               0x0060
2535 +#define SSB_SPROM1_PA0B2               0x0062
2536 +#define SSB_SPROM1_GPIOA               0x0064  /* General Purpose IO pins 0 and 1 */
2537  #define  SSB_SPROM1_GPIOA_P0           0x00FF  /* Pin 0 */
2538  #define  SSB_SPROM1_GPIOA_P1           0xFF00  /* Pin 1 */
2539  #define  SSB_SPROM1_GPIOA_P1_SHIFT     8
2540 -#define SSB_SPROM1_GPIOB               0x1066  /* General Purpuse IO pins 2 and 3 */
2541 +#define SSB_SPROM1_GPIOB               0x0066  /* General Purpuse IO pins 2 and 3 */
2542  #define  SSB_SPROM1_GPIOB_P2           0x00FF  /* Pin 2 */
2543  #define  SSB_SPROM1_GPIOB_P3           0xFF00  /* Pin 3 */
2544  #define  SSB_SPROM1_GPIOB_P3_SHIFT     8
2545 -#define SSB_SPROM1_MAXPWR              0x1068  /* Power Amplifier Max Power */
2546 +#define SSB_SPROM1_MAXPWR              0x0068  /* Power Amplifier Max Power */
2547  #define  SSB_SPROM1_MAXPWR_BG          0x00FF  /* B-PHY and G-PHY (in dBm Q5.2) */
2548  #define  SSB_SPROM1_MAXPWR_A           0xFF00  /* A-PHY (in dBm Q5.2) */
2549  #define  SSB_SPROM1_MAXPWR_A_SHIFT     8
2550 -#define SSB_SPROM1_PA1B0               0x106A
2551 -#define SSB_SPROM1_PA1B1               0x106C
2552 -#define SSB_SPROM1_PA1B2               0x106E
2553 -#define SSB_SPROM1_ITSSI               0x1070  /* Idle TSSI Target */
2554 +#define SSB_SPROM1_PA1B0               0x006A
2555 +#define SSB_SPROM1_PA1B1               0x006C
2556 +#define SSB_SPROM1_PA1B2               0x006E
2557 +#define SSB_SPROM1_ITSSI               0x0070  /* Idle TSSI Target */
2558  #define  SSB_SPROM1_ITSSI_BG           0x00FF  /* B-PHY and G-PHY*/
2559  #define  SSB_SPROM1_ITSSI_A            0xFF00  /* A-PHY */
2560  #define  SSB_SPROM1_ITSSI_A_SHIFT      8
2561 -#define SSB_SPROM1_BFLLO               0x1072  /* Boardflags (low 16 bits) */
2562 -#define SSB_SPROM1_AGAIN               0x1074  /* Antenna Gain (in dBm Q5.2) */
2563 +#define SSB_SPROM1_BFLLO               0x0072  /* Boardflags (low 16 bits) */
2564 +#define SSB_SPROM1_AGAIN               0x0074  /* Antenna Gain (in dBm Q5.2) */
2565  #define  SSB_SPROM1_AGAIN_BG           0x00FF  /* B-PHY and G-PHY */
2566  #define  SSB_SPROM1_AGAIN_BG_SHIFT     0
2567  #define  SSB_SPROM1_AGAIN_A            0xFF00  /* A-PHY */
2568  #define  SSB_SPROM1_AGAIN_A_SHIFT      8
2569  
2570  /* SPROM Revision 2 (inherits from rev 1) */
2571 -#define SSB_SPROM2_BFLHI               0x1038  /* Boardflags (high 16 bits) */
2572 -#define SSB_SPROM2_MAXP_A              0x103A  /* A-PHY Max Power */
2573 +#define SSB_SPROM2_BFLHI               0x0038  /* Boardflags (high 16 bits) */
2574 +#define SSB_SPROM2_MAXP_A              0x003A  /* A-PHY Max Power */
2575  #define  SSB_SPROM2_MAXP_A_HI          0x00FF  /* Max Power High */
2576  #define  SSB_SPROM2_MAXP_A_LO          0xFF00  /* Max Power Low */
2577  #define  SSB_SPROM2_MAXP_A_LO_SHIFT    8
2578 -#define SSB_SPROM2_PA1LOB0             0x103C  /* A-PHY PowerAmplifier Low Settings */
2579 -#define SSB_SPROM2_PA1LOB1             0x103E  /* A-PHY PowerAmplifier Low Settings */
2580 -#define SSB_SPROM2_PA1LOB2             0x1040  /* A-PHY PowerAmplifier Low Settings */
2581 -#define SSB_SPROM2_PA1HIB0             0x1042  /* A-PHY PowerAmplifier High Settings */
2582 -#define SSB_SPROM2_PA1HIB1             0x1044  /* A-PHY PowerAmplifier High Settings */
2583 -#define SSB_SPROM2_PA1HIB2             0x1046  /* A-PHY PowerAmplifier High Settings */
2584 -#define SSB_SPROM2_OPO                 0x1078  /* OFDM Power Offset from CCK Level */
2585 +#define SSB_SPROM2_PA1LOB0             0x003C  /* A-PHY PowerAmplifier Low Settings */
2586 +#define SSB_SPROM2_PA1LOB1             0x003E  /* A-PHY PowerAmplifier Low Settings */
2587 +#define SSB_SPROM2_PA1LOB2             0x0040  /* A-PHY PowerAmplifier Low Settings */
2588 +#define SSB_SPROM2_PA1HIB0             0x0042  /* A-PHY PowerAmplifier High Settings */
2589 +#define SSB_SPROM2_PA1HIB1             0x0044  /* A-PHY PowerAmplifier High Settings */
2590 +#define SSB_SPROM2_PA1HIB2             0x0046  /* A-PHY PowerAmplifier High Settings */
2591 +#define SSB_SPROM2_OPO                 0x0078  /* OFDM Power Offset from CCK Level */
2592  #define  SSB_SPROM2_OPO_VALUE          0x00FF
2593  #define  SSB_SPROM2_OPO_UNUSED         0xFF00
2594 -#define SSB_SPROM2_CCODE               0x107C  /* Two char Country Code */
2595 +#define SSB_SPROM2_CCODE               0x007C  /* Two char Country Code */
2596  
2597  /* SPROM Revision 3 (inherits most data from rev 2) */
2598 -#define SSB_SPROM3_IL0MAC              0x104A  /* 6 bytes MAC address for 802.11b/g */
2599 -#define SSB_SPROM3_OFDMAPO             0x102C  /* A-PHY OFDM Mid Power Offset (4 bytes, BigEndian) */
2600 -#define SSB_SPROM3_OFDMALPO            0x1030  /* A-PHY OFDM Low Power Offset (4 bytes, BigEndian) */
2601 -#define SSB_SPROM3_OFDMAHPO            0x1034  /* A-PHY OFDM High Power Offset (4 bytes, BigEndian) */
2602 -#define SSB_SPROM3_GPIOLDC             0x1042  /* GPIO LED Powersave Duty Cycle (4 bytes, BigEndian) */
2603 +#define SSB_SPROM3_OFDMAPO             0x002C  /* A-PHY OFDM Mid Power Offset (4 bytes, BigEndian) */
2604 +#define SSB_SPROM3_OFDMALPO            0x0030  /* A-PHY OFDM Low Power Offset (4 bytes, BigEndian) */
2605 +#define SSB_SPROM3_OFDMAHPO            0x0034  /* A-PHY OFDM High Power Offset (4 bytes, BigEndian) */
2606 +#define SSB_SPROM3_GPIOLDC             0x0042  /* GPIO LED Powersave Duty Cycle (4 bytes, BigEndian) */
2607  #define  SSB_SPROM3_GPIOLDC_OFF                0x0000FF00      /* Off Count */
2608  #define  SSB_SPROM3_GPIOLDC_OFF_SHIFT  8
2609  #define  SSB_SPROM3_GPIOLDC_ON         0x00FF0000      /* On Count */
2610  #define  SSB_SPROM3_GPIOLDC_ON_SHIFT   16
2611 -#define SSB_SPROM3_CCKPO               0x1078  /* CCK Power Offset */
2612 +#define SSB_SPROM3_IL0MAC              0x004A  /* 6 bytes MAC address for 802.11b/g */
2613 +#define SSB_SPROM3_CCKPO               0x0078  /* CCK Power Offset */
2614  #define  SSB_SPROM3_CCKPO_1M           0x000F  /* 1M Rate PO */
2615  #define  SSB_SPROM3_CCKPO_2M           0x00F0  /* 2M Rate PO */
2616  #define  SSB_SPROM3_CCKPO_2M_SHIFT     4
2617 @@ -264,104 +267,200 @@
2618  #define  SSB_SPROM3_OFDMGPO            0x107A  /* G-PHY OFDM Power Offset (4 bytes, BigEndian) */
2619  
2620  /* SPROM Revision 4 */
2621 -#define SSB_SPROM4_IL0MAC              0x104C  /* 6 byte MAC address for a/b/g/n */
2622 -#define SSB_SPROM4_ETHPHY              0x105A  /* Ethernet PHY settings ?? */
2623 +#define SSB_SPROM4_BFLLO               0x0044  /* Boardflags (low 16 bits) */
2624 +#define SSB_SPROM4_BFLHI               0x0046  /* Board Flags Hi */
2625 +#define SSB_SPROM4_BFL2LO              0x0048  /* Board flags 2 (low 16 bits) */
2626 +#define SSB_SPROM4_BFL2HI              0x004A  /* Board flags 2 Hi */
2627 +#define SSB_SPROM4_IL0MAC              0x004C  /* 6 byte MAC address for a/b/g/n */
2628 +#define SSB_SPROM4_CCODE               0x0052  /* Country Code (2 bytes) */
2629 +#define SSB_SPROM4_GPIOA               0x0056  /* Gen. Purpose IO # 0 and 1 */
2630 +#define  SSB_SPROM4_GPIOA_P0           0x00FF  /* Pin 0 */
2631 +#define  SSB_SPROM4_GPIOA_P1           0xFF00  /* Pin 1 */
2632 +#define  SSB_SPROM4_GPIOA_P1_SHIFT     8
2633 +#define SSB_SPROM4_GPIOB               0x0058  /* Gen. Purpose IO # 2 and 3 */
2634 +#define  SSB_SPROM4_GPIOB_P2           0x00FF  /* Pin 2 */
2635 +#define  SSB_SPROM4_GPIOB_P3           0xFF00  /* Pin 3 */
2636 +#define  SSB_SPROM4_GPIOB_P3_SHIFT     8
2637 +#define SSB_SPROM4_ETHPHY              0x005A  /* Ethernet PHY settings ?? */
2638  #define  SSB_SPROM4_ETHPHY_ET0A                0x001F  /* MII Address for enet0 */
2639  #define  SSB_SPROM4_ETHPHY_ET1A                0x03E0  /* MII Address for enet1 */
2640  #define  SSB_SPROM4_ETHPHY_ET1A_SHIFT  5
2641  #define  SSB_SPROM4_ETHPHY_ET0M                (1<<14) /* MDIO for enet0 */
2642  #define  SSB_SPROM4_ETHPHY_ET1M                (1<<15) /* MDIO for enet1 */
2643 -#define SSB_SPROM4_CCODE               0x1052  /* Country Code (2 bytes) */
2644 -#define SSB_SPROM4_ANTAVAIL            0x105D  /* Antenna available bitfields */
2645 -#define SSB_SPROM4_ANTAVAIL_A          0x00FF  /* A-PHY bitfield */
2646 -#define SSB_SPROM4_ANTAVAIL_A_SHIFT    0
2647 -#define SSB_SPROM4_ANTAVAIL_BG         0xFF00  /* B-PHY and G-PHY bitfield */
2648 -#define SSB_SPROM4_ANTAVAIL_BG_SHIFT   8
2649 -#define SSB_SPROM4_BFLLO               0x1044  /* Boardflags (low 16 bits) */
2650 -#define SSB_SPROM4_AGAIN01             0x105E  /* Antenna Gain (in dBm Q5.2) */
2651 +#define SSB_SPROM4_ANTAVAIL            0x005D  /* Antenna available bitfields */
2652 +#define  SSB_SPROM4_ANTAVAIL_A         0x00FF  /* A-PHY bitfield */
2653 +#define  SSB_SPROM4_ANTAVAIL_A_SHIFT   0
2654 +#define  SSB_SPROM4_ANTAVAIL_BG                0xFF00  /* B-PHY and G-PHY bitfield */
2655 +#define  SSB_SPROM4_ANTAVAIL_BG_SHIFT  8
2656 +#define SSB_SPROM4_AGAIN01             0x005E  /* Antenna Gain (in dBm Q5.2) */
2657  #define  SSB_SPROM4_AGAIN0             0x00FF  /* Antenna 0 */
2658  #define  SSB_SPROM4_AGAIN0_SHIFT       0
2659  #define  SSB_SPROM4_AGAIN1             0xFF00  /* Antenna 1 */
2660  #define  SSB_SPROM4_AGAIN1_SHIFT       8
2661 -#define SSB_SPROM4_AGAIN23             0x1060
2662 +#define SSB_SPROM4_AGAIN23             0x0060
2663  #define  SSB_SPROM4_AGAIN2             0x00FF  /* Antenna 2 */
2664  #define  SSB_SPROM4_AGAIN2_SHIFT       0
2665  #define  SSB_SPROM4_AGAIN3             0xFF00  /* Antenna 3 */
2666  #define  SSB_SPROM4_AGAIN3_SHIFT       8
2667 -#define SSB_SPROM4_BFLHI               0x1046  /* Board Flags Hi */
2668 -#define SSB_SPROM4_MAXP_BG             0x1080  /* Max Power BG in path 1 */
2669 +#define SSB_SPROM4_TXPID2G01           0x0062  /* TX Power Index 2GHz */
2670 +#define  SSB_SPROM4_TXPID2G0           0x00FF
2671 +#define  SSB_SPROM4_TXPID2G0_SHIFT     0
2672 +#define  SSB_SPROM4_TXPID2G1           0xFF00
2673 +#define  SSB_SPROM4_TXPID2G1_SHIFT     8
2674 +#define SSB_SPROM4_TXPID2G23           0x0064  /* TX Power Index 2GHz */
2675 +#define  SSB_SPROM4_TXPID2G2           0x00FF
2676 +#define  SSB_SPROM4_TXPID2G2_SHIFT     0
2677 +#define  SSB_SPROM4_TXPID2G3           0xFF00
2678 +#define  SSB_SPROM4_TXPID2G3_SHIFT     8
2679 +#define SSB_SPROM4_TXPID5G01           0x0066  /* TX Power Index 5GHz middle subband */
2680 +#define  SSB_SPROM4_TXPID5G0           0x00FF
2681 +#define  SSB_SPROM4_TXPID5G0_SHIFT     0
2682 +#define  SSB_SPROM4_TXPID5G1           0xFF00
2683 +#define  SSB_SPROM4_TXPID5G1_SHIFT     8
2684 +#define SSB_SPROM4_TXPID5G23           0x0068  /* TX Power Index 5GHz middle subband */
2685 +#define  SSB_SPROM4_TXPID5G2           0x00FF
2686 +#define  SSB_SPROM4_TXPID5G2_SHIFT     0
2687 +#define  SSB_SPROM4_TXPID5G3           0xFF00
2688 +#define  SSB_SPROM4_TXPID5G3_SHIFT     8
2689 +#define SSB_SPROM4_TXPID5GL01          0x006A  /* TX Power Index 5GHz low subband */
2690 +#define  SSB_SPROM4_TXPID5GL0          0x00FF
2691 +#define  SSB_SPROM4_TXPID5GL0_SHIFT    0
2692 +#define  SSB_SPROM4_TXPID5GL1          0xFF00
2693 +#define  SSB_SPROM4_TXPID5GL1_SHIFT    8
2694 +#define SSB_SPROM4_TXPID5GL23          0x006C  /* TX Power Index 5GHz low subband */
2695 +#define  SSB_SPROM4_TXPID5GL2          0x00FF
2696 +#define  SSB_SPROM4_TXPID5GL2_SHIFT    0
2697 +#define  SSB_SPROM4_TXPID5GL3          0xFF00
2698 +#define  SSB_SPROM4_TXPID5GL3_SHIFT    8
2699 +#define SSB_SPROM4_TXPID5GH01          0x006E  /* TX Power Index 5GHz high subband */
2700 +#define  SSB_SPROM4_TXPID5GH0          0x00FF
2701 +#define  SSB_SPROM4_TXPID5GH0_SHIFT    0
2702 +#define  SSB_SPROM4_TXPID5GH1          0xFF00
2703 +#define  SSB_SPROM4_TXPID5GH1_SHIFT    8
2704 +#define SSB_SPROM4_TXPID5GH23          0x0070  /* TX Power Index 5GHz high subband */
2705 +#define  SSB_SPROM4_TXPID5GH2          0x00FF
2706 +#define  SSB_SPROM4_TXPID5GH2_SHIFT    0
2707 +#define  SSB_SPROM4_TXPID5GH3          0xFF00
2708 +#define  SSB_SPROM4_TXPID5GH3_SHIFT    8
2709 +#define SSB_SPROM4_MAXP_BG             0x0080  /* Max Power BG in path 1 */
2710  #define  SSB_SPROM4_MAXP_BG_MASK       0x00FF  /* Mask for Max Power BG */
2711  #define  SSB_SPROM4_ITSSI_BG           0xFF00  /* Mask for path 1 itssi_bg */
2712  #define  SSB_SPROM4_ITSSI_BG_SHIFT     8
2713 -#define SSB_SPROM4_MAXP_A              0x108A  /* Max Power A in path 1 */
2714 +#define SSB_SPROM4_MAXP_A              0x008A  /* Max Power A in path 1 */
2715  #define  SSB_SPROM4_MAXP_A_MASK                0x00FF  /* Mask for Max Power A */
2716  #define  SSB_SPROM4_ITSSI_A            0xFF00  /* Mask for path 1 itssi_a */
2717  #define  SSB_SPROM4_ITSSI_A_SHIFT      8
2718 -#define SSB_SPROM4_GPIOA               0x1056  /* Gen. Purpose IO # 0 and 1 */
2719 -#define  SSB_SPROM4_GPIOA_P0           0x00FF  /* Pin 0 */
2720 -#define  SSB_SPROM4_GPIOA_P1           0xFF00  /* Pin 1 */
2721 -#define  SSB_SPROM4_GPIOA_P1_SHIFT     8
2722 -#define SSB_SPROM4_GPIOB               0x1058  /* Gen. Purpose IO # 2 and 3 */
2723 -#define  SSB_SPROM4_GPIOB_P2           0x00FF  /* Pin 2 */
2724 -#define  SSB_SPROM4_GPIOB_P3           0xFF00  /* Pin 3 */
2725 -#define  SSB_SPROM4_GPIOB_P3_SHIFT     8
2726 -#define SSB_SPROM4_PA0B0               0x1082  /* The paXbY locations are */
2727 -#define SSB_SPROM4_PA0B1               0x1084  /*   only guesses */
2728 -#define SSB_SPROM4_PA0B2               0x1086
2729 -#define SSB_SPROM4_PA1B0               0x108E
2730 -#define SSB_SPROM4_PA1B1               0x1090
2731 -#define SSB_SPROM4_PA1B2               0x1092
2732 +#define SSB_SPROM4_PA0B0               0x0082  /* The paXbY locations are */
2733 +#define SSB_SPROM4_PA0B1               0x0084  /*   only guesses */
2734 +#define SSB_SPROM4_PA0B2               0x0086
2735 +#define SSB_SPROM4_PA1B0               0x008E
2736 +#define SSB_SPROM4_PA1B1               0x0090
2737 +#define SSB_SPROM4_PA1B2               0x0092
2738  
2739  /* SPROM Revision 5 (inherits most data from rev 4) */
2740 -#define SSB_SPROM5_BFLLO               0x104A  /* Boardflags (low 16 bits) */
2741 -#define SSB_SPROM5_BFLHI               0x104C  /* Board Flags Hi */
2742 -#define SSB_SPROM5_IL0MAC              0x1052  /* 6 byte MAC address for a/b/g/n */
2743 -#define SSB_SPROM5_CCODE               0x1044  /* Country Code (2 bytes) */
2744 -#define SSB_SPROM5_GPIOA               0x1076  /* Gen. Purpose IO # 0 and 1 */
2745 +#define SSB_SPROM5_CCODE               0x0044  /* Country Code (2 bytes) */
2746 +#define SSB_SPROM5_BFLLO               0x004A  /* Boardflags (low 16 bits) */
2747 +#define SSB_SPROM5_BFLHI               0x004C  /* Board Flags Hi */
2748 +#define SSB_SPROM5_BFL2LO              0x004E  /* Board flags 2 (low 16 bits) */
2749 +#define SSB_SPROM5_BFL2HI              0x0050  /* Board flags 2 Hi */
2750 +#define SSB_SPROM5_IL0MAC              0x0052  /* 6 byte MAC address for a/b/g/n */
2751 +#define SSB_SPROM5_GPIOA               0x0076  /* Gen. Purpose IO # 0 and 1 */
2752  #define  SSB_SPROM5_GPIOA_P0           0x00FF  /* Pin 0 */
2753  #define  SSB_SPROM5_GPIOA_P1           0xFF00  /* Pin 1 */
2754  #define  SSB_SPROM5_GPIOA_P1_SHIFT     8
2755 -#define SSB_SPROM5_GPIOB               0x1078  /* Gen. Purpose IO # 2 and 3 */
2756 +#define SSB_SPROM5_GPIOB               0x0078  /* Gen. Purpose IO # 2 and 3 */
2757  #define  SSB_SPROM5_GPIOB_P2           0x00FF  /* Pin 2 */
2758  #define  SSB_SPROM5_GPIOB_P3           0xFF00  /* Pin 3 */
2759  #define  SSB_SPROM5_GPIOB_P3_SHIFT     8
2760  
2761  /* SPROM Revision 8 */
2762 -#define SSB_SPROM8_BFLLO               0x1084  /* Boardflags (low 16 bits) */
2763 -#define SSB_SPROM8_BFLHI               0x1086  /* Boardflags Hi */
2764 -#define SSB_SPROM8_IL0MAC              0x108C  /* 6 byte MAC address */
2765 -#define SSB_SPROM8_CCODE               0x1092  /* 2 byte country code */
2766 -#define SSB_SPROM8_ANTAVAIL            0x109C  /* Antenna available bitfields*/
2767 -#define SSB_SPROM8_ANTAVAIL_A          0xFF00  /* A-PHY bitfield */
2768 -#define SSB_SPROM8_ANTAVAIL_A_SHIFT    8
2769 -#define SSB_SPROM8_ANTAVAIL_BG         0x00FF  /* B-PHY and G-PHY bitfield */
2770 -#define SSB_SPROM8_ANTAVAIL_BG_SHIFT   0
2771 -#define SSB_SPROM8_AGAIN01             0x109E  /* Antenna Gain (in dBm Q5.2) */
2772 +#define SSB_SPROM8_BOARDREV            0x0082  /* Board revision */
2773 +#define SSB_SPROM8_BFLLO               0x0084  /* Board flags (bits 0-15) */
2774 +#define SSB_SPROM8_BFLHI               0x0086  /* Board flags (bits 16-31) */
2775 +#define SSB_SPROM8_BFL2LO              0x0088  /* Board flags (bits 32-47) */
2776 +#define SSB_SPROM8_BFL2HI              0x008A  /* Board flags (bits 48-63) */
2777 +#define SSB_SPROM8_IL0MAC              0x008C  /* 6 byte MAC address */
2778 +#define SSB_SPROM8_CCODE               0x0092  /* 2 byte country code */
2779 +#define SSB_SPROM8_GPIOA               0x0096  /*Gen. Purpose IO # 0 and 1 */
2780 +#define  SSB_SPROM8_GPIOA_P0           0x00FF  /* Pin 0 */
2781 +#define  SSB_SPROM8_GPIOA_P1           0xFF00  /* Pin 1 */
2782 +#define  SSB_SPROM8_GPIOA_P1_SHIFT     8
2783 +#define SSB_SPROM8_GPIOB               0x0098  /* Gen. Purpose IO # 2 and 3 */
2784 +#define  SSB_SPROM8_GPIOB_P2           0x00FF  /* Pin 2 */
2785 +#define  SSB_SPROM8_GPIOB_P3           0xFF00  /* Pin 3 */
2786 +#define  SSB_SPROM8_GPIOB_P3_SHIFT     8
2787 +#define SSB_SPROM8_ANTAVAIL            0x009C  /* Antenna available bitfields*/
2788 +#define  SSB_SPROM8_ANTAVAIL_A         0xFF00  /* A-PHY bitfield */
2789 +#define  SSB_SPROM8_ANTAVAIL_A_SHIFT   8
2790 +#define  SSB_SPROM8_ANTAVAIL_BG                0x00FF  /* B-PHY and G-PHY bitfield */
2791 +#define  SSB_SPROM8_ANTAVAIL_BG_SHIFT  0
2792 +#define SSB_SPROM8_AGAIN01             0x009E  /* Antenna Gain (in dBm Q5.2) */
2793  #define  SSB_SPROM8_AGAIN0             0x00FF  /* Antenna 0 */
2794  #define  SSB_SPROM8_AGAIN0_SHIFT       0
2795  #define  SSB_SPROM8_AGAIN1             0xFF00  /* Antenna 1 */
2796  #define  SSB_SPROM8_AGAIN1_SHIFT       8
2797 -#define SSB_SPROM8_AGAIN23             0x10A0
2798 +#define SSB_SPROM8_AGAIN23             0x00A0
2799  #define  SSB_SPROM8_AGAIN2             0x00FF  /* Antenna 2 */
2800  #define  SSB_SPROM8_AGAIN2_SHIFT       0
2801  #define  SSB_SPROM8_AGAIN3             0xFF00  /* Antenna 3 */
2802  #define  SSB_SPROM8_AGAIN3_SHIFT       8
2803 -#define SSB_SPROM8_GPIOA               0x1096  /*Gen. Purpose IO # 0 and 1 */
2804 -#define  SSB_SPROM8_GPIOA_P0           0x00FF  /* Pin 0 */
2805 -#define  SSB_SPROM8_GPIOA_P1           0xFF00  /* Pin 1 */
2806 -#define  SSB_SPROM8_GPIOA_P1_SHIFT     8
2807 -#define SSB_SPROM8_GPIOB               0x1098  /* Gen. Purpose IO # 2 and 3 */
2808 -#define  SSB_SPROM8_GPIOB_P2           0x00FF  /* Pin 2 */
2809 -#define  SSB_SPROM8_GPIOB_P3           0xFF00  /* Pin 3 */
2810 -#define  SSB_SPROM8_GPIOB_P3_SHIFT     8
2811 -#define SSB_SPROM8_MAXP_BG             0x10C0  /* Max Power BG in path 1 */
2812 -#define  SSB_SPROM8_MAXP_BG_MASK       0x00FF  /* Mask for Max Power BG */
2813 +#define SSB_SPROM8_RSSIPARM2G          0x00A4  /* RSSI params for 2GHz */
2814 +#define  SSB_SPROM8_RSSISMF2G          0x000F
2815 +#define  SSB_SPROM8_RSSISMC2G          0x00F0
2816 +#define  SSB_SPROM8_RSSISMC2G_SHIFT    4
2817 +#define  SSB_SPROM8_RSSISAV2G          0x0700
2818 +#define  SSB_SPROM8_RSSISAV2G_SHIFT    8
2819 +#define  SSB_SPROM8_BXA2G              0x1800
2820 +#define  SSB_SPROM8_BXA2G_SHIFT                11
2821 +#define SSB_SPROM8_RSSIPARM5G          0x00A6  /* RSSI params for 5GHz */
2822 +#define  SSB_SPROM8_RSSISMF5G          0x000F
2823 +#define  SSB_SPROM8_RSSISMC5G          0x00F0
2824 +#define  SSB_SPROM8_RSSISMC5G_SHIFT    4
2825 +#define  SSB_SPROM8_RSSISAV5G          0x0700
2826 +#define  SSB_SPROM8_RSSISAV5G_SHIFT    8
2827 +#define  SSB_SPROM8_BXA5G              0x1800
2828 +#define  SSB_SPROM8_BXA5G_SHIFT                11
2829 +#define SSB_SPROM8_TRI25G              0x00A8  /* TX isolation 2.4&5.3GHz */
2830 +#define  SSB_SPROM8_TRI2G              0x00FF  /* TX isolation 2.4GHz */
2831 +#define  SSB_SPROM8_TRI5G              0xFF00  /* TX isolation 5.3GHz */
2832 +#define  SSB_SPROM8_TRI5G_SHIFT                8
2833 +#define SSB_SPROM8_TRI5GHL             0x00AA  /* TX isolation 5.2/5.8GHz */
2834 +#define  SSB_SPROM8_TRI5GL             0x00FF  /* TX isolation 5.2GHz */
2835 +#define  SSB_SPROM8_TRI5GH             0xFF00  /* TX isolation 5.8GHz */
2836 +#define  SSB_SPROM8_TRI5GH_SHIFT       8
2837 +#define SSB_SPROM8_RXPO                        0x00AC  /* RX power offsets */
2838 +#define  SSB_SPROM8_RXPO2G             0x00FF  /* 2GHz RX power offset */
2839 +#define  SSB_SPROM8_RXPO5G             0xFF00  /* 5GHz RX power offset */
2840 +#define  SSB_SPROM8_RXPO5G_SHIFT       8
2841 +#define SSB_SPROM8_MAXP_BG             0x00C0  /* Max Power 2GHz in path 1 */
2842 +#define  SSB_SPROM8_MAXP_BG_MASK       0x00FF  /* Mask for Max Power 2GHz */
2843  #define  SSB_SPROM8_ITSSI_BG           0xFF00  /* Mask for path 1 itssi_bg */
2844  #define  SSB_SPROM8_ITSSI_BG_SHIFT     8
2845 -#define SSB_SPROM8_MAXP_A              0x10C8  /* Max Power A in path 1 */
2846 -#define  SSB_SPROM8_MAXP_A_MASK                0x00FF  /* Mask for Max Power A */
2847 +#define SSB_SPROM8_PA0B0               0x00C2  /* 2GHz power amp settings */
2848 +#define SSB_SPROM8_PA0B1               0x00C4
2849 +#define SSB_SPROM8_PA0B2               0x00C6
2850 +#define SSB_SPROM8_MAXP_A              0x00C8  /* Max Power 5.3GHz */
2851 +#define  SSB_SPROM8_MAXP_A_MASK                0x00FF  /* Mask for Max Power 5.3GHz */
2852  #define  SSB_SPROM8_ITSSI_A            0xFF00  /* Mask for path 1 itssi_a */
2853  #define  SSB_SPROM8_ITSSI_A_SHIFT      8
2854 +#define SSB_SPROM8_MAXP_AHL            0x00CA  /* Max Power 5.2/5.8GHz */
2855 +#define  SSB_SPROM8_MAXP_AH_MASK       0x00FF  /* Mask for Max Power 5.8GHz */
2856 +#define  SSB_SPROM8_MAXP_AL_MASK       0xFF00  /* Mask for Max Power 5.2GHz */
2857 +#define  SSB_SPROM8_MAXP_AL_SHIFT      8
2858 +#define SSB_SPROM8_PA1B0               0x00CC  /* 5.3GHz power amp settings */
2859 +#define SSB_SPROM8_PA1B1               0x00CE
2860 +#define SSB_SPROM8_PA1B2               0x00D0
2861 +#define SSB_SPROM8_PA1LOB0             0x00D2  /* 5.2GHz power amp settings */
2862 +#define SSB_SPROM8_PA1LOB1             0x00D4
2863 +#define SSB_SPROM8_PA1LOB2             0x00D6
2864 +#define SSB_SPROM8_PA1HIB0             0x00D8  /* 5.8GHz power amp settings */
2865 +#define SSB_SPROM8_PA1HIB1             0x00DA
2866 +#define SSB_SPROM8_PA1HIB2             0x00DC
2867 +#define SSB_SPROM8_CCK2GPO             0x0140  /* CCK power offset */
2868 +#define SSB_SPROM8_OFDM2GPO            0x0142  /* 2.4GHz OFDM power offset */
2869 +#define SSB_SPROM8_OFDM5GPO            0x0146  /* 5.3GHz OFDM power offset */
2870 +#define SSB_SPROM8_OFDM5GLPO           0x014A  /* 5.2GHz OFDM power offset */
2871 +#define SSB_SPROM8_OFDM5GHPO           0x014E  /* 5.8GHz OFDM power offset */
2872  
2873  /* Values for SSB_SPROM1_BINF_CCODE */
2874  enum {