kernel: update bcma and ssb to version master-2011-12-16 from wireless-testing
[openwrt/svn-archive/archive.git] / target / linux / generic / patches-3.1 / 025-bcma_backport.patch
1 --- a/drivers/bcma/Kconfig
2 +++ b/drivers/bcma/Kconfig
3 @@ -33,6 +33,19 @@ config BCMA_DRIVER_PCI_HOSTMODE
4 help
5 PCI core hostmode operation (external PCI bus).
6
7 +config BCMA_HOST_SOC
8 + bool
9 + depends on BCMA_DRIVER_MIPS
10 +
11 +config BCMA_DRIVER_MIPS
12 + bool "BCMA Broadcom MIPS core driver"
13 + depends on BCMA && MIPS
14 + help
15 + Driver for the Broadcom MIPS core attached to Broadcom specific
16 + Advanced Microcontroller Bus.
17 +
18 + If unsure, say N
19 +
20 config BCMA_DEBUG
21 bool "BCMA debugging"
22 depends on BCMA
23 --- a/drivers/bcma/Makefile
24 +++ b/drivers/bcma/Makefile
25 @@ -2,7 +2,9 @@ bcma-y += main.o scan.o core.o sprom
26 bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
27 bcma-y += driver_pci.o
28 bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o
29 +bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o
30 bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
31 +bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o
32 obj-$(CONFIG_BCMA) += bcma.o
33
34 ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG
35 --- a/drivers/bcma/bcma_private.h
36 +++ b/drivers/bcma/bcma_private.h
37 @@ -15,13 +15,32 @@ struct bcma_bus;
38 /* main.c */
39 int bcma_bus_register(struct bcma_bus *bus);
40 void bcma_bus_unregister(struct bcma_bus *bus);
41 +int __init bcma_bus_early_register(struct bcma_bus *bus,
42 + struct bcma_device *core_cc,
43 + struct bcma_device *core_mips);
44 +#ifdef CONFIG_PM
45 +int bcma_bus_resume(struct bcma_bus *bus);
46 +#endif
47
48 /* scan.c */
49 int bcma_bus_scan(struct bcma_bus *bus);
50 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
51 + struct bcma_device_id *match,
52 + struct bcma_device *core);
53 +void bcma_init_bus(struct bcma_bus *bus);
54
55 /* sprom.c */
56 int bcma_sprom_get(struct bcma_bus *bus);
57
58 +/* driver_chipcommon.c */
59 +#ifdef CONFIG_BCMA_DRIVER_MIPS
60 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
61 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
62 +
63 +/* driver_chipcommon_pmu.c */
64 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc);
65 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
66 +
67 #ifdef CONFIG_BCMA_HOST_PCI
68 /* host_pci.c */
69 extern int __init bcma_host_pci_init(void);
70 --- a/drivers/bcma/core.c
71 +++ b/drivers/bcma/core.c
72 @@ -110,6 +110,8 @@ EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
73 u32 bcma_core_dma_translation(struct bcma_device *core)
74 {
75 switch (core->bus->hosttype) {
76 + case BCMA_HOSTTYPE_SOC:
77 + return 0;
78 case BCMA_HOSTTYPE_PCI:
79 if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
80 return BCMA_DMA_TRANSLATION_DMA64_CMT;
81 --- a/drivers/bcma/driver_chipcommon.c
82 +++ b/drivers/bcma/driver_chipcommon.c
83 @@ -26,6 +26,9 @@ void bcma_core_chipcommon_init(struct bc
84 u32 leddc_on = 10;
85 u32 leddc_off = 90;
86
87 + if (cc->setup_done)
88 + return;
89 +
90 if (cc->core->id.rev >= 11)
91 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
92 cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
93 @@ -52,6 +55,8 @@ void bcma_core_chipcommon_init(struct bc
94 ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
95 (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
96 }
97 +
98 + cc->setup_done = true;
99 }
100
101 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
102 @@ -101,3 +106,51 @@ u32 bcma_chipco_gpio_polarity(struct bcm
103 {
104 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
105 }
106 +
107 +#ifdef CONFIG_BCMA_DRIVER_MIPS
108 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
109 +{
110 + unsigned int irq;
111 + u32 baud_base;
112 + u32 i;
113 + unsigned int ccrev = cc->core->id.rev;
114 + struct bcma_serial_port *ports = cc->serial_ports;
115 +
116 + if (ccrev >= 11 && ccrev != 15) {
117 + /* Fixed ALP clock */
118 + baud_base = bcma_pmu_alp_clock(cc);
119 + if (ccrev >= 21) {
120 + /* Turn off UART clock before switching clocksource. */
121 + bcma_cc_write32(cc, BCMA_CC_CORECTL,
122 + bcma_cc_read32(cc, BCMA_CC_CORECTL)
123 + & ~BCMA_CC_CORECTL_UARTCLKEN);
124 + }
125 + /* Set the override bit so we don't divide it */
126 + bcma_cc_write32(cc, BCMA_CC_CORECTL,
127 + bcma_cc_read32(cc, BCMA_CC_CORECTL)
128 + | BCMA_CC_CORECTL_UARTCLK0);
129 + if (ccrev >= 21) {
130 + /* Re-enable the UART clock. */
131 + bcma_cc_write32(cc, BCMA_CC_CORECTL,
132 + bcma_cc_read32(cc, BCMA_CC_CORECTL)
133 + | BCMA_CC_CORECTL_UARTCLKEN);
134 + }
135 + } else {
136 + pr_err("serial not supported on this device ccrev: 0x%x\n",
137 + ccrev);
138 + return;
139 + }
140 +
141 + irq = bcma_core_mips_irq(cc->core);
142 +
143 + /* Determine the registers of the UARTs */
144 + cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
145 + for (i = 0; i < cc->nr_serial_ports; i++) {
146 + ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
147 + (i * 256);
148 + ports[i].irq = irq;
149 + ports[i].baud_base = baud_base;
150 + ports[i].reg_shift = 0;
151 + }
152 +}
153 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
154 --- a/drivers/bcma/driver_chipcommon_pmu.c
155 +++ b/drivers/bcma/driver_chipcommon_pmu.c
156 @@ -11,20 +11,47 @@
157 #include "bcma_private.h"
158 #include <linux/bcma/bcma.h>
159
160 -static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
161 - u32 offset, u32 mask, u32 set)
162 +static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
163 {
164 - u32 value;
165 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
166 + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
167 + return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
168 +}
169
170 - bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
171 +void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
172 +{
173 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
174 + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
175 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
176 +}
177 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_write);
178 +
179 +void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
180 + u32 set)
181 +{
182 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
183 + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
184 + bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set);
185 +}
186 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset);
187 +
188 +void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
189 + u32 offset, u32 mask, u32 set)
190 +{
191 bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
192 bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
193 - value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
194 - value &= mask;
195 - value |= set;
196 - bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
197 - bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
198 + bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set);
199 }
200 +EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset);
201 +
202 +void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
203 + u32 set)
204 +{
205 + bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset);
206 + bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR);
207 + bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set);
208 +}
209 +EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
210
211 static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
212 {
213 @@ -83,6 +110,24 @@ void bcma_pmu_swreg_init(struct bcma_drv
214 }
215 }
216
217 +/* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
218 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
219 +{
220 + struct bcma_bus *bus = cc->core->bus;
221 + u32 val;
222 +
223 + val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL);
224 + if (enable) {
225 + val |= BCMA_CHIPCTL_4331_EXTPA_EN;
226 + if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
227 + val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
228 + } else {
229 + val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
230 + val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
231 + }
232 + bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
233 +}
234 +
235 void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
236 {
237 struct bcma_bus *bus = cc->core->bus;
238 @@ -92,7 +137,7 @@ void bcma_pmu_workarounds(struct bcma_dr
239 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
240 break;
241 case 0x4331:
242 - pr_err("Enabling Ext PA lines not implemented\n");
243 + /* BCM4331 workaround is SPROM-related, we put it in sprom.c */
244 break;
245 case 43224:
246 if (bus->chipinfo.rev == 0) {
247 @@ -136,3 +181,129 @@ void bcma_pmu_init(struct bcma_drv_cc *c
248 bcma_pmu_swreg_init(cc);
249 bcma_pmu_workarounds(cc);
250 }
251 +
252 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
253 +{
254 + struct bcma_bus *bus = cc->core->bus;
255 +
256 + switch (bus->chipinfo.id) {
257 + case 0x4716:
258 + case 0x4748:
259 + case 47162:
260 + case 0x4313:
261 + case 0x5357:
262 + case 0x4749:
263 + case 53572:
264 + /* always 20Mhz */
265 + return 20000 * 1000;
266 + case 0x5356:
267 + case 0x5300:
268 + /* always 25Mhz */
269 + return 25000 * 1000;
270 + default:
271 + pr_warn("No ALP clock specified for %04X device, "
272 + "pmu rev. %d, using default %d Hz\n",
273 + bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
274 + }
275 + return BCMA_CC_PMU_ALP_CLOCK;
276 +}
277 +
278 +/* Find the output of the "m" pll divider given pll controls that start with
279 + * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
280 + */
281 +static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
282 +{
283 + u32 tmp, div, ndiv, p1, p2, fc;
284 + struct bcma_bus *bus = cc->core->bus;
285 +
286 + BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
287 +
288 + BUG_ON(!m || m > 4);
289 +
290 + if (bus->chipinfo.id == 0x5357 || bus->chipinfo.id == 0x4749) {
291 + /* Detect failure in clock setting */
292 + tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
293 + if (tmp & 0x40000)
294 + return 133 * 1000000;
295 + }
296 +
297 + tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
298 + p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
299 + p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
300 +
301 + tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
302 + div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
303 + BCMA_CC_PPL_MDIV_MASK;
304 +
305 + tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
306 + ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
307 +
308 + /* Do calculation in Mhz */
309 + fc = bcma_pmu_alp_clock(cc) / 1000000;
310 + fc = (p1 * ndiv * fc) / p2;
311 +
312 + /* Return clock in Hertz */
313 + return (fc / div) * 1000000;
314 +}
315 +
316 +/* query bus clock frequency for PMU-enabled chipcommon */
317 +u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
318 +{
319 + struct bcma_bus *bus = cc->core->bus;
320 +
321 + switch (bus->chipinfo.id) {
322 + case 0x4716:
323 + case 0x4748:
324 + case 47162:
325 + return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
326 + BCMA_CC_PMU5_MAINPLL_SSB);
327 + case 0x5356:
328 + return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
329 + BCMA_CC_PMU5_MAINPLL_SSB);
330 + case 0x5357:
331 + case 0x4749:
332 + return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
333 + BCMA_CC_PMU5_MAINPLL_SSB);
334 + case 0x5300:
335 + return bcma_pmu_clock(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
336 + BCMA_CC_PMU5_MAINPLL_SSB);
337 + case 53572:
338 + return 75000000;
339 + default:
340 + pr_warn("No backplane clock specified for %04X device, "
341 + "pmu rev. %d, using default %d Hz\n",
342 + bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
343 + }
344 + return BCMA_CC_PMU_HT_CLOCK;
345 +}
346 +
347 +/* query cpu clock frequency for PMU-enabled chipcommon */
348 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
349 +{
350 + struct bcma_bus *bus = cc->core->bus;
351 +
352 + if (bus->chipinfo.id == 53572)
353 + return 300000000;
354 +
355 + if (cc->pmu.rev >= 5) {
356 + u32 pll;
357 + switch (bus->chipinfo.id) {
358 + case 0x5356:
359 + pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
360 + break;
361 + case 0x5357:
362 + case 0x4749:
363 + pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
364 + break;
365 + default:
366 + pll = BCMA_CC_PMU4716_MAINPLL_PLL0;
367 + break;
368 + }
369 +
370 + /* TODO: if (bus->chipinfo.id == 0x5300)
371 + return si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); */
372 + return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
373 + }
374 +
375 + return bcma_pmu_get_clockcontrol(cc);
376 +}
377 --- /dev/null
378 +++ b/drivers/bcma/driver_mips.c
379 @@ -0,0 +1,256 @@
380 +/*
381 + * Broadcom specific AMBA
382 + * Broadcom MIPS32 74K core driver
383 + *
384 + * Copyright 2009, Broadcom Corporation
385 + * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
386 + * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
387 + * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
388 + *
389 + * Licensed under the GNU/GPL. See COPYING for details.
390 + */
391 +
392 +#include "bcma_private.h"
393 +
394 +#include <linux/bcma/bcma.h>
395 +
396 +#include <linux/serial.h>
397 +#include <linux/serial_core.h>
398 +#include <linux/serial_reg.h>
399 +#include <linux/time.h>
400 +
401 +/* The 47162a0 hangs when reading MIPS DMP registers registers */
402 +static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
403 +{
404 + return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
405 + dev->id.id == BCMA_CORE_MIPS_74K;
406 +}
407 +
408 +/* The 5357b0 hangs when reading USB20H DMP registers */
409 +static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
410 +{
411 + return (dev->bus->chipinfo.id == 0x5357 ||
412 + dev->bus->chipinfo.id == 0x4749) &&
413 + dev->bus->chipinfo.pkg == 11 &&
414 + dev->id.id == BCMA_CORE_USB20_HOST;
415 +}
416 +
417 +static inline u32 mips_read32(struct bcma_drv_mips *mcore,
418 + u16 offset)
419 +{
420 + return bcma_read32(mcore->core, offset);
421 +}
422 +
423 +static inline void mips_write32(struct bcma_drv_mips *mcore,
424 + u16 offset,
425 + u32 value)
426 +{
427 + bcma_write32(mcore->core, offset, value);
428 +}
429 +
430 +static const u32 ipsflag_irq_mask[] = {
431 + 0,
432 + BCMA_MIPS_IPSFLAG_IRQ1,
433 + BCMA_MIPS_IPSFLAG_IRQ2,
434 + BCMA_MIPS_IPSFLAG_IRQ3,
435 + BCMA_MIPS_IPSFLAG_IRQ4,
436 +};
437 +
438 +static const u32 ipsflag_irq_shift[] = {
439 + 0,
440 + BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
441 + BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
442 + BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
443 + BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
444 +};
445 +
446 +static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
447 +{
448 + u32 flag;
449 +
450 + if (bcma_core_mips_bcm47162a0_quirk(dev))
451 + return dev->core_index;
452 + if (bcma_core_mips_bcm5357b0_quirk(dev))
453 + return dev->core_index;
454 + flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
455 +
456 + return flag & 0x1F;
457 +}
458 +
459 +/* Get the MIPS IRQ assignment for a specified device.
460 + * If unassigned, 0 is returned.
461 + */
462 +unsigned int bcma_core_mips_irq(struct bcma_device *dev)
463 +{
464 + struct bcma_device *mdev = dev->bus->drv_mips.core;
465 + u32 irqflag;
466 + unsigned int irq;
467 +
468 + irqflag = bcma_core_mips_irqflag(dev);
469 +
470 + for (irq = 1; irq <= 4; irq++)
471 + if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
472 + (1 << irqflag))
473 + return irq;
474 +
475 + return 0;
476 +}
477 +EXPORT_SYMBOL(bcma_core_mips_irq);
478 +
479 +static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
480 +{
481 + unsigned int oldirq = bcma_core_mips_irq(dev);
482 + struct bcma_bus *bus = dev->bus;
483 + struct bcma_device *mdev = bus->drv_mips.core;
484 + u32 irqflag;
485 +
486 + irqflag = bcma_core_mips_irqflag(dev);
487 + BUG_ON(oldirq == 6);
488 +
489 + dev->irq = irq + 2;
490 +
491 + /* clear the old irq */
492 + if (oldirq == 0)
493 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
494 + bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
495 + ~(1 << irqflag));
496 + else
497 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
498 +
499 + /* assign the new one */
500 + if (irq == 0) {
501 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
502 + bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
503 + (1 << irqflag));
504 + } else {
505 + u32 oldirqflag = bcma_read32(mdev,
506 + BCMA_MIPS_MIPS74K_INTMASK(irq));
507 + if (oldirqflag) {
508 + struct bcma_device *core;
509 +
510 + /* backplane irq line is in use, find out who uses
511 + * it and set user to irq 0
512 + */
513 + list_for_each_entry_reverse(core, &bus->cores, list) {
514 + if ((1 << bcma_core_mips_irqflag(core)) ==
515 + oldirqflag) {
516 + bcma_core_mips_set_irq(core, 0);
517 + break;
518 + }
519 + }
520 + }
521 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
522 + 1 << irqflag);
523 + }
524 +
525 + pr_info("set_irq: core 0x%04x, irq %d => %d\n",
526 + dev->id.id, oldirq + 2, irq + 2);
527 +}
528 +
529 +static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
530 +{
531 + int i;
532 + static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
533 + printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
534 + for (i = 0; i <= 6; i++)
535 + printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
536 + printk("\n");
537 +}
538 +
539 +static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
540 +{
541 + struct bcma_device *core;
542 +
543 + list_for_each_entry_reverse(core, &bus->cores, list) {
544 + bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
545 + }
546 +}
547 +
548 +u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
549 +{
550 + struct bcma_bus *bus = mcore->core->bus;
551 +
552 + if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
553 + return bcma_pmu_get_clockcpu(&bus->drv_cc);
554 +
555 + pr_err("No PMU available, need this to get the cpu clock\n");
556 + return 0;
557 +}
558 +EXPORT_SYMBOL(bcma_cpu_clock);
559 +
560 +static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
561 +{
562 + struct bcma_bus *bus = mcore->core->bus;
563 +
564 + switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
565 + case BCMA_CC_FLASHT_STSER:
566 + case BCMA_CC_FLASHT_ATSER:
567 + pr_err("Serial flash not supported.\n");
568 + break;
569 + case BCMA_CC_FLASHT_PARA:
570 + pr_info("found parallel flash.\n");
571 + bus->drv_cc.pflash.window = 0x1c000000;
572 + bus->drv_cc.pflash.window_size = 0x02000000;
573 +
574 + if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
575 + BCMA_CC_FLASH_CFG_DS) == 0)
576 + bus->drv_cc.pflash.buswidth = 1;
577 + else
578 + bus->drv_cc.pflash.buswidth = 2;
579 + break;
580 + default:
581 + pr_err("flash not supported.\n");
582 + }
583 +}
584 +
585 +void bcma_core_mips_init(struct bcma_drv_mips *mcore)
586 +{
587 + struct bcma_bus *bus;
588 + struct bcma_device *core;
589 + bus = mcore->core->bus;
590 +
591 + pr_info("Initializing MIPS core...\n");
592 +
593 + if (!mcore->setup_done)
594 + mcore->assigned_irqs = 1;
595 +
596 + /* Assign IRQs to all cores on the bus */
597 + list_for_each_entry_reverse(core, &bus->cores, list) {
598 + int mips_irq;
599 + if (core->irq)
600 + continue;
601 +
602 + mips_irq = bcma_core_mips_irq(core);
603 + if (mips_irq > 4)
604 + core->irq = 0;
605 + else
606 + core->irq = mips_irq + 2;
607 + if (core->irq > 5)
608 + continue;
609 + switch (core->id.id) {
610 + case BCMA_CORE_PCI:
611 + case BCMA_CORE_PCIE:
612 + case BCMA_CORE_ETHERNET:
613 + case BCMA_CORE_ETHERNET_GBIT:
614 + case BCMA_CORE_MAC_GBIT:
615 + case BCMA_CORE_80211:
616 + case BCMA_CORE_USB20_HOST:
617 + /* These devices get their own IRQ line if available,
618 + * the rest goes on IRQ0
619 + */
620 + if (mcore->assigned_irqs <= 4)
621 + bcma_core_mips_set_irq(core,
622 + mcore->assigned_irqs++);
623 + break;
624 + }
625 + }
626 + pr_info("IRQ reconfiguration done\n");
627 + bcma_core_mips_dump_irq(bus);
628 +
629 + if (mcore->setup_done)
630 + return;
631 +
632 + bcma_chipco_serial_init(&bus->drv_cc);
633 + bcma_core_mips_flash_detect(mcore);
634 + mcore->setup_done = true;
635 +}
636 --- a/drivers/bcma/driver_pci.c
637 +++ b/drivers/bcma/driver_pci.c
638 @@ -173,7 +173,7 @@ static bool bcma_core_pci_is_in_hostmode
639 return false;
640
641 #ifdef CONFIG_SSB_DRIVER_PCICORE
642 - if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
643 + if (bus->sprom.boardflags_lo & SSB_BFL_NOPCI)
644 return false;
645 #endif /* CONFIG_SSB_DRIVER_PCICORE */
646
647 @@ -189,6 +189,9 @@ static bool bcma_core_pci_is_in_hostmode
648
649 void bcma_core_pci_init(struct bcma_drv_pci *pc)
650 {
651 + if (pc->setup_done)
652 + return;
653 +
654 if (bcma_core_pci_is_in_hostmode(pc)) {
655 #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
656 bcma_core_pci_hostmode_init(pc);
657 @@ -198,6 +201,8 @@ void bcma_core_pci_init(struct bcma_drv_
658 } else {
659 bcma_core_pci_clientmode_init(pc);
660 }
661 +
662 + pc->setup_done = true;
663 }
664
665 int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
666 @@ -205,7 +210,14 @@ int bcma_core_pci_irq_ctl(struct bcma_dr
667 {
668 struct pci_dev *pdev = pc->core->bus->host_pci;
669 u32 coremask, tmp;
670 - int err;
671 + int err = 0;
672 +
673 + if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
674 + /* This bcma device is not on a PCI host-bus. So the IRQs are
675 + * not routed through the PCI core.
676 + * So we must not enable routing through the PCI core. */
677 + goto out;
678 + }
679
680 err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
681 if (err)
682 --- a/drivers/bcma/host_pci.c
683 +++ b/drivers/bcma/host_pci.c
684 @@ -9,6 +9,7 @@
685 #include <linux/slab.h>
686 #include <linux/bcma/bcma.h>
687 #include <linux/pci.h>
688 +#include <linux/module.h>
689
690 static void bcma_host_pci_switch_core(struct bcma_device *core)
691 {
692 @@ -20,48 +21,58 @@ static void bcma_host_pci_switch_core(st
693 pr_debug("Switched to core: 0x%X\n", core->id.id);
694 }
695
696 -static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
697 -{
698 +/* Provides access to the requested core. Returns base offset that has to be
699 + * used. It makes use of fixed windows when possible. */
700 +static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core)
701 +{
702 + switch (core->id.id) {
703 + case BCMA_CORE_CHIPCOMMON:
704 + return 3 * BCMA_CORE_SIZE;
705 + case BCMA_CORE_PCIE:
706 + return 2 * BCMA_CORE_SIZE;
707 + }
708 +
709 if (core->bus->mapped_core != core)
710 bcma_host_pci_switch_core(core);
711 + return 0;
712 +}
713 +
714 +static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
715 +{
716 + offset += bcma_host_pci_provide_access_to_core(core);
717 return ioread8(core->bus->mmio + offset);
718 }
719
720 static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
721 {
722 - if (core->bus->mapped_core != core)
723 - bcma_host_pci_switch_core(core);
724 + offset += bcma_host_pci_provide_access_to_core(core);
725 return ioread16(core->bus->mmio + offset);
726 }
727
728 static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
729 {
730 - if (core->bus->mapped_core != core)
731 - bcma_host_pci_switch_core(core);
732 + offset += bcma_host_pci_provide_access_to_core(core);
733 return ioread32(core->bus->mmio + offset);
734 }
735
736 static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
737 u8 value)
738 {
739 - if (core->bus->mapped_core != core)
740 - bcma_host_pci_switch_core(core);
741 + offset += bcma_host_pci_provide_access_to_core(core);
742 iowrite8(value, core->bus->mmio + offset);
743 }
744
745 static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
746 u16 value)
747 {
748 - if (core->bus->mapped_core != core)
749 - bcma_host_pci_switch_core(core);
750 + offset += bcma_host_pci_provide_access_to_core(core);
751 iowrite16(value, core->bus->mmio + offset);
752 }
753
754 static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
755 u32 value)
756 {
757 - if (core->bus->mapped_core != core)
758 - bcma_host_pci_switch_core(core);
759 + offset += bcma_host_pci_provide_access_to_core(core);
760 iowrite32(value, core->bus->mmio + offset);
761 }
762
763 @@ -223,6 +234,41 @@ static void bcma_host_pci_remove(struct
764 pci_set_drvdata(dev, NULL);
765 }
766
767 +#ifdef CONFIG_PM
768 +static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state)
769 +{
770 + /* Host specific */
771 + pci_save_state(dev);
772 + pci_disable_device(dev);
773 + pci_set_power_state(dev, pci_choose_state(dev, state));
774 +
775 + return 0;
776 +}
777 +
778 +static int bcma_host_pci_resume(struct pci_dev *dev)
779 +{
780 + struct bcma_bus *bus = pci_get_drvdata(dev);
781 + int err;
782 +
783 + /* Host specific */
784 + pci_set_power_state(dev, 0);
785 + err = pci_enable_device(dev);
786 + if (err)
787 + return err;
788 + pci_restore_state(dev);
789 +
790 + /* Bus specific */
791 + err = bcma_bus_resume(bus);
792 + if (err)
793 + return err;
794 +
795 + return 0;
796 +}
797 +#else /* CONFIG_PM */
798 +# define bcma_host_pci_suspend NULL
799 +# define bcma_host_pci_resume NULL
800 +#endif /* CONFIG_PM */
801 +
802 static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
803 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
804 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
805 @@ -238,6 +284,8 @@ static struct pci_driver bcma_pci_bridge
806 .id_table = bcma_pci_bridge_tbl,
807 .probe = bcma_host_pci_probe,
808 .remove = bcma_host_pci_remove,
809 + .suspend = bcma_host_pci_suspend,
810 + .resume = bcma_host_pci_resume,
811 };
812
813 int __init bcma_host_pci_init(void)
814 --- /dev/null
815 +++ b/drivers/bcma/host_soc.c
816 @@ -0,0 +1,183 @@
817 +/*
818 + * Broadcom specific AMBA
819 + * System on Chip (SoC) Host
820 + *
821 + * Licensed under the GNU/GPL. See COPYING for details.
822 + */
823 +
824 +#include "bcma_private.h"
825 +#include "scan.h"
826 +#include <linux/bcma/bcma.h>
827 +#include <linux/bcma/bcma_soc.h>
828 +
829 +static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
830 +{
831 + return readb(core->io_addr + offset);
832 +}
833 +
834 +static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
835 +{
836 + return readw(core->io_addr + offset);
837 +}
838 +
839 +static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
840 +{
841 + return readl(core->io_addr + offset);
842 +}
843 +
844 +static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
845 + u8 value)
846 +{
847 + writeb(value, core->io_addr + offset);
848 +}
849 +
850 +static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
851 + u16 value)
852 +{
853 + writew(value, core->io_addr + offset);
854 +}
855 +
856 +static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
857 + u32 value)
858 +{
859 + writel(value, core->io_addr + offset);
860 +}
861 +
862 +#ifdef CONFIG_BCMA_BLOCKIO
863 +static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
864 + size_t count, u16 offset, u8 reg_width)
865 +{
866 + void __iomem *addr = core->io_addr + offset;
867 +
868 + switch (reg_width) {
869 + case sizeof(u8): {
870 + u8 *buf = buffer;
871 +
872 + while (count) {
873 + *buf = __raw_readb(addr);
874 + buf++;
875 + count--;
876 + }
877 + break;
878 + }
879 + case sizeof(u16): {
880 + __le16 *buf = buffer;
881 +
882 + WARN_ON(count & 1);
883 + while (count) {
884 + *buf = (__force __le16)__raw_readw(addr);
885 + buf++;
886 + count -= 2;
887 + }
888 + break;
889 + }
890 + case sizeof(u32): {
891 + __le32 *buf = buffer;
892 +
893 + WARN_ON(count & 3);
894 + while (count) {
895 + *buf = (__force __le32)__raw_readl(addr);
896 + buf++;
897 + count -= 4;
898 + }
899 + break;
900 + }
901 + default:
902 + WARN_ON(1);
903 + }
904 +}
905 +
906 +static void bcma_host_soc_block_write(struct bcma_device *core,
907 + const void *buffer,
908 + size_t count, u16 offset, u8 reg_width)
909 +{
910 + void __iomem *addr = core->io_addr + offset;
911 +
912 + switch (reg_width) {
913 + case sizeof(u8): {
914 + const u8 *buf = buffer;
915 +
916 + while (count) {
917 + __raw_writeb(*buf, addr);
918 + buf++;
919 + count--;
920 + }
921 + break;
922 + }
923 + case sizeof(u16): {
924 + const __le16 *buf = buffer;
925 +
926 + WARN_ON(count & 1);
927 + while (count) {
928 + __raw_writew((__force u16)(*buf), addr);
929 + buf++;
930 + count -= 2;
931 + }
932 + break;
933 + }
934 + case sizeof(u32): {
935 + const __le32 *buf = buffer;
936 +
937 + WARN_ON(count & 3);
938 + while (count) {
939 + __raw_writel((__force u32)(*buf), addr);
940 + buf++;
941 + count -= 4;
942 + }
943 + break;
944 + }
945 + default:
946 + WARN_ON(1);
947 + }
948 +}
949 +#endif /* CONFIG_BCMA_BLOCKIO */
950 +
951 +static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
952 +{
953 + return readl(core->io_wrap + offset);
954 +}
955 +
956 +static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
957 + u32 value)
958 +{
959 + writel(value, core->io_wrap + offset);
960 +}
961 +
962 +const struct bcma_host_ops bcma_host_soc_ops = {
963 + .read8 = bcma_host_soc_read8,
964 + .read16 = bcma_host_soc_read16,
965 + .read32 = bcma_host_soc_read32,
966 + .write8 = bcma_host_soc_write8,
967 + .write16 = bcma_host_soc_write16,
968 + .write32 = bcma_host_soc_write32,
969 +#ifdef CONFIG_BCMA_BLOCKIO
970 + .block_read = bcma_host_soc_block_read,
971 + .block_write = bcma_host_soc_block_write,
972 +#endif
973 + .aread32 = bcma_host_soc_aread32,
974 + .awrite32 = bcma_host_soc_awrite32,
975 +};
976 +
977 +int __init bcma_host_soc_register(struct bcma_soc *soc)
978 +{
979 + struct bcma_bus *bus = &soc->bus;
980 + int err;
981 +
982 + /* iomap only first core. We have to read some register on this core
983 + * to scan the bus.
984 + */
985 + bus->mmio = ioremap_nocache(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
986 + if (!bus->mmio)
987 + return -ENOMEM;
988 +
989 + /* Host specific */
990 + bus->hosttype = BCMA_HOSTTYPE_SOC;
991 + bus->ops = &bcma_host_soc_ops;
992 +
993 + /* Register */
994 + err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
995 + if (err)
996 + iounmap(bus->mmio);
997 +
998 + return err;
999 +}
1000 --- a/drivers/bcma/main.c
1001 +++ b/drivers/bcma/main.c
1002 @@ -6,6 +6,7 @@
1003 */
1004
1005 #include "bcma_private.h"
1006 +#include <linux/module.h>
1007 #include <linux/bcma/bcma.h>
1008 #include <linux/slab.h>
1009
1010 @@ -68,6 +69,10 @@ static struct bcma_device *bcma_find_cor
1011 static void bcma_release_core_dev(struct device *dev)
1012 {
1013 struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1014 + if (core->io_addr)
1015 + iounmap(core->io_addr);
1016 + if (core->io_wrap)
1017 + iounmap(core->io_wrap);
1018 kfree(core);
1019 }
1020
1021 @@ -82,6 +87,7 @@ static int bcma_register_cores(struct bc
1022 case BCMA_CORE_CHIPCOMMON:
1023 case BCMA_CORE_PCI:
1024 case BCMA_CORE_PCIE:
1025 + case BCMA_CORE_MIPS_74K:
1026 continue;
1027 }
1028
1029 @@ -95,7 +101,10 @@ static int bcma_register_cores(struct bc
1030 core->dma_dev = &bus->host_pci->dev;
1031 core->irq = bus->host_pci->irq;
1032 break;
1033 - case BCMA_HOSTTYPE_NONE:
1034 + case BCMA_HOSTTYPE_SOC:
1035 + core->dev.dma_mask = &core->dev.coherent_dma_mask;
1036 + core->dma_dev = &core->dev;
1037 + break;
1038 case BCMA_HOSTTYPE_SDIO:
1039 break;
1040 }
1041 @@ -142,6 +151,13 @@ int bcma_bus_register(struct bcma_bus *b
1042 bcma_core_chipcommon_init(&bus->drv_cc);
1043 }
1044
1045 + /* Init MIPS core */
1046 + core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
1047 + if (core) {
1048 + bus->drv_mips.core = core;
1049 + bcma_core_mips_init(&bus->drv_mips);
1050 + }
1051 +
1052 /* Init PCIE core */
1053 core = bcma_find_core(bus, BCMA_CORE_PCIE);
1054 if (core) {
1055 @@ -171,6 +187,75 @@ void bcma_bus_unregister(struct bcma_bus
1056 bcma_unregister_cores(bus);
1057 }
1058
1059 +int __init bcma_bus_early_register(struct bcma_bus *bus,
1060 + struct bcma_device *core_cc,
1061 + struct bcma_device *core_mips)
1062 +{
1063 + int err;
1064 + struct bcma_device *core;
1065 + struct bcma_device_id match;
1066 +
1067 + bcma_init_bus(bus);
1068 +
1069 + match.manuf = BCMA_MANUF_BCM;
1070 + match.id = BCMA_CORE_CHIPCOMMON;
1071 + match.class = BCMA_CL_SIM;
1072 + match.rev = BCMA_ANY_REV;
1073 +
1074 + /* Scan for chip common core */
1075 + err = bcma_bus_scan_early(bus, &match, core_cc);
1076 + if (err) {
1077 + pr_err("Failed to scan for common core: %d\n", err);
1078 + return -1;
1079 + }
1080 +
1081 + match.manuf = BCMA_MANUF_MIPS;
1082 + match.id = BCMA_CORE_MIPS_74K;
1083 + match.class = BCMA_CL_SIM;
1084 + match.rev = BCMA_ANY_REV;
1085 +
1086 + /* Scan for mips core */
1087 + err = bcma_bus_scan_early(bus, &match, core_mips);
1088 + if (err) {
1089 + pr_err("Failed to scan for mips core: %d\n", err);
1090 + return -1;
1091 + }
1092 +
1093 + /* Init CC core */
1094 + core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
1095 + if (core) {
1096 + bus->drv_cc.core = core;
1097 + bcma_core_chipcommon_init(&bus->drv_cc);
1098 + }
1099 +
1100 + /* Init MIPS core */
1101 + core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
1102 + if (core) {
1103 + bus->drv_mips.core = core;
1104 + bcma_core_mips_init(&bus->drv_mips);
1105 + }
1106 +
1107 + pr_info("Early bus registered\n");
1108 +
1109 + return 0;
1110 +}
1111 +
1112 +#ifdef CONFIG_PM
1113 +int bcma_bus_resume(struct bcma_bus *bus)
1114 +{
1115 + struct bcma_device *core;
1116 +
1117 + /* Init CC core */
1118 + core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
1119 + if (core) {
1120 + bus->drv_cc.setup_done = false;
1121 + bcma_core_chipcommon_init(&bus->drv_cc);
1122 + }
1123 +
1124 + return 0;
1125 +}
1126 +#endif
1127 +
1128 int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
1129 {
1130 drv->drv.name = drv->name;
1131 --- a/drivers/bcma/scan.c
1132 +++ b/drivers/bcma/scan.c
1133 @@ -200,18 +200,162 @@ static s32 bcma_erom_get_addr_desc(struc
1134 return addrl;
1135 }
1136
1137 -int bcma_bus_scan(struct bcma_bus *bus)
1138 +static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
1139 + u16 index)
1140 {
1141 - u32 erombase;
1142 - u32 __iomem *eromptr, *eromend;
1143 + struct bcma_device *core;
1144
1145 + list_for_each_entry(core, &bus->cores, list) {
1146 + if (core->core_index == index)
1147 + return core;
1148 + }
1149 + return NULL;
1150 +}
1151 +
1152 +static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
1153 + struct bcma_device_id *match, int core_num,
1154 + struct bcma_device *core)
1155 +{
1156 + s32 tmp;
1157 + u8 i, j;
1158 s32 cia, cib;
1159 u8 ports[2], wrappers[2];
1160
1161 + /* get CIs */
1162 + cia = bcma_erom_get_ci(bus, eromptr);
1163 + if (cia < 0) {
1164 + bcma_erom_push_ent(eromptr);
1165 + if (bcma_erom_is_end(bus, eromptr))
1166 + return -ESPIPE;
1167 + return -EILSEQ;
1168 + }
1169 + cib = bcma_erom_get_ci(bus, eromptr);
1170 + if (cib < 0)
1171 + return -EILSEQ;
1172 +
1173 + /* parse CIs */
1174 + core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
1175 + core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
1176 + core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
1177 + ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
1178 + ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
1179 + wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
1180 + wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
1181 + core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
1182 +
1183 + if (((core->id.manuf == BCMA_MANUF_ARM) &&
1184 + (core->id.id == 0xFFF)) ||
1185 + (ports[1] == 0)) {
1186 + bcma_erom_skip_component(bus, eromptr);
1187 + return -ENXIO;
1188 + }
1189 +
1190 + /* check if component is a core at all */
1191 + if (wrappers[0] + wrappers[1] == 0) {
1192 + /* we could save addrl of the router
1193 + if (cid == BCMA_CORE_OOB_ROUTER)
1194 + */
1195 + bcma_erom_skip_component(bus, eromptr);
1196 + return -ENXIO;
1197 + }
1198 +
1199 + if (bcma_erom_is_bridge(bus, eromptr)) {
1200 + bcma_erom_skip_component(bus, eromptr);
1201 + return -ENXIO;
1202 + }
1203 +
1204 + if (bcma_find_core_by_index(bus, core_num)) {
1205 + bcma_erom_skip_component(bus, eromptr);
1206 + return -ENODEV;
1207 + }
1208 +
1209 + if (match && ((match->manuf != BCMA_ANY_MANUF &&
1210 + match->manuf != core->id.manuf) ||
1211 + (match->id != BCMA_ANY_ID && match->id != core->id.id) ||
1212 + (match->rev != BCMA_ANY_REV && match->rev != core->id.rev) ||
1213 + (match->class != BCMA_ANY_CLASS && match->class != core->id.class)
1214 + )) {
1215 + bcma_erom_skip_component(bus, eromptr);
1216 + return -ENODEV;
1217 + }
1218 +
1219 + /* get & parse master ports */
1220 + for (i = 0; i < ports[0]; i++) {
1221 + s32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
1222 + if (mst_port_d < 0)
1223 + return -EILSEQ;
1224 + }
1225 +
1226 + /* get & parse slave ports */
1227 + for (i = 0; i < ports[1]; i++) {
1228 + for (j = 0; ; j++) {
1229 + tmp = bcma_erom_get_addr_desc(bus, eromptr,
1230 + SCAN_ADDR_TYPE_SLAVE, i);
1231 + if (tmp < 0) {
1232 + /* no more entries for port _i_ */
1233 + /* pr_debug("erom: slave port %d "
1234 + * "has %d descriptors\n", i, j); */
1235 + break;
1236 + } else {
1237 + if (i == 0 && j == 0)
1238 + core->addr = tmp;
1239 + }
1240 + }
1241 + }
1242 +
1243 + /* get & parse master wrappers */
1244 + for (i = 0; i < wrappers[0]; i++) {
1245 + for (j = 0; ; j++) {
1246 + tmp = bcma_erom_get_addr_desc(bus, eromptr,
1247 + SCAN_ADDR_TYPE_MWRAP, i);
1248 + if (tmp < 0) {
1249 + /* no more entries for port _i_ */
1250 + /* pr_debug("erom: master wrapper %d "
1251 + * "has %d descriptors\n", i, j); */
1252 + break;
1253 + } else {
1254 + if (i == 0 && j == 0)
1255 + core->wrap = tmp;
1256 + }
1257 + }
1258 + }
1259 +
1260 + /* get & parse slave wrappers */
1261 + for (i = 0; i < wrappers[1]; i++) {
1262 + u8 hack = (ports[1] == 1) ? 0 : 1;
1263 + for (j = 0; ; j++) {
1264 + tmp = bcma_erom_get_addr_desc(bus, eromptr,
1265 + SCAN_ADDR_TYPE_SWRAP, i + hack);
1266 + if (tmp < 0) {
1267 + /* no more entries for port _i_ */
1268 + /* pr_debug("erom: master wrapper %d "
1269 + * has %d descriptors\n", i, j); */
1270 + break;
1271 + } else {
1272 + if (wrappers[0] == 0 && !i && !j)
1273 + core->wrap = tmp;
1274 + }
1275 + }
1276 + }
1277 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1278 + core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE);
1279 + if (!core->io_addr)
1280 + return -ENOMEM;
1281 + core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE);
1282 + if (!core->io_wrap) {
1283 + iounmap(core->io_addr);
1284 + return -ENOMEM;
1285 + }
1286 + }
1287 + return 0;
1288 +}
1289 +
1290 +void bcma_init_bus(struct bcma_bus *bus)
1291 +{
1292 s32 tmp;
1293 - u8 i, j;
1294
1295 - int err;
1296 + if (bus->init_done)
1297 + return;
1298
1299 INIT_LIST_HEAD(&bus->cores);
1300 bus->nr_cores = 0;
1301 @@ -222,9 +366,27 @@ int bcma_bus_scan(struct bcma_bus *bus)
1302 bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
1303 bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
1304 bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
1305 + bus->init_done = true;
1306 +}
1307 +
1308 +int bcma_bus_scan(struct bcma_bus *bus)
1309 +{
1310 + u32 erombase;
1311 + u32 __iomem *eromptr, *eromend;
1312 +
1313 + int err, core_num = 0;
1314 +
1315 + bcma_init_bus(bus);
1316
1317 erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
1318 - eromptr = bus->mmio;
1319 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1320 + eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
1321 + if (!eromptr)
1322 + return -ENOMEM;
1323 + } else {
1324 + eromptr = bus->mmio;
1325 + }
1326 +
1327 eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
1328
1329 bcma_scan_switch_core(bus, erombase);
1330 @@ -236,125 +398,89 @@ int bcma_bus_scan(struct bcma_bus *bus)
1331 INIT_LIST_HEAD(&core->list);
1332 core->bus = bus;
1333
1334 - /* get CIs */
1335 - cia = bcma_erom_get_ci(bus, &eromptr);
1336 - if (cia < 0) {
1337 - bcma_erom_push_ent(&eromptr);
1338 - if (bcma_erom_is_end(bus, &eromptr))
1339 - break;
1340 - err= -EILSEQ;
1341 - goto out;
1342 - }
1343 - cib = bcma_erom_get_ci(bus, &eromptr);
1344 - if (cib < 0) {
1345 - err= -EILSEQ;
1346 - goto out;
1347 - }
1348 -
1349 - /* parse CIs */
1350 - core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
1351 - core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
1352 - core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
1353 - ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
1354 - ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
1355 - wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
1356 - wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
1357 - core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
1358 -
1359 - if (((core->id.manuf == BCMA_MANUF_ARM) &&
1360 - (core->id.id == 0xFFF)) ||
1361 - (ports[1] == 0)) {
1362 - bcma_erom_skip_component(bus, &eromptr);
1363 + err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
1364 + if (err == -ENODEV) {
1365 + core_num++;
1366 continue;
1367 - }
1368 -
1369 - /* check if component is a core at all */
1370 - if (wrappers[0] + wrappers[1] == 0) {
1371 - /* we could save addrl of the router
1372 - if (cid == BCMA_CORE_OOB_ROUTER)
1373 - */
1374 - bcma_erom_skip_component(bus, &eromptr);
1375 + } else if (err == -ENXIO)
1376 continue;
1377 - }
1378 + else if (err == -ESPIPE)
1379 + break;
1380 + else if (err < 0)
1381 + return err;
1382
1383 - if (bcma_erom_is_bridge(bus, &eromptr)) {
1384 - bcma_erom_skip_component(bus, &eromptr);
1385 - continue;
1386 - }
1387 + core->core_index = core_num++;
1388 + bus->nr_cores++;
1389
1390 - /* get & parse master ports */
1391 - for (i = 0; i < ports[0]; i++) {
1392 - u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
1393 - if (mst_port_d < 0) {
1394 - err= -EILSEQ;
1395 - goto out;
1396 - }
1397 - }
1398 + pr_info("Core %d found: %s "
1399 + "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
1400 + core->core_index, bcma_device_name(&core->id),
1401 + core->id.manuf, core->id.id, core->id.rev,
1402 + core->id.class);
1403
1404 - /* get & parse slave ports */
1405 - for (i = 0; i < ports[1]; i++) {
1406 - for (j = 0; ; j++) {
1407 - tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1408 - SCAN_ADDR_TYPE_SLAVE, i);
1409 - if (tmp < 0) {
1410 - /* no more entries for port _i_ */
1411 - /* pr_debug("erom: slave port %d "
1412 - * "has %d descriptors\n", i, j); */
1413 - break;
1414 - } else {
1415 - if (i == 0 && j == 0)
1416 - core->addr = tmp;
1417 - }
1418 - }
1419 - }
1420 + list_add(&core->list, &bus->cores);
1421 + }
1422
1423 - /* get & parse master wrappers */
1424 - for (i = 0; i < wrappers[0]; i++) {
1425 - for (j = 0; ; j++) {
1426 - tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1427 - SCAN_ADDR_TYPE_MWRAP, i);
1428 - if (tmp < 0) {
1429 - /* no more entries for port _i_ */
1430 - /* pr_debug("erom: master wrapper %d "
1431 - * "has %d descriptors\n", i, j); */
1432 - break;
1433 - } else {
1434 - if (i == 0 && j == 0)
1435 - core->wrap = tmp;
1436 - }
1437 - }
1438 - }
1439 + if (bus->hosttype == BCMA_HOSTTYPE_SOC)
1440 + iounmap(eromptr);
1441
1442 - /* get & parse slave wrappers */
1443 - for (i = 0; i < wrappers[1]; i++) {
1444 - u8 hack = (ports[1] == 1) ? 0 : 1;
1445 - for (j = 0; ; j++) {
1446 - tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1447 - SCAN_ADDR_TYPE_SWRAP, i + hack);
1448 - if (tmp < 0) {
1449 - /* no more entries for port _i_ */
1450 - /* pr_debug("erom: master wrapper %d "
1451 - * has %d descriptors\n", i, j); */
1452 - break;
1453 - } else {
1454 - if (wrappers[0] == 0 && !i && !j)
1455 - core->wrap = tmp;
1456 - }
1457 - }
1458 - }
1459 + return 0;
1460 +}
1461 +
1462 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
1463 + struct bcma_device_id *match,
1464 + struct bcma_device *core)
1465 +{
1466 + u32 erombase;
1467 + u32 __iomem *eromptr, *eromend;
1468
1469 + int err = -ENODEV;
1470 + int core_num = 0;
1471 +
1472 + erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
1473 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1474 + eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
1475 + if (!eromptr)
1476 + return -ENOMEM;
1477 + } else {
1478 + eromptr = bus->mmio;
1479 + }
1480 +
1481 + eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
1482 +
1483 + bcma_scan_switch_core(bus, erombase);
1484 +
1485 + while (eromptr < eromend) {
1486 + memset(core, 0, sizeof(*core));
1487 + INIT_LIST_HEAD(&core->list);
1488 + core->bus = bus;
1489 +
1490 + err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
1491 + if (err == -ENODEV) {
1492 + core_num++;
1493 + continue;
1494 + } else if (err == -ENXIO)
1495 + continue;
1496 + else if (err == -ESPIPE)
1497 + break;
1498 + else if (err < 0)
1499 + return err;
1500 +
1501 + core->core_index = core_num++;
1502 + bus->nr_cores++;
1503 pr_info("Core %d found: %s "
1504 "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
1505 - bus->nr_cores, bcma_device_name(&core->id),
1506 + core->core_index, bcma_device_name(&core->id),
1507 core->id.manuf, core->id.id, core->id.rev,
1508 core->id.class);
1509
1510 - core->core_index = bus->nr_cores++;
1511 list_add(&core->list, &bus->cores);
1512 - continue;
1513 -out:
1514 - return err;
1515 + err = 0;
1516 + break;
1517 }
1518
1519 - return 0;
1520 + if (bus->hosttype == BCMA_HOSTTYPE_SOC)
1521 + iounmap(eromptr);
1522 +
1523 + return err;
1524 }
1525 --- a/drivers/bcma/sprom.c
1526 +++ b/drivers/bcma/sprom.c
1527 @@ -129,10 +129,80 @@ static void bcma_sprom_extract_r8(struct
1528 u16 v;
1529 int i;
1530
1531 + bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
1532 + SSB_SPROM_REVISION_REV;
1533 +
1534 for (i = 0; i < 3; i++) {
1535 v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
1536 *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
1537 }
1538 +
1539 + bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)];
1540 +
1541 + bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
1542 + SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT;
1543 + bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
1544 + SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT;
1545 + bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
1546 + SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT;
1547 + bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
1548 + SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT;
1549 +
1550 + bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
1551 + SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT;
1552 + bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
1553 + SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT;
1554 + bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
1555 + SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT;
1556 + bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
1557 + SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT;
1558 +
1559 + bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
1560 + SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT;
1561 + bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
1562 + SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT;
1563 + bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
1564 + SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT;
1565 + bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
1566 + SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT;
1567 +
1568 + bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
1569 + SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT;
1570 + bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
1571 + SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT;
1572 + bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
1573 + SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT;
1574 + bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
1575 + SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT;
1576 +
1577 + bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)];
1578 + bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)];
1579 + bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)];
1580 + bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)];
1581 +
1582 + bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)];
1583 +
1584 + bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1585 + SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
1586 + bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1587 + SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
1588 + bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1589 + SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
1590 + bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1591 + SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
1592 + bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
1593 + SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
1594 +
1595 + bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1596 + SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
1597 + bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1598 + SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
1599 + bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1600 + SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
1601 + bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1602 + SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
1603 + bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
1604 + SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
1605 }
1606
1607 int bcma_sprom_get(struct bcma_bus *bus)
1608 @@ -152,6 +222,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
1609 if (!sprom)
1610 return -ENOMEM;
1611
1612 + if (bus->chipinfo.id == 0x4331)
1613 + bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
1614 +
1615 /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
1616 * According to brcm80211 this applies to cards with PCIe rev >= 6
1617 * TODO: understand this condition and use it */
1618 @@ -159,6 +232,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
1619 BCMA_CC_SPROM_PCIE6;
1620 bcma_sprom_read(bus, offset, sprom);
1621
1622 + if (bus->chipinfo.id == 0x4331)
1623 + bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
1624 +
1625 err = bcma_sprom_valid(sprom);
1626 if (err)
1627 goto out;
1628 --- a/include/linux/bcma/bcma.h
1629 +++ b/include/linux/bcma/bcma.h
1630 @@ -6,6 +6,7 @@
1631
1632 #include <linux/bcma/bcma_driver_chipcommon.h>
1633 #include <linux/bcma/bcma_driver_pci.h>
1634 +#include <linux/bcma/bcma_driver_mips.h>
1635 #include <linux/ssb/ssb.h> /* SPROM sharing */
1636
1637 #include "bcma_regs.h"
1638 @@ -14,9 +15,9 @@ struct bcma_device;
1639 struct bcma_bus;
1640
1641 enum bcma_hosttype {
1642 - BCMA_HOSTTYPE_NONE,
1643 BCMA_HOSTTYPE_PCI,
1644 BCMA_HOSTTYPE_SDIO,
1645 + BCMA_HOSTTYPE_SOC,
1646 };
1647
1648 struct bcma_chipinfo {
1649 @@ -130,6 +131,7 @@ struct bcma_device {
1650
1651 struct device dev;
1652 struct device *dma_dev;
1653 +
1654 unsigned int irq;
1655 bool dev_registered;
1656
1657 @@ -138,6 +140,9 @@ struct bcma_device {
1658 u32 addr;
1659 u32 wrap;
1660
1661 + void __iomem *io_addr;
1662 + void __iomem *io_wrap;
1663 +
1664 void *drvdata;
1665 struct list_head list;
1666 };
1667 @@ -165,10 +170,9 @@ struct bcma_driver {
1668 };
1669 extern
1670 int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
1671 -static inline int bcma_driver_register(struct bcma_driver *drv)
1672 -{
1673 - return __bcma_driver_register(drv, THIS_MODULE);
1674 -}
1675 +#define bcma_driver_register(drv) \
1676 + __bcma_driver_register(drv, THIS_MODULE)
1677 +
1678 extern void bcma_driver_unregister(struct bcma_driver *drv);
1679
1680 struct bcma_bus {
1681 @@ -190,70 +194,93 @@ struct bcma_bus {
1682 struct bcma_device *mapped_core;
1683 struct list_head cores;
1684 u8 nr_cores;
1685 + u8 init_done:1;
1686
1687 struct bcma_drv_cc drv_cc;
1688 struct bcma_drv_pci drv_pci;
1689 + struct bcma_drv_mips drv_mips;
1690
1691 /* We decided to share SPROM struct with SSB as long as we do not need
1692 * any hacks for BCMA. This simplifies drivers code. */
1693 struct ssb_sprom sprom;
1694 };
1695
1696 -extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
1697 +static inline u32 bcma_read8(struct bcma_device *core, u16 offset)
1698 {
1699 return core->bus->ops->read8(core, offset);
1700 }
1701 -extern inline u32 bcma_read16(struct bcma_device *core, u16 offset)
1702 +static inline u32 bcma_read16(struct bcma_device *core, u16 offset)
1703 {
1704 return core->bus->ops->read16(core, offset);
1705 }
1706 -extern inline u32 bcma_read32(struct bcma_device *core, u16 offset)
1707 +static inline u32 bcma_read32(struct bcma_device *core, u16 offset)
1708 {
1709 return core->bus->ops->read32(core, offset);
1710 }
1711 -extern inline
1712 +static inline
1713 void bcma_write8(struct bcma_device *core, u16 offset, u32 value)
1714 {
1715 core->bus->ops->write8(core, offset, value);
1716 }
1717 -extern inline
1718 +static inline
1719 void bcma_write16(struct bcma_device *core, u16 offset, u32 value)
1720 {
1721 core->bus->ops->write16(core, offset, value);
1722 }
1723 -extern inline
1724 +static inline
1725 void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
1726 {
1727 core->bus->ops->write32(core, offset, value);
1728 }
1729 #ifdef CONFIG_BCMA_BLOCKIO
1730 -extern inline void bcma_block_read(struct bcma_device *core, void *buffer,
1731 +static inline void bcma_block_read(struct bcma_device *core, void *buffer,
1732 size_t count, u16 offset, u8 reg_width)
1733 {
1734 core->bus->ops->block_read(core, buffer, count, offset, reg_width);
1735 }
1736 -extern inline void bcma_block_write(struct bcma_device *core, const void *buffer,
1737 - size_t count, u16 offset, u8 reg_width)
1738 +static inline void bcma_block_write(struct bcma_device *core,
1739 + const void *buffer, size_t count,
1740 + u16 offset, u8 reg_width)
1741 {
1742 core->bus->ops->block_write(core, buffer, count, offset, reg_width);
1743 }
1744 #endif
1745 -extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
1746 +static inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
1747 {
1748 return core->bus->ops->aread32(core, offset);
1749 }
1750 -extern inline
1751 +static inline
1752 void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
1753 {
1754 core->bus->ops->awrite32(core, offset, value);
1755 }
1756
1757 -#define bcma_mask32(cc, offset, mask) \
1758 - bcma_write32(cc, offset, bcma_read32(cc, offset) & (mask))
1759 -#define bcma_set32(cc, offset, set) \
1760 - bcma_write32(cc, offset, bcma_read32(cc, offset) | (set))
1761 -#define bcma_maskset32(cc, offset, mask, set) \
1762 - bcma_write32(cc, offset, (bcma_read32(cc, offset) & (mask)) | (set))
1763 +static inline void bcma_mask32(struct bcma_device *cc, u16 offset, u32 mask)
1764 +{
1765 + bcma_write32(cc, offset, bcma_read32(cc, offset) & mask);
1766 +}
1767 +static inline void bcma_set32(struct bcma_device *cc, u16 offset, u32 set)
1768 +{
1769 + bcma_write32(cc, offset, bcma_read32(cc, offset) | set);
1770 +}
1771 +static inline void bcma_maskset32(struct bcma_device *cc,
1772 + u16 offset, u32 mask, u32 set)
1773 +{
1774 + bcma_write32(cc, offset, (bcma_read32(cc, offset) & mask) | set);
1775 +}
1776 +static inline void bcma_mask16(struct bcma_device *cc, u16 offset, u16 mask)
1777 +{
1778 + bcma_write16(cc, offset, bcma_read16(cc, offset) & mask);
1779 +}
1780 +static inline void bcma_set16(struct bcma_device *cc, u16 offset, u16 set)
1781 +{
1782 + bcma_write16(cc, offset, bcma_read16(cc, offset) | set);
1783 +}
1784 +static inline void bcma_maskset16(struct bcma_device *cc,
1785 + u16 offset, u16 mask, u16 set)
1786 +{
1787 + bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
1788 +}
1789
1790 extern bool bcma_core_is_enabled(struct bcma_device *core);
1791 extern void bcma_core_disable(struct bcma_device *core, u32 flags);
1792 --- a/include/linux/bcma/bcma_driver_chipcommon.h
1793 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
1794 @@ -24,6 +24,7 @@
1795 #define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */
1796 #define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */
1797 #define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */
1798 +#define BCMA_CC_FLASHT_NFLASH 0x00000200
1799 #define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */
1800 #define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */
1801 #define BCMA_PLLTYPE_NONE 0x00000000
1802 @@ -178,6 +179,7 @@
1803 #define BCMA_CC_PROG_CFG 0x0120
1804 #define BCMA_CC_PROG_WAITCNT 0x0124
1805 #define BCMA_CC_FLASH_CFG 0x0128
1806 +#define BCMA_CC_FLASH_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */
1807 #define BCMA_CC_FLASH_WAITCNT 0x012C
1808 /* 0x1E0 is defined as shared BCMA_CLKCTLST */
1809 #define BCMA_CC_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */
1810 @@ -201,6 +203,7 @@
1811 #define BCMA_CC_PMU_CTL 0x0600 /* PMU control */
1812 #define BCMA_CC_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */
1813 #define BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16
1814 +#define BCMA_CC_PMU_CTL_PLL_UPD 0x00000400
1815 #define BCMA_CC_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */
1816 #define BCMA_CC_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */
1817 #define BCMA_CC_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */
1818 @@ -239,6 +242,64 @@
1819 #define BCMA_CC_SPROM 0x0800 /* SPROM beginning */
1820 #define BCMA_CC_SPROM_PCIE6 0x0830 /* SPROM beginning on PCIe rev >= 6 */
1821
1822 +/* Divider allocation in 4716/47162/5356 */
1823 +#define BCMA_CC_PMU5_MAINPLL_CPU 1
1824 +#define BCMA_CC_PMU5_MAINPLL_MEM 2
1825 +#define BCMA_CC_PMU5_MAINPLL_SSB 3
1826 +
1827 +/* PLL usage in 4716/47162 */
1828 +#define BCMA_CC_PMU4716_MAINPLL_PLL0 12
1829 +
1830 +/* PLL usage in 5356/5357 */
1831 +#define BCMA_CC_PMU5356_MAINPLL_PLL0 0
1832 +#define BCMA_CC_PMU5357_MAINPLL_PLL0 0
1833 +
1834 +/* 4706 PMU */
1835 +#define BCMA_CC_PMU4706_MAINPLL_PLL0 0
1836 +
1837 +/* ALP clock on pre-PMU chips */
1838 +#define BCMA_CC_PMU_ALP_CLOCK 20000000
1839 +/* HT clock for systems with PMU-enabled chipcommon */
1840 +#define BCMA_CC_PMU_HT_CLOCK 80000000
1841 +
1842 +/* PMU rev 5 (& 6) */
1843 +#define BCMA_CC_PPL_P1P2_OFF 0
1844 +#define BCMA_CC_PPL_P1_MASK 0x0f000000
1845 +#define BCMA_CC_PPL_P1_SHIFT 24
1846 +#define BCMA_CC_PPL_P2_MASK 0x00f00000
1847 +#define BCMA_CC_PPL_P2_SHIFT 20
1848 +#define BCMA_CC_PPL_M14_OFF 1
1849 +#define BCMA_CC_PPL_MDIV_MASK 0x000000ff
1850 +#define BCMA_CC_PPL_MDIV_WIDTH 8
1851 +#define BCMA_CC_PPL_NM5_OFF 2
1852 +#define BCMA_CC_PPL_NDIV_MASK 0xfff00000
1853 +#define BCMA_CC_PPL_NDIV_SHIFT 20
1854 +#define BCMA_CC_PPL_FMAB_OFF 3
1855 +#define BCMA_CC_PPL_MRAT_MASK 0xf0000000
1856 +#define BCMA_CC_PPL_MRAT_SHIFT 28
1857 +#define BCMA_CC_PPL_ABRAT_MASK 0x08000000
1858 +#define BCMA_CC_PPL_ABRAT_SHIFT 27
1859 +#define BCMA_CC_PPL_FDIV_MASK 0x07ffffff
1860 +#define BCMA_CC_PPL_PLLCTL_OFF 4
1861 +#define BCMA_CC_PPL_PCHI_OFF 5
1862 +#define BCMA_CC_PPL_PCHI_MASK 0x0000003f
1863 +
1864 +/* BCM4331 ChipControl numbers. */
1865 +#define BCMA_CHIPCTL_4331_BT_COEXIST BIT(0) /* 0 disable */
1866 +#define BCMA_CHIPCTL_4331_SECI BIT(1) /* 0 SECI is disabled (JATG functional) */
1867 +#define BCMA_CHIPCTL_4331_EXT_LNA BIT(2) /* 0 disable */
1868 +#define BCMA_CHIPCTL_4331_SPROM_GPIO13_15 BIT(3) /* sprom/gpio13-15 mux */
1869 +#define BCMA_CHIPCTL_4331_EXTPA_EN BIT(4) /* 0 ext pa disable, 1 ext pa enabled */
1870 +#define BCMA_CHIPCTL_4331_GPIOCLK_ON_SPROMCS BIT(5) /* set drive out GPIO_CLK on sprom_cs pin */
1871 +#define BCMA_CHIPCTL_4331_PCIE_MDIO_ON_SPROMCS BIT(6) /* use sprom_cs pin as PCIE mdio interface */
1872 +#define BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5 BIT(7) /* aband extpa will be at gpio2/5 and sprom_dout */
1873 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXCLKEN BIT(8) /* override core control on pipe_AuxClkEnable */
1874 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN BIT(9) /* override core control on pipe_AuxPowerDown */
1875 +#define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN BIT(10) /* pcie_auxclkenable */
1876 +#define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN BIT(11) /* pcie_pipe_pllpowerdown */
1877 +#define BCMA_CHIPCTL_4331_BT_SHD0_ON_GPIO4 BIT(16) /* enable bt_shd0 at gpio4 */
1878 +#define BCMA_CHIPCTL_4331_BT_SHD1_ON_GPIO5 BIT(17) /* enable bt_shd1 at gpio5 */
1879 +
1880 /* Data for the PMU, if available.
1881 * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
1882 */
1883 @@ -247,14 +308,37 @@ struct bcma_chipcommon_pmu {
1884 u32 crystalfreq; /* The active crystal frequency (in kHz) */
1885 };
1886
1887 +#ifdef CONFIG_BCMA_DRIVER_MIPS
1888 +struct bcma_pflash {
1889 + u8 buswidth;
1890 + u32 window;
1891 + u32 window_size;
1892 +};
1893 +
1894 +struct bcma_serial_port {
1895 + void *regs;
1896 + unsigned long clockspeed;
1897 + unsigned int irq;
1898 + unsigned int baud_base;
1899 + unsigned int reg_shift;
1900 +};
1901 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
1902 +
1903 struct bcma_drv_cc {
1904 struct bcma_device *core;
1905 u32 status;
1906 u32 capabilities;
1907 u32 capabilities_ext;
1908 + u8 setup_done:1;
1909 /* Fast Powerup Delay constant */
1910 u16 fast_pwrup_delay;
1911 struct bcma_chipcommon_pmu pmu;
1912 +#ifdef CONFIG_BCMA_DRIVER_MIPS
1913 + struct bcma_pflash pflash;
1914 +
1915 + int nr_serial_ports;
1916 + struct bcma_serial_port serial_ports[4];
1917 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
1918 };
1919
1920 /* Register access */
1921 @@ -275,6 +359,8 @@ extern void bcma_core_chipcommon_init(st
1922 extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
1923 extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
1924
1925 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
1926 +
1927 extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
1928 u32 ticks);
1929
1930 @@ -293,4 +379,13 @@ u32 bcma_chipco_gpio_polarity(struct bcm
1931 /* PMU support */
1932 extern void bcma_pmu_init(struct bcma_drv_cc *cc);
1933
1934 +extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset,
1935 + u32 value);
1936 +extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset,
1937 + u32 mask, u32 set);
1938 +extern void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
1939 + u32 offset, u32 mask, u32 set);
1940 +extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc,
1941 + u32 offset, u32 mask, u32 set);
1942 +
1943 #endif /* LINUX_BCMA_DRIVER_CC_H_ */
1944 --- /dev/null
1945 +++ b/include/linux/bcma/bcma_driver_mips.h
1946 @@ -0,0 +1,51 @@
1947 +#ifndef LINUX_BCMA_DRIVER_MIPS_H_
1948 +#define LINUX_BCMA_DRIVER_MIPS_H_
1949 +
1950 +#define BCMA_MIPS_IPSFLAG 0x0F08
1951 +/* which sbflags get routed to mips interrupt 1 */
1952 +#define BCMA_MIPS_IPSFLAG_IRQ1 0x0000003F
1953 +#define BCMA_MIPS_IPSFLAG_IRQ1_SHIFT 0
1954 +/* which sbflags get routed to mips interrupt 2 */
1955 +#define BCMA_MIPS_IPSFLAG_IRQ2 0x00003F00
1956 +#define BCMA_MIPS_IPSFLAG_IRQ2_SHIFT 8
1957 +/* which sbflags get routed to mips interrupt 3 */
1958 +#define BCMA_MIPS_IPSFLAG_IRQ3 0x003F0000
1959 +#define BCMA_MIPS_IPSFLAG_IRQ3_SHIFT 16
1960 +/* which sbflags get routed to mips interrupt 4 */
1961 +#define BCMA_MIPS_IPSFLAG_IRQ4 0x3F000000
1962 +#define BCMA_MIPS_IPSFLAG_IRQ4_SHIFT 24
1963 +
1964 +/* MIPS 74K core registers */
1965 +#define BCMA_MIPS_MIPS74K_CORECTL 0x0000
1966 +#define BCMA_MIPS_MIPS74K_EXCEPTBASE 0x0004
1967 +#define BCMA_MIPS_MIPS74K_BIST 0x000C
1968 +#define BCMA_MIPS_MIPS74K_INTMASK_INT0 0x0014
1969 +#define BCMA_MIPS_MIPS74K_INTMASK(int) \
1970 + ((int) * 4 + BCMA_MIPS_MIPS74K_INTMASK_INT0)
1971 +#define BCMA_MIPS_MIPS74K_NMIMASK 0x002C
1972 +#define BCMA_MIPS_MIPS74K_GPIOSEL 0x0040
1973 +#define BCMA_MIPS_MIPS74K_GPIOOUT 0x0044
1974 +#define BCMA_MIPS_MIPS74K_GPIOEN 0x0048
1975 +#define BCMA_MIPS_MIPS74K_CLKCTLST 0x01E0
1976 +
1977 +#define BCMA_MIPS_OOBSELOUTA30 0x100
1978 +
1979 +struct bcma_device;
1980 +
1981 +struct bcma_drv_mips {
1982 + struct bcma_device *core;
1983 + u8 setup_done:1;
1984 + unsigned int assigned_irqs;
1985 +};
1986 +
1987 +#ifdef CONFIG_BCMA_DRIVER_MIPS
1988 +extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
1989 +#else
1990 +static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { }
1991 +#endif
1992 +
1993 +extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
1994 +
1995 +extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
1996 +
1997 +#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
1998 --- /dev/null
1999 +++ b/include/linux/bcma/bcma_soc.h
2000 @@ -0,0 +1,16 @@
2001 +#ifndef LINUX_BCMA_SOC_H_
2002 +#define LINUX_BCMA_SOC_H_
2003 +
2004 +#include <linux/bcma/bcma.h>
2005 +
2006 +struct bcma_soc {
2007 + struct bcma_bus bus;
2008 + struct bcma_device core_cc;
2009 + struct bcma_device core_mips;
2010 +};
2011 +
2012 +int __init bcma_host_soc_register(struct bcma_soc *soc);
2013 +
2014 +int bcma_bus_register(struct bcma_bus *bus);
2015 +
2016 +#endif /* LINUX_BCMA_SOC_H_ */