kernel: ssb/bcma: update to version from wireless-testing tag master-2012-05-16-2
[openwrt.git] / target / linux / generic / patches-2.6.39 / 025-bcma_backport.patch
1 --- /dev/null
2 +++ b/Documentation/ABI/testing/sysfs-bus-bcma
3 @@ -0,0 +1,31 @@
4 +What:          /sys/bus/bcma/devices/.../manuf
5 +Date:          May 2011
6 +KernelVersion: 2.6.40
7 +Contact:       Rafał Miłecki <zajec5@gmail.com>
8 +Description:
9 +               Each BCMA core has it's manufacturer id. See
10 +               include/linux/bcma/bcma.h for possible values.
11 +
12 +What:          /sys/bus/bcma/devices/.../id
13 +Date:          May 2011
14 +KernelVersion: 2.6.40
15 +Contact:       Rafał Miłecki <zajec5@gmail.com>
16 +Description:
17 +               There are a few types of BCMA cores, they can be identified by
18 +               id field.
19 +
20 +What:          /sys/bus/bcma/devices/.../rev
21 +Date:          May 2011
22 +KernelVersion: 2.6.40
23 +Contact:       Rafał Miłecki <zajec5@gmail.com>
24 +Description:
25 +               BCMA cores of the same type can still slightly differ depending
26 +               on their revision. Use it for detailed programming.
27 +
28 +What:          /sys/bus/bcma/devices/.../class
29 +Date:          May 2011
30 +KernelVersion: 2.6.40
31 +Contact:       Rafał Miłecki <zajec5@gmail.com>
32 +Description:
33 +               Each BCMA core is identified by few fields, including class it
34 +               belongs to. See include/linux/bcma/bcma.h for possible values.
35 --- a/MAINTAINERS
36 +++ b/MAINTAINERS
37 @@ -5832,6 +5832,13 @@ S:       Maintained
38  F:     drivers/ssb/
39  F:     include/linux/ssb/
40  
41 +BROADCOM SPECIFIC AMBA DRIVER (BCMA)
42 +M:     Rafał Miłecki <zajec5@gmail.com>
43 +L:     linux-wireless@vger.kernel.org
44 +S:     Maintained
45 +F:     drivers/bcma/
46 +F:     include/linux/bcma/
47 +
48  SONY VAIO CONTROL DEVICE DRIVER
49  M:     Mattia Dongili <malattia@linux.it>
50  L:     platform-driver-x86@vger.kernel.org
51 --- a/drivers/Kconfig
52 +++ b/drivers/Kconfig
53 @@ -68,6 +68,8 @@ source "drivers/watchdog/Kconfig"
54  
55  source "drivers/ssb/Kconfig"
56  
57 +source "drivers/bcma/Kconfig"
58 +
59  source "drivers/mfd/Kconfig"
60  
61  source "drivers/regulator/Kconfig"
62 --- a/drivers/Makefile
63 +++ b/drivers/Makefile
64 @@ -110,6 +110,7 @@ obj-$(CONFIG_HID)           += hid/
65  obj-$(CONFIG_PPC_PS3)          += ps3/
66  obj-$(CONFIG_OF)               += of/
67  obj-$(CONFIG_SSB)              += ssb/
68 +obj-$(CONFIG_BCMA)             += bcma/
69  obj-$(CONFIG_VHOST_NET)                += vhost/
70  obj-$(CONFIG_VLYNQ)            += vlynq/
71  obj-$(CONFIG_STAGING)          += staging/
72 --- /dev/null
73 +++ b/drivers/bcma/Kconfig
74 @@ -0,0 +1,57 @@
75 +config BCMA_POSSIBLE
76 +       bool
77 +       depends on HAS_IOMEM && HAS_DMA
78 +       default y
79 +
80 +menu "Broadcom specific AMBA"
81 +       depends on BCMA_POSSIBLE
82 +
83 +config BCMA
84 +       tristate "BCMA support"
85 +       depends on BCMA_POSSIBLE
86 +       help
87 +         Bus driver for Broadcom specific Advanced Microcontroller Bus
88 +         Architecture.
89 +
90 +# Support for Block-I/O. SELECT this from the driver that needs it.
91 +config BCMA_BLOCKIO
92 +       bool
93 +       depends on BCMA
94 +
95 +config BCMA_HOST_PCI_POSSIBLE
96 +       bool
97 +       depends on BCMA && PCI = y
98 +       default y
99 +
100 +config BCMA_HOST_PCI
101 +       bool "Support for BCMA on PCI-host bus"
102 +       depends on BCMA_HOST_PCI_POSSIBLE
103 +
104 +config BCMA_DRIVER_PCI_HOSTMODE
105 +       bool "Driver for PCI core working in hostmode"
106 +       depends on BCMA && MIPS && BCMA_HOST_PCI
107 +       help
108 +         PCI core hostmode operation (external PCI bus).
109 +
110 +config BCMA_HOST_SOC
111 +       bool
112 +       depends on BCMA_DRIVER_MIPS
113 +
114 +config BCMA_DRIVER_MIPS
115 +       bool "BCMA Broadcom MIPS core driver"
116 +       depends on BCMA && MIPS
117 +       help
118 +         Driver for the Broadcom MIPS core attached to Broadcom specific
119 +         Advanced Microcontroller Bus.
120 +
121 +         If unsure, say N
122 +
123 +config BCMA_DEBUG
124 +       bool "BCMA debugging"
125 +       depends on BCMA
126 +       help
127 +         This turns on additional debugging messages.
128 +
129 +         If unsure, say N
130 +
131 +endmenu
132 --- /dev/null
133 +++ b/drivers/bcma/Makefile
134 @@ -0,0 +1,10 @@
135 +bcma-y                                 += main.o scan.o core.o sprom.o
136 +bcma-y                                 += driver_chipcommon.o driver_chipcommon_pmu.o
137 +bcma-y                                 += driver_pci.o
138 +bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE)        += driver_pci_host.o
139 +bcma-$(CONFIG_BCMA_DRIVER_MIPS)                += driver_mips.o
140 +bcma-$(CONFIG_BCMA_HOST_PCI)           += host_pci.o
141 +bcma-$(CONFIG_BCMA_HOST_SOC)           += host_soc.o
142 +obj-$(CONFIG_BCMA)                     += bcma.o
143 +
144 +ccflags-$(CONFIG_BCMA_DEBUG)           := -DDEBUG
145 --- /dev/null
146 +++ b/drivers/bcma/README
147 @@ -0,0 +1,19 @@
148 +Broadcom introduced new bus as replacement for older SSB. It is based on AMBA,
149 +however from programming point of view there is nothing AMBA specific we use.
150 +
151 +Standard AMBA drivers are platform specific, have hardcoded addresses and use
152 +AMBA standard fields like CID and PID.
153 +
154 +In case of Broadcom's cards every device consists of:
155 +1) Broadcom specific AMBA device. It is put on AMBA bus, but can not be treated
156 +   as standard AMBA device. Reading it's CID or PID can cause machine lockup.
157 +2) AMBA standard devices called ports or wrappers. They have CIDs (AMBA_CID)
158 +   and PIDs (0x103BB369), but we do not use that info for anything. One of that
159 +   devices is used for managing Broadcom specific core.
160 +
161 +Addresses of AMBA devices are not hardcoded in driver and have to be read from
162 +EPROM.
163 +
164 +In this situation we decided to introduce separated bus. It can contain up to
165 +16 devices identified by Broadcom specific fields: manufacturer, id, revision
166 +and class.
167 --- /dev/null
168 +++ b/drivers/bcma/TODO
169 @@ -0,0 +1,3 @@
170 +- Interrupts
171 +- Defines for PCI core driver
172 +- Create kernel Documentation (use info from README)
173 --- /dev/null
174 +++ b/drivers/bcma/bcma_private.h
175 @@ -0,0 +1,59 @@
176 +#ifndef LINUX_BCMA_PRIVATE_H_
177 +#define LINUX_BCMA_PRIVATE_H_
178 +
179 +#ifndef pr_fmt
180 +#define pr_fmt(fmt)            KBUILD_MODNAME ": " fmt
181 +#endif
182 +
183 +#include <linux/bcma/bcma.h>
184 +#include <linux/delay.h>
185 +
186 +#define BCMA_CORE_SIZE         0x1000
187 +
188 +struct bcma_bus;
189 +
190 +/* main.c */
191 +int __devinit bcma_bus_register(struct bcma_bus *bus);
192 +void bcma_bus_unregister(struct bcma_bus *bus);
193 +int __init bcma_bus_early_register(struct bcma_bus *bus,
194 +                                  struct bcma_device *core_cc,
195 +                                  struct bcma_device *core_mips);
196 +#ifdef CONFIG_PM
197 +int bcma_bus_suspend(struct bcma_bus *bus);
198 +int bcma_bus_resume(struct bcma_bus *bus);
199 +#endif
200 +
201 +/* scan.c */
202 +int bcma_bus_scan(struct bcma_bus *bus);
203 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
204 +                              struct bcma_device_id *match,
205 +                              struct bcma_device *core);
206 +void bcma_init_bus(struct bcma_bus *bus);
207 +
208 +/* sprom.c */
209 +int bcma_sprom_get(struct bcma_bus *bus);
210 +
211 +/* driver_chipcommon.c */
212 +#ifdef CONFIG_BCMA_DRIVER_MIPS
213 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
214 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
215 +
216 +/* driver_chipcommon_pmu.c */
217 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc);
218 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
219 +
220 +#ifdef CONFIG_BCMA_HOST_PCI
221 +/* host_pci.c */
222 +extern int __init bcma_host_pci_init(void);
223 +extern void __exit bcma_host_pci_exit(void);
224 +#endif /* CONFIG_BCMA_HOST_PCI */
225 +
226 +/* driver_pci.c */
227 +u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
228 +
229 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
230 +bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc);
231 +void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
232 +#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
233 +
234 +#endif
235 --- /dev/null
236 +++ b/drivers/bcma/core.c
237 @@ -0,0 +1,127 @@
238 +/*
239 + * Broadcom specific AMBA
240 + * Core ops
241 + *
242 + * Licensed under the GNU/GPL. See COPYING for details.
243 + */
244 +
245 +#include "bcma_private.h"
246 +#include <linux/bcma/bcma.h>
247 +
248 +bool bcma_core_is_enabled(struct bcma_device *core)
249 +{
250 +       if ((bcma_aread32(core, BCMA_IOCTL) & (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC))
251 +           != BCMA_IOCTL_CLK)
252 +               return false;
253 +       if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
254 +               return false;
255 +       return true;
256 +}
257 +EXPORT_SYMBOL_GPL(bcma_core_is_enabled);
258 +
259 +void bcma_core_disable(struct bcma_device *core, u32 flags)
260 +{
261 +       if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
262 +               return;
263 +
264 +       bcma_awrite32(core, BCMA_IOCTL, flags);
265 +       bcma_aread32(core, BCMA_IOCTL);
266 +       udelay(10);
267 +
268 +       bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
269 +       bcma_aread32(core, BCMA_RESET_CTL);
270 +       udelay(1);
271 +}
272 +EXPORT_SYMBOL_GPL(bcma_core_disable);
273 +
274 +int bcma_core_enable(struct bcma_device *core, u32 flags)
275 +{
276 +       bcma_core_disable(core, flags);
277 +
278 +       bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags));
279 +       bcma_aread32(core, BCMA_IOCTL);
280 +
281 +       bcma_awrite32(core, BCMA_RESET_CTL, 0);
282 +       udelay(1);
283 +
284 +       bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags));
285 +       bcma_aread32(core, BCMA_IOCTL);
286 +       udelay(1);
287 +
288 +       return 0;
289 +}
290 +EXPORT_SYMBOL_GPL(bcma_core_enable);
291 +
292 +void bcma_core_set_clockmode(struct bcma_device *core,
293 +                            enum bcma_clkmode clkmode)
294 +{
295 +       u16 i;
296 +
297 +       WARN_ON(core->id.id != BCMA_CORE_CHIPCOMMON &&
298 +               core->id.id != BCMA_CORE_PCIE &&
299 +               core->id.id != BCMA_CORE_80211);
300 +
301 +       switch (clkmode) {
302 +       case BCMA_CLKMODE_FAST:
303 +               bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
304 +               udelay(64);
305 +               for (i = 0; i < 1500; i++) {
306 +                       if (bcma_read32(core, BCMA_CLKCTLST) &
307 +                           BCMA_CLKCTLST_HAVEHT) {
308 +                               i = 0;
309 +                               break;
310 +                       }
311 +                       udelay(10);
312 +               }
313 +               if (i)
314 +                       pr_err("HT force timeout\n");
315 +               break;
316 +       case BCMA_CLKMODE_DYNAMIC:
317 +               bcma_set32(core, BCMA_CLKCTLST, ~BCMA_CLKCTLST_FORCEHT);
318 +               break;
319 +       }
320 +}
321 +EXPORT_SYMBOL_GPL(bcma_core_set_clockmode);
322 +
323 +void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on)
324 +{
325 +       u16 i;
326 +
327 +       WARN_ON(req & ~BCMA_CLKCTLST_EXTRESREQ);
328 +       WARN_ON(status & ~BCMA_CLKCTLST_EXTRESST);
329 +
330 +       if (on) {
331 +               bcma_set32(core, BCMA_CLKCTLST, req);
332 +               for (i = 0; i < 10000; i++) {
333 +                       if ((bcma_read32(core, BCMA_CLKCTLST) & status) ==
334 +                           status) {
335 +                               i = 0;
336 +                               break;
337 +                       }
338 +                       udelay(10);
339 +               }
340 +               if (i)
341 +                       pr_err("PLL enable timeout\n");
342 +       } else {
343 +               pr_warn("Disabling PLL not supported yet!\n");
344 +       }
345 +}
346 +EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
347 +
348 +u32 bcma_core_dma_translation(struct bcma_device *core)
349 +{
350 +       switch (core->bus->hosttype) {
351 +       case BCMA_HOSTTYPE_SOC:
352 +               return 0;
353 +       case BCMA_HOSTTYPE_PCI:
354 +               if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
355 +                       return BCMA_DMA_TRANSLATION_DMA64_CMT;
356 +               else
357 +                       return BCMA_DMA_TRANSLATION_DMA32_CMT;
358 +       default:
359 +               pr_err("DMA translation unknown for host %d\n",
360 +                      core->bus->hosttype);
361 +       }
362 +       return BCMA_DMA_TRANSLATION_NONE;
363 +}
364 +EXPORT_SYMBOL(bcma_core_dma_translation);
365 --- /dev/null
366 +++ b/drivers/bcma/driver_chipcommon.c
367 @@ -0,0 +1,156 @@
368 +/*
369 + * Broadcom specific AMBA
370 + * ChipCommon core driver
371 + *
372 + * Copyright 2005, Broadcom Corporation
373 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
374 + *
375 + * Licensed under the GNU/GPL. See COPYING for details.
376 + */
377 +
378 +#include "bcma_private.h"
379 +#include <linux/bcma/bcma.h>
380 +
381 +static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
382 +                                        u32 mask, u32 value)
383 +{
384 +       value &= mask;
385 +       value |= bcma_cc_read32(cc, offset) & ~mask;
386 +       bcma_cc_write32(cc, offset, value);
387 +
388 +       return value;
389 +}
390 +
391 +void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
392 +{
393 +       u32 leddc_on = 10;
394 +       u32 leddc_off = 90;
395 +
396 +       if (cc->setup_done)
397 +               return;
398 +
399 +       if (cc->core->id.rev >= 11)
400 +               cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
401 +       cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
402 +       if (cc->core->id.rev >= 35)
403 +               cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT);
404 +
405 +       if (cc->core->id.rev >= 20) {
406 +               bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0);
407 +               bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0);
408 +       }
409 +
410 +       if (cc->capabilities & BCMA_CC_CAP_PMU)
411 +               bcma_pmu_init(cc);
412 +       if (cc->capabilities & BCMA_CC_CAP_PCTL)
413 +               pr_err("Power control not implemented!\n");
414 +
415 +       if (cc->core->id.rev >= 16) {
416 +               if (cc->core->bus->sprom.leddc_on_time &&
417 +                   cc->core->bus->sprom.leddc_off_time) {
418 +                       leddc_on = cc->core->bus->sprom.leddc_on_time;
419 +                       leddc_off = cc->core->bus->sprom.leddc_off_time;
420 +               }
421 +               bcma_cc_write32(cc, BCMA_CC_GPIOTIMER,
422 +                       ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
423 +                        (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
424 +       }
425 +
426 +       cc->setup_done = true;
427 +}
428 +
429 +/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
430 +void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
431 +{
432 +       /* instant NMI */
433 +       bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
434 +}
435 +
436 +void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
437 +{
438 +       bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value);
439 +}
440 +
441 +u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask)
442 +{
443 +       return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask;
444 +}
445 +
446 +u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask)
447 +{
448 +       return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask;
449 +}
450 +
451 +u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
452 +{
453 +       return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
454 +}
455 +
456 +u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
457 +{
458 +       return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
459 +}
460 +
461 +u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
462 +{
463 +       return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
464 +}
465 +EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
466 +
467 +u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
468 +{
469 +       return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
470 +}
471 +
472 +u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
473 +{
474 +       return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
475 +}
476 +
477 +#ifdef CONFIG_BCMA_DRIVER_MIPS
478 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
479 +{
480 +       unsigned int irq;
481 +       u32 baud_base;
482 +       u32 i;
483 +       unsigned int ccrev = cc->core->id.rev;
484 +       struct bcma_serial_port *ports = cc->serial_ports;
485 +
486 +       if (ccrev >= 11 && ccrev != 15) {
487 +               /* Fixed ALP clock */
488 +               baud_base = bcma_pmu_alp_clock(cc);
489 +               if (ccrev >= 21) {
490 +                       /* Turn off UART clock before switching clocksource. */
491 +                       bcma_cc_write32(cc, BCMA_CC_CORECTL,
492 +                                      bcma_cc_read32(cc, BCMA_CC_CORECTL)
493 +                                      & ~BCMA_CC_CORECTL_UARTCLKEN);
494 +               }
495 +               /* Set the override bit so we don't divide it */
496 +               bcma_cc_write32(cc, BCMA_CC_CORECTL,
497 +                              bcma_cc_read32(cc, BCMA_CC_CORECTL)
498 +                              | BCMA_CC_CORECTL_UARTCLK0);
499 +               if (ccrev >= 21) {
500 +                       /* Re-enable the UART clock. */
501 +                       bcma_cc_write32(cc, BCMA_CC_CORECTL,
502 +                                      bcma_cc_read32(cc, BCMA_CC_CORECTL)
503 +                                      | BCMA_CC_CORECTL_UARTCLKEN);
504 +               }
505 +       } else {
506 +               pr_err("serial not supported on this device ccrev: 0x%x\n",
507 +                      ccrev);
508 +               return;
509 +       }
510 +
511 +       irq = bcma_core_mips_irq(cc->core);
512 +
513 +       /* Determine the registers of the UARTs */
514 +       cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
515 +       for (i = 0; i < cc->nr_serial_ports; i++) {
516 +               ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
517 +                               (i * 256);
518 +               ports[i].irq = irq;
519 +               ports[i].baud_base = baud_base;
520 +               ports[i].reg_shift = 0;
521 +       }
522 +}
523 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
524 --- /dev/null
525 +++ b/drivers/bcma/driver_chipcommon_pmu.c
526 @@ -0,0 +1,310 @@
527 +/*
528 + * Broadcom specific AMBA
529 + * ChipCommon Power Management Unit driver
530 + *
531 + * Copyright 2009, Michael Buesch <m@bues.ch>
532 + * Copyright 2007, Broadcom Corporation
533 + *
534 + * Licensed under the GNU/GPL. See COPYING for details.
535 + */
536 +
537 +#include "bcma_private.h"
538 +#include <linux/bcma/bcma.h>
539 +
540 +static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
541 +{
542 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
543 +       bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
544 +       return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
545 +}
546 +
547 +void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
548 +{
549 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
550 +       bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
551 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
552 +}
553 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_write);
554 +
555 +void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
556 +                            u32 set)
557 +{
558 +       bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
559 +       bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
560 +       bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set);
561 +}
562 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset);
563 +
564 +void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
565 +                                u32 offset, u32 mask, u32 set)
566 +{
567 +       bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
568 +       bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
569 +       bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set);
570 +}
571 +EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset);
572 +
573 +void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
574 +                               u32 set)
575 +{
576 +       bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset);
577 +       bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR);
578 +       bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set);
579 +}
580 +EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
581 +
582 +static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
583 +{
584 +       struct bcma_bus *bus = cc->core->bus;
585 +
586 +       switch (bus->chipinfo.id) {
587 +       case 0x4313:
588 +       case 0x4331:
589 +       case 43224:
590 +       case 43225:
591 +               break;
592 +       default:
593 +               pr_err("PLL init unknown for device 0x%04X\n",
594 +                       bus->chipinfo.id);
595 +       }
596 +}
597 +
598 +static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
599 +{
600 +       struct bcma_bus *bus = cc->core->bus;
601 +       u32 min_msk = 0, max_msk = 0;
602 +
603 +       switch (bus->chipinfo.id) {
604 +       case 0x4313:
605 +               min_msk = 0x200D;
606 +               max_msk = 0xFFFF;
607 +               break;
608 +       case 0x4331:
609 +       case 43224:
610 +       case 43225:
611 +               break;
612 +       default:
613 +               pr_err("PMU resource config unknown for device 0x%04X\n",
614 +                       bus->chipinfo.id);
615 +       }
616 +
617 +       /* Set the resource masks. */
618 +       if (min_msk)
619 +               bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk);
620 +       if (max_msk)
621 +               bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk);
622 +}
623 +
624 +void bcma_pmu_swreg_init(struct bcma_drv_cc *cc)
625 +{
626 +       struct bcma_bus *bus = cc->core->bus;
627 +
628 +       switch (bus->chipinfo.id) {
629 +       case 0x4313:
630 +       case 0x4331:
631 +       case 43224:
632 +       case 43225:
633 +               break;
634 +       default:
635 +               pr_err("PMU switch/regulators init unknown for device "
636 +                       "0x%04X\n", bus->chipinfo.id);
637 +       }
638 +}
639 +
640 +/* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
641 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
642 +{
643 +       struct bcma_bus *bus = cc->core->bus;
644 +       u32 val;
645 +
646 +       val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL);
647 +       if (enable) {
648 +               val |= BCMA_CHIPCTL_4331_EXTPA_EN;
649 +               if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
650 +                       val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
651 +       } else {
652 +               val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
653 +               val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
654 +       }
655 +       bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
656 +}
657 +
658 +void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
659 +{
660 +       struct bcma_bus *bus = cc->core->bus;
661 +
662 +       switch (bus->chipinfo.id) {
663 +       case 0x4313:
664 +               bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
665 +               break;
666 +       case 0x4331:
667 +               /* BCM4331 workaround is SPROM-related, we put it in sprom.c */
668 +               break;
669 +       case 43224:
670 +               if (bus->chipinfo.rev == 0) {
671 +                       pr_err("Workarounds for 43224 rev 0 not fully "
672 +                               "implemented\n");
673 +                       bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x00F000F0);
674 +               } else {
675 +                       bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
676 +               }
677 +               break;
678 +       case 43225:
679 +               break;
680 +       default:
681 +               pr_err("Workarounds unknown for device 0x%04X\n",
682 +                       bus->chipinfo.id);
683 +       }
684 +}
685 +
686 +void bcma_pmu_init(struct bcma_drv_cc *cc)
687 +{
688 +       u32 pmucap;
689 +
690 +       pmucap = bcma_cc_read32(cc, BCMA_CC_PMU_CAP);
691 +       cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION);
692 +
693 +       pr_debug("Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev,
694 +                pmucap);
695 +
696 +       if (cc->pmu.rev == 1)
697 +               bcma_cc_mask32(cc, BCMA_CC_PMU_CTL,
698 +                             ~BCMA_CC_PMU_CTL_NOILPONW);
699 +       else
700 +               bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
701 +                            BCMA_CC_PMU_CTL_NOILPONW);
702 +
703 +       if (cc->core->id.id == 0x4329 && cc->core->id.rev == 2)
704 +               pr_err("Fix for 4329b0 bad LPOM state not implemented!\n");
705 +
706 +       bcma_pmu_pll_init(cc);
707 +       bcma_pmu_resources_init(cc);
708 +       bcma_pmu_swreg_init(cc);
709 +       bcma_pmu_workarounds(cc);
710 +}
711 +
712 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
713 +{
714 +       struct bcma_bus *bus = cc->core->bus;
715 +
716 +       switch (bus->chipinfo.id) {
717 +       case 0x4716:
718 +       case 0x4748:
719 +       case 47162:
720 +       case 0x4313:
721 +       case 0x5357:
722 +       case 0x4749:
723 +       case 53572:
724 +               /* always 20Mhz */
725 +               return 20000 * 1000;
726 +       case 0x5356:
727 +       case 0x5300:
728 +               /* always 25Mhz */
729 +               return 25000 * 1000;
730 +       default:
731 +               pr_warn("No ALP clock specified for %04X device, "
732 +                       "pmu rev. %d, using default %d Hz\n",
733 +                       bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
734 +       }
735 +       return BCMA_CC_PMU_ALP_CLOCK;
736 +}
737 +
738 +/* Find the output of the "m" pll divider given pll controls that start with
739 + * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
740 + */
741 +static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
742 +{
743 +       u32 tmp, div, ndiv, p1, p2, fc;
744 +       struct bcma_bus *bus = cc->core->bus;
745 +
746 +       BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
747 +
748 +       BUG_ON(!m || m > 4);
749 +
750 +       if (bus->chipinfo.id == 0x5357 || bus->chipinfo.id == 0x4749) {
751 +               /* Detect failure in clock setting */
752 +               tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
753 +               if (tmp & 0x40000)
754 +                       return 133 * 1000000;
755 +       }
756 +
757 +       tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
758 +       p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
759 +       p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
760 +
761 +       tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
762 +       div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
763 +               BCMA_CC_PPL_MDIV_MASK;
764 +
765 +       tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
766 +       ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
767 +
768 +       /* Do calculation in Mhz */
769 +       fc = bcma_pmu_alp_clock(cc) / 1000000;
770 +       fc = (p1 * ndiv * fc) / p2;
771 +
772 +       /* Return clock in Hertz */
773 +       return (fc / div) * 1000000;
774 +}
775 +
776 +/* query bus clock frequency for PMU-enabled chipcommon */
777 +u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
778 +{
779 +       struct bcma_bus *bus = cc->core->bus;
780 +
781 +       switch (bus->chipinfo.id) {
782 +       case 0x4716:
783 +       case 0x4748:
784 +       case 47162:
785 +               return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
786 +                                     BCMA_CC_PMU5_MAINPLL_SSB);
787 +       case 0x5356:
788 +               return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
789 +                                     BCMA_CC_PMU5_MAINPLL_SSB);
790 +       case 0x5357:
791 +       case 0x4749:
792 +               return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
793 +                                     BCMA_CC_PMU5_MAINPLL_SSB);
794 +       case 0x5300:
795 +               return bcma_pmu_clock(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
796 +                                     BCMA_CC_PMU5_MAINPLL_SSB);
797 +       case 53572:
798 +               return 75000000;
799 +       default:
800 +               pr_warn("No backplane clock specified for %04X device, "
801 +                       "pmu rev. %d, using default %d Hz\n",
802 +                       bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
803 +       }
804 +       return BCMA_CC_PMU_HT_CLOCK;
805 +}
806 +
807 +/* query cpu clock frequency for PMU-enabled chipcommon */
808 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
809 +{
810 +       struct bcma_bus *bus = cc->core->bus;
811 +
812 +       if (bus->chipinfo.id == 53572)
813 +               return 300000000;
814 +
815 +       if (cc->pmu.rev >= 5) {
816 +               u32 pll;
817 +               switch (bus->chipinfo.id) {
818 +               case 0x5356:
819 +                       pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
820 +                       break;
821 +               case 0x5357:
822 +               case 0x4749:
823 +                       pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
824 +                       break;
825 +               default:
826 +                       pll = BCMA_CC_PMU4716_MAINPLL_PLL0;
827 +                       break;
828 +               }
829 +
830 +               /* TODO: if (bus->chipinfo.id == 0x5300)
831 +                 return si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); */
832 +               return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
833 +       }
834 +
835 +       return bcma_pmu_get_clockcontrol(cc);
836 +}
837 --- /dev/null
838 +++ b/drivers/bcma/driver_mips.c
839 @@ -0,0 +1,256 @@
840 +/*
841 + * Broadcom specific AMBA
842 + * Broadcom MIPS32 74K core driver
843 + *
844 + * Copyright 2009, Broadcom Corporation
845 + * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
846 + * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
847 + * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
848 + *
849 + * Licensed under the GNU/GPL. See COPYING for details.
850 + */
851 +
852 +#include "bcma_private.h"
853 +
854 +#include <linux/bcma/bcma.h>
855 +
856 +#include <linux/serial.h>
857 +#include <linux/serial_core.h>
858 +#include <linux/serial_reg.h>
859 +#include <linux/time.h>
860 +
861 +/* The 47162a0 hangs when reading MIPS DMP registers registers */
862 +static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
863 +{
864 +       return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
865 +              dev->id.id == BCMA_CORE_MIPS_74K;
866 +}
867 +
868 +/* The 5357b0 hangs when reading USB20H DMP registers */
869 +static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
870 +{
871 +       return (dev->bus->chipinfo.id == 0x5357 ||
872 +               dev->bus->chipinfo.id == 0x4749) &&
873 +              dev->bus->chipinfo.pkg == 11 &&
874 +              dev->id.id == BCMA_CORE_USB20_HOST;
875 +}
876 +
877 +static inline u32 mips_read32(struct bcma_drv_mips *mcore,
878 +                             u16 offset)
879 +{
880 +       return bcma_read32(mcore->core, offset);
881 +}
882 +
883 +static inline void mips_write32(struct bcma_drv_mips *mcore,
884 +                               u16 offset,
885 +                               u32 value)
886 +{
887 +       bcma_write32(mcore->core, offset, value);
888 +}
889 +
890 +static const u32 ipsflag_irq_mask[] = {
891 +       0,
892 +       BCMA_MIPS_IPSFLAG_IRQ1,
893 +       BCMA_MIPS_IPSFLAG_IRQ2,
894 +       BCMA_MIPS_IPSFLAG_IRQ3,
895 +       BCMA_MIPS_IPSFLAG_IRQ4,
896 +};
897 +
898 +static const u32 ipsflag_irq_shift[] = {
899 +       0,
900 +       BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
901 +       BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
902 +       BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
903 +       BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
904 +};
905 +
906 +static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
907 +{
908 +       u32 flag;
909 +
910 +       if (bcma_core_mips_bcm47162a0_quirk(dev))
911 +               return dev->core_index;
912 +       if (bcma_core_mips_bcm5357b0_quirk(dev))
913 +               return dev->core_index;
914 +       flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
915 +
916 +       return flag & 0x1F;
917 +}
918 +
919 +/* Get the MIPS IRQ assignment for a specified device.
920 + * If unassigned, 0 is returned.
921 + */
922 +unsigned int bcma_core_mips_irq(struct bcma_device *dev)
923 +{
924 +       struct bcma_device *mdev = dev->bus->drv_mips.core;
925 +       u32 irqflag;
926 +       unsigned int irq;
927 +
928 +       irqflag = bcma_core_mips_irqflag(dev);
929 +
930 +       for (irq = 1; irq <= 4; irq++)
931 +               if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
932 +                   (1 << irqflag))
933 +                       return irq;
934 +
935 +       return 0;
936 +}
937 +EXPORT_SYMBOL(bcma_core_mips_irq);
938 +
939 +static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
940 +{
941 +       unsigned int oldirq = bcma_core_mips_irq(dev);
942 +       struct bcma_bus *bus = dev->bus;
943 +       struct bcma_device *mdev = bus->drv_mips.core;
944 +       u32 irqflag;
945 +
946 +       irqflag = bcma_core_mips_irqflag(dev);
947 +       BUG_ON(oldirq == 6);
948 +
949 +       dev->irq = irq + 2;
950 +
951 +       /* clear the old irq */
952 +       if (oldirq == 0)
953 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
954 +                           bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
955 +                           ~(1 << irqflag));
956 +       else
957 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
958 +
959 +       /* assign the new one */
960 +       if (irq == 0) {
961 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
962 +                           bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
963 +                           (1 << irqflag));
964 +       } else {
965 +               u32 oldirqflag = bcma_read32(mdev,
966 +                                            BCMA_MIPS_MIPS74K_INTMASK(irq));
967 +               if (oldirqflag) {
968 +                       struct bcma_device *core;
969 +
970 +                       /* backplane irq line is in use, find out who uses
971 +                        * it and set user to irq 0
972 +                        */
973 +                       list_for_each_entry_reverse(core, &bus->cores, list) {
974 +                               if ((1 << bcma_core_mips_irqflag(core)) ==
975 +                                   oldirqflag) {
976 +                                       bcma_core_mips_set_irq(core, 0);
977 +                                       break;
978 +                               }
979 +                       }
980 +               }
981 +               bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
982 +                            1 << irqflag);
983 +       }
984 +
985 +       pr_info("set_irq: core 0x%04x, irq %d => %d\n",
986 +               dev->id.id, oldirq + 2, irq + 2);
987 +}
988 +
989 +static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
990 +{
991 +       int i;
992 +       static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
993 +       printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
994 +       for (i = 0; i <= 6; i++)
995 +               printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
996 +       printk("\n");
997 +}
998 +
999 +static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
1000 +{
1001 +       struct bcma_device *core;
1002 +
1003 +       list_for_each_entry_reverse(core, &bus->cores, list) {
1004 +               bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
1005 +       }
1006 +}
1007 +
1008 +u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
1009 +{
1010 +       struct bcma_bus *bus = mcore->core->bus;
1011 +
1012 +       if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
1013 +               return bcma_pmu_get_clockcpu(&bus->drv_cc);
1014 +
1015 +       pr_err("No PMU available, need this to get the cpu clock\n");
1016 +       return 0;
1017 +}
1018 +EXPORT_SYMBOL(bcma_cpu_clock);
1019 +
1020 +static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
1021 +{
1022 +       struct bcma_bus *bus = mcore->core->bus;
1023 +
1024 +       switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
1025 +       case BCMA_CC_FLASHT_STSER:
1026 +       case BCMA_CC_FLASHT_ATSER:
1027 +               pr_err("Serial flash not supported.\n");
1028 +               break;
1029 +       case BCMA_CC_FLASHT_PARA:
1030 +               pr_info("found parallel flash.\n");
1031 +               bus->drv_cc.pflash.window = 0x1c000000;
1032 +               bus->drv_cc.pflash.window_size = 0x02000000;
1033 +
1034 +               if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
1035 +                    BCMA_CC_FLASH_CFG_DS) == 0)
1036 +                       bus->drv_cc.pflash.buswidth = 1;
1037 +               else
1038 +                       bus->drv_cc.pflash.buswidth = 2;
1039 +               break;
1040 +       default:
1041 +               pr_err("flash not supported.\n");
1042 +       }
1043 +}
1044 +
1045 +void bcma_core_mips_init(struct bcma_drv_mips *mcore)
1046 +{
1047 +       struct bcma_bus *bus;
1048 +       struct bcma_device *core;
1049 +       bus = mcore->core->bus;
1050 +
1051 +       pr_info("Initializing MIPS core...\n");
1052 +
1053 +       if (!mcore->setup_done)
1054 +               mcore->assigned_irqs = 1;
1055 +
1056 +       /* Assign IRQs to all cores on the bus */
1057 +       list_for_each_entry_reverse(core, &bus->cores, list) {
1058 +               int mips_irq;
1059 +               if (core->irq)
1060 +                       continue;
1061 +
1062 +               mips_irq = bcma_core_mips_irq(core);
1063 +               if (mips_irq > 4)
1064 +                       core->irq = 0;
1065 +               else
1066 +                       core->irq = mips_irq + 2;
1067 +               if (core->irq > 5)
1068 +                       continue;
1069 +               switch (core->id.id) {
1070 +               case BCMA_CORE_PCI:
1071 +               case BCMA_CORE_PCIE:
1072 +               case BCMA_CORE_ETHERNET:
1073 +               case BCMA_CORE_ETHERNET_GBIT:
1074 +               case BCMA_CORE_MAC_GBIT:
1075 +               case BCMA_CORE_80211:
1076 +               case BCMA_CORE_USB20_HOST:
1077 +                       /* These devices get their own IRQ line if available,
1078 +                        * the rest goes on IRQ0
1079 +                        */
1080 +                       if (mcore->assigned_irqs <= 4)
1081 +                               bcma_core_mips_set_irq(core,
1082 +                                                      mcore->assigned_irqs++);
1083 +                       break;
1084 +               }
1085 +       }
1086 +       pr_info("IRQ reconfiguration done\n");
1087 +       bcma_core_mips_dump_irq(bus);
1088 +
1089 +       if (mcore->setup_done)
1090 +               return;
1091 +
1092 +       bcma_chipco_serial_init(&bus->drv_cc);
1093 +       bcma_core_mips_flash_detect(mcore);
1094 +       mcore->setup_done = true;
1095 +}
1096 --- /dev/null
1097 +++ b/drivers/bcma/driver_pci.c
1098 @@ -0,0 +1,274 @@
1099 +/*
1100 + * Broadcom specific AMBA
1101 + * PCI Core
1102 + *
1103 + * Copyright 2005, 2011, Broadcom Corporation
1104 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
1105 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
1106 + *
1107 + * Licensed under the GNU/GPL. See COPYING for details.
1108 + */
1109 +
1110 +#include "bcma_private.h"
1111 +#include <linux/bcma/bcma.h>
1112 +
1113 +/**************************************************
1114 + * R/W ops.
1115 + **************************************************/
1116 +
1117 +u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
1118 +{
1119 +       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
1120 +       pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
1121 +       return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA);
1122 +}
1123 +
1124 +static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
1125 +{
1126 +       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
1127 +       pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
1128 +       pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
1129 +}
1130 +
1131 +static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
1132 +{
1133 +       u32 v;
1134 +       int i;
1135 +
1136 +       v = BCMA_CORE_PCI_MDIODATA_START;
1137 +       v |= BCMA_CORE_PCI_MDIODATA_WRITE;
1138 +       v |= (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
1139 +             BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
1140 +       v |= (BCMA_CORE_PCI_MDIODATA_BLK_ADDR <<
1141 +             BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
1142 +       v |= BCMA_CORE_PCI_MDIODATA_TA;
1143 +       v |= (phy << 4);
1144 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
1145 +
1146 +       udelay(10);
1147 +       for (i = 0; i < 200; i++) {
1148 +               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
1149 +               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
1150 +                       break;
1151 +               msleep(1);
1152 +       }
1153 +}
1154 +
1155 +static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
1156 +{
1157 +       int max_retries = 10;
1158 +       u16 ret = 0;
1159 +       u32 v;
1160 +       int i;
1161 +
1162 +       /* enable mdio access to SERDES */
1163 +       v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
1164 +       v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
1165 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
1166 +
1167 +       if (pc->core->id.rev >= 10) {
1168 +               max_retries = 200;
1169 +               bcma_pcie_mdio_set_phy(pc, device);
1170 +               v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
1171 +                    BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
1172 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
1173 +       } else {
1174 +               v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
1175 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
1176 +       }
1177 +
1178 +       v = BCMA_CORE_PCI_MDIODATA_START;
1179 +       v |= BCMA_CORE_PCI_MDIODATA_READ;
1180 +       v |= BCMA_CORE_PCI_MDIODATA_TA;
1181 +
1182 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
1183 +       /* Wait for the device to complete the transaction */
1184 +       udelay(10);
1185 +       for (i = 0; i < max_retries; i++) {
1186 +               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
1187 +               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) {
1188 +                       udelay(10);
1189 +                       ret = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_DATA);
1190 +                       break;
1191 +               }
1192 +               msleep(1);
1193 +       }
1194 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
1195 +       return ret;
1196 +}
1197 +
1198 +static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
1199 +                               u8 address, u16 data)
1200 +{
1201 +       int max_retries = 10;
1202 +       u32 v;
1203 +       int i;
1204 +
1205 +       /* enable mdio access to SERDES */
1206 +       v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
1207 +       v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
1208 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
1209 +
1210 +       if (pc->core->id.rev >= 10) {
1211 +               max_retries = 200;
1212 +               bcma_pcie_mdio_set_phy(pc, device);
1213 +               v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
1214 +                    BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
1215 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
1216 +       } else {
1217 +               v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
1218 +               v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
1219 +       }
1220 +
1221 +       v = BCMA_CORE_PCI_MDIODATA_START;
1222 +       v |= BCMA_CORE_PCI_MDIODATA_WRITE;
1223 +       v |= BCMA_CORE_PCI_MDIODATA_TA;
1224 +       v |= data;
1225 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
1226 +       /* Wait for the device to complete the transaction */
1227 +       udelay(10);
1228 +       for (i = 0; i < max_retries; i++) {
1229 +               v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
1230 +               if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
1231 +                       break;
1232 +               msleep(1);
1233 +       }
1234 +       pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
1235 +}
1236 +
1237 +/**************************************************
1238 + * Workarounds.
1239 + **************************************************/
1240 +
1241 +static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
1242 +{
1243 +       u32 tmp;
1244 +
1245 +       tmp = bcma_pcie_read(pc, BCMA_CORE_PCI_PLP_STATUSREG);
1246 +       if (tmp & BCMA_CORE_PCI_PLP_POLARITYINV_STAT)
1247 +               return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE |
1248 +                      BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY;
1249 +       else
1250 +               return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE;
1251 +}
1252 +
1253 +static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
1254 +{
1255 +       u16 tmp;
1256 +
1257 +       bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_RX,
1258 +                            BCMA_CORE_PCI_SERDES_RX_CTRL,
1259 +                            bcma_pcicore_polarity_workaround(pc));
1260 +       tmp = bcma_pcie_mdio_read(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
1261 +                                 BCMA_CORE_PCI_SERDES_PLL_CTRL);
1262 +       if (tmp & BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN)
1263 +               bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
1264 +                                    BCMA_CORE_PCI_SERDES_PLL_CTRL,
1265 +                                    tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN);
1266 +}
1267 +
1268 +static void bcma_core_pci_fixcfg(struct bcma_drv_pci *pc)
1269 +{
1270 +       struct bcma_device *core = pc->core;
1271 +       u16 val16, core_index;
1272 +       uint regoff;
1273 +
1274 +       regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_PI_OFFSET);
1275 +       core_index = (u16)core->core_index;
1276 +
1277 +       val16 = pcicore_read16(pc, regoff);
1278 +       if (((val16 & BCMA_CORE_PCI_SPROM_PI_MASK) >> BCMA_CORE_PCI_SPROM_PI_SHIFT)
1279 +            != core_index) {
1280 +               val16 = (core_index << BCMA_CORE_PCI_SPROM_PI_SHIFT) |
1281 +                       (val16 & ~BCMA_CORE_PCI_SPROM_PI_MASK);
1282 +               pcicore_write16(pc, regoff, val16);
1283 +       }
1284 +}
1285 +
1286 +/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
1287 +/* Needs to happen when coming out of 'standby'/'hibernate' */
1288 +static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc)
1289 +{
1290 +       u16 val16;
1291 +       uint regoff;
1292 +
1293 +       regoff = BCMA_CORE_PCI_SPROM(BCMA_CORE_PCI_SPROM_MISC_CONFIG);
1294 +
1295 +       val16 = pcicore_read16(pc, regoff);
1296 +
1297 +       if (!(val16 & BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST)) {
1298 +               val16 |= BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST;
1299 +               pcicore_write16(pc, regoff, val16);
1300 +       }
1301 +}
1302 +
1303 +/**************************************************
1304 + * Init.
1305 + **************************************************/
1306 +
1307 +static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
1308 +{
1309 +       bcma_core_pci_fixcfg(pc);
1310 +       bcma_pcicore_serdes_workaround(pc);
1311 +       bcma_core_pci_config_fixup(pc);
1312 +}
1313 +
1314 +void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc)
1315 +{
1316 +       if (pc->setup_done)
1317 +               return;
1318 +
1319 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
1320 +       pc->hostmode = bcma_core_pci_is_in_hostmode(pc);
1321 +       if (pc->hostmode)
1322 +               bcma_core_pci_hostmode_init(pc);
1323 +#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
1324 +
1325 +       if (!pc->hostmode)
1326 +               bcma_core_pci_clientmode_init(pc);
1327 +}
1328 +
1329 +int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
1330 +                         bool enable)
1331 +{
1332 +       struct pci_dev *pdev = pc->core->bus->host_pci;
1333 +       u32 coremask, tmp;
1334 +       int err = 0;
1335 +
1336 +       if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
1337 +               /* This bcma device is not on a PCI host-bus. So the IRQs are
1338 +                * not routed through the PCI core.
1339 +                * So we must not enable routing through the PCI core. */
1340 +               goto out;
1341 +       }
1342 +
1343 +       err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
1344 +       if (err)
1345 +               goto out;
1346 +
1347 +       coremask = BIT(core->core_index) << 8;
1348 +       if (enable)
1349 +               tmp |= coremask;
1350 +       else
1351 +               tmp &= ~coremask;
1352 +
1353 +       err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp);
1354 +
1355 +out:
1356 +       return err;
1357 +}
1358 +EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
1359 +
1360 +void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend)
1361 +{
1362 +       u32 w;
1363 +
1364 +       w = bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
1365 +       if (extend)
1366 +               w |= BCMA_CORE_PCI_ASPMTIMER_EXTEND;
1367 +       else
1368 +               w &= ~BCMA_CORE_PCI_ASPMTIMER_EXTEND;
1369 +       bcma_pcie_write(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG, w);
1370 +       bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
1371 +}
1372 +EXPORT_SYMBOL_GPL(bcma_core_pci_extend_L1timer);
1373 --- /dev/null
1374 +++ b/drivers/bcma/driver_pci_host.c
1375 @@ -0,0 +1,588 @@
1376 +/*
1377 + * Broadcom specific AMBA
1378 + * PCI Core in hostmode
1379 + *
1380 + * Copyright 2005 - 2011, Broadcom Corporation
1381 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
1382 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
1383 + *
1384 + * Licensed under the GNU/GPL. See COPYING for details.
1385 + */
1386 +
1387 +#include "bcma_private.h"
1388 +#include <linux/pci.h>
1389 +#include <linux/bcma/bcma.h>
1390 +#include <asm/paccess.h>
1391 +
1392 +/* Probe a 32bit value on the bus and catch bus exceptions.
1393 + * Returns nonzero on a bus exception.
1394 + * This is MIPS specific */
1395 +#define mips_busprobe32(val, addr)     get_dbe((val), ((u32 *)(addr)))
1396 +
1397 +/* Assume one-hot slot wiring */
1398 +#define BCMA_PCI_SLOT_MAX      16
1399 +#define        PCI_CONFIG_SPACE_SIZE   256
1400 +
1401 +bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
1402 +{
1403 +       struct bcma_bus *bus = pc->core->bus;
1404 +       u16 chipid_top;
1405 +       u32 tmp;
1406 +
1407 +       chipid_top = (bus->chipinfo.id & 0xFF00);
1408 +       if (chipid_top != 0x4700 &&
1409 +           chipid_top != 0x5300)
1410 +               return false;
1411 +
1412 +       if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) {
1413 +               pr_info("This PCI core is disabled and not working\n");
1414 +               return false;
1415 +       }
1416 +
1417 +       bcma_core_enable(pc->core, 0);
1418 +
1419 +       return !mips_busprobe32(tmp, pc->core->io_addr);
1420 +}
1421 +
1422 +static u32 bcma_pcie_read_config(struct bcma_drv_pci *pc, u32 address)
1423 +{
1424 +       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
1425 +       pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
1426 +       return pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_DATA);
1427 +}
1428 +
1429 +static void bcma_pcie_write_config(struct bcma_drv_pci *pc, u32 address,
1430 +                                  u32 data)
1431 +{
1432 +       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
1433 +       pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
1434 +       pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_DATA, data);
1435 +}
1436 +
1437 +static u32 bcma_get_cfgspace_addr(struct bcma_drv_pci *pc, unsigned int dev,
1438 +                            unsigned int func, unsigned int off)
1439 +{
1440 +       u32 addr = 0;
1441 +
1442 +       /* Issue config commands only when the data link is up (atleast
1443 +        * one external pcie device is present).
1444 +        */
1445 +       if (dev >= 2 || !(bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_LSREG)
1446 +                         & BCMA_CORE_PCI_DLLP_LSREG_LINKUP))
1447 +               goto out;
1448 +
1449 +       /* Type 0 transaction */
1450 +       /* Slide the PCI window to the appropriate slot */
1451 +       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
1452 +       /* Calculate the address */
1453 +       addr = pc->host_controller->host_cfg_addr;
1454 +       addr |= (dev << BCMA_CORE_PCI_CFG_SLOT_SHIFT);
1455 +       addr |= (func << BCMA_CORE_PCI_CFG_FUN_SHIFT);
1456 +       addr |= (off & ~3);
1457 +
1458 +out:
1459 +       return addr;
1460 +}
1461 +
1462 +static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev,
1463 +                                 unsigned int func, unsigned int off,
1464 +                                 void *buf, int len)
1465 +{
1466 +       int err = -EINVAL;
1467 +       u32 addr, val;
1468 +       void __iomem *mmio = 0;
1469 +
1470 +       WARN_ON(!pc->hostmode);
1471 +       if (unlikely(len != 1 && len != 2 && len != 4))
1472 +               goto out;
1473 +       if (dev == 0) {
1474 +               /* we support only two functions on device 0 */
1475 +               if (func > 1)
1476 +                       return -EINVAL;
1477 +
1478 +               /* accesses to config registers with offsets >= 256
1479 +                * requires indirect access.
1480 +                */
1481 +               if (off >= PCI_CONFIG_SPACE_SIZE) {
1482 +                       addr = (func << 12);
1483 +                       addr |= (off & 0x0FFF);
1484 +                       val = bcma_pcie_read_config(pc, addr);
1485 +               } else {
1486 +                       addr = BCMA_CORE_PCI_PCICFG0;
1487 +                       addr |= (func << 8);
1488 +                       addr |= (off & 0xfc);
1489 +                       val = pcicore_read32(pc, addr);
1490 +               }
1491 +       } else {
1492 +               addr = bcma_get_cfgspace_addr(pc, dev, func, off);
1493 +               if (unlikely(!addr))
1494 +                       goto out;
1495 +               err = -ENOMEM;
1496 +               mmio = ioremap_nocache(addr, sizeof(val));
1497 +               if (!mmio)
1498 +                       goto out;
1499 +
1500 +               if (mips_busprobe32(val, mmio)) {
1501 +                       val = 0xffffffff;
1502 +                       goto unmap;
1503 +               }
1504 +
1505 +               val = readl(mmio);
1506 +       }
1507 +       val >>= (8 * (off & 3));
1508 +
1509 +       switch (len) {
1510 +       case 1:
1511 +               *((u8 *)buf) = (u8)val;
1512 +               break;
1513 +       case 2:
1514 +               *((u16 *)buf) = (u16)val;
1515 +               break;
1516 +       case 4:
1517 +               *((u32 *)buf) = (u32)val;
1518 +               break;
1519 +       }
1520 +       err = 0;
1521 +unmap:
1522 +       if (mmio)
1523 +               iounmap(mmio);
1524 +out:
1525 +       return err;
1526 +}
1527 +
1528 +static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
1529 +                                  unsigned int func, unsigned int off,
1530 +                                  const void *buf, int len)
1531 +{
1532 +       int err = -EINVAL;
1533 +       u32 addr = 0, val = 0;
1534 +       void __iomem *mmio = 0;
1535 +       u16 chipid = pc->core->bus->chipinfo.id;
1536 +
1537 +       WARN_ON(!pc->hostmode);
1538 +       if (unlikely(len != 1 && len != 2 && len != 4))
1539 +               goto out;
1540 +       if (dev == 0) {
1541 +               /* accesses to config registers with offsets >= 256
1542 +                * requires indirect access.
1543 +                */
1544 +               if (off < PCI_CONFIG_SPACE_SIZE) {
1545 +                       addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
1546 +                       addr |= (func << 8);
1547 +                       addr |= (off & 0xfc);
1548 +                       mmio = ioremap_nocache(addr, sizeof(val));
1549 +                       if (!mmio)
1550 +                               goto out;
1551 +               }
1552 +       } else {
1553 +               addr = bcma_get_cfgspace_addr(pc, dev, func, off);
1554 +               if (unlikely(!addr))
1555 +                       goto out;
1556 +               err = -ENOMEM;
1557 +               mmio = ioremap_nocache(addr, sizeof(val));
1558 +               if (!mmio)
1559 +                       goto out;
1560 +
1561 +               if (mips_busprobe32(val, mmio)) {
1562 +                       val = 0xffffffff;
1563 +                       goto unmap;
1564 +               }
1565 +       }
1566 +
1567 +       switch (len) {
1568 +       case 1:
1569 +               val = readl(mmio);
1570 +               val &= ~(0xFF << (8 * (off & 3)));
1571 +               val |= *((const u8 *)buf) << (8 * (off & 3));
1572 +               break;
1573 +       case 2:
1574 +               val = readl(mmio);
1575 +               val &= ~(0xFFFF << (8 * (off & 3)));
1576 +               val |= *((const u16 *)buf) << (8 * (off & 3));
1577 +               break;
1578 +       case 4:
1579 +               val = *((const u32 *)buf);
1580 +               break;
1581 +       }
1582 +       if (dev == 0 && !addr) {
1583 +               /* accesses to config registers with offsets >= 256
1584 +                * requires indirect access.
1585 +                */
1586 +               addr = (func << 12);
1587 +               addr |= (off & 0x0FFF);
1588 +               bcma_pcie_write_config(pc, addr, val);
1589 +       } else {
1590 +               writel(val, mmio);
1591 +
1592 +               if (chipid == 0x4716 || chipid == 0x4748)
1593 +                       readl(mmio);
1594 +       }
1595 +
1596 +       err = 0;
1597 +unmap:
1598 +       if (mmio)
1599 +               iounmap(mmio);
1600 +out:
1601 +       return err;
1602 +}
1603 +
1604 +static int bcma_core_pci_hostmode_read_config(struct pci_bus *bus,
1605 +                                             unsigned int devfn,
1606 +                                             int reg, int size, u32 *val)
1607 +{
1608 +       unsigned long flags;
1609 +       int err;
1610 +       struct bcma_drv_pci *pc;
1611 +       struct bcma_drv_pci_host *pc_host;
1612 +
1613 +       pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
1614 +       pc = pc_host->pdev;
1615 +
1616 +       spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
1617 +       err = bcma_extpci_read_config(pc, PCI_SLOT(devfn),
1618 +                                    PCI_FUNC(devfn), reg, val, size);
1619 +       spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
1620 +
1621 +       return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
1622 +}
1623 +
1624 +static int bcma_core_pci_hostmode_write_config(struct pci_bus *bus,
1625 +                                              unsigned int devfn,
1626 +                                              int reg, int size, u32 val)
1627 +{
1628 +       unsigned long flags;
1629 +       int err;
1630 +       struct bcma_drv_pci *pc;
1631 +       struct bcma_drv_pci_host *pc_host;
1632 +
1633 +       pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
1634 +       pc = pc_host->pdev;
1635 +
1636 +       spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
1637 +       err = bcma_extpci_write_config(pc, PCI_SLOT(devfn),
1638 +                                     PCI_FUNC(devfn), reg, &val, size);
1639 +       spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
1640 +
1641 +       return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
1642 +}
1643 +
1644 +/* return cap_offset if requested capability exists in the PCI config space */
1645 +static u8 __devinit bcma_find_pci_capability(struct bcma_drv_pci *pc,
1646 +                                            unsigned int dev,
1647 +                                            unsigned int func, u8 req_cap_id,
1648 +                                            unsigned char *buf, u32 *buflen)
1649 +{
1650 +       u8 cap_id;
1651 +       u8 cap_ptr = 0;
1652 +       u32 bufsize;
1653 +       u8 byte_val;
1654 +
1655 +       /* check for Header type 0 */
1656 +       bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val,
1657 +                               sizeof(u8));
1658 +       if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
1659 +               return cap_ptr;
1660 +
1661 +       /* check if the capability pointer field exists */
1662 +       bcma_extpci_read_config(pc, dev, func, PCI_STATUS, &byte_val,
1663 +                               sizeof(u8));
1664 +       if (!(byte_val & PCI_STATUS_CAP_LIST))
1665 +               return cap_ptr;
1666 +
1667 +       /* check if the capability pointer is 0x00 */
1668 +       bcma_extpci_read_config(pc, dev, func, PCI_CAPABILITY_LIST, &cap_ptr,
1669 +                               sizeof(u8));
1670 +       if (cap_ptr == 0x00)
1671 +               return cap_ptr;
1672 +
1673 +       /* loop thr'u the capability list and see if the requested capabilty
1674 +        * exists */
1675 +       bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id, sizeof(u8));
1676 +       while (cap_id != req_cap_id) {
1677 +               bcma_extpci_read_config(pc, dev, func, cap_ptr + 1, &cap_ptr,
1678 +                                       sizeof(u8));
1679 +               if (cap_ptr == 0x00)
1680 +                       return cap_ptr;
1681 +               bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id,
1682 +                                       sizeof(u8));
1683 +       }
1684 +
1685 +       /* found the caller requested capability */
1686 +       if ((buf != NULL) && (buflen != NULL)) {
1687 +               u8 cap_data;
1688 +
1689 +               bufsize = *buflen;
1690 +               if (!bufsize)
1691 +                       return cap_ptr;
1692 +
1693 +               *buflen = 0;
1694 +
1695 +               /* copy the cpability data excluding cap ID and next ptr */
1696 +               cap_data = cap_ptr + 2;
1697 +               if ((bufsize + cap_data)  > PCI_CONFIG_SPACE_SIZE)
1698 +                       bufsize = PCI_CONFIG_SPACE_SIZE - cap_data;
1699 +               *buflen = bufsize;
1700 +               while (bufsize--) {
1701 +                       bcma_extpci_read_config(pc, dev, func, cap_data, buf,
1702 +                                               sizeof(u8));
1703 +                       cap_data++;
1704 +                       buf++;
1705 +               }
1706 +       }
1707 +
1708 +       return cap_ptr;
1709 +}
1710 +
1711 +/* If the root port is capable of returning Config Request
1712 + * Retry Status (CRS) Completion Status to software then
1713 + * enable the feature.
1714 + */
1715 +static void __devinit bcma_core_pci_enable_crs(struct bcma_drv_pci *pc)
1716 +{
1717 +       u8 cap_ptr, root_ctrl, root_cap, dev;
1718 +       u16 val16;
1719 +       int i;
1720 +
1721 +       cap_ptr = bcma_find_pci_capability(pc, 0, 0, PCI_CAP_ID_EXP, NULL,
1722 +                                          NULL);
1723 +       root_cap = cap_ptr + PCI_EXP_RTCAP;
1724 +       bcma_extpci_read_config(pc, 0, 0, root_cap, &val16, sizeof(u16));
1725 +       if (val16 & BCMA_CORE_PCI_RC_CRS_VISIBILITY) {
1726 +               /* Enable CRS software visibility */
1727 +               root_ctrl = cap_ptr + PCI_EXP_RTCTL;
1728 +               val16 = PCI_EXP_RTCTL_CRSSVE;
1729 +               bcma_extpci_read_config(pc, 0, 0, root_ctrl, &val16,
1730 +                                       sizeof(u16));
1731 +
1732 +               /* Initiate a configuration request to read the vendor id
1733 +                * field of the device function's config space header after
1734 +                * 100 ms wait time from the end of Reset. If the device is
1735 +                * not done with its internal initialization, it must at
1736 +                * least return a completion TLP, with a completion status
1737 +                * of "Configuration Request Retry Status (CRS)". The root
1738 +                * complex must complete the request to the host by returning
1739 +                * a read-data value of 0001h for the Vendor ID field and
1740 +                * all 1s for any additional bytes included in the request.
1741 +                * Poll using the config reads for max wait time of 1 sec or
1742 +                * until we receive the successful completion status. Repeat
1743 +                * the procedure for all the devices.
1744 +                */
1745 +               for (dev = 1; dev < BCMA_PCI_SLOT_MAX; dev++) {
1746 +                       for (i = 0; i < 100000; i++) {
1747 +                               bcma_extpci_read_config(pc, dev, 0,
1748 +                                                       PCI_VENDOR_ID, &val16,
1749 +                                                       sizeof(val16));
1750 +                               if (val16 != 0x1)
1751 +                                       break;
1752 +                               udelay(10);
1753 +                       }
1754 +                       if (val16 == 0x1)
1755 +                               pr_err("PCI: Broken device in slot %d\n", dev);
1756 +               }
1757 +       }
1758 +}
1759 +
1760 +void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
1761 +{
1762 +       struct bcma_bus *bus = pc->core->bus;
1763 +       struct bcma_drv_pci_host *pc_host;
1764 +       u32 tmp;
1765 +       u32 pci_membase_1G;
1766 +       unsigned long io_map_base;
1767 +
1768 +       pr_info("PCIEcore in host mode found\n");
1769 +
1770 +       pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL);
1771 +       if (!pc_host)  {
1772 +               pr_err("can not allocate memory");
1773 +               return;
1774 +       }
1775 +
1776 +       pc->host_controller = pc_host;
1777 +       pc_host->pci_controller.io_resource = &pc_host->io_resource;
1778 +       pc_host->pci_controller.mem_resource = &pc_host->mem_resource;
1779 +       pc_host->pci_controller.pci_ops = &pc_host->pci_ops;
1780 +       pc_host->pdev = pc;
1781 +
1782 +       pci_membase_1G = BCMA_SOC_PCI_DMA;
1783 +       pc_host->host_cfg_addr = BCMA_SOC_PCI_CFG;
1784 +
1785 +       pc_host->pci_ops.read = bcma_core_pci_hostmode_read_config;
1786 +       pc_host->pci_ops.write = bcma_core_pci_hostmode_write_config;
1787 +
1788 +       pc_host->mem_resource.name = "BCMA PCIcore external memory",
1789 +       pc_host->mem_resource.start = BCMA_SOC_PCI_DMA;
1790 +       pc_host->mem_resource.end = BCMA_SOC_PCI_DMA + BCMA_SOC_PCI_DMA_SZ - 1;
1791 +       pc_host->mem_resource.flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED;
1792 +
1793 +       pc_host->io_resource.name = "BCMA PCIcore external I/O",
1794 +       pc_host->io_resource.start = 0x100;
1795 +       pc_host->io_resource.end = 0x7FF;
1796 +       pc_host->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED;
1797 +
1798 +       /* Reset RC */
1799 +       udelay(3000);
1800 +       pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE);
1801 +       udelay(1000);
1802 +       pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST |
1803 +                       BCMA_CORE_PCI_CTL_RST_OE);
1804 +
1805 +       /* 64 MB I/O access window. On 4716, use
1806 +        * sbtopcie0 to access the device registers. We
1807 +        * can't use address match 2 (1 GB window) region
1808 +        * as mips can't generate 64-bit address on the
1809 +        * backplane.
1810 +        */
1811 +       if (bus->chipinfo.id == 0x4716 || bus->chipinfo.id == 0x4748) {
1812 +               pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
1813 +               pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
1814 +                                           BCMA_SOC_PCI_MEM_SZ - 1;
1815 +               pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
1816 +                               BCMA_CORE_PCI_SBTOPCI_MEM | BCMA_SOC_PCI_MEM);
1817 +       } else if (bus->chipinfo.id == 0x5300) {
1818 +               tmp = BCMA_CORE_PCI_SBTOPCI_MEM;
1819 +               tmp |= BCMA_CORE_PCI_SBTOPCI_PREF;
1820 +               tmp |= BCMA_CORE_PCI_SBTOPCI_BURST;
1821 +               if (pc->core->core_unit == 0) {
1822 +                       pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
1823 +                       pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
1824 +                                                   BCMA_SOC_PCI_MEM_SZ - 1;
1825 +                       pci_membase_1G = BCMA_SOC_PCIE_DMA_H32;
1826 +                       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
1827 +                                       tmp | BCMA_SOC_PCI_MEM);
1828 +               } else if (pc->core->core_unit == 1) {
1829 +                       pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM;
1830 +                       pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM +
1831 +                                                   BCMA_SOC_PCI_MEM_SZ - 1;
1832 +                       pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32;
1833 +                       pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG;
1834 +                       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
1835 +                                       tmp | BCMA_SOC_PCI1_MEM);
1836 +               }
1837 +       } else
1838 +               pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
1839 +                               BCMA_CORE_PCI_SBTOPCI_IO);
1840 +
1841 +       /* 64 MB configuration access window */
1842 +       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
1843 +
1844 +       /* 1 GB memory access window */
1845 +       pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI2,
1846 +                       BCMA_CORE_PCI_SBTOPCI_MEM | pci_membase_1G);
1847 +
1848 +
1849 +       /* As per PCI Express Base Spec 1.1 we need to wait for
1850 +        * at least 100 ms from the end of a reset (cold/warm/hot)
1851 +        * before issuing configuration requests to PCI Express
1852 +        * devices.
1853 +        */
1854 +       udelay(100000);
1855 +
1856 +       bcma_core_pci_enable_crs(pc);
1857 +
1858 +       /* Enable PCI bridge BAR0 memory & master access */
1859 +       tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
1860 +       bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp));
1861 +
1862 +       /* Enable PCI interrupts */
1863 +       pcicore_write32(pc, BCMA_CORE_PCI_IMASK, BCMA_CORE_PCI_IMASK_INTA);
1864 +
1865 +       /* Ok, ready to run, register it to the system.
1866 +        * The following needs change, if we want to port hostmode
1867 +        * to non-MIPS platform. */
1868 +       io_map_base = (unsigned long)ioremap_nocache(pc_host->mem_resource.start,
1869 +                                                    resource_size(&pc_host->mem_resource));
1870 +       pc_host->pci_controller.io_map_base = io_map_base;
1871 +       set_io_port_base(pc_host->pci_controller.io_map_base);
1872 +       /* Give some time to the PCI controller to configure itself with the new
1873 +        * values. Not waiting at this point causes crashes of the machine. */
1874 +       mdelay(10);
1875 +       register_pci_controller(&pc_host->pci_controller);
1876 +       return;
1877 +}
1878 +
1879 +/* Early PCI fixup for a device on the PCI-core bridge. */
1880 +static void bcma_core_pci_fixup_pcibridge(struct pci_dev *dev)
1881 +{
1882 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
1883 +               /* This is not a device on the PCI-core bridge. */
1884 +               return;
1885 +       }
1886 +       if (PCI_SLOT(dev->devfn) != 0)
1887 +               return;
1888 +
1889 +       pr_info("PCI: Fixing up bridge %s\n", pci_name(dev));
1890 +
1891 +       /* Enable PCI bridge bus mastering and memory space */
1892 +       pci_set_master(dev);
1893 +       if (pcibios_enable_device(dev, ~0) < 0) {
1894 +               pr_err("PCI: BCMA bridge enable failed\n");
1895 +               return;
1896 +       }
1897 +
1898 +       /* Enable PCI bridge BAR1 prefetch and burst */
1899 +       pci_write_config_dword(dev, BCMA_PCI_BAR1_CONTROL, 3);
1900 +}
1901 +DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_pcibridge);
1902 +
1903 +/* Early PCI fixup for all PCI-cores to set the correct memory address. */
1904 +static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
1905 +{
1906 +       struct resource *res;
1907 +       int pos;
1908 +
1909 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
1910 +               /* This is not a device on the PCI-core bridge. */
1911 +               return;
1912 +       }
1913 +       if (PCI_SLOT(dev->devfn) == 0)
1914 +               return;
1915 +
1916 +       pr_info("PCI: Fixing up addresses %s\n", pci_name(dev));
1917 +
1918 +       for (pos = 0; pos < 6; pos++) {
1919 +               res = &dev->resource[pos];
1920 +               if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM))
1921 +                       pci_assign_resource(dev, pos);
1922 +       }
1923 +}
1924 +DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses);
1925 +
1926 +/* This function is called when doing a pci_enable_device().
1927 + * We must first check if the device is a device on the PCI-core bridge. */
1928 +int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
1929 +{
1930 +       struct bcma_drv_pci_host *pc_host;
1931 +
1932 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
1933 +               /* This is not a device on the PCI-core bridge. */
1934 +               return -ENODEV;
1935 +       }
1936 +       pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
1937 +                              pci_ops);
1938 +
1939 +       pr_info("PCI: Fixing up device %s\n", pci_name(dev));
1940 +
1941 +       /* Fix up interrupt lines */
1942 +       dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2;
1943 +       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
1944 +
1945 +       return 0;
1946 +}
1947 +EXPORT_SYMBOL(bcma_core_pci_plat_dev_init);
1948 +
1949 +/* PCI device IRQ mapping. */
1950 +int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev)
1951 +{
1952 +       struct bcma_drv_pci_host *pc_host;
1953 +
1954 +       if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
1955 +               /* This is not a device on the PCI-core bridge. */
1956 +               return -ENODEV;
1957 +       }
1958 +
1959 +       pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
1960 +                              pci_ops);
1961 +       return bcma_core_mips_irq(pc_host->pdev->core) + 2;
1962 +}
1963 +EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq);
1964 --- /dev/null
1965 +++ b/drivers/bcma/host_pci.c
1966 @@ -0,0 +1,295 @@
1967 +/*
1968 + * Broadcom specific AMBA
1969 + * PCI Host
1970 + *
1971 + * Licensed under the GNU/GPL. See COPYING for details.
1972 + */
1973 +
1974 +#include "bcma_private.h"
1975 +#include <linux/slab.h>
1976 +#include <linux/bcma/bcma.h>
1977 +#include <linux/pci.h>
1978 +#include <linux/module.h>
1979 +
1980 +static void bcma_host_pci_switch_core(struct bcma_device *core)
1981 +{
1982 +       pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN,
1983 +                              core->addr);
1984 +       pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN2,
1985 +                              core->wrap);
1986 +       core->bus->mapped_core = core;
1987 +       pr_debug("Switched to core: 0x%X\n", core->id.id);
1988 +}
1989 +
1990 +/* Provides access to the requested core. Returns base offset that has to be
1991 + * used. It makes use of fixed windows when possible. */
1992 +static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core)
1993 +{
1994 +       switch (core->id.id) {
1995 +       case BCMA_CORE_CHIPCOMMON:
1996 +               return 3 * BCMA_CORE_SIZE;
1997 +       case BCMA_CORE_PCIE:
1998 +               return 2 * BCMA_CORE_SIZE;
1999 +       }
2000 +
2001 +       if (core->bus->mapped_core != core)
2002 +               bcma_host_pci_switch_core(core);
2003 +       return 0;
2004 +}
2005 +
2006 +static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
2007 +{
2008 +       offset += bcma_host_pci_provide_access_to_core(core);
2009 +       return ioread8(core->bus->mmio + offset);
2010 +}
2011 +
2012 +static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
2013 +{
2014 +       offset += bcma_host_pci_provide_access_to_core(core);
2015 +       return ioread16(core->bus->mmio + offset);
2016 +}
2017 +
2018 +static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
2019 +{
2020 +       offset += bcma_host_pci_provide_access_to_core(core);
2021 +       return ioread32(core->bus->mmio + offset);
2022 +}
2023 +
2024 +static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
2025 +                                u8 value)
2026 +{
2027 +       offset += bcma_host_pci_provide_access_to_core(core);
2028 +       iowrite8(value, core->bus->mmio + offset);
2029 +}
2030 +
2031 +static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
2032 +                                u16 value)
2033 +{
2034 +       offset += bcma_host_pci_provide_access_to_core(core);
2035 +       iowrite16(value, core->bus->mmio + offset);
2036 +}
2037 +
2038 +static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
2039 +                                u32 value)
2040 +{
2041 +       offset += bcma_host_pci_provide_access_to_core(core);
2042 +       iowrite32(value, core->bus->mmio + offset);
2043 +}
2044 +
2045 +#ifdef CONFIG_BCMA_BLOCKIO
2046 +void bcma_host_pci_block_read(struct bcma_device *core, void *buffer,
2047 +                             size_t count, u16 offset, u8 reg_width)
2048 +{
2049 +       void __iomem *addr = core->bus->mmio + offset;
2050 +       if (core->bus->mapped_core != core)
2051 +               bcma_host_pci_switch_core(core);
2052 +       switch (reg_width) {
2053 +       case sizeof(u8):
2054 +               ioread8_rep(addr, buffer, count);
2055 +               break;
2056 +       case sizeof(u16):
2057 +               WARN_ON(count & 1);
2058 +               ioread16_rep(addr, buffer, count >> 1);
2059 +               break;
2060 +       case sizeof(u32):
2061 +               WARN_ON(count & 3);
2062 +               ioread32_rep(addr, buffer, count >> 2);
2063 +               break;
2064 +       default:
2065 +               WARN_ON(1);
2066 +       }
2067 +}
2068 +
2069 +void bcma_host_pci_block_write(struct bcma_device *core, const void *buffer,
2070 +                              size_t count, u16 offset, u8 reg_width)
2071 +{
2072 +       void __iomem *addr = core->bus->mmio + offset;
2073 +       if (core->bus->mapped_core != core)
2074 +               bcma_host_pci_switch_core(core);
2075 +       switch (reg_width) {
2076 +       case sizeof(u8):
2077 +               iowrite8_rep(addr, buffer, count);
2078 +               break;
2079 +       case sizeof(u16):
2080 +               WARN_ON(count & 1);
2081 +               iowrite16_rep(addr, buffer, count >> 1);
2082 +               break;
2083 +       case sizeof(u32):
2084 +               WARN_ON(count & 3);
2085 +               iowrite32_rep(addr, buffer, count >> 2);
2086 +               break;
2087 +       default:
2088 +               WARN_ON(1);
2089 +       }
2090 +}
2091 +#endif
2092 +
2093 +static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset)
2094 +{
2095 +       if (core->bus->mapped_core != core)
2096 +               bcma_host_pci_switch_core(core);
2097 +       return ioread32(core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
2098 +}
2099 +
2100 +static void bcma_host_pci_awrite32(struct bcma_device *core, u16 offset,
2101 +                                 u32 value)
2102 +{
2103 +       if (core->bus->mapped_core != core)
2104 +               bcma_host_pci_switch_core(core);
2105 +       iowrite32(value, core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
2106 +}
2107 +
2108 +const struct bcma_host_ops bcma_host_pci_ops = {
2109 +       .read8          = bcma_host_pci_read8,
2110 +       .read16         = bcma_host_pci_read16,
2111 +       .read32         = bcma_host_pci_read32,
2112 +       .write8         = bcma_host_pci_write8,
2113 +       .write16        = bcma_host_pci_write16,
2114 +       .write32        = bcma_host_pci_write32,
2115 +#ifdef CONFIG_BCMA_BLOCKIO
2116 +       .block_read     = bcma_host_pci_block_read,
2117 +       .block_write    = bcma_host_pci_block_write,
2118 +#endif
2119 +       .aread32        = bcma_host_pci_aread32,
2120 +       .awrite32       = bcma_host_pci_awrite32,
2121 +};
2122 +
2123 +static int __devinit bcma_host_pci_probe(struct pci_dev *dev,
2124 +                                        const struct pci_device_id *id)
2125 +{
2126 +       struct bcma_bus *bus;
2127 +       int err = -ENOMEM;
2128 +       const char *name;
2129 +       u32 val;
2130 +
2131 +       /* Alloc */
2132 +       bus = kzalloc(sizeof(*bus), GFP_KERNEL);
2133 +       if (!bus)
2134 +               goto out;
2135 +
2136 +       /* Basic PCI configuration */
2137 +       err = pci_enable_device(dev);
2138 +       if (err)
2139 +               goto err_kfree_bus;
2140 +
2141 +       name = dev_name(&dev->dev);
2142 +       if (dev->driver && dev->driver->name)
2143 +               name = dev->driver->name;
2144 +       err = pci_request_regions(dev, name);
2145 +       if (err)
2146 +               goto err_pci_disable;
2147 +       pci_set_master(dev);
2148 +
2149 +       /* Disable the RETRY_TIMEOUT register (0x41) to keep
2150 +        * PCI Tx retries from interfering with C3 CPU state */
2151 +       pci_read_config_dword(dev, 0x40, &val);
2152 +       if ((val & 0x0000ff00) != 0)
2153 +               pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
2154 +
2155 +       /* SSB needed additional powering up, do we have any AMBA PCI cards? */
2156 +       if (!pci_is_pcie(dev))
2157 +               pr_err("PCI card detected, report problems.\n");
2158 +
2159 +       /* Map MMIO */
2160 +       err = -ENOMEM;
2161 +       bus->mmio = pci_iomap(dev, 0, ~0UL);
2162 +       if (!bus->mmio)
2163 +               goto err_pci_release_regions;
2164 +
2165 +       /* Host specific */
2166 +       bus->host_pci = dev;
2167 +       bus->hosttype = BCMA_HOSTTYPE_PCI;
2168 +       bus->ops = &bcma_host_pci_ops;
2169 +
2170 +       bus->boardinfo.vendor = bus->host_pci->subsystem_vendor;
2171 +       bus->boardinfo.type = bus->host_pci->subsystem_device;
2172 +
2173 +       /* Register */
2174 +       err = bcma_bus_register(bus);
2175 +       if (err)
2176 +               goto err_pci_unmap_mmio;
2177 +
2178 +       pci_set_drvdata(dev, bus);
2179 +
2180 +out:
2181 +       return err;
2182 +
2183 +err_pci_unmap_mmio:
2184 +       pci_iounmap(dev, bus->mmio);
2185 +err_pci_release_regions:
2186 +       pci_release_regions(dev);
2187 +err_pci_disable:
2188 +       pci_disable_device(dev);
2189 +err_kfree_bus:
2190 +       kfree(bus);
2191 +       return err;
2192 +}
2193 +
2194 +static void __devexit bcma_host_pci_remove(struct pci_dev *dev)
2195 +{
2196 +       struct bcma_bus *bus = pci_get_drvdata(dev);
2197 +
2198 +       bcma_bus_unregister(bus);
2199 +       pci_iounmap(dev, bus->mmio);
2200 +       pci_release_regions(dev);
2201 +       pci_disable_device(dev);
2202 +       kfree(bus);
2203 +       pci_set_drvdata(dev, NULL);
2204 +}
2205 +
2206 +#ifdef CONFIG_PM
2207 +static int bcma_host_pci_suspend(struct device *dev)
2208 +{
2209 +       struct pci_dev *pdev = to_pci_dev(dev);
2210 +       struct bcma_bus *bus = pci_get_drvdata(pdev);
2211 +
2212 +       bus->mapped_core = NULL;
2213 +
2214 +       return bcma_bus_suspend(bus);
2215 +}
2216 +
2217 +static int bcma_host_pci_resume(struct device *dev)
2218 +{
2219 +       struct pci_dev *pdev = to_pci_dev(dev);
2220 +       struct bcma_bus *bus = pci_get_drvdata(pdev);
2221 +
2222 +       return bcma_bus_resume(bus);
2223 +}
2224 +
2225 +static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend,
2226 +                        bcma_host_pci_resume);
2227 +#define BCMA_PM_OPS    (&bcma_pm_ops)
2228 +
2229 +#else /* CONFIG_PM */
2230 +
2231 +#define BCMA_PM_OPS     NULL
2232 +
2233 +#endif /* CONFIG_PM */
2234 +
2235 +static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
2236 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
2237 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
2238 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
2239 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
2240 +       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
2241 +       { 0, },
2242 +};
2243 +MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
2244 +
2245 +static struct pci_driver bcma_pci_bridge_driver = {
2246 +       .name = "bcma-pci-bridge",
2247 +       .id_table = bcma_pci_bridge_tbl,
2248 +       .probe = bcma_host_pci_probe,
2249 +       .remove = __devexit_p(bcma_host_pci_remove),
2250 +       .driver.pm = BCMA_PM_OPS,
2251 +};
2252 +
2253 +int __init bcma_host_pci_init(void)
2254 +{
2255 +       return pci_register_driver(&bcma_pci_bridge_driver);
2256 +}
2257 +
2258 +void __exit bcma_host_pci_exit(void)
2259 +{
2260 +       pci_unregister_driver(&bcma_pci_bridge_driver);
2261 +}
2262 --- /dev/null
2263 +++ b/drivers/bcma/host_soc.c
2264 @@ -0,0 +1,183 @@
2265 +/*
2266 + * Broadcom specific AMBA
2267 + * System on Chip (SoC) Host
2268 + *
2269 + * Licensed under the GNU/GPL. See COPYING for details.
2270 + */
2271 +
2272 +#include "bcma_private.h"
2273 +#include "scan.h"
2274 +#include <linux/bcma/bcma.h>
2275 +#include <linux/bcma/bcma_soc.h>
2276 +
2277 +static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
2278 +{
2279 +       return readb(core->io_addr + offset);
2280 +}
2281 +
2282 +static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
2283 +{
2284 +       return readw(core->io_addr + offset);
2285 +}
2286 +
2287 +static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
2288 +{
2289 +       return readl(core->io_addr + offset);
2290 +}
2291 +
2292 +static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
2293 +                                u8 value)
2294 +{
2295 +       writeb(value, core->io_addr + offset);
2296 +}
2297 +
2298 +static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
2299 +                                u16 value)
2300 +{
2301 +       writew(value, core->io_addr + offset);
2302 +}
2303 +
2304 +static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
2305 +                                u32 value)
2306 +{
2307 +       writel(value, core->io_addr + offset);
2308 +}
2309 +
2310 +#ifdef CONFIG_BCMA_BLOCKIO
2311 +static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
2312 +                                    size_t count, u16 offset, u8 reg_width)
2313 +{
2314 +       void __iomem *addr = core->io_addr + offset;
2315 +
2316 +       switch (reg_width) {
2317 +       case sizeof(u8): {
2318 +               u8 *buf = buffer;
2319 +
2320 +               while (count) {
2321 +                       *buf = __raw_readb(addr);
2322 +                       buf++;
2323 +                       count--;
2324 +               }
2325 +               break;
2326 +       }
2327 +       case sizeof(u16): {
2328 +               __le16 *buf = buffer;
2329 +
2330 +               WARN_ON(count & 1);
2331 +               while (count) {
2332 +                       *buf = (__force __le16)__raw_readw(addr);
2333 +                       buf++;
2334 +                       count -= 2;
2335 +               }
2336 +               break;
2337 +       }
2338 +       case sizeof(u32): {
2339 +               __le32 *buf = buffer;
2340 +
2341 +               WARN_ON(count & 3);
2342 +               while (count) {
2343 +                       *buf = (__force __le32)__raw_readl(addr);
2344 +                       buf++;
2345 +                       count -= 4;
2346 +               }
2347 +               break;
2348 +       }
2349 +       default:
2350 +               WARN_ON(1);
2351 +       }
2352 +}
2353 +
2354 +static void bcma_host_soc_block_write(struct bcma_device *core,
2355 +                                     const void *buffer,
2356 +                                     size_t count, u16 offset, u8 reg_width)
2357 +{
2358 +       void __iomem *addr = core->io_addr + offset;
2359 +
2360 +       switch (reg_width) {
2361 +       case sizeof(u8): {
2362 +               const u8 *buf = buffer;
2363 +
2364 +               while (count) {
2365 +                       __raw_writeb(*buf, addr);
2366 +                       buf++;
2367 +                       count--;
2368 +               }
2369 +               break;
2370 +       }
2371 +       case sizeof(u16): {
2372 +               const __le16 *buf = buffer;
2373 +
2374 +               WARN_ON(count & 1);
2375 +               while (count) {
2376 +                       __raw_writew((__force u16)(*buf), addr);
2377 +                       buf++;
2378 +                       count -= 2;
2379 +               }
2380 +               break;
2381 +       }
2382 +       case sizeof(u32): {
2383 +               const __le32 *buf = buffer;
2384 +
2385 +               WARN_ON(count & 3);
2386 +               while (count) {
2387 +                       __raw_writel((__force u32)(*buf), addr);
2388 +                       buf++;
2389 +                       count -= 4;
2390 +               }
2391 +               break;
2392 +       }
2393 +       default:
2394 +               WARN_ON(1);
2395 +       }
2396 +}
2397 +#endif /* CONFIG_BCMA_BLOCKIO */
2398 +
2399 +static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
2400 +{
2401 +       return readl(core->io_wrap + offset);
2402 +}
2403 +
2404 +static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
2405 +                                 u32 value)
2406 +{
2407 +       writel(value, core->io_wrap + offset);
2408 +}
2409 +
2410 +const struct bcma_host_ops bcma_host_soc_ops = {
2411 +       .read8          = bcma_host_soc_read8,
2412 +       .read16         = bcma_host_soc_read16,
2413 +       .read32         = bcma_host_soc_read32,
2414 +       .write8         = bcma_host_soc_write8,
2415 +       .write16        = bcma_host_soc_write16,
2416 +       .write32        = bcma_host_soc_write32,
2417 +#ifdef CONFIG_BCMA_BLOCKIO
2418 +       .block_read     = bcma_host_soc_block_read,
2419 +       .block_write    = bcma_host_soc_block_write,
2420 +#endif
2421 +       .aread32        = bcma_host_soc_aread32,
2422 +       .awrite32       = bcma_host_soc_awrite32,
2423 +};
2424 +
2425 +int __init bcma_host_soc_register(struct bcma_soc *soc)
2426 +{
2427 +       struct bcma_bus *bus = &soc->bus;
2428 +       int err;
2429 +
2430 +       /* iomap only first core. We have to read some register on this core
2431 +        * to scan the bus.
2432 +        */
2433 +       bus->mmio = ioremap_nocache(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
2434 +       if (!bus->mmio)
2435 +               return -ENOMEM;
2436 +
2437 +       /* Host specific */
2438 +       bus->hosttype = BCMA_HOSTTYPE_SOC;
2439 +       bus->ops = &bcma_host_soc_ops;
2440 +
2441 +       /* Register */
2442 +       err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
2443 +       if (err)
2444 +               iounmap(bus->mmio);
2445 +
2446 +       return err;
2447 +}
2448 --- /dev/null
2449 +++ b/drivers/bcma/main.c
2450 @@ -0,0 +1,387 @@
2451 +/*
2452 + * Broadcom specific AMBA
2453 + * Bus subsystem
2454 + *
2455 + * Licensed under the GNU/GPL. See COPYING for details.
2456 + */
2457 +
2458 +#include "bcma_private.h"
2459 +#include <linux/module.h>
2460 +#include <linux/bcma/bcma.h>
2461 +#include <linux/slab.h>
2462 +
2463 +MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
2464 +MODULE_LICENSE("GPL");
2465 +
2466 +/* contains the number the next bus should get. */
2467 +static unsigned int bcma_bus_next_num = 0;
2468 +
2469 +/* bcma_buses_mutex locks the bcma_bus_next_num */
2470 +static DEFINE_MUTEX(bcma_buses_mutex);
2471 +
2472 +static int bcma_bus_match(struct device *dev, struct device_driver *drv);
2473 +static int bcma_device_probe(struct device *dev);
2474 +static int bcma_device_remove(struct device *dev);
2475 +static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env);
2476 +
2477 +static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
2478 +{
2479 +       struct bcma_device *core = container_of(dev, struct bcma_device, dev);
2480 +       return sprintf(buf, "0x%03X\n", core->id.manuf);
2481 +}
2482 +static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
2483 +{
2484 +       struct bcma_device *core = container_of(dev, struct bcma_device, dev);
2485 +       return sprintf(buf, "0x%03X\n", core->id.id);
2486 +}
2487 +static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf)
2488 +{
2489 +       struct bcma_device *core = container_of(dev, struct bcma_device, dev);
2490 +       return sprintf(buf, "0x%02X\n", core->id.rev);
2491 +}
2492 +static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf)
2493 +{
2494 +       struct bcma_device *core = container_of(dev, struct bcma_device, dev);
2495 +       return sprintf(buf, "0x%X\n", core->id.class);
2496 +}
2497 +static struct device_attribute bcma_device_attrs[] = {
2498 +       __ATTR_RO(manuf),
2499 +       __ATTR_RO(id),
2500 +       __ATTR_RO(rev),
2501 +       __ATTR_RO(class),
2502 +       __ATTR_NULL,
2503 +};
2504 +
2505 +static struct bus_type bcma_bus_type = {
2506 +       .name           = "bcma",
2507 +       .match          = bcma_bus_match,
2508 +       .probe          = bcma_device_probe,
2509 +       .remove         = bcma_device_remove,
2510 +       .uevent         = bcma_device_uevent,
2511 +       .dev_attrs      = bcma_device_attrs,
2512 +};
2513 +
2514 +struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
2515 +{
2516 +       struct bcma_device *core;
2517 +
2518 +       list_for_each_entry(core, &bus->cores, list) {
2519 +               if (core->id.id == coreid)
2520 +                       return core;
2521 +       }
2522 +       return NULL;
2523 +}
2524 +EXPORT_SYMBOL_GPL(bcma_find_core);
2525 +
2526 +static void bcma_release_core_dev(struct device *dev)
2527 +{
2528 +       struct bcma_device *core = container_of(dev, struct bcma_device, dev);
2529 +       if (core->io_addr)
2530 +               iounmap(core->io_addr);
2531 +       if (core->io_wrap)
2532 +               iounmap(core->io_wrap);
2533 +       kfree(core);
2534 +}
2535 +
2536 +static int bcma_register_cores(struct bcma_bus *bus)
2537 +{
2538 +       struct bcma_device *core;
2539 +       int err, dev_id = 0;
2540 +
2541 +       list_for_each_entry(core, &bus->cores, list) {
2542 +               /* We support that cores ourself */
2543 +               switch (core->id.id) {
2544 +               case BCMA_CORE_CHIPCOMMON:
2545 +               case BCMA_CORE_PCI:
2546 +               case BCMA_CORE_PCIE:
2547 +               case BCMA_CORE_MIPS_74K:
2548 +                       continue;
2549 +               }
2550 +
2551 +               core->dev.release = bcma_release_core_dev;
2552 +               core->dev.bus = &bcma_bus_type;
2553 +               dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
2554 +
2555 +               switch (bus->hosttype) {
2556 +               case BCMA_HOSTTYPE_PCI:
2557 +                       core->dev.parent = &bus->host_pci->dev;
2558 +                       core->dma_dev = &bus->host_pci->dev;
2559 +                       core->irq = bus->host_pci->irq;
2560 +                       break;
2561 +               case BCMA_HOSTTYPE_SOC:
2562 +                       core->dev.dma_mask = &core->dev.coherent_dma_mask;
2563 +                       core->dma_dev = &core->dev;
2564 +                       break;
2565 +               case BCMA_HOSTTYPE_SDIO:
2566 +                       break;
2567 +               }
2568 +
2569 +               err = device_register(&core->dev);
2570 +               if (err) {
2571 +                       pr_err("Could not register dev for core 0x%03X\n",
2572 +                              core->id.id);
2573 +                       continue;
2574 +               }
2575 +               core->dev_registered = true;
2576 +               dev_id++;
2577 +       }
2578 +
2579 +       return 0;
2580 +}
2581 +
2582 +static void bcma_unregister_cores(struct bcma_bus *bus)
2583 +{
2584 +       struct bcma_device *core;
2585 +
2586 +       list_for_each_entry(core, &bus->cores, list) {
2587 +               if (core->dev_registered)
2588 +                       device_unregister(&core->dev);
2589 +       }
2590 +}
2591 +
2592 +int __devinit bcma_bus_register(struct bcma_bus *bus)
2593 +{
2594 +       int err;
2595 +       struct bcma_device *core;
2596 +
2597 +       mutex_lock(&bcma_buses_mutex);
2598 +       bus->num = bcma_bus_next_num++;
2599 +       mutex_unlock(&bcma_buses_mutex);
2600 +
2601 +       /* Scan for devices (cores) */
2602 +       err = bcma_bus_scan(bus);
2603 +       if (err) {
2604 +               pr_err("Failed to scan: %d\n", err);
2605 +               return -1;
2606 +       }
2607 +
2608 +       /* Init CC core */
2609 +       core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
2610 +       if (core) {
2611 +               bus->drv_cc.core = core;
2612 +               bcma_core_chipcommon_init(&bus->drv_cc);
2613 +       }
2614 +
2615 +       /* Init MIPS core */
2616 +       core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
2617 +       if (core) {
2618 +               bus->drv_mips.core = core;
2619 +               bcma_core_mips_init(&bus->drv_mips);
2620 +       }
2621 +
2622 +       /* Init PCIE core */
2623 +       core = bcma_find_core(bus, BCMA_CORE_PCIE);
2624 +       if (core) {
2625 +               bus->drv_pci.core = core;
2626 +               bcma_core_pci_init(&bus->drv_pci);
2627 +       }
2628 +
2629 +       /* Try to get SPROM */
2630 +       err = bcma_sprom_get(bus);
2631 +       if (err == -ENOENT) {
2632 +               pr_err("No SPROM available\n");
2633 +       } else if (err)
2634 +               pr_err("Failed to get SPROM: %d\n", err);
2635 +
2636 +       /* Register found cores */
2637 +       bcma_register_cores(bus);
2638 +
2639 +       pr_info("Bus registered\n");
2640 +
2641 +       return 0;
2642 +}
2643 +
2644 +void bcma_bus_unregister(struct bcma_bus *bus)
2645 +{
2646 +       bcma_unregister_cores(bus);
2647 +}
2648 +
2649 +int __init bcma_bus_early_register(struct bcma_bus *bus,
2650 +                                  struct bcma_device *core_cc,
2651 +                                  struct bcma_device *core_mips)
2652 +{
2653 +       int err;
2654 +       struct bcma_device *core;
2655 +       struct bcma_device_id match;
2656 +
2657 +       bcma_init_bus(bus);
2658 +
2659 +       match.manuf = BCMA_MANUF_BCM;
2660 +       match.id = BCMA_CORE_CHIPCOMMON;
2661 +       match.class = BCMA_CL_SIM;
2662 +       match.rev = BCMA_ANY_REV;
2663 +
2664 +       /* Scan for chip common core */
2665 +       err = bcma_bus_scan_early(bus, &match, core_cc);
2666 +       if (err) {
2667 +               pr_err("Failed to scan for common core: %d\n", err);
2668 +               return -1;
2669 +       }
2670 +
2671 +       match.manuf = BCMA_MANUF_MIPS;
2672 +       match.id = BCMA_CORE_MIPS_74K;
2673 +       match.class = BCMA_CL_SIM;
2674 +       match.rev = BCMA_ANY_REV;
2675 +
2676 +       /* Scan for mips core */
2677 +       err = bcma_bus_scan_early(bus, &match, core_mips);
2678 +       if (err) {
2679 +               pr_err("Failed to scan for mips core: %d\n", err);
2680 +               return -1;
2681 +       }
2682 +
2683 +       /* Init CC core */
2684 +       core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
2685 +       if (core) {
2686 +               bus->drv_cc.core = core;
2687 +               bcma_core_chipcommon_init(&bus->drv_cc);
2688 +       }
2689 +
2690 +       /* Init MIPS core */
2691 +       core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
2692 +       if (core) {
2693 +               bus->drv_mips.core = core;
2694 +               bcma_core_mips_init(&bus->drv_mips);
2695 +       }
2696 +
2697 +       pr_info("Early bus registered\n");
2698 +
2699 +       return 0;
2700 +}
2701 +
2702 +#ifdef CONFIG_PM
2703 +int bcma_bus_suspend(struct bcma_bus *bus)
2704 +{
2705 +       struct bcma_device *core;
2706 +
2707 +       list_for_each_entry(core, &bus->cores, list) {
2708 +               struct device_driver *drv = core->dev.driver;
2709 +               if (drv) {
2710 +                       struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
2711 +                       if (adrv->suspend)
2712 +                               adrv->suspend(core);
2713 +               }
2714 +       }
2715 +       return 0;
2716 +}
2717 +
2718 +int bcma_bus_resume(struct bcma_bus *bus)
2719 +{
2720 +       struct bcma_device *core;
2721 +
2722 +       /* Init CC core */
2723 +       core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
2724 +       if (core) {
2725 +               bus->drv_cc.setup_done = false;
2726 +               bcma_core_chipcommon_init(&bus->drv_cc);
2727 +       }
2728 +
2729 +       list_for_each_entry(core, &bus->cores, list) {
2730 +               struct device_driver *drv = core->dev.driver;
2731 +               if (drv) {
2732 +                       struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
2733 +                       if (adrv->resume)
2734 +                               adrv->resume(core);
2735 +               }
2736 +       }
2737 +
2738 +       return 0;
2739 +}
2740 +#endif
2741 +
2742 +int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
2743 +{
2744 +       drv->drv.name = drv->name;
2745 +       drv->drv.bus = &bcma_bus_type;
2746 +       drv->drv.owner = owner;
2747 +
2748 +       return driver_register(&drv->drv);
2749 +}
2750 +EXPORT_SYMBOL_GPL(__bcma_driver_register);
2751 +
2752 +void bcma_driver_unregister(struct bcma_driver *drv)
2753 +{
2754 +       driver_unregister(&drv->drv);
2755 +}
2756 +EXPORT_SYMBOL_GPL(bcma_driver_unregister);
2757 +
2758 +static int bcma_bus_match(struct device *dev, struct device_driver *drv)
2759 +{
2760 +       struct bcma_device *core = container_of(dev, struct bcma_device, dev);
2761 +       struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
2762 +       const struct bcma_device_id *cid = &core->id;
2763 +       const struct bcma_device_id *did;
2764 +
2765 +       for (did = adrv->id_table; did->manuf || did->id || did->rev; did++) {
2766 +           if ((did->manuf == cid->manuf || did->manuf == BCMA_ANY_MANUF) &&
2767 +               (did->id == cid->id || did->id == BCMA_ANY_ID) &&
2768 +               (did->rev == cid->rev || did->rev == BCMA_ANY_REV) &&
2769 +               (did->class == cid->class || did->class == BCMA_ANY_CLASS))
2770 +                       return 1;
2771 +       }
2772 +       return 0;
2773 +}
2774 +
2775 +static int bcma_device_probe(struct device *dev)
2776 +{
2777 +       struct bcma_device *core = container_of(dev, struct bcma_device, dev);
2778 +       struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
2779 +                                              drv);
2780 +       int err = 0;
2781 +
2782 +       if (adrv->probe)
2783 +               err = adrv->probe(core);
2784 +
2785 +       return err;
2786 +}
2787 +
2788 +static int bcma_device_remove(struct device *dev)
2789 +{
2790 +       struct bcma_device *core = container_of(dev, struct bcma_device, dev);
2791 +       struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
2792 +                                              drv);
2793 +
2794 +       if (adrv->remove)
2795 +               adrv->remove(core);
2796 +
2797 +       return 0;
2798 +}
2799 +
2800 +static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env)
2801 +{
2802 +       struct bcma_device *core = container_of(dev, struct bcma_device, dev);
2803 +
2804 +       return add_uevent_var(env,
2805 +                             "MODALIAS=bcma:m%04Xid%04Xrev%02Xcl%02X",
2806 +                             core->id.manuf, core->id.id,
2807 +                             core->id.rev, core->id.class);
2808 +}
2809 +
2810 +static int __init bcma_modinit(void)
2811 +{
2812 +       int err;
2813 +
2814 +       err = bus_register(&bcma_bus_type);
2815 +       if (err)
2816 +               return err;
2817 +
2818 +#ifdef CONFIG_BCMA_HOST_PCI
2819 +       err = bcma_host_pci_init();
2820 +       if (err) {
2821 +               pr_err("PCI host initialization failed\n");
2822 +               err = 0;
2823 +       }
2824 +#endif
2825 +
2826 +       return err;
2827 +}
2828 +fs_initcall(bcma_modinit);
2829 +
2830 +static void __exit bcma_modexit(void)
2831 +{
2832 +#ifdef CONFIG_BCMA_HOST_PCI
2833 +       bcma_host_pci_exit();
2834 +#endif
2835 +       bus_unregister(&bcma_bus_type);
2836 +}
2837 +module_exit(bcma_modexit)
2838 --- /dev/null
2839 +++ b/drivers/bcma/scan.c
2840 @@ -0,0 +1,533 @@
2841 +/*
2842 + * Broadcom specific AMBA
2843 + * Bus scanning
2844 + *
2845 + * Licensed under the GNU/GPL. See COPYING for details.
2846 + */
2847 +
2848 +#include "scan.h"
2849 +#include "bcma_private.h"
2850 +
2851 +#include <linux/bcma/bcma.h>
2852 +#include <linux/bcma/bcma_regs.h>
2853 +#include <linux/pci.h>
2854 +#include <linux/io.h>
2855 +#include <linux/dma-mapping.h>
2856 +#include <linux/slab.h>
2857 +
2858 +struct bcma_device_id_name {
2859 +       u16 id;
2860 +       const char *name;
2861 +};
2862 +
2863 +static const struct bcma_device_id_name bcma_arm_device_names[] = {
2864 +       { BCMA_CORE_ARM_1176, "ARM 1176" },
2865 +       { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
2866 +       { BCMA_CORE_ARM_CM3, "ARM CM3" },
2867 +};
2868 +
2869 +static const struct bcma_device_id_name bcma_bcm_device_names[] = {
2870 +       { BCMA_CORE_OOB_ROUTER, "OOB Router" },
2871 +       { BCMA_CORE_INVALID, "Invalid" },
2872 +       { BCMA_CORE_CHIPCOMMON, "ChipCommon" },
2873 +       { BCMA_CORE_ILINE20, "ILine 20" },
2874 +       { BCMA_CORE_SRAM, "SRAM" },
2875 +       { BCMA_CORE_SDRAM, "SDRAM" },
2876 +       { BCMA_CORE_PCI, "PCI" },
2877 +       { BCMA_CORE_ETHERNET, "Fast Ethernet" },
2878 +       { BCMA_CORE_V90, "V90" },
2879 +       { BCMA_CORE_USB11_HOSTDEV, "USB 1.1 Hostdev" },
2880 +       { BCMA_CORE_ADSL, "ADSL" },
2881 +       { BCMA_CORE_ILINE100, "ILine 100" },
2882 +       { BCMA_CORE_IPSEC, "IPSEC" },
2883 +       { BCMA_CORE_UTOPIA, "UTOPIA" },
2884 +       { BCMA_CORE_PCMCIA, "PCMCIA" },
2885 +       { BCMA_CORE_INTERNAL_MEM, "Internal Memory" },
2886 +       { BCMA_CORE_MEMC_SDRAM, "MEMC SDRAM" },
2887 +       { BCMA_CORE_OFDM, "OFDM" },
2888 +       { BCMA_CORE_EXTIF, "EXTIF" },
2889 +       { BCMA_CORE_80211, "IEEE 802.11" },
2890 +       { BCMA_CORE_PHY_A, "PHY A" },
2891 +       { BCMA_CORE_PHY_B, "PHY B" },
2892 +       { BCMA_CORE_PHY_G, "PHY G" },
2893 +       { BCMA_CORE_USB11_HOST, "USB 1.1 Host" },
2894 +       { BCMA_CORE_USB11_DEV, "USB 1.1 Device" },
2895 +       { BCMA_CORE_USB20_HOST, "USB 2.0 Host" },
2896 +       { BCMA_CORE_USB20_DEV, "USB 2.0 Device" },
2897 +       { BCMA_CORE_SDIO_HOST, "SDIO Host" },
2898 +       { BCMA_CORE_ROBOSWITCH, "Roboswitch" },
2899 +       { BCMA_CORE_PARA_ATA, "PATA" },
2900 +       { BCMA_CORE_SATA_XORDMA, "SATA XOR-DMA" },
2901 +       { BCMA_CORE_ETHERNET_GBIT, "GBit Ethernet" },
2902 +       { BCMA_CORE_PCIE, "PCIe" },
2903 +       { BCMA_CORE_PHY_N, "PHY N" },
2904 +       { BCMA_CORE_SRAM_CTL, "SRAM Controller" },
2905 +       { BCMA_CORE_MINI_MACPHY, "Mini MACPHY" },
2906 +       { BCMA_CORE_PHY_LP, "PHY LP" },
2907 +       { BCMA_CORE_PMU, "PMU" },
2908 +       { BCMA_CORE_PHY_SSN, "PHY SSN" },
2909 +       { BCMA_CORE_SDIO_DEV, "SDIO Device" },
2910 +       { BCMA_CORE_PHY_HT, "PHY HT" },
2911 +       { BCMA_CORE_MAC_GBIT, "GBit MAC" },
2912 +       { BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" },
2913 +       { BCMA_CORE_PCIE_RC, "PCIe Root Complex" },
2914 +       { BCMA_CORE_OCP_OCP_BRIDGE, "OCP to OCP Bridge" },
2915 +       { BCMA_CORE_SHARED_COMMON, "Common Shared" },
2916 +       { BCMA_CORE_OCP_AHB_BRIDGE, "OCP to AHB Bridge" },
2917 +       { BCMA_CORE_SPI_HOST, "SPI Host" },
2918 +       { BCMA_CORE_I2S, "I2S" },
2919 +       { BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" },
2920 +       { BCMA_CORE_SHIM, "SHIM" },
2921 +       { BCMA_CORE_DEFAULT, "Default" },
2922 +};
2923 +
2924 +static const struct bcma_device_id_name bcma_mips_device_names[] = {
2925 +       { BCMA_CORE_MIPS, "MIPS" },
2926 +       { BCMA_CORE_MIPS_3302, "MIPS 3302" },
2927 +       { BCMA_CORE_MIPS_74K, "MIPS 74K" },
2928 +};
2929 +
2930 +static const char *bcma_device_name(const struct bcma_device_id *id)
2931 +{
2932 +       const struct bcma_device_id_name *names;
2933 +       int size, i;
2934 +
2935 +       /* search manufacturer specific names */
2936 +       switch (id->manuf) {
2937 +       case BCMA_MANUF_ARM:
2938 +               names = bcma_arm_device_names;
2939 +               size = ARRAY_SIZE(bcma_arm_device_names);
2940 +               break;
2941 +       case BCMA_MANUF_BCM:
2942 +               names = bcma_bcm_device_names;
2943 +               size = ARRAY_SIZE(bcma_bcm_device_names);
2944 +               break;
2945 +       case BCMA_MANUF_MIPS:
2946 +               names = bcma_mips_device_names;
2947 +               size = ARRAY_SIZE(bcma_mips_device_names);
2948 +               break;
2949 +       default:
2950 +               return "UNKNOWN";
2951 +       }
2952 +
2953 +       for (i = 0; i < size; i++) {
2954 +               if (names[i].id == id->id)
2955 +                       return names[i].name;
2956 +       }
2957 +
2958 +       return "UNKNOWN";
2959 +}
2960 +
2961 +static u32 bcma_scan_read32(struct bcma_bus *bus, u8 current_coreidx,
2962 +                      u16 offset)
2963 +{
2964 +       return readl(bus->mmio + offset);
2965 +}
2966 +
2967 +static void bcma_scan_switch_core(struct bcma_bus *bus, u32 addr)
2968 +{
2969 +       if (bus->hosttype == BCMA_HOSTTYPE_PCI)
2970 +               pci_write_config_dword(bus->host_pci, BCMA_PCI_BAR0_WIN,
2971 +                                      addr);
2972 +}
2973 +
2974 +static u32 bcma_erom_get_ent(struct bcma_bus *bus, u32 **eromptr)
2975 +{
2976 +       u32 ent = readl(*eromptr);
2977 +       (*eromptr)++;
2978 +       return ent;
2979 +}
2980 +
2981 +static void bcma_erom_push_ent(u32 **eromptr)
2982 +{
2983 +       (*eromptr)--;
2984 +}
2985 +
2986 +static s32 bcma_erom_get_ci(struct bcma_bus *bus, u32 **eromptr)
2987 +{
2988 +       u32 ent = bcma_erom_get_ent(bus, eromptr);
2989 +       if (!(ent & SCAN_ER_VALID))
2990 +               return -ENOENT;
2991 +       if ((ent & SCAN_ER_TAG) != SCAN_ER_TAG_CI)
2992 +               return -ENOENT;
2993 +       return ent;
2994 +}
2995 +
2996 +static bool bcma_erom_is_end(struct bcma_bus *bus, u32 **eromptr)
2997 +{
2998 +       u32 ent = bcma_erom_get_ent(bus, eromptr);
2999 +       bcma_erom_push_ent(eromptr);
3000 +       return (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID));
3001 +}
3002 +
3003 +static bool bcma_erom_is_bridge(struct bcma_bus *bus, u32 **eromptr)
3004 +{
3005 +       u32 ent = bcma_erom_get_ent(bus, eromptr);
3006 +       bcma_erom_push_ent(eromptr);
3007 +       return (((ent & SCAN_ER_VALID)) &&
3008 +               ((ent & SCAN_ER_TAGX) == SCAN_ER_TAG_ADDR) &&
3009 +               ((ent & SCAN_ADDR_TYPE) == SCAN_ADDR_TYPE_BRIDGE));
3010 +}
3011 +
3012 +static void bcma_erom_skip_component(struct bcma_bus *bus, u32 **eromptr)
3013 +{
3014 +       u32 ent;
3015 +       while (1) {
3016 +               ent = bcma_erom_get_ent(bus, eromptr);
3017 +               if ((ent & SCAN_ER_VALID) &&
3018 +                   ((ent & SCAN_ER_TAG) == SCAN_ER_TAG_CI))
3019 +                       break;
3020 +               if (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID))
3021 +                       break;
3022 +       }
3023 +       bcma_erom_push_ent(eromptr);
3024 +}
3025 +
3026 +static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 **eromptr)
3027 +{
3028 +       u32 ent = bcma_erom_get_ent(bus, eromptr);
3029 +       if (!(ent & SCAN_ER_VALID))
3030 +               return -ENOENT;
3031 +       if ((ent & SCAN_ER_TAG) != SCAN_ER_TAG_MP)
3032 +               return -ENOENT;
3033 +       return ent;
3034 +}
3035 +
3036 +static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
3037 +                                 u32 type, u8 port)
3038 +{
3039 +       u32 addrl, addrh, sizel, sizeh = 0;
3040 +       u32 size;
3041 +
3042 +       u32 ent = bcma_erom_get_ent(bus, eromptr);
3043 +       if ((!(ent & SCAN_ER_VALID)) ||
3044 +           ((ent & SCAN_ER_TAGX) != SCAN_ER_TAG_ADDR) ||
3045 +           ((ent & SCAN_ADDR_TYPE) != type) ||
3046 +           (((ent & SCAN_ADDR_PORT) >> SCAN_ADDR_PORT_SHIFT) != port)) {
3047 +               bcma_erom_push_ent(eromptr);
3048 +               return -EINVAL;
3049 +       }
3050 +
3051 +       addrl = ent & SCAN_ADDR_ADDR;
3052 +       if (ent & SCAN_ADDR_AG32)
3053 +               addrh = bcma_erom_get_ent(bus, eromptr);
3054 +       else
3055 +               addrh = 0;
3056 +
3057 +       if ((ent & SCAN_ADDR_SZ) == SCAN_ADDR_SZ_SZD) {
3058 +               size = bcma_erom_get_ent(bus, eromptr);
3059 +               sizel = size & SCAN_SIZE_SZ;
3060 +               if (size & SCAN_SIZE_SG32)
3061 +                       sizeh = bcma_erom_get_ent(bus, eromptr);
3062 +       } else
3063 +               sizel = SCAN_ADDR_SZ_BASE <<
3064 +                               ((ent & SCAN_ADDR_SZ) >> SCAN_ADDR_SZ_SHIFT);
3065 +
3066 +       return addrl;
3067 +}
3068 +
3069 +static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
3070 +                                                  u16 index)
3071 +{
3072 +       struct bcma_device *core;
3073 +
3074 +       list_for_each_entry(core, &bus->cores, list) {
3075 +               if (core->core_index == index)
3076 +                       return core;
3077 +       }
3078 +       return NULL;
3079 +}
3080 +
3081 +static struct bcma_device *bcma_find_core_reverse(struct bcma_bus *bus, u16 coreid)
3082 +{
3083 +       struct bcma_device *core;
3084 +
3085 +       list_for_each_entry_reverse(core, &bus->cores, list) {
3086 +               if (core->id.id == coreid)
3087 +                       return core;
3088 +       }
3089 +       return NULL;
3090 +}
3091 +
3092 +static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
3093 +                             struct bcma_device_id *match, int core_num,
3094 +                             struct bcma_device *core)
3095 +{
3096 +       s32 tmp;
3097 +       u8 i, j;
3098 +       s32 cia, cib;
3099 +       u8 ports[2], wrappers[2];
3100 +
3101 +       /* get CIs */
3102 +       cia = bcma_erom_get_ci(bus, eromptr);
3103 +       if (cia < 0) {
3104 +               bcma_erom_push_ent(eromptr);
3105 +               if (bcma_erom_is_end(bus, eromptr))
3106 +                       return -ESPIPE;
3107 +               return -EILSEQ;
3108 +       }
3109 +       cib = bcma_erom_get_ci(bus, eromptr);
3110 +       if (cib < 0)
3111 +               return -EILSEQ;
3112 +
3113 +       /* parse CIs */
3114 +       core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
3115 +       core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
3116 +       core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
3117 +       ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
3118 +       ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
3119 +       wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
3120 +       wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
3121 +       core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
3122 +
3123 +       if (((core->id.manuf == BCMA_MANUF_ARM) &&
3124 +            (core->id.id == 0xFFF)) ||
3125 +           (ports[1] == 0)) {
3126 +               bcma_erom_skip_component(bus, eromptr);
3127 +               return -ENXIO;
3128 +       }
3129 +
3130 +       /* check if component is a core at all */
3131 +       if (wrappers[0] + wrappers[1] == 0) {
3132 +               /* we could save addrl of the router
3133 +               if (cid == BCMA_CORE_OOB_ROUTER)
3134 +                */
3135 +               bcma_erom_skip_component(bus, eromptr);
3136 +               return -ENXIO;
3137 +       }
3138 +
3139 +       if (bcma_erom_is_bridge(bus, eromptr)) {
3140 +               bcma_erom_skip_component(bus, eromptr);
3141 +               return -ENXIO;
3142 +       }
3143 +
3144 +       if (bcma_find_core_by_index(bus, core_num)) {
3145 +               bcma_erom_skip_component(bus, eromptr);
3146 +               return -ENODEV;
3147 +       }
3148 +
3149 +       if (match && ((match->manuf != BCMA_ANY_MANUF &&
3150 +             match->manuf != core->id.manuf) ||
3151 +            (match->id != BCMA_ANY_ID && match->id != core->id.id) ||
3152 +            (match->rev != BCMA_ANY_REV && match->rev != core->id.rev) ||
3153 +            (match->class != BCMA_ANY_CLASS && match->class != core->id.class)
3154 +           )) {
3155 +               bcma_erom_skip_component(bus, eromptr);
3156 +               return -ENODEV;
3157 +       }
3158 +
3159 +       /* get & parse master ports */
3160 +       for (i = 0; i < ports[0]; i++) {
3161 +               s32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
3162 +               if (mst_port_d < 0)
3163 +                       return -EILSEQ;
3164 +       }
3165 +
3166 +       /* get & parse slave ports */
3167 +       for (i = 0; i < ports[1]; i++) {
3168 +               for (j = 0; ; j++) {
3169 +                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
3170 +                               SCAN_ADDR_TYPE_SLAVE, i);
3171 +                       if (tmp < 0) {
3172 +                               /* no more entries for port _i_ */
3173 +                               /* pr_debug("erom: slave port %d "
3174 +                                * "has %d descriptors\n", i, j); */
3175 +                               break;
3176 +                       } else {
3177 +                               if (i == 0 && j == 0)
3178 +                                       core->addr = tmp;
3179 +                       }
3180 +               }
3181 +       }
3182 +
3183 +       /* get & parse master wrappers */
3184 +       for (i = 0; i < wrappers[0]; i++) {
3185 +               for (j = 0; ; j++) {
3186 +                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
3187 +                               SCAN_ADDR_TYPE_MWRAP, i);
3188 +                       if (tmp < 0) {
3189 +                               /* no more entries for port _i_ */
3190 +                               /* pr_debug("erom: master wrapper %d "
3191 +                                * "has %d descriptors\n", i, j); */
3192 +                               break;
3193 +                       } else {
3194 +                               if (i == 0 && j == 0)
3195 +                                       core->wrap = tmp;
3196 +                       }
3197 +               }
3198 +       }
3199 +
3200 +       /* get & parse slave wrappers */
3201 +       for (i = 0; i < wrappers[1]; i++) {
3202 +               u8 hack = (ports[1] == 1) ? 0 : 1;
3203 +               for (j = 0; ; j++) {
3204 +                       tmp = bcma_erom_get_addr_desc(bus, eromptr,
3205 +                               SCAN_ADDR_TYPE_SWRAP, i + hack);
3206 +                       if (tmp < 0) {
3207 +                               /* no more entries for port _i_ */
3208 +                               /* pr_debug("erom: master wrapper %d "
3209 +                                * has %d descriptors\n", i, j); */
3210 +                               break;
3211 +                       } else {
3212 +                               if (wrappers[0] == 0 && !i && !j)
3213 +                                       core->wrap = tmp;
3214 +                       }
3215 +               }
3216 +       }
3217 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
3218 +               core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE);
3219 +               if (!core->io_addr)
3220 +                       return -ENOMEM;
3221 +               core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE);
3222 +               if (!core->io_wrap) {
3223 +                       iounmap(core->io_addr);
3224 +                       return -ENOMEM;
3225 +               }
3226 +       }
3227 +       return 0;
3228 +}
3229 +
3230 +void bcma_init_bus(struct bcma_bus *bus)
3231 +{
3232 +       s32 tmp;
3233 +       struct bcma_chipinfo *chipinfo = &(bus->chipinfo);
3234 +
3235 +       if (bus->init_done)
3236 +               return;
3237 +
3238 +       INIT_LIST_HEAD(&bus->cores);
3239 +       bus->nr_cores = 0;
3240 +
3241 +       bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
3242 +
3243 +       tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
3244 +       chipinfo->id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
3245 +       chipinfo->rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
3246 +       chipinfo->pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
3247 +       pr_info("Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n",
3248 +               chipinfo->id, chipinfo->rev, chipinfo->pkg);
3249 +
3250 +       bus->init_done = true;
3251 +}
3252 +
3253 +int bcma_bus_scan(struct bcma_bus *bus)
3254 +{
3255 +       u32 erombase;
3256 +       u32 __iomem *eromptr, *eromend;
3257 +
3258 +       int err, core_num = 0;
3259 +
3260 +       bcma_init_bus(bus);
3261 +
3262 +       erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
3263 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
3264 +               eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
3265 +               if (!eromptr)
3266 +                       return -ENOMEM;
3267 +       } else {
3268 +               eromptr = bus->mmio;
3269 +       }
3270 +
3271 +       eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
3272 +
3273 +       bcma_scan_switch_core(bus, erombase);
3274 +
3275 +       while (eromptr < eromend) {
3276 +               struct bcma_device *other_core;
3277 +               struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
3278 +               if (!core)
3279 +                       return -ENOMEM;
3280 +               INIT_LIST_HEAD(&core->list);
3281 +               core->bus = bus;
3282 +
3283 +               err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
3284 +               if (err < 0) {
3285 +                       kfree(core);
3286 +                       if (err == -ENODEV) {
3287 +                               core_num++;
3288 +                               continue;
3289 +                       } else if (err == -ENXIO) {
3290 +                               continue;
3291 +                       } else if (err == -ESPIPE) {
3292 +                               break;
3293 +                       }
3294 +                       return err;
3295 +               }
3296 +
3297 +               core->core_index = core_num++;
3298 +               bus->nr_cores++;
3299 +               other_core = bcma_find_core_reverse(bus, core->id.id);
3300 +               core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1;
3301 +
3302 +               pr_info("Core %d found: %s "
3303 +                       "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
3304 +                       core->core_index, bcma_device_name(&core->id),
3305 +                       core->id.manuf, core->id.id, core->id.rev,
3306 +                       core->id.class);
3307 +
3308 +               list_add(&core->list, &bus->cores);
3309 +       }
3310 +
3311 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC)
3312 +               iounmap(eromptr);
3313 +
3314 +       return 0;
3315 +}
3316 +
3317 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
3318 +                              struct bcma_device_id *match,
3319 +                              struct bcma_device *core)
3320 +{
3321 +       u32 erombase;
3322 +       u32 __iomem *eromptr, *eromend;
3323 +
3324 +       int err = -ENODEV;
3325 +       int core_num = 0;
3326 +
3327 +       erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
3328 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
3329 +               eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
3330 +               if (!eromptr)
3331 +                       return -ENOMEM;
3332 +       } else {
3333 +               eromptr = bus->mmio;
3334 +       }
3335 +
3336 +       eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
3337 +
3338 +       bcma_scan_switch_core(bus, erombase);
3339 +
3340 +       while (eromptr < eromend) {
3341 +               memset(core, 0, sizeof(*core));
3342 +               INIT_LIST_HEAD(&core->list);
3343 +               core->bus = bus;
3344 +
3345 +               err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
3346 +               if (err == -ENODEV) {
3347 +                       core_num++;
3348 +                       continue;
3349 +               } else if (err == -ENXIO)
3350 +                       continue;
3351 +               else if (err == -ESPIPE)
3352 +                       break;
3353 +               else if (err < 0)
3354 +                       return err;
3355 +
3356 +               core->core_index = core_num++;
3357 +               bus->nr_cores++;
3358 +               pr_info("Core %d found: %s "
3359 +                       "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
3360 +                       core->core_index, bcma_device_name(&core->id),
3361 +                       core->id.manuf, core->id.id, core->id.rev,
3362 +                       core->id.class);
3363 +
3364 +               list_add(&core->list, &bus->cores);
3365 +               err = 0;
3366 +               break;
3367 +       }
3368 +
3369 +       if (bus->hosttype == BCMA_HOSTTYPE_SOC)
3370 +               iounmap(eromptr);
3371 +
3372 +       return err;
3373 +}
3374 --- /dev/null
3375 +++ b/drivers/bcma/scan.h
3376 @@ -0,0 +1,56 @@
3377 +#ifndef BCMA_SCAN_H_
3378 +#define BCMA_SCAN_H_
3379 +
3380 +#define BCMA_ADDR_BASE         0x18000000
3381 +#define BCMA_WRAP_BASE         0x18100000
3382 +
3383 +#define SCAN_ER_VALID          0x00000001
3384 +#define SCAN_ER_TAGX           0x00000006 /* we have to ignore 0x8 bit when checking tag for SCAN_ER_TAG_ADDR */
3385 +#define SCAN_ER_TAG            0x0000000E
3386 +#define  SCAN_ER_TAG_CI                0x00000000
3387 +#define  SCAN_ER_TAG_MP                0x00000002
3388 +#define  SCAN_ER_TAG_ADDR      0x00000004
3389 +#define  SCAN_ER_TAG_END       0x0000000E
3390 +#define SCAN_ER_BAD            0xFFFFFFFF
3391 +
3392 +#define SCAN_CIA_CLASS         0x000000F0
3393 +#define SCAN_CIA_CLASS_SHIFT   4
3394 +#define SCAN_CIA_ID            0x000FFF00
3395 +#define SCAN_CIA_ID_SHIFT      8
3396 +#define SCAN_CIA_MANUF         0xFFF00000
3397 +#define SCAN_CIA_MANUF_SHIFT   20
3398 +
3399 +#define SCAN_CIB_NMP           0x000001F0
3400 +#define SCAN_CIB_NMP_SHIFT     4
3401 +#define SCAN_CIB_NSP           0x00003E00
3402 +#define SCAN_CIB_NSP_SHIFT     9
3403 +#define SCAN_CIB_NMW           0x0007C000
3404 +#define SCAN_CIB_NMW_SHIFT     14
3405 +#define SCAN_CIB_NSW           0x00F80000
3406 +#define SCAN_CIB_NSW_SHIFT     17
3407 +#define SCAN_CIB_REV           0xFF000000
3408 +#define SCAN_CIB_REV_SHIFT     24
3409 +
3410 +#define SCAN_ADDR_AG32         0x00000008
3411 +#define SCAN_ADDR_SZ           0x00000030
3412 +#define SCAN_ADDR_SZ_SHIFT     4
3413 +#define  SCAN_ADDR_SZ_4K       0x00000000
3414 +#define  SCAN_ADDR_SZ_8K       0x00000010
3415 +#define  SCAN_ADDR_SZ_16K      0x00000020
3416 +#define  SCAN_ADDR_SZ_SZD      0x00000030
3417 +#define SCAN_ADDR_TYPE         0x000000C0
3418 +#define  SCAN_ADDR_TYPE_SLAVE  0x00000000
3419 +#define  SCAN_ADDR_TYPE_BRIDGE 0x00000040
3420 +#define  SCAN_ADDR_TYPE_SWRAP  0x00000080
3421 +#define  SCAN_ADDR_TYPE_MWRAP  0x000000C0
3422 +#define SCAN_ADDR_PORT         0x00000F00
3423 +#define SCAN_ADDR_PORT_SHIFT   8
3424 +#define SCAN_ADDR_ADDR         0xFFFFF000
3425 +
3426 +#define SCAN_ADDR_SZ_BASE      0x00001000      /* 4KB */
3427 +
3428 +#define SCAN_SIZE_SZ_ALIGN     0x00000FFF
3429 +#define SCAN_SIZE_SZ           0xFFFFF000
3430 +#define SCAN_SIZE_SG32         0x00000008
3431 +
3432 +#endif /* BCMA_SCAN_H_ */
3433 --- /dev/null
3434 +++ b/drivers/bcma/sprom.c
3435 @@ -0,0 +1,600 @@
3436 +/*
3437 + * Broadcom specific AMBA
3438 + * SPROM reading
3439 + *
3440 + * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
3441 + *
3442 + * Licensed under the GNU/GPL. See COPYING for details.
3443 + */
3444 +
3445 +#include "bcma_private.h"
3446 +
3447 +#include <linux/bcma/bcma.h>
3448 +#include <linux/bcma/bcma_regs.h>
3449 +#include <linux/pci.h>
3450 +#include <linux/io.h>
3451 +#include <linux/dma-mapping.h>
3452 +#include <linux/slab.h>
3453 +
3454 +static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out);
3455 +
3456 +/**
3457 + * bcma_arch_register_fallback_sprom - Registers a method providing a
3458 + * fallback SPROM if no SPROM is found.
3459 + *
3460 + * @sprom_callback: The callback function.
3461 + *
3462 + * With this function the architecture implementation may register a
3463 + * callback handler which fills the SPROM data structure. The fallback is
3464 + * used for PCI based BCMA devices, where no valid SPROM can be found
3465 + * in the shadow registers and to provide the SPROM for SoCs where BCMA is
3466 + * to controll the system bus.
3467 + *
3468 + * This function is useful for weird architectures that have a half-assed
3469 + * BCMA device hardwired to their PCI bus.
3470 + *
3471 + * This function is available for architecture code, only. So it is not
3472 + * exported.
3473 + */
3474 +int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus,
3475 +                                    struct ssb_sprom *out))
3476 +{
3477 +       if (get_fallback_sprom)
3478 +               return -EEXIST;
3479 +       get_fallback_sprom = sprom_callback;
3480 +
3481 +       return 0;
3482 +}
3483 +
3484 +static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus,
3485 +                                        struct ssb_sprom *out)
3486 +{
3487 +       int err;
3488 +
3489 +       if (!get_fallback_sprom) {
3490 +               err = -ENOENT;
3491 +               goto fail;
3492 +       }
3493 +
3494 +       err = get_fallback_sprom(bus, out);
3495 +       if (err)
3496 +               goto fail;
3497 +
3498 +       pr_debug("Using SPROM revision %d provided by"
3499 +                " platform.\n", bus->sprom.revision);
3500 +       return 0;
3501 +fail:
3502 +       pr_warn("Using fallback SPROM failed (err %d)\n", err);
3503 +       return err;
3504 +}
3505 +
3506 +/**************************************************
3507 + * R/W ops.
3508 + **************************************************/
3509 +
3510 +static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom)
3511 +{
3512 +       int i;
3513 +       for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
3514 +               sprom[i] = bcma_read16(bus->drv_cc.core,
3515 +                                      offset + (i * 2));
3516 +}
3517 +
3518 +/**************************************************
3519 + * Validation.
3520 + **************************************************/
3521 +
3522 +static inline u8 bcma_crc8(u8 crc, u8 data)
3523 +{
3524 +       /* Polynomial:   x^8 + x^7 + x^6 + x^4 + x^2 + 1   */
3525 +       static const u8 t[] = {
3526 +               0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
3527 +               0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
3528 +               0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
3529 +               0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
3530 +               0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
3531 +               0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
3532 +               0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
3533 +               0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
3534 +               0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
3535 +               0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
3536 +               0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
3537 +               0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
3538 +               0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
3539 +               0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
3540 +               0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
3541 +               0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
3542 +               0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
3543 +               0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
3544 +               0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
3545 +               0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
3546 +               0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
3547 +               0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
3548 +               0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
3549 +               0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
3550 +               0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
3551 +               0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
3552 +               0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
3553 +               0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
3554 +               0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
3555 +               0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
3556 +               0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
3557 +               0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
3558 +       };
3559 +       return t[crc ^ data];
3560 +}
3561 +
3562 +static u8 bcma_sprom_crc(const u16 *sprom)
3563 +{
3564 +       int word;
3565 +       u8 crc = 0xFF;
3566 +
3567 +       for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) {
3568 +               crc = bcma_crc8(crc, sprom[word] & 0x00FF);
3569 +               crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
3570 +       }
3571 +       crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF);
3572 +       crc ^= 0xFF;
3573 +
3574 +       return crc;
3575 +}
3576 +
3577 +static int bcma_sprom_check_crc(const u16 *sprom)
3578 +{
3579 +       u8 crc;
3580 +       u8 expected_crc;
3581 +       u16 tmp;
3582 +
3583 +       crc = bcma_sprom_crc(sprom);
3584 +       tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC;
3585 +       expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
3586 +       if (crc != expected_crc)
3587 +               return -EPROTO;
3588 +
3589 +       return 0;
3590 +}
3591 +
3592 +static int bcma_sprom_valid(const u16 *sprom)
3593 +{
3594 +       u16 revision;
3595 +       int err;
3596 +
3597 +       err = bcma_sprom_check_crc(sprom);
3598 +       if (err)
3599 +               return err;
3600 +
3601 +       revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
3602 +       if (revision != 8 && revision != 9) {
3603 +               pr_err("Unsupported SPROM revision: %d\n", revision);
3604 +               return -ENOENT;
3605 +       }
3606 +
3607 +       return 0;
3608 +}
3609 +
3610 +/**************************************************
3611 + * SPROM extraction.
3612 + **************************************************/
3613 +
3614 +#define SPOFF(offset)  ((offset) / sizeof(u16))
3615 +
3616 +#define SPEX(_field, _offset, _mask, _shift)   \
3617 +       bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift))
3618 +
3619 +#define SPEX32(_field, _offset, _mask, _shift) \
3620 +       bus->sprom._field = ((((u32)sprom[SPOFF((_offset)+2)] << 16 | \
3621 +                               sprom[SPOFF(_offset)]) & (_mask)) >> (_shift))
3622 +
3623 +#define SPEX_ARRAY8(_field, _offset, _mask, _shift)    \
3624 +       do {    \
3625 +               SPEX(_field[0], _offset +  0, _mask, _shift);   \
3626 +               SPEX(_field[1], _offset +  2, _mask, _shift);   \
3627 +               SPEX(_field[2], _offset +  4, _mask, _shift);   \
3628 +               SPEX(_field[3], _offset +  6, _mask, _shift);   \
3629 +               SPEX(_field[4], _offset +  8, _mask, _shift);   \
3630 +               SPEX(_field[5], _offset + 10, _mask, _shift);   \
3631 +               SPEX(_field[6], _offset + 12, _mask, _shift);   \
3632 +               SPEX(_field[7], _offset + 14, _mask, _shift);   \
3633 +       } while (0)
3634 +
3635 +static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
3636 +{
3637 +       u16 v, o;
3638 +       int i;
3639 +       u16 pwr_info_offset[] = {
3640 +               SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
3641 +               SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
3642 +       };
3643 +       BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
3644 +                       ARRAY_SIZE(bus->sprom.core_pwr_info));
3645 +
3646 +       bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
3647 +               SSB_SPROM_REVISION_REV;
3648 +
3649 +       for (i = 0; i < 3; i++) {
3650 +               v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
3651 +               *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
3652 +       }
3653 +
3654 +       SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0);
3655 +
3656 +       SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0,
3657 +            SSB_SPROM4_TXPID2G0_SHIFT);
3658 +       SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G1,
3659 +            SSB_SPROM4_TXPID2G1_SHIFT);
3660 +       SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G2,
3661 +            SSB_SPROM4_TXPID2G2_SHIFT);
3662 +       SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G3,
3663 +            SSB_SPROM4_TXPID2G3_SHIFT);
3664 +
3665 +       SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL0,
3666 +            SSB_SPROM4_TXPID5GL0_SHIFT);
3667 +       SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL1,
3668 +            SSB_SPROM4_TXPID5GL1_SHIFT);
3669 +       SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL2,
3670 +            SSB_SPROM4_TXPID5GL2_SHIFT);
3671 +       SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL3,
3672 +            SSB_SPROM4_TXPID5GL3_SHIFT);
3673 +
3674 +       SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G0,
3675 +            SSB_SPROM4_TXPID5G0_SHIFT);
3676 +       SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G1,
3677 +            SSB_SPROM4_TXPID5G1_SHIFT);
3678 +       SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G2,
3679 +            SSB_SPROM4_TXPID5G2_SHIFT);
3680 +       SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G3,
3681 +            SSB_SPROM4_TXPID5G3_SHIFT);
3682 +
3683 +       SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH0,
3684 +            SSB_SPROM4_TXPID5GH0_SHIFT);
3685 +       SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH1,
3686 +            SSB_SPROM4_TXPID5GH1_SHIFT);
3687 +       SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH2,
3688 +            SSB_SPROM4_TXPID5GH2_SHIFT);
3689 +       SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH3,
3690 +            SSB_SPROM4_TXPID5GH3_SHIFT);
3691 +
3692 +       SPEX(boardflags_lo, SSB_SPROM8_BFLLO, ~0, 0);
3693 +       SPEX(boardflags_hi, SSB_SPROM8_BFLHI, ~0, 0);
3694 +       SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0);
3695 +       SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0);
3696 +
3697 +       SPEX(alpha2[0], SSB_SPROM8_CCODE, 0xff00, 8);
3698 +       SPEX(alpha2[1], SSB_SPROM8_CCODE, 0x00ff, 0);
3699 +
3700 +       /* Extract cores power info info */
3701 +       for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
3702 +               o = pwr_info_offset[i];
3703 +               SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
3704 +                       SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
3705 +               SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
3706 +                       SSB_SPROM8_2G_MAXP, 0);
3707 +
3708 +               SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
3709 +               SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
3710 +               SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
3711 +
3712 +               SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
3713 +                       SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
3714 +               SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
3715 +                       SSB_SPROM8_5G_MAXP, 0);
3716 +               SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
3717 +                       SSB_SPROM8_5GH_MAXP, 0);
3718 +               SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
3719 +                       SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
3720 +
3721 +               SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
3722 +               SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
3723 +               SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
3724 +               SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
3725 +               SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
3726 +               SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
3727 +               SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
3728 +               SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
3729 +               SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
3730 +       }
3731 +
3732 +       SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS,
3733 +            SSB_SROM8_FEM_TSSIPOS_SHIFT);
3734 +       SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN,
3735 +            SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
3736 +       SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_PDET_RANGE,
3737 +            SSB_SROM8_FEM_PDET_RANGE_SHIFT);
3738 +       SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TR_ISO,
3739 +            SSB_SROM8_FEM_TR_ISO_SHIFT);
3740 +       SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_ANTSWLUT,
3741 +            SSB_SROM8_FEM_ANTSWLUT_SHIFT);
3742 +
3743 +       SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TSSIPOS,
3744 +            SSB_SROM8_FEM_TSSIPOS_SHIFT);
3745 +       SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_EXTPA_GAIN,
3746 +            SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
3747 +       SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_PDET_RANGE,
3748 +            SSB_SROM8_FEM_PDET_RANGE_SHIFT);
3749 +       SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TR_ISO,
3750 +            SSB_SROM8_FEM_TR_ISO_SHIFT);
3751 +       SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT,
3752 +            SSB_SROM8_FEM_ANTSWLUT_SHIFT);
3753 +
3754 +       SPEX(ant_available_a, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_A,
3755 +            SSB_SPROM8_ANTAVAIL_A_SHIFT);
3756 +       SPEX(ant_available_bg, SSB_SPROM8_ANTAVAIL, SSB_SPROM8_ANTAVAIL_BG,
3757 +            SSB_SPROM8_ANTAVAIL_BG_SHIFT);
3758 +       SPEX(maxpwr_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_MAXP_BG_MASK, 0);
3759 +       SPEX(itssi_bg, SSB_SPROM8_MAXP_BG, SSB_SPROM8_ITSSI_BG,
3760 +            SSB_SPROM8_ITSSI_BG_SHIFT);
3761 +       SPEX(maxpwr_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_MAXP_A_MASK, 0);
3762 +       SPEX(itssi_a, SSB_SPROM8_MAXP_A, SSB_SPROM8_ITSSI_A,
3763 +            SSB_SPROM8_ITSSI_A_SHIFT);
3764 +       SPEX(maxpwr_ah, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AH_MASK, 0);
3765 +       SPEX(maxpwr_al, SSB_SPROM8_MAXP_AHL, SSB_SPROM8_MAXP_AL_MASK,
3766 +            SSB_SPROM8_MAXP_AL_SHIFT);
3767 +       SPEX(gpio0, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P0, 0);
3768 +       SPEX(gpio1, SSB_SPROM8_GPIOA, SSB_SPROM8_GPIOA_P1,
3769 +            SSB_SPROM8_GPIOA_P1_SHIFT);
3770 +       SPEX(gpio2, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P2, 0);
3771 +       SPEX(gpio3, SSB_SPROM8_GPIOB, SSB_SPROM8_GPIOB_P3,
3772 +            SSB_SPROM8_GPIOB_P3_SHIFT);
3773 +       SPEX(tri2g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI2G, 0);
3774 +       SPEX(tri5g, SSB_SPROM8_TRI25G, SSB_SPROM8_TRI5G,
3775 +            SSB_SPROM8_TRI5G_SHIFT);
3776 +       SPEX(tri5gl, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GL, 0);
3777 +       SPEX(tri5gh, SSB_SPROM8_TRI5GHL, SSB_SPROM8_TRI5GH,
3778 +            SSB_SPROM8_TRI5GH_SHIFT);
3779 +       SPEX(rxpo2g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO2G,
3780 +            SSB_SPROM8_RXPO2G_SHIFT);
3781 +       SPEX(rxpo5g, SSB_SPROM8_RXPO, SSB_SPROM8_RXPO5G,
3782 +            SSB_SPROM8_RXPO5G_SHIFT);
3783 +       SPEX(rssismf2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMF2G, 0);
3784 +       SPEX(rssismc2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISMC2G,
3785 +            SSB_SPROM8_RSSISMC2G_SHIFT);
3786 +       SPEX(rssisav2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_RSSISAV2G,
3787 +            SSB_SPROM8_RSSISAV2G_SHIFT);
3788 +       SPEX(bxa2g, SSB_SPROM8_RSSIPARM2G, SSB_SPROM8_BXA2G,
3789 +            SSB_SPROM8_BXA2G_SHIFT);
3790 +       SPEX(rssismf5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMF5G, 0);
3791 +       SPEX(rssismc5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISMC5G,
3792 +            SSB_SPROM8_RSSISMC5G_SHIFT);
3793 +       SPEX(rssisav5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_RSSISAV5G,
3794 +            SSB_SPROM8_RSSISAV5G_SHIFT);
3795 +       SPEX(bxa5g, SSB_SPROM8_RSSIPARM5G, SSB_SPROM8_BXA5G,
3796 +            SSB_SPROM8_BXA5G_SHIFT);
3797 +
3798 +       SPEX(pa0b0, SSB_SPROM8_PA0B0, ~0, 0);
3799 +       SPEX(pa0b1, SSB_SPROM8_PA0B1, ~0, 0);
3800 +       SPEX(pa0b2, SSB_SPROM8_PA0B2, ~0, 0);
3801 +       SPEX(pa1b0, SSB_SPROM8_PA1B0, ~0, 0);
3802 +       SPEX(pa1b1, SSB_SPROM8_PA1B1, ~0, 0);
3803 +       SPEX(pa1b2, SSB_SPROM8_PA1B2, ~0, 0);
3804 +       SPEX(pa1lob0, SSB_SPROM8_PA1LOB0, ~0, 0);
3805 +       SPEX(pa1lob1, SSB_SPROM8_PA1LOB1, ~0, 0);
3806 +       SPEX(pa1lob2, SSB_SPROM8_PA1LOB2, ~0, 0);
3807 +       SPEX(pa1hib0, SSB_SPROM8_PA1HIB0, ~0, 0);
3808 +       SPEX(pa1hib1, SSB_SPROM8_PA1HIB1, ~0, 0);
3809 +       SPEX(pa1hib2, SSB_SPROM8_PA1HIB2, ~0, 0);
3810 +       SPEX(cck2gpo, SSB_SPROM8_CCK2GPO, ~0, 0);
3811 +       SPEX32(ofdm2gpo, SSB_SPROM8_OFDM2GPO, ~0, 0);
3812 +       SPEX32(ofdm5glpo, SSB_SPROM8_OFDM5GLPO, ~0, 0);
3813 +       SPEX32(ofdm5gpo, SSB_SPROM8_OFDM5GPO, ~0, 0);
3814 +       SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, ~0, 0);
3815 +
3816 +       /* Extract the antenna gain values. */
3817 +       SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
3818 +            SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
3819 +       SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
3820 +            SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
3821 +       SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
3822 +            SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
3823 +       SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
3824 +            SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
3825 +
3826 +       SPEX(leddc_on_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_ON,
3827 +            SSB_SPROM8_LEDDC_ON_SHIFT);
3828 +       SPEX(leddc_off_time, SSB_SPROM8_LEDDC, SSB_SPROM8_LEDDC_OFF,
3829 +            SSB_SPROM8_LEDDC_OFF_SHIFT);
3830 +
3831 +       SPEX(txchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_TXCHAIN,
3832 +            SSB_SPROM8_TXRXC_TXCHAIN_SHIFT);
3833 +       SPEX(rxchain, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_RXCHAIN,
3834 +            SSB_SPROM8_TXRXC_RXCHAIN_SHIFT);
3835 +       SPEX(antswitch, SSB_SPROM8_TXRXC, SSB_SPROM8_TXRXC_SWITCH,
3836 +            SSB_SPROM8_TXRXC_SWITCH_SHIFT);
3837 +
3838 +       SPEX(opo, SSB_SPROM8_OFDM2GPO, 0x00ff, 0);
3839 +
3840 +       SPEX_ARRAY8(mcs2gpo, SSB_SPROM8_2G_MCSPO, ~0, 0);
3841 +       SPEX_ARRAY8(mcs5gpo, SSB_SPROM8_5G_MCSPO, ~0, 0);
3842 +       SPEX_ARRAY8(mcs5glpo, SSB_SPROM8_5GL_MCSPO, ~0, 0);
3843 +       SPEX_ARRAY8(mcs5ghpo, SSB_SPROM8_5GH_MCSPO, ~0, 0);
3844 +
3845 +       SPEX(rawtempsense, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_RAWTEMP,
3846 +            SSB_SPROM8_RAWTS_RAWTEMP_SHIFT);
3847 +       SPEX(measpower, SSB_SPROM8_RAWTS, SSB_SPROM8_RAWTS_MEASPOWER,
3848 +            SSB_SPROM8_RAWTS_MEASPOWER_SHIFT);
3849 +       SPEX(tempsense_slope, SSB_SPROM8_OPT_CORRX,
3850 +            SSB_SPROM8_OPT_CORRX_TEMP_SLOPE,
3851 +            SSB_SPROM8_OPT_CORRX_TEMP_SLOPE_SHIFT);
3852 +       SPEX(tempcorrx, SSB_SPROM8_OPT_CORRX, SSB_SPROM8_OPT_CORRX_TEMPCORRX,
3853 +            SSB_SPROM8_OPT_CORRX_TEMPCORRX_SHIFT);
3854 +       SPEX(tempsense_option, SSB_SPROM8_OPT_CORRX,
3855 +            SSB_SPROM8_OPT_CORRX_TEMP_OPTION,
3856 +            SSB_SPROM8_OPT_CORRX_TEMP_OPTION_SHIFT);
3857 +       SPEX(freqoffset_corr, SSB_SPROM8_HWIQ_IQSWP,
3858 +            SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR,
3859 +            SSB_SPROM8_HWIQ_IQSWP_FREQ_CORR_SHIFT);
3860 +       SPEX(iqcal_swp_dis, SSB_SPROM8_HWIQ_IQSWP,
3861 +            SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP,
3862 +            SSB_SPROM8_HWIQ_IQSWP_IQCAL_SWP_SHIFT);
3863 +       SPEX(hw_iqcal_en, SSB_SPROM8_HWIQ_IQSWP, SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL,
3864 +            SSB_SPROM8_HWIQ_IQSWP_HW_IQCAL_SHIFT);
3865 +
3866 +       SPEX(bw40po, SSB_SPROM8_BW40PO, ~0, 0);
3867 +       SPEX(cddpo, SSB_SPROM8_CDDPO, ~0, 0);
3868 +       SPEX(stbcpo, SSB_SPROM8_STBCPO, ~0, 0);
3869 +       SPEX(bwduppo, SSB_SPROM8_BWDUPPO, ~0, 0);
3870 +
3871 +       SPEX(tempthresh, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_TRESH,
3872 +            SSB_SPROM8_THERMAL_TRESH_SHIFT);
3873 +       SPEX(tempoffset, SSB_SPROM8_THERMAL, SSB_SPROM8_THERMAL_OFFSET,
3874 +            SSB_SPROM8_THERMAL_OFFSET_SHIFT);
3875 +       SPEX(phycal_tempdelta, SSB_SPROM8_TEMPDELTA,
3876 +            SSB_SPROM8_TEMPDELTA_PHYCAL,
3877 +            SSB_SPROM8_TEMPDELTA_PHYCAL_SHIFT);
3878 +       SPEX(temps_period, SSB_SPROM8_TEMPDELTA, SSB_SPROM8_TEMPDELTA_PERIOD,
3879 +            SSB_SPROM8_TEMPDELTA_PERIOD_SHIFT);
3880 +       SPEX(temps_hysteresis, SSB_SPROM8_TEMPDELTA,
3881 +            SSB_SPROM8_TEMPDELTA_HYSTERESIS,
3882 +            SSB_SPROM8_TEMPDELTA_HYSTERESIS_SHIFT);
3883 +}
3884 +
3885 +/*
3886 + * Indicates the presence of external SPROM.
3887 + */
3888 +static bool bcma_sprom_ext_available(struct bcma_bus *bus)
3889 +{
3890 +       u32 chip_status;
3891 +       u32 srom_control;
3892 +       u32 present_mask;
3893 +
3894 +       if (bus->drv_cc.core->id.rev >= 31) {
3895 +               if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
3896 +                       return false;
3897 +
3898 +               srom_control = bcma_read32(bus->drv_cc.core,
3899 +                                          BCMA_CC_SROM_CONTROL);
3900 +               return srom_control & BCMA_CC_SROM_CONTROL_PRESENT;
3901 +       }
3902 +
3903 +       /* older chipcommon revisions use chip status register */
3904 +       chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
3905 +       switch (bus->chipinfo.id) {
3906 +       case 0x4313:
3907 +               present_mask = BCMA_CC_CHIPST_4313_SPROM_PRESENT;
3908 +               break;
3909 +
3910 +       case 0x4331:
3911 +               present_mask = BCMA_CC_CHIPST_4331_SPROM_PRESENT;
3912 +               break;
3913 +
3914 +       default:
3915 +               return true;
3916 +       }
3917 +
3918 +       return chip_status & present_mask;
3919 +}
3920 +
3921 +/*
3922 + * Indicates that on-chip OTP memory is present and enabled.
3923 + */
3924 +static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
3925 +{
3926 +       u32 chip_status;
3927 +       u32 otpsize = 0;
3928 +       bool present;
3929 +
3930 +       chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
3931 +       switch (bus->chipinfo.id) {
3932 +       case 0x4313:
3933 +               present = chip_status & BCMA_CC_CHIPST_4313_OTP_PRESENT;
3934 +               break;
3935 +
3936 +       case 0x4331:
3937 +               present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
3938 +               break;
3939 +
3940 +       case 43224:
3941 +       case 43225:
3942 +               /* for these chips OTP is always available */
3943 +               present = true;
3944 +               break;
3945 +
3946 +       default:
3947 +               present = false;
3948 +               break;
3949 +       }
3950 +
3951 +       if (present) {
3952 +               otpsize = bus->drv_cc.capabilities & BCMA_CC_CAP_OTPS;
3953 +               otpsize >>= BCMA_CC_CAP_OTPS_SHIFT;
3954 +       }
3955 +
3956 +       return otpsize != 0;
3957 +}
3958 +
3959 +/*
3960 + * Verify OTP is filled and determine the byte
3961 + * offset where SPROM data is located.
3962 + *
3963 + * On error, returns 0; byte offset otherwise.
3964 + */
3965 +static int bcma_sprom_onchip_offset(struct bcma_bus *bus)
3966 +{
3967 +       struct bcma_device *cc = bus->drv_cc.core;
3968 +       u32 offset;
3969 +
3970 +       /* verify OTP status */
3971 +       if ((bcma_read32(cc, BCMA_CC_OTPS) & BCMA_CC_OTPS_GU_PROG_HW) == 0)
3972 +               return 0;
3973 +
3974 +       /* obtain bit offset from otplayout register */
3975 +       offset = (bcma_read32(cc, BCMA_CC_OTPL) & BCMA_CC_OTPL_GURGN_OFFSET);
3976 +       return BCMA_CC_SPROM + (offset >> 3);
3977 +}
3978 +
3979 +int bcma_sprom_get(struct bcma_bus *bus)
3980 +{
3981 +       u16 offset = BCMA_CC_SPROM;
3982 +       u16 *sprom;
3983 +       int err = 0;
3984 +
3985 +       if (!bus->drv_cc.core)
3986 +               return -EOPNOTSUPP;
3987 +
3988 +       if (!bcma_sprom_ext_available(bus)) {
3989 +               bool sprom_onchip;
3990 +
3991 +               /*
3992 +                * External SPROM takes precedence so check
3993 +                * on-chip OTP only when no external SPROM
3994 +                * is present.
3995 +                */
3996 +               sprom_onchip = bcma_sprom_onchip_available(bus);
3997 +               if (sprom_onchip) {
3998 +                       /* determine offset */
3999 +                       offset = bcma_sprom_onchip_offset(bus);
4000 +               }
4001 +               if (!offset || !sprom_onchip) {
4002 +                       /*
4003 +                        * Maybe there is no SPROM on the device?
4004 +                        * Now we ask the arch code if there is some sprom
4005 +                        * available for this device in some other storage.
4006 +                        */
4007 +                       err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
4008 +                       return err;
4009 +               }
4010 +       }
4011 +
4012 +       sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
4013 +                       GFP_KERNEL);
4014 +       if (!sprom)
4015 +               return -ENOMEM;
4016 +
4017 +       if (bus->chipinfo.id == 0x4331)
4018 +               bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
4019 +
4020 +       pr_debug("SPROM offset 0x%x\n", offset);
4021 +       bcma_sprom_read(bus, offset, sprom);
4022 +
4023 +       if (bus->chipinfo.id == 0x4331)
4024 +               bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
4025 +
4026 +       err = bcma_sprom_valid(sprom);
4027 +       if (err)
4028 +               goto out;
4029 +
4030 +       bcma_sprom_extract_r8(bus, sprom);
4031 +
4032 +out:
4033 +       kfree(sprom);
4034 +       return err;
4035 +}
4036 --- /dev/null
4037 +++ b/include/linux/bcma/bcma.h
4038 @@ -0,0 +1,314 @@
4039 +#ifndef LINUX_BCMA_H_
4040 +#define LINUX_BCMA_H_
4041 +
4042 +#include <linux/pci.h>
4043 +#include <linux/mod_devicetable.h>
4044 +
4045 +#include <linux/bcma/bcma_driver_chipcommon.h>
4046 +#include <linux/bcma/bcma_driver_pci.h>
4047 +#include <linux/bcma/bcma_driver_mips.h>
4048 +#include <linux/ssb/ssb.h> /* SPROM sharing */
4049 +
4050 +#include "bcma_regs.h"
4051 +
4052 +struct bcma_device;
4053 +struct bcma_bus;
4054 +
4055 +enum bcma_hosttype {
4056 +       BCMA_HOSTTYPE_PCI,
4057 +       BCMA_HOSTTYPE_SDIO,
4058 +       BCMA_HOSTTYPE_SOC,
4059 +};
4060 +
4061 +struct bcma_chipinfo {
4062 +       u16 id;
4063 +       u8 rev;
4064 +       u8 pkg;
4065 +};
4066 +
4067 +struct bcma_boardinfo {
4068 +       u16 vendor;
4069 +       u16 type;
4070 +};
4071 +
4072 +enum bcma_clkmode {
4073 +       BCMA_CLKMODE_FAST,
4074 +       BCMA_CLKMODE_DYNAMIC,
4075 +};
4076 +
4077 +struct bcma_host_ops {
4078 +       u8 (*read8)(struct bcma_device *core, u16 offset);
4079 +       u16 (*read16)(struct bcma_device *core, u16 offset);
4080 +       u32 (*read32)(struct bcma_device *core, u16 offset);
4081 +       void (*write8)(struct bcma_device *core, u16 offset, u8 value);
4082 +       void (*write16)(struct bcma_device *core, u16 offset, u16 value);
4083 +       void (*write32)(struct bcma_device *core, u16 offset, u32 value);
4084 +#ifdef CONFIG_BCMA_BLOCKIO
4085 +       void (*block_read)(struct bcma_device *core, void *buffer,
4086 +                          size_t count, u16 offset, u8 reg_width);
4087 +       void (*block_write)(struct bcma_device *core, const void *buffer,
4088 +                           size_t count, u16 offset, u8 reg_width);
4089 +#endif
4090 +       /* Agent ops */
4091 +       u32 (*aread32)(struct bcma_device *core, u16 offset);
4092 +       void (*awrite32)(struct bcma_device *core, u16 offset, u32 value);
4093 +};
4094 +
4095 +/* Core manufacturers */
4096 +#define BCMA_MANUF_ARM                 0x43B
4097 +#define BCMA_MANUF_MIPS                        0x4A7
4098 +#define BCMA_MANUF_BCM                 0x4BF
4099 +
4100 +/* Core class values. */
4101 +#define BCMA_CL_SIM                    0x0
4102 +#define BCMA_CL_EROM                   0x1
4103 +#define BCMA_CL_CORESIGHT              0x9
4104 +#define BCMA_CL_VERIF                  0xB
4105 +#define BCMA_CL_OPTIMO                 0xD
4106 +#define BCMA_CL_GEN                    0xE
4107 +#define BCMA_CL_PRIMECELL              0xF
4108 +
4109 +/* Core-ID values. */
4110 +#define BCMA_CORE_OOB_ROUTER           0x367   /* Out of band */
4111 +#define BCMA_CORE_INVALID              0x700
4112 +#define BCMA_CORE_CHIPCOMMON           0x800
4113 +#define BCMA_CORE_ILINE20              0x801
4114 +#define BCMA_CORE_SRAM                 0x802
4115 +#define BCMA_CORE_SDRAM                        0x803
4116 +#define BCMA_CORE_PCI                  0x804
4117 +#define BCMA_CORE_MIPS                 0x805
4118 +#define BCMA_CORE_ETHERNET             0x806
4119 +#define BCMA_CORE_V90                  0x807
4120 +#define BCMA_CORE_USB11_HOSTDEV                0x808
4121 +#define BCMA_CORE_ADSL                 0x809
4122 +#define BCMA_CORE_ILINE100             0x80A
4123 +#define BCMA_CORE_IPSEC                        0x80B
4124 +#define BCMA_CORE_UTOPIA               0x80C
4125 +#define BCMA_CORE_PCMCIA               0x80D
4126 +#define BCMA_CORE_INTERNAL_MEM         0x80E
4127 +#define BCMA_CORE_MEMC_SDRAM           0x80F
4128 +#define BCMA_CORE_OFDM                 0x810
4129 +#define BCMA_CORE_EXTIF                        0x811
4130 +#define BCMA_CORE_80211                        0x812
4131 +#define BCMA_CORE_PHY_A                        0x813
4132 +#define BCMA_CORE_PHY_B                        0x814
4133 +#define BCMA_CORE_PHY_G                        0x815
4134 +#define BCMA_CORE_MIPS_3302            0x816
4135 +#define BCMA_CORE_USB11_HOST           0x817
4136 +#define BCMA_CORE_USB11_DEV            0x818
4137 +#define BCMA_CORE_USB20_HOST           0x819
4138 +#define BCMA_CORE_USB20_DEV            0x81A
4139 +#define BCMA_CORE_SDIO_HOST            0x81B
4140 +#define BCMA_CORE_ROBOSWITCH           0x81C
4141 +#define BCMA_CORE_PARA_ATA             0x81D
4142 +#define BCMA_CORE_SATA_XORDMA          0x81E
4143 +#define BCMA_CORE_ETHERNET_GBIT                0x81F
4144 +#define BCMA_CORE_PCIE                 0x820
4145 +#define BCMA_CORE_PHY_N                        0x821
4146 +#define BCMA_CORE_SRAM_CTL             0x822
4147 +#define BCMA_CORE_MINI_MACPHY          0x823
4148 +#define BCMA_CORE_ARM_1176             0x824
4149 +#define BCMA_CORE_ARM_7TDMI            0x825
4150 +#define BCMA_CORE_PHY_LP               0x826
4151 +#define BCMA_CORE_PMU                  0x827
4152 +#define BCMA_CORE_PHY_SSN              0x828
4153 +#define BCMA_CORE_SDIO_DEV             0x829
4154 +#define BCMA_CORE_ARM_CM3              0x82A
4155 +#define BCMA_CORE_PHY_HT               0x82B
4156 +#define BCMA_CORE_MIPS_74K             0x82C
4157 +#define BCMA_CORE_MAC_GBIT             0x82D
4158 +#define BCMA_CORE_DDR12_MEM_CTL                0x82E
4159 +#define BCMA_CORE_PCIE_RC              0x82F   /* PCIe Root Complex */
4160 +#define BCMA_CORE_OCP_OCP_BRIDGE       0x830
4161 +#define BCMA_CORE_SHARED_COMMON                0x831
4162 +#define BCMA_CORE_OCP_AHB_BRIDGE       0x832
4163 +#define BCMA_CORE_SPI_HOST             0x833
4164 +#define BCMA_CORE_I2S                  0x834
4165 +#define BCMA_CORE_SDR_DDR1_MEM_CTL     0x835   /* SDR/DDR1 memory controller core */
4166 +#define BCMA_CORE_SHIM                 0x837   /* SHIM component in ubus/6362 */
4167 +#define BCMA_CORE_DEFAULT              0xFFF
4168 +
4169 +#define BCMA_MAX_NR_CORES              16
4170 +
4171 +struct bcma_device {
4172 +       struct bcma_bus *bus;
4173 +       struct bcma_device_id id;
4174 +
4175 +       struct device dev;
4176 +       struct device *dma_dev;
4177 +
4178 +       unsigned int irq;
4179 +       bool dev_registered;
4180 +
4181 +       u8 core_index;
4182 +       u8 core_unit;
4183 +
4184 +       u32 addr;
4185 +       u32 wrap;
4186 +
4187 +       void __iomem *io_addr;
4188 +       void __iomem *io_wrap;
4189 +
4190 +       void *drvdata;
4191 +       struct list_head list;
4192 +};
4193 +
4194 +static inline void *bcma_get_drvdata(struct bcma_device *core)
4195 +{
4196 +       return core->drvdata;
4197 +}
4198 +static inline void bcma_set_drvdata(struct bcma_device *core, void *drvdata)
4199 +{
4200 +       core->drvdata = drvdata;
4201 +}
4202 +
4203 +struct bcma_driver {
4204 +       const char *name;
4205 +       const struct bcma_device_id *id_table;
4206 +
4207 +       int (*probe)(struct bcma_device *dev);
4208 +       void (*remove)(struct bcma_device *dev);
4209 +       int (*suspend)(struct bcma_device *dev);
4210 +       int (*resume)(struct bcma_device *dev);
4211 +       void (*shutdown)(struct bcma_device *dev);
4212 +
4213 +       struct device_driver drv;
4214 +};
4215 +extern
4216 +int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
4217 +#define bcma_driver_register(drv) \
4218 +       __bcma_driver_register(drv, THIS_MODULE)
4219 +
4220 +extern void bcma_driver_unregister(struct bcma_driver *drv);
4221 +
4222 +/* Set a fallback SPROM.
4223 + * See kdoc at the function definition for complete documentation. */
4224 +extern int bcma_arch_register_fallback_sprom(
4225 +               int (*sprom_callback)(struct bcma_bus *bus,
4226 +               struct ssb_sprom *out));
4227 +
4228 +struct bcma_bus {
4229 +       /* The MMIO area. */
4230 +       void __iomem *mmio;
4231 +
4232 +       const struct bcma_host_ops *ops;
4233 +
4234 +       enum bcma_hosttype hosttype;
4235 +       union {
4236 +               /* Pointer to the PCI bus (only for BCMA_HOSTTYPE_PCI) */
4237 +               struct pci_dev *host_pci;
4238 +               /* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */
4239 +               struct sdio_func *host_sdio;
4240 +       };
4241 +
4242 +       struct bcma_chipinfo chipinfo;
4243 +
4244 +       struct bcma_boardinfo boardinfo;
4245 +
4246 +       struct bcma_device *mapped_core;
4247 +       struct list_head cores;
4248 +       u8 nr_cores;
4249 +       u8 init_done:1;
4250 +       u8 num;
4251 +
4252 +       struct bcma_drv_cc drv_cc;
4253 +       struct bcma_drv_pci drv_pci;
4254 +       struct bcma_drv_mips drv_mips;
4255 +
4256 +       /* We decided to share SPROM struct with SSB as long as we do not need
4257 +        * any hacks for BCMA. This simplifies drivers code. */
4258 +       struct ssb_sprom sprom;
4259 +};
4260 +
4261 +static inline u32 bcma_read8(struct bcma_device *core, u16 offset)
4262 +{
4263 +       return core->bus->ops->read8(core, offset);
4264 +}
4265 +static inline u32 bcma_read16(struct bcma_device *core, u16 offset)
4266 +{
4267 +       return core->bus->ops->read16(core, offset);
4268 +}
4269 +static inline u32 bcma_read32(struct bcma_device *core, u16 offset)
4270 +{
4271 +       return core->bus->ops->read32(core, offset);
4272 +}
4273 +static inline
4274 +void bcma_write8(struct bcma_device *core, u16 offset, u32 value)
4275 +{
4276 +       core->bus->ops->write8(core, offset, value);
4277 +}
4278 +static inline
4279 +void bcma_write16(struct bcma_device *core, u16 offset, u32 value)
4280 +{
4281 +       core->bus->ops->write16(core, offset, value);
4282 +}
4283 +static inline
4284 +void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
4285 +{
4286 +       core->bus->ops->write32(core, offset, value);
4287 +}
4288 +#ifdef CONFIG_BCMA_BLOCKIO
4289 +static inline void bcma_block_read(struct bcma_device *core, void *buffer,
4290 +                                  size_t count, u16 offset, u8 reg_width)
4291 +{
4292 +       core->bus->ops->block_read(core, buffer, count, offset, reg_width);
4293 +}
4294 +static inline void bcma_block_write(struct bcma_device *core,
4295 +                                   const void *buffer, size_t count,
4296 +                                   u16 offset, u8 reg_width)
4297 +{
4298 +       core->bus->ops->block_write(core, buffer, count, offset, reg_width);
4299 +}
4300 +#endif
4301 +static inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
4302 +{
4303 +       return core->bus->ops->aread32(core, offset);
4304 +}
4305 +static inline
4306 +void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
4307 +{
4308 +       core->bus->ops->awrite32(core, offset, value);
4309 +}
4310 +
4311 +static inline void bcma_mask32(struct bcma_device *cc, u16 offset, u32 mask)
4312 +{
4313 +       bcma_write32(cc, offset, bcma_read32(cc, offset) & mask);
4314 +}
4315 +static inline void bcma_set32(struct bcma_device *cc, u16 offset, u32 set)
4316 +{
4317 +       bcma_write32(cc, offset, bcma_read32(cc, offset) | set);
4318 +}
4319 +static inline void bcma_maskset32(struct bcma_device *cc,
4320 +                                 u16 offset, u32 mask, u32 set)
4321 +{
4322 +       bcma_write32(cc, offset, (bcma_read32(cc, offset) & mask) | set);
4323 +}
4324 +static inline void bcma_mask16(struct bcma_device *cc, u16 offset, u16 mask)
4325 +{
4326 +       bcma_write16(cc, offset, bcma_read16(cc, offset) & mask);
4327 +}
4328 +static inline void bcma_set16(struct bcma_device *cc, u16 offset, u16 set)
4329 +{
4330 +       bcma_write16(cc, offset, bcma_read16(cc, offset) | set);
4331 +}
4332 +static inline void bcma_maskset16(struct bcma_device *cc,
4333 +                                 u16 offset, u16 mask, u16 set)
4334 +{
4335 +       bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
4336 +}
4337 +
4338 +extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid);
4339 +extern bool bcma_core_is_enabled(struct bcma_device *core);
4340 +extern void bcma_core_disable(struct bcma_device *core, u32 flags);
4341 +extern int bcma_core_enable(struct bcma_device *core, u32 flags);
4342 +extern void bcma_core_set_clockmode(struct bcma_device *core,
4343 +                                   enum bcma_clkmode clkmode);
4344 +extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status,
4345 +                             bool on);
4346 +#define BCMA_DMA_TRANSLATION_MASK      0xC0000000
4347 +#define  BCMA_DMA_TRANSLATION_NONE     0x00000000
4348 +#define  BCMA_DMA_TRANSLATION_DMA32_CMT        0x40000000 /* Client Mode Translation for 32-bit DMA */
4349 +#define  BCMA_DMA_TRANSLATION_DMA64_CMT        0x80000000 /* Client Mode Translation for 64-bit DMA */
4350 +extern u32 bcma_core_dma_translation(struct bcma_device *core);
4351 +
4352 +#endif /* LINUX_BCMA_H_ */
4353 --- /dev/null
4354 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
4355 @@ -0,0 +1,415 @@
4356 +#ifndef LINUX_BCMA_DRIVER_CC_H_
4357 +#define LINUX_BCMA_DRIVER_CC_H_
4358 +
4359 +/** ChipCommon core registers. **/
4360 +#define BCMA_CC_ID                     0x0000
4361 +#define  BCMA_CC_ID_ID                 0x0000FFFF
4362 +#define  BCMA_CC_ID_ID_SHIFT           0
4363 +#define  BCMA_CC_ID_REV                        0x000F0000
4364 +#define  BCMA_CC_ID_REV_SHIFT          16
4365 +#define  BCMA_CC_ID_PKG                        0x00F00000
4366 +#define  BCMA_CC_ID_PKG_SHIFT          20
4367 +#define  BCMA_CC_ID_NRCORES            0x0F000000
4368 +#define  BCMA_CC_ID_NRCORES_SHIFT      24
4369 +#define  BCMA_CC_ID_TYPE               0xF0000000
4370 +#define  BCMA_CC_ID_TYPE_SHIFT         28
4371 +#define BCMA_CC_CAP                    0x0004          /* Capabilities */
4372 +#define  BCMA_CC_CAP_NRUART            0x00000003      /* # of UARTs */
4373 +#define  BCMA_CC_CAP_MIPSEB            0x00000004      /* MIPS in BigEndian Mode */
4374 +#define  BCMA_CC_CAP_UARTCLK           0x00000018      /* UART clock select */
4375 +#define   BCMA_CC_CAP_UARTCLK_INT      0x00000008      /* UARTs are driven by internal divided clock */
4376 +#define  BCMA_CC_CAP_UARTGPIO          0x00000020      /* UARTs on GPIO 15-12 */
4377 +#define  BCMA_CC_CAP_EXTBUS            0x000000C0      /* External buses present */
4378 +#define  BCMA_CC_CAP_FLASHT            0x00000700      /* Flash Type */
4379 +#define   BCMA_CC_FLASHT_NONE          0x00000000      /* No flash */
4380 +#define   BCMA_CC_FLASHT_STSER         0x00000100      /* ST serial flash */
4381 +#define   BCMA_CC_FLASHT_ATSER         0x00000200      /* Atmel serial flash */
4382 +#define   BCMA_CC_FLASHT_NFLASH                0x00000200
4383 +#define          BCMA_CC_FLASHT_PARA           0x00000700      /* Parallel flash */
4384 +#define  BCMA_CC_CAP_PLLT              0x00038000      /* PLL Type */
4385 +#define   BCMA_PLLTYPE_NONE            0x00000000
4386 +#define   BCMA_PLLTYPE_1               0x00010000      /* 48Mhz base, 3 dividers */
4387 +#define   BCMA_PLLTYPE_2               0x00020000      /* 48Mhz, 4 dividers */
4388 +#define   BCMA_PLLTYPE_3               0x00030000      /* 25Mhz, 2 dividers */
4389 +#define   BCMA_PLLTYPE_4               0x00008000      /* 48Mhz, 4 dividers */
4390 +#define   BCMA_PLLTYPE_5               0x00018000      /* 25Mhz, 4 dividers */
4391 +#define   BCMA_PLLTYPE_6               0x00028000      /* 100/200 or 120/240 only */
4392 +#define   BCMA_PLLTYPE_7               0x00038000      /* 25Mhz, 4 dividers */
4393 +#define  BCMA_CC_CAP_PCTL              0x00040000      /* Power Control */
4394 +#define  BCMA_CC_CAP_OTPS              0x00380000      /* OTP size */
4395 +#define  BCMA_CC_CAP_OTPS_SHIFT                19
4396 +#define  BCMA_CC_CAP_OTPS_BASE         5
4397 +#define  BCMA_CC_CAP_JTAGM             0x00400000      /* JTAG master present */
4398 +#define  BCMA_CC_CAP_BROM              0x00800000      /* Internal boot ROM active */
4399 +#define  BCMA_CC_CAP_64BIT             0x08000000      /* 64-bit Backplane */
4400 +#define  BCMA_CC_CAP_PMU               0x10000000      /* PMU available (rev >= 20) */
4401 +#define  BCMA_CC_CAP_ECI               0x20000000      /* ECI available (rev >= 20) */
4402 +#define  BCMA_CC_CAP_SPROM             0x40000000      /* SPROM present */
4403 +#define BCMA_CC_CORECTL                        0x0008
4404 +#define  BCMA_CC_CORECTL_UARTCLK0      0x00000001      /* Drive UART with internal clock */
4405 +#define         BCMA_CC_CORECTL_SE             0x00000002      /* sync clk out enable (corerev >= 3) */
4406 +#define  BCMA_CC_CORECTL_UARTCLKEN     0x00000008      /* UART clock enable (rev >= 21) */
4407 +#define BCMA_CC_BIST                   0x000C
4408 +#define BCMA_CC_OTPS                   0x0010          /* OTP status */
4409 +#define         BCMA_CC_OTPS_PROGFAIL          0x80000000
4410 +#define         BCMA_CC_OTPS_PROTECT           0x00000007
4411 +#define         BCMA_CC_OTPS_HW_PROTECT        0x00000001
4412 +#define         BCMA_CC_OTPS_SW_PROTECT        0x00000002
4413 +#define         BCMA_CC_OTPS_CID_PROTECT       0x00000004
4414 +#define  BCMA_CC_OTPS_GU_PROG_IND      0x00000F00      /* General Use programmed indication */
4415 +#define  BCMA_CC_OTPS_GU_PROG_IND_SHIFT        8
4416 +#define  BCMA_CC_OTPS_GU_PROG_HW       0x00000100      /* HW region programmed */
4417 +#define BCMA_CC_OTPC                   0x0014          /* OTP control */
4418 +#define         BCMA_CC_OTPC_RECWAIT           0xFF000000
4419 +#define         BCMA_CC_OTPC_PROGWAIT          0x00FFFF00
4420 +#define         BCMA_CC_OTPC_PRW_SHIFT         8
4421 +#define         BCMA_CC_OTPC_MAXFAIL           0x00000038
4422 +#define         BCMA_CC_OTPC_VSEL              0x00000006
4423 +#define         BCMA_CC_OTPC_SELVL             0x00000001
4424 +#define BCMA_CC_OTPP                   0x0018          /* OTP prog */
4425 +#define         BCMA_CC_OTPP_COL               0x000000FF
4426 +#define         BCMA_CC_OTPP_ROW               0x0000FF00
4427 +#define         BCMA_CC_OTPP_ROW_SHIFT         8
4428 +#define         BCMA_CC_OTPP_READERR           0x10000000
4429 +#define         BCMA_CC_OTPP_VALUE             0x20000000
4430 +#define         BCMA_CC_OTPP_READ              0x40000000
4431 +#define         BCMA_CC_OTPP_START             0x80000000
4432 +#define         BCMA_CC_OTPP_BUSY              0x80000000
4433 +#define BCMA_CC_OTPL                   0x001C          /* OTP layout */
4434 +#define  BCMA_CC_OTPL_GURGN_OFFSET     0x00000FFF      /* offset of general use region */
4435 +#define BCMA_CC_IRQSTAT                        0x0020
4436 +#define BCMA_CC_IRQMASK                        0x0024
4437 +#define         BCMA_CC_IRQ_GPIO               0x00000001      /* gpio intr */
4438 +#define         BCMA_CC_IRQ_EXT                0x00000002      /* ro: ext intr pin (corerev >= 3) */
4439 +#define         BCMA_CC_IRQ_WDRESET            0x80000000      /* watchdog reset occurred */
4440 +#define BCMA_CC_CHIPCTL                        0x0028          /* Rev >= 11 only */
4441 +#define BCMA_CC_CHIPSTAT               0x002C          /* Rev >= 11 only */
4442 +#define  BCMA_CC_CHIPST_4313_SPROM_PRESENT     1
4443 +#define  BCMA_CC_CHIPST_4313_OTP_PRESENT       2
4444 +#define  BCMA_CC_CHIPST_4331_SPROM_PRESENT     2
4445 +#define  BCMA_CC_CHIPST_4331_OTP_PRESENT       4
4446 +#define BCMA_CC_JCMD                   0x0030          /* Rev >= 10 only */
4447 +#define  BCMA_CC_JCMD_START            0x80000000
4448 +#define  BCMA_CC_JCMD_BUSY             0x80000000
4449 +#define  BCMA_CC_JCMD_PAUSE            0x40000000
4450 +#define  BCMA_CC_JCMD0_ACC_MASK                0x0000F000
4451 +#define  BCMA_CC_JCMD0_ACC_IRDR                0x00000000
4452 +#define  BCMA_CC_JCMD0_ACC_DR          0x00001000
4453 +#define  BCMA_CC_JCMD0_ACC_IR          0x00002000
4454 +#define  BCMA_CC_JCMD0_ACC_RESET       0x00003000
4455 +#define  BCMA_CC_JCMD0_ACC_IRPDR       0x00004000
4456 +#define  BCMA_CC_JCMD0_ACC_PDR         0x00005000
4457 +#define  BCMA_CC_JCMD0_IRW_MASK                0x00000F00
4458 +#define  BCMA_CC_JCMD_ACC_MASK         0x000F0000      /* Changes for corerev 11 */
4459 +#define  BCMA_CC_JCMD_ACC_IRDR         0x00000000
4460 +#define  BCMA_CC_JCMD_ACC_DR           0x00010000
4461 +#define  BCMA_CC_JCMD_ACC_IR           0x00020000
4462 +#define  BCMA_CC_JCMD_ACC_RESET                0x00030000
4463 +#define  BCMA_CC_JCMD_ACC_IRPDR                0x00040000
4464 +#define  BCMA_CC_JCMD_ACC_PDR          0x00050000
4465 +#define  BCMA_CC_JCMD_IRW_MASK         0x00001F00
4466 +#define  BCMA_CC_JCMD_IRW_SHIFT                8
4467 +#define  BCMA_CC_JCMD_DRW_MASK         0x0000003F
4468 +#define BCMA_CC_JIR                    0x0034          /* Rev >= 10 only */
4469 +#define BCMA_CC_JDR                    0x0038          /* Rev >= 10 only */
4470 +#define BCMA_CC_JCTL                   0x003C          /* Rev >= 10 only */
4471 +#define  BCMA_CC_JCTL_FORCE_CLK                4               /* Force clock */
4472 +#define  BCMA_CC_JCTL_EXT_EN           2               /* Enable external targets */
4473 +#define  BCMA_CC_JCTL_EN               1               /* Enable Jtag master */
4474 +#define BCMA_CC_FLASHCTL               0x0040
4475 +#define  BCMA_CC_FLASHCTL_START                0x80000000
4476 +#define  BCMA_CC_FLASHCTL_BUSY         BCMA_CC_FLASHCTL_START
4477 +#define BCMA_CC_FLASHADDR              0x0044
4478 +#define BCMA_CC_FLASHDATA              0x0048
4479 +#define BCMA_CC_BCAST_ADDR             0x0050
4480 +#define BCMA_CC_BCAST_DATA             0x0054
4481 +#define BCMA_CC_GPIOPULLUP             0x0058          /* Rev >= 20 only */
4482 +#define BCMA_CC_GPIOPULLDOWN           0x005C          /* Rev >= 20 only */
4483 +#define BCMA_CC_GPIOIN                 0x0060
4484 +#define BCMA_CC_GPIOOUT                        0x0064
4485 +#define BCMA_CC_GPIOOUTEN              0x0068
4486 +#define BCMA_CC_GPIOCTL                        0x006C
4487 +#define BCMA_CC_GPIOPOL                        0x0070
4488 +#define BCMA_CC_GPIOIRQ                        0x0074
4489 +#define BCMA_CC_WATCHDOG               0x0080
4490 +#define BCMA_CC_GPIOTIMER              0x0088          /* LED powersave (corerev >= 16) */
4491 +#define  BCMA_CC_GPIOTIMER_OFFTIME     0x0000FFFF
4492 +#define  BCMA_CC_GPIOTIMER_OFFTIME_SHIFT       0
4493 +#define  BCMA_CC_GPIOTIMER_ONTIME      0xFFFF0000
4494 +#define  BCMA_CC_GPIOTIMER_ONTIME_SHIFT        16
4495 +#define BCMA_CC_GPIOTOUTM              0x008C          /* LED powersave (corerev >= 16) */
4496 +#define BCMA_CC_CLOCK_N                        0x0090
4497 +#define BCMA_CC_CLOCK_SB               0x0094
4498 +#define BCMA_CC_CLOCK_PCI              0x0098
4499 +#define BCMA_CC_CLOCK_M2               0x009C
4500 +#define BCMA_CC_CLOCK_MIPS             0x00A0
4501 +#define BCMA_CC_CLKDIV                 0x00A4          /* Rev >= 3 only */
4502 +#define         BCMA_CC_CLKDIV_SFLASH          0x0F000000
4503 +#define         BCMA_CC_CLKDIV_SFLASH_SHIFT    24
4504 +#define         BCMA_CC_CLKDIV_OTP             0x000F0000
4505 +#define         BCMA_CC_CLKDIV_OTP_SHIFT       16
4506 +#define         BCMA_CC_CLKDIV_JTAG            0x00000F00
4507 +#define         BCMA_CC_CLKDIV_JTAG_SHIFT      8
4508 +#define         BCMA_CC_CLKDIV_UART            0x000000FF
4509 +#define BCMA_CC_CAP_EXT                        0x00AC          /* Capabilities */
4510 +#define BCMA_CC_PLLONDELAY             0x00B0          /* Rev >= 4 only */
4511 +#define BCMA_CC_FREFSELDELAY           0x00B4          /* Rev >= 4 only */
4512 +#define BCMA_CC_SLOWCLKCTL             0x00B8          /* 6 <= Rev <= 9 only */
4513 +#define  BCMA_CC_SLOWCLKCTL_SRC                0x00000007      /* slow clock source mask */
4514 +#define          BCMA_CC_SLOWCLKCTL_SRC_LPO    0x00000000      /* source of slow clock is LPO */
4515 +#define   BCMA_CC_SLOWCLKCTL_SRC_XTAL  0x00000001      /* source of slow clock is crystal */
4516 +#define          BCMA_CC_SLOECLKCTL_SRC_PCI    0x00000002      /* source of slow clock is PCI */
4517 +#define  BCMA_CC_SLOWCLKCTL_LPOFREQ    0x00000200      /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
4518 +#define  BCMA_CC_SLOWCLKCTL_LPOPD      0x00000400      /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */
4519 +#define  BCMA_CC_SLOWCLKCTL_FSLOW      0x00000800      /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */
4520 +#define  BCMA_CC_SLOWCLKCTL_IPLL       0x00001000      /* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */
4521 +#define  BCMA_CC_SLOWCLKCTL_ENXTAL     0x00002000      /* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */
4522 +#define  BCMA_CC_SLOWCLKCTL_XTALPU     0x00004000      /* XtalPU (RO), 1/0: crystal running/disabled */
4523 +#define  BCMA_CC_SLOWCLKCTL_CLKDIV     0xFFFF0000      /* ClockDivider (SlowClk = 1/(4+divisor)) */
4524 +#define  BCMA_CC_SLOWCLKCTL_CLKDIV_SHIFT       16
4525 +#define BCMA_CC_SYSCLKCTL              0x00C0          /* Rev >= 3 only */
4526 +#define         BCMA_CC_SYSCLKCTL_IDLPEN       0x00000001      /* ILPen: Enable Idle Low Power */
4527 +#define         BCMA_CC_SYSCLKCTL_ALPEN        0x00000002      /* ALPen: Enable Active Low Power */
4528 +#define         BCMA_CC_SYSCLKCTL_PLLEN        0x00000004      /* ForcePLLOn */
4529 +#define         BCMA_CC_SYSCLKCTL_FORCEALP     0x00000008      /* Force ALP (or HT if ALPen is not set */
4530 +#define         BCMA_CC_SYSCLKCTL_FORCEHT      0x00000010      /* Force HT */
4531 +#define  BCMA_CC_SYSCLKCTL_CLKDIV      0xFFFF0000      /* ClkDiv  (ILP = 1/(4+divisor)) */
4532 +#define  BCMA_CC_SYSCLKCTL_CLKDIV_SHIFT        16
4533 +#define BCMA_CC_CLKSTSTR               0x00C4          /* Rev >= 3 only */
4534 +#define BCMA_CC_EROM                   0x00FC
4535 +#define BCMA_CC_PCMCIA_CFG             0x0100
4536 +#define BCMA_CC_PCMCIA_MEMWAIT         0x0104
4537 +#define BCMA_CC_PCMCIA_ATTRWAIT                0x0108
4538 +#define BCMA_CC_PCMCIA_IOWAIT          0x010C
4539 +#define BCMA_CC_IDE_CFG                        0x0110
4540 +#define BCMA_CC_IDE_MEMWAIT            0x0114
4541 +#define BCMA_CC_IDE_ATTRWAIT           0x0118
4542 +#define BCMA_CC_IDE_IOWAIT             0x011C
4543 +#define BCMA_CC_PROG_CFG               0x0120
4544 +#define BCMA_CC_PROG_WAITCNT           0x0124
4545 +#define BCMA_CC_FLASH_CFG              0x0128
4546 +#define  BCMA_CC_FLASH_CFG_DS          0x0010  /* Data size, 0=8bit, 1=16bit */
4547 +#define BCMA_CC_FLASH_WAITCNT          0x012C
4548 +#define BCMA_CC_SROM_CONTROL           0x0190
4549 +#define  BCMA_CC_SROM_CONTROL_START    0x80000000
4550 +#define  BCMA_CC_SROM_CONTROL_BUSY     0x80000000
4551 +#define  BCMA_CC_SROM_CONTROL_OPCODE   0x60000000
4552 +#define  BCMA_CC_SROM_CONTROL_OP_READ  0x00000000
4553 +#define  BCMA_CC_SROM_CONTROL_OP_WRITE 0x20000000
4554 +#define  BCMA_CC_SROM_CONTROL_OP_WRDIS 0x40000000
4555 +#define  BCMA_CC_SROM_CONTROL_OP_WREN  0x60000000
4556 +#define  BCMA_CC_SROM_CONTROL_OTPSEL   0x00000010
4557 +#define  BCMA_CC_SROM_CONTROL_LOCK     0x00000008
4558 +#define  BCMA_CC_SROM_CONTROL_SIZE_MASK        0x00000006
4559 +#define  BCMA_CC_SROM_CONTROL_SIZE_1K  0x00000000
4560 +#define  BCMA_CC_SROM_CONTROL_SIZE_4K  0x00000002
4561 +#define  BCMA_CC_SROM_CONTROL_SIZE_16K 0x00000004
4562 +#define  BCMA_CC_SROM_CONTROL_SIZE_SHIFT       1
4563 +#define  BCMA_CC_SROM_CONTROL_PRESENT  0x00000001
4564 +/* 0x1E0 is defined as shared BCMA_CLKCTLST */
4565 +#define BCMA_CC_HW_WORKAROUND          0x01E4 /* Hardware workaround (rev >= 20) */
4566 +#define BCMA_CC_UART0_DATA             0x0300
4567 +#define BCMA_CC_UART0_IMR              0x0304
4568 +#define BCMA_CC_UART0_FCR              0x0308
4569 +#define BCMA_CC_UART0_LCR              0x030C
4570 +#define BCMA_CC_UART0_MCR              0x0310
4571 +#define BCMA_CC_UART0_LSR              0x0314
4572 +#define BCMA_CC_UART0_MSR              0x0318
4573 +#define BCMA_CC_UART0_SCRATCH          0x031C
4574 +#define BCMA_CC_UART1_DATA             0x0400
4575 +#define BCMA_CC_UART1_IMR              0x0404
4576 +#define BCMA_CC_UART1_FCR              0x0408
4577 +#define BCMA_CC_UART1_LCR              0x040C
4578 +#define BCMA_CC_UART1_MCR              0x0410
4579 +#define BCMA_CC_UART1_LSR              0x0414
4580 +#define BCMA_CC_UART1_MSR              0x0418
4581 +#define BCMA_CC_UART1_SCRATCH          0x041C
4582 +/* PMU registers (rev >= 20) */
4583 +#define BCMA_CC_PMU_CTL                        0x0600 /* PMU control */
4584 +#define  BCMA_CC_PMU_CTL_ILP_DIV       0xFFFF0000 /* ILP div mask */
4585 +#define  BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16
4586 +#define  BCMA_CC_PMU_CTL_PLL_UPD       0x00000400
4587 +#define  BCMA_CC_PMU_CTL_NOILPONW      0x00000200 /* No ILP on wait */
4588 +#define  BCMA_CC_PMU_CTL_HTREQEN       0x00000100 /* HT req enable */
4589 +#define  BCMA_CC_PMU_CTL_ALPREQEN      0x00000080 /* ALP req enable */
4590 +#define  BCMA_CC_PMU_CTL_XTALFREQ      0x0000007C /* Crystal freq */
4591 +#define  BCMA_CC_PMU_CTL_XTALFREQ_SHIFT        2
4592 +#define  BCMA_CC_PMU_CTL_ILPDIVEN      0x00000002 /* ILP div enable */
4593 +#define  BCMA_CC_PMU_CTL_LPOSEL                0x00000001 /* LPO sel */
4594 +#define BCMA_CC_PMU_CAP                        0x0604 /* PMU capabilities */
4595 +#define  BCMA_CC_PMU_CAP_REVISION      0x000000FF /* Revision mask */
4596 +#define BCMA_CC_PMU_STAT               0x0608 /* PMU status */
4597 +#define  BCMA_CC_PMU_STAT_INTPEND      0x00000040 /* Interrupt pending */
4598 +#define  BCMA_CC_PMU_STAT_SBCLKST      0x00000030 /* Backplane clock status? */
4599 +#define  BCMA_CC_PMU_STAT_HAVEALP      0x00000008 /* ALP available */
4600 +#define  BCMA_CC_PMU_STAT_HAVEHT       0x00000004 /* HT available */
4601 +#define  BCMA_CC_PMU_STAT_RESINIT      0x00000003 /* Res init */
4602 +#define BCMA_CC_PMU_RES_STAT           0x060C /* PMU res status */
4603 +#define BCMA_CC_PMU_RES_PEND           0x0610 /* PMU res pending */
4604 +#define BCMA_CC_PMU_TIMER              0x0614 /* PMU timer */
4605 +#define BCMA_CC_PMU_MINRES_MSK         0x0618 /* PMU min res mask */
4606 +#define BCMA_CC_PMU_MAXRES_MSK         0x061C /* PMU max res mask */
4607 +#define BCMA_CC_PMU_RES_TABSEL         0x0620 /* PMU res table sel */
4608 +#define BCMA_CC_PMU_RES_DEPMSK         0x0624 /* PMU res dep mask */
4609 +#define BCMA_CC_PMU_RES_UPDNTM         0x0628 /* PMU res updown timer */
4610 +#define BCMA_CC_PMU_RES_TIMER          0x062C /* PMU res timer */
4611 +#define BCMA_CC_PMU_CLKSTRETCH         0x0630 /* PMU clockstretch */
4612 +#define BCMA_CC_PMU_WATCHDOG           0x0634 /* PMU watchdog */
4613 +#define BCMA_CC_PMU_RES_REQTS          0x0640 /* PMU res req timer sel */
4614 +#define BCMA_CC_PMU_RES_REQT           0x0644 /* PMU res req timer */
4615 +#define BCMA_CC_PMU_RES_REQM           0x0648 /* PMU res req mask */
4616 +#define BCMA_CC_CHIPCTL_ADDR           0x0650
4617 +#define BCMA_CC_CHIPCTL_DATA           0x0654
4618 +#define BCMA_CC_REGCTL_ADDR            0x0658
4619 +#define BCMA_CC_REGCTL_DATA            0x065C
4620 +#define BCMA_CC_PLLCTL_ADDR            0x0660
4621 +#define BCMA_CC_PLLCTL_DATA            0x0664
4622 +#define BCMA_CC_SPROM                  0x0800 /* SPROM beginning */
4623 +
4624 +/* Divider allocation in 4716/47162/5356 */
4625 +#define BCMA_CC_PMU5_MAINPLL_CPU       1
4626 +#define BCMA_CC_PMU5_MAINPLL_MEM       2
4627 +#define BCMA_CC_PMU5_MAINPLL_SSB       3
4628 +
4629 +/* PLL usage in 4716/47162 */
4630 +#define BCMA_CC_PMU4716_MAINPLL_PLL0   12
4631 +
4632 +/* PLL usage in 5356/5357 */
4633 +#define BCMA_CC_PMU5356_MAINPLL_PLL0   0
4634 +#define BCMA_CC_PMU5357_MAINPLL_PLL0   0
4635 +
4636 +/* 4706 PMU */
4637 +#define BCMA_CC_PMU4706_MAINPLL_PLL0   0
4638 +
4639 +/* ALP clock on pre-PMU chips */
4640 +#define BCMA_CC_PMU_ALP_CLOCK          20000000
4641 +/* HT clock for systems with PMU-enabled chipcommon */
4642 +#define BCMA_CC_PMU_HT_CLOCK           80000000
4643 +
4644 +/* PMU rev 5 (& 6) */
4645 +#define BCMA_CC_PPL_P1P2_OFF           0
4646 +#define BCMA_CC_PPL_P1_MASK            0x0f000000
4647 +#define BCMA_CC_PPL_P1_SHIFT           24
4648 +#define BCMA_CC_PPL_P2_MASK            0x00f00000
4649 +#define BCMA_CC_PPL_P2_SHIFT           20
4650 +#define BCMA_CC_PPL_M14_OFF            1
4651 +#define BCMA_CC_PPL_MDIV_MASK          0x000000ff
4652 +#define BCMA_CC_PPL_MDIV_WIDTH         8
4653 +#define BCMA_CC_PPL_NM5_OFF            2
4654 +#define BCMA_CC_PPL_NDIV_MASK          0xfff00000
4655 +#define BCMA_CC_PPL_NDIV_SHIFT         20
4656 +#define BCMA_CC_PPL_FMAB_OFF           3
4657 +#define BCMA_CC_PPL_MRAT_MASK          0xf0000000
4658 +#define BCMA_CC_PPL_MRAT_SHIFT         28
4659 +#define BCMA_CC_PPL_ABRAT_MASK         0x08000000
4660 +#define BCMA_CC_PPL_ABRAT_SHIFT                27
4661 +#define BCMA_CC_PPL_FDIV_MASK          0x07ffffff
4662 +#define BCMA_CC_PPL_PLLCTL_OFF         4
4663 +#define BCMA_CC_PPL_PCHI_OFF           5
4664 +#define BCMA_CC_PPL_PCHI_MASK          0x0000003f
4665 +
4666 +/* BCM4331 ChipControl numbers. */
4667 +#define BCMA_CHIPCTL_4331_BT_COEXIST           BIT(0)  /* 0 disable */
4668 +#define BCMA_CHIPCTL_4331_SECI                 BIT(1)  /* 0 SECI is disabled (JATG functional) */
4669 +#define BCMA_CHIPCTL_4331_EXT_LNA              BIT(2)  /* 0 disable */
4670 +#define BCMA_CHIPCTL_4331_SPROM_GPIO13_15      BIT(3)  /* sprom/gpio13-15 mux */
4671 +#define BCMA_CHIPCTL_4331_EXTPA_EN             BIT(4)  /* 0 ext pa disable, 1 ext pa enabled */
4672 +#define BCMA_CHIPCTL_4331_GPIOCLK_ON_SPROMCS   BIT(5)  /* set drive out GPIO_CLK on sprom_cs pin */
4673 +#define BCMA_CHIPCTL_4331_PCIE_MDIO_ON_SPROMCS BIT(6)  /* use sprom_cs pin as PCIE mdio interface */
4674 +#define BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5     BIT(7)  /* aband extpa will be at gpio2/5 and sprom_dout */
4675 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXCLKEN     BIT(8)  /* override core control on pipe_AuxClkEnable */
4676 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN   BIT(9)  /* override core control on pipe_AuxPowerDown */
4677 +#define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN                BIT(10) /* pcie_auxclkenable */
4678 +#define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN    BIT(11) /* pcie_pipe_pllpowerdown */
4679 +#define BCMA_CHIPCTL_4331_BT_SHD0_ON_GPIO4     BIT(16) /* enable bt_shd0 at gpio4 */
4680 +#define BCMA_CHIPCTL_4331_BT_SHD1_ON_GPIO5     BIT(17) /* enable bt_shd1 at gpio5 */
4681 +
4682 +/* Data for the PMU, if available.
4683 + * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
4684 + */
4685 +struct bcma_chipcommon_pmu {
4686 +       u8 rev;                 /* PMU revision */
4687 +       u32 crystalfreq;        /* The active crystal frequency (in kHz) */
4688 +};
4689 +
4690 +#ifdef CONFIG_BCMA_DRIVER_MIPS
4691 +struct bcma_pflash {
4692 +       u8 buswidth;
4693 +       u32 window;
4694 +       u32 window_size;
4695 +};
4696 +
4697 +struct bcma_serial_port {
4698 +       void *regs;
4699 +       unsigned long clockspeed;
4700 +       unsigned int irq;
4701 +       unsigned int baud_base;
4702 +       unsigned int reg_shift;
4703 +};
4704 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
4705 +
4706 +struct bcma_drv_cc {
4707 +       struct bcma_device *core;
4708 +       u32 status;
4709 +       u32 capabilities;
4710 +       u32 capabilities_ext;
4711 +       u8 setup_done:1;
4712 +       /* Fast Powerup Delay constant */
4713 +       u16 fast_pwrup_delay;
4714 +       struct bcma_chipcommon_pmu pmu;
4715 +#ifdef CONFIG_BCMA_DRIVER_MIPS
4716 +       struct bcma_pflash pflash;
4717 +
4718 +       int nr_serial_ports;
4719 +       struct bcma_serial_port serial_ports[4];
4720 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
4721 +};
4722 +
4723 +/* Register access */
4724 +#define bcma_cc_read32(cc, offset) \
4725 +       bcma_read32((cc)->core, offset)
4726 +#define bcma_cc_write32(cc, offset, val) \
4727 +       bcma_write32((cc)->core, offset, val)
4728 +
4729 +#define bcma_cc_mask32(cc, offset, mask) \
4730 +       bcma_cc_write32(cc, offset, bcma_cc_read32(cc, offset) & (mask))
4731 +#define bcma_cc_set32(cc, offset, set) \
4732 +       bcma_cc_write32(cc, offset, bcma_cc_read32(cc, offset) | (set))
4733 +#define bcma_cc_maskset32(cc, offset, mask, set) \
4734 +       bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set))
4735 +
4736 +extern void bcma_core_chipcommon_init(struct bcma_drv_cc *cc);
4737 +
4738 +extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
4739 +extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
4740 +
4741 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
4742 +
4743 +extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
4744 +                                         u32 ticks);
4745 +
4746 +void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value);
4747 +
4748 +u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask);
4749 +
4750 +/* Chipcommon GPIO pin access. */
4751 +u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask);
4752 +u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value);
4753 +u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value);
4754 +u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value);
4755 +u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value);
4756 +u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value);
4757 +
4758 +/* PMU support */
4759 +extern void bcma_pmu_init(struct bcma_drv_cc *cc);
4760 +
4761 +extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset,
4762 +                                 u32 value);
4763 +extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset,
4764 +                                   u32 mask, u32 set);
4765 +extern void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
4766 +                                       u32 offset, u32 mask, u32 set);
4767 +extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc,
4768 +                                      u32 offset, u32 mask, u32 set);
4769 +
4770 +#endif /* LINUX_BCMA_DRIVER_CC_H_ */
4771 --- /dev/null
4772 +++ b/include/linux/bcma/bcma_driver_mips.h
4773 @@ -0,0 +1,51 @@
4774 +#ifndef LINUX_BCMA_DRIVER_MIPS_H_
4775 +#define LINUX_BCMA_DRIVER_MIPS_H_
4776 +
4777 +#define BCMA_MIPS_IPSFLAG              0x0F08
4778 +/* which sbflags get routed to mips interrupt 1 */
4779 +#define  BCMA_MIPS_IPSFLAG_IRQ1                0x0000003F
4780 +#define  BCMA_MIPS_IPSFLAG_IRQ1_SHIFT  0
4781 +/* which sbflags get routed to mips interrupt 2 */
4782 +#define  BCMA_MIPS_IPSFLAG_IRQ2                0x00003F00
4783 +#define  BCMA_MIPS_IPSFLAG_IRQ2_SHIFT  8
4784 +/* which sbflags get routed to mips interrupt 3 */
4785 +#define  BCMA_MIPS_IPSFLAG_IRQ3                0x003F0000
4786 +#define  BCMA_MIPS_IPSFLAG_IRQ3_SHIFT  16
4787 +/* which sbflags get routed to mips interrupt 4 */
4788 +#define  BCMA_MIPS_IPSFLAG_IRQ4                0x3F000000
4789 +#define  BCMA_MIPS_IPSFLAG_IRQ4_SHIFT  24
4790 +
4791 +/* MIPS 74K core registers */
4792 +#define BCMA_MIPS_MIPS74K_CORECTL      0x0000
4793 +#define BCMA_MIPS_MIPS74K_EXCEPTBASE   0x0004
4794 +#define BCMA_MIPS_MIPS74K_BIST         0x000C
4795 +#define BCMA_MIPS_MIPS74K_INTMASK_INT0 0x0014
4796 +#define BCMA_MIPS_MIPS74K_INTMASK(int) \
4797 +       ((int) * 4 + BCMA_MIPS_MIPS74K_INTMASK_INT0)
4798 +#define BCMA_MIPS_MIPS74K_NMIMASK      0x002C
4799 +#define BCMA_MIPS_MIPS74K_GPIOSEL      0x0040
4800 +#define BCMA_MIPS_MIPS74K_GPIOOUT      0x0044
4801 +#define BCMA_MIPS_MIPS74K_GPIOEN       0x0048
4802 +#define BCMA_MIPS_MIPS74K_CLKCTLST     0x01E0
4803 +
4804 +#define BCMA_MIPS_OOBSELOUTA30         0x100
4805 +
4806 +struct bcma_device;
4807 +
4808 +struct bcma_drv_mips {
4809 +       struct bcma_device *core;
4810 +       u8 setup_done:1;
4811 +       unsigned int assigned_irqs;
4812 +};
4813 +
4814 +#ifdef CONFIG_BCMA_DRIVER_MIPS
4815 +extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
4816 +#else
4817 +static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { }
4818 +#endif
4819 +
4820 +extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
4821 +
4822 +extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
4823 +
4824 +#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
4825 --- /dev/null
4826 +++ b/include/linux/bcma/bcma_driver_pci.h
4827 @@ -0,0 +1,225 @@
4828 +#ifndef LINUX_BCMA_DRIVER_PCI_H_
4829 +#define LINUX_BCMA_DRIVER_PCI_H_
4830 +
4831 +#include <linux/types.h>
4832 +
4833 +struct pci_dev;
4834 +
4835 +/** PCI core registers. **/
4836 +#define BCMA_CORE_PCI_CTL                      0x0000  /* PCI Control */
4837 +#define  BCMA_CORE_PCI_CTL_RST_OE              0x00000001 /* PCI_RESET Output Enable */
4838 +#define  BCMA_CORE_PCI_CTL_RST                 0x00000002 /* PCI_RESET driven out to pin */
4839 +#define  BCMA_CORE_PCI_CTL_CLK_OE              0x00000004 /* Clock gate Output Enable */
4840 +#define  BCMA_CORE_PCI_CTL_CLK                 0x00000008 /* Gate for clock driven out to pin */
4841 +#define BCMA_CORE_PCI_ARBCTL                   0x0010  /* PCI Arbiter Control */
4842 +#define  BCMA_CORE_PCI_ARBCTL_INTERN           0x00000001 /* Use internal arbiter */
4843 +#define  BCMA_CORE_PCI_ARBCTL_EXTERN           0x00000002 /* Use external arbiter */
4844 +#define  BCMA_CORE_PCI_ARBCTL_PARKID           0x00000006 /* Mask, selects which agent is parked on an idle bus */
4845 +#define   BCMA_CORE_PCI_ARBCTL_PARKID_LAST     0x00000000 /* Last requestor */
4846 +#define   BCMA_CORE_PCI_ARBCTL_PARKID_4710     0x00000002 /* 4710 */
4847 +#define   BCMA_CORE_PCI_ARBCTL_PARKID_EXT0     0x00000004 /* External requestor 0 */
4848 +#define   BCMA_CORE_PCI_ARBCTL_PARKID_EXT1     0x00000006 /* External requestor 1 */
4849 +#define BCMA_CORE_PCI_ISTAT                    0x0020  /* Interrupt status */
4850 +#define  BCMA_CORE_PCI_ISTAT_INTA              0x00000001 /* PCI INTA# */
4851 +#define  BCMA_CORE_PCI_ISTAT_INTB              0x00000002 /* PCI INTB# */
4852 +#define  BCMA_CORE_PCI_ISTAT_SERR              0x00000004 /* PCI SERR# (write to clear) */
4853 +#define  BCMA_CORE_PCI_ISTAT_PERR              0x00000008 /* PCI PERR# (write to clear) */
4854 +#define  BCMA_CORE_PCI_ISTAT_PME               0x00000010 /* PCI PME# */
4855 +#define BCMA_CORE_PCI_IMASK                    0x0024  /* Interrupt mask */
4856 +#define  BCMA_CORE_PCI_IMASK_INTA              0x00000001 /* PCI INTA# */
4857 +#define  BCMA_CORE_PCI_IMASK_INTB              0x00000002 /* PCI INTB# */
4858 +#define  BCMA_CORE_PCI_IMASK_SERR              0x00000004 /* PCI SERR# */
4859 +#define  BCMA_CORE_PCI_IMASK_PERR              0x00000008 /* PCI PERR# */
4860 +#define  BCMA_CORE_PCI_IMASK_PME               0x00000010 /* PCI PME# */
4861 +#define BCMA_CORE_PCI_MBOX                     0x0028  /* Backplane to PCI Mailbox */
4862 +#define  BCMA_CORE_PCI_MBOX_F0_0               0x00000100 /* PCI function 0, INT 0 */
4863 +#define  BCMA_CORE_PCI_MBOX_F0_1               0x00000200 /* PCI function 0, INT 1 */
4864 +#define  BCMA_CORE_PCI_MBOX_F1_0               0x00000400 /* PCI function 1, INT 0 */
4865 +#define  BCMA_CORE_PCI_MBOX_F1_1               0x00000800 /* PCI function 1, INT 1 */
4866 +#define  BCMA_CORE_PCI_MBOX_F2_0               0x00001000 /* PCI function 2, INT 0 */
4867 +#define  BCMA_CORE_PCI_MBOX_F2_1               0x00002000 /* PCI function 2, INT 1 */
4868 +#define  BCMA_CORE_PCI_MBOX_F3_0               0x00004000 /* PCI function 3, INT 0 */
4869 +#define  BCMA_CORE_PCI_MBOX_F3_1               0x00008000 /* PCI function 3, INT 1 */
4870 +#define BCMA_CORE_PCI_BCAST_ADDR               0x0050  /* Backplane Broadcast Address */
4871 +#define  BCMA_CORE_PCI_BCAST_ADDR_MASK         0x000000FF
4872 +#define BCMA_CORE_PCI_BCAST_DATA               0x0054  /* Backplane Broadcast Data */
4873 +#define BCMA_CORE_PCI_GPIO_IN                  0x0060  /* rev >= 2 only */
4874 +#define BCMA_CORE_PCI_GPIO_OUT                 0x0064  /* rev >= 2 only */
4875 +#define BCMA_CORE_PCI_GPIO_ENABLE              0x0068  /* rev >= 2 only */
4876 +#define BCMA_CORE_PCI_GPIO_CTL                 0x006C  /* rev >= 2 only */
4877 +#define BCMA_CORE_PCI_SBTOPCI0                 0x0100  /* Backplane to PCI translation 0 (sbtopci0) */
4878 +#define  BCMA_CORE_PCI_SBTOPCI0_MASK           0xFC000000
4879 +#define BCMA_CORE_PCI_SBTOPCI1                 0x0104  /* Backplane to PCI translation 1 (sbtopci1) */
4880 +#define  BCMA_CORE_PCI_SBTOPCI1_MASK           0xFC000000
4881 +#define BCMA_CORE_PCI_SBTOPCI2                 0x0108  /* Backplane to PCI translation 2 (sbtopci2) */
4882 +#define  BCMA_CORE_PCI_SBTOPCI2_MASK           0xC0000000
4883 +#define BCMA_CORE_PCI_CONFIG_ADDR              0x0120  /* pcie config space access */
4884 +#define BCMA_CORE_PCI_CONFIG_DATA              0x0124  /* pcie config space access */
4885 +#define BCMA_CORE_PCI_MDIO_CONTROL             0x0128  /* controls the mdio access */
4886 +#define  BCMA_CORE_PCI_MDIOCTL_DIVISOR_MASK    0x7f    /* clock to be used on MDIO */
4887 +#define  BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL     0x2
4888 +#define  BCMA_CORE_PCI_MDIOCTL_PREAM_EN                0x80    /* Enable preamble sequnce */
4889 +#define  BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE     0x100   /* Tranaction complete */
4890 +#define BCMA_CORE_PCI_MDIO_DATA                        0x012c  /* Data to the mdio access */
4891 +#define  BCMA_CORE_PCI_MDIODATA_MASK           0x0000ffff /* data 2 bytes */
4892 +#define  BCMA_CORE_PCI_MDIODATA_TA             0x00020000 /* Turnaround */
4893 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD        18      /* Regaddr shift (rev < 10) */
4894 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_MASK_OLD       0x003c0000 /* Regaddr Mask (rev < 10) */
4895 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD        22      /* Physmedia devaddr shift (rev < 10) */
4896 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK_OLD       0x0fc00000 /* Physmedia devaddr Mask (rev < 10) */
4897 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_SHF    18      /* Regaddr shift */
4898 +#define  BCMA_CORE_PCI_MDIODATA_REGADDR_MASK   0x007c0000 /* Regaddr Mask */
4899 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF    23      /* Physmedia devaddr shift */
4900 +#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK   0x0f800000 /* Physmedia devaddr Mask */
4901 +#define  BCMA_CORE_PCI_MDIODATA_WRITE          0x10000000 /* write Transaction */
4902 +#define  BCMA_CORE_PCI_MDIODATA_READ           0x20000000 /* Read Transaction */
4903 +#define  BCMA_CORE_PCI_MDIODATA_START          0x40000000 /* start of Transaction */
4904 +#define  BCMA_CORE_PCI_MDIODATA_DEV_ADDR       0x0     /* dev address for serdes */
4905 +#define  BCMA_CORE_PCI_MDIODATA_BLK_ADDR       0x1F    /* blk address for serdes */
4906 +#define  BCMA_CORE_PCI_MDIODATA_DEV_PLL                0x1d    /* SERDES PLL Dev */
4907 +#define  BCMA_CORE_PCI_MDIODATA_DEV_TX         0x1e    /* SERDES TX Dev */
4908 +#define  BCMA_CORE_PCI_MDIODATA_DEV_RX         0x1f    /* SERDES RX Dev */
4909 +#define BCMA_CORE_PCI_PCIEIND_ADDR             0x0130  /* indirect access to the internal register */
4910 +#define BCMA_CORE_PCI_PCIEIND_DATA             0x0134  /* Data to/from the internal regsiter */
4911 +#define BCMA_CORE_PCI_CLKREQENCTRL             0x0138  /*  >= rev 6, Clkreq rdma control */
4912 +#define BCMA_CORE_PCI_PCICFG0                  0x0400  /* PCI config space 0 (rev >= 8) */
4913 +#define BCMA_CORE_PCI_PCICFG1                  0x0500  /* PCI config space 1 (rev >= 8) */
4914 +#define BCMA_CORE_PCI_PCICFG2                  0x0600  /* PCI config space 2 (rev >= 8) */
4915 +#define BCMA_CORE_PCI_PCICFG3                  0x0700  /* PCI config space 3 (rev >= 8) */
4916 +#define BCMA_CORE_PCI_SPROM(wordoffset)                (0x0800 + ((wordoffset) * 2)) /* SPROM shadow area (72 bytes) */
4917 +#define  BCMA_CORE_PCI_SPROM_PI_OFFSET         0       /* first word */
4918 +#define   BCMA_CORE_PCI_SPROM_PI_MASK          0xf000  /* bit 15:12 */
4919 +#define   BCMA_CORE_PCI_SPROM_PI_SHIFT         12      /* bit 15:12 */
4920 +#define  BCMA_CORE_PCI_SPROM_MISC_CONFIG       5       /* word 5 */
4921 +#define   BCMA_CORE_PCI_SPROM_L23READY_EXIT_NOPERST    0x8000  /* bit 15 */
4922 +#define   BCMA_CORE_PCI_SPROM_CLKREQ_OFFSET_REV5       20      /* word 20 for srom rev <= 5 */
4923 +#define   BCMA_CORE_PCI_SPROM_CLKREQ_ENB       0x0800  /* bit 11 */
4924 +
4925 +/* SBtoPCIx */
4926 +#define BCMA_CORE_PCI_SBTOPCI_MEM              0x00000000
4927 +#define BCMA_CORE_PCI_SBTOPCI_IO               0x00000001
4928 +#define BCMA_CORE_PCI_SBTOPCI_CFG0             0x00000002
4929 +#define BCMA_CORE_PCI_SBTOPCI_CFG1             0x00000003
4930 +#define BCMA_CORE_PCI_SBTOPCI_PREF             0x00000004 /* Prefetch enable */
4931 +#define BCMA_CORE_PCI_SBTOPCI_BURST            0x00000008 /* Burst enable */
4932 +#define BCMA_CORE_PCI_SBTOPCI_MRM              0x00000020 /* Memory Read Multiple */
4933 +#define BCMA_CORE_PCI_SBTOPCI_RC               0x00000030 /* Read Command mask (rev >= 11) */
4934 +#define  BCMA_CORE_PCI_SBTOPCI_RC_READ         0x00000000 /* Memory read */
4935 +#define  BCMA_CORE_PCI_SBTOPCI_RC_READL                0x00000010 /* Memory read line */
4936 +#define  BCMA_CORE_PCI_SBTOPCI_RC_READM                0x00000020 /* Memory read multiple */
4937 +
4938 +/* PCIE protocol PHY diagnostic registers */
4939 +#define BCMA_CORE_PCI_PLP_MODEREG              0x200   /* Mode */
4940 +#define BCMA_CORE_PCI_PLP_STATUSREG            0x204   /* Status */
4941 +#define  BCMA_CORE_PCI_PLP_POLARITYINV_STAT    0x10    /* Status reg PCIE_PLP_STATUSREG */
4942 +#define BCMA_CORE_PCI_PLP_LTSSMCTRLREG         0x208   /* LTSSM control */
4943 +#define BCMA_CORE_PCI_PLP_LTLINKNUMREG         0x20c   /* Link Training Link number */
4944 +#define BCMA_CORE_PCI_PLP_LTLANENUMREG         0x210   /* Link Training Lane number */
4945 +#define BCMA_CORE_PCI_PLP_LTNFTSREG            0x214   /* Link Training N_FTS */
4946 +#define BCMA_CORE_PCI_PLP_ATTNREG              0x218   /* Attention */
4947 +#define BCMA_CORE_PCI_PLP_ATTNMASKREG          0x21C   /* Attention Mask */
4948 +#define BCMA_CORE_PCI_PLP_RXERRCTR             0x220   /* Rx Error */
4949 +#define BCMA_CORE_PCI_PLP_RXFRMERRCTR          0x224   /* Rx Framing Error */
4950 +#define BCMA_CORE_PCI_PLP_RXERRTHRESHREG       0x228   /* Rx Error threshold */
4951 +#define BCMA_CORE_PCI_PLP_TESTCTRLREG          0x22C   /* Test Control reg */
4952 +#define BCMA_CORE_PCI_PLP_SERDESCTRLOVRDREG    0x230   /* SERDES Control Override */
4953 +#define BCMA_CORE_PCI_PLP_TIMINGOVRDREG                0x234   /* Timing param override */
4954 +#define BCMA_CORE_PCI_PLP_RXTXSMDIAGREG                0x238   /* RXTX State Machine Diag */
4955 +#define BCMA_CORE_PCI_PLP_LTSSMDIAGREG         0x23C   /* LTSSM State Machine Diag */
4956 +
4957 +/* PCIE protocol DLLP diagnostic registers */
4958 +#define BCMA_CORE_PCI_DLLP_LCREG               0x100   /* Link Control */
4959 +#define BCMA_CORE_PCI_DLLP_LSREG               0x104   /* Link Status */
4960 +#define BCMA_CORE_PCI_DLLP_LAREG               0x108   /* Link Attention */
4961 +#define  BCMA_CORE_PCI_DLLP_LSREG_LINKUP       (1 << 16)
4962 +#define BCMA_CORE_PCI_DLLP_LAMASKREG           0x10C   /* Link Attention Mask */
4963 +#define BCMA_CORE_PCI_DLLP_NEXTTXSEQNUMREG     0x110   /* Next Tx Seq Num */
4964 +#define BCMA_CORE_PCI_DLLP_ACKEDTXSEQNUMREG    0x114   /* Acked Tx Seq Num */
4965 +#define BCMA_CORE_PCI_DLLP_PURGEDTXSEQNUMREG   0x118   /* Purged Tx Seq Num */
4966 +#define BCMA_CORE_PCI_DLLP_RXSEQNUMREG         0x11C   /* Rx Sequence Number */
4967 +#define BCMA_CORE_PCI_DLLP_LRREG               0x120   /* Link Replay */
4968 +#define BCMA_CORE_PCI_DLLP_LACKTOREG           0x124   /* Link Ack Timeout */
4969 +#define BCMA_CORE_PCI_DLLP_PMTHRESHREG         0x128   /* Power Management Threshold */
4970 +#define  BCMA_CORE_PCI_ASPMTIMER_EXTEND                0x01000000 /* > rev7: enable extend ASPM timer */
4971 +#define BCMA_CORE_PCI_DLLP_RTRYWPREG           0x12C   /* Retry buffer write ptr */
4972 +#define BCMA_CORE_PCI_DLLP_RTRYRPREG           0x130   /* Retry buffer Read ptr */
4973 +#define BCMA_CORE_PCI_DLLP_RTRYPPREG           0x134   /* Retry buffer Purged ptr */
4974 +#define BCMA_CORE_PCI_DLLP_RTRRWREG            0x138   /* Retry buffer Read/Write */
4975 +#define BCMA_CORE_PCI_DLLP_ECTHRESHREG         0x13C   /* Error Count Threshold */
4976 +#define BCMA_CORE_PCI_DLLP_TLPERRCTRREG                0x140   /* TLP Error Counter */
4977 +#define BCMA_CORE_PCI_DLLP_ERRCTRREG           0x144   /* Error Counter */
4978 +#define BCMA_CORE_PCI_DLLP_NAKRXCTRREG         0x148   /* NAK Received Counter */
4979 +#define BCMA_CORE_PCI_DLLP_TESTREG             0x14C   /* Test */
4980 +#define BCMA_CORE_PCI_DLLP_PKTBIST             0x150   /* Packet BIST */
4981 +#define BCMA_CORE_PCI_DLLP_PCIE11              0x154   /* DLLP PCIE 1.1 reg */
4982 +
4983 +/* SERDES RX registers */
4984 +#define BCMA_CORE_PCI_SERDES_RX_CTRL           1       /* Rx cntrl */
4985 +#define  BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE    0x80    /* rxpolarity_force */
4986 +#define  BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY 0x40    /* rxpolarity_value */
4987 +#define BCMA_CORE_PCI_SERDES_RX_TIMER1         2       /* Rx Timer1 */
4988 +#define BCMA_CORE_PCI_SERDES_RX_CDR            6       /* CDR */
4989 +#define BCMA_CORE_PCI_SERDES_RX_CDRBW          7       /* CDR BW */
4990 +
4991 +/* SERDES PLL registers */
4992 +#define BCMA_CORE_PCI_SERDES_PLL_CTRL          1       /* PLL control reg */
4993 +#define BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN      0x4000  /* bit 14 is FREQDET on */
4994 +
4995 +/* PCIcore specific boardflags */
4996 +#define BCMA_CORE_PCI_BFL_NOPCI                        0x00000400 /* Board leaves PCI floating */
4997 +
4998 +/* PCIE Config space accessing MACROS */
4999 +#define BCMA_CORE_PCI_CFG_BUS_SHIFT            24      /* Bus shift */
5000 +#define BCMA_CORE_PCI_CFG_SLOT_SHIFT           19      /* Slot/Device shift */
5001 +#define BCMA_CORE_PCI_CFG_FUN_SHIFT            16      /* Function shift */
5002 +#define BCMA_CORE_PCI_CFG_OFF_SHIFT            0       /* Register shift */
5003 +
5004 +#define BCMA_CORE_PCI_CFG_BUS_MASK             0xff    /* Bus mask */
5005 +#define BCMA_CORE_PCI_CFG_SLOT_MASK            0x1f    /* Slot/Device mask */
5006 +#define BCMA_CORE_PCI_CFG_FUN_MASK             7       /* Function mask */
5007 +#define BCMA_CORE_PCI_CFG_OFF_MASK             0xfff   /* Register mask */
5008 +
5009 +/* PCIE Root Capability Register bits (Host mode only) */
5010 +#define BCMA_CORE_PCI_RC_CRS_VISIBILITY                0x0001
5011 +
5012 +struct bcma_drv_pci;
5013 +
5014 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
5015 +struct bcma_drv_pci_host {
5016 +       struct bcma_drv_pci *pdev;
5017 +
5018 +       u32 host_cfg_addr;
5019 +       spinlock_t cfgspace_lock;
5020 +
5021 +       struct pci_controller pci_controller;
5022 +       struct pci_ops pci_ops;
5023 +       struct resource mem_resource;
5024 +       struct resource io_resource;
5025 +};
5026 +#endif
5027 +
5028 +struct bcma_drv_pci {
5029 +       struct bcma_device *core;
5030 +       u8 setup_done:1;
5031 +       u8 hostmode:1;
5032 +
5033 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
5034 +       struct bcma_drv_pci_host *host_controller;
5035 +#endif
5036 +};
5037 +
5038 +/* Register access */
5039 +#define pcicore_read16(pc, offset)             bcma_read16((pc)->core, offset)
5040 +#define pcicore_read32(pc, offset)             bcma_read32((pc)->core, offset)
5041 +#define pcicore_write16(pc, offset, val)       bcma_write16((pc)->core, offset, val)
5042 +#define pcicore_write32(pc, offset, val)       bcma_write32((pc)->core, offset, val)
5043 +
5044 +extern void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc);
5045 +extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
5046 +                                struct bcma_device *core, bool enable);
5047 +extern void bcma_core_pci_extend_L1timer(struct bcma_drv_pci *pc, bool extend);
5048 +
5049 +extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
5050 +extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
5051 +
5052 +#endif /* LINUX_BCMA_DRIVER_PCI_H_ */
5053 --- /dev/null
5054 +++ b/include/linux/bcma/bcma_regs.h
5055 @@ -0,0 +1,86 @@
5056 +#ifndef LINUX_BCMA_REGS_H_
5057 +#define LINUX_BCMA_REGS_H_
5058 +
5059 +/* Some single registers are shared between many cores */
5060 +/* BCMA_CLKCTLST: ChipCommon (rev >= 20), PCIe, 80211 */
5061 +#define BCMA_CLKCTLST                  0x01E0 /* Clock control and status */
5062 +#define  BCMA_CLKCTLST_FORCEALP                0x00000001 /* Force ALP request */
5063 +#define  BCMA_CLKCTLST_FORCEHT         0x00000002 /* Force HT request */
5064 +#define  BCMA_CLKCTLST_FORCEILP                0x00000004 /* Force ILP request */
5065 +#define  BCMA_CLKCTLST_HAVEALPREQ      0x00000008 /* ALP available request */
5066 +#define  BCMA_CLKCTLST_HAVEHTREQ       0x00000010 /* HT available request */
5067 +#define  BCMA_CLKCTLST_HWCROFF         0x00000020 /* Force HW clock request off */
5068 +#define  BCMA_CLKCTLST_EXTRESREQ       0x00000700 /* Mask of external resource requests */
5069 +#define  BCMA_CLKCTLST_HAVEALP         0x00010000 /* ALP available */
5070 +#define  BCMA_CLKCTLST_HAVEHT          0x00020000 /* HT available */
5071 +#define  BCMA_CLKCTLST_BP_ON_ALP       0x00040000 /* RO: running on ALP clock */
5072 +#define  BCMA_CLKCTLST_BP_ON_HT                0x00080000 /* RO: running on HT clock */
5073 +#define  BCMA_CLKCTLST_EXTRESST                0x07000000 /* Mask of external resource status */
5074 +/* Is there any BCM4328 on BCMA bus? */
5075 +#define  BCMA_CLKCTLST_4328A0_HAVEHT   0x00010000 /* 4328a0 has reversed bits */
5076 +#define  BCMA_CLKCTLST_4328A0_HAVEALP  0x00020000 /* 4328a0 has reversed bits */
5077 +
5078 +/* Agent registers (common for every core) */
5079 +#define BCMA_IOCTL                     0x0408 /* IO control */
5080 +#define  BCMA_IOCTL_CLK                        0x0001
5081 +#define  BCMA_IOCTL_FGC                        0x0002
5082 +#define  BCMA_IOCTL_CORE_BITS          0x3FFC
5083 +#define  BCMA_IOCTL_PME_EN             0x4000
5084 +#define  BCMA_IOCTL_BIST_EN            0x8000
5085 +#define BCMA_IOST                      0x0500 /* IO status */
5086 +#define  BCMA_IOST_CORE_BITS           0x0FFF
5087 +#define  BCMA_IOST_DMA64               0x1000
5088 +#define  BCMA_IOST_GATED_CLK           0x2000
5089 +#define  BCMA_IOST_BIST_ERROR          0x4000
5090 +#define  BCMA_IOST_BIST_DONE           0x8000
5091 +#define BCMA_RESET_CTL                 0x0800
5092 +#define  BCMA_RESET_CTL_RESET          0x0001
5093 +
5094 +/* BCMA PCI config space registers. */
5095 +#define BCMA_PCI_PMCSR                 0x44
5096 +#define  BCMA_PCI_PE                   0x100
5097 +#define BCMA_PCI_BAR0_WIN              0x80    /* Backplane address space 0 */
5098 +#define BCMA_PCI_BAR1_WIN              0x84    /* Backplane address space 1 */
5099 +#define BCMA_PCI_SPROMCTL              0x88    /* SPROM control */
5100 +#define  BCMA_PCI_SPROMCTL_WE          0x10    /* SPROM write enable */
5101 +#define BCMA_PCI_BAR1_CONTROL          0x8c    /* Address space 1 burst control */
5102 +#define BCMA_PCI_IRQS                  0x90    /* PCI interrupts */
5103 +#define BCMA_PCI_IRQMASK               0x94    /* PCI IRQ control and mask (pcirev >= 6 only) */
5104 +#define BCMA_PCI_BACKPLANE_IRQS                0x98    /* Backplane Interrupts */
5105 +#define BCMA_PCI_BAR0_WIN2             0xAC
5106 +#define BCMA_PCI_GPIO_IN               0xB0    /* GPIO Input (pcirev >= 3 only) */
5107 +#define BCMA_PCI_GPIO_OUT              0xB4    /* GPIO Output (pcirev >= 3 only) */
5108 +#define BCMA_PCI_GPIO_OUT_ENABLE       0xB8    /* GPIO Output Enable/Disable (pcirev >= 3 only) */
5109 +#define  BCMA_PCI_GPIO_SCS             0x10    /* PCI config space bit 4 for 4306c0 slow clock source */
5110 +#define  BCMA_PCI_GPIO_HWRAD           0x20    /* PCI config space GPIO 13 for hw radio disable */
5111 +#define  BCMA_PCI_GPIO_XTAL            0x40    /* PCI config space GPIO 14 for Xtal powerup */
5112 +#define  BCMA_PCI_GPIO_PLL             0x80    /* PCI config space GPIO 15 for PLL powerdown */
5113 +
5114 +/* SiliconBackplane Address Map.
5115 + * All regions may not exist on all chips.
5116 + */
5117 +#define BCMA_SOC_SDRAM_BASE            0x00000000U     /* Physical SDRAM */
5118 +#define BCMA_SOC_PCI_MEM               0x08000000U     /* Host Mode sb2pcitranslation0 (64 MB) */
5119 +#define BCMA_SOC_PCI_MEM_SZ            (64 * 1024 * 1024)
5120 +#define BCMA_SOC_PCI_CFG               0x0c000000U     /* Host Mode sb2pcitranslation1 (64 MB) */
5121 +#define BCMA_SOC_SDRAM_SWAPPED         0x10000000U     /* Byteswapped Physical SDRAM */
5122 +#define BCMA_SOC_SDRAM_R2              0x80000000U     /* Region 2 for sdram (512 MB) */
5123 +
5124 +
5125 +#define BCMA_SOC_PCI_DMA               0x40000000U     /* Client Mode sb2pcitranslation2 (1 GB) */
5126 +#define BCMA_SOC_PCI_DMA2              0x80000000U     /* Client Mode sb2pcitranslation2 (1 GB) */
5127 +#define BCMA_SOC_PCI_DMA_SZ            0x40000000U     /* Client Mode sb2pcitranslation2 size in bytes */
5128 +#define BCMA_SOC_PCIE_DMA_L32          0x00000000U     /* PCIE Client Mode sb2pcitranslation2
5129 +                                                        * (2 ZettaBytes), low 32 bits
5130 +                                                        */
5131 +#define BCMA_SOC_PCIE_DMA_H32          0x80000000U     /* PCIE Client Mode sb2pcitranslation2
5132 +                                                        * (2 ZettaBytes), high 32 bits
5133 +                                                        */
5134 +
5135 +#define BCMA_SOC_PCI1_MEM              0x40000000U     /* Host Mode sb2pcitranslation0 (64 MB) */
5136 +#define BCMA_SOC_PCI1_CFG              0x44000000U     /* Host Mode sb2pcitranslation1 (64 MB) */
5137 +#define BCMA_SOC_PCIE1_DMA_H32         0xc0000000U     /* PCIE Client Mode sb2pcitranslation2
5138 +                                                        * (2 ZettaBytes), high 32 bits
5139 +                                                        */
5140 +
5141 +#endif /* LINUX_BCMA_REGS_H_ */
5142 --- /dev/null
5143 +++ b/include/linux/bcma/bcma_soc.h
5144 @@ -0,0 +1,16 @@
5145 +#ifndef LINUX_BCMA_SOC_H_
5146 +#define LINUX_BCMA_SOC_H_
5147 +
5148 +#include <linux/bcma/bcma.h>
5149 +
5150 +struct bcma_soc {
5151 +       struct bcma_bus bus;
5152 +       struct bcma_device core_cc;
5153 +       struct bcma_device core_mips;
5154 +};
5155 +
5156 +int __init bcma_host_soc_register(struct bcma_soc *soc);
5157 +
5158 +int bcma_bus_register(struct bcma_bus *bus);
5159 +
5160 +#endif /* LINUX_BCMA_SOC_H_ */
5161 --- a/include/linux/mod_devicetable.h
5162 +++ b/include/linux/mod_devicetable.h
5163 @@ -382,6 +382,23 @@ struct ssb_device_id {
5164  #define SSB_ANY_ID             0xFFFF
5165  #define SSB_ANY_REV            0xFF
5166  
5167 +/* Broadcom's specific AMBA core, see drivers/bcma/ */
5168 +struct bcma_device_id {
5169 +       __u16   manuf;
5170 +       __u16   id;
5171 +       __u8    rev;
5172 +       __u8    class;
5173 +};
5174 +#define BCMA_CORE(_manuf, _id, _rev, _class)  \
5175 +       { .manuf = _manuf, .id = _id, .rev = _rev, .class = _class, }
5176 +#define BCMA_CORETABLE_END  \
5177 +       { 0, },
5178 +
5179 +#define BCMA_ANY_MANUF         0xFFFF
5180 +#define BCMA_ANY_ID            0xFFFF
5181 +#define BCMA_ANY_REV           0xFF
5182 +#define BCMA_ANY_CLASS         0xFF
5183 +
5184  struct virtio_device_id {
5185         __u32 device;
5186         __u32 vendor;
5187 --- a/scripts/mod/file2alias.c
5188 +++ b/scripts/mod/file2alias.c
5189 @@ -702,6 +702,24 @@ static int do_ssb_entry(const char *file
5190         return 1;
5191  }
5192  
5193 +/* Looks like: bcma:mNidNrevNclN. */
5194 +static int do_bcma_entry(const char *filename,
5195 +                        struct bcma_device_id *id, char *alias)
5196 +{
5197 +       id->manuf = TO_NATIVE(id->manuf);
5198 +       id->id = TO_NATIVE(id->id);
5199 +       id->rev = TO_NATIVE(id->rev);
5200 +       id->class = TO_NATIVE(id->class);
5201 +
5202 +       strcpy(alias, "bcma:");
5203 +       ADD(alias, "m", id->manuf != BCMA_ANY_MANUF, id->manuf);
5204 +       ADD(alias, "id", id->id != BCMA_ANY_ID, id->id);
5205 +       ADD(alias, "rev", id->rev != BCMA_ANY_REV, id->rev);
5206 +       ADD(alias, "cl", id->class != BCMA_ANY_CLASS, id->class);
5207 +       add_wildcard(alias);
5208 +       return 1;
5209 +}
5210 +
5211  /* Looks like: virtio:dNvN */
5212  static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
5213                            char *alias)
5214 @@ -968,6 +986,10 @@ void handle_moddevtable(struct module *m
5215                 do_table(symval, sym->st_size,
5216                          sizeof(struct ssb_device_id), "ssb",
5217                          do_ssb_entry, mod);
5218 +       else if (sym_is(symname, "__mod_bcma_device_table"))
5219 +               do_table(symval, sym->st_size,
5220 +                        sizeof(struct bcma_device_id), "bcma",
5221 +                        do_bcma_entry, mod);
5222         else if (sym_is(symname, "__mod_virtio_device_table"))
5223                 do_table(symval, sym->st_size,
5224                          sizeof(struct virtio_device_id), "virtio",