cns3xxx: sync kernel config
[openwrt/svn-archive/archive.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",