kernel: update bcma and ssb to version master-2011-12-16 from wireless-testing
[openwrt.git] / target / linux / generic / patches-3.0 / 025-bcma_backport.patch
1 --- a/drivers/bcma/Kconfig
2 +++ b/drivers/bcma/Kconfig
3 @@ -13,6 +13,11 @@ config BCMA
4 Bus driver for Broadcom specific Advanced Microcontroller Bus
5 Architecture.
6
7 +# Support for Block-I/O. SELECT this from the driver that needs it.
8 +config BCMA_BLOCKIO
9 + bool
10 + depends on BCMA
11 +
12 config BCMA_HOST_PCI_POSSIBLE
13 bool
14 depends on BCMA && PCI = y
15 @@ -22,6 +27,25 @@ config BCMA_HOST_PCI
16 bool "Support for BCMA on PCI-host bus"
17 depends on BCMA_HOST_PCI_POSSIBLE
18
19 +config BCMA_DRIVER_PCI_HOSTMODE
20 + bool "Driver for PCI core working in hostmode"
21 + depends on BCMA && MIPS
22 + help
23 + PCI core hostmode operation (external PCI bus).
24 +
25 +config BCMA_HOST_SOC
26 + bool
27 + depends on BCMA_DRIVER_MIPS
28 +
29 +config BCMA_DRIVER_MIPS
30 + bool "BCMA Broadcom MIPS core driver"
31 + depends on BCMA && MIPS
32 + help
33 + Driver for the Broadcom MIPS core attached to Broadcom specific
34 + Advanced Microcontroller Bus.
35 +
36 + If unsure, say N
37 +
38 config BCMA_DEBUG
39 bool "BCMA debugging"
40 depends on BCMA
41 --- a/drivers/bcma/Makefile
42 +++ b/drivers/bcma/Makefile
43 @@ -1,7 +1,10 @@
44 -bcma-y += main.o scan.o core.o
45 +bcma-y += main.o scan.o core.o sprom.o
46 bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
47 bcma-y += driver_pci.o
48 +bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o
49 +bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o
50 bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
51 +bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o
52 obj-$(CONFIG_BCMA) += bcma.o
53
54 ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG
55 --- a/drivers/bcma/bcma_private.h
56 +++ b/drivers/bcma/bcma_private.h
57 @@ -13,11 +13,33 @@
58 struct bcma_bus;
59
60 /* main.c */
61 -extern int bcma_bus_register(struct bcma_bus *bus);
62 -extern void bcma_bus_unregister(struct bcma_bus *bus);
63 +int bcma_bus_register(struct bcma_bus *bus);
64 +void bcma_bus_unregister(struct bcma_bus *bus);
65 +int __init bcma_bus_early_register(struct bcma_bus *bus,
66 + struct bcma_device *core_cc,
67 + struct bcma_device *core_mips);
68 +#ifdef CONFIG_PM
69 +int bcma_bus_resume(struct bcma_bus *bus);
70 +#endif
71
72 /* scan.c */
73 int bcma_bus_scan(struct bcma_bus *bus);
74 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
75 + struct bcma_device_id *match,
76 + struct bcma_device *core);
77 +void bcma_init_bus(struct bcma_bus *bus);
78 +
79 +/* sprom.c */
80 +int bcma_sprom_get(struct bcma_bus *bus);
81 +
82 +/* driver_chipcommon.c */
83 +#ifdef CONFIG_BCMA_DRIVER_MIPS
84 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
85 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
86 +
87 +/* driver_chipcommon_pmu.c */
88 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc);
89 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
90
91 #ifdef CONFIG_BCMA_HOST_PCI
92 /* host_pci.c */
93 @@ -25,4 +47,8 @@ extern int __init bcma_host_pci_init(voi
94 extern void __exit bcma_host_pci_exit(void);
95 #endif /* CONFIG_BCMA_HOST_PCI */
96
97 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
98 +void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
99 +#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
100 +
101 #endif
102 --- a/drivers/bcma/core.c
103 +++ b/drivers/bcma/core.c
104 @@ -19,7 +19,7 @@ bool bcma_core_is_enabled(struct bcma_de
105 }
106 EXPORT_SYMBOL_GPL(bcma_core_is_enabled);
107
108 -static void bcma_core_disable(struct bcma_device *core, u32 flags)
109 +void bcma_core_disable(struct bcma_device *core, u32 flags)
110 {
111 if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
112 return;
113 @@ -31,6 +31,7 @@ static void bcma_core_disable(struct bcm
114 bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
115 udelay(1);
116 }
117 +EXPORT_SYMBOL_GPL(bcma_core_disable);
118
119 int bcma_core_enable(struct bcma_device *core, u32 flags)
120 {
121 @@ -49,3 +50,77 @@ int bcma_core_enable(struct bcma_device
122 return 0;
123 }
124 EXPORT_SYMBOL_GPL(bcma_core_enable);
125 +
126 +void bcma_core_set_clockmode(struct bcma_device *core,
127 + enum bcma_clkmode clkmode)
128 +{
129 + u16 i;
130 +
131 + WARN_ON(core->id.id != BCMA_CORE_CHIPCOMMON &&
132 + core->id.id != BCMA_CORE_PCIE &&
133 + core->id.id != BCMA_CORE_80211);
134 +
135 + switch (clkmode) {
136 + case BCMA_CLKMODE_FAST:
137 + bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
138 + udelay(64);
139 + for (i = 0; i < 1500; i++) {
140 + if (bcma_read32(core, BCMA_CLKCTLST) &
141 + BCMA_CLKCTLST_HAVEHT) {
142 + i = 0;
143 + break;
144 + }
145 + udelay(10);
146 + }
147 + if (i)
148 + pr_err("HT force timeout\n");
149 + break;
150 + case BCMA_CLKMODE_DYNAMIC:
151 + pr_warn("Dynamic clockmode not supported yet!\n");
152 + break;
153 + }
154 +}
155 +EXPORT_SYMBOL_GPL(bcma_core_set_clockmode);
156 +
157 +void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on)
158 +{
159 + u16 i;
160 +
161 + WARN_ON(req & ~BCMA_CLKCTLST_EXTRESREQ);
162 + WARN_ON(status & ~BCMA_CLKCTLST_EXTRESST);
163 +
164 + if (on) {
165 + bcma_set32(core, BCMA_CLKCTLST, req);
166 + for (i = 0; i < 10000; i++) {
167 + if ((bcma_read32(core, BCMA_CLKCTLST) & status) ==
168 + status) {
169 + i = 0;
170 + break;
171 + }
172 + udelay(10);
173 + }
174 + if (i)
175 + pr_err("PLL enable timeout\n");
176 + } else {
177 + pr_warn("Disabling PLL not supported yet!\n");
178 + }
179 +}
180 +EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
181 +
182 +u32 bcma_core_dma_translation(struct bcma_device *core)
183 +{
184 + switch (core->bus->hosttype) {
185 + case BCMA_HOSTTYPE_SOC:
186 + return 0;
187 + case BCMA_HOSTTYPE_PCI:
188 + if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
189 + return BCMA_DMA_TRANSLATION_DMA64_CMT;
190 + else
191 + return BCMA_DMA_TRANSLATION_DMA32_CMT;
192 + default:
193 + pr_err("DMA translation unknown for host %d\n",
194 + core->bus->hosttype);
195 + }
196 + return BCMA_DMA_TRANSLATION_NONE;
197 +}
198 +EXPORT_SYMBOL(bcma_core_dma_translation);
199 --- a/drivers/bcma/driver_chipcommon.c
200 +++ b/drivers/bcma/driver_chipcommon.c
201 @@ -3,7 +3,7 @@
202 * ChipCommon core driver
203 *
204 * Copyright 2005, Broadcom Corporation
205 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
206 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
207 *
208 * Licensed under the GNU/GPL. See COPYING for details.
209 */
210 @@ -23,6 +23,12 @@ static inline u32 bcma_cc_write32_masked
211
212 void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
213 {
214 + u32 leddc_on = 10;
215 + u32 leddc_off = 90;
216 +
217 + if (cc->setup_done)
218 + return;
219 +
220 if (cc->core->id.rev >= 11)
221 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
222 cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
223 @@ -38,6 +44,19 @@ void bcma_core_chipcommon_init(struct bc
224 bcma_pmu_init(cc);
225 if (cc->capabilities & BCMA_CC_CAP_PCTL)
226 pr_err("Power control not implemented!\n");
227 +
228 + if (cc->core->id.rev >= 16) {
229 + if (cc->core->bus->sprom.leddc_on_time &&
230 + cc->core->bus->sprom.leddc_off_time) {
231 + leddc_on = cc->core->bus->sprom.leddc_on_time;
232 + leddc_off = cc->core->bus->sprom.leddc_off_time;
233 + }
234 + bcma_cc_write32(cc, BCMA_CC_GPIOTIMER,
235 + ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
236 + (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
237 + }
238 +
239 + cc->setup_done = true;
240 }
241
242 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
243 @@ -87,3 +106,51 @@ u32 bcma_chipco_gpio_polarity(struct bcm
244 {
245 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
246 }
247 +
248 +#ifdef CONFIG_BCMA_DRIVER_MIPS
249 +void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
250 +{
251 + unsigned int irq;
252 + u32 baud_base;
253 + u32 i;
254 + unsigned int ccrev = cc->core->id.rev;
255 + struct bcma_serial_port *ports = cc->serial_ports;
256 +
257 + if (ccrev >= 11 && ccrev != 15) {
258 + /* Fixed ALP clock */
259 + baud_base = bcma_pmu_alp_clock(cc);
260 + if (ccrev >= 21) {
261 + /* Turn off UART clock before switching clocksource. */
262 + bcma_cc_write32(cc, BCMA_CC_CORECTL,
263 + bcma_cc_read32(cc, BCMA_CC_CORECTL)
264 + & ~BCMA_CC_CORECTL_UARTCLKEN);
265 + }
266 + /* Set the override bit so we don't divide it */
267 + bcma_cc_write32(cc, BCMA_CC_CORECTL,
268 + bcma_cc_read32(cc, BCMA_CC_CORECTL)
269 + | BCMA_CC_CORECTL_UARTCLK0);
270 + if (ccrev >= 21) {
271 + /* Re-enable the UART clock. */
272 + bcma_cc_write32(cc, BCMA_CC_CORECTL,
273 + bcma_cc_read32(cc, BCMA_CC_CORECTL)
274 + | BCMA_CC_CORECTL_UARTCLKEN);
275 + }
276 + } else {
277 + pr_err("serial not supported on this device ccrev: 0x%x\n",
278 + ccrev);
279 + return;
280 + }
281 +
282 + irq = bcma_core_mips_irq(cc->core);
283 +
284 + /* Determine the registers of the UARTs */
285 + cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
286 + for (i = 0; i < cc->nr_serial_ports; i++) {
287 + ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
288 + (i * 256);
289 + ports[i].irq = irq;
290 + ports[i].baud_base = baud_base;
291 + ports[i].reg_shift = 0;
292 + }
293 +}
294 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
295 --- a/drivers/bcma/driver_chipcommon_pmu.c
296 +++ b/drivers/bcma/driver_chipcommon_pmu.c
297 @@ -2,7 +2,7 @@
298 * Broadcom specific AMBA
299 * ChipCommon Power Management Unit driver
300 *
301 - * Copyright 2009, Michael Buesch <mb@bu3sch.de>
302 + * Copyright 2009, Michael Buesch <m@bues.ch>
303 * Copyright 2007, Broadcom Corporation
304 *
305 * Licensed under the GNU/GPL. See COPYING for details.
306 @@ -11,20 +11,47 @@
307 #include "bcma_private.h"
308 #include <linux/bcma/bcma.h>
309
310 -static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
311 - u32 offset, u32 mask, u32 set)
312 +static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
313 {
314 - u32 value;
315 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
316 + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
317 + return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
318 +}
319
320 - bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
321 +void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
322 +{
323 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
324 + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
325 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
326 +}
327 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_write);
328 +
329 +void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
330 + u32 set)
331 +{
332 + bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
333 + bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
334 + bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set);
335 +}
336 +EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset);
337 +
338 +void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
339 + u32 offset, u32 mask, u32 set)
340 +{
341 bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
342 bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
343 - value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
344 - value &= mask;
345 - value |= set;
346 - bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
347 - bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
348 + bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set);
349 +}
350 +EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset);
351 +
352 +void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
353 + u32 set)
354 +{
355 + bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset);
356 + bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR);
357 + bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set);
358 }
359 +EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
360
361 static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
362 {
363 @@ -53,6 +80,7 @@ static void bcma_pmu_resources_init(stru
364 max_msk = 0xFFFF;
365 break;
366 case 43224:
367 + case 43225:
368 break;
369 default:
370 pr_err("PMU resource config unknown for device 0x%04X\n",
371 @@ -74,6 +102,7 @@ void bcma_pmu_swreg_init(struct bcma_drv
372 case 0x4313:
373 case 0x4331:
374 case 43224:
375 + case 43225:
376 break;
377 default:
378 pr_err("PMU switch/regulators init unknown for device "
379 @@ -81,6 +110,24 @@ void bcma_pmu_swreg_init(struct bcma_drv
380 }
381 }
382
383 +/* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
384 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
385 +{
386 + struct bcma_bus *bus = cc->core->bus;
387 + u32 val;
388 +
389 + val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL);
390 + if (enable) {
391 + val |= BCMA_CHIPCTL_4331_EXTPA_EN;
392 + if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
393 + val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
394 + } else {
395 + val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
396 + val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
397 + }
398 + bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
399 +}
400 +
401 void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
402 {
403 struct bcma_bus *bus = cc->core->bus;
404 @@ -90,17 +137,19 @@ void bcma_pmu_workarounds(struct bcma_dr
405 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
406 break;
407 case 0x4331:
408 - pr_err("Enabling Ext PA lines not implemented\n");
409 + /* BCM4331 workaround is SPROM-related, we put it in sprom.c */
410 break;
411 case 43224:
412 if (bus->chipinfo.rev == 0) {
413 pr_err("Workarounds for 43224 rev 0 not fully "
414 "implemented\n");
415 - bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
416 + bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x00F000F0);
417 } else {
418 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
419 }
420 break;
421 + case 43225:
422 + break;
423 default:
424 pr_err("Workarounds unknown for device 0x%04X\n",
425 bus->chipinfo.id);
426 @@ -132,3 +181,129 @@ void bcma_pmu_init(struct bcma_drv_cc *c
427 bcma_pmu_swreg_init(cc);
428 bcma_pmu_workarounds(cc);
429 }
430 +
431 +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
432 +{
433 + struct bcma_bus *bus = cc->core->bus;
434 +
435 + switch (bus->chipinfo.id) {
436 + case 0x4716:
437 + case 0x4748:
438 + case 47162:
439 + case 0x4313:
440 + case 0x5357:
441 + case 0x4749:
442 + case 53572:
443 + /* always 20Mhz */
444 + return 20000 * 1000;
445 + case 0x5356:
446 + case 0x5300:
447 + /* always 25Mhz */
448 + return 25000 * 1000;
449 + default:
450 + pr_warn("No ALP clock specified for %04X device, "
451 + "pmu rev. %d, using default %d Hz\n",
452 + bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
453 + }
454 + return BCMA_CC_PMU_ALP_CLOCK;
455 +}
456 +
457 +/* Find the output of the "m" pll divider given pll controls that start with
458 + * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
459 + */
460 +static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
461 +{
462 + u32 tmp, div, ndiv, p1, p2, fc;
463 + struct bcma_bus *bus = cc->core->bus;
464 +
465 + BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
466 +
467 + BUG_ON(!m || m > 4);
468 +
469 + if (bus->chipinfo.id == 0x5357 || bus->chipinfo.id == 0x4749) {
470 + /* Detect failure in clock setting */
471 + tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
472 + if (tmp & 0x40000)
473 + return 133 * 1000000;
474 + }
475 +
476 + tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
477 + p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
478 + p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
479 +
480 + tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
481 + div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
482 + BCMA_CC_PPL_MDIV_MASK;
483 +
484 + tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
485 + ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
486 +
487 + /* Do calculation in Mhz */
488 + fc = bcma_pmu_alp_clock(cc) / 1000000;
489 + fc = (p1 * ndiv * fc) / p2;
490 +
491 + /* Return clock in Hertz */
492 + return (fc / div) * 1000000;
493 +}
494 +
495 +/* query bus clock frequency for PMU-enabled chipcommon */
496 +u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
497 +{
498 + struct bcma_bus *bus = cc->core->bus;
499 +
500 + switch (bus->chipinfo.id) {
501 + case 0x4716:
502 + case 0x4748:
503 + case 47162:
504 + return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
505 + BCMA_CC_PMU5_MAINPLL_SSB);
506 + case 0x5356:
507 + return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
508 + BCMA_CC_PMU5_MAINPLL_SSB);
509 + case 0x5357:
510 + case 0x4749:
511 + return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
512 + BCMA_CC_PMU5_MAINPLL_SSB);
513 + case 0x5300:
514 + return bcma_pmu_clock(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
515 + BCMA_CC_PMU5_MAINPLL_SSB);
516 + case 53572:
517 + return 75000000;
518 + default:
519 + pr_warn("No backplane clock specified for %04X device, "
520 + "pmu rev. %d, using default %d Hz\n",
521 + bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
522 + }
523 + return BCMA_CC_PMU_HT_CLOCK;
524 +}
525 +
526 +/* query cpu clock frequency for PMU-enabled chipcommon */
527 +u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
528 +{
529 + struct bcma_bus *bus = cc->core->bus;
530 +
531 + if (bus->chipinfo.id == 53572)
532 + return 300000000;
533 +
534 + if (cc->pmu.rev >= 5) {
535 + u32 pll;
536 + switch (bus->chipinfo.id) {
537 + case 0x5356:
538 + pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
539 + break;
540 + case 0x5357:
541 + case 0x4749:
542 + pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
543 + break;
544 + default:
545 + pll = BCMA_CC_PMU4716_MAINPLL_PLL0;
546 + break;
547 + }
548 +
549 + /* TODO: if (bus->chipinfo.id == 0x5300)
550 + return si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); */
551 + return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
552 + }
553 +
554 + return bcma_pmu_get_clockcontrol(cc);
555 +}
556 --- /dev/null
557 +++ b/drivers/bcma/driver_mips.c
558 @@ -0,0 +1,256 @@
559 +/*
560 + * Broadcom specific AMBA
561 + * Broadcom MIPS32 74K core driver
562 + *
563 + * Copyright 2009, Broadcom Corporation
564 + * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
565 + * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
566 + * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
567 + *
568 + * Licensed under the GNU/GPL. See COPYING for details.
569 + */
570 +
571 +#include "bcma_private.h"
572 +
573 +#include <linux/bcma/bcma.h>
574 +
575 +#include <linux/serial.h>
576 +#include <linux/serial_core.h>
577 +#include <linux/serial_reg.h>
578 +#include <linux/time.h>
579 +
580 +/* The 47162a0 hangs when reading MIPS DMP registers registers */
581 +static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
582 +{
583 + return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
584 + dev->id.id == BCMA_CORE_MIPS_74K;
585 +}
586 +
587 +/* The 5357b0 hangs when reading USB20H DMP registers */
588 +static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
589 +{
590 + return (dev->bus->chipinfo.id == 0x5357 ||
591 + dev->bus->chipinfo.id == 0x4749) &&
592 + dev->bus->chipinfo.pkg == 11 &&
593 + dev->id.id == BCMA_CORE_USB20_HOST;
594 +}
595 +
596 +static inline u32 mips_read32(struct bcma_drv_mips *mcore,
597 + u16 offset)
598 +{
599 + return bcma_read32(mcore->core, offset);
600 +}
601 +
602 +static inline void mips_write32(struct bcma_drv_mips *mcore,
603 + u16 offset,
604 + u32 value)
605 +{
606 + bcma_write32(mcore->core, offset, value);
607 +}
608 +
609 +static const u32 ipsflag_irq_mask[] = {
610 + 0,
611 + BCMA_MIPS_IPSFLAG_IRQ1,
612 + BCMA_MIPS_IPSFLAG_IRQ2,
613 + BCMA_MIPS_IPSFLAG_IRQ3,
614 + BCMA_MIPS_IPSFLAG_IRQ4,
615 +};
616 +
617 +static const u32 ipsflag_irq_shift[] = {
618 + 0,
619 + BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
620 + BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
621 + BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
622 + BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
623 +};
624 +
625 +static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
626 +{
627 + u32 flag;
628 +
629 + if (bcma_core_mips_bcm47162a0_quirk(dev))
630 + return dev->core_index;
631 + if (bcma_core_mips_bcm5357b0_quirk(dev))
632 + return dev->core_index;
633 + flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
634 +
635 + return flag & 0x1F;
636 +}
637 +
638 +/* Get the MIPS IRQ assignment for a specified device.
639 + * If unassigned, 0 is returned.
640 + */
641 +unsigned int bcma_core_mips_irq(struct bcma_device *dev)
642 +{
643 + struct bcma_device *mdev = dev->bus->drv_mips.core;
644 + u32 irqflag;
645 + unsigned int irq;
646 +
647 + irqflag = bcma_core_mips_irqflag(dev);
648 +
649 + for (irq = 1; irq <= 4; irq++)
650 + if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
651 + (1 << irqflag))
652 + return irq;
653 +
654 + return 0;
655 +}
656 +EXPORT_SYMBOL(bcma_core_mips_irq);
657 +
658 +static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
659 +{
660 + unsigned int oldirq = bcma_core_mips_irq(dev);
661 + struct bcma_bus *bus = dev->bus;
662 + struct bcma_device *mdev = bus->drv_mips.core;
663 + u32 irqflag;
664 +
665 + irqflag = bcma_core_mips_irqflag(dev);
666 + BUG_ON(oldirq == 6);
667 +
668 + dev->irq = irq + 2;
669 +
670 + /* clear the old irq */
671 + if (oldirq == 0)
672 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
673 + bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
674 + ~(1 << irqflag));
675 + else
676 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
677 +
678 + /* assign the new one */
679 + if (irq == 0) {
680 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
681 + bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
682 + (1 << irqflag));
683 + } else {
684 + u32 oldirqflag = bcma_read32(mdev,
685 + BCMA_MIPS_MIPS74K_INTMASK(irq));
686 + if (oldirqflag) {
687 + struct bcma_device *core;
688 +
689 + /* backplane irq line is in use, find out who uses
690 + * it and set user to irq 0
691 + */
692 + list_for_each_entry_reverse(core, &bus->cores, list) {
693 + if ((1 << bcma_core_mips_irqflag(core)) ==
694 + oldirqflag) {
695 + bcma_core_mips_set_irq(core, 0);
696 + break;
697 + }
698 + }
699 + }
700 + bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
701 + 1 << irqflag);
702 + }
703 +
704 + pr_info("set_irq: core 0x%04x, irq %d => %d\n",
705 + dev->id.id, oldirq + 2, irq + 2);
706 +}
707 +
708 +static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
709 +{
710 + int i;
711 + static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
712 + printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
713 + for (i = 0; i <= 6; i++)
714 + printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
715 + printk("\n");
716 +}
717 +
718 +static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
719 +{
720 + struct bcma_device *core;
721 +
722 + list_for_each_entry_reverse(core, &bus->cores, list) {
723 + bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
724 + }
725 +}
726 +
727 +u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
728 +{
729 + struct bcma_bus *bus = mcore->core->bus;
730 +
731 + if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
732 + return bcma_pmu_get_clockcpu(&bus->drv_cc);
733 +
734 + pr_err("No PMU available, need this to get the cpu clock\n");
735 + return 0;
736 +}
737 +EXPORT_SYMBOL(bcma_cpu_clock);
738 +
739 +static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
740 +{
741 + struct bcma_bus *bus = mcore->core->bus;
742 +
743 + switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
744 + case BCMA_CC_FLASHT_STSER:
745 + case BCMA_CC_FLASHT_ATSER:
746 + pr_err("Serial flash not supported.\n");
747 + break;
748 + case BCMA_CC_FLASHT_PARA:
749 + pr_info("found parallel flash.\n");
750 + bus->drv_cc.pflash.window = 0x1c000000;
751 + bus->drv_cc.pflash.window_size = 0x02000000;
752 +
753 + if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
754 + BCMA_CC_FLASH_CFG_DS) == 0)
755 + bus->drv_cc.pflash.buswidth = 1;
756 + else
757 + bus->drv_cc.pflash.buswidth = 2;
758 + break;
759 + default:
760 + pr_err("flash not supported.\n");
761 + }
762 +}
763 +
764 +void bcma_core_mips_init(struct bcma_drv_mips *mcore)
765 +{
766 + struct bcma_bus *bus;
767 + struct bcma_device *core;
768 + bus = mcore->core->bus;
769 +
770 + pr_info("Initializing MIPS core...\n");
771 +
772 + if (!mcore->setup_done)
773 + mcore->assigned_irqs = 1;
774 +
775 + /* Assign IRQs to all cores on the bus */
776 + list_for_each_entry_reverse(core, &bus->cores, list) {
777 + int mips_irq;
778 + if (core->irq)
779 + continue;
780 +
781 + mips_irq = bcma_core_mips_irq(core);
782 + if (mips_irq > 4)
783 + core->irq = 0;
784 + else
785 + core->irq = mips_irq + 2;
786 + if (core->irq > 5)
787 + continue;
788 + switch (core->id.id) {
789 + case BCMA_CORE_PCI:
790 + case BCMA_CORE_PCIE:
791 + case BCMA_CORE_ETHERNET:
792 + case BCMA_CORE_ETHERNET_GBIT:
793 + case BCMA_CORE_MAC_GBIT:
794 + case BCMA_CORE_80211:
795 + case BCMA_CORE_USB20_HOST:
796 + /* These devices get their own IRQ line if available,
797 + * the rest goes on IRQ0
798 + */
799 + if (mcore->assigned_irqs <= 4)
800 + bcma_core_mips_set_irq(core,
801 + mcore->assigned_irqs++);
802 + break;
803 + }
804 + }
805 + pr_info("IRQ reconfiguration done\n");
806 + bcma_core_mips_dump_irq(bus);
807 +
808 + if (mcore->setup_done)
809 + return;
810 +
811 + bcma_chipco_serial_init(&bus->drv_cc);
812 + bcma_core_mips_flash_detect(mcore);
813 + mcore->setup_done = true;
814 +}
815 --- a/drivers/bcma/driver_pci.c
816 +++ b/drivers/bcma/driver_pci.c
817 @@ -3,7 +3,7 @@
818 * PCI Core
819 *
820 * Copyright 2005, Broadcom Corporation
821 - * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
822 + * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
823 *
824 * Licensed under the GNU/GPL. See COPYING for details.
825 */
826 @@ -157,7 +157,81 @@ static void bcma_pcicore_serdes_workarou
827 * Init.
828 **************************************************/
829
830 -void bcma_core_pci_init(struct bcma_drv_pci *pc)
831 +static void bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
832 {
833 bcma_pcicore_serdes_workaround(pc);
834 }
835 +
836 +static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
837 +{
838 + struct bcma_bus *bus = pc->core->bus;
839 + u16 chipid_top;
840 +
841 + chipid_top = (bus->chipinfo.id & 0xFF00);
842 + if (chipid_top != 0x4700 &&
843 + chipid_top != 0x5300)
844 + return false;
845 +
846 +#ifdef CONFIG_SSB_DRIVER_PCICORE
847 + if (bus->sprom.boardflags_lo & SSB_BFL_NOPCI)
848 + return false;
849 +#endif /* CONFIG_SSB_DRIVER_PCICORE */
850 +
851 +#if 0
852 + /* TODO: on BCMA we use address from EROM instead of magic formula */
853 + u32 tmp;
854 + return !mips_busprobe32(tmp, (bus->mmio +
855 + (pc->core->core_index * BCMA_CORE_SIZE)));
856 +#endif
857 +
858 + return true;
859 +}
860 +
861 +void bcma_core_pci_init(struct bcma_drv_pci *pc)
862 +{
863 + if (pc->setup_done)
864 + return;
865 +
866 + if (bcma_core_pci_is_in_hostmode(pc)) {
867 +#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
868 + bcma_core_pci_hostmode_init(pc);
869 +#else
870 + pr_err("Driver compiled without support for hostmode PCI\n");
871 +#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
872 + } else {
873 + bcma_core_pci_clientmode_init(pc);
874 + }
875 +
876 + pc->setup_done = true;
877 +}
878 +
879 +int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
880 + bool enable)
881 +{
882 + struct pci_dev *pdev = pc->core->bus->host_pci;
883 + u32 coremask, tmp;
884 + int err = 0;
885 +
886 + if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
887 + /* This bcma device is not on a PCI host-bus. So the IRQs are
888 + * not routed through the PCI core.
889 + * So we must not enable routing through the PCI core. */
890 + goto out;
891 + }
892 +
893 + err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
894 + if (err)
895 + goto out;
896 +
897 + coremask = BIT(core->core_index) << 8;
898 + if (enable)
899 + tmp |= coremask;
900 + else
901 + tmp &= ~coremask;
902 +
903 + err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp);
904 +
905 +out:
906 + return err;
907 +}
908 +EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
909 --- /dev/null
910 +++ b/drivers/bcma/driver_pci_host.c
911 @@ -0,0 +1,14 @@
912 +/*
913 + * Broadcom specific AMBA
914 + * PCI Core in hostmode
915 + *
916 + * Licensed under the GNU/GPL. See COPYING for details.
917 + */
918 +
919 +#include "bcma_private.h"
920 +#include <linux/bcma/bcma.h>
921 +
922 +void bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
923 +{
924 + pr_err("No support for PCI core in hostmode yet\n");
925 +}
926 --- a/drivers/bcma/host_pci.c
927 +++ b/drivers/bcma/host_pci.c
928 @@ -9,6 +9,7 @@
929 #include <linux/slab.h>
930 #include <linux/bcma/bcma.h>
931 #include <linux/pci.h>
932 +#include <linux/module.h>
933
934 static void bcma_host_pci_switch_core(struct bcma_device *core)
935 {
936 @@ -20,50 +21,108 @@ static void bcma_host_pci_switch_core(st
937 pr_debug("Switched to core: 0x%X\n", core->id.id);
938 }
939
940 -static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
941 -{
942 +/* Provides access to the requested core. Returns base offset that has to be
943 + * used. It makes use of fixed windows when possible. */
944 +static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core)
945 +{
946 + switch (core->id.id) {
947 + case BCMA_CORE_CHIPCOMMON:
948 + return 3 * BCMA_CORE_SIZE;
949 + case BCMA_CORE_PCIE:
950 + return 2 * BCMA_CORE_SIZE;
951 + }
952 +
953 if (core->bus->mapped_core != core)
954 bcma_host_pci_switch_core(core);
955 + return 0;
956 +}
957 +
958 +static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
959 +{
960 + offset += bcma_host_pci_provide_access_to_core(core);
961 return ioread8(core->bus->mmio + offset);
962 }
963
964 static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
965 {
966 - if (core->bus->mapped_core != core)
967 - bcma_host_pci_switch_core(core);
968 + offset += bcma_host_pci_provide_access_to_core(core);
969 return ioread16(core->bus->mmio + offset);
970 }
971
972 static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
973 {
974 - if (core->bus->mapped_core != core)
975 - bcma_host_pci_switch_core(core);
976 + offset += bcma_host_pci_provide_access_to_core(core);
977 return ioread32(core->bus->mmio + offset);
978 }
979
980 static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
981 u8 value)
982 {
983 - if (core->bus->mapped_core != core)
984 - bcma_host_pci_switch_core(core);
985 + offset += bcma_host_pci_provide_access_to_core(core);
986 iowrite8(value, core->bus->mmio + offset);
987 }
988
989 static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
990 u16 value)
991 {
992 - if (core->bus->mapped_core != core)
993 - bcma_host_pci_switch_core(core);
994 + offset += bcma_host_pci_provide_access_to_core(core);
995 iowrite16(value, core->bus->mmio + offset);
996 }
997
998 static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
999 u32 value)
1000 {
1001 + offset += bcma_host_pci_provide_access_to_core(core);
1002 + iowrite32(value, core->bus->mmio + offset);
1003 +}
1004 +
1005 +#ifdef CONFIG_BCMA_BLOCKIO
1006 +void bcma_host_pci_block_read(struct bcma_device *core, void *buffer,
1007 + size_t count, u16 offset, u8 reg_width)
1008 +{
1009 + void __iomem *addr = core->bus->mmio + offset;
1010 if (core->bus->mapped_core != core)
1011 bcma_host_pci_switch_core(core);
1012 - iowrite32(value, core->bus->mmio + offset);
1013 + switch (reg_width) {
1014 + case sizeof(u8):
1015 + ioread8_rep(addr, buffer, count);
1016 + break;
1017 + case sizeof(u16):
1018 + WARN_ON(count & 1);
1019 + ioread16_rep(addr, buffer, count >> 1);
1020 + break;
1021 + case sizeof(u32):
1022 + WARN_ON(count & 3);
1023 + ioread32_rep(addr, buffer, count >> 2);
1024 + break;
1025 + default:
1026 + WARN_ON(1);
1027 + }
1028 +}
1029 +
1030 +void bcma_host_pci_block_write(struct bcma_device *core, const void *buffer,
1031 + size_t count, u16 offset, u8 reg_width)
1032 +{
1033 + void __iomem *addr = core->bus->mmio + offset;
1034 + if (core->bus->mapped_core != core)
1035 + bcma_host_pci_switch_core(core);
1036 + switch (reg_width) {
1037 + case sizeof(u8):
1038 + iowrite8_rep(addr, buffer, count);
1039 + break;
1040 + case sizeof(u16):
1041 + WARN_ON(count & 1);
1042 + iowrite16_rep(addr, buffer, count >> 1);
1043 + break;
1044 + case sizeof(u32):
1045 + WARN_ON(count & 3);
1046 + iowrite32_rep(addr, buffer, count >> 2);
1047 + break;
1048 + default:
1049 + WARN_ON(1);
1050 + }
1051 }
1052 +#endif
1053
1054 static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset)
1055 {
1056 @@ -87,6 +146,10 @@ const struct bcma_host_ops bcma_host_pci
1057 .write8 = bcma_host_pci_write8,
1058 .write16 = bcma_host_pci_write16,
1059 .write32 = bcma_host_pci_write32,
1060 +#ifdef CONFIG_BCMA_BLOCKIO
1061 + .block_read = bcma_host_pci_block_read,
1062 + .block_write = bcma_host_pci_block_write,
1063 +#endif
1064 .aread32 = bcma_host_pci_aread32,
1065 .awrite32 = bcma_host_pci_awrite32,
1066 };
1067 @@ -171,10 +234,46 @@ static void bcma_host_pci_remove(struct
1068 pci_set_drvdata(dev, NULL);
1069 }
1070
1071 +#ifdef CONFIG_PM
1072 +static int bcma_host_pci_suspend(struct pci_dev *dev, pm_message_t state)
1073 +{
1074 + /* Host specific */
1075 + pci_save_state(dev);
1076 + pci_disable_device(dev);
1077 + pci_set_power_state(dev, pci_choose_state(dev, state));
1078 +
1079 + return 0;
1080 +}
1081 +
1082 +static int bcma_host_pci_resume(struct pci_dev *dev)
1083 +{
1084 + struct bcma_bus *bus = pci_get_drvdata(dev);
1085 + int err;
1086 +
1087 + /* Host specific */
1088 + pci_set_power_state(dev, 0);
1089 + err = pci_enable_device(dev);
1090 + if (err)
1091 + return err;
1092 + pci_restore_state(dev);
1093 +
1094 + /* Bus specific */
1095 + err = bcma_bus_resume(bus);
1096 + if (err)
1097 + return err;
1098 +
1099 + return 0;
1100 +}
1101 +#else /* CONFIG_PM */
1102 +# define bcma_host_pci_suspend NULL
1103 +# define bcma_host_pci_resume NULL
1104 +#endif /* CONFIG_PM */
1105 +
1106 static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
1107 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
1108 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
1109 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
1110 + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
1111 { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
1112 { 0, },
1113 };
1114 @@ -185,6 +284,8 @@ static struct pci_driver bcma_pci_bridge
1115 .id_table = bcma_pci_bridge_tbl,
1116 .probe = bcma_host_pci_probe,
1117 .remove = bcma_host_pci_remove,
1118 + .suspend = bcma_host_pci_suspend,
1119 + .resume = bcma_host_pci_resume,
1120 };
1121
1122 int __init bcma_host_pci_init(void)
1123 --- /dev/null
1124 +++ b/drivers/bcma/host_soc.c
1125 @@ -0,0 +1,183 @@
1126 +/*
1127 + * Broadcom specific AMBA
1128 + * System on Chip (SoC) Host
1129 + *
1130 + * Licensed under the GNU/GPL. See COPYING for details.
1131 + */
1132 +
1133 +#include "bcma_private.h"
1134 +#include "scan.h"
1135 +#include <linux/bcma/bcma.h>
1136 +#include <linux/bcma/bcma_soc.h>
1137 +
1138 +static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
1139 +{
1140 + return readb(core->io_addr + offset);
1141 +}
1142 +
1143 +static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
1144 +{
1145 + return readw(core->io_addr + offset);
1146 +}
1147 +
1148 +static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
1149 +{
1150 + return readl(core->io_addr + offset);
1151 +}
1152 +
1153 +static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
1154 + u8 value)
1155 +{
1156 + writeb(value, core->io_addr + offset);
1157 +}
1158 +
1159 +static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
1160 + u16 value)
1161 +{
1162 + writew(value, core->io_addr + offset);
1163 +}
1164 +
1165 +static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
1166 + u32 value)
1167 +{
1168 + writel(value, core->io_addr + offset);
1169 +}
1170 +
1171 +#ifdef CONFIG_BCMA_BLOCKIO
1172 +static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
1173 + size_t count, u16 offset, u8 reg_width)
1174 +{
1175 + void __iomem *addr = core->io_addr + offset;
1176 +
1177 + switch (reg_width) {
1178 + case sizeof(u8): {
1179 + u8 *buf = buffer;
1180 +
1181 + while (count) {
1182 + *buf = __raw_readb(addr);
1183 + buf++;
1184 + count--;
1185 + }
1186 + break;
1187 + }
1188 + case sizeof(u16): {
1189 + __le16 *buf = buffer;
1190 +
1191 + WARN_ON(count & 1);
1192 + while (count) {
1193 + *buf = (__force __le16)__raw_readw(addr);
1194 + buf++;
1195 + count -= 2;
1196 + }
1197 + break;
1198 + }
1199 + case sizeof(u32): {
1200 + __le32 *buf = buffer;
1201 +
1202 + WARN_ON(count & 3);
1203 + while (count) {
1204 + *buf = (__force __le32)__raw_readl(addr);
1205 + buf++;
1206 + count -= 4;
1207 + }
1208 + break;
1209 + }
1210 + default:
1211 + WARN_ON(1);
1212 + }
1213 +}
1214 +
1215 +static void bcma_host_soc_block_write(struct bcma_device *core,
1216 + const void *buffer,
1217 + size_t count, u16 offset, u8 reg_width)
1218 +{
1219 + void __iomem *addr = core->io_addr + offset;
1220 +
1221 + switch (reg_width) {
1222 + case sizeof(u8): {
1223 + const u8 *buf = buffer;
1224 +
1225 + while (count) {
1226 + __raw_writeb(*buf, addr);
1227 + buf++;
1228 + count--;
1229 + }
1230 + break;
1231 + }
1232 + case sizeof(u16): {
1233 + const __le16 *buf = buffer;
1234 +
1235 + WARN_ON(count & 1);
1236 + while (count) {
1237 + __raw_writew((__force u16)(*buf), addr);
1238 + buf++;
1239 + count -= 2;
1240 + }
1241 + break;
1242 + }
1243 + case sizeof(u32): {
1244 + const __le32 *buf = buffer;
1245 +
1246 + WARN_ON(count & 3);
1247 + while (count) {
1248 + __raw_writel((__force u32)(*buf), addr);
1249 + buf++;
1250 + count -= 4;
1251 + }
1252 + break;
1253 + }
1254 + default:
1255 + WARN_ON(1);
1256 + }
1257 +}
1258 +#endif /* CONFIG_BCMA_BLOCKIO */
1259 +
1260 +static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
1261 +{
1262 + return readl(core->io_wrap + offset);
1263 +}
1264 +
1265 +static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
1266 + u32 value)
1267 +{
1268 + writel(value, core->io_wrap + offset);
1269 +}
1270 +
1271 +const struct bcma_host_ops bcma_host_soc_ops = {
1272 + .read8 = bcma_host_soc_read8,
1273 + .read16 = bcma_host_soc_read16,
1274 + .read32 = bcma_host_soc_read32,
1275 + .write8 = bcma_host_soc_write8,
1276 + .write16 = bcma_host_soc_write16,
1277 + .write32 = bcma_host_soc_write32,
1278 +#ifdef CONFIG_BCMA_BLOCKIO
1279 + .block_read = bcma_host_soc_block_read,
1280 + .block_write = bcma_host_soc_block_write,
1281 +#endif
1282 + .aread32 = bcma_host_soc_aread32,
1283 + .awrite32 = bcma_host_soc_awrite32,
1284 +};
1285 +
1286 +int __init bcma_host_soc_register(struct bcma_soc *soc)
1287 +{
1288 + struct bcma_bus *bus = &soc->bus;
1289 + int err;
1290 +
1291 + /* iomap only first core. We have to read some register on this core
1292 + * to scan the bus.
1293 + */
1294 + bus->mmio = ioremap_nocache(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
1295 + if (!bus->mmio)
1296 + return -ENOMEM;
1297 +
1298 + /* Host specific */
1299 + bus->hosttype = BCMA_HOSTTYPE_SOC;
1300 + bus->ops = &bcma_host_soc_ops;
1301 +
1302 + /* Register */
1303 + err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
1304 + if (err)
1305 + iounmap(bus->mmio);
1306 +
1307 + return err;
1308 +}
1309 --- a/drivers/bcma/main.c
1310 +++ b/drivers/bcma/main.c
1311 @@ -6,7 +6,9 @@
1312 */
1313
1314 #include "bcma_private.h"
1315 +#include <linux/module.h>
1316 #include <linux/bcma/bcma.h>
1317 +#include <linux/slab.h>
1318
1319 MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
1320 MODULE_LICENSE("GPL");
1321 @@ -14,6 +16,7 @@ MODULE_LICENSE("GPL");
1322 static int bcma_bus_match(struct device *dev, struct device_driver *drv);
1323 static int bcma_device_probe(struct device *dev);
1324 static int bcma_device_remove(struct device *dev);
1325 +static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env);
1326
1327 static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
1328 {
1329 @@ -48,6 +51,7 @@ static struct bus_type bcma_bus_type = {
1330 .match = bcma_bus_match,
1331 .probe = bcma_device_probe,
1332 .remove = bcma_device_remove,
1333 + .uevent = bcma_device_uevent,
1334 .dev_attrs = bcma_device_attrs,
1335 };
1336
1337 @@ -65,6 +69,10 @@ static struct bcma_device *bcma_find_cor
1338 static void bcma_release_core_dev(struct device *dev)
1339 {
1340 struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1341 + if (core->io_addr)
1342 + iounmap(core->io_addr);
1343 + if (core->io_wrap)
1344 + iounmap(core->io_wrap);
1345 kfree(core);
1346 }
1347
1348 @@ -79,6 +87,7 @@ static int bcma_register_cores(struct bc
1349 case BCMA_CORE_CHIPCOMMON:
1350 case BCMA_CORE_PCI:
1351 case BCMA_CORE_PCIE:
1352 + case BCMA_CORE_MIPS_74K:
1353 continue;
1354 }
1355
1356 @@ -89,8 +98,13 @@ static int bcma_register_cores(struct bc
1357 switch (bus->hosttype) {
1358 case BCMA_HOSTTYPE_PCI:
1359 core->dev.parent = &bus->host_pci->dev;
1360 + core->dma_dev = &bus->host_pci->dev;
1361 + core->irq = bus->host_pci->irq;
1362 + break;
1363 + case BCMA_HOSTTYPE_SOC:
1364 + core->dev.dma_mask = &core->dev.coherent_dma_mask;
1365 + core->dma_dev = &core->dev;
1366 break;
1367 - case BCMA_HOSTTYPE_NONE:
1368 case BCMA_HOSTTYPE_SDIO:
1369 break;
1370 }
1371 @@ -137,6 +151,13 @@ int bcma_bus_register(struct bcma_bus *b
1372 bcma_core_chipcommon_init(&bus->drv_cc);
1373 }
1374
1375 + /* Init MIPS core */
1376 + core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
1377 + if (core) {
1378 + bus->drv_mips.core = core;
1379 + bcma_core_mips_init(&bus->drv_mips);
1380 + }
1381 +
1382 /* Init PCIE core */
1383 core = bcma_find_core(bus, BCMA_CORE_PCIE);
1384 if (core) {
1385 @@ -144,6 +165,15 @@ int bcma_bus_register(struct bcma_bus *b
1386 bcma_core_pci_init(&bus->drv_pci);
1387 }
1388
1389 + /* Try to get SPROM */
1390 + err = bcma_sprom_get(bus);
1391 + if (err == -ENOENT) {
1392 + pr_err("No SPROM available\n");
1393 + } else if (err) {
1394 + pr_err("Failed to get SPROM: %d\n", err);
1395 + return -ENOENT;
1396 + }
1397 +
1398 /* Register found cores */
1399 bcma_register_cores(bus);
1400
1401 @@ -151,13 +181,80 @@ int bcma_bus_register(struct bcma_bus *b
1402
1403 return 0;
1404 }
1405 -EXPORT_SYMBOL_GPL(bcma_bus_register);
1406
1407 void bcma_bus_unregister(struct bcma_bus *bus)
1408 {
1409 bcma_unregister_cores(bus);
1410 }
1411 -EXPORT_SYMBOL_GPL(bcma_bus_unregister);
1412 +
1413 +int __init bcma_bus_early_register(struct bcma_bus *bus,
1414 + struct bcma_device *core_cc,
1415 + struct bcma_device *core_mips)
1416 +{
1417 + int err;
1418 + struct bcma_device *core;
1419 + struct bcma_device_id match;
1420 +
1421 + bcma_init_bus(bus);
1422 +
1423 + match.manuf = BCMA_MANUF_BCM;
1424 + match.id = BCMA_CORE_CHIPCOMMON;
1425 + match.class = BCMA_CL_SIM;
1426 + match.rev = BCMA_ANY_REV;
1427 +
1428 + /* Scan for chip common core */
1429 + err = bcma_bus_scan_early(bus, &match, core_cc);
1430 + if (err) {
1431 + pr_err("Failed to scan for common core: %d\n", err);
1432 + return -1;
1433 + }
1434 +
1435 + match.manuf = BCMA_MANUF_MIPS;
1436 + match.id = BCMA_CORE_MIPS_74K;
1437 + match.class = BCMA_CL_SIM;
1438 + match.rev = BCMA_ANY_REV;
1439 +
1440 + /* Scan for mips core */
1441 + err = bcma_bus_scan_early(bus, &match, core_mips);
1442 + if (err) {
1443 + pr_err("Failed to scan for mips core: %d\n", err);
1444 + return -1;
1445 + }
1446 +
1447 + /* Init CC core */
1448 + core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
1449 + if (core) {
1450 + bus->drv_cc.core = core;
1451 + bcma_core_chipcommon_init(&bus->drv_cc);
1452 + }
1453 +
1454 + /* Init MIPS core */
1455 + core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
1456 + if (core) {
1457 + bus->drv_mips.core = core;
1458 + bcma_core_mips_init(&bus->drv_mips);
1459 + }
1460 +
1461 + pr_info("Early bus registered\n");
1462 +
1463 + return 0;
1464 +}
1465 +
1466 +#ifdef CONFIG_PM
1467 +int bcma_bus_resume(struct bcma_bus *bus)
1468 +{
1469 + struct bcma_device *core;
1470 +
1471 + /* Init CC core */
1472 + core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
1473 + if (core) {
1474 + bus->drv_cc.setup_done = false;
1475 + bcma_core_chipcommon_init(&bus->drv_cc);
1476 + }
1477 +
1478 + return 0;
1479 +}
1480 +#endif
1481
1482 int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
1483 {
1484 @@ -217,6 +314,16 @@ static int bcma_device_remove(struct dev
1485 return 0;
1486 }
1487
1488 +static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env)
1489 +{
1490 + struct bcma_device *core = container_of(dev, struct bcma_device, dev);
1491 +
1492 + return add_uevent_var(env,
1493 + "MODALIAS=bcma:m%04Xid%04Xrev%02Xcl%02X",
1494 + core->id.manuf, core->id.id,
1495 + core->id.rev, core->id.class);
1496 +}
1497 +
1498 static int __init bcma_modinit(void)
1499 {
1500 int err;
1501 --- a/drivers/bcma/scan.c
1502 +++ b/drivers/bcma/scan.c
1503 @@ -200,18 +200,162 @@ static s32 bcma_erom_get_addr_desc(struc
1504 return addrl;
1505 }
1506
1507 -int bcma_bus_scan(struct bcma_bus *bus)
1508 +static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
1509 + u16 index)
1510 {
1511 - u32 erombase;
1512 - u32 __iomem *eromptr, *eromend;
1513 + struct bcma_device *core;
1514
1515 + list_for_each_entry(core, &bus->cores, list) {
1516 + if (core->core_index == index)
1517 + return core;
1518 + }
1519 + return NULL;
1520 +}
1521 +
1522 +static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
1523 + struct bcma_device_id *match, int core_num,
1524 + struct bcma_device *core)
1525 +{
1526 + s32 tmp;
1527 + u8 i, j;
1528 s32 cia, cib;
1529 u8 ports[2], wrappers[2];
1530
1531 + /* get CIs */
1532 + cia = bcma_erom_get_ci(bus, eromptr);
1533 + if (cia < 0) {
1534 + bcma_erom_push_ent(eromptr);
1535 + if (bcma_erom_is_end(bus, eromptr))
1536 + return -ESPIPE;
1537 + return -EILSEQ;
1538 + }
1539 + cib = bcma_erom_get_ci(bus, eromptr);
1540 + if (cib < 0)
1541 + return -EILSEQ;
1542 +
1543 + /* parse CIs */
1544 + core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
1545 + core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
1546 + core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
1547 + ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
1548 + ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
1549 + wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
1550 + wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
1551 + core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
1552 +
1553 + if (((core->id.manuf == BCMA_MANUF_ARM) &&
1554 + (core->id.id == 0xFFF)) ||
1555 + (ports[1] == 0)) {
1556 + bcma_erom_skip_component(bus, eromptr);
1557 + return -ENXIO;
1558 + }
1559 +
1560 + /* check if component is a core at all */
1561 + if (wrappers[0] + wrappers[1] == 0) {
1562 + /* we could save addrl of the router
1563 + if (cid == BCMA_CORE_OOB_ROUTER)
1564 + */
1565 + bcma_erom_skip_component(bus, eromptr);
1566 + return -ENXIO;
1567 + }
1568 +
1569 + if (bcma_erom_is_bridge(bus, eromptr)) {
1570 + bcma_erom_skip_component(bus, eromptr);
1571 + return -ENXIO;
1572 + }
1573 +
1574 + if (bcma_find_core_by_index(bus, core_num)) {
1575 + bcma_erom_skip_component(bus, eromptr);
1576 + return -ENODEV;
1577 + }
1578 +
1579 + if (match && ((match->manuf != BCMA_ANY_MANUF &&
1580 + match->manuf != core->id.manuf) ||
1581 + (match->id != BCMA_ANY_ID && match->id != core->id.id) ||
1582 + (match->rev != BCMA_ANY_REV && match->rev != core->id.rev) ||
1583 + (match->class != BCMA_ANY_CLASS && match->class != core->id.class)
1584 + )) {
1585 + bcma_erom_skip_component(bus, eromptr);
1586 + return -ENODEV;
1587 + }
1588 +
1589 + /* get & parse master ports */
1590 + for (i = 0; i < ports[0]; i++) {
1591 + s32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
1592 + if (mst_port_d < 0)
1593 + return -EILSEQ;
1594 + }
1595 +
1596 + /* get & parse slave ports */
1597 + for (i = 0; i < ports[1]; i++) {
1598 + for (j = 0; ; j++) {
1599 + tmp = bcma_erom_get_addr_desc(bus, eromptr,
1600 + SCAN_ADDR_TYPE_SLAVE, i);
1601 + if (tmp < 0) {
1602 + /* no more entries for port _i_ */
1603 + /* pr_debug("erom: slave port %d "
1604 + * "has %d descriptors\n", i, j); */
1605 + break;
1606 + } else {
1607 + if (i == 0 && j == 0)
1608 + core->addr = tmp;
1609 + }
1610 + }
1611 + }
1612 +
1613 + /* get & parse master wrappers */
1614 + for (i = 0; i < wrappers[0]; i++) {
1615 + for (j = 0; ; j++) {
1616 + tmp = bcma_erom_get_addr_desc(bus, eromptr,
1617 + SCAN_ADDR_TYPE_MWRAP, i);
1618 + if (tmp < 0) {
1619 + /* no more entries for port _i_ */
1620 + /* pr_debug("erom: master wrapper %d "
1621 + * "has %d descriptors\n", i, j); */
1622 + break;
1623 + } else {
1624 + if (i == 0 && j == 0)
1625 + core->wrap = tmp;
1626 + }
1627 + }
1628 + }
1629 +
1630 + /* get & parse slave wrappers */
1631 + for (i = 0; i < wrappers[1]; i++) {
1632 + u8 hack = (ports[1] == 1) ? 0 : 1;
1633 + for (j = 0; ; j++) {
1634 + tmp = bcma_erom_get_addr_desc(bus, eromptr,
1635 + SCAN_ADDR_TYPE_SWRAP, i + hack);
1636 + if (tmp < 0) {
1637 + /* no more entries for port _i_ */
1638 + /* pr_debug("erom: master wrapper %d "
1639 + * has %d descriptors\n", i, j); */
1640 + break;
1641 + } else {
1642 + if (wrappers[0] == 0 && !i && !j)
1643 + core->wrap = tmp;
1644 + }
1645 + }
1646 + }
1647 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1648 + core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE);
1649 + if (!core->io_addr)
1650 + return -ENOMEM;
1651 + core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE);
1652 + if (!core->io_wrap) {
1653 + iounmap(core->io_addr);
1654 + return -ENOMEM;
1655 + }
1656 + }
1657 + return 0;
1658 +}
1659 +
1660 +void bcma_init_bus(struct bcma_bus *bus)
1661 +{
1662 s32 tmp;
1663 - u8 i, j;
1664
1665 - int err;
1666 + if (bus->init_done)
1667 + return;
1668
1669 INIT_LIST_HEAD(&bus->cores);
1670 bus->nr_cores = 0;
1671 @@ -222,9 +366,27 @@ int bcma_bus_scan(struct bcma_bus *bus)
1672 bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
1673 bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
1674 bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
1675 + bus->init_done = true;
1676 +}
1677 +
1678 +int bcma_bus_scan(struct bcma_bus *bus)
1679 +{
1680 + u32 erombase;
1681 + u32 __iomem *eromptr, *eromend;
1682 +
1683 + int err, core_num = 0;
1684 +
1685 + bcma_init_bus(bus);
1686
1687 erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
1688 - eromptr = bus->mmio;
1689 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1690 + eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
1691 + if (!eromptr)
1692 + return -ENOMEM;
1693 + } else {
1694 + eromptr = bus->mmio;
1695 + }
1696 +
1697 eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
1698
1699 bcma_scan_switch_core(bus, erombase);
1700 @@ -236,125 +398,89 @@ int bcma_bus_scan(struct bcma_bus *bus)
1701 INIT_LIST_HEAD(&core->list);
1702 core->bus = bus;
1703
1704 - /* get CIs */
1705 - cia = bcma_erom_get_ci(bus, &eromptr);
1706 - if (cia < 0) {
1707 - bcma_erom_push_ent(&eromptr);
1708 - if (bcma_erom_is_end(bus, &eromptr))
1709 - break;
1710 - err= -EILSEQ;
1711 - goto out;
1712 - }
1713 - cib = bcma_erom_get_ci(bus, &eromptr);
1714 - if (cib < 0) {
1715 - err= -EILSEQ;
1716 - goto out;
1717 - }
1718 -
1719 - /* parse CIs */
1720 - core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
1721 - core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
1722 - core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
1723 - ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
1724 - ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
1725 - wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
1726 - wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
1727 - core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
1728 -
1729 - if (((core->id.manuf == BCMA_MANUF_ARM) &&
1730 - (core->id.id == 0xFFF)) ||
1731 - (ports[1] == 0)) {
1732 - bcma_erom_skip_component(bus, &eromptr);
1733 + err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
1734 + if (err == -ENODEV) {
1735 + core_num++;
1736 continue;
1737 - }
1738 -
1739 - /* check if component is a core at all */
1740 - if (wrappers[0] + wrappers[1] == 0) {
1741 - /* we could save addrl of the router
1742 - if (cid == BCMA_CORE_OOB_ROUTER)
1743 - */
1744 - bcma_erom_skip_component(bus, &eromptr);
1745 + } else if (err == -ENXIO)
1746 continue;
1747 - }
1748 + else if (err == -ESPIPE)
1749 + break;
1750 + else if (err < 0)
1751 + return err;
1752
1753 - if (bcma_erom_is_bridge(bus, &eromptr)) {
1754 - bcma_erom_skip_component(bus, &eromptr);
1755 - continue;
1756 - }
1757 + core->core_index = core_num++;
1758 + bus->nr_cores++;
1759
1760 - /* get & parse master ports */
1761 - for (i = 0; i < ports[0]; i++) {
1762 - u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
1763 - if (mst_port_d < 0) {
1764 - err= -EILSEQ;
1765 - goto out;
1766 - }
1767 - }
1768 + pr_info("Core %d found: %s "
1769 + "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
1770 + core->core_index, bcma_device_name(&core->id),
1771 + core->id.manuf, core->id.id, core->id.rev,
1772 + core->id.class);
1773
1774 - /* get & parse slave ports */
1775 - for (i = 0; i < ports[1]; i++) {
1776 - for (j = 0; ; j++) {
1777 - tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1778 - SCAN_ADDR_TYPE_SLAVE, i);
1779 - if (tmp < 0) {
1780 - /* no more entries for port _i_ */
1781 - /* pr_debug("erom: slave port %d "
1782 - * "has %d descriptors\n", i, j); */
1783 - break;
1784 - } else {
1785 - if (i == 0 && j == 0)
1786 - core->addr = tmp;
1787 - }
1788 - }
1789 - }
1790 + list_add(&core->list, &bus->cores);
1791 + }
1792
1793 - /* get & parse master wrappers */
1794 - for (i = 0; i < wrappers[0]; i++) {
1795 - for (j = 0; ; j++) {
1796 - tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1797 - SCAN_ADDR_TYPE_MWRAP, i);
1798 - if (tmp < 0) {
1799 - /* no more entries for port _i_ */
1800 - /* pr_debug("erom: master wrapper %d "
1801 - * "has %d descriptors\n", i, j); */
1802 - break;
1803 - } else {
1804 - if (i == 0 && j == 0)
1805 - core->wrap = tmp;
1806 - }
1807 - }
1808 - }
1809 + if (bus->hosttype == BCMA_HOSTTYPE_SOC)
1810 + iounmap(eromptr);
1811
1812 - /* get & parse slave wrappers */
1813 - for (i = 0; i < wrappers[1]; i++) {
1814 - u8 hack = (ports[1] == 1) ? 0 : 1;
1815 - for (j = 0; ; j++) {
1816 - tmp = bcma_erom_get_addr_desc(bus, &eromptr,
1817 - SCAN_ADDR_TYPE_SWRAP, i + hack);
1818 - if (tmp < 0) {
1819 - /* no more entries for port _i_ */
1820 - /* pr_debug("erom: master wrapper %d "
1821 - * has %d descriptors\n", i, j); */
1822 - break;
1823 - } else {
1824 - if (wrappers[0] == 0 && !i && !j)
1825 - core->wrap = tmp;
1826 - }
1827 - }
1828 - }
1829 + return 0;
1830 +}
1831 +
1832 +int __init bcma_bus_scan_early(struct bcma_bus *bus,
1833 + struct bcma_device_id *match,
1834 + struct bcma_device *core)
1835 +{
1836 + u32 erombase;
1837 + u32 __iomem *eromptr, *eromend;
1838
1839 + int err = -ENODEV;
1840 + int core_num = 0;
1841 +
1842 + erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
1843 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
1844 + eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
1845 + if (!eromptr)
1846 + return -ENOMEM;
1847 + } else {
1848 + eromptr = bus->mmio;
1849 + }
1850 +
1851 + eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
1852 +
1853 + bcma_scan_switch_core(bus, erombase);
1854 +
1855 + while (eromptr < eromend) {
1856 + memset(core, 0, sizeof(*core));
1857 + INIT_LIST_HEAD(&core->list);
1858 + core->bus = bus;
1859 +
1860 + err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
1861 + if (err == -ENODEV) {
1862 + core_num++;
1863 + continue;
1864 + } else if (err == -ENXIO)
1865 + continue;
1866 + else if (err == -ESPIPE)
1867 + break;
1868 + else if (err < 0)
1869 + return err;
1870 +
1871 + core->core_index = core_num++;
1872 + bus->nr_cores++;
1873 pr_info("Core %d found: %s "
1874 "(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
1875 - bus->nr_cores, bcma_device_name(&core->id),
1876 + core->core_index, bcma_device_name(&core->id),
1877 core->id.manuf, core->id.id, core->id.rev,
1878 core->id.class);
1879
1880 - core->core_index = bus->nr_cores++;
1881 list_add(&core->list, &bus->cores);
1882 - continue;
1883 -out:
1884 - return err;
1885 + err = 0;
1886 + break;
1887 }
1888
1889 - return 0;
1890 + if (bus->hosttype == BCMA_HOSTTYPE_SOC)
1891 + iounmap(eromptr);
1892 +
1893 + return err;
1894 }
1895 --- /dev/null
1896 +++ b/drivers/bcma/sprom.c
1897 @@ -0,0 +1,247 @@
1898 +/*
1899 + * Broadcom specific AMBA
1900 + * SPROM reading
1901 + *
1902 + * Licensed under the GNU/GPL. See COPYING for details.
1903 + */
1904 +
1905 +#include "bcma_private.h"
1906 +
1907 +#include <linux/bcma/bcma.h>
1908 +#include <linux/bcma/bcma_regs.h>
1909 +#include <linux/pci.h>
1910 +#include <linux/io.h>
1911 +#include <linux/dma-mapping.h>
1912 +#include <linux/slab.h>
1913 +
1914 +#define SPOFF(offset) ((offset) / sizeof(u16))
1915 +
1916 +/**************************************************
1917 + * R/W ops.
1918 + **************************************************/
1919 +
1920 +static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom)
1921 +{
1922 + int i;
1923 + for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
1924 + sprom[i] = bcma_read16(bus->drv_cc.core,
1925 + offset + (i * 2));
1926 +}
1927 +
1928 +/**************************************************
1929 + * Validation.
1930 + **************************************************/
1931 +
1932 +static inline u8 bcma_crc8(u8 crc, u8 data)
1933 +{
1934 + /* Polynomial: x^8 + x^7 + x^6 + x^4 + x^2 + 1 */
1935 + static const u8 t[] = {
1936 + 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
1937 + 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
1938 + 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
1939 + 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
1940 + 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
1941 + 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
1942 + 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
1943 + 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
1944 + 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
1945 + 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
1946 + 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
1947 + 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
1948 + 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
1949 + 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
1950 + 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
1951 + 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
1952 + 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
1953 + 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
1954 + 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
1955 + 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
1956 + 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
1957 + 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
1958 + 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
1959 + 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
1960 + 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
1961 + 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
1962 + 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
1963 + 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
1964 + 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
1965 + 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
1966 + 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
1967 + 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
1968 + };
1969 + return t[crc ^ data];
1970 +}
1971 +
1972 +static u8 bcma_sprom_crc(const u16 *sprom)
1973 +{
1974 + int word;
1975 + u8 crc = 0xFF;
1976 +
1977 + for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) {
1978 + crc = bcma_crc8(crc, sprom[word] & 0x00FF);
1979 + crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
1980 + }
1981 + crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF);
1982 + crc ^= 0xFF;
1983 +
1984 + return crc;
1985 +}
1986 +
1987 +static int bcma_sprom_check_crc(const u16 *sprom)
1988 +{
1989 + u8 crc;
1990 + u8 expected_crc;
1991 + u16 tmp;
1992 +
1993 + crc = bcma_sprom_crc(sprom);
1994 + tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC;
1995 + expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
1996 + if (crc != expected_crc)
1997 + return -EPROTO;
1998 +
1999 + return 0;
2000 +}
2001 +
2002 +static int bcma_sprom_valid(const u16 *sprom)
2003 +{
2004 + u16 revision;
2005 + int err;
2006 +
2007 + err = bcma_sprom_check_crc(sprom);
2008 + if (err)
2009 + return err;
2010 +
2011 + revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
2012 + if (revision != 8 && revision != 9) {
2013 + pr_err("Unsupported SPROM revision: %d\n", revision);
2014 + return -ENOENT;
2015 + }
2016 +
2017 + return 0;
2018 +}
2019 +
2020 +/**************************************************
2021 + * SPROM extraction.
2022 + **************************************************/
2023 +
2024 +static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
2025 +{
2026 + u16 v;
2027 + int i;
2028 +
2029 + bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
2030 + SSB_SPROM_REVISION_REV;
2031 +
2032 + for (i = 0; i < 3; i++) {
2033 + v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
2034 + *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
2035 + }
2036 +
2037 + bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)];
2038 +
2039 + bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
2040 + SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT;
2041 + bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] &
2042 + SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT;
2043 + bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
2044 + SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT;
2045 + bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] &
2046 + SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT;
2047 +
2048 + bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
2049 + SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT;
2050 + bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] &
2051 + SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT;
2052 + bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
2053 + SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT;
2054 + bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] &
2055 + SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT;
2056 +
2057 + bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
2058 + SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT;
2059 + bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] &
2060 + SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT;
2061 + bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
2062 + SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT;
2063 + bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] &
2064 + SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT;
2065 +
2066 + bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
2067 + SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT;
2068 + bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] &
2069 + SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT;
2070 + bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
2071 + SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT;
2072 + bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] &
2073 + SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT;
2074 +
2075 + bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)];
2076 + bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)];
2077 + bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)];
2078 + bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)];
2079 +
2080 + bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)];
2081 +
2082 + bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
2083 + SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
2084 + bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
2085 + SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
2086 + bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
2087 + SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
2088 + bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
2089 + SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
2090 + bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] &
2091 + SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
2092 +
2093 + bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
2094 + SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT;
2095 + bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
2096 + SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT;
2097 + bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
2098 + SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT;
2099 + bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
2100 + SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT;
2101 + bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] &
2102 + SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT;
2103 +}
2104 +
2105 +int bcma_sprom_get(struct bcma_bus *bus)
2106 +{
2107 + u16 offset;
2108 + u16 *sprom;
2109 + int err = 0;
2110 +
2111 + if (!bus->drv_cc.core)
2112 + return -EOPNOTSUPP;
2113 +
2114 + if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
2115 + return -ENOENT;
2116 +
2117 + sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
2118 + GFP_KERNEL);
2119 + if (!sprom)
2120 + return -ENOMEM;
2121 +
2122 + if (bus->chipinfo.id == 0x4331)
2123 + bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
2124 +
2125 + /* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
2126 + * According to brcm80211 this applies to cards with PCIe rev >= 6
2127 + * TODO: understand this condition and use it */
2128 + offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM :
2129 + BCMA_CC_SPROM_PCIE6;
2130 + bcma_sprom_read(bus, offset, sprom);
2131 +
2132 + if (bus->chipinfo.id == 0x4331)
2133 + bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
2134 +
2135 + err = bcma_sprom_valid(sprom);
2136 + if (err)
2137 + goto out;
2138 +
2139 + bcma_sprom_extract_r8(bus, sprom);
2140 +
2141 +out:
2142 + kfree(sprom);
2143 + return err;
2144 +}
2145 --- a/include/linux/bcma/bcma.h
2146 +++ b/include/linux/bcma/bcma.h
2147 @@ -6,6 +6,8 @@
2148
2149 #include <linux/bcma/bcma_driver_chipcommon.h>
2150 #include <linux/bcma/bcma_driver_pci.h>
2151 +#include <linux/bcma/bcma_driver_mips.h>
2152 +#include <linux/ssb/ssb.h> /* SPROM sharing */
2153
2154 #include "bcma_regs.h"
2155
2156 @@ -13,9 +15,9 @@ struct bcma_device;
2157 struct bcma_bus;
2158
2159 enum bcma_hosttype {
2160 - BCMA_HOSTTYPE_NONE,
2161 BCMA_HOSTTYPE_PCI,
2162 BCMA_HOSTTYPE_SDIO,
2163 + BCMA_HOSTTYPE_SOC,
2164 };
2165
2166 struct bcma_chipinfo {
2167 @@ -24,6 +26,11 @@ struct bcma_chipinfo {
2168 u8 pkg;
2169 };
2170
2171 +enum bcma_clkmode {
2172 + BCMA_CLKMODE_FAST,
2173 + BCMA_CLKMODE_DYNAMIC,
2174 +};
2175 +
2176 struct bcma_host_ops {
2177 u8 (*read8)(struct bcma_device *core, u16 offset);
2178 u16 (*read16)(struct bcma_device *core, u16 offset);
2179 @@ -31,6 +38,12 @@ struct bcma_host_ops {
2180 void (*write8)(struct bcma_device *core, u16 offset, u8 value);
2181 void (*write16)(struct bcma_device *core, u16 offset, u16 value);
2182 void (*write32)(struct bcma_device *core, u16 offset, u32 value);
2183 +#ifdef CONFIG_BCMA_BLOCKIO
2184 + void (*block_read)(struct bcma_device *core, void *buffer,
2185 + size_t count, u16 offset, u8 reg_width);
2186 + void (*block_write)(struct bcma_device *core, const void *buffer,
2187 + size_t count, u16 offset, u8 reg_width);
2188 +#endif
2189 /* Agent ops */
2190 u32 (*aread32)(struct bcma_device *core, u16 offset);
2191 void (*awrite32)(struct bcma_device *core, u16 offset, u32 value);
2192 @@ -117,6 +130,9 @@ struct bcma_device {
2193 struct bcma_device_id id;
2194
2195 struct device dev;
2196 + struct device *dma_dev;
2197 +
2198 + unsigned int irq;
2199 bool dev_registered;
2200
2201 u8 core_index;
2202 @@ -124,6 +140,9 @@ struct bcma_device {
2203 u32 addr;
2204 u32 wrap;
2205
2206 + void __iomem *io_addr;
2207 + void __iomem *io_wrap;
2208 +
2209 void *drvdata;
2210 struct list_head list;
2211 };
2212 @@ -151,10 +170,9 @@ struct bcma_driver {
2213 };
2214 extern
2215 int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
2216 -static inline int bcma_driver_register(struct bcma_driver *drv)
2217 -{
2218 - return __bcma_driver_register(drv, THIS_MODULE);
2219 -}
2220 +#define bcma_driver_register(drv) \
2221 + __bcma_driver_register(drv, THIS_MODULE)
2222 +
2223 extern void bcma_driver_unregister(struct bcma_driver *drv);
2224
2225 struct bcma_bus {
2226 @@ -176,49 +194,105 @@ struct bcma_bus {
2227 struct bcma_device *mapped_core;
2228 struct list_head cores;
2229 u8 nr_cores;
2230 + u8 init_done:1;
2231
2232 struct bcma_drv_cc drv_cc;
2233 struct bcma_drv_pci drv_pci;
2234 + struct bcma_drv_mips drv_mips;
2235 +
2236 + /* We decided to share SPROM struct with SSB as long as we do not need
2237 + * any hacks for BCMA. This simplifies drivers code. */
2238 + struct ssb_sprom sprom;
2239 };
2240
2241 -extern inline u32 bcma_read8(struct bcma_device *core, u16 offset)
2242 +static inline u32 bcma_read8(struct bcma_device *core, u16 offset)
2243 {
2244 return core->bus->ops->read8(core, offset);
2245 }
2246 -extern inline u32 bcma_read16(struct bcma_device *core, u16 offset)
2247 +static inline u32 bcma_read16(struct bcma_device *core, u16 offset)
2248 {
2249 return core->bus->ops->read16(core, offset);
2250 }
2251 -extern inline u32 bcma_read32(struct bcma_device *core, u16 offset)
2252 +static inline u32 bcma_read32(struct bcma_device *core, u16 offset)
2253 {
2254 return core->bus->ops->read32(core, offset);
2255 }
2256 -extern inline
2257 +static inline
2258 void bcma_write8(struct bcma_device *core, u16 offset, u32 value)
2259 {
2260 core->bus->ops->write8(core, offset, value);
2261 }
2262 -extern inline
2263 +static inline
2264 void bcma_write16(struct bcma_device *core, u16 offset, u32 value)
2265 {
2266 core->bus->ops->write16(core, offset, value);
2267 }
2268 -extern inline
2269 +static inline
2270 void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
2271 {
2272 core->bus->ops->write32(core, offset, value);
2273 }
2274 -extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
2275 +#ifdef CONFIG_BCMA_BLOCKIO
2276 +static inline void bcma_block_read(struct bcma_device *core, void *buffer,
2277 + size_t count, u16 offset, u8 reg_width)
2278 +{
2279 + core->bus->ops->block_read(core, buffer, count, offset, reg_width);
2280 +}
2281 +static inline void bcma_block_write(struct bcma_device *core,
2282 + const void *buffer, size_t count,
2283 + u16 offset, u8 reg_width)
2284 +{
2285 + core->bus->ops->block_write(core, buffer, count, offset, reg_width);
2286 +}
2287 +#endif
2288 +static inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
2289 {
2290 return core->bus->ops->aread32(core, offset);
2291 }
2292 -extern inline
2293 +static inline
2294 void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
2295 {
2296 core->bus->ops->awrite32(core, offset, value);
2297 }
2298
2299 +static inline void bcma_mask32(struct bcma_device *cc, u16 offset, u32 mask)
2300 +{
2301 + bcma_write32(cc, offset, bcma_read32(cc, offset) & mask);
2302 +}
2303 +static inline void bcma_set32(struct bcma_device *cc, u16 offset, u32 set)
2304 +{
2305 + bcma_write32(cc, offset, bcma_read32(cc, offset) | set);
2306 +}
2307 +static inline void bcma_maskset32(struct bcma_device *cc,
2308 + u16 offset, u32 mask, u32 set)
2309 +{
2310 + bcma_write32(cc, offset, (bcma_read32(cc, offset) & mask) | set);
2311 +}
2312 +static inline void bcma_mask16(struct bcma_device *cc, u16 offset, u16 mask)
2313 +{
2314 + bcma_write16(cc, offset, bcma_read16(cc, offset) & mask);
2315 +}
2316 +static inline void bcma_set16(struct bcma_device *cc, u16 offset, u16 set)
2317 +{
2318 + bcma_write16(cc, offset, bcma_read16(cc, offset) | set);
2319 +}
2320 +static inline void bcma_maskset16(struct bcma_device *cc,
2321 + u16 offset, u16 mask, u16 set)
2322 +{
2323 + bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
2324 +}
2325 +
2326 extern bool bcma_core_is_enabled(struct bcma_device *core);
2327 +extern void bcma_core_disable(struct bcma_device *core, u32 flags);
2328 extern int bcma_core_enable(struct bcma_device *core, u32 flags);
2329 +extern void bcma_core_set_clockmode(struct bcma_device *core,
2330 + enum bcma_clkmode clkmode);
2331 +extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status,
2332 + bool on);
2333 +#define BCMA_DMA_TRANSLATION_MASK 0xC0000000
2334 +#define BCMA_DMA_TRANSLATION_NONE 0x00000000
2335 +#define BCMA_DMA_TRANSLATION_DMA32_CMT 0x40000000 /* Client Mode Translation for 32-bit DMA */
2336 +#define BCMA_DMA_TRANSLATION_DMA64_CMT 0x80000000 /* Client Mode Translation for 64-bit DMA */
2337 +extern u32 bcma_core_dma_translation(struct bcma_device *core);
2338
2339 #endif /* LINUX_BCMA_H_ */
2340 --- a/include/linux/bcma/bcma_driver_chipcommon.h
2341 +++ b/include/linux/bcma/bcma_driver_chipcommon.h
2342 @@ -24,6 +24,7 @@
2343 #define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */
2344 #define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */
2345 #define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */
2346 +#define BCMA_CC_FLASHT_NFLASH 0x00000200
2347 #define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */
2348 #define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */
2349 #define BCMA_PLLTYPE_NONE 0x00000000
2350 @@ -178,16 +179,9 @@
2351 #define BCMA_CC_PROG_CFG 0x0120
2352 #define BCMA_CC_PROG_WAITCNT 0x0124
2353 #define BCMA_CC_FLASH_CFG 0x0128
2354 +#define BCMA_CC_FLASH_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */
2355 #define BCMA_CC_FLASH_WAITCNT 0x012C
2356 -#define BCMA_CC_CLKCTLST 0x01E0 /* Clock control and status (rev >= 20) */
2357 -#define BCMA_CC_CLKCTLST_FORCEALP 0x00000001 /* Force ALP request */
2358 -#define BCMA_CC_CLKCTLST_FORCEHT 0x00000002 /* Force HT request */
2359 -#define BCMA_CC_CLKCTLST_FORCEILP 0x00000004 /* Force ILP request */
2360 -#define BCMA_CC_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */
2361 -#define BCMA_CC_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
2362 -#define BCMA_CC_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
2363 -#define BCMA_CC_CLKCTLST_HAVEHT 0x00010000 /* HT available */
2364 -#define BCMA_CC_CLKCTLST_HAVEALP 0x00020000 /* APL available */
2365 +/* 0x1E0 is defined as shared BCMA_CLKCTLST */
2366 #define BCMA_CC_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */
2367 #define BCMA_CC_UART0_DATA 0x0300
2368 #define BCMA_CC_UART0_IMR 0x0304
2369 @@ -209,6 +203,7 @@
2370 #define BCMA_CC_PMU_CTL 0x0600 /* PMU control */
2371 #define BCMA_CC_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */
2372 #define BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16
2373 +#define BCMA_CC_PMU_CTL_PLL_UPD 0x00000400
2374 #define BCMA_CC_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */
2375 #define BCMA_CC_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */
2376 #define BCMA_CC_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */
2377 @@ -244,6 +239,66 @@
2378 #define BCMA_CC_REGCTL_DATA 0x065C
2379 #define BCMA_CC_PLLCTL_ADDR 0x0660
2380 #define BCMA_CC_PLLCTL_DATA 0x0664
2381 +#define BCMA_CC_SPROM 0x0800 /* SPROM beginning */
2382 +#define BCMA_CC_SPROM_PCIE6 0x0830 /* SPROM beginning on PCIe rev >= 6 */
2383 +
2384 +/* Divider allocation in 4716/47162/5356 */
2385 +#define BCMA_CC_PMU5_MAINPLL_CPU 1
2386 +#define BCMA_CC_PMU5_MAINPLL_MEM 2
2387 +#define BCMA_CC_PMU5_MAINPLL_SSB 3
2388 +
2389 +/* PLL usage in 4716/47162 */
2390 +#define BCMA_CC_PMU4716_MAINPLL_PLL0 12
2391 +
2392 +/* PLL usage in 5356/5357 */
2393 +#define BCMA_CC_PMU5356_MAINPLL_PLL0 0
2394 +#define BCMA_CC_PMU5357_MAINPLL_PLL0 0
2395 +
2396 +/* 4706 PMU */
2397 +#define BCMA_CC_PMU4706_MAINPLL_PLL0 0
2398 +
2399 +/* ALP clock on pre-PMU chips */
2400 +#define BCMA_CC_PMU_ALP_CLOCK 20000000
2401 +/* HT clock for systems with PMU-enabled chipcommon */
2402 +#define BCMA_CC_PMU_HT_CLOCK 80000000
2403 +
2404 +/* PMU rev 5 (& 6) */
2405 +#define BCMA_CC_PPL_P1P2_OFF 0
2406 +#define BCMA_CC_PPL_P1_MASK 0x0f000000
2407 +#define BCMA_CC_PPL_P1_SHIFT 24
2408 +#define BCMA_CC_PPL_P2_MASK 0x00f00000
2409 +#define BCMA_CC_PPL_P2_SHIFT 20
2410 +#define BCMA_CC_PPL_M14_OFF 1
2411 +#define BCMA_CC_PPL_MDIV_MASK 0x000000ff
2412 +#define BCMA_CC_PPL_MDIV_WIDTH 8
2413 +#define BCMA_CC_PPL_NM5_OFF 2
2414 +#define BCMA_CC_PPL_NDIV_MASK 0xfff00000
2415 +#define BCMA_CC_PPL_NDIV_SHIFT 20
2416 +#define BCMA_CC_PPL_FMAB_OFF 3
2417 +#define BCMA_CC_PPL_MRAT_MASK 0xf0000000
2418 +#define BCMA_CC_PPL_MRAT_SHIFT 28
2419 +#define BCMA_CC_PPL_ABRAT_MASK 0x08000000
2420 +#define BCMA_CC_PPL_ABRAT_SHIFT 27
2421 +#define BCMA_CC_PPL_FDIV_MASK 0x07ffffff
2422 +#define BCMA_CC_PPL_PLLCTL_OFF 4
2423 +#define BCMA_CC_PPL_PCHI_OFF 5
2424 +#define BCMA_CC_PPL_PCHI_MASK 0x0000003f
2425 +
2426 +/* BCM4331 ChipControl numbers. */
2427 +#define BCMA_CHIPCTL_4331_BT_COEXIST BIT(0) /* 0 disable */
2428 +#define BCMA_CHIPCTL_4331_SECI BIT(1) /* 0 SECI is disabled (JATG functional) */
2429 +#define BCMA_CHIPCTL_4331_EXT_LNA BIT(2) /* 0 disable */
2430 +#define BCMA_CHIPCTL_4331_SPROM_GPIO13_15 BIT(3) /* sprom/gpio13-15 mux */
2431 +#define BCMA_CHIPCTL_4331_EXTPA_EN BIT(4) /* 0 ext pa disable, 1 ext pa enabled */
2432 +#define BCMA_CHIPCTL_4331_GPIOCLK_ON_SPROMCS BIT(5) /* set drive out GPIO_CLK on sprom_cs pin */
2433 +#define BCMA_CHIPCTL_4331_PCIE_MDIO_ON_SPROMCS BIT(6) /* use sprom_cs pin as PCIE mdio interface */
2434 +#define BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5 BIT(7) /* aband extpa will be at gpio2/5 and sprom_dout */
2435 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXCLKEN BIT(8) /* override core control on pipe_AuxClkEnable */
2436 +#define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN BIT(9) /* override core control on pipe_AuxPowerDown */
2437 +#define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN BIT(10) /* pcie_auxclkenable */
2438 +#define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN BIT(11) /* pcie_pipe_pllpowerdown */
2439 +#define BCMA_CHIPCTL_4331_BT_SHD0_ON_GPIO4 BIT(16) /* enable bt_shd0 at gpio4 */
2440 +#define BCMA_CHIPCTL_4331_BT_SHD1_ON_GPIO5 BIT(17) /* enable bt_shd1 at gpio5 */
2441
2442 /* Data for the PMU, if available.
2443 * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
2444 @@ -253,14 +308,37 @@ struct bcma_chipcommon_pmu {
2445 u32 crystalfreq; /* The active crystal frequency (in kHz) */
2446 };
2447
2448 +#ifdef CONFIG_BCMA_DRIVER_MIPS
2449 +struct bcma_pflash {
2450 + u8 buswidth;
2451 + u32 window;
2452 + u32 window_size;
2453 +};
2454 +
2455 +struct bcma_serial_port {
2456 + void *regs;
2457 + unsigned long clockspeed;
2458 + unsigned int irq;
2459 + unsigned int baud_base;
2460 + unsigned int reg_shift;
2461 +};
2462 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
2463 +
2464 struct bcma_drv_cc {
2465 struct bcma_device *core;
2466 u32 status;
2467 u32 capabilities;
2468 u32 capabilities_ext;
2469 + u8 setup_done:1;
2470 /* Fast Powerup Delay constant */
2471 u16 fast_pwrup_delay;
2472 struct bcma_chipcommon_pmu pmu;
2473 +#ifdef CONFIG_BCMA_DRIVER_MIPS
2474 + struct bcma_pflash pflash;
2475 +
2476 + int nr_serial_ports;
2477 + struct bcma_serial_port serial_ports[4];
2478 +#endif /* CONFIG_BCMA_DRIVER_MIPS */
2479 };
2480
2481 /* Register access */
2482 @@ -281,6 +359,8 @@ extern void bcma_core_chipcommon_init(st
2483 extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
2484 extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
2485
2486 +void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
2487 +
2488 extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
2489 u32 ticks);
2490
2491 @@ -299,4 +379,13 @@ u32 bcma_chipco_gpio_polarity(struct bcm
2492 /* PMU support */
2493 extern void bcma_pmu_init(struct bcma_drv_cc *cc);
2494
2495 +extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset,
2496 + u32 value);
2497 +extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset,
2498 + u32 mask, u32 set);
2499 +extern void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
2500 + u32 offset, u32 mask, u32 set);
2501 +extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc,
2502 + u32 offset, u32 mask, u32 set);
2503 +
2504 #endif /* LINUX_BCMA_DRIVER_CC_H_ */
2505 --- /dev/null
2506 +++ b/include/linux/bcma/bcma_driver_mips.h
2507 @@ -0,0 +1,51 @@
2508 +#ifndef LINUX_BCMA_DRIVER_MIPS_H_
2509 +#define LINUX_BCMA_DRIVER_MIPS_H_
2510 +
2511 +#define BCMA_MIPS_IPSFLAG 0x0F08
2512 +/* which sbflags get routed to mips interrupt 1 */
2513 +#define BCMA_MIPS_IPSFLAG_IRQ1 0x0000003F
2514 +#define BCMA_MIPS_IPSFLAG_IRQ1_SHIFT 0
2515 +/* which sbflags get routed to mips interrupt 2 */
2516 +#define BCMA_MIPS_IPSFLAG_IRQ2 0x00003F00
2517 +#define BCMA_MIPS_IPSFLAG_IRQ2_SHIFT 8
2518 +/* which sbflags get routed to mips interrupt 3 */
2519 +#define BCMA_MIPS_IPSFLAG_IRQ3 0x003F0000
2520 +#define BCMA_MIPS_IPSFLAG_IRQ3_SHIFT 16
2521 +/* which sbflags get routed to mips interrupt 4 */
2522 +#define BCMA_MIPS_IPSFLAG_IRQ4 0x3F000000
2523 +#define BCMA_MIPS_IPSFLAG_IRQ4_SHIFT 24
2524 +
2525 +/* MIPS 74K core registers */
2526 +#define BCMA_MIPS_MIPS74K_CORECTL 0x0000
2527 +#define BCMA_MIPS_MIPS74K_EXCEPTBASE 0x0004
2528 +#define BCMA_MIPS_MIPS74K_BIST 0x000C
2529 +#define BCMA_MIPS_MIPS74K_INTMASK_INT0 0x0014
2530 +#define BCMA_MIPS_MIPS74K_INTMASK(int) \
2531 + ((int) * 4 + BCMA_MIPS_MIPS74K_INTMASK_INT0)
2532 +#define BCMA_MIPS_MIPS74K_NMIMASK 0x002C
2533 +#define BCMA_MIPS_MIPS74K_GPIOSEL 0x0040
2534 +#define BCMA_MIPS_MIPS74K_GPIOOUT 0x0044
2535 +#define BCMA_MIPS_MIPS74K_GPIOEN 0x0048
2536 +#define BCMA_MIPS_MIPS74K_CLKCTLST 0x01E0
2537 +
2538 +#define BCMA_MIPS_OOBSELOUTA30 0x100
2539 +
2540 +struct bcma_device;
2541 +
2542 +struct bcma_drv_mips {
2543 + struct bcma_device *core;
2544 + u8 setup_done:1;
2545 + unsigned int assigned_irqs;
2546 +};
2547 +
2548 +#ifdef CONFIG_BCMA_DRIVER_MIPS
2549 +extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
2550 +#else
2551 +static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { }
2552 +#endif
2553 +
2554 +extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
2555 +
2556 +extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
2557 +
2558 +#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
2559 --- a/include/linux/bcma/bcma_driver_pci.h
2560 +++ b/include/linux/bcma/bcma_driver_pci.h
2561 @@ -85,5 +85,7 @@ struct bcma_drv_pci {
2562 #define pcicore_write32(pc, offset, val) bcma_write32((pc)->core, offset, val)
2563
2564 extern void bcma_core_pci_init(struct bcma_drv_pci *pc);
2565 +extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
2566 + struct bcma_device *core, bool enable);
2567
2568 #endif /* LINUX_BCMA_DRIVER_PCI_H_ */
2569 --- a/include/linux/bcma/bcma_regs.h
2570 +++ b/include/linux/bcma/bcma_regs.h
2571 @@ -1,13 +1,38 @@
2572 #ifndef LINUX_BCMA_REGS_H_
2573 #define LINUX_BCMA_REGS_H_
2574
2575 +/* Some single registers are shared between many cores */
2576 +/* BCMA_CLKCTLST: ChipCommon (rev >= 20), PCIe, 80211 */
2577 +#define BCMA_CLKCTLST 0x01E0 /* Clock control and status */
2578 +#define BCMA_CLKCTLST_FORCEALP 0x00000001 /* Force ALP request */
2579 +#define BCMA_CLKCTLST_FORCEHT 0x00000002 /* Force HT request */
2580 +#define BCMA_CLKCTLST_FORCEILP 0x00000004 /* Force ILP request */
2581 +#define BCMA_CLKCTLST_HAVEALPREQ 0x00000008 /* ALP available request */
2582 +#define BCMA_CLKCTLST_HAVEHTREQ 0x00000010 /* HT available request */
2583 +#define BCMA_CLKCTLST_HWCROFF 0x00000020 /* Force HW clock request off */
2584 +#define BCMA_CLKCTLST_EXTRESREQ 0x00000700 /* Mask of external resource requests */
2585 +#define BCMA_CLKCTLST_HAVEALP 0x00010000 /* ALP available */
2586 +#define BCMA_CLKCTLST_HAVEHT 0x00020000 /* HT available */
2587 +#define BCMA_CLKCTLST_BP_ON_ALP 0x00040000 /* RO: running on ALP clock */
2588 +#define BCMA_CLKCTLST_BP_ON_HT 0x00080000 /* RO: running on HT clock */
2589 +#define BCMA_CLKCTLST_EXTRESST 0x07000000 /* Mask of external resource status */
2590 +/* Is there any BCM4328 on BCMA bus? */
2591 +#define BCMA_CLKCTLST_4328A0_HAVEHT 0x00010000 /* 4328a0 has reversed bits */
2592 +#define BCMA_CLKCTLST_4328A0_HAVEALP 0x00020000 /* 4328a0 has reversed bits */
2593 +
2594 /* Agent registers (common for every core) */
2595 -#define BCMA_IOCTL 0x0408
2596 +#define BCMA_IOCTL 0x0408 /* IO control */
2597 #define BCMA_IOCTL_CLK 0x0001
2598 #define BCMA_IOCTL_FGC 0x0002
2599 #define BCMA_IOCTL_CORE_BITS 0x3FFC
2600 #define BCMA_IOCTL_PME_EN 0x4000
2601 #define BCMA_IOCTL_BIST_EN 0x8000
2602 +#define BCMA_IOST 0x0500 /* IO status */
2603 +#define BCMA_IOST_CORE_BITS 0x0FFF
2604 +#define BCMA_IOST_DMA64 0x1000
2605 +#define BCMA_IOST_GATED_CLK 0x2000
2606 +#define BCMA_IOST_BIST_ERROR 0x4000
2607 +#define BCMA_IOST_BIST_DONE 0x8000
2608 #define BCMA_RESET_CTL 0x0800
2609 #define BCMA_RESET_CTL_RESET 0x0001
2610
2611 --- /dev/null
2612 +++ b/include/linux/bcma/bcma_soc.h
2613 @@ -0,0 +1,16 @@
2614 +#ifndef LINUX_BCMA_SOC_H_
2615 +#define LINUX_BCMA_SOC_H_
2616 +
2617 +#include <linux/bcma/bcma.h>
2618 +
2619 +struct bcma_soc {
2620 + struct bcma_bus bus;
2621 + struct bcma_device core_cc;
2622 + struct bcma_device core_mips;
2623 +};
2624 +
2625 +int __init bcma_host_soc_register(struct bcma_soc *soc);
2626 +
2627 +int bcma_bus_register(struct bcma_bus *bus);
2628 +
2629 +#endif /* LINUX_BCMA_SOC_H_ */
This page took 0.185878 seconds and 5 git commands to generate.